diff options
author | Kirill Chibisov <contact@kchibisov.com> | 2023-12-20 10:37:21 +0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-20 10:37:21 +0400 |
commit | 3d7d81c8482eb9465763020a397290765b70b541 (patch) | |
tree | 687a7bf867b543670eb463ddcba3ea1913bfc6ad | |
parent | a10fb8adc0857633be428d673ab8d36d2a90193a (diff) | |
download | alacritty-3d7d81c8482eb9465763020a397290765b70b541.tar.gz alacritty-3d7d81c8482eb9465763020a397290765b70b541.zip |
Account for option_as_alt when doing kitty protocol
By default `Alt` is not a real `Alt` on macOS, so we shouldn't treat
it as a modifier.
Fixes #7443.
-rw-r--r-- | alacritty/src/input/keyboard.rs | 54 |
1 files changed, 36 insertions, 18 deletions
diff --git a/alacritty/src/input/keyboard.rs b/alacritty/src/input/keyboard.rs index 9db67f42..160600a1 100644 --- a/alacritty/src/input/keyboard.rs +++ b/alacritty/src/input/keyboard.rs @@ -78,13 +78,16 @@ impl<T: EventListener, A: ActionContext<T>> Processor<T, A> { return; } + // Mask `Alt` modifier from input when we won't send esc. + let mods = if self.alt_send_esc(&key, text) { mods } else { mods & !ModifiersState::ALT }; + let build_key_sequence = Self::should_build_sequence(&key, text, mode, mods); let bytes = if build_key_sequence { build_sequence(key, mods, mode) } else { let mut bytes = Vec::with_capacity(text.len() + 1); - if self.alt_send_esc() && text.len() == 1 { + if mods.alt_key() { bytes.push(b'\x1b'); } @@ -99,6 +102,34 @@ impl<T: EventListener, A: ActionContext<T>> Processor<T, A> { } } + fn alt_send_esc(&mut self, key: &KeyEvent, text: &str) -> bool { + #[cfg(not(target_os = "macos"))] + let alt_send_esc = self.ctx.modifiers().state().alt_key(); + + #[cfg(target_os = "macos")] + let alt_send_esc = { + let option_as_alt = self.ctx.config().window.option_as_alt(); + self.ctx.modifiers().state().alt_key() + && (option_as_alt == OptionAsAlt::Both + || (option_as_alt == OptionAsAlt::OnlyLeft + && self.ctx.modifiers().lalt_state() == ModifiersKeyState::Pressed) + || (option_as_alt == OptionAsAlt::OnlyRight + && self.ctx.modifiers().ralt_state() == ModifiersKeyState::Pressed)) + }; + + match key.logical_key { + Key::Named(named) => { + if named.to_text().is_some() { + alt_send_esc + } else { + // Treat `Alt` as modifier for named keys without text, like ArrowUp. + self.ctx.modifiers().state().alt_key() + } + }, + _ => text.len() == 1 && alt_send_esc, + } + } + /// Check whether we should try to build escape sequence for the [`KeyEvent`]. fn should_build_sequence( key: &KeyEvent, @@ -123,23 +154,6 @@ impl<T: EventListener, A: ActionContext<T>> Processor<T, A> { } } - /// Whether we should send `ESC` due to `Alt` being pressed. - #[cfg(not(target_os = "macos"))] - fn alt_send_esc(&mut self) -> bool { - self.ctx.modifiers().state().alt_key() - } - - #[cfg(target_os = "macos")] - fn alt_send_esc(&mut self) -> bool { - let option_as_alt = self.ctx.config().window.option_as_alt(); - self.ctx.modifiers().state().alt_key() - && (option_as_alt == OptionAsAlt::Both - || (option_as_alt == OptionAsAlt::OnlyLeft - && self.ctx.modifiers().lalt_state() == ModifiersKeyState::Pressed) - || (option_as_alt == OptionAsAlt::OnlyRight - && self.ctx.modifiers().ralt_state() == ModifiersKeyState::Pressed)) - } - /// Attempt to find a binding and execute its action. /// /// The provided mode, mods, and key must match what is allowed by a binding @@ -190,6 +204,10 @@ impl<T: EventListener, A: ActionContext<T>> Processor<T, A> { return; } + // Mask `Alt` modifier from input when we won't send esc. + let text = key.text_with_all_modifiers().unwrap_or_default(); + let mods = if self.alt_send_esc(&key, text) { mods } else { mods & !ModifiersState::ALT }; + let bytes: Cow<'static, [u8]> = match key.logical_key.as_ref() { // NOTE: Echo the key back on release to follow kitty/foot behavior. When // KEYBOARD_REPORT_ALL_KEYS_AS_ESC is used, we build proper escapes for |