From 61e2cf1544f1823e7a529cc1549dd3a6adadf7ae Mon Sep 17 00:00:00 2001 From: Emil Date: Sat, 20 Jun 2026 23:43:31 +0300 Subject: [PATCH] fix: dual-timeout held keys to fix terminal initial repeat delay Root cause: terminals wait 300-500ms after initial Press before sending the first Repeat event. With 60ms timeout, the key was released during this gap, causing step-pause-accelerate pattern. Fix: two timeout phases: - After Press (no Repeat seen yet): 400ms timeout Covers terminal's initial repeat delay, key stays held - After first Repeat: 80ms timeout Repeats arrive every ~30ms, 80ms is safe margin Quick release detection once repeating starts Result: smooth continuous movement from first keypress, no gap --- src/input.rs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/input.rs b/src/input.rs index 4efca4c..dbe0437 100644 --- a/src/input.rs +++ b/src/input.rs @@ -44,9 +44,11 @@ pub enum HeldKey { struct HeldState { last_seen: Instant, + seen_repeat: bool, } -const HOLD_TIMEOUT: Duration = Duration::from_millis(60); +const HOLD_TIMEOUT_PRESS: Duration = Duration::from_millis(400); +const HOLD_TIMEOUT_REPEAT: Duration = Duration::from_millis(80); pub struct InputHandler { pub paint_brush: MaterialBrush, @@ -102,8 +104,11 @@ impl InputHandler { } } - fn mark_held(&mut self, key: HeldKey) { - self.held.insert(key, HeldState { last_seen: Instant::now() }); + fn mark_held(&mut self, key: HeldKey, is_repeat: bool) { + self.held.insert(key, HeldState { + last_seen: Instant::now(), + seen_repeat: is_repeat, + }); } fn release(&mut self, key: HeldKey) { @@ -119,7 +124,10 @@ impl InputHandler { self.jump_pressed = false; let now = Instant::now(); - self.held.retain(|_, state| now.duration_since(state.last_seen) < HOLD_TIMEOUT); + self.held.retain(|_, state| { + let timeout = if state.seen_repeat { HOLD_TIMEOUT_REPEAT } else { HOLD_TIMEOUT_PRESS }; + now.duration_since(state.last_seen) < timeout + }); let events: Vec = match &self.receiver { Some(rx) => rx.try_iter().collect(), @@ -163,8 +171,10 @@ impl InputHandler { } if let Some(held_key) = Self::key_to_held(code) { - if is_press || is_repeat { - self.mark_held(held_key); + if is_press { + self.mark_held(held_key, false); + } else if is_repeat { + self.mark_held(held_key, true); } else if is_release { self.release(held_key); }