-
Notifications
You must be signed in to change notification settings - Fork 30.1k
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
Move keybinding dispatching off e.keyCode #17521
Comments
[This comment will be updated to reflect the status of this issue] Additional constraintsWe cannot dispatch based on e.g. for the dead key problem on the GER Windows layout:
After examining multiple applications (e.g. Visual Studio) on Windows, we have concluded that VS Code's keybinding dispatching on Windows should continue using [23.03.2017] What changedon Windows
on OSX and Linux
A note on how the changes are implementedThe common type that can encapsulate all these cases is All keybindings go through an
A note on mapping heuristicsHere is an example for how the scan code These are the raw mappings read by
Explanation:
E.g. This effectively causes the Toggle Line Comment (bound to A note on the new user
|
using visual code with a japanese layout has been madness for me. |
Any chance a setting to use new keybinding dispatch could be either released as an add-on or a setting until the support for multiple shortcut syntax can be implemented and shipped. With non US layout on non-windows editor just behaves extremely odd. For example on dvorak |
Dvorak on mac is rough, I edited the raw js to disable the custom mac keycode handler. Cheering y'all on to get this resolved! |
Intro
VS Code dispatches keyboard shorcuts to commands by listening to
keydown
events.At the time VS Code was first released, we shipped with Chromium version 45. It did not support
KeyboardEvent.key
, norKeyboardEvent.code
(see the current spec here).It supported
KeyboardEvent.keyCode
,KeyboardEvent.charCode
,KeyboardEvent.which
andKeyboardEvent.keyIdentifier
:KeyboardEvent.charCode
is often not set forkeydown
events, therefore unreliable.KeyboardEvent.which
was, from my testing, always equal toKeyboardEvent.keyCode
.KeyboardEvent.keyIdentifier
was known to be severely flawed already at that time, and it was marked as deprecated (it got removed in Chromium version 54).KeyboardEvent.keyCode
for dispatching keyboard shortcuts.What is wrong with
KeyboardEvent.keyCode
and why is it deprecated?The w3c spec is dry (which is a good thing in general, maybe not in this case), and does not explain what went wrong or why it is now deprecated.
In this section, after having browsed through Chromium's source code, I will try to explain what I think is wrong with it.
To understand the shortcomings of
KeyboardEvent.keyCode
, we must first understand what its value means and where it comes from. The only reasonable explanation I could find is that it must be rooted in how Windows does keyboard input.I've found a good explanation about keyboard input in Windows here.
... and a hint to how keyboard layouts work:
So a keyboard layout on Windows consists of two mappings. The first one maps scan codes to virtual keys and the second one maps virtual keys and modifiers combinations to generated characters. The list of Virtual Key Codes is defined here.
Since this is pretty abstract, let's pick an example where we compare the US standard keyboard layout with the GER (Germany) keyboard layout, as it can exemplify both mappings:
Turns out the indirection through Virtual Key Codes is quite helpful, e.g. one can write an application and simply look for Ctrl+0x5A (i.e. Ctrl+Z) keydown events and this will work as expected on keyboards where keys are moved around, e.g. QWERTZ or AZERTY keyboards, etc.
By looking for
KeyboardCodeFromNative
in Chromium's sources we can confirm that under Windows,KeyboardEvent.keyCode
is simply equal to the Windows Virtual Key Code:The problem: Linux and Mac
AFAICT keyboard input and keyboard layouts on Linux and Mac do not work through this double indirection (from scan code to key code, and from key code and modifiers to character), apparently keyboard input on Linux and Mac goes straight from scan code and modifiers to characters.
This raises the question, what then is the value of
KeyboardEvent.keyCode
on Linux and Mac?By looking for the Linux and Mac equivalents of
KeyboardCodeForWindowsKeyCode
(i.e.KeyboardCodeFromXKeyEvent
andKeyboardCodeFromNSEvent
) we can conclude that nobody really knows.On Linux:
On Mac:
The way
KeyboardEvent.keyCode
is computed leads to some weird situations, such as the one documented in issue #1302:Here are the values observed in
KeyboardEvent
:This is probably the case from above where "mileage may vary". We have tried to workaround this on our side, but the workaround is limited and only functions for a subset of these key codes (i.e. does not work, perhaps it is even making things worse for DVORAK).
Issues that possibly all share the same root cause (the fuzzyness of
keyCode
on Linux and Mac and/or our workaround not working or making things worse):The path forward
We can now use
KeyboardEvent.code
andKeyboardEvent.key
(see the current spec here). The simplified explanation is thatKeyboardEvent.code
is a string representation of the scan code, andKeyboardEvent.key
is the produced character (skipping entirely the Virtual Keys hop on Windows). This has a chance to work correctly because all Operating Systems have these concepts.The text was updated successfully, but these errors were encountered: