After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 774148 - Gtk.Popover misplacement in Wayland
Gtk.Popover misplacement in Wayland
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Backend: Wayland
3.22.x
Other Linux
: Normal normal
: ---
Assigned To: gtk-bugs
gtk-bugs
Depends on:
Blocks:
 
 
Reported: 2016-11-09 15:14 UTC by Cédric Bellegarde
Modified: 2017-03-30 13:49 UTC
See Also:
GNOME target: ---
GNOME version: 3.21/3.22


Attachments
test.py (1.18 KB, text/plain)
2016-11-09 15:14 UTC, Cédric Bellegarde
  Details
[PATCH] gtkwidget: return translated coords (2.39 KB, patch)
2017-02-01 14:22 UTC, Olivier Fourdan
none Details | Review
[PATCH] gdkwindow: subsurface in gdk_window_get_effective_parent() (1.80 KB, patch)
2017-02-08 14:50 UTC, Olivier Fourdan
committed Details | Review
[PATCH master] gdkwindow: subsurface in gdk_window_get_effective_parent() (1.75 KB, patch)
2017-02-23 13:43 UTC, Olivier Fourdan
committed Details | Review

Description Cédric Bellegarde 2016-11-09 15:14:11 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
Comment 1 Cédric Bellegarde 2016-11-09 15:22:54 UTC
After some more testing, seems issue is only related to set_relative_to()
Comment 2 Cédric Bellegarde 2016-11-10 22:31:00 UTC
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.
Comment 3 Olivier Fourdan 2017-02-01 14:04:56 UTC
gtk_widget_translate_coordinates() fails (i.e. return FALSE) when the popover parent is another popover, and the coords are left unchanged, not translated.
Comment 4 Olivier Fourdan 2017-02-01 14:22:42 UTC
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 5 Carlos Garnacho 2017-02-07 16:09:57 UTC
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.
Comment 6 Olivier Fourdan 2017-02-08 14:49:22 UTC
(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 :)
Comment 7 Olivier Fourdan 2017-02-08 14:50:17 UTC
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).
Comment 8 Matthias Clasen 2017-02-15 22:56:04 UTC
Carlos, is this on your list to review ?
Comment 9 Carlos Garnacho 2017-02-17 18:28:41 UTC
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 10 Olivier Fourdan 2017-02-23 13:17:31 UTC
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()
Comment 11 Olivier Fourdan 2017-02-23 13:43:29 UTC
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...
Comment 12 Matthias Clasen 2017-03-30 13:41:20 UTC
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 13 Olivier Fourdan 2017-03-30 13:48:34 UTC
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()