Skip to content

Commit 03e1523

Browse files
committed
wayland: Add the libdecor toplevel bounds and constraints properties
1 parent 08d84ea commit 03e1523

File tree

1 file changed

+36
-2
lines changed

1 file changed

+36
-2
lines changed

src/video/wayland/SDL_waylandwindow.c

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1198,6 +1198,7 @@ static void decoration_frame_configure(struct libdecor_frame *frame,
11981198
bool tiled = false;
11991199
bool suspended = false;
12001200
bool resizing = false;
1201+
wind->toplevel_constraints = 0;
12011202

12021203
static const enum libdecor_window_state tiled_states = (LIBDECOR_WINDOW_STATE_TILED_LEFT | LIBDECOR_WINDOW_STATE_TILED_RIGHT |
12031204
LIBDECOR_WINDOW_STATE_TILED_TOP | LIBDECOR_WINDOW_STATE_TILED_BOTTOM);
@@ -1213,8 +1214,20 @@ static void decoration_frame_configure(struct libdecor_frame *frame,
12131214
#endif
12141215
#if SDL_LIBDECOR_CHECK_VERSION(0, 3, 0)
12151216
resizing = (window_state & LIBDECOR_WINDOW_STATE_RESIZING) != 0;
1217+
1218+
if (window_state & LIBDECOR_WINDOW_STATE_CONSTRAINED_LEFT) {
1219+
wind->toplevel_constraints |= WAYLAND_TOPLEVEL_CONSTRAINED_LEFT;
1220+
}
1221+
if (window_state & LIBDECOR_WINDOW_STATE_CONSTRAINED_RIGHT) {
1222+
wind->toplevel_constraints |= WAYLAND_TOPLEVEL_CONSTRAINED_RIGHT;
1223+
}
1224+
if (window_state & LIBDECOR_WINDOW_STATE_CONSTRAINED_TOP) {
1225+
wind->toplevel_constraints |= WAYLAND_TOPLEVEL_CONSTRAINED_TOP;
1226+
}
1227+
if (window_state & LIBDECOR_WINDOW_STATE_CONSTRAINED_BOTTOM) {
1228+
wind->toplevel_constraints |= WAYLAND_TOPLEVEL_CONSTRAINED_BOTTOM;
1229+
}
12161230
#endif
1217-
// TODO: Toplevel constraint passthrough is waiting on upstream libdecor changes.
12181231
}
12191232
const bool floating = !(fullscreen || maximized || tiled);
12201233

@@ -1289,6 +1302,13 @@ static void decoration_frame_configure(struct libdecor_frame *frame,
12891302
if (floating) {
12901303
width = window->floating.w;
12911304
height = window->floating.h;
1305+
1306+
// Clamp the window to the toplevel bounds, if any are set.
1307+
if (wind->shell_surface_status == WAYLAND_SHELL_SURFACE_STATUS_WAITING_FOR_CONFIGURE &&
1308+
wind->toplevel_bounds.width && wind->toplevel_bounds.height) {
1309+
width = SDL_min(wind->toplevel_bounds.width, width);
1310+
height = SDL_min(wind->toplevel_bounds.height, height);
1311+
}
12921312
} else {
12931313
width = window->windowed.w;
12941314
height = window->windowed.h;
@@ -1451,11 +1471,25 @@ static void decoration_dismiss_popup(struct libdecor_frame *frame, const char *s
14511471
// NOP
14521472
}
14531473

1474+
static void decoration_frame_bounds(struct libdecor_frame *frame, int width, int height, void *user_data)
1475+
{
1476+
SDL_WindowData *window = (SDL_WindowData *)user_data;
1477+
window->toplevel_bounds.width = width;
1478+
window->toplevel_bounds.height = height;
1479+
}
1480+
1481+
#if SDL_LIBDECOR_CHECK_VERSION(0, 3, 0)
1482+
#define FRAME_BOUNDS_FUNC_CAST(func) func
1483+
#else
1484+
#define FRAME_BOUNDS_FUNC_CAST(func) (void(*)(void))func
1485+
#endif
1486+
14541487
static struct libdecor_frame_interface libdecor_frame_interface = {
14551488
decoration_frame_configure,
14561489
decoration_frame_close,
14571490
decoration_frame_commit,
1458-
decoration_dismiss_popup
1491+
decoration_dismiss_popup,
1492+
FRAME_BOUNDS_FUNC_CAST(decoration_frame_bounds)
14591493
};
14601494
#endif
14611495

0 commit comments

Comments
 (0)