Skip to content

Commit

Permalink
Make didReceiveEvent() only called by event completion handlers
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=261214
rdar://115064837

Reviewed by Alex Christensen.

Events sent from the UI process expect a returning DidReceiveEvent() call to indicate that the event
has been handled or not. Change this so that these events are sent using sendWithAsyncReply and the
completion handler calls didReceiveEvent().

* Source/WebKit/UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::processNextQueuedMouseEvent):
(WebKit::WebPageProxy::handleKeyboardEvent):
(WebKit::WebPageProxy::handleGestureEvent):
(WebKit::WebPageProxy::handleTouchEvent):
(WebKit::WebPageProxy::didReceiveEvent):
* Source/WebKit/WebProcess/WebPage/EventDispatcher.cpp:
(WebKit::EventDispatcher::gestureEvent):
(WebKit::EventDispatcher::dispatchGestureEvent):
* Source/WebKit/WebProcess/WebPage/EventDispatcher.h:
* Source/WebKit/WebProcess/WebPage/EventDispatcher.messages.in:
* Source/WebKit/WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::mouseEvent):
(WebKit::WebPage::flushDeferredDidReceiveMouseEvent):
(WebKit::WebPage::keyEvent):
(WebKit::WebPage::touchEvent):
(WebKit::WebPage::gestureEvent):
* Source/WebKit/WebProcess/WebPage/WebPage.h:
* Source/WebKit/WebProcess/WebPage/WebPage.messages.in:

Canonical link: https://commits.webkit.org/267849@main
  • Loading branch information
charliewolfe committed Sep 11, 2023
1 parent ec255a8 commit 8683b68
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 38 deletions.
30 changes: 25 additions & 5 deletions Source/WebKit/UIProcess/WebPageProxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3279,7 +3279,11 @@ void WebPageProxy::processNextQueuedMouseEvent()

LOG_WITH_STREAM(MouseHandling, stream << "UIProcess: sent mouse event " << eventType << " (queue size " << internals().mouseEventQueue.size() << ")");
m_process->recordUserGestureAuthorizationToken(event.authorizationToken());
send(Messages::WebPage::MouseEvent(m_mainFrame->frameID(), event, sandboxExtensions));
sendWithAsyncReply(Messages::WebPage::MouseEvent(m_mainFrame->frameID(), event, sandboxExtensions), [this, protectedThis = Ref { *this }] (WebEventType eventType, bool handled) {
if (!m_pageClient)
return;
didReceiveEvent(eventType, handled);
});
}

void WebPageProxy::doAfterProcessingAllPendingMouseEvents(WTF::Function<void ()>&& action)
Expand Down Expand Up @@ -3545,7 +3549,11 @@ bool WebPageProxy::handleKeyboardEvent(const NativeWebKeyboardEvent& event)
if (internals().keyEventQueue.size() == 1) {
LOG(KeyHandling, " UI process: sent keyEvent from handleKeyboardEvent");
m_process->recordUserGestureAuthorizationToken(event.authorizationToken());
send(Messages::WebPage::KeyEvent(m_mainFrame->frameID(), event));
sendWithAsyncReply(Messages::WebPage::KeyEvent(m_mainFrame->frameID(), event), [this, protectedThis = Ref { *this }] (WebEventType eventType, bool handled) {
if (!m_pageClient)
return;
didReceiveEvent(eventType, handled);
});
}

return true;
Expand Down Expand Up @@ -3649,7 +3657,11 @@ void WebPageProxy::handleGestureEvent(const NativeWebGestureEvent& event)

m_process->startResponsivenessTimer((event.type() == WebEventType::GestureStart || event.type() == WebEventType::GestureChange) ? WebProcessProxy::UseLazyStop::Yes : WebProcessProxy::UseLazyStop::No);

send(Messages::EventDispatcher::GestureEvent(internals().webPageID, event), 0);
sendWithAsyncReply(Messages::EventDispatcher::GestureEvent(internals().webPageID, event), [this, protectedThis = Ref { *this }] (WebEventType eventType, bool handled) {
if (!m_pageClient)
return;
didReceiveEvent(eventType, handled);
}, 0);
}
#endif

Expand Down Expand Up @@ -3797,7 +3809,11 @@ void WebPageProxy::handleTouchEvent(const NativeWebTouchEvent& event)
if (!m_areActiveDOMObjectsAndAnimationsSuspended) {
internals().touchEventQueue.append(event);
m_process->startResponsivenessTimer();
send(Messages::WebPage::TouchEvent(event));
sendWithAsyncReply(Messages::WebPage::TouchEvent(event), [this, protectedThis = Ref { *this }] (WebEventType eventType, bool handled) {
if (!m_pageClient)
return;
didReceiveEvent(eventType, handled);
});
} else {
if (internals().touchEventQueue.isEmpty()) {
bool isEventHandled = false;
Expand Down Expand Up @@ -8579,7 +8595,11 @@ void WebPageProxy::didReceiveEvent(WebEventType eventType, bool handled)
auto nextEvent = internals().keyEventQueue.first();
LOG(KeyHandling, " UI process: sent keyEvent from didReceiveEvent");
m_process->recordUserGestureAuthorizationToken(nextEvent.authorizationToken());
send(Messages::WebPage::KeyEvent(m_mainFrame->frameID(), internals().keyEventQueue.first()));
sendWithAsyncReply(Messages::WebPage::KeyEvent(m_mainFrame->frameID(), nextEvent), [this, protectedThis = Ref { *this }] (WebEventType eventType, bool handled) {
if (!m_pageClient)
return;
didReceiveEvent(eventType, handled);
});
}

// The call to doneWithKeyEvent may close this WebPage.
Expand Down
12 changes: 6 additions & 6 deletions Source/WebKit/WebProcess/WebPage/EventDispatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,10 +191,10 @@ void EventDispatcher::wheelEvent(PageIdentifier pageID, const WebWheelEvent& whe
}

#if ENABLE(MAC_GESTURE_EVENTS)
void EventDispatcher::gestureEvent(PageIdentifier pageID, const WebKit::WebGestureEvent& gestureEvent)
void EventDispatcher::gestureEvent(PageIdentifier pageID, const WebKit::WebGestureEvent& gestureEvent, CompletionHandler<void(WebEventType, bool)>&& completionHandler)
{
RunLoop::main().dispatch([this, pageID, gestureEvent] {
dispatchGestureEvent(pageID, gestureEvent);
RunLoop::main().dispatch([this, pageID, gestureEvent, completionHandler = WTFMove(completionHandler)] () mutable {
dispatchGestureEvent(pageID, gestureEvent, WTFMove(completionHandler));
});
}
#endif
Expand Down Expand Up @@ -281,15 +281,15 @@ void EventDispatcher::dispatchWheelEvent(PageIdentifier pageID, const WebWheelEv
}

#if ENABLE(MAC_GESTURE_EVENTS)
void EventDispatcher::dispatchGestureEvent(PageIdentifier pageID, const WebGestureEvent& gestureEvent)
void EventDispatcher::dispatchGestureEvent(PageIdentifier pageID, const WebGestureEvent& gestureEvent, CompletionHandler<void(WebEventType, bool)>&& completionHandler)
{
ASSERT(RunLoop::isMain());

RefPtr webPage = WebProcess::singleton().webPage(pageID);
if (!webPage)
return;
return completionHandler(gestureEvent.type(), false);

webPage->gestureEvent(gestureEvent);
webPage->gestureEvent(gestureEvent, WTFMove(completionHandler));
}
#endif

Expand Down
4 changes: 2 additions & 2 deletions Source/WebKit/WebProcess/WebPage/EventDispatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ class EventDispatcher final :
void touchEventWithoutCallback(WebCore::PageIdentifier, const WebTouchEvent&);
#endif
#if ENABLE(MAC_GESTURE_EVENTS)
void gestureEvent(WebCore::PageIdentifier, const WebGestureEvent&);
void gestureEvent(WebCore::PageIdentifier, const WebGestureEvent&, CompletionHandler<void(WebEventType, bool)>&&);
#endif

// This is called on the main thread.
Expand All @@ -117,7 +117,7 @@ class EventDispatcher final :
void dispatchTouchEvents();
#endif
#if ENABLE(MAC_GESTURE_EVENTS)
void dispatchGestureEvent(WebCore::PageIdentifier, const WebGestureEvent&);
void dispatchGestureEvent(WebCore::PageIdentifier, const WebGestureEvent&, CompletionHandler<void(WebEventType, bool)>&&);
#endif

static void sendDidReceiveEvent(WebCore::PageIdentifier, WebEventType, bool didHandleEvent);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ messages -> EventDispatcher NotRefCounted {
TouchEventWithoutCallback(WebCore::PageIdentifier pageID, WebKit::WebTouchEvent event)
#endif
#if ENABLE(MAC_GESTURE_EVENTS)
GestureEvent(WebCore::PageIdentifier pageID, WebKit::WebGestureEvent event)
GestureEvent(WebCore::PageIdentifier pageID, WebKit::WebGestureEvent event) -> (enum:int8_t WebKit::WebEventType eventType, bool handled) MainThreadCallback
#endif
#if HAVE(CVDISPLAYLINK)
DisplayDidRefresh(uint32_t displayID, struct WebCore::DisplayUpdate update, bool sendToMainThread)
Expand Down
28 changes: 13 additions & 15 deletions Source/WebKit/WebProcess/WebPage/WebPage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3333,7 +3333,7 @@ void WebPage::contextMenuForKeyEvent()
}
#endif

void WebPage::mouseEvent(FrameIdentifier frameID, const WebMouseEvent& mouseEvent, std::optional<Vector<SandboxExtension::Handle>>&& sandboxExtensions)
void WebPage::mouseEvent(FrameIdentifier frameID, const WebMouseEvent& mouseEvent, std::optional<Vector<SandboxExtension::Handle>>&& sandboxExtensions, CompletionHandler<void(WebEventType, bool)>&& completionHandler)
{
SetForScope userIsInteractingChange { m_userIsInteracting, true };

Expand All @@ -3351,10 +3351,8 @@ void WebPage::mouseEvent(FrameIdentifier frameID, const WebMouseEvent& mouseEven
shouldHandleEvent = false;
#endif

if (!shouldHandleEvent) {
send(Messages::WebPageProxy::DidReceiveEvent(mouseEvent.type(), false));
return;
}
if (!shouldHandleEvent)
return completionHandler(mouseEvent.type(), false);

Vector<Ref<SandboxExtension>> mouseEventSandboxExtensions;
if (sandboxExtensions)
Expand Down Expand Up @@ -3401,17 +3399,17 @@ void WebPage::mouseEvent(FrameIdentifier frameID, const WebMouseEvent& mouseEven
// This logic works in tandem with the mouse event queue in the UI process, which
// coalesces mousemove events until the DidReceiveEvent() message is received after
// the rendering update.
m_deferredDidReceiveMouseEvent = { { mouseEvent.type(), handled } };
m_deferredMouseEventCompletionHandler = { { mouseEvent.type(), handled, WTFMove(completionHandler) } };
return;
}

send(Messages::WebPageProxy::DidReceiveEvent(mouseEvent.type(), handled));
completionHandler(mouseEvent.type(), handled);
}

void WebPage::flushDeferredDidReceiveMouseEvent()
{
if (auto info = std::exchange(m_deferredDidReceiveMouseEvent, std::nullopt))
send(Messages::WebPageProxy::DidReceiveEvent(info->type, info->handled));
if (auto info = std::exchange(m_deferredMouseEventCompletionHandler, std::nullopt))
info->completionHandler(info->type, info->handled);
}

void WebPage::performHitTestForMouseEvent(const WebMouseEvent& event, CompletionHandler<void(WebHitTestResultData&&, OptionSet<WebEventModifier>, UserData&&)>&& completionHandler)
Expand Down Expand Up @@ -3493,7 +3491,7 @@ void WebPage::dispatchWheelEventWithoutScrolling(FrameIdentifier frameID, const
}
#endif

void WebPage::keyEvent(FrameIdentifier frameID, const WebKeyboardEvent& keyboardEvent)
void WebPage::keyEvent(FrameIdentifier frameID, const WebKeyboardEvent& keyboardEvent, CompletionHandler<void(WebEventType, bool)>&& completionHandler)
{
SetForScope userIsInteractingChange { m_userIsInteracting, true };

Expand All @@ -3507,7 +3505,7 @@ void WebPage::keyEvent(FrameIdentifier frameID, const WebKeyboardEvent& keyboard
if (WebFrame* frame = WebProcess::singleton().webFrame(frameID))
handled = frame->handleKeyEvent(keyboardEvent);

send(Messages::WebPageProxy::DidReceiveEvent(keyboardEvent.type(), handled));
completionHandler(keyboardEvent.type(), handled);
}

bool WebPage::handleKeyEventByRelinquishingFocusToChrome(const KeyboardEvent& event)
Expand Down Expand Up @@ -3671,13 +3669,13 @@ void WebPage::updatePotentialTapSecurityOrigin(const WebTouchEvent& touchEvent,
m_potentialTapSecurityOrigin = &targetDocument->securityOrigin();
}
#elif ENABLE(TOUCH_EVENTS)
void WebPage::touchEvent(const WebTouchEvent& touchEvent)
void WebPage::touchEvent(const WebTouchEvent& touchEvent, CompletionHandler<void(WebEventType, bool)>&& completionHandler)
{
CurrentEvent currentEvent(touchEvent);

bool handled = handleTouchEvent(touchEvent, m_page.get());

send(Messages::WebPageProxy::DidReceiveEvent(touchEvent.type(), handled));
completionHandler(touchEvent.type(), handled);
}
#endif

Expand All @@ -3701,11 +3699,11 @@ static bool handleGestureEvent(const WebGestureEvent& event, Page* page)
return localMainFrame->eventHandler().handleGestureEvent(platform(event));
}

void WebPage::gestureEvent(const WebGestureEvent& gestureEvent)
void WebPage::gestureEvent(const WebGestureEvent& gestureEvent, CompletionHandler<void(WebEventType, bool)>&& completionHandler)
{
CurrentEvent currentEvent(gestureEvent);
bool handled = handleGestureEvent(gestureEvent, m_page.get());
send(Messages::WebPageProxy::DidReceiveEvent(gestureEvent.type(), handled));
completionHandler(gestureEvent.type(), handled);
}
#endif

Expand Down
13 changes: 7 additions & 6 deletions Source/WebKit/WebProcess/WebPage/WebPage.h
Original file line number Diff line number Diff line change
Expand Up @@ -1180,7 +1180,7 @@ class WebPage : public API::ObjectImpl<API::Object::Type::BundlePage>, public IP
void recomputeShortCircuitHorizontalWheelEventsState();

#if ENABLE(MAC_GESTURE_EVENTS)
void gestureEvent(const WebGestureEvent&);
void gestureEvent(const WebGestureEvent&, CompletionHandler<void(WebEventType, bool)>&&);
#endif

void updateVisibilityState(bool isInitialState = false);
Expand Down Expand Up @@ -1790,15 +1790,15 @@ class WebPage : public API::ObjectImpl<API::Object::Type::BundlePage>, public IP

void setNeedsFontAttributes(bool);

void mouseEvent(WebCore::FrameIdentifier, const WebMouseEvent&, std::optional<Vector<SandboxExtension::Handle>>&& sandboxExtensions);
void keyEvent(WebCore::FrameIdentifier, const WebKeyboardEvent&);
void mouseEvent(WebCore::FrameIdentifier, const WebMouseEvent&, std::optional<Vector<SandboxExtension::Handle>>&& sandboxExtensions, CompletionHandler<void(WebEventType, bool)>&&);
void keyEvent(WebCore::FrameIdentifier, const WebKeyboardEvent&, CompletionHandler<void(WebEventType, bool)>&&);

#if ENABLE(IOS_TOUCH_EVENTS)
void touchEventSync(const WebTouchEvent&, CompletionHandler<void(bool)>&&);
void resetPotentialTapSecurityOrigin();
void updatePotentialTapSecurityOrigin(const WebTouchEvent&, bool wasHandled);
#elif ENABLE(TOUCH_EVENTS)
void touchEvent(const WebTouchEvent&);
void touchEvent(const WebTouchEvent&, CompletionHandler<void(WebEventType, bool)>&&);
#endif

void cancelPointer(WebCore::PointerID, const WebCore::IntPoint&);
Expand Down Expand Up @@ -2360,11 +2360,12 @@ class WebPage : public API::ObjectImpl<API::Object::Type::BundlePage>, public IP

unsigned m_cachedPageCount { 0 };

struct DeferredDidReceiveMouseEvent {
struct DeferredMouseEventCompletionHandler {
WebEventType type { WebEventType::NoType };
bool handled { false };
CompletionHandler<void(WebEventType, bool)> completionHandler;
};
std::optional<DeferredDidReceiveMouseEvent> m_deferredDidReceiveMouseEvent;
std::optional<DeferredMouseEventCompletionHandler> m_deferredMouseEventCompletionHandler;

HashSet<WebCore::ResourceLoaderIdentifier> m_trackedNetworkResourceRequestIdentifiers;

Expand Down
6 changes: 3 additions & 3 deletions Source/WebKit/WebProcess/WebPage/WebPage.messages.in
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ messages -> WebPage LegacyReceiver {
ViewWillEndLiveResize()

ExecuteEditCommandWithCallback(String name, String argument) -> ()
KeyEvent(WebCore::FrameIdentifier frameID, WebKit::WebKeyboardEvent event)
MouseEvent(WebCore::FrameIdentifier frameID, WebKit::WebMouseEvent event, std::optional<Vector<WebKit::SandboxExtension::Handle>> sandboxExtensions)
KeyEvent(WebCore::FrameIdentifier frameID, WebKit::WebKeyboardEvent event) -> (enum:int8_t WebKit::WebEventType eventType, bool handled)
MouseEvent(WebCore::FrameIdentifier frameID, WebKit::WebMouseEvent event, std::optional<Vector<WebKit::SandboxExtension::Handle>> sandboxExtensions) -> (enum:int8_t WebKit::WebEventType eventType, bool handled)

#if ENABLE(NOTIFICATIONS)
ClearNotificationPermissionState()
Expand Down Expand Up @@ -158,7 +158,7 @@ GenerateSyntheticEditingCommand(enum:uint8_t WebKit::SyntheticEditingCommandType
ResetPotentialTapSecurityOrigin()
#endif
#if !ENABLE(IOS_TOUCH_EVENTS) && ENABLE(TOUCH_EVENTS)
TouchEvent(WebKit::WebTouchEvent event)
TouchEvent(WebKit::WebTouchEvent event) -> (enum:int8_t WebKit::WebEventType eventType, bool handled)
#endif

CancelPointer(WebCore::PointerID pointerId, WebCore::IntPoint documentPoint)
Expand Down

0 comments on commit 8683b68

Please sign in to comment.