summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKirill Chibisov <contact@kchibisov.com>2023-12-25 18:52:35 +0400
committerGitHub <noreply@github.com>2023-12-25 18:52:35 +0400
commit187f9ca3e5c436a59e9c0249c5aa9de77058c05d (patch)
treeef2caf2a45a84dfcc95285c9e3878c8c9a6e730f
parentcaf8c7fc7feca662528e46bd5455054ad9daeb02 (diff)
downloadalacritty-187f9ca3e5c436a59e9c0249c5aa9de77058c05d.tar.gz
alacritty-187f9ca3e5c436a59e9c0249c5aa9de77058c05d.zip
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
-rw-r--r--alacritty/src/input/keyboard.rs23
1 files 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<T: EventListener, A: ActionContext<T>> Processor<T, A> {
/// 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<u8> {
- 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<u8
let sequence_base = context
.try_build_numpad(&key)
.or_else(|| context.try_build_named(&key))
- .or_else(|| context.try_build_control_char_or_mod(&key))
+ .or_else(|| context.try_build_control_char_or_mod(&key, &mut modifiers))
.or_else(|| context.try_build_textual(&key));
let (payload, terminator) = match sequence_base {
@@ -493,7 +493,11 @@ impl SequenceBuilder {
}
/// Try building escape from control characters (e.g. Enter) and modifiers.
- fn try_build_control_char_or_mod(&self, key: &KeyEvent) -> Option<SequenceBase> {
+ fn try_build_control_char_or_mod(
+ &self,
+ key: &KeyEvent,
+ mods: &mut SequenceModifiers,
+ ) -> Option<SequenceBase> {
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 {