Diff
Modified: trunk/LayoutTests/ChangeLog (245817 => 245818)
--- trunk/LayoutTests/ChangeLog 2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/LayoutTests/ChangeLog 2019-05-28 18:11:52 UTC (rev 245818)
@@ -1,3 +1,15 @@
+2019-05-28 Antti Koivisto <[email protected]>
+
+ [async scrolling] Fixed positioning inside stacking context overflow scroll is jumpy
+ https://bugs.webkit.org/show_bug.cgi?id=198292
+
+ Reviewed by Darin Adler.
+
+ * scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll-2-expected.html: Added.
+ * scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll-2.html: Added.
+ * scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll-expected.html: Added.
+ * scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll.html: Added.
+
2019-05-27 Takashi Komori <[email protected]>
[CURL] Fix crashing SocketStreamHandle.
Added: trunk/LayoutTests/scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll-2-expected.html (0 => 245818)
--- trunk/LayoutTests/scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll-2-expected.html (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll-2-expected.html 2019-05-28 18:11:52 UTC (rev 245818)
@@ -0,0 +1,56 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true internal:AsyncOverflowScrollingEnabled=true internal:AsyncFrameScrollingEnabled=true ] -->
+<html>
+<head>
+ <meta name="viewport" content="initial-scale=1.0">
+ <style>
+ #scroller {
+ left: 100px;
+ margin: 10px;
+ height: 300px;
+ width: 300px;
+ border: 1px solid black;
+ overflow: scroll;
+ z-index: 0;
+ position: relative;
+ }
+
+ .box {
+ position: fixed;
+ margin-top: 200px;
+ width: 200px;
+ height: 200px;
+ background-color: green;
+ }
+
+ .spacer {
+ border: 2px solid blue;
+ height: 5000px;
+ }
+ </style>
+ <script src=""
+ <script>
+ if (window.testRunner)
+ testRunner.waitUntilDone();
+
+ async function doTest()
+ {
+ await UIHelper.ensurePresentationUpdate(); // Not sure why this is necessary, but it is.
+ window.scrollTo(0, 50);
+ await UIHelper.ensurePresentationUpdate();
+
+ if (window.testRunner)
+ testRunner.notifyDone();
+ }
+
+ window.addEventListener('load', doTest, false);
+ </script>
+</head>
+<body>
+ <div class="spacer">
+ <div id="scroller">
+ <div class="box"></div>
+ <div class="spacer"></div>
+ </div>
+ </div>
+</body>
+</html>
Added: trunk/LayoutTests/scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll-2.html (0 => 245818)
--- trunk/LayoutTests/scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll-2.html (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll-2.html 2019-05-28 18:11:52 UTC (rev 245818)
@@ -0,0 +1,59 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true internal:AsyncOverflowScrollingEnabled=true internal:AsyncFrameScrollingEnabled=true ] -->
+<html>
+<head>
+ <meta name="viewport" content="initial-scale=1.0">
+ <style>
+ .scroller {
+ left: 100px;
+ margin: 10px;
+ height: 300px;
+ width: 300px;
+ border: 1px solid black;
+ overflow: scroll;
+ z-index: 0;
+ position: relative;
+ }
+
+ .box {
+ position: fixed;
+ margin-top: 200px;
+ width: 200px;
+ height: 200px;
+ background-color: green;
+ }
+
+ .spacer {
+ border: 2px solid blue;
+ height: 5000px;
+ }
+ </style>
+ <script src=""
+ <script>
+ if (window.testRunner)
+ testRunner.waitUntilDone();
+
+ async function doTest()
+ {
+ if (!window.testRunner)
+ return;
+
+ if (!testRunner.runUIScript)
+ return;
+
+ const scrollUpdatesDisabled = true;
+ await UIHelper.immediateScrollElementAtContentPointToOffset(50, 50, 0, 50, scrollUpdatesDisabled);
+ testRunner.notifyDone();
+ }
+
+ window.addEventListener('load', doTest, false);
+ </script>
+</head>
+<body>
+ <div class="spacer">
+ <div class="scroller">
+ <div class="box"></div>
+ <div class="spacer"></div>
+ </div>
+ </div>
+</body>
+</html>
Added: trunk/LayoutTests/scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll-expected.html (0 => 245818)
--- trunk/LayoutTests/scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll-expected.html (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll-expected.html 2019-05-28 18:11:52 UTC (rev 245818)
@@ -0,0 +1,55 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true internal:AsyncOverflowScrollingEnabled=true internal:AsyncFrameScrollingEnabled=true ] -->
+<html>
+<head>
+ <meta name="viewport" content="initial-scale=1.0">
+ <style>
+ #scroller {
+ margin: 10px;
+ height: 300px;
+ width: 300px;
+ border: 1px solid black;
+ overflow: scroll;
+ z-index: 0;
+ position: relative;
+ }
+
+ .box {
+ position: fixed;
+ margin-top: 200px;
+ width: 200px;
+ height: 200px;
+ background-color: green;
+ }
+
+ .spacer {
+ border: 2px solid blue;
+ height: 5000px;
+ }
+ </style>
+ <script src=""
+ <script>
+ if (window.testRunner)
+ testRunner.waitUntilDone();
+
+ async function doTest()
+ {
+ await UIHelper.ensurePresentationUpdate(); // Not sure why this is necessary, but it is.
+ scroller.scrollTo(0, 200);
+ await UIHelper.ensurePresentationUpdate();
+
+ if (window.testRunner)
+ testRunner.notifyDone();
+ }
+
+ window.addEventListener('load', doTest, false);
+ </script>
+</head>
+<body>
+ <div class="spacer">
+ <div id="scroller">
+ <div class="box"></div>
+ <div class="spacer"></div>
+ </div>
+ </div>
+</body>
+</html>
Added: trunk/LayoutTests/scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll.html (0 => 245818)
--- trunk/LayoutTests/scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll.html (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll.html 2019-05-28 18:11:52 UTC (rev 245818)
@@ -0,0 +1,58 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true internal:AsyncOverflowScrollingEnabled=true internal:AsyncFrameScrollingEnabled=true ] -->
+<html>
+<head>
+ <meta name="viewport" content="initial-scale=1.0">
+ <style>
+ .scroller {
+ margin: 10px;
+ height: 300px;
+ width: 300px;
+ border: 1px solid black;
+ overflow: scroll;
+ z-index: 0;
+ position: relative;
+ }
+
+ .box {
+ position: fixed;
+ margin-top: 200px;
+ width: 200px;
+ height: 200px;
+ background-color: green;
+ }
+
+ .spacer {
+ border: 2px solid blue;
+ height: 5000px;
+ }
+ </style>
+ <script src=""
+ <script>
+ if (window.testRunner)
+ testRunner.waitUntilDone();
+
+ async function doTest()
+ {
+ if (!window.testRunner)
+ return;
+
+ if (!testRunner.runUIScript)
+ return;
+
+ const scrollUpdatesDisabled = true;
+ await UIHelper.immediateScrollElementAtContentPointToOffset(50, 50, 0, 200, scrollUpdatesDisabled);
+ testRunner.notifyDone();
+ }
+
+ window.addEventListener('load', doTest, false);
+ </script>
+</head>
+<body>
+ <div class="spacer">
+ <div class="scroller">
+ <div class="box"></div>
+ <div class="spacer"></div>
+ </div>
+ </div>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (245817 => 245818)
--- trunk/Source/WebCore/ChangeLog 2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/ChangeLog 2019-05-28 18:11:52 UTC (rev 245818)
@@ -1,3 +1,54 @@
+2019-05-28 Antti Koivisto <[email protected]>
+
+ [async scrolling] Fixed positioning inside stacking context overflow scroll is jumpy
+ https://bugs.webkit.org/show_bug.cgi?id=198292
+
+ Reviewed by Darin Adler.
+
+ Tests: scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll-2.html
+ scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll.html
+
+ We were computing delta from the layout scroll position in ScrollingTree::notifyRelatedNodesAfterScrollPositionChange
+ based on the passed in node only. If any other node had deltas they were not taken into account at all. This would occur
+ frequently since the function is always invoked for the root node after layer tree commit.
+
+ Fix by moving the delta computation (and fetching layoutViewport) to ScrollingTreeFixedNode.
+
+ * page/scrolling/ScrollingTree.cpp:
+ (WebCore::ScrollingTree::applyLayerPositions):
+
+ No need to pass offset and layoutViewport around anymore.
+
+ (WebCore::ScrollingTree::applyLayerPositionsRecursive):
+ (WebCore::ScrollingTree::notifyRelatedNodesAfterScrollPositionChange):
+
+ Remove the offset and layoutViewport computations.
+
+ (WebCore::ScrollingTree::notifyRelatedNodesRecursive):
+ * page/scrolling/ScrollingTree.h:
+ * page/scrolling/ScrollingTreeFrameHostingNode.cpp:
+ (WebCore::ScrollingTreeFrameHostingNode::applyLayerPositions):
+ * page/scrolling/ScrollingTreeFrameHostingNode.h:
+ * page/scrolling/ScrollingTreeNode.cpp:
+ (WebCore::ScrollingTreeNode::relatedNodeScrollPositionDidChange):
+ * page/scrolling/ScrollingTreeNode.h:
+ * page/scrolling/ScrollingTreeScrollingNode.cpp:
+ (WebCore::ScrollingTreeScrollingNode::applyLayerPositions):
+ * page/scrolling/ScrollingTreeScrollingNode.h:
+ * page/scrolling/cocoa/ScrollingTreeFixedNode.h:
+ * page/scrolling/cocoa/ScrollingTreeFixedNode.mm:
+ (WebCore::ScrollingTreeFixedNode::applyLayerPositions):
+
+ Compute them here instead, always taking all overflow scrollers up to the closest frame into account.
+
+ * page/scrolling/cocoa/ScrollingTreePositionedNode.h:
+ * page/scrolling/cocoa/ScrollingTreePositionedNode.mm:
+ (WebCore::ScrollingTreePositionedNode::applyLayerPositions):
+ (WebCore::ScrollingTreePositionedNode::relatedNodeScrollPositionDidChange):
+ * page/scrolling/cocoa/ScrollingTreeStickyNode.h:
+ * page/scrolling/cocoa/ScrollingTreeStickyNode.mm:
+ (WebCore::ScrollingTreeStickyNode::applyLayerPositions):
+
2019-05-28 Zalan Bujtas <[email protected]>
[LFC][Verification] Add additional inline and block checks
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp (245817 => 245818)
--- trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp 2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp 2019-05-28 18:11:52 UTC (rev 245818)
@@ -264,23 +264,18 @@
LOG(Scrolling, "\nScrollingTree %p applyLayerPositions", this);
- applyLayerPositionsRecursive(*m_rootNode, { }, { });
+ applyLayerPositionsRecursive(*m_rootNode);
LOG(Scrolling, "ScrollingTree %p applyLayerPositions - done\n", this);
}
-void ScrollingTree::applyLayerPositionsRecursive(ScrollingTreeNode& currNode, FloatRect layoutViewport, FloatSize cumulativeDelta)
+void ScrollingTree::applyLayerPositionsRecursive(ScrollingTreeNode& currNode)
{
- if (is<ScrollingTreeFrameScrollingNode>(currNode)) {
- layoutViewport = downcast<ScrollingTreeFrameScrollingNode>(currNode).layoutViewport();
- cumulativeDelta = { };
- }
+ currNode.applyLayerPositions();
- currNode.applyLayerPositions(layoutViewport, cumulativeDelta);
-
if (auto children = currNode.children()) {
for (auto& child : *children)
- applyLayerPositionsRecursive(*child, layoutViewport, cumulativeDelta);
+ applyLayerPositionsRecursive(*child);
}
}
@@ -296,41 +291,31 @@
{
Vector<ScrollingNodeID> additionalUpdateRoots;
- FloatSize deltaFromLastCommittedScrollPosition;
- FloatRect currentFrameLayoutViewport;
- if (is<ScrollingTreeFrameScrollingNode>(changedNode))
- currentFrameLayoutViewport = downcast<ScrollingTreeFrameScrollingNode>(changedNode).layoutViewport();
- else if (is<ScrollingTreeOverflowScrollingNode>(changedNode)) {
- deltaFromLastCommittedScrollPosition = changedNode.lastCommittedScrollPosition() - changedNode.currentScrollPosition();
-
- if (auto* frameScrollingNode = changedNode.enclosingFrameNodeIncludingSelf())
- currentFrameLayoutViewport = frameScrollingNode->layoutViewport();
-
+ if (is<ScrollingTreeOverflowScrollingNode>(changedNode))
additionalUpdateRoots = overflowRelatedNodes().get(changedNode.scrollingNodeID());
- }
- notifyRelatedNodesRecursive(changedNode, changedNode, currentFrameLayoutViewport, deltaFromLastCommittedScrollPosition);
+ notifyRelatedNodesRecursive(changedNode, changedNode);
for (auto positionedNodeID : additionalUpdateRoots) {
auto* positionedNode = nodeForID(positionedNodeID);
if (positionedNode)
- notifyRelatedNodesRecursive(changedNode, *positionedNode, currentFrameLayoutViewport, deltaFromLastCommittedScrollPosition);
+ notifyRelatedNodesRecursive(changedNode, *positionedNode);
}
}
-void ScrollingTree::notifyRelatedNodesRecursive(ScrollingTreeScrollingNode& changedNode, ScrollingTreeNode& currNode, const FloatRect& layoutViewport, FloatSize cumulativeDelta)
+void ScrollingTree::notifyRelatedNodesRecursive(ScrollingTreeScrollingNode& changedNode, ScrollingTreeNode& currNode)
{
- currNode.relatedNodeScrollPositionDidChange(changedNode, layoutViewport, cumulativeDelta);
+ currNode.relatedNodeScrollPositionDidChange(changedNode);
if (!currNode.children())
return;
-
+
for (auto& child : *currNode.children()) {
// Never need to cross frame boundaries, since scroll layer adjustments are isolated to each document.
if (is<ScrollingTreeFrameScrollingNode>(child))
continue;
- notifyRelatedNodesRecursive(changedNode, *child, layoutViewport, cumulativeDelta);
+ notifyRelatedNodesRecursive(changedNode, *child);
}
}
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.h (245817 => 245818)
--- trunk/Source/WebCore/page/scrolling/ScrollingTree.h 2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.h 2019-05-28 18:11:52 UTC (rev 245818)
@@ -165,9 +165,9 @@
using OrphanScrollingNodeMap = HashMap<ScrollingNodeID, RefPtr<ScrollingTreeNode>>;
void updateTreeFromStateNode(const ScrollingStateNode*, OrphanScrollingNodeMap&, HashSet<ScrollingNodeID>& unvisitedNodes);
- void applyLayerPositionsRecursive(ScrollingTreeNode&, FloatRect layoutViewport, FloatSize cumulativeDelta);
+ void applyLayerPositionsRecursive(ScrollingTreeNode&);
- void notifyRelatedNodesRecursive(ScrollingTreeScrollingNode& changedNode, ScrollingTreeNode& currNode, const FloatRect& layoutViewport, FloatSize cumulativeDelta);
+ void notifyRelatedNodesRecursive(ScrollingTreeScrollingNode& changedNode, ScrollingTreeNode& currNode);
Lock m_treeMutex; // Protects the scrolling tree.
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeFrameHostingNode.cpp (245817 => 245818)
--- trunk/Source/WebCore/page/scrolling/ScrollingTreeFrameHostingNode.cpp 2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeFrameHostingNode.cpp 2019-05-28 18:11:52 UTC (rev 245818)
@@ -57,7 +57,7 @@
m_parentRelativeScrollableRect = frameHostingStateNode.parentRelativeScrollableRect();
}
-void ScrollingTreeFrameHostingNode::applyLayerPositions(const FloatRect&, FloatSize&)
+void ScrollingTreeFrameHostingNode::applyLayerPositions()
{
}
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeFrameHostingNode.h (245817 => 245818)
--- trunk/Source/WebCore/page/scrolling/ScrollingTreeFrameHostingNode.h 2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeFrameHostingNode.h 2019-05-28 18:11:52 UTC (rev 245818)
@@ -42,7 +42,7 @@
ScrollingTreeFrameHostingNode(ScrollingTree&, ScrollingNodeID);
void commitStateBeforeChildren(const ScrollingStateNode&) final;
- void applyLayerPositions(const FloatRect&, FloatSize&) final;
+ void applyLayerPositions() final;
const LayoutRect& parentRelativeScrollableRect() const { return m_parentRelativeScrollableRect; }
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeNode.cpp (245817 => 245818)
--- trunk/Source/WebCore/page/scrolling/ScrollingTreeNode.cpp 2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeNode.cpp 2019-05-28 18:11:52 UTC (rev 245818)
@@ -77,9 +77,9 @@
return m_scrollingTree.rootNode() == this;
}
-void ScrollingTreeNode::relatedNodeScrollPositionDidChange(const ScrollingTreeScrollingNode&, const FloatRect& layoutViewport, FloatSize& cumulativeDelta)
+void ScrollingTreeNode::relatedNodeScrollPositionDidChange(const ScrollingTreeScrollingNode&)
{
- applyLayerPositions(layoutViewport, cumulativeDelta);
+ applyLayerPositions();
}
void ScrollingTreeNode::dumpProperties(TextStream& ts, ScrollingStateTreeAsTextBehavior behavior) const
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeNode.h (245817 => 245818)
--- trunk/Source/WebCore/page/scrolling/ScrollingTreeNode.h 2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeNode.h 2019-05-28 18:11:52 UTC (rev 245818)
@@ -84,9 +84,9 @@
ScrollingTreeNode(ScrollingTree&, ScrollingNodeType, ScrollingNodeID);
ScrollingTree& scrollingTree() const { return m_scrollingTree; }
- WEBCORE_EXPORT virtual void relatedNodeScrollPositionDidChange(const ScrollingTreeScrollingNode& changedNode, const FloatRect& layoutViewport, FloatSize& cumulativeDelta);
+ WEBCORE_EXPORT virtual void relatedNodeScrollPositionDidChange(const ScrollingTreeScrollingNode& changedNode);
- virtual void applyLayerPositions(const FloatRect& layoutViewport, FloatSize& cumulativeDelta) = 0;
+ virtual void applyLayerPositions() = 0;
WEBCORE_EXPORT virtual void dumpProperties(WTF::TextStream&, ScrollingStateTreeAsTextBehavior) const;
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp (245817 => 245818)
--- trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp 2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp 2019-05-28 18:11:52 UTC (rev 245818)
@@ -188,7 +188,7 @@
return position == m_currentScrollPosition;
}
-void ScrollingTreeScrollingNode::applyLayerPositions(const FloatRect&, FloatSize&)
+void ScrollingTreeScrollingNode::applyLayerPositions()
{
repositionScrollingLayers();
repositionRelatedLayers();
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h (245817 => 245818)
--- trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h 2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h 2019-05-28 18:11:52 UTC (rev 245818)
@@ -107,7 +107,7 @@
virtual void repositionScrollingLayers() { }
virtual void repositionRelatedLayers() { }
- void applyLayerPositions(const FloatRect& layoutViewport, FloatSize& cumulativeDelta) override;
+ void applyLayerPositions() override;
const FloatSize& reachableContentsSize() const { return m_reachableContentsSize; }
const LayoutRect& parentRelativeScrollableRect() const { return m_parentRelativeScrollableRect; }
Modified: trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeFixedNode.h (245817 => 245818)
--- trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeFixedNode.h 2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeFixedNode.h 2019-05-28 18:11:52 UTC (rev 245818)
@@ -47,7 +47,7 @@
ScrollingTreeFixedNode(ScrollingTree&, ScrollingNodeID);
void commitStateBeforeChildren(const ScrollingStateNode&) override;
- void applyLayerPositions(const FloatRect&, FloatSize&) override;
+ void applyLayerPositions() override;
void dumpProperties(WTF::TextStream&, ScrollingStateTreeAsTextBehavior) const override;
Modified: trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeFixedNode.mm (245817 => 245818)
--- trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeFixedNode.mm 2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeFixedNode.mm 2019-05-28 18:11:52 UTC (rev 245818)
@@ -31,6 +31,8 @@
#import "Logging.h"
#import "ScrollingStateFixedNode.h"
#import "ScrollingTree.h"
+#import "ScrollingTreeFrameScrollingNode.h"
+#import "ScrollingTreeOverflowScrollingNode.h"
#import "WebCoreCALayerExtras.h"
#import <wtf/text/TextStream.h>
@@ -63,16 +65,36 @@
m_constraints = fixedStateNode.viewportConstraints();
}
-void ScrollingTreeFixedNode::applyLayerPositions(const FloatRect& layoutViewport, FloatSize& cumulativeDelta)
+void ScrollingTreeFixedNode::applyLayerPositions()
{
- FloatPoint layerPosition = m_constraints.layerPositionForViewportRect(layoutViewport);
+ auto computeLayerPosition = [&] {
+ FloatSize overflowScrollDelta;
+ // FIXME: This code is wrong in complex cases where the fixed element is inside a positioned node as
+ // the scroll container order does not match the scrolling tree ancestor order.
+ for (auto* node = parent(); node; node = node->parent()) {
+ if (is<ScrollingTreeFrameScrollingNode>(*node)) {
+ // Fixed nodes are positioned relative to the containing frame scrolling node.
+ // We bail out after finding one.
+ auto layoutViewport = downcast<ScrollingTreeFrameScrollingNode>(*node).layoutViewport();
+ return m_constraints.layerPositionForViewportRect(layoutViewport) - overflowScrollDelta;
+ }
- LOG_WITH_STREAM(Scrolling, stream << "ScrollingTreeFixedNode " << scrollingNodeID() << " relatedNodeScrollPositionDidChange: new viewport " << layoutViewport << " viewportRectAtLastLayout " << m_constraints.viewportRectAtLastLayout() << " last layer pos " << m_constraints.layerPositionAtLastLayout() << " new offset from top " << (layoutViewport.y() - layerPosition.y()));
+ if (is<ScrollingTreeOverflowScrollingNode>(*node)) {
+ // To keep the layer still during async scrolling we adjust by how much the position has changed since layout.
+ auto& overflowNode = downcast<ScrollingTreeOverflowScrollingNode>(*node);
+ auto localDelta = overflowNode.lastCommittedScrollPosition() - overflowNode.currentScrollPosition();
+ overflowScrollDelta += localDelta;
+ }
+ }
+ ASSERT_NOT_REACHED();
+ return FloatPoint();
+ };
- layerPosition -= cumulativeDelta;
+ auto layerPosition = computeLayerPosition();
+ LOG_WITH_STREAM(Scrolling, stream << "ScrollingTreeFixedNode " << scrollingNodeID() << " relatedNodeScrollPositionDidChange: viewportRectAtLastLayout " << m_constraints.viewportRectAtLastLayout() << " last layer pos " << m_constraints.layerPositionAtLastLayout() << " layerPosition " << layerPosition);
+
[m_layer _web_setLayerTopLeftPosition:layerPosition - m_constraints.alignmentOffset()];
- cumulativeDelta += layerPosition - m_constraints.layerPositionAtLastLayout();
}
void ScrollingTreeFixedNode::dumpProperties(TextStream& ts, ScrollingStateTreeAsTextBehavior behavior) const
Modified: trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreePositionedNode.h (245817 => 245818)
--- trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreePositionedNode.h 2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreePositionedNode.h 2019-05-28 18:11:52 UTC (rev 245818)
@@ -50,9 +50,9 @@
ScrollingTreePositionedNode(ScrollingTree&, ScrollingNodeID);
void commitStateBeforeChildren(const ScrollingStateNode&) override;
- void relatedNodeScrollPositionDidChange(const ScrollingTreeScrollingNode& changedNode, const FloatRect& layoutViewport, FloatSize& cumulativeDelta) override;
+ void relatedNodeScrollPositionDidChange(const ScrollingTreeScrollingNode& changedNode) override;
- void applyLayerPositions(const FloatRect& layoutViewport, FloatSize& cumulativeDelta) override;
+ void applyLayerPositions() override;
WEBCORE_EXPORT void dumpProperties(WTF::TextStream&, ScrollingStateTreeAsTextBehavior) const override;
Modified: trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreePositionedNode.mm (245817 => 245818)
--- trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreePositionedNode.mm 2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreePositionedNode.mm 2019-05-28 18:11:52 UTC (rev 245818)
@@ -76,10 +76,8 @@
scrollingTree().positionedNodesWithRelatedOverflow().add(scrollingNodeID());
}
-void ScrollingTreePositionedNode::applyLayerPositions(const FloatRect&, FloatSize& cumulativeDelta)
+void ScrollingTreePositionedNode::applyLayerPositions()
{
- // Note that we ignore cumulativeDelta because it will contain the delta for ancestor scrollers,
- // but not non-ancestor ones, so it's simpler to just recompute from the scrollers we know about here.
FloatSize scrollOffsetSinceLastCommit;
for (auto nodeID : m_relatedOverflowScrollingNodes) {
if (auto* node = scrollingTree().nodeForID(nodeID)) {
@@ -100,17 +98,14 @@
LOG_WITH_STREAM(Scrolling, stream << "ScrollingTreePositionedNode " << scrollingNodeID() << " applyLayerPositions: overflow delta " << scrollOffsetSinceLastCommit << " moving layer to " << layerPosition);
[m_layer _web_setLayerTopLeftPosition:layerPosition - m_constraints.alignmentOffset()];
-
- // FIXME: Should our scroller deltas propagate to descendants?
- cumulativeDelta = layerPosition - m_constraints.layerPositionAtLastLayout();
}
-void ScrollingTreePositionedNode::relatedNodeScrollPositionDidChange(const ScrollingTreeScrollingNode& changedNode, const FloatRect& layoutViewport, FloatSize& cumulativeDelta)
+void ScrollingTreePositionedNode::relatedNodeScrollPositionDidChange(const ScrollingTreeScrollingNode& changedNode)
{
if (!m_relatedOverflowScrollingNodes.contains(changedNode.scrollingNodeID()))
return;
- applyLayerPositions(layoutViewport, cumulativeDelta);
+ applyLayerPositions();
}
void ScrollingTreePositionedNode::dumpProperties(TextStream& ts, ScrollingStateTreeAsTextBehavior behavior) const
Modified: trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeStickyNode.h (245817 => 245818)
--- trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeStickyNode.h 2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeStickyNode.h 2019-05-28 18:11:52 UTC (rev 245818)
@@ -45,7 +45,7 @@
ScrollingTreeStickyNode(ScrollingTree&, ScrollingNodeID);
void commitStateBeforeChildren(const ScrollingStateNode&) override;
- void applyLayerPositions(const FloatRect& layoutViewport, FloatSize& cumulativeDelta) override;
+ void applyLayerPositions() override;
void dumpProperties(WTF::TextStream&, ScrollingStateTreeAsTextBehavior) const override;
Modified: trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeStickyNode.mm (245817 => 245818)
--- trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeStickyNode.mm 2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeStickyNode.mm 2019-05-28 18:11:52 UTC (rev 245818)
@@ -65,7 +65,7 @@
m_constraints = stickyStateNode.viewportConstraints();
}
-void ScrollingTreeStickyNode::applyLayerPositions(const FloatRect& layoutViewport, FloatSize& cumulativeDelta)
+void ScrollingTreeStickyNode::applyLayerPositions()
{
FloatRect constrainingRect;
@@ -73,16 +73,15 @@
if (is<ScrollingTreeOverflowScrollingNode>(enclosingScrollingNode))
constrainingRect = FloatRect(downcast<ScrollingTreeOverflowScrollingNode>(*enclosingScrollingNode).currentScrollPosition(), m_constraints.constrainingRectAtLastLayout().size());
else if (is<ScrollingTreeFrameScrollingNode>(enclosingScrollingNode))
- constrainingRect = layoutViewport;
+ constrainingRect = downcast<ScrollingTreeFrameScrollingNode>(enclosingScrollingNode)->layoutViewport();
else
return;
- LOG_WITH_STREAM(Scrolling, stream << "ScrollingTreeStickyNode " << scrollingNodeID() << " relatedNodeScrollPositionDidChange: new viewport " << layoutViewport << " constrainingRectAtLastLayout " << m_constraints.constrainingRectAtLastLayout() << " last layer pos " << m_constraints.layerPositionAtLastLayout());
+ FloatPoint layerPosition = m_constraints.layerPositionForConstrainingRect(constrainingRect) - m_constraints.alignmentOffset();
- FloatPoint layerPosition = m_constraints.layerPositionForConstrainingRect(constrainingRect) - m_constraints.alignmentOffset();
+ LOG_WITH_STREAM(Scrolling, stream << "ScrollingTreeStickyNode " << scrollingNodeID() << " constrainingRect " << constrainingRect << " constrainingRectAtLastLayout " << m_constraints.constrainingRectAtLastLayout() << " last layer pos " << m_constraints.layerPositionAtLastLayout() << " layerPosition " << layerPosition);
+
[m_layer _web_setLayerTopLeftPosition:layerPosition];
-
- cumulativeDelta += layerPosition - m_constraints.layerPositionAtLastLayout();
}
void ScrollingTreeStickyNode::dumpProperties(TextStream& ts, ScrollingStateTreeAsTextBehavior behavior) const
Modified: trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFixedNode.cpp (245817 => 245818)
--- trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFixedNode.cpp 2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFixedNode.cpp 2019-05-28 18:11:52 UTC (rev 245818)
@@ -54,7 +54,7 @@
{
}
-void ScrollingTreeFixedNode::applyLayerPositions(const FloatRect&, FloatSize&)
+void ScrollingTreeFixedNode::applyLayerPositions()
{
}
Modified: trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFixedNode.h (245817 => 245818)
--- trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFixedNode.h 2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFixedNode.h 2019-05-28 18:11:52 UTC (rev 245818)
@@ -42,7 +42,7 @@
ScrollingTreeFixedNode(ScrollingTree&, ScrollingNodeID);
void commitStateBeforeChildren(const ScrollingStateNode&) override;
- void applyLayerPositions(const FloatRect& layoutViewport, FloatSize& cumulativeDelta) override;
+ void applyLayerPositions() override;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeStickyNode.cpp (245817 => 245818)
--- trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeStickyNode.cpp 2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeStickyNode.cpp 2019-05-28 18:11:52 UTC (rev 245818)
@@ -54,7 +54,7 @@
{
}
-void ScrollingTreeStickyNode::applyLayerPositions(const FloatRect&, FloatSize&)
+void ScrollingTreeStickyNode::applyLayerPositions()
{
}
Modified: trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeStickyNode.h (245817 => 245818)
--- trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeStickyNode.h 2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeStickyNode.h 2019-05-28 18:11:52 UTC (rev 245818)
@@ -42,7 +42,7 @@
ScrollingTreeStickyNode(ScrollingTree&, ScrollingNodeID);
void commitStateBeforeChildren(const ScrollingStateNode&) override;
- void applyLayerPositions(const FloatRect& layoutViewport, FloatSize& cumulativeDelta) override;
+ void applyLayerPositions() override;
};