Title: [269973] trunk
Revision
269973
Author
[email protected]
Date
2020-11-18 12:14:43 -0800 (Wed, 18 Nov 2020)

Log Message

Propagate wheel event handling back to the scrolling thread
https://bugs.webkit.org/show_bug.cgi?id=219050

Reviewed by Chris Dumez.
Source/WebCore:

Prepare to fix webkit.org/b/218764 by adding a way for the main thread to communicate back
to the scrolling thread information about whether the wheel event was dispatched to JS,
and whether preventDefault() was called on it.

The EventHandling enum has bits that are set when the event is dispatched to JS,
when it's canceled, and if default handling happened. These values are filled in
Element::dispatchWheelEvent(). They propagate back to the scrolling thread via
EventHandler::wheelEventWasProcessedByMainThread(), whose macOS implementation
calls into the ScrollingCoordinator, which will set state on the ScrollingTree in
a future patch.

WheelEventTestMonitor gains a "reason" flag to track the async propagation of
wheelEventWasProcessedByMainThread() back to the scrolling thread.

This patch also adds infrastructure for the scrolling thread to specify that wheel events
sent to the main thread will be uncancelable; WheelEventProcessingSteps gains
MainThreadForNonBlockingDOMEventDispatch and MainThreadForBlockingDOMEventDispatch,
and if MainThreadForNonBlockingDOMEventDispatch is set, then we create
WheelEvents with IsCancelable::No. This will be the case for wheel events in
the passive event region.

Rename ScrollingCoordinator::handleWheelEvent() to performDefaultWheelEventHandling()
for clarity, and stop passing the FrameView* which was unused.

Add a missing lock in ThreadedScrollingTree::handleWheelEventAfterMainThread().

* dom/Element.cpp:
(WebCore::Element::dispatchWheelEvent):
* dom/Element.h:
* dom/WheelEvent.cpp:
(WebCore::WheelEvent::WheelEvent):
(WebCore::WheelEvent::create):
* dom/WheelEvent.h:
* page/EventHandler.cpp:
(WebCore::EventHandler::wheelEventWasProcessedByMainThread):
(WebCore::EventHandler::handleWheelEvent):
(WebCore::EventHandler::handleWheelEventInternal):
* page/EventHandler.h:
* page/FrameView.cpp:
(WebCore::FrameView::wheelEvent):
* page/PointerLockController.cpp:
(WebCore::PointerLockController::dispatchLockedWheelEvent):
* page/WheelEventTestMonitor.cpp:
(WebCore::operator<<):
* page/WheelEventTestMonitor.h:
* page/ios/EventHandlerIOS.mm:
(WebCore::EventHandler::wheelEvent):
* page/mac/EventHandlerMac.mm:
(WebCore::EventHandler::wheelEvent):
(WebCore::EventHandler::wheelEventWasProcessedByMainThread):
* page/scrolling/ScrollingCoordinator.h:
(WebCore::ScrollingCoordinator::performDefaultWheelEventHandling):
(WebCore::ScrollingCoordinator::wheelEventWasProcessedByMainThread):
(WebCore::ScrollingCoordinator::handleWheelEvent): Deleted.
* page/scrolling/ScrollingTree.cpp:
(WebCore::ScrollingTree::determineWheelEventProcessing):
(WebCore::ScrollingTree::handleWheelEvent):
* page/scrolling/ScrollingTree.h:
(WebCore::WheelEventHandlingResult::needsMainThreadProcessing const):
* page/scrolling/ScrollingTreeLatchingController.cpp:
(WebCore::ScrollingTreeLatchingController::receivedWheelEvent): Send in WheelEventProcessingSteps which
a future patch will use.
* page/scrolling/ScrollingTreeLatchingController.h:
* page/scrolling/ThreadedScrollingTree.cpp:
(WebCore::ThreadedScrollingTree::handleWheelEventAfterMainThread): There was a missing lock here.
(WebCore::ThreadedScrollingTree::wheelEventWasProcessedByMainThread):
* page/scrolling/ThreadedScrollingTree.h:
* page/scrolling/mac/ScrollingCoordinatorMac.h:
* page/scrolling/mac/ScrollingCoordinatorMac.mm:
(WebCore::ScrollingCoordinatorMac::performDefaultWheelEventHandling):
(WebCore::nextDeferIdentifier):
(WebCore::ScrollingCoordinatorMac::wheelEventWasProcessedByMainThread):
(WebCore::ScrollingCoordinatorMac::handleWheelEvent): Deleted.
* page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.mm:
(WebCore::ScrollingTreeOverflowScrollingNodeMac::handleWheelEvent):
* page/scrolling/nicosia/ScrollingCoordinatorNicosia.cpp:
(WebCore::ScrollingCoordinatorNicosia::performDefaultWheelEventHandling):
(WebCore::ScrollingCoordinatorNicosia::wheelEventWasProcessedByMainThread):
(WebCore::ScrollingCoordinatorNicosia::handleWheelEvent): Deleted.
* page/scrolling/nicosia/ScrollingCoordinatorNicosia.h:
* platform/PlatformEvent.h:
* platform/PlatformWheelEvent.cpp:
(WebCore::operator<<): Add dumping of EventHandling.
* platform/PlatformWheelEvent.h:

Source/WebKit:

For now, use MainThreadForBlockingDOMEventDispatch for the default steps (used by non-macOS platforms).

* UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp:
(WebKit::RemoteScrollingCoordinatorProxy::handleWheelEvent):
* WebProcess/WebPage/EventDispatcher.cpp:
(WebKit::EventDispatcher::wheelEvent):

Source/WebKitLegacy/win:

Use MainThreadForBlockingDOMEventDispatch.

* WebView.cpp:
(WebView::mouseWheel):

LayoutTests:

* fast/events/wheel/wheel-event-in-passive-region-non-cancelable-expected.txt: Added.
* fast/events/wheel/wheel-event-in-passive-region-non-cancelable.html: Added.
* platform/mac-wk1/TestExpectations:
* platform/win/TestExpectations:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (269972 => 269973)


--- trunk/LayoutTests/ChangeLog	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/LayoutTests/ChangeLog	2020-11-18 20:14:43 UTC (rev 269973)
@@ -1,3 +1,15 @@
+2020-11-18  Simon Fraser  <[email protected]>
+
+        Propagate wheel event handling back to the scrolling thread
+        https://bugs.webkit.org/show_bug.cgi?id=219050
+
+        Reviewed by Chris Dumez.
+
+        * fast/events/wheel/wheel-event-in-passive-region-non-cancelable-expected.txt: Added.
+        * fast/events/wheel/wheel-event-in-passive-region-non-cancelable.html: Added.
+        * platform/mac-wk1/TestExpectations:
+        * platform/win/TestExpectations:
+
 2020-11-18  Chris Dumez  <[email protected]>
 
         [Rosetta] webaudio/BiquadFilter/tail-time-*.html tests are flaky

Added: trunk/LayoutTests/fast/events/wheel/wheel-event-in-passive-region-non-cancelable-expected.txt (0 => 269973)


--- trunk/LayoutTests/fast/events/wheel/wheel-event-in-passive-region-non-cancelable-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/events/wheel/wheel-event-in-passive-region-non-cancelable-expected.txt	2020-11-18 20:14:43 UTC (rev 269973)
@@ -0,0 +1,8 @@
+Tests that wheel events in the passive region are non-cancelable
+PASS windowScrollEventCount > 0 is true
+PASS wasCancelable is false
+PASS wasCanceled is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/events/wheel/wheel-event-in-passive-region-non-cancelable.html (0 => 269973)


--- trunk/LayoutTests/fast/events/wheel/wheel-event-in-passive-region-non-cancelable.html	                        (rev 0)
+++ trunk/LayoutTests/fast/events/wheel/wheel-event-in-passive-region-non-cancelable.html	2020-11-18 20:14:43 UTC (rev 269973)
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <style>
+        body {
+            height: 5000px;
+        }
+        
+        #target {
+            width: 200px;
+            height: 200px;
+            background-color: silver;
+            margin: 20px;
+        }
+    </style>
+    <script src=""
+    <script src=""
+    <script>
+        var jsTestIsAsync = true;
+
+        let isFirst = true;
+        let windowScrollEventCount = 0;
+        let wasCancelable;
+        let wasCanceled;
+
+        async function testScroll()
+        {
+            await UIHelper.mouseWheelScrollAt(100, 100);
+            shouldBeTrue('windowScrollEventCount > 0');
+
+            shouldBeFalse('wasCancelable');
+            shouldBeFalse('wasCanceled');
+
+            finishJSTest();
+        }
+
+        window.addEventListener('load', () => {
+            debug('Tests that wheel events in the passive region are non-cancelable')
+            let target = document.getElementById('target');
+
+            target.addEventListener('wheel', (event) => {
+                if (isFirst) {
+                    wasCancelable = event.cancelable;
+                    event.preventDefault();
+                    wasCanceled = event.defaultPrevented;
+                    isFirst = false;
+                }
+                
+            }, { passive: true });
+
+            window.addEventListener('scroll', () => {
+                ++windowScrollEventCount;
+            }, false);
+
+            setTimeout(testScroll, 0);
+        }, false);
+    </script>
+</head>
+<body>
+    <div id="target"></div>
+    <div id="console"></div>
+    <script src=""
+</body>
+</html>

Modified: trunk/LayoutTests/platform/mac-wk1/TestExpectations (269972 => 269973)


--- trunk/LayoutTests/platform/mac-wk1/TestExpectations	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/LayoutTests/platform/mac-wk1/TestExpectations	2020-11-18 20:14:43 UTC (rev 269973)
@@ -492,6 +492,9 @@
 fast/scrolling/scroll-animator-overlay-scrollbars-clicked.html [ Skip ]
 fast/scrolling/scroll-animator-overlay-scrollbars-hovered.html [ Skip ]
 
+# Tests that require async scrolling
+fast/events/wheel/wheel-event-in-passive-region-non-cancelable.html [ Skip ]
+
 # WK1 main frame scrollbars are native widgets whose size is unaffected by webkit-scrollbar.
 fast/visual-viewport/viewport-dimensions-exclude-custom-scrollbars.html [ Skip ]
 

Modified: trunk/LayoutTests/platform/win/TestExpectations (269972 => 269973)


--- trunk/LayoutTests/platform/win/TestExpectations	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/LayoutTests/platform/win/TestExpectations	2020-11-18 20:14:43 UTC (rev 269973)
@@ -275,10 +275,13 @@
 fast/events/wheel/platform-wheelevent-in-scrolling-div.html [ Failure Timeout ]
 fast/events/wheel/wheelevent-in-horizontal-scrollbar-in-rtl.html [ Failure ]
 fast/events/wheel/wheelevent-in-vertical-scrollbar-in-rtl.html [ Failure ]
+
+# Need async scrolling
 fast/events/wheel/wheel-event-listeners-on-body-made-passive.html [ Skip ]
 fast/events/wheel/wheel-event-listeners-on-document-made-passive.html [ Skip ]
 fast/events/wheel/wheel-event-listeners-on-window-left-active.html [ Skip ]
 fast/events/wheel/wheel-event-listeners-on-window-made-passive.html [ Skip ]
+fast/events/wheel/wheel-event-in-passive-region-non-cancelable.html [ Skip ]
 
 scrollbars/scroll-rtl-or-bt-layer.html [ Timeout ]
 webkit.org/b/208559 fast/scrolling/arrow-key-scroll-in-rtl-document.html [ Skip ]

Modified: trunk/Source/WebCore/ChangeLog (269972 => 269973)


--- trunk/Source/WebCore/ChangeLog	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/Source/WebCore/ChangeLog	2020-11-18 20:14:43 UTC (rev 269973)
@@ -1,3 +1,95 @@
+2020-11-18  Simon Fraser  <[email protected]>
+
+        Propagate wheel event handling back to the scrolling thread
+        https://bugs.webkit.org/show_bug.cgi?id=219050
+
+        Reviewed by Chris Dumez.
+
+        Prepare to fix webkit.org/b/218764 by adding a way for the main thread to communicate back
+        to the scrolling thread information about whether the wheel event was dispatched to JS,
+        and whether preventDefault() was called on it.
+
+        The EventHandling enum has bits that are set when the event is dispatched to JS,
+        when it's canceled, and if default handling happened. These values are filled in
+        Element::dispatchWheelEvent(). They propagate back to the scrolling thread via
+        EventHandler::wheelEventWasProcessedByMainThread(), whose macOS implementation
+        calls into the ScrollingCoordinator, which will set state on the ScrollingTree in
+        a future patch.
+
+        WheelEventTestMonitor gains a "reason" flag to track the async propagation of
+        wheelEventWasProcessedByMainThread() back to the scrolling thread.
+
+        This patch also adds infrastructure for the scrolling thread to specify that wheel events
+        sent to the main thread will be uncancelable; WheelEventProcessingSteps gains
+        MainThreadForNonBlockingDOMEventDispatch and MainThreadForBlockingDOMEventDispatch,
+        and if MainThreadForNonBlockingDOMEventDispatch is set, then we create
+        WheelEvents with IsCancelable::No. This will be the case for wheel events in
+        the passive event region.
+
+        Rename ScrollingCoordinator::handleWheelEvent() to performDefaultWheelEventHandling()
+        for clarity, and stop passing the FrameView* which was unused.
+
+        Add a missing lock in ThreadedScrollingTree::handleWheelEventAfterMainThread().
+
+        * dom/Element.cpp:
+        (WebCore::Element::dispatchWheelEvent):
+        * dom/Element.h:
+        * dom/WheelEvent.cpp:
+        (WebCore::WheelEvent::WheelEvent):
+        (WebCore::WheelEvent::create):
+        * dom/WheelEvent.h:
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::wheelEventWasProcessedByMainThread):
+        (WebCore::EventHandler::handleWheelEvent):
+        (WebCore::EventHandler::handleWheelEventInternal):
+        * page/EventHandler.h:
+        * page/FrameView.cpp:
+        (WebCore::FrameView::wheelEvent):
+        * page/PointerLockController.cpp:
+        (WebCore::PointerLockController::dispatchLockedWheelEvent):
+        * page/WheelEventTestMonitor.cpp:
+        (WebCore::operator<<):
+        * page/WheelEventTestMonitor.h:
+        * page/ios/EventHandlerIOS.mm:
+        (WebCore::EventHandler::wheelEvent):
+        * page/mac/EventHandlerMac.mm:
+        (WebCore::EventHandler::wheelEvent):
+        (WebCore::EventHandler::wheelEventWasProcessedByMainThread):
+        * page/scrolling/ScrollingCoordinator.h:
+        (WebCore::ScrollingCoordinator::performDefaultWheelEventHandling):
+        (WebCore::ScrollingCoordinator::wheelEventWasProcessedByMainThread):
+        (WebCore::ScrollingCoordinator::handleWheelEvent): Deleted.
+        * page/scrolling/ScrollingTree.cpp:
+        (WebCore::ScrollingTree::determineWheelEventProcessing):
+        (WebCore::ScrollingTree::handleWheelEvent):
+        * page/scrolling/ScrollingTree.h:
+        (WebCore::WheelEventHandlingResult::needsMainThreadProcessing const):
+        * page/scrolling/ScrollingTreeLatchingController.cpp:
+        (WebCore::ScrollingTreeLatchingController::receivedWheelEvent): Send in WheelEventProcessingSteps which
+        a future patch will use.
+        * page/scrolling/ScrollingTreeLatchingController.h:
+        * page/scrolling/ThreadedScrollingTree.cpp:
+        (WebCore::ThreadedScrollingTree::handleWheelEventAfterMainThread): There was a missing lock here.
+        (WebCore::ThreadedScrollingTree::wheelEventWasProcessedByMainThread):
+        * page/scrolling/ThreadedScrollingTree.h:
+        * page/scrolling/mac/ScrollingCoordinatorMac.h:
+        * page/scrolling/mac/ScrollingCoordinatorMac.mm:
+        (WebCore::ScrollingCoordinatorMac::performDefaultWheelEventHandling):
+        (WebCore::nextDeferIdentifier):
+        (WebCore::ScrollingCoordinatorMac::wheelEventWasProcessedByMainThread):
+        (WebCore::ScrollingCoordinatorMac::handleWheelEvent): Deleted.
+        * page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.mm:
+        (WebCore::ScrollingTreeOverflowScrollingNodeMac::handleWheelEvent):
+        * page/scrolling/nicosia/ScrollingCoordinatorNicosia.cpp:
+        (WebCore::ScrollingCoordinatorNicosia::performDefaultWheelEventHandling):
+        (WebCore::ScrollingCoordinatorNicosia::wheelEventWasProcessedByMainThread):
+        (WebCore::ScrollingCoordinatorNicosia::handleWheelEvent): Deleted.
+        * page/scrolling/nicosia/ScrollingCoordinatorNicosia.h:
+        * platform/PlatformEvent.h:
+        * platform/PlatformWheelEvent.cpp:
+        (WebCore::operator<<): Add dumping of EventHandling.
+        * platform/PlatformWheelEvent.h:
+
 2020-11-18  Antoine Quint  <[email protected]>
 
         [Web Animations] Ensure we don't schedule animation udpates when there are no styles to update

Modified: trunk/Source/WebCore/dom/Element.cpp (269972 => 269973)


--- trunk/Source/WebCore/dom/Element.cpp	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/Source/WebCore/dom/Element.cpp	2020-11-18 20:14:43 UTC (rev 269973)
@@ -420,9 +420,9 @@
     return didNotSwallowEvent;
 }
 
-bool Element::dispatchWheelEvent(const PlatformWheelEvent& platformEvent)
+bool Element::dispatchWheelEvent(const PlatformWheelEvent& platformEvent, OptionSet<EventHandling>& processing, Event::IsCancelable isCancelable)
 {
-    auto event = WheelEvent::create(platformEvent, document().windowProxy());
+    auto event = WheelEvent::create(platformEvent, document().windowProxy(), isCancelable);
 
     // Events with no deltas are important because they convey platform information about scroll gestures
     // and momentum beginning or ending. However, those events should not be sent to the DOM since some
@@ -430,12 +430,21 @@
     // event handler, and our platform code will correctly handle the phase changes. Calling stopPropagation()
     // will prevent the event from being sent to the DOM, but will still call the default event handler.
     // FIXME: Move this logic into WheelEvent::create.
-    if (!platformEvent.deltaX() && !platformEvent.deltaY())
+    if (platformEvent.delta().isZero())
         event->stopPropagation();
+    else
+        processing.add(EventHandling::DispatchedToDOM);
 
     dispatchEvent(event);
     
     LOG_WITH_STREAM(Scrolling, stream << "Element " << *this << " dispatchWheelEvent: defaultPrevented " << event->defaultPrevented() << " defaultHandled " << event->defaultHandled());
+    
+    if (event->defaultPrevented())
+        processing.add(EventHandling::DefaultPrevented);
+
+    if (event->defaultHandled())
+        processing.add(EventHandling::DefaultHandled);
+
     return !event->defaultPrevented() && !event->defaultHandled();
 }
 

Modified: trunk/Source/WebCore/dom/Element.h (269972 => 269973)


--- trunk/Source/WebCore/dom/Element.h	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/Source/WebCore/dom/Element.h	2020-11-18 20:14:43 UTC (rev 269973)
@@ -66,6 +66,8 @@
 struct ScrollIntoViewOptions;
 struct ScrollToOptions;
 
+enum class EventProcessing : uint8_t;
+
 #if ENABLE(INTERSECTION_OBSERVER)
 struct IntersectionObserverData;
 #endif
@@ -530,7 +532,7 @@
     void setSavedLayerScrollPosition(const IntPoint&);
 
     bool dispatchMouseEvent(const PlatformMouseEvent&, const AtomString& eventType, int clickCount = 0, Element* relatedTarget = nullptr);
-    bool dispatchWheelEvent(const PlatformWheelEvent&);
+    bool dispatchWheelEvent(const PlatformWheelEvent&, OptionSet<EventHandling>&, Event::IsCancelable = Event::IsCancelable::Yes);
     bool dispatchKeyEvent(const PlatformKeyboardEvent&);
     bool dispatchSimulatedClick(Event* underlyingEvent, SimulatedClickMouseEventOptions = SendNoEvents, SimulatedClickVisualOptions = ShowPressedLook);
     void dispatchFocusInEvent(const AtomString& eventType, RefPtr<Element>&& oldFocusedElement);

Modified: trunk/Source/WebCore/dom/WheelEvent.cpp (269972 => 269973)


--- trunk/Source/WebCore/dom/WheelEvent.cpp	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/Source/WebCore/dom/WheelEvent.cpp	2020-11-18 20:14:43 UTC (rev 269973)
@@ -50,8 +50,8 @@
 {
 }
 
-inline WheelEvent::WheelEvent(const PlatformWheelEvent& event, RefPtr<WindowProxy>&& view)
-    : MouseEvent(eventNames().wheelEvent, CanBubble::Yes, IsCancelable::Yes, IsComposed::Yes, event.timestamp().approximateMonotonicTime(), WTFMove(view), 0,
+inline WheelEvent::WheelEvent(const PlatformWheelEvent& event, RefPtr<WindowProxy>&& view, IsCancelable isCancelable)
+    : MouseEvent(eventNames().wheelEvent, CanBubble::Yes, isCancelable, IsComposed::Yes, event.timestamp().approximateMonotonicTime(), WTFMove(view), 0,
         event.globalPosition(), event.position() , { }, event.modifiers(), 0, 0, nullptr, 0, 0, IsSimulated::No, IsTrusted::Yes)
     , m_wheelDelta(event.wheelTicksX() * TickMultiplier, event.wheelTicksY() * TickMultiplier)
     , m_deltaX(-event.deltaX())
@@ -61,9 +61,9 @@
 {
 }
 
-Ref<WheelEvent> WheelEvent::create(const PlatformWheelEvent& event, RefPtr<WindowProxy>&& view)
+Ref<WheelEvent> WheelEvent::create(const PlatformWheelEvent& event, RefPtr<WindowProxy>&& view, IsCancelable isCancelable)
 {
-    return adoptRef(*new WheelEvent(event, WTFMove(view)));
+    return adoptRef(*new WheelEvent(event, WTFMove(view), isCancelable));
 }
 
 Ref<WheelEvent> WheelEvent::createForBindings()

Modified: trunk/Source/WebCore/dom/WheelEvent.h (269972 => 269973)


--- trunk/Source/WebCore/dom/WheelEvent.h	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/Source/WebCore/dom/WheelEvent.h	2020-11-18 20:14:43 UTC (rev 269973)
@@ -40,7 +40,7 @@
         DOM_DELTA_PAGE
     };
 
-    static Ref<WheelEvent> create(const PlatformWheelEvent&, RefPtr<WindowProxy>&&);
+    static Ref<WheelEvent> create(const PlatformWheelEvent&, RefPtr<WindowProxy>&&, IsCancelable = IsCancelable::Yes);
     static Ref<WheelEvent> createForBindings();
 
     struct Init : MouseEventInit {
@@ -76,7 +76,7 @@
 private:
     WheelEvent();
     WheelEvent(const AtomString&, const Init&);
-    WheelEvent(const PlatformWheelEvent&, RefPtr<WindowProxy>&&);
+    WheelEvent(const PlatformWheelEvent&, RefPtr<WindowProxy>&&, IsCancelable);
 
     EventInterface eventInterface() const final;
 

Modified: trunk/Source/WebCore/page/EventHandler.cpp (269972 => 269973)


--- trunk/Source/WebCore/page/EventHandler.cpp	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/Source/WebCore/page/EventHandler.cpp	2020-11-18 20:14:43 UTC (rev 269973)
@@ -2792,6 +2792,10 @@
     return didHandleEvent;
 }
 
+void EventHandler::wheelEventWasProcessedByMainThread(const PlatformWheelEvent&, OptionSet<EventHandling>)
+{
+}
+
 bool EventHandler::platformCompletePlatformWidgetWheelEvent(const PlatformWheelEvent&, const Widget&, const WeakPtr<ScrollableArea>&)
 {
     return true;
@@ -2863,6 +2867,14 @@
 
 bool EventHandler::handleWheelEvent(const PlatformWheelEvent& event, OptionSet<WheelEventProcessingSteps> processingSteps)
 {
+    OptionSet<EventHandling> handling;
+    bool handled = handleWheelEventInternal(event, processingSteps, handling);
+    wheelEventWasProcessedByMainThread(event, handling);
+    return handled;
+}
+
+bool EventHandler::handleWheelEventInternal(const PlatformWheelEvent& event, OptionSet<WheelEventProcessingSteps> processingSteps, OptionSet<EventHandling>& handling)
+{
     auto* document = m_frame.document();
     if (!document)
         return false;
@@ -2924,7 +2936,8 @@
             }
         }
 
-        if (!element->dispatchWheelEvent(event)) {
+        auto isCancelable = processingSteps.contains(WheelEventProcessingSteps::MainThreadForBlockingDOMEventDispatch) ? Event::IsCancelable::Yes : Event::IsCancelable::No;
+        if (!element->dispatchWheelEvent(event, handling, isCancelable)) {
             m_isHandlingWheelEvent = false;
             if (scrollableArea && scrollableArea->scrollShouldClearLatchedState()) {
                 // Web developer is controlling scrolling, so don't attempt to latch.
@@ -2954,6 +2967,7 @@
         handledEvent = processWheelEventForScrolling(event, scrollableArea);
         processWheelEventForScrollSnap(event, scrollableArea);
     }
+
     return handledEvent;
 }
 

Modified: trunk/Source/WebCore/page/EventHandler.h (269972 => 269973)


--- trunk/Source/WebCore/page/EventHandler.h	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/Source/WebCore/page/EventHandler.h	2020-11-18 20:14:43 UTC (rev 269973)
@@ -208,8 +208,11 @@
     bool handleMouseMoveEvent(const PlatformMouseEvent&, HitTestResult* = nullptr, bool _onlyUpdateScrollbars_ = false);
     WEBCORE_EXPORT bool handleMouseReleaseEvent(const PlatformMouseEvent&);
     bool handleMouseForceEvent(const PlatformMouseEvent&);
+
     WEBCORE_EXPORT bool handleWheelEvent(const PlatformWheelEvent&, OptionSet<WheelEventProcessingSteps>);
     void defaultWheelEventHandler(Node*, WheelEvent&);
+    void wheelEventWasProcessedByMainThread(const PlatformWheelEvent&, OptionSet<EventHandling>);
+
     bool handlePasteGlobalSelection(const PlatformMouseEvent&);
 
 #if ENABLE(IOS_TOUCH_EVENTS) || ENABLE(IOS_GESTURE_EVENTS)
@@ -452,6 +455,7 @@
 
     bool passMouseDownEventToWidget(Widget*);
 
+    bool handleWheelEventInternal(const PlatformWheelEvent&, OptionSet<WheelEventProcessingSteps>, OptionSet<EventHandling>&);
     bool passWheelEventToWidget(const PlatformWheelEvent&, Widget&, OptionSet<WheelEventProcessingSteps>);
     void determineWheelEventTarget(const PlatformWheelEvent&, RefPtr<Element>& eventTarget, WeakPtr<ScrollableArea>&, bool& isOverWidget);
     void recordWheelEventForDeltaFilter(const PlatformWheelEvent&);

Modified: trunk/Source/WebCore/page/FrameView.cpp (269972 => 269973)


--- trunk/Source/WebCore/page/FrameView.cpp	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/Source/WebCore/page/FrameView.cpp	2020-11-18 20:14:43 UTC (rev 269973)
@@ -5128,7 +5128,7 @@
 #if ENABLE(ASYNC_SCROLLING)
     if (auto scrollingCoordinator = this->scrollingCoordinator()) {
         if (scrollingCoordinator->coordinatesScrollingForFrameView(*this))
-            return scrollingCoordinator->handleWheelEvent(*this, wheelEvent, scrollingNodeID());
+            return scrollingCoordinator->performDefaultWheelEventHandling(wheelEvent, scrollingNodeID());
     }
 #endif
 

Modified: trunk/Source/WebCore/page/PointerLockController.cpp (269972 => 269973)


--- trunk/Source/WebCore/page/PointerLockController.cpp	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/Source/WebCore/page/PointerLockController.cpp	2020-11-18 20:14:43 UTC (rev 269973)
@@ -193,7 +193,8 @@
     if (!m_element || !m_element->document().frame())
         return;
 
-    m_element->dispatchWheelEvent(event);
+    OptionSet<EventHandling> defaultHandling;
+    m_element->dispatchWheelEvent(event, defaultHandling);
 }
 
 void PointerLockController::clearElement()

Modified: trunk/Source/WebCore/page/WheelEventTestMonitor.cpp (269972 => 269973)


--- trunk/Source/WebCore/page/WheelEventTestMonitor.cpp	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/Source/WebCore/page/WheelEventTestMonitor.cpp	2020-11-18 20:14:43 UTC (rev 269973)
@@ -170,6 +170,7 @@
     switch (reason) {
     case WheelEventTestMonitor::HandlingWheelEvent: ts << "handling wheel event"; break;
     case WheelEventTestMonitor::HandlingWheelEventOnMainThread: ts << "handling wheel event on main thread"; break;
+    case WheelEventTestMonitor::ReportDOMEventHandling: ts << "report DOM event handling"; break;
     case WheelEventTestMonitor::RubberbandInProgress: ts << "rubberbanding"; break;
     case WheelEventTestMonitor::ScrollSnapInProgress: ts << "scroll-snapping"; break;
     case WheelEventTestMonitor::ScrollingThreadSyncNeeded: ts << "scrolling thread sync needed"; break;

Modified: trunk/Source/WebCore/page/WheelEventTestMonitor.h (269972 => 269973)


--- trunk/Source/WebCore/page/WheelEventTestMonitor.h	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/Source/WebCore/page/WheelEventTestMonitor.h	2020-11-18 20:14:43 UTC (rev 269973)
@@ -50,11 +50,12 @@
     enum DeferReason {
         HandlingWheelEvent              = 1 << 0,
         HandlingWheelEventOnMainThread  = 1 << 1,
-        RubberbandInProgress            = 1 << 2,
-        ScrollSnapInProgress            = 1 << 3,
-        ScrollingThreadSyncNeeded       = 1 << 4,
-        ContentScrollInProgress         = 1 << 5,
-        RequestedScrollPosition         = 1 << 6,
+        ReportDOMEventHandling          = 1 << 2,
+        RubberbandInProgress            = 1 << 3,
+        ScrollSnapInProgress            = 1 << 4,
+        ScrollingThreadSyncNeeded       = 1 << 5,
+        ContentScrollInProgress         = 1 << 6,
+        RequestedScrollPosition         = 1 << 7,
     };
     typedef const void* ScrollableAreaIdentifier;
 

Modified: trunk/Source/WebCore/page/ios/EventHandlerIOS.mm (269972 => 269973)


--- trunk/Source/WebCore/page/ios/EventHandlerIOS.mm	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/Source/WebCore/page/ios/EventHandlerIOS.mm	2020-11-18 20:14:43 UTC (rev 269973)
@@ -107,7 +107,7 @@
 
     CurrentEventScope scope(event);
 
-    bool eventWasHandled = handleWheelEvent(PlatformEventFactory::createPlatformWheelEvent(event), { WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForDOMEventDispatch });
+    bool eventWasHandled = handleWheelEvent(PlatformEventFactory::createPlatformWheelEvent(event), { WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForBlockingDOMEventDispatch });
     event.wasHandled = eventWasHandled;
     return eventWasHandled;
 }

Modified: trunk/Source/WebCore/page/mac/EventHandlerMac.mm (269972 => 269973)


--- trunk/Source/WebCore/page/mac/EventHandlerMac.mm	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/Source/WebCore/page/mac/EventHandlerMac.mm	2020-11-18 20:14:43 UTC (rev 269973)
@@ -63,6 +63,7 @@
 #import "ScrollLatchingController.h"
 #import "ScrollableArea.h"
 #import "Scrollbar.h"
+#import "ScrollingCoordinator.h"
 #import "Settings.h"
 #import "ShadowRoot.h"
 #import "SimpleRange.h"
@@ -146,7 +147,7 @@
         return false;
 
     CurrentEventScope scope(event, nil);
-    return handleWheelEvent(PlatformEventFactory::createPlatformWheelEvent(event, page->chrome().platformPageClient()), { WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForDOMEventDispatch });
+    return handleWheelEvent(PlatformEventFactory::createPlatformWheelEvent(event, page->chrome().platformPageClient()), { WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForBlockingDOMEventDispatch });
 }
 
 bool EventHandler::keyEvent(NSEvent *event)
@@ -952,6 +953,26 @@
     return didHandleEvent;
 }
 
+void EventHandler::wheelEventWasProcessedByMainThread(const PlatformWheelEvent& wheelEvent, OptionSet<EventHandling> eventHandling)
+{
+#if ENABLE(ASYNC_SCROLLING)
+    if (!m_frame.page())
+        return;
+
+    FrameView* view = m_frame.view();
+    if (!view)
+        return;
+
+    if (auto scrollingCoordinator = m_frame.page()->scrollingCoordinator()) {
+        if (scrollingCoordinator->coordinatesScrollingForFrameView(*view))
+            scrollingCoordinator->wheelEventWasProcessedByMainThread(wheelEvent, eventHandling);
+    }
+#else
+    UNUSED_PARAM(wheelEvent);
+    UNUSED_PARAM(eventHandling);
+#endif
+}
+
 bool EventHandler::platformCompletePlatformWidgetWheelEvent(const PlatformWheelEvent& wheelEvent, const Widget& widget, const WeakPtr<ScrollableArea>& scrollableArea)
 {
     // WebKit1: Prevent multiple copies of the scrollWheel event from being sent to the NSScrollView widget.

Modified: trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h (269972 => 269973)


--- trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h	2020-11-18 20:14:43 UTC (rev 269973)
@@ -127,7 +127,8 @@
     // These virtual functions are currently unique to the threaded scrolling architecture. 
     virtual void commitTreeStateIfNeeded() { }
     virtual bool requestScrollPositionUpdate(ScrollableArea&, const IntPoint&, ScrollType = ScrollType::Programmatic, ScrollClamping = ScrollClamping::Clamped) { return false; }
-    virtual bool handleWheelEvent(FrameView&, const PlatformWheelEvent&, ScrollingNodeID) { return false; }
+    virtual bool performDefaultWheelEventHandling(const PlatformWheelEvent&, ScrollingNodeID) { return false; }
+    virtual void wheelEventWasProcessedByMainThread(const PlatformWheelEvent&, OptionSet<EventHandling>) { }
 
     // Create an unparented node.
     virtual ScrollingNodeID createNode(ScrollingNodeType, ScrollingNodeID newNodeID) { return newNodeID; }

Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp (269972 => 269973)


--- trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp	2020-11-18 20:14:43 UTC (rev 269973)
@@ -74,8 +74,6 @@
         return latchedNodeAndSteps->processingSteps;
     }
 
-    m_latchingController.receivedWheelEvent(wheelEvent, m_allowLatching);
-
     auto processingSteps = [&]() -> OptionSet<WheelEventProcessingSteps> {
         if (!m_rootNode)
             return { WheelEventProcessingSteps::ScrollingThread };
@@ -93,20 +91,22 @@
             LOG_WITH_STREAM(Scrolling, stream << "\nScrollingTree::determineWheelEventProcessing: wheelEvent " << wheelEvent << " mapped to content point " << position << ", in non-fast region " << isSynchronousDispatchRegion);
 
             if (isSynchronousDispatchRegion)
-                return { WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForDOMEventDispatch };
+                return { WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForBlockingDOMEventDispatch };
         }
 
 #if ENABLE(WHEEL_EVENT_REGIONS)
         auto eventListenerTypes = eventListenerRegionTypesForPoint(position);
         if (eventListenerTypes.contains(EventListenerRegionType::NonPassiveWheel))
-            return { WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForDOMEventDispatch };
+            return { WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForBlockingDOMEventDispatch };
 
         if (eventListenerTypes.contains(EventListenerRegionType::Wheel))
-            return { WheelEventProcessingSteps::ScrollingThread, WheelEventProcessingSteps::MainThreadForDOMEventDispatch };
+            return { WheelEventProcessingSteps::ScrollingThread, WheelEventProcessingSteps::MainThreadForNonBlockingDOMEventDispatch };
 #endif
         return { WheelEventProcessingSteps::ScrollingThread };
     }();
 
+    m_latchingController.receivedWheelEvent(wheelEvent, processingSteps, m_allowLatching);
+
     LOG_WITH_STREAM(Scrolling, stream << "ScrollingTree::determineWheelEventProcessing: processingSteps " << processingSteps);
 
     return processingSteps;
@@ -121,7 +121,7 @@
     if (isMonitoringWheelEvents())
         receivedWheelEvent(wheelEvent);
 
-    m_latchingController.receivedWheelEvent(wheelEvent, m_allowLatching);
+    m_latchingController.receivedWheelEvent(wheelEvent, processingSteps, m_allowLatching);
 
     auto result = [&] {
         if (!m_rootNode)
@@ -163,7 +163,8 @@
         return handleWheelEventWithNode(wheelEvent, processingSteps, node.get());
     }();
 
-    result.steps.add(processingSteps & WheelEventProcessingSteps::MainThreadForDOMEventDispatch);
+    static constexpr OptionSet<WheelEventProcessingSteps> mainThreadSteps = { WheelEventProcessingSteps::MainThreadForNonBlockingDOMEventDispatch, WheelEventProcessingSteps::MainThreadForBlockingDOMEventDispatch };
+    result.steps.add(processingSteps & mainThreadSteps);
     return result;
 }
 

Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.h (269972 => 269973)


--- trunk/Source/WebCore/page/scrolling/ScrollingTree.h	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.h	2020-11-18 20:14:43 UTC (rev 269973)
@@ -59,7 +59,7 @@
 struct WheelEventHandlingResult {
     OptionSet<WheelEventProcessingSteps> steps;
     bool wasHandled { false };
-    bool needsMainThreadProcessing() const { return steps.containsAny({ WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForDOMEventDispatch }); }
+    bool needsMainThreadProcessing() const { return steps.containsAny({ WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForNonBlockingDOMEventDispatch, WheelEventProcessingSteps::MainThreadForBlockingDOMEventDispatch }); }
 
     static WheelEventHandlingResult handled(OptionSet<WheelEventProcessingSteps> steps = { })
     {

Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeLatchingController.cpp (269972 => 269973)


--- trunk/Source/WebCore/page/scrolling/ScrollingTreeLatchingController.cpp	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeLatchingController.cpp	2020-11-18 20:14:43 UTC (rev 269973)
@@ -41,7 +41,7 @@
 
 ScrollingTreeLatchingController::ScrollingTreeLatchingController() = default;
 
-void ScrollingTreeLatchingController::receivedWheelEvent(const PlatformWheelEvent& wheelEvent, bool allowLatching)
+void ScrollingTreeLatchingController::receivedWheelEvent(const PlatformWheelEvent& wheelEvent, OptionSet<WheelEventProcessingSteps>, bool allowLatching)
 {
     if (!allowLatching)
         return;

Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeLatchingController.h (269972 => 269973)


--- trunk/Source/WebCore/page/scrolling/ScrollingTreeLatchingController.h	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeLatchingController.h	2020-11-18 20:14:43 UTC (rev 269973)
@@ -48,7 +48,7 @@
 
     ScrollingTreeLatchingController();
 
-    void receivedWheelEvent(const PlatformWheelEvent&, bool allowLatching);
+    void receivedWheelEvent(const PlatformWheelEvent&, OptionSet<WheelEventProcessingSteps>, bool allowLatching);
 
     Optional<ScrollingNodeAndProcessingSteps> latchingDataForEvent(const PlatformWheelEvent&, bool allowLatching) const;
     void nodeDidHandleEvent(ScrollingNodeID, OptionSet<WheelEventProcessingSteps>, const PlatformWheelEvent&, bool allowLatching);

Modified: trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp (269972 => 269973)


--- trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp	2020-11-18 20:14:43 UTC (rev 269973)
@@ -67,13 +67,20 @@
 bool ThreadedScrollingTree::handleWheelEventAfterMainThread(const PlatformWheelEvent& wheelEvent, ScrollingNodeID targetNodeID)
 {
     LOG_WITH_STREAM(Scrolling, stream << "ThreadedScrollingTree::handleWheelEventAfterMainThread " << wheelEvent);
+
+    LockHolder locker(m_treeMutex);
+
     SetForScope<bool> disallowLatchingScope(m_allowLatching, false);
-
     RefPtr<ScrollingTreeNode> targetNode = nodeForID(targetNodeID);
     auto result = handleWheelEventWithNode(wheelEvent, { }, targetNode.get());
     return result.wasHandled;
 }
 
+void ThreadedScrollingTree::wheelEventWasProcessedByMainThread(const PlatformWheelEvent&, OptionSet<EventHandling>)
+{
+    // FIXME: Set state based on EventHandling flags.
+}
+
 void ThreadedScrollingTree::invalidate()
 {
     // Invalidate is dispatched by the ScrollingCoordinator class on the ScrollingThread

Modified: trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.h (269972 => 269973)


--- trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.h	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.h	2020-11-18 20:14:43 UTC (rev 269973)
@@ -48,6 +48,7 @@
     WheelEventHandlingResult handleWheelEvent(const PlatformWheelEvent&, OptionSet<WheelEventProcessingSteps>) override;
 
     bool handleWheelEventAfterMainThread(const PlatformWheelEvent&, ScrollingNodeID);
+    void wheelEventWasProcessedByMainThread(const PlatformWheelEvent&, OptionSet<EventHandling>);
 
     void invalidate() override;
 

Modified: trunk/Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.h (269972 => 269973)


--- trunk/Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.h	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.h	2020-11-18 20:14:43 UTC (rev 269973)
@@ -41,7 +41,8 @@
     void commitTreeStateIfNeeded() final;
 
     // Handle the wheel event on the scrolling thread. Returns whether the event was handled or not.
-    bool handleWheelEvent(FrameView&, const PlatformWheelEvent&, ScrollingNodeID) override;
+    bool performDefaultWheelEventHandling(const PlatformWheelEvent&, ScrollingNodeID) final;
+    void wheelEventWasProcessedByMainThread(const PlatformWheelEvent&, OptionSet<EventHandling>) final;
 
 private:
     void scheduleTreeStateCommit() final;

Modified: trunk/Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.mm (269972 => 269973)


--- trunk/Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.mm	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.mm	2020-11-18 20:14:43 UTC (rev 269973)
@@ -73,7 +73,7 @@
     });
 }
 
-bool ScrollingCoordinatorMac::handleWheelEvent(FrameView&, const PlatformWheelEvent& wheelEvent, ScrollingNodeID targetNode)
+bool ScrollingCoordinatorMac::performDefaultWheelEventHandling(const PlatformWheelEvent& wheelEvent, ScrollingNodeID targetNode)
 {
     ASSERT(isMainThread());
     ASSERT(m_page);
@@ -83,9 +83,6 @@
 
     LOG_WITH_STREAM(Scrolling, stream << "ScrollingCoordinatorMac::handleWheelEvent - sending event to scrolling thread");
     
-    // FIXME: Over on the scrolling thread, we'll hit-test the layers and possibly send the event to a node
-    // which we've already discounted on the main thread. This needs to target a specific node.
-
     RefPtr<ThreadedScrollingTree> threadedScrollingTree = downcast<ThreadedScrollingTree>(scrollingTree());
     ScrollingThread::dispatch([threadedScrollingTree, wheelEvent, targetNode] {
         threadedScrollingTree->handleWheelEventAfterMainThread(wheelEvent, targetNode);
@@ -93,6 +90,29 @@
     return true;
 }
 
+static uint64_t nextDeferIdentifier()
+{
+    static uint64_t deferIdentifier;
+    return ++deferIdentifier;
+}
+
+void ScrollingCoordinatorMac::wheelEventWasProcessedByMainThread(const PlatformWheelEvent& wheelEvent, OptionSet<EventHandling> defaultHandling)
+{
+    uint64_t deferIdentifier = 0;
+    if (m_page && m_page->isMonitoringWheelEvents()) {
+        deferIdentifier = nextDeferIdentifier();
+        m_page->wheelEventTestMonitor()->deferForReason(reinterpret_cast<WheelEventTestMonitor::ScrollableAreaIdentifier>(deferIdentifier), WheelEventTestMonitor::ReportDOMEventHandling);
+    }
+
+    RefPtr<ThreadedScrollingTree> threadedScrollingTree = downcast<ThreadedScrollingTree>(scrollingTree());
+    ScrollingThread::dispatch([threadedScrollingTree, wheelEvent, defaultHandling, deferIdentifier] {
+        threadedScrollingTree->wheelEventWasProcessedByMainThread(wheelEvent, defaultHandling);
+
+        if (threadedScrollingTree->isMonitoringWheelEvents())
+            threadedScrollingTree->removeWheelEventTestCompletionDeferralForReason(reinterpret_cast<WheelEventTestMonitor::ScrollableAreaIdentifier>(deferIdentifier), WheelEventTestMonitor::ReportDOMEventHandling);
+    });
+}
+
 void ScrollingCoordinatorMac::scheduleTreeStateCommit()
 {
     // FIXME: This one needs work.

Modified: trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.mm (269972 => 269973)


--- trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.mm	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.mm	2020-11-18 20:14:43 UTC (rev 269973)
@@ -77,7 +77,7 @@
 {
 #if ENABLE(SCROLLING_THREAD)
     if (hasSynchronousScrollingReasons())
-        return { { WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForDOMEventDispatch }, false };
+        return { { WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForNonBlockingDOMEventDispatch }, false };
 #endif
 
     if (!canHandleWheelEvent(wheelEvent))

Modified: trunk/Source/WebCore/page/scrolling/nicosia/ScrollingCoordinatorNicosia.cpp (269972 => 269973)


--- trunk/Source/WebCore/page/scrolling/nicosia/ScrollingCoordinatorNicosia.cpp	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/Source/WebCore/page/scrolling/nicosia/ScrollingCoordinatorNicosia.cpp	2020-11-18 20:14:43 UTC (rev 269973)
@@ -69,7 +69,7 @@
     m_scrollingStateTreeCommitterTimer.stop();
 }
 
-bool ScrollingCoordinatorNicosia::handleWheelEvent(FrameView&, const PlatformWheelEvent& wheelEvent, ScrollingNodeID targetNode)
+bool ScrollingCoordinatorNicosia::performDefaultWheelEventHandling(const PlatformWheelEvent& wheelEvent, ScrollingNodeID targetNode)
 {
     ASSERT(isMainThread());
     ASSERT(m_page);
@@ -81,6 +81,13 @@
     return true;
 }
 
+void ScrollingCoordinatorNicosia::wheelEventWasProcessedByMainThread(const PlatformWheelEvent& wheelEvent, OptionSet<EventHandling> defaultHandling)
+{
+    ScrollingThread::dispatch([threadedScrollingTree = makeRef(downcast<ThreadedScrollingTree>(*scrollingTree())), wheelEvent, defaultHandling] {
+        threadedScrollingTree->wheelEventWasProcessedByMainThread(wheelEvent, defaultHandling);
+    });
+}
+
 void ScrollingCoordinatorNicosia::scheduleTreeStateCommit()
 {
     if (!m_scrollingStateTreeCommitterTimer.isActive())

Modified: trunk/Source/WebCore/page/scrolling/nicosia/ScrollingCoordinatorNicosia.h (269972 => 269973)


--- trunk/Source/WebCore/page/scrolling/nicosia/ScrollingCoordinatorNicosia.h	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/Source/WebCore/page/scrolling/nicosia/ScrollingCoordinatorNicosia.h	2020-11-18 20:14:43 UTC (rev 269973)
@@ -44,7 +44,8 @@
 
     void commitTreeStateIfNeeded() override;
 
-    bool handleWheelEvent(FrameView&, const PlatformWheelEvent&, ScrollingNodeID) override;
+    bool performDefaultWheelEventHandling(const PlatformWheelEvent&, ScrollingNodeID) override;
+    void wheelEventWasProcessedByMainThread(const PlatformWheelEvent&, OptionSet<EventHandling>) override;
 
 private:
     void scheduleTreeStateCommit() override;

Modified: trunk/Source/WebCore/platform/PlatformEvent.h (269972 => 269973)


--- trunk/Source/WebCore/platform/PlatformEvent.h	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/Source/WebCore/platform/PlatformEvent.h	2020-11-18 20:14:43 UTC (rev 269973)
@@ -30,6 +30,12 @@
 
 namespace WebCore {
 
+enum class EventHandling : uint8_t {
+    DispatchedToDOM     = 1 << 0,
+    DefaultPrevented    = 1 << 1,
+    DefaultHandled      = 1 << 2,
+};
+
 class PlatformEvent {
 public:
     enum Type : uint8_t {

Modified: trunk/Source/WebCore/platform/PlatformWheelEvent.cpp (269972 => 269973)


--- trunk/Source/WebCore/platform/PlatformWheelEvent.cpp	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/Source/WebCore/platform/PlatformWheelEvent.cpp	2020-11-18 20:14:43 UTC (rev 269973)
@@ -64,9 +64,20 @@
     switch (steps) {
     case WheelEventProcessingSteps::ScrollingThread: ts << "scrolling thread"; break;
     case WheelEventProcessingSteps::MainThreadForScrolling: ts << "main thread scrolling"; break;
-    case WheelEventProcessingSteps::MainThreadForDOMEventDispatch: ts << "main thread DOM event dispatch"; break;
+    case WheelEventProcessingSteps::MainThreadForNonBlockingDOMEventDispatch: ts << "main thread non-blocking DOM event dispatch"; break;
+    case WheelEventProcessingSteps::MainThreadForBlockingDOMEventDispatch: ts << "main thread blocking DOM event dispatch"; break;
     }
     return ts;
 }
 
+TextStream& operator<<(TextStream& ts, EventHandling steps)
+{
+    switch (steps) {
+    case EventHandling::DispatchedToDOM: ts << "dispatched to DOM"; break;
+    case EventHandling::DefaultPrevented: ts << "default prevented"; break;
+    case EventHandling::DefaultHandled: ts << "default handled"; break;
+    }
+    return ts;
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/PlatformWheelEvent.h (269972 => 269973)


--- trunk/Source/WebCore/platform/PlatformWheelEvent.h	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/Source/WebCore/platform/PlatformWheelEvent.h	2020-11-18 20:14:43 UTC (rev 269973)
@@ -37,9 +37,10 @@
 namespace WebCore {
 
 enum class WheelEventProcessingSteps : uint8_t {
-    ScrollingThread                 = 1 << 0,
-    MainThreadForScrolling          = 1 << 1,
-    MainThreadForDOMEventDispatch   = 1 << 2,
+    ScrollingThread                             = 1 << 0,
+    MainThreadForScrolling                      = 1 << 1,
+    MainThreadForNonBlockingDOMEventDispatch    = 1 << 2,
+    MainThreadForBlockingDOMEventDispatch       = 1 << 3,
 };
 
 // The ScrollByPixelWheelEvent is a fine-grained event that specifies the precise number of pixels to scroll.
@@ -265,5 +266,6 @@
 
 WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const PlatformWheelEvent&);
 WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, WheelEventProcessingSteps);
+WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, EventHandling);
 
 } // namespace WebCore

Modified: trunk/Source/WebKit/ChangeLog (269972 => 269973)


--- trunk/Source/WebKit/ChangeLog	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/Source/WebKit/ChangeLog	2020-11-18 20:14:43 UTC (rev 269973)
@@ -1,3 +1,17 @@
+2020-11-18  Simon Fraser  <[email protected]>
+
+        Propagate wheel event handling back to the scrolling thread
+        https://bugs.webkit.org/show_bug.cgi?id=219050
+
+        Reviewed by Chris Dumez.
+        
+        For now, use MainThreadForBlockingDOMEventDispatch for the default steps (used by non-macOS platforms).
+
+        * UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp:
+        (WebKit::RemoteScrollingCoordinatorProxy::handleWheelEvent):
+        * WebProcess/WebPage/EventDispatcher.cpp:
+        (WebKit::EventDispatcher::wheelEvent):
+
 2020-11-18  Wenson Hsieh  <[email protected]>
 
         Clean up some code in SharedDisplayListHandle

Modified: trunk/Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp (269972 => 269973)


--- trunk/Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp	2020-11-18 20:14:43 UTC (rev 269973)
@@ -180,7 +180,7 @@
         return false;
 
     auto processingSteps = m_scrollingTree->determineWheelEventProcessing(wheelEvent);
-    if (processingSteps.containsAny({ WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForDOMEventDispatch }))
+    if (processingSteps.containsAny({ WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForNonBlockingDOMEventDispatch, WheelEventProcessingSteps::MainThreadForBlockingDOMEventDispatch }))
         return false;
 
     if (m_scrollingTree->willWheelEventStartSwipeGesture(wheelEvent))

Modified: trunk/Source/WebKit/WebProcess/WebPage/EventDispatcher.cpp (269972 => 269973)


--- trunk/Source/WebKit/WebProcess/WebPage/EventDispatcher.cpp	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/Source/WebKit/WebProcess/WebPage/EventDispatcher.cpp	2020-11-18 20:14:43 UTC (rev 269973)
@@ -121,7 +121,7 @@
     }
 #endif
 
-    auto processingSteps = OptionSet<WebCore::WheelEventProcessingSteps> { WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForDOMEventDispatch };
+    auto processingSteps = OptionSet<WebCore::WheelEventProcessingSteps> { WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForBlockingDOMEventDispatch };
 #if ENABLE(SCROLLING_THREAD)
     processingSteps = [&]() -> OptionSet<WheelEventProcessingSteps> {
         LockHolder locker(m_scrollingTreesMutex);
@@ -128,7 +128,7 @@
 
         auto scrollingTree = m_scrollingTrees.get(pageID);
         if (!scrollingTree)
-            return { WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForDOMEventDispatch };
+            return { WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForBlockingDOMEventDispatch };
         
         // FIXME: It's pretty horrible that we're updating the back/forward state here.
         // WebCore should always know the current state and know when it changes so the

Modified: trunk/Source/WebKitLegacy/win/ChangeLog (269972 => 269973)


--- trunk/Source/WebKitLegacy/win/ChangeLog	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/Source/WebKitLegacy/win/ChangeLog	2020-11-18 20:14:43 UTC (rev 269973)
@@ -1,3 +1,15 @@
+2020-11-18  Simon Fraser  <[email protected]>
+
+        Propagate wheel event handling back to the scrolling thread
+        https://bugs.webkit.org/show_bug.cgi?id=219050
+
+        Reviewed by Chris Dumez.
+
+        Use MainThreadForBlockingDOMEventDispatch.
+
+        * WebView.cpp:
+        (WebView::mouseWheel):
+
 2020-11-11  Sam Weinig  <[email protected]>
 
         Remove unused ExperimentalNotificationsEnabled setting

Modified: trunk/Source/WebKitLegacy/win/WebView.cpp (269972 => 269973)


--- trunk/Source/WebKitLegacy/win/WebView.cpp	2020-11-18 20:02:50 UTC (rev 269972)
+++ trunk/Source/WebKitLegacy/win/WebView.cpp	2020-11-18 20:14:43 UTC (rev 269973)
@@ -2137,7 +2137,7 @@
     if (!coreFrame)
         return false;
 
-    return coreFrame->eventHandler().handleWheelEvent(wheelEvent, { WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForDOMEventDispatch });
+    return coreFrame->eventHandler().handleWheelEvent(wheelEvent, { WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForBlockingDOMEventDispatch });
 }
 
 bool WebView::verticalScroll(WPARAM wParam, LPARAM /*lParam*/)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to