From 1a6d1b038fa446d60715838344dd8cb25356d05b Mon Sep 17 00:00:00 2001 From: Andy Dodd Date: Wed, 28 Aug 2019 18:40:00 -0400 Subject: [PATCH] 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