From 858ad4e37835d45819f3348d521c29af2fa9eb8d Mon Sep 17 00:00:00 2001 From: akbash Date: Sun, 13 Sep 2026 16:14:31 +0300 Subject: fix(input): preserve super-modified pane keys (#4044) refs #3710 Co-authored-by: akbash-bot <300245827+akbash-bot@users.noreply.github.com> Co-authored-by: JJ Liebig --- src/input/encode.rs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'src/input') diff --git a/src/input/encode.rs b/src/input/encode.rs index 27e59dce..58543232 100644 --- a/src/input/encode.rs +++ b/src/input/encode.rs @@ -23,6 +23,18 @@ pub fn encode_terminal_key(key: TerminalKey, protocol: KeyboardProtocol) -> Vec< return Vec::new(); } + // Super has no legacy character encoding. Preserve the chord with CSI-u + // instead of leaking the unmodified character into the pane. + if matches!(protocol, KeyboardProtocol::Legacy) + && key.kind != crossterm::event::KeyEventKind::Release + && matches!(key.code, KeyCode::Char(_)) + && key.modifiers.contains(KeyModifiers::SUPER) + { + if let Some(bytes) = try_encode_csi_u(&key, 0) { + return bytes; + } + } + // REPORT_ALL_KEYS must retain physical press/repeat/release semantics instead of // reducing a native key to its layout-generated text. let preserve_physical_key = key.has_physical_identity() && protocol.reports_all_keys(); @@ -1195,6 +1207,19 @@ mod tests { } } + #[test] + fn legacy_super_character_preserves_csi_u_chord() { + let sequence = "\x1b[99;9u"; + let key = parse_terminal_key_sequence(sequence).expect("Super+C CSI-u key"); + + assert_eq!(key.code, KeyCode::Char('c')); + assert_eq!(key.modifiers, KeyModifiers::SUPER); + assert_eq!( + encode_terminal_key(key, KeyboardProtocol::Legacy), + sequence.as_bytes() + ); + } + #[test] fn kitty_shifted_symbol_pair_matrix_is_encoded_as_text() { let cases = [('1', '!'), ('/', '?'), ('[', '{')]; -- cgit v1.2.3