From 38d63abd5f227fe639ee0f9f0e3f1cf4d6207e28 Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Wed, 31 Jan 2024 00:11:16 +0400 Subject: [PATCH] Don't use kitty sequences outside protocol Originally kitty defined that functional keys, which are not encoded by default, like `Pause` should be encoded with `CSI u`. However the specification was clarified and now it says that terminal may ignore that part. Given that Alacritty tries to follow xterm/urxvt when it comes to bindings, CSI u bindings are not send for consistency reasons. This also brings back F13-F20 bindings used by Alacritty in 0.12.3, as well as explicitly defines `NumpadEnter` like it was before. Closes #7623. --- CHANGELOG.md | 1 + alacritty/src/config/bindings.rs | 1 + alacritty/src/input/keyboard.rs | 91 +++++++++++++++++++------------- 3 files changed, 57 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c17768b..5473813c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - No unused-key warnings will be emitted for OS-specific config keys - Use built-in font for sextant symbols from `U+1FB00` to `U+1FB3B` +- Kitty encoding is not used anymore for uncommon keys unless the protocol enabled ## 0.13.1 diff --git a/alacritty/src/config/bindings.rs b/alacritty/src/config/bindings.rs index 794cb04d..9940cb5b 100644 --- a/alacritty/src/config/bindings.rs +++ b/alacritty/src/config/bindings.rs @@ -453,6 +453,7 @@ pub fn default_key_bindings() -> Vec { Backspace, ~BindingMode::VI, ~BindingMode::SEARCH, ~BindingMode::REPORT_ALL_KEYS_AS_ESC; Action::Esc("\x7f".into()); Backspace, ModifiersState::ALT, ~BindingMode::VI, ~BindingMode::SEARCH, ~BindingMode::REPORT_ALL_KEYS_AS_ESC; Action::Esc("\x1b\x7f".into()); Backspace, ModifiersState::SHIFT, ~BindingMode::VI, ~BindingMode::SEARCH, ~BindingMode::REPORT_ALL_KEYS_AS_ESC; Action::Esc("\x7f".into()); + Enter => KeyLocation::Numpad, ~BindingMode::VI, ~BindingMode::SEARCH, ~BindingMode::REPORT_ALL_KEYS_AS_ESC, ~BindingMode::DISAMBIGUATE_ESC_CODES; Action::Esc("\n".into()); // Vi mode. Space, ModifiersState::SHIFT | ModifiersState::CONTROL, ~BindingMode::SEARCH; Action::ToggleViMode; Space, ModifiersState::SHIFT | ModifiersState::CONTROL, +BindingMode::VI, ~BindingMode::SEARCH; Action::ScrollToBottom; diff --git a/alacritty/src/input/keyboard.rs b/alacritty/src/input/keyboard.rs index 1df1b13b..b7635bd9 100644 --- a/alacritty/src/input/keyboard.rs +++ b/alacritty/src/input/keyboard.rs @@ -284,7 +284,8 @@ fn build_sequence(key: KeyEvent, mods: ModifiersState, mode: TermMode) -> Vec Option { + /// Try building from [`NamedKey`] using the kitty keyboard protocol encoding + /// for functional keys. + fn try_build_named_kitty(&self, key: &KeyEvent) -> Option { let named = match key.logical_key { - Key::Named(named) => named, + Key::Named(named) if self.kitty_seq => named, _ => return None, }; - // The default parameter is 1, so we can omit it. - let one_based = if self.modifiers.is_empty() && !self.kitty_event_type { "" } else { "1" }; let (base, terminator) = match named { - NamedKey::PageUp => ("5", SequenceTerminator::Normal('~')), - NamedKey::PageDown => ("6", SequenceTerminator::Normal('~')), - NamedKey::Insert => ("2", SequenceTerminator::Normal('~')), - NamedKey::Delete => ("3", SequenceTerminator::Normal('~')), - NamedKey::Home => (one_based, SequenceTerminator::Normal('H')), - NamedKey::End => (one_based, SequenceTerminator::Normal('F')), - NamedKey::ArrowLeft => (one_based, SequenceTerminator::Normal('D')), - NamedKey::ArrowRight => (one_based, SequenceTerminator::Normal('C')), - NamedKey::ArrowUp => (one_based, SequenceTerminator::Normal('A')), - NamedKey::ArrowDown => (one_based, SequenceTerminator::Normal('B')), - NamedKey::F1 => (one_based, SequenceTerminator::Normal('P')), - NamedKey::F2 => (one_based, SequenceTerminator::Normal('Q')), - NamedKey::F3 => { - // F3 in kitty protocol diverges from alacritty's terminfo. - if self.kitty_seq { - ("13", SequenceTerminator::Normal('~')) - } else { - (one_based, SequenceTerminator::Normal('R')) - } - }, - NamedKey::F4 => (one_based, SequenceTerminator::Normal('S')), - NamedKey::F5 => ("15", SequenceTerminator::Normal('~')), - NamedKey::F6 => ("17", SequenceTerminator::Normal('~')), - NamedKey::F7 => ("18", SequenceTerminator::Normal('~')), - NamedKey::F8 => ("19", SequenceTerminator::Normal('~')), - NamedKey::F9 => ("20", SequenceTerminator::Normal('~')), - NamedKey::F10 => ("21", SequenceTerminator::Normal('~')), - NamedKey::F11 => ("23", SequenceTerminator::Normal('~')), - NamedKey::F12 => ("24", SequenceTerminator::Normal('~')), + // F3 in kitty protocol diverges from alacritty's terminfo. + NamedKey::F3 => ("13", SequenceTerminator::Normal('~')), NamedKey::F13 => ("57376", SequenceTerminator::Kitty), NamedKey::F14 => ("57377", SequenceTerminator::Kitty), NamedKey::F15 => ("57378", SequenceTerminator::Kitty), @@ -514,6 +487,52 @@ impl SequenceBuilder { Some(SequenceBase::new(base.into(), terminator)) } + /// Try building from [`NamedKey`]. + fn try_build_named_normal(&self, key: &KeyEvent) -> Option { + let named = match key.logical_key { + Key::Named(named) => named, + _ => return None, + }; + + // The default parameter is 1, so we can omit it. + let one_based = if self.modifiers.is_empty() && !self.kitty_event_type { "" } else { "1" }; + let (base, terminator) = match named { + NamedKey::PageUp => ("5", SequenceTerminator::Normal('~')), + NamedKey::PageDown => ("6", SequenceTerminator::Normal('~')), + NamedKey::Insert => ("2", SequenceTerminator::Normal('~')), + NamedKey::Delete => ("3", SequenceTerminator::Normal('~')), + NamedKey::Home => (one_based, SequenceTerminator::Normal('H')), + NamedKey::End => (one_based, SequenceTerminator::Normal('F')), + NamedKey::ArrowLeft => (one_based, SequenceTerminator::Normal('D')), + NamedKey::ArrowRight => (one_based, SequenceTerminator::Normal('C')), + NamedKey::ArrowUp => (one_based, SequenceTerminator::Normal('A')), + NamedKey::ArrowDown => (one_based, SequenceTerminator::Normal('B')), + NamedKey::F1 => (one_based, SequenceTerminator::Normal('P')), + NamedKey::F2 => (one_based, SequenceTerminator::Normal('Q')), + NamedKey::F3 => (one_based, SequenceTerminator::Normal('R')), + NamedKey::F4 => (one_based, SequenceTerminator::Normal('S')), + NamedKey::F5 => ("15", SequenceTerminator::Normal('~')), + NamedKey::F6 => ("17", SequenceTerminator::Normal('~')), + NamedKey::F7 => ("18", SequenceTerminator::Normal('~')), + NamedKey::F8 => ("19", SequenceTerminator::Normal('~')), + NamedKey::F9 => ("20", SequenceTerminator::Normal('~')), + NamedKey::F10 => ("21", SequenceTerminator::Normal('~')), + NamedKey::F11 => ("23", SequenceTerminator::Normal('~')), + NamedKey::F12 => ("24", SequenceTerminator::Normal('~')), + NamedKey::F13 => ("25", SequenceTerminator::Normal('~')), + NamedKey::F14 => ("26", SequenceTerminator::Normal('~')), + NamedKey::F15 => ("28", SequenceTerminator::Normal('~')), + NamedKey::F16 => ("29", SequenceTerminator::Normal('~')), + NamedKey::F17 => ("31", SequenceTerminator::Normal('~')), + NamedKey::F18 => ("32", SequenceTerminator::Normal('~')), + NamedKey::F19 => ("33", SequenceTerminator::Normal('~')), + NamedKey::F20 => ("34", SequenceTerminator::Normal('~')), + _ => return None, + }; + + Some(SequenceBase::new(base.into(), terminator)) + } + /// Try building escape from control characters (e.g. Enter) and modifiers. fn try_build_control_char_or_mod( &self, @@ -596,7 +615,7 @@ impl SequenceBase { } } -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum SequenceTerminator { /// The normal key esc sequence terminator defined by xterm/dec. Normal(char),