w3c / uievents

UI Events
https://w3c.github.io/uievents/
Other
147 stars 52 forks source link

"keyCode" is the only way to work with KeyboardEvents now #267

Open photopea opened 4 years ago

photopea commented 4 years ago

I would like to detect the Alt+Ctrl+T on a Dvorak keyboard in Mac OS (in the latest web browsers).

When the user holds Alt and Ctrl, pressing T fires a KeyboardEvent with code='KeyK' and key='†' . Only the keyCode="84" suggests, that the T was pressed.

Is it possible to work with KeyboardEvents without the "keyCode" property? I think it is not, as the "code" does not reflect the "localized keyboard settings" (such as Dvorak or Azerty), and "key" just tells us what would be typed (the OS can modify it, when Alt or other character is added).

garykac commented 4 years ago

To summarize: the "t" key on a dvorak layout is where the "k" key is on a standard QWERTY layout, so the code value will always be KeyK for this.

On a Dvorak layout, the following key values are produced:

Ctrl + any of the above combos returns the same character for key. The only common value is code = KeyK.

The deprecated keyCode field was not specified properly and is implemented inconsistently across browsers (even across the same browser for different OSs). If you try this key combo on other browsers/OSs, it can return different values.

In this case, the name of the key is code = KeyK and you can rely on this being true for all browsers/OSs (unless there are bugs, which will be fixed). This design is to support the common use case so that (for example) the WASD keys in games can work for Dvorak users (or any locale) by default.

photopea commented 4 years ago

@garykac That is not what I need.

Native programs can do an action, after the user presses Alt+Ctrl+T. That "T" is the key with a label "T" on the keyboard. It can be anywhere, depending on the keyboard settings.

To make the web as powerful as native programs, it should be possible to detect shortcuts like Alt+Ctrl+T, and by "T" I don't mean any physical key on a specific location, but a key, which would type "T" if Alt and Ctrl were not pressed.

Now, I think it is not possible with "code" and "key" properties of the event. That is why I think you should make "keyCode" equally important, or add a new property, which would allow do things as native programs can do. A new property, which describes a "localized" key code, and its value does not depend on whether other keys are pressed or not.

garykac commented 4 years ago

To identify the key that produces the 't' character, you can use the Keyboard Map API. This will tell you which code is associated with each character.

Because of how inconsistent the currently implementations of keyCode are, it is not practical to specify the current behavior.

garykac commented 4 years ago

I will, however, make a note of the desire to have a field that contains the "character that would be generated by the key pressed if no modifiers were present". I'm not sure how easy this is to do on all platforms.

photopea commented 4 years ago

@garykac I did not know about the Keyboard Map API. I started to use it and it seems to work well, thank you :)

Too bad that it is available only in Chromium. Also, I never understood why all new APIs are based on promises, even when it does not require any confirming of permissions from the user.

garykac commented 4 years ago

We use promises when we think that one or more User Agents might want to have a permission (or some user agreement), which means that we use them whenever there are any security or privacy concerns. This is to give the UAs the flexibility they need to control the user experience as they see fit. Keyboard Map can provide info for fingerprinting, and while we worked to minimize the surface, there are still valid concerns.

robertknight commented 2 years ago

The Keyboard Map API has unfortunately been rejected by Mozilla and has not received feedback from WebKit. My use case is essentially the same as photopea's, and it looks like using keyCode may be the only workable solution, if it works "consistently enough" for at least ASCII letters.

https://w3c.github.io/uievents/#determine-keydown-keyup-keyCode has what seems like a reasonable effort at specifying the behavior of this property. Are there more details available anywhere on the remaining differences across the major platforms (Windows, Mac, Linux) and browsers (Chrome, Safari, Firefox)?

robertknight commented 2 years ago

Closely related/duplicate issue: https://github.com/w3c/uievents/issues/247

ggPeti commented 1 year ago

Unfortunately keyCode doesn't always work. According to keyCode spec,

If an Input Method Editor is processing key input and the event is keydown, return 229.

Example: On the "ABC" layout, Chrome on Mac emits keyCode 229 for Option-N (combining tilde) when the cursor is inside a text input field. In any other place, it emits keyCode 78 (N). (To make matters even worse, Cmd-Option-N emits keyCode 192 - which is the key code for a regular tilde (as well as backtick, but that just goes to show how jagged the landscape is.)). It's funny that in 2023, keyboard shortcuts on the web are an unsolved problem.

ggPeti commented 1 year ago

@garykac Is this basic functionality going to be a victim of control creep?

User need: I want to be able to develop a web app with the shortcut Ctrl+K.

Institutional response: First, get the keyboard layout of the user. This is not yet supported by some of the browsers but we are applying political pressure so we expect them to eventually cave in. Then, deal with the fact that it returns a promise. That is because while we don't yet requre user consent, we maintain the option to do so in the future. Then, read your keyboard event's code and resolve it via the keyboard map. Ignore all browsers that didn't cave in and users who are cautious to give access to their keyboard layout.

Simple solution: Return the baseKey and let the developer handle Ctrl+K.