From c6102ddca1eda5e3bf374bd3dbef764a9611bd40 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Tue, 5 Aug 2025 12:30:06 +0800 Subject: [PATCH] feat: respect the min and max size hint for the floating window --- src/animation/client.h | 5 ++++ src/client/client.h | 52 ++++++++++++++++++++++++++++++++++++++++++ src/mango.c | 3 +++ 3 files changed, 60 insertions(+) diff --git a/src/animation/client.h b/src/animation/client.h index 98b9a99..c5105f4 100644 --- a/src/animation/client.h +++ b/src/animation/client.h @@ -921,6 +921,10 @@ void resize(Client *c, struct wlr_box geo, int interact) { bbox); // 去掉这个推荐的窗口大小,因为有时推荐的窗口特别大导致平铺异常 } + if (!c->ismaxmizescreen && !c->isfullscreen && c->isfloating) { + client_set_size_bound(c); + } + if (!c->is_pending_open_animation) { c->animation.begin_fade_in = false; } @@ -965,6 +969,7 @@ void resize(Client *c, struct wlr_box geo, int interact) { if (c == grabc) { c->animation.running = false; c->need_output_flush = false; + c->animainit_geom = c->current = c->pending = c->animation.current = c->geom; wlr_scene_node_set_position(&c->scene->node, c->geom.x, c->geom.y); diff --git a/src/client/client.h b/src/client/client.h index 215d56e..2bf8203 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -213,6 +213,10 @@ static inline int client_is_float_type(Client *c) { if (client_is_x11(c)) { struct wlr_xwayland_surface *surface = c->surface.xwayland; xcb_size_hints_t *size_hints = surface->size_hints; + + if (!size_hints) + return 0; + if (surface->modal) return 1; @@ -467,4 +471,52 @@ static inline bool client_request_minimize(Client *c, void *data) { #endif return c->surface.xdg->toplevel->requested.minimized; +} + +static inline void client_set_size_bound(Client *c) { + struct wlr_xdg_toplevel *toplevel; + struct wlr_xdg_toplevel_state state; + +#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 (!size_hints) + return; + + if ((unsigned int)c->geom.width - 2 * c->bw < size_hints->min_width && + size_hints->min_width > 0) + c->geom.width = size_hints->min_width + 2 * c->bw; + if ((unsigned int)c->geom.height - 2 * c->bw < size_hints->min_height && + size_hints->min_height > 0) + c->geom.height = size_hints->min_height + 2 * c->bw; + if ((unsigned int)c->geom.width - 2 * c->bw > size_hints->max_width && + size_hints->max_width > 0) + c->geom.width = size_hints->max_width + 2 * c->bw; + if ((unsigned int)c->geom.height - 2 * c->bw > size_hints->max_height && + size_hints->max_height > 0) + c->geom.height = size_hints->max_height + 2 * c->bw; + return; + } +#endif + + toplevel = c->surface.xdg->toplevel; + state = toplevel->current; + if ((unsigned int)c->geom.width - 2 * c->bw < state.min_width && + state.min_width > 0) { + c->geom.width = state.min_width + 2 * c->bw; + } + if ((unsigned int)c->geom.height - 2 * c->bw < state.min_height && + state.min_height > 0) { + c->geom.height = state.min_height + 2 * c->bw; + } + if ((unsigned int)c->geom.width - 2 * c->bw > state.max_width && + state.max_width > 0) { + c->geom.width = state.max_width + 2 * c->bw; + } + if ((unsigned int)c->geom.height - 2 * c->bw > state.max_height && + state.max_height > 0) { + c->geom.height = state.max_height + 2 * c->bw; + } } \ No newline at end of file diff --git a/src/mango.c b/src/mango.c index 313e766..5f11604 100644 --- a/src/mango.c +++ b/src/mango.c @@ -1077,6 +1077,7 @@ int applyrulesgeom(Client *c) { c->geom.width = r->width > 0 ? r->width : c->geom.width; c->geom.height = r->height > 0 ? r->height : c->geom.height; + client_set_size_bound(c); // 重新计算居中的坐标 if (r->offsetx != 0 || r->offsety != 0 || r->width > 0 || r->height > 0) @@ -1135,6 +1136,8 @@ void applyrules(Client *c) { if (r->height > 0) c->geom.height = r->height; + client_set_size_bound(c); + if (r->offsetx || r->offsety || r->width > 0 || r->height > 0) { hit_rule_pos = true; c->oldgeom = c->geom = setclient_coordinate_center(