From 30f00ba50a01112e62265945157ddaf16bb30c26 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Tue, 12 May 2026 16:30:26 +0800 Subject: [PATCH] opt: optimize scroller insert reset --- src/dispatch/bind_define.h | 25 +++++++++++++++++---- src/layout/scroll.h | 45 +++++++++++++++++++++++++++++++------- src/mango.c | 1 + 3 files changed, 59 insertions(+), 12 deletions(-) diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index fd17d03e..ffeff6f0 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -1838,14 +1838,26 @@ int32_t scroller_apply_stack(Client *c, Client *target_client, struct ScrollerStackNode *move_out_refer_node = cnode->prev_in_stack ? cnode->prev_in_stack : cnode->next_in_stack; scroller_node_remove(st, cnode); + + // 必须先更新,不然里面节点还存着的是cnode的信息, + // 会造成stach_head/stack_tail指向的客户端不对 + update_scroller_state(c->mon); + Client *stack_head = scroll_get_stack_head_client(move_out_refer_node->client); + Client *stack_tail = + scroll_get_stack_tail_client(move_out_refer_node->client); + if (direction == LEFT || direction == UP) { - wl_list_remove(&c->link); - wl_list_insert(stack_head->link.prev, &c->link); + if (c != stack_head) { + wl_list_remove(&c->link); + wl_list_insert(stack_head->link.prev, &c->link); + } } else if (direction == RIGHT || direction == DOWN) { - wl_list_remove(&c->link); - wl_list_insert(&stack_head->link, &c->link); + if (c != stack_tail) { + wl_list_remove(&c->link); + wl_list_insert(&stack_tail->link, &c->link); + } } sync_scroller_state_to_clients(m, tag); arrange(m, false, false); @@ -1862,6 +1874,11 @@ int32_t scroller_apply_stack(Client *c, Client *target_client, /* 通过封装好的插入函数实现(尾部插入) */ scroller_insert_stack(c, tail->client, false); + + if (c != tail->client) { + wl_list_remove(&c->link); + wl_list_insert(&tail->client->link, &c->link); + } return 0; } diff --git a/src/layout/scroll.h b/src/layout/scroll.h index 84e84e2c..e4a6d75f 100644 --- a/src/layout/scroll.h +++ b/src/layout/scroll.h @@ -793,7 +793,12 @@ void scroller_insert_stack(Client *c, Client *target_client, void scroller_drop_tile(Client *c, Client *closest, int vertical) { + // 必须先更新,不然里面节点还存着的是cnode的信息, + // 会造成stach_head/stack_tail指向的客户端不对 + update_scroller_state(c->mon); + Client *stack_head = scroll_get_stack_head_client(closest); + Client *stack_tail = scroll_get_stack_tail_client(closest); if (vertical) { if (closest->drop_direction == LEFT) { @@ -805,11 +810,15 @@ void scroller_drop_tile(Client *c, Client *closest, int vertical) { scroller_insert_stack(c, closest, false); return; } else if (closest->drop_direction == UP) { - wl_list_remove(&c->link); - wl_list_insert(stack_head->link.prev, &c->link); + if (c != stack_head) { + wl_list_remove(&c->link); + wl_list_insert(stack_head->link.prev, &c->link); + } } else if (closest->drop_direction == DOWN) { - wl_list_remove(&c->link); - wl_list_insert(&stack_head->link, &c->link); + if (c != stack_tail) { + wl_list_remove(&c->link); + wl_list_insert(&stack_head->link, &c->link); + } } } else { if (closest->drop_direction == UP) { @@ -821,11 +830,15 @@ void scroller_drop_tile(Client *c, Client *closest, int vertical) { scroller_insert_stack(c, closest, false); return; } else if (closest->drop_direction == LEFT) { - wl_list_remove(&c->link); - wl_list_insert(stack_head->link.prev, &c->link); + if (c != stack_head) { + wl_list_remove(&c->link); + wl_list_insert(stack_head->link.prev, &c->link); + } } else if (closest->drop_direction == RIGHT) { - wl_list_remove(&c->link); - wl_list_insert(&stack_head->link, &c->link); + if (c != stack_tail) { + wl_list_remove(&c->link); + wl_list_insert(&stack_head->link, &c->link); + } } } @@ -848,6 +861,22 @@ Client *scroll_get_stack_head_client(Client *c) { return c; } +Client *scroll_get_stack_tail_client(Client *c) { + if (!c || !c->mon) + return c; + uint32_t tag = c->mon->pertag->curtag; + struct TagScrollerState *st = c->mon->pertag->scroller_state[tag]; + if (st) { + struct ScrollerStackNode *n = find_scroller_node(st, c); + if (n) { + while (n->next_in_stack) + n = n->next_in_stack; + return n->client; + } + } + return c; +} + static void update_scroller_state(Monitor *m) { uint32_t tag = m->pertag->curtag; struct TagScrollerState *st = ensure_scroller_state(m, tag); diff --git a/src/mango.c b/src/mango.c index cf9bf6a3..4781a5d9 100644 --- a/src/mango.c +++ b/src/mango.c @@ -847,6 +847,7 @@ static void scroller_node_remove(struct TagScrollerState *st, static struct ScrollerStackNode * scroller_node_create(struct TagScrollerState *st, Client *c); static void update_scroller_state(Monitor *m); +Client *scroll_get_stack_tail_client(Client *c); #include "data/static_keymap.h" #include "dispatch/bind_declare.h"