Bug 1016035 - Refactor the code that decides whether we want to start a swipe. r=kats
authorMarkus Stange <mstange@themasta.com>
Thu, 27 Aug 2015 14:20:56 -0400
changeset 259972 e2743b8411a3e1b41ebac9f62421b61a1e339988
parent 259971 04156e25e29eb5846b77e094e7f204ef77ff9a8a
child 259973 2274ab11481d959ff6b90448d8e136f117f935f0
push id29296
push userryanvm@gmail.com
push dateSun, 30 Aug 2015 19:45:10 +0000
treeherdermozilla-central@2ad5077d86ba [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats
bugs1016035
milestone43.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1016035 - Refactor the code that decides whether we want to start a swipe. r=kats
widget/cocoa/nsChildView.mm
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -191,16 +191,18 @@ static uint32_t gNumberOfWidgetsNeedingE
 #endif
 
 - (nsIntPoint)convertWindowCoordinates:(NSPoint)aPoint;
 - (APZCTreeManager*)apzctm;
 
 - (BOOL)inactiveWindowAcceptsMouseEvent:(NSEvent*)aEvent;
 - (void)updateWindowDraggableState;
 
+- (bool)shouldConsiderStartingSwipeFromEvent:(NSEvent*)aEvent;
+
 @end
 
 @interface EventThreadRunner : NSObject
 {
   NSThread* mThread;
 }
 - (id)init;
 
@@ -4275,103 +4277,91 @@ NSEvent* gLastDragMouseDownEvent = nil;
     uint32_t allowedDirectionsCopy = aAllowedDirections;
     [self sendSwipeEvent:anEvent
                 withKind:NS_SIMPLE_GESTURE_SWIPE_END
        allowedDirections:&allowedDirectionsCopy
                direction:0
                    delta:0.0];
 }
 
+- (bool)shouldConsiderStartingSwipeFromEvent:(NSEvent*)anEvent
+{
+  if (!nsCocoaFeatures::OnLionOrLater()) {
+    return false;
+  }
+
+  // This method checks whether the AppleEnableSwipeNavigateWithScrolls global
+  // preference is set.  If it isn't, fluid swipe tracking is disabled, and a
+  // horizontal two-finger gesture is always a scroll (even in Safari).  This
+  // preference can't (currently) be set from the Preferences UI -- only using
+  // 'defaults write'.
+  if (![NSEvent isSwipeTrackingFromScrollEventsEnabled]) {
+    return false;
+  }
+
+  // Only initiate horizontal tracking for gestures that have just begun --
+  // otherwise a scroll to one side of the page can have a swipe tacked on
+  // to it.
+  NSEventPhase eventPhase = nsCocoaUtils::EventPhase(anEvent);
+  if ([anEvent type] != NSScrollWheel ||
+      eventPhase != NSEventPhaseBegan ||
+      ![anEvent hasPreciseScrollingDeltas]) {
+    return false;
+  }
+
+  // Only initiate horizontal tracking for events whose horizontal element is
+  // at least eight times larger than its vertical element. This minimizes
+  // performance problems with vertical scrolls (by minimizing the possibility
+  // that they'll be misinterpreted as horizontal swipes), while still
+  // tolerating a small vertical element to a true horizontal swipe.  The number
+  // '8' was arrived at by trial and error.
+  CGFloat deltaX = [anEvent scrollingDeltaX];
+  CGFloat deltaY = [anEvent scrollingDeltaY];
+  return std::abs(deltaX) > std::abs(deltaY) * 8;
+}
+
 // Support fluid swipe tracking on OS X 10.7 and higher. We must be careful
 // to only invoke this support on a two-finger gesture that really
 // is a swipe (and not a scroll) -- in other words, the app is responsible
 // for deciding which is which. But once the decision is made, the OS tracks
 // the swipe until it has finished, and decides whether or not it succeeded.
 // A horizontal swipe has the same functionality as the Back and Forward
 // buttons.
 // This method is partly based on Apple sample code available at
 // developer.apple.com/library/mac/#releasenotes/Cocoa/AppKitOlderNotes.html
 // (under Fluid Swipe Tracking API).
 - (void)maybeTrackScrollEventAsSwipe:(NSEvent *)anEvent
                      scrollOverflowX:(double)anOverflowX
                      scrollOverflowY:(double)anOverflowY
               viewPortIsOverscrolled:(BOOL)aViewPortIsOverscrolled
 {
-  if (!nsCocoaFeatures::OnLionOrLater()) {
-    return;
-  }
-
-  // This method checks whether the AppleEnableSwipeNavigateWithScrolls global
-  // preference is set.  If it isn't, fluid swipe tracking is disabled, and a
-  // horizontal two-finger gesture is always a scroll (even in Safari).  This
-  // preference can't (currently) be set from the Preferences UI -- only using
-  // 'defaults write'.
-  if (![NSEvent isSwipeTrackingFromScrollEventsEnabled]) {
-    return;
-  }
-
   // We should only track scroll events as swipe if the viewport is being
   // overscrolled.
   if (!aViewPortIsOverscrolled) {
     return;
   }
 
-  NSEventPhase eventPhase = nsCocoaUtils::EventPhase(anEvent);
-  // Verify that this is a scroll wheel event with proper phase to be tracked
-  // by the OS.
-  if ([anEvent type] != NSScrollWheel || eventPhase == NSEventPhaseNone) {
-    return;
-  }
-
   // Only initiate tracking if the user has tried to scroll past the edge of
   // the current page (as indicated by 'anOverflowX' or 'anOverflowY' being
   // non-zero). Gecko only sets WidgetMouseScrollEvent.scrollOverflow when it's
   // processing NS_MOUSE_PIXEL_SCROLL events (not NS_MOUSE_SCROLL events).
-  if (anOverflowX == 0.0 && anOverflowY == 0.0) {
-    return;
-  }
-
-  CGFloat deltaX, deltaY;
-  if ([anEvent hasPreciseScrollingDeltas]) {
-    deltaX = [anEvent scrollingDeltaX];
-    deltaY = [anEvent scrollingDeltaY];
-  } else {
+  if (anOverflowX == 0.0) {
     return;
   }
 
-  uint32_t direction = 0;
-
-  // Only initiate horizontal tracking for events whose horizontal element is
-  // at least eight times larger than its vertical element. This minimizes
-  // performance problems with vertical scrolls (by minimizing the possibility
-  // that they'll be misinterpreted as horizontal swipes), while still
-  // tolerating a small vertical element to a true horizontal swipe.  The number
-  // '8' was arrived at by trial and error.
-  if (anOverflowX != 0.0 && deltaX != 0.0 &&
-      std::abs(deltaX) > std::abs(deltaY) * 8) {
-    // Only initiate horizontal tracking for gestures that have just begun --
-    // otherwise a scroll to one side of the page can have a swipe tacked on
-    // to it.
-    if (eventPhase != NSEventPhaseBegan) {
-      return;
-    }
-
-    if (deltaX < 0.0) {
-      direction = (uint32_t)nsIDOMSimpleGestureEvent::DIRECTION_RIGHT;
-    } else {
-      direction = (uint32_t)nsIDOMSimpleGestureEvent::DIRECTION_LEFT;
-    }
-  } else {
-    return;
-  }
-
-  uint32_t allowedDirections = 0;
+  CGFloat deltaX = [anEvent scrollingDeltaX];
+
+  uint32_t direction = (deltaX < 0.0)
+    ? (uint32_t)nsIDOMSimpleGestureEvent::DIRECTION_RIGHT
+    : (uint32_t)nsIDOMSimpleGestureEvent::DIRECTION_LEFT;
+
   // We're ready to start the animation. Tell Gecko about it, and at the same
   // time ask it if it really wants to start an animation for this event.
   // This event also reports back the directions that we can swipe in.
+  uint32_t allowedDirections = 0;
   bool shouldStartSwipe = [self sendSwipeEvent:anEvent
                                       withKind:NS_SIMPLE_GESTURE_SWIPE_START
                              allowedDirections:&allowedDirections
                                      direction:direction
                                          delta:0.0];
 
   if (!shouldStartSwipe) {
     return;
@@ -4969,24 +4959,26 @@ PanGestureTypeForEvent(NSEvent* aEvent)
   }
 
   if (usePreciseDeltas && hasPhaseInformation) {
     PanGestureInput panEvent(PanGestureTypeForEvent(theEvent),
                              eventIntervalTime, eventTimeStamp,
                              position, preciseDelta, modifiers);
     panEvent.mLineOrPageDeltaX = lineOrPageDeltaX;
     panEvent.mLineOrPageDeltaY = lineOrPageDeltaY;
+
     widgetWheelEvent = mGeckoChild->DispatchAPZWheelInputEvent(panEvent);
 
     if (!mGeckoChild) {
       return;
     }
 
 #ifdef __LP64__
-    if ((widgetWheelEvent.deltaX != 0.0 || widgetWheelEvent.deltaY != 0.0)) {
+    bool canTriggerSwipe = [self shouldConsiderStartingSwipeFromEvent:theEvent];
+    if (canTriggerSwipe) {
       // overflowDeltaX and overflowDeltaY tell us when the user has tried to
       // scroll past the edge of a page (in those cases it's non-zero).
       [self maybeTrackScrollEventAsSwipe:theEvent
                          scrollOverflowX:widgetWheelEvent.overflowDeltaX
                          scrollOverflowY:widgetWheelEvent.overflowDeltaY
                   viewPortIsOverscrolled:widgetWheelEvent.mViewPortIsOverscrolled];
     }
 #endif // #ifdef __LP64__