-
Notifications
You must be signed in to change notification settings - Fork 98
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
Add a special Mod
modifier that translates to either Meta
on Mac or Control
on other platforms
#66
Conversation
Previously: map ctrl / meta to Mod. Now: map mod to meta on mac / control on other platforms Also maps upper case key to `Shift+<key>`
112547a
to
4ab901f
Compare
examples/hotkey_mapper.html
Outdated
@@ -1,45 +1,61 @@ | |||
<!doctype html> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there's no functional change — this is just the result form running prettier on this file.
examples/index.html
Outdated
@@ -1,29 +1,33 @@ | |||
<!doctype html> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same — there's no functional change — this is just the result form running prettier on this file.
src/utils.ts
Outdated
@@ -25,5 +27,5 @@ export function fireDeterminedAction(el: HTMLElement, path: string[]): void { | |||
} | |||
|
|||
export function expandHotkeyToEdges(hotkey: string): string[][] { | |||
return hotkey.split(',').map(edge => edge.split(' ')) | |||
return hotkey.split(',').map(edge => edge.split(' ').map(k => normalizeHotkey(k))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is where the normalization is applied, so we take the user-provided hotkey string, normalize (or localize?) it for the current platform and store that on the trie. Then when we later serialize a keyboard event we compare it to the normalized version of the string.
test/test-normalize-hotkey.js
Outdated
['Mod+A', 'Meta+A', 'mac'], // TODO: on a mac upper-case keys are lowercased when Meta is pressed | ||
['Mod+9', 'Control+9', 'win'], | ||
['Mod+9', 'Meta+9', 'mac'], | ||
['Mod+)', 'Control+)', 'win'], | ||
['Mod+)', 'Meta+)', 'mac'], // TODO: on a mac upper-case keys are lowercased when Meta is pressed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that the tests on line 18 and 22 are incorrect: the hotkey Meta+A
won't match on Mac: instead it should be Meta+Shift+a
in the current implementation. Likewise, Meta+)
should be Meta+Shift+0
.
I hope to address this in #54
README.md
Outdated
6. `"Mod"` is a special modifier that localizes to `Meta` on MacOS/iOS, and `Control` on Windows/Linux. | ||
1. `"Mod+"` can appear in any order in a hotkey string. For example: `"Mod+Alt+Shift+KEY"` | ||
2. Neither the `Control` or `Meta` modifiers should appear in a hotkey string with `Mod`. | ||
3. Due to the inconsistent lower-caseing of `event.key` on Mac and iOS when `Meta` is pressed along with `Shift`, it is recommended to avoid hotkey strings containing both `Mod` and `Shift`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added this note for now, but hope to resolve this inconsistency in #54 — I have made a note to update the README in that issue.
Mod
character that translates to either Meta
on Mac or Control
on other platformsMod
character that translates to either Meta
on Mac or Control
on other platforms
Mod
character that translates to either Meta
on Mac or Control
on other platformsMod
modifier that translates to either Meta
on Mac or Control
on other platforms
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for adding the notes around inconsistent behavior 🙇♀️
['Mod+Alt+a', 'Alt+Meta+a', 'mac'], | ||
// Modifier sorting | ||
['Shift+Alt+Meta+Control+m', 'Control+Alt+Meta+Shift+m'], | ||
['Shift+Alt+Mod+m', 'Control+Alt+Shift+m', 'win'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we include linux in these tests to demonstrate that it is considered, as noted in the README?
Also, should we have tests for the other apple platform matches: /Mac|iPod|iPhone|iPad/i
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can make this change for sure!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
['Mod+Alt+a', 'Control+Alt+a', 'win'], | ||
['Mod+Alt+a', 'Alt+Meta+a', 'mac'], | ||
// Modifier sorting | ||
['Shift+Alt+Meta+Control+m', 'Control+Alt+Meta+Shift+m'], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this test is only meant to demonstrate sorting works but wondering if we should exclude this given it's invalid. Or maybe we can add a note that this is invalid along with note to not use Mod
with Meta
or Control
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is valid to have shortcuts that pair Control
and Meta
(just not either of those keys with Mod
).
✅ Control+Meta+a
🚫 Mod+Control+a
... would localize as Control+Meta+a
on Mac / Control+a
on windows / linux
🚫 Mod+Meta+a
... would localize as Meta+a
on Mac / Control+Meta+a
on windows / linux
Mod+Control+Meta+a
(would localize as Control+Meta+a
... which is okay but weird)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, it's technically valid on mac!
Co-authored-by: Kate Higa <16447748+khiga8@users.noreply.github.com>
Co-authored-by: Kate Higa <16447748+khiga8@users.noreply.github.com>
…ned/mod-character
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't approve this because it's my own PR, but there are a few minor tweaks regardless. Besides that I think this all makes sense. Exciting to see this finally getting finalized 😃
pages/demo.html
Outdated
// import {install} from '../dist/index.js' | ||
import {install} from 'https://unpkg.com/@github/hotkey@latest?module' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think given the change @iansan5653 just made in #91 this change should no longer apply
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed this change 6693f1f
given changes from #91 this change was no longer relevant
5. Modifier key combos are separated with a `+` and are prepended to a key in a consistent order as follows: `Control+Alt+Meta+Shift+KEY`. | ||
6. You can use the comma key `,` as a hotkey, e.g. `a,,` would activate if the user typed `a` or `,`. `Control+,,x` would activate for `Control+,` or `x`. | ||
5. Modifier key combos are separated with a `+` and are prepended to a key in a consistent order as follows: `"Control+Alt+Meta+Shift+KEY"`. | ||
6. `"Mod"` is a special modifier that localizes to `Meta` on MacOS/iOS, and `Control` on Windows/Linux. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Super nitpick, control
on Android as well? I'm not really familiar with that ecosystem
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think technically Android is Linux, so that might cover it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh, right -- that's fair! I've read enough "Android isn't REAL Linux" stuff on the internet I completely forgot about this 😆
resolves #56
What is this?
On Mac,
Meta
(command) is frequently used as the modifier for shortcuts: on Windows and LinuxControl
is used instead. Therefor in order to correctly localize hotkeys, it's common to see code that handles swapping platform-specific modifier keys in users of this library. It would make sense to do this in the library and eliminate all that custom code!Mod
modifierThis PR adds support for using a special
Mod
modifier that automatically localizes toControl
on Windows / Linux, orMeta
onMac
.The rational is that this allows an easy way to define cross-platform shortcuts. Without this feature, an implementer would have to either support both
Control
andMeta
forms of shortcuts, or write their own code to handle swapping these.Consistent sorting of modifiers
Although it was only documented in #62 , hotkey has always had a hard requirement that modifiers are sorted in the order that matches the order
eventToHotkeyString
formats the modifier keys from an event.Since the
Control
andMeta
keys appear in different places in the hotkey string, in order to support theMod
key, I also had to ensure that modifiers in a hotkey string are consistently sorted before comparoson to an event that is serialized viaeventToHotkeyString
.So this PR also removes the hard requirement that modifiers be sorted in a strict order.
Approach
I chose to add a new
normalizeHotkey
function to handle localizing theMod
key and sorting the modifiers. ThisnormalizeHotkey
is applied to the hotkey string in theexpandHotkeyToEdges
before it is added to the Trie. This ensures that when we later look for a serialized event in the trie, the hotkey string is already normalized to match the serialized output ofeventToHotkeyString
.Limitations
The
"Mod"
key is not currently compatible withShift
andAlt
modifiers.Because Mac treats
event.key
differently than Windows or Linux when theShift
and / orAlt
key is pressed, it means that theMod
modifier will not localize as expected when paired withShift
. I have noted this limitation in the tests and in the README. I was hoping to address #54 and #68 in this PR too but decided to defer to keep the size of the PR down.TODO
normalizeHotkey
function to allow comparing aeventToHotkey
string to a hotkey string containing aMod
character.Control
andMeta
!event.key
whenMeta+Shift
are pressed.normalizeHotkey
platform specific: convertMod
toMeta
on Mac orControl
on other platforms.normalizeHotkey
to map hotkey to Trie inexpandHotkeyToEdges
so that the Trie contains the platform-specific modifier: use it to allowkeyDownHandler
to match events to hotkey strings containing theMod
alias.Mod
characterShift
etc?