git.lucas.co / cce-compositor
Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git

commitb85558975aa31b1f11ffbd8eaa0cc3e2e94f2709
parent56cd6e4720
authorLucas Galante <[email protected]>
date2026-08-04 14:58
fix: echo absorb must also fire in Committed state, not just Idle

Verification of the previous commit caught it inert: after any completed
configure round-trip the state machine rests in Committed (Acked →
Committed on commit; only the timeout path returns to Idle), so an
Idle-only gate never matched in steady state — the exact moment the echo
loop runs. A padding-change probe showed size-restating configures still
going out one per module resize.

The absorb now fires in Idle | Committed. Inflight/Acked stay excluded: a
real configure is mid-flight there and the scheduled size may need to
supersede it.

Co-Authored-By: Claude Fable 5 <[email protected]>

 src/server/xdg_toplevel.rs | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/src/server/xdg_toplevel.rs b/src/server/xdg_toplevel.rs
index 395df6a..99003b4 100644
--- a/src/server/xdg_toplevel.rs
+++ b/src/server/xdg_toplevel.rs
@@ -229,8 +229,15 @@ impl XdgToplevel {
                 && scheduled.maximized == sent.maximized
                 && scheduled.inform_fullscreen == sent.inform_fullscreen
                 && scheduled.resizing == sent.resizing;
+            // Idle AND Committed: after any completed configure round-trip
+            // the state machine RESTS in Committed (Acked → Committed on
+            // commit; only the timeout path returns to Idle), so gating on
+            // Idle alone leaves this absorb dead in steady state — the exact
+            // moment the echo loop runs. Inflight/Acked stay excluded: a
+            // real configure is mid-flight and the scheduled size may need
+            // to supersede it.
             if non_size_equal
-                && matches!(self.configure_state, ConfigureState::Idle)
+                && matches!(self.configure_state, ConfigureState::Idle | ConfigureState::Committed)
                 && self.geometry.width > 0
                 && self.geometry.height > 0
                 && echo_w == Some(self.geometry.width as u32)