diff options
Diffstat (limited to 'src/client/input.rs')
| -rw-r--r-- | src/client/input.rs | 60 |
1 files changed, 56 insertions, 4 deletions
diff --git a/src/client/input.rs b/src/client/input.rs index 7099311b..bc7faf35 100644 --- a/src/client/input.rs +++ b/src/client/input.rs @@ -39,15 +39,21 @@ pub fn stdin_reader_loop( event_tx: mpsc::Sender<ClientLoopEvent>, should_quit: &Arc<AtomicBool>, host_color_query_sent: bool, + host_mouse_capture_active: Arc<AtomicBool>, ) { #[cfg(windows)] { - let _ = host_color_query_sent; + let _ = (host_color_query_sent, host_mouse_capture_active); windows_stdin_reader_loop(event_tx, should_quit); } #[cfg(unix)] - unix_stdin_reader_loop(event_tx, should_quit, host_color_query_sent); + unix_stdin_reader_loop( + event_tx, + should_quit, + host_color_query_sent, + host_mouse_capture_active, + ); } #[cfg(unix)] @@ -55,6 +61,7 @@ fn unix_stdin_reader_loop( event_tx: mpsc::Sender<ClientLoopEvent>, should_quit: &Arc<AtomicBool>, host_color_query_sent: bool, + host_mouse_capture_active: Arc<AtomicBool>, ) { let stdin = io::stdin(); let mut reader = stdin.lock(); @@ -78,7 +85,11 @@ fn unix_stdin_reader_loop( } } - if stdin_read_ready(&reader, 10) == Some(false) { + let timeout_ms = idle_flush_timeout_ms( + &framer, + host_mouse_capture_active.load(Ordering::Acquire), + ); + if stdin_read_ready(&reader, timeout_ms) == Some(false) { let had_pending = framer.has_pending_input(); let chunks = framer.flush_timeout(); let held_escape = had_pending && chunks.is_empty(); @@ -90,7 +101,12 @@ fn unix_stdin_reader_loop( return; } } - if held_escape && stdin_read_ready(&reader, 10) == Some(false) { + if held_escape + && stdin_read_ready( + &reader, + crate::raw_input::RAW_INPUT_IDLE_FLUSH_TIMEOUT_MS, + ) == Some(false) + { for data in framer.flush_timeout() { if event_tx .blocking_send(ClientLoopEvent::StdinInput(data)) @@ -112,6 +128,18 @@ fn unix_stdin_reader_loop( } } +#[cfg(unix)] +fn idle_flush_timeout_ms( + framer: &crate::raw_input::RawInputByteFramer, + host_mouse_capture_active: bool, +) -> i32 { + if host_mouse_capture_active && framer.has_pending_lone_escape() { + crate::raw_input::MOUSE_ACTIVE_LONE_ESCAPE_FLUSH_TIMEOUT_MS + } else { + crate::raw_input::RAW_INPUT_IDLE_FLUSH_TIMEOUT_MS + } +} + #[cfg(windows)] fn windows_stdin_reader_loop( event_tx: mpsc::Sender<ClientLoopEvent>, @@ -366,6 +394,30 @@ mod tests { _ => panic!("expected StdinInput event"), } } + + #[test] + fn raw_input_idle_flush_timeout_keeps_escape_responsive() { + let timeout_ms = std::hint::black_box(crate::raw_input::RAW_INPUT_IDLE_FLUSH_TIMEOUT_MS); + assert!(timeout_ms <= 20); + } + + #[test] + fn mouse_active_lone_escape_gets_longer_reassembly_window() { + let mut framer = crate::raw_input::RawInputByteFramer::default(); + assert!(framer.push(b"\x1b").is_empty()); + + assert_eq!( + idle_flush_timeout_ms(&framer, false), + crate::raw_input::RAW_INPUT_IDLE_FLUSH_TIMEOUT_MS + ); + assert_eq!( + idle_flush_timeout_ms(&framer, true), + crate::raw_input::MOUSE_ACTIVE_LONE_ESCAPE_FLUSH_TIMEOUT_MS + ); + let mouse_timeout_ms = + std::hint::black_box(crate::raw_input::MOUSE_ACTIVE_LONE_ESCAPE_FLUSH_TIMEOUT_MS); + assert!(mouse_timeout_ms > 100); + } } #[cfg(test)] |
