From 90e1603a21226c8c681b26da79e7c378b8932765 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Mon, 11 May 2026 08:39:17 +0800 Subject: [PATCH] opt: not need scroller link in client --- src/dispatch/bind_define.h | 4 -- src/fetch/client.h | 12 ++++-- src/layout/arrange.h | 5 +-- src/layout/scroll.h | 34 ++------------- src/mango.c | 86 ++++++++------------------------------ 5 files changed, 30 insertions(+), 111 deletions(-) diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index 6c187bfe..63c5d081 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -1381,10 +1381,6 @@ int32_t toggleglobal(const Arg *arg) { selmon->sel->isnamedscratchpad = 0; } selmon->sel->isglobal ^= 1; - if (selmon->sel->isglobal && - (selmon->sel->prev_in_stack || selmon->sel->next_in_stack)) { - arrange(selmon, false, false); - } setborder_color(selmon->sel); return 0; } diff --git a/src/fetch/client.h b/src/fetch/client.h index 49f16b6a..dd9f01d1 100644 --- a/src/fetch/client.h +++ b/src/fetch/client.h @@ -551,9 +551,6 @@ Client *get_scroll_stack_head(Client *c) { return n->client; } } - /* 如果 tag 状态未初始化或节点丢失,使用 client 字段 */ - while (c->prev_in_stack) - c = c->prev_in_stack; return c; } @@ -572,7 +569,14 @@ bool client_is_in_same_stack(Client *sc, Client *tc, Client *fc) { Client *source_stack_head = get_scroll_stack_head(sc); Client *target_stack_head = get_scroll_stack_head(tc); Client *fc_head = fc ? get_scroll_stack_head(fc) : NULL; - if (fc && fc->prev_in_stack && fc_head == source_stack_head) + struct ScrollerStackNode *fc_node = + fc && fc->mon + ? find_scroller_node( + fc->mon->pertag->scroller_state[fc->mon->pertag->curtag], + fc) + : NULL; + if (fc && (fc_node && fc_node->prev_in_stack) && + fc_head == source_stack_head) return false; if (source_stack_head == target_stack_head) return true; diff --git a/src/layout/arrange.h b/src/layout/arrange.h index fbff5590..c6d5ab67 100644 --- a/src/layout/arrange.h +++ b/src/layout/arrange.h @@ -870,9 +870,8 @@ void pre_caculate_before_arrange(Monitor *m, bool want_animation, struct ScrollerStackNode *n = find_scroller_node(st, c); if (n && !n->prev_in_stack) /* 是堆叠头部 */ m->visible_scroll_tiling_clients++; - } else { - if (ISSCROLLTILED(c) && !c->prev_in_stack) - m->visible_scroll_tiling_clients++; + } else if (ISSCROLLTILED(c)) { + m->visible_scroll_tiling_clients++; } } } diff --git a/src/layout/scroll.h b/src/layout/scroll.h index 8b2f3434..7c845aa5 100644 --- a/src/layout/scroll.h +++ b/src/layout/scroll.h @@ -52,12 +52,6 @@ static void scroller_node_remove(struct TagScrollerState *st, if (next) next->prev_in_stack = prev; - /* 清空目标客户端的堆叠指针,使其彻底脱离 */ - if (target->client) { - target->client->prev_in_stack = NULL; - target->client->next_in_stack = NULL; - } - /* 从 all 链表摘除 */ struct ScrollerStackNode **indirect = &st->all_first; while (*indirect && *indirect != target) @@ -102,8 +96,6 @@ static void sync_scroller_state_to_clients(Monitor *m, uint32_t tag) { c->scroller_proportion = n->scroller_proportion; c->stack_proportion = n->stack_proportion; c->scroller_proportion_single = n->scroller_proportion_single; - c->prev_in_stack = n->prev_in_stack ? n->prev_in_stack->client : NULL; - c->next_in_stack = n->next_in_stack ? n->next_in_stack->client : NULL; } } @@ -319,20 +311,10 @@ void scroller(Monitor *m) { n = next; } - /* 为新的可见窗口创建节点,并尝试恢复堆叠关系 */ + /* 为新的可见窗口创建节点 */ for (int i = 0; i < count; i++) { if (!find_scroller_node(st, vis[i])) { - struct ScrollerStackNode *new_node = - scroller_node_create(st, vis[i]); - Client *prev = vis[i]->prev_in_stack; - if (prev) { - struct ScrollerStackNode *prev_node = - find_scroller_node(st, prev); - if (prev_node) { - new_node->prev_in_stack = prev_node; - prev_node->next_in_stack = new_node; - } - } + scroller_node_create(st, vis[i]); } } @@ -585,17 +567,7 @@ void vertical_scroller(Monitor *m) { for (int i = 0; i < count; i++) { if (!find_scroller_node(st, vis[i])) { - struct ScrollerStackNode *new_node = - scroller_node_create(st, vis[i]); - Client *prev = vis[i]->prev_in_stack; - if (prev) { - struct ScrollerStackNode *prev_node = - find_scroller_node(st, prev); - if (prev_node) { - new_node->prev_in_stack = prev_node; - prev_node->next_in_stack = new_node; - } - } + scroller_node_create(st, vis[i]); } } diff --git a/src/mango.c b/src/mango.c index babd961f..7a996dd5 100644 --- a/src/mango.c +++ b/src/mango.c @@ -421,8 +421,6 @@ struct Client { int32_t allow_shortcuts_inhibit; float scroller_proportion_single; bool isfocusing; - struct Client *next_in_stack; - struct Client *prev_in_stack; bool enable_drop_area_draw; int32_t drop_direction; struct wlr_box drag_tile_float_backup_geom; @@ -1179,15 +1177,9 @@ void swallow(Client *c, Client *w) { c->master_inner_per = w->master_inner_per; c->master_mfact_per = w->master_mfact_per; c->scroller_proportion = w->scroller_proportion; - c->next_in_stack = w->next_in_stack; - c->prev_in_stack = w->prev_in_stack; c->isglobal = w->isglobal; /* 调整 w 的邻居指针,让它们指向 c */ - if (w->next_in_stack) - w->next_in_stack->prev_in_stack = c; - if (w->prev_in_stack) - w->prev_in_stack->next_in_stack = c; c->stack_proportion = w->stack_proportion; /* 全局链表替换 */ @@ -4384,8 +4376,6 @@ void init_client_properties(Client *c) { c->float_geom.x = 0; c->float_geom.y = 0; c->stack_proportion = 0.0f; - c->next_in_stack = NULL; - c->prev_in_stack = NULL; memset(c->oldmonname, 0, sizeof(c->oldmonname)); memcpy(c->opacity_animation.initial_border_color, config.bordercolor, sizeof(c->opacity_animation.initial_border_color)); @@ -5106,11 +5096,6 @@ void exchange_two_client(Client *c1, Client *c2) { uint32_t tag1 = m1->pertag->curtag; uint32_t tag2 = m2->pertag->curtag; - /* 跨显示器且任一方有堆叠关系时不允许交换 */ - if (m1 != m2 && (c1->prev_in_stack || c2->prev_in_stack || - c1->next_in_stack || c2->next_in_stack)) - return; - struct TagScrollerState *st1 = ensure_scroller_state(m1, tag1); struct TagScrollerState *st2 = (m1 == m2) ? st1 : ensure_scroller_state(m2, tag2); @@ -5121,6 +5106,11 @@ void exchange_two_client(Client *c1, Client *c2) { if (!n1 || !n2) goto non_scroller_fallback; + /* 跨显示器且任一方有堆叠关系时不允许交换 */ + if (m1 != m2 && (n1->prev_in_stack || n2->prev_in_stack || + n1->next_in_stack || n2->next_in_stack)) + return; + /* 获取各自的堆叠头节点 */ struct ScrollerStackNode *head1 = n1; while (head1->prev_in_stack) @@ -5327,10 +5317,6 @@ void exchange_two_client(Client *c1, Client *c2) { } non_scroller_fallback: - /* 原有的非 scroller 逻辑保持不变 */ - if (c1->mon != c2->mon && (c1->prev_in_stack || c2->prev_in_stack || - c1->next_in_stack || c2->next_in_stack)) - return; Client *c1head = get_scroll_stack_head(c1); Client *c2head = get_scroll_stack_head(c2); @@ -5354,38 +5340,6 @@ non_scroller_fallback: c2->master_mfact_per = master_mfact_per; c2->stack_inner_per = stack_inner_per; - Client *tmp1_next_in_stack = c1->next_in_stack; - Client *tmp1_prev_in_stack = c1->prev_in_stack; - Client *tmp2_next_in_stack = c2->next_in_stack; - Client *tmp2_prev_in_stack = c2->prev_in_stack; - - if (c1->next_in_stack == c2) { - c1->next_in_stack = tmp2_next_in_stack; - c2->next_in_stack = c1; - c1->prev_in_stack = c2; - c2->prev_in_stack = tmp1_prev_in_stack; - if (tmp1_prev_in_stack) - tmp1_prev_in_stack->next_in_stack = c2; - if (tmp2_next_in_stack) - tmp2_next_in_stack->prev_in_stack = c1; - } else if (c2->next_in_stack == c1) { - c2->next_in_stack = tmp1_next_in_stack; - c1->next_in_stack = c2; - c2->prev_in_stack = c1; - c1->prev_in_stack = tmp2_prev_in_stack; - if (tmp2_prev_in_stack) - tmp2_prev_in_stack->next_in_stack = c1; - if (tmp1_next_in_stack) - tmp1_next_in_stack->prev_in_stack = c2; - } else if (is_scroller_layout(c1->mon) && - (c1->prev_in_stack || c2->prev_in_stack)) { - Client *c1head = get_scroll_stack_head(c1); - Client *c2head = get_scroll_stack_head(c2); - exchange_two_client(c1head, c2head); - focusclient(c1, 0); - return; - } - struct wl_list *tmp1_prev = c1->link.prev; struct wl_list *tmp2_prev = c2->link.prev; struct wl_list *tmp1_next = c1->link.next; @@ -5714,16 +5668,6 @@ void exit_scroller_stack(Client *c) { return; /* 节点已移除,客户端指针已在函数内清空 */ } } - - /* 没有节点时也要确保客户端脱离堆叠 */ - if (c->prev_in_stack) { - c->prev_in_stack->next_in_stack = c->next_in_stack; - } - if (c->next_in_stack) { - c->next_in_stack->prev_in_stack = c->prev_in_stack; - } - c->prev_in_stack = NULL; - c->next_in_stack = NULL; } void setmaximizescreen(Client *c, int32_t maximizescreen) { @@ -6578,9 +6522,15 @@ void unmapnotify(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, unmap); Monitor *m = NULL; Client *nextfocus = NULL; - Client *next_in_stack = c->next_in_stack; - Client *prev_in_stack = c->prev_in_stack; c->iskilling = 1; + struct ScrollerStackNode *target_node = + c->mon ? find_scroller_node( + c->mon->pertag->scroller_state[c->mon->pertag->curtag], c) + : NULL; + struct ScrollerStackNode *prev_node = + target_node ? target_node->prev_in_stack : NULL; + struct ScrollerStackNode *next_node = + target_node ? target_node->next_in_stack : NULL; if (config.animations && !c->is_clip_to_hide && !c->isminimized && (!c->mon || VISIBLEON(c, c->mon))) @@ -6618,10 +6568,10 @@ void unmapnotify(struct wl_listener *listener, void *data) { } if (c->mon && c->mon == selmon) { - if (next_in_stack && !c->swallowedby) { - nextfocus = next_in_stack; - } else if (prev_in_stack && !c->swallowedby) { - nextfocus = prev_in_stack; + if (next_node && !c->swallowedby) { + nextfocus = next_node->client; + } else if (prev_node && !c->swallowedby) { + nextfocus = prev_node->client; } else { nextfocus = focustop(selmon); } @@ -6672,8 +6622,6 @@ void unmapnotify(struct wl_listener *listener, void *data) { } c->stack_proportion = 0.0f; - c->next_in_stack = NULL; - c->prev_in_stack = NULL; wlr_scene_node_destroy(&c->scene->node); printstatus();