Changeset 269973 in webkit


Ignore:
Timestamp:
Nov 18, 2020 12:14:43 PM (3 years ago)
Author:
Simon Fraser
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:
Location:
trunk
Files:
2 added
36 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r269972 r269973  
     12020-11-18  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Propagate wheel event handling back to the scrolling thread
     4        https://bugs.webkit.org/show_bug.cgi?id=219050
     5
     6        Reviewed by Chris Dumez.
     7
     8        * fast/events/wheel/wheel-event-in-passive-region-non-cancelable-expected.txt: Added.
     9        * fast/events/wheel/wheel-event-in-passive-region-non-cancelable.html: Added.
     10        * platform/mac-wk1/TestExpectations:
     11        * platform/win/TestExpectations:
     12
    1132020-11-18  Chris Dumez  <cdumez@apple.com>
    214
  • trunk/LayoutTests/platform/mac-wk1/TestExpectations

    r269866 r269973  
    493493fast/scrolling/scroll-animator-overlay-scrollbars-hovered.html [ Skip ]
    494494
     495# Tests that require async scrolling
     496fast/events/wheel/wheel-event-in-passive-region-non-cancelable.html [ Skip ]
     497
    495498# WK1 main frame scrollbars are native widgets whose size is unaffected by webkit-scrollbar.
    496499fast/visual-viewport/viewport-dimensions-exclude-custom-scrollbars.html [ Skip ]
  • trunk/LayoutTests/platform/win/TestExpectations

    r269950 r269973  
    276276fast/events/wheel/wheelevent-in-horizontal-scrollbar-in-rtl.html [ Failure ]
    277277fast/events/wheel/wheelevent-in-vertical-scrollbar-in-rtl.html [ Failure ]
     278
     279# Need async scrolling
    278280fast/events/wheel/wheel-event-listeners-on-body-made-passive.html [ Skip ]
    279281fast/events/wheel/wheel-event-listeners-on-document-made-passive.html [ Skip ]
    280282fast/events/wheel/wheel-event-listeners-on-window-left-active.html [ Skip ]
    281283fast/events/wheel/wheel-event-listeners-on-window-made-passive.html [ Skip ]
     284fast/events/wheel/wheel-event-in-passive-region-non-cancelable.html [ Skip ]
    282285
    283286scrollbars/scroll-rtl-or-bt-layer.html [ Timeout ]
  • trunk/Source/WebCore/ChangeLog

    r269963 r269973  
     12020-11-18  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Propagate wheel event handling back to the scrolling thread
     4        https://bugs.webkit.org/show_bug.cgi?id=219050
     5
     6        Reviewed by Chris Dumez.
     7
     8        Prepare to fix webkit.org/b/218764 by adding a way for the main thread to communicate back
     9        to the scrolling thread information about whether the wheel event was dispatched to JS,
     10        and whether preventDefault() was called on it.
     11
     12        The EventHandling enum has bits that are set when the event is dispatched to JS,
     13        when it's canceled, and if default handling happened. These values are filled in
     14        Element::dispatchWheelEvent(). They propagate back to the scrolling thread via
     15        EventHandler::wheelEventWasProcessedByMainThread(), whose macOS implementation
     16        calls into the ScrollingCoordinator, which will set state on the ScrollingTree in
     17        a future patch.
     18
     19        WheelEventTestMonitor gains a "reason" flag to track the async propagation of
     20        wheelEventWasProcessedByMainThread() back to the scrolling thread.
     21
     22        This patch also adds infrastructure for the scrolling thread to specify that wheel events
     23        sent to the main thread will be uncancelable; WheelEventProcessingSteps gains
     24        MainThreadForNonBlockingDOMEventDispatch and MainThreadForBlockingDOMEventDispatch,
     25        and if MainThreadForNonBlockingDOMEventDispatch is set, then we create
     26        WheelEvents with IsCancelable::No. This will be the case for wheel events in
     27        the passive event region.
     28
     29        Rename ScrollingCoordinator::handleWheelEvent() to performDefaultWheelEventHandling()
     30        for clarity, and stop passing the FrameView* which was unused.
     31
     32        Add a missing lock in ThreadedScrollingTree::handleWheelEventAfterMainThread().
     33
     34        * dom/Element.cpp:
     35        (WebCore::Element::dispatchWheelEvent):
     36        * dom/Element.h:
     37        * dom/WheelEvent.cpp:
     38        (WebCore::WheelEvent::WheelEvent):
     39        (WebCore::WheelEvent::create):
     40        * dom/WheelEvent.h:
     41        * page/EventHandler.cpp:
     42        (WebCore::EventHandler::wheelEventWasProcessedByMainThread):
     43        (WebCore::EventHandler::handleWheelEvent):
     44        (WebCore::EventHandler::handleWheelEventInternal):
     45        * page/EventHandler.h:
     46        * page/FrameView.cpp:
     47        (WebCore::FrameView::wheelEvent):
     48        * page/PointerLockController.cpp:
     49        (WebCore::PointerLockController::dispatchLockedWheelEvent):
     50        * page/WheelEventTestMonitor.cpp:
     51        (WebCore::operator<<):
     52        * page/WheelEventTestMonitor.h:
     53        * page/ios/EventHandlerIOS.mm:
     54        (WebCore::EventHandler::wheelEvent):
     55        * page/mac/EventHandlerMac.mm:
     56        (WebCore::EventHandler::wheelEvent):
     57        (WebCore::EventHandler::wheelEventWasProcessedByMainThread):
     58        * page/scrolling/ScrollingCoordinator.h:
     59        (WebCore::ScrollingCoordinator::performDefaultWheelEventHandling):
     60        (WebCore::ScrollingCoordinator::wheelEventWasProcessedByMainThread):
     61        (WebCore::ScrollingCoordinator::handleWheelEvent): Deleted.
     62        * page/scrolling/ScrollingTree.cpp:
     63        (WebCore::ScrollingTree::determineWheelEventProcessing):
     64        (WebCore::ScrollingTree::handleWheelEvent):
     65        * page/scrolling/ScrollingTree.h:
     66        (WebCore::WheelEventHandlingResult::needsMainThreadProcessing const):
     67        * page/scrolling/ScrollingTreeLatchingController.cpp:
     68        (WebCore::ScrollingTreeLatchingController::receivedWheelEvent): Send in WheelEventProcessingSteps which
     69        a future patch will use.
     70        * page/scrolling/ScrollingTreeLatchingController.h:
     71        * page/scrolling/ThreadedScrollingTree.cpp:
     72        (WebCore::ThreadedScrollingTree::handleWheelEventAfterMainThread): There was a missing lock here.
     73        (WebCore::ThreadedScrollingTree::wheelEventWasProcessedByMainThread):
     74        * page/scrolling/ThreadedScrollingTree.h:
     75        * page/scrolling/mac/ScrollingCoordinatorMac.h:
     76        * page/scrolling/mac/ScrollingCoordinatorMac.mm:
     77        (WebCore::ScrollingCoordinatorMac::performDefaultWheelEventHandling):
     78        (WebCore::nextDeferIdentifier):
     79        (WebCore::ScrollingCoordinatorMac::wheelEventWasProcessedByMainThread):
     80        (WebCore::ScrollingCoordinatorMac::handleWheelEvent): Deleted.
     81        * page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.mm:
     82        (WebCore::ScrollingTreeOverflowScrollingNodeMac::handleWheelEvent):
     83        * page/scrolling/nicosia/ScrollingCoordinatorNicosia.cpp:
     84        (WebCore::ScrollingCoordinatorNicosia::performDefaultWheelEventHandling):
     85        (WebCore::ScrollingCoordinatorNicosia::wheelEventWasProcessedByMainThread):
     86        (WebCore::ScrollingCoordinatorNicosia::handleWheelEvent): Deleted.
     87        * page/scrolling/nicosia/ScrollingCoordinatorNicosia.h:
     88        * platform/PlatformEvent.h:
     89        * platform/PlatformWheelEvent.cpp:
     90        (WebCore::operator<<): Add dumping of EventHandling.
     91        * platform/PlatformWheelEvent.h:
     92
    1932020-11-18  Antoine Quint  <graouts@webkit.org>
    294
  • trunk/Source/WebCore/dom/Element.cpp

    r269807 r269973  
    421421}
    422422
    423 bool Element::dispatchWheelEvent(const PlatformWheelEvent& platformEvent)
    424 {
    425     auto event = WheelEvent::create(platformEvent, document().windowProxy());
     423bool Element::dispatchWheelEvent(const PlatformWheelEvent& platformEvent, OptionSet<EventHandling>& processing, Event::IsCancelable isCancelable)
     424{
     425    auto event = WheelEvent::create(platformEvent, document().windowProxy(), isCancelable);
    426426
    427427    // Events with no deltas are important because they convey platform information about scroll gestures
     
    431431    // will prevent the event from being sent to the DOM, but will still call the default event handler.
    432432    // FIXME: Move this logic into WheelEvent::create.
    433     if (!platformEvent.deltaX() && !platformEvent.deltaY())
     433    if (platformEvent.delta().isZero())
    434434        event->stopPropagation();
     435    else
     436        processing.add(EventHandling::DispatchedToDOM);
    435437
    436438    dispatchEvent(event);
    437439   
    438440    LOG_WITH_STREAM(Scrolling, stream << "Element " << *this << " dispatchWheelEvent: defaultPrevented " << event->defaultPrevented() << " defaultHandled " << event->defaultHandled());
     441   
     442    if (event->defaultPrevented())
     443        processing.add(EventHandling::DefaultPrevented);
     444
     445    if (event->defaultHandled())
     446        processing.add(EventHandling::DefaultHandled);
     447
    439448    return !event->defaultPrevented() && !event->defaultHandled();
    440449}
  • trunk/Source/WebCore/dom/Element.h

    r269587 r269973  
    6767struct ScrollToOptions;
    6868
     69enum class EventProcessing : uint8_t;
     70
    6971#if ENABLE(INTERSECTION_OBSERVER)
    7072struct IntersectionObserverData;
     
    531533
    532534    bool dispatchMouseEvent(const PlatformMouseEvent&, const AtomString& eventType, int clickCount = 0, Element* relatedTarget = nullptr);
    533     bool dispatchWheelEvent(const PlatformWheelEvent&);
     535    bool dispatchWheelEvent(const PlatformWheelEvent&, OptionSet<EventHandling>&, Event::IsCancelable = Event::IsCancelable::Yes);
    534536    bool dispatchKeyEvent(const PlatformKeyboardEvent&);
    535537    bool dispatchSimulatedClick(Event* underlyingEvent, SimulatedClickMouseEventOptions = SendNoEvents, SimulatedClickVisualOptions = ShowPressedLook);
  • trunk/Source/WebCore/dom/WheelEvent.cpp

    r254029 r269973  
    5151}
    5252
    53 inline WheelEvent::WheelEvent(const PlatformWheelEvent& event, RefPtr<WindowProxy>&& view)
    54     : MouseEvent(eventNames().wheelEvent, CanBubble::Yes, IsCancelable::Yes, IsComposed::Yes, event.timestamp().approximateMonotonicTime(), WTFMove(view), 0,
     53inline WheelEvent::WheelEvent(const PlatformWheelEvent& event, RefPtr<WindowProxy>&& view, IsCancelable isCancelable)
     54    : MouseEvent(eventNames().wheelEvent, CanBubble::Yes, isCancelable, IsComposed::Yes, event.timestamp().approximateMonotonicTime(), WTFMove(view), 0,
    5555        event.globalPosition(), event.position() , { }, event.modifiers(), 0, 0, nullptr, 0, 0, IsSimulated::No, IsTrusted::Yes)
    5656    , m_wheelDelta(event.wheelTicksX() * TickMultiplier, event.wheelTicksY() * TickMultiplier)
     
    6262}
    6363
    64 Ref<WheelEvent> WheelEvent::create(const PlatformWheelEvent& event, RefPtr<WindowProxy>&& view)
     64Ref<WheelEvent> WheelEvent::create(const PlatformWheelEvent& event, RefPtr<WindowProxy>&& view, IsCancelable isCancelable)
    6565{
    66     return adoptRef(*new WheelEvent(event, WTFMove(view)));
     66    return adoptRef(*new WheelEvent(event, WTFMove(view), isCancelable));
    6767}
    6868
  • trunk/Source/WebCore/dom/WheelEvent.h

    r269659 r269973  
    4141    };
    4242
    43     static Ref<WheelEvent> create(const PlatformWheelEvent&, RefPtr<WindowProxy>&&);
     43    static Ref<WheelEvent> create(const PlatformWheelEvent&, RefPtr<WindowProxy>&&, IsCancelable = IsCancelable::Yes);
    4444    static Ref<WheelEvent> createForBindings();
    4545
     
    7777    WheelEvent();
    7878    WheelEvent(const AtomString&, const Init&);
    79     WheelEvent(const PlatformWheelEvent&, RefPtr<WindowProxy>&&);
     79    WheelEvent(const PlatformWheelEvent&, RefPtr<WindowProxy>&&, IsCancelable);
    8080
    8181    EventInterface eventInterface() const final;
  • trunk/Source/WebCore/page/EventHandler.cpp

    r269888 r269973  
    27932793}
    27942794
     2795void EventHandler::wheelEventWasProcessedByMainThread(const PlatformWheelEvent&, OptionSet<EventHandling>)
     2796{
     2797}
     2798
    27952799bool EventHandler::platformCompletePlatformWidgetWheelEvent(const PlatformWheelEvent&, const Widget&, const WeakPtr<ScrollableArea>&)
    27962800{
     
    28632867
    28642868bool EventHandler::handleWheelEvent(const PlatformWheelEvent& event, OptionSet<WheelEventProcessingSteps> processingSteps)
     2869{
     2870    OptionSet<EventHandling> handling;
     2871    bool handled = handleWheelEventInternal(event, processingSteps, handling);
     2872    wheelEventWasProcessedByMainThread(event, handling);
     2873    return handled;
     2874}
     2875
     2876bool EventHandler::handleWheelEventInternal(const PlatformWheelEvent& event, OptionSet<WheelEventProcessingSteps> processingSteps, OptionSet<EventHandling>& handling)
    28652877{
    28662878    auto* document = m_frame.document();
     
    29252937        }
    29262938
    2927         if (!element->dispatchWheelEvent(event)) {
     2939        auto isCancelable = processingSteps.contains(WheelEventProcessingSteps::MainThreadForBlockingDOMEventDispatch) ? Event::IsCancelable::Yes : Event::IsCancelable::No;
     2940        if (!element->dispatchWheelEvent(event, handling, isCancelable)) {
    29282941            m_isHandlingWheelEvent = false;
    29292942            if (scrollableArea && scrollableArea->scrollShouldClearLatchedState()) {
     
    29552968        processWheelEventForScrollSnap(event, scrollableArea);
    29562969    }
     2970
    29572971    return handledEvent;
    29582972}
  • trunk/Source/WebCore/page/EventHandler.h

    r268417 r269973  
    209209    WEBCORE_EXPORT bool handleMouseReleaseEvent(const PlatformMouseEvent&);
    210210    bool handleMouseForceEvent(const PlatformMouseEvent&);
     211
    211212    WEBCORE_EXPORT bool handleWheelEvent(const PlatformWheelEvent&, OptionSet<WheelEventProcessingSteps>);
    212213    void defaultWheelEventHandler(Node*, WheelEvent&);
     214    void wheelEventWasProcessedByMainThread(const PlatformWheelEvent&, OptionSet<EventHandling>);
     215
    213216    bool handlePasteGlobalSelection(const PlatformMouseEvent&);
    214217
     
    453456    bool passMouseDownEventToWidget(Widget*);
    454457
     458    bool handleWheelEventInternal(const PlatformWheelEvent&, OptionSet<WheelEventProcessingSteps>, OptionSet<EventHandling>&);
    455459    bool passWheelEventToWidget(const PlatformWheelEvent&, Widget&, OptionSet<WheelEventProcessingSteps>);
    456460    void determineWheelEventTarget(const PlatformWheelEvent&, RefPtr<Element>& eventTarget, WeakPtr<ScrollableArea>&, bool& isOverWidget);
  • trunk/Source/WebCore/page/FrameView.cpp

    r269953 r269973  
    51295129    if (auto scrollingCoordinator = this->scrollingCoordinator()) {
    51305130        if (scrollingCoordinator->coordinatesScrollingForFrameView(*this))
    5131             return scrollingCoordinator->handleWheelEvent(*this, wheelEvent, scrollingNodeID());
     5131            return scrollingCoordinator->performDefaultWheelEventHandling(wheelEvent, scrollingNodeID());
    51325132    }
    51335133#endif
  • trunk/Source/WebCore/page/PointerLockController.cpp

    r258148 r269973  
    194194        return;
    195195
    196     m_element->dispatchWheelEvent(event);
     196    OptionSet<EventHandling> defaultHandling;
     197    m_element->dispatchWheelEvent(event, defaultHandling);
    197198}
    198199
  • trunk/Source/WebCore/page/WheelEventTestMonitor.cpp

    r269659 r269973  
    171171    case WheelEventTestMonitor::HandlingWheelEvent: ts << "handling wheel event"; break;
    172172    case WheelEventTestMonitor::HandlingWheelEventOnMainThread: ts << "handling wheel event on main thread"; break;
     173    case WheelEventTestMonitor::ReportDOMEventHandling: ts << "report DOM event handling"; break;
    173174    case WheelEventTestMonitor::RubberbandInProgress: ts << "rubberbanding"; break;
    174175    case WheelEventTestMonitor::ScrollSnapInProgress: ts << "scroll-snapping"; break;
  • trunk/Source/WebCore/page/WheelEventTestMonitor.h

    r258805 r269973  
    5151        HandlingWheelEvent              = 1 << 0,
    5252        HandlingWheelEventOnMainThread  = 1 << 1,
    53         RubberbandInProgress            = 1 << 2,
    54         ScrollSnapInProgress            = 1 << 3,
    55         ScrollingThreadSyncNeeded       = 1 << 4,
    56         ContentScrollInProgress         = 1 << 5,
    57         RequestedScrollPosition         = 1 << 6,
     53        ReportDOMEventHandling          = 1 << 2,
     54        RubberbandInProgress            = 1 << 3,
     55        ScrollSnapInProgress            = 1 << 4,
     56        ScrollingThreadSyncNeeded       = 1 << 5,
     57        ContentScrollInProgress         = 1 << 6,
     58        RequestedScrollPosition         = 1 << 7,
    5859    };
    5960    typedef const void* ScrollableAreaIdentifier;
  • trunk/Source/WebCore/page/ios/EventHandlerIOS.mm

    r268417 r269973  
    108108    CurrentEventScope scope(event);
    109109
    110     bool eventWasHandled = handleWheelEvent(PlatformEventFactory::createPlatformWheelEvent(event), { WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForDOMEventDispatch });
     110    bool eventWasHandled = handleWheelEvent(PlatformEventFactory::createPlatformWheelEvent(event), { WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForBlockingDOMEventDispatch });
    111111    event.wasHandled = eventWasHandled;
    112112    return eventWasHandled;
  • trunk/Source/WebCore/page/mac/EventHandlerMac.mm

    r269659 r269973  
    6464#import "ScrollableArea.h"
    6565#import "Scrollbar.h"
     66#import "ScrollingCoordinator.h"
    6667#import "Settings.h"
    6768#import "ShadowRoot.h"
     
    147148
    148149    CurrentEventScope scope(event, nil);
    149     return handleWheelEvent(PlatformEventFactory::createPlatformWheelEvent(event, page->chrome().platformPageClient()), { WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForDOMEventDispatch });
     150    return handleWheelEvent(PlatformEventFactory::createPlatformWheelEvent(event, page->chrome().platformPageClient()), { WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForBlockingDOMEventDispatch });
    150151}
    151152
     
    953954}
    954955
     956void EventHandler::wheelEventWasProcessedByMainThread(const PlatformWheelEvent& wheelEvent, OptionSet<EventHandling> eventHandling)
     957{
     958#if ENABLE(ASYNC_SCROLLING)
     959    if (!m_frame.page())
     960        return;
     961
     962    FrameView* view = m_frame.view();
     963    if (!view)
     964        return;
     965
     966    if (auto scrollingCoordinator = m_frame.page()->scrollingCoordinator()) {
     967        if (scrollingCoordinator->coordinatesScrollingForFrameView(*view))
     968            scrollingCoordinator->wheelEventWasProcessedByMainThread(wheelEvent, eventHandling);
     969    }
     970#else
     971    UNUSED_PARAM(wheelEvent);
     972    UNUSED_PARAM(eventHandling);
     973#endif
     974}
     975
    955976bool EventHandler::platformCompletePlatformWidgetWheelEvent(const PlatformWheelEvent& wheelEvent, const Widget& widget, const WeakPtr<ScrollableArea>& scrollableArea)
    956977{
  • trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h

    r267002 r269973  
    128128    virtual void commitTreeStateIfNeeded() { }
    129129    virtual bool requestScrollPositionUpdate(ScrollableArea&, const IntPoint&, ScrollType = ScrollType::Programmatic, ScrollClamping = ScrollClamping::Clamped) { return false; }
    130     virtual bool handleWheelEvent(FrameView&, const PlatformWheelEvent&, ScrollingNodeID) { return false; }
     130    virtual bool performDefaultWheelEventHandling(const PlatformWheelEvent&, ScrollingNodeID) { return false; }
     131    virtual void wheelEventWasProcessedByMainThread(const PlatformWheelEvent&, OptionSet<EventHandling>) { }
    131132
    132133    // Create an unparented node.
  • trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp

    r269659 r269973  
    7575    }
    7676
    77     m_latchingController.receivedWheelEvent(wheelEvent, m_allowLatching);
    78 
    7977    auto processingSteps = [&]() -> OptionSet<WheelEventProcessingSteps> {
    8078        if (!m_rootNode)
     
    9492
    9593            if (isSynchronousDispatchRegion)
    96                 return { WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForDOMEventDispatch };
     94                return { WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForBlockingDOMEventDispatch };
    9795        }
    9896
     
    10098        auto eventListenerTypes = eventListenerRegionTypesForPoint(position);
    10199        if (eventListenerTypes.contains(EventListenerRegionType::NonPassiveWheel))
    102             return { WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForDOMEventDispatch };
     100            return { WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForBlockingDOMEventDispatch };
    103101
    104102        if (eventListenerTypes.contains(EventListenerRegionType::Wheel))
    105             return { WheelEventProcessingSteps::ScrollingThread, WheelEventProcessingSteps::MainThreadForDOMEventDispatch };
     103            return { WheelEventProcessingSteps::ScrollingThread, WheelEventProcessingSteps::MainThreadForNonBlockingDOMEventDispatch };
    106104#endif
    107105        return { WheelEventProcessingSteps::ScrollingThread };
    108106    }();
    109107
     108    m_latchingController.receivedWheelEvent(wheelEvent, processingSteps, m_allowLatching);
     109
    110110    LOG_WITH_STREAM(Scrolling, stream << "ScrollingTree::determineWheelEventProcessing: processingSteps " << processingSteps);
    111111
     
    122122        receivedWheelEvent(wheelEvent);
    123123
    124     m_latchingController.receivedWheelEvent(wheelEvent, m_allowLatching);
     124    m_latchingController.receivedWheelEvent(wheelEvent, processingSteps, m_allowLatching);
    125125
    126126    auto result = [&] {
     
    164164    }();
    165165
    166     result.steps.add(processingSteps & WheelEventProcessingSteps::MainThreadForDOMEventDispatch);
     166    static constexpr OptionSet<WheelEventProcessingSteps> mainThreadSteps = { WheelEventProcessingSteps::MainThreadForNonBlockingDOMEventDispatch, WheelEventProcessingSteps::MainThreadForBlockingDOMEventDispatch };
     167    result.steps.add(processingSteps & mainThreadSteps);
    167168    return result;
    168169}
  • trunk/Source/WebCore/page/scrolling/ScrollingTree.h

    r269312 r269973  
    6060    OptionSet<WheelEventProcessingSteps> steps;
    6161    bool wasHandled { false };
    62     bool needsMainThreadProcessing() const { return steps.containsAny({ WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForDOMEventDispatch }); }
     62    bool needsMainThreadProcessing() const { return steps.containsAny({ WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForNonBlockingDOMEventDispatch, WheelEventProcessingSteps::MainThreadForBlockingDOMEventDispatch }); }
    6363
    6464    static WheelEventHandlingResult handled(OptionSet<WheelEventProcessingSteps> steps = { })
  • trunk/Source/WebCore/page/scrolling/ScrollingTreeLatchingController.cpp

    r268544 r269973  
    4242ScrollingTreeLatchingController::ScrollingTreeLatchingController() = default;
    4343
    44 void ScrollingTreeLatchingController::receivedWheelEvent(const PlatformWheelEvent& wheelEvent, bool allowLatching)
     44void ScrollingTreeLatchingController::receivedWheelEvent(const PlatformWheelEvent& wheelEvent, OptionSet<WheelEventProcessingSteps>, bool allowLatching)
    4545{
    4646    if (!allowLatching)
  • trunk/Source/WebCore/page/scrolling/ScrollingTreeLatchingController.h

    r268895 r269973  
    4949    ScrollingTreeLatchingController();
    5050
    51     void receivedWheelEvent(const PlatformWheelEvent&, bool allowLatching);
     51    void receivedWheelEvent(const PlatformWheelEvent&, OptionSet<WheelEventProcessingSteps>, bool allowLatching);
    5252
    5353    Optional<ScrollingNodeAndProcessingSteps> latchingDataForEvent(const PlatformWheelEvent&, bool allowLatching) const;
  • trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp

    r269312 r269973  
    6868{
    6969    LOG_WITH_STREAM(Scrolling, stream << "ThreadedScrollingTree::handleWheelEventAfterMainThread " << wheelEvent);
     70
     71    LockHolder locker(m_treeMutex);
     72
    7073    SetForScope<bool> disallowLatchingScope(m_allowLatching, false);
    71 
    7274    RefPtr<ScrollingTreeNode> targetNode = nodeForID(targetNodeID);
    7375    auto result = handleWheelEventWithNode(wheelEvent, { }, targetNode.get());
    7476    return result.wasHandled;
     77}
     78
     79void ThreadedScrollingTree::wheelEventWasProcessedByMainThread(const PlatformWheelEvent&, OptionSet<EventHandling>)
     80{
     81    // FIXME: Set state based on EventHandling flags.
    7582}
    7683
  • trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.h

    r269579 r269973  
    4949
    5050    bool handleWheelEventAfterMainThread(const PlatformWheelEvent&, ScrollingNodeID);
     51    void wheelEventWasProcessedByMainThread(const PlatformWheelEvent&, OptionSet<EventHandling>);
    5152
    5253    void invalidate() override;
  • trunk/Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.h

    r266292 r269973  
    4242
    4343    // Handle the wheel event on the scrolling thread. Returns whether the event was handled or not.
    44     bool handleWheelEvent(FrameView&, const PlatformWheelEvent&, ScrollingNodeID) override;
     44    bool performDefaultWheelEventHandling(const PlatformWheelEvent&, ScrollingNodeID) final;
     45    void wheelEventWasProcessedByMainThread(const PlatformWheelEvent&, OptionSet<EventHandling>) final;
    4546
    4647private:
  • trunk/Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.mm

    r268075 r269973  
    7474}
    7575
    76 bool ScrollingCoordinatorMac::handleWheelEvent(FrameView&, const PlatformWheelEvent& wheelEvent, ScrollingNodeID targetNode)
     76bool ScrollingCoordinatorMac::performDefaultWheelEventHandling(const PlatformWheelEvent& wheelEvent, ScrollingNodeID targetNode)
    7777{
    7878    ASSERT(isMainThread());
     
    8484    LOG_WITH_STREAM(Scrolling, stream << "ScrollingCoordinatorMac::handleWheelEvent - sending event to scrolling thread");
    8585   
    86     // FIXME: Over on the scrolling thread, we'll hit-test the layers and possibly send the event to a node
    87     // which we've already discounted on the main thread. This needs to target a specific node.
    88 
    8986    RefPtr<ThreadedScrollingTree> threadedScrollingTree = downcast<ThreadedScrollingTree>(scrollingTree());
    9087    ScrollingThread::dispatch([threadedScrollingTree, wheelEvent, targetNode] {
     
    9289    });
    9390    return true;
     91}
     92
     93static uint64_t nextDeferIdentifier()
     94{
     95    static uint64_t deferIdentifier;
     96    return ++deferIdentifier;
     97}
     98
     99void ScrollingCoordinatorMac::wheelEventWasProcessedByMainThread(const PlatformWheelEvent& wheelEvent, OptionSet<EventHandling> defaultHandling)
     100{
     101    uint64_t deferIdentifier = 0;
     102    if (m_page && m_page->isMonitoringWheelEvents()) {
     103        deferIdentifier = nextDeferIdentifier();
     104        m_page->wheelEventTestMonitor()->deferForReason(reinterpret_cast<WheelEventTestMonitor::ScrollableAreaIdentifier>(deferIdentifier), WheelEventTestMonitor::ReportDOMEventHandling);
     105    }
     106
     107    RefPtr<ThreadedScrollingTree> threadedScrollingTree = downcast<ThreadedScrollingTree>(scrollingTree());
     108    ScrollingThread::dispatch([threadedScrollingTree, wheelEvent, defaultHandling, deferIdentifier] {
     109        threadedScrollingTree->wheelEventWasProcessedByMainThread(wheelEvent, defaultHandling);
     110
     111        if (threadedScrollingTree->isMonitoringWheelEvents())
     112            threadedScrollingTree->removeWheelEventTestCompletionDeferralForReason(reinterpret_cast<WheelEventTestMonitor::ScrollableAreaIdentifier>(deferIdentifier), WheelEventTestMonitor::ReportDOMEventHandling);
     113    });
    94114}
    95115
  • trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.mm

    r269559 r269973  
    7878#if ENABLE(SCROLLING_THREAD)
    7979    if (hasSynchronousScrollingReasons())
    80         return { { WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForDOMEventDispatch }, false };
     80        return { { WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForNonBlockingDOMEventDispatch }, false };
    8181#endif
    8282
  • trunk/Source/WebCore/page/scrolling/nicosia/ScrollingCoordinatorNicosia.cpp

    r266292 r269973  
    7070}
    7171
    72 bool ScrollingCoordinatorNicosia::handleWheelEvent(FrameView&, const PlatformWheelEvent& wheelEvent, ScrollingNodeID targetNode)
     72bool ScrollingCoordinatorNicosia::performDefaultWheelEventHandling(const PlatformWheelEvent& wheelEvent, ScrollingNodeID targetNode)
    7373{
    7474    ASSERT(isMainThread());
     
    8080    });
    8181    return true;
     82}
     83
     84void ScrollingCoordinatorNicosia::wheelEventWasProcessedByMainThread(const PlatformWheelEvent& wheelEvent, OptionSet<EventHandling> defaultHandling)
     85{
     86    ScrollingThread::dispatch([threadedScrollingTree = makeRef(downcast<ThreadedScrollingTree>(*scrollingTree())), wheelEvent, defaultHandling] {
     87        threadedScrollingTree->wheelEventWasProcessedByMainThread(wheelEvent, defaultHandling);
     88    });
    8289}
    8390
  • trunk/Source/WebCore/page/scrolling/nicosia/ScrollingCoordinatorNicosia.h

    r266292 r269973  
    4545    void commitTreeStateIfNeeded() override;
    4646
    47     bool handleWheelEvent(FrameView&, const PlatformWheelEvent&, ScrollingNodeID) override;
     47    bool performDefaultWheelEventHandling(const PlatformWheelEvent&, ScrollingNodeID) override;
     48    void wheelEventWasProcessedByMainThread(const PlatformWheelEvent&, OptionSet<EventHandling>) override;
    4849
    4950private:
  • trunk/Source/WebCore/platform/PlatformEvent.h

    r263208 r269973  
    3030
    3131namespace WebCore {
     32
     33enum class EventHandling : uint8_t {
     34    DispatchedToDOM     = 1 << 0,
     35    DefaultPrevented    = 1 << 1,
     36    DefaultHandled      = 1 << 2,
     37};
    3238
    3339class PlatformEvent {
  • trunk/Source/WebCore/platform/PlatformWheelEvent.cpp

    r269659 r269973  
    6565    case WheelEventProcessingSteps::ScrollingThread: ts << "scrolling thread"; break;
    6666    case WheelEventProcessingSteps::MainThreadForScrolling: ts << "main thread scrolling"; break;
    67     case WheelEventProcessingSteps::MainThreadForDOMEventDispatch: ts << "main thread DOM event dispatch"; break;
     67    case WheelEventProcessingSteps::MainThreadForNonBlockingDOMEventDispatch: ts << "main thread non-blocking DOM event dispatch"; break;
     68    case WheelEventProcessingSteps::MainThreadForBlockingDOMEventDispatch: ts << "main thread blocking DOM event dispatch"; break;
     69    }
     70    return ts;
     71}
     72
     73TextStream& operator<<(TextStream& ts, EventHandling steps)
     74{
     75    switch (steps) {
     76    case EventHandling::DispatchedToDOM: ts << "dispatched to DOM"; break;
     77    case EventHandling::DefaultPrevented: ts << "default prevented"; break;
     78    case EventHandling::DefaultHandled: ts << "default handled"; break;
    6879    }
    6980    return ts;
  • trunk/Source/WebCore/platform/PlatformWheelEvent.h

    r269659 r269973  
    3838
    3939enum class WheelEventProcessingSteps : uint8_t {
    40     ScrollingThread                 = 1 << 0,
    41     MainThreadForScrolling          = 1 << 1,
    42     MainThreadForDOMEventDispatch   = 1 << 2,
     40    ScrollingThread                             = 1 << 0,
     41    MainThreadForScrolling                      = 1 << 1,
     42    MainThreadForNonBlockingDOMEventDispatch    = 1 << 2,
     43    MainThreadForBlockingDOMEventDispatch       = 1 << 3,
    4344};
    4445
     
    266267WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const PlatformWheelEvent&);
    267268WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, WheelEventProcessingSteps);
     269WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, EventHandling);
    268270
    269271} // namespace WebCore
  • trunk/Source/WebKit/ChangeLog

    r269969 r269973  
     12020-11-18  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Propagate wheel event handling back to the scrolling thread
     4        https://bugs.webkit.org/show_bug.cgi?id=219050
     5
     6        Reviewed by Chris Dumez.
     7       
     8        For now, use MainThreadForBlockingDOMEventDispatch for the default steps (used by non-macOS platforms).
     9
     10        * UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp:
     11        (WebKit::RemoteScrollingCoordinatorProxy::handleWheelEvent):
     12        * WebProcess/WebPage/EventDispatcher.cpp:
     13        (WebKit::EventDispatcher::wheelEvent):
     14
    1152020-11-18  Wenson Hsieh  <wenson_hsieh@apple.com>
    216
  • trunk/Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp

    r269184 r269973  
    181181
    182182    auto processingSteps = m_scrollingTree->determineWheelEventProcessing(wheelEvent);
    183     if (processingSteps.containsAny({ WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForDOMEventDispatch }))
     183    if (processingSteps.containsAny({ WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForNonBlockingDOMEventDispatch, WheelEventProcessingSteps::MainThreadForBlockingDOMEventDispatch }))
    184184        return false;
    185185
  • trunk/Source/WebKit/WebProcess/WebPage/EventDispatcher.cpp

    r269659 r269973  
    122122#endif
    123123
    124     auto processingSteps = OptionSet<WebCore::WheelEventProcessingSteps> { WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForDOMEventDispatch };
     124    auto processingSteps = OptionSet<WebCore::WheelEventProcessingSteps> { WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForBlockingDOMEventDispatch };
    125125#if ENABLE(SCROLLING_THREAD)
    126126    processingSteps = [&]() -> OptionSet<WheelEventProcessingSteps> {
     
    129129        auto scrollingTree = m_scrollingTrees.get(pageID);
    130130        if (!scrollingTree)
    131             return { WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForDOMEventDispatch };
     131            return { WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForBlockingDOMEventDispatch };
    132132       
    133133        // FIXME: It's pretty horrible that we're updating the back/forward state here.
  • trunk/Source/WebKitLegacy/win/ChangeLog

    r269704 r269973  
     12020-11-18  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Propagate wheel event handling back to the scrolling thread
     4        https://bugs.webkit.org/show_bug.cgi?id=219050
     5
     6        Reviewed by Chris Dumez.
     7
     8        Use MainThreadForBlockingDOMEventDispatch.
     9
     10        * WebView.cpp:
     11        (WebView::mouseWheel):
     12
    1132020-11-11  Sam Weinig  <weinig@apple.com>
    214
  • trunk/Source/WebKitLegacy/win/WebView.cpp

    r269704 r269973  
    21382138        return false;
    21392139
    2140     return coreFrame->eventHandler().handleWheelEvent(wheelEvent, { WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForDOMEventDispatch });
     2140    return coreFrame->eventHandler().handleWheelEvent(wheelEvent, { WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForBlockingDOMEventDispatch });
    21412141}
    21422142
Note: See TracChangeset for help on using the changeset viewer.