aboutsummaryrefslogtreecommitdiff
path: root/src/client
diff options
context:
space:
mode:
authorJJ Liebig <jonathan.liebig@gmail.com>2026-09-17 00:07:58 +0200
committerGitHub <noreply@github.com>2026-09-17 00:07:58 +0200
commit20c15dd7c8e516753a09e74d400b0637f5fd5682 (patch)
treeed56565d7851b986071ec453eee757c94478e724 /src/client
parent5f3763dda88e0fefbce14afab7cc2c7232a5e2a8 (diff)
fix(windows): preserve VT input during mouse refresh (#4257)
refs #4251
Diffstat (limited to 'src/client')
-rw-r--r--src/client/input.rs2
-rw-r--r--src/client/input/windows_vti.rs10
-rw-r--r--src/client/terminal_setup.rs27
3 files changed, 22 insertions, 17 deletions
diff --git a/src/client/input.rs b/src/client/input.rs
index c86f0878..e77d51fa 100644
--- a/src/client/input.rs
+++ b/src/client/input.rs
@@ -330,7 +330,7 @@ fn windows_stdin_reader_loop(
windows_crossterm_reader_loop(event_tx, should_quit);
} else {
match windows_vti::console_input_handle() {
- Ok(handle) if windows_vti::virtual_terminal_input_enabled(handle) => {
+ Ok(handle) if crate::platform::windows_virtual_terminal_input_active() => {
windows_vti::raw_console_reader_loop(handle, event_tx, should_quit);
}
_ => windows_crossterm_reader_loop(event_tx, should_quit),
diff --git a/src/client/input/windows_vti.rs b/src/client/input/windows_vti.rs
index 95e01d4b..e9cfa4e6 100644
--- a/src/client/input/windows_vti.rs
+++ b/src/client/input/windows_vti.rs
@@ -97,16 +97,6 @@ pub(super) fn console_input_handle() -> std::io::Result<windows_sys::Win32::Foun
}
#[cfg(windows)]
-pub(super) fn virtual_terminal_input_enabled(
- handle: windows_sys::Win32::Foundation::HANDLE,
-) -> bool {
- use windows_sys::Win32::System::Console::{GetConsoleMode, ENABLE_VIRTUAL_TERMINAL_INPUT};
-
- let mut mode = 0;
- (unsafe { GetConsoleMode(handle, &mut mode) } != 0) && mode & ENABLE_VIRTUAL_TERMINAL_INPUT != 0
-}
-
-#[cfg(windows)]
enum WindowsInputItems {
Items(Vec<PlatformInputItem>),
Idle,
diff --git a/src/client/terminal_setup.rs b/src/client/terminal_setup.rs
index 44f6fbaa..e42c5ec8 100644
--- a/src/client/terminal_setup.rs
+++ b/src/client/terminal_setup.rs
@@ -280,9 +280,15 @@ fn set_windows_native_mouse_capture<W: io::Write>(
Ok(())
}
+#[cfg(windows)]
+fn windows_uses_vt_mouse_reporting() -> bool {
+ windows_vti_input_backend_enabled()
+ && (is_ssh_session() || crate::platform::windows_virtual_terminal_input_active())
+}
+
pub(super) fn set_mouse_capture(enabled: bool, sgr_pixels: bool) -> io::Result<()> {
#[cfg(windows)]
- if is_ssh_session() && windows_vti_input_backend_enabled() {
+ if windows_uses_vt_mouse_reporting() {
crate::terminal_modes::clear_host_mouse_reporting(&mut io::stdout())?;
return crate::terminal_modes::set_windows_mouse_reporting(
&mut io::stdout(),
@@ -295,11 +301,7 @@ pub(super) fn set_mouse_capture(enabled: bool, sgr_pixels: bool) -> io::Result<(
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),
- }
+ disable_windows_native_mouse_capture()
}
});
#[cfg(not(windows))]
@@ -320,6 +322,15 @@ pub(super) fn set_mouse_capture(enabled: bool, sgr_pixels: bool) -> io::Result<(
}
}
+#[cfg(windows)]
+fn disable_windows_native_mouse_capture() -> io::Result<()> {
+ match execute!(io::stdout(), DisableMouseCapture) {
+ Ok(()) => Ok(()),
+ Err(err) if err.to_string() == "Initial console modes not set" => Ok(()),
+ Err(err) => Err(err),
+ }
+}
+
fn restore_terminal_state_once(
restore_claimed: &AtomicBool,
reset_keyboard_enhancements: bool,
@@ -368,6 +379,10 @@ fn restore_terminal_state(
if let Some(mode) = restore_windows_input_mode {
restore_windows_input_mode_value(mode);
}
+ #[cfg(windows)]
+ if !is_ssh_session() {
+ let _ = disable_windows_native_mouse_capture();
+ }
let restore_result = ratatui::try_restore();
let postlude_result =