Diff
Modified: trunk/Source/WebKit/ChangeLog (264112 => 264113)
--- trunk/Source/WebKit/ChangeLog 2020-07-08 17:08:22 UTC (rev 264112)
+++ trunk/Source/WebKit/ChangeLog 2020-07-08 17:43:56 UTC (rev 264113)
@@ -1,3 +1,114 @@
+2020-07-08 Andy Estes <[email protected]>
+
+ REGRESSION (r207558): [Mac] Context clicks on links sometimes result in navigations
+ https://bugs.webkit.org/show_bug.cgi?id=213793
+ <rdar://problem/64294015>
+
+ Reviewed by Tim Horton.
+
+ WebPageProxy::showContextMenu was written with the assumption that WebContextMenuProxy::show
+ would present a context menu and spin a nested run loop, blocking until the menu dismisses.
+ Once WebContextMenuProxy::show returns, showContextMenu would send the
+ WebPage::ContextMenuHidden message, telling the WebContent process that it's OK to resume
+ processing mouse events.
+
+ This assumption was invalidated in r207558 (and again in several subsequent changes), which
+ added asynchronous APIs to WKPageContextMenuClient. If the context menu client provides
+ context menu items asynchronously, WebContextMenuProxy::show would return -- and the
+ WebContent process would resume processing mouse events -- before the context menu was even
+ presented. Since context menu presentation is triggered by a mouse press event, it's
+ possible that the corresponding mouse release event would be delivered after
+ getContextMenuFromProposedMenuAsync was dispatched but before the client responded with menu
+ items to present. If this happened, since mouse event processing was not disabled, the
+ WebContent process would dispatch a DOM click event to the page, possibly triggering a
+ navigation.
+
+ Fix this by teaching WebPageProxy to defer sending WebPage::ContextMenuHidden until the
+ context menu has been dismissed, even in cases where the context menu client provides menu
+ items asynchronously. Also, take the opportunity to modernize WebContextMenuProxy and its
+ subclasses by, e.g., moving duplicated subclass code into the base class, using the client
+ pattern, and using WeakPtrs instead of raw pointers/references.
+
+ New API tests: ContextMenuMouseEvents.*
+
+ * UIProcess/API/APIContextMenuClient.h:
+ (API::ContextMenuClient::showContextMenu):
+ (API::ContextMenuClient::canShowContextMenu const):
+ * UIProcess/API/C/WKPage.cpp:
+ (WKPageSetPageContextMenuClient): Added canShowContextMenu to determine whether the client
+ can show a context menu without actually showing it.
+
+ * UIProcess/API/wpe/PageClientImpl.cpp:
+ (WebKit::PageClientImpl::createContextMenuProxy): Passed page to
+ WebContextMenuProxyWPE::create.
+
+ * UIProcess/WebContextMenuListenerProxy.cpp:
+ (WebKit::WebContextMenuListenerProxy::WebContextMenuListenerProxy):
+ (WebKit::WebContextMenuListenerProxy::useContextMenuItems):
+ (WebKit::WebContextMenuListenerProxy::invalidate): Deleted. Not needed now that m_client is
+ a WeakPtr.
+
+ * UIProcess/WebContextMenuListenerProxy.h:
+ (WebKit::WebContextMenuListenerProxy::create): Rather than store a raw pointer to a
+ WebContextMenuProxy, store a WeakPtr to a WebContextMenuListenerProxy::Client (which
+ WebContextMenuProxy implements).
+
+ * UIProcess/WebContextMenuProxy.cpp:
+ (WebKit::WebContextMenuProxy::WebContextMenuProxy): Stored a WeakPtr to a WebPageProxy
+ rather than storing a raw pointer to the same in each subclass.
+ (WebKit::WebContextMenuProxy::proposedItems const): Added a virtual function to create
+ proposed WebContextMenuItems from m_context's menu items. WebContextMenuProxyGtk overrides
+ this to do something slightly different.
+ (WebKit::WebContextMenuProxy::show): Added a base class implementation that creates a
+ WebContextMenuListenerProxy and calls ContextMenuClient::getContextMenuFromProposedMenu.
+ (WebKit::WebContextMenuProxy::useContextMenuItems): Added a base class implementation that
+ performs the work previously done in WebPageProxy::showContextMenu. Calls
+ showContextMenuWithItems, which now always synchronously presents the menu.
+
+ * UIProcess/WebContextMenuProxy.h: Inherited from WebContextMenuListenerProxy::Client.
+ (WebKit::WebContextMenuProxy::page const): Added for use by WKSharingServicePickerDelegate.
+
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::WebPageProxy::showContextMenu): Moved code that assumes synchronous menu
+ presentation to WebContextMenuProxy::useContextMenuItems.
+
+ * UIProcess/gtk/WebContextMenuProxyGtk.cpp:
+ (WebKit::WebContextMenuProxyGtk::proposedItems const): Implemented GTK's special version
+ that excludes ContextMenuItemTagShareMenu.
+ (WebKit::WebContextMenuProxyGtk::show): Deleted. WebContextMenuProxy::show handles this now.
+ (WebKit::WebContextMenuProxyGtk::append):
+ (WebKit::WebContextMenuProxyGtk::showContextMenuWithItems):
+ (WebKit::WebContextMenuProxyGtk::WebContextMenuProxyGtk):
+ * UIProcess/gtk/WebContextMenuProxyGtk.h: Moved m_page to WebContextMenuProxy.
+
+ * UIProcess/mac/WKSharingServicePickerDelegate.mm:
+ (-[WKSharingServicePickerDelegate sharingService:didShareItems:]): Changed now that
+ WebContextMenuProxy::page returns a pointer.
+
+ * UIProcess/mac/WebContextMenuProxyMac.h:
+ (WebKit::WebContextMenuProxyMac::page const): Deleted.
+
+ * UIProcess/mac/WebContextMenuProxyMac.mm:
+ (WebKit::WebContextMenuProxyMac::WebContextMenuProxyMac):
+ (WebKit::WebContextMenuProxyMac::~WebContextMenuProxyMac): No need to invalidate
+ m_contextMenuListener now that it stores a WeakPtr to its WebContextMenuProxy.
+ (WebKit::WebContextMenuProxyMac::contextMenuItemSelected):
+ (WebKit::WebContextMenuProxyMac::showServicesMenu):
+ (WebKit::WebContextMenuProxyMac::show):
+ (WebKit::WebContextMenuProxyMac::showContextMenuWithItems): Overrode to handle service menus.
+ (WebKit::WebContextMenuProxyMac::useContextMenuItems): Overrode to get the standard Mac menu
+ items and dispatch ContextMenuClient::menuFromProposedMenu before showing the menu.
+ (WebKit::WebContextMenuProxyMac::showContextMenu): Deleted. WebContextMenuProxy::show now
+ handles this.
+
+ * UIProcess/win/WebContextMenuProxyWin.cpp:
+ (WebKit::WebContextMenuProxyWin::showContextMenuWithItems):
+ (WebKit::WebContextMenuProxyWin::WebContextMenuProxyWin):
+ (WebKit::WebContextMenuProxyWin::show): Deleted. WebContextMenuProxy::show now handles this.
+ * UIProcess/win/WebContextMenuProxyWin.h:
+
+ * UIProcess/wpe/WebContextMenuProxyWPE.h: Passed page to the WebContextMenuProxy ctor.
+
2020-07-08 Wenson Hsieh <[email protected]>
autocapitalize="words" capitalizes every word's second character
Modified: trunk/Source/WebKit/UIProcess/API/APIContextMenuClient.h (264112 => 264113)
--- trunk/Source/WebKit/UIProcess/API/APIContextMenuClient.h 2020-07-08 17:08:22 UTC (rev 264112)
+++ trunk/Source/WebKit/UIProcess/API/APIContextMenuClient.h 2020-07-08 17:43:56 UTC (rev 264113)
@@ -55,7 +55,8 @@
virtual void getContextMenuFromProposedMenu(WebKit::WebPageProxy&, Vector<Ref<WebKit::WebContextMenuItem>>&& proposedMenu, WebKit::WebContextMenuListenerProxy& listener, const WebKit::WebHitTestResultData&, API::Object* /* userData */) { listener.useContextMenuItems(WTFMove(proposedMenu)); }
virtual void customContextMenuItemSelected(WebKit::WebPageProxy&, const WebKit::WebContextMenuItemData&) { }
- virtual bool showContextMenu(WebKit::WebPageProxy&, const WebCore::IntPoint&, const Vector<Ref<WebKit::WebContextMenuItem>>&) { return false; }
+ virtual void showContextMenu(WebKit::WebPageProxy&, const WebCore::IntPoint&, const Vector<Ref<WebKit::WebContextMenuItem>>&) { }
+ virtual bool canShowContextMenu() const { return false; }
virtual bool hideContextMenu(WebKit::WebPageProxy&) { return false; }
#if PLATFORM(MAC)
Modified: trunk/Source/WebKit/UIProcess/API/C/WKPage.cpp (264112 => 264113)
--- trunk/Source/WebKit/UIProcess/API/C/WKPage.cpp 2020-07-08 17:08:22 UTC (rev 264112)
+++ trunk/Source/WebKit/UIProcess/API/C/WKPage.cpp 2020-07-08 17:43:56 UTC (rev 264113)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010, 2015-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2020 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -926,10 +926,10 @@
m_client.customContextMenuItemSelected(toAPI(&page), toAPI(WebContextMenuItem::create(itemData).ptr()), m_client.base.clientInfo);
}
- bool showContextMenu(WebPageProxy& page, const WebCore::IntPoint& menuLocation, const Vector<Ref<WebContextMenuItem>>& menuItemsVector) override
+ void showContextMenu(WebPageProxy& page, const WebCore::IntPoint& menuLocation, const Vector<Ref<WebContextMenuItem>>& menuItemsVector) override
{
- if (!m_client.showContextMenu)
- return false;
+ if (!canShowContextMenu())
+ return;
Vector<RefPtr<API::Object>> menuItems;
menuItems.reserveInitialCapacity(menuItemsVector.size());
@@ -938,8 +938,11 @@
menuItems.uncheckedAppend(menuItem.ptr());
m_client.showContextMenu(toAPI(&page), toAPI(menuLocation), toAPI(API::Array::create(WTFMove(menuItems)).ptr()), m_client.base.clientInfo);
+ }
- return true;
+ bool canShowContextMenu() const override
+ {
+ return m_client.showContextMenu;
}
bool hideContextMenu(WebPageProxy& page) override
Modified: trunk/Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp (264112 => 264113)
--- trunk/Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp 2020-07-08 17:08:22 UTC (rev 264112)
+++ trunk/Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp 2020-07-08 17:43:56 UTC (rev 264113)
@@ -263,9 +263,9 @@
}
#if ENABLE(CONTEXT_MENUS)
-Ref<WebContextMenuProxy> PageClientImpl::createContextMenuProxy(WebPageProxy&, ContextMenuContextData&& context, const UserData& userData)
+Ref<WebContextMenuProxy> PageClientImpl::createContextMenuProxy(WebPageProxy& page, ContextMenuContextData&& context, const UserData& userData)
{
- return WebContextMenuProxyWPE::create(WTFMove(context), userData);
+ return WebContextMenuProxyWPE::create(page, WTFMove(context), userData);
}
#endif
Modified: trunk/Source/WebKit/UIProcess/WebContextMenuListenerProxy.cpp (264112 => 264113)
--- trunk/Source/WebKit/UIProcess/WebContextMenuListenerProxy.cpp 2020-07-08 17:08:22 UTC (rev 264112)
+++ trunk/Source/WebKit/UIProcess/WebContextMenuListenerProxy.cpp 2020-07-08 17:43:56 UTC (rev 264113)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2020 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,37 +28,26 @@
#if ENABLE(CONTEXT_MENUS)
-#include "APIArray.h"
-#include "WKAPICast.h"
-#include "WKArray.h"
#include "WebContextMenuItem.h"
-#include "WebContextMenuItemData.h"
namespace WebKit {
using namespace WebCore;
-WebContextMenuListenerProxy::WebContextMenuListenerProxy(WebContextMenuProxy* contextMenuMac)
- : m_contextMenuMac(contextMenuMac)
+WebContextMenuListenerProxy::WebContextMenuListenerProxy(WebContextMenuListenerProxy::Client& client)
+ : m_client(makeWeakPtr(client))
{
}
-WebContextMenuListenerProxy::~WebContextMenuListenerProxy()
-{
-}
+WebContextMenuListenerProxy::~WebContextMenuListenerProxy() = default;
void WebContextMenuListenerProxy::useContextMenuItems(Vector<Ref<WebContextMenuItem>>&& items)
{
- if (!m_contextMenuMac)
+ if (!m_client)
return;
- m_contextMenuMac->showContextMenuWithItems(WTFMove(items));
+ m_client->useContextMenuItems(WTFMove(items));
}
-void WebContextMenuListenerProxy::invalidate()
-{
- m_contextMenuMac = nullptr;
-}
-
} // namespace WebKit
#endif // ENABLE(CONTEXT_MENUS)
Modified: trunk/Source/WebKit/UIProcess/WebContextMenuListenerProxy.h (264112 => 264113)
--- trunk/Source/WebKit/UIProcess/WebContextMenuListenerProxy.h 2020-07-08 17:08:22 UTC (rev 264112)
+++ trunk/Source/WebKit/UIProcess/WebContextMenuListenerProxy.h 2020-07-08 17:43:56 UTC (rev 264113)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2020 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,18 +28,23 @@
#if ENABLE(CONTEXT_MENUS)
#include "APIObject.h"
-#include "WKArray.h"
-#include "WebContextMenuProxy.h"
-#include <wtf/RefPtr.h>
+#include <wtf/Forward.h>
+#include <wtf/WeakPtr.h>
namespace WebKit {
-class WebContextMenuProxyMac;
+class WebContextMenuItem;
+
class WebContextMenuListenerProxy : public API::ObjectImpl<API::Object::Type::ContextMenuListener> {
public:
- static Ref<WebContextMenuListenerProxy> create(WebContextMenuProxy* contextMenuMac)
+ struct Client : CanMakeWeakPtr<Client> {
+ virtual ~Client() = default;
+ virtual void useContextMenuItems(Vector<Ref<WebContextMenuItem>>&&) = 0;
+ };
+
+ static Ref<WebContextMenuListenerProxy> create(Client& client)
{
- return adoptRef(*new WebContextMenuListenerProxy(contextMenuMac));
+ return adoptRef(*new WebContextMenuListenerProxy(client));
}
virtual ~WebContextMenuListenerProxy();
@@ -46,13 +51,12 @@
void useContextMenuItems(Vector<Ref<WebContextMenuItem>>&&);
- void invalidate();
private:
- explicit WebContextMenuListenerProxy(WebContextMenuProxy*);
+ explicit WebContextMenuListenerProxy(Client&);
- WebContextMenuProxy* m_contextMenuMac;
+ WeakPtr<Client> m_client;
};
-
+
} // namespace WebKit
#endif // ENABLE(CONTEXT_MENUS)
Modified: trunk/Source/WebKit/UIProcess/WebContextMenuProxy.cpp (264112 => 264113)
--- trunk/Source/WebKit/UIProcess/WebContextMenuProxy.cpp 2020-07-08 17:08:22 UTC (rev 264112)
+++ trunk/Source/WebKit/UIProcess/WebContextMenuProxy.cpp 2020-07-08 17:43:56 UTC (rev 264113)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2020 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,18 +28,52 @@
#if ENABLE(CONTEXT_MENUS)
+#include "APIContextMenuClient.h"
+#include "WebPageMessages.h"
+
namespace WebKit {
-WebContextMenuProxy::WebContextMenuProxy(ContextMenuContextData&& context, const UserData& userData)
+WebContextMenuProxy::WebContextMenuProxy(WebPageProxy& page, ContextMenuContextData&& context, const UserData& userData)
: m_context(WTFMove(context))
, m_userData(userData)
+ , m_page(makeWeakPtr(page))
{
}
-WebContextMenuProxy::~WebContextMenuProxy()
+WebContextMenuProxy::~WebContextMenuProxy() = default;
+
+Vector<Ref<WebContextMenuItem>> WebContextMenuProxy::proposedItems() const
{
+ return WTF::map(m_context.menuItems(), [](auto& item) {
+ return WebContextMenuItem::create(item);
+ });
}
+void WebContextMenuProxy::show()
+{
+ m_contextMenuListener = WebContextMenuListenerProxy::create(*this);
+ page()->contextMenuClient().getContextMenuFromProposedMenu(*page(), proposedItems(), *m_contextMenuListener, m_context.webHitTestResultData(), page()->process().transformHandlesToObjects(m_userData.object()).get());
+}
+
+void WebContextMenuProxy::useContextMenuItems(Vector<Ref<WebContextMenuItem>>&& items)
+{
+ m_contextMenuListener = nullptr;
+
+ auto page = makeRefPtr(this->page());
+ if (!page)
+ return;
+
+ // Since showContextMenuWithItems can spin a nested run loop we need to turn off the responsiveness timer.
+ page->process().stopResponsivenessTimer();
+
+ // Protect |this| from being deallocated if WebPageProxy code is re-entered from the menu runloop or delegates.
+ auto protectedThis = makeRef(*this);
+ showContextMenuWithItems(WTFMove(items));
+
+ // No matter the result of showContextMenuWithItems, always notify the WebProcess that the menu is hidden so it starts handling mouse events again.
+ page->send(Messages::WebPage::ContextMenuHidden());
+}
+
} // namespace WebKit
#endif
Modified: trunk/Source/WebKit/UIProcess/WebContextMenuProxy.h (264112 => 264113)
--- trunk/Source/WebKit/UIProcess/WebContextMenuProxy.h 2020-07-08 17:08:22 UTC (rev 264112)
+++ trunk/Source/WebKit/UIProcess/WebContextMenuProxy.h 2020-07-08 17:43:56 UTC (rev 264113)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2020 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,25 +29,38 @@
#include "ContextMenuContextData.h"
#include "UserData.h"
+#include "WebContextMenuListenerProxy.h"
#include <wtf/RefCounted.h>
+#include <wtf/WeakPtr.h>
namespace WebKit {
class WebContextMenuItem;
+class WebPageProxy;
-class WebContextMenuProxy : public RefCounted<WebContextMenuProxy> {
+class WebContextMenuProxy : public RefCounted<WebContextMenuProxy>, public WebContextMenuListenerProxy::Client {
public:
virtual ~WebContextMenuProxy();
- virtual void show() = 0;
+ virtual void show();
- virtual void showContextMenuWithItems(Vector<Ref<WebContextMenuItem>>&&) = 0;
+ WebPageProxy* page() const { return m_page.get(); }
protected:
- WebContextMenuProxy(ContextMenuContextData&&, const UserData&);
+ WebContextMenuProxy(WebPageProxy&, ContextMenuContextData&&, const UserData&);
+ // WebContextMenuListenerProxy::Client
+ void useContextMenuItems(Vector<Ref<WebContextMenuItem>>&&) override;
+
const ContextMenuContextData m_context;
const UserData m_userData;
+
+private:
+ virtual Vector<Ref<WebContextMenuItem>> proposedItems() const;
+ virtual void showContextMenuWithItems(Vector<Ref<WebContextMenuItem>>&&) = 0;
+
+ RefPtr<WebContextMenuListenerProxy> m_contextMenuListener;
+ WeakPtr<WebPageProxy> m_page;
};
} // namespace WebKit
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (264112 => 264113)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2020-07-08 17:08:22 UTC (rev 264112)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2020-07-08 17:43:56 UTC (rev 264113)
@@ -6556,15 +6556,7 @@
m_activeContextMenu = pageClient().createContextMenuProxy(*this, WTFMove(contextMenuContextData), userData);
- // Since showContextMenu() can spin a nested run loop we need to turn off the responsiveness timer.
- m_process->stopResponsivenessTimer();
-
- // m_activeContextMenu might get cleared if WebPageProxy code is re-entered from the menu runloop or delegates.
- Ref<WebContextMenuProxy> protector(*m_activeContextMenu);
m_activeContextMenu->show();
-
- // No matter the result of internalShowContextMenu, always notify the WebProcess that the menu is hidden so it starts handling mouse events again.
- send(Messages::WebPage::ContextMenuHidden());
}
void WebPageProxy::contextMenuItemSelected(const WebContextMenuItemData& item)
Modified: trunk/Source/WebKit/UIProcess/gtk/WebContextMenuProxyGtk.cpp (264112 => 264113)
--- trunk/Source/WebKit/UIProcess/gtk/WebContextMenuProxyGtk.cpp 2020-07-08 17:08:22 UTC (rev 264112)
+++ trunk/Source/WebKit/UIProcess/gtk/WebContextMenuProxyGtk.cpp 2020-07-08 17:43:56 UTC (rev 264113)
@@ -170,7 +170,7 @@
if (menuItem.action() < ContextMenuItemBaseApplicationTag) {
g_object_set_data(G_OBJECT(action), gContextMenuActionId, GINT_TO_POINTER(menuItem.action()));
g_object_set_data_full(G_OBJECT(action), gContextMenuTitle, g_strdup(menuItem.title().utf8().data()), g_free);
- signalHandlerId = g_signal_connect(action, "activate", G_CALLBACK(contextMenuItemActivatedCallback), m_page);
+ signalHandlerId = g_signal_connect(action, "activate", G_CALLBACK(contextMenuItemActivatedCallback), page());
m_signalHandlers.set(signalHandlerId, action);
}
break;
@@ -250,7 +250,7 @@
bindModelToMenuWidget(m_menu, G_MENU_MODEL(menu.get()));
}
-void WebContextMenuProxyGtk::show()
+Vector<Ref<WebContextMenuItem>> WebContextMenuProxyGtk::proposedItems() const
{
Vector<Ref<WebContextMenuItem>> proposedAPIItems;
for (auto& item : m_context.menuItems()) {
@@ -257,8 +257,7 @@
if (item.action() != ContextMenuItemTagShareMenu)
proposedAPIItems.append(WebContextMenuItem::create(item));
}
-
- m_page->contextMenuClient().getContextMenuFromProposedMenu(*m_page, WTFMove(proposedAPIItems), WebContextMenuListenerProxy::create(this).get(), m_context.webHitTestResultData(), m_page->process().transformHandlesToObjects(m_userData.object()).get());
+ return proposedAPIItems;
}
void WebContextMenuProxyGtk::showContextMenuWithItems(Vector<Ref<WebContextMenuItem>>&& items)
@@ -269,7 +268,7 @@
if (!menuWidgetHasItems(m_menu))
return;
- NativeWebMouseEvent* mouseEvent = m_page->currentlyProcessedMouseDownEvent();
+ NativeWebMouseEvent* mouseEvent = page()->currentlyProcessedMouseDownEvent();
const GdkEvent* event = mouseEvent ? mouseEvent->nativeEvent() : nullptr;
const GdkRectangle rect = { m_context.menuLocation().x(), m_context.menuLocation().y(), 1, 1 };
popupMenuWidget(m_menu, event, rect);
@@ -276,9 +275,8 @@
}
WebContextMenuProxyGtk::WebContextMenuProxyGtk(GtkWidget* webView, WebPageProxy& page, ContextMenuContextData&& context, const UserData& userData)
- : WebContextMenuProxy(WTFMove(context), userData)
+ : WebContextMenuProxy(page, WTFMove(context), userData)
, m_webView(webView)
- , m_page(&page)
, m_menu(createMenuWidget(m_webView))
{
gtk_widget_insert_action_group(GTK_WIDGET(m_menu), gContextMenuItemGroup, G_ACTION_GROUP(m_actionGroup.get()));
Modified: trunk/Source/WebKit/UIProcess/gtk/WebContextMenuProxyGtk.h (264112 => 264113)
--- trunk/Source/WebKit/UIProcess/gtk/WebContextMenuProxyGtk.h 2020-07-08 17:08:22 UTC (rev 264112)
+++ trunk/Source/WebKit/UIProcess/gtk/WebContextMenuProxyGtk.h 2020-07-08 17:43:56 UTC (rev 264113)
@@ -42,7 +42,7 @@
class WebContextMenuItemData;
class WebPageProxy;
-class WebContextMenuProxyGtk : public WebContextMenuProxy {
+class WebContextMenuProxyGtk final : public WebContextMenuProxy {
public:
static auto create(GtkWidget* widget, WebPageProxy& page, ContextMenuContextData&& context, const UserData& userData)
{
@@ -56,7 +56,7 @@
private:
WebContextMenuProxyGtk(GtkWidget*, WebPageProxy&, ContextMenuContextData&&, const UserData&);
- void show() override;
+ Vector<Ref<WebContextMenuItem>> proposedItems() const override;
void showContextMenuWithItems(Vector<Ref<WebContextMenuItem>>&&) override;
void append(GMenu*, const WebContextMenuItemGlib&);
GRefPtr<GMenu> buildMenu(const Vector<WebContextMenuItemGlib>&);
@@ -64,7 +64,6 @@
Vector<WebContextMenuItemGlib> populateSubMenu(const WebContextMenuItemData&);
GtkWidget* m_webView;
- WebPageProxy* m_page;
GtkWidget* m_menu;
HashMap<unsigned long, void*> m_signalHandlers;
GRefPtr<GSimpleActionGroup> m_actionGroup { adoptGRef(g_simple_action_group_new()) };
Modified: trunk/Source/WebKit/UIProcess/mac/WKSharingServicePickerDelegate.mm (264112 => 264113)
--- trunk/Source/WebKit/UIProcess/mac/WKSharingServicePickerDelegate.mm 2020-07-08 17:08:22 UTC (rev 264112)
+++ trunk/Source/WebKit/UIProcess/mac/WKSharingServicePickerDelegate.mm 2020-07-08 17:43:56 UTC (rev 264113)
@@ -129,7 +129,7 @@
}
// FIXME: We should adopt replaceSelectionWithAttributedString instead of bouncing through the (fake) pasteboard.
- _menuProxy->page().replaceSelectionWithPasteboardData(types, dataReference);
+ _menuProxy->page()->replaceSelectionWithPasteboardData(types, dataReference);
}
- (NSWindow *)sharingService:(NSSharingService *)sharingService sourceWindowForShareItems:(NSArray *)items sharingContentScope:(NSSharingContentScope *)sharingContentScope
@@ -140,4 +140,3 @@
@end
#endif // ENABLE(SERVICE_CONTROLS)
-
Modified: trunk/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.h (264112 => 264113)
--- trunk/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.h 2020-07-08 17:08:22 UTC (rev 264112)
+++ trunk/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.h 2020-07-08 17:43:56 UTC (rev 264113)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2020 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,50 +27,44 @@
#if PLATFORM(MAC)
-#include "WKArray.h"
#include "WebContextMenuProxy.h"
#include <wtf/RetainPtr.h>
+#include <wtf/WeakObjCPtr.h>
OBJC_CLASS NSMenu;
OBJC_CLASS NSMenuItem;
-OBJC_CLASS NSPopUpButtonCell;
OBJC_CLASS NSView;
OBJC_CLASS NSWindow;
namespace WebKit {
-class ShareableBitmap;
-class UserData;
class WebContextMenuItemData;
-class WebContextMenuListenerProxy;
-class WebPageProxy;
-class WebContextMenuProxyMac : public WebContextMenuProxy {
+class WebContextMenuProxyMac final : public WebContextMenuProxy {
public:
- static auto create(NSView* view, WebPageProxy& page, ContextMenuContextData&& context, const UserData& userData)
+ static auto create(NSView *webView, WebPageProxy& page, ContextMenuContextData&& context, const UserData& userData)
{
- return adoptRef(*new WebContextMenuProxyMac(view, page, WTFMove(context), userData));
+ return adoptRef(*new WebContextMenuProxyMac(webView, page, WTFMove(context), userData));
}
~WebContextMenuProxyMac();
void contextMenuItemSelected(const WebContextMenuItemData&);
- void showContextMenuWithItems(Vector<Ref<WebContextMenuItem>>&&) override;
#if ENABLE(SERVICE_CONTROLS)
void clearServicesMenu();
#endif
- WebPageProxy& page() const { return m_page; }
NSWindow *window() const;
private:
- WebContextMenuProxyMac(NSView*, WebPageProxy&, ContextMenuContextData&&, const UserData&);
+ WebContextMenuProxyMac(NSView *, WebPageProxy&, ContextMenuContextData&&, const UserData&);
+
void show() override;
+ void showContextMenuWithItems(Vector<Ref<WebContextMenuItem>>&&) override;
+ void useContextMenuItems(Vector<Ref<WebContextMenuItem>>&&) override;
- RefPtr<WebContextMenuListenerProxy> m_contextMenuListener;
void getContextMenuItem(const WebContextMenuItemData&, CompletionHandler<void(NSMenuItem *)>&&);
void getContextMenuFromItems(const Vector<WebContextMenuItemData>&, CompletionHandler<void(NSMenu *)>&&);
- void showContextMenu();
#if ENABLE(SERVICE_CONTROLS)
void getShareMenuItem(CompletionHandler<void(NSMenuItem *)>&&);
@@ -79,9 +73,7 @@
#endif
RetainPtr<NSMenu> m_menu;
-
- NSView* m_webView;
- WebPageProxy& m_page;
+ WeakObjCPtr<NSView> m_webView;
};
} // namespace WebKit
Modified: trunk/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.mm (264112 => 264113)
--- trunk/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.mm 2020-07-08 17:08:22 UTC (rev 264112)
+++ trunk/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.mm 2020-07-08 17:43:56 UTC (rev 264113)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2020 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,25 +29,19 @@
#if PLATFORM(MAC)
#import "APIContextMenuClient.h"
-#import "DataReference.h"
#import "MenuUtilities.h"
-#import "PageClientImplMac.h"
#import "ServicesController.h"
#import "ShareableBitmap.h"
-#import "StringUtilities.h"
#import "WKMenuItemIdentifiersPrivate.h"
#import "WKSharingServicePickerDelegate.h"
#import "WebContextMenuItem.h"
#import "WebContextMenuItemData.h"
-#import "WebContextMenuListenerProxy.h"
#import "WebPageProxy.h"
-#import "WebProcessProxy.h"
#import <WebCore/GraphicsContext.h>
#import <WebCore/IntRect.h>
#import <WebCore/LocalizedStrings.h>
#import <pal/spi/mac/NSMenuSPI.h>
#import <pal/spi/mac/NSSharingServicePickerSPI.h>
-#import <pal/spi/mac/NSSharingServiceSPI.h>
#import <wtf/RetainPtr.h>
@interface WKUserDataWrapper : NSObject {
@@ -154,10 +148,9 @@
namespace WebKit {
using namespace WebCore;
-WebContextMenuProxyMac::WebContextMenuProxyMac(NSView* webView, WebPageProxy& page, ContextMenuContextData&& context, const UserData& userData)
- : WebContextMenuProxy(WTFMove(context), userData)
+WebContextMenuProxyMac::WebContextMenuProxyMac(NSView *webView, WebPageProxy& page, ContextMenuContextData&& context, const UserData& userData)
+ : WebContextMenuProxy(page, WTFMove(context), userData)
, m_webView(webView)
- , m_page(page)
{
}
@@ -164,11 +157,6 @@
WebContextMenuProxyMac::~WebContextMenuProxyMac()
{
[m_menu cancelTracking];
-
- if (m_contextMenuListener) {
- m_contextMenuListener->invalidate();
- m_contextMenuListener = nullptr;
- }
}
void WebContextMenuProxyMac::contextMenuItemSelected(const WebContextMenuItemData& item)
@@ -177,7 +165,7 @@
clearServicesMenu();
#endif
- m_page.contextMenuItemSelected(item);
+ page()->contextMenuItemSelected(item);
}
#if ENABLE(SERVICE_CONTROLS)
@@ -251,8 +239,9 @@
{
setupServicesMenu();
+ auto webView = m_webView.get();
[[WKSharingServicePickerDelegate sharedSharingServicePickerDelegate] setMenuProxy:this];
- [m_menu popUpMenuPositioningItem:nil atLocation:m_context.menuLocation() inView:m_webView];
+ [m_menu popUpMenuPositioningItem:nil atLocation:m_context.menuLocation() inView:webView.get()];
}
void WebContextMenuProxyMac::clearServicesMenu()
@@ -337,16 +326,14 @@
void WebContextMenuProxyMac::show()
{
- Ref<WebPageProxy> protect(m_page);
-
#if ENABLE(SERVICE_CONTROLS)
if (m_context.isServicesMenu()) {
- showServicesMenu();
+ WebContextMenuProxy::useContextMenuItems({ });
return;
}
#endif
- showContextMenu();
+ WebContextMenuProxy::show();
}
void WebContextMenuProxyMac::getContextMenuFromItems(const Vector<WebContextMenuItemData>& items, CompletionHandler<void(NSMenu *)>&& completionHandler)
@@ -507,47 +494,52 @@
void WebContextMenuProxyMac::showContextMenuWithItems(Vector<Ref<WebContextMenuItem>>&& items)
{
- if (m_page.contextMenuClient().showContextMenu(m_page, m_context.menuLocation(), items))
+#if ENABLE(SERVICE_CONTROLS)
+ if (m_context.isServicesMenu()) {
+ ASSERT(items.isEmpty());
+ showServicesMenu();
return;
+ }
+#endif
- if (items.isEmpty())
+ if (page()->contextMenuClient().canShowContextMenu()) {
+ page()->contextMenuClient().showContextMenu(*page(), m_context.menuLocation(), items);
return;
+ }
- Vector<WebContextMenuItemData> data;
- data.reserveInitialCapacity(items.size());
- for (auto& item : items)
- data.uncheckedAppend(item->data());
+ ASSERT(items.isEmpty());
+ if (!m_menu)
+ return;
- getContextMenuFromItems(data, [protectedThis = makeRef(*this), this](NSMenu *menu) mutable {
- [[WKMenuTarget sharedMenuTarget] setMenuProxy:this];
- m_page.contextMenuClient().menuFromProposedMenu(m_page, menu, m_context.webHitTestResultData(), m_userData.object(), [this, protectedThis = WTFMove(protectedThis)] (RetainPtr<NSMenu>&& menu) {
- m_menu = WTFMove(menu);
- NSPoint menuLocation = [m_webView convertPoint:m_context.menuLocation() toView:nil];
- NSEvent *event = [NSEvent mouseEventWithType:NSEventTypeRightMouseUp location:menuLocation modifierFlags:0 timestamp:0 windowNumber:m_webView.window.windowNumber context:nil eventNumber:0 clickCount:0 pressure:0];
- [NSMenu popUpContextMenu:m_menu.get() withEvent:event forView:m_webView];
-
- if (m_contextMenuListener) {
- m_contextMenuListener->invalidate();
- m_contextMenuListener = nullptr;
- }
- });
- });
+ auto webView = m_webView.get();
+ NSPoint menuLocation = [webView convertPoint:m_context.menuLocation() toView:nil];
+ NSEvent *event = [NSEvent mouseEventWithType:NSEventTypeRightMouseUp location:menuLocation modifierFlags:0 timestamp:0 windowNumber:[webView window].windowNumber context:nil eventNumber:0 clickCount:0 pressure:0];
+ [NSMenu popUpContextMenu:m_menu.get() withEvent:event forView:webView.get()];
}
-void WebContextMenuProxyMac::showContextMenu()
+void WebContextMenuProxyMac::useContextMenuItems(Vector<Ref<WebContextMenuItem>>&& items)
{
- Vector<Ref<WebContextMenuItem>> proposedAPIItems;
- for (auto& item : m_context.menuItems())
- proposedAPIItems.append(WebContextMenuItem::create(item));
-
- if (m_contextMenuListener) {
- m_contextMenuListener->invalidate();
- m_contextMenuListener = nullptr;
+ if (items.isEmpty() || !page() || page()->contextMenuClient().canShowContextMenu()) {
+ WebContextMenuProxy::useContextMenuItems(WTFMove(items));
+ return;
}
- m_contextMenuListener = WebContextMenuListenerProxy::create(this);
+ auto data = "" [](auto& item) {
+ return item->data();
+ });
- m_page.contextMenuClient().getContextMenuFromProposedMenu(m_page, WTFMove(proposedAPIItems), *m_contextMenuListener, m_context.webHitTestResultData(), m_page.process().transformHandlesToObjects(m_userData.object()).get());
+ getContextMenuFromItems(data, [this, protectedThis = makeRef(*this)](NSMenu *menu) mutable {
+ if (!page()) {
+ WebContextMenuProxy::useContextMenuItems({ });
+ return;
+ }
+
+ [[WKMenuTarget sharedMenuTarget] setMenuProxy:this];
+ page()->contextMenuClient().menuFromProposedMenu(*page(), menu, m_context.webHitTestResultData(), m_userData.object(), [this, protectedThis = WTFMove(protectedThis)](RetainPtr<NSMenu>&& menu) {
+ m_menu = WTFMove(menu);
+ WebContextMenuProxy::useContextMenuItems({ });
+ });
+ });
}
NSWindow *WebContextMenuProxyMac::window() const
Modified: trunk/Source/WebKit/UIProcess/win/WebContextMenuProxyWin.cpp (264112 => 264113)
--- trunk/Source/WebKit/UIProcess/win/WebContextMenuProxyWin.cpp 2020-07-08 17:08:22 UTC (rev 264112)
+++ trunk/Source/WebKit/UIProcess/win/WebContextMenuProxyWin.cpp 2020-07-08 17:43:56 UTC (rev 264113)
@@ -38,15 +38,6 @@
namespace WebKit {
using namespace WebCore;
-void WebContextMenuProxyWin::show()
-{
- Vector<Ref<WebContextMenuItem>> proposedAPIItems;
- for (auto& item : m_context.menuItems())
- proposedAPIItems.append(WebContextMenuItem::create(item));
- m_contextMenuListener = WebContextMenuListenerProxy::create(this);
- m_page.contextMenuClient().getContextMenuFromProposedMenu(m_page, WTFMove(proposedAPIItems), *m_contextMenuListener, m_context.webHitTestResultData(), m_page.process().transformHandlesToObjects(m_userData.object()).get());
-}
-
static HMENU createMenu(const ContextMenuContextData &context)
{
HMENU menu = ::CreatePopupMenu();
@@ -104,14 +95,13 @@
UINT flags = TPM_RIGHTBUTTON | TPM_TOPALIGN | TPM_VERPOSANIMATION | TPM_HORIZONTAL | TPM_LEFTALIGN | TPM_HORPOSANIMATION;
POINT pt { m_context.menuLocation().x(), m_context.menuLocation().y() };
- HWND wnd = m_page.viewWidget();
+ HWND wnd = page()->viewWidget();
::ClientToScreen(wnd, &pt);
- ::TrackPopupMenuEx(m_menu, flags, pt.x, pt.y, m_page.viewWidget(), nullptr);
+ ::TrackPopupMenuEx(m_menu, flags, pt.x, pt.y, page()->viewWidget(), nullptr);
}
WebContextMenuProxyWin::WebContextMenuProxyWin(WebPageProxy& page, ContextMenuContextData&& context, const UserData& userData)
- : WebContextMenuProxy(WTFMove(context), userData)
- , m_page(page)
+ : WebContextMenuProxy(page, WTFMove(context), userData)
{
m_menu = createMenu(m_context);
}
Modified: trunk/Source/WebKit/UIProcess/win/WebContextMenuProxyWin.h (264112 => 264113)
--- trunk/Source/WebKit/UIProcess/win/WebContextMenuProxyWin.h 2020-07-08 17:08:22 UTC (rev 264112)
+++ trunk/Source/WebKit/UIProcess/win/WebContextMenuProxyWin.h 2020-07-08 17:43:56 UTC (rev 264113)
@@ -36,7 +36,7 @@
class WebContextMenuItemData;
class WebPageProxy;
-class WebContextMenuProxyWin : public WebContextMenuProxy {
+class WebContextMenuProxyWin final : public WebContextMenuProxy {
public:
static auto create(WebPageProxy& page, ContextMenuContextData&& context, const UserData& userData)
{
@@ -47,10 +47,7 @@
private:
WebContextMenuProxyWin(WebPageProxy&, ContextMenuContextData&&, const UserData&);
void showContextMenuWithItems(Vector<Ref<WebContextMenuItem>>&&) override;
- void show() override;
- WebPageProxy& m_page;
- RefPtr<WebContextMenuListenerProxy> m_contextMenuListener;
HMENU m_menu;
};
Modified: trunk/Source/WebKit/UIProcess/wpe/WebContextMenuProxyWPE.h (264112 => 264113)
--- trunk/Source/WebKit/UIProcess/wpe/WebContextMenuProxyWPE.h 2020-07-08 17:08:22 UTC (rev 264112)
+++ trunk/Source/WebKit/UIProcess/wpe/WebContextMenuProxyWPE.h 2020-07-08 17:43:56 UTC (rev 264113)
@@ -29,11 +29,11 @@
namespace WebKit {
-class WebContextMenuProxyWPE : public WebContextMenuProxy {
+class WebContextMenuProxyWPE final : public WebContextMenuProxy {
public:
- static auto create(ContextMenuContextData&& context, const UserData& userData)
+ static auto create(WebPageProxy& page, ContextMenuContextData&& context, const UserData& userData)
{
- return adoptRef(*new WebContextMenuProxyWPE(WTFMove(context), userData));
+ return adoptRef(*new WebContextMenuProxyWPE(page, WTFMove(context), userData));
}
void showContextMenuWithItems(Vector<Ref<WebContextMenuItem>>&&) final { }
@@ -40,8 +40,8 @@
void show() final { };
private:
- WebContextMenuProxyWPE(ContextMenuContextData&& context, const UserData& userData)
- : WebContextMenuProxy(WTFMove(context), userData)
+ WebContextMenuProxyWPE(WebPageProxy& page, ContextMenuContextData&& context, const UserData& userData)
+ : WebContextMenuProxy(page, WTFMove(context), userData)
{ }
};
Modified: trunk/Tools/ChangeLog (264112 => 264113)
--- trunk/Tools/ChangeLog 2020-07-08 17:08:22 UTC (rev 264112)
+++ trunk/Tools/ChangeLog 2020-07-08 17:43:56 UTC (rev 264113)
@@ -1,3 +1,32 @@
+2020-07-08 Andy Estes <[email protected]>
+
+ REGRESSION (r207558): [Mac] Context clicks on links sometimes result in navigations
+ https://bugs.webkit.org/show_bug.cgi?id=213793
+ <rdar://problem/64294015>
+
+ Reviewed by Tim Horton.
+
+ Added API tests.
+
+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/xcshareddata/xcschemes/TestWebKitAPI.xcscheme:
+ * TestWebKitAPI/Tests/WebKit/mac/ContextMenuMouseEvents.mm: Renamed from Tools/TestWebKitAPI/Tests/WebKit/mac/ContextMenuControlClick.mm.
+ (TestWebKitAPI::runTest):
+ (TestWebKitAPI::TEST):
+ * TestWebKitAPI/cocoa/TestWKWebView.h:
+ * TestWebKitAPI/cocoa/TestWKWebView.mm:
+ (-[TestWKWebViewHostWindow _mouseDownAtPoint:simulatePressure:clickCount:modifierFlags:mouseEventType:]):
+ (-[TestWKWebViewHostWindow _mouseUpAtPoint:clickCount:modifierFlags:eventType:]):
+ (-[TestWKWebView mouseDownAtPoint:simulatePressure:]):
+ (-[TestWKWebView mouseDownAtPoint:simulatePressure:withFlags:eventType:]):
+ (-[TestWKWebView mouseUpAtPoint:]):
+ (-[TestWKWebView mouseUpAtPoint:withFlags:eventType:]):
+ (-[TestWKWebView sendClicksAtPoint:numberOfClicks:]):
+ (-[TestWKWebViewHostWindow _mouseDownAtPoint:simulatePressure:clickCount:modifierFlags:]): Deleted.
+ (-[TestWKWebViewHostWindow _mouseUpAtPoint:clickCount:modifierFlags:]): Deleted.
+ (-[TestWKWebView mouseDownAtPoint:simulatePressure:withFlags:]): Deleted.
+ (-[TestWKWebView mouseUpAtPoint:withFlags:]): Deleted.
+
2020-07-08 Jer Noble <[email protected]>
Flaky API Test: TestWebKitAPI.SleepDisabler.NavigateBack
Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (264112 => 264113)
--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2020-07-08 17:08:22 UTC (rev 264112)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2020-07-08 17:43:56 UTC (rev 264113)
@@ -847,6 +847,7 @@
A12DDBFB1E836F0700CF6CAE /* RenderedImageWithOptions.mm in Sources */ = {isa = PBXBuildFile; fileRef = A12DDBF91E836F0700CF6CAE /* RenderedImageWithOptions.mm */; };
A12DDC001E8373E700CF6CAE /* rendered-image-excluding-overflow.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = A12DDBFF1E8373C100CF6CAE /* rendered-image-excluding-overflow.html */; };
A12DDC021E837C2400CF6CAE /* RenderedImageWithOptionsPlugIn.mm in Sources */ = {isa = PBXBuildFile; fileRef = A12DDBFC1E836FF100CF6CAE /* RenderedImageWithOptionsPlugIn.mm */; };
+ A13D1AD624AD468F003F92A8 /* context-menu-control-click.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = A13D1AD524AD4677003F92A8 /* context-menu-control-click.html */; };
A13EBBAA1B87428D00097110 /* WebProcessPlugIn.mm in Sources */ = {isa = PBXBuildFile; fileRef = A13EBBA91B87428D00097110 /* WebProcessPlugIn.mm */; };
A13EBBAB1B87434600097110 /* PlatformUtilitiesCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0F139E721A423A2B00F590F5 /* PlatformUtilitiesCocoa.mm */; };
A13EBBB01B87436F00097110 /* BundleParametersPlugIn.mm in Sources */ = {isa = PBXBuildFile; fileRef = A13EBBAE1B87436F00097110 /* BundleParametersPlugIn.mm */; };
@@ -868,6 +869,7 @@
A179918B1E1CA24100A505ED /* SharedBufferTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A17991891E1CA24100A505ED /* SharedBufferTest.cpp */; };
A17EAC55208305A00084B41B /* find.pdf in Copy Resources */ = {isa = PBXBuildFile; fileRef = A17EAC542083056E0084B41B /* find.pdf */; };
A180C0FA1EE67DF000468F47 /* RunOpenPanel.mm in Sources */ = {isa = PBXBuildFile; fileRef = A180C0F91EE67DF000468F47 /* RunOpenPanel.mm */; };
+ A1C142C224AA7B2E00444207 /* ContextMenuMouseEvents.mm in Sources */ = {isa = PBXBuildFile; fileRef = A1C142C124AA7B2E00444207 /* ContextMenuMouseEvents.mm */; };
A1C4FB731BACD1CA003742D0 /* pages.pages in Copy Resources */ = {isa = PBXBuildFile; fileRef = A1C4FB721BACD1B7003742D0 /* pages.pages */; };
A1DF74321C41B65800A2F4D0 /* AlwaysRevalidatedURLSchemes.mm in Sources */ = {isa = PBXBuildFile; fileRef = A1DF74301C41B65800A2F4D0 /* AlwaysRevalidatedURLSchemes.mm */; };
A1EC11881F42541200D0146E /* PreviewConverter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A1EC11871F42541200D0146E /* PreviewConverter.cpp */; };
@@ -1305,6 +1307,7 @@
F41AB9A11EF4696B0083FA08 /* contenteditable-and-textarea.html in Copy Resources */,
F4A32ECB1F0643370047C544 /* contenteditable-in-iframe.html in Copy Resources */,
A16F66BA1C40EB4F00BD4D24 /* ContentFiltering.html in Copy Resources */,
+ A13D1AD624AD468F003F92A8 /* context-menu-control-click.html in Copy Resources */,
5142B2731517C8C800C32B19 /* ContextMenuCanCopyURL.html in Copy Resources */,
CD0BD0A81F79982D001AB2CF /* ContextMenuImgWithVideo.html in Copy Resources */,
5C2936961D5C00ED00DEAB1E /* CookieMessage.html in Copy Resources */,
@@ -2414,6 +2417,7 @@
A12DDBFC1E836FF100CF6CAE /* RenderedImageWithOptionsPlugIn.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RenderedImageWithOptionsPlugIn.mm; sourceTree = "<group>"; };
A12DDBFF1E8373C100CF6CAE /* rendered-image-excluding-overflow.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "rendered-image-excluding-overflow.html"; sourceTree = "<group>"; };
A12DDC011E8374F500CF6CAE /* RenderedImageWithOptionsProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderedImageWithOptionsProtocol.h; sourceTree = "<group>"; };
+ A13D1AD524AD4677003F92A8 /* context-menu-control-click.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "context-menu-control-click.html"; sourceTree = "<group>"; };
A13EBB491B87339E00097110 /* TestWebKitAPI.wkbundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TestWebKitAPI.wkbundle; sourceTree = BUILT_PRODUCTS_DIR; };
A13EBB521B87346600097110 /* WebProcessPlugIn.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = WebProcessPlugIn.xcconfig; sourceTree = "<group>"; };
A13EBB541B8734E000097110 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@@ -2447,6 +2451,7 @@
A18AA8CC1C3FA218009B2B97 /* ContentFiltering.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContentFiltering.h; sourceTree = "<group>"; };
A1A4FE5D18DD3DB700B5EA8A /* Download.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Download.mm; sourceTree = "<group>"; };
A1B89B99221E029F00EB4CEA /* SDKVariant.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = SDKVariant.xcconfig; sourceTree = "<group>"; };
+ A1C142C124AA7B2E00444207 /* ContextMenuMouseEvents.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ContextMenuMouseEvents.mm; sourceTree = "<group>"; };
A1C4FB6C1BACCE50003742D0 /* QuickLook.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = QuickLook.mm; sourceTree = "<group>"; };
A1C4FB721BACD1B7003742D0 /* pages.pages */ = {isa = PBXFileReference; lastKnownFileType = file; name = pages.pages; path = ios/pages.pages; sourceTree = SOURCE_ROOT; };
A1DF74301C41B65800A2F4D0 /* AlwaysRevalidatedURLSchemes.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AlwaysRevalidatedURLSchemes.mm; sourceTree = "<group>"; };
@@ -4415,9 +4420,11 @@
isa = PBXGroup;
children = (
9BD423991E04BD9800200395 /* AttributedSubstringForProposedRangeWithImage.mm */,
+ A13D1AD524AD4677003F92A8 /* context-menu-control-click.html */,
8349D3C11DB96DDA004A9F65 /* ContextMenuDownload.mm */,
CD0BD0A71F7997C2001AB2CF /* ContextMenuImgWithVideo.html */,
CD0BD0A51F799220001AB2CF /* ContextMenuImgWithVideo.mm */,
+ A1C142C124AA7B2E00444207 /* ContextMenuMouseEvents.mm */,
7AC7B57220D9BAF0002C09A0 /* CustomBundleObject.h */,
7AC7B56F20D9BA5B002C09A0 /* CustomBundleObject.mm */,
7AC7B56C20D9768F002C09A0 /* CustomBundleParameter.mm */,
@@ -4913,6 +4920,7 @@
37FB72971DB2E82F00E41BE4 /* ContextMenuDefaultItemsHaveTags.mm in Sources */,
8349D3C21DB96DDE004A9F65 /* ContextMenuDownload.mm in Sources */,
CD0BD0A61F79924D001AB2CF /* ContextMenuImgWithVideo.mm in Sources */,
+ A1C142C224AA7B2E00444207 /* ContextMenuMouseEvents.mm in Sources */,
5C3B1D2622A74F6700BCF4D0 /* ContextMenus.mm in Sources */,
5C2936931D5BF70D00DEAB1E /* CookieAcceptPolicy.mm in Sources */,
5C19A5241FD0F60100EEA323 /* CookiePrivateBrowsing.mm in Sources */,
Added: trunk/Tools/TestWebKitAPI/Tests/WebKit/mac/ContextMenuMouseEvents.mm (0 => 264113)
--- trunk/Tools/TestWebKitAPI/Tests/WebKit/mac/ContextMenuMouseEvents.mm (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit/mac/ContextMenuMouseEvents.mm 2020-07-08 17:43:56 UTC (rev 264113)
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "TestCocoa.h"
+
+#if PLATFORM(MAC)
+
+#import "OffscreenWindow.h"
+#import "TestNavigationDelegate.h"
+#import "TestUIDelegate.h"
+#import "TestWKWebView.h"
+#import <Carbon/Carbon.h>
+#import <wtf/BlockPtr.h>
+
+namespace TestWebKitAPI {
+
+static void runTest(NSEventModifierFlags flags, NSEventType mouseDownType, NSEventType mouseUpType)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600)]);
+ [webView synchronouslyLoadTestPageNamed:@"context-menu-control-click"];
+
+ auto navigationDelegate = adoptNS([[TestNavigationDelegate alloc] init]);
+ [webView setNavigationDelegate:navigationDelegate.get()];
+
+ __block bool navigationAttempted = false;
+ [navigationDelegate setDecidePolicyForNavigationAction:^(WKNavigationAction *navigationAction, void (^decisionHandler)(WKNavigationActionPolicy)) {
+ decisionHandler(WKNavigationActionPolicyCancel);
+ navigationAttempted = true;
+ }];
+
+ auto uiDelegate = adoptNS([[TestUIDelegate alloc] init]);
+ [webView setUIDelegate:uiDelegate.get()];
+
+ __block bool done = false;
+ __block void(^completionHandlerCopy)(NSMenu *);
+ [uiDelegate setGetContextMenuFromProposedMenu:^(NSMenu *, _WKContextMenuElementInfo *, id <NSSecureCoding>, void (^completionHandler)(NSMenu *)) {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ completionHandlerCopy = [completionHandler copy];
+ done = true;
+ });
+ }];
+
+ auto clickPoint = NSMakePoint(10, 590);
+ [webView mouseDownAtPoint:clickPoint simulatePressure:NO withFlags:flags eventType:mouseDownType];
+ Util::run(&done);
+
+ [webView mouseUpAtPoint:clickPoint withFlags:flags eventType:mouseUpType];
+ completionHandlerCopy(nil);
+
+ EXPECT_FALSE([[webView objectByEvaluatingJavaScript:@"window.clickSeen"] boolValue]);
+ EXPECT_FALSE([[webView objectByEvaluatingJavaScript:@"window.mouseupSeen"] boolValue]);
+ EXPECT_TRUE([[webView objectByEvaluatingJavaScript:@"window.contextmenuSeen"] boolValue]);
+ EXPECT_TRUE([[webView objectByEvaluatingJavaScript:@"window.mousedownSeen"] boolValue]);
+
+ EXPECT_FALSE(navigationAttempted);
+}
+
+TEST(ContextMenuMouseEvents, ControlClick)
+{
+ runTest(NSEventModifierFlagControl, NSEventTypeLeftMouseDown, NSEventTypeLeftMouseUp);
+}
+
+TEST(ContextMenuMouseEvents, RightClick)
+{
+ runTest(0, NSEventTypeRightMouseDown, NSEventTypeRightMouseUp);
+}
+
+} // namespace TestWebKitAPI
+
+#endif // PLATFORM(MAC)
Added: trunk/Tools/TestWebKitAPI/Tests/WebKit/mac/context-menu-control-click.html (0 => 264113)
--- trunk/Tools/TestWebKitAPI/Tests/WebKit/mac/context-menu-control-click.html (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit/mac/context-menu-control-click.html 2020-07-08 17:43:56 UTC (rev 264113)
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script>
+ addEventListener('click', () => clickSeen = true);
+ addEventListener('contextmenu', () => contextmenuSeen = true);
+ addEventListener('mousedown', () => mousedownSeen = true);
+ addEventListener('mouseup', () => mouseupSeen = true);
+ </script>
+</head>
+<body>
+ <a href=''>link</a>
+</body>
+</html>
Modified: trunk/Tools/TestWebKitAPI/cocoa/TestUIDelegate.h (264112 => 264113)
--- trunk/Tools/TestWebKitAPI/cocoa/TestUIDelegate.h 2020-07-08 17:08:22 UTC (rev 264112)
+++ trunk/Tools/TestWebKitAPI/cocoa/TestUIDelegate.h 2020-07-08 17:43:56 UTC (rev 264113)
@@ -28,6 +28,9 @@
@interface TestUIDelegate : NSObject <WKUIDelegate>
@property (nonatomic, copy) void (^runJavaScriptAlertPanelWithMessage)(WKWebView *, NSString *, WKFrameInfo *, void (^)(void));
+#if PLATFORM(MAC)
+@property (nonatomic, copy) void (^getContextMenuFromProposedMenu)(NSMenu *, _WKContextMenuElementInfo *, id <NSSecureCoding>, void (^)(NSMenu *));
+#endif
- (NSString *)waitForAlert;
Modified: trunk/Tools/TestWebKitAPI/cocoa/TestUIDelegate.mm (264112 => 264113)
--- trunk/Tools/TestWebKitAPI/cocoa/TestUIDelegate.mm 2020-07-08 17:08:22 UTC (rev 264112)
+++ trunk/Tools/TestWebKitAPI/cocoa/TestUIDelegate.mm 2020-07-08 17:43:56 UTC (rev 264113)
@@ -40,6 +40,16 @@
completionHandler();
}
+#if PLATFORM(MAC)
+- (void)_webView:(WKWebView *)webView getContextMenuFromProposedMenu:(NSMenu *)menu forElement:(_WKContextMenuElementInfo *)element userInfo:(id <NSSecureCoding>)userInfo completionHandler:(void (^)(NSMenu *))completionHandler
+{
+ if (_getContextMenuFromProposedMenu)
+ _getContextMenuFromProposedMenu(menu, element, userInfo, completionHandler);
+ else
+ completionHandler(menu);
+}
+#endif // PLATFORM(MAC)
+
- (NSString *)waitForAlert
{
EXPECT_FALSE(self.runJavaScriptAlertPanelWithMessage);
Modified: trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.h (264112 => 264113)
--- trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.h 2020-07-08 17:08:22 UTC (rev 264112)
+++ trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.h 2020-07-08 17:43:56 UTC (rev 264113)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2020 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -121,9 +121,11 @@
@interface TestWKWebView (MacOnly)
// Simulates clicking with a pressure-sensitive device, if possible.
- (void)mouseDownAtPoint:(NSPoint)pointInWindow simulatePressure:(BOOL)simulatePressure;
+- (void)mouseDownAtPoint:(NSPoint)pointInWindow simulatePressure:(BOOL)simulatePressure withFlags:(NSEventModifierFlags)flags eventType:(NSEventType)eventType;
- (void)mouseDragToPoint:(NSPoint)pointInWindow;
- (void)mouseEnterAtPoint:(NSPoint)pointInWindow;
- (void)mouseUpAtPoint:(NSPoint)pointInWindow;
+- (void)mouseUpAtPoint:(NSPoint)pointInWindow withFlags:(NSEventModifierFlags)flags eventType:(NSEventType)eventType;
- (void)mouseMoveToPoint:(NSPoint)pointInWindow withFlags:(NSEventModifierFlags)flags;
- (void)sendClicksAtPoint:(NSPoint)pointInWindow numberOfClicks:(NSUInteger)numberOfClicks;
- (void)sendClickAtPoint:(NSPoint)pointInWindow;
Modified: trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.mm (264112 => 264113)
--- trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.mm 2020-07-08 17:08:22 UTC (rev 264112)
+++ trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.mm 2020-07-08 17:43:56 UTC (rev 264113)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2020 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -290,11 +290,8 @@
return self;
}
-- (void)_mouseDownAtPoint:(NSPoint)point simulatePressure:(BOOL)simulatePressure clickCount:(NSUInteger)clickCount
+- (void)_mouseDownAtPoint:(NSPoint)point simulatePressure:(BOOL)simulatePressure clickCount:(NSUInteger)clickCount modifierFlags:(NSEventModifierFlags)modifierFlags mouseEventType:(NSEventType)mouseEventType
{
- NSEventType mouseEventType = NSEventTypeLeftMouseDown;
-
- NSEventMask modifierFlags = 0;
if (simulatePressure)
modifierFlags |= NSEventMaskPressure;
@@ -316,9 +313,9 @@
}
}
-- (void)_mouseUpAtPoint:(NSPoint)point clickCount:(NSUInteger)clickCount
+- (void)_mouseUpAtPoint:(NSPoint)point clickCount:(NSUInteger)clickCount modifierFlags:(NSEventModifierFlags)modifierFlags eventType:(NSEventType)eventType
{
- [self sendEvent:[NSEvent mouseEventWithType:NSEventTypeLeftMouseUp location:point modifierFlags:0 timestamp:_webView.eventTimestamp windowNumber:self.windowNumber context:[NSGraphicsContext currentContext] eventNumber:++gEventNumber clickCount:clickCount pressure:0]];
+ [self sendEvent:[NSEvent mouseEventWithType:eventType location:point modifierFlags:modifierFlags timestamp:_webView.eventTimestamp windowNumber:self.windowNumber context:[NSGraphicsContext currentContext] eventNumber:++gEventNumber clickCount:clickCount pressure:0]];
}
#endif
@@ -721,14 +718,24 @@
- (void)mouseDownAtPoint:(NSPoint)pointInWindow simulatePressure:(BOOL)simulatePressure
{
- [_hostWindow _mouseDownAtPoint:pointInWindow simulatePressure:simulatePressure clickCount:1];
+ [self mouseDownAtPoint:pointInWindow simulatePressure:simulatePressure withFlags:0 eventType:NSEventTypeLeftMouseDown];
}
+- (void)mouseDownAtPoint:(NSPoint)pointInWindow simulatePressure:(BOOL)simulatePressure withFlags:(NSEventModifierFlags)flags eventType:(NSEventType)eventType
+{
+ [_hostWindow _mouseDownAtPoint:pointInWindow simulatePressure:simulatePressure clickCount:1 modifierFlags:flags mouseEventType:eventType];
+}
+
- (void)mouseUpAtPoint:(NSPoint)pointInWindow
{
- [_hostWindow _mouseUpAtPoint:pointInWindow clickCount:1];
+ [self mouseUpAtPoint:pointInWindow withFlags:0 eventType:NSEventTypeLeftMouseUp];
}
+- (void)mouseUpAtPoint:(NSPoint)pointInWindow withFlags:(NSEventModifierFlags)flags eventType:(NSEventType)eventType
+{
+ [_hostWindow _mouseUpAtPoint:pointInWindow clickCount:1 modifierFlags:flags eventType:eventType];
+}
+
- (void)mouseMoveToPoint:(NSPoint)pointInWindow withFlags:(NSEventModifierFlags)flags
{
[self mouseMoved:[self _mouseEventWithType:NSEventTypeMouseMoved atLocation:pointInWindow flags:flags timestamp:self.eventTimestamp clickCount:0]];
@@ -737,8 +744,8 @@
- (void)sendClicksAtPoint:(NSPoint)pointInWindow numberOfClicks:(NSUInteger)numberOfClicks
{
for (NSUInteger clickCount = 1; clickCount <= numberOfClicks; ++clickCount) {
- [_hostWindow _mouseDownAtPoint:pointInWindow simulatePressure:NO clickCount:clickCount];
- [_hostWindow _mouseUpAtPoint:pointInWindow clickCount:clickCount];
+ [_hostWindow _mouseDownAtPoint:pointInWindow simulatePressure:NO clickCount:clickCount modifierFlags:0 mouseEventType:NSEventTypeLeftMouseDown];
+ [_hostWindow _mouseUpAtPoint:pointInWindow clickCount:clickCount modifierFlags:0 eventType:NSEventTypeLeftMouseUp];
}
}