aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJJ Liebig <jonathan.liebig@gmail.com>2026-09-14 20:02:44 +0200
committerGitHub <noreply@github.com>2026-09-14 22:02:44 +0400
commit01a9733f59ef205d113359fa778ae5521ac9cc9f (patch)
tree70596ee6e0c5e9441edb3ebd2fa8b852abe9edd7
parentad415672878a98bfac92d0e7abed0fc8db26e16a (diff)
fix(windows): avoid lossy native Win32 input mode (#4133)
refs #3932 refs #3702 refs #3910
-rw-r--r--src/client/mod.rs3
-rw-r--r--src/client/terminal_setup.rs6
-rw-r--r--src/client/tests/mod.rs25
3 files changed, 24 insertions, 10 deletions
diff --git a/src/client/mod.rs b/src/client/mod.rs
index 59ff94c1..f78150ac 100644
--- a/src/client/mod.rs
+++ b/src/client/mod.rs
@@ -86,7 +86,8 @@ use terminal_setup::{
#[cfg(test)]
use terminal_setup::{
should_enable_host_color_scheme_reports, windows_virtual_terminal_input_mode,
- write_host_color_scheme_report_mode, write_terminal_restore_postlude,
+ windows_win32_input_mode_enabled, write_host_color_scheme_report_mode,
+ write_terminal_restore_postlude,
};
#[cfg(unix)]
diff --git a/src/client/terminal_setup.rs b/src/client/terminal_setup.rs
index 7441f6db..fd09a554 100644
--- a/src/client/terminal_setup.rs
+++ b/src/client/terminal_setup.rs
@@ -404,11 +404,11 @@ fn pop_keyboard_enhancement_flags() -> io::Result<()> {
Ok(())
}
-#[cfg(windows)]
-fn windows_win32_input_mode_enabled() -> bool {
+#[cfg(any(windows, test))]
+pub(super) fn windows_win32_input_mode_enabled() -> bool {
std::env::var("HERDR_WINDOWS_INPUT_PROBE")
.map(|probe| probe.eq_ignore_ascii_case("win32"))
- .unwrap_or(true)
+ .unwrap_or_else(|_| is_ssh_session())
}
#[cfg(windows)]
diff --git a/src/client/tests/mod.rs b/src/client/tests/mod.rs
index 24a8135f..e3b164ae 100644
--- a/src/client/tests/mod.rs
+++ b/src/client/tests/mod.rs
@@ -102,6 +102,23 @@ fn windows_virtual_terminal_input_mode_sets_only_vti_bit() {
assert_eq!(windows_virtual_terminal_input_mode(0x03f0), 0x03f0);
}
+#[test]
+fn windows_win32_input_mode_defaults_to_ssh_and_honors_probe() {
+ let _guard = env_lock().lock().unwrap();
+ let _removed =
+ EnvVarsRemovedGuard::new(&["HERDR_WINDOWS_INPUT_PROBE", "SSH_CONNECTION", "SSH_TTY"]);
+
+ assert!(!windows_win32_input_mode_enabled());
+ {
+ let _ssh = EnvVarGuard::set("SSH_CONNECTION", "1 2 3 4");
+ assert!(windows_win32_input_mode_enabled());
+ let _probe = EnvVarGuard::set("HERDR_WINDOWS_INPUT_PROBE", "vt");
+ assert!(!windows_win32_input_mode_enabled());
+ }
+ let _probe = EnvVarGuard::set("HERDR_WINDOWS_INPUT_PROBE", "win32");
+ assert!(windows_win32_input_mode_enabled());
+}
+
struct EnvVarsRemovedGuard {
previous: Vec<(&'static str, Option<OsString>)>,
}
@@ -870,12 +887,8 @@ fn terminal_control_scroll_command_maps_to_attach_scroll() {
#[test]
fn forward_clipboard_uses_local_clipboard_path() {
- unsafe {
- std::env::set_var("SSH_CONNECTION", "1 2 3 4");
- }
+ let _guard = env_lock().lock().unwrap();
+ let _ssh = EnvVarGuard::set("SSH_CONNECTION", "1 2 3 4");
assert!(forward_clipboard("dGVzdA=="));
assert!(!forward_clipboard("not base64"));
- unsafe {
- std::env::remove_var("SSH_CONNECTION");
- }
}