Bug 1230552 - Make immediate scroll handoff for panning prefable. r=kats

Immediate handoff is the current behaviour. The alternative is to
only allow a single input block to scroll a single APZC.
This commit is contained in:
Botond Ballo 2015-12-14 14:47:56 -05:00
parent fb864477b3
commit f0c8cde4e0
6 changed files with 69 additions and 1 deletions

View File

@ -105,6 +105,11 @@ using mozilla::gfx::PointTyped;
* \li\b apz.allow_checkerboarding
* Pref that allows or disallows checkerboarding
*
* \li\b apz.allow_immediate_handoff
* If set to true, scroll can be handed off from one APZC to another within
* a single input block. If set to false, a single input block can only
* scroll one APZC.
*
* \li\b apz.axis_lock.mode
* The preferred axis locking style. See AxisLockMode for possible values.
*
@ -1717,7 +1722,16 @@ AsyncPanZoomController::CanScroll(Layer::ScrollDirection aDirection) const
bool
AsyncPanZoomController::AllowScrollHandoffInCurrentBlock() const
{
return mInputQueue->AllowScrollHandoff();
bool result = mInputQueue->AllowScrollHandoff();
if (!gfxPrefs::APZAllowImmediateHandoff()) {
if (InputBlockState* currentBlock = CurrentInputBlock()) {
// Do not allow handoff beyond the first APZC to scroll.
if (currentBlock->GetScrolledApzc() == this) {
result = false;
}
}
}
return result;
}
nsEventStatus AsyncPanZoomController::OnScrollWheel(const ScrollWheelInput& aEvent)
@ -2294,6 +2308,11 @@ bool AsyncPanZoomController::AttemptScroll(ParentLayerPoint& aStartPoint,
if (!IsZero(adjustedDisplacement)) {
ScrollBy(adjustedDisplacement / mFrameMetrics.GetZoom());
if (!gfxPrefs::APZAllowImmediateHandoff()) {
if (InputBlockState* block = CurrentInputBlock()) {
block->SetScrolledApzc(this);
}
}
ScheduleCompositeAndMaybeRepaint();
UpdateSharedCompositorFrameMetrics();
}

View File

@ -87,6 +87,18 @@ InputBlockState::IsTargetConfirmed() const
return mTargetConfirmed;
}
void
InputBlockState::SetScrolledApzc(AsyncPanZoomController* aApzc)
{
mScrolledApzc = aApzc;
}
AsyncPanZoomController*
InputBlockState::GetScrolledApzc() const
{
return mScrolledApzc;
}
CancelableBlockState::CancelableBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
bool aTargetConfirmed)
: InputBlockState(aTargetApzc, aTargetConfirmed)

View File

@ -48,6 +48,9 @@ public:
bool IsTargetConfirmed() const;
void SetScrolledApzc(AsyncPanZoomController* aApzc);
AsyncPanZoomController* GetScrolledApzc() const;
protected:
virtual void UpdateTargetApzc(const RefPtr<AsyncPanZoomController>& aTargetApzc);
@ -55,6 +58,13 @@ private:
RefPtr<AsyncPanZoomController> mTargetApzc;
bool mTargetConfirmed;
const uint64_t mBlockId;
// The APZC that was actually scrolled by events in this input block.
// This is used in configurations where a single input block is only
// allowed to scroll a single APZC (configurations where gfxPrefs::
// APZAllowImmediateHandoff() is false).
// Set the first time an input event in this block scrolls an APZC.
RefPtr<AsyncPanZoomController> mScrolledApzc;
protected:
RefPtr<const OverscrollHandoffChain> mOverscrollHandoffChain;

View File

@ -3089,6 +3089,31 @@ TEST_F(APZOverscrollHandoffTester, ScrollgrabFlingAcceleration2) {
TestFlingAcceleration();
}
TEST_F(APZOverscrollHandoffTester, ImmediateHandoffDisallowed_Pan) {
SCOPED_GFX_PREF(APZAllowImmediateHandoff, bool, false);
CreateOverscrollHandoffLayerTree1();
RefPtr<TestAsyncPanZoomController> parentApzc = ApzcOf(root);
RefPtr<TestAsyncPanZoomController> childApzc = ApzcOf(layers[1]);
// Pan on the child, enough to scroll it to its end and have scroll
// left to hand off. Since immediate handoff is disallowed, we expect
// the leftover scroll not to be handed off.
Pan(childApzc, mcc, 60, 5);
// Verify that the parent has not scrolled.
EXPECT_EQ(50, childApzc->GetFrameMetrics().GetScrollOffset().y);
EXPECT_EQ(0, parentApzc->GetFrameMetrics().GetScrollOffset().y);
// Pan again on the child. This time, since the child was scrolled to
// its end when the gesture began, we expect the scroll to be handed off.
Pan(childApzc, mcc, 60, 50);
// Verify that the parent scrolled.
EXPECT_EQ(10, parentApzc->GetFrameMetrics().GetScrollOffset().y);
}
class APZEventRegionsTester : public APZCTreeManagerTester {
protected:
UniquePtr<ScopedLayerTreeRegistration> registration;

View File

@ -138,6 +138,7 @@ private:
// The apz prefs are explained in AsyncPanZoomController.cpp
DECL_GFX_PREF(Live, "apz.allow_checkerboarding", APZAllowCheckerboarding, bool, true);
DECL_GFX_PREF(Live, "apz.allow_immediate_handoff", APZAllowImmediateHandoff, bool, true);
DECL_GFX_PREF(Live, "apz.allow_zooming", APZAllowZooming, bool, false);
DECL_GFX_PREF(Live, "apz.axis_lock.breakout_angle", APZAxisBreakoutAngle, float, float(M_PI / 8.0) /* 22.5 degrees */);
DECL_GFX_PREF(Live, "apz.axis_lock.breakout_threshold", APZAxisBreakoutThreshold, float, 1.0f / 32.0f);

View File

@ -546,6 +546,7 @@ pref("layout.event-regions.enabled", false);
// APZ preferences. For documentation/details on what these prefs do, check
// gfx/layers/apz/src/AsyncPanZoomController.cpp.
pref("apz.allow_checkerboarding", true);
pref("apz.allow_immediate_handoff", true);
pref("apz.allow_zooming", false);
// Whether to lock touch scrolling to one axis at a time