[webkit-changes] [WebKit/WebKit] a10c48: Throttle `mousemove` events to one per rendering u...

Wenson Hsieh noreply at github.com
Wed Jul 26 17:03:17 PDT 2023


  Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: a10c4813fe62020d18ca2073c2e687a9f86279af
      https://github.com/WebKit/WebKit/commit/a10c4813fe62020d18ca2073c2e687a9f86279af
  Author: Wenson Hsieh <wenson_hsieh at apple.com>
  Date:   2023-07-26 (Wed, 26 Jul 2023)

  Changed paths:
    M LayoutTests/fast/selectors/style-invalidation-hover-change-descendants-expected.txt
    M LayoutTests/fast/selectors/style-invalidation-hover-change-descendants.html
    M LayoutTests/fast/selectors/style-invalidation-hover-change-siblings-expected.txt
    M LayoutTests/fast/selectors/style-invalidation-hover-change-siblings.html
    M Source/WebKit/Shared/WebEvent.h
    A Source/WebKit/Shared/WebEventType.h
    M Source/WebKit/UIProcess/WebPageProxy.cpp
    M Source/WebKit/WebKit.xcodeproj/project.pbxproj
    M Source/WebKit/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp
    M Source/WebKit/WebProcess/InjectedBundle/API/c/WKBundlePage.h
    M Source/WebKit/WebProcess/WebPage/WebPage.cpp
    M Source/WebKit/WebProcess/WebPage/WebPage.h
    M Source/WebKit/WebProcess/WebPage/WebPage.messages.in
    M Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
    A Tools/TestWebKitAPI/Tests/mac/MouseEventTests.mm
    M Tools/WebKitTestRunner/InjectedBundle/EventSendingController.cpp
    M Tools/WebKitTestRunner/TestController.cpp

  Log Message:
  -----------
  Throttle `mousemove` events to one per rendering update
https://bugs.webkit.org/show_bug.cgi?id=259408
rdar://110921187

Reviewed by Tim Horton and Simon Fraser.

Throttle the mousemove event dispatch rate to a maximum of 1 per rendering update, if the user isn't
clicking or dragging. See below for more details.

Test:   MouseEventTests.CoalesceMouseMoveEvents
        MouseEventTests.ProcessSwapWithDeferredMouseMoveEventCompletion

* LayoutTests/fast/selectors/style-invalidation-hover-change-descendants-expected.txt:
* LayoutTests/fast/selectors/style-invalidation-hover-change-descendants.html:
* LayoutTests/fast/selectors/style-invalidation-hover-change-siblings-expected.txt:
* LayoutTests/fast/selectors/style-invalidation-hover-change-siblings.html:

Adjust a couple of layout tests that need to run checks for style invalidation state immediately
after handling the mousemove event, without waiting for any further IPC messages to be dispatched.
Ensure this by moving the test logic into one-shot `mousemove` event listeners; we also take the
opportunity to modernize the test a bit by using `js-test.js` and `testPassed` / `testFailed`.

* Source/WebKit/Shared/WebEvent.h:
* Source/WebKit/Shared/WebEventType.h: Copied from Source/WebKit/Shared/WebEvent.h.
* Source/WebKit/UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::handleMouseEvent):

See comments under `WebPage::mouseEvent`.

* Source/WebKit/WebKit.xcodeproj/project.pbxproj:
* Source/WebKit/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp:
(WKBundlePageFlushDeferredDidReceiveMouseEventForTesting):

Add a testing-only SPI hook to flush the `DidReceiveEvent` message corresponding to any `mousemove`
events that have already been handled in the web process. WebKitTestRunner uses this to ensure that
`window.eventSender` API to simulate mouse events behaves the same way as it currently does.

* Source/WebKit/WebProcess/InjectedBundle/API/c/WKBundlePage.h:
* Source/WebKit/WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::close):
(WebKit::WebPage::suspendForProcessSwap):

Flush any deferred `mousemove` IPC responses here when suspending right before a process swap, so
that we won't end up trying to send a `DidReceiveEvent` message back to the UI process when the
`WebPageProxy`'s `mouseEventQueue` has already been emptied, due to process swapping.

(WebKit::WebPage::mouseEvent):

When handling a `mousemove` event, rather than invoke the IPC completion handler immediately, we
instead defer the call to `WebPageProxy::DidReceiveEvent` until the end of the current rendering
update. This means that existing UI-side logic for coalescing `mousemove` events when the web
process is still handling mouse events will coalesce mousemove events until the end of the rendering
update, after which the web process will be done with current mousemove.

If a non-`mousemove` event enters the mouse event queue), we'll also tell the web process to
dispatch the deferred mousemove completion handler early so that we can process the incoming click
right away.

(WebKit::WebPage::flushDeferredDidReceiveMouseEvent):
(WebKit::WebPage::finalizeRenderingUpdate):

Clear out `m_deferredDidReceiveMouseEvent` if it was set, and dispatch the `DidReceiveEvent` message
back to the UI process for this deferred event.

(WebKit::WebPage::didCommitLoad):

Similarly, flush any deferred `DidReceiveEvent` response when committing a load.

* Source/WebKit/WebProcess/WebPage/WebPage.h:
* Source/WebKit/WebProcess/WebPage/WebPage.messages.in:
* Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* Tools/TestWebKitAPI/Tests/mac/MouseEventTests.mm: Added.

Add an API test to exercise `mousemove` event coalescing (both this new completion deferral, as well
as the preexisting mechanism for coalescing events in the UI process). This test simulates moving a
mouse cursor over (300, 300) in the window, clicking, and then verifies that:

1.  There are at least 4 mouse events observed: a `mousemove` for the starting location, another
    `mousemove` for the final destination, and `mousedown` and `mouseup` events for the click.

2.  There are no more than 200 events in total (in other words, some `mousemove` events were
    coalesced).

Also, add an API test to verify that we don't hit a `MESSAGE_CHECK` due to sending a deferred
`mousemove` event completion message during a process swap.

* Tools/WebKitTestRunner/InjectedBundle/EventSendingController.cpp:
(WTR::EventSendingController::mouseMoveTo):

Use the above testing hook. We also wait for one extra web <-> UI process round trip here in order
to ensure that the UI process has received the message from the web process indicating that we've
handled the `mousemove` event.

* Tools/WebKitTestRunner/TestController.cpp:
(WTR::TestController::didReceiveSynchronousMessageFromInjectedBundle):

Canonical link: https://commits.webkit.org/266341@main




More information about the webkit-changes mailing list