Skip to content

Commit

Permalink
macos: fixup SUPER+SHIFT+[ key decoding
Browse files Browse the repository at this point in the history
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: #601
  • Loading branch information
wez committed Apr 3, 2021
1 parent d7b78b4 commit fe48951
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 9 deletions.
8 changes: 2 additions & 6 deletions config/src/keyassignment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ impl InputMap {
ActivateTabRelative(-1)
],
[
Modifiers::SUPER | Modifiers::SHIFT,
Modifiers::SUPER,
KeyCode::Char('{'),
ActivateTabRelative(-1)
],
Expand All @@ -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)],
Expand Down
22 changes: 19 additions & 3 deletions window/src/os/macos/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1715,21 +1715,37 @@ 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 {
let raw = key_string_to_key_code(unmod);
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 {
Expand Down

0 comments on commit fe48951

Please sign in to comment.