wayland: Add MetaWaylandXdgSessionState
This object is a windowing-specific implementation of MetaSessionState, allowing to save window state for toplevel surfaces of a Wayland client using the xdg_session_management_v1 protocol. This object is detached from windowing logic itself, and will be integrated in later commits. Changes from Carlos Garnacho: Integrate state serialization with MetaSessionState and MetaSessionManager. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3825>
This commit is contained in:
parent
920de400f5
commit
6fa3a91325
4 changed files with 522 additions and 0 deletions
|
@ -709,6 +709,8 @@ if have_wayland
|
||||||
'wayland/meta-wayland-xdg-foreign.c',
|
'wayland/meta-wayland-xdg-foreign.c',
|
||||||
'wayland/meta-wayland-xdg-foreign.h',
|
'wayland/meta-wayland-xdg-foreign.h',
|
||||||
'wayland/meta-wayland-xdg-foreign-private.h',
|
'wayland/meta-wayland-xdg-foreign-private.h',
|
||||||
|
'wayland/meta-wayland-xdg-session-state.c',
|
||||||
|
'wayland/meta-wayland-xdg-session-state.h',
|
||||||
'wayland/meta-wayland-xdg-shell.c',
|
'wayland/meta-wayland-xdg-shell.c',
|
||||||
'wayland/meta-wayland-xdg-shell.h',
|
'wayland/meta-wayland-xdg-shell.h',
|
||||||
'wayland/meta-wayland-xdg-dialog.c',
|
'wayland/meta-wayland-xdg-dialog.c',
|
||||||
|
|
|
@ -73,3 +73,5 @@ typedef struct _MetaWaylandFilterManager MetaWaylandFilterManager;
|
||||||
typedef struct _MetaWaylandClient MetaWaylandClient;
|
typedef struct _MetaWaylandClient MetaWaylandClient;
|
||||||
|
|
||||||
typedef struct _MetaWaylandDrmLeaseManager MetaWaylandDrmLeaseManager;
|
typedef struct _MetaWaylandDrmLeaseManager MetaWaylandDrmLeaseManager;
|
||||||
|
|
||||||
|
typedef struct _MetaWaylandXdgSessionManager MetaWaylandXdgSessionManager;
|
||||||
|
|
486
src/wayland/meta-wayland-xdg-session-state.c
Normal file
486
src/wayland/meta-wayland-xdg-session-state.c
Normal file
|
@ -0,0 +1,486 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2024 Red Hat
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "wayland/meta-wayland-xdg-session-state.h"
|
||||||
|
|
||||||
|
#include <gio/gio.h>
|
||||||
|
|
||||||
|
#include "backends/meta-monitor.h"
|
||||||
|
#include "core/meta-context-private.h"
|
||||||
|
#include "core/window-private.h"
|
||||||
|
#include "wayland/meta-wayland.h"
|
||||||
|
|
||||||
|
#define STATE_FORMAT_VERSION 1
|
||||||
|
|
||||||
|
typedef enum _WindowState
|
||||||
|
{
|
||||||
|
WINDOW_STATE_NONE = 0,
|
||||||
|
/* floating */
|
||||||
|
WINDOW_STATE_FLOATING = 1,
|
||||||
|
/* tiling */
|
||||||
|
WINDOW_STATE_MAXIMIZED = 2,
|
||||||
|
WINDOW_STATE_TILED_LEFT = 3,
|
||||||
|
WINDOW_STATE_TILED_RIGHT = 4,
|
||||||
|
} WindowState;
|
||||||
|
|
||||||
|
struct _MetaWaylandXdgToplevelState
|
||||||
|
{
|
||||||
|
MetaWaylandXdgSessionState *session_state;
|
||||||
|
|
||||||
|
WindowState window_state;
|
||||||
|
struct {
|
||||||
|
MtkRectangle rect;
|
||||||
|
} floating;
|
||||||
|
struct {
|
||||||
|
MtkRectangle rect;
|
||||||
|
} tiled;
|
||||||
|
gboolean is_minimized;
|
||||||
|
int workspace_idx;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _MetaWaylandXdgSessionState
|
||||||
|
{
|
||||||
|
MetaSessionState parent;
|
||||||
|
|
||||||
|
GHashTable *toplevels;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (MetaWaylandXdgSessionState,
|
||||||
|
meta_wayland_xdg_session_state,
|
||||||
|
META_TYPE_SESSION_STATE)
|
||||||
|
|
||||||
|
static GVariant *
|
||||||
|
new_rect_variant (const MtkRectangle *rect)
|
||||||
|
{
|
||||||
|
return g_variant_new ("(iiii)",
|
||||||
|
rect->x,
|
||||||
|
rect->y,
|
||||||
|
rect->width,
|
||||||
|
rect->height);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
variant_to_rect (GVariant *variant,
|
||||||
|
MtkRectangle *rect)
|
||||||
|
{
|
||||||
|
g_variant_get (variant, "(iiii)",
|
||||||
|
&rect->x,
|
||||||
|
&rect->y,
|
||||||
|
&rect->width,
|
||||||
|
&rect->height);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_xdg_toplevel_state_free (MetaWaylandXdgToplevelState *toplevel_state)
|
||||||
|
{
|
||||||
|
g_free (toplevel_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
window_state_to_string (WindowState state)
|
||||||
|
{
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case WINDOW_STATE_NONE:
|
||||||
|
return "none";
|
||||||
|
case WINDOW_STATE_FLOATING:
|
||||||
|
return "floating";
|
||||||
|
case WINDOW_STATE_MAXIMIZED:
|
||||||
|
return "maximized";
|
||||||
|
case WINDOW_STATE_TILED_LEFT:
|
||||||
|
return "tiled-left";
|
||||||
|
case WINDOW_STATE_TILED_RIGHT:
|
||||||
|
return "tiled-right";
|
||||||
|
}
|
||||||
|
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
meta_wayland_xdg_toplevel_state_to_string (MetaWaylandXdgToplevelState *state)
|
||||||
|
{
|
||||||
|
GString *str = NULL;
|
||||||
|
|
||||||
|
str = g_string_new (NULL);
|
||||||
|
|
||||||
|
g_string_append (str, window_state_to_string (state->window_state));
|
||||||
|
|
||||||
|
switch (state->window_state)
|
||||||
|
{
|
||||||
|
case WINDOW_STATE_NONE:
|
||||||
|
break;
|
||||||
|
case WINDOW_STATE_FLOATING:
|
||||||
|
g_string_append_printf (str, " Rect [%d,%d +%d,%d]",
|
||||||
|
state->floating.rect.x,
|
||||||
|
state->floating.rect.y,
|
||||||
|
state->floating.rect.width,
|
||||||
|
state->floating.rect.height);
|
||||||
|
break;
|
||||||
|
case WINDOW_STATE_MAXIMIZED:
|
||||||
|
case WINDOW_STATE_TILED_LEFT:
|
||||||
|
case WINDOW_STATE_TILED_RIGHT:
|
||||||
|
g_string_append_printf (str, " Rect [%d,%d +%d,%d]",
|
||||||
|
state->tiled.rect.x,
|
||||||
|
state->tiled.rect.y,
|
||||||
|
state->tiled.rect.width,
|
||||||
|
state->tiled.rect.height);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_string_free_and_steal (str);
|
||||||
|
}
|
||||||
|
|
||||||
|
static MetaWaylandXdgToplevelState *
|
||||||
|
meta_wayland_xdg_session_state_ensure_toplevel (MetaWaylandXdgSessionState *session_state,
|
||||||
|
const char *name)
|
||||||
|
{
|
||||||
|
MetaWaylandXdgToplevelState *toplevel_state;
|
||||||
|
|
||||||
|
toplevel_state = g_hash_table_lookup (session_state->toplevels, name);
|
||||||
|
if (!toplevel_state)
|
||||||
|
{
|
||||||
|
toplevel_state = g_new0 (MetaWaylandXdgToplevelState, 1);
|
||||||
|
toplevel_state->session_state = session_state;
|
||||||
|
g_hash_table_insert (session_state->toplevels,
|
||||||
|
g_strdup (name), toplevel_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
return toplevel_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_xdg_session_state_dispose (GObject *object)
|
||||||
|
{
|
||||||
|
MetaWaylandXdgSessionState *session_state =
|
||||||
|
META_WAYLAND_XDG_SESSION_STATE (object);
|
||||||
|
|
||||||
|
g_clear_pointer (&session_state->toplevels, g_hash_table_unref);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (meta_wayland_xdg_session_state_parent_class)->dispose (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
meta_wayland_xdg_session_state_serialize (MetaSessionState *session_state,
|
||||||
|
GHashTable *gvdb_data)
|
||||||
|
{
|
||||||
|
MetaWaylandXdgSessionState *xdg_session_state =
|
||||||
|
META_WAYLAND_XDG_SESSION_STATE (session_state);
|
||||||
|
GHashTable *toplevels;
|
||||||
|
GHashTableIter iter;
|
||||||
|
gpointer key, value;
|
||||||
|
GvdbItem *item;
|
||||||
|
|
||||||
|
item = gvdb_hash_table_insert (gvdb_data, "version");
|
||||||
|
gvdb_item_set_value (item, g_variant_new ("i", STATE_FORMAT_VERSION));
|
||||||
|
|
||||||
|
item = gvdb_hash_table_insert (gvdb_data, "last-used");
|
||||||
|
gvdb_item_set_value (item, g_variant_new ("x", g_get_real_time ()));
|
||||||
|
|
||||||
|
toplevels = gvdb_hash_table_new (gvdb_data, "toplevels");
|
||||||
|
|
||||||
|
g_hash_table_iter_init (&iter, xdg_session_state->toplevels);
|
||||||
|
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||||
|
{
|
||||||
|
char *name = key;
|
||||||
|
MetaWaylandXdgToplevelState *toplevel_state = value;
|
||||||
|
GHashTable *toplevel;
|
||||||
|
|
||||||
|
meta_topic (META_DEBUG_SESSION_MANAGEMENT,
|
||||||
|
"Serializing toplevel state %s", name);
|
||||||
|
|
||||||
|
toplevel = gvdb_hash_table_new (toplevels, name);
|
||||||
|
|
||||||
|
item = gvdb_hash_table_insert (toplevel, "state");
|
||||||
|
gvdb_item_set_value (item, g_variant_new ("u", toplevel_state->window_state));
|
||||||
|
|
||||||
|
switch (toplevel_state->window_state)
|
||||||
|
{
|
||||||
|
case WINDOW_STATE_NONE:
|
||||||
|
break;
|
||||||
|
case WINDOW_STATE_FLOATING:
|
||||||
|
item = gvdb_hash_table_insert (toplevel, "floating-rect");
|
||||||
|
gvdb_item_set_value (item, new_rect_variant (&toplevel_state->floating.rect));
|
||||||
|
break;
|
||||||
|
case WINDOW_STATE_MAXIMIZED:
|
||||||
|
case WINDOW_STATE_TILED_LEFT:
|
||||||
|
case WINDOW_STATE_TILED_RIGHT:
|
||||||
|
item = gvdb_hash_table_insert (toplevel, "tiled-rect");
|
||||||
|
gvdb_item_set_value (item, new_rect_variant (&toplevel_state->tiled.rect));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
item = gvdb_hash_table_insert (toplevel, "is-minimized");
|
||||||
|
gvdb_item_set_value (item, g_variant_new_boolean (toplevel_state->is_minimized));
|
||||||
|
|
||||||
|
item = gvdb_hash_table_insert (toplevel, "workspace");
|
||||||
|
gvdb_item_set_value (item,
|
||||||
|
g_variant_new_int32 (toplevel_state->workspace_idx));
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
meta_wayland_xdg_session_state_parse (MetaSessionState *session_state,
|
||||||
|
GvdbTable *data,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
MetaWaylandXdgSessionState *xdg_session_state =
|
||||||
|
META_WAYLAND_XDG_SESSION_STATE (session_state);
|
||||||
|
g_autoptr (GVariant) version = NULL;
|
||||||
|
GvdbTable *toplevels, *toplevel;
|
||||||
|
GStrv toplevel_names = NULL;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
version = gvdb_table_get_value (data, "version");
|
||||||
|
if (!g_variant_is_of_type (version, G_VARIANT_TYPE ("i")) ||
|
||||||
|
g_variant_get_int32 (version) > STATE_FORMAT_VERSION)
|
||||||
|
{
|
||||||
|
g_set_error (error,
|
||||||
|
G_IO_ERROR,
|
||||||
|
G_IO_ERROR_FAILED,
|
||||||
|
"Too new session-data version");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
toplevels = gvdb_table_get_table (data, "toplevels");
|
||||||
|
toplevel_names = gvdb_table_get_names (toplevels, NULL);
|
||||||
|
|
||||||
|
for (i = 0; toplevel_names[i]; i++)
|
||||||
|
{
|
||||||
|
MetaWaylandXdgToplevelState * toplevel_state;
|
||||||
|
g_autoptr (GVariant) state = NULL, floating_rect = NULL, tiled_rect = NULL;
|
||||||
|
g_autoptr (GVariant) is_minimized = NULL, monitor = NULL, workspace = NULL;
|
||||||
|
|
||||||
|
meta_topic (META_DEBUG_SESSION_MANAGEMENT,
|
||||||
|
"Parsing toplevel state %s", toplevel_names[i]);
|
||||||
|
|
||||||
|
toplevel_state =
|
||||||
|
meta_wayland_xdg_session_state_ensure_toplevel (xdg_session_state,
|
||||||
|
toplevel_names[i]);
|
||||||
|
|
||||||
|
toplevel = gvdb_table_get_table (toplevels, toplevel_names[i]);
|
||||||
|
|
||||||
|
state = gvdb_table_get_value (toplevel, "state");
|
||||||
|
|
||||||
|
if (state && g_variant_is_of_type (state, G_VARIANT_TYPE ("u")))
|
||||||
|
toplevel_state->window_state = g_variant_get_uint32 (state);
|
||||||
|
|
||||||
|
floating_rect = gvdb_table_get_value (toplevel, "floating-rect");
|
||||||
|
if (floating_rect && g_variant_is_of_type (floating_rect, G_VARIANT_TYPE ("(iiii)")))
|
||||||
|
{
|
||||||
|
variant_to_rect (floating_rect, &toplevel_state->floating.rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
tiled_rect = gvdb_table_get_value (toplevel, "tiled-rect");
|
||||||
|
if (tiled_rect && g_variant_is_of_type (tiled_rect, G_VARIANT_TYPE ("(iiii)")))
|
||||||
|
{
|
||||||
|
variant_to_rect (floating_rect, &toplevel_state->tiled.rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
is_minimized = gvdb_table_get_value (toplevel, "is-minimized");
|
||||||
|
if (state && g_variant_is_of_type (state, G_VARIANT_TYPE ("b")))
|
||||||
|
toplevel_state->is_minimized = g_variant_get_boolean (is_minimized);
|
||||||
|
|
||||||
|
workspace = gvdb_table_get_value (toplevel, "workspace");
|
||||||
|
if (workspace && g_variant_is_of_type (workspace, G_VARIANT_TYPE ("i")))
|
||||||
|
toplevel_state->workspace_idx = g_variant_get_int32 (workspace);
|
||||||
|
|
||||||
|
gvdb_table_free (toplevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_clear_pointer (&toplevel_names, g_strfreev);
|
||||||
|
gvdb_table_free (toplevels);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_xdg_session_state_save_window (MetaSessionState *state,
|
||||||
|
const char *name,
|
||||||
|
MetaWindow *window)
|
||||||
|
{
|
||||||
|
MetaWaylandXdgSessionState *xdg_session_state =
|
||||||
|
META_WAYLAND_XDG_SESSION_STATE (state);
|
||||||
|
MetaWaylandXdgToplevelState *toplevel_state;
|
||||||
|
|
||||||
|
toplevel_state =
|
||||||
|
meta_wayland_xdg_session_state_ensure_toplevel (xdg_session_state,
|
||||||
|
name);
|
||||||
|
|
||||||
|
g_object_get (window,
|
||||||
|
"minimized", &toplevel_state->is_minimized,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (meta_window_get_maximized (window) ==
|
||||||
|
(META_MAXIMIZE_VERTICAL | META_MAXIMIZE_HORIZONTAL))
|
||||||
|
{
|
||||||
|
toplevel_state->window_state = WINDOW_STATE_MAXIMIZED;
|
||||||
|
|
||||||
|
toplevel_state->tiled.rect = window->rect;
|
||||||
|
}
|
||||||
|
else if (window->tile_mode == META_TILE_LEFT ||
|
||||||
|
window->tile_mode == META_TILE_RIGHT)
|
||||||
|
{
|
||||||
|
if (window->tile_mode == META_TILE_LEFT)
|
||||||
|
toplevel_state->window_state = WINDOW_STATE_TILED_LEFT;
|
||||||
|
else if (window->tile_mode == META_TILE_RIGHT)
|
||||||
|
toplevel_state->window_state = WINDOW_STATE_TILED_RIGHT;
|
||||||
|
|
||||||
|
toplevel_state->tiled.rect = window->rect;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
toplevel_state->window_state = WINDOW_STATE_FLOATING;
|
||||||
|
|
||||||
|
toplevel_state->floating.rect = window->rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
toplevel_state->workspace_idx = meta_workspace_index (window->workspace);
|
||||||
|
|
||||||
|
if (meta_is_topic_enabled (META_DEBUG_SESSION_MANAGEMENT))
|
||||||
|
{
|
||||||
|
g_autofree char *state_str = NULL;
|
||||||
|
|
||||||
|
state_str =
|
||||||
|
meta_wayland_xdg_toplevel_state_to_string (toplevel_state);
|
||||||
|
|
||||||
|
meta_topic (META_DEBUG_SESSION_MANAGEMENT,
|
||||||
|
"Saved window state %s: %s", name, state_str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
meta_wayland_xdg_session_state_restore_window (MetaSessionState *state,
|
||||||
|
const char *name,
|
||||||
|
MetaWindow *window)
|
||||||
|
{
|
||||||
|
MetaWaylandXdgSessionState *xdg_session_state =
|
||||||
|
META_WAYLAND_XDG_SESSION_STATE (state);
|
||||||
|
MetaWaylandXdgToplevelState *toplevel_state;
|
||||||
|
MtkRectangle *rect = NULL;
|
||||||
|
|
||||||
|
toplevel_state = g_hash_table_lookup (xdg_session_state->toplevels, name);
|
||||||
|
if (!toplevel_state)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
switch (toplevel_state->window_state)
|
||||||
|
{
|
||||||
|
case WINDOW_STATE_NONE:
|
||||||
|
break;
|
||||||
|
case WINDOW_STATE_FLOATING:
|
||||||
|
rect = &toplevel_state->floating.rect;
|
||||||
|
break;
|
||||||
|
case WINDOW_STATE_TILED_LEFT:
|
||||||
|
case WINDOW_STATE_TILED_RIGHT:
|
||||||
|
case WINDOW_STATE_MAXIMIZED:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (toplevel_state->window_state)
|
||||||
|
{
|
||||||
|
case WINDOW_STATE_NONE:
|
||||||
|
case WINDOW_STATE_FLOATING:
|
||||||
|
break;
|
||||||
|
case WINDOW_STATE_TILED_LEFT:
|
||||||
|
meta_window_tile (window, META_TILE_LEFT);
|
||||||
|
break;
|
||||||
|
case WINDOW_STATE_TILED_RIGHT:
|
||||||
|
meta_window_tile (window, META_TILE_RIGHT);
|
||||||
|
break;
|
||||||
|
case WINDOW_STATE_MAXIMIZED:
|
||||||
|
meta_window_maximize (window, META_MAXIMIZE_VERTICAL |
|
||||||
|
META_MAXIMIZE_HORIZONTAL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toplevel_state->is_minimized)
|
||||||
|
meta_window_minimize (window);
|
||||||
|
|
||||||
|
if (toplevel_state->workspace_idx >= 0)
|
||||||
|
{
|
||||||
|
meta_window_change_workspace_by_index (window,
|
||||||
|
toplevel_state->workspace_idx,
|
||||||
|
TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rect)
|
||||||
|
{
|
||||||
|
meta_window_move_resize_internal (window,
|
||||||
|
(META_MOVE_RESIZE_WAYLAND_CLIENT_RESIZE |
|
||||||
|
META_MOVE_RESIZE_WAYLAND_FINISH_MOVE_RESIZE |
|
||||||
|
META_MOVE_RESIZE_MOVE_ACTION |
|
||||||
|
META_MOVE_RESIZE_RESIZE_ACTION),
|
||||||
|
META_PLACE_FLAG_NONE,
|
||||||
|
META_GRAVITY_NORTH_WEST,
|
||||||
|
*rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
window->placed = TRUE;
|
||||||
|
|
||||||
|
if (meta_is_topic_enabled (META_DEBUG_SESSION_MANAGEMENT))
|
||||||
|
{
|
||||||
|
g_autofree char *state_str = NULL;
|
||||||
|
|
||||||
|
state_str =
|
||||||
|
meta_wayland_xdg_toplevel_state_to_string (toplevel_state);
|
||||||
|
|
||||||
|
meta_topic (META_DEBUG_SESSION_MANAGEMENT,
|
||||||
|
"Restored window state %s: %s", name, state_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_xdg_session_state_remove_window (MetaSessionState *state,
|
||||||
|
const char *name)
|
||||||
|
{
|
||||||
|
MetaWaylandXdgSessionState *xdg_session_state =
|
||||||
|
META_WAYLAND_XDG_SESSION_STATE (state);
|
||||||
|
|
||||||
|
g_hash_table_remove (xdg_session_state->toplevels, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_xdg_session_state_class_init (MetaWaylandXdgSessionStateClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
MetaSessionStateClass *session_state_class = META_SESSION_STATE_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->dispose = meta_wayland_xdg_session_state_dispose;
|
||||||
|
|
||||||
|
session_state_class->serialize = meta_wayland_xdg_session_state_serialize;
|
||||||
|
session_state_class->parse = meta_wayland_xdg_session_state_parse;
|
||||||
|
session_state_class->save_window = meta_wayland_xdg_session_state_save_window;
|
||||||
|
session_state_class->restore_window =
|
||||||
|
meta_wayland_xdg_session_state_restore_window;
|
||||||
|
session_state_class->remove_window =
|
||||||
|
meta_wayland_xdg_session_state_remove_window;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_xdg_session_state_init (MetaWaylandXdgSessionState *session_state)
|
||||||
|
{
|
||||||
|
session_state->toplevels =
|
||||||
|
g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||||
|
g_free,
|
||||||
|
(GDestroyNotify) meta_wayland_xdg_toplevel_state_free);
|
||||||
|
}
|
32
src/wayland/meta-wayland-xdg-session-state.h
Normal file
32
src/wayland/meta-wayland-xdg-session-state.h
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2024 Red Hat
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
#include "core/meta-session-state.h"
|
||||||
|
#include "wayland/meta-wayland-types.h"
|
||||||
|
|
||||||
|
typedef struct _MetaWaylandXdgToplevelState MetaWaylandXdgToplevelState;
|
||||||
|
|
||||||
|
#define META_TYPE_WAYLAND_XDG_SESSION_STATE (meta_wayland_xdg_session_state_get_type ())
|
||||||
|
G_DECLARE_FINAL_TYPE (MetaWaylandXdgSessionState,
|
||||||
|
meta_wayland_xdg_session_state,
|
||||||
|
META, WAYLAND_XDG_SESSION_STATE,
|
||||||
|
MetaSessionState)
|
Loading…
Reference in a new issue