Diff
Modified: trunk/LayoutTests/ChangeLog (258043 => 258044)
--- trunk/LayoutTests/ChangeLog 2020-03-07 01:44:56 UTC (rev 258043)
+++ trunk/LayoutTests/ChangeLog 2020-03-07 01:45:55 UTC (rev 258044)
@@ -58,12 +58,41 @@
2020-03-06 Simon Fraser <[email protected]>
+ Hit-test CALayers on the scrolling thread for async frame/overflow scrolling
+ https://bugs.webkit.org/show_bug.cgi?id=208740
+ <rdar://problem/48028836>
+
+ Reviewed by Tim Horton.
+
+ Add some UIHelper functions for mousewheel scrolling, and use them in new tests.
+ Fix some old malformed expectations.
+
+ * fast/scrolling/ios/hit-testing-iframe-001-expected.html: Was malformed.
+ * fast/scrolling/ios/hit-testing-iframe-002-expected.html:
+ * fast/scrolling/ios/hit-testing-iframe-003-expected.html:
+ * fast/scrolling/ios/hit-testing-iframe-004-expected.html:
+ * fast/scrolling/ios/hit-testing-iframe-005-expected.html:
+ * fast/scrolling/ios/hit-testing-iframe-006-expected.html:
+ * fast/scrolling/mac/absolute-in-overflow-scroll-expected.txt: Added.
+ * fast/scrolling/mac/absolute-in-overflow-scroll.html: Added.
+ * fast/scrolling/mac/async-scroll-overflow-expected.txt: Added.
+ * fast/scrolling/mac/async-scroll-overflow.html: Added.
+ * fast/scrolling/mac/move-node-in-overflow-scroll-expected.txt: Added.
+ * fast/scrolling/mac/move-node-in-overflow-scroll.html: Added.
+ * fast/scrolling/mac/overlapped-overflow-scroll-expected.txt: Added.
+ * fast/scrolling/mac/overlapped-overflow-scroll.html: Added.
+ * resources/ui-helper.js:
+ (window.UIHelper.async mouseWheelScrollAt):
+ (window.UIHelper.async animationFrame):
+
+2020-03-06 Simon Fraser <[email protected]>
+
Move synchronousScrollingReasons to ScrollingTreeScrollingNode
https://bugs.webkit.org/show_bug.cgi?id=208721
Reviewed by Antti Koivisto.
- Rebaselined.
+ Rebaselined.
* tiled-drawing/scrolling/scrolling-tree-slow-scrolling-expected.txt:
Modified: trunk/LayoutTests/fast/scrolling/ios/hit-testing-iframe-001-expected.html (258043 => 258044)
--- trunk/LayoutTests/fast/scrolling/ios/hit-testing-iframe-001-expected.html 2020-03-07 01:44:56 UTC (rev 258043)
+++ trunk/LayoutTests/fast/scrolling/ios/hit-testing-iframe-001-expected.html 2020-03-07 01:45:55 UTC (rev 258044)
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html
+<html>
<head>
<title>Hit testing of iframe</title>
</head>
Modified: trunk/LayoutTests/fast/scrolling/ios/hit-testing-iframe-002-expected.html (258043 => 258044)
--- trunk/LayoutTests/fast/scrolling/ios/hit-testing-iframe-002-expected.html 2020-03-07 01:44:56 UTC (rev 258043)
+++ trunk/LayoutTests/fast/scrolling/ios/hit-testing-iframe-002-expected.html 2020-03-07 01:45:55 UTC (rev 258044)
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html
+<html>
<head>
<title>Hit testing of iframe</title>
</head>
Modified: trunk/LayoutTests/fast/scrolling/ios/hit-testing-iframe-003-expected.html (258043 => 258044)
--- trunk/LayoutTests/fast/scrolling/ios/hit-testing-iframe-003-expected.html 2020-03-07 01:44:56 UTC (rev 258043)
+++ trunk/LayoutTests/fast/scrolling/ios/hit-testing-iframe-003-expected.html 2020-03-07 01:45:55 UTC (rev 258044)
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html
+<html>
<head>
<title>Hit testing of iframe</title>
</head>
Modified: trunk/LayoutTests/fast/scrolling/ios/hit-testing-iframe-004-expected.html (258043 => 258044)
--- trunk/LayoutTests/fast/scrolling/ios/hit-testing-iframe-004-expected.html 2020-03-07 01:44:56 UTC (rev 258043)
+++ trunk/LayoutTests/fast/scrolling/ios/hit-testing-iframe-004-expected.html 2020-03-07 01:45:55 UTC (rev 258044)
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html
+<html>
<head>
<title>Hit testing of iframe</title>
</head>
Modified: trunk/LayoutTests/fast/scrolling/ios/hit-testing-iframe-005-expected.html (258043 => 258044)
--- trunk/LayoutTests/fast/scrolling/ios/hit-testing-iframe-005-expected.html 2020-03-07 01:44:56 UTC (rev 258043)
+++ trunk/LayoutTests/fast/scrolling/ios/hit-testing-iframe-005-expected.html 2020-03-07 01:45:55 UTC (rev 258044)
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html
+<html>
<head>
<title>Hit testing of iframe</title>
</head>
Modified: trunk/LayoutTests/fast/scrolling/ios/hit-testing-iframe-006-expected.html (258043 => 258044)
--- trunk/LayoutTests/fast/scrolling/ios/hit-testing-iframe-006-expected.html 2020-03-07 01:44:56 UTC (rev 258043)
+++ trunk/LayoutTests/fast/scrolling/ios/hit-testing-iframe-006-expected.html 2020-03-07 01:45:55 UTC (rev 258044)
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html
+<html>
<head>
<title>Hit testing of iframe</title>
</head>
Added: trunk/LayoutTests/fast/scrolling/mac/absolute-in-overflow-scroll-expected.txt (0 => 258044)
--- trunk/LayoutTests/fast/scrolling/mac/absolute-in-overflow-scroll-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/scrolling/mac/absolute-in-overflow-scroll-expected.txt 2020-03-07 01:45:55 UTC (rev 258044)
@@ -0,0 +1,12 @@
+
+Test scroll over content
+PASS overflowScrollEventCount > 0 is true
+PASS windowScrollEventCount == 0 is true
+
+Test scroll over absolute element
+PASS overflowScrollEventCount == 0 is true
+PASS windowScrollEventCount > 0 is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/scrolling/mac/absolute-in-overflow-scroll.html (0 => 258044)
--- trunk/LayoutTests/fast/scrolling/mac/absolute-in-overflow-scroll.html (rev 0)
+++ trunk/LayoutTests/fast/scrolling/mac/absolute-in-overflow-scroll.html 2020-03-07 01:45:55 UTC (rev 258044)
@@ -0,0 +1,113 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+ <style>
+ body {
+ height: 1000px;
+ }
+ .container {
+ position: absolute; /* Containing block for the inner absolute */
+ top: 10px;
+ left: 10px;
+ }
+ .scroller {
+ height: 300px;
+ width: 300px;
+ border: 20px solid gray;
+ padding: 5px;
+ overflow: scroll;
+ opacity: 0.8; /* Force stackingc context */
+ }
+ .content {
+ width: 200%;
+ height: 300%;
+ }
+
+ .absolute {
+ position: absolute;
+ top: 100px;
+ left: 50px;
+ height: 200px;
+ width: 200px;
+ background-color: gray;
+ }
+ </style>
+ <script src=""
+ <script src=""
+ <script>
+ var jsTestIsAsync = true;
+
+ var scroller;
+ var overflowScrollEventCount = 0;
+ var windowScrollEventCount = 0;
+
+ async function resetScrollPositions()
+ {
+ window.scrollTop = 0;
+ scroller.scrollTop = 0;
+
+ // Wait for scroll events to fire.
+ await UIHelper.animationFrame();
+
+ overflowScrollEventCount = 0;
+ windowScrollEventCount = 0;
+ }
+
+ async function testScrollOverContent()
+ {
+ debug('');
+ debug('Test scroll over content');
+ await resetScrollPositions();
+ await UIHelper.mouseWheelScrollAt(50, 50);
+
+ shouldBe('overflowScrollEventCount > 0', 'true');
+ shouldBe('windowScrollEventCount == 0', 'true');
+ }
+
+ async function testScrollOverAbsolute()
+ {
+ debug('');
+ debug('Test scroll over absolute element');
+ await resetScrollPositions();
+ await UIHelper.mouseWheelScrollAt(100, 150);
+
+ shouldBe('overflowScrollEventCount == 0', 'true');
+ shouldBe('windowScrollEventCount > 0', 'true');
+ }
+
+ async function scrollTest()
+ {
+ await testScrollOverContent();
+ await testScrollOverAbsolute();
+
+ finishJSTest();
+ }
+
+ window.addEventListener('load', () => {
+ scroller = document.querySelector('.scroller');
+ scroller.addEventListener('scroll', () => {
+ ++overflowScrollEventCount;
+ }, false);
+
+ window.addEventListener('scroll', () => {
+ ++windowScrollEventCount;
+ }, false);
+
+ setTimeout(scrollTest, 0);
+ }, false);
+
+ var successfullyParsed = true;
+ </script>
+</head>
+<body>
+ <div class="container">
+ <div class="scroller">
+ <div class="content">
+ <div class="absolute">
+ </div>
+ </div>
+ </div>
+ </div>
+ <script src=""
+</body>
+</html>
Added: trunk/LayoutTests/fast/scrolling/mac/async-scroll-overflow-expected.txt (0 => 258044)
--- trunk/LayoutTests/fast/scrolling/mac/async-scroll-overflow-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/scrolling/mac/async-scroll-overflow-expected.txt 2020-03-07 01:45:55 UTC (rev 258044)
@@ -0,0 +1,12 @@
+
+Test scroll over content
+PASS overflowScrollEventCount > 0 is true
+PASS windowScrollEventCount == 0 is true
+
+Test scroll over border
+PASS overflowScrollEventCount == 0 is true
+PASS windowScrollEventCount > 0 is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/scrolling/mac/async-scroll-overflow.html (0 => 258044)
--- trunk/LayoutTests/fast/scrolling/mac/async-scroll-overflow.html (rev 0)
+++ trunk/LayoutTests/fast/scrolling/mac/async-scroll-overflow.html 2020-03-07 01:45:55 UTC (rev 258044)
@@ -0,0 +1,98 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+ <style>
+ body {
+ height: 1000px;
+ }
+ .scroller {
+ position: absolute;
+ top: 10px;
+ left: 10px;
+ height: 300px;
+ width: 300px;
+ border: 20px solid gray;
+ padding: 5px;
+ overflow: scroll;
+ }
+ .content {
+ width: 200%;
+ height: 300%;
+ }
+
+ </style>
+ <script src=""
+ <script src=""
+ <script>
+ var jsTestIsAsync = true;
+
+ var scroller;
+ var overflowScrollEventCount = 0;
+ var windowScrollEventCount = 0;
+
+ async function resetScrollPositions()
+ {
+ window.scrollTop = 0;
+ scroller.scrollTop = 0;
+
+ // Wait for scroll events to fire.
+ await UIHelper.animationFrame();
+
+ overflowScrollEventCount = 0;
+ windowScrollEventCount = 0;
+ }
+
+ async function testScrollOverContent()
+ {
+ debug('');
+ debug('Test scroll over content');
+ await resetScrollPositions();
+ await UIHelper.mouseWheelScrollAt(100, 100);
+
+ shouldBe('overflowScrollEventCount > 0', 'true');
+ shouldBe('windowScrollEventCount == 0', 'true');
+ }
+
+ async function testScrollOverBorder()
+ {
+ debug('');
+ debug('Test scroll over border');
+ await resetScrollPositions();
+ await UIHelper.mouseWheelScrollAt(15, 15);
+
+ shouldBe('overflowScrollEventCount == 0', 'true');
+ shouldBe('windowScrollEventCount > 0', 'true');
+ }
+
+ async function scrollTest()
+ {
+ await testScrollOverContent();
+ await testScrollOverBorder();
+
+ finishJSTest();
+ }
+
+ window.addEventListener('load', () => {
+ scroller = document.querySelector('.scroller');
+ scroller.addEventListener('scroll', () => {
+ ++overflowScrollEventCount;
+ }, false);
+
+ window.addEventListener('scroll', () => {
+ ++windowScrollEventCount;
+ }, false);
+
+ setTimeout(scrollTest, 0);
+ }, false);
+
+ var successfullyParsed = true;
+ </script>
+</head>
+<body>
+ <div class="scroller">
+ <div class="content"></div>
+ </div>
+ <div class="overlapper"></div>
+ <script src=""
+</body>
+</html>
Added: trunk/LayoutTests/fast/scrolling/mac/move-node-in-overflow-scroll-expected.txt (0 => 258044)
--- trunk/LayoutTests/fast/scrolling/mac/move-node-in-overflow-scroll-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/scrolling/mac/move-node-in-overflow-scroll-expected.txt 2020-03-07 01:45:55 UTC (rev 258044)
@@ -0,0 +1,12 @@
+
+Test scroll over content
+PASS overflowScrollEventCount > 0 is true
+PASS windowScrollEventCount == 0 is true
+
+Test scroll over transformed element
+PASS overflowScrollEventCount > 0 is true
+PASS windowScrollEventCount == 0 is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/scrolling/mac/move-node-in-overflow-scroll.html (0 => 258044)
--- trunk/LayoutTests/fast/scrolling/mac/move-node-in-overflow-scroll.html (rev 0)
+++ trunk/LayoutTests/fast/scrolling/mac/move-node-in-overflow-scroll.html 2020-03-07 01:45:55 UTC (rev 258044)
@@ -0,0 +1,108 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+ <style>
+ body {
+ height: 1000px;
+ }
+ /* non-stacking context scroller */
+ .scroller {
+ position: absolute;
+ top: 10px;
+ left: 10px;
+ height: 300px;
+ width: 300px;
+ border: 20px solid gray;
+ padding: 5px;
+ overflow: scroll;
+ }
+ .content {
+ width: 200%;
+ height: 300%;
+ }
+
+ /* Stacking context is the root */
+ .transformed {
+ margin: 50px;
+ height: 200px;
+ width: 200px;
+ background-color: gray;
+ transform: translateZ(1px);
+ }
+ </style>
+ <script src=""
+ <script src=""
+ <script>
+ var jsTestIsAsync = true;
+
+ var scroller;
+ var overflowScrollEventCount = 0;
+ var windowScrollEventCount = 0;
+
+ async function resetScrollPositions()
+ {
+ window.scrollTop = 0;
+ scroller.scrollTop = 0;
+
+ // Wait for scroll events to fire.
+ await UIHelper.animationFrame();
+
+ overflowScrollEventCount = 0;
+ windowScrollEventCount = 0;
+ }
+
+ async function testScrollOverContent()
+ {
+ debug('');
+ debug('Test scroll over content');
+ await resetScrollPositions();
+ await UIHelper.mouseWheelScrollAt(50, 50);
+
+ shouldBe('overflowScrollEventCount > 0', 'true');
+ shouldBe('windowScrollEventCount == 0', 'true');
+ }
+
+ async function testScrollOverTransformed()
+ {
+ debug('');
+ debug('Test scroll over transformed element');
+ await resetScrollPositions();
+ await UIHelper.mouseWheelScrollAt(150, 150);
+
+ shouldBe('overflowScrollEventCount > 0', 'true');
+ shouldBe('windowScrollEventCount == 0', 'true');
+ }
+
+ async function scrollTest()
+ {
+ await testScrollOverContent();
+ await testScrollOverTransformed();
+
+ finishJSTest();
+ }
+
+ window.addEventListener('load', () => {
+ scroller = document.querySelector('.scroller');
+ scroller.addEventListener('scroll', () => {
+ ++overflowScrollEventCount;
+ }, false);
+
+ window.addEventListener('scroll', () => {
+ ++windowScrollEventCount;
+ }, false);
+
+ setTimeout(scrollTest, 0);
+ }, false);
+
+ var successfullyParsed = true;
+ </script>
+</head>
+<body>
+ <div class="scroller">
+ <div class="content">
+ <div class="transformed"></div>
+ </div>
+ </div>
+ <script src=""
+</body>
+</html>
Added: trunk/LayoutTests/fast/scrolling/mac/overlapped-overflow-scroll-expected.txt (0 => 258044)
--- trunk/LayoutTests/fast/scrolling/mac/overlapped-overflow-scroll-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/scrolling/mac/overlapped-overflow-scroll-expected.txt 2020-03-07 01:45:55 UTC (rev 258044)
@@ -0,0 +1,16 @@
+
+Test scroll over content
+PASS overflowScrollEventCount > 0 is true
+PASS windowScrollEventCount == 0 is true
+
+Test scroll over overlapping element
+PASS overflowScrollEventCount == 0 is true
+PASS windowScrollEventCount > 0 is true
+
+Test scroll over overlapping element outside border
+PASS overflowScrollEventCount > 0 is true
+PASS windowScrollEventCount == 0 is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/scrolling/mac/overlapped-overflow-scroll.html (0 => 258044)
--- trunk/LayoutTests/fast/scrolling/mac/overlapped-overflow-scroll.html (rev 0)
+++ trunk/LayoutTests/fast/scrolling/mac/overlapped-overflow-scroll.html 2020-03-07 01:45:55 UTC (rev 258044)
@@ -0,0 +1,121 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+ <style>
+ body {
+ height: 1000px;
+ }
+ .scroller {
+ position: absolute;
+ top: 10px;
+ left: 10px;
+ height: 300px;
+ width: 300px;
+ border: 20px solid gray;
+ padding: 5px;
+ overflow: scroll;
+ }
+ .content {
+ width: 200%;
+ height: 300%;
+ }
+
+ .overlapper {
+ position: absolute;
+ width: 300px;
+ height: 300px;
+ top: 200px;
+ left: 200px;
+ border-radius: 50%;
+ box-shadow: 0 0 20px black; /* Inflate layer size for testing */
+ background-color: rgba(0, 0, 128, 0.5);
+ }
+
+ </style>
+ <script src=""
+ <script src=""
+ <script>
+ var jsTestIsAsync = true;
+
+ var scroller;
+ var overflowScrollEventCount = 0;
+ var windowScrollEventCount = 0;
+
+ async function resetScrollPositions()
+ {
+ window.scrollTop = 0;
+ scroller.scrollTop = 0;
+
+ // Wait for scroll events to fire.
+ await UIHelper.animationFrame();
+
+ overflowScrollEventCount = 0;
+ windowScrollEventCount = 0;
+ }
+
+ async function testScrollOverContent()
+ {
+ debug('');
+ debug('Test scroll over content');
+ await resetScrollPositions();
+ await UIHelper.mouseWheelScrollAt(50, 50);
+
+ shouldBe('overflowScrollEventCount > 0', 'true');
+ shouldBe('windowScrollEventCount == 0', 'true');
+ }
+
+ async function testScrollOverOverlapper()
+ {
+ debug('');
+ debug('Test scroll over overlapping element');
+ await resetScrollPositions();
+ await UIHelper.mouseWheelScrollAt(300, 300);
+
+ shouldBe('overflowScrollEventCount == 0', 'true');
+ shouldBe('windowScrollEventCount > 0', 'true');
+ }
+
+ async function testScrollOverOverlapperOutsideRadius()
+ {
+ debug('');
+ debug('Test scroll over overlapping element outside border');
+ await resetScrollPositions();
+ await UIHelper.mouseWheelScrollAt(230, 230);
+
+ shouldBe('overflowScrollEventCount > 0', 'true');
+ shouldBe('windowScrollEventCount == 0', 'true');
+ }
+
+ async function scrollTest()
+ {
+ await testScrollOverContent();
+ await testScrollOverOverlapper();
+ await testScrollOverOverlapperOutsideRadius();
+
+ finishJSTest();
+ }
+
+ window.addEventListener('load', () => {
+ scroller = document.querySelector('.scroller');
+ scroller.addEventListener('scroll', () => {
+ ++overflowScrollEventCount;
+ }, false);
+
+ window.addEventListener('scroll', () => {
+ ++windowScrollEventCount;
+ }, false);
+
+ setTimeout(scrollTest, 0);
+ }, false);
+
+ var successfullyParsed = true;
+ </script>
+</head>
+<body>
+ <div class="scroller">
+ <div class="content"></div>
+ </div>
+ <div class="overlapper"></div>
+ <script src=""
+</body>
+</html>
Modified: trunk/LayoutTests/resources/ui-helper.js (258043 => 258044)
--- trunk/LayoutTests/resources/ui-helper.js 2020-03-07 01:44:56 UTC (rev 258043)
+++ trunk/LayoutTests/resources/ui-helper.js 2020-03-07 01:45:55 UTC (rev 258044)
@@ -28,7 +28,26 @@
eventSender.mouseMoveTo(x2, y2);
eventSender.mouseUp();
}
+
+ static async mouseWheelScrollAt(x, y)
+ {
+ eventSender.monitorWheelEvents();
+ eventSender.mouseMoveTo(x, y);
+ eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, "began", "none");
+ eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -10, "changed", "none");
+ eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, "ended", "none");
+ return new Promise(resolve => {
+ eventSender.callAfterScrollingCompletes(() => {
+ requestAnimationFrame(resolve);
+ });
+ });
+ }
+ static async animationFrame()
+ {
+ return new Promise(requestAnimationFrame);
+ }
+
static sendEventStream(eventStream)
{
const eventStreamAsString = JSON.stringify(eventStream);
Modified: trunk/Source/WebCore/ChangeLog (258043 => 258044)
--- trunk/Source/WebCore/ChangeLog 2020-03-07 01:44:56 UTC (rev 258043)
+++ trunk/Source/WebCore/ChangeLog 2020-03-07 01:45:55 UTC (rev 258044)
@@ -1,3 +1,44 @@
+2020-03-06 Simon Fraser <[email protected]>
+
+ Hit-test CALayers on the scrolling thread for async frame/overflow scrolling
+ https://bugs.webkit.org/show_bug.cgi?id=208740
+ <rdar://problem/48028836>
+
+ Reviewed by Tim Horton.
+
+ Implement hit-testing in the scrolling thread so we can determine which overflow/subframe
+ to scroll without hitting the main thread.
+
+ ScrollingTreeMac overrides scrollingNodeForPoint() and hit-tests through CALayers, starting at the
+ root content layer. Locking ensures that the CALayer tree doesn't change while we're hit-testing it.
+ We collect layers for the given point in back-to-front order much like the iOS code _web_findDescendantViewAtPoint
+ (too different to share though), and consult event regions on PlatformCALayerCocoa's to determine if the
+ point is inside the part of the layer that should receive events.
+
+ To handle the complex stacking/containing block cases, isScrolledBy() consults the scrolling tree.
+
+ For testing, fix it so that multiple calls to monitorWheelEvents() in a single test each start
+ with clean state.
+
+ Tests: fast/scrolling/mac/absolute-in-overflow-scroll.html
+ fast/scrolling/mac/async-scroll-overflow.html
+ fast/scrolling/mac/move-node-in-overflow-scroll.html
+ fast/scrolling/mac/overlapped-overflow-scroll.html
+
+ * page/scrolling/ScrollingTree.cpp:
+ (WebCore::ScrollingTree::handleWheelEvent):
+ (WebCore::ScrollingTree::scrollingNodeForPoint):
+ * page/scrolling/ScrollingTree.h:
+ * page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.h:
+ * page/scrolling/mac/ScrollingTreeMac.h:
+ * page/scrolling/mac/ScrollingTreeMac.mm:
+ (collectDescendantLayersAtPoint):
+ (scrollingNodeIDForLayer):
+ (isScrolledBy):
+ (ScrollingTreeMac::scrollingNodeForPoint):
+ * testing/js/WebCoreTestSupport.cpp:
+ (WebCoreTestSupport::monitorWheelEvents): Make sure that each call to eventSender.monitorWheelEvents() clears previous state.
+
2020-03-06 Jer Noble <[email protected]>
[GPUP] Convert CDMFactory away from platformStrategies() and use WebProcess settings instead
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp (258043 => 258044)
--- trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp 2020-03-07 01:44:56 UTC (rev 258043)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp 2020-03-07 01:45:55 UTC (rev 258044)
@@ -111,7 +111,7 @@
if (m_rootNode) {
FloatPoint position = wheelEvent.position();
- ScrollingTreeNode* node = scrollingNodeForPoint(position);
+ auto node = scrollingNodeForPoint(position);
LOG_WITH_STREAM(Scrolling, stream << "ScrollingTree::handleWheelEvent found node " << (node ? node->scrollingNodeID() : 0) << " for point " << position << "\n");
@@ -128,10 +128,10 @@
return ScrollingEventResult::DidNotHandleEvent;
}
-ScrollingTreeNode* ScrollingTree::scrollingNodeForPoint(FloatPoint)
+RefPtr<ScrollingTreeNode> ScrollingTree::scrollingNodeForPoint(FloatPoint)
{
ASSERT(asyncFrameOrOverflowScrollingEnabled());
- return m_rootNode.get();
+ return m_rootNode;
}
void ScrollingTree::mainFrameViewportChangedViaDelegatedScrolling(const FloatPoint& scrollPosition, const FloatRect& layoutViewport, double)
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.h (258043 => 258044)
--- trunk/Source/WebCore/page/scrolling/ScrollingTree.h 2020-03-07 01:44:56 UTC (rev 258043)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.h 2020-03-07 01:45:55 UTC (rev 258044)
@@ -177,7 +177,7 @@
void notifyRelatedNodesRecursive(ScrollingTreeNode&);
- ScrollingTreeNode* scrollingNodeForPoint(FloatPoint);
+ WEBCORE_EXPORT virtual RefPtr<ScrollingTreeNode> scrollingNodeForPoint(FloatPoint);
Lock m_treeMutex; // Protects the scrolling tree.
Modified: trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.h (258043 => 258044)
--- trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.h 2020-03-07 01:44:56 UTC (rev 258043)
+++ trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.h 2020-03-07 01:45:55 UTC (rev 258044)
@@ -42,6 +42,8 @@
static Ref<ScrollingTreeFrameScrollingNode> create(ScrollingTree&, ScrollingNodeType, ScrollingNodeID);
virtual ~ScrollingTreeFrameScrollingNodeMac();
+ RetainPtr<CALayer> rootContentsLayer() const { return m_rootContentsLayer; }
+
protected:
ScrollingTreeFrameScrollingNodeMac(ScrollingTree&, ScrollingNodeType, ScrollingNodeID);
Modified: trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeMac.h (258043 => 258044)
--- trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeMac.h 2020-03-07 01:44:56 UTC (rev 258043)
+++ trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeMac.h 2020-03-07 01:45:55 UTC (rev 258044)
@@ -40,6 +40,8 @@
Ref<ScrollingTreeNode> createScrollingTreeNode(ScrollingNodeType, ScrollingNodeID) final;
+ RefPtr<ScrollingTreeNode> scrollingNodeForPoint(FloatPoint) final;
+
void lockLayersForHitTesting() final;
void unlockLayersForHitTesting() final;
Modified: trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeMac.mm (258043 => 258044)
--- trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeMac.mm 2020-03-07 01:44:56 UTC (rev 258043)
+++ trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeMac.mm 2020-03-07 01:45:55 UTC (rev 258044)
@@ -26,6 +26,7 @@
#include "config.h"
#include "ScrollingTreeMac.h"
+#include "PlatformCALayer.h"
#include "ScrollingTreeFixedNode.h"
#include "ScrollingTreeFrameHostingNode.h"
#include "ScrollingTreeFrameScrollingNodeMac.h"
@@ -33,6 +34,7 @@
#include "ScrollingTreeOverflowScrollingNodeMac.h"
#include "ScrollingTreePositionedNode.h"
#include "ScrollingTreeStickyNode.h"
+#include "WebLayer.h"
#if ENABLE(ASYNC_SCROLLING) && ENABLE(SCROLLING_THREAD)
@@ -71,6 +73,111 @@
return ScrollingTreeFixedNode::create(*this, nodeID);
}
+
+static void collectDescendantLayersAtPoint(Vector<CALayer *, 16>& layersAtPoint, CALayer *parent, CGPoint point)
+{
+ if (parent.masksToBounds && ![parent containsPoint:point])
+ return;
+
+ for (CALayer *layer in [parent sublayers]) {
+ CALayer *layerWithResolvedAnimations = layer;
+
+ if ([[layer animationKeys] count])
+ layerWithResolvedAnimations = [layer presentationLayer];
+
+ CGPoint subviewPoint = [layerWithResolvedAnimations convertPoint:point fromLayer:parent];
+
+ auto handlesEvent = [&] {
+ if (CGRectIsEmpty([layerWithResolvedAnimations frame]))
+ return false;
+
+ if (![layerWithResolvedAnimations containsPoint:subviewPoint])
+ return false;
+
+ auto platformCALayer = PlatformCALayer::platformCALayerForLayer((__bridge void*)layer);
+ if (platformCALayer) {
+ // Scrolling changes boundsOrigin on the scroll container layer, but we computed its event region ignoring scroll position, so factor out bounds origin.
+ FloatPoint boundsOrigin = layer.bounds.origin;
+ FloatPoint localPoint = subviewPoint - toFloatSize(boundsOrigin);
+ return platformCALayer->eventRegionContainsPoint(IntPoint(localPoint));
+ }
+
+ return false;
+ }();
+
+ if (handlesEvent)
+ layersAtPoint.append(layer);
+
+ if ([layer sublayers])
+ collectDescendantLayersAtPoint(layersAtPoint, layer, subviewPoint);
+ };
+}
+
+static ScrollingNodeID scrollingNodeIDForLayer(CALayer *layer)
+{
+ auto platformCALayer = PlatformCALayer::platformCALayerForLayer((__bridge void*)layer);
+ return platformCALayer ? platformCALayer->scrollingNodeID() : 0;
+}
+
+static bool isScrolledBy(const ScrollingTree& tree, ScrollingNodeID scrollingNodeID, CALayer *hitLayer)
+{
+ for (CALayer *layer = hitLayer; layer; layer = [layer superlayer]) {
+ auto nodeID = scrollingNodeIDForLayer(layer);
+ if (nodeID == scrollingNodeID)
+ return true;
+
+ auto* scrollingNode = tree.nodeForID(nodeID);
+ if (is<ScrollingTreeOverflowScrollProxyNode>(scrollingNode)) {
+ ScrollingNodeID actingOverflowScrollingNodeID = downcast<ScrollingTreeOverflowScrollProxyNode>(*scrollingNode).overflowScrollingNodeID();
+ if (actingOverflowScrollingNodeID == scrollingNodeID)
+ return true;
+ }
+
+ if (is<ScrollingTreePositionedNode>(scrollingNode)) {
+ if (downcast<ScrollingTreePositionedNode>(*scrollingNode).relatedOverflowScrollingNodes().contains(scrollingNodeID))
+ return false;
+ }
+ }
+
+ return false;
+}
+
+RefPtr<ScrollingTreeNode> ScrollingTreeMac::scrollingNodeForPoint(FloatPoint point)
+{
+ auto* rootScrollingNode = rootNode();
+ if (!rootScrollingNode)
+ return nullptr;
+
+ LockHolder lockHolder(m_layerHitTestMutex);
+
+ auto rootContentsLayer = static_cast<ScrollingTreeFrameScrollingNodeMac*>(rootScrollingNode)->rootContentsLayer();
+
+ Vector<CALayer *, 16> layersAtPoint;
+ collectDescendantLayersAtPoint(layersAtPoint, rootContentsLayer.get(), point);
+
+ LOG_WITH_STREAM(Scrolling, stream << "ScrollingTreeMac " << this << " scrollingNodeForPoint " << point << " found " << layersAtPoint.size() << " layers");
+#if !LOG_DISABLED
+ for (auto *layer : WTF::makeReversedRange(layersAtPoint))
+ LOG_WITH_STREAM(Scrolling, stream << " layer " << [layer description] << " scrolling node " << scrollingNodeIDForLayer(layer));
+#endif
+
+ for (auto *layer : WTF::makeReversedRange(layersAtPoint)) {
+ auto nodeID = scrollingNodeIDForLayer(layer);
+
+ auto* scrollingNode = nodeForID(nodeID);
+ if (!is<ScrollingTreeScrollingNode>(scrollingNode))
+ continue;
+
+ if (isScrolledBy(*this, nodeID, layersAtPoint.last()))
+ return scrollingNode;
+
+ // FIXME: Hit-test scroll indicator layers.
+ }
+
+ LOG_WITH_STREAM(Scrolling, stream << "ScrollingTreeMac " << this << " scrollingNodeForPoint " << point << " found no scrollable layers; using root node");
+ return rootScrollingNode;
+}
+
void ScrollingTreeMac::lockLayersForHitTesting()
{
m_layerHitTestMutex.lock();
Modified: trunk/Source/WebCore/testing/js/WebCoreTestSupport.cpp (258043 => 258044)
--- trunk/Source/WebCore/testing/js/WebCoreTestSupport.cpp 2020-03-07 01:44:56 UTC (rev 258043)
+++ trunk/Source/WebCore/testing/js/WebCoreTestSupport.cpp 2020-03-07 01:45:55 UTC (rev 258044)
@@ -85,7 +85,7 @@
if (!page)
return;
- page->ensureWheelEventTestMonitor();
+ page->ensureWheelEventTestMonitor().clearAllTestDeferrals();
}
void setTestCallbackAndStartNotificationTimer(WebCore::Frame& frame, JSContextRef context, JSObjectRef jsCallbackFunction)
Modified: trunk/Source/WebKit/ChangeLog (258043 => 258044)
--- trunk/Source/WebKit/ChangeLog 2020-03-07 01:44:56 UTC (rev 258043)
+++ trunk/Source/WebKit/ChangeLog 2020-03-07 01:45:55 UTC (rev 258044)
@@ -1,3 +1,16 @@
+2020-03-06 Simon Fraser <[email protected]>
+
+ Hit-test CALayers on the scrolling thread for async frame/overflow scrolling
+ https://bugs.webkit.org/show_bug.cgi?id=208740
+ <rdar://problem/48028836>
+
+ Reviewed by Tim Horton.
+
+ Make sure that each call to eventSender.monitorWheelEvents() clears previous state.
+
+ * WebProcess/InjectedBundle/API/c/WKBundlePage.cpp:
+ (WKBundlePageStartMonitoringScrollOperations):
+
2020-03-06 Brady Eidson <[email protected]>
Some PDFPlugin cleanup in prep for incremental loading.
Modified: trunk/Source/WebKit/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp (258043 => 258044)
--- trunk/Source/WebKit/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp 2020-03-07 01:44:56 UTC (rev 258043)
+++ trunk/Source/WebKit/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp 2020-03-07 01:45:55 UTC (rev 258044)
@@ -701,7 +701,7 @@
if (!page)
return;
- page->ensureWheelEventTestMonitor();
+ page->ensureWheelEventTestMonitor().clearAllTestDeferrals();
}
bool WKBundlePageRegisterScrollOperationCompletionCallback(WKBundlePageRef pageRef, WKBundlePageTestNotificationCallback callback, void* context)