Source/WebKit2/ChangeLog

 12017-06-04 Carlos Garcia Campos <cgarcia@igalia.com>
 2
 3 [GTK] Add API to allow overriding popup menus
 4 https://bugs.webkit.org/show_bug.cgi?id=172905
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 The GTK+ API uses GTK+ for the default implementation of several UI elements like the file chooser, print dialog,
 9 color picker, context menu, etc. but in all those cases it allows to override the default implementation. It's
 10 not possible to override the popup menu used for select elements. This patch adds WebKitOptionMenu to represent
 11 a select dropdown menu. It's passed as an argument of the new signal WebKitWebView::show-option-menu, and
 12 contains WebKitOptionMenuItem elements representng the items to be displayed.
 13
 14 * PlatformGTK.cmake:
 15 * UIProcess/API/gtk/PageClientImpl.cpp:
 16 (WebKit::PageClientImpl::createPopupMenuProxy): Create a WebKitPopupMenu.
 17 * UIProcess/API/gtk/WebKitOptionMenu.cpp: Added.
 18 (webkitOptionMenuCreate):
 19 (webkit_option_menu_get_n_items):
 20 (webkit_option_menu_get_item):
 21 (webkit_option_menu_select_item):
 22 (webkit_option_menu_activate_item):
 23 (webkit_option_menu_close):
 24 * UIProcess/API/gtk/WebKitOptionMenu.h: Added.
 25 * UIProcess/API/gtk/WebKitOptionMenuItem.cpp: Added.
 26 (webkit_option_menu_item_copy):
 27 (webkit_option_menu_item_free):
 28 (webkit_option_menu_item_get_label):
 29 (webkit_option_menu_item_get_tooltip):
 30 (webkit_option_menu_item_is_group_label):
 31 (webkit_option_menu_item_is_group_child):
 32 (webkit_option_menu_item_is_enabled):
 33 (webkit_option_menu_item_is_selected):
 34 * UIProcess/API/gtk/WebKitOptionMenuItem.h: Added.
 35 * UIProcess/API/gtk/WebKitOptionMenuItemPrivate.h: Added.
 36 (_WebKitOptionMenuItem::_WebKitOptionMenuItem):
 37 * UIProcess/API/gtk/WebKitOptionMenuPrivate.h: Added.
 38 * UIProcess/API/gtk/WebKitPopupMenu.cpp: Added.
 39 (WebKit::WebKitPopupMenu::WebKitPopupMenu):
 40 (WebKit::menuCloseCallback):
 41 (WebKit::WebKitPopupMenu::showPopupMenu): Call webkitWebViewShowOptionMenu() falling back to default
 42 implementation if the user didn't handle the signal.
 43 (WebKit::WebKitPopupMenu::hidePopupMenu):
 44 (WebKit::WebKitPopupMenu::cancelTracking):
 45 (WebKit::WebKitPopupMenu::selectItem):
 46 (WebKit::WebKitPopupMenu::activateItem):
 47 * UIProcess/API/gtk/WebKitPopupMenu.h: Added.
 48 * UIProcess/API/gtk/WebKitWebView.cpp:
 49 (webkit_web_view_class_init):
 50 (webkitWebViewShowOptionMenu): Emit WebKitWebView::show-option-menu.
 51 * UIProcess/API/gtk/WebKitWebView.h:
 52 * UIProcess/API/gtk/WebKitWebViewPrivate.h:
 53 * UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt: Add new symbols.
 54 * UIProcess/API/gtk/docs/webkit2gtk-4.0.types: Add new get_type functions.
 55 * UIProcess/API/gtk/docs/webkit2gtk-docs.sgml: Add new sections.
 56 * UIProcess/API/gtk/webkit2.h: Add new public headers.
 57 * UIProcess/gtk/WebPopupMenuProxyGtk.cpp:
 58 (WebKit::WebPopupMenuProxyGtk::WebPopupMenuProxyGtk): Do not create the GtkMenu in constructor.
 59 (WebKit::WebPopupMenuProxyGtk::showPopupMenu): Create the GtkMenu and connect to the signals here.
 60 (WebKit::WebPopupMenuProxyGtk::hidePopupMenu): Return early if the Gtk hasn't been shown.
 61 * UIProcess/gtk/WebPopupMenuProxyGtk.h: Make constructor and webview protected.
 62
1632017-06-01 Andreas Kling <akling@apple.com>
264
365 [Mac] Remove backing store for layers that are outside the viewport

Source/WebKit2/PlatformGTK.cmake

@@list(APPEND WebKit2_SOURCES
216216 UIProcess/API/gtk/WebKitNotificationPrivate.h
217217 UIProcess/API/gtk/WebKitNotificationProvider.cpp
218218 UIProcess/API/gtk/WebKitNotificationProvider.h
 219 UIProcess/API/gtk/WebKitOptionMenu.cpp
 220 UIProcess/API/gtk/WebKitOptionMenu.h
 221 UIProcess/API/gtk/WebKitOptionMenuPrivate.h
 222 UIProcess/API/gtk/WebKitOptionMenuItem.cpp
 223 UIProcess/API/gtk/WebKitOptionMenuItem.h
 224 UIProcess/API/gtk/WebKitOptionMenuItemPrivate.h
219225 UIProcess/API/gtk/WebKitPermissionRequest.cpp
220226 UIProcess/API/gtk/WebKitPermissionRequest.h
221227 UIProcess/API/gtk/WebKitPlugin.cpp

@@list(APPEND WebKit2_SOURCES
226232 UIProcess/API/gtk/WebKitPolicyDecision.cpp
227233 UIProcess/API/gtk/WebKitPolicyDecision.h
228234 UIProcess/API/gtk/WebKitPolicyDecisionPrivate.h
 235 UIProcess/API/gtk/WebKitPopupMenu.cpp
229236 UIProcess/API/gtk/WebKitPrintCustomWidget.cpp
230237 UIProcess/API/gtk/WebKitPrintCustomWidget.h
231238 UIProcess/API/gtk/WebKitPrintCustomWidgetPrivate.h

@@set(WebKit2GTK_INSTALLED_HEADERS
567574 ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitNetworkProxySettings.h
568575 ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitNotificationPermissionRequest.h
569576 ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitNotification.h
 577 ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitOptionMenu.h
 578 ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitOptionMenuItem.h
570579 ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitPermissionRequest.h
571580 ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitPlugin.h
572581 ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitPolicyDecision.h

Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp

3737#include "WebContextMenuProxyGtk.h"
3838#include "WebEventFactory.h"
3939#include "WebKitColorChooser.h"
 40#include "WebKitPopupMenu.h"
4041#include "WebKitWebViewBasePrivate.h"
4142#include "WebKitWebViewPrivate.h"
4243#include "WebPageProxy.h"
43 #include "WebPopupMenuProxyGtk.h"
4444#include "WebProcessPool.h"
4545#include <WebCore/CairoUtilities.h>
4646#include <WebCore/Cursor.h>

@@void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent& event, bool
206206
207207RefPtr<WebPopupMenuProxy> PageClientImpl::createPopupMenuProxy(WebPageProxy& page)
208208{
209  return WebPopupMenuProxyGtk::create(m_viewWidget, page);
 209 return WebKitPopupMenu::create(m_viewWidget, page);
210210}
211211
212212RefPtr<WebContextMenuProxy> PageClientImpl::createContextMenuProxy(WebPageProxy& page, const ContextMenuContextData& context, const UserData& userData)

Source/WebKit2/UIProcess/API/gtk/WebKitOptionMenu.cpp

 1/*
 2 * Copyright (C) 2017 Igalia S.L.
 3 *
 4 * This library is free software; you can redistribute it and/or
 5 * modify it under the terms of the GNU Library General Public
 6 * License as published by the Free Software Foundation; either
 7 * version 2 of the License, or (at your option) any later version.
 8 *
 9 * This library is distributed in the hope that it will be useful,
 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 12 * Library General Public License for more details.
 13 *
 14 * You should have received a copy of the GNU Library General Public License
 15 * along with this library; see the file COPYING.LIB. If not, write to
 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 17 * Boston, MA 02110-1301, USA.
 18 */
 19
 20#include "config.h"
 21#include "WebKitOptionMenu.h"
 22
 23#include "WebKitOptionMenuItemPrivate.h"
 24#include "WebKitOptionMenuPrivate.h"
 25#include "WebKitPrivate.h"
 26
 27using namespace WebKit;
 28
 29/**
 30 * SECTION: WebKitOptionMenu
 31 * @Short_description:
 32 * @Title: WebKitOptionMenu
 33 *
 34 * WebKitOptionMenu represents the dropdown menu of a select element in a #WebKitWebView.
 35 *
 36 * When a select element in a #WebKitWebView needs to display a dropdown menu, the signal
 37 * #WebKitWebView::show-option-menu is emitted, providing a WebKitOptionMenu with the
 38 * #WebKitOptionMenuItem<!-- -->s that should be displayed.
 39 *
 40 * Since: 2.18
 41 */
 42
 43struct _WebKitOptionMenuPrivate {
 44 Vector<WebKitOptionMenuItem> items;
 45 RefPtr<WebKitPopupMenu> popupMenu;
 46};
 47
 48enum {
 49 CLOSE,
 50
 51 LAST_SIGNAL
 52};
 53
 54static guint signals[LAST_SIGNAL] = { 0, };
 55
 56WEBKIT_DEFINE_TYPE(WebKitOptionMenu, webkit_option_menu, G_TYPE_OBJECT)
 57
 58static void webkit_option_menu_class_init(WebKitOptionMenuClass* optionMenuClass)
 59{
 60 /**
 61 * WebKitOptionMenu::close:
 62 * @menu: the #WebKitOptionMenu on which the signal is emitted
 63 *
 64 * Emitted when closing a #WebKitOptionMenu is requested. This can happen
 65 * when the user explicitly calls webkit_option_menu_close() or when the
 66 * element is detached from the current page.
 67 *
 68 * Since: 2.18
 69 */
 70 signals[CLOSE] =
 71 g_signal_new("close",
 72 G_TYPE_FROM_CLASS(optionMenuClass),
 73 G_SIGNAL_RUN_LAST,
 74 0, nullptr, nullptr,
 75 g_cclosure_marshal_VOID__VOID,
 76 G_TYPE_NONE, 0);
 77}
 78
 79WebKitOptionMenu* webkitOptionMenuCreate(WebKitPopupMenu& popupMenu, const Vector<WebPopupItem>& items, int32_t selectedIndex)
 80{
 81 auto* menu = WEBKIT_OPTION_MENU(g_object_new(WEBKIT_TYPE_OPTION_MENU, nullptr));
 82 menu->priv->popupMenu = &popupMenu;
 83 menu->priv->items.reserveInitialCapacity(items.size());
 84 for (const auto& item : items)
 85 menu->priv->items.uncheckedAppend(WebKitOptionMenuItem(item));
 86 if (selectedIndex >= 0) {
 87 ASSERT(static_cast<unsigned>(selectedIndex) < menu->priv->items.size());
 88 menu->priv->items[selectedIndex].isSelected = true;
 89 }
 90 return menu;
 91}
 92
 93/**
 94 * webkit_option_menu_get_n_items:
 95 * @menu: a #WebKitOptionMenu
 96 *
 97 * Gets the length of the @menu.
 98 *
 99 * Returns: the number of #WebKitOptionMenuItem<!-- -->s in @menu
 100 *
 101 * Since: 2.18
 102 */
 103guint webkit_option_menu_get_n_items(WebKitOptionMenu* menu)
 104{
 105 g_return_val_if_fail(WEBKIT_IS_OPTION_MENU(menu), 0);
 106
 107 return menu->priv->items.size();
 108}
 109
 110/**
 111 * webkit_option_menu_get_item:
 112 * @menu: a #WebKitOptionMenu
 113 * @index: the index of the item
 114 *
 115 * Returns the #WebKitOptionMenuItem at @index in @menu.
 116 *
 117 * Returns: (transfer none): a #WebKitOptionMenuItem of @menu.
 118 *
 119 * Since: 2.18
 120 */
 121WebKitOptionMenuItem* webkit_option_menu_get_item(WebKitOptionMenu* menu, guint index)
 122{
 123 g_return_val_if_fail(WEBKIT_IS_OPTION_MENU(menu), nullptr);
 124 g_return_val_if_fail(index < menu->priv->items.size(), nullptr);
 125
 126 return &menu->priv->items[index];
 127}
 128
 129/**
 130 * webkit_option_menu_select_item:
 131 * @menu: a #WebKitOptionMenu
 132 * @index: the index of the item
 133 *
 134 * Selects the #WebKitOptionMenuItem at @index in @menu. Selecting an item changes the
 135 * text shown by the combo button, but it doesn't change the value of the element. You need to
 136 * explicitly activate the item with webkit_option_menu_select_item() or close the menu with
 137 * webkit_option_menu_close() in which case the currently selected item will be activated.
 138 *
 139 * Since: 2.18
 140 */
 141void webkit_option_menu_select_item(WebKitOptionMenu* menu, guint index)
 142{
 143 g_return_if_fail(WEBKIT_IS_OPTION_MENU(menu));
 144 g_return_if_fail(index < menu->priv->items.size());
 145
 146 menu->priv->popupMenu->selectItem(index);
 147}
 148
 149/**
 150 * webkit_option_menu_activate_item:
 151 * @menu: a #WebKitOptionMenu
 152 * @index: the index of the item
 153 *
 154 * Activates the #WebKitOptionMenuItem at @index in @menu. Activating an item changes the value
 155 * of the element making the item the active one. You are expected to close the menu with
 156 * webkit_option_menu_close() after activating an item, calling this function again will have no
 157 * effect.
 158 *
 159 * Since: 2.18
 160 */
 161void webkit_option_menu_activate_item(WebKitOptionMenu* menu, guint index)
 162{
 163 g_return_if_fail(WEBKIT_IS_OPTION_MENU(menu));
 164 g_return_if_fail(index < menu->priv->items.size());
 165
 166 menu->priv->popupMenu->activateItem(index);
 167}
 168
 169/**
 170 * webkit_option_menu_close:
 171 * @menu: a #WebKitOptionMenu
 172 *
 173 * Request to close a #WebKitOptionMenu. This emits WebKitOptionMenu::close signal.
 174 * This function should always be called to notify WebKit that the associated
 175 * menu has been closed. If the menu is closed and neither webkit_option_menu_select_item()
 176 * nor webkit_option_menu_activate_item() have been called, the element value remains
 177 * unchanged.
 178 *
 179 * Since: 2.18
 180 */
 181void webkit_option_menu_close(WebKitOptionMenu* menu)
 182{
 183 g_return_if_fail(WEBKIT_IS_OPTION_MENU(menu));
 184
 185 g_signal_emit(menu, signals[CLOSE], 0, nullptr);
 186}

Source/WebKit2/UIProcess/API/gtk/WebKitOptionMenu.h

 1/*
 2 * Copyright (C) 2017 Igalia S.L.
 3 *
 4 * This library is free software; you can redistribute it and/or
 5 * modify it under the terms of the GNU Library General Public
 6 * License as published by the Free Software Foundation; either
 7 * version 2 of the License, or (at your option) any later version.
 8 *
 9 * This library is distributed in the hope that it will be useful,
 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 12 * Library General Public License for more details.
 13 *
 14 * You should have received a copy of the GNU Library General Public License
 15 * along with this library; see the file COPYING.LIB. If not, write to
 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 17 * Boston, MA 02110-1301, USA.
 18 */
 19
 20#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) && !defined(__WEBKIT_WEB_EXTENSION_H_INSIDE__)
 21#error "Only <webkit2/webkit2.h> can be included directly."
 22#endif
 23
 24#ifndef WebKitOptionMenu_h
 25#define WebKitOptionMenu_h
 26
 27#include <glib-object.h>
 28#include <webkit2/WebKitOptionMenuItem.h>
 29#include <webkit2/WebKitDefines.h>
 30
 31G_BEGIN_DECLS
 32
 33#define WEBKIT_TYPE_OPTION_MENU (webkit_option_menu_get_type())
 34#define WEBKIT_OPTION_MENU(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_OPTION_MENU, WebKitOptionMenu))
 35#define WEBKIT_IS_OPTION_MENU(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_OPTION_MENU))
 36#define WEBKIT_OPTION_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_OPTION_MENU, WebKitOptionMenuClass))
 37#define WEBKIT_IS_OPTION_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_OPTION_MENU))
 38#define WEBKIT_OPTION_MENU_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_OPTION_MENU, WebKitOptionMenuClass))
 39
 40typedef struct _WebKitOptionMenu WebKitOptionMenu;
 41typedef struct _WebKitOptionMenuClass WebKitOptionMenuClass;
 42typedef struct _WebKitOptionMenuPrivate WebKitOptionMenuPrivate;
 43
 44struct _WebKitOptionMenu {
 45 GObject parent;
 46
 47 WebKitOptionMenuPrivate *priv;
 48};
 49
 50struct _WebKitOptionMenuClass {
 51 GObjectClass parent_class;
 52
 53 void (*_webkit_reserved0) (void);
 54 void (*_webkit_reserved1) (void);
 55 void (*_webkit_reserved2) (void);
 56 void (*_webkit_reserved3) (void);
 57};
 58
 59WEBKIT_API GType
 60webkit_option_menu_get_type (void);
 61
 62WEBKIT_API guint
 63webkit_option_menu_get_n_items (WebKitOptionMenu *menu);
 64
 65WEBKIT_API WebKitOptionMenuItem *
 66webkit_option_menu_get_item (WebKitOptionMenu *menu,
 67 guint index);
 68
 69WEBKIT_API void
 70webkit_option_menu_select_item (WebKitOptionMenu *menu,
 71 guint index);
 72
 73WEBKIT_API void
 74webkit_option_menu_activate_item (WebKitOptionMenu *menu,
 75 guint index);
 76
 77WEBKIT_API void
 78webkit_option_menu_close (WebKitOptionMenu *menu);
 79
 80G_END_DECLS
 81
 82#endif

Source/WebKit2/UIProcess/API/gtk/WebKitOptionMenuItem.cpp

 1/*
 2 * Copyright (C) 2017 Igalia S.L.
 3 *
 4 * This library is free software; you can redistribute it and/or
 5 * modify it under the terms of the GNU Library General Public
 6 * License as published by the Free Software Foundation; either
 7 * version 2 of the License, or (at your option) any later version.
 8 *
 9 * This library is distributed in the hope that it will be useful,
 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 12 * Library General Public License for more details.
 13 *
 14 * You should have received a copy of the GNU Library General Public License
 15 * along with this library; see the file COPYING.LIB. If not, write to
 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 17 * Boston, MA 02110-1301, USA.
 18 */
 19
 20#include "config.h"
 21#include "WebKitOptionMenuItem.h"
 22
 23#include "WebKitOptionMenuItemPrivate.h"
 24
 25using namespace WebKit;
 26
 27G_DEFINE_BOXED_TYPE(WebKitOptionMenuItem, webkit_option_menu_item, webkit_option_menu_item_copy, webkit_option_menu_item_free)
 28
 29/**
 30 * webkit_option_menu_item_copy:
 31 * @item: a #WebKitOptionMenuItem
 32 *
 33 * Make a copy of the #WebKitOptionMenuItem.
 34 *
 35 * Returns: (transfer full): A copy of passed in #WebKitOptionMenuItem
 36 *
 37 * Since: 2.18
 38 */
 39WebKitOptionMenuItem* webkit_option_menu_item_copy(WebKitOptionMenuItem* item)
 40{
 41 g_return_val_if_fail(item, nullptr);
 42
 43 auto* copyItem = static_cast<WebKitOptionMenuItem*>(fastMalloc(sizeof(WebKitOptionMenuItem)));
 44 new (copyItem) WebKitOptionMenuItem(item);
 45 return copyItem;
 46}
 47
 48/**
 49 * webkit_option_menu_item_free:
 50 * @item: A #WebKitOptionMenuItem
 51 *
 52 * Free the #WebKitOptionMenuItem.
 53 *
 54 * Since: 2.18
 55 */
 56void webkit_option_menu_item_free(WebKitOptionMenuItem* item)
 57{
 58 g_return_if_fail(item);
 59
 60 item->~WebKitOptionMenuItem();
 61 fastFree(item);
 62}
 63
 64/**
 65 * webkit_option_menu_item_get_label:
 66 * @item: a #WebKitOptionMenuItem
 67 *
 68 * Get the label of a #WebKitOptionMenuItem.
 69 *
 70 * Returns: The label of @item.
 71 *
 72 * Since: 2.18
 73 */
 74const gchar* webkit_option_menu_item_get_label(WebKitOptionMenuItem* item)
 75{
 76 g_return_val_if_fail(item, nullptr);
 77
 78 return item->label.data();
 79}
 80
 81/**
 82 * webkit_option_menu_item_get_tooltip:
 83 * @item: a #WebKitOptionMenuItem
 84 *
 85 * Get the tooltip of a #WebKitOptionMenuItem.
 86 *
 87 * Returns: The tooltip of @item, or %NULL.
 88 *
 89 * Since: 2.18
 90 */
 91const gchar* webkit_option_menu_item_get_tooltip(WebKitOptionMenuItem* item)
 92{
 93 g_return_val_if_fail(item, nullptr);
 94
 95 return item->tooltip.isNull() ? nullptr : item->tooltip.data();
 96}
 97
 98/**
 99 * webkit_option_menu_item_is_group_label:
 100 * @item: a #WebKitOptionMenuItem
 101 *
 102 * Whether a#WebKitOptionMenuItem is a group label.
 103 *
 104 * Returns: %TRUE if the @item is a group label or %FALSE otherwise.
 105 *
 106 * Since: 2.18
 107 */
 108gboolean webkit_option_menu_item_is_group_label(WebKitOptionMenuItem* item)
 109{
 110 g_return_val_if_fail(item, FALSE);
 111
 112 return item->isGroupLabel;
 113}
 114
 115/**
 116 * webkit_option_menu_item_is_group_child:
 117 * @item: a #WebKitOptionMenuItem
 118 *
 119 * Whether a#WebKitOptionMenuItem is a group child.
 120 *
 121 * Returns: %TRUE if the @item is a group child or %FALSE otherwise.
 122 *
 123 * Since: 2.18
 124 */
 125gboolean webkit_option_menu_item_is_group_child(WebKitOptionMenuItem* item)
 126{
 127 g_return_val_if_fail(item, FALSE);
 128
 129 return item->isGroupChild;
 130}
 131
 132/**
 133 * webkit_option_menu_item_is_enabled:
 134 * @item: a #WebKitOptionMenuItem
 135 *
 136 * Whether a#WebKitOptionMenuItem is enabled.
 137 *
 138 * Returns: %TRUE if the @item is enabled or %FALSE otherwise.
 139 *
 140 * Since: 2.18
 141 */
 142gboolean webkit_option_menu_item_is_enabled(WebKitOptionMenuItem* item)
 143{
 144 g_return_val_if_fail(item, FALSE);
 145
 146 return item->isEnabled;
 147}
 148
 149/**
 150 * webkit_option_menu_item_is_selected:
 151 * @item: a #WebKitOptionMenuItem
 152 *
 153 * Whether a#WebKitOptionMenuItem is the currently selected one.
 154 *
 155 * Returns: %TRUE if the @item is selected or %FALSE otherwise.
 156 *
 157 * Since: 2.18
 158 */
 159gboolean webkit_option_menu_item_is_selected(WebKitOptionMenuItem* item)
 160{
 161 g_return_val_if_fail(item, FALSE);
 162
 163 return item->isSelected;
 164}

Source/WebKit2/UIProcess/API/gtk/WebKitOptionMenuItem.h

 1/*
 2 * Copyright (C) 2017 Igalia S.L.
 3 *
 4 * This library is free software; you can redistribute it and/or
 5 * modify it under the terms of the GNU Library General Public
 6 * License as published by the Free Software Foundation; either
 7 * version 2 of the License, or (at your option) any later version.
 8 *
 9 * This library is distributed in the hope that it will be useful,
 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 12 * Library General Public License for more details.
 13 *
 14 * You should have received a copy of the GNU Library General Public License
 15 * along with this library; see the file COPYING.LIB. If not, write to
 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 17 * Boston, MA 02110-1301, USA.
 18 */
 19
 20#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION)
 21#error "Only <webkit2/webkit2.h> can be included directly."
 22#endif
 23
 24#ifndef WebKitOptionMenuItem_h
 25#define WebKitOptionMenuItem_h
 26
 27#include <glib-object.h>
 28#include <webkit2/WebKitDefines.h>
 29
 30G_BEGIN_DECLS
 31
 32#define WEBKIT_TYPE_OPTION_MENU_ITEM (webkit_option_menu_item_get_type())
 33
 34typedef struct _WebKitOptionMenuItem WebKitOptionMenuItem;
 35
 36WEBKIT_API GType
 37webkit_option_menu_item_get_type (void);
 38
 39WEBKIT_API WebKitOptionMenuItem *
 40webkit_option_menu_item_copy (WebKitOptionMenuItem *item);
 41
 42WEBKIT_API void
 43webkit_option_menu_item_free (WebKitOptionMenuItem *item);
 44
 45WEBKIT_API const gchar *
 46webkit_option_menu_item_get_label (WebKitOptionMenuItem *item);
 47
 48WEBKIT_API const gchar *
 49webkit_option_menu_item_get_tooltip (WebKitOptionMenuItem *item);
 50
 51WEBKIT_API gboolean
 52webkit_option_menu_item_is_group_label (WebKitOptionMenuItem *item);
 53
 54WEBKIT_API gboolean
 55webkit_option_menu_item_is_group_child (WebKitOptionMenuItem *item);
 56
 57WEBKIT_API gboolean
 58webkit_option_menu_item_is_enabled (WebKitOptionMenuItem *item);
 59
 60WEBKIT_API gboolean
 61webkit_option_menu_item_is_selected (WebKitOptionMenuItem *item);
 62
 63G_END_DECLS
 64
 65#endif

Source/WebKit2/UIProcess/API/gtk/WebKitOptionMenuItemPrivate.h

 1/*
 2 * Copyright (C) 2017 Igalia S.L.
 3 *
 4 * This library is free software; you can redistribute it and/or
 5 * modify it under the terms of the GNU Library General Public
 6 * License as published by the Free Software Foundation; either
 7 * version 2 of the License, or (at your option) any later version.
 8 *
 9 * This library is distributed in the hope that it will be useful,
 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 12 * Library General Public License for more details.
 13 *
 14 * You should have received a copy of the GNU Library General Public License
 15 * along with this library; see the file COPYING.LIB. If not, write to
 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 17 * Boston, MA 02110-1301, USA.
 18 */
 19
 20#pragma once
 21
 22#include "WebKitOptionMenuItem.h"
 23#include "WebPopupItem.h"
 24#include <wtf/text/CString.h>
 25
 26struct _WebKitOptionMenuItem {
 27 _WebKitOptionMenuItem() = default;
 28
 29 _WebKitOptionMenuItem(const WebKit::WebPopupItem& item)
 30 : label(item.m_text.stripWhiteSpace().utf8())
 31 , isGroupLabel(item.m_isLabel)
 32 , isGroupChild(item.m_text.startsWith(" "))
 33 , isEnabled(item.m_isEnabled)
 34 {
 35 if (!item.m_toolTip.isEmpty())
 36 tooltip = item.m_toolTip.utf8();
 37 }
 38
 39 explicit _WebKitOptionMenuItem(_WebKitOptionMenuItem* other)
 40 : label(other->label)
 41 , tooltip(other->tooltip)
 42 , isGroupLabel(other->isGroupLabel)
 43 , isGroupChild(other->isGroupChild)
 44 , isEnabled(other->isEnabled)
 45 , isSelected(other->isSelected)
 46 {
 47 }
 48
 49 CString label;
 50 CString tooltip;
 51 bool isGroupLabel { false };
 52 bool isGroupChild { false };
 53 bool isEnabled { true };
 54 bool isSelected { false };
 55};

Source/WebKit2/UIProcess/API/gtk/WebKitOptionMenuPrivate.h

 1/*
 2 * Copyright (C) 2017 Igalia S.L.
 3 *
 4 * This library is free software; you can redistribute it and/or
 5 * modify it under the terms of the GNU Library General Public
 6 * License as published by the Free Software Foundation; either
 7 * version 2 of the License, or (at your option) any later version.
 8 *
 9 * This library is distributed in the hope that it will be useful,
 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 12 * Library General Public License for more details.
 13 *
 14 * You should have received a copy of the GNU Library General Public License
 15 * along with this library; see the file COPYING.LIB. If not, write to
 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 17 * Boston, MA 02110-1301, USA.
 18 */
 19
 20#pragma once
 21
 22#include "WebKitOptionMenu.h"
 23#include "WebKitPopupMenu.h"
 24
 25WebKitOptionMenu* webkitOptionMenuCreate(WebKit::WebKitPopupMenu&, const Vector<WebKit::WebPopupItem>&, int32_t selectedIndex);

Source/WebKit2/UIProcess/API/gtk/WebKitPopupMenu.cpp

 1/*
 2 * Copyright (C) 2017 Igalia S.L.
 3 *
 4 * This library is free software; you can redistribute it and/or
 5 * modify it under the terms of the GNU Library General Public
 6 * License as published by the Free Software Foundation; either
 7 * version 2 of the License, or (at your option) any later version.
 8 *
 9 * This library is distributed in the hope that it will be useful,
 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 12 * Library General Public License for more details.
 13 *
 14 * You should have received a copy of the GNU Library General Public License
 15 * along with this library; see the file COPYING.LIB. If not, write to
 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 17 * Boston, MA 02110-1301, USA.
 18 */
 19
 20#include "config.h"
 21#include "WebKitPopupMenu.h"
 22
 23#include "NativeWebMouseEvent.h"
 24#include "WebKitOptionMenuPrivate.h"
 25#include "WebKitWebViewPrivate.h"
 26
 27using namespace WebCore;
 28
 29namespace WebKit {
 30
 31WebKitPopupMenu::WebKitPopupMenu(GtkWidget* webView, WebPopupMenuProxy::Client& client)
 32 : WebPopupMenuProxyGtk(webView, client)
 33{
 34}
 35
 36static void menuCloseCallback(WebKitPopupMenu* popupMenu)
 37{
 38 popupMenu->activateItem(-1);
 39}
 40
 41void WebKitPopupMenu::showPopupMenu(const IntRect& rect, TextDirection direction, double pageScaleFactor, const Vector<WebPopupItem>& items, const PlatformPopupMenuData& platformData, int32_t selectedIndex)
 42{
 43 GRefPtr<WebKitOptionMenu> menu = adoptGRef(webkitOptionMenuCreate(*this, items, selectedIndex));
 44 const GdkEvent* event = m_client->currentlyProcessedMouseDownEvent() ? m_client->currentlyProcessedMouseDownEvent()->nativeEvent() : nullptr;
 45 if (webkitWebViewShowOptionMenu(WEBKIT_WEB_VIEW(m_webView), rect, menu.get(), event)) {
 46 m_menu = WTFMove(menu);
 47 g_signal_connect_swapped(m_menu.get(), "close", G_CALLBACK(menuCloseCallback), this);
 48 } else
 49 WebPopupMenuProxyGtk::showPopupMenu(rect, direction, pageScaleFactor, items, platformData, selectedIndex);
 50}
 51
 52void WebKitPopupMenu::hidePopupMenu()
 53{
 54 if (!m_menu) {
 55 WebPopupMenuProxyGtk::hidePopupMenu();
 56 return;
 57 }
 58 g_signal_handlers_disconnect_matched(m_menu.get(), G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, this);
 59 webkit_option_menu_close(m_menu.get());
 60}
 61
 62void WebKitPopupMenu::cancelTracking()
 63{
 64 if (!m_menu) {
 65 WebPopupMenuProxyGtk::cancelTracking();
 66 return;
 67 }
 68 hidePopupMenu();
 69 m_menu = nullptr;
 70}
 71
 72void WebKitPopupMenu::selectItem(unsigned itemIndex)
 73{
 74 if (!m_menu)
 75 return;
 76 m_client->setTextFromItemForPopupMenu(this, itemIndex);
 77 m_selectedItem = itemIndex;
 78}
 79
 80void WebKitPopupMenu::activateItem(int32_t itemIndex)
 81{
 82 if (!m_menu)
 83 return;
 84 m_client->valueChangedForPopupMenu(this, itemIndex == -1 ? m_selectedItem.value_or(-1) : itemIndex);
 85 g_signal_handlers_disconnect_matched(m_menu.get(), G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, this);
 86 m_menu = nullptr;
 87}
 88
 89} // namespace WebKit

Source/WebKit2/UIProcess/API/gtk/WebKitPopupMenu.h

 1/*
 2 * Copyright (C) 2017 Igalia S.L.
 3 *
 4 * This library is free software; you can redistribute it and/or
 5 * modify it under the terms of the GNU Library General Public
 6 * License as published by the Free Software Foundation; either
 7 * version 2 of the License, or (at your option) any later version.
 8 *
 9 * This library is distributed in the hope that it will be useful,
 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 12 * Library General Public License for more details.
 13 *
 14 * You should have received a copy of the GNU Library General Public License
 15 * along with this library; see the file COPYING.LIB. If not, write to
 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 17 * Boston, MA 02110-1301, USA.
 18 */
 19
 20#pragma once
 21
 22#include "WebPopupMenuProxyGtk.h"
 23#include <wtf/glib/GRefPtr.h>
 24
 25typedef struct _WebKitOptionMenu WebKitOptionMenu;
 26
 27namespace WebKit {
 28
 29class WebKitPopupMenu final : public WebPopupMenuProxyGtk {
 30public:
 31 static Ref<WebKitPopupMenu> create(GtkWidget* webView, WebPopupMenuProxy::Client& client)
 32 {
 33 return adoptRef(*new WebKitPopupMenu(webView, client));
 34 }
 35 ~WebKitPopupMenu() = default;
 36
 37 void selectItem(unsigned);
 38 void activateItem(int32_t);
 39
 40private:
 41 WebKitPopupMenu(GtkWidget*, WebPopupMenuProxy::Client&);
 42
 43 void showPopupMenu(const WebCore::IntRect&, WebCore::TextDirection, double pageScaleFactor, const Vector<WebPopupItem>&, const PlatformPopupMenuData&, int32_t selectedIndex) override;
 44 void hidePopupMenu() override;
 45 void cancelTracking() override;
 46
 47 GRefPtr<WebKitOptionMenu> m_menu;
 48 std::optional<unsigned> m_selectedItem;
 49};
 50
 51} // namespace WebKit

Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp

@@enum {
139139
140140 RUN_COLOR_CHOOSER,
141141
 142 SHOW_OPTION_MENU,
 143
142144 LAST_SIGNAL
143145};
144146

@@static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
18831885 webkit_marshal_BOOLEAN__OBJECT,
18841886 G_TYPE_BOOLEAN, 1,
18851887 WEBKIT_TYPE_COLOR_CHOOSER_REQUEST);
 1888
 1889 /**
 1890 * WebKitWebView::show-option-menu:
 1891 * @web_view: the #WebKitWebView on which the signal is emitted
 1892 * @menu: the #WebKitOptionMenu
 1893 * @event: the #GdkEvent that triggered the menu, or %NULL
 1894 * @rectangle: the option element area
 1895 *
 1896 * This signal is emitted when a select element in @web_view needs to display a
 1897 * dropdown menu. This signal can be used to show a custom menu, using @menu to get
 1898 * the details of all items that should be displayed. The area of the element in the
 1899 * #WebKitWebView is given as @rectangle parameter, it can be used to position the
 1900 * menu. If this was triggered by a user interaction, like a mouse click,
 1901 * @event parameter provides the #GdkEvent.
 1902 * To handle this signal asynchronously you should keep a ref of the @menu.
 1903 *
 1904 * The default signal handler will pop up a #GtkMenu.
 1905 *
 1906 * Returns: %TRUE to stop other handlers from being invoked for the event.
 1907 * %FALSE to propagate the event further.
 1908 *
 1909 * Since: 2.18.
 1910 */
 1911 signals[SHOW_OPTION_MENU] =
 1912 g_signal_new("show-option-menu",
 1913 G_TYPE_FROM_CLASS(webViewClass),
 1914 G_SIGNAL_RUN_LAST,
 1915 G_STRUCT_OFFSET(WebKitWebViewClass, show_option_menu),
 1916 g_signal_accumulator_true_handled, nullptr,
 1917 g_cclosure_marshal_generic,
 1918 G_TYPE_BOOLEAN, 3,
 1919 WEBKIT_TYPE_OPTION_MENU,
 1920 GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE,
 1921 GDK_TYPE_RECTANGLE | G_SIGNAL_TYPE_STATIC_SCOPE);
18861922}
18871923
18881924static void webkitWebViewCancelAuthenticationRequest(WebKitWebView* webView)

@@WebKitWebsiteDataManager* webkitWebViewGetWebsiteDataManager(WebKitWebView* webV
21892225 return webView->priv->websiteDataManager.get();
21902226}
21912227
 2228bool webkitWebViewShowOptionMenu(WebKitWebView* webView, const IntRect& rect, WebKitOptionMenu* menu, const GdkEvent* event)
 2229{
 2230 GdkRectangle menuRect = rect;
 2231 gboolean handled;
 2232 g_signal_emit(webView, signals[SHOW_OPTION_MENU], 0, menu, event, &menuRect, &handled);
 2233 return handled;
 2234}
 2235
21922236/**
21932237 * webkit_web_view_new:
21942238 *

Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h

4242#include <webkit2/WebKitJavascriptResult.h>
4343#include <webkit2/WebKitNavigationAction.h>
4444#include <webkit2/WebKitNotification.h>
 45#include <webkit2/WebKitOptionMenu.h>
4546#include <webkit2/WebKitPermissionRequest.h>
4647#include <webkit2/WebKitPolicyDecision.h>
4748#include <webkit2/WebKitScriptDialog.h>

@@struct _WebKitWebViewClass {
249250 WebKitNotification *notification);
250251 gboolean (* run_color_chooser) (WebKitWebView *web_view,
251252 WebKitColorChooserRequest *request);
 253 gboolean (* show_option_menu) (WebKitWebView *web_view,
 254 GdkRectangle *rectangle,
 255 WebKitOptionMenu *menu);
252256
253257 void (*_webkit_reserved0) (void);
254258 void (*_webkit_reserved1) (void);
255259 void (*_webkit_reserved2) (void);
256  void (*_webkit_reserved3) (void);
257260};
258261
259262WEBKIT_API GType

Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h

3131#include "WebContextMenuItemData.h"
3232#include "WebHitTestResultData.h"
3333#include "WebImage.h"
 34#include "WebKitPrivate.h"
3435#include "WebKitWebView.h"
 36#include <WebCore/IntRect.h>
3537#include <wtf/text/CString.h>
3638
3739void webkitWebViewLoadChanged(WebKitWebView*, WebKitLoadEvent);

@@void webkitWebViewIsPlayingAudioChanged(WebKitWebView*);
6769void webkitWebViewSelectionDidChange(WebKitWebView*);
6870void webkitWebViewRequestInstallMissingMediaPlugins(WebKitWebView*, WebKit::InstallMissingMediaPluginsPermissionRequest&);
6971WebKitWebsiteDataManager* webkitWebViewGetWebsiteDataManager(WebKitWebView*);
 72bool webkitWebViewShowOptionMenu(WebKitWebView*, const WebCore::IntRect&, WebKitOptionMenu*, const GdkEvent*);
7073
7174#endif // WebKitWebViewPrivate_h

Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt

@@webkit_context_menu_item_get_type
11761176</SECTION>
11771177
11781178<SECTION>
 1179<FILE>WebKitOptionMenu</FILE>
 1180WebKitOptionMenu
 1181webkit_option_menu_get_n_items
 1182webkit_option_menu_get_item
 1183webkit_option_menu_select_item
 1184webkit_option_menu_activate_item
 1185webkit_option_menu_close
 1186
 1187<SUBSECTION Standard>
 1188WebKitOptionMenuClass
 1189WEBKIT_TYPE_OPTION_MENU
 1190WEBKIT_OPTION_MENU
 1191WEBKIT_IS_OPTION_MENU
 1192WEBKIT_OPTION_MENU_CLASS
 1193WEBKIT_IS_OPTION_MENU_CLASS
 1194WEBKIT_OPTION_MENU_GET_CLASS
 1195
 1196<SUBSECTION Private>
 1197WebKitOptionMenuPrivate
 1198webkit_option_menu_get_type
 1199</SECTION>
 1200
 1201<SECTION>
 1202<FILE>WebKitOptionMenuItem</FILE>
 1203WebKitOptionMenuItem
 1204webkit_option_menu_item_copy
 1205webkit_option_menu_item_free
 1206webkit_option_menu_item_get_label
 1207webkit_option_menu_item_get_tooltip
 1208webkit_option_menu_item_is_group_label
 1209webkit_option_menu_item_is_group_child
 1210webkit_option_menu_item_is_enabled
 1211webkit_option_menu_item_is_selected
 1212
 1213<SUBSECTION Standard>
 1214WEBKIT_TYPE_OPTION_MENU_ITEM
 1215
 1216<SUBSECTION Private>
 1217webkit_option_menu_item_get_type
 1218</SECTION>
 1219
 1220<SECTION>
11791221<FILE>WebKitFormSubmissionRequest</FILE>
11801222WebKitFormSubmissionRequest
11811223webkit_form_submission_request_get_text_fields

Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-4.0.types

@@webkit_console_message_get_type
3636webkit_web_view_session_state_get_type
3737webkit_print_custom_widget_get_type
3838webkit_automation_session_get_type
 39webkit_option_menu_get_type
 40webkit_option_menu_item_get_type

Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml

4646 <xi:include href="xml/WebKitVersion.xml"/>
4747 <xi:include href="xml/WebKitContextMenu.xml"/>
4848 <xi:include href="xml/WebKitContextMenuItem.xml"/>
 49 <xi:include href="xml/WebKitOptionMenu.xml"/>
 50 <xi:include href="xml/WebKitOptionMenuItem.xml"/>
4951 <xi:include href="xml/WebKitFormSubmissionRequest.xml"/>
5052 <xi:include href="xml/WebKitSecurityManager.xml"/>
5153 <xi:include href="xml/WebKitUserContentManager.xml"/>

Source/WebKit2/UIProcess/API/gtk/webkit2.h

5757#include <webkit2/WebKitNetworkProxySettings.h>
5858#include <webkit2/WebKitNotification.h>
5959#include <webkit2/WebKitNotificationPermissionRequest.h>
 60#include <webkit2/WebKitOptionMenu.h>
 61#include <webkit2/WebKitOptionMenuItem.h>
6062#include <webkit2/WebKitPermissionRequest.h>
6163#include <webkit2/WebKitPlugin.h>
6264#include <webkit2/WebKitPrintCustomWidget.h>

Source/WebKit2/UIProcess/gtk/WebPopupMenuProxyGtk.cpp

@@namespace WebKit {
4141WebPopupMenuProxyGtk::WebPopupMenuProxyGtk(GtkWidget* webView, WebPopupMenuProxy::Client& client)
4242 : WebPopupMenuProxy(client)
4343 , m_webView(webView)
44  , m_popup(gtk_menu_new())
4544 , m_dismissMenuTimer(RunLoop::main(), this, &WebPopupMenuProxyGtk::dismissMenuTimerFired)
4645{
47  g_signal_connect(m_popup, "key-press-event", G_CALLBACK(keyPressEventCallback), this);
48  g_signal_connect(m_popup, "unmap", G_CALLBACK(menuUnmappedCallback), this);
4946}
5047
5148WebPopupMenuProxyGtk::~WebPopupMenuProxyGtk()

@@void WebPopupMenuProxyGtk::populatePopupMenu(const Vector<WebPopupItem>& items)
8885
8986void WebPopupMenuProxyGtk::showPopupMenu(const IntRect& rect, TextDirection, double /* pageScaleFactor */, const Vector<WebPopupItem>& items, const PlatformPopupMenuData&, int32_t selectedIndex)
9087{
91  m_dismissMenuTimer.stop();
 88 ASSERT(!m_popup);
 89 m_popup = gtk_menu_new();
 90 g_signal_connect(m_popup, "key-press-event", G_CALLBACK(keyPressEventCallback), this);
 91 g_signal_connect(m_popup, "unmap", G_CALLBACK(menuUnmappedCallback), this);
9292
9393 populatePopupMenu(items);
9494 gtk_menu_set_active(GTK_MENU(m_popup), selectedIndex);

@@void WebPopupMenuProxyGtk::showPopupMenu(const IntRect& rect, TextDirection, dou
178178
179179void WebPopupMenuProxyGtk::hidePopupMenu()
180180{
 181 if (!m_popup)
 182 return;
 183
181184 gtk_menu_popdown(GTK_MENU(m_popup));
182185 resetTypeAheadFindState();
183186}

Source/WebKit2/UIProcess/gtk/WebPopupMenuProxyGtk.h

@@public:
4848 void hidePopupMenu() override;
4949 void cancelTracking() override;
5050
51 private:
 51protected:
5252 WebPopupMenuProxyGtk(GtkWidget*, WebPopupMenuProxy::Client&);
5353
 54 GtkWidget* m_webView { nullptr };
 55
 56private:
5457 void setCurrentlySelectedMenuItem(GtkWidget* item) { m_currentlySelectedMenuItem = item; }
5558 GtkAction* createGtkActionForMenuItem(const WebPopupItem&, int itemIndex);
5659 void populatePopupMenu(const Vector<WebPopupItem>&);

@@private:
6467 static gboolean keyPressEventCallback(GtkWidget*, GdkEventKey*, WebPopupMenuProxyGtk*);
6568 static void menuUnmappedCallback(GtkWidget*, WebPopupMenuProxyGtk*);
6669
67  GtkWidget* m_webView { nullptr };
6870 GtkWidget* m_popup { nullptr };
6971
7072 RunLoop::Timer<WebPopupMenuProxyGtk> m_dismissMenuTimer;

Tools/ChangeLog

 12017-06-04 Carlos Garcia Campos <cgarcia@igalia.com>
 2
 3 [GTK] Add API to allow overriding popup menus
 4 https://bugs.webkit.org/show_bug.cgi?id=172905
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 Add a unit test to check the new API.
 9
 10 * TestWebKitAPI/Tests/WebKit2Gtk/CMakeLists.txt:
 11 * TestWebKitAPI/Tests/WebKit2Gtk/TestOptionMenu.cpp: Added.
 12 (OptionMenuTest::OptionMenuTest):
 13 (OptionMenuTest::~OptionMenuTest):
 14 (OptionMenuTest::destroyMenu):
 15 (OptionMenuTest::showOptionMenuCallback):
 16 (OptionMenuTest::menuCloseCallback):
 17 (OptionMenuTest::showOptionMenu):
 18 (OptionMenuTest::clickAtPositionAndWaitUntilOptionMenuShown):
 19 (OptionMenuTest::close):
 20 (OptionMenuTest::activateItem):
 21 (OptionMenuTest::selectItem):
 22 (testOptionMenuSimple):
 23 (testOptionMenuGroups):
 24 (testOptionMenuActivate):
 25 (testOptionMenuSelect):
 26 (beforeAll):
 27 (afterAll):
 28
1292017-06-01 Carlos Garcia Campos <cgarcia@igalia.com>
230
331 [GTK] Bump GTK+ and its dependencies in jhbuild

Tools/TestWebKitAPI/Tests/WebKit2Gtk/CMakeLists.txt

@@ADD_WK2_TEST(TestInspector TestInspector.cpp)
114114ADD_WK2_TEST(TestInspectorServer TestInspectorServer.cpp)
115115ADD_WK2_TEST(TestLoaderClient TestLoaderClient.cpp)
116116ADD_WK2_TEST(TestMultiprocess TestMultiprocess.cpp)
 117ADD_WK2_TEST(TestOptionMenu TestOptionMenu.cpp)
117118ADD_WK2_TEST(TestPrinting TestPrinting.cpp)
118119ADD_WK2_TEST(TestResources TestResources.cpp)
119120ADD_WK2_TEST(TestSSL TestSSL.cpp)

Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestOptionMenu.cpp

 1/*
 2 * Copyright (C) 2017 Igalia S.L.
 3 *
 4 * This library is free software; you can redistribute it and/or
 5 * modify it under the terms of the GNU Lesser General Public
 6 * License as published by the Free Software Foundation; either
 7 * version 2,1 of the License, or (at your option) any later version.
 8 *
 9 * This library is distributed in the hope that it will be useful,
 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 12 * Library General Public License for more details.
 13 *
 14 * You should have received a copy of the GNU Library General Public License
 15 * along with this library; see the file COPYING.LIB. If not, write to
 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 17 * Boston, MA 02110-1301, USA.
 18 */
 19
 20#include "config.h"
 21#include "WebViewTest.h"
 22
 23#include <wtf/RunLoop.h>
 24
 25class OptionMenuTest : public WebViewTest {
 26public:
 27 MAKE_GLIB_TEST_FIXTURE(OptionMenuTest);
 28
 29 OptionMenuTest()
 30 {
 31 g_signal_connect(m_webView, "show-option-menu", G_CALLBACK(showOptionMenuCallback), this);
 32 }
 33
 34 ~OptionMenuTest()
 35 {
 36 g_signal_handlers_disconnect_matched(m_webView, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this);
 37 if (m_menu)
 38 close();
 39 }
 40
 41 void destroyMenu()
 42 {
 43 if (!m_menu)
 44 return;
 45
 46 g_signal_handlers_disconnect_matched(m_menu.get(), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this);
 47 m_menu = nullptr;
 48 }
 49
 50 static gboolean showOptionMenuCallback(WebKitWebView* webView, WebKitOptionMenu* menu, GdkEvent* event, GdkRectangle* rect, OptionMenuTest* test)
 51 {
 52 g_assert(test->m_webView == webView);
 53 g_assert(rect);
 54 g_assert(WEBKIT_IS_OPTION_MENU(menu));
 55 test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(menu));
 56 test->showOptionMenu(menu, rect);
 57 return TRUE;
 58 }
 59
 60 static void menuCloseCallback(WebKitOptionMenu* menu, OptionMenuTest* test)
 61 {
 62 g_assert(test->m_menu.get() == menu);
 63 test->destroyMenu();
 64 }
 65
 66 void showOptionMenu(WebKitOptionMenu* menu, GdkRectangle* rect)
 67 {
 68 m_rectangle = *rect;
 69 m_menu = menu;
 70 g_signal_connect(m_menu.get(), "close", G_CALLBACK(menuCloseCallback), this);
 71 g_main_loop_quit(m_mainLoop);
 72 }
 73
 74 void clickAtPositionAndWaitUntilOptionMenuShown(int x, int y)
 75 {
 76 m_menu = nullptr;
 77 RunLoop::main().dispatch([this, x, y] { clickMouseButton(x, y); });
 78 g_main_loop_run(m_mainLoop);
 79 }
 80
 81 void close()
 82 {
 83 g_assert(m_menu.get());
 84 webkit_option_menu_close(m_menu.get());
 85 g_assert(!m_menu.get());
 86 }
 87
 88 void activateItem(unsigned item)
 89 {
 90 g_assert(m_menu.get());
 91 webkit_option_menu_activate_item(m_menu.get(), item);
 92 g_assert(m_menu.get());
 93 }
 94
 95 void selectItem(unsigned item)
 96 {
 97 g_assert(m_menu.get());
 98 webkit_option_menu_select_item(m_menu.get(), item);
 99 g_assert(m_menu.get());
 100 }
 101
 102 GRefPtr<WebKitOptionMenu> m_menu;
 103 GdkRectangle m_rectangle;
 104};
 105
 106static void testOptionMenuSimple(OptionMenuTest* test, gconstpointer)
 107{
 108 static const char html[] =
 109 "<html><body>"
 110 " <select style='position:absolute; left:1; top:10'>"
 111 " <option title='The Foo Option'>Foo</option>"
 112 " <option selected>Bar</option>"
 113 " <option disabled>Baz</option>"
 114 " </select></body></html>";
 115 test->showInWindowAndWaitUntilMapped();
 116 test->loadHtml(html, nullptr);
 117 test->waitUntilLoadFinished();
 118
 119 test->clickAtPositionAndWaitUntilOptionMenuShown(5, 15);
 120 g_assert(WEBKIT_IS_OPTION_MENU(test->m_menu.get()));
 121 g_assert_cmpint(webkit_option_menu_get_n_items(test->m_menu.get()), ==, 3);
 122 auto* item = webkit_option_menu_get_item(test->m_menu.get(), 0);
 123 g_assert_cmpstr(webkit_option_menu_item_get_label(item), ==, "Foo");
 124 g_assert_cmpstr(webkit_option_menu_item_get_tooltip(item), ==, "The Foo Option");
 125 g_assert(!webkit_option_menu_item_is_group_label(item));
 126 g_assert(!webkit_option_menu_item_is_group_child(item));
 127 g_assert(webkit_option_menu_item_is_enabled(item));
 128 g_assert(!webkit_option_menu_item_is_selected(item));
 129 item = webkit_option_menu_get_item(test->m_menu.get(), 1);
 130 g_assert_cmpstr(webkit_option_menu_item_get_label(item), ==, "Bar");
 131 g_assert(!webkit_option_menu_item_get_tooltip(item));
 132 g_assert(!webkit_option_menu_item_is_group_label(item));
 133 g_assert(!webkit_option_menu_item_is_group_child(item));
 134 g_assert(webkit_option_menu_item_is_enabled(item));
 135 g_assert(webkit_option_menu_item_is_selected(item));
 136 item = webkit_option_menu_get_item(test->m_menu.get(), 2);
 137 g_assert_cmpstr(webkit_option_menu_item_get_label(item), ==, "Baz");
 138 g_assert(!webkit_option_menu_item_get_tooltip(item));
 139 g_assert(!webkit_option_menu_item_is_group_label(item));
 140 g_assert(!webkit_option_menu_item_is_group_child(item));
 141 g_assert(!webkit_option_menu_item_is_enabled(item));
 142 g_assert(!webkit_option_menu_item_is_selected(item));
 143
 144 test->close();
 145 g_assert(!test->m_menu.get());
 146}
 147
 148static void testOptionMenuGroups(OptionMenuTest* test, gconstpointer)
 149{
 150 static const char html[] =
 151 "<html><body>"
 152 " <select style='position:absolute; left:1; top:10'>"
 153 " <option>Root</option>"
 154 " <optgroup label='Group 1'>"
 155 " <option>Child 1-1</option>"
 156 " <option disabled>Child 1-2</option>"
 157 " </optgroup>"
 158 " <optgroup label='Group 2'>"
 159 " <option selected>Child 2-1</option>"
 160 " <option>Child 2-2</option>"
 161 " </optgroup>"
 162 " <option>Tail</option>"
 163 " </select></body></html>";
 164 test->showInWindowAndWaitUntilMapped();
 165 test->loadHtml(html, nullptr);
 166 test->waitUntilLoadFinished();
 167
 168 test->clickAtPositionAndWaitUntilOptionMenuShown(5, 15);
 169 g_assert(WEBKIT_IS_OPTION_MENU(test->m_menu.get()));
 170 g_assert_cmpint(webkit_option_menu_get_n_items(test->m_menu.get()), ==, 8);
 171 auto* item = webkit_option_menu_get_item(test->m_menu.get(), 0);
 172 g_assert_cmpstr(webkit_option_menu_item_get_label(item), ==, "Root");
 173 g_assert(!webkit_option_menu_item_get_tooltip(item));
 174 g_assert(!webkit_option_menu_item_is_group_label(item));
 175 g_assert(!webkit_option_menu_item_is_group_child(item));
 176 g_assert(webkit_option_menu_item_is_enabled(item));
 177 g_assert(!webkit_option_menu_item_is_selected(item));
 178 item = webkit_option_menu_get_item(test->m_menu.get(), 1);
 179 g_assert_cmpstr(webkit_option_menu_item_get_label(item), ==, "Group 1");
 180 g_assert(!webkit_option_menu_item_get_tooltip(item));
 181 g_assert(webkit_option_menu_item_is_group_label(item));
 182 g_assert(!webkit_option_menu_item_is_group_child(item));
 183 g_assert(!webkit_option_menu_item_is_enabled(item));
 184 g_assert(!webkit_option_menu_item_is_selected(item));
 185 item = webkit_option_menu_get_item(test->m_menu.get(), 2);
 186 g_assert_cmpstr(webkit_option_menu_item_get_label(item), ==, "Child 1-1");
 187 g_assert(!webkit_option_menu_item_get_tooltip(item));
 188 g_assert(!webkit_option_menu_item_is_group_label(item));
 189 g_assert(webkit_option_menu_item_is_group_child(item));
 190 g_assert(webkit_option_menu_item_is_enabled(item));
 191 g_assert(!webkit_option_menu_item_is_selected(item));
 192 item = webkit_option_menu_get_item(test->m_menu.get(), 3);
 193 g_assert_cmpstr(webkit_option_menu_item_get_label(item), ==, "Child 1-2");
 194 g_assert(!webkit_option_menu_item_get_tooltip(item));
 195 g_assert(!webkit_option_menu_item_is_group_label(item));
 196 g_assert(webkit_option_menu_item_is_group_child(item));
 197 g_assert(!webkit_option_menu_item_is_enabled(item));
 198 g_assert(!webkit_option_menu_item_is_selected(item));
 199 item = webkit_option_menu_get_item(test->m_menu.get(), 4);
 200 g_assert_cmpstr(webkit_option_menu_item_get_label(item), ==, "Group 2");
 201 g_assert(!webkit_option_menu_item_get_tooltip(item));
 202 g_assert(webkit_option_menu_item_is_group_label(item));
 203 g_assert(!webkit_option_menu_item_is_group_child(item));
 204 g_assert(!webkit_option_menu_item_is_enabled(item));
 205 g_assert(!webkit_option_menu_item_is_selected(item));
 206 item = webkit_option_menu_get_item(test->m_menu.get(), 5);
 207 g_assert_cmpstr(webkit_option_menu_item_get_label(item), ==, "Child 2-1");
 208 g_assert(!webkit_option_menu_item_get_tooltip(item));
 209 g_assert(!webkit_option_menu_item_is_group_label(item));
 210 g_assert(webkit_option_menu_item_is_group_child(item));
 211 g_assert(webkit_option_menu_item_is_enabled(item));
 212 g_assert(webkit_option_menu_item_is_selected(item));
 213 item = webkit_option_menu_get_item(test->m_menu.get(), 6);
 214 g_assert_cmpstr(webkit_option_menu_item_get_label(item), ==, "Child 2-2");
 215 g_assert(!webkit_option_menu_item_get_tooltip(item));
 216 g_assert(!webkit_option_menu_item_is_group_label(item));
 217 g_assert(webkit_option_menu_item_is_group_child(item));
 218 g_assert(webkit_option_menu_item_is_enabled(item));
 219 g_assert(!webkit_option_menu_item_is_selected(item));
 220 item = webkit_option_menu_get_item(test->m_menu.get(), 7);
 221 g_assert_cmpstr(webkit_option_menu_item_get_label(item), ==, "Tail");
 222 g_assert(!webkit_option_menu_item_get_tooltip(item));
 223 g_assert(!webkit_option_menu_item_is_group_label(item));
 224 g_assert(!webkit_option_menu_item_is_group_child(item));
 225 g_assert(webkit_option_menu_item_is_enabled(item));
 226 g_assert(!webkit_option_menu_item_is_selected(item));
 227}
 228
 229static void testOptionMenuActivate(OptionMenuTest* test, gconstpointer)
 230{
 231 static const char html[] =
 232 "<html><body>"
 233 " <select id='combo' style='position:absolute; left:1; top:10'>"
 234 " <option>Foo</option>"
 235 " <option>Bar</option>"
 236 " <option>Baz</option>"
 237 " </select></body></html>";
 238 test->showInWindowAndWaitUntilMapped();
 239 test->loadHtml(html, nullptr);
 240 test->waitUntilLoadFinished();
 241
 242 test->clickAtPositionAndWaitUntilOptionMenuShown(5, 15);
 243 g_assert(WEBKIT_IS_OPTION_MENU(test->m_menu.get()));
 244 g_assert_cmpint(webkit_option_menu_get_n_items(test->m_menu.get()), ==, 3);
 245 test->activateItem(1);
 246 auto* result = test->runJavaScriptAndWaitUntilFinished("document.getElementById('combo').selectedIndex", nullptr);
 247 g_assert(result);
 248 g_assert_cmpfloat(WebViewTest::javascriptResultToNumber(result), ==, 1);
 249
 250 // We should close the menu after activate, further activates will be ignored.
 251 test->activateItem(2);
 252 result = test->runJavaScriptAndWaitUntilFinished("document.getElementById('combo').selectedIndex", nullptr);
 253 g_assert(result);
 254 g_assert_cmpfloat(WebViewTest::javascriptResultToNumber(result), ==, 1);
 255
 256 test->close();
 257}
 258
 259static void testOptionMenuSelect(OptionMenuTest* test, gconstpointer)
 260{
 261 static const char html[] =
 262 "<html><body>"
 263 " <select id='combo' style='position:absolute; left:1; top:10'>"
 264 " <option>Foo</option>"
 265 " <option>Bar</option>"
 266 " <option>Baz</option>"
 267 " </select></body></html>";
 268 test->showInWindowAndWaitUntilMapped();
 269 test->loadHtml(html, nullptr);
 270 test->waitUntilLoadFinished();
 271
 272 test->clickAtPositionAndWaitUntilOptionMenuShown(5, 15);
 273 g_assert(WEBKIT_IS_OPTION_MENU(test->m_menu.get()));
 274 g_assert_cmpint(webkit_option_menu_get_n_items(test->m_menu.get()), ==, 3);
 275
 276 // Select item changes the combo text, but not the currently selected item.
 277 test->selectItem(2);
 278 auto* result = test->runJavaScriptAndWaitUntilFinished("document.getElementById('combo').selectedIndex", nullptr);
 279 g_assert(result);
 280 g_assert_cmpfloat(WebViewTest::javascriptResultToNumber(result), ==, 0);
 281
 282 // It can be called multiple times.
 283 test->selectItem(1);
 284 result = test->runJavaScriptAndWaitUntilFinished("document.getElementById('combo').selectedIndex", nullptr);
 285 g_assert(result);
 286 g_assert_cmpfloat(WebViewTest::javascriptResultToNumber(result), ==, 0);
 287
 288 // And closing the menu activates the currently selected item.
 289 test->close();
 290 result = test->runJavaScriptAndWaitUntilFinished("document.getElementById('combo').selectedIndex", nullptr);
 291 g_assert(result);
 292 g_assert_cmpfloat(WebViewTest::javascriptResultToNumber(result), ==, 1);
 293}
 294
 295void beforeAll()
 296{
 297 OptionMenuTest::add("WebKitWebView", "option-menu-simple", testOptionMenuSimple);
 298 OptionMenuTest::add("WebKitWebView", "option-menu-groups", testOptionMenuGroups);
 299 OptionMenuTest::add("WebKitWebView", "option-menu-activate", testOptionMenuActivate);
 300 OptionMenuTest::add("WebKitWebView", "option-menu-select", testOptionMenuSelect);
 301}
 302
 303void afterAll()
 304{
 305}