Sorvig Morten wrote:

Hi,
> On the OS X side his is handled in the platform plugin: We read the key
> modifier state at the beginning of the scroll event sequence.
> 
> The code in question is in  - (void)scrollWheel:(NSEvent *)theEvent in
> qnsview.mm

Indeed, and it even has a nice comment that describes "my" issue perfectly:
  // Prevent keyboard modifier state from changing during scroll event streams.
  // A two-finger trackpad flick generates a stream of scroll events. We want
  // the keyboard modifier state to be the state at the beginning of the
  // flick in order to avoid changing the interpretation of the events
  // mid-stream. One example of this happening would be when pressing cmd
  // after scrolling in Qt Creator: not taking the phase into account causes
  // the end of the event stream to be interpreted as font size changes.

I've come up with the attached patch, which seems to have the intended effect.
Is there a reason to check and act on NSInputManager::wantsToHandleMouseEvents 
when QT_NO_WHEELEVENT is set? In other words, does the default scrollWheel 
method not do this already?

The question remains if it's possible to do something similar on X11/xcb ? 
Because the same issue occurs there too, and is actually worse because whatever 
simulates inertial scrolling there doesn't know when the view reached its top 
or 
bottom (so scroll events keep coming until the "inertia is coasted out").

R.
diff --git src/gui/kernel/qcocoaview_mac.mm src/gui/kernel/qcocoaview_mac.mm
index 34dc815..65b3712 100644
--- src/gui/kernel/qcocoaview_mac.mm
+++ src/gui/kernel/qcocoaview_mac.mm
@@ -600,6 +600,11 @@ static int qCocoaViewCount = 0;
     qt_mac_handleMouseEvent(theEvent, QEvent::MouseMove, Qt::NoButton, qwidget);
 }
 
+#ifndef QT_NO_WHEELEVENT
+// don't override super::scrollWheel when QT_NO_WHEELEVENT is set, rather than
+// only rendering the method inactive
+// But: can we assume that super::scrollWheel also checks
+// NSInputManager::wantsToHandleMouseEvents ?!
 - (void)scrollWheel:(NSEvent *)theEvent
 {
     // Give the Input Manager a chance to process the wheel event.
@@ -609,7 +614,22 @@ static int qCocoaViewCount = 0;
     }
 
     Qt::MouseButtons buttons = QApplication::mouseButtons();
-    Qt::KeyboardModifiers keyMods = qt_cocoaModifiers2QtModifiers([theEvent modifierFlags]);
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
+    // backported from Qt 5.4:
+    // Prevent keyboard modifier state from changing during scroll event streams.
+    // A two-finger trackpad flick generates a stream of scroll events. We want
+    // the keyboard modifier state to be the state at the beginning of the
+    // flick in order to avoid changing the interpretation of the events
+    // mid-stream. One example of this happening would be when pressing cmd
+    // after scrolling in Qt Creator: not taking the phase into account causes
+    // the end of the event stream to be interpreted as font size changes.
+    NSEventPhase momentumPhase = [theEvent momentumPhase];
+    if (momentumPhase == NSEventPhaseNone) {
+        currentWheelModifiers = qt_cocoaModifiers2QtModifiers([theEvent modifierFlags]);
+    }
+#else
+    Qt::KeyboardModifiers currentWheelModifiers = qt_cocoaModifiers2QtModifiers([theEvent modifierFlags]);
+#endif
 
     // Find the widget that should receive the event:
     QPoint qlocal, qglobal;
@@ -647,26 +667,25 @@ static int qCocoaViewCount = 0;
         deltaY = qBound(-120, int([theEvent deltaY] * 10000), 120);
     }
 
-#ifndef QT_NO_WHEELEVENT
     // ### Qt 5: Send one QWheelEvent with dx, dy and dz
 
     if (deltaX != 0 && deltaY != 0)
         QMacScrollOptimization::initDelayedScroll();
 
     if (deltaX != 0) {
-        QWheelEvent qwe(qlocal, qglobal, deltaX, buttons, keyMods, Qt::Horizontal);
+        QWheelEvent qwe(qlocal, qglobal, deltaX, buttons, currentWheelModifiers, Qt::Horizontal);
         qt_sendSpontaneousEvent(widgetToGetMouse, &qwe);
     }
 
     if (deltaY != 0) {
-        QWheelEvent qwe(qlocal, qglobal, deltaY, buttons, keyMods, Qt::Vertical);
+        QWheelEvent qwe(qlocal, qglobal, deltaY, buttons, currentWheelModifiers, Qt::Vertical);
         qt_sendSpontaneousEvent(widgetToGetMouse, &qwe);
     }
 
     if (deltaX != 0 && deltaY != 0)
         QMacScrollOptimization::performDelayedScroll();
-#endif //QT_NO_WHEELEVENT
 }
+#endif //QT_NO_WHEELEVENT
 
 - (void)tabletProximity:(NSEvent *)tabletEvent
 {
diff --git src/gui/kernel/qcocoaview_mac_p.h src/gui/kernel/qcocoaview_mac_p.h
index 07bd283..bf1fd30 100644
--- src/gui/kernel/qcocoaview_mac_p.h
+++ src/gui/kernel/qcocoaview_mac_p.h
@@ -70,6 +70,10 @@ Q_GUI_EXPORT
     int composingLength;
     bool sendKeyEvents;
     bool fromKeyDownEvent;
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
+    // backported from Qt 5.4 :
+    Qt::KeyboardModifiers currentWheelModifiers;
+#endif
     QString *composingText;
     @public int alienTouchCount;
 }

_______________________________________________
Development mailing list
[email protected]
http://lists.qt-project.org/mailman/listinfo/development

Reply via email to