diff --git a/gfx/layers/apz/src/APZCTreeManager.cpp b/gfx/layers/apz/src/APZCTreeManager.cpp index 3460cb3e36ce..6d3ae724af74 100644 --- a/gfx/layers/apz/src/APZCTreeManager.cpp +++ b/gfx/layers/apz/src/APZCTreeManager.cpp @@ -1198,6 +1198,9 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent, apzc->GetGuid(aOutTargetGuid); panInput.mPanStartPoint = *untransformedStartPoint; panInput.mPanDisplacement = *untransformedDisplacement; + + panInput.mOverscrollBehaviorAllowsSwipe = + apzc->OverscrollBehaviorAllowsSwipe(); } break; } case PINCHGESTURE_INPUT: { // note: no one currently sends these diff --git a/gfx/layers/apz/src/AsyncPanZoomController.cpp b/gfx/layers/apz/src/AsyncPanZoomController.cpp index 57b7abda9953..07a4ff4f2398 100644 --- a/gfx/layers/apz/src/AsyncPanZoomController.cpp +++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp @@ -2880,6 +2880,12 @@ ParentLayerPoint AsyncPanZoomController::AdjustHandoffVelocityForOverscrollBehav return residualVelocity; } +bool AsyncPanZoomController::OverscrollBehaviorAllowsSwipe() const +{ + RecursiveMutexAutoLock lock(mRecursiveMutex); + // Swipe navigation is a "non-local" overscroll behavior like handoff. + return mX.OverscrollBehaviorAllowsHandoff(); +} void AsyncPanZoomController::HandleFlingOverscroll(const ParentLayerPoint& aVelocity, const RefPtr& aOverscrollHandoffChain, diff --git a/gfx/layers/apz/src/AsyncPanZoomController.h b/gfx/layers/apz/src/AsyncPanZoomController.h index d603875a7380..cb581e290e16 100644 --- a/gfx/layers/apz/src/AsyncPanZoomController.h +++ b/gfx/layers/apz/src/AsyncPanZoomController.h @@ -442,6 +442,8 @@ public: void NotifyMozMouseScrollEvent(const nsString& aString) const; + bool OverscrollBehaviorAllowsSwipe() const; + protected: // Protected destructor, to discourage deletion outside of Release(): virtual ~AsyncPanZoomController(); diff --git a/widget/InputData.cpp b/widget/InputData.cpp index 9d514dc05ab1..f18f6780467a 100644 --- a/widget/InputData.cpp +++ b/widget/InputData.cpp @@ -490,6 +490,7 @@ PanGestureInput::PanGestureInput() , mHandledByAPZ(false) , mFollowedByMomentum(false) , mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection(false) + , mOverscrollBehaviorAllowsSwipe(false) { } @@ -509,6 +510,7 @@ PanGestureInput::PanGestureInput(PanGestureType aType, uint32_t aTime, , mHandledByAPZ(false) , mFollowedByMomentum(false) , mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection(false) + , mOverscrollBehaviorAllowsSwipe(false) { } diff --git a/widget/InputData.h b/widget/InputData.h index 44d19e5254af..b4be7e0f38aa 100644 --- a/widget/InputData.h +++ b/widget/InputData.h @@ -385,6 +385,14 @@ public: // confirmed target. // This is used by events that can result in a swipe instead of a scroll. bool mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection; + + // This is used by APZ to communicate to the macOS widget code whether + // the overscroll-behavior of the scroll frame handling this swipe allows + // non-local overscroll behaviors in the horizontal direction (such as + // swipe navigation). + bool mOverscrollBehaviorAllowsSwipe; + + // XXX: If adding any more bools, switch to using bitfields instead. }; /** diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm index 33ebc0f0d697..cb1d545ad7bb 100644 --- a/widget/cocoa/nsChildView.mm +++ b/widget/cocoa/nsChildView.mm @@ -2923,7 +2923,7 @@ nsChildView::DispatchAPZWheelInputEvent(InputData& aEvent, bool aCanTriggerSwipe PanGestureInput& panInput = aEvent.AsPanGestureInput(); event = panInput.ToWidgetWheelEvent(this); - if (aCanTriggerSwipe) { + if (aCanTriggerSwipe && panInput.mOverscrollBehaviorAllowsSwipe) { SwipeInfo swipeInfo = SendMayStartSwipe(panInput); event.mCanTriggerSwipe = swipeInfo.wantsSwipe; if (swipeInfo.wantsSwipe) { diff --git a/widget/nsGUIEventIPC.h b/widget/nsGUIEventIPC.h index c3aa90820072..d3a4bdea9eee 100644 --- a/widget/nsGUIEventIPC.h +++ b/widget/nsGUIEventIPC.h @@ -1225,6 +1225,7 @@ struct ParamTraits WriteParam(aMsg, aParam.mHandledByAPZ); WriteParam(aMsg, aParam.mFollowedByMomentum); WriteParam(aMsg, aParam.mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection); + WriteParam(aMsg, aParam.mOverscrollBehaviorAllowsSwipe); } static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult) @@ -1241,7 +1242,8 @@ struct ParamTraits ReadParam(aMsg, aIter, &aResult->mUserDeltaMultiplierY) && ReadParam(aMsg, aIter, &aResult->mHandledByAPZ) && ReadParam(aMsg, aIter, &aResult->mFollowedByMomentum) && - ReadParam(aMsg, aIter, &aResult->mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection); + ReadParam(aMsg, aIter, &aResult->mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection) && + ReadParam(aMsg, aIter, &aResult->mOverscrollBehaviorAllowsSwipe); } };