mirror of
https://github.com/wez/wezterm.git
synced 2024-12-23 21:32:13 +03:00
macos: fixup SUPER+SHIFT+[ key decoding
One of the default key assignments was registered as `SUPER+SHIFT+{` which worked on macOS, but on Linux, would never match because the keypress over there was (correctly) reporting as `SUPER+{`. I originally thought that the user reported issue was a linux normalization problem, but in looking deeper, the issue is really that macos is doing something funky! On macos we collect the interpreted key event as a string, and also the interpretation of that event without any modifiers applied. For letters this means that eg: `ALT-l` reports as `¬` for the processed string and `l` for the unmodified string. That's good! However, for punctuation we get a backwards result: SUPER+SHIFT+[ produces `[` for the processed text and `{` for the unmodified text! This commit tries to detect this, using a heuristic that is potentially bad on non-US layouts: if both the processed and unmodified strings are punctuation then we bias to the unmodified version. With that change, that key press is correctly reported as `SUPER+{`, and we can fix the key assignment registration to reflect that. I quickly checked the behavior of pressing that same physical key combination with a DEU layout active, and it appears that the unmodified stuff is also flipped there; we get a lower-case version of something that I think should be uppercase. This commit doesn't change that behavior: ``` key_event KeyEvent { key: Char('ü'), modifiers: NONE, raw_key: Some(Char('Ü')), raw_modifiers: SHIFT | SUPER, raw_code: Some(33), repeat_count: 1, key_is_down: true } ``` refs: https://github.com/wez/wezterm/issues/601
This commit is contained in:
parent
d7b78b4163
commit
fe48951e7a
@ -357,7 +357,7 @@ impl InputMap {
|
||||
ActivateTabRelative(-1)
|
||||
],
|
||||
[
|
||||
Modifiers::SUPER | Modifiers::SHIFT,
|
||||
Modifiers::SUPER,
|
||||
KeyCode::Char('{'),
|
||||
ActivateTabRelative(-1)
|
||||
],
|
||||
@ -366,11 +366,7 @@ impl InputMap {
|
||||
KeyCode::Char(']'),
|
||||
ActivateTabRelative(1)
|
||||
],
|
||||
[
|
||||
Modifiers::SUPER | Modifiers::SHIFT,
|
||||
KeyCode::Char('}'),
|
||||
ActivateTabRelative(1)
|
||||
],
|
||||
[Modifiers::SUPER, KeyCode::Char('}'), ActivateTabRelative(1)],
|
||||
[Modifiers::SUPER, KeyCode::Char('r'), ReloadConfiguration],
|
||||
[Modifiers::CTRL, KeyCode::Char('R'), ReloadConfiguration],
|
||||
[ctrl_shift, KeyCode::PageUp, MoveTabRelative(-1)],
|
||||
|
@ -1715,6 +1715,9 @@ impl WindowView {
|
||||
}
|
||||
|
||||
if let Some(key) = key_string_to_key_code(chars).or_else(|| key_string_to_key_code(unmod)) {
|
||||
let raw_modifiers = modifiers;
|
||||
let mut modifiers = modifiers;
|
||||
|
||||
let (key, raw_key) = if chars.is_empty() || chars == unmod {
|
||||
(key, None)
|
||||
} else {
|
||||
@ -1722,14 +1725,27 @@ impl WindowView {
|
||||
match (&key, &raw) {
|
||||
// Avoid eg: \x01 when we can use CTRL-A
|
||||
(KeyCode::Char(c), Some(raw)) if c.is_ascii_control() => (raw.clone(), None),
|
||||
(KeyCode::Char(k), Some(KeyCode::Char(r)))
|
||||
if k.is_ascii_punctuation() && r.is_ascii_punctuation() =>
|
||||
{
|
||||
// Well, `chars` is supposed to represent the processed and modified
|
||||
// interpretation of the keypress, and `unmod` the same, but ignoring
|
||||
// any modifier keys. eg: `ALT-l` has unmod=`l` and chars=`¬`.
|
||||
// However, SUPER+SHIFT+[ yields chars=`[` and unmod=`{` which is
|
||||
// the opposite of what we want.
|
||||
// If both chars and unmod are punctuation then let's take unmod,
|
||||
// and filter out the SHIFT state if present.
|
||||
modifiers -= Modifiers::SHIFT;
|
||||
(KeyCode::Char(*r), None)
|
||||
}
|
||||
_ => (key, raw),
|
||||
}
|
||||
};
|
||||
|
||||
let (modifiers, raw_modifiers) = if raw_key.is_some() {
|
||||
(Modifiers::NONE, modifiers)
|
||||
let modifiers = if raw_key.is_some() {
|
||||
Modifiers::NONE
|
||||
} else {
|
||||
(modifiers, Modifiers::NONE)
|
||||
modifiers
|
||||
};
|
||||
|
||||
let event = KeyEvent {
|
||||
|
Loading…
Reference in New Issue
Block a user