diff --git a/include/wlr/types/wlr_xdg_shell.h b/include/wlr/types/wlr_xdg_shell.h index 04463d2c..f6b3b362 100644 --- a/include/wlr/types/wlr_xdg_shell.h +++ b/include/wlr/types/wlr_xdg_shell.h @@ -137,10 +137,18 @@ struct wlr_xdg_toplevel_state { uint32_t min_width, min_height; }; +enum wlr_xdg_toplevel_configure_field { + WLR_XDG_TOPLEVEL_CONFIGURE_BOUNDS = 1 << 0, +}; + struct wlr_xdg_toplevel_configure { + uint32_t fields; // enum wlr_xdg_toplevel_configure_field bool maximized, fullscreen, resizing, activated; uint32_t tiled; // enum wlr_edges uint32_t width, height; + struct { + uint32_t width, height; + } bounds; }; struct wlr_xdg_toplevel_requested { @@ -376,6 +384,13 @@ uint32_t wlr_xdg_toplevel_set_resizing(struct wlr_xdg_toplevel *toplevel, uint32_t wlr_xdg_toplevel_set_tiled(struct wlr_xdg_toplevel *toplevel, uint32_t tiled_edges); +/** + * Configure the recommended bounds for the client's window geometry size. + * Returns the associated configure serial. + */ +uint32_t wlr_xdg_toplevel_set_bounds(struct wlr_xdg_toplevel *toplevel, + int32_t width, int32_t height); + /** * Request that this toplevel closes. */ diff --git a/types/xdg_shell/wlr_xdg_shell.c b/types/xdg_shell/wlr_xdg_shell.c index 7e6bf5f8..9008de4e 100644 --- a/types/xdg_shell/wlr_xdg_shell.c +++ b/types/xdg_shell/wlr_xdg_shell.c @@ -3,7 +3,7 @@ #include "types/wlr_xdg_shell.h" #include "util/signal.h" -#define WM_BASE_VERSION 3 +#define WM_BASE_VERSION 4 static const struct xdg_wm_base_interface xdg_shell_impl; diff --git a/types/xdg_shell/wlr_xdg_toplevel.c b/types/xdg_shell/wlr_xdg_toplevel.c index 750efeda..a7ca8257 100644 --- a/types/xdg_shell/wlr_xdg_toplevel.c +++ b/types/xdg_shell/wlr_xdg_toplevel.c @@ -31,6 +31,14 @@ struct wlr_xdg_toplevel_configure *send_xdg_toplevel_configure( } *configure = toplevel->scheduled; + uint32_t version = wl_resource_get_version(toplevel->resource); + + if ((configure->fields & WLR_XDG_TOPLEVEL_CONFIGURE_BOUNDS) && + version >= XDG_TOPLEVEL_CONFIGURE_BOUNDS_SINCE_VERSION) { + xdg_toplevel_send_configure_bounds(toplevel->resource, + configure->bounds.width, configure->bounds.height); + } + size_t nstates = 0; uint32_t states[32]; if (configure->maximized) { @@ -46,8 +54,7 @@ struct wlr_xdg_toplevel_configure *send_xdg_toplevel_configure( states[nstates++] = XDG_TOPLEVEL_STATE_ACTIVATED; } if (configure->tiled) { - if (wl_resource_get_version(toplevel->resource) >= - XDG_TOPLEVEL_STATE_TILED_LEFT_SINCE_VERSION) { + if (version >= XDG_TOPLEVEL_STATE_TILED_LEFT_SINCE_VERSION) { const struct { enum wlr_edges edge; enum xdg_toplevel_state state; @@ -79,6 +86,8 @@ struct wlr_xdg_toplevel_configure *send_xdg_toplevel_configure( xdg_toplevel_send_configure(toplevel->resource, width, height, &wl_states); + toplevel->scheduled.fields = 0; + return configure; } @@ -501,3 +510,14 @@ uint32_t wlr_xdg_toplevel_set_tiled(struct wlr_xdg_toplevel *toplevel, toplevel->scheduled.tiled = tiled; return wlr_xdg_surface_schedule_configure(toplevel->base); } + +uint32_t wlr_xdg_toplevel_set_bounds(struct wlr_xdg_toplevel *toplevel, + int32_t width, int32_t height) { + assert(toplevel->base->client->shell->version >= + XDG_TOPLEVEL_CONFIGURE_BOUNDS_SINCE_VERSION); + assert(width >= 0 && height >= 0); + toplevel->scheduled.fields |= WLR_XDG_TOPLEVEL_CONFIGURE_BOUNDS; + toplevel->scheduled.bounds.width = width; + toplevel->scheduled.bounds.height = height; + return wlr_xdg_surface_schedule_configure(toplevel->base); +}