Open laughinghan opened 4 months 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:
So the current state of things feels broken.
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 ]
.
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:.code === "KeyA"
because on an AZERTY (eg French) keyboard, that key is labeledQ
, and my shortcut is for Select All not Select Qll.key === "a"
because on eg a Russian keyboard, theA
key will have.key === "ф"
.key === "å"
for US English on Macs (in every browser), which is annoyingThe 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:keyboardLayoutMap.get("KeyA")
is specced to returnф
(altho this doesn't work for me in Chrome on Mac; instead it has an unreliable return value, see link for details).keyCode === 65
, same asA
on US English QWERTY.code === "Digit2"
, but with French AZERTY,keyboardLayoutMap.get("Digit2") === "é"
, not2
.keyCode === 50
, same as2
on US English QWERTYProposed 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 theKeyA
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:
.code
and ignore.key
, because of the Ctrl-Alt-A.key === "å"
problem.code
, instead first looking at.keyCode
, which for alphanumeric keys should sensibly map back to standard ANSI QWERTY; and if.keyCode
indicates non-alphanumeric, then look at.key
..key
should be the same as.code
; and otherwise for punctuation/symbols, in general there may not be a sensible mapping to an ANSI QWERTY/reference layout, but at least it'll tell you the actual punctuation typed, which hopefully is marked on the physical keycaps or understood by the end-user.