KeyboardEvent.getCharacterByKey(key, modifierList)

i18n
Tags: #<Tag:0x00007f8051f70278>

#1

I read about KeyboardEvent.prototype.key and somewhere it was mentioned that one of its use cases is to let a developer provide a consistent keyboard experience, for example, in games, where the W, A, S, D and X keys are used for moving and similar, regardless of the keyboard layout of the user. This is a good use case, however, applications (or even for help pages of games) that provide keyboard shortcuts (for example, the Developer Tools, GMail and others), cannot show meaningful keys to the user in some keyboard shortcut legend, because they cannot know in advance what KeyA really is in the keyboard of the user. This creates some funny situations where the application shows that Control + A is the keyboard shortcut for selecting all of the characters, but since it relies on KeyA, the shortcut will simply be wrong for German users with AZERTY keyboards, for example. It will do nothing, or worse - do something else (like discarding a new e-mail!).

My suggestion is to add a static method to KeyboardEvent, named getCharacterByKey (bikeshedding for the name or the placement is welcome only after establishing that the concept itself seems like a good idea, obviously :)). It will take two parameters, key, which is the value of KeyboardEvent.prototype.key, as well as a modifier list, which can be the same input used for KeyboardEvent.prototype.getModifierState. The method will return the value of KeyboardEvent.prototype.code (for the combination of the key and modifiers).

Privacy concerns - web applications will be able to identify the current keyboard layout (the operating system provided one, not the physical one, though) of the keyboard of the user. This can be used for fingerprinting in a way, though I heard that the number of bits that can be used for fingerprinting has already increased far enough for fingerprinting to happen anyway and thus fighting this specific concern is is pretty meaningless at this point. Also, it does not expose the name of the keyboard layout of the user, which can reveal much more about the locality, nationality or religion than just getting the keys.

Open questions -

  • In case the user has two keyboard layouts (I have Hebrew and English, for example), which one will be returned? The current one at the time of calling the API?
  • Should the method return a promise since it might involve some system calls?
  • Should the method accept multiple combinations (use case - a keyboard shortcut legend usually includes more than a few shortcuts. This can make the application call this API a lot at once. This is especially useful in the promise-returning method case).
  • Should the method return multiple outputs, per keyboard layout (in my case, one for Hebrew and one for English)?

#2

We had a proposal for something like this in the past, but didn’t have time to devote to it. I’ve added a bug to the UIEvents spec so that we can track this more easily.


#3

This issue came up again recently, so I have written up a proposal to get a mapping from code values to key values for the currently active keyboard.

Please add comments either here or as issues on Github. Thanks!


#4

According to the user story, isn’t it enough to limit web apps can retrieve only unmodified key value of the highest priority ASCII capable keyboard layout if shortcut keys are always displayed with ASCII characters even in non-ASCII keyboard layout users? If using active keyboard layout, shortcut key labels may be displayed with non-ASCII characters like Hebrew, Cyrillic, Greek, etc.

On macOS, we can retrieve the highest priority keyboard layout with TISCopyCurrentASCIICapableKeyboardLayoutInputSource().

On Linux/GTK, we can walk groups and check KeyA’s character like this: https://searchfox.org/mozilla-central/rev/877c99c523a054419ec964d4dfb3f0cadac9d497/widget/gtk/nsGtkKeyUtils.cpp#1211-1229

Although, I have no idea on Windows. Should give highest priority to first ASCII capable keyboard layout found in the result of GetKeyboardLayoutList()?

Additionally, should it only work with Writing System Keys? https://w3c.github.io/uievents-code/#key-alphanumeric-section

I know users may map character input to some function keys. But web API doesn’t need to treat such users only for this purpose since such users can remap shortcut keys in their brain.


#5

Re: “active layout” vs. “highest ASCII layout”

Those are good points about the ASCII layout. We can probably get away with just the ASCII layout.

If the info for the “active layout” is useful, we could have a useActiveLayout flag that defaults to false. I’m not sure if that’s necessary, though.

Re: Only Writing System keys

The Writing System keys are the ones for which this API is the most useful since the other keys already have special names (unless they have a custom override).

So I agree that’s a good idea to limit it to the just the Writing System keys. One advantage of restricting it in this way is that key map would be smaller since we could ignore the large number of special keys (Multimedia Keys, Brazil-only numpad keys, etc.).

Overall, though, I’m trying to gauge overall interest in migrating something like this to an official W3C specification where we could work out these issues:

  • There currently is no alternative mechanism for getting this data.
  • We’ve had requests for something like this for years.
  • It would help support a class of webapps that we want to encourage - specifically games (for control) and other apps that have a mode that uses the keyboard as a set of buttons (like a drawing app that has keys to select drawing tools) where they care about the location of the buttons relative to each other.

Thanks!


#6

I’ve placed an initial ED in the WICG github repo: https://wicg.github.io/keyboard-map/

Please add comments or file issues.