mirror of
https://github.com/libsdl-org/SDL.git
synced 2024-11-23 10:53:27 +08:00
wayland: client-side decoration
This commit is contained in:
parent
f4f9c6bc55
commit
9e6fcbe72c
@ -388,6 +388,7 @@ set_option(CLOCK_GETTIME "Use clock_gettime() instead of gettimeofday()" O
|
||||
set_option(VIDEO_X11 "Use X11 video driver" ${UNIX_SYS})
|
||||
set_option(VIDEO_WAYLAND "Use Wayland video driver" ${UNIX_SYS})
|
||||
dep_option(WAYLAND_SHARED "Dynamically load Wayland support" ON "VIDEO_WAYLAND" OFF)
|
||||
dep_option(WAYLAND_LIBDECOR "Use client-side window decorations on Wayland" ON "VIDEO_WAYLAND" ON)
|
||||
dep_option(VIDEO_WAYLAND_QT_TOUCH "QtWayland server support for Wayland video driver" ON "VIDEO_WAYLAND" OFF)
|
||||
set_option(VIDEO_RPI "Use Raspberry Pi video driver" ${UNIX_SYS})
|
||||
dep_option(X11_SHARED "Dynamically load X11 support" ON "VIDEO_X11" OFF)
|
||||
@ -2593,6 +2594,9 @@ if(SDL_SHARED)
|
||||
set_property(TARGET SDL2 APPEND_STRING PROPERTY COMPILE_FLAGS "-fobjc-arc")
|
||||
target_compile_definitions(SDL2 PRIVATE IOS_DYLIB=1)
|
||||
endif()
|
||||
if(WAYLAND_LIBDECOR)
|
||||
target_include_directories(SDL2 PRIVATE "${libdecor_INCLUDE_DIRS}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ANDROID)
|
||||
@ -2644,6 +2648,10 @@ if(SDL_STATIC)
|
||||
if(IOS OR TVOS)
|
||||
set_property(TARGET SDL2-static APPEND_STRING PROPERTY COMPILE_FLAGS "-fobjc-arc")
|
||||
endif()
|
||||
if(WAYLAND_LIBDECOR)
|
||||
target_include_directories(SDL2-static PRIVATE "${libdecor_INCLUDE_DIRS}")
|
||||
target_link_libraries(SDL2-static "${libdecor_LIBRARIES}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
##### Tests #####
|
||||
|
@ -697,6 +697,15 @@ macro(CheckWayland)
|
||||
set(EXTRA_LIBS ${WAYLAND_LIBRARIES} ${EXTRA_LIBS})
|
||||
endif()
|
||||
|
||||
if(WAYLAND_LIBDECOR)
|
||||
pkg_check_modules(libdecor REQUIRED libdecor-0)
|
||||
|
||||
FindLibraryAndSONAME(decor-0)
|
||||
set(SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR "\"${DECOR_0_LIB_SONAME}\"")
|
||||
|
||||
add_definitions(-DHAVE_LIBDECOR_H)
|
||||
endif()
|
||||
|
||||
set(SDL_VIDEO_DRIVER_WAYLAND 1)
|
||||
endif()
|
||||
endif()
|
||||
|
38
configure.ac
38
configure.ac
@ -2777,6 +2777,43 @@ CheckFcitx()
|
||||
fi
|
||||
}
|
||||
|
||||
dnl See if libdecor is available
|
||||
CheckLibDecor()
|
||||
{
|
||||
AC_ARG_ENABLE(libdecor,
|
||||
[AS_HELP_STRING([--enable-libdecor], [use libdecor for Wayland client-side decorations [default=yes]])],
|
||||
, enable_libdecor=yes)
|
||||
if test x$enable_libdecor = xyes; then
|
||||
AC_MSG_CHECKING(for libdecor support)
|
||||
AS_IF([$PKG_CONFIG --exists libdecor-0],
|
||||
[video_libdecor=yes],
|
||||
[video_libdecor=no])
|
||||
AC_MSG_RESULT($video_libdecor)
|
||||
if test x$video_libdecor = xyes; then
|
||||
EXTRA_CFLAGS="$EXTRA_CFLAGS `$PKG_CONFIG --cflags libdecor-0`"
|
||||
AC_DEFINE(HAVE_LIBDECOR_H, 1, [ ])
|
||||
|
||||
AC_ARG_ENABLE(libdecor-shared,
|
||||
[AS_HELP_STRING([--enable-libdecor-shared], [dynamically load libdecor [default=yes]])],
|
||||
, enable_libdecor_shared=yes)
|
||||
|
||||
decor_lib=[`find_lib "libdecor-0.so.*" "" | sed 's/.*\/\(.*\)/\1/; q'`]
|
||||
|
||||
if test x$have_loadso != xyes && \
|
||||
test x$enable_libdecor_shared = xyes; then
|
||||
AC_MSG_WARN([You must have SDL_LoadObject() support for dynamic libdecor loading])
|
||||
fi
|
||||
if test x$have_loadso = xyes && \
|
||||
test x$enable_libdecor_shared = xyes && test x$decor_lib != x; then
|
||||
echo "-- dynamic libdecor -> $decor_lib"
|
||||
AC_DEFINE_UNQUOTED(SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR, "$decor_lib", [ ])
|
||||
else
|
||||
EXTRA_LDFLAGS="$EXTRA_LDFLAGS `$PKG_CONFIG --libs libdecor-0`"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
dnl Check to see if GameController framework support is desired
|
||||
CheckJoystickMFI()
|
||||
{
|
||||
@ -3572,6 +3609,7 @@ case "$host" in
|
||||
CheckInotify
|
||||
CheckIBus
|
||||
CheckFcitx
|
||||
CheckLibDecor
|
||||
case $ARCH in
|
||||
linux)
|
||||
CheckInputKD
|
||||
|
@ -387,6 +387,7 @@
|
||||
#cmakedefine SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL @SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL@
|
||||
#cmakedefine SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR @SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR@
|
||||
#cmakedefine SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON @SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON@
|
||||
#cmakedefine SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR @SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR@
|
||||
|
||||
#cmakedefine SDL_VIDEO_DRIVER_X11 @SDL_VIDEO_DRIVER_X11@
|
||||
#cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC @SDL_VIDEO_DRIVER_X11_DYNAMIC@
|
||||
|
@ -225,6 +225,7 @@
|
||||
#undef HAVE_IMMINTRIN_H
|
||||
#undef HAVE_LIBUDEV_H
|
||||
#undef HAVE_LIBSAMPLERATE_H
|
||||
#undef HAVE_LIBDECOR_H
|
||||
|
||||
#undef HAVE_DDRAW_H
|
||||
#undef HAVE_DINPUT_H
|
||||
@ -365,6 +366,7 @@
|
||||
#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL
|
||||
#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR
|
||||
#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON
|
||||
#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR
|
||||
#undef SDL_VIDEO_DRIVER_X11
|
||||
#undef SDL_VIDEO_DRIVER_RPI
|
||||
#undef SDL_VIDEO_DRIVER_KMSDRM
|
||||
|
@ -47,12 +47,16 @@ typedef struct
|
||||
#ifndef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON
|
||||
#define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON NULL
|
||||
#endif
|
||||
#ifndef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR
|
||||
#define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR NULL
|
||||
#endif
|
||||
|
||||
static waylanddynlib waylandlibs[] = {
|
||||
{NULL, SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC},
|
||||
{NULL, SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL},
|
||||
{NULL, SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR},
|
||||
{NULL, SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON}
|
||||
{NULL, SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON},
|
||||
{NULL, SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR}
|
||||
};
|
||||
|
||||
static void *
|
||||
|
@ -34,6 +34,19 @@ struct wl_display;
|
||||
struct wl_surface;
|
||||
struct wl_shm;
|
||||
|
||||
/* We also need some for libdecor */
|
||||
struct wl_seat;
|
||||
struct wl_output;
|
||||
struct libdecor;
|
||||
struct libdecor_frame;
|
||||
struct libdecor_state;
|
||||
struct libdecor_configuration;
|
||||
struct libdecor_interface;
|
||||
struct libdecor_frame_interface;
|
||||
enum libdecor_resize_edge;
|
||||
enum libdecor_capabilities;
|
||||
enum libdecor_window_state;
|
||||
|
||||
#include <stdint.h>
|
||||
#include "wayland-cursor.h"
|
||||
#include "wayland-util.h"
|
||||
@ -82,6 +95,8 @@ void SDL_WAYLAND_UnloadSymbols(void);
|
||||
#define wl_proxy_add_listener (*WAYLAND_wl_proxy_add_listener)
|
||||
#define wl_proxy_marshal_constructor (*WAYLAND_wl_proxy_marshal_constructor)
|
||||
#define wl_proxy_marshal_constructor_versioned (*WAYLAND_wl_proxy_marshal_constructor_versioned)
|
||||
#define wl_proxy_set_tag (*WAYLAND_wl_proxy_set_tag)
|
||||
#define wl_proxy_get_tag (*WAYLAND_wl_proxy_get_tag)
|
||||
|
||||
#define wl_seat_interface (*WAYLAND_wl_seat_interface)
|
||||
#define wl_surface_interface (*WAYLAND_wl_surface_interface)
|
||||
@ -101,6 +116,35 @@ void SDL_WAYLAND_UnloadSymbols(void);
|
||||
#define wl_data_source_interface (*WAYLAND_wl_data_source_interface)
|
||||
#define wl_data_device_manager_interface (*WAYLAND_wl_data_device_manager_interface)
|
||||
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
/* Must be included before our defines */
|
||||
#include <libdecor.h>
|
||||
|
||||
#define libdecor_unref (*WAYLAND_libdecor_unref)
|
||||
#define libdecor_new (*WAYLAND_libdecor_new)
|
||||
#define libdecor_decorate (*WAYLAND_libdecor_decorate)
|
||||
#define libdecor_frame_unref (*WAYLAND_libdecor_frame_unref)
|
||||
#define libdecor_frame_set_title (*WAYLAND_libdecor_frame_set_title)
|
||||
#define libdecor_frame_set_app_id (*WAYLAND_libdecor_frame_set_app_id)
|
||||
#define libdecor_frame_set_max_content_size (*WAYLAND_libdecor_frame_set_max_content_size)
|
||||
#define libdecor_frame_set_min_content_size (*WAYLAND_libdecor_frame_set_min_content_size)
|
||||
#define libdecor_frame_resize (*WAYLAND_libdecor_frame_resize)
|
||||
#define libdecor_frame_move (*WAYLAND_libdecor_frame_move)
|
||||
#define libdecor_frame_commit (*WAYLAND_libdecor_frame_commit)
|
||||
#define libdecor_frame_set_minimized (*WAYLAND_libdecor_frame_set_minimized)
|
||||
#define libdecor_frame_set_maximized (*WAYLAND_libdecor_frame_set_maximized)
|
||||
#define libdecor_frame_unset_maximized (*WAYLAND_libdecor_frame_unset_maximized)
|
||||
#define libdecor_frame_set_fullscreen (*WAYLAND_libdecor_frame_set_fullscreen)
|
||||
#define libdecor_frame_unset_fullscreen (*WAYLAND_libdecor_frame_unset_fullscreen)
|
||||
#define libdecor_frame_set_capabilities (*WAYLAND_libdecor_frame_set_capabilities)
|
||||
#define libdecor_frame_unset_capabilities (*WAYLAND_libdecor_frame_unset_capabilities)
|
||||
#define libdecor_frame_map (*WAYLAND_libdecor_frame_map)
|
||||
#define libdecor_state_new (*WAYLAND_libdecor_state_new)
|
||||
#define libdecor_state_free (*WAYLAND_libdecor_state_free)
|
||||
#define libdecor_configuration_get_content_size (*WAYLAND_libdecor_configuration_get_content_size)
|
||||
#define libdecor_configuration_get_window_state (*WAYLAND_libdecor_configuration_get_window_state)
|
||||
#endif
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC */
|
||||
|
||||
#include "wayland-client-protocol.h"
|
||||
|
@ -43,6 +43,10 @@
|
||||
#include "xdg-shell-unstable-v6-client-protocol.h"
|
||||
#include "keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h"
|
||||
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
#include <libdecor.h>
|
||||
#endif
|
||||
|
||||
#ifdef SDL_INPUT_LINUXEV
|
||||
#include <linux/input.h>
|
||||
#else
|
||||
@ -272,6 +276,11 @@ pointer_handle_enter(void *data, struct wl_pointer *pointer,
|
||||
return;
|
||||
}
|
||||
|
||||
/* check that this surface belongs to one of the SDL windows */
|
||||
if (!SDL_WAYLAND_own_surface(surface)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* This handler will be called twice in Wayland 1.4
|
||||
* Once for the window surface which has valid user data
|
||||
* and again for the mouse cursor surface which does not have valid user data
|
||||
@ -301,6 +310,10 @@ pointer_handle_leave(void *data, struct wl_pointer *pointer,
|
||||
{
|
||||
struct SDL_WaylandInput *input = data;
|
||||
|
||||
if (!surface || !SDL_WAYLAND_own_surface(surface)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (input->pointer_focus) {
|
||||
SDL_SetMouseFocus(NULL);
|
||||
input->pointer_focus = NULL;
|
||||
@ -328,8 +341,20 @@ ProcessHitTest(struct SDL_WaylandInput *input, uint32_t serial)
|
||||
WL_SHELL_SURFACE_RESIZE_*), but the values are the same. */
|
||||
const uint32_t *directions_zxdg = directions_wl;
|
||||
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
/* ditto for libdecor. */
|
||||
const uint32_t *directions_libdecor = directions_wl;
|
||||
#endif
|
||||
|
||||
switch (rc) {
|
||||
case SDL_HITTEST_DRAGGABLE:
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
if (input->display->shell.libdecor) {
|
||||
if (window_data->shell_surface.libdecor.frame) {
|
||||
libdecor_frame_move(window_data->shell_surface.libdecor.frame, input->seat, serial);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
if (input->display->shell.xdg) {
|
||||
if (window_data->shell_surface.xdg.roleobj.toplevel) {
|
||||
xdg_toplevel_move(window_data->shell_surface.xdg.roleobj.toplevel,
|
||||
@ -357,6 +382,13 @@ ProcessHitTest(struct SDL_WaylandInput *input, uint32_t serial)
|
||||
case SDL_HITTEST_RESIZE_BOTTOM:
|
||||
case SDL_HITTEST_RESIZE_BOTTOMLEFT:
|
||||
case SDL_HITTEST_RESIZE_LEFT:
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
if (input->display->shell.libdecor) {
|
||||
if (window_data->shell_surface.libdecor.frame) {
|
||||
libdecor_frame_resize(window_data->shell_surface.libdecor.frame, input->seat, serial, directions_libdecor[rc - SDL_HITTEST_RESIZE_TOPLEFT]);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
if (input->display->shell.xdg) {
|
||||
if (window_data->shell_surface.xdg.roleobj.toplevel) {
|
||||
xdg_toplevel_resize(window_data->shell_surface.xdg.roleobj.toplevel,
|
||||
@ -723,6 +755,10 @@ keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!SDL_WAYLAND_own_surface(surface)) {
|
||||
return;
|
||||
}
|
||||
|
||||
window = wl_surface_get_user_data(surface);
|
||||
|
||||
if (window) {
|
||||
@ -741,6 +777,10 @@ keyboard_handle_leave(void *data, struct wl_keyboard *keyboard,
|
||||
{
|
||||
struct SDL_WaylandInput *input = data;
|
||||
|
||||
if (!surface || !SDL_WAYLAND_own_surface(surface)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Stop key repeat before clearing keyboard focus */
|
||||
keyboard_repeat_clear(&input->keyboard_repeat);
|
||||
|
||||
|
@ -33,6 +33,8 @@
|
||||
#define SDL_WAYLAND_INTERFACE(iface)
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
SDL_WAYLAND_MODULE(WAYLAND_CLIENT)
|
||||
SDL_WAYLAND_SYM(void, wl_proxy_marshal, (struct wl_proxy *, uint32_t, ...))
|
||||
SDL_WAYLAND_SYM(struct wl_proxy *, wl_proxy_create, (struct wl_proxy *, const struct wl_interface *))
|
||||
@ -71,6 +73,10 @@ SDL_WAYLAND_SYM(struct wl_proxy *, wl_proxy_marshal_constructor, (struct wl_prox
|
||||
SDL_WAYLAND_MODULE(WAYLAND_CLIENT_1_10)
|
||||
SDL_WAYLAND_SYM(struct wl_proxy *, wl_proxy_marshal_constructor_versioned, (struct wl_proxy *proxy, uint32_t opcode, const struct wl_interface *interface, uint32_t version, ...))
|
||||
|
||||
SDL_WAYLAND_MODULE(WAYLAND_CLIENT_1_18)
|
||||
SDL_WAYLAND_SYM(void, wl_proxy_set_tag, (struct wl_proxy *, const char * const *))
|
||||
SDL_WAYLAND_SYM(const char * const *, wl_proxy_get_tag, (struct wl_proxy *))
|
||||
|
||||
SDL_WAYLAND_INTERFACE(wl_seat_interface)
|
||||
SDL_WAYLAND_INTERFACE(wl_surface_interface)
|
||||
SDL_WAYLAND_INTERFACE(wl_shm_pool_interface)
|
||||
@ -134,6 +140,53 @@ SDL_WAYLAND_SYM(int, xkb_keymap_key_get_syms_by_level, (struct xkb_keymap *,
|
||||
const xkb_keysym_t **) )
|
||||
SDL_WAYLAND_SYM(uint32_t, xkb_keysym_to_utf32, (xkb_keysym_t) )
|
||||
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
SDL_WAYLAND_MODULE(WAYLAND_LIBDECOR)
|
||||
SDL_WAYLAND_SYM(void, libdecor_unref, (struct libdecor *))
|
||||
SDL_WAYLAND_SYM(struct libdecor *, libdecor_new, (struct wl_display *, struct libdecor_interface *))
|
||||
SDL_WAYLAND_SYM(struct libdecor_frame *, libdecor_decorate, (struct libdecor *,\
|
||||
struct wl_surface *,\
|
||||
struct libdecor_frame_interface *,\
|
||||
void *))
|
||||
SDL_WAYLAND_SYM(void, libdecor_frame_unref, (struct libdecor_frame *))
|
||||
SDL_WAYLAND_SYM(void, libdecor_frame_set_title, (struct libdecor_frame *, const char *))
|
||||
SDL_WAYLAND_SYM(void, libdecor_frame_set_app_id, (struct libdecor_frame *, const char *))
|
||||
SDL_WAYLAND_SYM(void, libdecor_frame_set_max_content_size, (struct libdecor_frame *frame,\
|
||||
int content_width,\
|
||||
int content_height))
|
||||
SDL_WAYLAND_SYM(void, libdecor_frame_set_min_content_size, (struct libdecor_frame *frame,\
|
||||
int content_width,\
|
||||
int content_height))
|
||||
SDL_WAYLAND_SYM(void, libdecor_frame_resize, (struct libdecor_frame *,\
|
||||
struct wl_seat *,\
|
||||
uint32_t,\
|
||||
enum libdecor_resize_edge))
|
||||
SDL_WAYLAND_SYM(void, libdecor_frame_move, (struct libdecor_frame *,\
|
||||
struct wl_seat *,\
|
||||
uint32_t))
|
||||
SDL_WAYLAND_SYM(void, libdecor_frame_commit, (struct libdecor_frame *,\
|
||||
struct libdecor_state *,\
|
||||
struct libdecor_configuration *))
|
||||
SDL_WAYLAND_SYM(void, libdecor_frame_set_minimized, (struct libdecor_frame *))
|
||||
SDL_WAYLAND_SYM(void, libdecor_frame_set_maximized, (struct libdecor_frame *))
|
||||
SDL_WAYLAND_SYM(void, libdecor_frame_unset_maximized, (struct libdecor_frame *))
|
||||
SDL_WAYLAND_SYM(void, libdecor_frame_set_fullscreen, (struct libdecor_frame *, struct wl_output *))
|
||||
SDL_WAYLAND_SYM(void, libdecor_frame_unset_fullscreen, (struct libdecor_frame *))
|
||||
SDL_WAYLAND_SYM(void, libdecor_frame_set_capabilities, (struct libdecor_frame *, \
|
||||
enum libdecor_capabilities))
|
||||
SDL_WAYLAND_SYM(void, libdecor_frame_unset_capabilities, (struct libdecor_frame *, \
|
||||
enum libdecor_capabilities))
|
||||
SDL_WAYLAND_SYM(void, libdecor_frame_map, (struct libdecor_frame *))
|
||||
SDL_WAYLAND_SYM(struct libdecor_state *, libdecor_state_new, (int, int))
|
||||
SDL_WAYLAND_SYM(void, libdecor_state_free, (struct libdecor_state *))
|
||||
SDL_WAYLAND_SYM(bool, libdecor_configuration_get_content_size, (struct libdecor_configuration *,\
|
||||
struct libdecor_frame *,\
|
||||
int *,\
|
||||
int *))
|
||||
SDL_WAYLAND_SYM(bool, libdecor_configuration_get_window_state, (struct libdecor_configuration *,\
|
||||
enum libdecor_window_state *))
|
||||
#endif
|
||||
|
||||
#undef SDL_WAYLAND_MODULE
|
||||
#undef SDL_WAYLAND_SYM
|
||||
#undef SDL_WAYLAND_INTERFACE
|
||||
|
@ -53,6 +53,10 @@
|
||||
#include "idle-inhibit-unstable-v1-client-protocol.h"
|
||||
#include "xdg-activation-v1-client-protocol.h"
|
||||
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
#include <libdecor.h>
|
||||
#endif
|
||||
|
||||
#define WAYLANDVID_DRIVER_NAME "wayland"
|
||||
|
||||
/* Initialization/Query functions */
|
||||
@ -433,6 +437,21 @@ static const struct xdg_wm_base_listener shell_listener_xdg = {
|
||||
};
|
||||
|
||||
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
static void
|
||||
libdecor_error(struct libdecor *context,
|
||||
enum libdecor_error error,
|
||||
const char *message)
|
||||
{
|
||||
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "libdecor error (%d): %s\n", error, message);
|
||||
}
|
||||
|
||||
static struct libdecor_interface libdecor_interface = {
|
||||
libdecor_error,
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
display_handle_global(void *data, struct wl_registry *registry, uint32_t id,
|
||||
const char *interface, uint32_t version)
|
||||
@ -447,13 +466,25 @@ display_handle_global(void *data, struct wl_registry *registry, uint32_t id,
|
||||
Wayland_add_display(d, id);
|
||||
} else if (SDL_strcmp(interface, "wl_seat") == 0) {
|
||||
Wayland_display_add_input(d, id, version);
|
||||
} else if (SDL_strcmp(interface, "xdg_wm_base") == 0) {
|
||||
} else if (
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
!d->shell.libdecor &&
|
||||
#endif
|
||||
SDL_strcmp(interface, "xdg_wm_base") == 0) {
|
||||
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);
|
||||
} else if (SDL_strcmp(interface, "zxdg_shell_v6") == 0) {
|
||||
} 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 (SDL_strcmp(interface, "wl_shell") == 0) {
|
||||
} 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) {
|
||||
d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
|
||||
@ -510,6 +541,12 @@ Wayland_VideoInit(_THIS)
|
||||
return SDL_SetError("Failed to get the Wayland registry");
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
if (SDL_WAYLAND_HAVE_WAYLAND_LIBDECOR) {
|
||||
data->shell.libdecor = libdecor_new(data->display, &libdecor_interface);
|
||||
}
|
||||
#endif
|
||||
|
||||
wl_registry_add_listener(data->registry, ®istry_listener, data);
|
||||
|
||||
// First roundtrip to receive all registry objects.
|
||||
@ -632,6 +669,13 @@ Wayland_VideoQuit(_THIS)
|
||||
if (data->decoration_manager)
|
||||
zxdg_decoration_manager_v1_destroy(data->decoration_manager);
|
||||
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
if (data->shell.libdecor) {
|
||||
libdecor_unref(data->shell.libdecor);
|
||||
data->shell.libdecor = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (data->compositor)
|
||||
wl_compositor_destroy(data->compositor);
|
||||
|
||||
|
@ -62,6 +62,9 @@ typedef struct {
|
||||
struct xdg_wm_base *xdg;
|
||||
struct zxdg_shell_v6 *zxdg;
|
||||
struct wl_shell *wl;
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
struct libdecor *libdecor;
|
||||
#endif
|
||||
} shell;
|
||||
struct zwp_relative_pointer_manager_v1 *relative_pointer_manager;
|
||||
struct zwp_pointer_constraints_v1 *pointer_constraints;
|
||||
|
@ -39,6 +39,20 @@
|
||||
#include "idle-inhibit-unstable-v1-client-protocol.h"
|
||||
#include "xdg-activation-v1-client-protocol.h"
|
||||
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
#include <libdecor.h>
|
||||
#endif
|
||||
|
||||
static const char *SDL_WAYLAND_surface_tag = "sdl-window";
|
||||
|
||||
SDL_bool SDL_WAYLAND_own_surface(struct wl_surface *surface)
|
||||
{
|
||||
if (SDL_WAYLAND_HAVE_WAYLAND_CLIENT_1_18) {
|
||||
return wl_proxy_get_tag((struct wl_proxy *) surface) == &SDL_WAYLAND_surface_tag;
|
||||
}
|
||||
return SDL_TRUE; /* For older clients we have to assume this is us... */
|
||||
}
|
||||
|
||||
static float get_window_scale_factor(SDL_Window *window) {
|
||||
return ((SDL_WindowData*)window->driverdata)->scale_factor;
|
||||
}
|
||||
@ -67,6 +81,19 @@ CommitMinMaxDimensions(SDL_Window *window)
|
||||
max_height = window->windowed.h;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
if (data->shell.libdecor) {
|
||||
if (wind->shell_surface.libdecor.frame == NULL) {
|
||||
return; /* Can't do anything yet, wait for ShowWindow */
|
||||
}
|
||||
libdecor_frame_set_min_content_size(wind->shell_surface.libdecor.frame,
|
||||
min_width,
|
||||
min_height);
|
||||
libdecor_frame_set_max_content_size(wind->shell_surface.libdecor.frame,
|
||||
max_width,
|
||||
max_height);
|
||||
} else
|
||||
#endif
|
||||
if (data->shell.xdg) {
|
||||
if (wind->shell_surface.xdg.roleobj.toplevel == NULL) {
|
||||
return; /* Can't do anything yet, wait for ShowWindow */
|
||||
@ -77,6 +104,7 @@ CommitMinMaxDimensions(SDL_Window *window)
|
||||
xdg_toplevel_set_max_size(wind->shell_surface.xdg.roleobj.toplevel,
|
||||
max_width,
|
||||
max_height);
|
||||
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 */
|
||||
@ -87,9 +115,8 @@ CommitMinMaxDimensions(SDL_Window *window)
|
||||
zxdg_toplevel_v6_set_max_size(wind->shell_surface.zxdg.roleobj.toplevel,
|
||||
max_width,
|
||||
max_height);
|
||||
wl_surface_commit(wind->surface);
|
||||
}
|
||||
|
||||
wl_surface_commit(wind->surface);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -103,6 +130,18 @@ SetFullscreen(SDL_Window *window, struct wl_output *output)
|
||||
*/
|
||||
CommitMinMaxDimensions(window);
|
||||
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
if (viddata->shell.libdecor) {
|
||||
if (wind->shell_surface.libdecor.frame == NULL) {
|
||||
return; /* Can't do anything yet, wait for ShowWindow */
|
||||
}
|
||||
if (output) {
|
||||
libdecor_frame_set_fullscreen(wind->shell_surface.libdecor.frame, output);
|
||||
} else {
|
||||
libdecor_frame_unset_fullscreen(wind->shell_surface.libdecor.frame);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
if (viddata->shell.xdg) {
|
||||
if (wind->shell_surface.xdg.roleobj.toplevel == NULL) {
|
||||
return; /* Can't do anything yet, wait for ShowWindow */
|
||||
@ -481,8 +520,97 @@ static const struct xdg_toplevel_listener toplevel_listener_xdg = {
|
||||
handle_close_xdg_toplevel
|
||||
};
|
||||
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
static void
|
||||
decoration_frame_configure(struct libdecor_frame *frame,
|
||||
struct libdecor_configuration *configuration,
|
||||
void *user_data)
|
||||
{
|
||||
SDL_WindowData *wind = user_data;
|
||||
SDL_Window *window = wind->sdlwindow;
|
||||
int width, height;
|
||||
enum libdecor_window_state window_state;
|
||||
struct libdecor_state *state;
|
||||
|
||||
/* window size */
|
||||
if (!libdecor_configuration_get_content_size(configuration, frame, &width, &height)) {
|
||||
width = window->w;
|
||||
height = window->h;
|
||||
}
|
||||
|
||||
wind->resize.width = width;
|
||||
wind->resize.height = height;
|
||||
|
||||
wind->resize.pending = SDL_TRUE;
|
||||
wind->resize.configure = SDL_TRUE;
|
||||
Wayland_HandlePendingResize(window);
|
||||
wind->shell_surface.libdecor.initial_configure_seen = SDL_TRUE;
|
||||
|
||||
window->w = wind->resize.width;
|
||||
window->h = wind->resize.height;
|
||||
|
||||
/* window state */
|
||||
if (!libdecor_configuration_get_window_state(configuration, &window_state)) {
|
||||
window_state = LIBDECOR_WINDOW_STATE_NONE;
|
||||
}
|
||||
|
||||
if (window_state & LIBDECOR_WINDOW_STATE_MAXIMIZED) {
|
||||
window->flags |= SDL_WINDOW_MAXIMIZED;
|
||||
}
|
||||
else {
|
||||
window->flags &= ~SDL_WINDOW_MAXIMIZED;
|
||||
}
|
||||
|
||||
if (window_state & LIBDECOR_WINDOW_STATE_ACTIVE) {
|
||||
window->flags |= SDL_WINDOW_INPUT_FOCUS;
|
||||
}
|
||||
else {
|
||||
window->flags &= ~SDL_WINDOW_INPUT_FOCUS;
|
||||
}
|
||||
|
||||
/* The fullscreen flag is already set my some other entity when 'SDL_SetWindowFullscreen'
|
||||
* is called, but we will set it here again in case the compositor requests fullscreen.
|
||||
*/
|
||||
if (window_state & LIBDECOR_WINDOW_STATE_FULLSCREEN) {
|
||||
window->flags |= SDL_WINDOW_FULLSCREEN;
|
||||
}
|
||||
else {
|
||||
window->flags &= ~SDL_WINDOW_FULLSCREEN;
|
||||
}
|
||||
|
||||
/* commit frame state */
|
||||
state = libdecor_state_new(width, height);
|
||||
libdecor_frame_commit(frame, state, configuration);
|
||||
libdecor_state_free(state);
|
||||
|
||||
/* Update the resize capability. Since this will change the capabilities and
|
||||
* commit a new frame state with the last known content dimension, this has
|
||||
* to be called after the new state has been commited and the new content
|
||||
* dimensions were updated. */
|
||||
Wayland_SetWindowResizable(SDL_GetVideoDevice(), window,
|
||||
window->flags & SDL_WINDOW_RESIZABLE);
|
||||
}
|
||||
|
||||
static void
|
||||
decoration_frame_close(struct libdecor_frame *frame, void *user_data)
|
||||
{
|
||||
SDL_SendWindowEvent(((SDL_WindowData *)user_data)->sdlwindow, SDL_WINDOWEVENT_CLOSE, 0, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
decoration_frame_commit(struct libdecor_frame *frame, void *user_data)
|
||||
{
|
||||
SDL_WindowData *wind = user_data;
|
||||
|
||||
SDL_SendWindowEvent(wind->sdlwindow, SDL_WINDOWEVENT_EXPOSED, 0, 0);
|
||||
}
|
||||
|
||||
static struct libdecor_frame_interface libdecor_frame_interface = {
|
||||
decoration_frame_configure,
|
||||
decoration_frame_close,
|
||||
decoration_frame_commit,
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
|
||||
static void
|
||||
@ -706,6 +834,20 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
|
||||
wl_surface_commit(data->surface);
|
||||
|
||||
/* Create the shell surface and map the toplevel */
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
if (c->shell.libdecor) {
|
||||
data->shell_surface.libdecor.frame = libdecor_decorate(c->shell.libdecor,
|
||||
data->surface,
|
||||
&libdecor_frame_interface,
|
||||
data);
|
||||
if (data->shell_surface.libdecor.frame == NULL) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Failed to create libdecor frame!");
|
||||
} else {
|
||||
libdecor_frame_set_app_id(data->shell_surface.libdecor.frame, c->classname);
|
||||
libdecor_frame_map(data->shell_surface.libdecor.frame);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
if (c->shell.xdg) {
|
||||
data->shell_surface.xdg.surface = xdg_wm_base_get_xdg_surface(c->shell.xdg, data->surface);
|
||||
xdg_surface_set_user_data(data->shell_surface.xdg.surface, data);
|
||||
@ -744,6 +886,16 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
|
||||
/* We have to wait until the surface gets a "configure" event, or use of
|
||||
* this surface will fail. This is a new rule for xdg_shell.
|
||||
*/
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
if (c->shell.libdecor) {
|
||||
if (data->shell_surface.libdecor.frame) {
|
||||
while (!data->shell_surface.libdecor.initial_configure_seen) {
|
||||
WAYLAND_wl_display_flush(c->display);
|
||||
WAYLAND_wl_display_dispatch(c->display);
|
||||
}
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
if (c->shell.xdg) {
|
||||
if (data->shell_surface.xdg.surface) {
|
||||
while (!data->shell_surface.xdg.initial_configure_seen) {
|
||||
@ -801,6 +953,14 @@ void Wayland_HideWindow(_THIS, SDL_Window *window)
|
||||
wind->server_decoration = NULL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
if (data->shell.libdecor) {
|
||||
if (wind->shell_surface.libdecor.frame) {
|
||||
libdecor_frame_unref(wind->shell_surface.libdecor.frame);
|
||||
wind->shell_surface.libdecor.frame = NULL;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
if (data->shell.xdg) {
|
||||
if (wind->shell_surface.xdg.roleobj.toplevel) {
|
||||
xdg_toplevel_destroy(wind->shell_surface.xdg.roleobj.toplevel);
|
||||
@ -1027,6 +1187,14 @@ Wayland_RestoreWindow(_THIS, SDL_Window * window)
|
||||
*/
|
||||
window->flags &= ~SDL_WINDOW_MAXIMIZED;
|
||||
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
if (viddata->shell.libdecor) {
|
||||
if (wind->shell_surface.libdecor.frame == NULL) {
|
||||
return; /* Can't do anything yet, wait for ShowWindow */
|
||||
}
|
||||
libdecor_frame_unset_maximized(wind->shell_surface.libdecor.frame);
|
||||
} else
|
||||
#endif
|
||||
/* Note that xdg-shell does NOT provide a way to unset minimize! */
|
||||
if (viddata->shell.xdg) {
|
||||
if (wind->shell_surface.xdg.roleobj.toplevel == NULL) {
|
||||
@ -1053,6 +1221,11 @@ Wayland_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
|
||||
{
|
||||
SDL_WindowData *wind = window->driverdata;
|
||||
const SDL_VideoData *viddata = (const SDL_VideoData *) _this->driverdata;
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
if (viddata->shell.libdecor) {
|
||||
SDL_SetError("FIXME libdecor: Implement toggling decorations");
|
||||
} else
|
||||
#endif
|
||||
if ((viddata->decoration_manager) && (wind->server_decoration)) {
|
||||
const enum zxdg_toplevel_decoration_v1_mode mode = bordered ? ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE : ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE;
|
||||
zxdg_toplevel_decoration_v1_set_mode(wind->server_decoration, mode);
|
||||
@ -1062,7 +1235,24 @@ Wayland_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
|
||||
void
|
||||
Wayland_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable)
|
||||
{
|
||||
CommitMinMaxDimensions(window);
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
SDL_VideoData *data = _this->driverdata;
|
||||
const SDL_WindowData *wind = window->driverdata;
|
||||
|
||||
if (data->shell.libdecor) {
|
||||
if (wind->shell_surface.libdecor.frame == NULL) {
|
||||
return; /* Can't do anything yet, wait for ShowWindow */
|
||||
}
|
||||
if (resizable) {
|
||||
libdecor_frame_set_capabilities(wind->shell_surface.libdecor.frame, LIBDECOR_ACTION_RESIZE);
|
||||
} else {
|
||||
libdecor_frame_unset_capabilities(wind->shell_surface.libdecor.frame, LIBDECOR_ACTION_RESIZE);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
CommitMinMaxDimensions(window);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -1080,6 +1270,14 @@ Wayland_MaximizeWindow(_THIS, SDL_Window * window)
|
||||
*/
|
||||
window->flags |= SDL_WINDOW_MAXIMIZED;
|
||||
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
if (viddata->shell.libdecor) {
|
||||
if (wind->shell_surface.libdecor.frame == NULL) {
|
||||
return; /* Can't do anything yet, wait for ShowWindow */
|
||||
}
|
||||
libdecor_frame_set_maximized(wind->shell_surface.libdecor.frame);
|
||||
} else
|
||||
#endif
|
||||
if (viddata->shell.xdg) {
|
||||
if (wind->shell_surface.xdg.roleobj.toplevel == NULL) {
|
||||
return; /* Can't do anything yet, wait for ShowWindow */
|
||||
@ -1106,6 +1304,14 @@ Wayland_MinimizeWindow(_THIS, SDL_Window * window)
|
||||
SDL_WindowData *wind = window->driverdata;
|
||||
SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata;
|
||||
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
if (viddata->shell.libdecor) {
|
||||
if (wind->shell_surface.libdecor.frame == NULL) {
|
||||
return; /* Can't do anything yet, wait for ShowWindow */
|
||||
}
|
||||
libdecor_frame_set_minimized(wind->shell_surface.libdecor.frame);
|
||||
} else
|
||||
#endif
|
||||
if (viddata->shell.xdg) {
|
||||
if (wind->shell_surface.xdg.roleobj.toplevel == NULL) {
|
||||
return; /* Can't do anything yet, wait for ShowWindow */
|
||||
@ -1199,6 +1405,10 @@ int Wayland_CreateWindow(_THIS, SDL_Window *window)
|
||||
wl_compositor_create_surface(c->compositor);
|
||||
wl_surface_add_listener(data->surface, &surface_listener, data);
|
||||
|
||||
if (SDL_WAYLAND_HAVE_WAYLAND_CLIENT_1_18) {
|
||||
wl_proxy_set_tag((struct wl_proxy *)data->surface, &SDL_WAYLAND_surface_tag);
|
||||
}
|
||||
|
||||
/* Fire a callback when the compositor wants a new frame rendered.
|
||||
* Right now this only matters for OpenGL; we use this callback to add a
|
||||
* wait timeout that avoids getting deadlocked by the compositor when the
|
||||
@ -1278,6 +1488,11 @@ Wayland_HandlePendingResize(SDL_Window *window)
|
||||
}
|
||||
|
||||
if (data->resize.configure) {
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
if (data->waylandData->shell.libdecor) {
|
||||
/* this has already been acknowledged in the the frames's 'configure' callback */
|
||||
} else
|
||||
#endif
|
||||
if (data->waylandData->shell.xdg) {
|
||||
xdg_surface_ack_configure(data->shell_surface.xdg.surface, data->resize.serial);
|
||||
} else if (data->waylandData->shell.zxdg) {
|
||||
@ -1312,6 +1527,9 @@ void Wayland_SetWindowSize(_THIS, SDL_Window * window)
|
||||
SDL_VideoData *data = _this->driverdata;
|
||||
SDL_WindowData *wind = window->driverdata;
|
||||
struct wl_region *region;
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
struct libdecor_state *state;
|
||||
#endif
|
||||
|
||||
wl_surface_set_buffer_scale(wind->surface, get_window_scale_factor(window));
|
||||
|
||||
@ -1319,6 +1537,14 @@ void Wayland_SetWindowSize(_THIS, SDL_Window * 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);
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
if (data->shell.libdecor && wind->shell_surface.libdecor.frame) {
|
||||
state = libdecor_state_new(window->w, window->h);
|
||||
libdecor_frame_commit(wind->shell_surface.libdecor.frame, state, NULL);
|
||||
libdecor_state_free(state);
|
||||
}
|
||||
#endif
|
||||
|
||||
region = wl_compositor_create_region(data->compositor);
|
||||
wl_region_add(region, 0, 0, window->w, window->h);
|
||||
wl_surface_set_opaque_region(wind->surface, region);
|
||||
@ -1331,6 +1557,14 @@ void Wayland_SetWindowTitle(_THIS, SDL_Window * window)
|
||||
SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata;
|
||||
|
||||
if (window->title != NULL) {
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
if (viddata->shell.libdecor) {
|
||||
if (wind->shell_surface.libdecor.frame == NULL) {
|
||||
return; /* Can't do anything yet, wait for ShowWindow */
|
||||
}
|
||||
libdecor_frame_set_title(wind->shell_surface.libdecor.frame, window->title);
|
||||
} else
|
||||
#endif
|
||||
if (viddata->shell.xdg) {
|
||||
if (wind->shell_surface.xdg.roleobj.toplevel == NULL) {
|
||||
return; /* Can't do anything yet, wait for ShowWindow */
|
||||
|
@ -50,6 +50,13 @@ typedef struct {
|
||||
SDL_bool initial_configure_seen;
|
||||
} SDL_xdg_shell_surface;
|
||||
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
typedef struct {
|
||||
struct libdecor_frame *frame;
|
||||
SDL_bool initial_configure_seen;
|
||||
} SDL_libdecor_surface;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
SDL_Window *sdlwindow;
|
||||
SDL_VideoData *waylandData;
|
||||
@ -58,6 +65,9 @@ typedef struct {
|
||||
union {
|
||||
SDL_xdg_shell_surface xdg;
|
||||
SDL_zxdg_shell_surface zxdg;
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
SDL_libdecor_surface libdecor;
|
||||
#endif
|
||||
struct wl_shell_surface *wl;
|
||||
} shell_surface;
|
||||
struct wl_egl_window *egl_window;
|
||||
@ -117,6 +127,8 @@ extern int Wayland_FlashWindow(_THIS, SDL_Window * window, SDL_FlashOperation op
|
||||
|
||||
extern void Wayland_HandlePendingResize(SDL_Window *window);
|
||||
|
||||
extern SDL_bool SDL_WAYLAND_own_surface(struct wl_surface *surface);
|
||||
|
||||
#endif /* SDL_waylandwindow_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
Loading…
Reference in New Issue
Block a user