Bug 1254275 - Inspect the event queue to find out whether momentum events are following. r=kats
authorMarkus Stange <mstange@themasta.com>
Mon, 28 Mar 2016 14:56:28 -0400
changeset 290766 dc4afd0b762634e6b1edb806e0749e69cbecc968
parent 290765 a5d8c5b653338303e9335f6358dbbe8c9a9dde7b
child 290767 2c10aa467bc5c6a86a982f281bda9594a81744be
push id19656
push usergwagner@mozilla.com
push dateMon, 04 Apr 2016 13:43:23 +0000
treeherderb2g-inbound@e99061fde28a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats
bugs1254275
milestone48.0a1
Bug 1254275 - Inspect the event queue to find out whether momentum events are following. r=kats MozReview-Commit-ID: 6k3SaJ6X7Mr
gfx/layers/apz/src/AsyncPanZoomController.cpp
widget/InputData.h
widget/cocoa/nsChildView.mm
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -1990,16 +1990,20 @@ nsEventStatus AsyncPanZoomController::On
   }
   if (!overscrollHandoffChain->CanScrollInDirection(this, Layer::VERTICAL)) {
     mY.SetVelocity(0);
   }
 
   SetState(NOTHING);
   RequestContentRepaint();
 
+  if (!aEvent.mFollowedByMomentum) {
+    RequestSnap();
+  }
+
   return nsEventStatus_eConsumeNoDefault;
 }
 
 nsEventStatus AsyncPanZoomController::OnPanMomentumStart(const PanGestureInput& aEvent) {
   APZC_LOG("%p got a pan-momentumstart in state %d\n", this, mState);
 
   if (mState == SMOOTH_SCROLL) {
     // SMOOTH_SCROLL scrolls are cancelled by pan gestures.
--- a/widget/InputData.h
+++ b/widget/InputData.h
@@ -366,16 +366,17 @@ public:
                   Modifiers aModifiers)
     : InputData(PANGESTURE_INPUT, aTime, aTimeStamp, aModifiers),
       mType(aType),
       mPanStartPoint(aPanStartPoint),
       mPanDisplacement(aPanDisplacement),
       mLineOrPageDeltaX(0),
       mLineOrPageDeltaY(0),
       mHandledByAPZ(false),
+      mFollowedByMomentum(false),
       mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection(false)
   {
   }
 
   bool IsMomentum() const;
 
   WidgetWheelEvent ToWidgetWheelEvent(nsIWidget* aWidget) const;
 
@@ -393,16 +394,20 @@ public:
   ParentLayerPoint mLocalPanDisplacement;
 
   // See lineOrPageDeltaX/Y on WidgetWheelEvent.
   int32_t mLineOrPageDeltaX;
   int32_t mLineOrPageDeltaY;
 
   bool mHandledByAPZ;
 
+  // true if this is a PANGESTURE_END event that will be followed by a
+  // PANGESTURE_MOMENTUMSTART event.
+  bool mFollowedByMomentum;
+
   // If this is true, and this event started a new input block that couldn't
   // find a scrollable target which is scrollable in the horizontal component
   // of the scroll start direction, then this input block needs to be put on
   // hold until a content response has arrived, even if the block has a
   // confirmed target.
   // This is used by events that can result in a swipe instead of a scroll.
   bool mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection;
 };
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -4936,16 +4936,30 @@ PanGestureTypeForEvent(NSEvent* aEvent)
 
   if (usePreciseDeltas && hasPhaseInformation) {
     PanGestureInput panEvent(PanGestureTypeForEvent(theEvent),
                              eventIntervalTime, eventTimeStamp,
                              position, preciseDelta, modifiers);
     panEvent.mLineOrPageDeltaX = lineOrPageDeltaX;
     panEvent.mLineOrPageDeltaY = lineOrPageDeltaY;
 
+    if (panEvent.mType == PanGestureInput::PANGESTURE_END) {
+      // Check if there's a momentum start event in the event queue, so that we
+      // can annotate this event.
+      NSEvent* nextWheelEvent =
+        [NSApp nextEventMatchingMask:NSScrollWheelMask
+                           untilDate:[NSDate distantPast]
+                              inMode:NSDefaultRunLoopMode
+                             dequeue:NO];
+      if (nextWheelEvent &&
+          PanGestureTypeForEvent(nextWheelEvent) == PanGestureInput::PANGESTURE_MOMENTUMSTART) {
+        panEvent.mFollowedByMomentum = true;
+      }
+    }
+
     bool canTriggerSwipe = [self shouldConsiderStartingSwipeFromEvent:theEvent];
     panEvent.mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection = canTriggerSwipe;
     mGeckoChild->DispatchAPZWheelInputEvent(panEvent, canTriggerSwipe);
   } else if (usePreciseDeltas) {
     // This is on 10.6 or old touchpads that don't have any phase information.
     ScrollWheelInput wheelEvent(eventIntervalTime, eventTimeStamp, modifiers,
                                 ScrollWheelInput::SCROLLMODE_INSTANT,
                                 ScrollWheelInput::SCROLLDELTA_PIXEL,