Skip to content

Commit

Permalink
Reland 267124@main: Refactor mouse and keyboard handling in the web p…
Browse files Browse the repository at this point in the history
…rocess to be frame specific

https://bugs.webkit.org/show_bug.cgi?id=260821
rdar://114586213

Reviewed by Alex Christensen.

Reland 267124@main after fixing mouse events on Windows and rebasing after 267293@main.

This change was initially incorrectly calling WebFrame::handleContextMenuEvent() instead
of EventHandler::sendContextMenuEvent().

Also added a mainFrame null check on WebPageProxy::handleMouseEvent() since the same null
check was added to WebPageProxy::processNextQueuedMouseEvent().

* Source/WebKit/UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::handleMouseEvent):
(WebKit::WebPageProxy::processNextQueuedMouseEvent):
(WebKit::WebPageProxy::dispatchWheelEventWithoutScrolling):
(WebKit::WebPageProxy::sendWheelEvent):
(WebKit::WebPageProxy::handleKeyboardEvent):
(WebKit::WebPageProxy::didReceiveEvent):
* Source/WebKit/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp:
(WKBundlePageCopyContextMenuAtPointInWindow):
* Source/WebKit/WebProcess/WebPage/EventDispatcher.cpp:
(WebKit::EventDispatcher::dispatchWheelEvent):
* Source/WebKit/WebProcess/WebPage/WebFrame.cpp:
(WebKit::isContextClick):
(WebKit::WebFrame::handleContextMenuEvent):
(WebKit::WebFrame::handleMouseEvent):
(WebKit::WebFrame::handleKeyEvent):
* Source/WebKit/WebProcess/WebPage/WebFrame.h:
* Source/WebKit/WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::contextMenuAtPointInWindow):
(WebKit::WebPage::mouseEvent):
(WebKit::WebPage::handleWheelEvent):
(WebKit::WebPage::wheelEvent):
(WebKit::WebPage::dispatchWheelEventWithoutScrolling):
(WebKit::WebPage::keyEvent):
(WebKit::WebPage::simulateMouseDown):
(WebKit::WebPage::simulateMouseUp):
(WebKit::WebPage::simulateMouseMotion):
(WebKit::isContextClick): Deleted.
(WebKit::handleContextMenuEvent): Deleted.
(WebKit::handleMouseEvent): Deleted.
(WebKit::handleKeyEvent): Deleted.
* Source/WebKit/WebProcess/WebPage/WebPage.h:
* Source/WebKit/WebProcess/WebPage/WebPage.messages.in:

Canonical link: https://commits.webkit.org/267410@main
  • Loading branch information
charliewolfe committed Aug 29, 2023
1 parent 9f045b6 commit f577450
Show file tree
Hide file tree
Showing 8 changed files with 182 additions and 134 deletions.
30 changes: 24 additions & 6 deletions Source/WebKit/UIProcess/WebPageProxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3210,6 +3210,9 @@ void WebPageProxy::handleMouseEvent(const NativeWebMouseEvent& event)
if (!hasRunningProcess())
return;

if (!m_mainFrame)
return;

#if ENABLE(CONTEXT_MENU_EVENT)
if (event.button() == WebMouseEventButton::RightButton && event.type() == WebEventType::MouseDown) {
ASSERT(m_contextMenuPreventionState != EventPreventionState::Waiting);
Expand Down Expand Up @@ -3246,6 +3249,9 @@ void WebPageProxy::processNextQueuedMouseEvent()
if (!hasRunningProcess())
return;

if (!m_mainFrame)
return;

ASSERT(!internals().mouseEventQueue.isEmpty());

const NativeWebMouseEvent& event = internals().mouseEventQueue.first();
Expand All @@ -3271,7 +3277,7 @@ 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(event, sandboxExtensions));
send(Messages::WebPage::MouseEvent(m_mainFrame->frameID(), event, sandboxExtensions));
}

void WebPageProxy::doAfterProcessingAllPendingMouseEvents(WTF::Function<void ()>&& action)
Expand Down Expand Up @@ -3300,7 +3306,11 @@ void WebPageProxy::flushPendingMouseEventCallbacks()
#if PLATFORM(IOS_FAMILY)
void WebPageProxy::dispatchWheelEventWithoutScrolling(const WebWheelEvent& event, CompletionHandler<void(bool)>&& completionHandler)
{
sendWithAsyncReply(Messages::WebPage::DispatchWheelEventWithoutScrolling(event), WTFMove(completionHandler));
if (!m_mainFrame) {
completionHandler(false);
return;
}
sendWithAsyncReply(Messages::WebPage::DispatchWheelEventWithoutScrolling(m_mainFrame->frameID(), event), WTFMove(completionHandler));
}
#endif

Expand Down Expand Up @@ -3362,11 +3372,14 @@ void WebPageProxy::sendWheelEvent(const WebWheelEvent& event, OptionSet<WheelEve
if (!connection)
return;

if (!m_mainFrame)
return;

if (drawingArea()->shouldSendWheelEventsToEventDispatcher()) {
sendWheelEventScrollingAccelerationCurveIfNecessary(event);
connection->send(Messages::EventDispatcher::WheelEvent(webPageID(), event, rubberBandableEdges), 0, { }, Thread::QOS::UserInteractive);
} else {
sendWithAsyncReply(Messages::WebPage::HandleWheelEvent(event, processingSteps, willStartSwipe), [weakThis = WeakPtr { *this }, wheelEvent = event, wasHandledForScrolling](ScrollingNodeID nodeID, std::optional<WheelScrollGestureState> gestureState, bool handled) {
sendWithAsyncReply(Messages::WebPage::HandleWheelEvent(m_mainFrame->frameID(), event, processingSteps, willStartSwipe), [weakThis = WeakPtr { *this }, wheelEvent = event, wasHandledForScrolling](ScrollingNodeID nodeID, std::optional<WheelScrollGestureState> gestureState, bool handled) {
RefPtr protectedThis = weakThis.get();
if (!protectedThis)
return;
Expand Down Expand Up @@ -3515,6 +3528,11 @@ bool WebPageProxy::handleKeyboardEvent(const NativeWebKeyboardEvent& event)
if (!hasRunningProcess())
return false;

if (!m_mainFrame) {
m_uiClient->didNotHandleKeyEvent(this, event);
return false;
}

LOG_WITH_STREAM(KeyHandling, stream << "WebPageProxy::handleKeyboardEvent: " << event.type());

internals().keyEventQueue.append(event);
Expand All @@ -3525,7 +3543,7 @@ 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(event));
send(Messages::WebPage::KeyEvent(m_mainFrame->frameID(), event));
}

return true;
Expand Down Expand Up @@ -8561,11 +8579,11 @@ void WebPageProxy::didReceiveEvent(WebEventType eventType, bool handled)
#endif

bool canProcessMoreKeyEvents = !internals().keyEventQueue.isEmpty();
if (canProcessMoreKeyEvents) {
if (canProcessMoreKeyEvents && m_mainFrame) {
auto nextEvent = internals().keyEventQueue.first();
LOG(KeyHandling, " UI process: sent keyEvent from didReceiveEvent");
m_process->recordUserGestureAuthorizationToken(nextEvent.authorizationToken());
send(Messages::WebPage::KeyEvent(internals().keyEventQueue.first()));
send(Messages::WebPage::KeyEvent(m_mainFrame->frameID(), internals().keyEventQueue.first()));
}

// The call to doneWithKeyEvent may close this WebPage.
Expand Down
10 changes: 9 additions & 1 deletion Source/WebKit/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,15 @@ WKArrayRef WKBundlePageCopyContextMenuItems(WKBundlePageRef pageRef)
WKArrayRef WKBundlePageCopyContextMenuAtPointInWindow(WKBundlePageRef pageRef, WKPoint point)
{
#if ENABLE(CONTEXT_MENUS)
WebKit::WebContextMenu* contextMenu = WebKit::toImpl(pageRef)->contextMenuAtPointInWindow(WebKit::toIntPoint(point));
WebCore::Page* page = WebKit::toImpl(pageRef)->corePage();
if (!page)
return nullptr;

auto* localMainFrame = dynamicDowncast<WebCore::LocalFrame>(page->mainFrame());
if (!localMainFrame)
return nullptr;

WebKit::WebContextMenu* contextMenu = WebKit::toImpl(pageRef)->contextMenuAtPointInWindow(localMainFrame->frameID(), WebKit::toIntPoint(point));
if (!contextMenu)
return nullptr;

Expand Down
4 changes: 3 additions & 1 deletion Source/WebKit/WebProcess/WebPage/EventDispatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,9 @@ void EventDispatcher::dispatchWheelEvent(PageIdentifier pageID, const WebWheelEv
if (!webPage)
return;

bool handled = webPage->wheelEvent(wheelEvent, processingSteps, wheelEventOrigin);
bool handled = false;
if (webPage->mainFrame())
handled = webPage->wheelEvent(webPage->mainFrame()->frameID(), wheelEvent, processingSteps, wheelEventOrigin);

if (processingSteps.contains(WheelEventProcessingSteps::SynchronousScrolling) && wheelEventOrigin == EventDispatcher::WheelEventOrigin::UIProcess)
sendDidReceiveEvent(pageID, wheelEvent.type(), handled);
Expand Down
105 changes: 105 additions & 0 deletions Source/WebKit/WebProcess/WebPage/WebFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,11 @@
#include "WKAPICast.h"
#include "WKBundleAPICast.h"
#include "WebChromeClient.h"
#include "WebContextMenu.h"
#include "WebCoreArgumentCoders.h"
#include "WebDocumentLoader.h"
#include "WebEventConversion.h"
#include "WebEventFactory.h"
#include "WebImage.h"
#include "WebPage.h"
#include "WebPageProxyMessages.h"
Expand All @@ -59,11 +62,13 @@
#include <WebCore/ArchiveResource.h>
#include <WebCore/CertificateInfo.h>
#include <WebCore/Chrome.h>
#include <WebCore/ContextMenuController.h>
#include <WebCore/DocumentLoader.h>
#include <WebCore/Editor.h>
#include <WebCore/ElementChildIteratorInlines.h>
#include <WebCore/EventHandler.h>
#include <WebCore/File.h>
#include <WebCore/FocusController.h>
#include <WebCore/FrameSnapshotting.h>
#include <WebCore/HTMLFormElement.h>
#include <WebCore/HTMLFrameOwnerElement.h>
Expand Down Expand Up @@ -1198,4 +1203,104 @@ OptionSet<WebCore::AdvancedPrivacyProtections> WebFrame::originatorAdvancedPriva
return loader->originatorAdvancedPrivacyProtections();
}

#if ENABLE(CONTEXT_MENU_EVENT)
static bool isContextClick(const PlatformMouseEvent& event)
{
#if USE(APPKIT)
return WebEventFactory::shouldBeHandledAsContextClick(event);
#else
return event.button() == WebCore::RightButton;
#endif
}

bool WebFrame::handleContextMenuEvent(const PlatformMouseEvent& platformMouseEvent)
{
auto* coreLocalFrame = dynamicDowncast<LocalFrame>(coreFrame());
if (!coreLocalFrame)
return false;
IntPoint point = coreLocalFrame->view()->windowToContents(platformMouseEvent.position());
constexpr OptionSet<HitTestRequest::Type> hitType { HitTestRequest::Type::ReadOnly, HitTestRequest::Type::Active, HitTestRequest::Type::DisallowUserAgentShadowContent, HitTestRequest::Type::AllowChildFrameContent };
HitTestResult result = coreLocalFrame->eventHandler().hitTestResultAtPoint(point, hitType);

Ref frame = *coreLocalFrame;
if (result.innerNonSharedNode())
frame = *result.innerNonSharedNode()->document().frame();

bool handled = frame->eventHandler().sendContextMenuEvent(platformMouseEvent);
#if ENABLE(CONTEXT_MENUS)
if (handled)
page()->contextMenu().show();
#endif
return handled;
}
#endif

bool WebFrame::handleMouseEvent(const WebMouseEvent& mouseEvent)
{
auto* coreLocalFrame = dynamicDowncast<LocalFrame>(coreFrame());
if (!coreLocalFrame)
return false;

if (!coreLocalFrame->view())
return false;

PlatformMouseEvent platformMouseEvent = platform(mouseEvent);

switch (platformMouseEvent.type()) {
case PlatformEvent::Type::MousePressed: {
#if ENABLE(CONTEXT_MENUS)
if (isContextClick(platformMouseEvent))
page()->corePage()->contextMenuController().clearContextMenu();
#endif

bool handled = coreLocalFrame->eventHandler().handleMousePressEvent(platformMouseEvent);
#if ENABLE(CONTEXT_MENU_EVENT)
if (isContextClick(platformMouseEvent))
handled = handleContextMenuEvent(platformMouseEvent);
#endif
return handled;
}
case PlatformEvent::Type::MouseReleased:
if (mouseEvent.gestureWasCancelled() == GestureWasCancelled::Yes)
coreLocalFrame->eventHandler().invalidateClick();
return coreLocalFrame->eventHandler().handleMouseReleaseEvent(platformMouseEvent);

case PlatformEvent::Type::MouseMoved:
#if PLATFORM(COCOA)
// We need to do a full, normal hit test during this mouse event if the page is active or if a mouse
// button is currently pressed. It is possible that neither of those things will be true since on
// Lion when legacy scrollbars are enabled, WebKit receives mouse events all the time. If it is one
// of those cases where the page is not active and the mouse is not pressed, then we can fire a more
// efficient scrollbars-only version of the event.
if (!(page()->corePage()->focusController().isActive() || (mouseEvent.button() != WebMouseEventButton::NoButton)))
return coreLocalFrame->eventHandler().passMouseMovedEventToScrollbars(platformMouseEvent);
#endif
return coreLocalFrame->eventHandler().mouseMoved(platformMouseEvent);

case PlatformEvent::Type::MouseForceChanged:
case PlatformEvent::Type::MouseForceDown:
case PlatformEvent::Type::MouseForceUp:
return coreLocalFrame->eventHandler().handleMouseForceEvent(platformMouseEvent);

default:
ASSERT_NOT_REACHED();
return false;
}
}

bool WebFrame::handleKeyEvent(const WebKeyboardEvent& keyboardEvent)
{
if (!m_coreFrame)
return false;

auto* page = m_coreFrame->page();
if (!page)
return false;

Ref frame = page->focusController().focusedOrMainFrame();
if (keyboardEvent.type() == WebEventType::Char && keyboardEvent.isSystemKey())
return frame->eventHandler().handleAccessKey(platform(keyboardEvent));
return frame->eventHandler().keyEvent(platform(keyboardEvent));
}

} // namespace WebKit
7 changes: 7 additions & 0 deletions Source/WebKit/WebProcess/WebPage/WebFrame.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class HTMLFrameOwnerElement;
class IntPoint;
class IntRect;
class LocalFrame;
class PlatformMouseEvent;
class RemoteFrame;
struct GlobalWindowIdentifier;
}
Expand All @@ -69,7 +70,9 @@ class InjectedBundleHitTestResult;
class InjectedBundleNodeHandle;
class InjectedBundleRangeHandle;
class InjectedBundleScriptWorld;
class WebKeyboardEvent;
class WebImage;
class WebMouseEvent;
class WebPage;
struct FrameInfoData;
struct FrameTreeNodeData;
Expand Down Expand Up @@ -224,6 +227,10 @@ class WebFrame : public API::ObjectImpl<API::Object::Type::BundleFrame>, public

OptionSet<WebCore::AdvancedPrivacyProtections> advancedPrivacyProtections() const;
OptionSet<WebCore::AdvancedPrivacyProtections> originatorAdvancedPrivacyProtections() const;

bool handleContextMenuEvent(const WebCore::PlatformMouseEvent&);
bool handleMouseEvent(const WebMouseEvent&);
bool handleKeyEvent(const WebKeyboardEvent&);
private:
WebFrame(WebPage&, WebCore::FrameIdentifier);

Expand Down
Loading

0 comments on commit f577450

Please sign in to comment.