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