Diff
Modified: trunk/LayoutTests/ChangeLog (288776 => 288777)
--- trunk/LayoutTests/ChangeLog 2022-01-29 02:42:21 UTC (rev 288776)
+++ trunk/LayoutTests/ChangeLog 2022-01-29 02:56:40 UTC (rev 288777)
@@ -1,3 +1,22 @@
+2022-01-28 Nikolaos Mouchtaris <nmouchta...@apple.com>
+
+ Implement CSS overscroll-behavior for asynchronous scroll on Mac
+ https://bugs.webkit.org/show_bug.cgi?id=220139
+
+ Reviewed by Simon Fraser.
+
+ * fast/scrolling/mac/async-overscroll-behavior-element-expected.txt: Added.
+ * fast/scrolling/mac/async-overscroll-behavior-element.html: Added.
+ * fast/scrolling/mac/async-overscroll-behavior-iframe-expected.txt: Added.
+ * fast/scrolling/mac/async-overscroll-behavior-iframe.html: Added.
+ * fast/scrolling/mac/async-overscroll-behavior-unscrollable-element-expected.txt: Added.
+ * fast/scrolling/mac/async-overscroll-behavior-unscrollable-element.html: Added.
+ * fast/scrolling/mac/async-overscroll-behavior-unscrollable-iframe-expected.txt: Added.
+ * fast/scrolling/mac/async-overscroll-behavior-unscrollable-iframe.html: Added.
+ * fast/scrolling/resources/overscroll-behavior-support.js: Added.
+ (getDeltas):
+ (async mouseWheelScrollAndWait):
+
2022-01-28 Robert Jenner <jen...@apple.com>
[ BigSur+ Release wk1 arm64 ] Bots are flaky exiting testing after 500 layout-test failures (235733)
Added: trunk/LayoutTests/fast/scrolling/mac/async-overscroll-behavior-element-expected.txt (0 => 288777)
--- trunk/LayoutTests/fast/scrolling/mac/async-overscroll-behavior-element-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/scrolling/mac/async-overscroll-behavior-element-expected.txt 2022-01-29 02:56:40 UTC (rev 288777)
@@ -0,0 +1,20 @@
+
+PASS Element horizontal scroll test with overscroll-behavior: auto auto.
+PASS Element vertical scroll test with overscroll-behavior: auto auto.
+PASS Element horizontal scroll test with overscroll-behavior: contain auto.
+PASS Element vertical scroll test with overscroll-behavior: contain auto.
+PASS Element horizontal scroll test with overscroll-behavior: none auto.
+PASS Element vertical scroll test with overscroll-behavior: none auto.
+PASS Element horizontal scroll test with overscroll-behavior: auto contain.
+PASS Element vertical scroll test with overscroll-behavior: auto contain.
+PASS Element horizontal scroll test with overscroll-behavior: contain contain.
+PASS Element vertical scroll test with overscroll-behavior: contain contain.
+PASS Element horizontal scroll test with overscroll-behavior: none contain.
+PASS Element vertical scroll test with overscroll-behavior: none contain.
+PASS Element horizontal scroll test with overscroll-behavior: auto none.
+PASS Element vertical scroll test with overscroll-behavior: auto none.
+PASS Element horizontal scroll test with overscroll-behavior: contain none.
+PASS Element vertical scroll test with overscroll-behavior: contain none.
+PASS Element horizontal scroll test with overscroll-behavior: none none.
+PASS Element vertical scroll test with overscroll-behavior: none none.
+
Added: trunk/LayoutTests/fast/scrolling/mac/async-overscroll-behavior-element.html (0 => 288777)
--- trunk/LayoutTests/fast/scrolling/mac/async-overscroll-behavior-element.html (rev 0)
+++ trunk/LayoutTests/fast/scrolling/mac/async-overscroll-behavior-element.html 2022-01-29 02:56:40 UTC (rev 288777)
@@ -0,0 +1,86 @@
+<!doctype html> <!-- webkit-test-runner [ AsyncOverflowScrollingEnabled=true AsyncFrameScrollingEnabled=true ] -->
+<script src=""
+<script src=""
+<script src=""
+<link rel="help" href=""
+<style>
+ .scrolling {
+ overflow: scroll;
+ }
+ .scrollContent {
+ width: 300px;
+ height: 300px;
+ }
+ #root {
+ width: 200px;
+ height: 200px;
+ }
+ #scroller {
+ width: 100px;
+ height: 100px;
+ }
+</style>
+<div id='root' class="scrolling">
+ <div id='scroller' class="scrolling">
+ <div class="scrollContent"></div>
+ </div>
+ <div class="scrollContent"></div>
+</div>
+
+<script>
+const root = document.getElementById('root');
+const scroller = document.getElementById('scroller');
+var overscrollDatas = [["auto", "auto", true, true],
+ ["contain", "auto", false, true],
+ ["none", "auto", false, true],
+ ["auto", "contain", true, false],
+ ["contain", "contain", false, false],
+ ["none", "contain", false, false],
+ ["auto", "none", true, false],
+ ["contain", "none", false, false],
+ ["none", "none", false, false]];
+
+function resetTest() {
+ // Try various methods to ensure the element position is reset immediately.
+ scroller.scrollLeft = 300;
+ scroller.scrollTop = 300;
+ scroller.scrollTo(300, 300);
+
+ root.scrollLeft = 0;
+ root.scrollTop = 0;
+ root.scrollTo(0, 0);
+}
+
+function startTest() {
+ overscrollDatas.forEach(([overscrollX, overscrollY, propagateX, propagateY]) => {
+ promise_test(() => {
+ resetTest();
+ scroller.style.overscrollBehaviorX = overscrollX;
+ scroller.style.overscrollBehaviorY = overscrollY;
+ document.body.clientWidth;
+
+ var x = scroller.clientWidth / 2;
+ var y = scroller.clientHeight / 2;
+ var delta = getDeltas("right");
+ return mouseWheelScrollAndWait(x, y, delta.X, delta.Y, delta.X, delta.Y).then(() => {
+ assert_equals(root.scrollLeft > 0, propagateX, 'Propagate horizontal scroll');
+ });
+ }, 'Element horizontal scroll test with overscroll-behavior: ' + overscrollX + ' ' + overscrollY + '.');
+
+ promise_test(() => {
+ resetTest();
+ scroller.style.overscrollBehaviorX = overscrollX;
+ scroller.style.overscrollBehaviorY = overscrollY;
+
+ var x = scroller.clientWidth / 2;
+ var y = scroller.clientHeight / 2;
+ var delta = getDeltas("down");
+ return mouseWheelScrollAndWait(x, y, delta.X, delta.Y, delta.X, delta.Y).then(() => {
+ assert_equals(root.scrollTop > 0, propagateY, 'Propagate vertical scroll');
+ });
+ }, 'Element vertical scroll test with overscroll-behavior: ' + overscrollX + ' ' + overscrollY + '.');
+ });
+}
+
+addEventListener("load", startTest);
+</script>
\ No newline at end of file
Added: trunk/LayoutTests/fast/scrolling/mac/async-overscroll-behavior-iframe-expected.txt (0 => 288777)
--- trunk/LayoutTests/fast/scrolling/mac/async-overscroll-behavior-iframe-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/scrolling/mac/async-overscroll-behavior-iframe-expected.txt 2022-01-29 02:56:40 UTC (rev 288777)
@@ -0,0 +1,21 @@
+
+
+PASS Iframe horizontal scroll test with overscroll-behavior: auto auto.
+PASS Iframe vertical scroll test with overscroll-behavior: auto auto.
+PASS Iframe horizontal scroll test with overscroll-behavior: contain auto.
+PASS Iframe vertical scroll test with overscroll-behavior: contain auto.
+PASS Iframe horizontal scroll test with overscroll-behavior: none auto.
+PASS Iframe vertical scroll test with overscroll-behavior: none auto.
+PASS Iframe horizontal scroll test with overscroll-behavior: auto contain.
+PASS Iframe vertical scroll test with overscroll-behavior: auto contain.
+PASS Iframe horizontal scroll test with overscroll-behavior: contain contain.
+PASS Iframe vertical scroll test with overscroll-behavior: contain contain.
+PASS Iframe horizontal scroll test with overscroll-behavior: none contain.
+PASS Iframe vertical scroll test with overscroll-behavior: none contain.
+PASS Iframe horizontal scroll test with overscroll-behavior: auto none.
+PASS Iframe vertical scroll test with overscroll-behavior: auto none.
+PASS Iframe horizontal scroll test with overscroll-behavior: contain none.
+PASS Iframe vertical scroll test with overscroll-behavior: contain none.
+PASS Iframe horizontal scroll test with overscroll-behavior: none none.
+PASS Iframe vertical scroll test with overscroll-behavior: none none.
+
Added: trunk/LayoutTests/fast/scrolling/mac/async-overscroll-behavior-iframe.html (0 => 288777)
--- trunk/LayoutTests/fast/scrolling/mac/async-overscroll-behavior-iframe.html (rev 0)
+++ trunk/LayoutTests/fast/scrolling/mac/async-overscroll-behavior-iframe.html 2022-01-29 02:56:40 UTC (rev 288777)
@@ -0,0 +1,85 @@
+<!doctype html> <!-- webkit-test-runner [ AsyncOverflowScrollingEnabled=true AsyncFrameScrollingEnabled=true ] -->
+<script src=""
+<script src=""
+<script src=""
+<link rel="help" href=""
+<style>
+ .scrolling {
+ overflow: scroll;
+ }
+ .scrollContent {
+ width: 300px;
+ height: 300px;
+ background: linear-gradient(135deg, red, blue);
+ }
+ #root {
+ width: 200px;
+ height: 200px;
+ }
+ #scroller {
+ width: 100px;
+ height: 100px;
+ overscroll-behavior-y: auto;
+ }
+</style>
+<div id='root' class="scrolling">
+ <iframe id='scroller' srcdoc="<html><div style='width: 300px; height: 300px;'></div></html>
+ "></iframe>
+ <div class="scrollContent"></div>
+</div>
+
+<script>
+ const root = document.getElementById('root');
+ const scroller = document.getElementById('scroller');
+ var overscrollDatas = [["auto", "auto", true, true],
+ ["contain", "auto", false, true],
+ ["none", "auto", false, true],
+ ["auto", "contain", true, false],
+ ["contain", "contain", false, false],
+ ["none", "contain", false, false],
+ ["auto", "none", true, false],
+ ["contain", "none", false, false],
+ ["none", "none", false, false]];
+ function resetTest() {
+ // Try various methods to ensure the element position is reset immediately.
+ scroller.contentWindow.scrollX = 300;
+ scroller.contentWindow.scrollY = 300;
+ scroller.contentWindow.scrollTo(300, 300);
+ root.scrollLeft = 0;
+ root.scrollTop = 0;
+ root.scrollTo(0, 0);
+ }
+
+ function overscrollBehaviorTest() {
+ overscrollDatas.forEach(([overscrollX, overscrollY, propagateX, propagateY]) => {
+ promise_test(() => {
+ resetTest();
+ var target = scroller.contentWindow.document.getElementsByTagName("html")[0];
+ target.style.overscrollBehaviorX = overscrollX;
+ target.style.overscrollBehaviorY = overscrollY;
+ var x = scroller.clientWidth / 2;
+ var y = scroller.clientHeight / 2;
+ var delta = getDeltas("right");
+ return mouseWheelScrollAndWait(x, y, delta.X, delta.Y, delta.X, delta.Y).then(() => {
+ assert_equals(root.scrollLeft > 0, propagateX, 'Propagate horizontal scroll');
+ });
+ }, 'Iframe horizontal scroll test with overscroll-behavior: ' + overscrollX + ' ' + overscrollY + '.');
+
+ promise_test(() => {
+ resetTest();
+ var target = scroller.contentWindow.document.getElementsByTagName("html")[0];
+ target.style.overscrollBehaviorX = overscrollX;
+ target.style.overscrollBehaviorY = overscrollY;
+
+ var x = scroller.clientWidth / 2;
+ var y = scroller.clientHeight / 2;
+ var delta = getDeltas("down");
+ return mouseWheelScrollAndWait(x, y, delta.X, delta.Y, delta.X, delta.Y).then(() => {
+ assert_equals(root.scrollTop > 0, propagateY, 'Propagate vertical scroll');
+ });
+ }, 'Iframe vertical scroll test with overscroll-behavior: ' + overscrollX + ' ' + overscrollY + '.');
+ });
+ }
+
+ scroller.addEventListener("load", overscrollBehaviorTest);
+</script>
\ No newline at end of file
Added: trunk/LayoutTests/fast/scrolling/mac/async-overscroll-behavior-unscrollable-element-expected.txt (0 => 288777)
--- trunk/LayoutTests/fast/scrolling/mac/async-overscroll-behavior-unscrollable-element-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/scrolling/mac/async-overscroll-behavior-unscrollable-element-expected.txt 2022-01-29 02:56:40 UTC (rev 288777)
@@ -0,0 +1,4 @@
+
+PASS Unscrollable element horizontal scroll test with overscroll-behavior: none.
+PASS Unscrollable element vertical scroll test with overscroll-behavior: none.
+
Added: trunk/LayoutTests/fast/scrolling/mac/async-overscroll-behavior-unscrollable-element.html (0 => 288777)
--- trunk/LayoutTests/fast/scrolling/mac/async-overscroll-behavior-unscrollable-element.html (rev 0)
+++ trunk/LayoutTests/fast/scrolling/mac/async-overscroll-behavior-unscrollable-element.html 2022-01-29 02:56:40 UTC (rev 288777)
@@ -0,0 +1,67 @@
+<!doctype html> <!-- webkit-test-runner [ AsyncOverflowScrollingEnabled=true AsyncFrameScrollingEnabled=true ] -->
+
+<script src=""
+<script src=""
+<script src=""
+<link rel="help" href=""
+<style>
+ .scrolling {
+ overflow: scroll;
+ }
+ .scrollContent {
+ width: 300px;
+ height: 300px;
+ }
+ #root {
+ width: 200px;
+ height: 200px;
+ }
+ #scroller {
+ width: 100px;
+ height: 100px;
+ overscroll-behavior: none;
+ overflow: visible;
+ background: linear-gradient(135deg, red, blue);
+ }
+</style>
+<div id="root" class="scrolling">
+ <div id="scroller">
+ <div class="scrollContent"></div>
+ </div>
+ <div class="scrollContent"></div>
+</div>
+
+<script>
+const root = document.getElementById('root');
+const scroller = document.getElementById('scroller');
+
+function resetTest() {
+ root.scrollLeft = 0;
+ root.scrollTop = 0;
+ root.scrollTo(0, 0);
+}
+
+function startTest() {
+ promise_test(() => {
+ resetTest();
+ var x = scroller.clientWidth / 2;
+ var y = scroller.clientHeight / 2;
+ var delta = getDeltas("right");
+ return mouseWheelScrollAndWait(x, y, delta.X, delta.Y, delta.X, delta.Y).then(() => {
+ assert_equals(root.scrollLeft > 0, true, 'Propagate horizontal scroll');
+ });
+ }, 'Unscrollable element horizontal scroll test with overscroll-behavior: none.');
+
+ promise_test(() => {
+ resetTest();
+ var x = scroller.clientWidth / 2;
+ var y = scroller.clientHeight / 2;
+ var delta = getDeltas("down");
+ return mouseWheelScrollAndWait(x, y, delta.X, delta.Y, delta.X, delta.Y).then(() => {
+ assert_equals(root.scrollTop > 0, true, 'Propagate vertical scroll');
+ });
+ }, 'Unscrollable element vertical scroll test with overscroll-behavior: none.');
+}
+
+addEventListener("load", startTest);
+</script>
\ No newline at end of file
Added: trunk/LayoutTests/fast/scrolling/mac/async-overscroll-behavior-unscrollable-iframe-expected.txt (0 => 288777)
--- trunk/LayoutTests/fast/scrolling/mac/async-overscroll-behavior-unscrollable-iframe-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/scrolling/mac/async-overscroll-behavior-unscrollable-iframe-expected.txt 2022-01-29 02:56:40 UTC (rev 288777)
@@ -0,0 +1,5 @@
+
+
+PASS Unscrollable iframe horizontal scroll test with overscroll-behavior: none.
+PASS Unscrollable iframe vertical scroll test with overscroll-behavior: none.
+
Added: trunk/LayoutTests/fast/scrolling/mac/async-overscroll-behavior-unscrollable-iframe.html (0 => 288777)
--- trunk/LayoutTests/fast/scrolling/mac/async-overscroll-behavior-unscrollable-iframe.html (rev 0)
+++ trunk/LayoutTests/fast/scrolling/mac/async-overscroll-behavior-unscrollable-iframe.html 2022-01-29 02:56:40 UTC (rev 288777)
@@ -0,0 +1,66 @@
+<!doctype html> <!-- webkit-test-runner [ AsyncOverflowScrollingEnabled=true AsyncFrameScrollingEnabled=true ] -->
+
+<script src=""
+<script src=""
+<script src=""
+<link rel="help" href=""
+<style>
+ .scrolling {
+ overflow: scroll;
+ }
+ .scrollContent {
+ width: 300px;
+ height: 300px;
+ }
+ #root {
+ width: 200px;
+ height: 200px;
+ }
+ #scroller {
+ width: 200px;
+ height: 200px;
+ overscroll-behavior: none;
+ overflow: visible;
+ background: linear-gradient(135deg, red, blue);
+ }
+</style>
+<div id='root' class="scrolling">
+ <iframe id='scroller' srcdoc="<html style='overscroll-behavior: none;'><div style='width: 100px; height: 100px;'></div></html>
+ "></iframe>
+ <div class="scrollContent"></div>
+</div>
+
+<script>
+const root = document.getElementById('root');
+const scroller = document.getElementById('scroller');
+
+function resetTest() {
+ root.scrollLeft = 0;
+ root.scrollTop = 0;
+ root.scrollTo(0, 0);
+}
+
+function startTest() {
+ promise_test(() => {
+ resetTest();
+ var x = scroller.clientWidth / 2;
+ var y = scroller.clientHeight / 2;
+ var delta = getDeltas("right");
+ return mouseWheelScrollAndWait(x, y, delta.X, delta.Y, delta.X, delta.Y).then(() => {
+ assert_equals(root.scrollLeft > 0, true, 'Propagate horizontal scroll');
+ });
+ }, 'Unscrollable iframe horizontal scroll test with overscroll-behavior: none.');
+
+ promise_test(() => {
+ resetTest();
+ var x = scroller.clientWidth / 2;
+ var y = scroller.clientHeight / 2;
+ var delta = getDeltas("down");
+ return mouseWheelScrollAndWait(x, y, delta.X, delta.Y, delta.X, delta.Y).then(() => {
+ assert_equals(root.scrollTop > 0, true, 'Propagate vertical scroll');
+ });
+ }, 'Unscrollable iframe vertical scroll test with overscroll-behavior: none.');
+}
+
+addEventListener("load", startTest);
+</script>
\ No newline at end of file
Added: trunk/LayoutTests/fast/scrolling/resources/overscroll-behavior-support.js (0 => 288777)
--- trunk/LayoutTests/fast/scrolling/resources/overscroll-behavior-support.js (rev 0)
+++ trunk/LayoutTests/fast/scrolling/resources/overscroll-behavior-support.js 2022-01-29 02:56:40 UTC (rev 288777)
@@ -0,0 +1,39 @@
+function getDeltas(direction) {
+ var deltaX = 0;
+ var deltaY = 0;
+ if (direction == "down")
+ deltaY = -5
+ else if (direction == "up")
+ deltaY = 5;
+ else if (direction == "right")
+ deltaX = -5;
+ else if (direction == "left")
+ deltaX = 5;
+ return {
+ X: deltaX,
+ Y: deltaY
+ };
+}
+
+async function mouseWheelScrollAndWait(x, y, beginX, beginY, deltaX, deltaY)
+{
+ if (beginX === undefined)
+ beginX = 0;
+ if (beginY === undefined)
+ beginY = -1;
+ if (deltaX === undefined)
+ deltaX = 0;
+ if (deltaY === undefined)
+ deltaY = -10;
+
+ eventSender.monitorWheelEvents();
+ eventSender.mouseMoveTo(x, y);
+ eventSender.mouseScrollByWithWheelAndMomentumPhases(beginX, beginY, "began", "none");
+ eventSender.mouseScrollByWithWheelAndMomentumPhases(deltaX, deltaY, "changed", "none");
+ eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, "ended", "none");
+ return new Promise(resolve => {
+ setTimeout(() => {
+ requestAnimationFrame(resolve);
+ }, 500);
+ });
+}
\ No newline at end of file
Modified: trunk/Source/WebCore/ChangeLog (288776 => 288777)
--- trunk/Source/WebCore/ChangeLog 2022-01-29 02:42:21 UTC (rev 288776)
+++ trunk/Source/WebCore/ChangeLog 2022-01-29 02:56:40 UTC (rev 288777)
@@ -1,3 +1,33 @@
+2022-01-28 Nikolaos Mouchtaris <nmouchta...@apple.com>
+
+ Implement CSS overscroll-behavior for asynchronous scroll on Mac
+ https://bugs.webkit.org/show_bug.cgi?id=220139
+
+ Reviewed by Simon Fraser.
+
+ Split up patch by Cathie Chen and Frederic Wang. Add function for blocking scroll chaining
+ and filtering scroll delta depending on the values of overscroll behavior for a scrolling
+ node. This patch is for asynchronous scrolling only.
+
+ Tests: fast/scrolling/mac/async-overscroll-behavior-element.html
+ fast/scrolling/mac/async-overscroll-behavior-iframe.html
+ fast/scrolling/mac/async-overscroll-behavior-unscrollable-element.html
+ fast/scrolling/mac/async-overscroll-behavior-unscrollable-iframe.html
+
+ * page/scrolling/ScrollingTree.cpp:
+ (WebCore::ScrollingTree::shouldBlockScrollChainingWithNode):
+ (WebCore::ScrollingTree::handleWheelEventWithNode):
+ * page/scrolling/ScrollingTree.h:
+ * page/scrolling/ScrollingTreeScrollingNode.h:
+ * page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm:
+ (WebCore::ScrollingTreeScrollingNodeDelegateMac::allowsHorizontalStretching const):
+ (WebCore::ScrollingTreeScrollingNodeDelegateMac::allowsVerticalStretching const):
+ * rendering/RenderLayerCompositor.cpp:
+ (WebCore::recompositeChangeRequiresGeometryUpdate):
+ (WebCore::RenderLayerCompositor::rootOrBodyStyleChanged):
+ * rendering/style/RenderStyle.cpp:
+ (WebCore::RenderStyle::changeRequiresRecompositeLayer const):
+
2022-01-28 Tyler Wilcock <tyle...@apple.com>
AX: AccessibilitySlider::inputElement should check if the renderer has become null
Modified: trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp (288776 => 288777)
--- trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp 2022-01-29 02:42:21 UTC (rev 288776)
+++ trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp 2022-01-29 02:56:40 UTC (rev 288777)
@@ -787,8 +787,8 @@
scrollingNode.setScrollableAreaSize(scrollableArea.visibleSize());
ScrollableAreaParameters scrollParameters;
- scrollParameters.horizontalScrollElasticity = scrollableArea.horizontalScrollElasticity();
- scrollParameters.verticalScrollElasticity = scrollableArea.verticalScrollElasticity();
+ scrollParameters.horizontalScrollElasticity = scrollableArea.horizontalOverscrollBehavior() == OverscrollBehavior::None ? ScrollElasticity::None : scrollableArea.horizontalScrollElasticity();
+ scrollParameters.verticalScrollElasticity = scrollableArea.verticalOverscrollBehavior() == OverscrollBehavior::None ? ScrollElasticity::None : scrollableArea.verticalScrollElasticity();
scrollParameters.allowsHorizontalScrolling = scrollableArea.allowsHorizontalScrolling();
scrollParameters.allowsVerticalScrolling = scrollableArea.allowsVerticalScrolling();
scrollParameters.horizontalOverscrollBehavior = scrollableArea.horizontalOverscrollBehavior();
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp (288776 => 288777)
--- trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp 2022-01-29 02:42:21 UTC (rev 288776)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp 2022-01-29 02:56:40 UTC (rev 288777)
@@ -31,6 +31,7 @@
#include "EventNames.h"
#include "Logging.h"
#include "PlatformWheelEvent.h"
+#include "ScrollingEffectsController.h"
#include "ScrollingStateFrameScrollingNode.h"
#include "ScrollingStateTree.h"
#include "ScrollingTreeFrameScrollingNode.h"
@@ -201,19 +202,27 @@
WheelEventHandlingResult ScrollingTree::handleWheelEventWithNode(const PlatformWheelEvent& wheelEvent, OptionSet<WheelEventProcessingSteps> processingSteps, ScrollingTreeNode* node, EventTargeting eventTargeting)
{
+ auto adjustedWheelEvent = wheelEvent;
while (node) {
if (is<ScrollingTreeScrollingNode>(*node)) {
auto& scrollingNode = downcast<ScrollingTreeScrollingNode>(*node);
- auto result = scrollingNode.handleWheelEvent(wheelEvent, eventTargeting);
+ auto result = scrollingNode.handleWheelEvent(adjustedWheelEvent, eventTargeting);
if (result.wasHandled) {
- m_latchingController.nodeDidHandleEvent(scrollingNode.scrollingNodeID(), processingSteps, wheelEvent, m_allowLatching);
- m_gestureState.nodeDidHandleEvent(scrollingNode.scrollingNodeID(), wheelEvent);
+ m_latchingController.nodeDidHandleEvent(scrollingNode.scrollingNodeID(), processingSteps, adjustedWheelEvent, m_allowLatching);
+ m_gestureState.nodeDidHandleEvent(scrollingNode.scrollingNodeID(), adjustedWheelEvent);
return result;
}
if (result.needsMainThreadProcessing() || eventTargeting != EventTargeting::Propagate)
return result;
+
+ if (scrollingNode.shouldBlockScrollPropagation(adjustedWheelEvent.delta())) {
+ m_latchingController.nodeDidHandleEvent(scrollingNode.scrollingNodeID(), processingSteps, adjustedWheelEvent, m_allowLatching);
+ m_gestureState.nodeDidHandleEvent(scrollingNode.scrollingNodeID(), adjustedWheelEvent);
+ return WheelEventHandlingResult::handled();
+ }
+ adjustedWheelEvent = scrollingNode.eventForPropagation(adjustedWheelEvent);
}
if (is<ScrollingTreeOverflowScrollProxyNode>(*node)) {
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp (288776 => 288777)
--- trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp 2022-01-29 02:42:21 UTC (rev 288776)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp 2022-01-29 02:56:40 UTC (rev 288777)
@@ -32,6 +32,7 @@
#if ENABLE(SCROLLING_THREAD)
#include "ScrollingStateFrameScrollingNode.h"
#endif
+#include "ScrollingEffectsController.h"
#include "ScrollingStateScrollingNode.h"
#include "ScrollingStateTree.h"
#include "ScrollingTree.h"
@@ -121,6 +122,15 @@
return scrollingTree().latchedNodeID() == scrollingNodeID();
}
+bool ScrollingTreeScrollingNode::shouldRubberBand(const PlatformWheelEvent& wheelEvent, EventTargeting eventTargeting) const
+{
+ // We always rubber-band the latched node, or the root node.
+ // The stateless wheel event doesn't trigger rubber-band.
+ // Also rubberband when we should block scroll propagation
+ // at this node, which has overscroll behavior that is not none.
+ return (isLatchedNode() || eventTargeting == EventTargeting::NodeOnly || (isRootNode() && !wheelEvent.isNonGestureEvent()) || (shouldBlockScrollPropagation(wheelEvent.delta()) && overscrollBehaviorAllowRubberBand()));
+}
+
bool ScrollingTreeScrollingNode::canHandleWheelEvent(const PlatformWheelEvent& wheelEvent, EventTargeting eventTargeting) const
{
if (!canHaveScrollbars())
@@ -130,9 +140,7 @@
if (wheelEvent.phase() == PlatformWheelEventPhase::MayBegin)
return true;
- // We always rubber-band the latched node, or the root node.
- // The stateless wheel event doesn't trigger rubber-band.
- if (isLatchedNode() || eventTargeting == EventTargeting::NodeOnly || (isRootNode() && !wheelEvent.isNonGestureEvent()))
+ if (shouldRubberBand(wheelEvent, eventTargeting))
return true;
return eventCanScrollContents(wheelEvent);
@@ -392,6 +400,29 @@
m_currentVerticalSnapPointIndex = index;
}
+PlatformWheelEvent ScrollingTreeScrollingNode::eventForPropagation(const PlatformWheelEvent& wheelEvent) const
+{
+ auto filteredDelta = wheelEvent.delta();
+#if PLATFORM(MAC)
+ auto biasedDelta = ScrollingEffectsController::wheelDeltaBiasingTowardsVertical(wheelEvent);
+#else
+ auto biasedDelta = wheelEvent.delta();
+#endif
+ if (horizontalOverscrollBehaviorPreventsPropagation() || verticalOverscrollBehaviorPreventsPropagation()) {
+ if(horizontalOverscrollBehaviorPreventsPropagation() || (verticalOverscrollBehaviorPreventsPropagation() && !biasedDelta.width()))
+ filteredDelta.setWidth(0);
+ if(verticalOverscrollBehaviorPreventsPropagation() || (horizontalOverscrollBehaviorPreventsPropagation() && !biasedDelta.height()))
+ filteredDelta.setHeight(0);
+ return wheelEvent.copyWithDeltaAndVelocity(filteredDelta, wheelEvent.scrollingVelocity());
+ }
+ return wheelEvent;
+}
+
+bool ScrollingTreeScrollingNode::shouldBlockScrollPropagation(const FloatSize& delta) const
+{
+ return ((horizontalOverscrollBehaviorPreventsPropagation() || verticalOverscrollBehaviorPreventsPropagation()) && ((horizontalOverscrollBehaviorPreventsPropagation() && verticalOverscrollBehaviorPreventsPropagation()) || (horizontalOverscrollBehaviorPreventsPropagation() && !delta.height()) || (verticalOverscrollBehaviorPreventsPropagation() && !delta.width())));
+}
+
} // namespace WebCore
#endif // ENABLE(ASYNC_SCROLLING)
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h (288776 => 288777)
--- trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h 2022-01-29 02:42:21 UTC (rev 288776)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h 2022-01-29 02:56:40 UTC (rev 288777)
@@ -159,7 +159,14 @@
bool allowsHorizontalScrolling() const { return m_scrollableAreaParameters.allowsHorizontalScrolling; }
bool allowsVerticalScrolling() const { return m_scrollableAreaParameters.allowsVerticalScrolling; }
-
+ OverscrollBehavior horizontalOverscrollBehavior() const { return m_scrollableAreaParameters.horizontalOverscrollBehavior; }
+ OverscrollBehavior verticalOverscrollBehavior() const { return m_scrollableAreaParameters.verticalOverscrollBehavior; }
+ bool horizontalOverscrollBehaviorPreventsPropagation() const { return m_scrollableAreaParameters.horizontalOverscrollBehavior != OverscrollBehavior::Auto; }
+ bool verticalOverscrollBehaviorPreventsPropagation() const { return m_scrollableAreaParameters.verticalOverscrollBehavior != OverscrollBehavior::Auto; }
+ PlatformWheelEvent eventForPropagation(const PlatformWheelEvent&) const;
+ bool shouldBlockScrollPropagation(const FloatSize&) const;
+ bool overscrollBehaviorAllowRubberBand() const { return m_scrollableAreaParameters.horizontalOverscrollBehavior != OverscrollBehavior::None || m_scrollableAreaParameters.verticalOverscrollBehavior != OverscrollBehavior::None; }
+ bool shouldRubberBand(const PlatformWheelEvent&, EventTargeting) const;
void dumpProperties(WTF::TextStream&, OptionSet<ScrollingStateTreeAsTextBehavior>) const override;
private:
Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp (288776 => 288777)
--- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp 2022-01-29 02:42:21 UTC (rev 288776)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp 2022-01-29 02:56:40 UTC (rev 288777)
@@ -1651,7 +1651,9 @@
|| oldStyle.offsetPosition() != newStyle.offsetPosition()
|| oldStyle.offsetDistance() != newStyle.offsetDistance()
|| oldStyle.offsetRotate() != newStyle.offsetRotate()
- || !arePointingToEqualData(oldStyle.clipPath(), newStyle.clipPath());
+ || !arePointingToEqualData(oldStyle.clipPath(), newStyle.clipPath())
+ || oldStyle.overscrollBehaviorX() != newStyle.overscrollBehaviorX()
+ || oldStyle.overscrollBehaviorY() != newStyle.overscrollBehaviorY();
}
void RenderLayerCompositor::layerStyleChanged(StyleDifference diff, RenderLayer& layer, const RenderStyle* oldStyle)
@@ -3944,6 +3946,11 @@
bool hadFixedBackground = oldStyle && oldStyle->hasEntirelyFixedBackground();
if (hadFixedBackground != renderer.style().hasEntirelyFixedBackground())
rootLayerConfigurationChanged();
+
+ if (oldStyle && (oldStyle->overscrollBehaviorX() != renderer.style().overscrollBehaviorX() || oldStyle->overscrollBehaviorY() != renderer.style().overscrollBehaviorY())) {
+ if (auto* layer = m_renderView.layer())
+ layer->setNeedsCompositingGeometryUpdate();
+ }
}
void RenderLayerCompositor::rootBackgroundColorOrTransparencyChanged()
Modified: trunk/Source/WebCore/rendering/style/RenderStyle.cpp (288776 => 288777)
--- trunk/Source/WebCore/rendering/style/RenderStyle.cpp 2022-01-29 02:42:21 UTC (rev 288776)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.cpp 2022-01-29 02:56:40 UTC (rev 288777)
@@ -1189,7 +1189,9 @@
|| m_rareNonInheritedData->backfaceVisibility != other.m_rareNonInheritedData->backfaceVisibility
|| m_rareNonInheritedData->perspective != other.m_rareNonInheritedData->perspective
|| m_rareNonInheritedData->perspectiveOriginX != other.m_rareNonInheritedData->perspectiveOriginX
- || m_rareNonInheritedData->perspectiveOriginY != other.m_rareNonInheritedData->perspectiveOriginY)
+ || m_rareNonInheritedData->perspectiveOriginY != other.m_rareNonInheritedData->perspectiveOriginY
+ || m_rareNonInheritedData->overscrollBehaviorX != other.m_rareNonInheritedData->overscrollBehaviorX
+ || m_rareNonInheritedData->overscrollBehaviorY != other.m_rareNonInheritedData->overscrollBehaviorY)
return true;
}