diff --git a/client.h b/client.h index a915f98..5d76b13 100644 --- a/client.h +++ b/client.h @@ -15,6 +15,32 @@ client_is_x11(Client *c) return 0; } +static inline void +client_get_size_hints(Client *c, struct wlr_box *max, struct wlr_box *min) +{ + struct wlr_xdg_toplevel_state *state; + +#ifdef XWAYLAND + if (client_is_x11(c)) { + xcb_size_hints_t *size_hints = c->surface.xwayland->size_hints; + if (size_hints) { + max->width = size_hints->max_width; + max->height = size_hints->max_height; + min->width = size_hints->min_width; + min->height = size_hints->min_height; + } + return; + } +#endif + + state = &c->surface.xdg->toplevel->current; + max->width = state->max_width; + max->height = state->max_height; + min->width = state->min_width; + min->height = state->min_height; +} + + static inline struct wlr_surface * client_surface(Client *c) { @@ -206,13 +232,12 @@ client_get_title(Client *c) static inline int client_is_float_type(Client *c) { - struct wlr_xdg_toplevel *toplevel; - struct wlr_xdg_toplevel_state state; + struct wlr_box min = {0}, max = {0}; + client_get_size_hints(c, &max, &min); #ifdef XWAYLAND if (client_is_x11(c)) { struct wlr_xwayland_surface *surface = c->surface.xwayland; - xcb_size_hints_t *size_hints = surface->size_hints; if (surface->modal) return 1; @@ -223,17 +248,13 @@ client_is_float_type(Client *c) return 1; } - return size_hints && size_hints->min_width > 0 && size_hints->min_height > 0 - && (size_hints->max_width == size_hints->min_width - || size_hints->max_height == size_hints->min_height); + return min.width && min.height && + (min.width == max.width || min.height == max.height); } #endif - toplevel = c->surface.xdg->toplevel; - state = toplevel->current; - return toplevel->parent || (state.min_width != 0 && state.min_height != 0 - && (state.min_width == state.max_width - || state.min_height == state.max_height)); + return c->surface.xdg->toplevel->parent || (min.width && min.height && + (min.width == max.width || min.height == max.height)); } static inline int diff --git a/dwl.c b/dwl.c index 6636a4d..f9ea272 100644 --- a/dwl.c +++ b/dwl.c @@ -3,6 +3,7 @@ */ #include #include +#include #include #include #include @@ -483,9 +484,18 @@ static struct wlr_xwayland *xwayland; void applybounds(Client *c, struct wlr_box *bbox) { - /* set minimum possible */ - c->geom.width = MAX(1 + 2 * (int)c->bw, c->geom.width); - c->geom.height = MAX(1 + 2 * (int)c->bw, c->geom.height); + if (!c->isfullscreen) { + struct wlr_box min = {0}, max = {0}; + client_get_size_hints(c, &max, &min); + c->geom.width = MAX(min.width + 2 * (int)c->bw, c->geom.width); + c->geom.height = MAX(min.height + 2 * (int)c->bw, c->geom.height); + /* Some clients set their max size to INT_MAX, which does not violate the + * protocol but it's unnecesary, as they can set their max size to zero. */ + if (max.width && 2 * (int)c->bw <= INT_MAX - max.width) /* Checks for overflow */ + c->geom.width = MIN(max.width + 2 * (int)c->bw, c->geom.width); + if (max.height && 2 * (int)c->bw <= INT_MAX - max.height) /* Checks for overflow */ + c->geom.height = MIN(max.height + 2 * (int)c->bw, c->geom.height); + } if (c->geom.x >= bbox->x + bbox->width) c->geom.x = bbox->x + bbox->width - c->geom.width;