Bug 1235994 - For wheel events which may have momentum following them, handle scroll snapping in APZ. r?mstange draft
authorKartikaya Gupta <kgupta@mozilla.com>
Thu, 31 Dec 2015 15:59:19 -0500
changeset 318200 bad68af236d8149e1d2209da03be0f373fe836b5
parent 318199 2d05dab6d29b5ce9763a2146e14c3779df180742
child 512439 856f192837f5f0ffb37bf800b42bfff1e2400d72
push id8853
push userkgupta@mozilla.com
push dateThu, 31 Dec 2015 20:59:46 +0000
reviewersmstange
bugs1235994
milestone46.0a1
Bug 1235994 - For wheel events which may have momentum following them, handle scroll snapping in APZ. r?mstange
dom/events/EventStateManager.cpp
gfx/layers/apz/src/AsyncPanZoomController.cpp
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -3158,20 +3158,25 @@ EventStateManager::PostHandleEvent(nsPre
       nsPluginFrame* pluginFrame = do_QueryFrame(frameToScroll);
 
       // When APZ is enabled, the actual scroll animation might be handled by
       // the compositor.
       WheelPrefs::Action action;
       if (pluginFrame) {
         MOZ_ASSERT(pluginFrame->WantsToHandleWheelEventAsDefaultAction());
         action = WheelPrefs::ACTION_SEND_TO_PLUGIN;
-      } else if (nsLayoutUtils::IsScrollFrameWithSnapping(frameToScroll)) {
+      } else if (!wheelEvent->mayHaveMomentum &&
+            nsLayoutUtils::IsScrollFrameWithSnapping(frameToScroll)) {
         // If the target has scroll-snapping points then we want to handle
         // the wheel event on the main thread even if we have APZ enabled. Do
-        // so and let the APZ know that it should ignore this event.
+        // so and let the APZ know that it should ignore this event. However,
+        // if the wheel event is synthesized from a Mac trackpad or other device
+        // that can generate additional momentum events, then we should allow
+        // APZ to handle it, because it will track the velocity and predicted
+        // destination from the momentum.
         if (wheelEvent->mFlags.mHandledByAPZ) {
           wheelEvent->mFlags.mDefaultPrevented = true;
         }
         action = WheelPrefs::GetInstance()->ComputeActionFor(wheelEvent);
       } else if (wheelEvent->mFlags.mHandledByAPZ) {
         action = WheelPrefs::ACTION_NONE;
       } else {
         action = WheelPrefs::GetInstance()->ComputeActionFor(wheelEvent);
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -1963,16 +1963,17 @@ nsEventStatus AsyncPanZoomController::On
   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.
     CancelAnimation();
   }
 
   SetState(PAN_MOMENTUM);
+  RequestSnapToDestination();
 
   // Call into OnPan in order to process any delta included in this event.
   OnPan(aEvent, false);
 
   return nsEventStatus_eConsumeNoDefault;
 }
 
 nsEventStatus AsyncPanZoomController::OnPanMomentumEnd(const PanGestureInput& aEvent) {