From 28389f1c38f4798ddbdb1c83fa288424346321f0 Mon Sep 17 00:00:00 2001
From: Frank Praznik <[EMAIL REDACTED]>
Date: Fri, 3 Jan 2025 16:16:28 -0500
Subject: [PATCH] wayland: Apply toplevel bounds to windows
Apply the supplied xdg-toplevel bounds to resizable windows during initial mapping. Libdecor functionality will have to be added separately, as the functionality needs to be added to the library first.
---
src/video/wayland/SDL_waylandwindow.c | 25 ++++++++++++++++---------
src/video/wayland/SDL_waylandwindow.h | 6 ++++++
2 files changed, 22 insertions(+), 9 deletions(-)
diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c
index 2755a43db8038..33e15724a54ce 100644
--- a/src/video/wayland/SDL_waylandwindow.c
+++ b/src/video/wayland/SDL_waylandwindow.c
@@ -833,6 +833,12 @@ static void handle_configure_xdg_toplevel(void *data,
if (floating) {
width = window->floating.w;
height = window->floating.h;
+
+ // Clamp the window to the toplevel bounds, if any are set.
+ if (wind->toplevel_bounds.width && wind->toplevel_bounds.height) {
+ width = SDL_min(wind->toplevel_bounds.width, width);
+ height = SDL_min(wind->toplevel_bounds.height, height);
+ }
} else {
width = window->windowed.w;
height = window->windowed.h;
@@ -972,7 +978,9 @@ static void handle_xdg_configure_toplevel_bounds(void *data,
struct xdg_toplevel *xdg_toplevel,
int32_t width, int32_t height)
{
- // NOP
+ SDL_WindowData *window = (SDL_WindowData *)data;
+ window->toplevel_bounds.width = width;
+ window->toplevel_bounds.height = height;
}
static void handle_xdg_toplevel_wm_capabilities(void *data,
@@ -1946,6 +1954,13 @@ void Wayland_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window)
} else
#endif
if (data->shell_surface_type == WAYLAND_SHELL_SURFACE_TYPE_XDG_POPUP || data->shell_surface_type == WAYLAND_SHELL_SURFACE_TYPE_XDG_TOPLEVEL) {
+
+ // Create the window decorations
+ if (data->shell_surface_type != WAYLAND_SHELL_SURFACE_TYPE_XDG_POPUP && data->shell_surface.xdg.toplevel.xdg_toplevel && c->decoration_manager) {
+ data->server_decoration = zxdg_decoration_manager_v1_get_toplevel_decoration(c->decoration_manager, data->shell_surface.xdg.toplevel.xdg_toplevel);
+ zxdg_toplevel_decoration_v1_add_listener(data->server_decoration, &decoration_listener, window);
+ }
+
/* Unlike libdecor we need to call this explicitly to prevent a deadlock.
* libdecor will call this as part of their configure event!
* -flibit
@@ -1957,14 +1972,6 @@ void Wayland_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window)
WAYLAND_wl_display_dispatch(c->display);
}
}
-
- // Create the window decorations
- if (data->shell_surface_type != WAYLAND_SHELL_SURFACE_TYPE_XDG_POPUP && data->shell_surface.xdg.toplevel.xdg_toplevel && c->decoration_manager) {
- data->server_decoration = zxdg_decoration_manager_v1_get_toplevel_decoration(c->decoration_manager, data->shell_surface.xdg.toplevel.xdg_toplevel);
- zxdg_toplevel_decoration_v1_add_listener(data->server_decoration,
- &decoration_listener,
- window);
- }
} else {
// Nothing to see here, just commit.
wl_surface_commit(data->surface);
diff --git a/src/video/wayland/SDL_waylandwindow.h b/src/video/wayland/SDL_waylandwindow.h
index d181b21dc6eb9..906c5e448dbe5 100644
--- a/src/video/wayland/SDL_waylandwindow.h
+++ b/src/video/wayland/SDL_waylandwindow.h
@@ -174,6 +174,12 @@ struct SDL_WindowData
int min_height;
} system_limits;
+ struct
+ {
+ int width;
+ int height;
+ } toplevel_bounds;
+
SDL_DisplayID last_displayID;
int fullscreen_deadline_count;
int maximized_restored_deadline_count;