diff --git a/src/bin/dosh-client.rs b/src/bin/dosh-client.rs index 66c0c07..ac2a60f 100644 --- a/src/bin/dosh-client.rs +++ b/src/bin/dosh-client.rs @@ -2904,8 +2904,11 @@ async fn run_terminal( if let Some(deadline) = startup_input_hold_until { if !predictor.alternate_screen && Instant::now() < deadline - && (hold_all_startup_input - || should_hold_post_submit_input(&bytes)) + && should_hold_during_startup_gate( + hold_all_startup_input, + !pending_user_input.is_empty(), + &bytes, + ) { queue_pending_user_input( &mut pending_user_input, @@ -3843,6 +3846,10 @@ fn should_hold_post_submit_input(bytes: &[u8]) -> bool { matches!(bytes.first(), Some(0x1b | 0x9b)) } +fn should_hold_during_startup_gate(hold_all: bool, already_queued: bool, bytes: &[u8]) -> bool { + hold_all || already_queued || should_hold_post_submit_input(bytes) +} + async fn flush_pending_user_input( socket: &UdpSocket, addr: SocketAddr, @@ -5313,9 +5320,9 @@ mod tests { queue_pending_user_input, raw_contains_host_table, recv_response_until, render_status_clear, render_status_overlay, requested_env, resolved_startup_command, rewrite_forward_command, selected_predict_mode, selected_udp_host, server_version_mismatch, - should_hold_post_submit_input, split_after_command_submit, ssh_destination_host, - ssh_username, ssh_with_user, startup_command, status_ssh_target, toml_bare_key_or_quoted, - update_check_requested, valid_forward_host, + should_hold_during_startup_gate, should_hold_post_submit_input, split_after_command_submit, + ssh_destination_host, ssh_username, ssh_with_user, startup_command, status_ssh_target, + toml_bare_key_or_quoted, update_check_requested, valid_forward_host, }; use dosh::config::{ClientConfig, CommandExtension, HostConfig}; use dosh::native::EnvVar; @@ -5988,6 +5995,14 @@ mod tests { assert!(!should_hold_post_submit_input(b"")); } + #[test] + fn startup_gate_keeps_later_input_behind_queued_control_input() { + assert!(should_hold_during_startup_gate(false, false, b"\x1b[B")); + assert!(should_hold_during_startup_gate(false, true, b"x")); + assert!(should_hold_during_startup_gate(true, false, b"x")); + assert!(!should_hold_during_startup_gate(false, false, b"x")); + } + #[test] fn update_check_accepts_only_check_flag() { assert!(!update_check_requested(&[]).unwrap());