aboutsummaryrefslogtreecommitdiff
path: root/src/client
diff options
context:
space:
mode:
authorJJ Liebig <jonathan.liebig@gmail.com>2026-09-14 03:06:01 +0400
committerGitHub <noreply@github.com>2026-09-14 02:06:01 +0300
commitaa961df943b874730b23f78baf94af7332f7acfa (patch)
tree34ee5b2e8b86b286e1aa9916719000b7a55dce09 /src/client
parent3b478e69dcbe8e416ddd46f0e24156392d4e71da (diff)
fix(windows): restore mouse reporting when reattaching (#4080)
Diffstat (limited to 'src/client')
-rw-r--r--src/client/terminal_setup.rs57
1 files changed, 53 insertions, 4 deletions
diff --git a/src/client/terminal_setup.rs b/src/client/terminal_setup.rs
index 9c035346..7441f6db 100644
--- a/src/client/terminal_setup.rs
+++ b/src/client/terminal_setup.rs
@@ -265,16 +265,46 @@ pub(super) fn effective_sgr_pixel_mouse(
enabled && requested && exact_geometry
}
+#[cfg(any(windows, test))]
+fn set_windows_native_mouse_capture<W: io::Write>(
+ writer: &mut W,
+ enabled: bool,
+ sgr_pixels: bool,
+ set_console_capture: impl FnOnce(bool) -> io::Result<()>,
+) -> io::Result<()> {
+ crate::terminal_modes::clear_host_mouse_reporting(writer)?;
+ set_console_capture(enabled)?;
+ if enabled {
+ crate::terminal_modes::set_windows_mouse_reporting(writer, true, sgr_pixels)?;
+ }
+ Ok(())
+}
+
pub(super) fn set_mouse_capture(enabled: bool, sgr_pixels: bool) -> io::Result<()> {
- crate::terminal_modes::clear_host_mouse_reporting(&mut io::stdout())?;
#[cfg(windows)]
if is_ssh_session() && windows_vti_input_backend_enabled() {
- return crate::terminal_modes::set_windows_ssh_mouse_reporting(
+ crate::terminal_modes::clear_host_mouse_reporting(&mut io::stdout())?;
+ return crate::terminal_modes::set_windows_mouse_reporting(
&mut io::stdout(),
enabled,
sgr_pixels,
);
}
+ #[cfg(windows)]
+ return set_windows_native_mouse_capture(&mut io::stdout(), enabled, sgr_pixels, |enabled| {
+ if enabled {
+ execute!(io::stdout(), EnableMouseCapture)
+ } else {
+ match execute!(io::stdout(), DisableMouseCapture) {
+ Ok(()) => Ok(()),
+ Err(err) if err.to_string() == "Initial console modes not set" => Ok(()),
+ Err(err) => Err(err),
+ }
+ }
+ });
+ #[cfg(not(windows))]
+ crate::terminal_modes::clear_host_mouse_reporting(&mut io::stdout())?;
+ #[cfg(not(windows))]
if enabled {
execute!(io::stdout(), EnableMouseCapture)?;
if sgr_pixels {
@@ -285,8 +315,6 @@ pub(super) fn set_mouse_capture(enabled: bool, sgr_pixels: bool) -> io::Result<(
} else {
match execute!(io::stdout(), DisableMouseCapture) {
Ok(()) => Ok(()),
- #[cfg(windows)]
- Err(err) if err.to_string() == "Initial console modes not set" => Ok(()),
Err(err) => Err(err),
}
}
@@ -443,3 +471,24 @@ impl Drop for TerminalGuard {
}
}
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn windows_native_mouse_capture_restores_reporting_after_reset() {
+ let mut output = Vec::new();
+
+ set_windows_native_mouse_capture(&mut output, true, false, |enabled| {
+ assert!(enabled);
+ Ok(())
+ })
+ .unwrap();
+
+ assert_eq!(
+ output,
+ b"\x1b[?1006l\x1b[?1016l\x1b[?1015l\x1b[?1005l\x1b[?1003l\x1b[?1002l\x1b[?1000l\x1b[?9l\x1b[?1000h\x1b[?1002h\x1b[?1003h\x1b[?1006h\x1b[?1016l"
+ );
+ }
+}