Title: [268544] trunk
Revision
268544
Author
[email protected]
Date
2020-10-15 12:24:40 -0700 (Thu, 15 Oct 2020)

Log Message

Scrolls in the passive event region only send one wheel event to the DOM
https://bugs.webkit.org/show_bug.cgi?id=217719

Reviewed by Tim Horton.
Source/WebCore:

When we hit the scrolling thread latching codepath, we'd always use { WheelEventProcessingSteps::ScrollingThread }
for the steps, but that caused us to not send DOM events.

Latching has to store the steps from when latching occurs (we should not re-hit-test
to get the region state on every event), so fix up ScrollingTreeLatchingController to
do that.

Test: fast/scrolling/latching/latched-scroll-in-passive-region.html

* page/scrolling/ScrollingTree.cpp:
(WebCore::ScrollingTree::determineWheelEventProcessing):
(WebCore::ScrollingTree::handleWheelEvent):
(WebCore::ScrollingTree::handleWheelEventWithNode):
* page/scrolling/ScrollingTree.h:
* page/scrolling/ScrollingTreeLatchingController.cpp:
(WebCore::ScrollingTreeLatchingController::receivedWheelEvent):
(WebCore::ScrollingTreeLatchingController::latchingDataForEvent const):
(WebCore::ScrollingTreeLatchingController::latchedNodeID const):
(WebCore::ScrollingTreeLatchingController::latchedNodeAndSteps const):
(WebCore::ScrollingTreeLatchingController::nodeDidHandleEvent):
(WebCore::ScrollingTreeLatchingController::nodeWasRemoved):
(WebCore::ScrollingTreeLatchingController::clearLatchedNode):
(WebCore::ScrollingTreeLatchingController::latchedNodeForEvent const): Deleted.
* page/scrolling/ScrollingTreeLatchingController.h:
* page/scrolling/ThreadedScrollingTree.cpp:
(WebCore::ThreadedScrollingTree::handleWheelEventAfterMainThread):

LayoutTests:

* fast/scrolling/latching/latched-scroll-in-passive-region-expected.txt: Added.
* fast/scrolling/latching/latched-scroll-in-passive-region.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (268543 => 268544)


--- trunk/LayoutTests/ChangeLog	2020-10-15 19:12:02 UTC (rev 268543)
+++ trunk/LayoutTests/ChangeLog	2020-10-15 19:24:40 UTC (rev 268544)
@@ -1,3 +1,13 @@
+2020-10-15  Simon Fraser  <[email protected]>
+
+        Scrolls in the passive event region only send one wheel event to the DOM
+        https://bugs.webkit.org/show_bug.cgi?id=217719
+
+        Reviewed by Tim Horton.
+
+        * fast/scrolling/latching/latched-scroll-in-passive-region-expected.txt: Added.
+        * fast/scrolling/latching/latched-scroll-in-passive-region.html: Added.
+
 2020-10-15  Andres Gonzalez  <[email protected]>
 
         Fix for multiple accessibility layout tests in isolated tree mode.

Added: trunk/LayoutTests/fast/scrolling/latching/latched-scroll-in-passive-region-expected.txt (0 => 268544)


--- trunk/LayoutTests/fast/scrolling/latching/latched-scroll-in-passive-region-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/scrolling/latching/latched-scroll-in-passive-region-expected.txt	2020-10-15 19:24:40 UTC (rev 268544)
@@ -0,0 +1,10 @@
+Tests that a gesture in the passive wheel event region dispatches more than one wheel event
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS wheelEventHandlerCount > 4 is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/scrolling/latching/latched-scroll-in-passive-region.html (0 => 268544)


--- trunk/LayoutTests/fast/scrolling/latching/latched-scroll-in-passive-region.html	                        (rev 0)
+++ trunk/LayoutTests/fast/scrolling/latching/latched-scroll-in-passive-region.html	2020-10-15 19:24:40 UTC (rev 268544)
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+    body {
+        height: 3000px;
+    }
+    </style>
+<script src=""
+<script src=""
+<script>
+    jsTestIsAsync = true;
+
+    let wheelEventHandlerCount = 0;
+    async function scrollTest()
+    {
+        window.addEventListener('wheel', (event) => {
+            ++wheelEventHandlerCount;
+            event.preventDefault();
+        }, { passive: true });
+
+        await UIHelper.renderingUpdate();
+
+        eventSender.mouseMoveTo(100, 10);
+        eventSender.monitorWheelEvents();
+        eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none');
+        eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none');
+        eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none');
+        eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none');
+        eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'begin');
+        eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue');
+        
+        await UIHelper.renderingUpdate();
+        eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue');
+        await UIHelper.renderingUpdate();
+        eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue');
+        await UIHelper.renderingUpdate();
+        eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue');
+        await UIHelper.renderingUpdate();
+        eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue');
+        await UIHelper.renderingUpdate();
+        eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue');
+        await UIHelper.renderingUpdate();
+        eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'none', 'end');
+
+        await UIHelper.waitForScrollCompletion();
+
+        shouldBeTrue('wheelEventHandlerCount > 4');
+
+        finishJSTest();
+    }
+
+    window.addEventListener('load', () => {
+        description("Tests that a gesture in the passive wheel event region dispatches more than one wheel event");
+        scrollTest();
+    }, false);
+</script>
+</head>
+<body>
+    <div id="wheel-handler-region"></div>
+    <div id="console"></div>
+<script src=""
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (268543 => 268544)


--- trunk/Source/WebCore/ChangeLog	2020-10-15 19:12:02 UTC (rev 268543)
+++ trunk/Source/WebCore/ChangeLog	2020-10-15 19:24:40 UTC (rev 268544)
@@ -1,3 +1,37 @@
+2020-10-15  Simon Fraser  <[email protected]>
+
+        Scrolls in the passive event region only send one wheel event to the DOM
+        https://bugs.webkit.org/show_bug.cgi?id=217719
+
+        Reviewed by Tim Horton.
+        
+        When we hit the scrolling thread latching codepath, we'd always use { WheelEventProcessingSteps::ScrollingThread }
+        for the steps, but that caused us to not send DOM events.
+
+        Latching has to store the steps from when latching occurs (we should not re-hit-test
+        to get the region state on every event), so fix up ScrollingTreeLatchingController to
+        do that.
+
+        Test: fast/scrolling/latching/latched-scroll-in-passive-region.html
+
+        * page/scrolling/ScrollingTree.cpp:
+        (WebCore::ScrollingTree::determineWheelEventProcessing):
+        (WebCore::ScrollingTree::handleWheelEvent):
+        (WebCore::ScrollingTree::handleWheelEventWithNode):
+        * page/scrolling/ScrollingTree.h:
+        * page/scrolling/ScrollingTreeLatchingController.cpp:
+        (WebCore::ScrollingTreeLatchingController::receivedWheelEvent):
+        (WebCore::ScrollingTreeLatchingController::latchingDataForEvent const):
+        (WebCore::ScrollingTreeLatchingController::latchedNodeID const):
+        (WebCore::ScrollingTreeLatchingController::latchedNodeAndSteps const):
+        (WebCore::ScrollingTreeLatchingController::nodeDidHandleEvent):
+        (WebCore::ScrollingTreeLatchingController::nodeWasRemoved):
+        (WebCore::ScrollingTreeLatchingController::clearLatchedNode):
+        (WebCore::ScrollingTreeLatchingController::latchedNodeForEvent const): Deleted.
+        * page/scrolling/ScrollingTreeLatchingController.h:
+        * page/scrolling/ThreadedScrollingTree.cpp:
+        (WebCore::ThreadedScrollingTree::handleWheelEventAfterMainThread):
+
 2020-10-15  Andres Gonzalez  <[email protected]>
 
         Fix for multiple accessibility layout tests in isolated tree mode.

Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp (268543 => 268544)


--- trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp	2020-10-15 19:12:02 UTC (rev 268543)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp	2020-10-15 19:24:40 UTC (rev 268544)
@@ -68,10 +68,11 @@
     // This method is invoked by the event handling thread
     LockHolder lock(m_treeStateMutex);
 
-    auto latchedNode = m_latchingController.latchedNodeForEvent(wheelEvent, m_allowLatching);
-    LOG_WITH_STREAM(ScrollLatching, stream << "ScrollingTree::shouldHandleWheelEventSynchronously " << wheelEvent << " have latched node " << latchedNode);
-    if (latchedNode)
-        return { WheelEventProcessingSteps::ScrollingThread };
+    auto latchedNodeAndSteps = m_latchingController.latchingDataForEvent(wheelEvent, m_allowLatching);
+    if (latchedNodeAndSteps) {
+        LOG_WITH_STREAM(ScrollLatching, stream << "ScrollingTree::determineWheelEventProcessing " << wheelEvent << " have latched node " << latchedNodeAndSteps->scrollingNodeID << " steps " << latchedNodeAndSteps->processingSteps);
+        return latchedNodeAndSteps->processingSteps;
+    }
 
     m_latchingController.receivedWheelEvent(wheelEvent, m_allowLatching);
 
@@ -135,14 +136,14 @@
 
         m_gestureState.receivedWheelEvent(wheelEvent);
 
-        if (auto latchedNodeID = m_latchingController.latchedNodeForEvent(wheelEvent, m_allowLatching)) {
-            LOG_WITH_STREAM(ScrollLatching, stream << "ScrollingTree::handleWheelEvent: has latched node " << latchedNodeID);
-            auto* node = nodeForID(*latchedNodeID);
+        if (auto latchedNodeAndSteps = m_latchingController.latchingDataForEvent(wheelEvent, m_allowLatching)) {
+            LOG_WITH_STREAM(ScrollLatching, stream << "ScrollingTree::handleWheelEvent: has latched node " << latchedNodeAndSteps->scrollingNodeID);
+            auto* node = nodeForID(latchedNodeAndSteps->scrollingNodeID);
             if (is<ScrollingTreeScrollingNode>(node)) {
                 auto result = downcast<ScrollingTreeScrollingNode>(*node).handleWheelEvent(wheelEvent);
                 if (result.wasHandled) {
-                    m_latchingController.nodeDidHandleEvent(*latchedNodeID, wheelEvent, m_allowLatching);
-                    m_gestureState.nodeDidHandleEvent(*latchedNodeID, wheelEvent);
+                    m_latchingController.nodeDidHandleEvent(latchedNodeAndSteps->scrollingNodeID, processingSteps, wheelEvent, m_allowLatching);
+                    m_gestureState.nodeDidHandleEvent(latchedNodeAndSteps->scrollingNodeID, wheelEvent);
                 }
                 return result;
             }
@@ -154,7 +155,7 @@
 
         LOG_WITH_STREAM(Scrolling, stream << "ScrollingTree::handleWheelEvent found node " << (node ? node->scrollingNodeID() : 0) << " for point " << position);
 
-        return handleWheelEventWithNode(wheelEvent, node.get());
+        return handleWheelEventWithNode(wheelEvent, processingSteps, node.get());
     }();
 
     result.steps.add(processingSteps & WheelEventProcessingSteps::MainThreadForDOMEventDispatch);
@@ -161,7 +162,7 @@
     return result;
 }
 
-WheelEventHandlingResult ScrollingTree::handleWheelEventWithNode(const PlatformWheelEvent& wheelEvent, ScrollingTreeNode* node)
+WheelEventHandlingResult ScrollingTree::handleWheelEventWithNode(const PlatformWheelEvent& wheelEvent, OptionSet<WheelEventProcessingSteps> processingSteps, ScrollingTreeNode* node)
 {
     while (node) {
         if (is<ScrollingTreeScrollingNode>(*node)) {
@@ -169,7 +170,7 @@
             auto result = scrollingNode.handleWheelEvent(wheelEvent);
 
             if (result.wasHandled) {
-                m_latchingController.nodeDidHandleEvent(scrollingNode.scrollingNodeID(), wheelEvent, m_allowLatching);
+                m_latchingController.nodeDidHandleEvent(scrollingNode.scrollingNodeID(), processingSteps, wheelEvent, m_allowLatching);
                 m_gestureState.nodeDidHandleEvent(scrollingNode.scrollingNodeID(), wheelEvent);
                 return result;
             }

Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.h (268543 => 268544)


--- trunk/Source/WebCore/page/scrolling/ScrollingTree.h	2020-10-15 19:12:02 UTC (rev 268543)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.h	2020-10-15 19:24:40 UTC (rev 268544)
@@ -212,7 +212,7 @@
     WEBCORE_EXPORT void willProcessWheelEvent();
 
 protected:
-    WheelEventHandlingResult handleWheelEventWithNode(const PlatformWheelEvent&, ScrollingTreeNode*);
+    WheelEventHandlingResult handleWheelEventWithNode(const PlatformWheelEvent&, OptionSet<WheelEventProcessingSteps>, ScrollingTreeNode*);
 
     FloatPoint mainFrameScrollPosition() const;
     void setMainFrameScrollPosition(FloatPoint);

Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeLatchingController.cpp (268543 => 268544)


--- trunk/Source/WebCore/page/scrolling/ScrollingTreeLatchingController.cpp	2020-10-15 19:12:02 UTC (rev 268543)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeLatchingController.cpp	2020-10-15 19:24:40 UTC (rev 268544)
@@ -47,13 +47,13 @@
         return;
 
     LockHolder locker(m_latchedNodeMutex);
-    if (wheelEvent.isGestureStart() && m_latchedNodeID && !latchedNodeIsRelevant()) {
+    if (wheelEvent.isGestureStart() && m_latchedNodeAndSteps && !latchedNodeIsRelevant()) {
         LOG_WITH_STREAM(ScrollLatching, stream << "ScrollingTreeLatchingController " << this << " receivedWheelEvent - " << (MonotonicTime::now() - m_lastLatchedNodeInterationTime).milliseconds() << "ms since last event, clearing latched node");
-        m_latchedNodeID.reset();
+        m_latchedNodeAndSteps.reset();
     }
 }
 
-Optional<ScrollingNodeID> ScrollingTreeLatchingController::latchedNodeForEvent(const PlatformWheelEvent& wheelEvent, bool allowLatching) const
+Optional<ScrollingTreeLatchingController::ScrollingNodeAndProcessingSteps> ScrollingTreeLatchingController::latchingDataForEvent(const PlatformWheelEvent& wheelEvent, bool allowLatching) const
 {
     if (!allowLatching)
         return WTF::nullopt;
@@ -61,9 +61,9 @@
     LockHolder locker(m_latchedNodeMutex);
 
     // If we have a latched node, use it.
-    if (wheelEvent.useLatchedEventElement() && m_latchedNodeID && latchedNodeIsRelevant()) {
-        LOG_WITH_STREAM(ScrollLatching, stream << "ScrollingTreeLatchingController " << this << " latchedNodeForEvent: returning " << m_latchedNodeID);
-        return m_latchedNodeID.value();
+    if (wheelEvent.useLatchedEventElement() && m_latchedNodeAndSteps && latchedNodeIsRelevant()) {
+        LOG_WITH_STREAM(ScrollLatching, stream << "ScrollingTreeLatchingController " << this << " latchedNodeForEvent: returning " << m_latchedNodeAndSteps->scrollingNodeID);
+        return m_latchedNodeAndSteps;
     }
 
     return WTF::nullopt;
@@ -72,17 +72,26 @@
 Optional<ScrollingNodeID> ScrollingTreeLatchingController::latchedNodeID() const
 {
     LockHolder locker(m_latchedNodeMutex);
-    return m_latchedNodeID;
+    if (m_latchedNodeAndSteps)
+        return m_latchedNodeAndSteps->scrollingNodeID;
+
+    return WTF::nullopt;
 }
 
-void ScrollingTreeLatchingController::nodeDidHandleEvent(ScrollingNodeID scrollingNodeID, const PlatformWheelEvent& wheelEvent, bool allowLatching)
+Optional<ScrollingTreeLatchingController::ScrollingNodeAndProcessingSteps> ScrollingTreeLatchingController::latchedNodeAndSteps() const
 {
+    LockHolder locker(m_latchedNodeMutex);
+    return m_latchedNodeAndSteps;
+}
+
+void ScrollingTreeLatchingController::nodeDidHandleEvent(ScrollingNodeID scrollingNodeID, OptionSet<WheelEventProcessingSteps> processingSteps, const PlatformWheelEvent& wheelEvent, bool allowLatching)
+{
     if (!allowLatching)
         return;
 
     LockHolder locker(m_latchedNodeMutex);
 
-    if (wheelEvent.useLatchedEventElement() && m_latchedNodeID == scrollingNodeID) {
+    if (wheelEvent.useLatchedEventElement() && m_latchedNodeAndSteps && m_latchedNodeAndSteps->scrollingNodeID == scrollingNodeID) {
         m_lastLatchedNodeInterationTime = MonotonicTime::now();
         return;
     }
@@ -91,7 +100,7 @@
         return;
 
     LOG_WITH_STREAM(ScrollLatching, stream << "ScrollingTreeLatchingController " << this << " nodeDidHandleEvent: latching to " << scrollingNodeID);
-    m_latchedNodeID = scrollingNodeID;
+    m_latchedNodeAndSteps = ScrollingNodeAndProcessingSteps { scrollingNodeID, processingSteps };
     m_lastLatchedNodeInterationTime = MonotonicTime::now();
 }
 
@@ -98,15 +107,15 @@
 void ScrollingTreeLatchingController::nodeWasRemoved(ScrollingNodeID nodeID)
 {
     LockHolder locker(m_latchedNodeMutex);
-    if (nodeID == m_latchedNodeID)
-        m_latchedNodeID.reset();
+    if (m_latchedNodeAndSteps && m_latchedNodeAndSteps->scrollingNodeID == nodeID)
+        m_latchedNodeAndSteps.reset();
 }
 
 void ScrollingTreeLatchingController::clearLatchedNode()
 {
     LockHolder locker(m_latchedNodeMutex);
-    LOG_WITH_STREAM(ScrollLatching, stream << "ScrollingTreeLatchingController " << this << " clearLatchedNode (was " << m_latchedNodeID << ")");
-    m_latchedNodeID.reset();
+    LOG_WITH_STREAM(ScrollLatching, stream << "ScrollingTreeLatchingController " << this << " clearLatchedNode");
+    m_latchedNodeAndSteps.reset();
 }
 
 bool ScrollingTreeLatchingController::latchedNodeIsRelevant() const

Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeLatchingController.h (268543 => 268544)


--- trunk/Source/WebCore/page/scrolling/ScrollingTreeLatchingController.h	2020-10-15 19:12:02 UTC (rev 268543)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeLatchingController.h	2020-10-15 19:24:40 UTC (rev 268544)
@@ -39,13 +39,20 @@
 
 class ScrollingTreeLatchingController {
 public:
+    struct ScrollingNodeAndProcessingSteps {
+        ScrollingNodeID scrollingNodeID;
+        OptionSet<WheelEventProcessingSteps> processingSteps;
+    };
+
     ScrollingTreeLatchingController();
 
     void receivedWheelEvent(const PlatformWheelEvent&, bool allowLatching);
-    Optional<ScrollingNodeID> latchedNodeForEvent(const PlatformWheelEvent&, bool allowLatching) const;
-    void nodeDidHandleEvent(ScrollingNodeID, const PlatformWheelEvent&, bool allowLatching);
 
+    Optional<ScrollingNodeAndProcessingSteps> latchingDataForEvent(const PlatformWheelEvent&, bool allowLatching) const;
+    void nodeDidHandleEvent(ScrollingNodeID, OptionSet<WheelEventProcessingSteps>, const PlatformWheelEvent&, bool allowLatching);
+
     Optional<ScrollingNodeID> latchedNodeID() const;
+    Optional<ScrollingNodeAndProcessingSteps> latchedNodeAndSteps() const;
 
     void nodeWasRemoved(ScrollingNodeID);
     void clearLatchedNode();
@@ -54,7 +61,7 @@
     bool latchedNodeIsRelevant() const;
 
     mutable Lock m_latchedNodeMutex;
-    Markable<ScrollingNodeID, IntegralMarkableTraits<ScrollingNodeID, 0>> m_latchedNodeID;
+    Optional<ScrollingNodeAndProcessingSteps> m_latchedNodeAndSteps;
     MonotonicTime m_lastLatchedNodeInterationTime;
 };
 

Modified: trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp (268543 => 268544)


--- trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp	2020-10-15 19:12:02 UTC (rev 268543)
+++ trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp	2020-10-15 19:24:40 UTC (rev 268544)
@@ -70,7 +70,7 @@
     SetForScope<bool> disallowLatchingScope(m_allowLatching, false);
 
     RefPtr<ScrollingTreeNode> targetNode = nodeForID(targetNodeID);
-    auto result = handleWheelEventWithNode(wheelEvent, targetNode.get());
+    auto result = handleWheelEventWithNode(wheelEvent, { }, targetNode.get());
     return result.wasHandled;
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to