[Mac] Implement basic hit testing in the scrolling tree
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 31 Jan 2019 16:28:27 +0000 (16:28 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 31 Jan 2019 16:28:27 +0000 (16:28 +0000)
https://bugs.webkit.org/show_bug.cgi?id=172917
<rdar://problem/34215516>

Reviewed by Antti Koivisto.

Source/WebCore:

First steps to getting hit testing of scrolling nodes in the scrolling tree. Based on patch
by Frédéric Wang.

First we pipe the "async scrolling enabled" setting through to the ScrollingTree via
the root node (like the other settings; weird, but that's how it's done). For now,
we hit test in the scrolling tree if either async overflow or frame scrolling are enabled
(it's hard to deal with one without the other).

Nodes in the scrolling tree implement scrollingNodeForPoint() to implement hit testing.
Two helper functions exist to simplify coordinate conversion: parentToLocalPoint()
and localToContentsPoint(). Child nodes are hit-testing in reverse order to find nodes
hightest in Z first. Only scrolling nodes are returned (not sure if we'll ever need
to hit-test non-scrolling nodes). Nodes use parentRelativeScrollableRect and scroll positions
to do these point mappings.

handleWheelEvent() is changed to return a ScrollingEventResult.

Latching is not correct with this change when async frame scrolling is enabled. That needs
to be fixed separately.

No tests yet; for ease of testing, I'd like to add an Internals API to hit-test the
scrolling tree, rather than doing eventSender stuff everywhere.

* page/scrolling/AsyncScrollingCoordinator.cpp:
(WebCore::AsyncScrollingCoordinator::frameViewLayoutUpdated):
(WebCore::AsyncScrollingCoordinator::asyncFrameOrOverflowScrollingEnabled const):
* page/scrolling/AsyncScrollingCoordinator.h:
* page/scrolling/ScrollingStateFrameScrollingNode.cpp:
(WebCore::ScrollingStateFrameScrollingNode::ScrollingStateFrameScrollingNode):
(WebCore::ScrollingStateFrameScrollingNode::setAllPropertiesChanged):
(WebCore::ScrollingStateFrameScrollingNode::setAsyncFrameOrOverflowScrollingEnabled):
* page/scrolling/ScrollingStateFrameScrollingNode.h:
* page/scrolling/ScrollingTree.cpp:
(WebCore::ScrollingTree::shouldHandleWheelEventSynchronously):
(WebCore::ScrollingTree::handleWheelEvent):
(WebCore::ScrollingTree::commitTreeState):
(WebCore::ScrollingTree::setAsyncFrameOrOverflowScrollingEnabled):
* page/scrolling/ScrollingTree.h:
(WebCore::ScrollingTree::asyncFrameOrOverflowScrollingEnabled const):
* page/scrolling/ScrollingTreeFrameHostingNode.cpp:
(WebCore::ScrollingTreeFrameHostingNode::parentToLocalPoint const):
* page/scrolling/ScrollingTreeFrameHostingNode.h:
* page/scrolling/ScrollingTreeFrameScrollingNode.cpp:
(WebCore::ScrollingTreeFrameScrollingNode::parentToLocalPoint const):
(WebCore::ScrollingTreeFrameScrollingNode::localToContentsPoint const):
* page/scrolling/ScrollingTreeFrameScrollingNode.h:
* page/scrolling/ScrollingTreeNode.cpp:
(WebCore::ScrollingTreeNode::scrollingNodeForPoint const):
* page/scrolling/ScrollingTreeNode.h:
(WebCore::ScrollingTreeNode::children const):
(WebCore::ScrollingTreeNode::parentToLocalPoint const):
(WebCore::ScrollingTreeNode::localToContentsPoint const):
* page/scrolling/ScrollingTreeScrollingNode.cpp:
(WebCore::ScrollingTreeScrollingNode::scrollLimitReached const):
(WebCore::ScrollingTreeScrollingNode::parentToLocalPoint const):
(WebCore::ScrollingTreeScrollingNode::localToContentsPoint const):
(WebCore::ScrollingTreeScrollingNode::scrollingNodeForPoint const):
* page/scrolling/ScrollingTreeScrollingNode.h:
* page/scrolling/ThreadedScrollingTree.cpp:
(WebCore::ThreadedScrollingTree::handleWheelEvent):
* page/scrolling/ThreadedScrollingTree.h:
* page/scrolling/ios/ScrollingTreeFrameScrollingNodeIOS.h:
* page/scrolling/ios/ScrollingTreeFrameScrollingNodeIOS.mm:
(WebCore::ScrollingTreeFrameScrollingNodeIOS::handleWheelEvent):
* page/scrolling/ios/ScrollingTreeIOS.h:
* page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.h:
* page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm:
(WebCore::ScrollingTreeFrameScrollingNodeMac::handleWheelEvent):
* page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.h:

Source/WebKit:

Changed return types, "using namespace WebCore" in ScrollingTreeFrameScrollingNodeRemoteMac.cpp.

* Shared/RemoteLayerTree/RemoteScrollingCoordinatorTransaction.cpp:
(ArgumentCoder<ScrollingStateFrameScrollingNode>::encode):
* UIProcess/RemoteLayerTree/ios/ScrollingTreeOverflowScrollingNodeIOS.h:
* UIProcess/RemoteLayerTree/mac/ScrollerPairMac.h:
* UIProcess/RemoteLayerTree/mac/ScrollerPairMac.mm:
(WebKit::ScrollerPairMac::handleWheelEvent):
(WebKit::ScrollerPairMac::handleMouseEvent):
* UIProcess/RemoteLayerTree/mac/ScrollingTreeFrameScrollingNodeRemoteMac.cpp:
(WebKit::ScrollingTreeFrameScrollingNodeRemoteMac::handleWheelEvent):
(WebKit::ScrollingTreeFrameScrollingNodeRemoteMac::handleMouseEvent):
* UIProcess/RemoteLayerTree/mac/ScrollingTreeFrameScrollingNodeRemoteMac.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240787 268f45cc-cd09-0410-ab3c-d52691b4dbfc

45 files changed:
Source/WebCore/ChangeLog
Source/WebCore/page/FrameView.cpp
Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp
Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h
Source/WebCore/page/scrolling/ScrollingCoordinator.h
Source/WebCore/page/scrolling/ScrollingCoordinatorTypes.h
Source/WebCore/page/scrolling/ScrollingStateFrameScrollingNode.cpp
Source/WebCore/page/scrolling/ScrollingStateFrameScrollingNode.h
Source/WebCore/page/scrolling/ScrollingTree.cpp
Source/WebCore/page/scrolling/ScrollingTree.h
Source/WebCore/page/scrolling/ScrollingTreeFrameHostingNode.cpp
Source/WebCore/page/scrolling/ScrollingTreeFrameHostingNode.h
Source/WebCore/page/scrolling/ScrollingTreeFrameScrollingNode.cpp
Source/WebCore/page/scrolling/ScrollingTreeFrameScrollingNode.h
Source/WebCore/page/scrolling/ScrollingTreeNode.cpp
Source/WebCore/page/scrolling/ScrollingTreeNode.h
Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp
Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h
Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp
Source/WebCore/page/scrolling/ThreadedScrollingTree.h
Source/WebCore/page/scrolling/ios/ScrollingCoordinatorIOS.h
Source/WebCore/page/scrolling/ios/ScrollingTreeFrameScrollingNodeIOS.h
Source/WebCore/page/scrolling/ios/ScrollingTreeFrameScrollingNodeIOS.mm
Source/WebCore/page/scrolling/ios/ScrollingTreeIOS.h
Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.h
Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.mm
Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.h
Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm
Source/WebCore/page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.h
Source/WebCore/page/scrolling/nicosia/ScrollingCoordinatorNicosia.cpp
Source/WebCore/page/scrolling/nicosia/ScrollingCoordinatorNicosia.h
Source/WebCore/page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.cpp
Source/WebCore/page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.h
Source/WebCore/page/scrolling/nicosia/ScrollingTreeNicosia.cpp
Source/WebKit/ChangeLog
Source/WebKit/Shared/RemoteLayerTree/RemoteScrollingCoordinatorTransaction.cpp
Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp
Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingTree.cpp
Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingTree.h
Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeOverflowScrollingNodeIOS.h
Source/WebKit/UIProcess/RemoteLayerTree/mac/ScrollerPairMac.h
Source/WebKit/UIProcess/RemoteLayerTree/mac/ScrollerPairMac.mm
Source/WebKit/UIProcess/RemoteLayerTree/mac/ScrollingTreeFrameScrollingNodeRemoteMac.cpp
Source/WebKit/UIProcess/RemoteLayerTree/mac/ScrollingTreeFrameScrollingNodeRemoteMac.h
Source/WebKit/WebProcess/WebPage/EventDispatcher.cpp

index 3fe2697..2e18b3b 100644 (file)
@@ -1,3 +1,81 @@
+2019-01-30  Simon Fraser  <simon.fraser@apple.com>
+
+        [Mac] Implement basic hit testing in the scrolling tree
+        https://bugs.webkit.org/show_bug.cgi?id=172917
+        <rdar://problem/34215516>
+
+        Reviewed by Antti Koivisto.
+
+        First steps to getting hit testing of scrolling nodes in the scrolling tree. Based on patch
+        by Frédéric Wang.
+
+        First we pipe the "async scrolling enabled" setting through to the ScrollingTree via
+        the root node (like the other settings; weird, but that's how it's done). For now,
+        we hit test in the scrolling tree if either async overflow or frame scrolling are enabled
+        (it's hard to deal with one without the other).
+
+        Nodes in the scrolling tree implement scrollingNodeForPoint() to implement hit testing.
+        Two helper functions exist to simplify coordinate conversion: parentToLocalPoint()
+        and localToContentsPoint(). Child nodes are hit-testing in reverse order to find nodes
+        hightest in Z first. Only scrolling nodes are returned (not sure if we'll ever need
+        to hit-test non-scrolling nodes). Nodes use parentRelativeScrollableRect and scroll positions
+        to do these point mappings.
+
+        handleWheelEvent() is changed to return a ScrollingEventResult.
+
+        Latching is not correct with this change when async frame scrolling is enabled. That needs
+        to be fixed separately.
+
+        No tests yet; for ease of testing, I'd like to add an Internals API to hit-test the
+        scrolling tree, rather than doing eventSender stuff everywhere.
+
+        * page/scrolling/AsyncScrollingCoordinator.cpp:
+        (WebCore::AsyncScrollingCoordinator::frameViewLayoutUpdated):
+        (WebCore::AsyncScrollingCoordinator::asyncFrameOrOverflowScrollingEnabled const):
+        * page/scrolling/AsyncScrollingCoordinator.h:
+        * page/scrolling/ScrollingStateFrameScrollingNode.cpp:
+        (WebCore::ScrollingStateFrameScrollingNode::ScrollingStateFrameScrollingNode):
+        (WebCore::ScrollingStateFrameScrollingNode::setAllPropertiesChanged):
+        (WebCore::ScrollingStateFrameScrollingNode::setAsyncFrameOrOverflowScrollingEnabled):
+        * page/scrolling/ScrollingStateFrameScrollingNode.h:
+        * page/scrolling/ScrollingTree.cpp:
+        (WebCore::ScrollingTree::shouldHandleWheelEventSynchronously):
+        (WebCore::ScrollingTree::handleWheelEvent):
+        (WebCore::ScrollingTree::commitTreeState):
+        (WebCore::ScrollingTree::setAsyncFrameOrOverflowScrollingEnabled):
+        * page/scrolling/ScrollingTree.h:
+        (WebCore::ScrollingTree::asyncFrameOrOverflowScrollingEnabled const):
+        * page/scrolling/ScrollingTreeFrameHostingNode.cpp:
+        (WebCore::ScrollingTreeFrameHostingNode::parentToLocalPoint const):
+        * page/scrolling/ScrollingTreeFrameHostingNode.h:
+        * page/scrolling/ScrollingTreeFrameScrollingNode.cpp:
+        (WebCore::ScrollingTreeFrameScrollingNode::parentToLocalPoint const):
+        (WebCore::ScrollingTreeFrameScrollingNode::localToContentsPoint const):
+        * page/scrolling/ScrollingTreeFrameScrollingNode.h:
+        * page/scrolling/ScrollingTreeNode.cpp:
+        (WebCore::ScrollingTreeNode::scrollingNodeForPoint const):
+        * page/scrolling/ScrollingTreeNode.h:
+        (WebCore::ScrollingTreeNode::children const):
+        (WebCore::ScrollingTreeNode::parentToLocalPoint const):
+        (WebCore::ScrollingTreeNode::localToContentsPoint const):
+        * page/scrolling/ScrollingTreeScrollingNode.cpp:
+        (WebCore::ScrollingTreeScrollingNode::scrollLimitReached const):
+        (WebCore::ScrollingTreeScrollingNode::parentToLocalPoint const):
+        (WebCore::ScrollingTreeScrollingNode::localToContentsPoint const):
+        (WebCore::ScrollingTreeScrollingNode::scrollingNodeForPoint const):
+        * page/scrolling/ScrollingTreeScrollingNode.h:
+        * page/scrolling/ThreadedScrollingTree.cpp:
+        (WebCore::ThreadedScrollingTree::handleWheelEvent):
+        * page/scrolling/ThreadedScrollingTree.h:
+        * page/scrolling/ios/ScrollingTreeFrameScrollingNodeIOS.h:
+        * page/scrolling/ios/ScrollingTreeFrameScrollingNodeIOS.mm:
+        (WebCore::ScrollingTreeFrameScrollingNodeIOS::handleWheelEvent):
+        * page/scrolling/ios/ScrollingTreeIOS.h:
+        * page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.h:
+        * page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm:
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::handleWheelEvent):
+        * page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.h:
+
 2019-01-31  Alicia Boya García  <aboya@igalia.com>
 
         [MSE][GStreamer] Remove unused GstFlowReturn in AppendPipeline methods
index b6bbaf3..d5c8897 100644 (file)
@@ -5011,7 +5011,7 @@ bool FrameView::wheelEvent(const PlatformWheelEvent& wheelEvent)
     if (Page* page = frame().page()) {
         if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator()) {
             if (scrollingCoordinator->coordinatesScrollingForFrameView(*this))
-                return scrollingCoordinator->handleWheelEvent(*this, wheelEvent);
+                return scrollingCoordinator->handleWheelEvent(*this, wheelEvent) != ScrollingEventResult::DidNotHandleEvent;
         }
     }
 #endif
index f7d809d..ee127d1 100644 (file)
@@ -130,30 +130,34 @@ void AsyncScrollingCoordinator::frameViewLayoutUpdated(FrameView& frameView)
     if (!coordinatesScrollingForFrameView(frameView))
         return;
 
-    auto* node = downcast<ScrollingStateFrameScrollingNode>(m_scrollingStateTree->stateNodeForID(frameView.scrollLayerID()));
-    if (!node)
+    auto* node = m_scrollingStateTree->stateNodeForID(frameView.scrollLayerID());
+    if (!node || !is<ScrollingStateFrameScrollingNode>(*node))
         return;
 
+    auto& frameScrollingNode = downcast<ScrollingStateFrameScrollingNode>(*node);
+
     auto* verticalScrollbar = frameView.verticalScrollbar();
     auto* horizontalScrollbar = frameView.horizontalScrollbar();
-    node->setScrollerImpsFromScrollbars(verticalScrollbar, horizontalScrollbar);
-
-    node->setFrameScaleFactor(frameView.frame().frameScaleFactor());
-    node->setHeaderHeight(frameView.headerHeight());
-    node->setFooterHeight(frameView.footerHeight());
-    node->setTopContentInset(frameView.topContentInset());
-
-    node->setVisualViewportEnabled(visualViewportEnabled());
-    node->setLayoutViewport(frameView.layoutViewportRect());
-    node->setMinLayoutViewportOrigin(frameView.minStableLayoutViewportOrigin());
-    node->setMaxLayoutViewportOrigin(frameView.maxStableLayoutViewportOrigin());
-
-    node->setScrollOrigin(frameView.scrollOrigin());
-    node->setScrollableAreaSize(frameView.visibleContentRect().size());
-    node->setTotalContentsSize(frameView.totalContentsSize());
-    node->setReachableContentsSize(frameView.totalContentsSize());
-    node->setFixedElementsLayoutRelativeToFrame(frameView.fixedElementsLayoutRelativeToFrame());
-    node->setScrollBehaviorForFixedElements(frameView.scrollBehaviorForFixedElements());
+    frameScrollingNode.setScrollerImpsFromScrollbars(verticalScrollbar, horizontalScrollbar);
+
+    frameScrollingNode.setFrameScaleFactor(frameView.frame().frameScaleFactor());
+    frameScrollingNode.setHeaderHeight(frameView.headerHeight());
+    frameScrollingNode.setFooterHeight(frameView.footerHeight());
+    frameScrollingNode.setTopContentInset(frameView.topContentInset());
+
+    frameScrollingNode.setVisualViewportEnabled(visualViewportEnabled());
+    frameScrollingNode.setLayoutViewport(frameView.layoutViewportRect());
+    frameScrollingNode.setAsyncFrameOrOverflowScrollingEnabled(asyncFrameOrOverflowScrollingEnabled());
+
+    frameScrollingNode.setMinLayoutViewportOrigin(frameView.minStableLayoutViewportOrigin());
+    frameScrollingNode.setMaxLayoutViewportOrigin(frameView.maxStableLayoutViewportOrigin());
+
+    frameScrollingNode.setScrollOrigin(frameView.scrollOrigin());
+    frameScrollingNode.setScrollableAreaSize(frameView.visibleContentRect().size());
+    frameScrollingNode.setTotalContentsSize(frameView.totalContentsSize());
+    frameScrollingNode.setReachableContentsSize(frameView.totalContentsSize());
+    frameScrollingNode.setFixedElementsLayoutRelativeToFrame(frameView.fixedElementsLayoutRelativeToFrame());
+    frameScrollingNode.setScrollBehaviorForFixedElements(frameView.scrollBehaviorForFixedElements());
 
 #if ENABLE(CSS_SCROLL_SNAP)
     frameView.updateSnapOffsets();
@@ -164,7 +168,7 @@ void AsyncScrollingCoordinator::frameViewLayoutUpdated(FrameView& frameView)
     auto* page = frameView.frame().page();
     if (page && page->expectsWheelEventTriggers()) {
         LOG(WheelEventTestTriggers, "    AsyncScrollingCoordinator::frameViewLayoutUpdated: Expects wheel event test trigger=%d", page->expectsWheelEventTriggers());
-        node->setExpectsWheelEventTestTrigger(page->expectsWheelEventTriggers());
+        frameScrollingNode.setExpectsWheelEventTestTrigger(page->expectsWheelEventTriggers());
     }
 #endif
 
@@ -177,7 +181,7 @@ void AsyncScrollingCoordinator::frameViewLayoutUpdated(FrameView& frameView)
     scrollParameters.verticalScrollbarMode = frameView.verticalScrollbarMode();
     scrollParameters.useDarkAppearanceForScrollbars = frameView.useDarkAppearanceForScrollbars();
 
-    node->setScrollableAreaParameters(scrollParameters);
+    frameScrollingNode.setScrollableAreaParameters(scrollParameters);
 }
 
 void AsyncScrollingCoordinator::updateExpectsWheelEventTestTriggerWithFrameView(const FrameView& frameView)
@@ -679,6 +683,12 @@ bool AsyncScrollingCoordinator::visualViewportEnabled() const
     return m_page->mainFrame().settings().visualViewportEnabled();
 }
 
+bool AsyncScrollingCoordinator::asyncFrameOrOverflowScrollingEnabled() const
+{
+    auto& settings = m_page->mainFrame().settings();
+    return settings.asyncFrameScrollingEnabled() || settings.asyncOverflowScrollingEnabled();
+}
+
 String AsyncScrollingCoordinator::scrollingStateTreeAsText(ScrollingStateTreeAsTextBehavior behavior) const
 {
     if (m_scrollingStateTree->rootStateNode()) {
index cc23da8..345a374 100644 (file)
@@ -90,6 +90,7 @@ private:
     bool hasVisibleSlowRepaintViewportConstrainedObjects(const FrameView&) const override { return false; }
     
     bool visualViewportEnabled() const;
+    bool asyncFrameOrOverflowScrollingEnabled() const;
 
     WEBCORE_EXPORT void frameViewLayoutUpdated(FrameView&) override;
     WEBCORE_EXPORT void frameViewRootLayerDidChange(FrameView&) override;
index 53322f6..02cbb27 100644 (file)
@@ -111,7 +111,7 @@ public:
     // These virtual functions are currently unique to the threaded scrolling architecture. 
     virtual void commitTreeStateIfNeeded() { }
     virtual bool requestScrollPositionUpdate(FrameView&, const IntPoint&) { return false; }
-    virtual bool handleWheelEvent(FrameView&, const PlatformWheelEvent&) { return true; }
+    virtual ScrollingEventResult handleWheelEvent(FrameView&, const PlatformWheelEvent&) { return ScrollingEventResult::DidNotHandleEvent; }
 
     // Create an unparented node.
     virtual ScrollingNodeID createNode(ScrollingNodeType, ScrollingNodeID newNodeID) { return newNodeID; }
index 137ebd2..5d6e200 100644 (file)
@@ -80,6 +80,12 @@ struct ScrollableAreaParameters {
     }
 };
 
+enum class ScrollingEventResult {
+    DidNotHandleEvent,
+    DidHandleEvent,
+    SendToMainThread
+};
+
 enum class ViewportRectStability {
     Stable,
     Unstable,
index 76b1d0f..66cd7ec 100644 (file)
@@ -64,6 +64,7 @@ ScrollingStateFrameScrollingNode::ScrollingStateFrameScrollingNode(const Scrolli
     , m_requestedScrollPositionRepresentsProgrammaticScroll(stateNode.requestedScrollPositionRepresentsProgrammaticScroll())
     , m_fixedElementsLayoutRelativeToFrame(stateNode.fixedElementsLayoutRelativeToFrame())
     , m_visualViewportEnabled(stateNode.visualViewportEnabled())
+    , m_asyncFrameOrOverflowScrollingEnabled(stateNode.asyncFrameOrOverflowScrollingEnabled())
 {
     if (hasChangedProperty(CounterScrollingLayer))
         setCounterScrollingLayer(stateNode.counterScrollingLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
@@ -114,6 +115,7 @@ void ScrollingStateFrameScrollingNode::setAllPropertiesChanged()
     setPropertyChangedBit(TopContentInset);
     setPropertyChangedBit(FixedElementsLayoutRelativeToFrame);
     setPropertyChangedBit(VisualViewportEnabled);
+    setPropertyChangedBit(AsyncFrameOrOverflowScrollingEnabled);
     setPropertyChangedBit(LayoutViewport);
     setPropertyChangedBit(MinLayoutViewportOrigin);
     setPropertyChangedBit(MaxLayoutViewportOrigin);
@@ -294,6 +296,15 @@ void ScrollingStateFrameScrollingNode::setVisualViewportEnabled(bool visualViewp
     setPropertyChanged(VisualViewportEnabled);
 }
 
+void ScrollingStateFrameScrollingNode::setAsyncFrameOrOverflowScrollingEnabled(bool enabled)
+{
+    if (enabled == m_asyncFrameOrOverflowScrollingEnabled)
+        return;
+    
+    m_asyncFrameOrOverflowScrollingEnabled = enabled;
+    setPropertyChanged(AsyncFrameOrOverflowScrollingEnabled);
+}
+
 #if !PLATFORM(MAC)
 void ScrollingStateFrameScrollingNode::setScrollerImpsFromScrollbars(Scrollbar*, Scrollbar*)
 {
index 7b5970a..f5d8646 100644 (file)
@@ -64,6 +64,7 @@ public:
         TopContentInset,
         FixedElementsLayoutRelativeToFrame,
         VisualViewportEnabled,
+        AsyncFrameOrOverflowScrollingEnabled,
         LayoutViewport,
         MinLayoutViewportOrigin,
         MaxLayoutViewportOrigin,
@@ -127,12 +128,16 @@ public:
     const LayerRepresentation& horizontalScrollbarLayer() const { return m_horizontalScrollbarLayer; }
     WEBCORE_EXPORT void setHorizontalScrollbarLayer(const LayerRepresentation&);
 
+    // These are more like Settings, and should probably move to the Scrolling{State}Tree itself.
     bool fixedElementsLayoutRelativeToFrame() const { return m_fixedElementsLayoutRelativeToFrame; }
     WEBCORE_EXPORT void setFixedElementsLayoutRelativeToFrame(bool);
 
     bool visualViewportEnabled() const { return m_visualViewportEnabled; };
     WEBCORE_EXPORT void setVisualViewportEnabled(bool);
 
+    bool asyncFrameOrOverflowScrollingEnabled() const { return m_asyncFrameOrOverflowScrollingEnabled; }
+    void setAsyncFrameOrOverflowScrollingEnabled(bool);
+
 #if PLATFORM(MAC)
     NSScrollerImp *verticalScrollerImp() const { return m_verticalScrollerImp.get(); }
     NSScrollerImp *horizontalScrollerImp() const { return m_horizontalScrollerImp.get(); }
@@ -176,6 +181,7 @@ private:
     bool m_requestedScrollPositionRepresentsProgrammaticScroll { false };
     bool m_fixedElementsLayoutRelativeToFrame { false };
     bool m_visualViewportEnabled { false };
+    bool m_asyncFrameOrOverflowScrollingEnabled { false };
 };
 
 } // namespace WebCore
index 7fb27f0..2790701 100644 (file)
@@ -65,6 +65,8 @@ bool ScrollingTree::shouldHandleWheelEventSynchronously(const PlatformWheelEvent
 
         const EventNames& names = eventNames();
         IntPoint roundedPosition = roundedIntPoint(position);
+
+        // Event regions are affected by page scale, so no need to map through scale.
         bool isSynchronousDispatchRegion = m_eventTrackingRegions.trackingTypeForPoint(names.wheelEvent, roundedPosition) == TrackingType::Synchronous
             || m_eventTrackingRegions.trackingTypeForPoint(names.mousewheelEvent, roundedPosition) == TrackingType::Synchronous;
         LOG_WITH_STREAM(Scrolling, stream << "ScrollingTree::shouldHandleWheelEventSynchronously: wheelEvent at " << wheelEvent.position() << " mapped to content point " << position << ", in non-fast region " << isSynchronousDispatchRegion);
@@ -83,10 +85,41 @@ void ScrollingTree::setOrClearLatchedNode(const PlatformWheelEvent& wheelEvent,
         clearLatchedNode();
 }
 
-void ScrollingTree::handleWheelEvent(const PlatformWheelEvent& wheelEvent)
+ScrollingEventResult ScrollingTree::handleWheelEvent(const PlatformWheelEvent& wheelEvent)
 {
-    if (m_rootNode)
-        downcast<ScrollingTreeScrollingNode>(*m_rootNode).handleWheelEvent(wheelEvent);
+    LOG_WITH_STREAM(Scrolling, stream << "ScrollingTree " << this << " handleWheelEvent (async scrolling enabled: " << asyncFrameOrOverflowScrollingEnabled() << ")");
+
+    if (!asyncFrameOrOverflowScrollingEnabled()) {
+        if (m_rootNode)
+            downcast<ScrollingTreeScrollingNode>(*m_rootNode).handleWheelEvent(wheelEvent);
+        return ScrollingEventResult::DidNotHandleEvent;
+    }
+
+    if (hasLatchedNode()) {
+        auto* node = nodeForID(latchedNode());
+        if (is<ScrollingTreeScrollingNode>(node))
+            return downcast<ScrollingTreeScrollingNode>(*node).handleWheelEvent(wheelEvent);
+    }
+
+    if (m_rootNode) {
+        auto& frameScrollingNode = downcast<ScrollingTreeFrameScrollingNode>(*m_rootNode);
+
+        FloatPoint position = wheelEvent.position();
+        ScrollingTreeNode* node = frameScrollingNode.scrollingNodeForPoint(LayoutPoint(position));
+
+        LOG_WITH_STREAM(Scrolling, stream << "ScrollingTree::handleWheelEvent found node " << (node ? node->scrollingNodeID() : 0) << " for point " << position << "\n");
+
+        while (node) {
+            if (is<ScrollingTreeScrollingNode>(*node)) {
+                auto& scrollingNode = downcast<ScrollingTreeScrollingNode>(*node);
+                // FIXME: this needs to consult latching logic.
+                if (scrollingNode.handleWheelEvent(wheelEvent) == ScrollingEventResult::DidHandleEvent)
+                    return ScrollingEventResult::DidHandleEvent;
+            }
+            node = node->parent();
+        }
+    }
+    return ScrollingEventResult::DidNotHandleEvent;
 }
 
 void ScrollingTree::viewportChangedViaDelegatedScrolling(ScrollingNodeID nodeID, const FloatRect& fixedPositionRect, double scale)
@@ -115,14 +148,15 @@ void ScrollingTree::commitTreeState(std::unique_ptr<ScrollingStateTree> scrollin
 {
     bool rootStateNodeChanged = scrollingStateTree->hasNewRootStateNode();
     
-    LOG(Scrolling, "\nScrollingTree::commitTreeState");
+    LOG(Scrolling, "\nScrollingTree %p commitTreeState", this);
     
     auto* rootNode = scrollingStateTree->rootStateNode();
     if (rootNode
         && (rootStateNodeChanged
             || rootNode->hasChangedProperty(ScrollingStateFrameScrollingNode::EventTrackingRegion)
             || rootNode->hasChangedProperty(ScrollingStateNode::ScrollLayer)
-            || rootNode->hasChangedProperty(ScrollingStateFrameScrollingNode::VisualViewportEnabled))) {
+            || rootNode->hasChangedProperty(ScrollingStateFrameScrollingNode::VisualViewportEnabled)
+            || rootNode->hasChangedProperty(ScrollingStateFrameScrollingNode::AsyncFrameOrOverflowScrollingEnabled))) {
         LockHolder lock(m_mutex);
 
         if (rootStateNodeChanged || rootNode->hasChangedProperty(ScrollingStateNode::ScrollLayer))
@@ -133,6 +167,9 @@ void ScrollingTree::commitTreeState(std::unique_ptr<ScrollingStateTree> scrollin
 
         if (rootStateNodeChanged || rootNode->hasChangedProperty(ScrollingStateFrameScrollingNode::VisualViewportEnabled))
             m_visualViewportEnabled = scrollingStateTree->rootStateNode()->visualViewportEnabled();
+
+        if (rootStateNodeChanged || rootNode->hasChangedProperty(ScrollingStateFrameScrollingNode::AsyncFrameOrOverflowScrollingEnabled))
+            m_asyncFrameOrOverflowScrollingEnabled = scrollingStateTree->rootStateNode()->asyncFrameOrOverflowScrollingEnabled();
     }
     
     bool scrollRequestIsProgammatic = rootNode ? rootNode->requestedScrollPositionRepresentsProgrammaticScroll() : false;
@@ -223,6 +260,12 @@ ScrollingTreeNode* ScrollingTree::nodeForID(ScrollingNodeID nodeID) const
     return m_nodeMap.get(nodeID);
 }
 
+void ScrollingTree::setAsyncFrameOrOverflowScrollingEnabled(bool enabled)
+{
+    LockHolder lock(m_mutex);
+    m_asyncFrameOrOverflowScrollingEnabled = enabled;
+}
+
 void ScrollingTree::setMainFramePinState(bool pinnedToTheLeft, bool pinnedToTheRight, bool pinnedToTheTop, bool pinnedToTheBottom)
 {
     LockHolder locker(m_swipeStateMutex);
index ec3dd6e..d937853 100644 (file)
@@ -50,19 +50,17 @@ public:
     WEBCORE_EXPORT ScrollingTree();
     WEBCORE_EXPORT virtual ~ScrollingTree();
 
-    enum EventResult {
-        DidNotHandleEvent,
-        DidHandleEvent,
-        SendToMainThread
-    };
-    
     virtual bool isThreadedScrollingTree() const { return false; }
     virtual bool isRemoteScrollingTree() const { return false; }
     virtual bool isScrollingTreeIOS() const { return false; }
 
     bool visualViewportEnabled() const { return m_visualViewportEnabled; }
 
-    virtual EventResult tryToHandleWheelEvent(const PlatformWheelEvent&) = 0;
+    // This implies that we'll do hit-testing in the scrolling tree.
+    bool asyncFrameOrOverflowScrollingEnabled() const { return m_asyncFrameOrOverflowScrollingEnabled; }
+    void setAsyncFrameOrOverflowScrollingEnabled(bool);
+
+    virtual ScrollingEventResult tryToHandleWheelEvent(const PlatformWheelEvent&) = 0;
     WEBCORE_EXPORT bool shouldHandleWheelEventSynchronously(const PlatformWheelEvent&);
     
     void setMainFrameIsRubberBanding(bool);
@@ -160,7 +158,7 @@ protected:
     void setMainFrameScrollPosition(FloatPoint);
     void setVisualViewportEnabled(bool b) { m_visualViewportEnabled = b; }
 
-    WEBCORE_EXPORT virtual void handleWheelEvent(const PlatformWheelEvent&);
+    WEBCORE_EXPORT virtual ScrollingEventResult handleWheelEvent(const PlatformWheelEvent&);
 
 private:
     using OrphanScrollingNodeMap = HashMap<ScrollingNodeID, RefPtr<ScrollingTreeNode>>;
@@ -196,6 +194,7 @@ private:
     bool m_scrollingPerformanceLoggingEnabled { false };
     bool m_isHandlingProgrammaticScroll { false };
     bool m_visualViewportEnabled { false };
+    bool m_asyncFrameOrOverflowScrollingEnabled { false };
 };
     
 } // namespace WebCore
index 24ad08f..e1607e7 100644 (file)
@@ -66,6 +66,11 @@ void ScrollingTreeFrameHostingNode::updateLayersAfterAncestorChange(const Scroll
         child->updateLayersAfterAncestorChange(changedNode, fixedPositionRect, cumulativeDelta);
 }
 
+LayoutPoint ScrollingTreeFrameHostingNode::parentToLocalPoint(LayoutPoint point) const
+{
+    return point - toLayoutSize(parentRelativeScrollableRect().location());
+}
+
 void ScrollingTreeFrameHostingNode::dumpProperties(TextStream& ts, ScrollingStateTreeAsTextBehavior behavior) const
 {
     ts << "frame hosting node";
index 5c3b797..ddf7adc 100644 (file)
@@ -46,6 +46,8 @@ private:
 
     const LayoutRect& parentRelativeScrollableRect() const { return m_parentRelativeScrollableRect; }
 
+    LayoutPoint parentToLocalPoint(LayoutPoint) const final;
+
     WEBCORE_EXPORT void dumpProperties(WTF::TextStream&, ScrollingStateTreeAsTextBehavior) const override;
 
     LayoutRect m_parentRelativeScrollableRect;
index f15a559..d0a9fb5 100644 (file)
@@ -126,6 +126,17 @@ FloatSize ScrollingTreeFrameScrollingNode::viewToContentsOffset(const FloatPoint
     return toFloatSize(scrollPosition) - FloatSize(0, headerHeight() + topContentInset());
 }
 
+LayoutPoint ScrollingTreeFrameScrollingNode::parentToLocalPoint(LayoutPoint point) const
+{
+    return point - LayoutSize(0, headerHeight() + topContentInset());
+}
+
+LayoutPoint ScrollingTreeFrameScrollingNode::localToContentsPoint(LayoutPoint point) const
+{
+    auto scrolledPoint = point + LayoutPoint(scrollPosition());
+    return scrolledPoint.scaled(1 / frameScaleFactor());
+}
+
 void ScrollingTreeFrameScrollingNode::dumpProperties(TextStream& ts, ScrollingStateTreeAsTextBehavior behavior) const
 {
     ts << "frame scrolling node";
index 7b08a67..18c913f 100644 (file)
@@ -44,7 +44,7 @@ public:
     // FIXME: We should implement this when we support ScrollingTreeScrollingNodes as children.
     void updateLayersAfterAncestorChange(const ScrollingTreeNode& /*changedNode*/, const FloatRect& /*fixedPositionRect*/, const FloatSize& /*cumulativeDelta*/) override { }
 
-    void handleWheelEvent(const PlatformWheelEvent&) override = 0;
+    ScrollingEventResult handleWheelEvent(const PlatformWheelEvent&) override = 0;
     void setScrollPosition(const FloatPoint&) override;
     void setScrollPositionWithoutContentEdgeConstraints(const FloatPoint&) override = 0;
 
@@ -80,6 +80,9 @@ protected:
     ScrollBehaviorForFixedElements scrollBehaviorForFixedElements() const { return m_behaviorForFixed; }
 
 private:
+    WEBCORE_EXPORT LayoutPoint parentToLocalPoint(LayoutPoint) const final;
+    WEBCORE_EXPORT LayoutPoint localToContentsPoint(LayoutPoint) const final;
+
     WEBCORE_EXPORT void dumpProperties(WTF::TextStream&, ScrollingStateTreeAsTextBehavior) const override;
 
     FloatRect m_layoutViewport;
index 0503cdb..5855d5e 100644 (file)
@@ -98,6 +98,21 @@ void ScrollingTreeNode::dump(TextStream& ts, ScrollingStateTreeAsTextBehavior be
     }
 }
 
+ScrollingTreeScrollingNode* ScrollingTreeNode::scrollingNodeForPoint(LayoutPoint parentPoint) const
+{
+    LayoutPoint localPoint = parentToLocalPoint(parentPoint);
+    LayoutPoint contentsPoint = localToContentsPoint(localPoint);
+
+    if (children()) {
+        for (auto iterator = children()->rbegin(), end = children()->rend(); iterator != end; iterator++) {
+            if (auto node = (**iterator).scrollingNodeForPoint(contentsPoint))
+                return node;
+        }
+    }
+
+    return nullptr;
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(ASYNC_SCROLLING)
index 2ae1a36..b5096ab 100644 (file)
@@ -40,6 +40,7 @@ namespace WebCore {
 class ScrollingStateFixedNode;
 class ScrollingStateScrollingNode;
 class ScrollingTreeFrameScrollingNode;
+class ScrollingTreeScrollingNode;
 
 class ScrollingTreeNode : public RefCounted<ScrollingTreeNode> {
 public:
@@ -64,6 +65,7 @@ public:
     void setParent(ScrollingTreeNode* parent) { m_parent = parent; }
 
     Vector<RefPtr<ScrollingTreeNode>>* children() { return m_children.get(); }
+    const Vector<RefPtr<ScrollingTreeNode>>* children() const { return m_children.get(); }
 
     void appendChild(Ref<ScrollingTreeNode>&&);
     void removeChild(ScrollingTreeNode&);
@@ -72,6 +74,10 @@ public:
 
     WEBCORE_EXPORT void dump(WTF::TextStream&, ScrollingStateTreeAsTextBehavior) const;
 
+    virtual LayoutPoint parentToLocalPoint(LayoutPoint point) const { return point; }
+    virtual LayoutPoint localToContentsPoint(LayoutPoint point) const { return point; }
+    virtual ScrollingTreeScrollingNode* scrollingNodeForPoint(LayoutPoint) const;
+
 protected:
     ScrollingTreeNode(ScrollingTree&, ScrollingNodeType, ScrollingNodeID);
     ScrollingTree& scrollingTree() const { return m_scrollingTree; }
index 6b56b1f..dcc96f1 100644 (file)
@@ -28,6 +28,7 @@
 
 #if ENABLE(ASYNC_SCROLLING)
 
+#include "Logging.h"
 #include "ScrollingStateScrollingNode.h"
 #include "ScrollingStateTree.h"
 #include "ScrollingTree.h"
@@ -133,6 +134,35 @@ FloatPoint ScrollingTreeScrollingNode::maximumScrollPosition() const
     return FloatPoint(contentSizePoint - scrollableAreaSize()).expandedTo(FloatPoint());
 }
 
+bool ScrollingTreeScrollingNode::scrollLimitReached(const PlatformWheelEvent& wheelEvent) const
+{
+    FloatPoint oldScrollPosition = scrollPosition();
+    FloatPoint newScrollPosition = oldScrollPosition + FloatSize(wheelEvent.deltaX(), -wheelEvent.deltaY());
+    newScrollPosition = newScrollPosition.constrainedBetween(minimumScrollPosition(), maximumScrollPosition());
+    return newScrollPosition == oldScrollPosition;
+}
+
+LayoutPoint ScrollingTreeScrollingNode::parentToLocalPoint(LayoutPoint point) const
+{
+    return point - toLayoutSize(parentRelativeScrollableRect().location());
+}
+
+LayoutPoint ScrollingTreeScrollingNode::localToContentsPoint(LayoutPoint point) const
+{
+    return point + LayoutPoint(scrollPosition());
+}
+
+ScrollingTreeScrollingNode* ScrollingTreeScrollingNode::scrollingNodeForPoint(LayoutPoint parentPoint) const
+{
+    if (auto* node = ScrollingTreeNode::scrollingNodeForPoint(parentPoint))
+        return node;
+
+    if (parentRelativeScrollableRect().contains(parentPoint))
+        return const_cast<ScrollingTreeScrollingNode*>(this);
+
+    return nullptr;
+}
+
 void ScrollingTreeScrollingNode::dumpProperties(TextStream& ts, ScrollingStateTreeAsTextBehavior behavior) const
 {
     ScrollingTreeNode::dumpProperties(ts, behavior);
index 70bd81d..f652b2d 100644 (file)
@@ -55,7 +55,7 @@ public:
 
     WEBCORE_EXPORT void updateLayersAfterAncestorChange(const ScrollingTreeNode& changedNode, const FloatRect& fixedPositionRect, const FloatSize& cumulativeDelta) override;
 
-    virtual void handleWheelEvent(const PlatformWheelEvent&) = 0;
+    virtual ScrollingEventResult handleWheelEvent(const PlatformWheelEvent&) = 0;
     WEBCORE_EXPORT virtual void setScrollPosition(const FloatPoint&);
     WEBCORE_EXPORT virtual void setScrollPositionWithoutContentEdgeConstraints(const FloatPoint&);
 
@@ -79,6 +79,9 @@ public:
 
     bool useDarkAppearanceForScrollbars() const { return m_scrollableAreaParameters.useDarkAppearanceForScrollbars; }
 
+    bool scrollLimitReached(const PlatformWheelEvent&) const;
+    WEBCORE_EXPORT ScrollingTreeScrollingNode* scrollingNodeForPoint(LayoutPoint) const override;
+
 protected:
     ScrollingTreeScrollingNode(ScrollingTree&, ScrollingNodeType, ScrollingNodeID);
 
@@ -106,6 +109,9 @@ protected:
 
     bool canHaveScrollbars() const { return m_scrollableAreaParameters.horizontalScrollbarMode != ScrollbarAlwaysOff || m_scrollableAreaParameters.verticalScrollbarMode != ScrollbarAlwaysOff; }
 
+    WEBCORE_EXPORT LayoutPoint parentToLocalPoint(LayoutPoint) const override;
+    WEBCORE_EXPORT LayoutPoint localToContentsPoint(LayoutPoint) const override;
+
     WEBCORE_EXPORT void dumpProperties(WTF::TextStream&, ScrollingStateTreeAsTextBehavior) const override;
 
 private:
index 06b3196..127b95f 100644 (file)
@@ -48,26 +48,26 @@ ThreadedScrollingTree::~ThreadedScrollingTree()
     ASSERT(!m_scrollingCoordinator);
 }
 
-ScrollingTree::EventResult ThreadedScrollingTree::tryToHandleWheelEvent(const PlatformWheelEvent& wheelEvent)
+ScrollingEventResult ThreadedScrollingTree::tryToHandleWheelEvent(const PlatformWheelEvent& wheelEvent)
 {
     if (shouldHandleWheelEventSynchronously(wheelEvent))
-        return SendToMainThread;
+        return ScrollingEventResult::SendToMainThread;
 
     if (willWheelEventStartSwipeGesture(wheelEvent))
-        return DidNotHandleEvent;
+        return ScrollingEventResult::DidNotHandleEvent;
 
     RefPtr<ThreadedScrollingTree> protectedThis(this);
     ScrollingThread::dispatch([protectedThis, wheelEvent] {
         protectedThis->handleWheelEvent(wheelEvent);
     });
     
-    return DidHandleEvent;
+    return ScrollingEventResult::DidHandleEvent;
 }
 
-void ThreadedScrollingTree::handleWheelEvent(const PlatformWheelEvent& wheelEvent)
+ScrollingEventResult ThreadedScrollingTree::handleWheelEvent(const PlatformWheelEvent& wheelEvent)
 {
     ASSERT(ScrollingThread::isCurrentThread());
-    ScrollingTree::handleWheelEvent(wheelEvent);
+    return ScrollingTree::handleWheelEvent(wheelEvent);
 }
 
 void ThreadedScrollingTree::invalidate()
index 402c2d9..e506ddd 100644 (file)
@@ -45,12 +45,12 @@ public:
 
     void commitTreeState(std::unique_ptr<ScrollingStateTree>) override;
 
-    void handleWheelEvent(const PlatformWheelEvent&) override;
+    ScrollingEventResult handleWheelEvent(const PlatformWheelEvent&) override;
 
     // Can be called from any thread. Will try to handle the wheel event on the scrolling thread.
     // Returns true if the wheel event can be handled on the scrolling thread and false if the
     // event must be sent again to the WebCore event handler.
-    EventResult tryToHandleWheelEvent(const PlatformWheelEvent&) override;
+    ScrollingEventResult tryToHandleWheelEvent(const PlatformWheelEvent&) override;
 
     void invalidate() override;
 
index 595304c..9cf639e 100644 (file)
@@ -47,7 +47,7 @@ public:
     void commitTreeStateIfNeeded() override;
 
     // Handle the wheel event on the scrolling thread. Returns whether the event was handled or not.
-    bool handleWheelEvent(FrameView&, const PlatformWheelEvent&) override { return false; }
+    ScrollingEventResult handleWheelEvent(FrameView&, const PlatformWheelEvent&) override { return ScrollingEventResult::DidNotHandleEvent; }
 
 private:
     void scheduleTreeStateCommit() override;
index 56a4790..8a61a0f 100644 (file)
@@ -46,7 +46,7 @@ protected:
     void commitStateBeforeChildren(const ScrollingStateNode&) override;
     void commitStateAfterChildren(const ScrollingStateNode&) override;
 
-    void handleWheelEvent(const PlatformWheelEvent&) override { }
+    ScrollingEventResult handleWheelEvent(const PlatformWheelEvent&) override;
 
     FloatPoint scrollPosition() const override;
     void setScrollPositionWithoutContentEdgeConstraints(const FloatPoint&) override;
index 24debd0..a4146a2 100644 (file)
@@ -96,6 +96,11 @@ void ScrollingTreeFrameScrollingNodeIOS::commitStateAfterChildren(const Scrollin
         setScrollPosition(scrollingStateNode.requestedScrollPosition());
 }
 
+ScrollingEventResult ScrollingTreeFrameScrollingNodeIOS::handleWheelEvent(const PlatformWheelEvent&)
+{
+    return ScrollingEventResult::DidNotHandleEvent;
+}
+
 FloatPoint ScrollingTreeFrameScrollingNodeIOS::scrollPosition() const
 {
     if (shouldUpdateScrollLayerPositionSynchronously())
index fcc7ee2..e9035d0 100644 (file)
@@ -45,8 +45,8 @@ private:
     bool isScrollingTreeIOS() const final { return true; }
 
     // No wheel events on iOS
-    void handleWheelEvent(const PlatformWheelEvent&) final { }
-    EventResult tryToHandleWheelEvent(const PlatformWheelEvent&) final { return DidNotHandleEvent; }
+    ScrollingEventResult handleWheelEvent(const PlatformWheelEvent&) final { return ScrollingEventResult::DidNotHandleEvent; }
+    ScrollingEventResult tryToHandleWheelEvent(const PlatformWheelEvent&) final { return ScrollingEventResult::DidNotHandleEvent; }
 
     void invalidate() final;
 
index abf0d79..893969b 100644 (file)
@@ -47,7 +47,7 @@ public:
     void commitTreeStateIfNeeded() override;
 
     // Handle the wheel event on the scrolling thread. Returns whether the event was handled or not.
-    bool handleWheelEvent(FrameView&, const PlatformWheelEvent&) override;
+    ScrollingEventResult handleWheelEvent(FrameView&, const PlatformWheelEvent&) override;
 
 private:
     void scheduleTreeStateCommit() override;
index 572e427..d157ceb 100644 (file)
@@ -82,19 +82,19 @@ void ScrollingCoordinatorMac::commitTreeStateIfNeeded()
     m_scrollingStateTreeCommitterTimer.stop();
 }
 
-bool ScrollingCoordinatorMac::handleWheelEvent(FrameView&, const PlatformWheelEvent& wheelEvent)
+ScrollingEventResult ScrollingCoordinatorMac::handleWheelEvent(FrameView&, const PlatformWheelEvent& wheelEvent)
 {
     ASSERT(isMainThread());
     ASSERT(m_page);
 
     if (scrollingTree()->willWheelEventStartSwipeGesture(wheelEvent))
-        return false;
+        return ScrollingEventResult::DidNotHandleEvent;
 
     RefPtr<ThreadedScrollingTree> threadedScrollingTree = downcast<ThreadedScrollingTree>(scrollingTree());
     ScrollingThread::dispatch([threadedScrollingTree, wheelEvent] {
         threadedScrollingTree->handleWheelEvent(wheelEvent);
     });
-    return true;
+    return ScrollingEventResult::DidHandleEvent;
 }
 
 void ScrollingCoordinatorMac::scheduleTreeStateCommit()
index 5faf3fb..178f1af 100644 (file)
@@ -51,7 +51,7 @@ protected:
     void commitStateBeforeChildren(const ScrollingStateNode&) override;
     void commitStateAfterChildren(const ScrollingStateNode&) override;
 
-    void handleWheelEvent(const PlatformWheelEvent&) override;
+    ScrollingEventResult handleWheelEvent(const PlatformWheelEvent&) override;
 
     // ScrollController member functions.
     bool allowsHorizontalStretching(const PlatformWheelEvent&) override;
index 06cb849..b716979 100644 (file)
@@ -184,10 +184,10 @@ void ScrollingTreeFrameScrollingNodeMac::commitStateAfterChildren(const Scrollin
         updateMainFramePinState(scrollPosition());
 }
 
-void ScrollingTreeFrameScrollingNodeMac::handleWheelEvent(const PlatformWheelEvent& wheelEvent)
+ScrollingEventResult ScrollingTreeFrameScrollingNodeMac::handleWheelEvent(const PlatformWheelEvent& wheelEvent)
 {
     if (!canHaveScrollbars())
-        return;
+        return ScrollingEventResult::DidNotHandleEvent;
 
     if (wheelEvent.momentumPhase() == PlatformWheelEventPhaseBegan) {
         [m_verticalScrollerImp setUsePresentationValue:YES];
@@ -215,6 +215,9 @@ void ScrollingTreeFrameScrollingNodeMac::handleWheelEvent(const PlatformWheelEve
 #endif
     scrollingTree().setOrClearLatchedNode(wheelEvent, scrollingNodeID());
     scrollingTree().handleWheelEventPhase(wheelEvent.phase());
+    
+    // FIXME: This needs to return whether the event was handled.
+    return ScrollingEventResult::DidHandleEvent;
 }
 
 // FIXME: We should find a way to share some of the code from newGestureIsStarting(), isAlreadyPinnedInDirectionOfGesture(),
index f1eedbe..ce397b9 100644 (file)
@@ -51,7 +51,7 @@ private:
 
     void updateLayersAfterAncestorChange(const WebCore::ScrollingTreeNode& changedNode, const WebCore::FloatRect& fixedPositionRect, const WebCore::FloatSize& cumulativeDelta) override;
 
-    void handleWheelEvent(const WebCore::PlatformWheelEvent&) override { }
+    ScrollingEventResult handleWheelEvent(const WebCore::PlatformWheelEvent&) override { return ScrollingEventResult::DidNotHandleEvent; }
 };
 
 } // namespace WebKit
index 68eaa98..0d343ab 100644 (file)
@@ -67,9 +67,9 @@ void ScrollingCoordinatorNicosia::commitTreeStateIfNeeded()
     m_scrollingStateTreeCommitterTimer.stop();
 }
 
-bool ScrollingCoordinatorNicosia::handleWheelEvent(FrameView&, const PlatformWheelEvent&)
+ScrollingEventResult ScrollingCoordinatorNicosia::handleWheelEvent(FrameView&, const PlatformWheelEvent&)
 {
-    return false;
+    return ScrollingEventResult::DidNotHandleEvent;
 }
 
 void ScrollingCoordinatorNicosia::scheduleTreeStateCommit()
index 71cc9fa..237d7c2 100644 (file)
@@ -44,7 +44,7 @@ public:
 
     void commitTreeStateIfNeeded() override;
 
-    bool handleWheelEvent(FrameView&, const PlatformWheelEvent&) override;
+    ScrollingEventResult handleWheelEvent(FrameView&, const PlatformWheelEvent&) override;
 
 private:
     void scheduleTreeStateCommit() override;
index 9b049b8..a94c98a 100644 (file)
@@ -44,8 +44,9 @@ ScrollingTreeFrameScrollingNodeNicosia::ScrollingTreeFrameScrollingNodeNicosia(S
 
 ScrollingTreeFrameScrollingNodeNicosia::~ScrollingTreeFrameScrollingNodeNicosia() = default;
 
-void ScrollingTreeFrameScrollingNodeNicosia::handleWheelEvent(const PlatformWheelEvent&)
+ScrollingEventResult ScrollingTreeFrameScrollingNodeNicosia::handleWheelEvent(const PlatformWheelEvent&)
 {
+    return ScrollingEventResult::DidNotHandleEvent;
 }
 
 FloatPoint ScrollingTreeFrameScrollingNodeNicosia::scrollPosition() const
index 2dc4823..0cc2816 100644 (file)
@@ -41,7 +41,7 @@ public:
 private:
     ScrollingTreeFrameScrollingNodeNicosia(ScrollingTree&, ScrollingNodeType, ScrollingNodeID);
 
-    void handleWheelEvent(const PlatformWheelEvent&) override;
+    ScrollingEventResult handleWheelEvent(const PlatformWheelEvent&) override;
 
     FloatPoint scrollPosition() const override;
     void setScrollPosition(const FloatPoint&) override;
index 98a4222..c2a65d2 100644 (file)
@@ -31,6 +31,7 @@
 #if ENABLE(ASYNC_SCROLLING) && USE(NICOSIA)
 
 #include "ScrollingTreeFixedNode.h"
+#include "ScrollingTreeFrameHostingNode.h"
 #include "ScrollingTreeFrameScrollingNodeNicosia.h"
 #include "ScrollingTreeStickyNode.h"
 
@@ -52,6 +53,8 @@ Ref<ScrollingTreeNode> ScrollingTreeNicosia::createScrollingTreeNode(ScrollingNo
     case ScrollingNodeType::MainFrame:
     case ScrollingNodeType::Subframe:
         return ScrollingTreeFrameScrollingNodeNicosia::create(*this, nodeType, nodeID);
+    case ScrollingNodeType::FrameHosting:
+        return ScrollingTreeFrameHostingNode::create(*this, nodeID);
     case ScrollingNodeType::Overflow:
         // Should not be reached -- caught by ASSERT_NOT_REACHED() below.
         break;
index 7d0ced4..dd09e1b 100644 (file)
@@ -1,3 +1,25 @@
+2019-01-30  Simon Fraser  <simon.fraser@apple.com>
+
+        [Mac] Implement basic hit testing in the scrolling tree
+        https://bugs.webkit.org/show_bug.cgi?id=172917
+        <rdar://problem/34215516>
+
+        Reviewed by Antti Koivisto.
+
+        Changed return types, "using namespace WebCore" in ScrollingTreeFrameScrollingNodeRemoteMac.cpp.
+
+        * Shared/RemoteLayerTree/RemoteScrollingCoordinatorTransaction.cpp:
+        (ArgumentCoder<ScrollingStateFrameScrollingNode>::encode):
+        * UIProcess/RemoteLayerTree/ios/ScrollingTreeOverflowScrollingNodeIOS.h:
+        * UIProcess/RemoteLayerTree/mac/ScrollerPairMac.h:
+        * UIProcess/RemoteLayerTree/mac/ScrollerPairMac.mm:
+        (WebKit::ScrollerPairMac::handleWheelEvent):
+        (WebKit::ScrollerPairMac::handleMouseEvent):
+        * UIProcess/RemoteLayerTree/mac/ScrollingTreeFrameScrollingNodeRemoteMac.cpp:
+        (WebKit::ScrollingTreeFrameScrollingNodeRemoteMac::handleWheelEvent):
+        (WebKit::ScrollingTreeFrameScrollingNodeRemoteMac::handleMouseEvent):
+        * UIProcess/RemoteLayerTree/mac/ScrollingTreeFrameScrollingNodeRemoteMac.h:
+
 2019-01-31  Michael Catanzaro  <mcatanzaro@igalia.com>
 
         [SOUP] Move cookiePersistentStoragePath and cookiePersistentStorageType from NetworkProcess to NetworkSession
index 0d01f33..8b38a42 100644 (file)
@@ -158,6 +158,7 @@ void ArgumentCoder<ScrollingStateFrameScrollingNode>::encode(Encoder& encoder, c
     SCROLLING_NODE_ENCODE(ScrollingStateFrameScrollingNode::TopContentInset, topContentInset)
     SCROLLING_NODE_ENCODE(ScrollingStateFrameScrollingNode::FixedElementsLayoutRelativeToFrame, fixedElementsLayoutRelativeToFrame)
     SCROLLING_NODE_ENCODE(ScrollingStateFrameScrollingNode::VisualViewportEnabled, visualViewportEnabled)
+    // AsyncFrameOrOverflowScrollingEnabled is not relevant for UI-side compositing.
     SCROLLING_NODE_ENCODE(ScrollingStateFrameScrollingNode::LayoutViewport, layoutViewport)
     SCROLLING_NODE_ENCODE(ScrollingStateFrameScrollingNode::MinLayoutViewportOrigin, minLayoutViewportOrigin)
     SCROLLING_NODE_ENCODE(ScrollingStateFrameScrollingNode::MaxLayoutViewportOrigin, maxLayoutViewportOrigin)
index f964fc9..9752e95 100644 (file)
@@ -151,8 +151,8 @@ void RemoteScrollingCoordinatorProxy::connectStateNodeLayers(ScrollingStateTree&
 
 bool RemoteScrollingCoordinatorProxy::handleWheelEvent(const PlatformWheelEvent& event)
 {
-    ScrollingTree::EventResult result = m_scrollingTree->tryToHandleWheelEvent(event);
-    return result == ScrollingTree::DidHandleEvent; // FIXME: handle other values.
+    ScrollingEventResult result = m_scrollingTree->tryToHandleWheelEvent(event);
+    return result == ScrollingEventResult::DidHandleEvent; // FIXME: handle other values.
 }
 
 void RemoteScrollingCoordinatorProxy::handleMouseEvent(const WebCore::PlatformMouseEvent& event)
index 26d9709..f30e25c 100644 (file)
@@ -59,16 +59,16 @@ RemoteScrollingTree::~RemoteScrollingTree()
 {
 }
 
-ScrollingTree::EventResult RemoteScrollingTree::tryToHandleWheelEvent(const PlatformWheelEvent& wheelEvent)
+ScrollingEventResult RemoteScrollingTree::tryToHandleWheelEvent(const PlatformWheelEvent& wheelEvent)
 {
     if (shouldHandleWheelEventSynchronously(wheelEvent))
-        return SendToMainThread;
+        return ScrollingEventResult::SendToMainThread;
 
     if (willWheelEventStartSwipeGesture(wheelEvent))
-        return DidNotHandleEvent;
+        return ScrollingEventResult::DidNotHandleEvent;
 
     handleWheelEvent(wheelEvent);
-    return DidHandleEvent;
+    return ScrollingEventResult::DidHandleEvent;
 }
 
 #if PLATFORM(MAC)
index 685b4f5..a5f4652 100644 (file)
@@ -45,7 +45,7 @@ public:
     virtual ~RemoteScrollingTree();
 
     bool isRemoteScrollingTree() const override { return true; }
-    EventResult tryToHandleWheelEvent(const WebCore::PlatformWheelEvent&) override;
+    WebCore::ScrollingEventResult tryToHandleWheelEvent(const WebCore::PlatformWheelEvent&) override;
 
     void handleMouseEvent(const WebCore::PlatformMouseEvent&);
 
index 842a987..bfbeb08 100644 (file)
@@ -53,7 +53,7 @@ private:
 
     void updateLayersAfterAncestorChange(const WebCore::ScrollingTreeNode& changedNode, const WebCore::FloatRect& fixedPositionRect, const WebCore::FloatSize& cumulativeDelta) override;
 
-    void handleWheelEvent(const WebCore::PlatformWheelEvent&) override { }
+    WebCore::ScrollingEventResult handleWheelEvent(const WebCore::PlatformWheelEvent&) override { return ScrollingEventResult::DidNotHandleEvent; }
 
     std::unique_ptr<ScrollingTreeScrollingNodeDelegateIOS> m_scrollingNodeDelegate;
 };
index f0725a0..b310b10 100644 (file)
@@ -52,8 +52,8 @@ public:
     ScrollerMac& verticalScroller() { return m_verticalScroller; }
     ScrollerMac& horizontalScroller() { return m_horizontalScroller; }
 
-    void handleWheelEvent(const WebCore::PlatformWheelEvent&);
-    void handleMouseEvent(const WebCore::PlatformMouseEvent&);
+    bool handleWheelEvent(const WebCore::PlatformWheelEvent&);
+    bool handleMouseEvent(const WebCore::PlatformMouseEvent&);
 
     void updateValues();
 
index 9b9f678..c226fc5 100644 (file)
@@ -141,7 +141,7 @@ ScrollerPairMac::~ScrollerPairMac()
     [m_scrollerImpPair setDelegate:nil];
 }
 
-void ScrollerPairMac::handleWheelEvent(const WebCore::PlatformWheelEvent& event)
+bool ScrollerPairMac::handleWheelEvent(const WebCore::PlatformWheelEvent& event)
 {
     switch (event.phase()) {
     case WebCore::PlatformWheelEventPhaseBegan:
@@ -158,15 +158,19 @@ void ScrollerPairMac::handleWheelEvent(const WebCore::PlatformWheelEvent& event)
     default:
         break;
     }
+    // FIXME: this needs to return whether the event was handled.
+    return true;
 }
 
-void ScrollerPairMac::handleMouseEvent(const WebCore::PlatformMouseEvent& event)
+bool ScrollerPairMac::handleMouseEvent(const WebCore::PlatformMouseEvent& event)
 {
     if (event.type() != WebCore::PlatformEvent::MouseMoved)
-        return;
+        return false;
 
     m_lastKnownMousePosition = event.position();
     [m_scrollerImpPair mouseMovedInContentArea];
+    // FIXME: this needs to return whether the event was handled.
+    return true;
 }
 
 void ScrollerPairMac::updateValues()
index 90866dc..80e8eef 100644 (file)
 #include "ScrollerPairMac.h"
 
 namespace WebKit {
+using namespace WebCore;
 
-ScrollingTreeFrameScrollingNodeRemoteMac::ScrollingTreeFrameScrollingNodeRemoteMac(WebCore::ScrollingTree& tree, WebCore::ScrollingNodeType nodeType, WebCore::ScrollingNodeID nodeID)
-    : WebCore::ScrollingTreeFrameScrollingNodeMac(tree, nodeType, nodeID)
+ScrollingTreeFrameScrollingNodeRemoteMac::ScrollingTreeFrameScrollingNodeRemoteMac(ScrollingTree& tree, ScrollingNodeType nodeType, ScrollingNodeID nodeID)
+    : ScrollingTreeFrameScrollingNodeMac(tree, nodeType, nodeID)
     , m_scrollerPair(std::make_unique<ScrollerPairMac>(*this))
 {
 }
@@ -43,42 +44,42 @@ ScrollingTreeFrameScrollingNodeRemoteMac::~ScrollingTreeFrameScrollingNodeRemote
 {
 }
 
-Ref<ScrollingTreeFrameScrollingNodeRemoteMac> ScrollingTreeFrameScrollingNodeRemoteMac::create(WebCore::ScrollingTree& tree, WebCore::ScrollingNodeType nodeType, WebCore::ScrollingNodeID nodeID)
+Ref<ScrollingTreeFrameScrollingNodeRemoteMac> ScrollingTreeFrameScrollingNodeRemoteMac::create(ScrollingTree& tree, ScrollingNodeType nodeType, ScrollingNodeID nodeID)
 {
     return adoptRef(*new ScrollingTreeFrameScrollingNodeRemoteMac(tree, nodeType, nodeID));
 }
 
-void ScrollingTreeFrameScrollingNodeRemoteMac::commitStateBeforeChildren(const WebCore::ScrollingStateNode& stateNode)
+void ScrollingTreeFrameScrollingNodeRemoteMac::commitStateBeforeChildren(const ScrollingStateNode& stateNode)
 {
-    WebCore::ScrollingTreeFrameScrollingNodeMac::commitStateBeforeChildren(stateNode);
-    const auto& scrollingStateNode = downcast<WebCore::ScrollingStateFrameScrollingNode>(stateNode);
+    ScrollingTreeFrameScrollingNodeMac::commitStateBeforeChildren(stateNode);
+    const auto& scrollingStateNode = downcast<ScrollingStateFrameScrollingNode>(stateNode);
 
-    if (scrollingStateNode.hasChangedProperty(WebCore::ScrollingStateFrameScrollingNode::VerticalScrollbarLayer))
+    if (scrollingStateNode.hasChangedProperty(ScrollingStateFrameScrollingNode::VerticalScrollbarLayer))
         m_scrollerPair->verticalScroller().setHostLayer(scrollingStateNode.verticalScrollbarLayer());
 
-    if (scrollingStateNode.hasChangedProperty(WebCore::ScrollingStateFrameScrollingNode::HorizontalScrollbarLayer))
+    if (scrollingStateNode.hasChangedProperty(ScrollingStateFrameScrollingNode::HorizontalScrollbarLayer))
         m_scrollerPair->horizontalScroller().setHostLayer(scrollingStateNode.horizontalScrollbarLayer());
 
     m_scrollerPair->updateValues();
 }
 
-void ScrollingTreeFrameScrollingNodeRemoteMac::setScrollLayerPosition(const WebCore::FloatPoint& position, const WebCore::FloatRect& layoutViewport)
+void ScrollingTreeFrameScrollingNodeRemoteMac::setScrollLayerPosition(const FloatPoint& position, const FloatRect& layoutViewport)
 {
     ScrollingTreeFrameScrollingNodeMac::setScrollLayerPosition(position, layoutViewport);
 
     m_scrollerPair->updateValues();
 }
 
-void ScrollingTreeFrameScrollingNodeRemoteMac::handleWheelEvent(const WebCore::PlatformWheelEvent& wheelEvent)
+ScrollingEventResult ScrollingTreeFrameScrollingNodeRemoteMac::handleWheelEvent(const PlatformWheelEvent& wheelEvent)
 {
     ScrollingTreeFrameScrollingNodeMac::handleWheelEvent(wheelEvent);
 
-    m_scrollerPair->handleWheelEvent(wheelEvent);
+    return m_scrollerPair->handleWheelEvent(wheelEvent) ? ScrollingEventResult::DidHandleEvent : ScrollingEventResult::DidNotHandleEvent;
 }
 
-void ScrollingTreeFrameScrollingNodeRemoteMac::handleMouseEvent(const WebCore::PlatformMouseEvent& mouseEvent)
+bool ScrollingTreeFrameScrollingNodeRemoteMac::handleMouseEvent(const PlatformMouseEvent& mouseEvent)
 {
-    m_scrollerPair->handleMouseEvent(mouseEvent);
+    return m_scrollerPair->handleMouseEvent(mouseEvent);
 }
 
 }
index f2c32b5..3c36847 100644 (file)
@@ -38,13 +38,13 @@ public:
     WEBCORE_EXPORT static Ref<ScrollingTreeFrameScrollingNodeRemoteMac> create(WebCore::ScrollingTree&, WebCore::ScrollingNodeType, WebCore::ScrollingNodeID);
     virtual ~ScrollingTreeFrameScrollingNodeRemoteMac();
 
-    void handleMouseEvent(const WebCore::PlatformMouseEvent&);
+    bool handleMouseEvent(const WebCore::PlatformMouseEvent&);
 
 private:
     ScrollingTreeFrameScrollingNodeRemoteMac(WebCore::ScrollingTree&, WebCore::ScrollingNodeType, WebCore::ScrollingNodeID);
 
     void commitStateBeforeChildren(const WebCore::ScrollingStateNode&) override;
-    void handleWheelEvent(const WebCore::PlatformWheelEvent&) override;
+    WebCore::ScrollingEventResult handleWheelEvent(const WebCore::PlatformWheelEvent&) override;
     void setScrollLayerPosition(const WebCore::FloatPoint& position, const WebCore::FloatRect& layoutViewport) override;
 
     std::unique_ptr<ScrollerPairMac> m_scrollerPair;
index 76c4826..691830b 100644 (file)
@@ -122,10 +122,10 @@ void EventDispatcher::wheelEvent(uint64_t pageID, const WebWheelEvent& wheelEven
         if (platformWheelEvent.phase() == PlatformWheelEventPhaseBegan)
             scrollingTree->setCanRubberBandState(canRubberBandAtLeft, canRubberBandAtRight, canRubberBandAtTop, canRubberBandAtBottom);
 
-        ScrollingTree::EventResult result = scrollingTree->tryToHandleWheelEvent(platformWheelEvent);
+        ScrollingEventResult result = scrollingTree->tryToHandleWheelEvent(platformWheelEvent);
 
-        if (result == ScrollingTree::DidHandleEvent || result == ScrollingTree::DidNotHandleEvent) {
-            sendDidReceiveEvent(pageID, wheelEvent, result == ScrollingTree::DidHandleEvent);
+        if (result == ScrollingEventResult::DidHandleEvent || result == ScrollingEventResult::DidNotHandleEvent) {
+            sendDidReceiveEvent(pageID, wheelEvent, result == ScrollingEventResult::DidHandleEvent);
             return;
         }
     }