Skip to content

Commit 8de30ff

Browse files
[GTK] Misplaced right click menu on web page due to deprecated gtk_menu_popup()
https://bugs.webkit.org/show_bug.cgi?id=170553 Patch by Adrian Perez de Castro <[email protected]> on 2017-04-10 Reviewed by Michael Catanzaro. Source/WebKit2: Use gtk_menu_popup_at_pointer() and gtk_menu_popup_at_rect() when building with GTK+ 3.22 or newer. This allows the Wayland GTK+ backend to properly position popup menus, and also avoids using functions which were deprecated starting at that GTK+ release. * UIProcess/gtk/WebContextMenuProxyGtk.cpp: (WebKit::WebContextMenuProxyGtk::show): Use gtk_menu_popup_at_pointer() as there is always a pointer event that can be passed to it. * UIProcess/gtk/WebPopupMenuProxyGtk.cpp: (WebKit::WebPopupMenuProxyGtk::showPopupMenu): Use gtk_menu_popup_at_rect(), using the coordinates of the control passed as reference rectangle. Some conditional code is needed because with newer GTK+ versions a relative offset instead of an absolute position is needed. Tools: Use gtk_menu_popup_at_pointer() and gtk_menu_popup_at_rect() when building with GTK+ 3.22 or newer. This allows the Wayland GTK+ backend to properly position popup menus, and also avoids using functions which were deprecated starting at that GTK+ release. * MiniBrowser/gtk/BrowserSearchBar.c: (searchEntryMenuIconPressedCallback): Update MiniBrowser to use gtk_menu_popup_at_pointer(). git-svn-id: http://svn.webkit.org/repository/webkit/trunk@215190 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent ed21ef7 commit 8de30ff

File tree

5 files changed

+73
-3
lines changed

5 files changed

+73
-3
lines changed

Source/WebKit2/ChangeLog

+19
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,22 @@
1+
2017-04-10 Adrian Perez de Castro <[email protected]>
2+
3+
[GTK] Misplaced right click menu on web page due to deprecated gtk_menu_popup()
4+
https://bugs.webkit.org/show_bug.cgi?id=170553
5+
6+
Reviewed by Michael Catanzaro.
7+
8+
Use gtk_menu_popup_at_pointer() and gtk_menu_popup_at_rect() when building with GTK+ 3.22 or
9+
newer. This allows the Wayland GTK+ backend to properly position popup menus, and also avoids
10+
using functions which were deprecated starting at that GTK+ release.
11+
12+
* UIProcess/gtk/WebContextMenuProxyGtk.cpp:
13+
(WebKit::WebContextMenuProxyGtk::show): Use gtk_menu_popup_at_pointer() as there is always a
14+
pointer event that can be passed to it.
15+
* UIProcess/gtk/WebPopupMenuProxyGtk.cpp:
16+
(WebKit::WebPopupMenuProxyGtk::showPopupMenu): Use gtk_menu_popup_at_rect(), using the coordinates
17+
of the control passed as reference rectangle. Some conditional code is needed because with newer
18+
GTK+ versions a relative offset instead of an absolute position is needed.
19+
120
2017-04-10 Adrian Perez de Castro <[email protected]>
221

322
[GTK] Opening a popup menu does not pre-select the active item

Source/WebKit2/UIProcess/gtk/WebContextMenuProxyGtk.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -167,8 +167,13 @@ void WebContextMenuProxyGtk::show()
167167
NativeWebMouseEvent* mouseEvent = m_page->currentlyProcessedMouseDownEvent();
168168
const GdkEvent* event = mouseEvent ? mouseEvent->nativeEvent() : 0;
169169
gtk_menu_attach_to_widget(m_menu, GTK_WIDGET(m_webView), nullptr);
170+
171+
#if GTK_CHECK_VERSION(3, 22, 0)
172+
gtk_menu_popup_at_pointer(m_menu, event);
173+
#else
170174
gtk_menu_popup(m_menu, nullptr, nullptr, reinterpret_cast<GtkMenuPositionFunc>(menuPositionFunction), this,
171175
event ? event->button.button : 3, event ? event->button.time : GDK_CURRENT_TIME);
176+
#endif
172177
}
173178

174179
void WebContextMenuProxyGtk::showContextMenuWithItems(const Vector<WebContextMenuItemData>& items)
@@ -204,6 +209,7 @@ WebContextMenuProxyGtk::~WebContextMenuProxyGtk()
204209
gtk_widget_destroy(GTK_WIDGET(m_menu));
205210
}
206211

212+
#if !GTK_CHECK_VERSION(3, 22, 0)
207213
void WebContextMenuProxyGtk::menuPositionFunction(GtkMenu* menu, gint* x, gint* y, gboolean* pushIn, WebContextMenuProxyGtk* popupMenu)
208214
{
209215
GtkRequisition menuSize;
@@ -220,6 +226,7 @@ void WebContextMenuProxyGtk::menuPositionFunction(GtkMenu* menu, gint* x, gint*
220226

221227
*pushIn = FALSE;
222228
}
229+
#endif
223230

224231
} // namespace WebKit
225232
#endif // ENABLE(CONTEXT_MENUS)

Source/WebKit2/UIProcess/gtk/WebPopupMenuProxyGtk.cpp

+27-3
Original file line numberDiff line numberDiff line change
@@ -95,22 +95,39 @@ void WebPopupMenuProxyGtk::showPopupMenu(const IntRect& rect, TextDirection, dou
9595

9696
resetTypeAheadFindState();
9797

98-
IntPoint menuPosition = convertWidgetPointToScreenPoint(m_webView, rect.location());
99-
menuPosition.move(0, rect.height());
100-
10198
// This approach follows the one in gtkcombobox.c.
10299
GtkRequisition requisition;
103100
gtk_widget_set_size_request(m_popup, -1, -1);
104101
gtk_widget_get_preferred_size(m_popup, &requisition, nullptr);
105102
gtk_widget_set_size_request(m_popup, std::max(rect.width(), requisition.width), -1);
106103

104+
// Reposition the menu after giving it a new width.
105+
gtk_menu_reposition(GTK_MENU(m_popup));
106+
107+
#if GTK_CHECK_VERSION(3, 22, 0)
108+
// With a recent GTK+ we calculate an offset from the position where the menu would
109+
// be normally popped up, and use it as value of the "rect-anchor-dy" property.
110+
// The code in gtkcombobox.c starts with the offset hardcoded as -2 as well.
111+
IntPoint menuPosition { 0, -2 };
112+
#else
113+
IntPoint menuPosition = convertWidgetPointToScreenPoint(m_webView, rect.location());
114+
menuPosition.move(0, rect.height());
115+
#endif
116+
107117
if (int itemCount = items.size()) {
108118
GUniquePtr<GList> children(gtk_container_get_children(GTK_CONTAINER(m_popup)));
109119
int i;
110120
GList* child;
111121
for (i = 0, child = children.get(); i < itemCount; i++, child = g_list_next(child)) {
122+
#if GTK_CHECK_VERSION(3, 22, 0)
123+
// Do not count the last one: we are using the top-left corner of the
124+
// item (GDK_GRAVITY_NORTH_WEST) as reference point of the popup.
125+
if (i >= selectedIndex)
126+
break;
127+
#else
112128
if (i > selectedIndex)
113129
break;
130+
#endif
114131

115132
GtkWidget* item = GTK_WIDGET(child->data);
116133
GtkRequisition itemRequisition;
@@ -123,6 +140,12 @@ void WebPopupMenuProxyGtk::showPopupMenu(const IntRect& rect, TextDirection, dou
123140
}
124141

125142
const GdkEvent* event = m_client->currentlyProcessedMouseDownEvent() ? m_client->currentlyProcessedMouseDownEvent()->nativeEvent() : nullptr;
143+
#if GTK_CHECK_VERSION(3, 22, 0)
144+
// Set the same properties that GTK+ uses itself for combo box popups.
145+
g_object_set(m_popup, "menu-type-hint", GDK_WINDOW_TYPE_HINT_COMBO, "rect-anchor-dy", menuPosition.y(), "anchor-hints", GDK_ANCHOR_SLIDE | GDK_ANCHOR_RESIZE, nullptr);
146+
const GdkRectangle referenceRect = { rect.x(), rect.y(), rect.width(), rect.height() };
147+
gtk_menu_popup_at_rect(GTK_MENU(m_popup), gtk_widget_get_window(m_webView), &referenceRect, GDK_GRAVITY_NORTH_WEST, GDK_GRAVITY_NORTH_WEST, event);
148+
#else
126149
gtk_menu_popup_for_device(GTK_MENU(m_popup), event ? gdk_event_get_device(event) : nullptr, nullptr, nullptr,
127150
[](GtkMenu*, gint* x, gint* y, gboolean* pushIn, gpointer userData) {
128151
// We can pass a pointer to the menuPosition local variable because the nested main loop ensures this is called in the function context.
@@ -132,6 +155,7 @@ void WebPopupMenuProxyGtk::showPopupMenu(const IntRect& rect, TextDirection, dou
132155
*pushIn = menuPosition->y() < 0;
133156
}, &menuPosition, nullptr, event && event->type == GDK_BUTTON_PRESS ? event->button.button : 1,
134157
event ? gdk_event_get_time(event) : GDK_CURRENT_TIME);
158+
#endif
135159

136160
// Now that the menu has a position, schedule a resize to make sure it's resized to fit vertically in the work area.
137161
gtk_widget_queue_resize(m_popup);

Tools/ChangeLog

+16
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
2017-04-10 Adrian Perez de Castro <[email protected]>
2+
3+
[GTK] Misplaced right click menu on web page due to deprecated gtk_menu_popup()
4+
https://bugs.webkit.org/show_bug.cgi?id=170553
5+
6+
Reviewed by Michael Catanzaro.
7+
8+
Use gtk_menu_popup_at_pointer() and gtk_menu_popup_at_rect() when
9+
building with GTK+ 3.22 or newer. This allows the Wayland GTK+ backend
10+
to properly position popup menus, and also avoids using functions
11+
which were deprecated starting at that GTK+ release.
12+
13+
* MiniBrowser/gtk/BrowserSearchBar.c:
14+
(searchEntryMenuIconPressedCallback):
15+
Update MiniBrowser to use gtk_menu_popup_at_pointer().
16+
117
2017-04-10 Wenson Hsieh <[email protected]>
218

319
REGRESSION (r214403): fast/events/drag-to-navigate.html and fast/events/only-valid-drop-targets-receive-file-drop.html failing

Tools/MiniBrowser/gtk/BrowserSearchBar.c

+4
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,12 @@ static void searchCloseButtonClickedCallback(BrowserSearchBar *searchBar)
9393
static void searchEntryMenuIconPressedCallback(BrowserSearchBar *searchBar, GtkEntryIconPosition iconPosition, GdkEvent *event)
9494
{
9595
if (iconPosition == GTK_ENTRY_ICON_PRIMARY) {
96+
#if GTK_CHECK_VERSION(3, 22, 0)
97+
gtk_menu_popup_at_pointer(GTK_MENU(searchBar->optionsMenu), event);
98+
#else
9699
GdkEventButton *eventButton = (GdkEventButton *)event;
97100
gtk_menu_popup(GTK_MENU(searchBar->optionsMenu), NULL, NULL, NULL, NULL, eventButton->button, eventButton->time);
101+
#endif
98102
}
99103
}
100104

0 commit comments

Comments
 (0)