Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make keyboard layouts in charge of modifier keys and formatting of keys #257

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from

Conversation

jasongrout
Copy link
Contributor

@jasongrout jasongrout commented Nov 2, 2021

Currently, the commands package is in charge of formatting a keyboard shortcut for display and hard-coding the modifiers for a keyboard shortcut. However, this means that the modifiers and how keyboard keys are displayed are both hard-coded in the command package rather than being specified in the keyboard layout, which is closer to the keyboard capabilities.

I think ideally, the keyboard layout should be responsible for encoding the capabilities of the keyboard, including what the modifier keys are and how keys are displayed. This PR explores how this might work.

A couple of notes and unfinished business:

  1. The parsed modifiers in a user-specified keyboard shortcut are still hard-coded in the commands package to be from the set Ctrl, Alt, Shift, and Cmd. To go further, we should make that modifier checking more generic, relying on the modifiers the keyboard layout says it has.
  2. There was a choice about whether the keyboard layout should use "Control" or "Ctrl" for the control modifier. In the end, I opted to keep things backwards compatible with Ctrl, though this PR also contains a reverted commit changing the layout to use Control and adjusting the user-specified shortcut when needed.
  3. I have not tested this PR beyond the existing unit tests. Caveat emptor.

It may be that when we are ready to support keyboard layouts with other modifiers, it is appropriate to switch from using .keyCode to .key, which may make this PR obsolete.

This reverts commit 57a6ee7.

It was not clear in issue jupyterlab#151 calling for a change in formatting of arrows that arrows should not be treated as modifier keys.
This puts the formatting of human-readable strings closer to where the keys are actually defined, and allows new keyboard layouts to extend this formatting for other keys the keyboard may have.

This is exploratory work. It seems that the formatting of specific keys is not standardized across applications, operating systems, or keyboards, so I’m not sure if this will make anyone happier. It does seem like the keyboard layout is the right place for this formatting logic to happen for individual keys in the layout.

I did verify that VoiceOver reads each of the macOS shortcuts correctly in menus (e.g., the curvy right arrow is read as “return” in a menu, etc.)
…g them.

This adds a modifierKeys attribute to the keyboard layout so we can iterate over the modifier keys. Since we often want to our modifier keys displayed in a specific order, we need the modifier keys to be an ordered set, but Object.keys ordering is not guaranteed until ES2020, I believe. Therefore I converted the modifier keys to a Set, which does iterate in insertion order for sure.

Finally, we make a kind of awkward special case for Command/Meta treatment on macos so that things are backwards-compatible with the current behavior.

There are some blockers to further progress using getModifierState to determine modifier keys:

1. It does not appear that we can easily clone a KeyboardEvent and clone the getModifierState function, at least not as easily as we did for the standardized ctrl, shift, alt, etc. A way forward is that we could keep a reference to the original event and proxy getModifierState calls to the original event.
2. The current keyboard layout specifies the control key as “Ctrl”, not the standardized “Control” used in getModifierState. This is so that users can specify their keyboard shortcuts using “Ctrl” instead of “Control”. To make more progress here, we could use “Control” in the keyboard layout, and carefully trace where “Ctrl” was used and convert it to “Control” at the appropriate places.
We still keep the user-facing label as Ctrl for now for compatibility.

This may be considered a breaking change in the keyboard package, since the layout has been changed to reference ‘Control’.
This preserves backwards compatibility for the keyboard layout, while still switching to getModifierState for checking the modifier state.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant