Diff
Modified: trunk/Source/WebKit2/ChangeLog (120304 => 120305)
--- trunk/Source/WebKit2/ChangeLog 2012-06-14 09:59:20 UTC (rev 120304)
+++ trunk/Source/WebKit2/ChangeLog 2012-06-14 10:10:05 UTC (rev 120305)
@@ -1,3 +1,53 @@
+2012-06-14 Carlos Garcia Campos <[email protected]>
+
+ [GTK] Add input methods submenu item to the default context menu for editable content
+ https://bugs.webkit.org/show_bug.cgi?id=80600
+
+ Reviewed by Martin Robinson.
+
+ * GNUmakefile.am: Add new files to compilation.
+ * UIProcess/API/gtk/WebKitContextMenuClient.cpp: Added.
+ (getContextMenuFromProposedMenu): Call webkitWebViewContextMenu().
+ (attachContextMenuClientToView): Add implementation for
+ getContextMenuFromProposedMenu callback.
+ * UIProcess/API/gtk/WebKitContextMenuClient.h: Added.
+ * UIProcess/API/gtk/WebKitWebView.cpp:
+ (webkitWebViewConstructed): Attach context menu client to view.
+ (webkitWebViewCreateAndAppendDefaultMenuItems): Helper function to
+ add default context menu items to the new context menu items vector.
+ (webkitWebViewShouldShowInputMethodsMenu): Helper function to
+ check whether to show the input methods submenu according to the
+ gtk-show-input-method-menu GTK+ setting.
+ (webkitWebViewCreateAndAppendInputMethodsMenuItem): Helper
+ function to add input methods submenu to the new context menu
+ items vector.
+ (webkitWebViewContextMenu): Create a new context menu items vector
+ containing default items and input methods submenu in case of
+ editable content. The active content menu is populated using that
+ new vector.
+ * UIProcess/API/gtk/WebKitWebViewBase.cpp:
+ (webkitWebViewBaseSetActiveContextMenu): Set the active context menu.
+ (webkitWebViewBaseGetActiveContextMenu): Get the active context menu.
+ * UIProcess/API/gtk/WebKitWebViewBasePrivate.h:
+ * UIProcess/API/gtk/WebKitWebViewPrivate.h:
+ * UIProcess/gtk/WebContextMenuProxyGtk.cpp:
+ (WebKit::WebContextMenuProxyGtk::append): Helper method to add a
+ new item to the context menu.
+ (WebKit::WebContextMenuProxyGtk::populate): Add items to the
+ context menu.
+ (WebKit::WebContextMenuProxyGtk::showContextMenu): Populate the
+ menu with the given items and popup the menu if it's not empty.
+ (WebKit::WebContextMenuProxyGtk::hideContextMenu): Get the GtkMenu
+ from the WebCore ContextMenu to popdown it.
+ (WebKit::WebContextMenuProxyGtk::WebContextMenuProxyGtk): Call
+ webkitWebViewBaseSetActiveContextMenu() to set the menu as the current
+ active one for the view.
+ (WebKit::WebContextMenuProxyGtk::~WebContextMenuProxyGtk): Call
+ webkitWebViewBaseSetActiveContextMenu() with NULL to reset the
+ current active context of the view. GtkMenu is destroyed by
+ WebCore ContextMenu in its destructor.
+ * UIProcess/gtk/WebContextMenuProxyGtk.h:
+
2012-06-14 Christophe Dumez <[email protected]>
[WK2] Add implementation for registerIntentService in WebFrameLoaderClient
Modified: trunk/Source/WebKit2/GNUmakefile.list.am (120304 => 120305)
--- trunk/Source/WebKit2/GNUmakefile.list.am 2012-06-14 09:59:20 UTC (rev 120304)
+++ trunk/Source/WebKit2/GNUmakefile.list.am 2012-06-14 10:10:05 UTC (rev 120305)
@@ -575,6 +575,8 @@
Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardListItem.h \
Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardListItem.cpp \
Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardListPrivate.h \
+ Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuClient.cpp \
+ Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuClient.h \
Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.h \
Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.cpp \
Source/WebKit2/UIProcess/API/gtk/WebKitCookieManagerPrivate.h \
Added: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuClient.cpp (0 => 120305)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuClient.cpp (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuClient.cpp 2012-06-14 10:10:05 UTC (rev 120305)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2012 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "WebKitContextMenuClient.h"
+
+#include "WebKitPrivate.h"
+#include "WebKitWebViewBasePrivate.h"
+#include "WebKitWebViewPrivate.h"
+
+using namespace WebKit;
+
+static void getContextMenuFromProposedMenu(WKPageRef, WKArrayRef proposedMenu, WKArrayRef*, WKHitTestResultRef hitTestResult, WKTypeRef userData, const void* clientInfo)
+{
+ webkitWebViewPopulateContextMenu(WEBKIT_WEB_VIEW(clientInfo), proposedMenu, hitTestResult);
+}
+
+void attachContextMenuClientToView(WebKitWebView* webView)
+{
+ WKPageContextMenuClient wkContextMenuClient = {
+ kWKPageContextMenuClientCurrentVersion,
+ webView, // clientInfo
+ 0, // getContextMenuFromProposedMenu_deprecatedForUseWithV0
+ 0, // customContextMenuItemSelected
+ 0, // contextMenuDismissed
+ getContextMenuFromProposedMenu,
+ };
+ WKPageRef wkPage = toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView)));
+ WKPageSetPageContextMenuClient(wkPage, &wkContextMenuClient);
+}
+
Added: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuClient.h (0 => 120305)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuClient.h (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuClient.h 2012-06-14 10:10:05 UTC (rev 120305)
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2012 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef WebKitContextMenuClient_h
+#define WebKitContextMenuClient_h
+
+#include "WebKitWebView.h"
+
+void attachContextMenuClientToView(WebKitWebView*);
+
+#endif
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp (120304 => 120305)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp 2012-06-14 09:59:20 UTC (rev 120304)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp 2012-06-14 10:10:05 UTC (rev 120305)
@@ -21,7 +21,10 @@
#include "config.h"
#include "WebKitWebView.h"
+#include "WebContextMenuItem.h"
+#include "WebContextMenuItemData.h"
#include "WebKitBackForwardListPrivate.h"
+#include "WebKitContextMenuClient.h"
#include "WebKitEnumTypes.h"
#include "WebKitError.h"
#include "WebKitFullscreenClient.h"
@@ -295,6 +298,7 @@
attachPolicyClientToPage(webView);
attachResourceLoadClientToView(webView);
attachFullScreenClientToView(webView);
+ attachContextMenuClientToView(webView);
WebPageProxy* page = webkitWebViewBaseGetPage(webViewBase);
priv->backForwardList = adoptGRef(webkitBackForwardListCreate(WKPageGetBackForwardList(toAPI(page))));
@@ -1168,6 +1172,54 @@
g_signal_emit(webView, signals[RUN_FILE_CHOOSER], 0, request, &returnValue);
}
+static void webkitWebViewCreateAndAppendDefaultMenuItems(WebKitWebView* webView, WKArrayRef wkProposedMenu, Vector<ContextMenuItem>& contextMenuItems)
+{
+ for (size_t i = 0; i < WKArrayGetSize(wkProposedMenu); ++i) {
+ WKContextMenuItemRef wkItem = static_cast<WKContextMenuItemRef>(WKArrayGetItemAtIndex(wkProposedMenu, i));
+ contextMenuItems.append(toImpl(wkItem)->data()->core());
+ }
+}
+
+static bool webkitWebViewShouldShowInputMethodsMenu(WebKitWebView* webView)
+{
+ GtkSettings* settings = gtk_widget_get_settings(GTK_WIDGET(webView));
+ if (!settings)
+ return true;
+
+ gboolean showInputMethodMenu;
+ g_object_get(settings, "gtk-show-input-method-menu", &showInputMethodMenu, NULL);
+ return showInputMethodMenu;
+}
+
+static void webkitWebViewCreateAndAppendInputMethodsMenuItem(WebKitWebView* webView, Vector<ContextMenuItem>& contextMenuItems)
+{
+ if (!webkitWebViewShouldShowInputMethodsMenu(webView))
+ return;
+
+ GtkIMContext* imContext = webkitWebViewBaseGetIMContext(WEBKIT_WEB_VIEW_BASE(webView));
+ GtkMenu* imContextMenu = GTK_MENU(gtk_menu_new());
+ gtk_im_multicontext_append_menuitems(GTK_IM_MULTICONTEXT(imContext), GTK_MENU_SHELL(imContextMenu));
+ ContextMenu subMenu(imContextMenu);
+
+ ContextMenuItem separator(SeparatorType, ContextMenuItemTagNoAction, String());
+ contextMenuItems.append(separator);
+ ContextMenuItem menuItem(SubmenuType, ContextMenuItemTagNoAction, _("Input _Methods"), &subMenu);
+ contextMenuItems.append(menuItem);
+}
+
+void webkitWebViewPopulateContextMenu(WebKitWebView* webView, WKArrayRef wkProposedMenu, WKHitTestResultRef wkHitTestResult)
+{
+ WebContextMenuProxyGtk* contextMenu = webkitWebViewBaseGetActiveContextMenuProxy(WEBKIT_WEB_VIEW_BASE(webView));
+ ASSERT(contextMenu);
+
+ Vector<ContextMenuItem> contextMenuItems;
+ webkitWebViewCreateAndAppendDefaultMenuItems(webView, wkProposedMenu, contextMenuItems);
+ if (WKHitTestResultIsContentEditable(wkHitTestResult))
+ webkitWebViewCreateAndAppendInputMethodsMenuItem(webView, contextMenuItems);
+
+ contextMenu->populate(contextMenuItems);
+}
+
/**
* webkit_web_view_new:
*
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp (120304 => 120305)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp 2012-06-14 09:59:20 UTC (rev 120304)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp 2012-06-14 10:10:05 UTC (rev 120305)
@@ -94,6 +94,7 @@
#endif
GtkWidget* inspectorView;
unsigned inspectorViewHeight;
+ WebContextMenuProxyGtk* activeContextMenuProxy;
};
G_DEFINE_TYPE(WebKitWebViewBase, webkit_web_view_base, GTK_TYPE_CONTAINER)
@@ -773,3 +774,13 @@
webkitWebViewBase->priv->inspectorViewHeight = height;
gtk_widget_queue_resize_no_redraw(GTK_WIDGET(webkitWebViewBase));
}
+
+void webkitWebViewBaseSetActiveContextMenuProxy(WebKitWebViewBase* webkitWebViewBase, WebContextMenuProxyGtk* contextMenuProxy)
+{
+ webkitWebViewBase->priv->activeContextMenuProxy = contextMenuProxy;
+}
+
+WebContextMenuProxyGtk* webkitWebViewBaseGetActiveContextMenuProxy(WebKitWebViewBase* webkitWebViewBase)
+{
+ return webkitWebViewBase->priv->activeContextMenuProxy;
+}
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h (120304 => 120305)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h 2012-06-14 09:59:20 UTC (rev 120304)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h 2012-06-14 10:10:05 UTC (rev 120305)
@@ -28,6 +28,7 @@
#ifndef WebKitWebViewBasePrivate_h
#define WebKitWebViewBasePrivate_h
+#include "WebContextMenuProxyGtk.h"
#include "WebKitPrivate.h"
#include "WebKitWebViewBase.h"
#include "WebPageProxy.h"
@@ -46,5 +47,7 @@
void webkitWebViewBaseExitFullScreen(WebKitWebViewBase*);
void webkitWebViewBaseInitializeFullScreenClient(WebKitWebViewBase*, const WKFullScreenClientGtk*);
void webkitWebViewBaseSetInspectorViewHeight(WebKitWebViewBase*, unsigned height);
+void webkitWebViewBaseSetActiveContextMenuProxy(WebKitWebViewBase*, WebContextMenuProxyGtk*);
+WebContextMenuProxyGtk* webkitWebViewBaseGetActiveContextMenuProxy(WebKitWebViewBase*);
#endif // WebKitWebViewBasePrivate_h
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h (120304 => 120305)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h 2012-06-14 09:59:20 UTC (rev 120304)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h 2012-06-14 10:10:05 UTC (rev 120305)
@@ -53,5 +53,6 @@
WebKitWebResource* webkitWebViewResourceLoadFinished(WebKitWebView*, uint64_t resourceIdentifier);
bool webkitWebViewEnterFullScreen(WebKitWebView*);
bool webkitWebViewLeaveFullScreen(WebKitWebView*);
+void webkitWebViewPopulateContextMenu(WebKitWebView*, WKArrayRef proposedMenu, WKHitTestResultRef);
#endif // WebKitWebViewPrivate_h
Modified: trunk/Source/WebKit2/UIProcess/gtk/WebContextMenuProxyGtk.cpp (120304 => 120305)
--- trunk/Source/WebKit2/UIProcess/gtk/WebContextMenuProxyGtk.cpp 2012-06-14 09:59:20 UTC (rev 120304)
+++ trunk/Source/WebKit2/UIProcess/gtk/WebContextMenuProxyGtk.cpp 2012-06-14 10:10:05 UTC (rev 120305)
@@ -30,8 +30,8 @@
#include "NativeWebMouseEvent.h"
#include "WebContextMenuItemData.h"
+#include "WebKitWebViewBasePrivate.h"
#include "WebPageProxy.h"
-#include <WebCore/ContextMenu.h>
#include <WebCore/GtkUtilities.h>
#include <gtk/gtk.h>
#include <wtf/text/CString.h>
@@ -53,59 +53,64 @@
page->contextMenuItemSelected(item);
}
-GtkMenu* WebContextMenuProxyGtk::createGtkMenu(const Vector<WebContextMenuItemData>& items)
+void WebContextMenuProxyGtk::append(ContextMenuItem& menuItem)
{
- ContextMenu menu;
- for (size_t i = 0; i < items.size(); i++) {
- const WebContextMenuItemData& item = items.at(i);
- ContextMenuItem menuItem(item.type(), item.action(), item.title(), item.enabled(), item.checked());
- GtkAction* action = ""
+ GtkAction* action = ""
- if (action && (item.type() == WebCore::ActionType || item.type() == WebCore::CheckableActionType)) {
- g_object_set_data(G_OBJECT(action), gContextMenuActionId, GINT_TO_POINTER(item.action()));
- g_signal_connect(action, "activate", G_CALLBACK(contextMenuItemActivatedCallback), m_page);
- }
+ if (action && (menuItem.type() == ActionType || menuItem.type() == CheckableActionType)) {
+ g_object_set_data(G_OBJECT(action), gContextMenuActionId, GINT_TO_POINTER(menuItem.action()));
+ g_signal_connect(action, "activate", G_CALLBACK(contextMenuItemActivatedCallback), m_page);
+ }
- if (item.type() == WebCore::SubmenuType) {
- ContextMenu subMenu(createGtkMenu(item.submenu()));
- menuItem.setSubMenu(&subMenu);
- }
- menu.appendItem(menuItem);
+ m_menu.appendItem(menuItem);
+}
+
+void WebContextMenuProxyGtk::populate(Vector<ContextMenuItem>& items)
+{
+ for (size_t i = 0; i < items.size(); i++)
+ append(items.at(i));
+}
+
+void WebContextMenuProxyGtk::populate(const Vector<WebContextMenuItemData>& items)
+{
+ for (size_t i = 0; i < items.size(); i++) {
+ ContextMenuItem menuitem = items.at(i).core();
+ append(menuitem);
}
- return menu.releasePlatformDescription();
}
void WebContextMenuProxyGtk::showContextMenu(const WebCore::IntPoint& position, const Vector<WebContextMenuItemData>& items)
{
- if (items.isEmpty())
+ if (!items.isEmpty())
+ populate(items);
+
+ if (!m_menu.itemCount())
return;
- m_popup = createGtkMenu(items);
m_popupPosition = convertWidgetPointToScreenPoint(m_webView, position);
// Display menu initiated by right click (mouse button pressed = 3).
NativeWebMouseEvent* mouseEvent = m_page->currentlyProcessedMouseDownEvent();
const GdkEvent* event = mouseEvent ? mouseEvent->nativeEvent() : 0;
- gtk_menu_popup(m_popup, 0, 0, reinterpret_cast<GtkMenuPositionFunc>(menuPositionFunction), this,
+ gtk_menu_popup(m_menu.platformDescription(), 0, 0, reinterpret_cast<GtkMenuPositionFunc>(menuPositionFunction), this,
event ? event->button.button : 3, event ? event->button.time : GDK_CURRENT_TIME);
}
void WebContextMenuProxyGtk::hideContextMenu()
{
- gtk_menu_popdown(m_popup);
+ gtk_menu_popdown(m_menu.platformDescription());
}
WebContextMenuProxyGtk::WebContextMenuProxyGtk(GtkWidget* webView, WebPageProxy* page)
: m_webView(webView)
, m_page(page)
- , m_popup(0)
{
+ webkitWebViewBaseSetActiveContextMenuProxy(WEBKIT_WEB_VIEW_BASE(m_webView), this);
}
WebContextMenuProxyGtk::~WebContextMenuProxyGtk()
{
- if (m_popup)
- gtk_widget_destroy(GTK_WIDGET(m_popup));
+ webkitWebViewBaseSetActiveContextMenuProxy(WEBKIT_WEB_VIEW_BASE(m_webView), 0);
}
void WebContextMenuProxyGtk::menuPositionFunction(GtkMenu* menu, gint* x, gint* y, gboolean* pushIn, WebContextMenuProxyGtk* popupMenu)
Modified: trunk/Source/WebKit2/UIProcess/gtk/WebContextMenuProxyGtk.h (120304 => 120305)
--- trunk/Source/WebKit2/UIProcess/gtk/WebContextMenuProxyGtk.h 2012-06-14 09:59:20 UTC (rev 120304)
+++ trunk/Source/WebKit2/UIProcess/gtk/WebContextMenuProxyGtk.h 2012-06-14 10:10:05 UTC (rev 120305)
@@ -29,6 +29,7 @@
#if ENABLE(CONTEXT_MENUS)
#include "WebContextMenuProxy.h"
+#include <WebCore/ContextMenu.h>
#include <WebCore/IntPoint.h>
namespace WebKit {
@@ -47,15 +48,18 @@
virtual void showContextMenu(const WebCore::IntPoint&, const Vector<WebContextMenuItemData>&);
virtual void hideContextMenu();
+ void populate(Vector<WebCore::ContextMenuItem>&);
+
private:
WebContextMenuProxyGtk(GtkWidget*, WebPageProxy*);
- GtkMenu* createGtkMenu(const Vector<WebContextMenuItemData>&);
+ void append(WebCore::ContextMenuItem&);
+ void populate(const Vector<WebContextMenuItemData>&);
static void menuPositionFunction(GtkMenu*, gint*, gint*, gboolean*, WebContextMenuProxyGtk*);
GtkWidget* m_webView;
WebPageProxy* m_page;
- GtkMenu* m_popup;
+ WebCore::ContextMenu m_menu;
WebCore::IntPoint m_popupPosition;
};