Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
fix: echo absorb also fires in the timeout recovery states
A hot echo loop drives the configure state machine into
TimedOut/TimedOutAcked (acks lag under storm load), and the absorb —
gated on Idle | Committed — disarmed there: it switched itself off at
exactly the moment it exists for. Observed live as a title-flapping
window module sustaining a 372↔456px storm (~3300 configures) at
state=TimedOutAcked, flickering its light_source neighbor.
The gate is now exclusion-based: absorb in every rest state, skip only
Inflight/Acked where a real configure is mid-flight. Absorbing leaves
timeout recovery untouched — a late ack or the next commit still walks
the state back to Idle.
Co-Authored-By: Claude Fable 5 <[email protected]>
src/server/xdg_toplevel.rs | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/src/server/xdg_toplevel.rs b/src/server/xdg_toplevel.rs
index a3e2f74..c0b8018 100644
--- a/src/server/xdg_toplevel.rs
+++ b/src/server/xdg_toplevel.rs
@@ -250,10 +250,21 @@ impl XdgToplevel {
&& self.geometry.height > 0
&& echo_w == Some(self.geometry.width as u32)
&& echo_h == Some(self.geometry.height as u32);
+ // Timeout recovery states absorb too: a hot echo loop drives the
+ // machine into TimedOut/TimedOutAcked, and an absorb that disarms
+ // there switches itself off at exactly the moment it exists for
+ // (observed live: a title-flapping window module sustained a
+ // 372↔456 storm at state=TimedOutAcked). Only Inflight/Acked stay
+ // excluded — a real configure is mid-flight there. Absorbing
+ // leaves the timeout recovery untouched: a late ack or the next
+ // commit still walks the state back to Idle.
if size_is_echo
&& non_size_equal
&& bounds_ok
- && matches!(self.configure_state, ConfigureState::Idle | ConfigureState::Committed)
+ && !matches!(
+ self.configure_state,
+ ConfigureState::Inflight(..) | ConfigureState::Acked
+ )
{
let absorbed_bounds = scheduled.bounds;
(*self.window).configure_sent.width = echo_w;