From 52676492fe22356b45f9cbda9d24d887f4039f02 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Mon, 30 Mar 2026 18:11:10 +0800 Subject: [PATCH] opt: optimize foreign toplevel state sync --- src/dispatch/bind_define.h | 2 +- src/mango.c | 77 +++++++++++++++++++++++--------------- 2 files changed, 47 insertions(+), 32 deletions(-) diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index 07eafde5..ec06ce5a 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -552,7 +552,7 @@ int32_t restore_minimized(const Arg *arg) { if (selmon && selmon->sel && selmon->sel->is_in_scratchpad && selmon->sel->is_scratchpad_show) { - selmon->sel->isminimized = 0; + client_pending_minimized_state(selmon->sel, 0); selmon->sel->is_scratchpad_show = 0; selmon->sel->is_in_scratchpad = 0; selmon->sel->isnamedscratchpad = 0; diff --git a/src/mango.c b/src/mango.c index fad86b20..8fdff709 100644 --- a/src/mango.c +++ b/src/mango.c @@ -806,6 +806,10 @@ static int32_t keep_idle_inhibit(void *data); static void check_keep_idle_inhibit(Client *c); static void pre_caculate_before_arrange(Monitor *m, bool want_animation, bool from_view, bool only_caculate); +static void client_pending_fullscreen_state(Client *c, int32_t isfullscreen); +static void client_pending_maximized_state(Client *c, int32_t ismaximized); +static void client_pending_minimized_state(Client *c, int32_t isminimized); + #include "data/static_keymap.h" #include "dispatch/bind_declare.h" #include "layout/layout.h" @@ -1063,11 +1067,33 @@ void clear_fullscreen_flag(Client *c) { } } +void client_pending_fullscreen_state(Client *c, int32_t isfullscreen) { + c->isfullscreen = isfullscreen; + + if (c->foreign_toplevel && !c->iskilling) + wlr_foreign_toplevel_handle_v1_set_fullscreen(c->foreign_toplevel, + isfullscreen); +} + +void client_pending_maximized_state(Client *c, int32_t ismaximized) { + c->ismaximizescreen = ismaximized; + if (c->foreign_toplevel && !c->iskilling) + wlr_foreign_toplevel_handle_v1_set_maximized(c->foreign_toplevel, + ismaximized); +} + +void client_pending_minimized_state(Client *c, int32_t isminimized) { + c->isminimized = isminimized; + if (c->foreign_toplevel && !c->iskilling) + wlr_foreign_toplevel_handle_v1_set_minimized(c->foreign_toplevel, + isminimized); +} + void show_scratchpad(Client *c) { c->is_scratchpad_show = 1; if (c->isfullscreen || c->ismaximizescreen) { - c->isfullscreen = 0; // 清除窗口全屏标志 - c->ismaximizescreen = 0; + client_pending_fullscreen_state(c, 0); + client_pending_maximized_state(c, 0); c->bw = c->isnoborder ? 0 : config.borderpx; } @@ -1106,9 +1132,6 @@ void swallow(Client *c, Client *w) { c->bw = w->bw; c->isfloating = w->isfloating; c->isurgent = w->isurgent; - c->isfullscreen = w->isfullscreen; - c->ismaximizescreen = w->ismaximizescreen; - c->isminimized = w->isminimized; c->is_in_scratchpad = w->is_in_scratchpad; c->is_scratchpad_show = w->is_scratchpad_show; c->tags = w->tags; @@ -1120,6 +1143,7 @@ void swallow(Client *c, Client *w) { c->scroller_proportion = w->scroller_proportion; c->next_in_stack = w->next_in_stack; c->prev_in_stack = w->prev_in_stack; + if (w->next_in_stack) w->next_in_stack->prev_in_stack = c; if (w->prev_in_stack) @@ -1138,11 +1162,9 @@ void swallow(Client *c, Client *w) { if (!c->foreign_toplevel && c->mon) add_foreign_toplevel(c); - if (c->isminimized && c->foreign_toplevel) { - wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, - false); - wlr_foreign_toplevel_handle_v1_set_minimized(c->foreign_toplevel, true); - } + client_pending_fullscreen_state(c, w->isfullscreen); + client_pending_maximized_state(c, w->ismaximizescreen); + client_pending_minimized_state(c, w->isminimized); } bool switch_scratchpad_client_state(Client *c) { @@ -4231,7 +4253,7 @@ void maximizenotify(struct wl_listener *listener, void *data) { void unminimize(Client *c) { if (c && c->is_in_scratchpad && c->is_scratchpad_show) { - c->isminimized = 0; + client_pending_minimized_state(c, 0); c->is_scratchpad_show = 0; c->is_in_scratchpad = 0; c->isnamedscratchpad = 0; @@ -4259,13 +4281,12 @@ void set_minimized(Client *c) { c->oldtags = c->mon->tagset[c->mon->seltags]; c->mini_restore_tag = c->tags; c->tags = 0; - c->isminimized = 1; + client_pending_minimized_state(c, 1); c->is_in_scratchpad = 1; c->is_scratchpad_show = 0; focusclient(focustop(selmon), 1); arrange(c->mon, false, false); wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, false); - wlr_foreign_toplevel_handle_v1_set_minimized(c->foreign_toplevel, true); wl_list_remove(&c->link); // 从原来位置移除 wl_list_insert(clients.prev, &c->link); // 插入尾部 } @@ -5042,11 +5063,11 @@ setfloating(Client *c, int32_t floating) { if (floating == 1 && c != grabc) { if (c->isfullscreen) { - c->isfullscreen = 0; + client_pending_fullscreen_state(c, 0); client_set_fullscreen(c, 0); } - c->ismaximizescreen = 0; + client_pending_maximized_state(c, 0); exit_scroller_stack(c); // 重新计算居中的坐标 @@ -5171,12 +5192,12 @@ void setmaximizescreen(Client *c, int32_t maximizescreen) { return; int32_t old_maximizescreen_state = c->ismaximizescreen; - c->ismaximizescreen = maximizescreen; + client_pending_maximized_state(c, maximizescreen); if (maximizescreen) { if (c->isfullscreen) { - c->isfullscreen = 0; + client_pending_fullscreen_state(c, 0); client_set_fullscreen(c, 0); } @@ -5189,10 +5210,8 @@ void setmaximizescreen(Client *c, int32_t maximizescreen) { wlr_scene_node_raise_to_top(&c->scene->node); if (!is_scroller_layout(c->mon) || c->isfloating) resize(c, maximizescreen_box, 0); - c->ismaximizescreen = 1; } else { c->bw = c->isnoborder ? 0 : config.borderpx; - c->ismaximizescreen = 0; if (c->isfloating) setfloating(c, 1); } @@ -5240,6 +5259,7 @@ void setfullscreen(Client *c, int32_t fullscreen) // 用自定义全屏代理自 c->isfullscreen = fullscreen; client_set_fullscreen(c, fullscreen); + client_pending_fullscreen_state(c, fullscreen); if (fullscreen) { @@ -5247,7 +5267,7 @@ void setfullscreen(Client *c, int32_t fullscreen) // 用自定义全屏代理自 client_set_maximized(c, false); } - c->ismaximizescreen = 0; + client_pending_maximized_state(c, 0); exit_scroller_stack(c); c->isfakefullscreen = 0; @@ -5256,10 +5276,8 @@ void setfullscreen(Client *c, int32_t fullscreen) // 用自定义全屏代理自 wlr_scene_node_raise_to_top(&c->scene->node); // 将视图提升到顶层 if (!is_scroller_layout(c->mon) || c->isfloating) resize(c, c->mon->m, 1); - c->isfullscreen = 1; } else { c->bw = c->isnoborder ? 0 : config.borderpx; - c->isfullscreen = 0; if (c->isfloating) setfloating(c, 1); } @@ -5451,8 +5469,7 @@ void show_hide_client(Client *c) { c->tags = c->oldtags; arrange(c->mon, false, false); } - c->isminimized = 0; - wlr_foreign_toplevel_handle_v1_set_minimized(c->foreign_toplevel, false); + client_pending_minimized_state(c, 0); focusclient(c, 1); wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, true); } @@ -5876,8 +5893,8 @@ void overview_backup(Client *c) { c->isfloating = 0; } if (c->isfullscreen || c->ismaximizescreen) { - c->isfullscreen = 0; // 清除窗口全屏标志 - c->ismaximizescreen = 0; + client_pending_fullscreen_state(c, 0); // 清除窗口全屏标志 + client_pending_maximized_state(c, 0); } c->bw = c->isnoborder ? 0 : config.borderpx; @@ -5907,8 +5924,8 @@ void overview_restore(Client *c, const Arg *arg) { } else if (want_restore_fullscreen(c) && c->isfullscreen) { setfullscreen(c, 1); } else { - c->isfullscreen = 0; - c->ismaximizescreen = 0; + client_pending_fullscreen_state(c, 0); + client_pending_maximized_state(c, 0); setfullscreen(c, false); } } else { @@ -6481,13 +6498,11 @@ void activatex11(struct wl_listener *listener, void *data) { return; if (c->isminimized) { - c->isminimized = 0; + client_pending_minimized_state(c, 0); c->tags = c->mini_restore_tag; c->is_scratchpad_show = 0; c->is_in_scratchpad = 0; c->isnamedscratchpad = 0; - wlr_foreign_toplevel_handle_v1_set_minimized(c->foreign_toplevel, - false); setborder_color(c); if (VISIBLEON(c, c->mon)) { need_arrange = true;