From 5d7e04812433df8e96286991a6964c06f9be2fe5 Mon Sep 17 00:00:00 2001 From: speckitor Date: Fri, 22 May 2026 21:28:11 +0700 Subject: [PATCH] smooth resize --- include/toplevel.h | 1 + include/types.h | 3 --- src/cursor.c | 4 --- src/layout.c | 1 + src/output.c | 10 -------- src/toplevel-handlers.c | 3 +-- src/toplevel.c | 56 ++++++++++++++++++++++++++++------------- src/xdg-toplevel.c | 10 +++----- 8 files changed, 45 insertions(+), 43 deletions(-) diff --git a/include/toplevel.h b/include/toplevel.h index bd3f01d..db026c9 100644 --- a/include/toplevel.h +++ b/include/toplevel.h @@ -15,4 +15,5 @@ void toplevel_set_floating(absn_toplevel *toplevel, bool floating); void toplevel_set_fullscreen(absn_toplevel *toplevel, bool fullscreen); void toplevel_set_border_color(absn_toplevel *toplevel, const float color[4]); +void toplevel_update_borders_geom(absn_toplevel *toplevel); #endif diff --git a/include/types.h b/include/types.h index ee63bf9..afb0825 100644 --- a/include/types.h +++ b/include/types.h @@ -218,12 +218,9 @@ struct absn_toplevel { struct wlr_scene_rect *border[4]; struct wlr_xdg_toplevel_decoration_v1 *deco; - bool can_be_tiled; - bool floating; bool fullscreen; bool urgent; - uint32_t resizing; struct wlr_box geom; struct wlr_box prev_geom; diff --git a/src/cursor.c b/src/cursor.c index 2b0f8cf..caeed61 100644 --- a/src/cursor.c +++ b/src/cursor.c @@ -127,10 +127,6 @@ static void process_cursor_resize(absn_server *server) return; } - if (toplevel->resizing) { - return; - } - if (toplevel->fullscreen) { toplevel_set_fullscreen(toplevel, false); } diff --git a/src/layout.c b/src/layout.c index de26cc4..980ead0 100644 --- a/src/layout.c +++ b/src/layout.c @@ -1,6 +1,7 @@ #include #include "config.h" +#include "layers.h" #include "output.h" #include "toplevel.h" #include "types.h" diff --git a/src/output.c b/src/output.c index 81f2191..22dc2ad 100644 --- a/src/output.c +++ b/src/output.c @@ -15,18 +15,8 @@ void output_frame(struct wl_listener *listener, void *data) struct wlr_scene *scene = output->server->scene; struct wlr_scene_output *scene_output = wlr_scene_get_scene_output(scene, output->wlr); - absn_toplevel *toplevel; - wl_list_for_each(toplevel, &output->server->toplevels, link) - { - if (toplevel->resizing && !toplevel->floating && - toplevel->output == output) { - goto skip; - } - } wlr_scene_output_commit(scene_output, NULL); - -skip: clock_gettime(CLOCK_MONOTONIC, &now); wlr_scene_output_send_frame_done(scene_output, &now); } diff --git a/src/toplevel-handlers.c b/src/toplevel-handlers.c index 4c64c5e..3fd1978 100644 --- a/src/toplevel-handlers.c +++ b/src/toplevel-handlers.c @@ -64,8 +64,7 @@ void toplevel_map(struct wl_listener *listener, void *data) } for (int i = 0; i < 4; ++i) { - toplevel->border[i] = - wlr_scene_rect_create(toplevel->scene_tree, 0, 0, unfocused_bc); + toplevel->border[i] = wlr_scene_rect_create(toplevel->scene_tree, 0, 0, unfocused_bc); toplevel->border[i]->node.data = toplevel; } diff --git a/src/toplevel.c b/src/toplevel.c index 1db0a9e..e3ad99b 100644 --- a/src/toplevel.c +++ b/src/toplevel.c @@ -48,7 +48,7 @@ void toplevel_get_geom(absn_toplevel *toplevel) } } -static void toplevel_update_borders_geom(absn_toplevel *toplevel) +void toplevel_update_borders_geom(absn_toplevel *toplevel) { int32_t bw = toplevel->bw; @@ -83,6 +83,28 @@ void toplevel_set_pos(absn_toplevel *toplevel, int32_t x, int32_t y) wlr_scene_node_set_position(&toplevel->scene_tree->node, x, y); } +static struct wlr_scene_buffer *find_buffer(struct wlr_scene_tree *tree) +{ + struct wlr_scene_node *node; + + wl_list_for_each(node, &tree->children, link) { + + if (node->type == WLR_SCENE_NODE_BUFFER) { + return wlr_scene_buffer_from_node(node); + } + + if (node->type == WLR_SCENE_NODE_TREE) { + struct wlr_scene_buffer *buffer = + find_buffer(wlr_scene_tree_from_node(node)); + + if (buffer) { + return buffer; + } + } + } + + return NULL; +} void toplevel_set_size(absn_toplevel *toplevel, int32_t width, int32_t height) { if (width <= 2 * toplevel->bw || height <= 2 * toplevel->bw || @@ -92,24 +114,18 @@ void toplevel_set_size(absn_toplevel *toplevel, int32_t width, int32_t height) toplevel->geom.width = width; toplevel->geom.height = height; - toplevel_update_borders_geom(toplevel); + struct wlr_scene_buffer *buffer = find_buffer(toplevel->scene_tree); + if (buffer) { + wlr_scene_buffer_set_dest_size(buffer, width, height); + } int32_t bw = toplevel->bw; - - struct wlr_box clip = { - .x = 0, - .y = 0, - .width = width - bw, - .height = height - bw, - }; - if (toplevel->type == TOPLEVEL_XDG) { if (wl_resource_get_version(toplevel->xdg->resource) >= XDG_TOPLEVEL_CONFIGURE_BOUNDS_SINCE_VERSION) { wlr_xdg_toplevel_set_bounds(toplevel->xdg, width, height); } - toplevel->resizing = wlr_xdg_toplevel_set_size( - toplevel->xdg, width - 2 * bw, height - 2 * bw); + wlr_xdg_toplevel_set_size(toplevel->xdg, width - 2 * bw, height - 2 * bw); } #ifdef XWAYLAND else if (toplevel->type == TOPLEVEL_X11) { @@ -121,13 +137,22 @@ void toplevel_set_size(absn_toplevel *toplevel, int32_t width, int32_t height) } #endif + struct wlr_box clip = { + .x = 0, + .y = 0, + .width = width - 2 * bw, + .height = height - 2 * bw, + }; + wlr_scene_subsurface_tree_set_clip(&toplevel->scene_surface->node, &clip); + + toplevel_update_borders_geom(toplevel); } void toplevel_set_geom(absn_toplevel *toplevel, struct wlr_box *geom) { - toplevel_set_pos(toplevel, geom->x, geom->y); toplevel_set_size(toplevel, geom->width, geom->height); + toplevel_set_pos(toplevel, geom->x, geom->y); } void toplevel_set_floating(absn_toplevel *toplevel, bool floating) @@ -136,10 +161,6 @@ void toplevel_set_floating(absn_toplevel *toplevel, bool floating) return; } - if (floating && !toplevel->can_be_tiled) { - return; - } - toplevel->floating = floating; if (floating) { @@ -175,6 +196,7 @@ void toplevel_set_fullscreen(absn_toplevel *toplevel, bool fullscreen) } else { toplevel->bw = toplevel_is_unmanaged(toplevel) ? 0 : TOPLEVEL_BW; toplevel_set_geom(toplevel, &toplevel->prev_geom); + if (toplevel->floating) { wlr_scene_node_reparent(&toplevel->scene_tree->node, toplevel->server->layers[LAYER_FLOAT]); diff --git a/src/xdg-toplevel.c b/src/xdg-toplevel.c index dcac164..9fc9d7d 100644 --- a/src/xdg-toplevel.c +++ b/src/xdg-toplevel.c @@ -2,6 +2,7 @@ #include #include +#include "toplevel.h" #include "types.h" #include "xdg-decoration.h" @@ -9,10 +10,7 @@ void toplevel_commit(struct wl_listener *listener, void *data) { UNUSED(data); absn_toplevel *toplevel = wl_container_of(listener, toplevel, commit); - - if (toplevel->xdg->base->current.configure_serial < toplevel->resizing) { - return; - } + struct wlr_surface *surface = toplevel->xdg->base->surface; if (toplevel->xdg->base->initial_commit) { wlr_xdg_toplevel_set_activated(toplevel->xdg, false); @@ -22,7 +20,7 @@ void toplevel_commit(struct wl_listener *listener, void *data) deco_request_mode(&toplevel->deco_request_mode, toplevel->deco); } /* let client set initial size */ - toplevel->resizing = wlr_xdg_toplevel_set_size(toplevel->xdg, 0, 0); + // wlr_xdg_toplevel_set_size(toplevel->xdg, 0, 0); return; } @@ -33,6 +31,4 @@ void toplevel_commit(struct wl_listener *listener, void *data) .height = toplevel->geom.height - toplevel->bw, }; wlr_scene_subsurface_tree_set_clip(&toplevel->scene_surface->node, &clip); - - toplevel->resizing = 0; }