diff --git a/src/shell.rs b/src/shell.rs index 54fc2f0..dee4def 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -83,2 +83 @@ struct State { - /// We've painted at least one frame with the modifier genuinely held; gates the - /// confirm-on-release so the launching chord's tail can't trigger it. + /// A rendered hold after sources arrived, enabling immediate confirmation on release. @@ -85,0 +85,2 @@ struct State { + /// A release received before source enumeration completes, to confirm after render. + pending_release: bool, @@ -179,0 +181 @@ pub fn run(app: App, t0: Instant) -> anyhow::Result<()> { + pending_release: false, @@ -205,5 +207,2 @@ impl State { - // Record that we've shown at least one frame with the modifier held; this - // gates confirm-on-release (see `reconcile`). - if self.armed && self.any_armed_held() { - self.armed_rendered = true; - } + // Record a frame with the modifier held after source enumeration completes. + let armed_held = self.armed && self.any_armed_held(); @@ -234,0 +234,7 @@ impl State { + if armed_held && self.app.release_ready() { + self.armed_rendered = true; + self.pending_release = false; + } else if self.pending_release && self.app.release_ready() { + self.pending_release = false; + self.app.confirm_release(); + } @@ -485,2 +491,2 @@ impl State { - // Confirm on release — but only after we've painted a frame with the - // modifier genuinely held, so the launching chord's tail can't fire it. + // Confirm on release. Before the UI is ready, latch the edge and consume it + // only after `run_ui` has received sources and the frame has rendered. @@ -488,2 +494,12 @@ impl State { - if self.armed && self.armed_rendered && self.prev_held && !held { - self.app.confirm_release(); + // A new hold represents a new switching gesture, so do not consume a + // release that belonged to an earlier gesture. + if held { + self.pending_release = false; + } + if self.armed && self.prev_held && !held { + if self.armed_rendered && self.app.release_ready() { + self.pending_release = false; + self.app.confirm_release(); + } else { + self.pending_release = true; + } diff --git a/src/ui.rs b/src/ui.rs index c821d66..854f6ad 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -854,0 +855 @@ pub struct App { + sources_received: bool, @@ -899,0 +901 @@ impl App { + sources_received: false, @@ -1008 +1010,4 @@ impl App { - Msg::Sources(s) => self.sources = s, + Msg::Sources(s) => { + self.sources = s; + self.sources_received = true; + } @@ -1080,0 +1086,5 @@ impl App { + /// True once `run_ui` has received the initial source enumeration. + pub fn release_ready(&self) -> bool { + self.sources_received + } +