diff options
author | Kirill Chibisov <contact@kchibisov.com> | 2023-12-20 10:37:21 +0400 |
---|---|---|
committer | Christian Duerr <contact@christianduerr.com> | 2023-12-22 10:42:02 +0100 |
commit | 813c8394de3b64fbcfdc09556cb83c48d4cbed98 (patch) | |
tree | 1850eccce1a03b7ba0fcd97638c79d809fadedfa | |
parent | 5d94e9ebee88c6542e2768f9bbdf252417039f99 (diff) | |
download | alacritty-813c8394de3b64fbcfdc09556cb83c48d4cbed98.tar.gz alacritty-813c8394de3b64fbcfdc09556cb83c48d4cbed98.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 |