Title: [258679] trunk
Revision
258679
Author
[email protected]
Date
2020-03-18 21:06:37 -0700 (Wed, 18 Mar 2020)

Log Message

eventSender.monitorWheelEvents() is very fragile
https://bugs.webkit.org/show_bug.cgi?id=197819
<rdar://problem/51319456>

Reviewed by Tim Horton.

Source/WebCore:

Deflake tests using eventSender.monitorWheelEvents() by fixing several causes of flakiness,
adding back changes from r257844 that were reverted in r258558.

First, have EventSendingController keep track of whether it's seen then "end" event
for the scrolling and momentum phases, and pass this down to WheelEventTestMonitor, which
now waits until it sees these, which prevents premature triggering which was a common cause of
failure before.

Second, remove WheelEventTestMonitor's 1/60s timer and instead have WheelEventTestMonitor test
for completion in a callout from the end of Page::updateRendering(), which makes it test
and fire at a more consistent time.

Third, push WheelEventTestMonitor to the ScrollingTree, so that reasons for deferral
can be added on the scrolling thread. This fixes an issue where the RunLoop::main().dispatch()
used to send the "ScrollingThreadSyncNeeded" reason to the main thread would get delayed,
also resulting in a premature trigger.

* Modules/applepay/ApplePaySession.cpp: Unified sources!
* dom/WindowEventLoop.cpp: Unified sources!
* page/EventHandler.cpp:
(WebCore::EventHandler::handleWheelEvent):
* page/FrameView.cpp:
(WebCore::FrameView::scrollOffsetChangedViaPlatformWidgetImpl):
* page/Page.cpp:
(WebCore::Page::doAfterUpdateRendering):
(WebCore::Page::wheelEventTestMonitor const):
(WebCore::Page::clearWheelEventTestMonitor):
(WebCore::Page::isMonitoringWheelEvents const):
(WebCore::Page::ensureWheelEventTestMonitor):
* page/Page.h:
(WebCore::Page::wheelEventTestMonitor const): Deleted.
(WebCore::Page::clearWheelEventTestMonitor): Deleted.
(WebCore::Page::isMonitoringWheelEvents const): Deleted.
* page/WheelEventTestMonitor.cpp:
(WebCore::WheelEventTestMonitor::WheelEventTestMonitor):
(WebCore::WheelEventTestMonitor::clearAllTestDeferrals):
(WebCore::WheelEventTestMonitor::setTestCallbackAndStartMonitoring):
(WebCore::WheelEventTestMonitor::deferForReason):
(WebCore::WheelEventTestMonitor::removeDeferralForReason):
(WebCore::WheelEventTestMonitor::receivedWheelEvent):
(WebCore::WheelEventTestMonitor::scheduleCallbackCheck):
(WebCore::WheelEventTestMonitor::checkShouldFireCallbacks):
(WebCore::operator<<):
(WebCore::WheelEventTestMonitor::setTestCallbackAndStartNotificationTimer): Deleted.
(WebCore::WheelEventTestMonitor::triggerTestTimerFired): Deleted.
* page/WheelEventTestMonitor.h:
(WebCore::WheelEventTestMonitorCompletionDeferrer::WheelEventTestMonitorCompletionDeferrer):
(WebCore::WheelEventTestMonitorCompletionDeferrer::~WheelEventTestMonitorCompletionDeferrer):
* page/scrolling/AsyncScrollingCoordinator.cpp:
(WebCore::AsyncScrollingCoordinator::frameViewLayoutUpdated):
(WebCore::AsyncScrollingCoordinator::deferWheelEventTestCompletionForReason const): Deleted.
(WebCore::AsyncScrollingCoordinator::removeWheelEventTestCompletionDeferralForReason const): Deleted.
* page/scrolling/AsyncScrollingCoordinator.h:
* page/scrolling/ScrollingCoordinator.h:
(WebCore::ScrollingCoordinator::startMonitoringWheelEvents):
(WebCore::ScrollingCoordinator::stopMonitoringWheelEvents):
* page/scrolling/ScrollingTree.cpp:
(WebCore::ScrollingTree::handleWheelEvent):
* page/scrolling/ScrollingTree.h:
(WebCore::ScrollingTree::setWheelEventTestMonitor):
(WebCore::ScrollingTree::receivedWheelEvent):
* page/scrolling/ThreadedScrollingTree.cpp:
(WebCore::ThreadedScrollingTree::scrollingTreeNodeDidScroll):
(WebCore::ThreadedScrollingTree::deferWheelEventTestCompletionForReason): Deleted.
(WebCore::ThreadedScrollingTree::removeWheelEventTestCompletionDeferralForReason): Deleted.
* page/scrolling/ThreadedScrollingTree.h:
* page/scrolling/mac/ScrollingCoordinatorMac.h:
* page/scrolling/mac/ScrollingCoordinatorMac.mm:
(WebCore::ScrollingCoordinatorMac::startMonitoringWheelEvents):
(WebCore::ScrollingCoordinatorMac::stopMonitoringWheelEvents):
* page/scrolling/mac/ScrollingTreeMac.h:
* page/scrolling/mac/ScrollingTreeMac.mm:
(ScrollingTreeMac::setWheelEventTestMonitor):
(ScrollingTreeMac::receivedWheelEvent):
(ScrollingTreeMac::deferWheelEventTestCompletionForReason):
(ScrollingTreeMac::removeWheelEventTestCompletionDeferralForReason):
* page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm:
(WebCore::ScrollingTreeScrollingNodeDelegateMac::deferWheelEventTestCompletionForReason const):
(WebCore::ScrollingTreeScrollingNodeDelegateMac::removeWheelEventTestCompletionDeferralForReason const):
* testing/js/WebCoreTestSupport.cpp:
(WebCoreTestSupport::setWheelEventMonitorTestCallbackAndStartMonitoring):
(WebCoreTestSupport::setTestCallbackAndStartNotificationTimer): Deleted.
* testing/js/WebCoreTestSupport.h:

Source/WebKit:

Deflake tests using eventSender.monitorWheelEvents() by fixing several causes of flakiness,
adding back changes from r257844 that were reverted in r258558.

First, have EventSendingController keep track of whether it's seen then "end" event
for the scrolling and momentum phases, and pass this down to WheelEventTestMonitor, which
now waits until it sees these, which prevents premature triggering which was a common cause of
failure before.

Second, remove WheelEventTestMonitor's 1/60s timer and instead have WheelEventTestMonitor test
for completion in a callout from the end of Page::updateRendering(), which makes it test
and fire at a more consistent time.

Third, push WheelEventTestMonitor to the ScrollingTree, so that reasons for deferral
can be added on the scrolling thread. This fixes an issue where the RunLoop::main().dispatch()
used to send the "ScrollingThreadSyncNeeded" reason to the main thread would get delayed,
also resulting in a premature trigger.

* WebProcess/InjectedBundle/API/c/WKBundlePage.cpp:
(WKBundlePageRegisterScrollOperationCompletionCallback):
* WebProcess/InjectedBundle/API/c/WKBundlePage.h:

Tools:

Deflake tests using eventSender.monitorWheelEvents() by fixing several causes of flakiness,
adding back changes from r257844 that were reverted in r258558.

First, have EventSendingController keep track of whether it's seen then "end" event
for the scrolling and momentum phases, and pass this down to WheelEventTestMonitor, which
now waits until it sees these, which prevents premature triggering which was a common cause of
failure before.

Second, remove WheelEventTestMonitor's 1/60s timer and instead have WheelEventTestMonitor test
for completion in a callout from the end of Page::updateRendering(), which makes it test
and fire at a more consistent time.

Third, push WheelEventTestMonitor to the ScrollingTree, so that reasons for deferral
can be added on the scrolling thread. This fixes an issue where the RunLoop::main().dispatch()
used to send the "ScrollingThreadSyncNeeded" reason to the main thread would get delayed,
also resulting in a premature trigger.

* DumpRenderTree/mac/EventSendingController.h:
* DumpRenderTree/mac/EventSendingController.mm:
(-[EventSendingController mouseScrollByX:andY:withWheel:andMomentumPhases:]):
(-[EventSendingController monitorWheelEvents]):
(-[EventSendingController callAfterScrollingCompletes:]):
* DumpRenderTree/win/EventSender.cpp:
(mouseScrollBy):
* WebKitTestRunner/InjectedBundle/EventSendingController.cpp:
(WTR::EventSendingController::mouseScrollByWithWheelAndMomentumPhases):
(WTR::EventSendingController::monitorWheelEvents):
(WTR::EventSendingController::callAfterScrollingCompletes):
* WebKitTestRunner/InjectedBundle/EventSendingController.h:

LayoutTests:

* platform/mac-wk2/TestExpectations:
* platform/win/TestExpectations:
* tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-2d-overflow.html: Need to call eventSender.monitorWheelEvents()
for each subtest.

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (258678 => 258679)


--- trunk/LayoutTests/ChangeLog	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/LayoutTests/ChangeLog	2020-03-19 04:06:37 UTC (rev 258679)
@@ -1,3 +1,16 @@
+2020-03-18  Simon Fraser  <[email protected]>
+
+        eventSender.monitorWheelEvents() is very fragile
+        https://bugs.webkit.org/show_bug.cgi?id=197819
+        <rdar://problem/51319456>
+
+        Reviewed by Tim Horton.
+
+        * platform/mac-wk2/TestExpectations:
+        * platform/win/TestExpectations:
+        * tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-2d-overflow.html: Need to call eventSender.monitorWheelEvents()
+        for each subtest.
+
 2020-03-18  Said Abou-Hallawa  <[email protected]>
 
         svg/custom/animate-initial-pause-unpause.html is flaky

Modified: trunk/LayoutTests/platform/mac-wk2/TestExpectations (258678 => 258679)


--- trunk/LayoutTests/platform/mac-wk2/TestExpectations	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/LayoutTests/platform/mac-wk2/TestExpectations	2020-03-19 04:06:37 UTC (rev 258679)
@@ -1059,8 +1059,6 @@
 
 webkit.org/b/208062 http/wpt/fetch/disable-speculative-for-reload.html [ Pass Failure ]
 
-webkit.org/b/208160 fast/scrolling/overflow-scroll-past-max.html [ Pass Failure ]
-
 webkit.org/b/208222 [ Release ] imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-iceConnectionState.https.html [ Pass Failure ]
 
 webkit.org/b/208340 webgpu/whlsl/textures-sample.html [ Pass ImageOnlyFailure ]

Modified: trunk/LayoutTests/platform/win/TestExpectations (258678 => 258679)


--- trunk/LayoutTests/platform/win/TestExpectations	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/LayoutTests/platform/win/TestExpectations	2020-03-19 04:06:37 UTC (rev 258679)
@@ -276,6 +276,8 @@
 fast/events/wheelevent-in-horizontal-scrollbar-in-rtl.html [ Failure ]
 fast/events/wheelevent-in-vertical-scrollbar-in-rtl.html [ Failure ]
 scrollbars/scroll-rtl-or-bt-layer.html [ Timeout ]
+webkit.org/b/208559 fast/scrolling/arrow-key-scroll-in-rtl-document.html [ Skip ]
+webkit.org/b/208559 fast/scrolling/programmatic-scroll-to-zero-zero.html [ Skip ]
 
 # TODO Needs testRunner.enableAutoResizeMode()
 fast/autoresize/ [ Skip ]

Modified: trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-2d-overflow.html (258678 => 258679)


--- trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-2d-overflow.html	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-2d-overflow.html	2020-03-19 04:06:37 UTC (rev 258679)
@@ -56,6 +56,8 @@
                 x: divTarget.scrollLeft,
                 y: divTarget.scrollTop
             };
+
+            eventSender.monitorWheelEvents();
             eventSender.mouseMoveTo(100, 100);
             eventSender.mouseScrollByWithWheelAndMomentumPhases(-1, 0, "began", "none");
             eventSender.mouseScrollByWithWheelAndMomentumPhases(-1, 0, "changed", "none");
@@ -84,6 +86,7 @@
                 y: divTarget.scrollTop
             };
 
+            eventSender.monitorWheelEvents();
             eventSender.mouseMoveTo(100, 100);
             eventSender.mouseScrollByWithWheelAndMomentumPhases(1, 1, "began", "none");
             eventSender.mouseScrollByWithWheelAndMomentumPhases(1, 1, "changed", "none");
@@ -108,6 +111,7 @@
                 y: divTarget.scrollTop
             };
 
+            eventSender.monitorWheelEvents();
             eventSender.mouseMoveTo(100, 100);
             eventSender.mouseScrollByWithWheelAndMomentumPhases(-1, -1, "began", "none");
             eventSender.mouseScrollByWithWheelAndMomentumPhases(-1, -1, "changed", "none");
@@ -122,7 +126,6 @@
 
         function onLoad() {
             if (window.eventSender) {
-                eventSender.monitorWheelEvents();
                 internals.setPlatformMomentumScrollingPredictionEnabled(false);
                 setTimeout(scrollGlideTest, 0);
             } else {

Modified: trunk/Source/WebCore/ChangeLog (258678 => 258679)


--- trunk/Source/WebCore/ChangeLog	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/Source/WebCore/ChangeLog	2020-03-19 04:06:37 UTC (rev 258679)
@@ -1,3 +1,95 @@
+2020-03-18  Simon Fraser  <[email protected]>
+
+        eventSender.monitorWheelEvents() is very fragile
+        https://bugs.webkit.org/show_bug.cgi?id=197819
+        <rdar://problem/51319456>
+
+        Reviewed by Tim Horton.
+
+        Deflake tests using eventSender.monitorWheelEvents() by fixing several causes of flakiness,
+        adding back changes from r257844 that were reverted in r258558.
+        
+        First, have EventSendingController keep track of whether it's seen then "end" event
+        for the scrolling and momentum phases, and pass this down to WheelEventTestMonitor, which
+        now waits until it sees these, which prevents premature triggering which was a common cause of
+        failure before.
+        
+        Second, remove WheelEventTestMonitor's 1/60s timer and instead have WheelEventTestMonitor test
+        for completion in a callout from the end of Page::updateRendering(), which makes it test
+        and fire at a more consistent time.
+        
+        Third, push WheelEventTestMonitor to the ScrollingTree, so that reasons for deferral
+        can be added on the scrolling thread. This fixes an issue where the RunLoop::main().dispatch()
+        used to send the "ScrollingThreadSyncNeeded" reason to the main thread would get delayed,
+        also resulting in a premature trigger.
+
+        * Modules/applepay/ApplePaySession.cpp: Unified sources!
+        * dom/WindowEventLoop.cpp: Unified sources!
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::handleWheelEvent):
+        * page/FrameView.cpp:
+        (WebCore::FrameView::scrollOffsetChangedViaPlatformWidgetImpl):
+        * page/Page.cpp:
+        (WebCore::Page::doAfterUpdateRendering):
+        (WebCore::Page::wheelEventTestMonitor const):
+        (WebCore::Page::clearWheelEventTestMonitor):
+        (WebCore::Page::isMonitoringWheelEvents const):
+        (WebCore::Page::ensureWheelEventTestMonitor):
+        * page/Page.h:
+        (WebCore::Page::wheelEventTestMonitor const): Deleted.
+        (WebCore::Page::clearWheelEventTestMonitor): Deleted.
+        (WebCore::Page::isMonitoringWheelEvents const): Deleted.
+        * page/WheelEventTestMonitor.cpp:
+        (WebCore::WheelEventTestMonitor::WheelEventTestMonitor):
+        (WebCore::WheelEventTestMonitor::clearAllTestDeferrals):
+        (WebCore::WheelEventTestMonitor::setTestCallbackAndStartMonitoring):
+        (WebCore::WheelEventTestMonitor::deferForReason):
+        (WebCore::WheelEventTestMonitor::removeDeferralForReason):
+        (WebCore::WheelEventTestMonitor::receivedWheelEvent):
+        (WebCore::WheelEventTestMonitor::scheduleCallbackCheck):
+        (WebCore::WheelEventTestMonitor::checkShouldFireCallbacks):
+        (WebCore::operator<<):
+        (WebCore::WheelEventTestMonitor::setTestCallbackAndStartNotificationTimer): Deleted.
+        (WebCore::WheelEventTestMonitor::triggerTestTimerFired): Deleted.
+        * page/WheelEventTestMonitor.h:
+        (WebCore::WheelEventTestMonitorCompletionDeferrer::WheelEventTestMonitorCompletionDeferrer):
+        (WebCore::WheelEventTestMonitorCompletionDeferrer::~WheelEventTestMonitorCompletionDeferrer):
+        * page/scrolling/AsyncScrollingCoordinator.cpp:
+        (WebCore::AsyncScrollingCoordinator::frameViewLayoutUpdated):
+        (WebCore::AsyncScrollingCoordinator::deferWheelEventTestCompletionForReason const): Deleted.
+        (WebCore::AsyncScrollingCoordinator::removeWheelEventTestCompletionDeferralForReason const): Deleted.
+        * page/scrolling/AsyncScrollingCoordinator.h:
+        * page/scrolling/ScrollingCoordinator.h:
+        (WebCore::ScrollingCoordinator::startMonitoringWheelEvents):
+        (WebCore::ScrollingCoordinator::stopMonitoringWheelEvents):
+        * page/scrolling/ScrollingTree.cpp:
+        (WebCore::ScrollingTree::handleWheelEvent):
+        * page/scrolling/ScrollingTree.h:
+        (WebCore::ScrollingTree::setWheelEventTestMonitor):
+        (WebCore::ScrollingTree::receivedWheelEvent):
+        * page/scrolling/ThreadedScrollingTree.cpp:
+        (WebCore::ThreadedScrollingTree::scrollingTreeNodeDidScroll):
+        (WebCore::ThreadedScrollingTree::deferWheelEventTestCompletionForReason): Deleted.
+        (WebCore::ThreadedScrollingTree::removeWheelEventTestCompletionDeferralForReason): Deleted.
+        * page/scrolling/ThreadedScrollingTree.h:
+        * page/scrolling/mac/ScrollingCoordinatorMac.h:
+        * page/scrolling/mac/ScrollingCoordinatorMac.mm:
+        (WebCore::ScrollingCoordinatorMac::startMonitoringWheelEvents):
+        (WebCore::ScrollingCoordinatorMac::stopMonitoringWheelEvents):
+        * page/scrolling/mac/ScrollingTreeMac.h:
+        * page/scrolling/mac/ScrollingTreeMac.mm:
+        (ScrollingTreeMac::setWheelEventTestMonitor):
+        (ScrollingTreeMac::receivedWheelEvent):
+        (ScrollingTreeMac::deferWheelEventTestCompletionForReason):
+        (ScrollingTreeMac::removeWheelEventTestCompletionDeferralForReason):
+        * page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm:
+        (WebCore::ScrollingTreeScrollingNodeDelegateMac::deferWheelEventTestCompletionForReason const):
+        (WebCore::ScrollingTreeScrollingNodeDelegateMac::removeWheelEventTestCompletionDeferralForReason const):
+        * testing/js/WebCoreTestSupport.cpp:
+        (WebCoreTestSupport::setWheelEventMonitorTestCallbackAndStartMonitoring):
+        (WebCoreTestSupport::setTestCallbackAndStartNotificationTimer): Deleted.
+        * testing/js/WebCoreTestSupport.h:
+
 2020-03-18  Fujii Hironori  <[email protected]>
 
         AuthenticatorResponseData::decode should check bufferIsLargeEnoughToContain before allocating buffers

Modified: trunk/Source/WebCore/Modules/applepay/ApplePaySession.cpp (258678 => 258679)


--- trunk/Source/WebCore/Modules/applepay/ApplePaySession.cpp	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/Source/WebCore/Modules/applepay/ApplePaySession.cpp	2020-03-19 04:06:37 UTC (rev 258679)
@@ -63,6 +63,7 @@
 #include "Settings.h"
 #include "UserGestureIndicator.h"
 #include <wtf/IsoMallocInlines.h>
+#include <wtf/RunLoop.h>
 
 #if USE(APPLE_INTERNAL_SDK)
 #include <WebKitAdditions/ApplePaySessionAdditions.cpp>

Modified: trunk/Source/WebCore/dom/WindowEventLoop.cpp (258678 => 258679)


--- trunk/Source/WebCore/dom/WindowEventLoop.cpp	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/Source/WebCore/dom/WindowEventLoop.cpp	2020-03-19 04:06:37 UTC (rev 258679)
@@ -34,6 +34,7 @@
 #include "MutationObserver.h"
 #include "SecurityOrigin.h"
 #include "ThreadGlobalData.h"
+#include <wtf/RunLoop.h>
 
 namespace WebCore {
 

Modified: trunk/Source/WebCore/page/EventHandler.cpp (258678 => 258679)


--- trunk/Source/WebCore/page/EventHandler.cpp	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/Source/WebCore/page/EventHandler.cpp	2020-03-19 04:06:37 UTC (rev 258679)
@@ -103,6 +103,7 @@
 #include "VisibleUnits.h"
 #include "WheelEvent.h"
 #include "WheelEventDeltaFilter.h"
+#include "WheelEventTestMonitor.h"
 #include "WindowsKeyboardCodes.h"
 #include <wtf/Assertions.h>
 #include <wtf/NeverDestroyed.h>
@@ -2825,6 +2826,14 @@
     }
 #endif
 
+#if PLATFORM(COCOA)
+    LOG_WITH_STREAM(WheelEventTestMonitor, stream << "EventHandler::handleWheelEvent on main thread, phase " << event.phase() << " momentum phase " << event.momentumPhase());
+    if (auto monitor = m_frame.page()->wheelEventTestMonitor())
+        monitor->receivedWheelEvent(event);
+
+    WheelEventTestMonitorCompletionDeferrer deferrer(m_frame.page()->wheelEventTestMonitor().get(), this, WheelEventTestMonitor::DeferReason::HandlingWheelEventOnMainThread);
+#endif
+
     m_isHandlingWheelEvent = true;
     setFrameWasScrolledByUser();
 

Modified: trunk/Source/WebCore/page/FrameView.cpp (258678 => 258679)


--- trunk/Source/WebCore/page/FrameView.cpp	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/Source/WebCore/page/FrameView.cpp	2020-03-19 04:06:37 UTC (rev 258679)
@@ -2445,6 +2445,10 @@
 
 void FrameView::scrollOffsetChangedViaPlatformWidgetImpl(const ScrollOffset& oldOffset, const ScrollOffset& newOffset)
 {
+#if PLATFORM(COCOA)
+    WheelEventTestMonitorCompletionDeferrer deferrer(frame().page()->wheelEventTestMonitor().get(), this, WheelEventTestMonitor::DeferReason::ContentScrollInProgress);
+#endif
+
     updateLayerPositionsAfterScrolling();
     updateCompositingLayersAfterScrolling();
     repaintSlowRepaintObjects();

Modified: trunk/Source/WebCore/page/Page.cpp (258678 => 258679)


--- trunk/Source/WebCore/page/Page.cpp	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/Source/WebCore/page/Page.cpp	2020-03-19 04:06:37 UTC (rev 258679)
@@ -130,6 +130,7 @@
 #include "VisitedLinkStore.h"
 #include "VoidCallback.h"
 #include "WheelEventDeltaFilter.h"
+#include "WheelEventTestMonitor.h"
 #include "Widget.h"
 #include <wtf/FileSystem.h>
 #include <wtf/RefCountedLeakCounter.h>
@@ -1390,6 +1391,9 @@
         document->updateTouchEventRegions();
 #endif
 
+    if (UNLIKELY(isMonitoringWheelEvents()))
+        wheelEventTestMonitor()->checkShouldFireCallbacks();
+
 #if ASSERT_ENABLED
     for (Frame* child = mainFrame().tree().firstRenderedChild(); child; child = child->tree().traverseNextRendered()) {
         auto* frameView = child->view();
@@ -2621,14 +2625,34 @@
 
 #endif
 
+RefPtr<WheelEventTestMonitor> Page::wheelEventTestMonitor() const
+{
+    return m_wheelEventTestMonitor;
+}
+
+void Page::clearWheelEventTestMonitor()
+{
+    if (m_scrollingCoordinator)
+        m_scrollingCoordinator->stopMonitoringWheelEvents();
+
+    m_wheelEventTestMonitor = nullptr;
+}
+
+bool Page::isMonitoringWheelEvents() const
+{
+    return !!m_wheelEventTestMonitor;
+}
+
 WheelEventTestMonitor& Page::ensureWheelEventTestMonitor()
 {
     if (!m_wheelEventTestMonitor) {
-        m_wheelEventTestMonitor = adoptRef(new WheelEventTestMonitor());
+        m_wheelEventTestMonitor = adoptRef(new WheelEventTestMonitor(*this));
         // We need to update the scrolling coordinator so that the mainframe scrolling node can expect wheel event test triggers.
         if (auto* frameView = mainFrame().view()) {
-            if (m_scrollingCoordinator)
+            if (m_scrollingCoordinator) {
+                m_scrollingCoordinator->startMonitoringWheelEvents();
                 m_scrollingCoordinator->updateIsMonitoringWheelEventsForFrameView(*frameView);
+            }
         }
     }
 

Modified: trunk/Source/WebCore/page/Page.h (258678 => 258679)


--- trunk/Source/WebCore/page/Page.h	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/Source/WebCore/page/Page.h	2020-03-19 04:06:37 UTC (rev 258679)
@@ -40,7 +40,6 @@
 #include "UserInterfaceLayoutDirection.h"
 #include "ViewportArguments.h"
 #include "VisibilityState.h"
-#include "WheelEventTestMonitor.h"
 #include <memory>
 #include <pal/SessionID.h>
 #include <wtf/Assertions.h>
@@ -147,6 +146,7 @@
 class VisitedLinkStore;
 class WebGLStateTracker;
 class WheelEventDeltaFilter;
+class WheelEventTestMonitor;
 
 using SharedStringHash = uint32_t;
 
@@ -649,10 +649,10 @@
     WEBCORE_EXPORT void playbackTargetPickerWasDismissed(uint64_t);
 #endif
 
-    RefPtr<WheelEventTestMonitor> wheelEventTestMonitor() const { return m_wheelEventTestMonitor; }
+    WEBCORE_EXPORT RefPtr<WheelEventTestMonitor> wheelEventTestMonitor() const;
     WEBCORE_EXPORT WheelEventTestMonitor& ensureWheelEventTestMonitor();
-    void clearWheelEventTestMonitor() { m_wheelEventTestMonitor = nullptr; }
-    bool isMonitoringWheelEvents() const { return !!m_wheelEventTestMonitor; }
+    WEBCORE_EXPORT void clearWheelEventTestMonitor();
+    WEBCORE_EXPORT bool isMonitoringWheelEvents() const;
 
 #if ENABLE(VIDEO)
     bool allowsMediaDocumentInlinePlayback() const { return m_allowsMediaDocumentInlinePlayback; }

Modified: trunk/Source/WebCore/page/WheelEventTestMonitor.cpp (258678 => 258679)


--- trunk/Source/WebCore/page/WheelEventTestMonitor.cpp	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/Source/WebCore/page/WheelEventTestMonitor.cpp	2020-03-19 04:06:37 UTC (rev 258679)
@@ -30,7 +30,9 @@
 #include "WheelEventTestMonitor.h"
 
 #include "Logging.h"
+#include "Page.h"
 #include <wtf/OptionSet.h>
+#include <wtf/RunLoop.h>
 #include <wtf/text/TextStream.h>
 
 #if !LOG_DISABLED
@@ -40,42 +42,56 @@
 
 namespace WebCore {
 
-WheelEventTestMonitor::WheelEventTestMonitor()
-    : m_testForCompletionTimer(RunLoop::current(), this, &WheelEventTestMonitor::triggerTestTimerFired)
+WheelEventTestMonitor::WheelEventTestMonitor(Page& page)
+    : m_page(page)
 {
 }
 
 void WheelEventTestMonitor::clearAllTestDeferrals()
 {
+    LockHolder lock(m_mutex);
+
     ASSERT(isMainThread());
     m_deferCompletionReasons.clear();
     m_completionCallback = nullptr;
-    m_testForCompletionTimer.stop();
-    LOG_WITH_STREAM(WheelEventTestMonitor, stream << "      (=) WheelEventTestMonitor::clearAllTestDeferrals: cleared all test state.");
+    m_everHadDeferral = false;
+    m_receivedWheelEndOrCancel = false;
+    m_receivedMomentumEnd = false;
+    LOG_WITH_STREAM(WheelEventTestMonitor, stream << "  WheelEventTestMonitor::clearAllTestDeferrals: cleared all test state.");
 }
 
-void WheelEventTestMonitor::setTestCallbackAndStartNotificationTimer(WTF::Function<void()>&& functionCallback)
+void WheelEventTestMonitor::setTestCallbackAndStartMonitoring(bool expectWheelEndOrCancel, bool expectMomentumEnd, WTF::Function<void()>&& functionCallback)
 {
     ASSERT(isMainThread());
     m_completionCallback = WTFMove(functionCallback);
-    
-    if (!m_testForCompletionTimer.isActive())
-        m_testForCompletionTimer.startRepeating(1_s / 60.);
+#if ENABLE(KINETIC_SCROLLING)
+    m_expectWheelEndOrCancel = expectWheelEndOrCancel;
+    m_expectMomentumEnd = expectMomentumEnd;
+#else
+    UNUSED_PARAM(expectWheelEndOrCancel);
+    UNUSED_PARAM(expectMomentumEnd);
+#endif
+
+    LOG_WITH_STREAM(WheelEventTestMonitor, stream << "  WheelEventTestMonitor::setTestCallbackAndStartMonitoring - expect end/cancel " << expectWheelEndOrCancel << ", expect momenum end " << expectMomentumEnd);
 }
 
 void WheelEventTestMonitor::deferForReason(ScrollableAreaIdentifier identifier, DeferReason reason)
 {
-    ASSERT(isMainThread());
+    LockHolder lock(m_mutex);
+
     m_deferCompletionReasons.ensure(identifier, [] {
         return OptionSet<DeferReason>();
     }).iterator->value.add(reason);
-    
+
+    m_everHadDeferral = true;
+
     LOG_WITH_STREAM(WheelEventTestMonitor, stream << "      (=) WheelEventTestMonitor::deferForReason: id=" << identifier << ", reason=" << reason);
 }
 
 void WheelEventTestMonitor::removeDeferralForReason(ScrollableAreaIdentifier identifier, DeferReason reason)
 {
-    ASSERT(isMainThread());
+    LockHolder lock(m_mutex);
+
     auto it = m_deferCompletionReasons.find(identifier);
     if (it == m_deferCompletionReasons.end())
         return;
@@ -85,22 +101,66 @@
     
     if (it->value.isEmpty())
         m_deferCompletionReasons.remove(it);
+
+    scheduleCallbackCheck();
 }
-    
-void WheelEventTestMonitor::triggerTestTimerFired()
+
+void WheelEventTestMonitor::receivedWheelEvent(const PlatformWheelEvent& event)
 {
-    ASSERT(isMainThread());
-    if (!m_deferCompletionReasons.isEmpty()) {
-        LOG_WITH_STREAM(WheelEventTestMonitor, stream << "  WheelEventTestMonitor::triggerTestTimerFired - scrolling still active, reasons " << m_deferCompletionReasons);
+#if ENABLE(KINETIC_SCROLLING)
+    if (event.phase() == PlatformWheelEventPhaseEnded || event.phase() == PlatformWheelEventPhaseCancelled)
+        m_receivedWheelEndOrCancel = true;
+
+    if (event.momentumPhase() == PlatformWheelEventPhaseEnded)
+        m_receivedMomentumEnd = true;
+#endif
+}
+
+void WheelEventTestMonitor::scheduleCallbackCheck()
+{
+    if (isMainThread()) {
+        m_page.scheduleRenderingUpdate();
         return;
     }
 
-    auto functionCallback = WTFMove(m_completionCallback);
-    m_testForCompletionTimer.stop();
+    RunLoop::main().dispatch([weakPage = makeWeakPtr(m_page)] {
+        if (weakPage)
+            weakPage->scheduleRenderingUpdate();
+    });
+}
 
-    LOG_WITH_STREAM(WheelEventTestMonitor, stream << "  WheelEventTestMonitor::triggerTestTimerFired: scrolling is idle, FIRING TEST");
-    if (functionCallback)
+void WheelEventTestMonitor::checkShouldFireCallbacks()
+{
+    ASSERT(isMainThread());
+    {
+        LockHolder lock(m_mutex);
+
+        if (!m_deferCompletionReasons.isEmpty()) {
+            LOG_WITH_STREAM(WheelEventTestMonitor, stream << "  WheelEventTestMonitor::checkShouldFireCallbacks - scrolling still active, reasons " << m_deferCompletionReasons);
+            return;
+        }
+
+        if (!m_everHadDeferral) {
+            LOG_WITH_STREAM(WheelEventTestMonitor, stream << "  WheelEventTestMonitor::checkShouldFireCallbacks - have not yet seen any deferral reasons");
+            return;
+        }
+        
+        if (m_expectWheelEndOrCancel && !m_receivedWheelEndOrCancel) {
+            LOG_WITH_STREAM(WheelEventTestMonitor, stream << "  WheelEventTestMonitor::checkShouldFireCallbacks - have not seen end of of wheel phase");
+            return;
+        }
+
+        if (m_expectMomentumEnd && !m_receivedMomentumEnd) {
+            LOG_WITH_STREAM(WheelEventTestMonitor, stream << "  WheelEventTestMonitor::checkShouldFireCallbacks - have not seen end of of momentum phase");
+            return;
+        }
+    }
+
+    if (auto functionCallback = WTFMove(m_completionCallback)) {
+        LOG_WITH_STREAM(WheelEventTestMonitor, stream << "  WheelEventTestMonitor::checkShouldFireCallbacks: scrolling is idle, FIRING TEST");
         functionCallback();
+    } else
+        LOG_WITH_STREAM(WheelEventTestMonitor, stream << "  WheelEventTestMonitor::checkShouldFireCallbacks - no callback");
 }
 
 TextStream& operator<<(TextStream& ts, WheelEventTestMonitor::DeferReason reason)
@@ -107,6 +167,7 @@
 {
     switch (reason) {
     case WheelEventTestMonitor::HandlingWheelEvent: ts << "handling wheel event"; break;
+    case WheelEventTestMonitor::HandlingWheelEventOnMainThread: ts << "handling wheel event on main thread"; 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 (258678 => 258679)


--- trunk/Source/WebCore/page/WheelEventTestMonitor.h	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/Source/WebCore/page/WheelEventTestMonitor.h	2020-03-19 04:06:37 UTC (rev 258679)
@@ -28,47 +28,81 @@
 
 #pragma once
 
+#include "PlatformWheelEvent.h"
 #include <functional>
 #include <wtf/Function.h>
 #include <wtf/HashMap.h>
 #include <wtf/Lock.h>
-#include <wtf/RunLoop.h>
-#include <wtf/StdSet.h>
 #include <wtf/ThreadSafeRefCounted.h>
 
 namespace WebCore {
 
+class Page;
+
 class WheelEventTestMonitor : public ThreadSafeRefCounted<WheelEventTestMonitor> {
     WTF_MAKE_NONCOPYABLE(WheelEventTestMonitor); WTF_MAKE_FAST_ALLOCATED;
 public:
-    WheelEventTestMonitor();
+    WheelEventTestMonitor(Page&);
 
-    WEBCORE_EXPORT void setTestCallbackAndStartNotificationTimer(WTF::Function<void()>&&);
+    WEBCORE_EXPORT void setTestCallbackAndStartMonitoring(bool expectWheelEndOrCancel, bool expectMomentumEnd, WTF::Function<void()>&&);
     WEBCORE_EXPORT void clearAllTestDeferrals();
     
     enum DeferReason {
-        HandlingWheelEvent          = 1 << 0,
-        RubberbandInProgress        = 1 << 1,
-        ScrollSnapInProgress        = 1 << 2,
-        ScrollingThreadSyncNeeded   = 1 << 3,
-        ContentScrollInProgress     = 1 << 4,
+        HandlingWheelEvent              = 1 << 0,
+        HandlingWheelEventOnMainThread  = 1 << 1,
+        RubberbandInProgress            = 1 << 2,
+        ScrollSnapInProgress            = 1 << 3,
+        ScrollingThreadSyncNeeded       = 1 << 4,
+        ContentScrollInProgress         = 1 << 5,
     };
     typedef const void* ScrollableAreaIdentifier;
 
+    WEBCORE_EXPORT void receivedWheelEvent(const PlatformWheelEvent&);
     WEBCORE_EXPORT void deferForReason(ScrollableAreaIdentifier, DeferReason);
     WEBCORE_EXPORT void removeDeferralForReason(ScrollableAreaIdentifier, DeferReason);
     
-    void triggerTestTimerFired();
+    void checkShouldFireCallbacks();
 
     using ScrollableAreaReasonMap = WTF::HashMap<ScrollableAreaIdentifier, OptionSet<DeferReason>>;
 
 private:
+    void scheduleCallbackCheck();
+
     WTF::Function<void()> m_completionCallback;
-    RunLoop::Timer<WheelEventTestMonitor> m_testForCompletionTimer;
+    Page& m_page;
 
+    Lock m_mutex;
     ScrollableAreaReasonMap m_deferCompletionReasons;
+    bool m_expectWheelEndOrCancel { false };
+    bool m_receivedWheelEndOrCancel { false };
+    bool m_expectMomentumEnd { false };
+    bool m_receivedMomentumEnd { false };
+    bool m_everHadDeferral { false };
 };
 
+class WheelEventTestMonitorCompletionDeferrer {
+public:
+    WheelEventTestMonitorCompletionDeferrer(WheelEventTestMonitor* monitor, WheelEventTestMonitor::ScrollableAreaIdentifier identifier, WheelEventTestMonitor::DeferReason reason)
+        : m_monitor(monitor)
+        , m_identifier(identifier)
+        , m_reason(reason)
+    {
+        if (m_monitor)
+            m_monitor->deferForReason(m_identifier, m_reason);
+    }
+    
+    ~WheelEventTestMonitorCompletionDeferrer()
+    {
+        if (m_monitor)
+            m_monitor->removeDeferralForReason(m_identifier, m_reason);
+    }
+
+private:
+    RefPtr<WheelEventTestMonitor> m_monitor;
+    WheelEventTestMonitor::ScrollableAreaIdentifier m_identifier;
+    WheelEventTestMonitor::DeferReason m_reason;
+};
+
 WTF::TextStream& operator<<(WTF::TextStream&, WheelEventTestMonitor::DeferReason);
 WTF::TextStream& operator<<(WTF::TextStream&, const WheelEventTestMonitor::ScrollableAreaReasonMap&);
 

Modified: trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp (258678 => 258679)


--- trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp	2020-03-19 04:06:37 UTC (rev 258679)
@@ -138,8 +138,6 @@
 
     auto* page = frameView.frame().page();
     if (page && page->isMonitoringWheelEvents()) {
-        LOG_WITH_STREAM(WheelEventTestMonitor, stream << "    AsyncScrollingCoordinator::frameViewLayoutUpdated: Expects wheel event test trigger: " << page->isMonitoringWheelEvents());
-
         auto* node = m_scrollingStateTree->stateNodeForID(frameView.scrollingNodeID());
         if (!is<ScrollingStateFrameScrollingNode>(node))
             return;
@@ -826,29 +824,6 @@
     }
 }
 
-void AsyncScrollingCoordinator::deferWheelEventTestCompletionForReason(WheelEventTestMonitor::ScrollableAreaIdentifier identifier, WheelEventTestMonitor::DeferReason reason) const
-{
-    ASSERT(isMainThread());
-    if (!m_page || !m_page->isMonitoringWheelEvents())
-        return;
-
-    if (const auto& trigger = m_page->wheelEventTestMonitor()) {
-        LOG_WITH_STREAM(WheelEventTestMonitor, stream << "    (!) AsyncScrollingCoordinator::deferForReason: Deferring " << identifier << " for reason " << reason);
-        trigger->deferForReason(identifier, reason);
-    }
-}
-
-void AsyncScrollingCoordinator::removeWheelEventTestCompletionDeferralForReason(WheelEventTestMonitor::ScrollableAreaIdentifier identifier, WheelEventTestMonitor::DeferReason reason) const
-{
-    ASSERT(isMainThread());
-    if (!m_page || !m_page->isMonitoringWheelEvents())
-        return;
-
-    if (const auto& trigger = m_page->wheelEventTestMonitor()) {
-        LOG_WITH_STREAM(WheelEventTestMonitor, stream << "    (!) AsyncScrollingCoordinator::removeWheelEventTestCompletionDeferralForReason: Deferring " << identifier << " for reason " << reason);
-        trigger->removeDeferralForReason(identifier, reason);
-    }
-}
 #endif
 
 #if ENABLE(CSS_SCROLL_SNAP)

Modified: trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h (258678 => 258679)


--- trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h	2020-03-19 04:06:37 UTC (rev 258679)
@@ -55,8 +55,6 @@
 
 #if PLATFORM(COCOA)
     WEBCORE_EXPORT void setActiveScrollSnapIndices(ScrollingNodeID, unsigned horizontalIndex, unsigned verticalIndex);
-    void deferWheelEventTestCompletionForReason(WheelEventTestMonitor::ScrollableAreaIdentifier, WheelEventTestMonitor::DeferReason) const;
-    void removeWheelEventTestCompletionDeferralForReason(WheelEventTestMonitor::ScrollableAreaIdentifier, WheelEventTestMonitor::DeferReason) const;
 #endif
 
 #if ENABLE(CSS_SCROLL_SNAP)

Modified: trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h (258678 => 258679)


--- trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h	2020-03-19 04:06:37 UTC (rev 258679)
@@ -180,6 +180,9 @@
     EventTrackingRegions absoluteEventTrackingRegions() const;
     virtual void updateIsMonitoringWheelEventsForFrameView(const FrameView&) { }
 
+    virtual void startMonitoringWheelEvents() { }
+    virtual void stopMonitoringWheelEvents() { }
+
 protected:
     explicit ScrollingCoordinator(Page*);
 

Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp (258678 => 258679)


--- trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp	2020-03-19 04:06:37 UTC (rev 258679)
@@ -96,6 +96,9 @@
 
     LockHolder locker(m_treeMutex);
 
+    if (isMonitoringWheelEvents())
+        receivedWheelEvent(wheelEvent);
+
     if (!asyncFrameOrOverflowScrollingEnabled()) {
         if (m_rootNode)
             m_rootNode->handleWheelEvent(wheelEvent);

Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.h (258678 => 258679)


--- trunk/Source/WebCore/page/scrolling/ScrollingTree.h	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.h	2020-03-19 04:06:37 UTC (rev 258679)
@@ -33,6 +33,7 @@
 #include "WheelEventTestMonitor.h"
 #include <wtf/HashMap.h>
 #include <wtf/Lock.h>
+#include <wtf/MonotonicTime.h>
 #include <wtf/ThreadSafeRefCounted.h>
 #include <wtf/TypeCasts.h>
 
@@ -107,6 +108,8 @@
     virtual void handleWheelEventPhase(PlatformWheelEventPhase) = 0;
     virtual void setActiveScrollSnapIndices(ScrollingNodeID, unsigned /*horizontalIndex*/, unsigned /*verticalIndex*/) { }
 
+    virtual void setWheelEventTestMonitor(RefPtr<WheelEventTestMonitor>&&) { }
+
     virtual void deferWheelEventTestCompletionForReason(WheelEventTestMonitor::ScrollableAreaIdentifier, WheelEventTestMonitor::DeferReason) { }
     virtual void removeWheelEventTestCompletionDeferralForReason(WheelEventTestMonitor::ScrollableAreaIdentifier, WheelEventTestMonitor::DeferReason) { }
 #endif
@@ -178,6 +181,7 @@
     void notifyRelatedNodesRecursive(ScrollingTreeNode&);
 
     WEBCORE_EXPORT virtual RefPtr<ScrollingTreeNode> scrollingNodeForPoint(FloatPoint);
+    virtual void receivedWheelEvent(const PlatformWheelEvent&) { }
 
     Lock m_treeMutex; // Protects the scrolling tree.
 

Modified: trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp (258678 => 258679)


--- trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp	2020-03-19 04:06:37 UTC (rev 258679)
@@ -99,7 +99,6 @@
         return;
 
     auto scrollPosition = node.currentScrollPosition();
-
     if (node.isRootNode())
         setMainFrameScrollPosition(scrollPosition);
 
@@ -116,11 +115,12 @@
     if (monitoringWheelEvents)
         deferWheelEventTestCompletionForReason(reinterpret_cast<WheelEventTestMonitor::ScrollableAreaIdentifier>(node.scrollingNodeID()), WheelEventTestMonitor::ScrollingThreadSyncNeeded);
 #endif
-    RunLoop::main().dispatch([scrollingCoordinator = m_scrollingCoordinator, nodeID = node.scrollingNodeID(), scrollPosition, layoutViewportOrigin, scrollingLayerPositionAction, monitoringWheelEvents] {
-        scrollingCoordinator->scheduleUpdateScrollPositionAfterAsyncScroll(nodeID, scrollPosition, layoutViewportOrigin, scrollingLayerPositionAction);
+
+    RunLoop::main().dispatch([strongThis = makeRef(*this), nodeID = node.scrollingNodeID(), scrollPosition, layoutViewportOrigin, scrollingLayerPositionAction, monitoringWheelEvents] {
+        strongThis->m_scrollingCoordinator->scheduleUpdateScrollPositionAfterAsyncScroll(nodeID, scrollPosition, layoutViewportOrigin, scrollingLayerPositionAction);
 #if PLATFORM(MAC)
         if (monitoringWheelEvents)
-            scrollingCoordinator->removeWheelEventTestCompletionDeferralForReason(reinterpret_cast<WheelEventTestMonitor::ScrollableAreaIdentifier>(nodeID), WheelEventTestMonitor::ScrollingThreadSyncNeeded);
+            strongThis->removeWheelEventTestCompletionDeferralForReason(reinterpret_cast<WheelEventTestMonitor::ScrollableAreaIdentifier>(nodeID), WheelEventTestMonitor::ScrollingThreadSyncNeeded);
 #else
         UNUSED_PARAM(monitoringWheelEvents);
 #endif
@@ -203,26 +203,6 @@
     });
 }
 
-void ThreadedScrollingTree::deferWheelEventTestCompletionForReason(WheelEventTestMonitor::ScrollableAreaIdentifier identifier, WheelEventTestMonitor::DeferReason reason)
-{
-    if (!m_scrollingCoordinator)
-        return;
-
-    RunLoop::main().dispatch([scrollingCoordinator = m_scrollingCoordinator, identifier, reason] {
-        scrollingCoordinator->deferWheelEventTestCompletionForReason(identifier, reason);
-    });
-}
-
-void ThreadedScrollingTree::removeWheelEventTestCompletionDeferralForReason(WheelEventTestMonitor::ScrollableAreaIdentifier identifier, WheelEventTestMonitor::DeferReason reason)
-{
-    if (!m_scrollingCoordinator)
-        return;
-    
-    RunLoop::main().dispatch([scrollingCoordinator = m_scrollingCoordinator, identifier, reason] {
-        scrollingCoordinator->removeWheelEventTestCompletionDeferralForReason(identifier, reason);
-    });
-}
-
 #endif
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.h (258678 => 258679)


--- trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.h	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.h	2020-03-19 04:06:37 UTC (rev 258679)
@@ -65,9 +65,6 @@
 #if PLATFORM(MAC)
     void handleWheelEventPhase(PlatformWheelEventPhase) override;
     void setActiveScrollSnapIndices(ScrollingNodeID, unsigned horizontalIndex, unsigned verticalIndex) override;
-
-    void deferWheelEventTestCompletionForReason(WheelEventTestMonitor::ScrollableAreaIdentifier, WheelEventTestMonitor::DeferReason) override;
-    void removeWheelEventTestCompletionDeferralForReason(WheelEventTestMonitor::ScrollableAreaIdentifier, WheelEventTestMonitor::DeferReason) override;
 #endif
 
 #if PLATFORM(COCOA)

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


--- trunk/Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.h	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.h	2020-03-19 04:06:37 UTC (rev 258679)
@@ -47,6 +47,9 @@
     void scheduleTreeStateCommit() final;
 
     void updateTiledScrollingIndicator();
+
+    void startMonitoringWheelEvents() final;
+    void stopMonitoringWheelEvents() final;
 };
 
 } // namespace WebCore

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


--- trunk/Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.mm	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.mm	2020-03-19 04:06:37 UTC (rev 258679)
@@ -136,6 +136,17 @@
     tiledBacking->setScrollingModeIndication(indicatorMode);
 }
 
+void ScrollingCoordinatorMac::startMonitoringWheelEvents()
+{
+    auto monitor = m_page->wheelEventTestMonitor();
+    scrollingTree()->setWheelEventTestMonitor(WTFMove(monitor));
+}
+
+void ScrollingCoordinatorMac::stopMonitoringWheelEvents()
+{
+    scrollingTree()->setWheelEventTestMonitor(nullptr);
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(ASYNC_SCROLLING) && ENABLE(SCROLLING_THREAD)

Modified: trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeMac.h (258678 => 258679)


--- trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeMac.h	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeMac.h	2020-03-19 04:06:37 UTC (rev 258679)
@@ -31,6 +31,8 @@
 
 namespace WebCore {
 
+class WheelEventTestMonitor;
+
 class ScrollingTreeMac final : public ThreadedScrollingTree {
 public:
     static Ref<ScrollingTreeMac> create(AsyncScrollingCoordinator&);
@@ -42,11 +44,20 @@
 
     RefPtr<ScrollingTreeNode> scrollingNodeForPoint(FloatPoint) final;
 
+    void setWheelEventTestMonitor(RefPtr<WheelEventTestMonitor>&&) final;
+
+    void receivedWheelEvent(const PlatformWheelEvent&) final;
+
+    void deferWheelEventTestCompletionForReason(WheelEventTestMonitor::ScrollableAreaIdentifier, WheelEventTestMonitor::DeferReason) final;
+    void removeWheelEventTestCompletionDeferralForReason(WheelEventTestMonitor::ScrollableAreaIdentifier, WheelEventTestMonitor::DeferReason) final;
+
     void lockLayersForHitTesting() final;
     void unlockLayersForHitTesting() final;
 
     // This lock protects the CALayer/PlatformCALayer tree.
     Lock m_layerHitTestMutex;
+    
+    RefPtr<WheelEventTestMonitor> m_wheelEventTestMonitor;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeMac.mm (258678 => 258679)


--- trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeMac.mm	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeMac.mm	2020-03-19 04:06:37 UTC (rev 258679)
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "ScrollingTreeMac.h"
 
+#include "Logging.h"
 #include "PlatformCALayer.h"
 #include "ScrollingTreeFixedNode.h"
 #include "ScrollingTreeFrameHostingNode.h"
@@ -35,6 +36,8 @@
 #include "ScrollingTreePositionedNode.h"
 #include "ScrollingTreeStickyNode.h"
 #include "WebLayer.h"
+#include "WheelEventTestMonitor.h"
+#include <wtf/text/TextStream.h>
 
 #if ENABLE(ASYNC_SCROLLING) && ENABLE(SCROLLING_THREAD)
 
@@ -188,4 +191,36 @@
     m_layerHitTestMutex.unlock();
 }
 
+void ScrollingTreeMac::setWheelEventTestMonitor(RefPtr<WheelEventTestMonitor>&& monitor)
+{
+    m_wheelEventTestMonitor = WTFMove(monitor);
+}
+
+void ScrollingTreeMac::receivedWheelEvent(const PlatformWheelEvent& event)
+{
+    auto monitor = m_wheelEventTestMonitor;
+    if (monitor)
+        monitor->receivedWheelEvent(event);
+}
+
+void ScrollingTreeMac::deferWheelEventTestCompletionForReason(WheelEventTestMonitor::ScrollableAreaIdentifier identifier, WheelEventTestMonitor::DeferReason reason)
+{
+    auto monitor = m_wheelEventTestMonitor;
+    if (!monitor)
+        return;
+
+    LOG_WITH_STREAM(WheelEventTestMonitor, stream << "    (!) ScrollingTreeMac::deferForReason: Deferring on " << identifier << " for reason " << reason);
+    monitor->deferForReason(identifier, reason);
+}
+
+void ScrollingTreeMac::removeWheelEventTestCompletionDeferralForReason(WheelEventTestMonitor::ScrollableAreaIdentifier identifier, WheelEventTestMonitor::DeferReason reason)
+{
+    auto monitor = m_wheelEventTestMonitor;
+    if (!monitor)
+        return;
+
+    LOG_WITH_STREAM(WheelEventTestMonitor, stream << "    (!) ScrollingTreeMac::removeDeferralForReason: Removing deferral on " << identifier << " for reason " << reason);
+    monitor->removeDeferralForReason(identifier, reason);
+}
+
 #endif // ENABLE(ASYNC_SCROLLING) && ENABLE(SCROLLING_THREAD)

Modified: trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm (258678 => 258679)


--- trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm	2020-03-19 04:06:37 UTC (rev 258679)
@@ -307,7 +307,6 @@
     if (!scrollingTree().isMonitoringWheelEvents())
         return;
 
-    LOG_WITH_STREAM(WheelEventTestMonitor, stream << isMainThread() << "  ScrollingTreeScrollingNodeDelegateMac::deferForReason: STARTING deferral for " << identifier << " because of " << reason);
     scrollingTree().deferWheelEventTestCompletionForReason(identifier, reason);
 }
     
@@ -316,7 +315,6 @@
     if (!scrollingTree().isMonitoringWheelEvents())
         return;
     
-    LOG_WITH_STREAM(WheelEventTestMonitor, stream << isMainThread() << "  ScrollingTreeScrollingNodeDelegateMac::deferForReason: ENDING deferral for " << identifier << " because of " << reason);
     scrollingTree().removeWheelEventTestCompletionDeferralForReason(identifier, reason);
 }
 

Modified: trunk/Source/WebCore/testing/js/WebCoreTestSupport.cpp (258678 => 258679)


--- trunk/Source/WebCore/testing/js/WebCoreTestSupport.cpp	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/Source/WebCore/testing/js/WebCoreTestSupport.cpp	2020-03-19 04:06:37 UTC (rev 258679)
@@ -88,7 +88,7 @@
     page->ensureWheelEventTestMonitor().clearAllTestDeferrals();
 }
 
-void setTestCallbackAndStartNotificationTimer(WebCore::Frame& frame, JSContextRef context, JSObjectRef jsCallbackFunction)
+void setWheelEventMonitorTestCallbackAndStartMonitoring(bool expectWheelEndOrCancel, bool expectMomentumEnd, WebCore::Frame& frame, JSContextRef context, JSObjectRef jsCallbackFunction)
 {
     Page* page = frame.page();
     if (!page || !page->isMonitoringWheelEvents())
@@ -96,7 +96,7 @@
 
     JSValueProtect(context, jsCallbackFunction);
     
-    page->ensureWheelEventTestMonitor().setTestCallbackAndStartNotificationTimer([=](void) {
+    page->ensureWheelEventTestMonitor().setTestCallbackAndStartMonitoring(expectWheelEndOrCancel, expectMomentumEnd, [=](void) {
         JSObjectCallAsFunction(context, jsCallbackFunction, nullptr, 0, nullptr, nullptr);
         JSValueUnprotect(context, jsCallbackFunction);
     });

Modified: trunk/Source/WebCore/testing/js/WebCoreTestSupport.h (258678 => 258679)


--- trunk/Source/WebCore/testing/js/WebCoreTestSupport.h	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/Source/WebCore/testing/js/WebCoreTestSupport.h	2020-03-19 04:06:37 UTC (rev 258679)
@@ -47,7 +47,7 @@
 void injectInternalsObject(JSContextRef) TEST_SUPPORT_EXPORT;
 void resetInternalsObject(JSContextRef) TEST_SUPPORT_EXPORT;
 void monitorWheelEvents(WebCore::Frame&) TEST_SUPPORT_EXPORT;
-void setTestCallbackAndStartNotificationTimer(WebCore::Frame&, JSContextRef, JSObjectRef) TEST_SUPPORT_EXPORT;
+void setWheelEventMonitorTestCallbackAndStartMonitoring(bool expectWheelEndOrCancel, bool expectMomentumEnd, WebCore::Frame&, JSContextRef, JSObjectRef) TEST_SUPPORT_EXPORT;
 void clearWheelEventTestMonitor(WebCore::Frame&) TEST_SUPPORT_EXPORT;
 
 void setLogChannelToAccumulate(const WTF::String& name) TEST_SUPPORT_EXPORT;

Modified: trunk/Source/WebKit/ChangeLog (258678 => 258679)


--- trunk/Source/WebKit/ChangeLog	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/Source/WebKit/ChangeLog	2020-03-19 04:06:37 UTC (rev 258679)
@@ -1,3 +1,32 @@
+2020-03-18  Simon Fraser  <[email protected]>
+
+        eventSender.monitorWheelEvents() is very fragile
+        https://bugs.webkit.org/show_bug.cgi?id=197819
+        <rdar://problem/51319456>
+
+        Reviewed by Tim Horton.
+
+        Deflake tests using eventSender.monitorWheelEvents() by fixing several causes of flakiness,
+        adding back changes from r257844 that were reverted in r258558.
+        
+        First, have EventSendingController keep track of whether it's seen then "end" event
+        for the scrolling and momentum phases, and pass this down to WheelEventTestMonitor, which
+        now waits until it sees these, which prevents premature triggering which was a common cause of
+        failure before.
+        
+        Second, remove WheelEventTestMonitor's 1/60s timer and instead have WheelEventTestMonitor test
+        for completion in a callout from the end of Page::updateRendering(), which makes it test
+        and fire at a more consistent time.
+        
+        Third, push WheelEventTestMonitor to the ScrollingTree, so that reasons for deferral
+        can be added on the scrolling thread. This fixes an issue where the RunLoop::main().dispatch()
+        used to send the "ScrollingThreadSyncNeeded" reason to the main thread would get delayed,
+        also resulting in a premature trigger.
+
+        * WebProcess/InjectedBundle/API/c/WKBundlePage.cpp:
+        (WKBundlePageRegisterScrollOperationCompletionCallback):
+        * WebProcess/InjectedBundle/API/c/WKBundlePage.h:
+
 2020-03-18  Alex Christensen  <[email protected]>
 
         Add HTTP3 as an experimental feature

Modified: trunk/Source/WebKit/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp (258678 => 258679)


--- trunk/Source/WebKit/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/Source/WebKit/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp	2020-03-19 04:06:37 UTC (rev 258679)
@@ -704,7 +704,7 @@
     page->ensureWheelEventTestMonitor().clearAllTestDeferrals();
 }
 
-bool WKBundlePageRegisterScrollOperationCompletionCallback(WKBundlePageRef pageRef, WKBundlePageTestNotificationCallback callback, void* context)
+bool WKBundlePageRegisterScrollOperationCompletionCallback(WKBundlePageRef pageRef, WKBundlePageTestNotificationCallback callback, bool expectWheelEndOrCancel, bool expectMomentumEnd, void* context)
 {
     if (!callback)
         return false;
@@ -714,7 +714,7 @@
     if (!page || !page->isMonitoringWheelEvents())
         return false;
     
-    page->ensureWheelEventTestMonitor().setTestCallbackAndStartNotificationTimer([=]() {
+    page->ensureWheelEventTestMonitor().setTestCallbackAndStartMonitoring(expectWheelEndOrCancel, expectMomentumEnd, [=]() {
         callback(context);
     });
     return true;

Modified: trunk/Source/WebKit/WebProcess/InjectedBundle/API/c/WKBundlePage.h (258678 => 258679)


--- trunk/Source/WebKit/WebProcess/InjectedBundle/API/c/WKBundlePage.h	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/Source/WebKit/WebProcess/InjectedBundle/API/c/WKBundlePage.h	2020-03-19 04:06:37 UTC (rev 258679)
@@ -121,7 +121,7 @@
 
 typedef void (*WKBundlePageTestNotificationCallback)(void* context);
 // Returns true  if the callback function will be called, else false.
-WK_EXPORT bool WKBundlePageRegisterScrollOperationCompletionCallback(WKBundlePageRef, WKBundlePageTestNotificationCallback, void* context);
+WK_EXPORT bool WKBundlePageRegisterScrollOperationCompletionCallback(WKBundlePageRef, WKBundlePageTestNotificationCallback, bool expectWheelEndOrCancel, bool expectMomentumEnd, void* context);
 
 // Call the given callback after both a postTask() on the page's document's ScriptExecutionContext, and a zero-delay timer.
 WK_EXPORT void WKBundlePageCallAfterTasksAndTimers(WKBundlePageRef, WKBundlePageTestNotificationCallback, void* context);

Modified: trunk/Tools/ChangeLog (258678 => 258679)


--- trunk/Tools/ChangeLog	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/Tools/ChangeLog	2020-03-19 04:06:37 UTC (rev 258679)
@@ -1,3 +1,41 @@
+2020-03-18  Simon Fraser  <[email protected]>
+
+        eventSender.monitorWheelEvents() is very fragile
+        https://bugs.webkit.org/show_bug.cgi?id=197819
+        <rdar://problem/51319456>
+
+        Reviewed by Tim Horton.
+
+        Deflake tests using eventSender.monitorWheelEvents() by fixing several causes of flakiness,
+        adding back changes from r257844 that were reverted in r258558.
+        
+        First, have EventSendingController keep track of whether it's seen then "end" event
+        for the scrolling and momentum phases, and pass this down to WheelEventTestMonitor, which
+        now waits until it sees these, which prevents premature triggering which was a common cause of
+        failure before.
+        
+        Second, remove WheelEventTestMonitor's 1/60s timer and instead have WheelEventTestMonitor test
+        for completion in a callout from the end of Page::updateRendering(), which makes it test
+        and fire at a more consistent time.
+        
+        Third, push WheelEventTestMonitor to the ScrollingTree, so that reasons for deferral
+        can be added on the scrolling thread. This fixes an issue where the RunLoop::main().dispatch()
+        used to send the "ScrollingThreadSyncNeeded" reason to the main thread would get delayed,
+        also resulting in a premature trigger.
+
+        * DumpRenderTree/mac/EventSendingController.h:
+        * DumpRenderTree/mac/EventSendingController.mm:
+        (-[EventSendingController mouseScrollByX:andY:withWheel:andMomentumPhases:]):
+        (-[EventSendingController monitorWheelEvents]):
+        (-[EventSendingController callAfterScrollingCompletes:]):
+        * DumpRenderTree/win/EventSender.cpp:
+        (mouseScrollBy):
+        * WebKitTestRunner/InjectedBundle/EventSendingController.cpp:
+        (WTR::EventSendingController::mouseScrollByWithWheelAndMomentumPhases):
+        (WTR::EventSendingController::monitorWheelEvents):
+        (WTR::EventSendingController::callAfterScrollingCompletes):
+        * WebKitTestRunner/InjectedBundle/EventSendingController.h:
+
 2020-03-18  John Wilander  <[email protected]>
 
         WebResourceLoadStatisticsStore::requestStorageAccessUnderOpener() should call its ephemeral counterpart when appropriate

Modified: trunk/Tools/DumpRenderTree/mac/EventSendingController.h (258678 => 258679)


--- trunk/Tools/DumpRenderTree/mac/EventSendingController.h	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/Tools/DumpRenderTree/mac/EventSendingController.h	2020-03-19 04:06:37 UTC (rev 258679)
@@ -38,6 +38,10 @@
     NSTimeInterval lastClick;
     int eventNumber;
     double timeOffset;
+#if PLATFORM(MAC)
+    BOOL _sentWheelPhaseEndOrCancel;
+    BOOL _sentMomentumPhaseEnd;
+#endif
 #if PLATFORM(IOS_FAMILY)
     NSMutableArray* touches;
     unsigned currentTouchIdentifier;

Modified: trunk/Tools/DumpRenderTree/mac/EventSendingController.mm (258678 => 258679)


--- trunk/Tools/DumpRenderTree/mac/EventSendingController.mm	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/Tools/DumpRenderTree/mac/EventSendingController.mm	2020-03-19 04:06:37 UTC (rev 258679)
@@ -852,30 +852,38 @@
 - (void)mouseScrollByX:(int)x andY:(int)y withWheel:(NSString*)phaseName andMomentumPhases:(NSString*)momentumName
 {
 #if PLATFORM(MAC)
+    [[[mainFrame frameView] documentView] layout];
+
     uint32_t phase = 0;
     if ([phaseName isEqualToString: @"none"])
         phase = 0;
     else if ([phaseName isEqualToString: @"began"])
-        phase = 1; // kCGScrollPhaseBegan
+        phase = kCGScrollPhaseBegan;
     else if ([phaseName isEqualToString: @"changed"])
-        phase = 2; // kCGScrollPhaseChanged;
+        phase = kCGScrollPhaseChanged;
     else if ([phaseName isEqualToString: @"ended"])
-        phase = 4; // kCGScrollPhaseEnded
+        phase = kCGScrollPhaseEnded;
     else if ([phaseName isEqualToString: @"cancelled"])
-        phase = 8; // kCGScrollPhaseCancelled
+        phase = kCGScrollPhaseCancelled;
     else if ([phaseName isEqualToString: @"maybegin"])
-        phase = 128; // kCGScrollPhaseMayBegin
+        phase = kCGScrollPhaseMayBegin;
 
     uint32_t momentum = 0;
     if ([momentumName isEqualToString: @"none"])
-        momentum = 0; //kCGMomentumScrollPhaseNone;
+        momentum = kCGMomentumScrollPhaseNone;
     else if ([momentumName isEqualToString:@"begin"])
-        momentum = 1; // kCGMomentumScrollPhaseBegin;
+        momentum = kCGMomentumScrollPhaseBegin;
     else if ([momentumName isEqualToString:@"continue"])
-        momentum = 2; // kCGMomentumScrollPhaseContinue;
+        momentum = kCGMomentumScrollPhaseContinue;
     else if ([momentumName isEqualToString:@"end"])
-        momentum = 3; // kCGMomentumScrollPhaseEnd;
+        momentum = kCGMomentumScrollPhaseEnd;
 
+    if (phase == kCGScrollPhaseEnded || phase == kCGScrollPhaseCancelled)
+        _sentWheelPhaseEndOrCancel = YES;
+
+    if (momentum == kCGMomentumScrollPhaseEnd)
+        _sentMomentumPhaseEnd = YES;
+
     CGEventRef cgScrollEvent = CGEventCreateScrollWheelEvent(NULL, kCGScrollEventUnitLine, 2, y, x);
 
     // Set the CGEvent location in flipped coords relative to the first screen, which
@@ -1387,6 +1395,8 @@
     if (!frame)
         return;
 
+    _sentWheelPhaseEndOrCancel = NO;
+    _sentMomentumPhaseEnd = NO;
     WebCoreTestSupport::monitorWheelEvents(*frame);
 #endif
 }
@@ -1403,7 +1413,7 @@
         return;
 
     JSGlobalContextRef globalContext = [mainFrame globalContext];
-    WebCoreTestSupport::setTestCallbackAndStartNotificationTimer(*frame, globalContext, jsCallbackFunction);
+    WebCoreTestSupport::setWheelEventMonitorTestCallbackAndStartMonitoring(_sentWheelPhaseEndOrCancel, _sentMomentumPhaseEnd, *frame, globalContext, jsCallbackFunction);
 #endif
 }
 

Modified: trunk/Tools/DumpRenderTree/win/EventSender.cpp (258678 => 258679)


--- trunk/Tools/DumpRenderTree/win/EventSender.cpp	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/Tools/DumpRenderTree/win/EventSender.cpp	2020-03-19 04:06:37 UTC (rev 258679)
@@ -832,6 +832,10 @@
     RECT rect;
     ::GetWindowRect(webViewWindow, &rect);
 
+    COMPtr<IWebFramePrivate> framePrivate;
+    if (SUCCEEDED(frame->QueryInterface(&framePrivate)))
+        framePrivate->layout();
+
     if (x) {
         UINT scrollChars = 1;
         ::SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &scrollChars, 0);
@@ -923,7 +927,7 @@
         return JSValueMakeUndefined(context);
 
     WebCore::Frame* coreFrame = core(static_cast<WebFrame*>(frame2.get()));
-    WebCoreTestSupport::setTestCallbackAndStartNotificationTimer(*coreFrame, globalContext, jsCallbackFunction);
+    WebCoreTestSupport::setWheelEventMonitorTestCallbackAndStartMonitoring(false, false, *coreFrame, globalContext, jsCallbackFunction);
 
     return JSValueMakeUndefined(context);
 }

Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/EventSendingController.cpp (258678 => 258679)


--- trunk/Tools/WebKitTestRunner/InjectedBundle/EventSendingController.cpp	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/EventSendingController.cpp	2020-03-19 04:06:37 UTC (rev 258679)
@@ -492,6 +492,12 @@
 
     uint64_t phase = cgEventPhaseFromString(phaseStr);
     uint64_t momentum = cgEventMomentumPhaseFromString(momentumStr);
+    
+    if (phase == 4 /* kCGScrollPhaseEnded */ || phase == 8 /* kCGScrollPhaseCancelled */)
+        m_sentWheelPhaseEndOrCancel = true;
+    
+    if (momentum == 3 /* kCGMomentumScrollPhaseEnd */)
+        m_sentWheelMomentumPhaseEnd = true;
 
     WKRetainPtr<WKStringRef> phaseKey = adoptWK(WKStringCreateWithUTF8CString("Phase"));
     WKRetainPtr<WKUInt64Ref> phaseRef = adoptWK(WKUInt64Create(phase));
@@ -608,6 +614,8 @@
 {
     WKBundlePageRef page = InjectedBundle::singleton().page()->page();
     
+    m_sentWheelPhaseEndOrCancel = false;
+    m_sentWheelMomentumPhaseEnd = false;
     WKBundlePageStartMonitoringScrollOperations(page);
 }
 
@@ -650,7 +658,7 @@
 
     auto scrollCompletionCallbackData = makeUnique<ScrollCompletionCallbackData>(context, functionCallbackObject);
     auto scrollCompletionCallbackDataPtr = scrollCompletionCallbackData.release();
-    bool callbackWillBeCalled = WKBundlePageRegisterScrollOperationCompletionCallback(page, executeCallback, scrollCompletionCallbackDataPtr);
+    bool callbackWillBeCalled = WKBundlePageRegisterScrollOperationCompletionCallback(page, executeCallback, m_sentWheelPhaseEndOrCancel, m_sentWheelMomentumPhaseEnd, scrollCompletionCallbackDataPtr);
     if (!callbackWillBeCalled) {
         // Reassign raw pointer to std::unique_ptr<> so it will not be leaked.
         scrollCompletionCallbackData.reset(scrollCompletionCallbackDataPtr);

Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/EventSendingController.h (258678 => 258679)


--- trunk/Tools/WebKitTestRunner/InjectedBundle/EventSendingController.h	2020-03-19 03:23:18 UTC (rev 258678)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/EventSendingController.h	2020-03-19 04:06:37 UTC (rev 258679)
@@ -87,6 +87,8 @@
 private:
     EventSendingController();
     WKPoint m_position;
+    bool m_sentWheelPhaseEndOrCancel { false };
+    bool m_sentWheelMomentumPhaseEnd { false };
 };
 
 } // namespace WTR
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to