Bug 1705280 - Allow overscroll handoff to the root content APZC on pan gestures even if the root APZC is not scrollable to the given input directions. r=botond

To be precise the root APZC should actually be scrollable in the opposed
directions of the given input, it's checked in
AsyncPanZoomController::GetOverscrollableDirections.

Differential Revision: https://phabricator.services.mozilla.com/D113061
This commit is contained in:
Hiroyuki Ikezoe 2021-04-26 08:48:08 +00:00
Родитель f91fe8a159
Коммит a0d7a740b9
3 изменённых файлов: 61 добавлений и 5 удалений

Просмотреть файл

@ -514,6 +514,9 @@ class AsyncPanZoomController {
// overscroll-behavior).
ScrollDirections GetAllowedHandoffDirections() const;
// Return the directions in which this APZC allows overscrolling.
ScrollDirections GetOverscrollableDirections() const;
// Return whether or not a scroll delta will be able to scroll in either
// direction.
bool CanScroll(const ParentLayerPoint& aDelta) const;
@ -1471,9 +1474,6 @@ class AsyncPanZoomController {
void StartOverscrollAnimation(const ParentLayerPoint& aVelocity,
SideBits aOverscrollSideBits);
// Return the directions in which this APZC allows overscrolling.
ScrollDirections GetOverscrollableDirections() const;
// Start a smooth-scrolling animation to the given destination, with physics
// based on the prefs for the indicated origin.
void SmoothScrollTo(const CSSPoint& aDestination,

Просмотреть файл

@ -152,6 +152,20 @@ RefPtr<AsyncPanZoomController> OverscrollHandoffChain::FindFirstScrollable(
return mChain[i];
}
// If there is any directions we allow overscroll effects on the root
// content APZC (i.e. the overscroll-behavior of the root one is not
// `none`), we consider the APZC can be scrollable in terms of pan gestures
// because it causes overscrolling even if it's not able to scroll to the
// direction.
if (StaticPrefs::apz_overscroll_enabled() &&
// FIXME: Bug 1707491: Drop this pan gesture input check.
aInput.mInputType == PANGESTURE_INPUT && mChain[i]->IsRootContent()) {
*aOutAllowedScrollDirections &= mChain[i]->GetOverscrollableDirections();
if (!aOutAllowedScrollDirections->isEmpty()) {
return mChain[i];
}
}
*aOutAllowedScrollDirections &= mChain[i]->GetAllowedHandoffDirections();
if (aOutAllowedScrollDirections->isEmpty()) {
return nullptr;

Просмотреть файл

@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "APZCBasicTester.h"
#include "APZCTreeManagerTester.h"
#include "APZTestCommon.h"
#include "mozilla/layers/WebRenderScrollDataWrapper.h"
@ -87,8 +88,7 @@ class APZCOverscrollTester : public APZCBasicTester {
rootLayerScrollData.AppendScrollMetadata(scrollData, metadata);
scrollData.AddLayerData(rootLayerScrollData);
registration =
MakeUnique<ScopedLayerTreeRegistration>(guid.mLayersId, mcc);
registration = MakeUnique<ScopedLayerTreeRegistration>(guid.mLayersId, mcc);
tm->UpdateHitTestingTree(WebRenderScrollDataWrapper(*updater, &scrollData),
false, guid.mLayersId, 0);
return guid;
@ -1318,3 +1318,45 @@ TEST_F(APZCOverscrollTester, OverscrollByPanGesturesInterruptedByReflowZoom) {
EXPECT_TRUE(!apzc->IsOverscrolled());
}
#endif
class APZCOverscrollTesterForLayersOnly : public APZCTreeManagerTester {
public:
APZCOverscrollTesterForLayersOnly() { mLayersOnly = true; }
UniquePtr<ScopedLayerTreeRegistration> registration;
TestAsyncPanZoomController* rootApzc;
};
#ifndef MOZ_WIDGET_ANDROID // Currently fails on Android
TEST_F(APZCOverscrollTesterForLayersOnly, OverscrollHandoff) {
SCOPED_GFX_PREF_BOOL("apz.overscroll.enabled", true);
const char* layerTreeSyntax = "c(c)";
nsIntRegion layerVisibleRegion[] = {nsIntRegion(IntRect(0, 0, 100, 100)),
nsIntRegion(IntRect(0, 0, 100, 50))};
root =
CreateLayerTree(layerTreeSyntax, layerVisibleRegion, nullptr, lm, layers);
SetScrollableFrameMetrics(root, ScrollableLayerGuid::START_SCROLL_ID,
CSSRect(0, 0, 200, 200));
SetScrollableFrameMetrics(layers[1], ScrollableLayerGuid::START_SCROLL_ID + 1,
// same size as the visible region so that
// the container is not scrollable in any directions
// actually. This is simulating overflow: hidden
// iframe document in Fission, though we don't set
// a different layers id.
CSSRect(0, 0, 100, 50));
SetScrollHandoff(layers[1], root);
registration =
MakeUnique<ScopedLayerTreeRegistration>(LayersId{0}, root, mcc);
UpdateHitTestingTree();
rootApzc = ApzcOf(root);
rootApzc->GetFrameMetrics().SetIsRootContent(true);
// A pan gesture on the child scroller (which is not scrollable though).
PanGesture(PanGestureInput::PANGESTURE_START, manager, ScreenIntPoint(50, 20),
ScreenPoint(0, -2), mcc->Time());
EXPECT_TRUE(rootApzc->IsOverscrolled());
}
#endif