Fix T45167: OS X inertial scrolling can lead to unexpected zooming.
authorBrecht Van Lommel <brechtvanlommel@gmail.com>
Mon, 5 Oct 2015 01:02:11 +0000 (03:02 +0200)
committerBrecht Van Lommel <brechtvanlommel@gmail.com>
Sat, 10 Oct 2015 12:00:02 +0000 (14:00 +0200)
Differential Revision: https://developer.blender.org/D1539

intern/ghost/intern/GHOST_SystemCocoa.h
intern/ghost/intern/GHOST_SystemCocoa.mm

index b49a7d8a0a3a53e0af6b14497e7bda5ac1e50072..cfddd5b3781500f92df05a901f31abc715852bf0 100644 (file)
@@ -297,6 +297,8 @@ protected:
         */
        GHOST_TInt32 m_cursorDelta_x, m_cursorDelta_y;
        
+       /** Temporarily ignore momentum scroll events */
+       bool m_ignoreMomentumScroll;
 };
 
 #endif // __GHOST_SYSTEMCOCOA_H__
index f5dfe5a175be51dc2e089224bf8be8359a88ea95..02ef7546c2fb53bae8367f35b02bbc700a2c22f4 100644 (file)
@@ -374,6 +374,7 @@ GHOST_SystemCocoa::GHOST_SystemCocoa()
        rstring = NULL;
        
        m_ignoreWindowSizedMessages = false;
+       m_ignoreMomentumScroll = false;
 }
 
 GHOST_SystemCocoa::~GHOST_SystemCocoa()
@@ -1391,19 +1392,33 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
 
                case NSScrollWheel:
                        {
-                               NSEventPhase momentum = NSEventPhaseNone;
+                               NSEventPhase momentumPhase = NSEventPhaseNone;
                                NSEventPhase phase = NSEventPhaseNone;
                                bool hasMultiTouch = false;
                                
                                if ([event respondsToSelector:@selector(momentumPhase)])
-                                       momentum = [event momentumPhase];
+                                       momentumPhase = [event momentumPhase];
                                if ([event respondsToSelector:@selector(phase)])
                                        phase = [event phase];
                                if ([event respondsToSelector:@selector(hasPreciseScrollingDeltas)])
                                        hasMultiTouch = [event hasPreciseScrollingDeltas];
 
+                               /* when pressing a key while momentum scrolling continues after
+                                * lifting fingers off the trackpad, the action can unexpectedly
+                                * change from e.g. scrolling to zooming. this works around the
+                                * issue by ignoring momentum scroll after a key press */
+                               if (momentumPhase)
+                               {
+                                       if (m_ignoreMomentumScroll)
+                                               break;
+                               }
+                               else
+                               {
+                                       m_ignoreMomentumScroll = false;
+                               }
+
                                /* standard scrollwheel case, if no swiping happened, and no momentum (kinetic scroll) works */
-                               if (!hasMultiTouch && momentum == NSEventPhaseNone) {
+                               if (!hasMultiTouch && momentumPhase == NSEventPhaseNone) {
                                        GHOST_TInt32 delta;
                                        
                                        double deltaF = [event deltaY];
@@ -1426,7 +1441,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
                                        dy = [event scrollingDeltaY];
                                        
                                        /* however, wacom tablet (intuos5) needs old deltas, it then has momentum and phase at zero */
-                                       if (phase == NSEventPhaseNone && momentum == NSEventPhaseNone) {
+                                       if (phase == NSEventPhaseNone && momentumPhase == NSEventPhaseNone) {
                                                dx = [event deltaX];
                                                dy = [event deltaY];
                                        }
@@ -1561,6 +1576,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr)
                                pushEvent( new GHOST_EventKey([event timestamp] * 1000, GHOST_kEventKeyUp, window, keyCode, 0, NULL) );
                                //printf("Key up rawCode=0x%x charsIgnoringModifiers=%c keyCode=%u ascii=%i %c utf8=%s\n",[event keyCode],[charsIgnoringModifiers length]>0?[charsIgnoringModifiers characterAtIndex:0]:' ',keyCode,ascii,ascii, utf8_buf);
                        }
+                       m_ignoreMomentumScroll = true;
                        break;
        
                case NSFlagsChanged: 
@@ -1580,6 +1596,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr)
                        }
                        
                        m_modifierMask = modifiers;
+                       m_ignoreMomentumScroll = true;
                        break;
                        
                default: