From a060b57ff607bf595c7e1e154ada078b40d85edf Mon Sep 17 00:00:00 2001 From: Andy Dodd Date: Tue, 27 Aug 2019 17:44:35 -0400 Subject: [PATCH 1/3] rtgui/thumbbrowserbase - Improve behavior with smooth scrolling devices Devices such as trackpads will emit smooth scrolling (GDK_SMOOTH_SCROLL) events with deltas smaller than +/-1.0 at high frequency. Quantizing these to +/-1.0 leads to significant amplification of scroll speed to the point of unusability Scroll by delta instead of +/-1.0 in these cases, permitting smooth scrolling through thumbnails Some mice emit GDK_SMOOTH_SCROLL with deltas of +/-1.0 per detent. This patch will not change behavior with such devices. However, if any mice emit deltas of smaller magnitude, the per-detent behavior will change. --- rtgui/thumbbrowserbase.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/rtgui/thumbbrowserbase.cc b/rtgui/thumbbrowserbase.cc index caf7d7b97..13709d8f7 100644 --- a/rtgui/thumbbrowserbase.cc +++ b/rtgui/thumbbrowserbase.cc @@ -79,10 +79,19 @@ void ThumbBrowserBase::scroll (int direction, double deltaX, double deltaY) delta = deltaY; } if (direction == GDK_SCROLL_SMOOTH && delta == 0.0) { - // sometimes this case happens. To avoid scrolling the wrong direction in this case, we just do nothing + // sometimes this case happens. To avoid scrolling the wrong direction in this case, we just do nothing + // This is probably no longer necessary now that coef is no longer quantized to +/-1.0 but why waste CPU cycles? return; } - double coef = direction == GDK_SCROLL_DOWN || (direction == GDK_SCROLL_SMOOTH && delta > 0.0) ? +1.0 : -1.0; + //GDK_SCROLL_SMOOTH can come in as many events with small deltas, don't quantize these to +/-1.0 so trackpads work well + double coef; + if(direction == GDK_SCROLL_SMOOTH) { + coef = delta; + } else if (direction == GDK_SCROLL_DOWN) { + coef = +1.0; + } else { + coef = -1.0; + } // GUI already acquired when here if (direction == GDK_SCROLL_UP || direction == GDK_SCROLL_DOWN || direction == GDK_SCROLL_SMOOTH) { From dadf01fe95b9f7ef61226703b1071e037dd553d1 Mon Sep 17 00:00:00 2001 From: Andy Dodd Date: Wed, 28 Aug 2019 18:19:53 -0400 Subject: [PATCH 2/3] rtgui/guiutils - Improve behavior with smooth scrolling devices Devices such as trackpads will emit smooth scrolling (GDK_SMOOTH_SCROLL) events with deltas smaller than +/-1.0 at high frequency. Quantizing these to +/-1.0 leads to significant amplification of scroll speed to the point of unusability Scroll by delta instead of +/-1.0 in these cases, permitting smooth scrolling through panels that use this code Some mice emit GDK_SMOOTH_SCROLL with deltas of +/-1.0 per detent. This patch will not change behavior with such devices. However, if any mice emit deltas of smaller magnitude, the per-detent behavior will change. --- rtgui/guiutils.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc index ec0bf6588..19762fd92 100644 --- a/rtgui/guiutils.cc +++ b/rtgui/guiutils.cc @@ -971,9 +971,8 @@ bool MyScrolledWindow::on_scroll_event (GdkEventScroll* event) scroll->set_value(value2); } } else if (event->direction == GDK_SCROLL_SMOOTH) { - if (abs(event->delta_y) > 0.1) { - value2 = rtengine::LIM(value + (event->delta_y > 0 ? step : -step), lowerBound, upperBound); - } + value2 = rtengine::LIM(value + event->delta_y * step, lowerBound, upperBound); + if (value2 != value) { scroll->set_value(value2); } From 1a6d1b038fa446d60715838344dd8cb25356d05b Mon Sep 17 00:00:00 2001 From: Andy Dodd Date: Wed, 28 Aug 2019 18:40:00 -0400 Subject: [PATCH 3/3] rtgui/cropwindow: Improve behavior with smooth scrolling devices Accumulate/coalesce GDK_SCROLL_SMOOTH events until we equal or exceed +/-1.0 This avoids having one zoom adjustment for every single event which makes touchpad zooming unusable due to frequent small deltas This makes trackpad zooming usable while having no effect on mice that emit GDK_SMOOTH_SCROLL with values of +/-1.0 instead of GDK_SCROLL_UP and GDK_SCROLL_DOWN If any mice exist that have scroll wheel detents but emit smaller values per detent, this may have the negative effect of requiring multiple detents per zoom level. It remains to be seen whether any mice behave like this. The discrete step implementation of zoomSteps requires us to coalesce events instead of smoothly zooming in and out. --- rtgui/cropwindow.cc | 15 ++++++++++----- rtgui/cropwindow.h | 1 + 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/rtgui/cropwindow.cc b/rtgui/cropwindow.cc index 575afd54b..1364855b0 100644 --- a/rtgui/cropwindow.cc +++ b/rtgui/cropwindow.cc @@ -51,7 +51,7 @@ CropWindow::CropWindow (ImageArea* parent, bool isLowUpdatePriority_, bool isDet backColor(options.bgcolor), decorated(true), isFlawnOver(false), titleHeight(30), sideBorderWidth(3), lowerBorderWidth(3), upperBorderWidth(1), sepWidth(2), xpos(30), ypos(30), width(0), height(0), imgAreaX(0), imgAreaY(0), imgAreaW(0), imgAreaH(0), imgX(-1), imgY(-1), imgW(1), imgH(1), iarea(parent), cropZoom(0), zoomVersion(0), exposeVersion(0), cropgl(nullptr), - pmlistener(nullptr), pmhlistener(nullptr), observedCropWin(nullptr), + pmlistener(nullptr), pmhlistener(nullptr), scrollAccum(0.0), observedCropWin(nullptr), crop_custom_ratio(0.f) { initZoomSteps(); @@ -295,11 +295,16 @@ void CropWindow::scroll (int state, GdkScrollDirection direction, int x, int y, } else { delta = deltaY; } - if (delta == 0.0 && direction == GDK_SCROLL_SMOOTH) { - // sometimes this case happens. To avoid zooming into the wrong direction in this case, we just do nothing - return; + + if (direction == GDK_SCROLL_SMOOTH) { + scrollAccum += delta; + //Only change zoom level if we've accumulated +/- 1.0 of deltas. This conditional handles the previous delta=0.0 case + if (abs(scrollAccum) < 1.0) { + return; + } } - bool isUp = direction == GDK_SCROLL_UP || (direction == GDK_SCROLL_SMOOTH && delta < 0.0); + bool isUp = direction == GDK_SCROLL_UP || (direction == GDK_SCROLL_SMOOTH && scrollAccum < 0.0); + scrollAccum = 0.0; if ((state & GDK_CONTROL_MASK) && onArea(ColorPicker, x, y)) { // resizing a color picker if (isUp) { diff --git a/rtgui/cropwindow.h b/rtgui/cropwindow.h index 26edf69ee..8c944cf0a 100644 --- a/rtgui/cropwindow.h +++ b/rtgui/cropwindow.h @@ -102,6 +102,7 @@ class CropWindow : public LWButtonListener, public CropDisplayHandler, public Ed PointerMotionListener* pmlistener; PointerMotionListener* pmhlistener; std::list listeners; + double scrollAccum; CropWindow* observedCropWin; // Pointer to the currently active detail CropWindow