summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKirill Chibisov <contact@kchibisov.com>2023-12-20 10:37:21 +0400
committerGitHub <noreply@github.com>2023-12-20 10:37:21 +0400
commit3d7d81c8482eb9465763020a397290765b70b541 (patch)
tree687a7bf867b543670eb463ddcba3ea1913bfc6ad
parenta10fb8adc0857633be428d673ab8d36d2a90193a (diff)
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.rs54
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