зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1709334 - Ensure calling SampleOverscrollAnimation for overscroll animations which are about to finish. r=botond
In cases where the overscroll amount is pretty small, the animation's physics model considers it's finished, which exacly means it's about to finish, so if we don't call SampleOverscrollAnimation in such cases, the small amount of overscrolling value remains there, then we try to create overscroll animations repeatedly even if the overscroll amount is visually noticeablt. Differential Revision: https://phabricator.services.mozilla.com/D114445
This commit is contained in:
Родитель
442aa07485
Коммит
c99a053acb
|
@ -235,6 +235,12 @@ bool Axis::IsOverscrollAnimationRunning() const {
|
|||
return !mMSDModel.IsFinished(1.0);
|
||||
}
|
||||
|
||||
bool Axis::IsOverscrollAnimationAlive() const {
|
||||
// Unlike IsOverscrollAnimationRunning, check the position and the velocity to
|
||||
// be sure that the animation has started but hasn't yet finished.
|
||||
return mMSDModel.GetPosition() != 0.0 || mMSDModel.GetVelocity() != 0.0;
|
||||
}
|
||||
|
||||
bool Axis::IsOverscrolled() const { return mOverscroll != 0.f; }
|
||||
|
||||
void Axis::ClearOverscroll() {
|
||||
|
|
|
@ -174,8 +174,17 @@ class Axis {
|
|||
*/
|
||||
void ClearOverscroll();
|
||||
|
||||
/**
|
||||
* Returns whether the overscroll animation is alive.
|
||||
*/
|
||||
bool IsOverscrollAnimationAlive() const;
|
||||
|
||||
/**
|
||||
* Returns whether the overscroll animation is running.
|
||||
* Note that unlike the above IsOverscrollAnimationAlive, this function
|
||||
* returns false even if the animation is still there but is very close to
|
||||
* the destination position and its velocity is quite low, i.e. it's time to
|
||||
* finish.
|
||||
*/
|
||||
bool IsOverscrollAnimationRunning() const;
|
||||
|
||||
|
|
|
@ -37,9 +37,9 @@ class OverscrollAnimation : public AsyncPanZoomAnimation {
|
|||
virtual bool DoSample(FrameMetrics& aFrameMetrics,
|
||||
const TimeDuration& aDelta) override {
|
||||
// Can't inline these variables due to short-circuit evaluation.
|
||||
bool continueX = mApzc.mX.IsOverscrollAnimationRunning() &&
|
||||
bool continueX = mApzc.mX.IsOverscrollAnimationAlive() &&
|
||||
mApzc.mX.SampleOverscrollAnimation(aDelta);
|
||||
bool continueY = mApzc.mY.IsOverscrollAnimationRunning() &&
|
||||
bool continueY = mApzc.mY.IsOverscrollAnimationAlive() &&
|
||||
mApzc.mY.SampleOverscrollAnimation(aDelta);
|
||||
if (!continueX && !continueY) {
|
||||
// If we got into overscroll from a fling, that fling did not request a
|
||||
|
|
|
@ -1437,6 +1437,64 @@ TEST_F(APZCOverscrollTester, DynamicallyLoadingContent) {
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifndef MOZ_WIDGET_ANDROID // Only applies to GenericOverscrollEffect
|
||||
TEST_F(APZCOverscrollTester, SmallAmountOfOverscroll) {
|
||||
SCOPED_GFX_PREF_BOOL("apz.overscroll.enabled", true);
|
||||
|
||||
ScrollMetadata metadata;
|
||||
FrameMetrics& metrics = metadata.GetMetrics();
|
||||
metrics.SetCompositionBounds(ParentLayerRect(0, 0, 100, 100));
|
||||
metrics.SetScrollableRect(CSSRect(0, 0, 100, 1000));
|
||||
|
||||
// Do vertical overscroll first.
|
||||
ScreenIntPoint panPoint(50, 50);
|
||||
PanGesture(PanGestureInput::PANGESTURE_START, apzc, panPoint,
|
||||
ScreenPoint(0, -10), mcc->Time());
|
||||
mcc->AdvanceByMillis(10);
|
||||
PanGesture(PanGestureInput::PANGESTURE_PAN, apzc, panPoint,
|
||||
ScreenPoint(0, -10), mcc->Time());
|
||||
mcc->AdvanceByMillis(10);
|
||||
PanGesture(PanGestureInput::PANGESTURE_END, apzc, panPoint, ScreenPoint(0, 0),
|
||||
mcc->Time());
|
||||
mcc->AdvanceByMillis(10);
|
||||
|
||||
// Then do small horizontal overscroll which will be considered as "finished"
|
||||
// by our overscroll animation physics model.
|
||||
PanGesture(PanGestureInput::PANGESTURE_START, apzc, panPoint,
|
||||
ScreenPoint(-0.1, 0), mcc->Time());
|
||||
mcc->AdvanceByMillis(10);
|
||||
PanGesture(PanGestureInput::PANGESTURE_PAN, apzc, panPoint,
|
||||
ScreenPoint(-0.2, 0), mcc->Time());
|
||||
mcc->AdvanceByMillis(10);
|
||||
PanGesture(PanGestureInput::PANGESTURE_END, apzc, panPoint, ScreenPoint(0, 0),
|
||||
mcc->Time());
|
||||
mcc->AdvanceByMillis(10);
|
||||
|
||||
EXPECT_TRUE(apzc->IsOverscrolled());
|
||||
EXPECT_TRUE(apzc->GetOverscrollAmount().y < 0); // overscrolled at top
|
||||
EXPECT_TRUE(apzc->GetOverscrollAmount().x < 0); // and overscrolled at left
|
||||
|
||||
// Then do vertical scroll.
|
||||
PanGesture(PanGestureInput::PANGESTURE_START, apzc, panPoint,
|
||||
ScreenPoint(0, 10), mcc->Time());
|
||||
mcc->AdvanceByMillis(10);
|
||||
PanGesture(PanGestureInput::PANGESTURE_PAN, apzc, panPoint,
|
||||
ScreenPoint(0, 100), mcc->Time());
|
||||
mcc->AdvanceByMillis(10);
|
||||
PanGesture(PanGestureInput::PANGESTURE_END, apzc, panPoint, ScreenPoint(0, 0),
|
||||
mcc->Time());
|
||||
|
||||
ParentLayerPoint scrollOffset =
|
||||
apzc->GetCurrentAsyncScrollOffset(AsyncPanZoomController::eForHitTesting);
|
||||
EXPECT_GT(scrollOffset.y, 0); // Make sure the vertical scroll offset is
|
||||
// greater than zero.
|
||||
|
||||
// The small horizontal overscroll amount should be restored to zero.
|
||||
ParentLayerPoint expectedScrollOffset(0, scrollOffset.y);
|
||||
SampleAnimationUntilRecoveredFromOverscroll(expectedScrollOffset);
|
||||
}
|
||||
#endif
|
||||
|
||||
class APZCOverscrollTesterForLayersOnly : public APZCTreeManagerTester {
|
||||
public:
|
||||
APZCOverscrollTesterForLayersOnly() { mLayersOnly = true; }
|
||||
|
|
Загрузка…
Ссылка в новой задаче