Bug 1016035 - Swallow the rest of the scroll gesture after swiping without APZ. r=kats
authorMarkus Stange <mstange@themasta.com>
Thu, 27 Aug 2015 00:23:09 -0400
changeset 292588 7ba6e5946b85c91319936ffb1cc174096205e14d
parent 292587 a918fecc22019c1b5694970b5b7309fe67340f45
child 292589 04a061abd407caf7646327abdaa34ba7d6c9471e
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [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 - Swallow the rest of the scroll gesture after swiping without APZ. r=kats With APZ this is handled because starting a swipe interrupts the PanGesture input block, and momentum events don't start a new input block so APZ ignores them.
widget/cocoa/nsChildView.h
widget/cocoa/nsChildView.mm
--- a/widget/cocoa/nsChildView.h
+++ b/widget/cocoa/nsChildView.h
@@ -672,14 +672,22 @@ protected:
   // Used in OMTC BasicLayers mode. Presents the BasicCompositor result
   // surface to the screen using an OpenGL context.
   nsAutoPtr<GLPresenter> mGLPresenter;
 
   mozilla::UniquePtr<mozilla::VibrancyManager> mVibrancyManager;
   nsRefPtr<mozilla::SwipeTracker> mSwipeTracker;
   mozilla::UniquePtr<mozilla::SwipeEventQueue> mSwipeEventQueue;
 
+  // This flag is only used when APZ is off. It indicates that the current pan
+  // gesture was processed as a swipe. Sometimes the swipe animation can finish
+  // before momentum events of the pan gesture have stopped firing, so this
+  // flag tells us that we shouldn't allow the remaining events to cause
+  // scrolling. It is reset to false once a new gesture starts (as indicated by
+  // a PANGESTURE_(MAY)START event).
+  bool mCurrentPanGestureBelongsToSwipe;
+
   static uint32_t sLastInputEventCount;
 
   void ReleaseTitlebarCGContext();
 };
 
 #endif // nsChildView_h_
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -2815,23 +2815,37 @@ nsChildView::DispatchAPZWheelInputEvent(
     }
     return;
   }
 
   nsEventStatus status;
   switch(aEvent.mInputType) {
     case PANGESTURE_INPUT: {
       PanGestureInput panInput = aEvent.AsPanGestureInput();
+      if (panInput.mType == PanGestureInput::PANGESTURE_MAYSTART ||
+          panInput.mType == PanGestureInput::PANGESTURE_START) {
+        mCurrentPanGestureBelongsToSwipe = false;
+      }
+      if (mCurrentPanGestureBelongsToSwipe) {
+        // Ignore this event. It's a momentum event from a scroll gesture
+        // that was processed as a swipe, and the swipe animation has
+        // already finished (so mSwipeTracker is already null).
+        MOZ_ASSERT(panInput.IsMomentum(),
+          "If the fingers are still on the touchpad, we should still have a SwipeTracker, and it should have consumed this event.");
+        return;
+      }
+
       event = panInput.ToWidgetWheelEvent(this);
       if (aCanTriggerSwipe) {
         SwipeInfo swipeInfo = SendMayStartSwipe(panInput);
         event.mCanTriggerSwipe = swipeInfo.wantsSwipe;
         DispatchEvent(&event, status);
         if (event.TriggersSwipe()) {
           TrackScrollEventAsSwipe(panInput, swipeInfo.allowedDirections);
+          mCurrentPanGestureBelongsToSwipe = true;
         }
         return;
       }
       break;
     }
     case SCROLLWHEEL_INPUT: {
       event = aEvent.AsScrollWheelInput().ToWidgetWheelEvent(this);
       break;