Bug 1264355

Summary: [GTK3][Wayland] misplaced popup child windows
Product: [Fedora] Fedora Reporter: Martin Stransky <stransky>
Component: gtk3Assignee: Matthias Clasen <mclasen>
Status: CLOSED RAWHIDE QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 24CC: alexl, anton4linux, ccecchi, extras-qa, gecko-bugs-nobody, ipun, jadahl, johannespfrang, jorgeml, mclasen, ofourdan, stransky
Target Milestone: ---   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
URL: https://github.com/stransky/gecko-dev
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: 1260773
: 1269437 (view as bug list) Environment:
Last Closed: 2017-06-19 11:37:13 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On: 1260773    
Bug Blocks: 1054334    
Attachments:
Description Flags
testcase
none
Example
none
Another example using subsurface
none
Another example using subsurface none

Description Martin Stransky 2015-09-18 09:30:19 UTC
Created attachment 1074755 [details]
testcase

+++ This bug was initially created as a clone of Bug #1260773 +++

When popup window is created (menubar for instance), it's misplaced (rendered at 0,0). Works fine on broadway backend.

Comment 1 Martin Stransky 2015-09-25 10:34:17 UTC
Oliver, there's the reproducer you requested. Thanks.

Comment 2 Olivier Fourdan 2015-09-25 12:14:32 UTC
Thanks MArtrin, I'll take a look at the code, but just to make sure, there is no absolute positioning in Wayland by definition:

http://lists.freedesktop.org/archives/wayland-devel/2015-September/024410.html

Comment 4 Olivier Fourdan 2015-09-30 09:07:25 UTC
As mentioned in comment 2, there is no absolute positioning in Wayland, so a gtk_window_move() on a toplevel or a popup won't work as is.

You can achieve *relative* positioning when using either subsurfaces or XdgPopup.

Looking at gdk_wayland_window_map() implementation [1] we can see that gdk Wayland backend will automatically create an XdgPopup for things like GDK_WINDOW_TYPE_HINT_POPUP_MENU, GDK_WINDOW_TYPE_HINT_POPUP_MENU and GDK_WINDOW_TYPE_HINT_POPUP_MENU (with a grab which is expected with a menu) as done in e.g. gtk_menu_position() from gtkmenu.c [2]

Looking at the example provided, I am not sure if you trying to code a menu or a tooltip, but but for tooltips (which do not imply any sort of grab), gtk uses a private API gtk_window_set_use_subsurface() which is private and not usable in regular applications.

[1] https://git.gnome.org/browse/gtk+/tree/gdk/wayland/gdkwindow-wayland.c?id=3.18.0#n1220
[2] https://git.gnome.org/browse/gtk+/tree/gtk/gtkmenu.c?id=3.18.0#n4460

Comment 5 Olivier Fourdan 2015-09-30 09:09:31 UTC
Sorry I meant "[...] gdk Wayland backend will automatically create an XdgPopup for things like GDK_WINDOW_TYPE_HINT_POPUP_MENU, GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU or GDK_WINDOW_TYPE_HINT_COMBO"

Comment 6 Martin Stransky 2015-09-30 09:13:24 UTC
Yes, Firefox uses that code to create popup menus, tooltips and so.

Comment 7 Martin Stransky 2015-09-30 09:18:47 UTC
And what about the gtk_window_resize()? Is it also unsupported on Wayland? 

btw. Those code is a regular part of Gtk3 documentation - how is possible that it "just doesn't work" without any notice there? I wonder how do you expect people will switch to Wayland with such glitches...

Comment 8 Olivier Fourdan 2015-09-30 12:40:49 UTC
(In reply to Martin Stransky from comment #7)
> And what about the gtk_window_resize()? Is it also unsupported on Wayland? 

gtk_window_resize() should work AFAIK. 

There can be bugs though (e.g. https://bugzilla.gnome.org/show_bug.cgi?id=755051) but it works on weston.

> btw. Those code is a regular part of Gtk3 documentation
> - how is possible that it "just doesn't work" without any notice there?

I think it's just because the documentation predates Wayland.

> I wonder how do you expect people will switch to Wayland with such glitches...

It's not a glitch, it's a design decision in Wayland, Wayland is not X11 (I suspect it's even one of the Wayland's raison d'etre) so it's not 1-to-1 mapping in design.

But you can join the current discussion upstream that I mentioned in comment 2 [1] and weigh in to try to change that :-)

[1] http://lists.freedesktop.org/archives/wayland-devel/2015-September/024484.html

Comment 9 Martin Stransky 2015-09-30 19:01:34 UTC
Okay, I updated the testcase with:

    shell = gtk_window_new(GTK_WINDOW_POPUP);
    gtk_window_set_type_hint (GTK_WINDOW(shell), GDK_WINDOW_TYPE_HINT_POPUP_MENU);
    gtk_window_set_transient_for(GTK_WINDOW(shell),window);
    gtk_widget_set_app_paintable(shell, FALSE);
    gtk_window_move(shell,0,0);
    gtk_window_resize(shell,500,500);
    gtk_widget_show_all (GTK_WIDGET(shell));

so the hints are set, then moved/resized. Resize works, but movement does not. Any idea? I'm on F23 with latest updates now.

Comment 10 Olivier Fourdan 2015-09-30 21:08:25 UTC
(In reply to Martin Stransky from comment #9)
> Okay, I updated the testcase with:
> 
>     shell = gtk_window_new(GTK_WINDOW_POPUP);
>     gtk_window_set_type_hint (GTK_WINDOW(shell),
> GDK_WINDOW_TYPE_HINT_POPUP_MENU);
>     gtk_window_set_transient_for(GTK_WINDOW(shell),window);
>     gtk_widget_set_app_paintable(shell, FALSE);
>     gtk_window_move(shell,0,0);
>     gtk_window_resize(shell,500,500);
>     gtk_widget_show_all (GTK_WIDGET(shell));
> 
> so the hints are set, then moved/resized. Resize works, but movement does
> not. Any idea? I'm on F23 with latest updates now.

You most likely need a grab for a menu, see https://git.gnome.org/browse/gtk+/tree/gdk/wayland/gdkwindow-wayland.c?id=3.18.0#n1285

          if (grab_input_seat && 
              (impl->hint == GDK_WINDOW_TYPE_HINT_POPUP_MENU ||
               impl->hint == GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU ||
               impl->hint == GDK_WINDOW_TYPE_HINT_COMBO))

Comment 11 Martin Stransky 2015-10-01 08:17:18 UTC
What's the grab_input_seat? Call gtk_grab_add() to the popup window does not help here:

    shell = gtk_window_new(GTK_WINDOW_POPUP);
    gtk_window_set_type_hint (GTK_WINDOW(shell), GDK_WINDOW_TYPE_HINT_POPUP_MENU);
    gtk_grab_add(GTK_WINDOW(shell));
    gtk_window_set_transient_for(GTK_WINDOW(shell),window);
    gtk_widget_set_app_paintable(shell, FALSE);
    gtk_window_move(shell,0,0);
    gtk_window_resize(shell,500,500);
    gtk_widget_show_all (GTK_WIDGET(shell));

Comment 12 Olivier Fourdan 2015-10-07 07:44:58 UTC
Not forgotten, but it's quite difficult to come up with something working as you might expect it. gtk_grab_add() won't work for this as this is not what the wayland gdk backends expects,  but that's not the main problem, the problem is that xdg_popup requires a serial that would be provided by a user action so that doesn;t work as its at startup anyway.

But again, expecting coordinates to work on Wayland is a bit of a hack and won't work in many cases, and if it does it will be a hack that works only in some corner cases and with relative coordinates anyway, and for popup windows.

Ideally, Firefox should not try to re-invent those widgets and should rely on gtk+ widgets, ie tooltips and popup menus are available in gtk and work on Wayland so Firefox should use those instead of trying to come up with its own.

Comment 13 Martin Stransky 2015-10-07 07:58:11 UTC
(In reply to Olivier Fourdan from comment #12)
> Not forgotten, but it's quite difficult to come up with something working as
> you might expect it. gtk_grab_add() won't work for this as this is not what
> the wayland gdk backends expects,  but that's not the main problem, the
> problem is that xdg_popup requires a serial that would be provided by a user
> action so that doesn;t work as its at startup anyway.
> 
> But again, expecting coordinates to work on Wayland is a bit of a hack and
> won't work in many cases, and if it does it will be a hack that works only
> in some corner cases and with relative coordinates anyway, and for popup
> windows.

I think the global coordinates missing are okay but one could expect the child popup window can be positioned by application. That change seems to be too much radical to me.
 
> Ideally, Firefox should not try to re-invent those widgets and should rely
> on gtk+ widgets, ie tooltips and popup menus are available in gtk and work
> on Wayland so Firefox should use those instead of trying to come up with its
> own.

Yes, that would fix that. But unfortunately the code is shared across platforms so such change (use regular menus and so) would also need a radical architectural changes for Windows/MacOS. I don't think Mozilla even think of that. More likely Firefox may abandon the toolkit elements and will draw those by itself like Chrome does.

Comment 14 Jonas Ådahl 2015-10-07 08:32:45 UTC
(In reply to Martin Stransky from comment #13)
> (In reply to Olivier Fourdan from comment #12)
> > Not forgotten, but it's quite difficult to come up with something working as
> > you might expect it. gtk_grab_add() won't work for this as this is not what
> > the wayland gdk backends expects,  but that's not the main problem, the
> > problem is that xdg_popup requires a serial that would be provided by a user
> > action so that doesn;t work as its at startup anyway.
> > 
> > But again, expecting coordinates to work on Wayland is a bit of a hack and
> > won't work in many cases, and if it does it will be a hack that works only
> > in some corner cases and with relative coordinates anyway, and for popup
> > windows.
> 
> I think the global coordinates missing are okay but one could expect the
> child popup window can be positioned by application. That change seems to be
> too much radical to me.

As long as you show the parent window before the popup, call gtk_window_move on the popup before showing it, and show the popup as a response to a user event, the popup should be placed correctly. Are you doing all those thnigs?

Comment 15 Olivier Fourdan 2015-10-07 08:46:20 UTC
Created attachment 1080549 [details]
Example

(In reply to Jonas Ådahl from comment #14)
> As long as you show the parent window before the popup, call gtk_window_move
> on the popup before showing it, and show the popup as a response to a user
> event, the popup should be placed correctly. Are you doing all those thnigs?

The problem is that the creation of the xdg_popup is not controlled directly by the higher layers (ie gtk), gdkwayland itself will decide depending on certain types of windows and if there is a grab. But gtk_grab_add() is not what gdkwayland expects so that won't suffice.

I am attaching an example that works for the xdg_popup, just press inside the window to show a popup at the pointer location. It's still rough on the edges and probably wrong in many respects but it gives an idea on how to hack that with gdk wayland backend.

But again, I reckon it would be better to rely on gtk widgets for all this.

Comment 16 Olivier Fourdan 2015-10-08 10:25:09 UTC
Created attachment 1080963 [details]
Another example using subsurface

Subsurface do not need any grab so it might be better suited for e.g. tooltips and the like.

Note, placement is *relative* to the parent window.

Please let me know if that helps...

Comment 17 Olivier Fourdan 2015-10-08 10:27:25 UTC
Created attachment 1080964 [details]
Another example using subsurface

(same with a bit of clean-up)

Comment 18 Martin Stransky 2015-10-08 10:41:28 UTC
Thanks, I'll check that.

Comment 19 Jonas Ådahl 2015-10-19 03:39:21 UTC
FYI, with the current gtk+ master, there is nothing needed to make the tooltips work. Popups will still need a device grab and be triggered in response to a user interaction.

Comment 20 Martin Stransky 2015-10-19 09:25:00 UTC
Can I get the master somewhere? I have Fedora 23 Beta - how can I install it here?

Comment 21 Olivier Fourdan 2015-10-19 13:16:09 UTC
This might help: http://www.gtk.org/download/#BleedingEdge

FYI, I just tried FF from your github repo with gtk+ master and the tooltips are rightfully placed as expected under Weston.

Comment 22 Jonas Ådahl 2015-10-20 14:20:13 UTC
(In reply to Martin Stransky from comment #20)
> Can I get the master somewhere? I have Fedora 23 Beta - how can I install it
> here?

I created this build. It is gtk+ 3.18.2 with the two patches fixing the subsurface mapping applied: http://copr.fedoraproject.org/coprs/jadahl/gtk3/build/128948/

Comment 23 Martin Stransky 2015-10-21 08:58:54 UTC
Hm, that's interesting. I tested that on Weston but the tooltips are shown at random position (but it's not the default 0,0 as before).

On gnome-shell on wayland it crashes immediately at:
#0  0x00007ffff0876e29 in wl_proxy_marshal () at /lib64/libwayland-client.so.0
#1  0x00007ffff452b1d1 in gdk_wayland_window_attach_image (y=0, x=0, buffer=<optimized out>, wl_surface=<optimized out>)
    at /usr/include/wayland-client-protocol.h:1474
#2  0x00007ffff452b1d1 in gdk_wayland_window_attach_image (window=window@entry=0x7fffbeb7fad0) at gdkwindow-wayland.c:565
#3  0x00007ffff452b294 in gdk_window_impl_wayland_end_paint (window=0x7fffbeb7fad0) at gdkwindow-wayland.c:655
#4  0x00007ffff44ed598 in gdk_window_end_paint (window=0x7fffbeb7fad0) at gdkwindow.c:3106
#5  0x00007ffff49883fb in gtk_main_do_event (event=0x7fffffffbd90) at gtkmain.c:1771
#6  0x00007ffff44e49f8 in _gdk_window_process_updates_recurse_helper (window=0x7fffbeb7fad0, expose_region=<optimized out>)
    at gdkwindow.c:3589
#7  0x00007ffff44e5b2c in gdk_window_process_updates_internal (window=0x7fffbeb7fad0) at gdkwindow.c:3734
#8  0x00007ffff44e5ce3 in gdk_window_process_updates_with_mode (window=<optimized out>, recurse_mode=<optimized out>)
    at gdkwindow.c:3935
#9  0x00007ffff1e309e4 in _g_closure_invoke_va () at /lib64/libgobject-2.0.so.0
#10 0x00007ffff1e4b2cd in g_signal_emit_valist () at /lib64/libgobject-2.0.so.0
#11 0x00007ffff1e4bdd5 in g_signal_emit_by_name () at /lib64/libgobject-2.0.so.0
#12 0x00007ffff44ded47 in gdk_frame_clock_paint_idle (data=0x7fffc1cd2ed0) at gdkframeclockidle.c:430
#13 0x00007ffff44ce218 in gdk_threads_dispatch (data=0x7fffbebb7620) at gdk.c:719
#14 0x00007ffff1b32893 in g_timeout_dispatch () at /lib64/libglib-2.0.so.0
#15 0x00007ffff1b31e3a in g_main_context_dispatch () at /lib64/libglib-2.0.so.0
#16 0x00007ffff1b321d0 in g_main_context_iterate.isra () at /lib64/libglib-2.0.so.0
#17 0x00007ffff1b3227c in g_main_context_iteration () at /lib64/libglib-2.0.so.0

Comment 24 Martin Stransky 2015-10-21 09:02:47 UTC
Sorry, the crash is produced by popups only, not by tooltips.

Comment 25 Olivier Fourdan 2015-10-21 11:15:37 UTC
(In reply to Martin Stransky from comment #23)
> Hm, that's interesting. I tested that on Weston but the tooltips are shown
> at random position (but it's not the default 0,0 as before).

Weston will use random coordinates so this is normal, and reinforce the idea that what you get is not a popup.

Is that with the sample code I provided for the popup? I don't get any crash here and the popup window is rightfully placed on both weston and mutter/gnome-shell.

Comment 26 Martin Stransky 2015-10-21 18:12:13 UTC
No, the crash comes from Firefox (the firefox wayland git repo).

Comment 27 Olivier Fourdan 2015-10-22 14:19:41 UTC
(In reply to Olivier Fourdan from comment #21)
> This might help: http://www.gtk.org/download/#BleedingEdge
> 
> FYI, I just tried FF from your github repo with gtk+ master and the tooltips
> are rightfully placed as expected under Weston.

Screenshots of the tooltips in both gnome-shell/wayland and weston: http://imgur.com/a/6iqVF

Comment 28 Jan Kurik 2016-02-24 13:46:00 UTC
This bug appears to have been reported against 'rawhide' during the Fedora 24 development cycle.
Changing version to '24'.

More information and reason for this action is here:
https://fedoraproject.org/wiki/Fedora_Program_Management/HouseKeeping/Fedora24#Rawhide_Rebase

Comment 29 Martin Stransky 2017-06-19 11:37:13 UTC
It's fixed now, Thanks.