Remove wl-shell and xdg-shell-unstable-v6 support (#4323)

* wayland-protocol: update wayland.xml to 1.19.0

* wayland: remove shell_surface field from SDL_SysWMinfo

* wayland: remove wl_shell support

* waypand-protocols: update xdg-shell.xml to 1.20

* wayland: remove xdg-shell-unstable-v6 support

* wayland: deprecate wl shell surface syswm info, add xdg surface
This commit is contained in:
Simon Zeni 2021-07-27 17:12:26 -04:00 committed by GitHub
parent 65dc4edb52
commit 6aae5b44f8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 378 additions and 1543 deletions

View file

@ -289,8 +289,9 @@ struct SDL_SysWMinfo
{ {
struct wl_display *display; /**< Wayland display */ struct wl_display *display; /**< Wayland display */
struct wl_surface *surface; /**< Wayland surface */ struct wl_surface *surface; /**< Wayland surface */
struct wl_shell_surface *shell_surface; /**< Wayland shell_surface (window manager handle) */ void *shell_surface; /**< DEPRECATED Wayland shell_surface (window manager handle) */
struct wl_egl_window *egl_window; /**< Wayland EGL window (native window) */ struct wl_egl_window *egl_window; /**< Wayland EGL window (native window) */
struct xdg_surface *xdg_surface; /**< Wayland xdg surface (window manager handle) */
} wl; } wl;
#endif #endif
#if defined(SDL_VIDEO_DRIVER_MIR) /* no longer available, left for API/ABI compatibility. Remove in 2.1! */ #if defined(SDL_VIDEO_DRIVER_MIR) /* no longer available, left for API/ABI compatibility. Remove in 2.1! */

View file

@ -24,7 +24,7 @@
#include "../../SDL_internal.h" #include "../../SDL_internal.h"
/* We can't include wayland-client.h here /* We can't include wayland-client.h here
* but we need some structs from it * but we need some structs from it
*/ */
struct wl_interface; struct wl_interface;
@ -103,13 +103,11 @@ void SDL_WAYLAND_UnloadSymbols(void);
#define wl_shm_pool_interface (*WAYLAND_wl_shm_pool_interface) #define wl_shm_pool_interface (*WAYLAND_wl_shm_pool_interface)
#define wl_buffer_interface (*WAYLAND_wl_buffer_interface) #define wl_buffer_interface (*WAYLAND_wl_buffer_interface)
#define wl_registry_interface (*WAYLAND_wl_registry_interface) #define wl_registry_interface (*WAYLAND_wl_registry_interface)
#define wl_shell_surface_interface (*WAYLAND_wl_shell_surface_interface)
#define wl_region_interface (*WAYLAND_wl_region_interface) #define wl_region_interface (*WAYLAND_wl_region_interface)
#define wl_pointer_interface (*WAYLAND_wl_pointer_interface) #define wl_pointer_interface (*WAYLAND_wl_pointer_interface)
#define wl_keyboard_interface (*WAYLAND_wl_keyboard_interface) #define wl_keyboard_interface (*WAYLAND_wl_keyboard_interface)
#define wl_compositor_interface (*WAYLAND_wl_compositor_interface) #define wl_compositor_interface (*WAYLAND_wl_compositor_interface)
#define wl_output_interface (*WAYLAND_wl_output_interface) #define wl_output_interface (*WAYLAND_wl_output_interface)
#define wl_shell_interface (*WAYLAND_wl_shell_interface)
#define wl_shm_interface (*WAYLAND_wl_shm_interface) #define wl_shm_interface (*WAYLAND_wl_shm_interface)
#define wl_data_device_interface (*WAYLAND_wl_data_device_interface) #define wl_data_device_interface (*WAYLAND_wl_data_device_interface)
#define wl_data_offer_interface (*WAYLAND_wl_data_offer_interface) #define wl_data_offer_interface (*WAYLAND_wl_data_offer_interface)

View file

@ -40,7 +40,6 @@
#include "pointer-constraints-unstable-v1-client-protocol.h" #include "pointer-constraints-unstable-v1-client-protocol.h"
#include "relative-pointer-unstable-v1-client-protocol.h" #include "relative-pointer-unstable-v1-client-protocol.h"
#include "xdg-shell-client-protocol.h" #include "xdg-shell-client-protocol.h"
#include "xdg-shell-unstable-v6-client-protocol.h"
#include "keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h" #include "keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h"
#ifdef HAVE_LIBDECOR_H #ifdef HAVE_LIBDECOR_H
@ -330,20 +329,16 @@ ProcessHitTest(struct SDL_WaylandInput *input, uint32_t serial)
const SDL_Point point = { wl_fixed_to_int(input->sx_w), wl_fixed_to_int(input->sy_w) }; const SDL_Point point = { wl_fixed_to_int(input->sx_w), wl_fixed_to_int(input->sy_w) };
const SDL_HitTestResult rc = window->hit_test(window, &point, window->hit_test_data); const SDL_HitTestResult rc = window->hit_test(window, &point, window->hit_test_data);
static const uint32_t directions_wl[] = { static const uint32_t directions[] = {
WL_SHELL_SURFACE_RESIZE_TOP_LEFT, WL_SHELL_SURFACE_RESIZE_TOP, XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT, XDG_TOPLEVEL_RESIZE_EDGE_TOP,
WL_SHELL_SURFACE_RESIZE_TOP_RIGHT, WL_SHELL_SURFACE_RESIZE_RIGHT, XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT, XDG_TOPLEVEL_RESIZE_EDGE_RIGHT,
WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT, WL_SHELL_SURFACE_RESIZE_BOTTOM, XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT, XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM,
WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT, WL_SHELL_SURFACE_RESIZE_LEFT XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT, XDG_TOPLEVEL_RESIZE_EDGE_LEFT
}; };
/* the names are different (ZXDG_TOPLEVEL_V6_RESIZE_EDGE_* vs
WL_SHELL_SURFACE_RESIZE_*), but the values are the same. */
const uint32_t *directions_zxdg = directions_wl;
#ifdef HAVE_LIBDECOR_H #ifdef HAVE_LIBDECOR_H
/* ditto for libdecor. */ /* ditto for libdecor. */
const uint32_t *directions_libdecor = directions_wl; const uint32_t *directions_libdecor = directions;
#endif #endif
switch (rc) { switch (rc) {
@ -361,16 +356,6 @@ ProcessHitTest(struct SDL_WaylandInput *input, uint32_t serial)
input->seat, input->seat,
serial); serial);
} }
} else if (input->display->shell.zxdg) {
if (window_data->shell_surface.zxdg.roleobj.toplevel) {
zxdg_toplevel_v6_move(window_data->shell_surface.zxdg.roleobj.toplevel,
input->seat,
serial);
}
} else {
if (window_data->shell_surface.wl) {
wl_shell_surface_move(window_data->shell_surface.wl, input->seat, serial);
}
} }
return SDL_TRUE; return SDL_TRUE;
@ -394,18 +379,7 @@ ProcessHitTest(struct SDL_WaylandInput *input, uint32_t serial)
xdg_toplevel_resize(window_data->shell_surface.xdg.roleobj.toplevel, xdg_toplevel_resize(window_data->shell_surface.xdg.roleobj.toplevel,
input->seat, input->seat,
serial, serial,
directions_zxdg[rc - SDL_HITTEST_RESIZE_TOPLEFT]); directions[rc - SDL_HITTEST_RESIZE_TOPLEFT]);
}
} else if (input->display->shell.zxdg) {
if (window_data->shell_surface.zxdg.roleobj.toplevel) {
zxdg_toplevel_v6_resize(window_data->shell_surface.zxdg.roleobj.toplevel,
input->seat,
serial,
directions_zxdg[rc - SDL_HITTEST_RESIZE_TOPLEFT]);
}
} else {
if (window_data->shell_surface.wl) {
wl_shell_surface_resize(window_data->shell_surface.wl, input->seat, serial, directions_wl[rc - SDL_HITTEST_RESIZE_TOPLEFT]);
} }
} }
return SDL_TRUE; return SDL_TRUE;
@ -784,7 +758,7 @@ keyboard_handle_leave(void *data, struct wl_keyboard *keyboard,
/* Stop key repeat before clearing keyboard focus */ /* Stop key repeat before clearing keyboard focus */
keyboard_repeat_clear(&input->keyboard_repeat); keyboard_repeat_clear(&input->keyboard_repeat);
/* This will release any keys still pressed */ /* This will release any keys still pressed */
SDL_SetKeyboardFocus(NULL); SDL_SetKeyboardFocus(NULL);
#ifdef SDL_USE_IME #ifdef SDL_USE_IME
SDL_IME_SetFocus(SDL_FALSE); SDL_IME_SetFocus(SDL_FALSE);
@ -1615,7 +1589,7 @@ int Wayland_input_grab_keyboard(SDL_Window *window, struct SDL_WaylandInput *inp
zwp_keyboard_shortcuts_inhibit_manager_v1_inhibit_shortcuts(d->key_inhibitor_manager, zwp_keyboard_shortcuts_inhibit_manager_v1_inhibit_shortcuts(d->key_inhibitor_manager,
w->surface, w->surface,
input->seat); input->seat);
return 0; return 0;
} }

View file

@ -33,7 +33,6 @@
#include "SDL_waylanddyn.h" #include "SDL_waylanddyn.h"
#include "xdg-shell-client-protocol.h" #include "xdg-shell-client-protocol.h"
#include "xdg-shell-unstable-v6-client-protocol.h"
/* EGL implementation of SDL OpenGL ES support */ /* EGL implementation of SDL OpenGL ES support */
@ -41,12 +40,12 @@ int
Wayland_GLES_LoadLibrary(_THIS, const char *path) { Wayland_GLES_LoadLibrary(_THIS, const char *path) {
int ret; int ret;
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
ret = SDL_EGL_LoadLibrary(_this, path, (NativeDisplayType) data->display, 0); ret = SDL_EGL_LoadLibrary(_this, path, (NativeDisplayType) data->display, 0);
Wayland_PumpEvents(_this); Wayland_PumpEvents(_this);
WAYLAND_wl_display_flush(data->display); WAYLAND_wl_display_flush(data->display);
return ret; return ret;
} }
@ -57,6 +56,7 @@ Wayland_GLES_CreateContext(_THIS, SDL_Window * window)
SDL_GLContext context; SDL_GLContext context;
context = SDL_EGL_CreateContext(_this, ((SDL_WindowData *) window->driverdata)->egl_surface); context = SDL_EGL_CreateContext(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);
WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display ); WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display );
return context; return context;
} }
@ -160,14 +160,14 @@ int
Wayland_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) Wayland_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
{ {
int ret; int ret;
if (window && context) { if (window && context) {
ret = SDL_EGL_MakeCurrent(_this, ((SDL_WindowData *) window->driverdata)->egl_surface, context); ret = SDL_EGL_MakeCurrent(_this, ((SDL_WindowData *) window->driverdata)->egl_surface, context);
} }
else { else {
ret = SDL_EGL_MakeCurrent(_this, NULL, NULL); ret = SDL_EGL_MakeCurrent(_this, NULL, NULL);
} }
WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display ); WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display );
_this->egl_data->eglSwapInterval(_this->egl_data->egl_display, 0); /* see comments on Wayland_GLES_SetSwapInterval. */ _this->egl_data->eglSwapInterval(_this->egl_data->egl_display, 0); /* see comments on Wayland_GLES_SetSwapInterval. */
@ -192,7 +192,7 @@ Wayland_GLES_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h)
} }
} }
void void
Wayland_GLES_DeleteContext(_THIS, SDL_GLContext context) Wayland_GLES_DeleteContext(_THIS, SDL_GLContext context)
{ {
SDL_EGL_DeleteContext(_this, context); SDL_EGL_DeleteContext(_this, context);

View file

@ -82,13 +82,11 @@ SDL_WAYLAND_INTERFACE(wl_surface_interface)
SDL_WAYLAND_INTERFACE(wl_shm_pool_interface) SDL_WAYLAND_INTERFACE(wl_shm_pool_interface)
SDL_WAYLAND_INTERFACE(wl_buffer_interface) SDL_WAYLAND_INTERFACE(wl_buffer_interface)
SDL_WAYLAND_INTERFACE(wl_registry_interface) SDL_WAYLAND_INTERFACE(wl_registry_interface)
SDL_WAYLAND_INTERFACE(wl_shell_surface_interface)
SDL_WAYLAND_INTERFACE(wl_region_interface) SDL_WAYLAND_INTERFACE(wl_region_interface)
SDL_WAYLAND_INTERFACE(wl_pointer_interface) SDL_WAYLAND_INTERFACE(wl_pointer_interface)
SDL_WAYLAND_INTERFACE(wl_keyboard_interface) SDL_WAYLAND_INTERFACE(wl_keyboard_interface)
SDL_WAYLAND_INTERFACE(wl_compositor_interface) SDL_WAYLAND_INTERFACE(wl_compositor_interface)
SDL_WAYLAND_INTERFACE(wl_output_interface) SDL_WAYLAND_INTERFACE(wl_output_interface)
SDL_WAYLAND_INTERFACE(wl_shell_interface)
SDL_WAYLAND_INTERFACE(wl_shm_interface) SDL_WAYLAND_INTERFACE(wl_shm_interface)
SDL_WAYLAND_INTERFACE(wl_data_device_interface) SDL_WAYLAND_INTERFACE(wl_data_device_interface)
SDL_WAYLAND_INTERFACE(wl_data_source_interface) SDL_WAYLAND_INTERFACE(wl_data_source_interface)

View file

@ -47,7 +47,6 @@
#include <wayland-util.h> #include <wayland-util.h>
#include "xdg-shell-client-protocol.h" #include "xdg-shell-client-protocol.h"
#include "xdg-shell-unstable-v6-client-protocol.h"
#include "xdg-decoration-unstable-v1-client-protocol.h" #include "xdg-decoration-unstable-v1-client-protocol.h"
#include "keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h" #include "keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h"
#include "idle-inhibit-unstable-v1-client-protocol.h" #include "idle-inhibit-unstable-v1-client-protocol.h"
@ -414,18 +413,6 @@ static const struct qt_windowmanager_listener windowmanager_listener = {
}; };
#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ #endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
static void
handle_ping_zxdg_shell(void *data, struct zxdg_shell_v6 *zxdg, uint32_t serial)
{
zxdg_shell_v6_pong(zxdg, serial);
}
static const struct zxdg_shell_v6_listener shell_listener_zxdg = {
handle_ping_zxdg_shell
};
static void static void
handle_ping_xdg_wm_base(void *data, struct xdg_wm_base *xdg, uint32_t serial) handle_ping_xdg_wm_base(void *data, struct xdg_wm_base *xdg, uint32_t serial)
{ {
@ -473,19 +460,6 @@ display_handle_global(void *data, struct wl_registry *registry, uint32_t id,
SDL_strcmp(interface, "xdg_wm_base") == 0) { SDL_strcmp(interface, "xdg_wm_base") == 0) {
d->shell.xdg = wl_registry_bind(d->registry, id, &xdg_wm_base_interface, 1); d->shell.xdg = wl_registry_bind(d->registry, id, &xdg_wm_base_interface, 1);
xdg_wm_base_add_listener(d->shell.xdg, &shell_listener_xdg, NULL); xdg_wm_base_add_listener(d->shell.xdg, &shell_listener_xdg, NULL);
} else if (
#ifdef HAVE_LIBDECOR_H
!d->shell.libdecor &&
#endif
SDL_strcmp(interface, "zxdg_shell_v6") == 0) {
d->shell.zxdg = wl_registry_bind(d->registry, id, &zxdg_shell_v6_interface, 1);
zxdg_shell_v6_add_listener(d->shell.zxdg, &shell_listener_zxdg, NULL);
} else if (
#ifdef HAVE_LIBDECOR_H
!d->shell.libdecor &&
#endif
SDL_strcmp(interface, "wl_shell") == 0) {
d->shell.wl = wl_registry_bind(d->registry, id, &wl_shell_interface, 1);
} else if (SDL_strcmp(interface, "wl_shm") == 0) { } else if (SDL_strcmp(interface, "wl_shm") == 0) {
d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1); d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
d->cursor_theme = WAYLAND_wl_cursor_theme_load(NULL, 32, d->shm); d->cursor_theme = WAYLAND_wl_cursor_theme_load(NULL, 32, d->shm);
@ -657,15 +631,9 @@ Wayland_VideoQuit(_THIS)
if (data->cursor_theme) if (data->cursor_theme)
WAYLAND_wl_cursor_theme_destroy(data->cursor_theme); WAYLAND_wl_cursor_theme_destroy(data->cursor_theme);
if (data->shell.wl)
wl_shell_destroy(data->shell.wl);
if (data->shell.xdg) if (data->shell.xdg)
xdg_wm_base_destroy(data->shell.xdg); xdg_wm_base_destroy(data->shell.xdg);
if (data->shell.zxdg)
zxdg_shell_v6_destroy(data->shell.zxdg);
if (data->decoration_manager) if (data->decoration_manager)
zxdg_decoration_manager_v1_destroy(data->decoration_manager); zxdg_decoration_manager_v1_destroy(data->decoration_manager);

View file

@ -25,15 +25,6 @@
#ifndef SDL_waylandvideo_h_ #ifndef SDL_waylandvideo_h_
#define SDL_waylandvideo_h_ #define SDL_waylandvideo_h_
/*
!!! FIXME: xdg_wm_base is the stable replacement for zxdg_shell_v6. While it's
!!! FIXME: harmless to leave it here, consider deleting the obsolete codepath
!!! FIXME: soon, since Wayland (with xdg_wm_base) will probably be mainline
!!! FIXME: by the time people are relying on this SDL target. It's available
!!! FIXME: in Ubuntu 18.04 (and other distros).
*/
#include <EGL/egl.h> #include <EGL/egl.h>
#include "wayland-util.h" #include "wayland-util.h"
@ -60,8 +51,6 @@ typedef struct {
struct wl_pointer *pointer; struct wl_pointer *pointer;
struct { struct {
struct xdg_wm_base *xdg; struct xdg_wm_base *xdg;
struct zxdg_shell_v6 *zxdg;
struct wl_shell *wl;
#ifdef HAVE_LIBDECOR_H #ifdef HAVE_LIBDECOR_H
struct libdecor *libdecor; struct libdecor *libdecor;
#endif #endif

View file

@ -34,7 +34,6 @@
#include "SDL_hints.h" #include "SDL_hints.h"
#include "xdg-shell-client-protocol.h" #include "xdg-shell-client-protocol.h"
#include "xdg-shell-unstable-v6-client-protocol.h"
#include "xdg-decoration-unstable-v1-client-protocol.h" #include "xdg-decoration-unstable-v1-client-protocol.h"
#include "idle-inhibit-unstable-v1-client-protocol.h" #include "idle-inhibit-unstable-v1-client-protocol.h"
#include "xdg-activation-v1-client-protocol.h" #include "xdg-activation-v1-client-protocol.h"
@ -61,7 +60,7 @@ static void
CommitMinMaxDimensions(SDL_Window *window) CommitMinMaxDimensions(SDL_Window *window)
{ {
SDL_WindowData *wind = window->driverdata; SDL_WindowData *wind = window->driverdata;
SDL_VideoData *data = wind->waylandData; SDL_VideoData *viddata = wind->waylandData;
int min_width, min_height, max_width, max_height; int min_width, min_height, max_width, max_height;
if (window->flags & SDL_WINDOW_FULLSCREEN) { if (window->flags & SDL_WINDOW_FULLSCREEN) {
@ -82,7 +81,7 @@ CommitMinMaxDimensions(SDL_Window *window)
} }
#ifdef HAVE_LIBDECOR_H #ifdef HAVE_LIBDECOR_H
if (data->shell.libdecor) { if (viddata->shell.libdecor) {
if (wind->shell_surface.libdecor.frame == NULL) { if (wind->shell_surface.libdecor.frame == NULL) {
return; /* Can't do anything yet, wait for ShowWindow */ return; /* Can't do anything yet, wait for ShowWindow */
} }
@ -94,7 +93,7 @@ CommitMinMaxDimensions(SDL_Window *window)
max_height); max_height);
} else } else
#endif #endif
if (data->shell.xdg) { if (viddata->shell.xdg) {
if (wind->shell_surface.xdg.roleobj.toplevel == NULL) { if (wind->shell_surface.xdg.roleobj.toplevel == NULL) {
return; /* Can't do anything yet, wait for ShowWindow */ return; /* Can't do anything yet, wait for ShowWindow */
} }
@ -105,17 +104,6 @@ CommitMinMaxDimensions(SDL_Window *window)
max_width, max_width,
max_height); max_height);
wl_surface_commit(wind->surface); wl_surface_commit(wind->surface);
} else if (data->shell.zxdg) {
if (wind->shell_surface.zxdg.roleobj.toplevel == NULL) {
return; /* Can't do anything yet, wait for ShowWindow */
}
zxdg_toplevel_v6_set_min_size(wind->shell_surface.zxdg.roleobj.toplevel,
min_width,
min_height);
zxdg_toplevel_v6_set_max_size(wind->shell_surface.zxdg.roleobj.toplevel,
max_width,
max_height);
wl_surface_commit(wind->surface);
} }
} }
@ -159,92 +147,9 @@ SetFullscreen(SDL_Window *window, struct wl_output *output)
} else { } else {
xdg_toplevel_unset_fullscreen(wind->shell_surface.xdg.roleobj.toplevel); xdg_toplevel_unset_fullscreen(wind->shell_surface.xdg.roleobj.toplevel);
} }
} else if (viddata->shell.zxdg) {
if (wind->shell_surface.zxdg.roleobj.toplevel == NULL) {
return; /* Can't do anything yet, wait for ShowWindow */
}
if (output) {
zxdg_toplevel_v6_set_fullscreen(wind->shell_surface.zxdg.roleobj.toplevel, output);
} else {
zxdg_toplevel_v6_unset_fullscreen(wind->shell_surface.zxdg.roleobj.toplevel);
}
} else {
if (wind->shell_surface.wl == NULL) {
return; /* Can't do anything yet, wait for ShowWindow */
}
if (output) {
wl_shell_surface_set_fullscreen(wind->shell_surface.wl,
WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
0, output);
} else {
wl_shell_surface_set_toplevel(wind->shell_surface.wl);
}
} }
} }
/* On modern desktops, we probably will use the xdg-shell protocol instead
of wl_shell, but wl_shell might be useful on older Wayland installs that
don't have the newer protocol, or embedded things that don't have a full
window manager. */
static void
handle_ping_wl_shell_surface(void *data, struct wl_shell_surface *shell_surface,
uint32_t serial)
{
wl_shell_surface_pong(shell_surface, serial);
}
static void
handle_configure_wl_shell_surface(void *data, struct wl_shell_surface *shell_surface,
uint32_t edges, int32_t width, int32_t height)
{
SDL_WindowData *wind = (SDL_WindowData *)data;
SDL_Window *window = wind->sdlwindow;
/* wl_shell_surface spec states that this is a suggestion.
Ignore if less than or greater than max/min size. */
if (width == 0 || height == 0) {
return;
}
if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
if ((window->flags & SDL_WINDOW_RESIZABLE)) {
if (window->max_w > 0) {
width = SDL_min(width, window->max_w);
}
width = SDL_max(width, window->min_w);
if (window->max_h > 0) {
height = SDL_min(height, window->max_h);
}
height = SDL_max(height, window->min_h);
} else {
return;
}
}
wind->resize.width = width;
wind->resize.height = height;
wind->resize.pending = SDL_TRUE;
if (!(window->flags & SDL_WINDOW_OPENGL)) {
Wayland_HandlePendingResize(window); /* OpenGL windows handle this in SwapWindow */
}
}
static void
handle_popup_done_wl_shell_surface(void *data, struct wl_shell_surface *shell_surface)
{
}
static const struct wl_shell_surface_listener shell_surface_listener_wl = {
handle_ping_wl_shell_surface,
handle_configure_wl_shell_surface,
handle_popup_done_wl_shell_surface
};
static const struct wl_callback_listener surface_frame_listener; static const struct wl_callback_listener surface_frame_listener;
static void static void
@ -263,140 +168,6 @@ static const struct wl_callback_listener surface_frame_listener = {
handle_surface_frame_done handle_surface_frame_done
}; };
static void
handle_configure_zxdg_shell_surface(void *data, struct zxdg_surface_v6 *zxdg, uint32_t serial)
{
SDL_WindowData *wind = (SDL_WindowData *)data;
SDL_Window *window = wind->sdlwindow;
struct wl_region *region;
if (!wind->shell_surface.zxdg.initial_configure_seen) {
window->w = 0;
window->h = 0;
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, wind->resize.width, wind->resize.height);
window->w = wind->resize.width;
window->h = wind->resize.height;
wl_surface_set_buffer_scale(wind->surface, get_window_scale_factor(window));
if (wind->egl_window) {
WAYLAND_wl_egl_window_resize(wind->egl_window, window->w * get_window_scale_factor(window), window->h * get_window_scale_factor(window), 0, 0);
}
zxdg_surface_v6_ack_configure(zxdg, serial);
region = wl_compositor_create_region(wind->waylandData->compositor);
wl_region_add(region, 0, 0, window->w, window->h);
wl_surface_set_opaque_region(wind->surface, region);
wl_region_destroy(region);
wind->shell_surface.zxdg.initial_configure_seen = SDL_TRUE;
} else {
wind->resize.pending = SDL_TRUE;
wind->resize.configure = SDL_TRUE;
wind->resize.serial = serial;
if (!(window->flags & SDL_WINDOW_OPENGL)) {
Wayland_HandlePendingResize(window); /* OpenGL windows handle this in SwapWindow */
}
}
}
static const struct zxdg_surface_v6_listener shell_surface_listener_zxdg = {
handle_configure_zxdg_shell_surface
};
static void
handle_configure_zxdg_toplevel(void *data,
struct zxdg_toplevel_v6 *zxdg_toplevel_v6,
int32_t width,
int32_t height,
struct wl_array *states)
{
SDL_WindowData *wind = (SDL_WindowData *)data;
SDL_Window *window = wind->sdlwindow;
enum zxdg_toplevel_v6_state *state;
SDL_bool fullscreen = SDL_FALSE;
SDL_bool maximized = SDL_FALSE;
wl_array_for_each(state, states) {
if (*state == ZXDG_TOPLEVEL_V6_STATE_FULLSCREEN) {
fullscreen = SDL_TRUE;
} else if (*state == ZXDG_TOPLEVEL_V6_STATE_MAXIMIZED) {
maximized = SDL_TRUE;
}
}
if (!fullscreen) {
if (window->flags & SDL_WINDOW_FULLSCREEN) {
/* We might need to re-enter fullscreen after being restored from minimized */
SDL_WaylandOutputData *driverdata = (SDL_WaylandOutputData *) SDL_GetDisplayForWindow(window)->driverdata;
SetFullscreen(window, driverdata->output);
fullscreen = SDL_TRUE;
}
if (width == 0 || height == 0) {
width = window->windowed.w;
height = window->windowed.h;
}
/* zxdg_toplevel spec states that this is a suggestion.
Ignore if less than or greater than max/min size. */
if ((window->flags & SDL_WINDOW_RESIZABLE)) {
if (window->max_w > 0) {
width = SDL_min(width, window->max_w);
}
width = SDL_max(width, window->min_w);
if (window->max_h > 0) {
height = SDL_min(height, window->max_h);
}
height = SDL_max(height, window->min_h);
} else {
wind->resize.width = window->w;
wind->resize.height = window->h;
return;
}
}
/* Always send a maximized/restore event; if the event is redundant it will
* automatically be discarded (see src/events/SDL_windowevents.c).
*
* No, we do not get minimize events from zxdg-shell.
*/
if (!fullscreen) {
SDL_SendWindowEvent(window,
maximized ?
SDL_WINDOWEVENT_MAXIMIZED :
SDL_WINDOWEVENT_RESTORED,
0, 0);
}
if (width == 0 || height == 0) {
wind->resize.width = window->w;
wind->resize.height = window->h;
return;
}
wind->resize.width = width;
wind->resize.height = height;
}
static void
handle_close_zxdg_toplevel(void *data, struct zxdg_toplevel_v6 *zxdg_toplevel_v6)
{
SDL_WindowData *window = (SDL_WindowData *)data;
SDL_SendWindowEvent(window->sdlwindow, SDL_WINDOWEVENT_CLOSE, 0, 0);
}
static const struct zxdg_toplevel_v6_listener toplevel_listener_zxdg = {
handle_configure_zxdg_toplevel,
handle_close_zxdg_toplevel
};
static void static void
handle_configure_xdg_shell_surface(void *data, struct xdg_surface *xdg, uint32_t serial) handle_configure_xdg_shell_surface(void *data, struct xdg_surface *xdg, uint32_t serial)
{ {
@ -438,7 +209,6 @@ static const struct xdg_surface_listener shell_surface_listener_xdg = {
handle_configure_xdg_shell_surface handle_configure_xdg_shell_surface
}; };
static void static void
handle_configure_xdg_toplevel(void *data, handle_configure_xdg_toplevel(void *data,
struct xdg_toplevel *xdg_toplevel, struct xdg_toplevel *xdg_toplevel,
@ -784,10 +554,14 @@ Wayland_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
info->info.wl.display = data->waylandData->display; info->info.wl.display = data->waylandData->display;
info->info.wl.surface = data->surface; info->info.wl.surface = data->surface;
info->info.wl.shell_surface = data->shell_surface.wl;
if (version >= SDL_VERSIONNUM(2, 0, 15)) { if (version >= SDL_VERSIONNUM(2, 0, 15)) {
info->info.wl.egl_window = data->egl_window; info->info.wl.egl_window = data->egl_window;
} }
info->info.wl.shell_surface = NULL;
info->info.wl.xdg_surface = data->shell_surface.xdg.surface;
info->subsystem = SDL_SYSWM_WAYLAND; info->subsystem = SDL_SYSWM_WAYLAND;
return SDL_TRUE; return SDL_TRUE;
@ -802,7 +576,7 @@ Wayland_SetWindowHitTest(SDL_Window *window, SDL_bool enabled)
int int
Wayland_SetWindowModalFor(_THIS, SDL_Window *modal_window, SDL_Window *parent_window) Wayland_SetWindowModalFor(_THIS, SDL_Window *modal_window, SDL_Window *parent_window)
{ {
const SDL_VideoData *viddata = (const SDL_VideoData *) _this->driverdata; SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata;
SDL_WindowData *modal_data = modal_window->driverdata; SDL_WindowData *modal_data = modal_window->driverdata;
SDL_WindowData *parent_data = parent_window->driverdata; SDL_WindowData *parent_data = parent_window->driverdata;
@ -815,20 +589,9 @@ Wayland_SetWindowModalFor(_THIS, SDL_Window *modal_window, SDL_Window *parent_wi
} }
xdg_toplevel_set_parent(modal_data->shell_surface.xdg.roleobj.toplevel, xdg_toplevel_set_parent(modal_data->shell_surface.xdg.roleobj.toplevel,
parent_data->shell_surface.xdg.roleobj.toplevel); parent_data->shell_surface.xdg.roleobj.toplevel);
} else if (viddata->shell.zxdg) {
if (modal_data->shell_surface.zxdg.roleobj.toplevel == NULL) {
return SDL_SetError("Modal window was hidden");
}
if (parent_data->shell_surface.zxdg.roleobj.toplevel == NULL) {
return SDL_SetError("Parent window was hidden");
}
zxdg_toplevel_v6_set_parent(modal_data->shell_surface.zxdg.roleobj.toplevel,
parent_data->shell_surface.zxdg.roleobj.toplevel);
} else {
return SDL_Unsupported();
} }
WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display ); WAYLAND_wl_display_flush(viddata->display);
return 0; return 0;
} }
@ -868,20 +631,11 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
data->shell_surface.xdg.roleobj.toplevel = xdg_surface_get_toplevel(data->shell_surface.xdg.surface); data->shell_surface.xdg.roleobj.toplevel = xdg_surface_get_toplevel(data->shell_surface.xdg.surface);
xdg_toplevel_set_app_id(data->shell_surface.xdg.roleobj.toplevel, c->classname); xdg_toplevel_set_app_id(data->shell_surface.xdg.roleobj.toplevel, c->classname);
xdg_toplevel_add_listener(data->shell_surface.xdg.roleobj.toplevel, &toplevel_listener_xdg, data); xdg_toplevel_add_listener(data->shell_surface.xdg.roleobj.toplevel, &toplevel_listener_xdg, data);
} else if (c->shell.zxdg) { }
data->shell_surface.zxdg.surface = zxdg_shell_v6_get_xdg_surface(c->shell.zxdg, data->surface);
zxdg_surface_v6_set_user_data(data->shell_surface.zxdg.surface, data);
zxdg_surface_v6_add_listener(data->shell_surface.zxdg.surface, &shell_surface_listener_zxdg, data);
/* !!! FIXME: add popup role */ /* Create the window decorations */
data->shell_surface.zxdg.roleobj.toplevel = zxdg_surface_v6_get_toplevel(data->shell_surface.zxdg.surface); if (c->decoration_manager) {
zxdg_toplevel_v6_add_listener(data->shell_surface.zxdg.roleobj.toplevel, &toplevel_listener_zxdg, data); data->server_decoration = zxdg_decoration_manager_v1_get_toplevel_decoration(c->decoration_manager, data->shell_surface.xdg.roleobj.toplevel);
zxdg_toplevel_v6_set_app_id(data->shell_surface.zxdg.roleobj.toplevel, c->classname);
} else {
data->shell_surface.wl = wl_shell_get_shell_surface(c->shell.wl, data->surface);
wl_shell_surface_set_class(data->shell_surface.wl, c->classname);
wl_shell_surface_set_user_data(data->shell_surface.wl, data);
wl_shell_surface_add_listener(data->shell_surface.wl, &shell_surface_listener_wl, data);
} }
/* Restore state that was set prior to this call */ /* Restore state that was set prior to this call */
@ -919,13 +673,6 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
if (data->shell_surface.xdg.roleobj.toplevel && c->decoration_manager) { if (data->shell_surface.xdg.roleobj.toplevel && c->decoration_manager) {
data->server_decoration = zxdg_decoration_manager_v1_get_toplevel_decoration(c->decoration_manager, data->shell_surface.xdg.roleobj.toplevel); data->server_decoration = zxdg_decoration_manager_v1_get_toplevel_decoration(c->decoration_manager, data->shell_surface.xdg.roleobj.toplevel);
} }
} else if (c->shell.zxdg) {
if (data->shell_surface.zxdg.surface) {
while (!data->shell_surface.zxdg.initial_configure_seen) {
WAYLAND_wl_display_flush(c->display);
WAYLAND_wl_display_dispatch(c->display);
}
}
} }
/* Unlike the rest of window state we have to set this _after_ flushing the /* Unlike the rest of window state we have to set this _after_ flushing the
@ -981,20 +728,6 @@ void Wayland_HideWindow(_THIS, SDL_Window *window)
xdg_surface_destroy(wind->shell_surface.xdg.surface); xdg_surface_destroy(wind->shell_surface.xdg.surface);
wind->shell_surface.xdg.surface = NULL; wind->shell_surface.xdg.surface = NULL;
} }
} else if (data->shell.zxdg) {
if (wind->shell_surface.zxdg.roleobj.toplevel) {
zxdg_toplevel_v6_destroy(wind->shell_surface.zxdg.roleobj.toplevel);
wind->shell_surface.zxdg.roleobj.toplevel = NULL;
}
if (wind->shell_surface.zxdg.surface) {
zxdg_surface_v6_destroy(wind->shell_surface.zxdg.surface);
wind->shell_surface.zxdg.surface = NULL;
}
} else {
if (wind->shell_surface.wl) {
wl_shell_surface_destroy(wind->shell_surface.wl);
wind->shell_surface.wl = NULL;
}
} }
} }
@ -1191,7 +924,7 @@ void
Wayland_RestoreWindow(_THIS, SDL_Window * window) Wayland_RestoreWindow(_THIS, SDL_Window * window)
{ {
SDL_WindowData *wind = window->driverdata; SDL_WindowData *wind = window->driverdata;
const SDL_VideoData *viddata = (const SDL_VideoData *) _this->driverdata; SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata;
/* Set this flag now even if we never actually maximized, eventually /* Set this flag now even if we never actually maximized, eventually
* ShowWindow will take care of it along with the other window state. * ShowWindow will take care of it along with the other window state.
@ -1212,19 +945,9 @@ Wayland_RestoreWindow(_THIS, SDL_Window * window)
return; /* Can't do anything yet, wait for ShowWindow */ return; /* Can't do anything yet, wait for ShowWindow */
} }
xdg_toplevel_unset_maximized(wind->shell_surface.xdg.roleobj.toplevel); xdg_toplevel_unset_maximized(wind->shell_surface.xdg.roleobj.toplevel);
} else if (viddata->shell.zxdg) {
if (wind->shell_surface.zxdg.roleobj.toplevel == NULL) {
return; /* Can't do anything yet, wait for ShowWindow */
}
zxdg_toplevel_v6_unset_maximized(wind->shell_surface.zxdg.roleobj.toplevel);
} else {
if (wind->shell_surface.wl == NULL) {
return; /* Can't do anything yet, wait for ShowWindow */
}
wl_shell_surface_set_toplevel(wind->shell_surface.wl);
} }
WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display ); WAYLAND_wl_display_flush( viddata->display );
} }
void void
@ -1296,19 +1019,9 @@ Wayland_MaximizeWindow(_THIS, SDL_Window * window)
return; /* Can't do anything yet, wait for ShowWindow */ return; /* Can't do anything yet, wait for ShowWindow */
} }
xdg_toplevel_set_maximized(wind->shell_surface.xdg.roleobj.toplevel); xdg_toplevel_set_maximized(wind->shell_surface.xdg.roleobj.toplevel);
} else if (viddata->shell.zxdg) {
if (wind->shell_surface.zxdg.roleobj.toplevel == NULL) {
return; /* Can't do anything yet, wait for ShowWindow */
}
zxdg_toplevel_v6_set_maximized(wind->shell_surface.zxdg.roleobj.toplevel);
} else {
if (wind->shell_surface.wl == NULL) {
return; /* Can't do anything yet, wait for ShowWindow */
}
wl_shell_surface_set_maximized(wind->shell_surface.wl, NULL);
} }
WAYLAND_wl_display_flush( viddata->display ); WAYLAND_wl_display_flush(viddata->display);
} }
void void
@ -1330,11 +1043,6 @@ Wayland_MinimizeWindow(_THIS, SDL_Window * window)
return; /* Can't do anything yet, wait for ShowWindow */ return; /* Can't do anything yet, wait for ShowWindow */
} }
xdg_toplevel_set_minimized(wind->shell_surface.xdg.roleobj.toplevel); xdg_toplevel_set_minimized(wind->shell_surface.xdg.roleobj.toplevel);
} else if (viddata->shell.zxdg) {
if (wind->shell_surface.zxdg.roleobj.toplevel == NULL) {
return; /* Can't do anything yet, wait for ShowWindow */
}
zxdg_toplevel_v6_set_minimized(wind->shell_surface.zxdg.roleobj.toplevel);
} }
WAYLAND_wl_display_flush(viddata->display); WAYLAND_wl_display_flush(viddata->display);
@ -1447,7 +1155,7 @@ int Wayland_CreateWindow(_THIS, SDL_Window *window)
/* Create the GLES window surface */ /* Create the GLES window surface */
data->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) data->egl_window); data->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) data->egl_window);
if (data->egl_surface == EGL_NO_SURFACE) { if (data->egl_surface == EGL_NO_SURFACE) {
return SDL_SetError("failed to create an EGL window surface"); return SDL_SetError("failed to create an EGL window surface");
} }
@ -1508,8 +1216,6 @@ Wayland_HandlePendingResize(SDL_Window *window)
#endif #endif
if (data->waylandData->shell.xdg) { if (data->waylandData->shell.xdg) {
xdg_surface_ack_configure(data->shell_surface.xdg.surface, data->resize.serial); xdg_surface_ack_configure(data->shell_surface.xdg.surface, data->resize.serial);
} else if (data->waylandData->shell.zxdg) {
zxdg_surface_v6_ack_configure(data->shell_surface.zxdg.surface, data->resize.serial);
} }
data->resize.configure = SDL_FALSE; data->resize.configure = SDL_FALSE;
} }
@ -1576,7 +1282,7 @@ void Wayland_SetWindowSize(_THIS, SDL_Window * window)
void Wayland_SetWindowTitle(_THIS, SDL_Window * window) void Wayland_SetWindowTitle(_THIS, SDL_Window * window)
{ {
SDL_WindowData *wind = window->driverdata; SDL_WindowData *wind = window->driverdata;
SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata; SDL_VideoData *viddata = _this->driverdata;
if (window->title != NULL) { if (window->title != NULL) {
#ifdef HAVE_LIBDECOR_H #ifdef HAVE_LIBDECOR_H
@ -1592,20 +1298,10 @@ void Wayland_SetWindowTitle(_THIS, SDL_Window * window)
return; /* Can't do anything yet, wait for ShowWindow */ return; /* Can't do anything yet, wait for ShowWindow */
} }
xdg_toplevel_set_title(wind->shell_surface.xdg.roleobj.toplevel, window->title); xdg_toplevel_set_title(wind->shell_surface.xdg.roleobj.toplevel, window->title);
} else if (viddata->shell.zxdg) {
if (wind->shell_surface.zxdg.roleobj.toplevel == NULL) {
return; /* Can't do anything yet, wait for ShowWindow */
}
zxdg_toplevel_v6_set_title(wind->shell_surface.zxdg.roleobj.toplevel, window->title);
} else {
if (wind->shell_surface.wl == NULL) {
return; /* Can'd do anything yet, wait for ShowWindow */
}
wl_shell_surface_set_title(wind->shell_surface.wl, window->title);
} }
} }
WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display ); WAYLAND_wl_display_flush(viddata->display);
} }
void void
@ -1622,7 +1318,7 @@ Wayland_SuspendScreenSaver(_THIS)
/* The idle_inhibit_unstable_v1 protocol suspends the screensaver /* The idle_inhibit_unstable_v1 protocol suspends the screensaver
on a per wl_surface basis, but SDL assumes that suspending on a per wl_surface basis, but SDL assumes that suspending
the screensaver can be done independently of any window. the screensaver can be done independently of any window.
To reconcile these differences, we propagate the idle inhibit To reconcile these differences, we propagate the idle inhibit
state to each window. If there is no window active, we will state to each window. If there is no window active, we will
be able to inhibit idle once the first window is created. be able to inhibit idle once the first window is created.

View file

@ -32,15 +32,6 @@
struct SDL_WaylandInput; struct SDL_WaylandInput;
typedef struct {
struct zxdg_surface_v6 *surface;
union {
struct zxdg_toplevel_v6 *toplevel;
struct zxdg_popup_v6 *popup;
} roleobj;
SDL_bool initial_configure_seen;
} SDL_zxdg_shell_surface;
typedef struct { typedef struct {
struct xdg_surface *surface; struct xdg_surface *surface;
union { union {
@ -63,12 +54,10 @@ typedef struct {
struct wl_surface *surface; struct wl_surface *surface;
struct wl_callback *frame_callback; struct wl_callback *frame_callback;
union { union {
SDL_xdg_shell_surface xdg;
SDL_zxdg_shell_surface zxdg;
#ifdef HAVE_LIBDECOR_H #ifdef HAVE_LIBDECOR_H
SDL_libdecor_surface libdecor; SDL_libdecor_surface libdecor;
#endif #endif
struct wl_shell_surface *wl; SDL_xdg_shell_surface xdg;
} shell_surface; } shell_surface;
struct wl_egl_window *egl_window; struct wl_egl_window *egl_window;
struct SDL_WaylandInput *keyboard_device; struct SDL_WaylandInput *keyboard_device;

View file

@ -57,6 +57,12 @@
This request creates a registry object that allows the client This request creates a registry object that allows the client
to list and bind the global objects available from the to list and bind the global objects available from the
compositor. compositor.
It should be noted that the server side resources consumed in
response to a get_registry request can only be released when the
client disconnects, not when the client side proxy is destroyed.
Therefore, clients should invoke get_registry as infrequently as
possible to avoid wasting memory.
</description> </description>
<arg name="registry" type="new_id" interface="wl_registry" <arg name="registry" type="new_id" interface="wl_registry"
summary="global registry object"/> summary="global registry object"/>
@ -85,18 +91,20 @@
<entry name="invalid_object" value="0" <entry name="invalid_object" value="0"
summary="server couldn't find object"/> summary="server couldn't find object"/>
<entry name="invalid_method" value="1" <entry name="invalid_method" value="1"
summary="method doesn't exist on the specified interface"/> summary="method doesn't exist on the specified interface or malformed request"/>
<entry name="no_memory" value="2" <entry name="no_memory" value="2"
summary="server is out of memory"/> summary="server is out of memory"/>
<entry name="implementation" value="3"
summary="implementation error in compositor"/>
</enum> </enum>
<event name="delete_id"> <event name="delete_id">
<description summary="acknowledge object ID deletion"> <description summary="acknowledge object ID deletion">
This event is used internally by the object ID management This event is used internally by the object ID management
logic. When a client deletes an object, the server will send logic. When a client deletes an object that it had created,
this event to acknowledge that it has seen the delete request. the server will send this event to acknowledge that it has
When the client receives this event, it will know that it can seen the delete request. When the client receives this event,
safely reuse the object ID. it will know that it can safely reuse the object ID.
</description> </description>
<arg name="id" type="uint" summary="deleted object ID"/> <arg name="id" type="uint" summary="deleted object ID"/>
</event> </event>
@ -285,10 +293,12 @@
formats are optional and may not be supported by the particular formats are optional and may not be supported by the particular
renderer in use. renderer in use.
The drm format codes match the macros defined in drm_fourcc.h. The drm format codes match the macros defined in drm_fourcc.h, except
The formats actually supported by the compositor will be argb8888 and xrgb8888. The formats actually supported by the compositor
reported by the format event. will be reported by the format event.
</description> </description>
<!-- Note to protocol writers: don't update this list manually, instead
run the automated script that keeps it in sync with drm_fourcc.h. -->
<entry name="argb8888" value="0" summary="32-bit ARGB format, [31:0] A:R:G:B 8:8:8:8 little endian"/> <entry name="argb8888" value="0" summary="32-bit ARGB format, [31:0] A:R:G:B 8:8:8:8 little endian"/>
<entry name="xrgb8888" value="1" summary="32-bit RGB format, [31:0] x:R:G:B 8:8:8:8 little endian"/> <entry name="xrgb8888" value="1" summary="32-bit RGB format, [31:0] x:R:G:B 8:8:8:8 little endian"/>
<entry name="c8" value="0x20203843" summary="8-bit color index format, [7:0] C"/> <entry name="c8" value="0x20203843" summary="8-bit color index format, [7:0] C"/>
@ -347,6 +357,52 @@
<entry name="yvu422" value="0x36315659" summary="3 plane YCbCr format, 2x1 subsampled Cr (1) and Cb (2) planes"/> <entry name="yvu422" value="0x36315659" summary="3 plane YCbCr format, 2x1 subsampled Cr (1) and Cb (2) planes"/>
<entry name="yuv444" value="0x34325559" summary="3 plane YCbCr format, non-subsampled Cb (1) and Cr (2) planes"/> <entry name="yuv444" value="0x34325559" summary="3 plane YCbCr format, non-subsampled Cb (1) and Cr (2) planes"/>
<entry name="yvu444" value="0x34325659" summary="3 plane YCbCr format, non-subsampled Cr (1) and Cb (2) planes"/> <entry name="yvu444" value="0x34325659" summary="3 plane YCbCr format, non-subsampled Cr (1) and Cb (2) planes"/>
<entry name="r8" value="0x20203852" summary="[7:0] R"/>
<entry name="r16" value="0x20363152" summary="[15:0] R little endian"/>
<entry name="rg88" value="0x38384752" summary="[15:0] R:G 8:8 little endian"/>
<entry name="gr88" value="0x38385247" summary="[15:0] G:R 8:8 little endian"/>
<entry name="rg1616" value="0x32334752" summary="[31:0] R:G 16:16 little endian"/>
<entry name="gr1616" value="0x32335247" summary="[31:0] G:R 16:16 little endian"/>
<entry name="xrgb16161616f" value="0x48345258" summary="[63:0] x:R:G:B 16:16:16:16 little endian"/>
<entry name="xbgr16161616f" value="0x48344258" summary="[63:0] x:B:G:R 16:16:16:16 little endian"/>
<entry name="argb16161616f" value="0x48345241" summary="[63:0] A:R:G:B 16:16:16:16 little endian"/>
<entry name="abgr16161616f" value="0x48344241" summary="[63:0] A:B:G:R 16:16:16:16 little endian"/>
<entry name="xyuv8888" value="0x56555958" summary="[31:0] X:Y:Cb:Cr 8:8:8:8 little endian"/>
<entry name="vuy888" value="0x34325556" summary="[23:0] Cr:Cb:Y 8:8:8 little endian"/>
<entry name="vuy101010" value="0x30335556" summary="Y followed by U then V, 10:10:10. Non-linear modifier only"/>
<entry name="y210" value="0x30313259" summary="[63:0] Cr0:0:Y1:0:Cb0:0:Y0:0 10:6:10:6:10:6:10:6 little endian per 2 Y pixels"/>
<entry name="y212" value="0x32313259" summary="[63:0] Cr0:0:Y1:0:Cb0:0:Y0:0 12:4:12:4:12:4:12:4 little endian per 2 Y pixels"/>
<entry name="y216" value="0x36313259" summary="[63:0] Cr0:Y1:Cb0:Y0 16:16:16:16 little endian per 2 Y pixels"/>
<entry name="y410" value="0x30313459" summary="[31:0] A:Cr:Y:Cb 2:10:10:10 little endian"/>
<entry name="y412" value="0x32313459" summary="[63:0] A:0:Cr:0:Y:0:Cb:0 12:4:12:4:12:4:12:4 little endian"/>
<entry name="y416" value="0x36313459" summary="[63:0] A:Cr:Y:Cb 16:16:16:16 little endian"/>
<entry name="xvyu2101010" value="0x30335658" summary="[31:0] X:Cr:Y:Cb 2:10:10:10 little endian"/>
<entry name="xvyu12_16161616" value="0x36335658" summary="[63:0] X:0:Cr:0:Y:0:Cb:0 12:4:12:4:12:4:12:4 little endian"/>
<entry name="xvyu16161616" value="0x38345658" summary="[63:0] X:Cr:Y:Cb 16:16:16:16 little endian"/>
<entry name="y0l0" value="0x304c3059" summary="[63:0] A3:A2:Y3:0:Cr0:0:Y2:0:A1:A0:Y1:0:Cb0:0:Y0:0 1:1:8:2:8:2:8:2:1:1:8:2:8:2:8:2 little endian"/>
<entry name="x0l0" value="0x304c3058" summary="[63:0] X3:X2:Y3:0:Cr0:0:Y2:0:X1:X0:Y1:0:Cb0:0:Y0:0 1:1:8:2:8:2:8:2:1:1:8:2:8:2:8:2 little endian"/>
<entry name="y0l2" value="0x324c3059" summary="[63:0] A3:A2:Y3:Cr0:Y2:A1:A0:Y1:Cb0:Y0 1:1:10:10:10:1:1:10:10:10 little endian"/>
<entry name="x0l2" value="0x324c3058" summary="[63:0] X3:X2:Y3:Cr0:Y2:X1:X0:Y1:Cb0:Y0 1:1:10:10:10:1:1:10:10:10 little endian"/>
<entry name="yuv420_8bit" value="0x38305559"/>
<entry name="yuv420_10bit" value="0x30315559"/>
<entry name="xrgb8888_a8" value="0x38415258"/>
<entry name="xbgr8888_a8" value="0x38414258"/>
<entry name="rgbx8888_a8" value="0x38415852"/>
<entry name="bgrx8888_a8" value="0x38415842"/>
<entry name="rgb888_a8" value="0x38413852"/>
<entry name="bgr888_a8" value="0x38413842"/>
<entry name="rgb565_a8" value="0x38413552"/>
<entry name="bgr565_a8" value="0x38413542"/>
<entry name="nv24" value="0x3432564e" summary="non-subsampled Cr:Cb plane"/>
<entry name="nv42" value="0x3234564e" summary="non-subsampled Cb:Cr plane"/>
<entry name="p210" value="0x30313250" summary="2x1 subsampled Cr:Cb plane, 10 bit per channel"/>
<entry name="p010" value="0x30313050" summary="2x2 subsampled Cr:Cb plane 10 bits per channel"/>
<entry name="p012" value="0x32313050" summary="2x2 subsampled Cr:Cb plane 12 bits per channel"/>
<entry name="p016" value="0x36313050" summary="2x2 subsampled Cr:Cb plane 16 bits per channel"/>
<entry name="axbxgxrx106106106106" value="0x30314241" summary="[63:0] A:x:B:x:G:x:R:x 10:6:10:6:10:6:10:6 little endian"/>
<entry name="nv15" value="0x3531564e" summary="2x2 subsampled Cr:Cb plane"/>
<entry name="q410" value="0x30313451"/>
<entry name="q401" value="0x31303451"/>
</enum> </enum>
<request name="create_pool"> <request name="create_pool">
@ -501,6 +557,9 @@
this request after a NULL mime type has been set in this request after a NULL mime type has been set in
wl_data_offer.accept or no action was received through wl_data_offer.accept or no action was received through
wl_data_offer.action. wl_data_offer.action.
If wl_data_offer.finish request is received for a non drag and drop
operation, the invalid_finish protocol error is raised.
</description> </description>
</request> </request>
@ -517,7 +576,7 @@
This request determines the final result of the drag-and-drop This request determines the final result of the drag-and-drop
operation. If the end result is that no action is accepted, operation. If the end result is that no action is accepted,
the drag source will receive wl_drag_source.cancelled. the drag source will receive wl_data_source.cancelled.
The dnd_actions argument must contain only values expressed in the The dnd_actions argument must contain only values expressed in the
wl_data_device_manager.dnd_actions enum, and the preferred_action wl_data_device_manager.dnd_actions enum, and the preferred_action
@ -538,8 +597,10 @@
This request can only be made on drag-and-drop offers, a protocol error This request can only be made on drag-and-drop offers, a protocol error
will be raised otherwise. will be raised otherwise.
</description> </description>
<arg name="dnd_actions" type="uint" summary="actions supported by the destination client"/> <arg name="dnd_actions" type="uint" summary="actions supported by the destination client"
<arg name="preferred_action" type="uint" summary="action preferred by the destination client"/> enum="wl_data_device_manager.dnd_action"/>
<arg name="preferred_action" type="uint" summary="action preferred by the destination client"
enum="wl_data_device_manager.dnd_action"/>
</request> </request>
<event name="source_actions" since="3"> <event name="source_actions" since="3">
@ -548,7 +609,8 @@
will be sent right after wl_data_device.enter, or anytime the source will be sent right after wl_data_device.enter, or anytime the source
side changes its offered actions through wl_data_source.set_actions. side changes its offered actions through wl_data_source.set_actions.
</description> </description>
<arg name="source_actions" type="uint" summary="actions offered by the data source"/> <arg name="source_actions" type="uint" summary="actions offered by the data source"
enum="wl_data_device_manager.dnd_action"/>
</event> </event>
<event name="action" since="3"> <event name="action" since="3">
@ -589,7 +651,8 @@
final wl_data_offer.set_actions and wl_data_offer.accept requests final wl_data_offer.set_actions and wl_data_offer.accept requests
must happen before the call to wl_data_offer.finish. must happen before the call to wl_data_offer.finish.
</description> </description>
<arg name="dnd_action" type="uint" summary="action selected by the compositor"/> <arg name="dnd_action" type="uint" summary="action selected by the compositor"
enum="wl_data_device_manager.dnd_action"/>
</event> </event>
</interface> </interface>
@ -686,7 +749,8 @@
wl_data_device.start_drag. Attempting to use the source other than wl_data_device.start_drag. Attempting to use the source other than
for drag-and-drop will raise a protocol error. for drag-and-drop will raise a protocol error.
</description> </description>
<arg name="dnd_actions" type="uint" summary="actions supported by the data source"/> <arg name="dnd_actions" type="uint" summary="actions supported by the data source"
enum="wl_data_device_manager.dnd_action"/>
</request> </request>
<event name="dnd_drop_performed" since="3"> <event name="dnd_drop_performed" since="3">
@ -742,7 +806,8 @@
Clients can trigger cursor surface changes from this point, so Clients can trigger cursor surface changes from this point, so
they reflect the current action. they reflect the current action.
</description> </description>
<arg name="dnd_action" type="uint" summary="action selected by the compositor"/> <arg name="dnd_action" type="uint" summary="action selected by the compositor"
enum="wl_data_device_manager.dnd_action"/>
</event> </event>
</interface> </interface>
@ -768,7 +833,8 @@
for the eventual data transfer. If source is NULL, enter, leave for the eventual data transfer. If source is NULL, enter, leave
and motion events are sent only to the client that initiated the and motion events are sent only to the client that initiated the
drag and the client is expected to handle the data passing drag and the client is expected to handle the data passing
internally. internally. If source is destroyed, the drag-and-drop session will be
cancelled.
The origin surface is the surface where the drag originates and The origin surface is the surface where the drag originates and
the client must have an active implicit grab that matches the the client must have an active implicit grab that matches the
@ -970,6 +1036,9 @@
It allows clients to associate a wl_shell_surface with It allows clients to associate a wl_shell_surface with
a basic surface. a basic surface.
Note! This protocol is deprecated and not intended for production use.
For desktop-style user interfaces, use xdg_shell.
</description> </description>
<enum name="error"> <enum name="error">
@ -1265,8 +1334,10 @@
<interface name="wl_surface" version="4"> <interface name="wl_surface" version="4">
<description summary="an onscreen surface"> <description summary="an onscreen surface">
A surface is a rectangular area that is displayed on the screen. A surface is a rectangular area that may be displayed on zero
It has a location, size and pixel contents. or more outputs, and shown any number of times at the compositor's
discretion. They can present wl_buffers, receive user input, and
define a local coordinate system.
The size of a surface (and relative positions on it) is described The size of a surface (and relative positions on it) is described
in surface-local coordinates, which may differ from the buffer in surface-local coordinates, which may differ from the buffer
@ -1312,6 +1383,7 @@
</description> </description>
<entry name="invalid_scale" value="0" summary="buffer scale value is invalid"/> <entry name="invalid_scale" value="0" summary="buffer scale value is invalid"/>
<entry name="invalid_transform" value="1" summary="buffer transform value is invalid"/> <entry name="invalid_transform" value="1" summary="buffer transform value is invalid"/>
<entry name="invalid_size" value="2" summary="buffer size is invalid"/>
</enum> </enum>
<request name="destroy" type="destructor"> <request name="destroy" type="destructor">
@ -1326,8 +1398,9 @@
The new size of the surface is calculated based on the buffer The new size of the surface is calculated based on the buffer
size transformed by the inverse buffer_transform and the size transformed by the inverse buffer_transform and the
inverse buffer_scale. This means that the supplied buffer inverse buffer_scale. This means that at commit time the supplied
must be an integer multiple of the buffer_scale. buffer size must be an integer multiple of the buffer_scale. If
that's not the case, an invalid_size error is sent.
The x and y arguments specify the location of the new pending The x and y arguments specify the location of the new pending
buffer's upper left corner, relative to the current buffer's upper buffer's upper left corner, relative to the current buffer's upper
@ -1354,6 +1427,12 @@
will not receive a release event, and is not used by the will not receive a release event, and is not used by the
compositor. compositor.
If a pending wl_buffer has been committed to more than one wl_surface,
the delivery of wl_buffer.release events becomes undefined. A well
behaved client should not rely on wl_buffer.release events in this
case. Alternatively, a client could create multiple wl_buffer objects
from the same backing storage or use wp_linux_buffer_release.
Destroying the wl_buffer after wl_buffer.release does not change Destroying the wl_buffer after wl_buffer.release does not change
the surface contents. However, if the client destroys the the surface contents. However, if the client destroys the
wl_buffer before receiving the wl_buffer.release event, the surface wl_buffer before receiving the wl_buffer.release event, the surface
@ -1388,9 +1467,9 @@
and clears pending damage. The server will clear the current and clears pending damage. The server will clear the current
damage as it repaints the surface. damage as it repaints the surface.
Alternatively, damage can be posted with wl_surface.damage_buffer Note! New clients should not use this request. Instead damage can be
which uses buffer coordinates instead of surface coordinates, posted with wl_surface.damage_buffer which uses buffer coordinates
and is probably the preferred and intuitive way of doing this. instead of surface coordinates.
</description> </description>
<arg name="x" type="int" summary="surface-local x coordinate"/> <arg name="x" type="int" summary="surface-local x coordinate"/>
<arg name="y" type="int" summary="surface-local y coordinate"/> <arg name="y" type="int" summary="surface-local y coordinate"/>
@ -1534,6 +1613,12 @@
This is emitted whenever a surface's creation, movement, or resizing This is emitted whenever a surface's creation, movement, or resizing
results in it no longer having any part of it within the scanout region results in it no longer having any part of it within the scanout region
of an output. of an output.
Clients should not use the number of outputs the surface is on for frame
throttling purposes. The surface might be hidden even if no leave event
has been sent, and the compositor might expect new surface content
updates even if no enter event has been sent. The frame event should be
used instead.
</description> </description>
<arg name="output" type="object" interface="wl_output" summary="output left by the surface"/> <arg name="output" type="object" interface="wl_output" summary="output left by the surface"/>
</event> </event>
@ -1651,7 +1736,7 @@
</request> </request>
</interface> </interface>
<interface name="wl_seat" version="6"> <interface name="wl_seat" version="7">
<description summary="group of input devices"> <description summary="group of input devices">
A seat is a group of keyboards, pointer and touch devices. This A seat is a group of keyboards, pointer and touch devices. This
object is published as a global during start up, or when such a object is published as a global during start up, or when such a
@ -1669,6 +1754,14 @@
<entry name="touch" value="4" summary="the seat has touch devices"/> <entry name="touch" value="4" summary="the seat has touch devices"/>
</enum> </enum>
<enum name="error">
<description summary="wl_seat error values">
These errors can be emitted in response to wl_seat requests.
</description>
<entry name="missing_capability" value="0"
summary="get_pointer, get_keyboard or get_touch called on seat without the matching capability"/>
</enum>
<event name="capabilities"> <event name="capabilities">
<description summary="seat capabilities changed"> <description summary="seat capabilities changed">
This is emitted whenever a seat gains or loses the pointer, This is emitted whenever a seat gains or loses the pointer,
@ -1707,7 +1800,8 @@
This request only takes effect if the seat has the pointer This request only takes effect if the seat has the pointer
capability, or has had the pointer capability in the past. capability, or has had the pointer capability in the past.
It is a protocol violation to issue this request on a seat that has It is a protocol violation to issue this request on a seat that has
never had the pointer capability. never had the pointer capability. The missing_capability error will
be sent in this case.
</description> </description>
<arg name="id" type="new_id" interface="wl_pointer" summary="seat pointer"/> <arg name="id" type="new_id" interface="wl_pointer" summary="seat pointer"/>
</request> </request>
@ -1720,7 +1814,8 @@
This request only takes effect if the seat has the keyboard This request only takes effect if the seat has the keyboard
capability, or has had the keyboard capability in the past. capability, or has had the keyboard capability in the past.
It is a protocol violation to issue this request on a seat that has It is a protocol violation to issue this request on a seat that has
never had the keyboard capability. never had the keyboard capability. The missing_capability error will
be sent in this case.
</description> </description>
<arg name="id" type="new_id" interface="wl_keyboard" summary="seat keyboard"/> <arg name="id" type="new_id" interface="wl_keyboard" summary="seat keyboard"/>
</request> </request>
@ -1733,7 +1828,8 @@
This request only takes effect if the seat has the touch This request only takes effect if the seat has the touch
capability, or has had the touch capability in the past. capability, or has had the touch capability in the past.
It is a protocol violation to issue this request on a seat that has It is a protocol violation to issue this request on a seat that has
never had the touch capability. never had the touch capability. The missing_capability error will
be sent in this case.
</description> </description>
<arg name="id" type="new_id" interface="wl_touch" summary="seat touch interface"/> <arg name="id" type="new_id" interface="wl_touch" summary="seat touch interface"/>
</request> </request>
@ -1760,7 +1856,7 @@
</interface> </interface>
<interface name="wl_pointer" version="6"> <interface name="wl_pointer" version="7">
<description summary="pointer input device"> <description summary="pointer input device">
The wl_pointer interface represents one or more input devices, The wl_pointer interface represents one or more input devices,
such as mice, which control the pointer location and pointer_focus such as mice, which control the pointer location and pointer_focus
@ -2083,7 +2179,7 @@
</event> </event>
</interface> </interface>
<interface name="wl_keyboard" version="6"> <interface name="wl_keyboard" version="7">
<description summary="keyboard input device"> <description summary="keyboard input device">
The wl_keyboard interface represents one or more keyboards The wl_keyboard interface represents one or more keyboards
associated with a seat. associated with a seat.
@ -2104,6 +2200,9 @@
<description summary="keyboard mapping"> <description summary="keyboard mapping">
This event provides a file descriptor to the client which can be This event provides a file descriptor to the client which can be
memory-mapped to provide a keyboard mapping description. memory-mapped to provide a keyboard mapping description.
From version 7 onwards, the fd must be mapped with MAP_PRIVATE by
the recipient, as MAP_SHARED may fail.
</description> </description>
<arg name="format" type="uint" enum="keymap_format" summary="keymap format"/> <arg name="format" type="uint" enum="keymap_format" summary="keymap format"/>
<arg name="fd" type="fd" summary="keymap file descriptor"/> <arg name="fd" type="fd" summary="keymap file descriptor"/>
@ -2114,6 +2213,9 @@
<description summary="enter event"> <description summary="enter event">
Notification that this seat's keyboard focus is on a certain Notification that this seat's keyboard focus is on a certain
surface. surface.
The compositor must send the wl_keyboard.modifiers event after this
event.
</description> </description>
<arg name="serial" type="uint" summary="serial number of the enter event"/> <arg name="serial" type="uint" summary="serial number of the enter event"/>
<arg name="surface" type="object" interface="wl_surface" summary="surface gaining keyboard focus"/> <arg name="surface" type="object" interface="wl_surface" summary="surface gaining keyboard focus"/>
@ -2127,6 +2229,9 @@
The leave notification is sent before the enter notification The leave notification is sent before the enter notification
for the new focus. for the new focus.
After this event client must assume that all keys, including modifiers,
are lifted and also it must stop key repeating if there's some going on.
</description> </description>
<arg name="serial" type="uint" summary="serial number of the leave event"/> <arg name="serial" type="uint" summary="serial number of the leave event"/>
<arg name="surface" type="object" interface="wl_surface" summary="surface that lost keyboard focus"/> <arg name="surface" type="object" interface="wl_surface" summary="surface that lost keyboard focus"/>
@ -2145,6 +2250,12 @@
A key was pressed or released. A key was pressed or released.
The time argument is a timestamp with millisecond The time argument is a timestamp with millisecond
granularity, with an undefined base. granularity, with an undefined base.
The key is a platform-specific key code that can be interpreted
by feeding it to the keyboard mapping (see the keymap event).
If this event produces a change in modifiers, then the resulting
wl_keyboard.modifiers event must be sent after this event.
</description> </description>
<arg name="serial" type="uint" summary="serial number of the key event"/> <arg name="serial" type="uint" summary="serial number of the key event"/>
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/> <arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
@ -2194,7 +2305,7 @@
</event> </event>
</interface> </interface>
<interface name="wl_touch" version="6"> <interface name="wl_touch" version="7">
<description summary="touchscreen input device"> <description summary="touchscreen input device">
The wl_touch interface represents a touchscreen The wl_touch interface represents a touchscreen
associated with a seat. associated with a seat.
@ -2390,6 +2501,16 @@
The geometry event describes geometric properties of the output. The geometry event describes geometric properties of the output.
The event is sent when binding to the output object and whenever The event is sent when binding to the output object and whenever
any of the properties change. any of the properties change.
The physical size can be set to zero if it doesn't make sense for this
output (e.g. for projectors or virtual outputs).
Note: wl_output only advertises partial information about the output
position and identification. Some compositors, for instance those not
implementing a desktop-style output layout or those exposing virtual
outputs, might fake this information. Instead of using x and y, clients
should use xdg_output.logical_position. Instead of using make and model,
clients should use xdg_output.name and xdg_output.description.
</description> </description>
<arg name="x" type="int" <arg name="x" type="int"
summary="x position within the global compositor space"/> summary="x position within the global compositor space"/>
@ -2430,11 +2551,28 @@
current. In other words, the current mode is always the last current. In other words, the current mode is always the last
mode that was received with the current flag set. mode that was received with the current flag set.
Non-current modes are deprecated. A compositor can decide to only
advertise the current mode and never send other modes. Clients
should not rely on non-current modes.
The size of a mode is given in physical hardware units of The size of a mode is given in physical hardware units of
the output device. This is not necessarily the same as the output device. This is not necessarily the same as
the output size in the global compositor space. For instance, the output size in the global compositor space. For instance,
the output may be scaled, as described in wl_output.scale, the output may be scaled, as described in wl_output.scale,
or transformed, as described in wl_output.transform. or transformed, as described in wl_output.transform. Clients
willing to retrieve the output size in the global compositor
space should use xdg_output.logical_size instead.
The vertical refresh rate can be set to zero if it doesn't make
sense for this output (e.g. for virtual outputs).
Clients should not use the refresh rate to schedule frames. Instead,
they should use the wl_surface.frame event or the presentation-time
protocol.
Note: this information is not always meaningful for all outputs. Some
compositors, such as those exposing virtual outputs, might fake the
refresh rate or the size.
</description> </description>
<arg name="flags" type="uint" enum="mode" summary="bitfield of mode flags"/> <arg name="flags" type="uint" enum="mode" summary="bitfield of mode flags"/>
<arg name="width" type="int" summary="width of the mode in hardware units"/> <arg name="width" type="int" summary="width of the mode in hardware units"/>
@ -2568,6 +2706,14 @@
The to-be sub-surface must not already have another role, and it The to-be sub-surface must not already have another role, and it
must not have an existing wl_subsurface object. Otherwise a protocol must not have an existing wl_subsurface object. Otherwise a protocol
error is raised. error is raised.
Adding sub-surfaces to a parent is a double-buffered operation on the
parent (see wl_surface.commit). The effect of adding a sub-surface
becomes visible on the next time the state of the parent surface is
applied.
This request modifies the behaviour of wl_surface.commit request on
the sub-surface, see the documentation on wl_subsurface interface.
</description> </description>
<arg name="id" type="new_id" interface="wl_subsurface" <arg name="id" type="new_id" interface="wl_subsurface"
summary="the new sub-surface object ID"/> summary="the new sub-surface object ID"/>
@ -2601,7 +2747,7 @@
wl_surface state directly. A sub-surface is initially in the wl_surface state directly. A sub-surface is initially in the
synchronized mode. synchronized mode.
Sub-surfaces have also other kind of state, which is managed by Sub-surfaces also have another kind of state, which is managed by
wl_subsurface requests, as opposed to wl_surface requests. This wl_subsurface requests, as opposed to wl_surface requests. This
state includes the sub-surface position relative to the parent state includes the sub-surface position relative to the parent
surface (wl_subsurface.set_position), and the stacking order of surface (wl_subsurface.set_position), and the stacking order of
@ -2637,7 +2783,7 @@
that was turned into a sub-surface with a that was turned into a sub-surface with a
wl_subcompositor.get_subsurface request. The wl_surface's association wl_subcompositor.get_subsurface request. The wl_surface's association
to the parent is deleted, and the wl_surface loses its role as to the parent is deleted, and the wl_surface loses its role as
a sub-surface. The wl_surface is unmapped. a sub-surface. The wl_surface is unmapped immediately.
</description> </description>
</request> </request>

File diff suppressed because it is too large Load diff

View file

@ -29,7 +29,7 @@
DEALINGS IN THE SOFTWARE. DEALINGS IN THE SOFTWARE.
</copyright> </copyright>
<interface name="xdg_wm_base" version="1"> <interface name="xdg_wm_base" version="3">
<description summary="create desktop-style surfaces"> <description summary="create desktop-style surfaces">
The xdg_wm_base interface is exposed as a global object enabling clients The xdg_wm_base interface is exposed as a global object enabling clients
to turn their wl_surfaces into windows in a desktop environment. It to turn their wl_surfaces into windows in a desktop environment. It
@ -101,7 +101,7 @@
<description summary="check if the client is alive"> <description summary="check if the client is alive">
The ping event asks the client if it's still alive. Pass the The ping event asks the client if it's still alive. Pass the
serial specified in the event back to the compositor by sending serial specified in the event back to the compositor by sending
a "pong" request back with the specified serial. See xdg_wm_base.ping. a "pong" request back with the specified serial. See xdg_wm_base.pong.
Compositors can use this to determine if the client is still Compositors can use this to determine if the client is still
alive. It's unspecified what will happen if the client doesn't alive. It's unspecified what will happen if the client doesn't
@ -115,7 +115,7 @@
</event> </event>
</interface> </interface>
<interface name="xdg_positioner" version="1"> <interface name="xdg_positioner" version="3">
<description summary="child surface positioner"> <description summary="child surface positioner">
The xdg_positioner provides a collection of rules for the placement of a The xdg_positioner provides a collection of rules for the placement of a
child surface relative to a parent surface. Rules can be defined to ensure child surface relative to a parent surface. Rules can be defined to ensure
@ -357,9 +357,49 @@
<arg name="x" type="int" summary="surface position x offset"/> <arg name="x" type="int" summary="surface position x offset"/>
<arg name="y" type="int" summary="surface position y offset"/> <arg name="y" type="int" summary="surface position y offset"/>
</request> </request>
<!-- Version 3 additions -->
<request name="set_reactive" since="3">
<description summary="continuously reconstrain the surface">
When set reactive, the surface is reconstrained if the conditions used
for constraining changed, e.g. the parent window moved.
If the conditions changed and the popup was reconstrained, an
xdg_popup.configure event is sent with updated geometry, followed by an
xdg_surface.configure event.
</description>
</request>
<request name="set_parent_size" since="3">
<description summary="">
Set the parent window geometry the compositor should use when
positioning the popup. The compositor may use this information to
determine the future state the popup should be constrained using. If
this doesn't match the dimension of the parent the popup is eventually
positioned against, the behavior is undefined.
The arguments are given in the surface-local coordinate space.
</description>
<arg name="parent_width" type="int"
summary="future window geometry width of parent"/>
<arg name="parent_height" type="int"
summary="future window geometry height of parent"/>
</request>
<request name="set_parent_configure" since="3">
<description summary="set parent configure this is a response to">
Set the serial of a xdg_surface.configure event this positioner will be
used in response to. The compositor may use this information together
with set_parent_size to determine what future state the popup should be
constrained using.
</description>
<arg name="serial" type="uint"
summary="serial of parent configure event"/>
</request>
</interface> </interface>
<interface name="xdg_surface" version="1"> <interface name="xdg_surface" version="3">
<description summary="desktop user interface surface base interface"> <description summary="desktop user interface surface base interface">
An interface that may be implemented by a wl_surface, for An interface that may be implemented by a wl_surface, for
implementations that provide a desktop-style user interface. implementations that provide a desktop-style user interface.
@ -526,9 +566,10 @@
</description> </description>
<arg name="serial" type="uint" summary="serial of the configure event"/> <arg name="serial" type="uint" summary="serial of the configure event"/>
</event> </event>
</interface> </interface>
<interface name="xdg_toplevel" version="1"> <interface name="xdg_toplevel" version="3">
<description summary="toplevel surface"> <description summary="toplevel surface">
This interface defines an xdg_surface role which allows a surface to, This interface defines an xdg_surface role which allows a surface to,
among other things, set window-like properties such as maximize, among other things, set window-like properties such as maximize,
@ -604,6 +645,9 @@
For example, "org.freedesktop.FooViewer" where the .desktop file is For example, "org.freedesktop.FooViewer" where the .desktop file is
"org.freedesktop.FooViewer.desktop". "org.freedesktop.FooViewer.desktop".
Like other properties, a set_app_id request can be sent after the
xdg_toplevel has been mapped to update the property.
See the desktop-entry specification [0] for more details on See the desktop-entry specification [0] for more details on
application identifiers and how they relate to well-known D-Bus application identifiers and how they relate to well-known D-Bus
names and .desktop files. names and .desktop files.
@ -707,7 +751,7 @@
</description> </description>
<arg name="seat" type="object" interface="wl_seat" summary="the wl_seat of the user event"/> <arg name="seat" type="object" interface="wl_seat" summary="the wl_seat of the user event"/>
<arg name="serial" type="uint" summary="the serial of the user event"/> <arg name="serial" type="uint" summary="the serial of the user event"/>
<arg name="edges" type="uint" summary="which edge or corner is being dragged"/> <arg name="edges" type="uint" enum="resize_edge" summary="which edge or corner is being dragged"/>
</request> </request>
<enum name="state"> <enum name="state">
@ -724,6 +768,9 @@
<description summary="the surface is maximized"> <description summary="the surface is maximized">
The surface is maximized. The window geometry specified in the configure The surface is maximized. The window geometry specified in the configure
event must be obeyed by the client. event must be obeyed by the client.
The client should draw without shadow or other
decoration outside of the window geometry.
</description> </description>
</entry> </entry>
<entry name="fullscreen" value="2" summary="the surface is fullscreen"> <entry name="fullscreen" value="2" summary="the surface is fullscreen">
@ -750,6 +797,30 @@
keyboard or pointer focus. keyboard or pointer focus.
</description> </description>
</entry> </entry>
<entry name="tiled_left" value="5" since="2">
<description summary="the surface is tiled">
The window is currently in a tiled layout and the left edge is
considered to be adjacent to another part of the tiling grid.
</description>
</entry>
<entry name="tiled_right" value="6" since="2">
<description summary="the surface is tiled">
The window is currently in a tiled layout and the right edge is
considered to be adjacent to another part of the tiling grid.
</description>
</entry>
<entry name="tiled_top" value="7" since="2">
<description summary="the surface is tiled">
The window is currently in a tiled layout and the top edge is
considered to be adjacent to another part of the tiling grid.
</description>
</entry>
<entry name="tiled_bottom" value="8" since="2">
<description summary="the surface is tiled">
The window is currently in a tiled layout and the bottom edge is
considered to be adjacent to another part of the tiling grid.
</description>
</entry>
</enum> </enum>
<request name="set_max_size"> <request name="set_max_size">
@ -839,12 +910,11 @@
Maximize the surface. Maximize the surface.
After requesting that the surface should be maximized, the compositor After requesting that the surface should be maximized, the compositor
will respond by emitting a configure event with the "maximized" state will respond by emitting a configure event. Whether this configure
and the required window geometry. The client should then update its actually sets the window maximized is subject to compositor policies.
content, drawing it in a maximized state, i.e. without shadow or other The client must then update its content, drawing in the configured
decoration outside of the window geometry. The client must also state. The client must also acknowledge the configure when committing
acknowledge the configure when committing the new content (see the new content (see ack_configure).
ack_configure).
It is up to the compositor to decide how and where to maximize the It is up to the compositor to decide how and where to maximize the
surface, for example which output and what region of the screen should surface, for example which output and what region of the screen should
@ -854,8 +924,8 @@
a configure event with the "maximized" state. a configure event with the "maximized" state.
If the surface is in a fullscreen state, this request has no direct If the surface is in a fullscreen state, this request has no direct
effect. It will alter the state the surface is returned to when effect. It may alter the state the surface is returned to when
unmaximized if not overridden by the compositor. unmaximized unless overridden by the compositor.
</description> </description>
</request> </request>
@ -864,13 +934,13 @@
Unmaximize the surface. Unmaximize the surface.
After requesting that the surface should be unmaximized, the compositor After requesting that the surface should be unmaximized, the compositor
will respond by emitting a configure event without the "maximized" will respond by emitting a configure event. Whether this actually
state. If available, the compositor will include the window geometry un-maximizes the window is subject to compositor policies.
dimensions the window had prior to being maximized in the configure If available and applicable, the compositor will include the window
event. The client must then update its content, drawing it in a geometry dimensions the window had prior to being maximized in the
regular state, i.e. potentially with shadow, etc. The client must also configure event. The client must then update its content, drawing it in
acknowledge the configure when committing the new content (see the configured state. The client must also acknowledge the configure
ack_configure). when committing the new content (see ack_configure).
It is up to the compositor to position the surface after it was It is up to the compositor to position the surface after it was
unmaximized; usually the position the surface had before maximizing, if unmaximized; usually the position the surface had before maximizing, if
@ -880,8 +950,8 @@
emit a configure event without the "maximized" state. emit a configure event without the "maximized" state.
If the surface is in a fullscreen state, this request has no direct If the surface is in a fullscreen state, this request has no direct
effect. It will alter the state the surface is returned to when effect. It may alter the state the surface is returned to when
unmaximized if not overridden by the compositor. unmaximized unless overridden by the compositor.
</description> </description>
</request> </request>
@ -890,10 +960,10 @@
Make the surface fullscreen. Make the surface fullscreen.
After requesting that the surface should be fullscreened, the After requesting that the surface should be fullscreened, the
compositor will respond by emitting a configure event with the compositor will respond by emitting a configure event. Whether the
"fullscreen" state and the fullscreen window geometry. The client must client is actually put into a fullscreen state is subject to compositor
also acknowledge the configure when committing the new content (see policies. The client must also acknowledge the configure when
ack_configure). committing the new content (see ack_configure).
The output passed by the request indicates the client's preference as The output passed by the request indicates the client's preference as
to which display it should be set fullscreen on. If this value is NULL, to which display it should be set fullscreen on. If this value is NULL,
@ -919,8 +989,9 @@
Make the surface no longer fullscreen. Make the surface no longer fullscreen.
After requesting that the surface should be unfullscreened, the After requesting that the surface should be unfullscreened, the
compositor will respond by emitting a configure event without the compositor will respond by emitting a configure event.
"fullscreen" state. Whether this actually removes the fullscreen state of the client is
subject to compositor policies.
Making a surface unfullscreen sets states for the surface based on the following: Making a surface unfullscreen sets states for the surface based on the following:
* the state(s) it may have had before becoming fullscreen * the state(s) it may have had before becoming fullscreen
@ -989,7 +1060,7 @@
</event> </event>
</interface> </interface>
<interface name="xdg_popup" version="1"> <interface name="xdg_popup" version="3">
<description summary="short-lived, popup surfaces for menus"> <description summary="short-lived, popup surfaces for menus">
A popup surface is a short-lived, temporary surface. It can be used to A popup surface is a short-lived, temporary surface. It can be used to
implement for example menus, popovers, tooltips and other similar user implement for example menus, popovers, tooltips and other similar user
@ -1007,21 +1078,12 @@
surface of their own is clicked should dismiss the popup using the destroy surface of their own is clicked should dismiss the popup using the destroy
request. request.
The parent surface must have either the xdg_toplevel or xdg_popup surface
role.
A newly created xdg_popup will be stacked on top of all previously created A newly created xdg_popup will be stacked on top of all previously created
xdg_popup surfaces associated with the same xdg_toplevel. xdg_popup surfaces associated with the same xdg_toplevel.
The parent of an xdg_popup must be mapped (see the xdg_surface The parent of an xdg_popup must be mapped (see the xdg_surface
description) before the xdg_popup itself. description) before the xdg_popup itself.
The x and y arguments passed when creating the popup object specify
where the top left of the popup should be placed, relative to the
local surface coordinates of the parent surface. See
xdg_surface.get_popup. An xdg_popup must intersect with or be at least
partially adjacent to its parent surface.
The client must call wl_surface.commit on the corresponding wl_surface The client must call wl_surface.commit on the corresponding wl_surface
for the xdg_popup state to take effect. for the xdg_popup state to take effect.
</description> </description>
@ -1099,6 +1161,11 @@
The x and y arguments represent the position the popup was placed at The x and y arguments represent the position the popup was placed at
given the xdg_positioner rule, relative to the upper left corner of the given the xdg_positioner rule, relative to the upper left corner of the
window geometry of the parent surface. window geometry of the parent surface.
For version 2 or older, the configure event for an xdg_popup is only
ever sent once for the initial configuration. Starting with version 3,
it may be sent again if the popup is setup with an xdg_positioner with
set_reactive requested, or in response to xdg_popup.reposition requests.
</description> </description>
<arg name="x" type="int" <arg name="x" type="int"
summary="x position relative to parent surface window geometry"/> summary="x position relative to parent surface window geometry"/>
@ -1116,5 +1183,58 @@
</description> </description>
</event> </event>
<!-- Version 3 additions -->
<request name="reposition" since="3">
<description summary="recalculate the popup's location">
Reposition an already-mapped popup. The popup will be placed given the
details in the passed xdg_positioner object, and a
xdg_popup.repositioned followed by xdg_popup.configure and
xdg_surface.configure will be emitted in response. Any parameters set
by the previous positioner will be discarded.
The passed token will be sent in the corresponding
xdg_popup.repositioned event. The new popup position will not take
effect until the corresponding configure event is acknowledged by the
client. See xdg_popup.repositioned for details. The token itself is
opaque, and has no other special meaning.
If multiple reposition requests are sent, the compositor may skip all
but the last one.
If the popup is repositioned in response to a configure event for its
parent, the client should send an xdg_positioner.set_parent_configure
and possibly a xdg_positioner.set_parent_size request to allow the
compositor to properly constrain the popup.
If the popup is repositioned together with a parent that is being
resized, but not in response to a configure event, the client should
send a xdg_positioner.set_parent_size request.
</description>
<arg name="positioner" type="object" interface="xdg_positioner"/>
<arg name="token" type="uint" summary="reposition request token"/>
</request>
<event name="repositioned" since="3">
<description summary="signal the completion of a repositioned request">
The repositioned event is sent as part of a popup configuration
sequence, together with xdg_popup.configure and lastly
xdg_surface.configure to notify the completion of a reposition request.
The repositioned event is to notify about the completion of a
xdg_popup.reposition request. The token argument is the token passed
in the xdg_popup.reposition request.
Immediately after this event is emitted, xdg_popup.configure and
xdg_surface.configure will be sent with the updated size and position,
as well as a new configure serial.
The client should optionally update the content of the popup, but must
acknowledge the new popup configuration for the new position to take
effect. See xdg_surface.ack_configure for details.
</description>
<arg name="token" type="uint" summary="reposition request token"/>
</event>
</interface> </interface>
</protocol> </protocol>