diff options
| author | akbash <akbash@herdr.dev> | 2026-09-03 00:19:49 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-09-02 23:19:49 +0200 |
| commit | 2ae8b91ca5919c26df7ce779b0e9a5dd98b769ae (patch) | |
| tree | ad5374d3cf754346be29e525f7abb6ca3a04367b /src/protocol | |
| parent | 45484aab84430ac2b18c7bbf44aba15f2b039677 (diff) | |
fix(windows): preserve dead-key composition in kitty panes (#3548)
refs #3546
Co-authored-by: akbash-bot <300245827+akbash-bot@users.noreply.github.com>
Co-authored-by: JJ Liebig <jonathan.liebig@gmail.com>
Diffstat (limited to 'src/protocol')
| -rw-r--r-- | src/protocol/wire.rs | 52 |
1 files changed, 48 insertions, 4 deletions
diff --git a/src/protocol/wire.rs b/src/protocol/wire.rs index cbca829a..96881b14 100644 --- a/src/protocol/wire.rs +++ b/src/protocol/wire.rs @@ -325,6 +325,13 @@ impl ClientPaneInputEvent { } pub(crate) fn to_raw_input_event(&self) -> crate::raw_input::RawInputEvent { + self.to_raw_input_event_with_windows_source(cfg!(any(windows, test))) + } + + fn to_raw_input_event_with_windows_source( + &self, + attach_windows_source: bool, + ) -> crate::raw_input::RawInputEvent { match self { Self::Key { code, @@ -344,16 +351,19 @@ impl ClientPaneInputEvent { .with_kind(kind.to_crossterm()) .with_repeat_count(*repeat_count) .with_generated_text(generated_text.clone()) - .with_physical_identity_hint(*tracks_release && generated_text.is_some()); + .with_physical_identity_hint(*tracks_release && generated_text.is_some()) + .with_windows_composition_hint(*windows_record); if let Some(shifted_codepoint) = shifted_codepoint { key = key.with_shifted_codepoint(*shifted_codepoint); } #[cfg(any(windows, test))] - if let Some(record) = windows_record { - key = key.with_windows_record(*record); + if attach_windows_source { + if let Some(record) = windows_record { + key = key.with_windows_record(*record); + } } #[cfg(not(any(windows, test)))] - let _ = windows_record; + let _ = (attach_windows_source, windows_record); crate::raw_input::RawInputEvent::Key(key) } Self::TextCommit(text) => { @@ -2032,6 +2042,40 @@ mod tests { } #[test] + fn client_shell_pane_input_reconstructs_windows_dead_key_without_native_source() { + let event = ClientPaneInputEvent::Key { + code: ClientKeyCode::Char('6'), + modifiers: crossterm::event::KeyModifiers::SHIFT.bits(), + kind: ClientKeyKind::Press, + repeat_count: 1, + shifted_codepoint: None, + generated_text: None, + tracks_release: true, + physical_key_id: Some(0x07), + windows_record: Some(crate::input::WindowsKeyRecord { + key_down: true, + repeat_count: 1, + virtual_key_code: 0x36, + virtual_scan_code: 0x07, + unicode: 0, + control_key_state: 0x0030, + }), + }; + let crate::raw_input::RawInputEvent::Key(key) = + event.to_raw_input_event_with_windows_source(false) + else { + panic!("pane dead key should remain a key"); + }; + assert!(key.is_windows_shift_dead_key()); + assert_eq!(key.windows_record(), None); + assert!(crate::input::encode_terminal_key( + key, + crate::input::KeyboardProtocol::Kitty { flags: 1 }, + ) + .is_empty()); + } + + #[test] fn client_shell_key_roundtrip_preserves_physical_generated_text_encoding() { let key = crate::input::TerminalKey::new( crossterm::event::KeyCode::Char('/'), |
