diff --git a/gfx/layers/apz/src/AsyncPanZoomAnimation.h b/gfx/layers/apz/src/AsyncPanZoomAnimation.h index 575e1b68e532..127667afd949 100644 --- a/gfx/layers/apz/src/AsyncPanZoomAnimation.h +++ b/gfx/layers/apz/src/AsyncPanZoomAnimation.h @@ -81,6 +81,8 @@ class AsyncPanZoomAnimation { virtual void Cancel(CancelAnimationFlags aFlags) {} + virtual bool WasTriggeredByScript() const { return false; } + protected: // Protected destructor, to discourage deletion outside of Release(): virtual ~AsyncPanZoomAnimation() = default; diff --git a/gfx/layers/apz/src/AsyncPanZoomController.cpp b/gfx/layers/apz/src/AsyncPanZoomController.cpp index 265331d52734..3cb4c00e53eb 100644 --- a/gfx/layers/apz/src/AsyncPanZoomController.cpp +++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp @@ -1995,7 +1995,7 @@ nsEventStatus AsyncPanZoomController::OnKeyboard(const KeyboardInput& aEvent) { // existing smooth scroll animation if there is one. APZC_LOG("%p keyboard scrolling to snap point %s\n", this, ToString(destination).c_str()); - SmoothMsdScrollTo(destination); + SmoothMsdScrollTo(destination, ScrollTriggeredByScript::No); return nsEventStatus_eConsumeDoDefault; } @@ -2408,7 +2408,7 @@ nsEventStatus AsyncPanZoomController::OnScrollWheel( // existing smooth scroll animation if there is one. APZC_LOG("%p wheel scrolling to snap point %s\n", this, ToString(startPosition).c_str()); - SmoothMsdScrollTo(startPosition); + SmoothMsdScrollTo(startPosition, ScrollTriggeredByScript::No); break; } @@ -3719,12 +3719,13 @@ void AsyncPanZoomController::SmoothScrollTo(const CSSPoint& aDestination, StartAnimation(animation.get()); } -void AsyncPanZoomController::SmoothMsdScrollTo(const CSSPoint& aDestination) { +void AsyncPanZoomController::SmoothMsdScrollTo( + const CSSPoint& aDestination, ScrollTriggeredByScript aTriggeredByScript) { if (mState == SMOOTHMSD_SCROLL && mAnimation) { APZC_LOG("%p updating destination on existing animation\n", this); RefPtr animation( static_cast(mAnimation.get())); - animation->SetDestination(aDestination); + animation->SetDestination(aDestination, aTriggeredByScript); } else { CancelAnimation(); SetState(SMOOTHMSD_SCROLL); @@ -3739,7 +3740,8 @@ void AsyncPanZoomController::SmoothMsdScrollTo(const CSSPoint& aDestination) { StartAnimation(new SmoothMsdScrollAnimation( *this, Metrics().GetVisualScrollOffset(), initialVelocity, aDestination, StaticPrefs::layout_css_scroll_behavior_spring_constant(), - StaticPrefs::layout_css_scroll_behavior_damping_ratio())); + StaticPrefs::layout_css_scroll_behavior_damping_ratio(), + aTriggeredByScript)); } } @@ -5123,9 +5125,11 @@ void AsyncPanZoomController::NotifyLayersUpdated( } if (scrollUpdate.GetMode() == ScrollMode::SmoothMsd) { - SmoothMsdScrollTo(destination); + SmoothMsdScrollTo(destination, + scrollUpdate.GetScrollTriggeredByScript()); } else { MOZ_ASSERT(scrollUpdate.GetMode() == ScrollMode::Smooth); + MOZ_ASSERT(!scrollUpdate.WasTriggeredByScript()); SmoothScrollTo(destination, scrollUpdate.GetOrigin()); } continue; @@ -5907,7 +5911,7 @@ void AsyncPanZoomController::ScrollSnapNear(const CSSPoint& aDestination) { if (*snapPoint != Metrics().GetVisualScrollOffset()) { APZC_LOG("%p smooth scrolling to snap point %s\n", this, ToString(*snapPoint).c_str()); - SmoothMsdScrollTo(*snapPoint); + SmoothMsdScrollTo(*snapPoint, ScrollTriggeredByScript::No); } } } @@ -5953,7 +5957,7 @@ void AsyncPanZoomController::ScrollSnapToDestination() { (float)Metrics().GetVisualScrollOffset().y, (float)startPosition.x, (float)startPosition.y); - SmoothMsdScrollTo(startPosition); + SmoothMsdScrollTo(startPosition, ScrollTriggeredByScript::No); } } diff --git a/gfx/layers/apz/src/AsyncPanZoomController.h b/gfx/layers/apz/src/AsyncPanZoomController.h index e35fbaf1f17a..ebb8e98b4089 100644 --- a/gfx/layers/apz/src/AsyncPanZoomController.h +++ b/gfx/layers/apz/src/AsyncPanZoomController.h @@ -1483,7 +1483,8 @@ class AsyncPanZoomController { // Start a smooth-scrolling animation to the given destination, with MSD // physics that is suited for scroll-snapping. - void SmoothMsdScrollTo(const CSSPoint& aDestination); + void SmoothMsdScrollTo(const CSSPoint& aDestination, + ScrollTriggeredByScript aTriggeredByScript); // Returns whether overscroll is allowed during an event. bool AllowScrollHandoffInCurrentBlock() const; diff --git a/gfx/layers/apz/src/SmoothMsdScrollAnimation.cpp b/gfx/layers/apz/src/SmoothMsdScrollAnimation.cpp index 03d4850b498c..dc9d5e544518 100644 --- a/gfx/layers/apz/src/SmoothMsdScrollAnimation.cpp +++ b/gfx/layers/apz/src/SmoothMsdScrollAnimation.cpp @@ -12,12 +12,14 @@ namespace layers { SmoothMsdScrollAnimation::SmoothMsdScrollAnimation( AsyncPanZoomController& aApzc, const CSSPoint& aInitialPosition, const CSSPoint& aInitialVelocity, const CSSPoint& aDestination, - double aSpringConstant, double aDampingRatio) + double aSpringConstant, double aDampingRatio, + ScrollTriggeredByScript aTriggeredByScript) : mApzc(aApzc), mXAxisModel(aInitialPosition.x, aDestination.x, aInitialVelocity.x, aSpringConstant, aDampingRatio), mYAxisModel(aInitialPosition.y, aDestination.y, aInitialVelocity.y, - aSpringConstant, aDampingRatio) {} + aSpringConstant, aDampingRatio), + mTriggeredByScript(aTriggeredByScript) {} bool SmoothMsdScrollAnimation::DoSample(FrameMetrics& aFrameMetrics, const TimeDuration& aDelta) { @@ -113,9 +115,12 @@ bool SmoothMsdScrollAnimation::DoSample(FrameMetrics& aFrameMetrics, return true; } -void SmoothMsdScrollAnimation::SetDestination(const CSSPoint& aNewDestination) { +void SmoothMsdScrollAnimation::SetDestination( + const CSSPoint& aNewDestination, + ScrollTriggeredByScript aTriggeredByScript) { mXAxisModel.SetDestination(aNewDestination.x); mYAxisModel.SetDestination(aNewDestination.y); + mTriggeredByScript = aTriggeredByScript; } CSSPoint SmoothMsdScrollAnimation::GetDestination() const { diff --git a/gfx/layers/apz/src/SmoothMsdScrollAnimation.h b/gfx/layers/apz/src/SmoothMsdScrollAnimation.h index 956672a03fca..dc105d77019e 100644 --- a/gfx/layers/apz/src/SmoothMsdScrollAnimation.h +++ b/gfx/layers/apz/src/SmoothMsdScrollAnimation.h @@ -9,19 +9,21 @@ #include "AsyncPanZoomAnimation.h" #include "mozilla/layers/AxisPhysicsMSDModel.h" +#include "mozilla/ScrollPositionUpdate.h" namespace mozilla { namespace layers { class AsyncPanZoomController; -class SmoothMsdScrollAnimation : public AsyncPanZoomAnimation { +class SmoothMsdScrollAnimation final : public AsyncPanZoomAnimation { public: SmoothMsdScrollAnimation(AsyncPanZoomController& aApzc, const CSSPoint& aInitialPosition, const CSSPoint& aInitialVelocity, const CSSPoint& aDestination, double aSpringConstant, - double aDampingRatio); + double aDampingRatio, + ScrollTriggeredByScript aTriggeredByScript); /** * Advances a smooth scroll simulation based on the time passed in |aDelta|. @@ -32,14 +34,20 @@ class SmoothMsdScrollAnimation : public AsyncPanZoomAnimation { bool DoSample(FrameMetrics& aFrameMetrics, const TimeDuration& aDelta) override; - void SetDestination(const CSSPoint& aNewDestination); + void SetDestination(const CSSPoint& aNewDestination, + ScrollTriggeredByScript aTriggeredByScript); CSSPoint GetDestination() const; SmoothMsdScrollAnimation* AsSmoothMsdScrollAnimation() override; + bool WasTriggeredByScript() const override { + return mTriggeredByScript == ScrollTriggeredByScript::Yes; + } + private: AsyncPanZoomController& mApzc; AxisPhysicsMSDModel mXAxisModel; AxisPhysicsMSDModel mYAxisModel; + ScrollTriggeredByScript mTriggeredByScript; }; } // namespace layers