Bug 1705927 - Make GenericOverscrollEffect a no-op if prefers-reduced-motion is set. r=hiro

Differential Revision: https://phabricator.services.mozilla.com/D112660
This commit is contained in:
Botond Ballo 2021-04-20 01:50:53 +00:00
Родитель 2bce9ccde2
Коммит d229ecb8e4
8 изменённых файлов: 91 добавлений и 0 удалений

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

@ -820,6 +820,7 @@ struct ScrollMetadata {
mResolutionUpdated(false),
mIsRDMTouchSimulationActive(false),
mDidContentGetPainted(true),
mPrefersReducedMotion(false),
mOverscrollBehavior() {}
bool operator==(const ScrollMetadata& aOther) const {
@ -837,6 +838,7 @@ struct ScrollMetadata {
mResolutionUpdated == aOther.mResolutionUpdated &&
mIsRDMTouchSimulationActive == aOther.mIsRDMTouchSimulationActive &&
mDidContentGetPainted == aOther.mDidContentGetPainted &&
mPrefersReducedMotion == aOther.mPrefersReducedMotion &&
mDisregardedDirection == aOther.mDisregardedDirection &&
mOverscrollBehavior == aOther.mOverscrollBehavior &&
mScrollUpdates == aOther.mScrollUpdates;
@ -924,6 +926,9 @@ struct ScrollMetadata {
return mIsRDMTouchSimulationActive;
}
void SetPrefersReducedMotion(bool aValue) { mPrefersReducedMotion = aValue; }
bool PrefersReducedMotion() const { return mPrefersReducedMotion; }
bool DidContentGetPainted() const { return mDidContentGetPainted; }
private:
@ -1037,6 +1042,11 @@ struct ScrollMetadata {
// can use the correct transforms.
bool mDidContentGetPainted : 1;
// Whether the user has requested the system minimze the amount of
// non-essential motion it uses (see the prefers-reduced-motion
// media query).
bool mPrefersReducedMotion : 1;
// The disregarded direction means the direction which is disregarded anyway,
// even if the scroll frame overflows in that direction and the direction is
// specified as scrollable. This could happen in some scenarios, for instance,

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

@ -5057,6 +5057,8 @@ void AsyncPanZoomController::NotifyLayersUpdated(
mScrollMetadata.SetForceDisableApz(aScrollMetadata.IsApzForceDisabled());
mScrollMetadata.SetIsRDMTouchSimulationActive(
aScrollMetadata.GetIsRDMTouchSimulationActive());
mScrollMetadata.SetPrefersReducedMotion(
aScrollMetadata.PrefersReducedMotion());
mScrollMetadata.SetDisregardedDirection(
aScrollMetadata.GetDisregardedDirection());
mScrollMetadata.SetOverscrollBehavior(

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

@ -138,6 +138,10 @@ class GenericOverscrollEffect : public OverscrollEffectBase {
void ConsumeOverscroll(ParentLayerPoint& aOverscroll,
ScrollDirections aOverscrolableDirections) override {
if (mApzc.mScrollMetadata.PrefersReducedMotion()) {
return;
}
if (aOverscrolableDirections.contains(ScrollDirection::eHorizontal)) {
mApzc.mX.OverscrollBy(aOverscroll.x);
aOverscroll.x = 0;
@ -155,6 +159,10 @@ class GenericOverscrollEffect : public OverscrollEffectBase {
void HandleFlingOverscroll(const ParentLayerPoint& aVelocity,
SideBits aOverscrollSideBits) override {
if (mApzc.mScrollMetadata.PrefersReducedMotion()) {
return;
}
mApzc.StartOverscrollAnimation(aVelocity, aOverscrollSideBits);
}

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

@ -444,6 +444,7 @@ struct ParamTraits<mozilla::layers::ScrollMetadata>
WriteParam(aMsg, aParam.mResolutionUpdated);
WriteParam(aMsg, aParam.mIsRDMTouchSimulationActive);
WriteParam(aMsg, aParam.mDidContentGetPainted);
WriteParam(aMsg, aParam.mPrefersReducedMotion);
WriteParam(aMsg, aParam.mDisregardedDirection);
WriteParam(aMsg, aParam.mOverscrollBehavior);
WriteParam(aMsg, aParam.mScrollUpdates);
@ -483,6 +484,8 @@ struct ParamTraits<mozilla::layers::ScrollMetadata>
&paramType::SetIsRDMTouchSimulationActive)) &&
ReadBoolForBitfield(aMsg, aIter, aResult,
&paramType::SetDidContentGetPainted) &&
ReadBoolForBitfield(aMsg, aIter, aResult,
&paramType::SetPrefersReducedMotion) &&
ReadParam(aMsg, aIter, &aResult->mDisregardedDirection) &&
ReadParam(aMsg, aIter, &aResult->mOverscrollBehavior) &&
ReadParam(aMsg, aIter, &aResult->mScrollUpdates);

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

@ -35,6 +35,7 @@
#include "mozilla/BasicEvents.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/DisplayPortUtils.h"
#include "mozilla/GeckoBindings.h"
#include "mozilla/dom/AnonymousContent.h"
#include "mozilla/dom/BrowserChild.h"
#include "mozilla/dom/CanvasUtils.h"
@ -8782,6 +8783,9 @@ ScrollMetadata nsLayoutUtils::ComputeScrollMetadata(
metadata.SetForceDisableApz(true);
}
metadata.SetPrefersReducedMotion(
Gecko_MediaFeatures_PrefersReducedMotion(document));
return metadata;
}

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

@ -0,0 +1,24 @@
<!DOCTYPE html>
<html>
<head>
<style>
html {
scrollbar-width: none;
}
body {
height: 3000px;
margin: 0;
}
div {
position: absolute;
top: 0px;
width: 200px;
height: 200px;
background: green;
}
</style>
</head>
<body>
<div></div>
</body>
</html>

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

@ -0,0 +1,39 @@
<!DOCTYPE html>
<html
reftest-async-scroll
reftest-displayport-x="0" reftest-displayport-y="0"
reftest-displayport-w="800" reftest-displayport-h="2000"
reftest-async-scroll-x="0" reftest-async-scroll-y="-200">
<head>
<style>
html {
scrollbar-width: none;
}
body {
height: 3000px;
margin: 0;
}
div {
position: absolute;
top: 0px;
width: 200px;
height: 200px;
background: green;
}
</style>
</head>
<body >
<!-- Test that an overscroll past one end of a viewport is rendered
as having the content create a gutter, and that
the overscroll is reduced by some factor such that
a 100px scroll must produce a rendered translation of less than
100px.
Current overscroll physics mean that an instantaneous overscroll
by 200px produces an 8px gutter. This is governed by the logic in
Axis::ApplyResistance(); if that logic is changed, this test will
need to be modified to account for the new result.
-->
<div></div>
</body>
</html>

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

@ -99,6 +99,7 @@ fuzzy-if(!webrender,111-112,600-600) pref(apz.allow_zooming,true) == async-scrol
# on Android we have a different overscroll effect so this test is disabled
skip-if(!asyncPan||Android) pref(apz.overscroll.enabled,true) pref(apz.overscroll.test_async_scroll_offset.enabled,true) == overscroll.html overscroll-ref.html
skip-if(!asyncPan||Android) pref(ui.prefersReducedMotion,1) pref(apz.overscroll.enabled,true) pref(apz.overscroll.test_async_scroll_offset.enabled,true) == overscroll-reduced-motion.html no-overscroll-ref.html
# for this test, apz.allow_zooming is needed to ensure we take the containerless scrolling codepath that creates
# an async zoom container (since we are testing a regression in that codepath)