diff --git a/include/SDL_hints.h b/include/SDL_hints.h index 12466e990..c5371324a 100644 --- a/include/SDL_hints.h +++ b/include/SDL_hints.h @@ -1475,6 +1475,20 @@ extern "C" { */ #define SDL_HINT_VIDEO_WAYLAND_ALLOW_LIBDECOR "SDL_VIDEO_WAYLAND_ALLOW_LIBDECOR" +/** + * \brief A variable controlling whether the libdecor Wayland backend is preferred over native decrations. + * + * When this hint is set, libdecor will be used to provide window decorations, even if xdg-decoration is + * available. (Note that, by default, libdecor will use xdg-decoration itself if available). + * + * This variable can be set to the following values: + * "0" - libdecor is enabled only if server-side decorations are unavailable. + * "1" - libdecor is always enabled if available. + * + * libdecor is used over xdg-shell when xdg-decoration protocol is unavailable. + */ +#define SDL_HINT_VIDEO_WAYLAND_PREFER_LIBDECOR "SDL_VIDEO_WAYLAND_PREFER_LIBDECOR" + /** * \brief A variable that is the address of another SDL_Window* (as a hex string formatted with "%p"). * diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c index 9c325d78a..bce982fc6 100644 --- a/src/video/wayland/SDL_waylandvideo.c +++ b/src/video/wayland/SDL_waylandvideo.c @@ -876,6 +876,29 @@ static const struct wl_registry_listener registry_listener = { display_handle_global, display_remove_global }; + +#ifdef HAVE_LIBDECOR_H +static SDL_bool should_use_libdecor(SDL_VideoData *data) +{ + if (!SDL_WAYLAND_HAVE_WAYLAND_LIBDECOR) { + return SDL_FALSE; + } + + if (!SDL_GetHintBoolean(SDL_HINT_VIDEO_WAYLAND_ALLOW_LIBDECOR, SDL_TRUE)) { + return SDL_FALSE; + } + + if (SDL_GetHintBoolean(SDL_HINT_VIDEO_WAYLAND_PREFER_LIBDECOR, SDL_FALSE)) { + return SDL_TRUE; + } + + if (data->decoration_manager) { + return SDL_FALSE; + } + + return SDL_TRUE; +} +#endif int Wayland_VideoInit(_THIS) @@ -899,7 +922,7 @@ Wayland_VideoInit(_THIS) #ifdef HAVE_LIBDECOR_H /* Don't have server-side decorations? Try client-side instead. */ - if (!data->decoration_manager && SDL_WAYLAND_HAVE_WAYLAND_LIBDECOR && SDL_GetHintBoolean(SDL_HINT_VIDEO_WAYLAND_ALLOW_LIBDECOR, SDL_TRUE)) { + if (should_use_libdecor(data)) { data->shell.libdecor = libdecor_new(data->display, &libdecor_interface); /* If libdecor works, we don't need xdg-shell anymore. */