aboutsummaryrefslogtreecommitdiffstats
path: root/zellij-client/src/stdin_handler.rs
diff options
context:
space:
mode:
authordivens <divens@users.noreply.github.com>2026-07-07 14:41:44 +0200
committerGitHub <noreply@github.com>2026-07-07 14:41:44 +0200
commit39a75c54934617ef9d38fe02bfab777291e39d7e (patch)
treefa784ed52e78a6c29db27d2318a5baf9b097d2ad /zellij-client/src/stdin_handler.rs
parentUI tweaks (#5337) (diff)
downloadsl0ppij-39a75c54934617ef9d38fe02bfab777291e39d7e.tar.gz
sl0ppij-39a75c54934617ef9d38fe02bfab777291e39d7e.tar.xz
sl0ppij-39a75c54934617ef9d38fe02bfab777291e39d7e.zip
fix(windows): route Windows Terminal through the VT input path (#5335)
Windows Terminal does not set TERM by default, so zellij on WT was using the native-console crossterm path that reads INPUT_RECORDs. That path can't observe bracketed-paste sequences (`\e[200~/\e[201~`), which is one of the reasons multi-line paste has never worked correctly on Windows (issue #4885). WT sets `WT_SESSION` per-process. Use that as a second trigger for the VT input path so default WT installs get raw VT byte input (and with it, termwiz's bracketed-paste detection, the SGR mouse format, correct emoji delivery, etc.) without requiring the user to set TERM. Introduce `use_vt_path()` in `os_input_output_windows.rs` as the single source of truth for the gate. Previously the stdin handler had one TERM check and `enable_mouse_support` / `disable_mouse_support` each had their own — so adding `WT_SESSION` to just the stdin gate caused mouse setup to take the native-console branch, which calls `crossterm::event::EnableMouseCapture` and clobbers the `ENABLE_VIRTUAL_TERMINAL_INPUT` flag the stdin path had just set. That broke all input from WT until the helper aligned every site.
Diffstat (limited to 'zellij-client/src/stdin_handler.rs')
-rw-r--r--zellij-client/src/stdin_handler.rs18
1 files changed, 6 insertions, 12 deletions
diff --git a/zellij-client/src/stdin_handler.rs b/zellij-client/src/stdin_handler.rs
index 26418188..535d9b67 100644
--- a/zellij-client/src/stdin_handler.rs
+++ b/zellij-client/src/stdin_handler.rs
@@ -1,5 +1,7 @@
use crate::keyboard_parser::{KittyKeyboardParser, KittyParseOutcome};
use crate::os_input_output::ClientOsApi;
+#[cfg(windows)]
+use crate::os_input_output_windows::use_vt_path;
use crate::stdin_ansi_parser::{PendingPartial, StdinAnsiParser};
#[cfg(windows)]
use crate::stdin_handler_windows::enable_vt_input;
@@ -21,19 +23,11 @@ pub(crate) fn stdin_loop(
explicitly_disable_kitty_keyboard_protocol: bool,
resize_sender: Option<std::sync::mpsc::Sender<()>>,
) {
- // On Windows, choose between two input strategies early — we need this
- // decision before the startup ANSI query below.
- //
- // 1. Native console (no TERM env var): Use crossterm's event::read() which
- // reads INPUT_RECORDs via ReadConsoleInput. Works in cmd.exe, PowerShell,
- // and Windows Terminal where ALT is reported as a modifier flag.
- //
- // 2. Terminal emulator (TERM is set, e.g. Alacritty): Enable
- // ENABLE_VIRTUAL_TERMINAL_INPUT so ReadFile on stdin returns raw VT bytes,
- // bypassing conpty's lossy VT→INPUT_RECORD translation. Then use the
- // termwiz byte parser (same as Unix) which understands ESC-prefixed ALT.
+ // On Windows we choose between the VT byte path (termwiz/kitty parsing)
+ // and the native-console path (crossterm INPUT_RECORDs) early, before the
+ // startup ANSI query below. See `use_vt_path()` for the trigger conditions.
#[cfg(windows)]
- let use_vt_reader = std::env::var("TERM").is_ok() && enable_vt_input();
+ let use_vt_reader = use_vt_path() && enable_vt_input();
// Send the startup host query string so the host terminal replies
// with its live pixel dimensions, fg/bg, sync-output support, and