diff options
author | Matthias Clasen <mclasen@redhat.com> | 2023-05-14 17:38:11 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2023-05-14 23:49:44 -0400 |
commit | af3ceb57551ee410be1641e6c51281d2aef1a978 (patch) | |
tree | de0e81d710ab5bdeb38687dee7696adb28108658 | |
parent | 982a696311ed44add2b4a3c54f59a658928fea11 (diff) | |
download | gtk+-af3ceb57551ee410be1641e6c51281d2aef1a978.tar.gz |
wayland: Reimplement exporting
Change things so that every call to export_handle
creates a new handle, and unexport_handle destroys
the handle that it is given.
-rw-r--r-- | gdk/wayland/gdktoplevel-wayland.c | 98 |
1 files changed, 75 insertions, 23 deletions
diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c index 459462485a..bd3738ff3d 100644 --- a/gdk/wayland/gdktoplevel-wayland.c +++ b/gdk/wayland/gdktoplevel-wayland.c @@ -54,11 +54,16 @@ static void gdk_wayland_toplevel_sync_parent (GdkWaylandToplevel *to static void gdk_wayland_toplevel_sync_parent_of_imported (GdkWaylandToplevel *toplevel); static void gdk_wayland_surface_create_xdg_toplevel (GdkWaylandToplevel *toplevel); static void gdk_wayland_toplevel_sync_title (GdkWaylandToplevel *toplevel); -static gboolean gdk_wayland_toplevel_is_exported (GdkWaylandToplevel *toplevel); static void unset_transient_for_exported (GdkWaylandToplevel *toplevel); /* {{{ GdkWaylandToplevel definition */ +typedef struct { + struct zxdg_exported_v1 *xdg_exported; + struct zxdg_exported_v2 *xdg_exported_v2; + char *handle; +} GdkWaylandExported; + /** * GdkWaylandToplevel: * @@ -83,8 +88,7 @@ struct _GdkWaylandToplevel GdkWaylandToplevel *transient_for; struct org_kde_kwin_server_decoration *server_decoration; - struct zxdg_exported_v1 *xdg_exported; - struct zxdg_exported_v2 *xdg_exported_v2; + GList *exported; struct { int width; @@ -1274,9 +1278,6 @@ gdk_wayland_toplevel_finalize (GObject *object) display_wayland->toplevels = g_list_remove (display_wayland->toplevels, self); - if (gdk_wayland_toplevel_is_exported (self)) - gdk_wayland_toplevel_unexport_handle (GDK_TOPLEVEL (self)); - g_free (self->application.application_id); g_free (self->application.app_menu_path); g_free (self->application.menubar_path); @@ -1741,8 +1742,12 @@ xdg_exported_handle_v1 (void *data, struct zxdg_exported_v1 *zxdg_exported_v1, const char *handle) { - g_task_return_pointer (G_TASK (data), g_strdup (handle), g_free); - g_object_unref (data); + GTask *task = G_TASK (data); + GdkWaylandExported *exported = (GdkWaylandExported *)g_task_get_task_data (task); + + exported->handle = g_strdup (handle); + g_task_return_pointer (task, g_strdup (handle), g_free); + g_object_unref (task); } static const struct zxdg_exported_v1_listener xdg_exported_listener_v1 = { @@ -1754,8 +1759,12 @@ xdg_exported_handle_v2 (void *data, struct zxdg_exported_v2 *zxdg_exported_v2, const char *handle) { - g_task_return_pointer (G_TASK (data), g_strdup (handle), g_free); - g_object_unref (data); + GTask *task = G_TASK (data); + GdkWaylandExported *exported = (GdkWaylandExported *)g_task_get_task_data (task); + + exported->handle = g_strdup (handle); + g_task_return_pointer (task, g_strdup (handle), g_free); + g_object_unref (task); } static const struct zxdg_exported_v2_listener xdg_exported_listener_v2 = { @@ -1778,19 +1787,27 @@ gdk_wayland_toplevel_real_export_handle (GdkToplevel *toplevel, if (display_wayland->xdg_exporter_v2) { - wayland_toplevel->xdg_exported_v2 = + GdkWaylandExported *exported = g_new0 (GdkWaylandExported, 1); + exported->xdg_exported_v2 = zxdg_exporter_v2_export_toplevel (display_wayland->xdg_exporter_v2, gdk_wayland_surface_get_wl_surface (surface)); - zxdg_exported_v2_add_listener (wayland_toplevel->xdg_exported_v2, + zxdg_exported_v2_add_listener (exported->xdg_exported_v2, &xdg_exported_listener_v2, task); + + wayland_toplevel->exported = g_list_prepend (wayland_toplevel->exported, exported); + g_task_set_task_data (task, exported, NULL); } else if (display_wayland->xdg_exporter) { - wayland_toplevel->xdg_exported = + GdkWaylandExported *exported = g_new0 (GdkWaylandExported, 1); + exported->xdg_exported = zxdg_exporter_v1_export (display_wayland->xdg_exporter, gdk_wayland_surface_get_wl_surface (surface)); - zxdg_exported_v1_add_listener (wayland_toplevel->xdg_exported, + zxdg_exported_v1_add_listener (exported->xdg_exported, &xdg_exported_listener_v1, task); + + wayland_toplevel->exported = g_list_prepend (wayland_toplevel->exported, exported); + g_task_set_task_data (task, exported, NULL); } else { @@ -1809,16 +1826,36 @@ gdk_wayland_toplevel_real_export_handle_finish (GdkToplevel *toplevel, } static void +destroy_exported (GdkWaylandExported *exported) +{ + g_clear_pointer (&exported->handle, g_free); + g_clear_pointer (&exported->xdg_exported_v2, zxdg_exported_v2_destroy); + g_clear_pointer (&exported->xdg_exported, zxdg_exported_v1_destroy); + g_free (exported); +} + +static void gdk_wayland_toplevel_real_unexport_handle (GdkToplevel *toplevel, const char *handle) { GdkWaylandToplevel *wayland_toplevel = GDK_WAYLAND_TOPLEVEL (toplevel); g_return_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel)); - g_return_if_fail (wayland_toplevel->xdg_exported_v2 || wayland_toplevel->xdg_exported); + g_return_if_fail (handle != NULL); + + for (GList *l = wayland_toplevel->exported; l; l = l->next) + { + GdkWaylandExported *exported = l->data; - g_clear_pointer (&wayland_toplevel->xdg_exported_v2, zxdg_exported_v2_destroy); - g_clear_pointer (&wayland_toplevel->xdg_exported, zxdg_exported_v1_destroy); + if (exported->handle && strcmp (exported->handle, handle) == 0) + { + wayland_toplevel->exported = g_list_delete_link (wayland_toplevel->exported, l); + destroy_exported (exported); + return; + } + } + + g_warn_if_reached (); } static gboolean @@ -2253,6 +2290,27 @@ gdk_wayland_toplevel_set_dbus_properties (GdkToplevel *toplevel, void gdk_wayland_toplevel_destroy (GdkToplevel *toplevel) { + GdkWaylandToplevel *self = GDK_WAYLAND_TOPLEVEL (toplevel); + + while (self->exported) + { + GdkWaylandExported *exported = self->exported->data; + self->exported = g_list_delete_link (self->exported, self->exported); + if (exported->handle == NULL) + { + GTask *task; + + if (exported->xdg_exported_v2) + task = G_TASK (wl_proxy_get_user_data ((struct wl_proxy *) exported->xdg_exported_v2)); + else + task = G_TASK (wl_proxy_get_user_data ((struct wl_proxy *) exported->xdg_exported)); + + g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED, "Surface was destroyed"); + g_object_unref (task); + } + + destroy_exported (exported); + } } /* }}} */ @@ -2397,12 +2455,6 @@ gdk_wayland_toplevel_uninhibit_idle (GdkToplevel *toplevel) * marking surfaces as transient for out-of-process surfaces. */ -static gboolean -gdk_wayland_toplevel_is_exported (GdkWaylandToplevel *toplevel) -{ - return toplevel->xdg_exported != NULL || toplevel->xdg_exported_v2 != NULL; -} - typedef struct { GdkWaylandToplevelExported callback; gpointer user_data; |