From 187f9ca3e5c436a59e9c0249c5aa9de77058c05d Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Mon, 25 Dec 2023 18:52:35 +0400 Subject: Apply modifiers before presses in kitty protocol While this doesn't handle releases with multiple identical modifiers pressed, the release can't work reliable anyway, since one modifier could be pressed before focusing the window, thus tracking modifiers based on the keysym values won't work as it was suggested by kitty author. Links: https://github.com/kovidgoyal/kitty/issues/6913 --- alacritty/src/input/keyboard.rs | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/alacritty/src/input/keyboard.rs b/alacritty/src/input/keyboard.rs index 160600a1..423f8bae 100644 --- a/alacritty/src/input/keyboard.rs +++ b/alacritty/src/input/keyboard.rs @@ -244,7 +244,7 @@ impl> Processor { /// The key sequences for `APP_KEYPAD` and alike are handled inside the bindings. #[inline(never)] fn build_sequence(key: KeyEvent, mods: ModifiersState, mode: TermMode) -> Vec { - let modifiers = mods.into(); + let mut modifiers = mods.into(); let kitty_seq = mode.intersects( TermMode::REPORT_ALL_KEYS_AS_ESC @@ -263,7 +263,7 @@ fn build_sequence(key: KeyEvent, mods: ModifiersState, mode: TermMode) -> Vec Option { + fn try_build_control_char_or_mod( + &self, + key: &KeyEvent, + mods: &mut SequenceModifiers, + ) -> Option { if !self.kitty_encode_all && !self.kitty_seq { return None; } @@ -536,6 +540,19 @@ impl SequenceBuilder { _ => base, }; + // NOTE: Kitty's protocol mandates that the modifier state is applied before + // key press, however winit sends them after the key press, so for modifiers + // itself apply the state based on keysyms and not the _actual_ modifiers + // state, which is how kitty is doing so and what is suggested in such case. + let press = key.state.is_pressed(); + match named { + NamedKey::Shift => mods.set(SequenceModifiers::SHIFT, press), + NamedKey::Control => mods.set(SequenceModifiers::CONTROL, press), + NamedKey::Alt => mods.set(SequenceModifiers::ALT, press), + NamedKey::Super => mods.set(SequenceModifiers::SUPER, press), + _ => (), + } + if base.is_empty() { None } else { -- cgit v1.2.3-54-g00ecf