Skip to content

Conversation

@vespakoen
Copy link
Contributor

@vespakoen vespakoen commented Nov 23, 2020

This is for macOS only at the moment, and probably breaks scrolling on windows and linux.
This is just an initial experiment, tested with a trackpad and an external mouse with a scroll wheel on macOS.

I will test this on windows and linux and will move the calculations to the platform specific code.

EDIT: Damn.. looks like my editor decided to format the whole mouse.cpp file...

@phkahler
Copy link
Member

phkahler commented Nov 24, 2020

@vespakoen What's wrong with the way scroll wheell works now?

@vespakoen
Copy link
Contributor Author

Right now I have to scroll "large amounts" for a zoom to happen, and the amount / speed is not taken into account.
The scrolling right now is based on the amount of events, and I want to base it on the amount of "pixels scrolled".

Right now it casts the scroll amount to an integer, and always zoom by *= or /= 1.2.

When scrolling slowly now, nothing happens, with this change, scrolling starts immediately and is smooth.

However, this is only tested on macOS right now, and I should probably change the code so it actually only changes the scrolling behaviour on macOS right now until I test / implement it on Windows / Linux.

@vespakoen vespakoen force-pushed the mouse-zoom-improvements branch from 11408ac to aa0950d Compare November 24, 2020 06:54
@vespakoen
Copy link
Contributor Author

vespakoen commented Nov 24, 2020

I made some changes so that it should only affect macOS. can someone test this on Windows / Linux?
We could possibly also add a setting to enable "smooth scroll" that takes the scrolled distance into account for Windows / Linux and gather some feedback?

On macOS I tested it with a Magic Trackpad 2, a Magic Mouse and a simple Logitech mouse with a scroll wheel and those are all working great now.

@ruevs ruevs force-pushed the mouse-zoom-improvements branch 2 times, most recently from 4b24536 to 8a0b29c Compare November 24, 2020 11:08
@ruevs
Copy link
Member

ruevs commented Nov 24, 2020

I amended the commit and force pushed it to what I think should be the right incantation for Windows.
https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-mousewheel

With a normal mouse I can not achieve anything but 0.2 (1.2) though. I'll go to a machine with a 10 point multi touch screen now and test. I don't have access to a Windows laptop with a "modern" trackpad so if anyone has please test it.

@vespakoen
Copy link
Contributor Author

I'll test it out with my 3 "mice" on Windows this evening (need to be on macOS for work today)
Can you upload your SolveSpace.exe for this build perhaps?

@ruevs
Copy link
Member

ruevs commented Nov 24, 2020

Tried zooming with

  • scroll wheel on a normal mouse
  • pinch zoom on a 10 point multi-touch screen showing up as a USB "HID-compliant touch screen"
  • two finger drag on a Bluetooth keyboard and touch pad combo showing up as a HID-compliant mouse

On all of them GET_WHEEL_DELTA_WPARAM(wParam) is 120 and thus event.scrollDelta is 0.2. Menanig that I can not get zoom speed dependent on the "action speed".

But scrolling works just as good as it always has on Windows, so I am fine with this change.

@ruevs
Copy link
Member

ruevs commented Nov 24, 2020

By the way the documentation states:

The delta was set to 120 to allow Microsoft or other vendors to build finer-resolution wheels (a freely-rotating wheel with no notches) to send more messages per rotation, but with a smaller value in each message. To use this feature, you can either add the incoming delta values until WHEEL_DELTA is reached (so for a delta-rotation you get the same response), or scroll partial lines in response to the more frequent messages. You can also choose your scroll granularity and accumulate deltas until it is reached.

So theoretically some devices may send different deltas, but the ones I have probably just generate more or less frequent events with 120. But the calculation

event.scrollDelta = 0.2 * GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA;

should handle them properly.

@ruevs
Copy link
Member

ruevs commented Nov 24, 2020

@vespakoen
Copy link
Contributor Author

Awesome! Excited to try it out later, thanks a lot =)

@vespakoen
Copy link
Contributor Author

I just tried this out in Windows, it works fine but the scrolling is a bit coarse to my taste, I would suggest using 0.1 in stead of 0.2 for the scaling. The logic all looks correct though, and trackpad and mouse behave similarly.

Guess we just have to make sure nothing broke on linux. I bricked my linux install but I will try to get it working again or boot it live from a usb stick tomorrow.

@phkahler
Copy link
Member

The patch (from the commit) here works on Linux. Not sure the zooming is any different on my normal 3-button mouse. Might be a little more sensitive but not excessively IMO.

@vespakoen
Copy link
Contributor Author

I just changed the zoom to 0.1 for windows and linux, let me know if this makes things too slow or if it is fine.

@ruevs
Copy link
Member

ruevs commented Nov 25, 2020

A definite HUGE NO from me for a 1.1 (0.1) zoom factor! Unacceptably slow!
I don't care for smoothness - in fact I turn off all animations and fade effects in the UI. I want speed!
While working in #815 I was considering increasing it to 0.3 or at least 0.25, but decided against it in order not to change the experience for existing users.

AnimationsAreCrap

@vespakoen
Copy link
Contributor Author

Fair enough, It looks like Windows just doesn't support my "Magic Trackpad" well, everything scrolls way to fast (even when setting to "scroll 1 line" only)

So I will revert Windows and Linux to 0.2, and call it good =)

@vespakoen vespakoen changed the title WIP: Improve zooming with trackpad and scrollwheel (macOS only at the moment) Fix zoom not working while scrolling slowly on macOS, take WHEEL_DELTA into account on Windows. Nov 25, 2020
@vespakoen vespakoen marked this pull request as ready for review November 25, 2020 09:25
@ruevs ruevs force-pushed the mouse-zoom-improvements branch from 1667b45 to 126ea8b Compare November 25, 2020 09:27
@ruevs
Copy link
Member

ruevs commented Nov 25, 2020

If for some reason "very fine zooming" is important we can (at least on Windows) easily do Shift+Scroll and do 0.01 in that case.

I'm sorry for being too "pushy" but I pushed this change. Please comment.

Shift+Scroll should be also trivial on GTK but I can not test it.

@ruevs ruevs force-pushed the mouse-zoom-improvements branch 2 times, most recently from c5d1bfb to d081d5a Compare November 25, 2020 09:38
@ruevs
Copy link
Member

ruevs commented Nov 25, 2020

OK I pushed guigtk.cpp without even compiling it (it seems trivial enough) - I am sorry.

@vespakoen @phkahler please try it. And if the whole "Shift+Scroll" idea seems stupid I will revert it.

Attached is a Windows binary for testing
solvespace_PR825_Win32_x86_GL1.zip

ruevs
ruevs previously requested changes Nov 25, 2020
@vespakoen
Copy link
Contributor Author

No worries on being "pushy", happy that it's being worked on...
For me, the scrolling on macOS is working perfectly now, and it's for sure a big improvement over the last version, I don't need extra precision on macOS because the system already handles it, if I scroll very fast it will also zoom very fast now, but scrolling slow will be very precise.

It looks like on Linux we don't take the 'distance scrolled' into account yet, and simply look at the amount of events.
It might be worth investigating if using a scale based on the amount scrolled (like I did on macOS) gives a better experience.

@phkahler
Copy link
Member

The current version of this seems to work fine on Linux.

@phkahler
Copy link
Member

BTW using SHIFT is enough to slow it way down on Linux. Seems like a nice little extra.

@ruevs ruevs force-pushed the mouse-zoom-improvements branch from d081d5a to dacadea Compare November 25, 2020 23:06
@ruevs
Copy link
Member

ruevs commented Nov 25, 2020

After playing with it some more I changed the Shift+Scroll zoom to be 10x slower than the normal zoom. The original 20x was a bit excessive. What do you guys think?

Especially @jwesthues what is your opinion on the whole Shift+Scroll feature? Your taste in UI is very good in my opinion, based on using SolveSpace for 8+ years :-)

@vespakoen Should we do something on Mac with Shift+Scroll? If we do it on other platforms it would be good for consistency.
What does the if([nsEvent momentumPhase] != NSEventPhaseNone || [nsEvent phase] != NSEventPhaseNone) do?

On Linux/GTK using actual scroll deltas for smooth scrolling definitely seems possible based on the docummentation. It seems some systems even send GDK_SCROLL_SMOOTH events and in that case gdk_event_get_scroll_deltas can be used to get double precision scroll deltas.
I would try to implement it myself, but the only Linux "box" I have is a Raspberry Pi 3 - I'm not sure if I'll succeed ;-)

On Windows smooth scrolling seems to be a matter of support in the lower layers (drivers, devices) and the current code in this PR should "just work" when a device supports it.

One thing we can improve is use SystemParametersInfoW to get SPI_GETWHEELSCROLLLINES which is the "number of lines to scroll per WHEEL_DELTA" in the mouse options in Control Panel (default 3) we could use this to increase or decrease the default 1.2 zoom factor. This would solve @vespakoen's problem with scrolling being too sensitive and the configuration not making a difference.
Should I implement this as a separate commit in this PR? Or a new PR after this is merged? Or not at all?

@ruevs
Copy link
Member

ruevs commented Nov 27, 2020

An here https://fossies.org/linux/scintilla/gtk/ScintillaGTK.cxx on line 1897+ they simulate smooth scrolling by timing the scroll events.... brrrrr...

@phkahler
Copy link
Member

An here https://fossies.org/linux/scintilla/gtk/ScintillaGTK.cxx on line 1897+ they simulate smooth scrolling by timing the scroll events.... brrrrr...

Yeah, screw that. It's an unsupported feature further upstream and that's where it should be fixed.

BTW, how does it run on the PI? I've been dying to know.

@ruevs
Copy link
Member

ruevs commented Nov 27, 2020

BTW, how does it run on the PI? I've been dying to know.

It works fine. I have not done anything complicated so I can not say much about the performance. Starting takes a perceptible time - a second or two.

There is a strange glitch with the menu bar disappearing (black). You need to hit e.g. Alt-F to make it show up. It's weird. Otherwise it works fine.

One thing it does better than Windows is render tiny objects at huge zoom levels (guess what I was testing:-D ). I think this is because it uses some kind of 128bit OpenGL implementation. I will post details when I am on the Raspberry again.
2nm9nmTriangularPrism.zip

Unlike Windows dimension lines are properly drawn down to ~1.5nm and zoomed in to take up the whole (1920x1080) screen.

@ruevs
Copy link
Member

ruevs commented Nov 27, 2020

An here https://fossies.org/linux/scintilla/gtk/ScintillaGTK.cxx on line 1897+ they simulate smooth scrolling by timing the scroll events.... brrrrr...

Yeah, screw that. It's an unsupported feature further upstream and that's where it should be fixed.

Absolutely!

@vespakoen vespakoen force-pushed the mouse-zoom-improvements branch 2 times, most recently from 6c126d8 to 269d561 Compare November 30, 2020 21:24
@vespakoen
Copy link
Contributor Author

vespakoen commented Nov 30, 2020

Thanks for all the suggestions and testing!
And glad you had some fun on the way ;)

I just noticed this PR breaks the scrolling on the text window (at least on macOS). I am working on a fix... EDIT: done

The option to precisely scroll while holding Shift is also a nice addition, this way I can "smooth scroll" on Windows with the trackpad.

@ruevs this line: if([nsEvent momentumPhase] != NSEventPhaseNone || [nsEvent phase] != NSEventPhaseNone) checks if the input device is a Trackpad, there is probably a better way to do this but this works fine on all the macs I tested it on so far.
I stored that in a variable isTrackpad to make more clear what it's for.

Unfortunately the text window scrolling is a bit hard to get working right, so it will probably take a couple of days before this PR is in good shape...

I ignored the scrollDelta for the TextWindow and now it seems to be working again.

Let me know if this works fine on Windows and Linux, then this should be good to go.

@vespakoen vespakoen force-pushed the mouse-zoom-improvements branch from 269d561 to 90e78f9 Compare November 30, 2020 23:42
@vespakoen vespakoen requested a review from ruevs November 30, 2020 23:48
@vespakoen vespakoen dismissed ruevs’s stale review December 1, 2020 08:42

The diff outdated, but the changes are made.

@ruevs
Copy link
Member

ruevs commented Dec 1, 2020

I'll take alook soon(ish) :-)

@vespakoen
Copy link
Contributor Author

Cool, and no rush! the important thing to make sure still works fine is scrolling the info panel.

@ruevs
Copy link
Member

ruevs commented Dec 1, 2020

OK going one by one:

  • I love the way you moved the shift check to GraphicsWindow::MouseEvent - this is the proper place and makes the code much cleaner!

  • The text window scrolling worked even in 269d561 and the previous revisions on Widows and RasPi. What we effectively had done was decrease the default "delta" for one mouse wheel click from 1 to 0.2. What the delta values on Mac "before and after" are I can not say. With your last commit 90e78f9 you forced it to 0.2 in the text windows for all platforms.

  • The above made me think that having delta=1 for one scroll wheel click is a nice abstraction (this was the original behaviour).

  • You added the exp() in he correct place, but to keep the default zoom factor for one "scroll wheel click" 1.2x with delta=1 it needs to be
    scale *= exp(0.1823216 * delta);
    where ln(1.2) = 0.1823216

  • I don't understand why your change breaks the text window scrolling on macOS. How does it break it?

I looked at the macOS docs
https://developer.apple.com/documentation/appkit/nsevent
https://developer.apple.com/documentation/appkit/nsevent/1534158-deltay
https://developer.apple.com/documentation/appkit/nsevent/1535387-scrollingdeltay
From the last one it seems that

When hasPreciseScrollingDeltas is false, multiply [scrollingDeltaY] by the line or row height. Otherwise scroll by the returned amount.

We do have a LINE_HEIGHT= 20 so if your expression mimics hasPreciseScrollingDeltas then the two constants should be e.g. 1000 and 50 ... but how does this correspond to "one scroll wheel click"?

In my opinion you should test with a "normal" (PC) mouse connected to the mac and see what scrollingDeltaY is for one click of the wheel. Then adjust the "imprecise" constant so that delta = 1 in this case and make the "precise" one 20 times bigger. But even the current 500 and 50 (rescaled for delta=1 instead of 0.2) should be fine.

In this way (I guess) you should not have to change textwin.cpp.

Also does using hasPreciseScrollingDeltas instead of the current isTouchpad expression make sense? The docs seem to imply it.

With all of the above in mind I will force push my changes to make delta=1 by default (and 0.1823216). I will also revert the text window change - it does not seem right - please see above and double check what is going on on Mac.

@ruevs ruevs force-pushed the mouse-zoom-improvements branch 2 times, most recently from 03aa308 to 0960c59 Compare December 1, 2020 20:48
@ruevs
Copy link
Member

ruevs commented Dec 1, 2020

@vespakoen even if you figure out the text window on Mac please do not merge this yet.
Once this part is clear I want to implement and add the checking of the mouse scroll sensitivity settings on Windows that I mentioned above](#825 (comment)) - this time as a separate commit ;-)

And also the gdk_event_get_scroll_deltas for smooth scrolling on Linux/GTK (even though I can not test how in works on the Raspberry).

@vespakoen
Copy link
Contributor Author

Hey, this is great! I was also thinking to change the scroll delta back to 1, so thanks for that!

And hasPreciseScrollingDeltas is a great find! I'll experiment with it and get the macOS side of this PR back in shape.

The problem with the text window I had (on macOS) was that when scrolling less than a line, the text window "jumps back up" to the nearest line, so every scroll event should at least move it a whole line for it to even scroll at all on macOS.

Basically it would have been nicer if the Window itself would handle the scrolling, and the content would change based on the position, but that is out of the scope of this issue.

@vespakoen vespakoen force-pushed the mouse-zoom-improvements branch from 0960c59 to 1c1b736 Compare December 2, 2020 11:07
On macOS actual scroll delta is used for the zoom amount.
On Windows WHEEL_DELTA is used to allow smooth scrolling if supported.
Shift+Scroll is added for 10x finer zooming.
@vespakoen vespakoen force-pushed the mouse-zoom-improvements branch from 1c1b736 to f237ab3 Compare December 2, 2020 11:56
@vespakoen
Copy link
Contributor Author

I updated the code to use isPrecise, and tweaked the values a bit, it is correctly reporting my touchpad as precise and external mouse as imprecise.

The text window also scrolls better now by removing this from guimac in SetScrollbarPosition, I didn't see a regression from removing it, and it was causing a kind of a loop that I think was not intended to be there:

-        if(onScrollbarAdjusted) {
-            onScrollbarAdjusted(pos);
-        }

When scrolling very slowly, the scrollDelta was so small that it didn't scroll a single pixel.

I added a check back to the TextWindow that now makes sure the scrollDelta is at least 0.2 or -0.2 which results in an offset of at least 2 pixels. Somehow, using 1 pixel didn't fix it, It has to do with rounding somewhere, but that was too hairy to try and understand for me at this point.

The code I wrote can probably be expressed better than I did now, let me know if you have any suggestions, or simply force push again ;)

@vespakoen
Copy link
Contributor Author

Can we merge this and make a new PR for smooth scrolling on Linux once that's a thing?
This is quite an annoying bug on macOS at the moment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants