From f5b2e4e674d38247d78f95531beaa15510131b5f Mon Sep 17 00:00:00 2001 From: speckitor Date: Thu, 23 Apr 2026 10:47:42 +0700 Subject: [PATCH] resizing serial --- include/types.h | 6 ++---- src/absinthe-toplevel.c | 7 +++++-- src/cursor.c | 9 +++++---- src/layout.c | 6 +++--- src/output.c | 7 +++++++ src/xdg-toplevel.c | 5 +++-- 6 files changed, 25 insertions(+), 15 deletions(-) diff --git a/include/types.h b/include/types.h index 9a5a51d..4c56999 100644 --- a/include/types.h +++ b/include/types.h @@ -139,10 +139,8 @@ struct absinthe_toplevel { struct wlr_scene_rect *border[4]; struct wlr_xdg_toplevel_decoration_v1 *decoration; - bool floating; - bool tiled; - bool fullscreen; - bool performing_resize; + bool tiled, floating, fullscreen, maximized; + uint32_t resizing; struct wlr_box geometry; struct wlr_box prev_geometry; diff --git a/src/absinthe-toplevel.c b/src/absinthe-toplevel.c index 66be46e..93c90b7 100644 --- a/src/absinthe-toplevel.c +++ b/src/absinthe-toplevel.c @@ -57,6 +57,8 @@ void absinthe_toplevel_map(struct wl_listener *listener, void *data) toplevel->scene_tree->node.data = toplevel; wlr_scene_node_set_enabled(&toplevel->scene_tree->node, false); + toplevel->tiled = true; + toplevel->border_width = absinthe_toplevel_is_unmanaged(toplevel) ? 0 : ABSINTHE_TOPLEVEL_BORDER_WIDTH; @@ -201,8 +203,9 @@ void absinthe_toplevel_set_size(struct absinthe_toplevel *toplevel, int32_t widt { if (width < 0 || height < 0) return; - if (toplevel->type == ABSINTHE_TOPLEVEL_XDG) - wlr_xdg_toplevel_set_size(toplevel->toplevel.xdg, width, height); + if (toplevel->type == ABSINTHE_TOPLEVEL_XDG) { + toplevel->resizing = wlr_xdg_toplevel_set_size(toplevel->toplevel.xdg, width, height); + } #ifdef XWAYLAND else if (toplevel->type == ABSINTHE_TOPLEVEL_X11) { wlr_xwayland_surface_configure(toplevel->toplevel.x11, diff --git a/src/cursor.c b/src/cursor.c index 6b656f3..7581776 100644 --- a/src/cursor.c +++ b/src/cursor.c @@ -41,6 +41,7 @@ static void apply_resize(struct absinthe_toplevel *toplevel, struct wlr_box *new int32_t max_width = toplevel->toplevel.xdg->current.max_width; int32_t max_height = toplevel->toplevel.xdg->current.max_height; + bool resize = false; if (max_width == 0) max_width = 10000; @@ -51,16 +52,16 @@ static void apply_resize(struct absinthe_toplevel *toplevel, struct wlr_box *new if (new_geometry->width - borders_width >= min_width && new_geometry->width - borders_width <= max_width) { toplevel->geometry.x = new_geometry->x; toplevel->geometry.width = new_geometry->width; - toplevel->performing_resize = true; + resize = true; } if (new_geometry->height - borders_width >= min_height && new_geometry->height - borders_width <= max_height) { toplevel->geometry.y = new_geometry->y; toplevel->geometry.height = new_geometry->height; - toplevel->performing_resize = true; + resize = true; } - if (toplevel->performing_resize) + if (resize) absinthe_toplevel_set_size(toplevel, toplevel->geometry.width - borders_width, toplevel->geometry.height - borders_width); } @@ -70,7 +71,7 @@ static void process_cursor_resize(struct absinthe_server *server) { if (!toplevel) return; - if (toplevel->performing_resize == true) + if (toplevel->resizing) return; if (toplevel->fullscreen) diff --git a/src/layout.c b/src/layout.c index 6c8c2a9..f9fc193 100644 --- a/src/layout.c +++ b/src/layout.c @@ -9,7 +9,7 @@ void layout_arrange(struct absinthe_output *output) struct absinthe_toplevel *toplevel; size_t toplevels_count = 0; wl_list_for_each(toplevel, &output->server->toplevels, link) { - if (toplevel->output == output) { + if (toplevel->tiled && toplevel->output == output) { toplevels_count++; wlr_scene_node_set_enabled(&toplevel->scene_tree->node, true); } @@ -46,7 +46,7 @@ void layout_arrange(struct absinthe_output *output) if (toplevels_count <= output->main_stack_size) { wl_list_for_each(toplevel, &output->server->toplevels, link) { - if (toplevel->output != output) + if (toplevel->output != output || !toplevel->tiled) continue; height = (output->geometry.height - dy - output_gap) / (output->main_stack_size - i) - borders_width; @@ -61,7 +61,7 @@ void layout_arrange(struct absinthe_output *output) } wl_list_for_each(toplevel, &output->server->toplevels, link) { - if (toplevel->output != output) + if (toplevel->output != output || !toplevel->tiled) continue; diff --git a/src/output.c b/src/output.c index 9f436fe..42ec002 100644 --- a/src/output.c +++ b/src/output.c @@ -11,8 +11,15 @@ void output_frame(struct wl_listener *listener, void *data) struct wlr_scene_output *scene_output = wlr_scene_get_scene_output(scene, output->wlr_output); + struct absinthe_toplevel *toplevel; + wl_list_for_each(toplevel, &output->server->toplevels, link) { + if (toplevel->resizing && toplevel->output == output) + goto skip; + } + wlr_scene_output_commit(scene_output, NULL); +skip: struct timespec now; clock_gettime(CLOCK_MONOTONIC, &now); wlr_scene_output_send_frame_done(scene_output, &now); diff --git a/src/xdg-toplevel.c b/src/xdg-toplevel.c index f8d134a..8b67419 100644 --- a/src/xdg-toplevel.c +++ b/src/xdg-toplevel.c @@ -18,13 +18,13 @@ void xdg_toplevel_commit(struct wl_listener *listener, void *data) if (toplevel->toplevel.xdg->base->initial_commit) { /* Let toplevel set preferred size */ - wlr_xdg_toplevel_set_size(toplevel->toplevel.xdg, 0, 0); toplevel->geometry.width = toplevel->toplevel.xdg->base->geometry.width + borders_width; toplevel->geometry.height = toplevel->toplevel.xdg->base->geometry.height + borders_width; /* Forse server side decoration mode */ if (toplevel->decoration) xdg_decoration_request_mode(&toplevel->decoration_request_mode, toplevel->decoration); + toplevel->resizing = wlr_xdg_toplevel_set_size(toplevel->toplevel.xdg, 0, 0); return; } /* Check for size because we did't set it on initial commit */ @@ -34,5 +34,6 @@ void xdg_toplevel_commit(struct wl_listener *listener, void *data) /* Update borders and position only after client prepared new buffer */ absinthe_toplevel_set_position(toplevel, toplevel->geometry.x, toplevel->geometry.y); absinthe_toplevel_update_borders_geometry(toplevel); - toplevel->performing_resize = false; + if (toplevel->resizing && toplevel->resizing <= toplevel->toplevel.xdg->base->current.configure_serial) + toplevel->resizing = 0; }