Beep6581 / RawTherapee

A powerful cross-platform raw photo processing program
https://rawtherapee.com
GNU General Public License v3.0
2.78k stars 315 forks source link

Trackpad gestures #5426

Open Davide-sd opened 5 years ago

Davide-sd commented 5 years ago

I just installed Rawtherapee on a Windows 10 laptop, which comes with a decent trackpad and a handful of useful gestures. I'm most interested in the zoom and swipe to scroll between photos.

Looking at the settings, I did not find any references to gestures. At the moment, it is possible to zoom by moving two fingers in the trackpad (both vertical and horizontal), but the zoom velocity is very very high even using medium sensitivity. Would love a slower zoom.

About scrolling photos, would it be possible to implement something like a two-finger swipe (left-right) two change to the previous or next photo?

Entropy512 commented 5 years ago

Two-finger scrolling is a fairly default behavior usually implemented in the OS trackpad driver.

That said - I can confirm that on an Ubuntu 19.04 laptop with an ELAN touchpad (Acer Aspire R15), zoom gain is waaaay too high - if anything one of the first things I noticed when giving RT a try after working with another application for a while. I haven't compared against a proper hardware mouse yet... I've been doing most of my work on the living room floor lately. :)

Same goes for the file browser - a slight movement of the trackpad goes from the beginning of the directory to the end almost instantly.

Scroll response is OK within the Settings screen.

This is on a build from the git "dev" branch as of early Saturday.

On your machine, do you know if two-finger swipe right and left gets mapped at a low level to a mouse axis? (Some mice do support left/right scroll in addition to up/down) I'm not sure if any trackpad drivers actually return individual multitouch data to the application, at least for the touchpad?

Entropy512 commented 5 years ago

If you place your mouse cursor over the upper film roll and two-finger swipe left/right - do you see it scroll?

It scrolls for me, but at similarly incredibly high gain as zooming in/out.

Also - while the thumbnails in the file browser have extremely high scroll gain with my trackpad, the folder list on the left does not.

Thanatomanic commented 5 years ago

I'm pretty sure we're all very inexperienced in handling any other input method than a simple mouse and keyboard. At least afaik RT hasn't been optimized for use with a trackpad. If anyone can point to a good resource on how to handle those (including maybe ease-in and ease-out functions for movement) that would be a start in the right direction.

Entropy512 commented 5 years ago

Good question. I'll see what I can find, and see if I can see something obvious in RT's code that explains why only certain uses of scrollwheel input misbehave with this particular variation of scrollwheel input.

For the file browser main window (e.g. where thumbnails are displayed, not the folder list on the left), I'm wondering if it is somehow connected with the fact that with a mouse, RT maps exactly one "click" of the scrollwheel detents (I need to look at evtest or something similar tonight or tomorrow to see how much one "click" on this mouse's scrollwheel is in terms of scroll axis movement) to one row of images.

Possibly a similar phenomenon for zoom increments?

Similarly, the upper "film roll" display (not sure what the normal RT terminology for this is) above the image being currently edited in the editor has a similar "one scroll detent = one image" behavior with my mouse scrollwheel.

Entropy512 commented 5 years ago

Looks like potential resources (I won't get a chance to review them in detail for applicability until tonight): https://gitlab.gnome.org/GNOME/gtk/issues/1308

https://github.com/lxde/lxterminal/issues/33 which points to https://developer.gnome.org/gtk3/stable/GtkScrolledWindow.html#gtk-scrolled-window-set-kinetic-scrolling

In what files are the scrolling behaviors for the components of RT that I mention above located? Maybe I can take a look later this week. (Upcoming family wedding and vacation the following week so I won't have too much time to investigate and come up to speed on a new codebase.)

heckflosse commented 5 years ago

@Entropy512

zoom gain is waaaay too high

zoom ratios in RT are not linear, Maybe that's the problem:

On a D800 36 MP file at my screen it opens at 18% Next steps (by pressing + key) are 20% 25% 33% 50% 100% 200% 300% 400% 500% 600% 700% 800% 1600%

Entropy512 commented 5 years ago

That might be part of it.

For the thumbnails browser - is scroll handling handled in ThumbBrowserBase::scroll() in thumbbrowserbase.cc ?

If I'm reading this correctly, if it gets a GDK_SCROLL_SMOOTH event, it's treated the same as a single GDK_SCROLL_UP or GDK_SCROLL_DOWN event regardless of the value of delta?

Possibly the solution is to have coef be derived from delta if the event is GDK_SCROLL_SMOOTH in a non-quantized fashion, as opposed to quantizing it to +/- 1.0 as it is there?

Edit: Very quick proof of concept hack at https://github.com/Entropy512/RawTherapee/tree/scroll_hax

Edit 2: Yup, my Intellimouse Classic's scrollwheel clicks are being interpreted as GDK_SCROLL_SMOOTH with what appears to be a delta of 1.0 per event instead of GDK_SCROLL_DOWN or GDK_SCROLL_UP. So scaling delta as opposed to just making coef = delta breaks behavior with the scrollwheel. It's a bit too fast with the trackpad with coef = delta, but it is at least usable now - it wasn't before.

Edit 3: Dealing with zoomSteps in cropwindow.cc is going to be a lot more difficult... I'm guessing making that play with noninteger scroll deltas is going to require some significant rework of that whole implementation, I probably won't have a chance to try tackling that until after I get back from mid-September vacation. At least for me, thumbnail scrolling was far more painful as hitting the side scrollbars was much more difficult than hitting the zoom in/out buttons.

Entropy512 commented 5 years ago

I was thinking a bit more about handling zoom. The problem isn't that it's nonlinear, the problem is that it's currently implemented in discrete steps. As a result, GDK_SCROLL_SMOOTH events with small deltas are increased significantly in amplitude, just like they are in thumbbrowserbase.cc

Possible solutions I can think of: Approach 1 - add a state tracking variable accumScroll that is used by CropWindow::scroll - If a GDK_SCROLL_SMOOTH event comes in, add the value to accumScroll, and if abs(accumScroll) is still less than 1.0, return out of the function. Else - actually do a zoomIn or zoomOut operation and either reset accumScroll to 0.0 or subtract/add 1.0 to move it that much closer to 0.0. The former would implement a slight speed limit on the behavior. Advantages: Much easier to implement Disadvantages: If the user moves the scroll a bit but not enough to zoom, they'll need to move farther the other way before something happens. Also if we ever come across a mouse that reports GDK_SCROLL_SMOOTH events once per detent like my Intellimouse but reports them with deltas of less than 1.0, we would now have multiple detents per zoom response

Approach 2: Keep zoom as nonlinear but fix the fact that it is implemented as uneven noncontinous steps (and additionally with very different step sizes for positive vs. negative zoom, see initZoomSteps() and the whole is_major workaround...). Instead define it in this form: zoompct = 100.0*pow2(zoomlevel) where TBD <= zoomlevel < 4.0

(4.0 leads to the same max percent of 1600% that there is now)

Possibly have zoom buttons always move to an integer value of zoomlevel, with noninteger values only possible when scroll-zooming or performing a fitting operation.

Advantages: Ease of implementing other smooth zooming use cases in the future, maybe easier to maintain in the future? Disadvantages: MAJOR rework of cropwindow.cc needed, if you get a lot of GDK_SMOOTH_SCROLL events with small deltas you might eat a lot of CPU with a bunch of minor zoom adjustments

Thoughts?

Edit: MyScrolledWindow::on_scroll_event in guiutils.cc could probably use some similar improvements to GDK_SCROLL_SMOOTH handling, it may be that other aspects of how it's used mitigate the disadvantages of the current approach. It looks like it's used for the various right panel subpanels, and it does appear that it's got the same excessive gain issue. I'll take a look at this tonight.

Entropy512 commented 5 years ago

I think I've addressed touchpad responsiveness issues in the three cases where I could identify potential issues. I used approach 1 above (scroll accumulator). I need to do some testing with my mouse again to determine if there were any regressions.

Prototype patches are at https://github.com/Entropy512/RawTherapee/commits/scroll_hax - I need to do some cleanup and possible reorganization of things before setting up a pull request, but it might be beneficial if someone takes a look at the general approach first. Do I pull request against dev or another branch?

Beep6581 commented 5 years ago

@Entropy512 's changes: https://github.com/Beep6581/RawTherapee/compare/dev...Entropy512:scroll_hax

rfranke commented 4 years ago

Unfortunately there are still issues.

Nice to have: In addition to the exploitation of event->delta for smooth scrolling introduced in #5430, it should also be exploited for non-smooth scrolling under macOS, where event->delta encodes the speed of a scroll wheel. This allows to adapt the scroll speed from shifts on pixel level up to fast scrolling though multiple pages. The intended scroll behaviour can easily be tested with a web browser and would be nice to have in RT's file browser.

Must have: Moving two fingers besides each other on a mac trackpad initiates smooth scrolling in RT's file browser -- unfortunately about 100 times too fast, i.e. unusable, due to multiplication of event->delta with the thumb size, see #5599 . Is this different on a Windows laptop?

Inconsistent: Moving two fingers besides each other in RT's editor initiates zooming, like in the Google Maps app for instance, but unlike other programs, see e.g. the system's default JPEG viewer, or RT's file browser. The zoom speed is ok.

Mouse drag initiates panning in RT's editor (and Google Maps app), whereas it initiates drag&drop in other programs, e.g. to copy a picture out of a web page.

Two finger zooming (moving two fingers away from or closer to each other) does nothing in RT :-(

Did anyone investigate the exploitation of gestures introduced with GTK 3.14 for RT?

Entropy512 commented 4 years ago

Hmm... On every device I've looked at so far on my Ubuntu machine, event->delta is 1.0 for any event coming from a scroll wheel with clicks/detents...

rfranke commented 4 years ago

I just saw it under macOS. It is neat if you can scroll faster instead of having to scroll repeatedly on large pages. To make it even more tricky: under macOS I get absolute values for the speed and no direction when using a scroll wheel. Under Linux I get +-1 indicating the direction but no speed. Anyhow, a MacBook and a PC mouse are possibly paired in rare cases only, so that the treatment of this mac feature might not be worth it.

rfranke commented 4 years ago

Coming back to the original issue, I implemented the zoom gesture (move two fingers away or closer to each other) for a fullscreen inspector window (PR #5593). Gtk supports this nicely. Additionally using alt scroll for zooming, whereas scroll (move two fingers in parallel) is used to move a large image.

Wondering if the editor shouldn't support zoom gestures as well. Maybe a gesture preference setting to:

?