wayland: Implement the XDG session management protocol
The xdg_session_manager_v1 global interface is the generator of xdg_session_v1 objects for clients. These will notify of an unique ID that can be used for future instantiations. Once a xdg_session_v1 object is obtained, toplevels can be added to be managed by it, and clients may get a hint about whether the toplevel was restored to a saved state. Changes by Carlos Garnacho: Integrate with MetaSessionManager core object. Flesh out event emission of xdg_session_v1 and xdg_toplevel_session_v1 objects, handle sessions being replaced/deleted. Changes by Sebastian Wick: * make lifetimes of xdg_sessions entirely determined by the wayland and handle its destruction via the signal * fix session destruction vs deletion * do not drop refcount of replaced session state temporarily to make sure the replacing session keeps the state * disconnect signals of destroyed and replaced sessions * disconnect window-unmanaging signal handler for MetaWaylandXdgToplevelSession * call wl_resource_destroy in xdg_toplevel_session_remove to make it a destructor * handle session being destroyed before topevel-sessions * handle the toplevel going away before the topevel-sessions Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3825>
This commit is contained in:
parent
2074e4e146
commit
74ce36f323
8 changed files with 935 additions and 1 deletions
|
@ -709,8 +709,12 @@ 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-manager.c',
|
||||||
|
'wayland/meta-wayland-xdg-session-manager.h',
|
||||||
'wayland/meta-wayland-xdg-session-state.c',
|
'wayland/meta-wayland-xdg-session-state.c',
|
||||||
'wayland/meta-wayland-xdg-session-state.h',
|
'wayland/meta-wayland-xdg-session-state.h',
|
||||||
|
'wayland/meta-wayland-xdg-session.c',
|
||||||
|
'wayland/meta-wayland-xdg-session.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',
|
||||||
|
|
|
@ -103,6 +103,7 @@ struct _MetaWaylandCompositor
|
||||||
MetaWaylandTabletManager *tablet_manager;
|
MetaWaylandTabletManager *tablet_manager;
|
||||||
MetaWaylandActivation *activation;
|
MetaWaylandActivation *activation;
|
||||||
MetaWaylandXdgForeign *foreign;
|
MetaWaylandXdgForeign *foreign;
|
||||||
|
MetaWaylandXdgSessionManager *session_manager;
|
||||||
|
|
||||||
GHashTable *scheduled_surface_associations;
|
GHashTable *scheduled_surface_associations;
|
||||||
|
|
||||||
|
|
|
@ -60,3 +60,4 @@
|
||||||
#define META_XX_COLOR_MANAGEMENT_VERSION 1
|
#define META_XX_COLOR_MANAGEMENT_VERSION 1
|
||||||
#define META_XDG_DIALOG_VERSION 1
|
#define META_XDG_DIALOG_VERSION 1
|
||||||
#define META_WP_DRM_LEASE_DEVICE_V1_VERSION 1
|
#define META_WP_DRM_LEASE_DEVICE_V1_VERSION 1
|
||||||
|
#define META_XDG_SESSION_MANAGER_V1_VERSION 1
|
||||||
|
|
397
src/wayland/meta-wayland-xdg-session-manager.c
Normal file
397
src/wayland/meta-wayland-xdg-session-manager.c
Normal file
|
@ -0,0 +1,397 @@
|
||||||
|
/*
|
||||||
|
* 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-manager.h"
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include "wayland/meta-wayland-xdg-shell.h"
|
||||||
|
#include "wayland/meta-wayland-xdg-session.h"
|
||||||
|
#include "wayland/meta-wayland-private.h"
|
||||||
|
#include "core/meta-debug-control-private.h"
|
||||||
|
#include "core/meta-session-manager.h"
|
||||||
|
|
||||||
|
#include "session-management-v1-server-protocol.h"
|
||||||
|
|
||||||
|
typedef struct _MetaWaylandXdgSessionManager
|
||||||
|
{
|
||||||
|
MetaWaylandCompositor *compositor;
|
||||||
|
struct wl_global *global;
|
||||||
|
|
||||||
|
GHashTable *sessions;
|
||||||
|
GHashTable *session_states;
|
||||||
|
} MetaWaylandXdgSessionManager;
|
||||||
|
|
||||||
|
static void xdg_session_manager_remove_session (MetaWaylandXdgSessionManager *session_manager,
|
||||||
|
MetaWaylandXdgSession *session);
|
||||||
|
|
||||||
|
static void
|
||||||
|
xdg_session_manager_destroy (struct wl_client *client,
|
||||||
|
struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
wl_resource_destroy (resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
on_restore_toplevel (MetaWaylandXdgSession *session,
|
||||||
|
MetaWaylandXdgToplevel *xdg_toplevel,
|
||||||
|
const char *name,
|
||||||
|
MetaWaylandXdgSessionManager *xdg_session_manager)
|
||||||
|
{
|
||||||
|
MetaContext *context =
|
||||||
|
meta_wayland_compositor_get_context (xdg_session_manager->compositor);
|
||||||
|
MetaSessionManager *session_manager =
|
||||||
|
meta_context_get_session_manager (context);
|
||||||
|
MetaSessionState *session_state;
|
||||||
|
MetaWaylandSurface *surface;
|
||||||
|
MetaWindow *window;
|
||||||
|
|
||||||
|
session_state =
|
||||||
|
meta_session_manager_get_session (META_SESSION_MANAGER (session_manager),
|
||||||
|
META_TYPE_WAYLAND_XDG_SESSION_STATE,
|
||||||
|
meta_wayland_xdg_session_get_id (session));
|
||||||
|
|
||||||
|
surface =
|
||||||
|
meta_wayland_surface_role_get_surface (META_WAYLAND_SURFACE_ROLE (xdg_toplevel));
|
||||||
|
if (!surface)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
window = meta_wayland_surface_get_toplevel_window (surface);
|
||||||
|
if (!window)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!meta_session_state_restore_window (session_state, name, window))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
meta_wayland_xdg_toplevel_set_hint_restored (xdg_toplevel);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_save_toplevel (MetaWaylandXdgSession *session,
|
||||||
|
MetaWaylandXdgToplevel *xdg_toplevel,
|
||||||
|
const char *name,
|
||||||
|
MetaWindow *window,
|
||||||
|
MetaWaylandXdgSessionManager *xdg_session_manager)
|
||||||
|
{
|
||||||
|
MetaContext *context =
|
||||||
|
meta_wayland_compositor_get_context (xdg_session_manager->compositor);
|
||||||
|
MetaSessionManager *session_manager =
|
||||||
|
meta_context_get_session_manager (context);
|
||||||
|
MetaSessionState *session_state;
|
||||||
|
|
||||||
|
session_state =
|
||||||
|
meta_session_manager_get_session (META_SESSION_MANAGER (session_manager),
|
||||||
|
META_TYPE_WAYLAND_XDG_SESSION_STATE,
|
||||||
|
meta_wayland_xdg_session_get_id (session));
|
||||||
|
|
||||||
|
meta_session_state_save_window (session_state, name, window);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_remove_toplevel (MetaWaylandXdgSession *session,
|
||||||
|
const char *name,
|
||||||
|
MetaWaylandXdgSessionManager *xdg_session_manager)
|
||||||
|
{
|
||||||
|
MetaContext *context =
|
||||||
|
meta_wayland_compositor_get_context (xdg_session_manager->compositor);
|
||||||
|
MetaSessionManager *session_manager =
|
||||||
|
meta_context_get_session_manager (context);
|
||||||
|
MetaSessionState *session_state;
|
||||||
|
|
||||||
|
session_state =
|
||||||
|
meta_session_manager_get_session (session_manager,
|
||||||
|
META_TYPE_WAYLAND_XDG_SESSION_STATE,
|
||||||
|
meta_wayland_xdg_session_get_id (session));
|
||||||
|
|
||||||
|
meta_session_state_remove_window (session_state, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_session_destroyed (MetaWaylandXdgSession *session,
|
||||||
|
MetaWaylandXdgSessionManager *session_manager)
|
||||||
|
{
|
||||||
|
xdg_session_manager_remove_session (session_manager, session);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_session_delete (MetaWaylandXdgSession *xdg_session,
|
||||||
|
MetaWaylandXdgSessionManager *xdg_session_manager)
|
||||||
|
{
|
||||||
|
MetaContext *context =
|
||||||
|
meta_wayland_compositor_get_context (xdg_session_manager->compositor);
|
||||||
|
MetaSessionManager *session_manager =
|
||||||
|
meta_context_get_session_manager (context);
|
||||||
|
const char *session_id = meta_wayland_xdg_session_get_id (xdg_session);
|
||||||
|
|
||||||
|
g_hash_table_remove (xdg_session_manager->session_states, session_id);
|
||||||
|
meta_session_manager_delete_session (session_manager, session_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
xdg_session_manager_remove_session (MetaWaylandXdgSessionManager *session_manager,
|
||||||
|
MetaWaylandXdgSession *session)
|
||||||
|
{
|
||||||
|
const char *session_id = meta_wayland_xdg_session_get_id (session);
|
||||||
|
|
||||||
|
g_signal_handlers_disconnect_by_func (session,
|
||||||
|
on_session_destroyed,
|
||||||
|
session_manager);
|
||||||
|
g_signal_handlers_disconnect_by_func (session,
|
||||||
|
on_restore_toplevel,
|
||||||
|
session_manager);
|
||||||
|
g_signal_handlers_disconnect_by_func (session,
|
||||||
|
on_save_toplevel,
|
||||||
|
session_manager);
|
||||||
|
g_signal_handlers_disconnect_by_func (session,
|
||||||
|
on_remove_toplevel,
|
||||||
|
session_manager);
|
||||||
|
g_signal_handlers_disconnect_by_func (session,
|
||||||
|
on_session_delete,
|
||||||
|
session_manager);
|
||||||
|
|
||||||
|
g_hash_table_remove (session_manager->sessions, session_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
generate_session_id (MetaWaylandXdgSessionManager *session_manager)
|
||||||
|
{
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
g_autofree char *id = NULL;
|
||||||
|
|
||||||
|
id = g_uuid_string_random ();
|
||||||
|
if (!g_hash_table_lookup (session_manager->sessions, id))
|
||||||
|
return g_steal_pointer (&id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
xdg_session_manager_get_session (struct wl_client *client,
|
||||||
|
struct wl_resource *resource,
|
||||||
|
uint32_t id,
|
||||||
|
uint32_t reason_value,
|
||||||
|
const char *session_id)
|
||||||
|
{
|
||||||
|
MetaWaylandXdgSessionManager *xdg_session_manager =
|
||||||
|
wl_resource_get_user_data (resource);
|
||||||
|
MetaContext *context =
|
||||||
|
meta_wayland_compositor_get_context (xdg_session_manager->compositor);
|
||||||
|
MetaSessionManager *session_manager =
|
||||||
|
meta_context_get_session_manager (context);
|
||||||
|
g_autoptr (MetaSessionState) session_state = NULL;
|
||||||
|
g_autoptr (MetaWaylandXdgSession) session = NULL;
|
||||||
|
g_autofree char *name = NULL, *stolen_name = NULL;
|
||||||
|
gboolean created = FALSE;
|
||||||
|
|
||||||
|
/* Unknown session ID is the same as NULL */
|
||||||
|
if (session_id &&
|
||||||
|
!meta_session_manager_get_session_exists (session_manager, session_id))
|
||||||
|
session_id = NULL;
|
||||||
|
|
||||||
|
if (session_id)
|
||||||
|
{
|
||||||
|
MetaWaylandXdgSession *prev_session;
|
||||||
|
|
||||||
|
prev_session =
|
||||||
|
g_hash_table_lookup (xdg_session_manager->sessions, session_id);
|
||||||
|
|
||||||
|
if (prev_session)
|
||||||
|
{
|
||||||
|
if (meta_wayland_xdg_session_is_same_client (prev_session, client))
|
||||||
|
{
|
||||||
|
wl_resource_post_error (resource,
|
||||||
|
XX_SESSION_MANAGER_V1_ERROR_IN_USE,
|
||||||
|
"Session %s already in use",
|
||||||
|
session_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Replace existing session */
|
||||||
|
meta_wayland_xdg_session_emit_replaced (prev_session);
|
||||||
|
xdg_session_manager_remove_session (xdg_session_manager,
|
||||||
|
prev_session);
|
||||||
|
}
|
||||||
|
|
||||||
|
name = g_strdup (session_id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
name = generate_session_id (xdg_session_manager);
|
||||||
|
created = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!g_hash_table_steal_extended (xdg_session_manager->session_states,
|
||||||
|
name,
|
||||||
|
(gpointer *) &stolen_name,
|
||||||
|
(gpointer *) &session_state))
|
||||||
|
{
|
||||||
|
session_state =
|
||||||
|
meta_session_manager_get_session (session_manager,
|
||||||
|
META_TYPE_WAYLAND_XDG_SESSION_STATE,
|
||||||
|
name);
|
||||||
|
}
|
||||||
|
|
||||||
|
session = meta_wayland_xdg_session_new (META_WAYLAND_XDG_SESSION_STATE (session_state),
|
||||||
|
client,
|
||||||
|
wl_resource_get_version (resource),
|
||||||
|
id);
|
||||||
|
g_signal_connect (session, "destroyed",
|
||||||
|
G_CALLBACK (on_session_destroyed), xdg_session_manager);
|
||||||
|
g_signal_connect (session, "restore-toplevel",
|
||||||
|
G_CALLBACK (on_restore_toplevel), xdg_session_manager);
|
||||||
|
g_signal_connect (session, "save-toplevel",
|
||||||
|
G_CALLBACK (on_save_toplevel), xdg_session_manager);
|
||||||
|
g_signal_connect (session, "remove-toplevel",
|
||||||
|
G_CALLBACK (on_remove_toplevel), xdg_session_manager);
|
||||||
|
g_signal_connect (session, "delete",
|
||||||
|
G_CALLBACK (on_session_delete), xdg_session_manager);
|
||||||
|
|
||||||
|
if (created)
|
||||||
|
meta_wayland_xdg_session_emit_created (session);
|
||||||
|
else
|
||||||
|
meta_wayland_xdg_session_emit_restored (session);
|
||||||
|
|
||||||
|
g_hash_table_insert (xdg_session_manager->sessions,
|
||||||
|
g_strdup (name),
|
||||||
|
session);
|
||||||
|
|
||||||
|
g_hash_table_insert (xdg_session_manager->session_states,
|
||||||
|
g_strdup (name),
|
||||||
|
g_steal_pointer (&session_state));
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct xx_session_manager_v1_interface meta_xdg_session_manager_interface = {
|
||||||
|
xdg_session_manager_destroy,
|
||||||
|
xdg_session_manager_get_session,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
bind_session_manager (struct wl_client *client,
|
||||||
|
void *data,
|
||||||
|
uint32_t version,
|
||||||
|
uint32_t id)
|
||||||
|
{
|
||||||
|
MetaWaylandXdgSessionManager *session_manager = data;
|
||||||
|
struct wl_resource *resource;
|
||||||
|
|
||||||
|
resource = wl_resource_create (client, &xx_session_manager_v1_interface,
|
||||||
|
version, id);
|
||||||
|
wl_resource_set_implementation (resource, &meta_xdg_session_manager_interface,
|
||||||
|
session_manager, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_enabled (MetaWaylandXdgSessionManager *session_manager)
|
||||||
|
{
|
||||||
|
MetaWaylandCompositor *compositor = session_manager->compositor;
|
||||||
|
MetaDebugControl *debug_control =
|
||||||
|
meta_context_get_debug_control (compositor->context);
|
||||||
|
gboolean is_enabled;
|
||||||
|
|
||||||
|
is_enabled =
|
||||||
|
meta_debug_control_is_session_management_protocol_enabled (debug_control);
|
||||||
|
|
||||||
|
if (is_enabled && !session_manager->global)
|
||||||
|
{
|
||||||
|
struct wl_display *wayland_display;
|
||||||
|
|
||||||
|
wayland_display =
|
||||||
|
meta_wayland_compositor_get_wayland_display (compositor);
|
||||||
|
|
||||||
|
session_manager->global =
|
||||||
|
wl_global_create (wayland_display,
|
||||||
|
&xx_session_manager_v1_interface,
|
||||||
|
META_XDG_SESSION_MANAGER_V1_VERSION,
|
||||||
|
session_manager, bind_session_manager);
|
||||||
|
if (!session_manager->global)
|
||||||
|
g_error ("Could not create session manager global");
|
||||||
|
}
|
||||||
|
else if (!is_enabled)
|
||||||
|
{
|
||||||
|
g_clear_pointer (&session_manager->global, wl_global_destroy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static MetaWaylandXdgSessionManager *
|
||||||
|
meta_wayland_session_manager_new (MetaWaylandCompositor *compositor)
|
||||||
|
{
|
||||||
|
MetaWaylandXdgSessionManager *session_manager;
|
||||||
|
|
||||||
|
session_manager = g_new0 (MetaWaylandXdgSessionManager, 1);
|
||||||
|
session_manager->compositor = compositor;
|
||||||
|
|
||||||
|
session_manager->sessions =
|
||||||
|
g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||||
|
g_free, NULL);
|
||||||
|
session_manager->session_states =
|
||||||
|
g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||||
|
g_free, g_object_unref);
|
||||||
|
|
||||||
|
return session_manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_session_manager_free (MetaWaylandXdgSessionManager *session_manager)
|
||||||
|
{
|
||||||
|
g_clear_pointer (&session_manager->sessions, g_hash_table_unref);
|
||||||
|
g_clear_pointer (&session_manager->session_states, g_hash_table_unref);
|
||||||
|
g_free (session_manager);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_protocol_enabled_changed (GObject *object,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MetaWaylandXdgSessionManager *session_manager = user_data;
|
||||||
|
|
||||||
|
update_enabled (session_manager);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_xdg_session_management_init (MetaWaylandCompositor *compositor)
|
||||||
|
{
|
||||||
|
MetaDebugControl *debug_control =
|
||||||
|
meta_context_get_debug_control (compositor->context);
|
||||||
|
|
||||||
|
compositor->session_manager = meta_wayland_session_manager_new (compositor);
|
||||||
|
|
||||||
|
g_signal_connect (debug_control, "notify::session-management-protocol",
|
||||||
|
G_CALLBACK (on_protocol_enabled_changed),
|
||||||
|
compositor->session_manager);
|
||||||
|
|
||||||
|
update_enabled (compositor->session_manager);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_xdg_session_management_finalize (MetaWaylandCompositor *compositor)
|
||||||
|
{
|
||||||
|
MetaDebugControl *debug_control =
|
||||||
|
meta_context_get_debug_control (compositor->context);
|
||||||
|
|
||||||
|
g_signal_handlers_disconnect_by_func (debug_control,
|
||||||
|
on_protocol_enabled_changed,
|
||||||
|
compositor->session_manager);
|
||||||
|
|
||||||
|
g_clear_pointer (&compositor->session_manager,
|
||||||
|
meta_wayland_session_manager_free);
|
||||||
|
}
|
25
src/wayland/meta-wayland-xdg-session-manager.h
Normal file
25
src/wayland/meta-wayland-xdg-session-manager.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* 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 "wayland/meta-wayland-types.h"
|
||||||
|
|
||||||
|
void meta_wayland_xdg_session_management_init (MetaWaylandCompositor *compositor);
|
||||||
|
|
||||||
|
void meta_wayland_xdg_session_management_finalize (MetaWaylandCompositor *compositor);
|
457
src/wayland/meta-wayland-xdg-session.c
Normal file
457
src/wayland/meta-wayland-xdg-session.c
Normal file
|
@ -0,0 +1,457 @@
|
||||||
|
/*
|
||||||
|
* 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.h"
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
#include "wayland/meta-wayland-xdg-session-state.h"
|
||||||
|
#include "wayland/meta-wayland-xdg-shell.h"
|
||||||
|
|
||||||
|
#include "session-management-v1-server-protocol.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _MetaWaylandXdgToplevelSession
|
||||||
|
{
|
||||||
|
grefcount ref_count;
|
||||||
|
MetaWaylandSurface *surface;
|
||||||
|
struct wl_resource *resource;
|
||||||
|
MetaWaylandXdgSession *session;
|
||||||
|
char *name;
|
||||||
|
} MetaWaylandXdgToplevelSession;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
DESTROYED,
|
||||||
|
RESTORE_TOPLEVEL,
|
||||||
|
SAVE_TOPLEVEL,
|
||||||
|
REMOVE_TOPLEVEL,
|
||||||
|
DELETE,
|
||||||
|
|
||||||
|
N_SIGNALS
|
||||||
|
};
|
||||||
|
|
||||||
|
static guint signals[N_SIGNALS];
|
||||||
|
|
||||||
|
struct _MetaWaylandXdgSession
|
||||||
|
{
|
||||||
|
GObject parent;
|
||||||
|
|
||||||
|
char *id;
|
||||||
|
struct wl_resource *resource;
|
||||||
|
GHashTable *toplevels; /* name -> MetaWaylandXdgToplevelSession */
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_FINAL_TYPE (MetaWaylandXdgSession,
|
||||||
|
meta_wayland_xdg_session,
|
||||||
|
G_TYPE_OBJECT)
|
||||||
|
|
||||||
|
static void on_window_unmanaging (MetaWindow *window,
|
||||||
|
MetaWaylandXdgToplevelSession *toplevel_session);
|
||||||
|
|
||||||
|
static MetaWaylandXdgToplevelSession *
|
||||||
|
meta_wayland_xdg_toplevel_session_ref (MetaWaylandXdgToplevelSession *toplevel_session)
|
||||||
|
{
|
||||||
|
g_ref_count_inc (&toplevel_session->ref_count);
|
||||||
|
return toplevel_session;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_xdg_toplevel_session_unref (MetaWaylandXdgToplevelSession *toplevel_session)
|
||||||
|
{
|
||||||
|
if (g_ref_count_dec (&toplevel_session->ref_count))
|
||||||
|
{
|
||||||
|
MetaWindow *window = NULL;
|
||||||
|
MetaWaylandSurface *surface = toplevel_session->surface;
|
||||||
|
|
||||||
|
if (surface)
|
||||||
|
window = meta_wayland_surface_get_toplevel_window (surface);
|
||||||
|
|
||||||
|
if (window)
|
||||||
|
{
|
||||||
|
g_signal_handlers_disconnect_by_func (window,
|
||||||
|
on_window_unmanaging,
|
||||||
|
toplevel_session);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free (toplevel_session->name);
|
||||||
|
g_free (toplevel_session);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
xdg_toplevel_session_destroy (struct wl_client *wl_client,
|
||||||
|
struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
wl_resource_destroy (resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
xdg_toplevel_session_remove (struct wl_client *wl_client,
|
||||||
|
struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
MetaWaylandXdgToplevelSession *toplevel_session =
|
||||||
|
wl_resource_get_user_data (resource);
|
||||||
|
MetaWaylandXdgSession *session = toplevel_session->session;
|
||||||
|
|
||||||
|
if (session)
|
||||||
|
{
|
||||||
|
g_signal_emit (session, signals[REMOVE_TOPLEVEL], 0, toplevel_session->name);
|
||||||
|
g_hash_table_remove (session->toplevels, toplevel_session->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_resource_destroy (resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct xx_toplevel_session_v1_interface meta_xdg_toplevel_session_interface = {
|
||||||
|
xdg_toplevel_session_destroy,
|
||||||
|
xdg_toplevel_session_remove,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
xdg_toplevel_session_destructor (struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
MetaWaylandXdgToplevelSession *toplevel_session =
|
||||||
|
wl_resource_get_user_data (resource);
|
||||||
|
|
||||||
|
meta_wayland_xdg_toplevel_session_unref (toplevel_session);
|
||||||
|
}
|
||||||
|
|
||||||
|
static MetaWaylandXdgToplevelSession *
|
||||||
|
meta_wayland_xdg_toplevel_session_new (MetaWaylandXdgSession *xdg_session,
|
||||||
|
MetaWaylandSurface *surface,
|
||||||
|
const char *name,
|
||||||
|
struct wl_client *wl_client,
|
||||||
|
uint32_t version,
|
||||||
|
uint32_t id)
|
||||||
|
{
|
||||||
|
MetaWaylandXdgToplevelSession *toplevel_session;
|
||||||
|
|
||||||
|
toplevel_session = g_new0 (MetaWaylandXdgToplevelSession, 1);
|
||||||
|
g_ref_count_init (&toplevel_session->ref_count);
|
||||||
|
toplevel_session->surface = surface;
|
||||||
|
toplevel_session->session = xdg_session;
|
||||||
|
toplevel_session->name = g_strdup (name);
|
||||||
|
toplevel_session->resource =
|
||||||
|
wl_resource_create (wl_client,
|
||||||
|
&xx_toplevel_session_v1_interface,
|
||||||
|
version, id);
|
||||||
|
wl_resource_set_implementation (toplevel_session->resource,
|
||||||
|
&meta_xdg_toplevel_session_interface,
|
||||||
|
meta_wayland_xdg_toplevel_session_ref (toplevel_session),
|
||||||
|
xdg_toplevel_session_destructor);
|
||||||
|
|
||||||
|
return toplevel_session;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_xdg_toplevel_session_emit_restored (MetaWaylandXdgToplevelSession *toplevel_session)
|
||||||
|
{
|
||||||
|
MetaWaylandXdgToplevel *xdg_toplevel =
|
||||||
|
META_WAYLAND_XDG_TOPLEVEL (toplevel_session->surface->role);
|
||||||
|
struct wl_resource *xdg_toplevel_resource =
|
||||||
|
meta_wayland_xdg_toplevel_get_resource (xdg_toplevel);
|
||||||
|
|
||||||
|
xx_toplevel_session_v1_send_restored (toplevel_session->resource,
|
||||||
|
xdg_toplevel_resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_xdg_session_dispose (GObject *object)
|
||||||
|
{
|
||||||
|
MetaWaylandXdgSession *session = META_WAYLAND_XDG_SESSION (object);
|
||||||
|
|
||||||
|
g_clear_pointer (&session->id, g_free);
|
||||||
|
g_clear_pointer (&session->toplevels, g_hash_table_unref);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (meta_wayland_xdg_session_parent_class)->dispose (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_xdg_session_class_init (MetaWaylandXdgSessionClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->dispose = meta_wayland_xdg_session_dispose;
|
||||||
|
|
||||||
|
signals[DESTROYED] =
|
||||||
|
g_signal_new ("destroyed",
|
||||||
|
G_TYPE_FROM_CLASS (klass),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
0, NULL, NULL,
|
||||||
|
NULL,
|
||||||
|
G_TYPE_NONE, 0);
|
||||||
|
|
||||||
|
signals[RESTORE_TOPLEVEL] =
|
||||||
|
g_signal_new ("restore-toplevel",
|
||||||
|
G_TYPE_FROM_CLASS (klass),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
0,
|
||||||
|
g_signal_accumulator_true_handled,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
G_TYPE_BOOLEAN, 2,
|
||||||
|
META_TYPE_WAYLAND_XDG_TOPLEVEL,
|
||||||
|
G_TYPE_STRING);
|
||||||
|
signals[SAVE_TOPLEVEL] =
|
||||||
|
g_signal_new ("save-toplevel",
|
||||||
|
G_TYPE_FROM_CLASS (klass),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
0, NULL, NULL, NULL,
|
||||||
|
G_TYPE_NONE, 3,
|
||||||
|
META_TYPE_WAYLAND_XDG_TOPLEVEL,
|
||||||
|
G_TYPE_STRING,
|
||||||
|
META_TYPE_WINDOW);
|
||||||
|
signals[REMOVE_TOPLEVEL] =
|
||||||
|
g_signal_new ("remove-toplevel",
|
||||||
|
G_TYPE_FROM_CLASS (klass),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
0, NULL, NULL, NULL,
|
||||||
|
G_TYPE_NONE, 1,
|
||||||
|
G_TYPE_STRING);
|
||||||
|
signals[DELETE] =
|
||||||
|
g_signal_new ("delete",
|
||||||
|
G_TYPE_FROM_CLASS (klass),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
0, NULL, NULL, NULL,
|
||||||
|
G_TYPE_NONE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_xdg_session_init (MetaWaylandXdgSession *session)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
xdg_session_destroy (struct wl_client *wl_client,
|
||||||
|
struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
wl_resource_destroy (resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
xdg_session_remove (struct wl_client *wl_client,
|
||||||
|
struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
MetaWaylandXdgSession *session =
|
||||||
|
META_WAYLAND_XDG_SESSION (wl_resource_get_user_data (resource));
|
||||||
|
|
||||||
|
g_signal_emit (session, signals[DELETE], 0);
|
||||||
|
|
||||||
|
wl_resource_destroy (resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_window_unmanaging (MetaWindow *window,
|
||||||
|
MetaWaylandXdgToplevelSession *toplevel_session)
|
||||||
|
{
|
||||||
|
MetaWaylandXdgSession *session = toplevel_session->session;
|
||||||
|
|
||||||
|
if (session)
|
||||||
|
{
|
||||||
|
MetaWaylandXdgToplevel *xdg_toplevel =
|
||||||
|
META_WAYLAND_XDG_TOPLEVEL (toplevel_session->surface->role);
|
||||||
|
|
||||||
|
g_signal_emit (session, signals[SAVE_TOPLEVEL], 0,
|
||||||
|
xdg_toplevel, toplevel_session->name, window);
|
||||||
|
}
|
||||||
|
|
||||||
|
toplevel_session->surface = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
xdg_session_add_toplevel (struct wl_client *wl_client,
|
||||||
|
struct wl_resource *resource,
|
||||||
|
uint32_t id,
|
||||||
|
struct wl_resource *toplevel_resource,
|
||||||
|
const char *name)
|
||||||
|
{
|
||||||
|
MetaWaylandXdgSession *session =
|
||||||
|
META_WAYLAND_XDG_SESSION (wl_resource_get_user_data (resource));
|
||||||
|
MetaWaylandXdgToplevel *xdg_toplevel =
|
||||||
|
wl_resource_get_user_data (toplevel_resource);
|
||||||
|
MetaWaylandSurfaceRole *surface_role;
|
||||||
|
MetaWaylandSurface *surface;
|
||||||
|
MetaWaylandXdgToplevelSession *toplevel_session;
|
||||||
|
MetaWindow *window;
|
||||||
|
|
||||||
|
if (g_hash_table_lookup (session->toplevels, name))
|
||||||
|
{
|
||||||
|
wl_resource_post_error (resource, XX_SESSION_V1_ERROR_NAME_IN_USE,
|
||||||
|
"Name of toplevel was already in use");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
surface_role = META_WAYLAND_SURFACE_ROLE (xdg_toplevel);
|
||||||
|
surface = meta_wayland_surface_role_get_surface (surface_role);
|
||||||
|
toplevel_session =
|
||||||
|
meta_wayland_xdg_toplevel_session_new (session, surface, name,
|
||||||
|
wl_client,
|
||||||
|
wl_resource_get_version (resource),
|
||||||
|
id);
|
||||||
|
g_hash_table_insert (session->toplevels, g_strdup (name), toplevel_session);
|
||||||
|
|
||||||
|
window = meta_wayland_surface_get_toplevel_window (surface);
|
||||||
|
if (window)
|
||||||
|
{
|
||||||
|
g_signal_connect (window, "unmanaging",
|
||||||
|
G_CALLBACK (on_window_unmanaging), toplevel_session);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
xdg_session_restore_toplevel (struct wl_client *wl_client,
|
||||||
|
struct wl_resource *resource,
|
||||||
|
uint32_t id,
|
||||||
|
struct wl_resource *toplevel_resource,
|
||||||
|
const char *name)
|
||||||
|
{
|
||||||
|
MetaWaylandXdgSession *session =
|
||||||
|
META_WAYLAND_XDG_SESSION (wl_resource_get_user_data (resource));
|
||||||
|
MetaWaylandXdgToplevel *xdg_toplevel =
|
||||||
|
wl_resource_get_user_data (toplevel_resource);
|
||||||
|
MetaWaylandSurfaceRole *surface_role;
|
||||||
|
MetaWaylandSurface *surface;
|
||||||
|
MetaWaylandXdgToplevelSession *toplevel_session;
|
||||||
|
MetaWindow *window;
|
||||||
|
gboolean restored = FALSE;
|
||||||
|
|
||||||
|
if (g_hash_table_lookup (session->toplevels, name))
|
||||||
|
{
|
||||||
|
wl_resource_post_error (resource, XX_SESSION_V1_ERROR_NAME_IN_USE,
|
||||||
|
"Name of toplevel was already in use");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
surface_role = META_WAYLAND_SURFACE_ROLE (xdg_toplevel);
|
||||||
|
surface = meta_wayland_surface_role_get_surface (surface_role);
|
||||||
|
if (meta_wayland_surface_has_initial_commit (surface))
|
||||||
|
{
|
||||||
|
wl_resource_post_error (resource, XX_SESSION_V1_ERROR_ALREADY_MAPPED,
|
||||||
|
"Tried to restore an already mapped toplevel");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
toplevel_session =
|
||||||
|
meta_wayland_xdg_toplevel_session_new (session, surface, name,
|
||||||
|
wl_client,
|
||||||
|
wl_resource_get_version (resource),
|
||||||
|
id);
|
||||||
|
g_hash_table_insert (session->toplevels, g_strdup (name), toplevel_session);
|
||||||
|
|
||||||
|
window = meta_wayland_surface_get_toplevel_window (surface);
|
||||||
|
if (window)
|
||||||
|
{
|
||||||
|
g_signal_connect (window, "unmanaging",
|
||||||
|
G_CALLBACK (on_window_unmanaging), toplevel_session);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_signal_emit (session,
|
||||||
|
signals[RESTORE_TOPLEVEL], 0,
|
||||||
|
xdg_toplevel, name, &restored);
|
||||||
|
|
||||||
|
if (restored)
|
||||||
|
meta_wayland_xdg_toplevel_session_emit_restored (toplevel_session);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct xx_session_v1_interface meta_xdg_session_interface = {
|
||||||
|
xdg_session_destroy,
|
||||||
|
xdg_session_remove,
|
||||||
|
xdg_session_add_toplevel,
|
||||||
|
xdg_session_restore_toplevel,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
xdg_session_destructor (struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
MetaWaylandXdgSession *session =
|
||||||
|
META_WAYLAND_XDG_SESSION (wl_resource_get_user_data (resource));
|
||||||
|
GHashTableIter iter;
|
||||||
|
gpointer value;
|
||||||
|
|
||||||
|
g_signal_emit (session, signals[DESTROYED], 0);
|
||||||
|
|
||||||
|
g_hash_table_iter_init (&iter, session->toplevels);
|
||||||
|
while (g_hash_table_iter_next (&iter, NULL, &value))
|
||||||
|
{
|
||||||
|
MetaWaylandXdgToplevelSession *toplevel_session = value;
|
||||||
|
|
||||||
|
toplevel_session->session = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_unref (session);
|
||||||
|
}
|
||||||
|
|
||||||
|
MetaWaylandXdgSession *
|
||||||
|
meta_wayland_xdg_session_new (MetaWaylandXdgSessionState *session_state,
|
||||||
|
struct wl_client *wl_client,
|
||||||
|
uint32_t version,
|
||||||
|
uint32_t id)
|
||||||
|
{
|
||||||
|
g_autoptr (MetaWaylandXdgSession) session = NULL;
|
||||||
|
|
||||||
|
session = g_object_new (META_TYPE_WAYLAND_XDG_SESSION, NULL);
|
||||||
|
session->id =
|
||||||
|
g_strdup (meta_session_state_get_name (META_SESSION_STATE (session_state)));
|
||||||
|
session->toplevels =
|
||||||
|
g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||||
|
g_free,
|
||||||
|
(GDestroyNotify) meta_wayland_xdg_toplevel_session_unref);
|
||||||
|
session->resource = wl_resource_create (wl_client,
|
||||||
|
&xx_session_v1_interface,
|
||||||
|
version, id);
|
||||||
|
wl_resource_set_implementation (session->resource,
|
||||||
|
&meta_xdg_session_interface,
|
||||||
|
g_object_ref (session),
|
||||||
|
xdg_session_destructor);
|
||||||
|
|
||||||
|
return g_steal_pointer (&session);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
meta_wayland_xdg_session_get_id (MetaWaylandXdgSession *session)
|
||||||
|
{
|
||||||
|
return session->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_xdg_session_emit_created (MetaWaylandXdgSession *session)
|
||||||
|
{
|
||||||
|
xx_session_v1_send_created (session->resource, session->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_xdg_session_emit_replaced (MetaWaylandXdgSession *session)
|
||||||
|
{
|
||||||
|
xx_session_v1_send_replaced (session->resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_xdg_session_emit_restored (MetaWaylandXdgSession *session)
|
||||||
|
{
|
||||||
|
xx_session_v1_send_restored (session->resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
meta_wayland_xdg_session_is_same_client (MetaWaylandXdgSession *session,
|
||||||
|
struct wl_client *client)
|
||||||
|
{
|
||||||
|
return wl_resource_get_client (session->resource) == client;
|
||||||
|
}
|
46
src/wayland/meta-wayland-xdg-session.h
Normal file
46
src/wayland/meta-wayland-xdg-session.h
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* 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 <wayland-server-core.h>
|
||||||
|
|
||||||
|
#include "wayland/meta-wayland-types.h"
|
||||||
|
#include "wayland/meta-wayland-xdg-session-state.h"
|
||||||
|
|
||||||
|
#define META_TYPE_WAYLAND_XDG_SESSION (meta_wayland_xdg_session_get_type ())
|
||||||
|
G_DECLARE_FINAL_TYPE (MetaWaylandXdgSession,
|
||||||
|
meta_wayland_xdg_session,
|
||||||
|
META, WAYLAND_XDG_SESSION,
|
||||||
|
GObject)
|
||||||
|
|
||||||
|
MetaWaylandXdgSession * meta_wayland_xdg_session_new (MetaWaylandXdgSessionState *session_state,
|
||||||
|
struct wl_client *wl_client,
|
||||||
|
uint32_t version,
|
||||||
|
uint32_t id);
|
||||||
|
|
||||||
|
const char * meta_wayland_xdg_session_get_id (MetaWaylandXdgSession *session);
|
||||||
|
|
||||||
|
void meta_wayland_xdg_session_emit_created (MetaWaylandXdgSession *session);
|
||||||
|
|
||||||
|
void meta_wayland_xdg_session_emit_replaced (MetaWaylandXdgSession *session);
|
||||||
|
|
||||||
|
void meta_wayland_xdg_session_emit_restored (MetaWaylandXdgSession *session);
|
||||||
|
|
||||||
|
gboolean meta_wayland_xdg_session_is_same_client (MetaWaylandXdgSession *session,
|
||||||
|
struct wl_client *client);
|
|
@ -48,6 +48,7 @@
|
||||||
#include "wayland/meta-wayland-inhibit-shortcuts-dialog.h"
|
#include "wayland/meta-wayland-inhibit-shortcuts-dialog.h"
|
||||||
#include "wayland/meta-wayland-inhibit-shortcuts.h"
|
#include "wayland/meta-wayland-inhibit-shortcuts.h"
|
||||||
#include "wayland/meta-wayland-legacy-xdg-foreign.h"
|
#include "wayland/meta-wayland-legacy-xdg-foreign.h"
|
||||||
|
#include "wayland/meta-wayland-linux-drm-syncobj.h"
|
||||||
#include "wayland/meta-wayland-outputs.h"
|
#include "wayland/meta-wayland-outputs.h"
|
||||||
#include "wayland/meta-wayland-presentation-time-private.h"
|
#include "wayland/meta-wayland-presentation-time-private.h"
|
||||||
#include "wayland/meta-wayland-private.h"
|
#include "wayland/meta-wayland-private.h"
|
||||||
|
@ -58,7 +59,7 @@
|
||||||
#include "wayland/meta-wayland-transaction.h"
|
#include "wayland/meta-wayland-transaction.h"
|
||||||
#include "wayland/meta-wayland-xdg-dialog.h"
|
#include "wayland/meta-wayland-xdg-dialog.h"
|
||||||
#include "wayland/meta-wayland-xdg-foreign.h"
|
#include "wayland/meta-wayland-xdg-foreign.h"
|
||||||
#include "wayland/meta-wayland-linux-drm-syncobj.h"
|
#include "wayland/meta-wayland-xdg-session-manager.h"
|
||||||
|
|
||||||
#ifdef HAVE_XWAYLAND
|
#ifdef HAVE_XWAYLAND
|
||||||
#include "wayland/meta-wayland-x11-interop.h"
|
#include "wayland/meta-wayland-x11-interop.h"
|
||||||
|
@ -690,6 +691,7 @@ meta_wayland_compositor_finalize (GObject *object)
|
||||||
MetaBackend *backend = meta_context_get_backend (compositor->context);
|
MetaBackend *backend = meta_context_get_backend (compositor->context);
|
||||||
ClutterActor *stage = meta_backend_get_stage (backend);
|
ClutterActor *stage = meta_backend_get_stage (backend);
|
||||||
|
|
||||||
|
meta_wayland_xdg_session_management_finalize (compositor);
|
||||||
meta_wayland_activation_finalize (compositor);
|
meta_wayland_activation_finalize (compositor);
|
||||||
meta_wayland_outputs_finalize (compositor);
|
meta_wayland_outputs_finalize (compositor);
|
||||||
meta_wayland_presentation_time_finalize (compositor);
|
meta_wayland_presentation_time_finalize (compositor);
|
||||||
|
@ -892,6 +894,7 @@ meta_wayland_compositor_new (MetaContext *context)
|
||||||
meta_wayland_drm_syncobj_init (compositor);
|
meta_wayland_drm_syncobj_init (compositor);
|
||||||
meta_wayland_init_xdg_wm_dialog (compositor);
|
meta_wayland_init_xdg_wm_dialog (compositor);
|
||||||
meta_wayland_init_color_management (compositor);
|
meta_wayland_init_color_management (compositor);
|
||||||
|
meta_wayland_xdg_session_management_init (compositor);
|
||||||
|
|
||||||
#ifdef HAVE_NATIVE_BACKEND
|
#ifdef HAVE_NATIVE_BACKEND
|
||||||
meta_wayland_drm_lease_manager_init (compositor);
|
meta_wayland_drm_lease_manager_init (compositor);
|
||||||
|
|
Loading…
Reference in a new issue