wayland: Add API to restore GdkToplevels from an ID in the session

Any toplevel may be referred by an ID, that will be used by the compositor
to restore window state for it. Add the glue so that the upper layers
may restore a toplevel from one of these IDs.
This commit is contained in:
Carlos Garnacho 2024-06-19 13:25:51 +02:00 committed by Matthias Clasen
parent a06c412f5f
commit adfc69d501
3 changed files with 75 additions and 3 deletions

View File

@ -42,7 +42,7 @@
#include <gdk/wayland/presentation-time-client-protocol.h>
#include <gdk/wayland/single-pixel-buffer-v1-client-protocol.h>
#include <gdk/wayland/xdg-dialog-v1-client-protocol.h>
#include <gdk/wayland/xdg-session-management-v1-client-protocol.h>
#include <gdk/wayland/xx-session-management-v1-client-protocol.h>
#include <glib.h>
#include <gdk/gdkkeys.h>
@ -125,8 +125,8 @@ struct _GdkWaylandDisplay
struct wp_viewporter *viewporter;
struct wp_presentation *presentation;
struct wp_single_pixel_buffer_manager_v1 *single_pixel_buffer;
struct xdg_session_manager_v1 *xdg_session_manager;
struct xdg_session_v1 *xdg_session;
struct xx_session_manager_v1 *xdg_session_manager;
struct xx_session_v1 *xdg_session;
GdkWaylandColor *color;
GList *async_roundtrips;

View File

@ -38,6 +38,7 @@
#include <wayland/xdg-shell-unstable-v6-client-protocol.h>
#include <wayland/xdg-foreign-unstable-v2-client-protocol.h>
#include <wayland/xdg-dialog-v1-client-protocol.h>
#include <wayland/xx-session-management-v1-client-protocol.h>
#include <stdlib.h>
#include <stdio.h>
@ -126,6 +127,7 @@ struct _GdkWaylandToplevel
struct wl_output *initial_fullscreen_output;
struct wp_presentation_feedback *feedback;
struct xx_toplevel_session_v1 *toplevel_session;
struct {
GdkToplevelState unset_flags;
@ -142,6 +144,7 @@ struct _GdkWaylandToplevel
char *title;
gboolean decorated;
char *session_id;
GdkGeometry geometry_hints;
GdkSurfaceHints geometry_mask;
@ -819,6 +822,23 @@ create_zxdg_toplevel_v6_resources (GdkWaylandToplevel *toplevel)
toplevel);
}
static void
attempt_restore_toplevel (GdkWaylandToplevel *wayland_toplevel)
{
GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (wayland_toplevel));
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
if (display_wayland->xdg_session &&
wayland_toplevel->session_id &&
wayland_toplevel->display_server.xdg_toplevel)
{
wayland_toplevel->toplevel_session =
xx_session_v1_restore_toplevel (display_wayland->xdg_session,
wayland_toplevel->display_server.xdg_toplevel,
wayland_toplevel->session_id);
}
}
static void
gdk_wayland_surface_create_xdg_toplevel (GdkWaylandToplevel *wayland_toplevel)
{
@ -885,6 +905,8 @@ gdk_wayland_surface_create_xdg_toplevel (GdkWaylandToplevel *wayland_toplevel)
if (!maybe_set_xdg_dialog_modal (wayland_toplevel))
maybe_set_gtk_surface_modal (wayland_toplevel);
attempt_restore_toplevel (wayland_toplevel);
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "Wayland surface commit", NULL);
wl_surface_commit (wayland_surface->display_server.wl_surface);
}
@ -1409,6 +1431,9 @@ gdk_wayland_toplevel_finalize (GObject *object)
g_free (self->application.application_object_path);
g_free (self->application.unique_bus_name);
g_free (self->session_id);
g_clear_pointer (&self->toplevel_session, xx_toplevel_session_v1_destroy);
g_free (self->title);
g_clear_pointer (&self->shortcuts_inhibitors, g_hash_table_unref);
@ -2764,5 +2789,45 @@ gdk_wayland_toplevel_set_transient_for_exported (GdkToplevel *toplevel,
return TRUE;
}
void
gdk_wayland_toplevel_set_session_id (GdkToplevel *toplevel,
const char *session_id)
{
GdkWaylandToplevel *wayland_toplevel = GDK_WAYLAND_TOPLEVEL (toplevel);
g_clear_pointer (&wayland_toplevel->session_id, g_free);
wayland_toplevel->session_id = g_strdup (session_id);
}
void
gdk_wayland_toplevel_restore_from_session (GdkToplevel *toplevel)
{
GdkWaylandToplevel *wayland_toplevel = GDK_WAYLAND_TOPLEVEL (toplevel);
GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (toplevel));
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
if (display_wayland->xdg_session && wayland_toplevel->display_server.xdg_toplevel)
{
wayland_toplevel->toplevel_session =
xx_session_v1_restore_toplevel (display_wayland->xdg_session,
wayland_toplevel->display_server.xdg_toplevel,
wayland_toplevel->session_id);
}
}
void
gdk_wayland_toplevel_remove_from_session (GdkToplevel *toplevel)
{
GdkWaylandToplevel *wayland_toplevel = GDK_WAYLAND_TOPLEVEL (toplevel);
GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (toplevel));
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
if (display_wayland->xdg_session && wayland_toplevel->toplevel_session)
{
xx_toplevel_session_v1_remove (wayland_toplevel->toplevel_session);
wayland_toplevel->toplevel_session = NULL;
}
}
/* }}} */
/* vim:set foldmethod=marker expandtab: */

View File

@ -67,4 +67,11 @@ GDK_AVAILABLE_IN_ALL
void gdk_wayland_toplevel_set_application_id (GdkToplevel *toplevel,
const char *application_id);
void gdk_wayland_toplevel_set_session_id (GdkToplevel *toplevel,
const char *session_id);
void gdk_wayland_toplevel_restore_from_session (GdkToplevel *toplevel);
void gdk_wayland_toplevel_remove_from_session (GdkToplevel *toplevel);
G_END_DECLS