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 769786 - wayland: Add support for the xdg-foreign protocol
wayland: Add support for the xdg-foreign protocol
Status: RESOLVED FIXED
Product: mutter
Classification: Core
Component: wayland
unspecified
Other All
: Normal normal
: ---
Assigned To: mutter-maint
mutter-maint
Depends on:
Blocks:
 
 
Reported: 2016-08-12 10:04 UTC by Jonas Ådahl
Modified: 2016-08-22 13:04 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
wayland: Add support for the xdg-foreign protocol (17.23 KB, patch)
2016-08-12 10:04 UTC, Jonas Ådahl
none Details | Review
MetaWaylandSurface: Add 'unmapped' signal (1.69 KB, patch)
2016-08-18 05:23 UTC, Jonas Ådahl
none Details | Review
wayland: Add support for the xdg-foreign protocol (18.58 KB, patch)
2016-08-18 05:23 UTC, Jonas Ådahl
none Details | Review
MetaWaylandSurface: Add 'unmapped' signal (1.76 KB, patch)
2016-08-19 05:00 UTC, Jonas Ådahl
committed Details | Review
wayland: Add support for the xdg-foreign protocol (18.60 KB, patch)
2016-08-19 05:00 UTC, Jonas Ådahl
committed Details | Review

Description Jonas Ådahl 2016-08-12 10:04:46 UTC
This is needed for flatpak portals to be stacked correctly on Wayland. The
corresponding Wayland protocol was released as part of wayland-protocols 1.6.
Comment 1 Jonas Ådahl 2016-08-12 10:04:52 UTC
Created attachment 333167 [details] [review]
wayland: Add support for the xdg-foreign protocol

This commits adds support for exporting xdg_surface handles via
xdg_exporter and importing them via xdg_importer.

This bumps the required wayland-protocols version to 1.6.
Comment 2 Rui Matos 2016-08-17 17:36:09 UTC
Review of attachment 333167 [details] [review]:

::: src/Makefile.am
@@ +78,3 @@
 	wayland/protocol/gtk-shell.xml		\
 	wayland/protocol/gtk-primary-selection.xml	\
+	wayland/protocol/xdg-foregin.xml	\

leftover?

::: src/wayland/meta-wayland-xdg-foreign.c
@@ +132,3 @@
+  char *handle;
+
+  if (!surface->role || META_IS_WAYLAND_XDG_SURFACE (surface->role))

!META_IS_WAYLAND_XDG_SURFACE ?

@@ +153,3 @@
+  exported = g_new0 (MetaWaylandXdgExported, 1);
+  exported->foreign = foreign;
+  exported->surface = wl_resource_get_user_data (wl_surface_resource);

exported->surface = surface ?

Also, what happens if this surface is destroyed ?

@@ +165,3 @@
+      if (g_hash_table_insert (foreign->exported_surfaces, handle, exported))
+        break;
+      g_free (handle);

if g_hash_table_insert() fails, it frees the passed key so this is a double free

@@ +168,3 @@
+    }
+
+  exported->handle = g_strdup (handle);

looks like there's no need to dup the string, you could just point to the original buffer

@@ +218,3 @@
+  MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
+
+  if (!surface->role || META_IS_WAYLAND_XDG_SURFACE (surface->role))

!META_IS_WAYLAND_XDG_SURFACE

@@ +235,3 @@
+  imported->parent_of = surface;
+
+  if (surface)

if surface was NULL we'd have crashed dereferencing surface->role above

@@ +243,3 @@
+        {
+          meta_window_set_transient_for (surface->window,
+                                         imported->exported->surface->window);

is it guaranteed that exported->surface->window exists here ?

@@ +327,3 @@
+  imported->resource = xdg_imported_resource;
+
+  exported->imported = g_list_append (exported->imported, imported);

g_list_append is O(n) so, since the order doesn't matter here, you should use _prepend()
Comment 3 Jonas Ådahl 2016-08-18 04:03:22 UTC
(In reply to Rui Matos from comment #2)
> Review of attachment 333167 [details] [review] [review]:
> 
> @@ +153,3 @@
> +  exported = g_new0 (MetaWaylandXdgExported, 1);
> +  exported->foreign = foreign;
> +  exported->surface = wl_resource_get_user_data (wl_surface_resource);
> 
> exported->surface = surface ?
> 
> Also, what happens if this surface is destroyed ?

Good point. Had omitted that part, only dealt with explicit unexporting and client destruction. Surface being destroyed is not enough as well, we need a "unmapped" kind of thing.

I'll add a MetaWaylandSurface::unmapped signal for that.

> 
> @@ +235,3 @@
> +  imported->parent_of = surface;
> +
> +  if (surface)
> 
> if surface was NULL we'd have crashed dereferencing surface->role above

surface can never be NULL since it'll always survive until the wl_surface resource is destroyed.

> 
> @@ +243,3 @@
> +        {
> +          meta_window_set_transient_for (surface->window,
> +                                        
> imported->exported->surface->window);
> 
> is it guaranteed that exported->surface->window exists here ?

Added that (do we have a window) as a "is-mapped" check.
Comment 4 Jonas Ådahl 2016-08-18 05:23:00 UTC
Created attachment 333540 [details] [review]
MetaWaylandSurface: Add 'unmapped' signal

Meant to be used by users of MetaWaylandSurface's that need to know
when the surface was unmapped. So far only emitted by shell surfaces
(surfaces with MetaWindow's).
Comment 5 Jonas Ådahl 2016-08-18 05:23:06 UTC
Created attachment 333541 [details] [review]
wayland: Add support for the xdg-foreign protocol

This commits adds support for exporting xdg_surface handles via
xdg_exporter and importing them via xdg_importer.

This bumps the required wayland-protocols version to 1.6.
Comment 6 Rui Matos 2016-08-18 16:17:27 UTC
Review of attachment 333541 [details] [review]:

almost good

::: src/wayland/meta-wayland-xdg-foreign.c
@@ +125,3 @@
+  g_free (exported->handle);
+
+  g_hash_table_remove (foreign->exported_surfaces, exported->handle);

this needs to be done before freeing ->handle above

@@ +199,3 @@
+        {
+          g_hash_table_insert (foreign->exported_surfaces,
+                               g_strdup (handle), exported);

is there really a need to have a handle copy here?

@@ +338,3 @@
+
+      g_object_remove_weak_pointer (G_OBJECT (imported->parent_of),
+                                    (gpointer *) &imported->parent_of);

this should be disconnecting the signal now

@@ +345,3 @@
+    }
+
+  wl_resource_set_user_data (imported->resource, NULL);

we're not freeing the MetaWaylandXdgImported struct anywhere, or am I missing it?
Comment 7 Rui Matos 2016-08-18 16:24:40 UTC
Review of attachment 333540 [details] [review]:

::: src/wayland/meta-wayland-surface.c
@@ +317,3 @@
       meta_window_unmanage (surface->window, timestamp);
+
+      g_signal_emit (surface, surface_signals[SURFACE_UNMAPPED], 0);

wouldn't it be better to do this in meta_wayland_surface_set_window() when going from surface->window existing to it being set to NULL ?

doing it here doesn't catch xwayland surfaces being detached nor other calls to meta_window_unmanage(). None of these cases matter for xdg_foreign but it would be more correct I think
Comment 8 Jonas Ådahl 2016-08-19 04:27:45 UTC
(In reply to Rui Matos from comment #6)
> Review of attachment 333541 [details] [review] [review]:
> 
> almost good
> 
> ::: src/wayland/meta-wayland-xdg-foreign.c
> @@ +125,3 @@
> +  g_free (exported->handle);
> +
> +  g_hash_table_remove (foreign->exported_surfaces, exported->handle);
> 
> this needs to be done before freeing ->handle above

Ah right. I changed the hast table to not free 'exported' automatically, moved the free (exported->handle) after removing from the table, and finally a free (exported); in the end.

> 
> @@ +199,3 @@
> +        {
> +          g_hash_table_insert (foreign->exported_surfaces,
> +                               g_strdup (handle), exported);
> 
> is there really a need to have a handle copy here?

Yes, it seems so. g_hash_table_insert() will, if I read the docs correctly, always free the key when done with it; but I need to keep it alive so I can put it in 'exported'.

> 
> @@ +338,3 @@
> +
> +      g_object_remove_weak_pointer (G_OBJECT (imported->parent_of),
> +                                    (gpointer *) &imported->parent_of);
> 
> this should be disconnecting the signal now
> 
> @@ +345,3 @@
> +    }
> +
> +  wl_resource_set_user_data (imported->resource, NULL);
> 
> we're not freeing the MetaWaylandXdgImported struct anywhere, or am I
> missing it?

No, it was missing.
Comment 9 Jonas Ådahl 2016-08-19 05:00:06 UTC
Created attachment 333605 [details] [review]
MetaWaylandSurface: Add 'unmapped' signal

Meant to be used by users of MetaWaylandSurface's that need to know
when the surface was unmapped. So far only emitted by shell surfaces
(surfaces with MetaWindow's).
Comment 10 Jonas Ådahl 2016-08-19 05:00:11 UTC
Created attachment 333606 [details] [review]
wayland: Add support for the xdg-foreign protocol

This commits adds support for exporting xdg_surface handles via
xdg_exporter and importing them via xdg_importer.

This bumps the required wayland-protocols version to 1.6.
Comment 11 Rui Matos 2016-08-19 13:45:18 UTC
Review of attachment 333605 [details] [review]:

looks good

::: src/wayland/meta-wayland-surface.c
@@ +1102,3 @@
                                  MetaWindow         *window)
 {
+  gboolean was_unmapped = surface->window && !window;

was_mapped instead?
Comment 12 Rui Matos 2016-08-19 13:53:07 UTC
Review of attachment 333606 [details] [review]:

looks good. untested though

::: src/wayland/meta-wayland-xdg-foreign.c
@@ +201,3 @@
+        {
+          g_hash_table_insert (foreign->exported_surfaces,
+                               g_strdup (handle), exported);

if you didn't provide a key free function to g_hash_table_new_full() the dup wouldn't be needed. anyway, bikeshedding at this point
Comment 13 Jonas Ådahl 2016-08-19 14:56:43 UTC
(In reply to Rui Matos from comment #11)
> Review of attachment 333605 [details] [review] [review]:
> 
> looks good
> 
> ::: src/wayland/meta-wayland-surface.c
> @@ +1102,3 @@
>                                   MetaWindow         *window)
>  {
> +  gboolean was_unmapped = surface->window && !window;
> 
> was_mapped instead?

The signal that is triggered is "unmapped" so thought to make the variable reflect that change made sense.

(In reply to Rui Matos from comment #12)
> Review of attachment 333606 [details] [review] [review]:
> 
> looks good. untested though
> 
> ::: src/wayland/meta-wayland-xdg-foreign.c
> @@ +201,3 @@
> +        {
> +          g_hash_table_insert (foreign->exported_surfaces,
> +                               g_strdup (handle), exported);
> 
> if you didn't provide a key free function to g_hash_table_new_full() the dup
> wouldn't be needed. anyway, bikeshedding at this point

True. Slighty less string duplication is probably slightly better in the end.
Comment 14 Jonas Ådahl 2016-08-22 13:04:46 UTC
Attachment 333605 [details] pushed as aea7062 - MetaWaylandSurface: Add 'unmapped' signal
Attachment 333606 [details] pushed as 6f8e686 - wayland: Add support for the xdg-foreign protocol