diff options
Diffstat (limited to 'src/input')
| -rw-r--r-- | src/input/encode.rs | 7 | ||||
| -rw-r--r-- | src/input/model.rs | 17 |
2 files changed, 24 insertions, 0 deletions
diff --git a/src/input/encode.rs b/src/input/encode.rs index 774ab1a6..6dfff4ce 100644 --- a/src/input/encode.rs +++ b/src/input/encode.rs @@ -16,6 +16,13 @@ pub fn encode_key(key: KeyEvent, protocol: KeyboardProtocol) -> Vec<u8> { } pub fn encode_terminal_key(key: TerminalKey, protocol: KeyboardProtocol) -> Vec<u8> { + // A zero Unicode value on this Windows character event means the host layout is + // still composing a dead key. Kitty panes must not receive its physical fallback. + // Legacy Windows panes take the native ConPTY fallback before reaching this encoder. + if matches!(protocol, KeyboardProtocol::Kitty { .. }) && key.is_windows_shift_dead_key() { + return Vec::new(); + } + // 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(); diff --git a/src/input/model.rs b/src/input/model.rs index 304c4f20..50cd7e42 100644 --- a/src/input/model.rs +++ b/src/input/model.rs @@ -78,6 +78,7 @@ pub struct TerminalKey { pub shifted_codepoint: Option<u32>, pub generated_text: Option<String>, physical_identity_hint: bool, + windows_shift_dead_key: bool, source: KeySource, } @@ -91,6 +92,7 @@ impl TerminalKey { shifted_codepoint: None, generated_text: None, physical_identity_hint: false, + windows_shift_dead_key: false, source: KeySource::Synthesized, } } @@ -139,6 +141,7 @@ impl TerminalKey { #[cfg(any(windows, test))] pub fn with_windows_record(mut self, record: WindowsKeyRecord) -> Self { + self = self.with_windows_composition_hint(Some(record)); self.repeat_count = if self.kind == crossterm::event::KeyEventKind::Release { 1 } else { @@ -153,6 +156,16 @@ impl TerminalKey { self } + pub(crate) fn with_windows_composition_hint( + mut self, + record: Option<WindowsKeyRecord>, + ) -> Self { + self.windows_shift_dead_key = matches!(self.code, KeyCode::Char(_)) + && self.modifiers == KeyModifiers::SHIFT + && record.is_some_and(|record| record.unicode == 0); + self + } + pub(crate) fn with_physical_identity_hint(mut self, physical: bool) -> Self { self.physical_identity_hint = physical; self @@ -176,6 +189,10 @@ impl TerminalKey { None } + pub(crate) fn is_windows_shift_dead_key(&self) -> bool { + self.windows_shift_dead_key + } + pub(crate) fn identity(&self) -> KeyIdentity { match self.source { #[cfg(any(windows, test))] |
