GNOME Bugzilla – Bug 748951
popup menus are being displayed at wrong position
Last modified: 2015-06-10 03:30:27 UTC
In some gtk3 (3.16.2) applications popup menus are placed at wrong positions. Steps to reproduce: 1. open gnome-terminal in a gnome wayland session (configuration of Fedora 22) 2. right-click somewhere in the terminal Expected behavior: popup menu should be displayed with the top left corner at the mouse pointer What happens: popup menu is placed somewhere completely off the window. This also affects: evolution, calendar component (in all views) evolution, email component (folder list, mail list, mail preview) evolution, email composer yelp It does not effect: gedit, nautilus, gnome-system-monitor, evince, epiphany
*** Bug 747682 has been marked as a duplicate of this bug. ***
So the issue seems to be that gtk+ Wayland backend will fail to calculate a parent for popup menus not explicitly attached to a parent which happens if a "transfer window" is used for the popup grab. A possible work around is to call gtk_menu_attach_to_widget before gtk_menu_popup, which avoids trying to find the parent via the grabbed device. It seems to work with the reproduction case I have used (WebPopupMenuProxyGtk in WebKit2, reproduced with any <select>...</select> form). A proper solution I assume would be to rework how grabs are done in gtkmenu.c as it seem to have various X11 related grab logics in there (the reason for creating a transfer window being one?). An input only grab window in Wayland would probably not make much sense, since a popup gets an explict grab when it is created. Maybe also we could enable the Wayland backend to find the transfer window which has the device grab. The device would then find what window has the pointer focus. We never map the transfer window, so it wouldn't be the focus window, which might break some assumptions regarding that. Another semi related issue is that the GtkMenu API allows arbitrary positioning of the menu via the positioning callback. This is not the reason for the displacement of this bug since the global positioning issue is "worked around" in the Wayland backend. Any opinions on what path I should take here? I'm not familiar with reasoning behind the menu grab logic, and git blame tells me that part has not changed since 2002.
(In reply to Jonas Ådahl from comment #2) > Maybe also we could enable the Wayland backend to find the transfer window > which has the device grab. The device would then find what window has the > pointer focus. We never map the transfer window, so it wouldn't be the focus > window, which might break some assumptions regarding that. This connection seems to be already there, with a big "HACK" label on top. Making use of this connection to find the grab device makes the popup become proper xdg_popups, but at least for the WebKit2 case, the positioning is inconsistent with when running using the X11 backend.
> A possible work around is to call gtk_menu_attach_to_widget before gtk_menu_popup That is certainly what I would recommend for popups
Created attachment 304633 [details] [review] wayland: Don't try to guess the popup menu placement when it was set If a position was already explicitly set, don't try to guess the position of popup menus by looking at the pointer position, just use the set coordinates.
Created attachment 304634 [details] [review] wayland: Improve guessing of popup placement for detached popup menus If a menu was not attached to any widget, we try to calculate its position given where the grabbed pointer is and what window has its focus. Previously we failed to do so if a "transfer window" was used for the grab, and this patch adds a code path that, if the menu window itself didn't have the grab, look for the transfer window and get the grab device from there.
As far as my testing shows (testing with gtk3-widget-factory, various gtk3-demo demos, epiphany, yelp) doing things the way as with these patches fixes the behavior where before menus were incorrectly positioned. I have yet to see any regressions, which I imagine could happen if for some reason a popup that was not positioned relies on being placed relative to the pointer position. On the other hand, I'm not sure whether the was-positioned check is needed, or if we can rely on a gdk popup menu window always being positioned before being mapped. I'm also not aware of how to trigger the popup menu case where there is no transfer window and no parent widget.
Review of attachment 304633 [details] [review]: With that cleanup, good to go. ::: gdk/wayland/gdkwindow-wayland.c @@ +1205,3 @@ + grab_device, + &window->x, &window->y, NULL); + } Please move the */ to the next line, and drop the {} here.
Review of attachment 304634 [details] [review]: Other than the cosmetics, looks good to me., ::: gdk/wayland/gdkwindow-wayland.c @@ +1201,3 @@ + * to find that window to get the grab device. If so is the case + * the "transfer window" can be retrieved via the + * "gdk-attached-grab-window" associated data field. */ Please move the */ to the next line here.
Attachment 304633 [details] pushed as 9e46425 - wayland: Don't try to guess the popup menu placement when it was set Attachment 304634 [details] pushed as 8563545 - wayland: Improve guessing of popup placement for detached popup menus