From 30376c8190439f64981e222ef5c1c560884cd933 Mon Sep 17 00:00:00 2001 From: Botond Ballo Date: Wed, 20 Jan 2016 20:41:30 -0500 Subject: [PATCH] Bug 1240202 - Avoid getting stuck in overscroll when a second finger goes down while overscrolled and in the TOUCHING state. r=kats --HG-- extra : source : f92c04fc06584164ac8f9451977c5fa5d8e6c230 --- gfx/layers/apz/src/AsyncPanZoomController.cpp | 5 ++ .../apz/test/gtest/TestScrollHandoff.cpp | 46 +++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/gfx/layers/apz/src/AsyncPanZoomController.cpp b/gfx/layers/apz/src/AsyncPanZoomController.cpp index 437fbe733678..c616301e6083 100644 --- a/gfx/layers/apz/src/AsyncPanZoomController.cpp +++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp @@ -3564,6 +3564,11 @@ AsyncPanZoomController::ResetTouchInputState() listener->HandleInputEvent(cancel); } CancelAnimationAndGestureState(); + // Clear overscroll along the entire handoff chain, in case an APZC + // later in the chain is overscrolled. + if (TouchBlockState* block = CurrentTouchBlock()) { + block->GetOverscrollHandoffChain()->ClearOverscroll(); + } } void diff --git a/gfx/layers/apz/test/gtest/TestScrollHandoff.cpp b/gfx/layers/apz/test/gtest/TestScrollHandoff.cpp index 4fa9b26cccdb..d1b58eb56f4c 100644 --- a/gfx/layers/apz/test/gtest/TestScrollHandoff.cpp +++ b/gfx/layers/apz/test/gtest/TestScrollHandoff.cpp @@ -26,6 +26,7 @@ protected: registration = MakeUnique(manager, 0, root, mcc); manager->UpdateHitTestingTree(nullptr, root, false, 0, 0); rootApzc = ApzcOf(root); + rootApzc->GetFrameMetrics().SetIsRootContent(true); // make root APZC zoomable } void CreateScrollHandoffLayerTree2() { @@ -306,6 +307,51 @@ TEST_F(APZScrollHandoffTester, StuckInOverscroll_Bug1240202a) { EXPECT_FALSE(rootApzc->IsOverscrolled()); } +TEST_F(APZScrollHandoffTester, StuckInOverscroll_Bug1240202b) { + // Enable overscrolling. + SCOPED_GFX_PREF(APZOverscrollEnabled, bool, true); + + CreateScrollHandoffLayerTree1(); + + TestAsyncPanZoomController* child = ApzcOf(layers[1]); + + // Pan, causing the parent APZC to overscroll. + Pan(manager, mcc, 60, 90, true /* keep finger down */); + EXPECT_FALSE(child->IsOverscrolled()); + EXPECT_TRUE(rootApzc->IsOverscrolled()); + + // Lift the finger, triggering an overscroll animation + // (but don't allow it to run). + TouchUp(manager, ScreenIntPoint(10, 90), mcc->Time()); + + // Put the finger down again, interrupting the animation + // and entering the TOUCHING state. + TouchDown(manager, ScreenIntPoint(10, 90), mcc->Time()); + + // Put a second finger down. Since we're in the TOUCHING state, + // the "are we panned into overscroll" check will fail and we + // will not ignore the second finger, instead entering the + // PINCHING state. + MultiTouchInput secondFingerDown(MultiTouchInput::MULTITOUCH_START, 0, TimeStamp(), 0); + // Use the same touch identifier for the first touch (0) as TouchDown(). (A bit hacky.) + secondFingerDown.mTouches.AppendElement(SingleTouchData(0, ScreenIntPoint(10, 90), ScreenSize(0, 0), 0, 0)); + secondFingerDown.mTouches.AppendElement(SingleTouchData(1, ScreenIntPoint(10, 80), ScreenSize(0, 0), 0, 0)); + manager->ReceiveInputEvent(secondFingerDown, nullptr, nullptr); + + // Release the fingers. + MultiTouchInput fingersUp = secondFingerDown; + fingersUp.mType = MultiTouchInput::MULTITOUCH_END; + manager->ReceiveInputEvent(fingersUp, nullptr, nullptr); + + // Allow any animations to run their course. + child->AdvanceAnimationsUntilEnd(); + rootApzc->AdvanceAnimationsUntilEnd(); + + // Make sure nothing is overscrolled. + EXPECT_FALSE(child->IsOverscrolled()); + EXPECT_FALSE(rootApzc->IsOverscrolled()); +} + // Test that flinging in a direction where one component of the fling goes into // overscroll but the other doesn't, results in just the one component being // handed off to the parent, while the original APZC continues flinging in the