diff --git a/gfx/layers/apz/src/AsyncPanZoomController.cpp b/gfx/layers/apz/src/AsyncPanZoomController.cpp index 95c2a00ed654..c4cbfe6e63da 100644 --- a/gfx/layers/apz/src/AsyncPanZoomController.cpp +++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp @@ -3936,11 +3936,12 @@ void AsyncPanZoomController::HandleSmoothScrollOverscroll( BuildOverscrollHandoffChain(), nullptr); } -void AsyncPanZoomController::SmoothScrollTo(const CSSPoint& aDestination, - const ScrollOrigin& aOrigin) { +void AsyncPanZoomController::SmoothScrollTo( + CSSSnapTarget&& aDestination, ScrollTriggeredByScript aTriggeredByScript, + const ScrollOrigin& aOrigin) { // Convert velocity from ParentLayerPoints/ms to ParentLayerPoints/s and then // to appunits/second. - nsPoint destination = CSSPoint::ToAppUnits(aDestination); + nsPoint destination = CSSPoint::ToAppUnits(aDestination.mPosition); nsSize velocity; if (Metrics().GetZoom() != CSSToParentLayerScale(0)) { velocity = CSSSize::ToAppUnits(ParentLayerSize(mX.GetVelocity() * 1000.0f, @@ -3953,8 +3954,9 @@ void AsyncPanZoomController::SmoothScrollTo(const CSSPoint& aDestination, mAnimation->AsSmoothScrollAnimation()); if (animation->GetScrollOrigin() == aOrigin) { APZC_LOG("%p updating destination on existing animation\n", this); - animation->UpdateDestination(GetFrameTime().Time(), destination, - velocity); + animation->UpdateDestinationAndSnapTargets( + GetFrameTime().Time(), destination, velocity, + std::move(aDestination.mTargetIds), aTriggeredByScript); return; } } @@ -3965,7 +3967,9 @@ void AsyncPanZoomController::SmoothScrollTo(const CSSPoint& aDestination, CSSPoint::ToAppUnits(Metrics().GetVisualScrollOffset()); RefPtr animation = new SmoothScrollAnimation(*this, initialPosition, aOrigin); - animation->UpdateDestination(GetFrameTime().Time(), destination, velocity); + animation->UpdateDestinationAndSnapTargets( + GetFrameTime().Time(), destination, velocity, + std::move(aDestination.mTargetIds), aTriggeredByScript); StartAnimation(animation.get()); } @@ -4690,6 +4694,10 @@ bool AsyncPanZoomController::UpdateAnimation( mLastSnapTargetIds = mAnimation->AsSmoothMsdScrollAnimation()->TakeSnapTargetIds(); } + } else if (mAnimation->AsSmoothScrollAnimation()) { + RecursiveMutexAutoLock lock(mRecursiveMutex); + mLastSnapTargetIds = + mAnimation->AsSmoothScrollAnimation()->TakeSnapTargetIds(); } mAnimation = nullptr; } @@ -5518,10 +5526,10 @@ void AsyncPanZoomController::NotifyLayersUpdated( scrollUpdate.GetScrollTriggeredByScript()); } else { MOZ_ASSERT(scrollUpdate.GetMode() == ScrollMode::Smooth); - MOZ_ASSERT(!scrollUpdate.WasTriggeredByScript()); - MOZ_ASSERT(scrollUpdate.GetSnapTargetIds().mIdsOnX.IsEmpty()); - MOZ_ASSERT(scrollUpdate.GetSnapTargetIds().mIdsOnY.IsEmpty()); - SmoothScrollTo(destination, scrollUpdate.GetOrigin()); + SmoothScrollTo( + CSSSnapTarget{destination, scrollUpdate.GetSnapTargetIds()}, + scrollUpdate.GetScrollTriggeredByScript(), + scrollUpdate.GetOrigin()); } continue; } diff --git a/gfx/layers/apz/src/AsyncPanZoomController.h b/gfx/layers/apz/src/AsyncPanZoomController.h index e5b5eede8ce0..c85ef0cb4c57 100644 --- a/gfx/layers/apz/src/AsyncPanZoomController.h +++ b/gfx/layers/apz/src/AsyncPanZoomController.h @@ -1583,7 +1583,8 @@ class AsyncPanZoomController { // Start a smooth-scrolling animation to the given destination, with physics // based on the prefs for the indicated origin. - void SmoothScrollTo(const CSSPoint& aDestination, + void SmoothScrollTo(CSSSnapTarget&& aDestination, + ScrollTriggeredByScript aTriggeredByScript, const ScrollOrigin& aOrigin); // Start a smooth-scrolling animation to the given destination, with MSD diff --git a/gfx/layers/apz/src/SmoothScrollAnimation.cpp b/gfx/layers/apz/src/SmoothScrollAnimation.cpp index 266c027a55d8..dbeb9c695788 100644 --- a/gfx/layers/apz/src/SmoothScrollAnimation.cpp +++ b/gfx/layers/apz/src/SmoothScrollAnimation.cpp @@ -6,6 +6,8 @@ #include "SmoothScrollAnimation.h" #include "ScrollAnimationBezierPhysics.h" +#include "ScrollPositionUpdate.h" +#include "apz/src/GenericScrollAnimation.h" #include "mozilla/layers/APZPublicUtils.h" namespace mozilla { @@ -17,12 +19,23 @@ SmoothScrollAnimation::SmoothScrollAnimation(AsyncPanZoomController& aApzc, : GenericScrollAnimation( aApzc, aInitialPosition, apz::ComputeBezierAnimationSettingsForOrigin(aOrigin)), - mOrigin(aOrigin) {} + mOrigin(aOrigin), + mTriggeredByScript(ScrollTriggeredByScript::No) {} SmoothScrollAnimation* SmoothScrollAnimation::AsSmoothScrollAnimation() { return this; } +void SmoothScrollAnimation::UpdateDestinationAndSnapTargets( + TimeStamp aTime, const nsPoint& aDestination, + const nsSize& aCurrentVelocity, ScrollSnapTargetIds&& aSnapTargetIds, + ScrollTriggeredByScript aTriggeredByScript) { + GenericScrollAnimation::UpdateDestination(aTime, aDestination, + aCurrentVelocity); + mSnapTargetIds = std::move(aSnapTargetIds); + mTriggeredByScript = aTriggeredByScript; +} + ScrollOrigin SmoothScrollAnimation::GetScrollOrigin() const { return mOrigin; } ScrollOrigin SmoothScrollAnimation::GetScrollOriginForAction( diff --git a/gfx/layers/apz/src/SmoothScrollAnimation.h b/gfx/layers/apz/src/SmoothScrollAnimation.h index 1143744cc1d6..8096875a5151 100644 --- a/gfx/layers/apz/src/SmoothScrollAnimation.h +++ b/gfx/layers/apz/src/SmoothScrollAnimation.h @@ -8,6 +8,7 @@ #define mozilla_layers_SmoothScrollAnimation_h_ #include "GenericScrollAnimation.h" +#include "ScrollPositionUpdate.h" #include "mozilla/ScrollOrigin.h" #include "mozilla/layers/KeyboardScrollAction.h" @@ -19,16 +20,26 @@ class AsyncPanZoomController; class SmoothScrollAnimation : public GenericScrollAnimation { public: SmoothScrollAnimation(AsyncPanZoomController& aApzc, - const nsPoint& aInitialPosition, - ScrollOrigin aScrollOrigin); + const nsPoint& aInitialPosition, ScrollOrigin aOrigin); + + void UpdateDestinationAndSnapTargets( + TimeStamp aTime, const nsPoint& aDestination, + const nsSize& aCurrentVelocity, ScrollSnapTargetIds&& aSnapTargetIds, + ScrollTriggeredByScript aTriggeredByScript); SmoothScrollAnimation* AsSmoothScrollAnimation() override; + bool WasTriggeredByScript() const override { + return mTriggeredByScript == ScrollTriggeredByScript::Yes; + } + ScrollSnapTargetIds TakeSnapTargetIds() { return std::move(mSnapTargetIds); } ScrollOrigin GetScrollOrigin() const; static ScrollOrigin GetScrollOriginForAction( KeyboardScrollAction::KeyboardScrollActionType aAction); private: ScrollOrigin mOrigin; + ScrollSnapTargetIds mSnapTargetIds; + ScrollTriggeredByScript mTriggeredByScript; }; } // namespace layers diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index 989fbfb84b4f..9e3af308f807 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -2560,14 +2560,6 @@ void nsHTMLScrollFrame::ScrollToWithOrigin(nsPoint aScrollPosition, aParams.IsSmooth() && nsLayoutUtils::IsSmoothScrollingEnabled(); if (!mAsyncScroll) { if (isSmoothScroll && canHandoffToApz) { - // APZ does not handle ScrollTriggeredByScript::Yes and snapTargetIds for - // ScrollMode::Smooth (but this can be added if the assertion firing - // indicates it's necessary). - MOZ_ASSERT(aParams.mTriggeredByScript == ScrollTriggeredByScript::No); - if (snapTargetIds) { - MOZ_ASSERT(snapTargetIds->mIdsOnX.IsEmpty()); - MOZ_ASSERT(snapTargetIds->mIdsOnY.IsEmpty()); - } ApzSmoothScrollTo(mDestination, ScrollMode::Smooth, aParams.mOrigin, aParams.mTriggeredByScript, std::move(snapTargetIds)); return;