GNOME Bugzilla – Bug 774148
Gtk.Popover misplacement in Wayland
Last modified: 2017-03-30 13:49:02 UTC
Created attachment 339399 [details] test.py Description of problem: When having a Gtk.Popover relative to a Gtk.Popover child, widget is misplaced in Wayland (no issue with Xorg). How reproducible: Run test.py (attachement) like this: python3 test.py Steps to Reproduce: 1. Click on "Click me" button 2. Click on "Click me again" button Actual results: Popover is misplaced Expected results: Popover placed at set_pointing_to() of set_relative_to() widget Additional info: GDK_BACKEND=x11 python3 test.py fix the issue
After some more testing, seems issue is only related to set_relative_to()
Seems issue comes from this code: https://mail.gnome.org/archives/commits-list/2014-December/msg04928.html gtk_widget_translate_coordinates (priv->widget, GTK_WIDGET (priv->window), rect.x, rect.y, &rect.x, &rect.y); gdk_window_get_origin (gtk_widget_get_window (GTK_WIDGET (popover)), &win_x, &win_y); sets unwanted values when having a popover pointing to a popover.
gtk_widget_translate_coordinates() fails (i.e. return FALSE) when the popover parent is another popover, and the coords are left unchanged, not translated.
Created attachment 344713 [details] [review] [PATCH] gtkwidget: return translated coords hen the GtkWidget hierarchy does not match the GdkWindow hierarchy, the GtkWidget code may find a common ancestor that cannot be found while traversing the GdkWindow tree. This happens with for example on Wayland, a GtkPopover has another GtkPopover as parent, in this case, the GdkWindow parent is the root window, whereas the GtkWidget parent is the other GtkPopover. That confuses the gtk_widget_translate_coordinates() logic which will bail out in this case and won't return the translated coordinates. For this particular corner case, translate the coordinates but still return FALSE. The existing GTK+ API for gtk_widget_translate_coordinates() states that it would return FALSE if either widget was not realized, or there was no common ancestor, in which case nothing is stored in the return variables, so this particular corner case should not affect the documented behavior. -- /!\ This is a corner case, some sort of a grey area in the documented behavior, I am not sure about the possible side-effects of this patch - But it seems to fix this particular issue with popover on Wayland...
Comment on attachment 344713 [details] [review] [PATCH] gtkwidget: return translated coords Uhm... I think I'd rather have gtk_widget_translate_coordinates() explicitly handle popover hierarchies than adding a third intermediate return state, tbh.
(In reply to Carlos Garnacho from comment #5) > Uhm... I think I'd rather have gtk_widget_translate_coordinates() explicitly > handle popover hierarchies than adding a third intermediate return state, > tbh. Yeah, I agree of course and actually it's even better to teach gdk_window_get_effective_parent() how to deal with subsurfaces :)
Created attachment 345232 [details] [review] [PATCH] gdkwindow: subsurface in gdk_window_get_effective_parent() When the GtkWidget hierarchy does not match the GdkWindow hierarchy, the GtkWidget code may find a common ancestor that cannot be found while traversing the GdkWindow tree using gdk_window_get_effective_parent(). This happens with for example on Wayland, a GtkPopover has another GtkPopover as parent, in this case, the GdkWindow parent is the root window, whereas the GtkWidget parent is the other GtkPopover. That confuses the gtk_widget_translate_coordinates() logic which will bail out in this case and won't return the translated coordinates. Make gdk_window_get_effective_parent() aware of subsurfaces and use the transient_for which represents the actual parent (whereas the parent might be pointing to the root window).
Carlos, is this on your list to review ?
Review of attachment 345232 [details] [review]: Given how gtk+3 subsurface windows work, I think this makes sense. Also works after testing with nested GtkPopovers and text handles.
Comment on attachment 345232 [details] [review] [PATCH] gdkwindow: subsurface in gdk_window_get_effective_parent() attachment 345232 [details] [review] pushed to branch gtk-3-22 as git commit e5b6375 - gdkwindow: subsurface in gdk_window_get_effective_parent()
Created attachment 346568 [details] [review] [PATCH master] gdkwindow: subsurface in gdk_window_get_effective_parent() Patch ported to current git master. git master got rid of offscreen windows, and of get_effective_parent() along with it...
Review of attachment 346568 [details] [review]: lets go with this for working popovers until we can clear up the whole popover vs subsurface vs toplevel situation
Comment on attachment 346568 [details] [review] [PATCH master] gdkwindow: subsurface in gdk_window_get_effective_parent() attachment 346568 [details] [review] pushed to git master as commit 19ce6a8 - gdkwindow: subsurface in gdk_window_get_parent()