mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-09-20 05:50:11 +00:00
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.
This commit is contained in:
parent
982a696311
commit
af3ceb5755
@ -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
|
||||
{
|
||||
@ -1808,6 +1825,15 @@ gdk_wayland_toplevel_real_export_handle_finish (GdkToplevel *toplevel,
|
||||
return g_task_propagate_pointer (G_TASK (result), error);
|
||||
}
|
||||
|
||||
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)
|
||||
@ -1815,10 +1841,21 @@ gdk_wayland_toplevel_real_unexport_handle (GdkToplevel *toplevel,
|
||||
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);
|
||||
|
||||
g_clear_pointer (&wayland_toplevel->xdg_exported_v2, zxdg_exported_v2_destroy);
|
||||
g_clear_pointer (&wayland_toplevel->xdg_exported, zxdg_exported_v1_destroy);
|
||||
for (GList *l = wayland_toplevel->exported; l; l = l->next)
|
||||
{
|
||||
GdkWaylandExported *exported = l->data;
|
||||
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user