w3c / uievents

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

Need virtual key codes #377

Open laughinghan opened 4 months ago

laughinghan commented 4 months ago

The Problem

So in this new world (since ~2020), we're supposed to use .key (printable character) and .code (scancode) instead of .keyCode/.charCode/.which. This has a big problem:

The closest to what I want is actually sad, old, deprecated .keyCode === 65! Because .keyCode was a kind of cross-platform version of OS virtual key codes (and was cross-browser compatible at least for alphanumeric keys).

Severity

It seems obvious to me that this is affects almost every webapp with keyboard shortcuts. Indeed, this seems like a much more common use case than games that want physical WASD controls. Even this obscure repo has 3 open tickets on it: #229, #247, #267

Non-Solutions

In #229, #247, and #267, @garykac offers Keyboard.getLayoutMap() as a solution, which shipped to GA in Chrome in 2018. It has since been rejected both by Mozilla and by WebKit for privacy reasons, but to be clear it also doesn't solve the problem in the first place:

Proposed Solution

Rather than the hardware scancode that .code is based on, .keyCode is supposed to be based on the OS "virtual key code". In my testing, for alphanumeric keys, it's pretty cross-compatible, however for punctuation/symbols it's pretty inconsistent across browsers and reputedly platforms. Can we standardize a cross-platform "virtual key code" using the KeyA etc names that respects, rather than ignores, the keyboard layout (QWERTY vs AZERTY vs Dvorak), but doesn't map to character input (ф)?

To me, unifying 2 or 3 OS virtual key code tables sounds much simpler than mucking with keyboard layout priority lists.

Open Questions

Punctuation/symbols are inconsistent because it's pretty unclear what they should do. For example, instead of a /? key, French AZERTY has a :/ key. Should that map to ANSI QWERTY /? or ;:? Or some other universal-ish "reference keyboard" (context, original)?

Recommended Workaround

In the meantime, the situation for web devs appears to be:

oliviertassinari commented 1 month ago

Yes! We are facing the same problem in https://github.com/mui/mui-x/pull/14220#discussion_r1720441510 to detect the copy-paste shortcuts.

Only event.keyCode seems to work to detect those. It's still the only solution working in https://stackoverflow.com/questions/2903991/how-to-detect-ctrlv-ctrlc-using-javascript too.

The problem is that this is deprecated in https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode:

SCR-20240818-qnxg

So the current state of things feels broken.

masayuki-nakano commented 1 month ago

First of all, .keyCode values cannot be changed on the browser side because the values are just arbitrary values, i.e., do not have meaning. Therefore, web apps handle .keyCode values with checking UA etc. So, even if all browsers start using exactly same rules to map .keyCode values, existing web apps using .keyCode values will be broken. So, if .key and .code are not enough, there should be new API.

In my experience at implementing the shortcut key handling rules of Firefox, completely compatible behavior between browsers and/or platforms may be impossible. Especially when Shift key is required, there are some open bugs in Firefox with some keyboard layouts which map punctuation to numeric keys. E.g., Ctrl + Shift + 1 may be conflict with Ctrl + ! if ! is mapped to Digit1 key.

Additionally, some keyboard layout users use 2 keyboard layouts, one is ASCII capable and the other is not so. Then, even if the ASCII capable keyboard layout is not selected, the user wants to work shortcut keys as the ASCII capable keyboard layout is selected. So, this additional information requires to store in keydown events.

Similarly, some keyboard layout may switch ASCII character mapping when it works with some modifiers. E.g., a keyboard layout may be Dvorak layout, but QWERTY if Ctrl or something is pressed. This is also fixable with the above approach.

Finally, using punctuation with Shift and/or AltGr for shortcut may make specific keyboard layout users inaccessible. For avoiding this issue completely, it might be better to make new API work only when the key combination matches only with [a-z0-9 ].