mirror of https://github.com/libsdl-org/SDL
Merge 7a2ed151b0
into 88a01fbc96
This commit is contained in:
commit
137af84a7f
|
@ -6,6 +6,18 @@ encounter limitations or behavior that is different from other windowing systems
|
|||
|
||||
## Common issues:
|
||||
|
||||
### ```SDL_SetWindowPosition()``` doesn't work on non-popup windows
|
||||
|
||||
- Wayland does not allow toplevel windows to position themselves programmatically.
|
||||
|
||||
### How do I save and restore window layout and state between runs?
|
||||
|
||||
- To preserve the state of toplevel windows across runs, assign the window a stable ID string with the
|
||||
`SDL_PROP_WINDOW_CREATE_WAYLAND_WINDOW_ID_STRING` property at creation time, and serialize the global session property
|
||||
string `SDL_PROP_GLOBAL_VIDEO_WAYLAND_SESSION_ID_STRING` before shutting down. On subsequent runs, restore the session
|
||||
ID string property to the previously serialized value before window creation. This functionality requires that the
|
||||
compositor supports the `xdg_session_management_v1` protocol.
|
||||
|
||||
### Legacy, DPI-unaware applications are blurry
|
||||
|
||||
- Wayland handles high-DPI displays by scaling the desktop, which causes applications that are not designed to be
|
||||
|
@ -28,10 +40,6 @@ encounter limitations or behavior that is different from other windowing systems
|
|||
applications _must_ have an event loop and processes messages on a regular basis, or the application can appear
|
||||
unresponsive to both the user and desktop compositor.
|
||||
|
||||
### ```SDL_SetWindowPosition()``` doesn't work on non-popup windows
|
||||
|
||||
- Wayland does not allow toplevel windows to position themselves programmatically.
|
||||
|
||||
### Retrieving the global mouse cursor position when the cursor is outside a window doesn't work
|
||||
|
||||
- Wayland only provides applications with the cursor position within the borders of the application windows. Querying
|
||||
|
|
|
@ -79,6 +79,28 @@ typedef Uint32 SDL_WindowID;
|
|||
*/
|
||||
#define SDL_PROP_GLOBAL_VIDEO_WAYLAND_WL_DISPLAY_POINTER "SDL.video.wayland.wl_display"
|
||||
|
||||
/**
|
||||
* The session ID string used for saving and restoring window state across runs.
|
||||
*
|
||||
* To save the current state of toplevel windows, serialize this value before
|
||||
* shutting down. To restore the previous state, set this property to the previously
|
||||
* serialized value before window creation begins.
|
||||
*
|
||||
* This can be set at any time before the first call to a window creation function, and
|
||||
* read at any time after the first window with an ID string is created.
|
||||
*
|
||||
* Setting this to null or an empty string will cause a new session to be created.
|
||||
*
|
||||
* Note that for windows to be saved/restored by the session, they also need a stable, unique identifier
|
||||
* string set via the `SDL_PROP_WINDOW_CREATE_WAYLAND_WINDOW_ID_STRING` property at creation
|
||||
* time.
|
||||
*
|
||||
* \since This property is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_CreateWindowWithProperties
|
||||
*/
|
||||
#define SDL_PROP_GLOBAL_VIDEO_WAYLAND_SESSION_ID_STRING "SDL.video.wayland.session_id"
|
||||
|
||||
/**
|
||||
* System theme.
|
||||
*
|
||||
|
@ -1026,6 +1048,9 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_CreatePopupWindow(SDL_Window *paren
|
|||
* - `SDL_PROP_WINDOW_CREATE_WAYLAND_CREATE_EGL_WINDOW_BOOLEAN` - true if the
|
||||
* application wants an associated `wl_egl_window` object to be created,
|
||||
* even if the window does not have the OpenGL property or flag set.
|
||||
* - `SDL_PROP_WINDOW_CREATE_WAYLAND_WINDOW_ID_STRING` - a string used as
|
||||
* a stable identifier for toplevel windows for the purpose of allowing
|
||||
* the compositor to save/restore their state between runs.
|
||||
* - `SDL_PROP_WINDOW_CREATE_WAYLAND_WL_SURFACE_POINTER` - the wl_surface
|
||||
* associated with the window, if you want to wrap an existing window. See
|
||||
* [README/wayland](README/wayland) for more information.
|
||||
|
@ -1099,6 +1124,7 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_CreateWindowWithProperties(SDL_Prop
|
|||
#define SDL_PROP_WINDOW_CREATE_COCOA_VIEW_POINTER "SDL.window.create.cocoa.view"
|
||||
#define SDL_PROP_WINDOW_CREATE_WAYLAND_SURFACE_ROLE_CUSTOM_BOOLEAN "SDL.window.create.wayland.surface_role_custom"
|
||||
#define SDL_PROP_WINDOW_CREATE_WAYLAND_CREATE_EGL_WINDOW_BOOLEAN "SDL.window.create.wayland.create_egl_window"
|
||||
#define SDL_PROP_WINDOW_CREATE_WAYLAND_WINDOW_ID_STRING "SDL.window.create.wayland.window_id"
|
||||
#define SDL_PROP_WINDOW_CREATE_WAYLAND_WL_SURFACE_POINTER "SDL.window.create.wayland.wl_surface"
|
||||
#define SDL_PROP_WINDOW_CREATE_WIN32_HWND_POINTER "SDL.window.create.win32.hwnd"
|
||||
#define SDL_PROP_WINDOW_CREATE_WIN32_PIXEL_FORMAT_HWND_POINTER "SDL.window.create.win32.pixel_format_hwnd"
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
#include "xdg-dialog-v1-client-protocol.h"
|
||||
#include "xdg-foreign-unstable-v2-client-protocol.h"
|
||||
#include "xdg-output-unstable-v1-client-protocol.h"
|
||||
#include "xdg-session-management-v1-client-protocol.h"
|
||||
#include "xdg-shell-client-protocol.h"
|
||||
#include "xdg-toplevel-icon-v1-client-protocol.h"
|
||||
|
||||
|
@ -1194,6 +1195,8 @@ static void display_handle_global(void *data, struct wl_registry *registry, uint
|
|||
d->xdg_wm_dialog_v1 = wl_registry_bind(d->registry, id, &xdg_wm_dialog_v1_interface, 1);
|
||||
} else if (SDL_strcmp(interface, "wp_alpha_modifier_v1") == 0) {
|
||||
d->wp_alpha_modifier_v1 = wl_registry_bind(d->registry, id, &wp_alpha_modifier_v1_interface, 1);
|
||||
} else if (SDL_strcmp(interface, "xdg_session_manager_v1") == 0) {
|
||||
d->xdg_session_manager_v1 = wl_registry_bind(d->registry, id, &xdg_session_manager_v1_interface, 1);
|
||||
} else if (SDL_strcmp(interface, "xdg_toplevel_icon_manager_v1") == 0) {
|
||||
d->xdg_toplevel_icon_manager_v1 = wl_registry_bind(d->registry, id, &xdg_toplevel_icon_manager_v1_interface, 1);
|
||||
} else if (SDL_strcmp(interface, "kde_output_order_v1") == 0) {
|
||||
|
@ -1465,6 +1468,16 @@ static void Wayland_VideoCleanup(SDL_VideoDevice *_this)
|
|||
data->wp_alpha_modifier_v1 = NULL;
|
||||
}
|
||||
|
||||
if (data->xdg_session_v1) {
|
||||
xdg_session_v1_destroy(data->xdg_session_v1);
|
||||
data->xdg_session_v1 = NULL;
|
||||
}
|
||||
|
||||
if (data->xdg_session_manager_v1) {
|
||||
xdg_session_manager_v1_destroy(data->xdg_session_manager_v1);
|
||||
data->xdg_session_manager_v1 = NULL;
|
||||
}
|
||||
|
||||
if (data->xdg_toplevel_icon_manager_v1) {
|
||||
xdg_toplevel_icon_manager_v1_destroy(data->xdg_toplevel_icon_manager_v1);
|
||||
data->xdg_toplevel_icon_manager_v1 = NULL;
|
||||
|
|
|
@ -85,7 +85,9 @@ struct SDL_VideoData
|
|||
struct kde_output_order_v1 *kde_output_order;
|
||||
struct frog_color_management_factory_v1 *frog_color_management_factory_v1;
|
||||
struct zwp_tablet_manager_v2 *tablet_manager;
|
||||
struct xdg_session_manager_v1 *xdg_session_manager_v1;
|
||||
|
||||
struct xdg_session_v1 *xdg_session_v1;
|
||||
struct xkb_context *xkb_context;
|
||||
struct SDL_WaylandInput *input;
|
||||
struct wl_list output_list;
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "xdg-dialog-v1-client-protocol.h"
|
||||
#include "frog-color-management-v1-client-protocol.h"
|
||||
#include "xdg-toplevel-icon-v1-client-protocol.h"
|
||||
#include "xdg-session-management-v1-client-protocol.h"
|
||||
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
#include <libdecor.h>
|
||||
|
@ -1502,6 +1503,77 @@ static const struct wp_fractional_scale_v1_listener fractional_scale_listener =
|
|||
handle_preferred_fractional_scale
|
||||
};
|
||||
|
||||
static struct xdg_toplevel *GetToplevelForWindow(SDL_WindowData *wind)
|
||||
{
|
||||
if (wind) {
|
||||
/* Libdecor crashes on attempts to unset the parent by passing null, which is allowed by the
|
||||
* toplevel spec, so just use the raw xdg-toplevel instead (that's what libdecor does
|
||||
* internally anyways).
|
||||
*/
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
if (wind->shell_surface_type == WAYLAND_SURFACE_LIBDECOR && wind->shell_surface.libdecor.frame) {
|
||||
return libdecor_frame_get_xdg_toplevel(wind->shell_surface.libdecor.frame);
|
||||
} else
|
||||
#endif
|
||||
if (wind->shell_surface_type == WAYLAND_SURFACE_XDG_TOPLEVEL && wind->shell_surface.xdg.roleobj.toplevel) {
|
||||
return wind->shell_surface.xdg.roleobj.toplevel;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void handle_xdg_session_created(void *data, struct xdg_session_v1 *xdg_session_v1, const char *id)
|
||||
{
|
||||
SDL_SetStringProperty(SDL_GetGlobalProperties(), SDL_PROP_GLOBAL_VIDEO_WAYLAND_SESSION_ID_STRING, id);
|
||||
}
|
||||
|
||||
static void handle_xdg_session_restored(void *data, struct xdg_session_v1 *xdg_session_v1)
|
||||
{
|
||||
// NOP
|
||||
}
|
||||
|
||||
static void handle_xdg_session_replaced(void *data, struct xdg_session_v1 *xdg_session_v1)
|
||||
{
|
||||
// NOP
|
||||
}
|
||||
|
||||
static const struct xdg_session_v1_listener xdg_session_listener = {
|
||||
.created = handle_xdg_session_created,
|
||||
.restored = handle_xdg_session_restored,
|
||||
.replaced = handle_xdg_session_replaced
|
||||
};
|
||||
|
||||
static void Wayland_CreateSession(SDL_VideoData *data)
|
||||
{
|
||||
if (!data->xdg_session_manager_v1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Register a new session, if one does not yet exist.
|
||||
if (!data->xdg_session_v1) {
|
||||
const char *session_id = SDL_GetStringProperty(SDL_GetGlobalProperties(), SDL_PROP_GLOBAL_VIDEO_WAYLAND_SESSION_ID_STRING, NULL);
|
||||
if (session_id && *session_id == '\0') {
|
||||
session_id = NULL;
|
||||
}
|
||||
data->xdg_session_v1 = xdg_session_manager_v1_get_session(data->xdg_session_manager_v1, XDG_SESSION_MANAGER_V1_REASON_LAUNCH, session_id);
|
||||
|
||||
xdg_session_v1_add_listener(data->xdg_session_v1, &xdg_session_listener, data);
|
||||
|
||||
// Need to round trip as the session ID is needed now.
|
||||
WAYLAND_wl_display_roundtrip(data->display);
|
||||
}
|
||||
}
|
||||
|
||||
static void Wayland_RegisterToplevelForSession(SDL_WindowData *data)
|
||||
{
|
||||
SDL_VideoData *vid = data->waylandData;
|
||||
|
||||
if (vid->xdg_session_v1 && data->window_id) {
|
||||
data->xdg_toplevel_session_v1 = xdg_session_v1_restore_toplevel(vid->xdg_session_v1, GetToplevelForWindow(data), data->window_id);
|
||||
}
|
||||
}
|
||||
|
||||
static void frog_preferred_metadata_handler(void *data, struct frog_color_managed_surface *frog_color_managed_surface, uint32_t transfer_function,
|
||||
uint32_t output_display_primary_red_x, uint32_t output_display_primary_red_y,
|
||||
uint32_t output_display_primary_green_x, uint32_t output_display_primary_green_y,
|
||||
|
@ -1562,26 +1634,6 @@ bool Wayland_SetWindowHitTest(SDL_Window *window, bool enabled)
|
|||
return true; // just succeed, the real work is done elsewhere.
|
||||
}
|
||||
|
||||
static struct xdg_toplevel *GetToplevelForWindow(SDL_WindowData *wind)
|
||||
{
|
||||
if (wind) {
|
||||
/* Libdecor crashes on attempts to unset the parent by passing null, which is allowed by the
|
||||
* toplevel spec, so just use the raw xdg-toplevel instead (that's what libdecor does
|
||||
* internally anyways).
|
||||
*/
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
if (wind->shell_surface_type == WAYLAND_SURFACE_LIBDECOR && wind->shell_surface.libdecor.frame) {
|
||||
return libdecor_frame_get_xdg_toplevel(wind->shell_surface.libdecor.frame);
|
||||
} else
|
||||
#endif
|
||||
if (wind->shell_surface_type == WAYLAND_SURFACE_XDG_TOPLEVEL && wind->shell_surface.xdg.roleobj.toplevel) {
|
||||
return wind->shell_surface.xdg.roleobj.toplevel;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool Wayland_SetWindowParent(SDL_VideoDevice *_this, SDL_Window *window, SDL_Window *parent_window)
|
||||
{
|
||||
SDL_WindowData *child_data = window->internal;
|
||||
|
@ -1733,6 +1785,8 @@ void Wayland_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
|||
libdecor_frame_set_app_id(data->shell_surface.libdecor.frame, data->app_id);
|
||||
libdecor_frame_map(data->shell_surface.libdecor.frame);
|
||||
|
||||
Wayland_RegisterToplevelForSession(data);
|
||||
|
||||
if (c->zxdg_exporter_v2) {
|
||||
data->exported = zxdg_exporter_v2_export_toplevel(c->zxdg_exporter_v2, data->surface);
|
||||
zxdg_exported_v2_add_listener(data->exported, &exported_v2_listener, data);
|
||||
|
@ -1819,6 +1873,8 @@ void Wayland_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
|||
xdg_toplevel_set_app_id(data->shell_surface.xdg.roleobj.toplevel, data->app_id);
|
||||
xdg_toplevel_add_listener(data->shell_surface.xdg.roleobj.toplevel, &toplevel_listener_xdg, data);
|
||||
|
||||
Wayland_RegisterToplevelForSession(data);
|
||||
|
||||
if (c->zxdg_exporter_v2) {
|
||||
data->exported = zxdg_exporter_v2_export_toplevel(c->zxdg_exporter_v2, data->surface);
|
||||
zxdg_exported_v2_add_listener(data->exported, &exported_v2_listener, data);
|
||||
|
@ -2537,6 +2593,17 @@ bool Wayland_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_Proper
|
|||
data->surface_status = WAYLAND_SURFACE_STATUS_SHOWN;
|
||||
}
|
||||
|
||||
if (data->shell_surface_type == WAYLAND_SURFACE_XDG_TOPLEVEL || data->shell_surface_type == WAYLAND_SURFACE_LIBDECOR) {
|
||||
const char *window_id = SDL_GetStringProperty(create_props, SDL_PROP_WINDOW_CREATE_WAYLAND_WINDOW_ID_STRING, NULL);
|
||||
if (window_id && *window_id == '\0') {
|
||||
window_id = NULL;
|
||||
}
|
||||
if (window_id) {
|
||||
data->window_id = SDL_strdup(window_id);
|
||||
Wayland_CreateSession(c);
|
||||
}
|
||||
}
|
||||
|
||||
if (SDL_GetHintBoolean(SDL_HINT_VIDEO_DOUBLE_BUFFER, false)) {
|
||||
data->double_buffer = true;
|
||||
}
|
||||
|
@ -2861,6 +2928,7 @@ void Wayland_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
|||
|
||||
SDL_free(wind->outputs);
|
||||
SDL_free(wind->app_id);
|
||||
SDL_free(wind->window_id);
|
||||
|
||||
if (wind->gles_swap_frame_callback) {
|
||||
wl_callback_destroy(wind->gles_swap_frame_callback);
|
||||
|
@ -2882,6 +2950,10 @@ void Wayland_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
|||
xdg_toplevel_icon_v1_destroy(wind->xdg_toplevel_icon_v1);
|
||||
}
|
||||
|
||||
if (wind->xdg_toplevel_session_v1) {
|
||||
xdg_toplevel_session_v1_destroy(wind->xdg_toplevel_session_v1);
|
||||
}
|
||||
|
||||
Wayland_ReleaseSHMBuffer(&wind->icon);
|
||||
|
||||
SDL_free(wind);
|
||||
|
|
|
@ -99,6 +99,7 @@ struct SDL_WindowData
|
|||
struct zxdg_exported_v2 *exported;
|
||||
struct xdg_dialog_v1 *xdg_dialog_v1;
|
||||
struct wp_alpha_modifier_surface_v1 *wp_alpha_modifier_surface_v1;
|
||||
struct xdg_toplevel_session_v1 *xdg_toplevel_session_v1;
|
||||
struct xdg_toplevel_icon_v1 *xdg_toplevel_icon_v1;
|
||||
struct frog_color_managed_surface *frog_color_managed_surface;
|
||||
|
||||
|
@ -110,6 +111,7 @@ struct SDL_WindowData
|
|||
SDL_Window *keyboard_focus;
|
||||
|
||||
char *app_id;
|
||||
char *window_id;
|
||||
double scale_factor;
|
||||
|
||||
struct Wayland_SHMBuffer icon;
|
||||
|
|
|
@ -0,0 +1,247 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="xdg_session_management_v1">
|
||||
<copyright>
|
||||
Copyright 2018 Mike Blumenkrantz
|
||||
Copyright 2018 Samsung Electronics Co., Ltd
|
||||
Copyright 2018 Red Hat Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
</copyright>
|
||||
|
||||
<description summary="Protocol for managing application sessions">
|
||||
Warning! The protocol described in this file is currently in the testing
|
||||
phase. Backward compatible changes may be added together with the
|
||||
corresponding interface version bump. Backward incompatible changes can
|
||||
only be done by creating a new major version of the extension.
|
||||
</description>
|
||||
|
||||
<interface name="xdg_session_manager_v1" version="1">
|
||||
<description summary="manage sessions for applications">
|
||||
The xdg_session_manager interface defines base requests for creating and
|
||||
managing a session for an application. Sessions persist across application
|
||||
and compositor restarts unless explicitly destroyed. A session is created
|
||||
for the purpose of maintaining an application's xdg_toplevel surfaces
|
||||
across compositor or application restarts. The compositor should remember
|
||||
as many states as possible for surfaces in a given session, but there is
|
||||
no requirement for which states must be remembered.
|
||||
</description>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="in_use" summary="a requested session is already in use"
|
||||
value="1"/>
|
||||
</enum>
|
||||
|
||||
<enum name="reason">
|
||||
<description summary="reason for getting a session">
|
||||
The reason may determine in what way a session restores the window
|
||||
management state of associated toplevels.
|
||||
|
||||
For example newly launched applications might be launched on the active
|
||||
workspace with restored size and position, while a recovered
|
||||
applications might restore additional state such as active workspace and
|
||||
stacking order.
|
||||
</description>
|
||||
<entry name="launch" value="1">
|
||||
<description summary="an app is newly launched">
|
||||
A new app instance is launched, for example from an app launcher.
|
||||
</description>
|
||||
</entry>
|
||||
<entry name="recover" value="2">
|
||||
<description summary="an app recovered">
|
||||
A app instance is recovering from for example a compositor or app crash.
|
||||
</description>
|
||||
</entry>
|
||||
<entry name="session_restore" value="2">
|
||||
<description summary="an app restored">
|
||||
A app instance is restored, for example part of a restored session, or
|
||||
restored from having been temporarily terminated due to resource
|
||||
constraints.
|
||||
</description>
|
||||
</entry>
|
||||
</enum>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="Destroy this object">
|
||||
This has no effect other than to destroy the xdg_session_manager object.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<request name="get_session">
|
||||
<description summary="create or restore a session">
|
||||
Create a session object corresponding to the given session
|
||||
identifier string. While the session object exists, the session is
|
||||
considered to be "in use".
|
||||
|
||||
If a identifier string represents a session that is currently actively
|
||||
in use by the the same client, an 'in_use' error is raised. If some
|
||||
other client is currently using the same session, the new session will
|
||||
replace managing the associated state.
|
||||
|
||||
NULL is passed to initiate a new session. If an id is passed which does
|
||||
not represent a valid session, the compositor treats it as if NULL had
|
||||
been passed.
|
||||
|
||||
A client is allowed to have any number of in use sessions at the same
|
||||
time.
|
||||
</description>
|
||||
<arg name="id" type="new_id" interface="xdg_session_v1"/>
|
||||
<arg name="reason" type="uint" enum="reason"
|
||||
summary="reason for session"/>
|
||||
<arg name="session" type="string"
|
||||
summary="the session identifier string"
|
||||
allow-null="true"/>
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="xdg_session_v1" version="1">
|
||||
<description summary="A session for an application">
|
||||
A xdg_session_v1 object represents a session for an application. While the
|
||||
object exists, all surfaces which have been added to the session will
|
||||
have states stored by the compositor which can be reapplied at a later
|
||||
time. Two sessions cannot exist for the same identifier string.
|
||||
|
||||
States for surfaces added to a session are automatically updated by the
|
||||
compositor when they are changed.
|
||||
|
||||
Surfaces which have been added to a session are automatically removed from
|
||||
the session if xdg_toplevel.destroy is called for the surface.
|
||||
</description>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="invalid_restore"
|
||||
summary="restore cannot be performed after initial toplevel commit"
|
||||
value="1"/>
|
||||
<entry name="name_in_use"
|
||||
summary="toplevel name is already in used"
|
||||
value="2"/>
|
||||
<entry name="already_mapped"
|
||||
summary="toplevel was already mapped when restored"
|
||||
value="3"/>
|
||||
</enum>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="Destroy the session">
|
||||
Destroy a session object, preserving the current state but not continuing
|
||||
to make further updates if state changes occur. This makes the associated
|
||||
xdg_toplevel_session_v1 objects inert.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<request name="remove" type="destructor">
|
||||
<description summary="Remove the session">
|
||||
Remove the session, making it no longer available for restoration. A
|
||||
compositor should in response to this request remove the data related to
|
||||
this session from its storage.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<request name="add_toplevel">
|
||||
<description summary="add a new surface to the session">
|
||||
Attempt to add a given surface to the session. The passed name is used
|
||||
to identify what window is being restored, and may be used store window
|
||||
specific state within the session.
|
||||
|
||||
Calling this with a toplevel that is already managed by the session with
|
||||
the same associated will raise an in_use error.
|
||||
</description>
|
||||
<arg name="id" type="new_id" interface="xdg_toplevel_session_v1"/>
|
||||
<arg name="toplevel" type="object" interface="xdg_toplevel"/>
|
||||
<arg name="name" type="string"/>
|
||||
</request>
|
||||
|
||||
<request name="restore_toplevel">
|
||||
<description summary="restore a surface state">
|
||||
Inform the compositor that the toplevel associated with the passed name
|
||||
should have its window management state restored.
|
||||
|
||||
Calling this with a toplevel that is already managed by the session with
|
||||
the same associated will raise an in_use error.
|
||||
|
||||
This request must be called prior to the first commit on the associated
|
||||
wl_surface, otherwise an already_mapped error is raised.
|
||||
|
||||
As part of the initial configure sequence, if the toplevel was
|
||||
successfully restored, a xdg_toplevel_session_v1.restored event is
|
||||
emitted. See the xdg_toplevel_session_v1.restored event for further
|
||||
details.
|
||||
</description>
|
||||
<arg name="id" type="new_id" interface="xdg_toplevel_session_v1"/>
|
||||
<arg name="toplevel" type="object" interface="xdg_toplevel"/>
|
||||
<arg name="name" type="string"/>
|
||||
</request>
|
||||
|
||||
<request name="remove_toplevel">
|
||||
<description summary="remove a surface from the session">
|
||||
Remove a specified surface from the session and render any corresponding
|
||||
xdg_toplevel_session_v1 object inert. The compositor should remove any
|
||||
data related to the toplevel in the corresponding session from its internal
|
||||
storage.
|
||||
|
||||
Passing an unknown toplevel name identifier has no effect.
|
||||
</description>
|
||||
<arg name="name" type="string"/>
|
||||
</request>
|
||||
|
||||
<event name="created">
|
||||
<description summary="newly-created session id">
|
||||
Emitted at most once some time after getting a new session object. It
|
||||
means that no previous state restored, and a new session was created.
|
||||
The passed id can be used to restore previous sessions.
|
||||
</description>
|
||||
<arg name="id" type="string"/>
|
||||
</event>
|
||||
|
||||
<event name="restored">
|
||||
<description summary="the session has been restored">
|
||||
Emitted at most once some time after getting a new session object. It
|
||||
means that previous state was at least partially restored. The same id
|
||||
can again be used to restore previous sessions.
|
||||
</description>
|
||||
</event>
|
||||
|
||||
<event name="replaced">
|
||||
<description summary="the session has been restored">
|
||||
Emitted at most once, if the session was taken over by some other
|
||||
client. When this happens, the session and all its toplevel session
|
||||
objects become inert, and should be destroyed.
|
||||
</description>
|
||||
</event>
|
||||
</interface>
|
||||
|
||||
<interface name="xdg_toplevel_session_v1" version="1">
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="Destroy the object">
|
||||
Destroy the object. This has no effect window management of the
|
||||
associated toplevel.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<event name="restored">
|
||||
<description summary="a toplevel's session has been restored">
|
||||
The "restored" event is emitted prior to the first
|
||||
xdg_toplevel.configure for the toplevel. It will only be emitted after
|
||||
xdg_session_v1.restore_toplevel, and the initial empty surface state has
|
||||
been applied, and it indicates that the surface's session is being
|
||||
restored with this configure event.
|
||||
</description>
|
||||
<arg name="surface" type="object" interface="xdg_toplevel"/>
|
||||
</event>
|
||||
</interface>
|
||||
</protocol>
|
Loading…
Reference in New Issue