Bug 1016035 - Add mCanTriggerSwipe and TriggersSwipe(). r?masayuki draft
authorMarkus Stange <mstange@themasta.com>
Sun, 23 Aug 2015 18:59:05 -0400
changeset 288171 e8ff28b0d25cb033dbe392c56b44cd9b57bad88c
parent 288170 55462a571ebcaef89616d501e366c89a96702c74
child 288172 68675aa64bfc44e185ab9acab03019f1e3473740
push id4815
push usermstange@themasta.com
push dateThu, 27 Aug 2015 05:31:12 +0000
reviewersmasayuki
bugs1016035
milestone43.0a1
Bug 1016035 - Add mCanTriggerSwipe and TriggersSwipe(). r?masayuki
widget/BasicEvents.h
widget/MouseEvents.h
widget/cocoa/nsChildView.mm
--- a/widget/BasicEvents.h
+++ b/widget/BasicEvents.h
@@ -110,16 +110,19 @@ public:
   // in the parent process after the content process has handled it. Useful
   // for when the parent process need the know first how the event was used
   // by content before handling it itself.
   bool mWantReplyFromContentProcess : 1;
   // The event's action will be handled by APZ. The main thread should not
   // perform its associated action. This is currently only relevant for
   // wheel events.
   bool mHandledByAPZ : 1;
+  // The event is a wheel event that can trigger a swipe to start if it's
+  // overscrolling the viewport.
+  bool mCanTriggerSwipe : 1;
 
   // If the event is being handled in target phase, returns true.
   inline bool InTargetPhase() const
   {
     return (mInBubblingPhase && mInCapturePhase);
   }
 
   inline void Clear()
--- a/widget/MouseEvents.h
+++ b/widget/MouseEvents.h
@@ -463,16 +463,26 @@ public:
                "Duplicate() must be overridden by sub class");
     // Not copying widget, it is a weak reference.
     WidgetWheelEvent* result = new WidgetWheelEvent(false, mMessage, nullptr);
     result->AssignWheelEventData(*this, true);
     result->mFlags = mFlags;
     return result;
   }
 
+  // On OS X, scroll gestures that start at the edge of the scrollable range
+  // can result in a swipe gesture. For the first wheel event of such a
+  // gesture, call TriggersSwipe() after the event has been processed
+  // in order to find out whether a swipe should be started.
+  bool TriggersSwipe() const
+  {
+    return mFlags.mCanTriggerSwipe && mViewPortIsOverscrolled &&
+           this->overflowDeltaX != 0.0;
+  }
+
   // NOTE: deltaX, deltaY and deltaZ may be customized by
   //       mousewheel.*.delta_multiplier_* prefs which are applied by
   //       EventStateManager.  So, after widget dispatches this event,
   //       these delta values may have different values than before.
   double deltaX;
   double deltaY;
   double deltaZ;
 
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -2704,24 +2704,16 @@ void
 nsChildView::UpdateWindowDraggingRegion(const nsIntRegion& aRegion)
 {
   if (mDraggableRegion != aRegion) {
     mDraggableRegion = aRegion;
     [(ChildView*)mView updateWindowDraggableState];
   }
 }
 
-static bool
-IsPotentialSwipeStartEventOverscrollingViewport(const WidgetWheelEvent& aEvent)
-{
-  // We should only track scroll events as swipe if the viewport is being
-  // overscrolled.
-  return aEvent.mViewPortIsOverscrolled && aEvent.overflowDeltaX != 0.0;
-}
-
 void
 nsChildView::DispatchAPZWheelInputEvent(InputData& aEvent, bool aCanTriggerSwipe)
 {
   if (mSwipeTracker && aEvent.mInputType == PANGESTURE_INPUT) {
     // Give the swipe tracker a first pass at the event. If a new pan gesture
     // has been started since the beginning of the swipe, the swipe tracker
     // will know to ignore the event.
     nsEventStatus status = mSwipeTracker->ProcessEvent(aEvent.AsPanGestureInput());
@@ -2763,21 +2755,21 @@ nsChildView::DispatchAPZWheelInputEvent(
 
   nsEventStatus status;
   switch(aEvent.mInputType) {
     case PANGESTURE_INPUT: {
       PanGestureInput panInput = aEvent.AsPanGestureInput();
       event = panInput.ToWidgetWheelEvent(this);
       if (aCanTriggerSwipe) {
         SwipeInfo swipeInfo = SendMayStartSwipe(panInput);
+        event.mFlags.mCanTriggerSwipe = swipeInfo.wantsSwipe;
         if (event.mMessage == NS_WHEEL_WHEEL &&
             (event.deltaX != 0 || event.deltaY != 0)) {
           DispatchEvent(&event, status);
-          if (swipeInfo.wantsSwipe &&
-              IsPotentialSwipeStartEventOverscrollingViewport(event)) {
+          if (event.TriggersSwipe()) {
             TrackScrollEventAsSwipe(panInput, swipeInfo.allowedDirections);
           }
         }
         return;
       }
       break;
     }
     case SCROLLWHEEL_INPUT: {