From 61361ad3193a163018626ac4532fd7136ebdaf7f Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Sun, 8 Sep 2024 09:30:38 +0100 Subject: [PATCH 1/4] misc: update README.md We use asciidoctor now, not asciidoc. Fixes #1329 Signed-off-by: Yuxuan Shui --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 41f62679dd..02a0580bd7 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ On Fedora, the needed packages are dbus-devel gcc git libconfig-devel libdrm-devel libev-devel libX11-devel libX11-xcb libxcb-devel libGL-devel libEGL-devel libepoxy-devel meson pcre2-devel pixman-devel uthash-devel xcb-util-image-devel xcb-util-renderutil-devel xorg-x11-proto-devel xcb-util-devel ``` -To build the documents, you need `asciidoc` +To build the documents, you need `asciidoctor` ### To build From 0d7b254fd98f02a40a2aabe46007fb9c86cd38cb Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Tue, 10 Sep 2024 00:25:36 +0100 Subject: [PATCH 2/4] core: queue update and redraw when wm tree becomes consistent When the wm tree is not consistent, there might be certain updates we can't do (e.g. refreshing window leaders). So once the wm tree becomes consistent we should retry. Signed-off-by: Yuxuan Shui --- src/picom.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/picom.c b/src/picom.c index aa1880cc13..2afb8be8cc 100644 --- a/src/picom.c +++ b/src/picom.c @@ -1448,6 +1448,8 @@ static void unredirect(session_t *ps) { /// keeps an internal queue of events, so we have to be 100% sure no events are /// left in that queue before we go to sleep. static void handle_x_events(struct session *ps) { + bool wm_was_consistent = wm_is_consistent(ps->wm); + if (ps->vblank_scheduler) { vblank_handle_x_events(ps->vblank_scheduler); } @@ -1478,6 +1480,12 @@ static void handle_x_events(struct session *ps) { log_fatal("X11 server connection broke (error %d)", err); exit(1); } + + if (wm_is_consistent(ps->wm) != wm_was_consistent && !wm_was_consistent) { + log_debug("Window tree has just become consistent, queueing redraw."); + ps->pending_updates = true; + queue_redraw(ps); + } } static void handle_x_events_ev(EV_P attr_unused, ev_prepare *w, int revents attr_unused) { From 67ec733c1e537ad2241a7c1e676096e65559217a Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Tue, 10 Sep 2024 00:30:47 +0100 Subject: [PATCH 3/4] wm: don't update leader if tree is not consistent The leader nodes referenced might not be in the tree yet. Fixes #1336 Signed-off-by: Yuxuan Shui --- src/wm/wm.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/wm/wm.c b/src/wm/wm.c index 29b66a994e..a89cd6bd64 100644 --- a/src/wm/wm.c +++ b/src/wm/wm.c @@ -236,6 +236,22 @@ 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"); wm->needs_leader_refresh = false; list_foreach(struct wm_tree_node, i, &wm->tree.root->children, siblings) { if (i->is_zombie) { @@ -249,6 +265,9 @@ void wm_refresh_leaders(struct wm *wm) { continue; } wm_find_leader(wm, i); + BUG_ON_NULL(i->leader_final); + log_verbose("Window %#010x has leader %#010x", i->id.x, + i->leader_final->id.x); } } From 3820c33519c220ee0a8326c3bab83d0aac90c502 Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Tue, 10 Sep 2024 01:17:45 +0100 Subject: [PATCH 4/4] 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