From 4d5474d218a6c8aaa679982647a590a81a1e5015 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sat, 17 Jan 2026 14:08:07 +0800 Subject: [PATCH] feat: support vertical scroller stack --- src/dispatch/bind_define.h | 4 +-- src/layout/vertical.h | 54 ++++++++++++++++++++++++++++++++------ 2 files changed, 48 insertions(+), 10 deletions(-) diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index 5718062..ae81c49 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -1599,7 +1599,7 @@ int32_t scroller_stack(const Arg *arg) { Client *left_c = find_client_by_direction(c, arg, false, true); if (!left_c) { - if (arg->i == LEFT) { + if (arg->i == LEFT || arg->i == UP) { exit_scroller_stack(c); wl_list_remove(&c->link); wl_list_insert(&clients, &c->link); @@ -1652,7 +1652,7 @@ int32_t scroller_unstack(const Arg *arg) { // Insert c after the stack it was in wl_list_remove(&c->link); - if (arg->i == RIGHT) + if (arg->i == RIGHT || arg->i == DOWN) wl_list_insert(&scroller_stack_head->link, &c->link); else wl_list_insert(scroller_stack_head->link.prev, &c->link); diff --git a/src/layout/vertical.h b/src/layout/vertical.h index 9513824..f04866b 100644 --- a/src/layout/vertical.h +++ b/src/layout/vertical.h @@ -199,6 +199,34 @@ void vertical_scroll_adjust_fullandmax(Client *c, struct wlr_box *target_geom) { target_geom->x = m->w.x + (m->w.width - target_geom->width) / 2; } +void arrange_stack_vertical(Client *scroller_stack_head, + struct wlr_box geometry, int32_t gappih) { + int32_t stack_size = 0; + Client *iter = scroller_stack_head; + while (iter) { + stack_size++; + iter = iter->next_in_stack; + } + + if (stack_size == 0) + return; + + int32_t client_width = + (geometry.width - (stack_size - 1) * gappih) / stack_size; + int32_t current_x = geometry.x; + + iter = scroller_stack_head; + while (iter) { + struct wlr_box client_geom = {.y = geometry.y, + .x = current_x, + .height = geometry.height, + .width = client_width}; + resize(iter, client_geom, 0); + current_x += client_width + gappih; + iter = iter->next_in_stack; + } +} + // 竖屏滚动布局 void vertical_scroller(Monitor *m) { int32_t i, n, j; @@ -212,6 +240,7 @@ void vertical_scroller(Monitor *m) { int32_t cur_gappiv = enablegaps ? m->gappiv : 0; int32_t cur_gappov = enablegaps ? m->gappov : 0; int32_t cur_gappoh = enablegaps ? m->gappoh : 0; + int32_t cur_gappih = enablegaps ? m->gappih : 0; cur_gappiv = smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappiv; @@ -235,7 +264,7 @@ void vertical_scroller(Monitor *m) { j = 0; wl_list_for_each(c, &clients, link) { - if (VISIBLEON(c, m) && ISSCROLLTILED(c)) { + if (VISIBLEON(c, m) && ISSCROLLTILED(c) && !c->prev_in_stack) { tempClients[j] = c; j++; } @@ -253,7 +282,7 @@ void vertical_scroller(Monitor *m) { target_geom.height = (m->w.height - 2 * cur_gappov) * single_proportion; target_geom.y = m->w.y + (m->w.height - target_geom.height) / 2; target_geom.x = m->w.x + (m->w.width - target_geom.width) / 2; - resize(c, target_geom, 0); + arrange_stack_vertical(c, target_geom, cur_gappih); free(tempClients); return; } @@ -267,6 +296,11 @@ void vertical_scroller(Monitor *m) { root_client = center_tiled_select(m); } + // root_client might be in a stack, find the stack head + if (root_client) { + root_client = get_scroll_stack_head(root_client); + } + if (!root_client) { free(tempClients); return; @@ -302,10 +336,12 @@ void vertical_scroller(Monitor *m) { if (tempClients[focus_client_index]->isfullscreen) { target_geom.y = m->m.y; - resize(tempClients[focus_client_index], target_geom, 0); + arrange_stack_vertical(tempClients[focus_client_index], target_geom, + cur_gappih); } else if (tempClients[focus_client_index]->ismaximizescreen) { target_geom.y = m->w.y + cur_gappov; - resize(tempClients[focus_client_index], target_geom, 0); + arrange_stack_vertical(tempClients[focus_client_index], target_geom, + cur_gappih); } else if (need_scroller) { if (scroller_focus_center || ((!m->prevsel || @@ -323,10 +359,12 @@ void vertical_scroller(Monitor *m) { scroller_structs) : m->w.y + scroller_structs; } - resize(tempClients[focus_client_index], target_geom, 0); + arrange_stack_vertical(tempClients[focus_client_index], target_geom, + cur_gappih); } else { target_geom.y = c->geom.y; - resize(tempClients[focus_client_index], target_geom, 0); + arrange_stack_vertical(tempClients[focus_client_index], target_geom, + cur_gappih); } for (i = 1; i <= focus_client_index; i++) { @@ -336,7 +374,7 @@ void vertical_scroller(Monitor *m) { target_geom.y = tempClients[focus_client_index - i + 1]->geom.y - cur_gappiv - target_geom.height; - resize(c, target_geom, 0); + arrange_stack_vertical(c, target_geom, cur_gappih); } for (i = 1; i < n - focus_client_index; i++) { @@ -346,7 +384,7 @@ void vertical_scroller(Monitor *m) { target_geom.y = tempClients[focus_client_index + i - 1]->geom.y + cur_gappiv + tempClients[focus_client_index + i - 1]->geom.height; - resize(c, target_geom, 0); + arrange_stack_vertical(c, target_geom, cur_gappih); } free(tempClients);