feat: respect the min and max size hint for the floating window

This commit is contained in:
DreamMaoMao 2025-08-05 12:30:06 +08:00
parent 47809c5783
commit c6102ddca1
3 changed files with 60 additions and 0 deletions

View file

@ -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);

View file

@ -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;
}
}

View file

@ -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(