From 3820c33519c220ee0a8326c3bab83d0aac90c502 Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Tue, 10 Sep 2024 01:17:45 +0100 Subject: [PATCH] wm: best effort refreshing leaders even an inconsistent tree On second thought, it is not very nice to give up as soon as we see the tree being inconsistent. This could results in flickering, etc. Instead, still refresh the leaders with best effort. And only set the flag to retry leader refresh when we actually hit an inconsistent tree node. Related #1336 Signed-off-by: Yuxuan Shui --- src/wm/wm.c | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/src/wm/wm.c b/src/wm/wm.c index a89cd6bd64..f0b3536044 100644 --- a/src/wm/wm.c +++ b/src/wm/wm.c @@ -225,6 +225,13 @@ static struct wm_tree_node *wm_find_leader(struct wm *wm, struct wm_tree_node *n return node->leader_final; } leader_node = wm_tree_find_toplevel_for(&wm->tree, leader_node); + if (leader_node == NULL) { + log_debug("Cannot find toplevel for leader %#010x of window " + "%#010x. tree consistency: %d", + node->leader, node->id.x, wm_is_consistent(wm)); + wm->needs_leader_refresh = true; + return node->leader_final; + } node->visited = true; node->leader_final = wm_find_leader(wm, leader_node); node->visited = false; @@ -236,22 +243,7 @@ void wm_refresh_leaders(struct wm *wm) { if (!wm->needs_leader_refresh) { return; } - if (!wm_is_consistent(wm)) { - // The window tree has not been fully replicated, we might be missing - // windows, so we couldn't refresh the leaders here, but also can't leave - // them NULL. So we just set them to themselves. - log_debug("Window tree is not consistent, setting all leaders to " - "themselves"); - list_foreach(struct wm_tree_node, i, &wm->tree.root->children, siblings) { - if (i->is_zombie) { - // Don't change anything about a zombie window. - continue; - } - i->leader_final = i; - } - return; - } - log_debug("Refreshing window leaders"); + log_debug("Refreshing window leaders, tree consistency: %d", wm_is_consistent(wm)); wm->needs_leader_refresh = false; list_foreach(struct wm_tree_node, i, &wm->tree.root->children, siblings) { if (i->is_zombie) { @@ -269,6 +261,9 @@ void wm_refresh_leaders(struct wm *wm) { log_verbose("Window %#010x has leader %#010x", i->id.x, i->leader_final->id.x); } + if (wm->needs_leader_refresh) { + log_debug("Leaders not fully resolved, will try again later."); + } } /// Move window `w` so it's right above `below`, if `below` is 0, `w` is moved