Diff
Modified: trunk/Source/WebKit2/ChangeLog (218324 => 218325)
--- trunk/Source/WebKit2/ChangeLog 2017-06-15 09:19:50 UTC (rev 218324)
+++ trunk/Source/WebKit2/ChangeLog 2017-06-15 09:41:27 UTC (rev 218325)
@@ -1,3 +1,65 @@
+2017-06-15 Carlos Garcia Campos <cgar...@igalia.com>
+
+ [GTK] Add API to allow overriding popup menus
+ https://bugs.webkit.org/show_bug.cgi?id=172905
+
+ Reviewed by Michael Catanzaro.
+
+ The GTK+ API uses GTK+ for the default implementation of several UI elements like the file chooser, print dialog,
+ color picker, context menu, etc. but in all those cases it allows to override the default implementation. It's
+ not possible to override the popup menu used for select elements. This patch adds WebKitOptionMenu to represent
+ a select dropdown menu. It's passed as an argument of the new signal WebKitWebView::show-option-menu, and
+ contains WebKitOptionMenuItem elements representing the items to be displayed.
+
+ * PlatformGTK.cmake:
+ * UIProcess/API/gtk/PageClientImpl.cpp:
+ (WebKit::PageClientImpl::createPopupMenuProxy): Create a WebKitPopupMenu.
+ * UIProcess/API/gtk/WebKitOptionMenu.cpp: Added.
+ (webkitOptionMenuCreate):
+ (webkit_option_menu_get_n_items):
+ (webkit_option_menu_get_item):
+ (webkit_option_menu_select_item):
+ (webkit_option_menu_activate_item):
+ (webkit_option_menu_close):
+ * UIProcess/API/gtk/WebKitOptionMenu.h: Added.
+ * UIProcess/API/gtk/WebKitOptionMenuItem.cpp: Added.
+ (webkit_option_menu_item_copy):
+ (webkit_option_menu_item_free):
+ (webkit_option_menu_item_get_label):
+ (webkit_option_menu_item_get_tooltip):
+ (webkit_option_menu_item_is_group_label):
+ (webkit_option_menu_item_is_group_child):
+ (webkit_option_menu_item_is_enabled):
+ (webkit_option_menu_item_is_selected):
+ * UIProcess/API/gtk/WebKitOptionMenuItem.h: Added.
+ * UIProcess/API/gtk/WebKitOptionMenuItemPrivate.h: Added.
+ (_WebKitOptionMenuItem::_WebKitOptionMenuItem):
+ * UIProcess/API/gtk/WebKitOptionMenuPrivate.h: Added.
+ * UIProcess/API/gtk/WebKitPopupMenu.cpp: Added.
+ (WebKit::WebKitPopupMenu::WebKitPopupMenu):
+ (WebKit::menuCloseCallback):
+ (WebKit::WebKitPopupMenu::showPopupMenu): Call webkitWebViewShowOptionMenu() falling back to default
+ implementation if the user didn't handle the signal.
+ (WebKit::WebKitPopupMenu::hidePopupMenu):
+ (WebKit::WebKitPopupMenu::cancelTracking):
+ (WebKit::WebKitPopupMenu::selectItem):
+ (WebKit::WebKitPopupMenu::activateItem):
+ * UIProcess/API/gtk/WebKitPopupMenu.h: Added.
+ * UIProcess/API/gtk/WebKitWebView.cpp:
+ (webkit_web_view_class_init):
+ (webkitWebViewShowOptionMenu): Emit WebKitWebView::show-option-menu.
+ * UIProcess/API/gtk/WebKitWebView.h:
+ * UIProcess/API/gtk/WebKitWebViewPrivate.h:
+ * UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt: Add new symbols.
+ * UIProcess/API/gtk/docs/webkit2gtk-4.0.types: Add new get_type functions.
+ * UIProcess/API/gtk/docs/webkit2gtk-docs.sgml: Add new sections.
+ * UIProcess/API/gtk/webkit2.h: Add new public headers.
+ * UIProcess/gtk/WebPopupMenuProxyGtk.cpp:
+ (WebKit::WebPopupMenuProxyGtk::WebPopupMenuProxyGtk): Do not create the GtkMenu in constructor.
+ (WebKit::WebPopupMenuProxyGtk::showPopupMenu): Create the GtkMenu and connect to the signals here.
+ (WebKit::WebPopupMenuProxyGtk::hidePopupMenu): Return early if the Gtk hasn't been shown.
+ * UIProcess/gtk/WebPopupMenuProxyGtk.h: Make constructor and webview protected.
+
2017-06-14 Carlos Garcia Campos <cgar...@igalia.com>
[GTK] Use API::InjectedBundle::ResourceLoadClient in WebKitWebPage
Modified: trunk/Source/WebKit2/PlatformGTK.cmake (218324 => 218325)
--- trunk/Source/WebKit2/PlatformGTK.cmake 2017-06-15 09:19:50 UTC (rev 218324)
+++ trunk/Source/WebKit2/PlatformGTK.cmake 2017-06-15 09:41:27 UTC (rev 218325)
@@ -212,6 +212,12 @@
UIProcess/API/gtk/WebKitNotificationPrivate.h
UIProcess/API/gtk/WebKitNotificationProvider.cpp
UIProcess/API/gtk/WebKitNotificationProvider.h
+ UIProcess/API/gtk/WebKitOptionMenu.cpp
+ UIProcess/API/gtk/WebKitOptionMenu.h
+ UIProcess/API/gtk/WebKitOptionMenuPrivate.h
+ UIProcess/API/gtk/WebKitOptionMenuItem.cpp
+ UIProcess/API/gtk/WebKitOptionMenuItem.h
+ UIProcess/API/gtk/WebKitOptionMenuItemPrivate.h
UIProcess/API/gtk/WebKitPermissionRequest.cpp
UIProcess/API/gtk/WebKitPermissionRequest.h
UIProcess/API/gtk/WebKitPlugin.cpp
@@ -222,6 +228,7 @@
UIProcess/API/gtk/WebKitPolicyDecision.cpp
UIProcess/API/gtk/WebKitPolicyDecision.h
UIProcess/API/gtk/WebKitPolicyDecisionPrivate.h
+ UIProcess/API/gtk/WebKitPopupMenu.cpp
UIProcess/API/gtk/WebKitPrintCustomWidget.cpp
UIProcess/API/gtk/WebKitPrintCustomWidget.h
UIProcess/API/gtk/WebKitPrintCustomWidgetPrivate.h
@@ -560,6 +567,8 @@
${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitNetworkProxySettings.h
${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitNotificationPermissionRequest.h
${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitNotification.h
+ ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitOptionMenu.h
+ ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitOptionMenuItem.h
${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitPermissionRequest.h
${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitPlugin.h
${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitPolicyDecision.h
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp (218324 => 218325)
--- trunk/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp 2017-06-15 09:19:50 UTC (rev 218324)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp 2017-06-15 09:41:27 UTC (rev 218325)
@@ -37,10 +37,10 @@
#include "WebContextMenuProxyGtk.h"
#include "WebEventFactory.h"
#include "WebKitColorChooser.h"
+#include "WebKitPopupMenu.h"
#include "WebKitWebViewBasePrivate.h"
#include "WebKitWebViewPrivate.h"
#include "WebPageProxy.h"
-#include "WebPopupMenuProxyGtk.h"
#include "WebProcessPool.h"
#include <WebCore/CairoUtilities.h>
#include <WebCore/Cursor.h>
@@ -206,7 +206,7 @@
RefPtr<WebPopupMenuProxy> PageClientImpl::createPopupMenuProxy(WebPageProxy& page)
{
- return WebPopupMenuProxyGtk::create(m_viewWidget, page);
+ return WebKitPopupMenu::create(m_viewWidget, page);
}
RefPtr<WebContextMenuProxy> PageClientImpl::createContextMenuProxy(WebPageProxy& page, const ContextMenuContextData& context, const UserData& userData)
Added: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitOptionMenu.cpp (0 => 218325)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitOptionMenu.cpp (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitOptionMenu.cpp 2017-06-15 09:41:27 UTC (rev 218325)
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2017 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 "WebKitOptionMenu.h"
+
+#include "WebKitOptionMenuItemPrivate.h"
+#include "WebKitOptionMenuPrivate.h"
+#include "WebKitPrivate.h"
+
+using namespace WebKit;
+
+/**
+ * SECTION: WebKitOptionMenu
+ * @Short_description:
+ * @Title: WebKitOptionMenu
+ *
+ * WebKitOptionMenu represents the dropdown menu of a select element in a #WebKitWebView.
+ *
+ * When a select element in a #WebKitWebView needs to display a dropdown menu, the signal
+ * #WebKitWebView::show-option-menu is emitted, providing a WebKitOptionMenu with the
+ * #WebKitOptionMenuItem<!-- -->s that should be displayed.
+ *
+ * Since: 2.18
+ */
+
+struct _WebKitOptionMenuPrivate {
+ Vector<WebKitOptionMenuItem> items;
+ RefPtr<WebKitPopupMenu> popupMenu;
+};
+
+enum {
+ CLOSE,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0, };
+
+WEBKIT_DEFINE_TYPE(WebKitOptionMenu, webkit_option_menu, G_TYPE_OBJECT)
+
+static void webkit_option_menu_class_init(WebKitOptionMenuClass* optionMenuClass)
+{
+ /**
+ * WebKitOptionMenu::close:
+ * @menu: the #WebKitOptionMenu on which the signal is emitted
+ *
+ * Emitted when closing a #WebKitOptionMenu is requested. This can happen
+ * when the user explicitly calls webkit_option_menu_close() or when the
+ * element is detached from the current page.
+ *
+ * Since: 2.18
+ */
+ signals[CLOSE] =
+ g_signal_new("close",
+ G_TYPE_FROM_CLASS(optionMenuClass),
+ G_SIGNAL_RUN_LAST,
+ 0, nullptr, nullptr,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+WebKitOptionMenu* webkitOptionMenuCreate(WebKitPopupMenu& popupMenu, const Vector<WebPopupItem>& items, int32_t selectedIndex)
+{
+ auto* menu = WEBKIT_OPTION_MENU(g_object_new(WEBKIT_TYPE_OPTION_MENU, nullptr));
+ menu->priv->popupMenu = &popupMenu;
+ menu->priv->items.reserveInitialCapacity(items.size());
+ for (const auto& item : items)
+ menu->priv->items.uncheckedAppend(WebKitOptionMenuItem(item));
+ if (selectedIndex >= 0) {
+ ASSERT(static_cast<unsigned>(selectedIndex) < menu->priv->items.size());
+ menu->priv->items[selectedIndex].isSelected = true;
+ }
+ return menu;
+}
+
+/**
+ * webkit_option_menu_get_n_items:
+ * @menu: a #WebKitOptionMenu
+ *
+ * Gets the length of the @menu.
+ *
+ * Returns: the number of #WebKitOptionMenuItem<!-- -->s in @menu
+ *
+ * Since: 2.18
+ */
+guint webkit_option_menu_get_n_items(WebKitOptionMenu* menu)
+{
+ g_return_val_if_fail(WEBKIT_IS_OPTION_MENU(menu), 0);
+
+ return menu->priv->items.size();
+}
+
+/**
+ * webkit_option_menu_get_item:
+ * @menu: a #WebKitOptionMenu
+ * @index: the index of the item
+ *
+ * Returns the #WebKitOptionMenuItem at @index in @menu.
+ *
+ * Returns: (transfer none): a #WebKitOptionMenuItem of @menu.
+ *
+ * Since: 2.18
+ */
+WebKitOptionMenuItem* webkit_option_menu_get_item(WebKitOptionMenu* menu, guint index)
+{
+ g_return_val_if_fail(WEBKIT_IS_OPTION_MENU(menu), nullptr);
+ g_return_val_if_fail(index < menu->priv->items.size(), nullptr);
+
+ return &menu->priv->items[index];
+}
+
+/**
+ * webkit_option_menu_select_item:
+ * @menu: a #WebKitOptionMenu
+ * @index: the index of the item
+ *
+ * Selects the #WebKitOptionMenuItem at @index in @menu. Selecting an item changes the
+ * text shown by the combo button, but it doesn't change the value of the element. You need to
+ * explicitly activate the item with webkit_option_menu_select_item() or close the menu with
+ * webkit_option_menu_close() in which case the currently selected item will be activated.
+ *
+ * Since: 2.18
+ */
+void webkit_option_menu_select_item(WebKitOptionMenu* menu, guint index)
+{
+ g_return_if_fail(WEBKIT_IS_OPTION_MENU(menu));
+ g_return_if_fail(index < menu->priv->items.size());
+
+ menu->priv->popupMenu->selectItem(index);
+}
+
+/**
+ * webkit_option_menu_activate_item:
+ * @menu: a #WebKitOptionMenu
+ * @index: the index of the item
+ *
+ * Activates the #WebKitOptionMenuItem at @index in @menu. Activating an item changes the value
+ * of the element making the item the active one. You are expected to close the menu with
+ * webkit_option_menu_close() after activating an item, calling this function again will have no
+ * effect.
+ *
+ * Since: 2.18
+ */
+void webkit_option_menu_activate_item(WebKitOptionMenu* menu, guint index)
+{
+ g_return_if_fail(WEBKIT_IS_OPTION_MENU(menu));
+ g_return_if_fail(index < menu->priv->items.size());
+
+ menu->priv->popupMenu->activateItem(index);
+}
+
+/**
+ * webkit_option_menu_close:
+ * @menu: a #WebKitOptionMenu
+ *
+ * Request to close a #WebKitOptionMenu. This emits WebKitOptionMenu::close signal.
+ * This function should always be called to notify WebKit that the associated
+ * menu has been closed. If the menu is closed and neither webkit_option_menu_select_item()
+ * nor webkit_option_menu_activate_item() have been called, the element value remains
+ * unchanged.
+ *
+ * Since: 2.18
+ */
+void webkit_option_menu_close(WebKitOptionMenu* menu)
+{
+ g_return_if_fail(WEBKIT_IS_OPTION_MENU(menu));
+
+ g_signal_emit(menu, signals[CLOSE], 0, nullptr);
+}
Added: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitOptionMenu.h (0 => 218325)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitOptionMenu.h (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitOptionMenu.h 2017-06-15 09:41:27 UTC (rev 218325)
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) && !defined(__WEBKIT_WEB_EXTENSION_H_INSIDE__)
+#error "Only <webkit2/webkit2.h> can be included directly."
+#endif
+
+#ifndef WebKitOptionMenu_h
+#define WebKitOptionMenu_h
+
+#include <glib-object.h>
+#include <webkit2/WebKitDefines.h>
+#include <webkit2/WebKitOptionMenuItem.h>
+
+G_BEGIN_DECLS
+
+#define WEBKIT_TYPE_OPTION_MENU (webkit_option_menu_get_type())
+#define WEBKIT_OPTION_MENU(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_OPTION_MENU, WebKitOptionMenu))
+#define WEBKIT_IS_OPTION_MENU(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_OPTION_MENU))
+#define WEBKIT_OPTION_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_OPTION_MENU, WebKitOptionMenuClass))
+#define WEBKIT_IS_OPTION_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_OPTION_MENU))
+#define WEBKIT_OPTION_MENU_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_OPTION_MENU, WebKitOptionMenuClass))
+
+typedef struct _WebKitOptionMenu WebKitOptionMenu;
+typedef struct _WebKitOptionMenuClass WebKitOptionMenuClass;
+typedef struct _WebKitOptionMenuPrivate WebKitOptionMenuPrivate;
+
+struct _WebKitOptionMenu {
+ GObject parent;
+
+ WebKitOptionMenuPrivate *priv;
+};
+
+struct _WebKitOptionMenuClass {
+ GObjectClass parent_class;
+
+ void (*_webkit_reserved0) (void);
+ void (*_webkit_reserved1) (void);
+ void (*_webkit_reserved2) (void);
+ void (*_webkit_reserved3) (void);
+};
+
+WEBKIT_API GType
+webkit_option_menu_get_type (void);
+
+WEBKIT_API guint
+webkit_option_menu_get_n_items (WebKitOptionMenu *menu);
+
+WEBKIT_API WebKitOptionMenuItem *
+webkit_option_menu_get_item (WebKitOptionMenu *menu,
+ guint index);
+
+WEBKIT_API void
+webkit_option_menu_select_item (WebKitOptionMenu *menu,
+ guint index);
+
+WEBKIT_API void
+webkit_option_menu_activate_item (WebKitOptionMenu *menu,
+ guint index);
+
+WEBKIT_API void
+webkit_option_menu_close (WebKitOptionMenu *menu);
+
+G_END_DECLS
+
+#endif
Added: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitOptionMenuItem.cpp (0 => 218325)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitOptionMenuItem.cpp (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitOptionMenuItem.cpp 2017-06-15 09:41:27 UTC (rev 218325)
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2017 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 "WebKitOptionMenuItem.h"
+
+#include "WebKitOptionMenuItemPrivate.h"
+
+using namespace WebKit;
+
+/**
+ * SECTION: WebKitOptionMenuItem
+ * @Short_description: One item of the #WebKitOptionMenu
+ * @Title: WebKitOptionMenuItem
+ *
+ * The #WebKitOptionMenu is composed of WebKitOptionMenuItem<!-- -->s.
+ * A WebKitOptionMenuItem always has a label and can contain a tooltip text.
+ * You can use the WebKitOptionMenuItem of a #WebKitOptionMenu to build your
+ * own menus.
+ *
+ * Since: 2.18
+ */
+
+G_DEFINE_BOXED_TYPE(WebKitOptionMenuItem, webkit_option_menu_item, webkit_option_menu_item_copy, webkit_option_menu_item_free)
+
+/**
+ * webkit_option_menu_item_copy:
+ * @item: a #WebKitOptionMenuItem
+ *
+ * Make a copy of the #WebKitOptionMenuItem.
+ *
+ * Returns: (transfer full): A copy of passed in #WebKitOptionMenuItem
+ *
+ * Since: 2.18
+ */
+WebKitOptionMenuItem* webkit_option_menu_item_copy(WebKitOptionMenuItem* item)
+{
+ g_return_val_if_fail(item, nullptr);
+
+ auto* copyItem = static_cast<WebKitOptionMenuItem*>(fastMalloc(sizeof(WebKitOptionMenuItem)));
+ new (copyItem) WebKitOptionMenuItem(item);
+ return copyItem;
+}
+
+/**
+ * webkit_option_menu_item_free:
+ * @item: A #WebKitOptionMenuItem
+ *
+ * Free the #WebKitOptionMenuItem.
+ *
+ * Since: 2.18
+ */
+void webkit_option_menu_item_free(WebKitOptionMenuItem* item)
+{
+ g_return_if_fail(item);
+
+ item->~WebKitOptionMenuItem();
+ fastFree(item);
+}
+
+/**
+ * webkit_option_menu_item_get_label:
+ * @item: a #WebKitOptionMenuItem
+ *
+ * Get the label of a #WebKitOptionMenuItem.
+ *
+ * Returns: The label of @item.
+ *
+ * Since: 2.18
+ */
+const gchar* webkit_option_menu_item_get_label(WebKitOptionMenuItem* item)
+{
+ g_return_val_if_fail(item, nullptr);
+
+ return item->label.data();
+}
+
+/**
+ * webkit_option_menu_item_get_tooltip:
+ * @item: a #WebKitOptionMenuItem
+ *
+ * Get the tooltip of a #WebKitOptionMenuItem.
+ *
+ * Returns: The tooltip of @item, or %NULL.
+ *
+ * Since: 2.18
+ */
+const gchar* webkit_option_menu_item_get_tooltip(WebKitOptionMenuItem* item)
+{
+ g_return_val_if_fail(item, nullptr);
+
+ return item->tooltip.isNull() ? nullptr : item->tooltip.data();
+}
+
+/**
+ * webkit_option_menu_item_is_group_label:
+ * @item: a #WebKitOptionMenuItem
+ *
+ * Whether a #WebKitOptionMenuItem is a group label.
+ *
+ * Returns: %TRUE if the @item is a group label or %FALSE otherwise.
+ *
+ * Since: 2.18
+ */
+gboolean webkit_option_menu_item_is_group_label(WebKitOptionMenuItem* item)
+{
+ g_return_val_if_fail(item, FALSE);
+
+ return item->isGroupLabel;
+}
+
+/**
+ * webkit_option_menu_item_is_group_child:
+ * @item: a #WebKitOptionMenuItem
+ *
+ * Whether a #WebKitOptionMenuItem is a group child.
+ *
+ * Returns: %TRUE if the @item is a group child or %FALSE otherwise.
+ *
+ * Since: 2.18
+ */
+gboolean webkit_option_menu_item_is_group_child(WebKitOptionMenuItem* item)
+{
+ g_return_val_if_fail(item, FALSE);
+
+ return item->isGroupChild;
+}
+
+/**
+ * webkit_option_menu_item_is_enabled:
+ * @item: a #WebKitOptionMenuItem
+ *
+ * Whether a #WebKitOptionMenuItem is enabled.
+ *
+ * Returns: %TRUE if the @item is enabled or %FALSE otherwise.
+ *
+ * Since: 2.18
+ */
+gboolean webkit_option_menu_item_is_enabled(WebKitOptionMenuItem* item)
+{
+ g_return_val_if_fail(item, FALSE);
+
+ return item->isEnabled;
+}
+
+/**
+ * webkit_option_menu_item_is_selected:
+ * @item: a #WebKitOptionMenuItem
+ *
+ * Whether a #WebKitOptionMenuItem is the currently selected one.
+ *
+ * Returns: %TRUE if the @item is selected or %FALSE otherwise.
+ *
+ * Since: 2.18
+ */
+gboolean webkit_option_menu_item_is_selected(WebKitOptionMenuItem* item)
+{
+ g_return_val_if_fail(item, FALSE);
+
+ return item->isSelected;
+}
Added: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitOptionMenuItem.h (0 => 218325)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitOptionMenuItem.h (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitOptionMenuItem.h 2017-06-15 09:41:27 UTC (rev 218325)
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION)
+#error "Only <webkit2/webkit2.h> can be included directly."
+#endif
+
+#ifndef WebKitOptionMenuItem_h
+#define WebKitOptionMenuItem_h
+
+#include <glib-object.h>
+#include <webkit2/WebKitDefines.h>
+
+G_BEGIN_DECLS
+
+#define WEBKIT_TYPE_OPTION_MENU_ITEM (webkit_option_menu_item_get_type())
+
+typedef struct _WebKitOptionMenuItem WebKitOptionMenuItem;
+
+WEBKIT_API GType
+webkit_option_menu_item_get_type (void);
+
+WEBKIT_API WebKitOptionMenuItem *
+webkit_option_menu_item_copy (WebKitOptionMenuItem *item);
+
+WEBKIT_API void
+webkit_option_menu_item_free (WebKitOptionMenuItem *item);
+
+WEBKIT_API const gchar *
+webkit_option_menu_item_get_label (WebKitOptionMenuItem *item);
+
+WEBKIT_API const gchar *
+webkit_option_menu_item_get_tooltip (WebKitOptionMenuItem *item);
+
+WEBKIT_API gboolean
+webkit_option_menu_item_is_group_label (WebKitOptionMenuItem *item);
+
+WEBKIT_API gboolean
+webkit_option_menu_item_is_group_child (WebKitOptionMenuItem *item);
+
+WEBKIT_API gboolean
+webkit_option_menu_item_is_enabled (WebKitOptionMenuItem *item);
+
+WEBKIT_API gboolean
+webkit_option_menu_item_is_selected (WebKitOptionMenuItem *item);
+
+G_END_DECLS
+
+#endif
Added: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitOptionMenuItemPrivate.h (0 => 218325)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitOptionMenuItemPrivate.h (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitOptionMenuItemPrivate.h 2017-06-15 09:41:27 UTC (rev 218325)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#pragma once
+
+#include "WebKitOptionMenuItem.h"
+#include "WebPopupItem.h"
+#include <wtf/text/CString.h>
+
+struct _WebKitOptionMenuItem {
+ _WebKitOptionMenuItem() = default;
+
+ _WebKitOptionMenuItem(const WebKit::WebPopupItem& item)
+ : label(item.m_text.stripWhiteSpace().utf8())
+ , isGroupLabel(item.m_isLabel)
+ , isGroupChild(item.m_text.startsWith(" "))
+ , isEnabled(item.m_isEnabled)
+ {
+ if (!item.m_toolTip.isEmpty())
+ tooltip = item.m_toolTip.utf8();
+ }
+
+ explicit _WebKitOptionMenuItem(_WebKitOptionMenuItem* other)
+ : label(other->label)
+ , tooltip(other->tooltip)
+ , isGroupLabel(other->isGroupLabel)
+ , isGroupChild(other->isGroupChild)
+ , isEnabled(other->isEnabled)
+ , isSelected(other->isSelected)
+ {
+ }
+
+ CString label;
+ CString tooltip;
+ bool isGroupLabel { false };
+ bool isGroupChild { false };
+ bool isEnabled { true };
+ bool isSelected { false };
+};
Added: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitOptionMenuPrivate.h (0 => 218325)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitOptionMenuPrivate.h (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitOptionMenuPrivate.h 2017-06-15 09:41:27 UTC (rev 218325)
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#pragma once
+
+#include "WebKitOptionMenu.h"
+#include "WebKitPopupMenu.h"
+
+WebKitOptionMenu* webkitOptionMenuCreate(WebKit::WebKitPopupMenu&, const Vector<WebKit::WebPopupItem>&, int32_t selectedIndex);
Added: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitPopupMenu.cpp (0 => 218325)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitPopupMenu.cpp (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitPopupMenu.cpp 2017-06-15 09:41:27 UTC (rev 218325)
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2017 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 "WebKitPopupMenu.h"
+
+#include "NativeWebMouseEvent.h"
+#include "WebKitOptionMenuPrivate.h"
+#include "WebKitWebViewPrivate.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+WebKitPopupMenu::WebKitPopupMenu(GtkWidget* webView, WebPopupMenuProxy::Client& client)
+ : WebPopupMenuProxyGtk(webView, client)
+{
+}
+
+static void menuCloseCallback(WebKitPopupMenu* popupMenu)
+{
+ popupMenu->activateItem(-1);
+}
+
+void WebKitPopupMenu::showPopupMenu(const IntRect& rect, TextDirection direction, double pageScaleFactor, const Vector<WebPopupItem>& items, const PlatformPopupMenuData& platformData, int32_t selectedIndex)
+{
+ GRefPtr<WebKitOptionMenu> menu = adoptGRef(webkitOptionMenuCreate(*this, items, selectedIndex));
+ const GdkEvent* event = m_client->currentlyProcessedMouseDownEvent() ? m_client->currentlyProcessedMouseDownEvent()->nativeEvent() : nullptr;
+ if (webkitWebViewShowOptionMenu(WEBKIT_WEB_VIEW(m_webView), rect, menu.get(), event)) {
+ m_menu = WTFMove(menu);
+ g_signal_connect_swapped(m_menu.get(), "close", G_CALLBACK(menuCloseCallback), this);
+ } else
+ WebPopupMenuProxyGtk::showPopupMenu(rect, direction, pageScaleFactor, items, platformData, selectedIndex);
+}
+
+void WebKitPopupMenu::hidePopupMenu()
+{
+ if (!m_menu) {
+ WebPopupMenuProxyGtk::hidePopupMenu();
+ return;
+ }
+ g_signal_handlers_disconnect_matched(m_menu.get(), G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, this);
+ webkit_option_menu_close(m_menu.get());
+}
+
+void WebKitPopupMenu::cancelTracking()
+{
+ if (!m_menu) {
+ WebPopupMenuProxyGtk::cancelTracking();
+ return;
+ }
+ hidePopupMenu();
+ m_menu = nullptr;
+}
+
+void WebKitPopupMenu::selectItem(unsigned itemIndex)
+{
+ if (!m_menu)
+ return;
+ m_client->setTextFromItemForPopupMenu(this, itemIndex);
+ m_selectedItem = itemIndex;
+}
+
+void WebKitPopupMenu::activateItem(int32_t itemIndex)
+{
+ if (!m_menu)
+ return;
+ m_client->valueChangedForPopupMenu(this, itemIndex == -1 ? m_selectedItem.value_or(-1) : itemIndex);
+ g_signal_handlers_disconnect_matched(m_menu.get(), G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, this);
+ m_menu = nullptr;
+}
+
+} // namespace WebKit
Added: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitPopupMenu.h (0 => 218325)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitPopupMenu.h (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitPopupMenu.h 2017-06-15 09:41:27 UTC (rev 218325)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#pragma once
+
+#include "WebPopupMenuProxyGtk.h"
+#include <wtf/glib/GRefPtr.h>
+
+typedef struct _WebKitOptionMenu WebKitOptionMenu;
+
+namespace WebKit {
+
+class WebKitPopupMenu final : public WebPopupMenuProxyGtk {
+public:
+ static Ref<WebKitPopupMenu> create(GtkWidget* webView, WebPopupMenuProxy::Client& client)
+ {
+ return adoptRef(*new WebKitPopupMenu(webView, client));
+ }
+ ~WebKitPopupMenu() = default;
+
+ void selectItem(unsigned);
+ void activateItem(int32_t);
+
+private:
+ WebKitPopupMenu(GtkWidget*, WebPopupMenuProxy::Client&);
+
+ void showPopupMenu(const WebCore::IntRect&, WebCore::TextDirection, double pageScaleFactor, const Vector<WebPopupItem>&, const PlatformPopupMenuData&, int32_t selectedIndex) override;
+ void hidePopupMenu() override;
+ void cancelTracking() override;
+
+ GRefPtr<WebKitOptionMenu> m_menu;
+ std::optional<unsigned> m_selectedItem;
+};
+
+} // namespace WebKit
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp (218324 => 218325)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp 2017-06-15 09:19:50 UTC (rev 218324)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp 2017-06-15 09:41:27 UTC (rev 218325)
@@ -137,6 +137,8 @@
RUN_COLOR_CHOOSER,
+ SHOW_OPTION_MENU,
+
LAST_SIGNAL
};
@@ -1883,6 +1885,40 @@
g_cclosure_marshal_generic,
G_TYPE_BOOLEAN, 1,
WEBKIT_TYPE_COLOR_CHOOSER_REQUEST);
+
+ /**
+ * WebKitWebView::show-option-menu:
+ * @web_view: the #WebKitWebView on which the signal is emitted
+ * @menu: the #WebKitOptionMenu
+ * @event: the #GdkEvent that triggered the menu, or %NULL
+ * @rectangle: the option element area
+ *
+ * This signal is emitted when a select element in @web_view needs to display a
+ * dropdown menu. This signal can be used to show a custom menu, using @menu to get
+ * the details of all items that should be displayed. The area of the element in the
+ * #WebKitWebView is given as @rectangle parameter, it can be used to position the
+ * menu. If this was triggered by a user interaction, like a mouse click,
+ * @event parameter provides the #GdkEvent.
+ * To handle this signal asynchronously you should keep a ref of the @menu.
+ *
+ * The default signal handler will pop up a #GtkMenu.
+ *
+ * Returns: %TRUE to stop other handlers from being invoked for the event.
+ * %FALSE to propagate the event further.
+ *
+ * Since: 2.18.
+ */
+ signals[SHOW_OPTION_MENU] = g_signal_new(
+ "show-option-menu",
+ G_TYPE_FROM_CLASS(webViewClass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(WebKitWebViewClass, show_option_menu),
+ g_signal_accumulator_true_handled, nullptr,
+ g_cclosure_marshal_generic,
+ G_TYPE_BOOLEAN, 3,
+ WEBKIT_TYPE_OPTION_MENU,
+ GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE,
+ GDK_TYPE_RECTANGLE | G_SIGNAL_TYPE_STATIC_SCOPE);
}
static void webkitWebViewCancelAuthenticationRequest(WebKitWebView* webView)
@@ -2212,6 +2248,14 @@
return webView->priv->websiteDataManager.get();
}
+bool webkitWebViewShowOptionMenu(WebKitWebView* webView, const IntRect& rect, WebKitOptionMenu* menu, const GdkEvent* event)
+{
+ GdkRectangle menuRect = rect;
+ gboolean handled;
+ g_signal_emit(webView, signals[SHOW_OPTION_MENU], 0, menu, event, &menuRect, &handled);
+ return handled;
+}
+
/**
* webkit_web_view_new:
*
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h (218324 => 218325)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h 2017-06-15 09:19:50 UTC (rev 218324)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h 2017-06-15 09:41:27 UTC (rev 218325)
@@ -42,6 +42,7 @@
#include <webkit2/WebKitJavascriptResult.h>
#include <webkit2/WebKitNavigationAction.h>
#include <webkit2/WebKitNotification.h>
+#include <webkit2/WebKitOptionMenu.h>
#include <webkit2/WebKitPermissionRequest.h>
#include <webkit2/WebKitPolicyDecision.h>
#include <webkit2/WebKitScriptDialog.h>
@@ -249,11 +250,13 @@
WebKitNotification *notification);
gboolean (* run_color_chooser) (WebKitWebView *web_view,
WebKitColorChooserRequest *request);
+ gboolean (* show_option_menu) (WebKitWebView *web_view,
+ GdkRectangle *rectangle,
+ WebKitOptionMenu *menu);
void (*_webkit_reserved0) (void);
void (*_webkit_reserved1) (void);
void (*_webkit_reserved2) (void);
- void (*_webkit_reserved3) (void);
};
WEBKIT_API GType
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h (218324 => 218325)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h 2017-06-15 09:19:50 UTC (rev 218324)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h 2017-06-15 09:41:27 UTC (rev 218325)
@@ -34,6 +34,7 @@
#include "WebKitPrivate.h"
#include "WebKitWebView.h"
#include "WebPageProxy.h"
+#include <WebCore/IntRect.h>
#include <wtf/text/CString.h>
void webkitWebViewCreatePage(WebKitWebView*, Ref<API::PageConfiguration>&&);
@@ -72,3 +73,4 @@
void webkitWebViewSelectionDidChange(WebKitWebView*);
void webkitWebViewRequestInstallMissingMediaPlugins(WebKitWebView*, WebKit::InstallMissingMediaPluginsPermissionRequest&);
WebKitWebsiteDataManager* webkitWebViewGetWebsiteDataManager(WebKitWebView*);
+bool webkitWebViewShowOptionMenu(WebKitWebView*, const WebCore::IntRect&, WebKitOptionMenu*, const GdkEvent*);
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt (218324 => 218325)
--- trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt 2017-06-15 09:19:50 UTC (rev 218324)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt 2017-06-15 09:41:27 UTC (rev 218325)
@@ -1176,6 +1176,48 @@
</SECTION>
<SECTION>
+<FILE>WebKitOptionMenu</FILE>
+WebKitOptionMenu
+webkit_option_menu_get_n_items
+webkit_option_menu_get_item
+webkit_option_menu_select_item
+webkit_option_menu_activate_item
+webkit_option_menu_close
+
+<SUBSECTION Standard>
+WebKitOptionMenuClass
+WEBKIT_TYPE_OPTION_MENU
+WEBKIT_OPTION_MENU
+WEBKIT_IS_OPTION_MENU
+WEBKIT_OPTION_MENU_CLASS
+WEBKIT_IS_OPTION_MENU_CLASS
+WEBKIT_OPTION_MENU_GET_CLASS
+
+<SUBSECTION Private>
+WebKitOptionMenuPrivate
+webkit_option_menu_get_type
+</SECTION>
+
+<SECTION>
+<FILE>WebKitOptionMenuItem</FILE>
+WebKitOptionMenuItem
+webkit_option_menu_item_copy
+webkit_option_menu_item_free
+webkit_option_menu_item_get_label
+webkit_option_menu_item_get_tooltip
+webkit_option_menu_item_is_group_label
+webkit_option_menu_item_is_group_child
+webkit_option_menu_item_is_enabled
+webkit_option_menu_item_is_selected
+
+<SUBSECTION Standard>
+WEBKIT_TYPE_OPTION_MENU_ITEM
+
+<SUBSECTION Private>
+webkit_option_menu_item_get_type
+</SECTION>
+
+<SECTION>
<FILE>WebKitFormSubmissionRequest</FILE>
WebKitFormSubmissionRequest
webkit_form_submission_request_get_text_fields
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-4.0.types (218324 => 218325)
--- trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-4.0.types 2017-06-15 09:19:50 UTC (rev 218324)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-4.0.types 2017-06-15 09:41:27 UTC (rev 218325)
@@ -36,3 +36,5 @@
webkit_web_view_session_state_get_type
webkit_print_custom_widget_get_type
webkit_automation_session_get_type
+webkit_option_menu_get_type
+webkit_option_menu_item_get_type
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml (218324 => 218325)
--- trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml 2017-06-15 09:19:50 UTC (rev 218324)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml 2017-06-15 09:41:27 UTC (rev 218325)
@@ -46,6 +46,8 @@
<xi:include href=""
<xi:include href=""
<xi:include href=""
+ <xi:include href=""
+ <xi:include href=""
<xi:include href=""
<xi:include href=""
<xi:include href=""
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/webkit2.h (218324 => 218325)
--- trunk/Source/WebKit2/UIProcess/API/gtk/webkit2.h 2017-06-15 09:19:50 UTC (rev 218324)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/webkit2.h 2017-06-15 09:41:27 UTC (rev 218325)
@@ -57,6 +57,8 @@
#include <webkit2/WebKitNetworkProxySettings.h>
#include <webkit2/WebKitNotification.h>
#include <webkit2/WebKitNotificationPermissionRequest.h>
+#include <webkit2/WebKitOptionMenu.h>
+#include <webkit2/WebKitOptionMenuItem.h>
#include <webkit2/WebKitPermissionRequest.h>
#include <webkit2/WebKitPlugin.h>
#include <webkit2/WebKitPrintCustomWidget.h>
Modified: trunk/Source/WebKit2/UIProcess/gtk/WebPopupMenuProxyGtk.cpp (218324 => 218325)
--- trunk/Source/WebKit2/UIProcess/gtk/WebPopupMenuProxyGtk.cpp 2017-06-15 09:19:50 UTC (rev 218324)
+++ trunk/Source/WebKit2/UIProcess/gtk/WebPopupMenuProxyGtk.cpp 2017-06-15 09:41:27 UTC (rev 218325)
@@ -41,11 +41,8 @@
WebPopupMenuProxyGtk::WebPopupMenuProxyGtk(GtkWidget* webView, WebPopupMenuProxy::Client& client)
: WebPopupMenuProxy(client)
, m_webView(webView)
- , m_popup(gtk_menu_new())
, m_dismissMenuTimer(RunLoop::main(), this, &WebPopupMenuProxyGtk::dismissMenuTimerFired)
{
- g_signal_connect(m_popup, "key-press-event", G_CALLBACK(keyPressEventCallback), this);
- g_signal_connect(m_popup, "unmap", G_CALLBACK(menuUnmappedCallback), this);
}
WebPopupMenuProxyGtk::~WebPopupMenuProxyGtk()
@@ -88,7 +85,10 @@
void WebPopupMenuProxyGtk::showPopupMenu(const IntRect& rect, TextDirection, double /* pageScaleFactor */, const Vector<WebPopupItem>& items, const PlatformPopupMenuData&, int32_t selectedIndex)
{
- m_dismissMenuTimer.stop();
+ ASSERT(!m_popup);
+ m_popup = gtk_menu_new();
+ g_signal_connect(m_popup, "key-press-event", G_CALLBACK(keyPressEventCallback), this);
+ g_signal_connect(m_popup, "unmap", G_CALLBACK(menuUnmappedCallback), this);
populatePopupMenu(items);
gtk_menu_set_active(GTK_MENU(m_popup), selectedIndex);
@@ -178,6 +178,9 @@
void WebPopupMenuProxyGtk::hidePopupMenu()
{
+ if (!m_popup)
+ return;
+
gtk_menu_popdown(GTK_MENU(m_popup));
resetTypeAheadFindState();
}
Modified: trunk/Source/WebKit2/UIProcess/gtk/WebPopupMenuProxyGtk.h (218324 => 218325)
--- trunk/Source/WebKit2/UIProcess/gtk/WebPopupMenuProxyGtk.h 2017-06-15 09:19:50 UTC (rev 218324)
+++ trunk/Source/WebKit2/UIProcess/gtk/WebPopupMenuProxyGtk.h 2017-06-15 09:41:27 UTC (rev 218325)
@@ -48,9 +48,12 @@
void hidePopupMenu() override;
void cancelTracking() override;
-private:
+protected:
WebPopupMenuProxyGtk(GtkWidget*, WebPopupMenuProxy::Client&);
+ GtkWidget* m_webView { nullptr };
+
+private:
void setCurrentlySelectedMenuItem(GtkWidget* item) { m_currentlySelectedMenuItem = item; }
GtkAction* createGtkActionForMenuItem(const WebPopupItem&, int itemIndex);
void populatePopupMenu(const Vector<WebPopupItem>&);
@@ -64,7 +67,6 @@
static gboolean keyPressEventCallback(GtkWidget*, GdkEventKey*, WebPopupMenuProxyGtk*);
static void menuUnmappedCallback(GtkWidget*, WebPopupMenuProxyGtk*);
- GtkWidget* m_webView { nullptr };
GtkWidget* m_popup { nullptr };
RunLoop::Timer<WebPopupMenuProxyGtk> m_dismissMenuTimer;
Modified: trunk/Tools/ChangeLog (218324 => 218325)
--- trunk/Tools/ChangeLog 2017-06-15 09:19:50 UTC (rev 218324)
+++ trunk/Tools/ChangeLog 2017-06-15 09:41:27 UTC (rev 218325)
@@ -1,3 +1,31 @@
+2017-06-15 Carlos Garcia Campos <cgar...@igalia.com>
+
+ [GTK] Add API to allow overriding popup menus
+ https://bugs.webkit.org/show_bug.cgi?id=172905
+
+ Reviewed by Michael Catanzaro.
+
+ Add a unit test to check the new API.
+
+ * TestWebKitAPI/Tests/WebKit2Gtk/CMakeLists.txt:
+ * TestWebKitAPI/Tests/WebKit2Gtk/TestOptionMenu.cpp: Added.
+ (OptionMenuTest::OptionMenuTest):
+ (OptionMenuTest::~OptionMenuTest):
+ (OptionMenuTest::destroyMenu):
+ (OptionMenuTest::showOptionMenuCallback):
+ (OptionMenuTest::menuCloseCallback):
+ (OptionMenuTest::showOptionMenu):
+ (OptionMenuTest::clickAtPositionAndWaitUntilOptionMenuShown):
+ (OptionMenuTest::close):
+ (OptionMenuTest::activateItem):
+ (OptionMenuTest::selectItem):
+ (testOptionMenuSimple):
+ (testOptionMenuGroups):
+ (testOptionMenuActivate):
+ (testOptionMenuSelect):
+ (beforeAll):
+ (afterAll):
+
2017-06-15 Fujii Hironori <hironori.fu...@sony.com>
[WinCairo] DumpRenderTree.cpp: error C3861: 'CFURLCacheCreate': identifier not found
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/CMakeLists.txt (218324 => 218325)
--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/CMakeLists.txt 2017-06-15 09:19:50 UTC (rev 218324)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/CMakeLists.txt 2017-06-15 09:41:27 UTC (rev 218325)
@@ -114,6 +114,7 @@
ADD_WK2_TEST(TestInspectorServer TestInspectorServer.cpp)
ADD_WK2_TEST(TestLoaderClient TestLoaderClient.cpp)
ADD_WK2_TEST(TestMultiprocess TestMultiprocess.cpp)
+ADD_WK2_TEST(TestOptionMenu TestOptionMenu.cpp)
ADD_WK2_TEST(TestPrinting TestPrinting.cpp)
ADD_WK2_TEST(TestResources TestResources.cpp)
ADD_WK2_TEST(TestSSL TestSSL.cpp)
Added: trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestOptionMenu.cpp (0 => 218325)
--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestOptionMenu.cpp (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestOptionMenu.cpp 2017-06-15 09:41:27 UTC (rev 218325)
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2017 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2,1 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 "WebViewTest.h"
+
+#include <wtf/RunLoop.h>
+
+class OptionMenuTest : public WebViewTest {
+public:
+ MAKE_GLIB_TEST_FIXTURE(OptionMenuTest);
+
+ OptionMenuTest()
+ {
+ g_signal_connect(m_webView, "show-option-menu", G_CALLBACK(showOptionMenuCallback), this);
+ }
+
+ ~OptionMenuTest()
+ {
+ g_signal_handlers_disconnect_matched(m_webView, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this);
+ if (m_menu)
+ close();
+ }
+
+ void destroyMenu()
+ {
+ if (!m_menu)
+ return;
+
+ g_signal_handlers_disconnect_matched(m_menu.get(), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this);
+ m_menu = nullptr;
+ }
+
+ static gboolean showOptionMenuCallback(WebKitWebView* webView, WebKitOptionMenu* menu, GdkEvent* event, GdkRectangle* rect, OptionMenuTest* test)
+ {
+ g_assert(test->m_webView == webView);
+ g_assert(rect);
+ g_assert(WEBKIT_IS_OPTION_MENU(menu));
+ test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(menu));
+ test->showOptionMenu(menu, rect);
+ return TRUE;
+ }
+
+ static void menuCloseCallback(WebKitOptionMenu* menu, OptionMenuTest* test)
+ {
+ g_assert(test->m_menu.get() == menu);
+ test->destroyMenu();
+ }
+
+ void showOptionMenu(WebKitOptionMenu* menu, GdkRectangle* rect)
+ {
+ m_rectangle = *rect;
+ m_menu = menu;
+ g_signal_connect(m_menu.get(), "close", G_CALLBACK(menuCloseCallback), this);
+ g_main_loop_quit(m_mainLoop);
+ }
+
+ void clickAtPositionAndWaitUntilOptionMenuShown(int x, int y)
+ {
+ m_menu = nullptr;
+ RunLoop::main().dispatch([this, x, y] { clickMouseButton(x, y); });
+ g_main_loop_run(m_mainLoop);
+ }
+
+ void close()
+ {
+ g_assert(m_menu.get());
+ webkit_option_menu_close(m_menu.get());
+ g_assert(!m_menu.get());
+ }
+
+ void activateItem(unsigned item)
+ {
+ g_assert(m_menu.get());
+ webkit_option_menu_activate_item(m_menu.get(), item);
+ g_assert(m_menu.get());
+ }
+
+ void selectItem(unsigned item)
+ {
+ g_assert(m_menu.get());
+ webkit_option_menu_select_item(m_menu.get(), item);
+ g_assert(m_menu.get());
+ }
+
+ GRefPtr<WebKitOptionMenu> m_menu;
+ GdkRectangle m_rectangle;
+};
+
+static void testOptionMenuSimple(OptionMenuTest* test, gconstpointer)
+{
+ static const char html[] =
+ "<html><body>"
+ " <select style='position:absolute; left:1; top:10'>"
+ " <option title='The Foo Option'>Foo</option>"
+ " <option selected>Bar</option>"
+ " <option disabled>Baz</option>"
+ " </select></body></html>";
+ test->showInWindowAndWaitUntilMapped();
+ test->loadHtml(html, nullptr);
+ test->waitUntilLoadFinished();
+
+ test->clickAtPositionAndWaitUntilOptionMenuShown(5, 15);
+ g_assert(WEBKIT_IS_OPTION_MENU(test->m_menu.get()));
+ g_assert_cmpint(webkit_option_menu_get_n_items(test->m_menu.get()), ==, 3);
+ auto* item = webkit_option_menu_get_item(test->m_menu.get(), 0);
+ g_assert_cmpstr(webkit_option_menu_item_get_label(item), ==, "Foo");
+ g_assert_cmpstr(webkit_option_menu_item_get_tooltip(item), ==, "The Foo Option");
+ g_assert(!webkit_option_menu_item_is_group_label(item));
+ g_assert(!webkit_option_menu_item_is_group_child(item));
+ g_assert(webkit_option_menu_item_is_enabled(item));
+ g_assert(!webkit_option_menu_item_is_selected(item));
+ item = webkit_option_menu_get_item(test->m_menu.get(), 1);
+ g_assert_cmpstr(webkit_option_menu_item_get_label(item), ==, "Bar");
+ g_assert(!webkit_option_menu_item_get_tooltip(item));
+ g_assert(!webkit_option_menu_item_is_group_label(item));
+ g_assert(!webkit_option_menu_item_is_group_child(item));
+ g_assert(webkit_option_menu_item_is_enabled(item));
+ g_assert(webkit_option_menu_item_is_selected(item));
+ item = webkit_option_menu_get_item(test->m_menu.get(), 2);
+ g_assert_cmpstr(webkit_option_menu_item_get_label(item), ==, "Baz");
+ g_assert(!webkit_option_menu_item_get_tooltip(item));
+ g_assert(!webkit_option_menu_item_is_group_label(item));
+ g_assert(!webkit_option_menu_item_is_group_child(item));
+ g_assert(!webkit_option_menu_item_is_enabled(item));
+ g_assert(!webkit_option_menu_item_is_selected(item));
+
+ test->close();
+ g_assert(!test->m_menu.get());
+}
+
+static void testOptionMenuGroups(OptionMenuTest* test, gconstpointer)
+{
+ static const char html[] =
+ "<html><body>"
+ " <select style='position:absolute; left:1; top:10'>"
+ " <option>Root</option>"
+ " <optgroup label='Group 1'>"
+ " <option>Child 1-1</option>"
+ " <option disabled>Child 1-2</option>"
+ " </optgroup>"
+ " <optgroup label='Group 2'>"
+ " <option selected>Child 2-1</option>"
+ " <option>Child 2-2</option>"
+ " </optgroup>"
+ " <option>Tail</option>"
+ " </select></body></html>";
+ test->showInWindowAndWaitUntilMapped();
+ test->loadHtml(html, nullptr);
+ test->waitUntilLoadFinished();
+
+ test->clickAtPositionAndWaitUntilOptionMenuShown(5, 15);
+ g_assert(WEBKIT_IS_OPTION_MENU(test->m_menu.get()));
+ g_assert_cmpint(webkit_option_menu_get_n_items(test->m_menu.get()), ==, 8);
+ auto* item = webkit_option_menu_get_item(test->m_menu.get(), 0);
+ g_assert_cmpstr(webkit_option_menu_item_get_label(item), ==, "Root");
+ g_assert(!webkit_option_menu_item_get_tooltip(item));
+ g_assert(!webkit_option_menu_item_is_group_label(item));
+ g_assert(!webkit_option_menu_item_is_group_child(item));
+ g_assert(webkit_option_menu_item_is_enabled(item));
+ g_assert(!webkit_option_menu_item_is_selected(item));
+ item = webkit_option_menu_get_item(test->m_menu.get(), 1);
+ g_assert_cmpstr(webkit_option_menu_item_get_label(item), ==, "Group 1");
+ g_assert(!webkit_option_menu_item_get_tooltip(item));
+ g_assert(webkit_option_menu_item_is_group_label(item));
+ g_assert(!webkit_option_menu_item_is_group_child(item));
+ g_assert(!webkit_option_menu_item_is_enabled(item));
+ g_assert(!webkit_option_menu_item_is_selected(item));
+ item = webkit_option_menu_get_item(test->m_menu.get(), 2);
+ g_assert_cmpstr(webkit_option_menu_item_get_label(item), ==, "Child 1-1");
+ g_assert(!webkit_option_menu_item_get_tooltip(item));
+ g_assert(!webkit_option_menu_item_is_group_label(item));
+ g_assert(webkit_option_menu_item_is_group_child(item));
+ g_assert(webkit_option_menu_item_is_enabled(item));
+ g_assert(!webkit_option_menu_item_is_selected(item));
+ item = webkit_option_menu_get_item(test->m_menu.get(), 3);
+ g_assert_cmpstr(webkit_option_menu_item_get_label(item), ==, "Child 1-2");
+ g_assert(!webkit_option_menu_item_get_tooltip(item));
+ g_assert(!webkit_option_menu_item_is_group_label(item));
+ g_assert(webkit_option_menu_item_is_group_child(item));
+ g_assert(!webkit_option_menu_item_is_enabled(item));
+ g_assert(!webkit_option_menu_item_is_selected(item));
+ item = webkit_option_menu_get_item(test->m_menu.get(), 4);
+ g_assert_cmpstr(webkit_option_menu_item_get_label(item), ==, "Group 2");
+ g_assert(!webkit_option_menu_item_get_tooltip(item));
+ g_assert(webkit_option_menu_item_is_group_label(item));
+ g_assert(!webkit_option_menu_item_is_group_child(item));
+ g_assert(!webkit_option_menu_item_is_enabled(item));
+ g_assert(!webkit_option_menu_item_is_selected(item));
+ item = webkit_option_menu_get_item(test->m_menu.get(), 5);
+ g_assert_cmpstr(webkit_option_menu_item_get_label(item), ==, "Child 2-1");
+ g_assert(!webkit_option_menu_item_get_tooltip(item));
+ g_assert(!webkit_option_menu_item_is_group_label(item));
+ g_assert(webkit_option_menu_item_is_group_child(item));
+ g_assert(webkit_option_menu_item_is_enabled(item));
+ g_assert(webkit_option_menu_item_is_selected(item));
+ item = webkit_option_menu_get_item(test->m_menu.get(), 6);
+ g_assert_cmpstr(webkit_option_menu_item_get_label(item), ==, "Child 2-2");
+ g_assert(!webkit_option_menu_item_get_tooltip(item));
+ g_assert(!webkit_option_menu_item_is_group_label(item));
+ g_assert(webkit_option_menu_item_is_group_child(item));
+ g_assert(webkit_option_menu_item_is_enabled(item));
+ g_assert(!webkit_option_menu_item_is_selected(item));
+ item = webkit_option_menu_get_item(test->m_menu.get(), 7);
+ g_assert_cmpstr(webkit_option_menu_item_get_label(item), ==, "Tail");
+ g_assert(!webkit_option_menu_item_get_tooltip(item));
+ g_assert(!webkit_option_menu_item_is_group_label(item));
+ g_assert(!webkit_option_menu_item_is_group_child(item));
+ g_assert(webkit_option_menu_item_is_enabled(item));
+ g_assert(!webkit_option_menu_item_is_selected(item));
+}
+
+static void testOptionMenuActivate(OptionMenuTest* test, gconstpointer)
+{
+ static const char html[] =
+ "<html><body>"
+ " <select id='combo' style='position:absolute; left:1; top:10'>"
+ " <option>Foo</option>"
+ " <option>Bar</option>"
+ " <option>Baz</option>"
+ " </select></body></html>";
+ test->showInWindowAndWaitUntilMapped();
+ test->loadHtml(html, nullptr);
+ test->waitUntilLoadFinished();
+
+ test->clickAtPositionAndWaitUntilOptionMenuShown(5, 15);
+ g_assert(WEBKIT_IS_OPTION_MENU(test->m_menu.get()));
+ g_assert_cmpint(webkit_option_menu_get_n_items(test->m_menu.get()), ==, 3);
+ test->activateItem(1);
+ auto* result = test->runJavaScriptAndWaitUntilFinished("document.getElementById('combo').selectedIndex", nullptr);
+ g_assert(result);
+ g_assert_cmpfloat(WebViewTest::_javascript_ResultToNumber(result), ==, 1);
+
+ // We should close the menu after activate, further activates will be ignored.
+ test->activateItem(2);
+ result = test->runJavaScriptAndWaitUntilFinished("document.getElementById('combo').selectedIndex", nullptr);
+ g_assert(result);
+ g_assert_cmpfloat(WebViewTest::_javascript_ResultToNumber(result), ==, 1);
+
+ test->close();
+}
+
+static void testOptionMenuSelect(OptionMenuTest* test, gconstpointer)
+{
+ static const char html[] =
+ "<html><body>"
+ " <select id='combo' style='position:absolute; left:1; top:10'>"
+ " <option>Foo</option>"
+ " <option>Bar</option>"
+ " <option>Baz</option>"
+ " </select></body></html>";
+ test->showInWindowAndWaitUntilMapped();
+ test->loadHtml(html, nullptr);
+ test->waitUntilLoadFinished();
+
+ test->clickAtPositionAndWaitUntilOptionMenuShown(5, 15);
+ g_assert(WEBKIT_IS_OPTION_MENU(test->m_menu.get()));
+ g_assert_cmpint(webkit_option_menu_get_n_items(test->m_menu.get()), ==, 3);
+
+ // Select item changes the combo text, but not the currently selected item.
+ test->selectItem(2);
+ auto* result = test->runJavaScriptAndWaitUntilFinished("document.getElementById('combo').selectedIndex", nullptr);
+ g_assert(result);
+ g_assert_cmpfloat(WebViewTest::_javascript_ResultToNumber(result), ==, 0);
+
+ // It can be called multiple times.
+ test->selectItem(1);
+ result = test->runJavaScriptAndWaitUntilFinished("document.getElementById('combo').selectedIndex", nullptr);
+ g_assert(result);
+ g_assert_cmpfloat(WebViewTest::_javascript_ResultToNumber(result), ==, 0);
+
+ // And closing the menu activates the currently selected item.
+ test->close();
+ result = test->runJavaScriptAndWaitUntilFinished("document.getElementById('combo').selectedIndex", nullptr);
+ g_assert(result);
+ g_assert_cmpfloat(WebViewTest::_javascript_ResultToNumber(result), ==, 1);
+}
+
+void beforeAll()
+{
+ OptionMenuTest::add("WebKitWebView", "option-menu-simple", testOptionMenuSimple);
+ OptionMenuTest::add("WebKitWebView", "option-menu-groups", testOptionMenuGroups);
+ OptionMenuTest::add("WebKitWebView", "option-menu-activate", testOptionMenuActivate);
+ OptionMenuTest::add("WebKitWebView", "option-menu-select", testOptionMenuSelect);
+}
+
+void afterAll()
+{
+}