Title: [243380] trunk
Revision
243380
Author
an...@apple.com
Date
2019-03-22 09:28:55 -0700 (Fri, 22 Mar 2019)

Log Message

Handle UI side hit testing for ScrollPositioningBehavior::Stationary positioned nodes
https://bugs.webkit.org/show_bug.cgi?id=196100
<rdar://problem/49117933>

Reviewed by Simon Fraser.

Source/WebCore:

Test: fast/scrolling/ios/overflow-scroll-overlap-6.html

* page/scrolling/ScrollingTree.cpp:
(WebCore::ScrollingTree::commitTreeState):
* page/scrolling/ScrollingTree.h:
(WebCore::ScrollingTree::positionedNodesWithRelatedOverflow):

Add a separate map of positioned node ids for easy access.

* page/scrolling/cocoa/ScrollingTreePositionedNode.h:
(WebCore::ScrollingTreePositionedNode::scrollPositioningBehavior const):
(WebCore::ScrollingTreePositionedNode::relatedOverflowScrollingNodes const):
* page/scrolling/cocoa/ScrollingTreePositionedNode.mm:
(WebCore::ScrollingTreePositionedNode::commitStateBeforeChildren):

Source/WebKit:

Test: fast/scrolling/ios/overflow-scroll-overlap-6.html

* UIProcess/RemoteLayerTree/RemoteLayerTreeNode.h:
(WebKit::RemoteLayerTreeNode::relatedScrollContainerIDs const):
(WebKit::RemoteLayerTreeNode::relatedScrollContainerPositioningBehavior const):

Make more generic and save the associated positioning behavior.

(WebKit::RemoteLayerTreeNode::nonAncestorScrollContainerIDs const): Deleted.
(WebKit::RemoteLayerTreeNode::addNonAncestorScrollContainerID): Deleted.
(WebKit::RemoteLayerTreeNode::clearNonAncestorScrollContainerIDs): Deleted.
* UIProcess/RemoteLayerTree/RemoteLayerTreeNode.mm:
(WebKit::RemoteLayerTreeNode::setRelatedScrollContainerBehaviorAndIDs):
* UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h:
* UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.mm:
(WebKit::isScrolledBy):

Stationary relationship means the layer won't scroll the scroller.

* UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm:
(WebKit::RemoteScrollingCoordinatorProxy::establishLayerTreeScrollingRelations):

LayoutTests:

* fast/scrolling/ios/overflow-scroll-overlap-6-expected.txt: Added.
* fast/scrolling/ios/overflow-scroll-overlap-6.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (243379 => 243380)


--- trunk/LayoutTests/ChangeLog	2019-03-22 16:27:14 UTC (rev 243379)
+++ trunk/LayoutTests/ChangeLog	2019-03-22 16:28:55 UTC (rev 243380)
@@ -1,3 +1,14 @@
+2019-03-22  Antti Koivisto  <an...@apple.com>
+
+        Handle UI side hit testing for ScrollPositioningBehavior::Stationary positioned nodes
+        https://bugs.webkit.org/show_bug.cgi?id=196100
+        <rdar://problem/49117933>
+
+        Reviewed by Simon Fraser.
+
+        * fast/scrolling/ios/overflow-scroll-overlap-6-expected.txt: Added.
+        * fast/scrolling/ios/overflow-scroll-overlap-6.html: Added.
+
 2019-03-22  Simon Fraser  <simon.fra...@apple.com>
 
         Unreviewed test gardening of plugin tests

Added: trunk/LayoutTests/fast/scrolling/ios/overflow-scroll-overlap-6-expected.txt (0 => 243380)


--- trunk/LayoutTests/fast/scrolling/ios/overflow-scroll-overlap-6-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/scrolling/ios/overflow-scroll-overlap-6-expected.txt	2019-03-22 16:28:55 UTC (rev 243380)
@@ -0,0 +1,6 @@
+Test that absolute positioned layer inside stacking-context overflow:scroll is correctly hit tested.
+
+case 1: 
+case 2: Scrollable 2 
+case 3: Scrollable 3 
+

Added: trunk/LayoutTests/fast/scrolling/ios/overflow-scroll-overlap-6.html (0 => 243380)


--- trunk/LayoutTests/fast/scrolling/ios/overflow-scroll-overlap-6.html	                        (rev 0)
+++ trunk/LayoutTests/fast/scrolling/ios/overflow-scroll-overlap-6.html	2019-03-22 16:28:55 UTC (rev 243380)
@@ -0,0 +1,84 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<script src=""
+<script src=""
+<style>
+.case {
+    width: 200px;
+    height: 200px;
+    display: inline-block;
+    position: relative;
+}
+.scrollcontent {
+    width: 500px;
+    height: 500px;
+    background: green;
+}
+
+.overflowscroll {
+    overflow: scroll;
+    height: 100px;
+    width: 100px;
+    border: 2px solid black;
+}
+.overlapping {
+    position:absolute;
+    left: 25px;
+    top: 25px;
+    width: 100px;
+    height: 100px;
+    background: red;
+}
+.clip {
+    position:absolute;
+    width: 100px;
+    height: 100px;
+    overflow:hidden;
+}
+.large {
+    width: 3000px;
+    height: 150px;
+}
+#log {
+    position:relative;
+    white-space: pre;
+}
+</style>
+</head>
+<body _onload_="runTest()">
+<p>
+Test that absolute positioned layer inside stacking-context overflow:scroll is correctly hit tested.
+</p>
+
+<div class="case">
+    <div class="overflowscroll target" style="opacity: 0.8;">
+        <div class="overlapping"></div>
+        <div class="scrollcontent"></div>
+    </div>
+</div>
+
+<div class="case">
+    <div class="overflowscroll target" style="opacity: 0.8;">
+        <div class="overlapping">
+            <div class="overlapping" style="left:10px;top:10px"></div>
+        </div>
+        <div class="scrollcontent"></div>
+    </div>
+</div>
+
+<div class="case">
+    <div class="overflowscroll target" style="position:relative;">
+        <div class="overflowscroll target" style="opacity: 0.8; margin:10px">
+            <div class="overlapping"></div>
+            <div class="scrollcontent"></div>
+        </div>
+        <div class="scrollcontent"></div>
+    </div>
+</div>
+
+<div id=log></div>
+
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (243379 => 243380)


--- trunk/Source/WebCore/ChangeLog	2019-03-22 16:27:14 UTC (rev 243379)
+++ trunk/Source/WebCore/ChangeLog	2019-03-22 16:28:55 UTC (rev 243380)
@@ -1,3 +1,26 @@
+2019-03-22  Antti Koivisto  <an...@apple.com>
+
+        Handle UI side hit testing for ScrollPositioningBehavior::Stationary positioned nodes
+        https://bugs.webkit.org/show_bug.cgi?id=196100
+        <rdar://problem/49117933>
+
+        Reviewed by Simon Fraser.
+
+        Test: fast/scrolling/ios/overflow-scroll-overlap-6.html
+
+        * page/scrolling/ScrollingTree.cpp:
+        (WebCore::ScrollingTree::commitTreeState):
+        * page/scrolling/ScrollingTree.h:
+        (WebCore::ScrollingTree::positionedNodesWithRelatedOverflow):
+
+        Add a separate map of positioned node ids for easy access.
+
+        * page/scrolling/cocoa/ScrollingTreePositionedNode.h:
+        (WebCore::ScrollingTreePositionedNode::scrollPositioningBehavior const):
+        (WebCore::ScrollingTreePositionedNode::relatedOverflowScrollingNodes const):
+        * page/scrolling/cocoa/ScrollingTreePositionedNode.mm:
+        (WebCore::ScrollingTreePositionedNode::commitStateBeforeChildren):
+
 2019-03-22  Antoine Quint  <grao...@apple.com>
 
         [Web Animations] com.apple.WebKit.WebContent.Development at com.apple.WebCore: WebCore::WebAnimation::timeToNextTick const + 757

Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp (243379 => 243380)


--- trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp	2019-03-22 16:27:14 UTC (rev 243379)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp	2019-03-22 16:28:55 UTC (rev 243380)
@@ -175,6 +175,7 @@
         unvisitedNodes.add(nodeID);
 
     m_overflowRelatedNodesMap.clear();
+    m_positionedNodesWithRelatedOverflow.clear();
 
     // orphanNodes keeps child nodes alive while we rebuild child lists.
     OrphanScrollingNodeMap orphanNodes;

Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.h (243379 => 243380)


--- trunk/Source/WebCore/page/scrolling/ScrollingTree.h	2019-03-22 16:27:14 UTC (rev 243379)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.h	2019-03-22 16:28:55 UTC (rev 243380)
@@ -150,6 +150,8 @@
     using RelatedNodesMap = HashMap<ScrollingNodeID, Vector<ScrollingNodeID>>;
     RelatedNodesMap& overflowRelatedNodes() { return m_overflowRelatedNodesMap; }
 
+    HashSet<ScrollingNodeID>& positionedNodesWithRelatedOverflow() { return m_positionedNodesWithRelatedOverflow; }
+
     WEBCORE_EXPORT String scrollingTreeAsText(ScrollingStateTreeAsTextBehavior = ScrollingStateTreeAsTextBehaviorNormal);
     
 protected:
@@ -173,6 +175,7 @@
     ScrollingTreeNodeMap m_nodeMap;
 
     RelatedNodesMap m_overflowRelatedNodesMap;
+    HashSet<ScrollingNodeID> m_positionedNodesWithRelatedOverflow;
 
     struct TreeState {
         ScrollingNodeID latchedNodeID { 0 };

Modified: trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreePositionedNode.h (243379 => 243380)


--- trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreePositionedNode.h	2019-03-22 16:27:14 UTC (rev 243379)
+++ trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreePositionedNode.h	2019-03-22 16:28:55 UTC (rev 243380)
@@ -43,6 +43,9 @@
 
     CALayer *layer() const { return m_layer.get(); }
 
+    ScrollPositioningBehavior scrollPositioningBehavior() const { return m_constraints.scrollPositioningBehavior(); }
+    const Vector<ScrollingNodeID>& relatedOverflowScrollingNodes() const { return m_relatedOverflowScrollingNodes; }
+
 private:
     ScrollingTreePositionedNode(ScrollingTree&, ScrollingNodeID);
 

Modified: trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreePositionedNode.mm (243379 => 243380)


--- trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreePositionedNode.mm	2019-03-22 16:27:14 UTC (rev 243379)
+++ trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreePositionedNode.mm	2019-03-22 16:28:55 UTC (rev 243380)
@@ -72,6 +72,8 @@
             }).iterator->value.append(scrollingNodeID());
         }
     }
+    if (!m_relatedOverflowScrollingNodes.isEmpty() && m_constraints.scrollPositioningBehavior() != ScrollPositioningBehavior::None)
+        scrollingTree().positionedNodesWithRelatedOverflow().add(scrollingNodeID());
 }
 
 void ScrollingTreePositionedNode::applyLayerPositions(const FloatRect&, FloatSize& cumulativeDelta)

Modified: trunk/Source/WebKit/ChangeLog (243379 => 243380)


--- trunk/Source/WebKit/ChangeLog	2019-03-22 16:27:14 UTC (rev 243379)
+++ trunk/Source/WebKit/ChangeLog	2019-03-22 16:28:55 UTC (rev 243380)
@@ -1,3 +1,33 @@
+2019-03-22  Antti Koivisto  <an...@apple.com>
+
+        Handle UI side hit testing for ScrollPositioningBehavior::Stationary positioned nodes
+        https://bugs.webkit.org/show_bug.cgi?id=196100
+        <rdar://problem/49117933>
+
+        Reviewed by Simon Fraser.
+
+        Test: fast/scrolling/ios/overflow-scroll-overlap-6.html
+
+        * UIProcess/RemoteLayerTree/RemoteLayerTreeNode.h:
+        (WebKit::RemoteLayerTreeNode::relatedScrollContainerIDs const):
+        (WebKit::RemoteLayerTreeNode::relatedScrollContainerPositioningBehavior const):
+
+        Make more generic and save the associated positioning behavior.
+
+        (WebKit::RemoteLayerTreeNode::nonAncestorScrollContainerIDs const): Deleted.
+        (WebKit::RemoteLayerTreeNode::addNonAncestorScrollContainerID): Deleted.
+        (WebKit::RemoteLayerTreeNode::clearNonAncestorScrollContainerIDs): Deleted.
+        * UIProcess/RemoteLayerTree/RemoteLayerTreeNode.mm:
+        (WebKit::RemoteLayerTreeNode::setRelatedScrollContainerBehaviorAndIDs):
+        * UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h:
+        * UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.mm:
+        (WebKit::isScrolledBy):
+
+        Stationary relationship means the layer won't scroll the scroller.
+
+        * UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm:
+        (WebKit::RemoteScrollingCoordinatorProxy::establishLayerTreeScrollingRelations):
+
 2019-03-22  Chris Dumez  <cdu...@apple.com>
 
         REGRESSION (r243094): ePub files do not render or open in Books

Modified: trunk/Source/WebKit/UIProcess/RemoteLayerTree/RemoteLayerTreeNode.h (243379 => 243380)


--- trunk/Source/WebKit/UIProcess/RemoteLayerTree/RemoteLayerTreeNode.h	2019-03-22 16:27:14 UTC (rev 243379)
+++ trunk/Source/WebKit/UIProcess/RemoteLayerTree/RemoteLayerTreeNode.h	2019-03-22 16:28:55 UTC (rev 243380)
@@ -59,10 +59,10 @@
     const WebCore::Region& eventRegion() const { return m_eventRegion; }
     void setEventRegion(const WebCore::Region&);
 
-    // If empty the layer is scrolled by an ancestor scroller.
-    const auto& nonAncestorScrollContainerIDs() const { return m_nonAncestorScrollLayerIDs; }
-    void addNonAncestorScrollContainerID(WebCore::GraphicsLayer::PlatformLayerID layerID) { m_nonAncestorScrollLayerIDs.append(layerID); }
-    void clearNonAncestorScrollContainerIDs() { m_nonAncestorScrollLayerIDs.clear(); }
+    // If empty the layer is scrolled normally by an ancestor scroller.
+    const auto& relatedScrollContainerIDs() const { return m_relatedScrollContainerIDs; }
+    WebCore::ScrollPositioningBehavior relatedScrollContainerPositioningBehavior() const { return m_relatedScrollContainerPositioningBehavior; }
+    void setRelatedScrollContainerBehaviorAndIDs(WebCore::ScrollPositioningBehavior, Vector<WebCore::GraphicsLayer::PlatformLayerID>&&);
 
     void detachFromParent();
 
@@ -82,7 +82,9 @@
 #endif
 
     WebCore::Region m_eventRegion;
-    Vector<WebCore::GraphicsLayer::PlatformLayerID> m_nonAncestorScrollLayerIDs;
+
+    Vector<WebCore::GraphicsLayer::PlatformLayerID> m_relatedScrollContainerIDs;
+    WebCore::ScrollPositioningBehavior m_relatedScrollContainerPositioningBehavior { WebCore::ScrollPositioningBehavior::None };
 };
 
 }

Modified: trunk/Source/WebKit/UIProcess/RemoteLayerTree/RemoteLayerTreeNode.mm (243379 => 243380)


--- trunk/Source/WebKit/UIProcess/RemoteLayerTree/RemoteLayerTreeNode.mm	2019-03-22 16:27:14 UTC (rev 243379)
+++ trunk/Source/WebKit/UIProcess/RemoteLayerTree/RemoteLayerTreeNode.mm	2019-03-22 16:28:55 UTC (rev 243380)
@@ -92,6 +92,12 @@
     m_eventRegion = eventRegion;
 }
 
+void RemoteLayerTreeNode::setRelatedScrollContainerBehaviorAndIDs(WebCore::ScrollPositioningBehavior behavior, Vector<WebCore::GraphicsLayer::PlatformLayerID>&& scrollContainerIDs)
+{
+    m_relatedScrollContainerPositioningBehavior = behavior;
+    m_relatedScrollContainerIDs = WTFMove(scrollContainerIDs);
+}
+
 void RemoteLayerTreeNode::initializeLayer()
 {
     [layer() setValue:[NSValue valueWithPointer:this] forKey:WKRemoteLayerTreeNodePropertyKey];

Modified: trunk/Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h (243379 => 243380)


--- trunk/Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h	2019-03-22 16:27:14 UTC (rev 243379)
+++ trunk/Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h	2019-03-22 16:28:55 UTC (rev 243380)
@@ -127,7 +127,7 @@
     unsigned m_currentVerticalSnapPointIndex { 0 };
 #endif
     bool m_propagatesMainFrameScrolls;
-    HashSet<WebCore::GraphicsLayer::PlatformLayerID> m_layersWithNonAncestorScrollingRelations;
+    HashSet<WebCore::GraphicsLayer::PlatformLayerID> m_layersWithScrollingRelations;
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.mm (243379 => 243380)


--- trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.mm	2019-03-22 16:27:14 UTC (rev 243379)
+++ trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.mm	2019-03-22 16:28:55 UTC (rev 243380)
@@ -74,8 +74,16 @@
             return true;
 
         auto* node = RemoteLayerTreeNode::forCALayer(view.layer);
-        if (node && scrollLayerID && node->nonAncestorScrollContainerIDs().contains(scrollLayerID))
-            return true;
+        if (node && scrollLayerID && node->relatedScrollContainerIDs().contains(scrollLayerID)) {
+            switch (node->relatedScrollContainerPositioningBehavior()) {
+            case WebCore::ScrollPositioningBehavior::Moves:
+                return true;
+            case WebCore::ScrollPositioningBehavior::Stationary:
+                return false;
+            case WebCore::ScrollPositioningBehavior::None:
+                ASSERT_NOT_REACHED();
+            }
+        }
     }
 
     return false;

Modified: trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm (243379 => 243380)


--- trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm	2019-03-22 16:27:14 UTC (rev 243379)
+++ trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm	2019-03-22 16:28:55 UTC (rev 243380)
@@ -121,27 +121,28 @@
 
 void RemoteScrollingCoordinatorProxy::establishLayerTreeScrollingRelations(const RemoteLayerTreeHost& remoteLayerTreeHost)
 {
-    for (auto layerID : m_layersWithNonAncestorScrollingRelations) {
+    for (auto layerID : m_layersWithScrollingRelations) {
         if (auto* layerNode = remoteLayerTreeHost.nodeForID(layerID))
-            layerNode->clearNonAncestorScrollContainerIDs();
+            layerNode->setRelatedScrollContainerBehaviorAndIDs({ }, { });
     }
-    m_layersWithNonAncestorScrollingRelations.clear();
+    m_layersWithScrollingRelations.clear();
 
-    // Usually a scroll view scrolls its descendant layers. In some positioning cases it also controls non-descendants.
+    // Usually a scroll view scrolls its descendant layers. In some positioning cases it also controls non-descendants, or doesn't control a descendant.
     // To do overlap hit testing correctly we tell layers about such relations.
+    for (auto positionedNodeID : m_scrollingTree->positionedNodesWithRelatedOverflow()) {
+        auto* positionedNode = downcast<ScrollingTreePositionedNode>(m_scrollingTree->nodeForID(positionedNodeID));
+        auto* positionedLayerNode = RemoteLayerTreeNode::forCALayer(positionedNode->layer());
 
-    // FIXME: This doesn't contain ScrollPositioningBehavior::Stationary nodes. They will need to be handled too.
-    //        See https://bugs.webkit.org/show_bug.cgi?id=196100
-    for (auto& overflowAndPositionedNodeIDs : m_scrollingTree->overflowRelatedNodes()) {
-        auto* overflowNode = downcast<ScrollingTreeOverflowScrollingNode>(m_scrollingTree->nodeForID(overflowAndPositionedNodeIDs.key));
-        for (auto positionedNodeID : overflowAndPositionedNodeIDs.value) {
-            auto* positionedNode = downcast<ScrollingTreePositionedNode>(m_scrollingTree->nodeForID(positionedNodeID));
-            auto* positionedLayerNode = RemoteLayerTreeNode::forCALayer(positionedNode->layer());
+        Vector<GraphicsLayer::PlatformLayerID> scrollContainerLayerIDs;
 
-            positionedLayerNode->addNonAncestorScrollContainerID(RemoteLayerTreeNode::layerID(overflowNode->scrollContainerLayer()));
+        for (auto overflowNodeID : positionedNode->relatedOverflowScrollingNodes()) {
+            auto* overflowNode = downcast<ScrollingTreeOverflowScrollingNode>(m_scrollingTree->nodeForID(overflowNodeID));
+            scrollContainerLayerIDs.append(RemoteLayerTreeNode::layerID(overflowNode->scrollContainerLayer()));
+        }
 
-            m_layersWithNonAncestorScrollingRelations.add(positionedLayerNode->layerID());
-        }
+        positionedLayerNode->setRelatedScrollContainerBehaviorAndIDs(positionedNode->scrollPositioningBehavior(), WTFMove(scrollContainerLayerIDs));
+
+        m_layersWithScrollingRelations.add(positionedLayerNode->layerID());
     }
 }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to