vscode
vscode copied to clipboard
Keyboard mappings with `setxkbmap` on Linux not working
- VSCode Version: 1.11.0
- OS Version: Ubuntu 16.04
I have my Caps Lock key bound to Escape using setxkbmap on Linux. This worked fine till 1.10, but broke with 1.11. At first I thought it was an issue with the VSCodeVim extension, but the issue persists with all the other Vim extensions on the marketplace as well. Pressing the escape button still works as expected.
The binding is still respected everywhere else in the operating system, it's only Visual Studio Code that ignores it for some reason.
Steps to Reproduce:
- Run
setxkbmap -option caps:escape(binds caps to escape for the duration of the session) - Hitting caps lock when in insert mode (with a Vim extension like VSCodeVim installed) no longer puts you normal mode.
- Hitting escape still works as expected and puts you in normal mode.
Same, with swapescape. Oddly caps lock works as escape to cancel in the keybinding editor, and either caps lock or escape cancel the F1 menu. Tried disabling all extensions, wiping user settings and using an empty workspace to no avail.
I have problems with numpad keys too. With num lock off they do nothing, but work as number keys with it on. If I press a direction with numpad off, nothing happens, but then turn it on and type a number and the cursor will move and then put the number.
In the keyboard shortcuts editor numpad PgDn, for example, shows up as numpad3 whether num lock is on or off.
This is something that might be broken by us dispatching based on scan codes. I am sorry about it, I need some time to investigate how these options should be handled. i.e. should Chromium handle these mappings or should we do it at the application layer.
Workaround to switch VS Code to dispatch based on key code again. Add the following setting:
"keyboard.dispatch": "keyCode" and restart VS Code
Thanks for the workaround! 👍
The workaround works like a charm, thanks!
I have a similar issue, with my Caps Lock bound to Control, where Code is unable to autoclose the quick open window when pressing Ctrl+Tab and then releasing Control. I've tested the workaround and it does not solve this issue.
Note: this appears to be specifically an issue with detecting the modifier key. Caps+Tab still launches the quick open just fine, and I have other remapped key bindings for arrow key movements that also work fine.
this workaround isn't working for me on vscode 1.12.2-1..
@navdeepio Can you please follow our troubleshooting guide at https://github.com/Microsoft/vscode/wiki/Keybindings#troubleshoot
If nothing in there works, then please proceed to create a new issue using the steps in the "I have tried all of the above" section.
@alexandrudima Do you guys plan on fixing this issue at some point? Or is the workaround satisfactory as a long term solution?
@Chillee This method needs to be enhanced to account for setxkbmap customizations and then we might need some tweaks here to cover mappings of those scan codes
Is it tricky or is it feasible as a first time contribution?
The work would be split between making first a change in native-keymap and then in vscode.
- the work in
native-keymapwould involve finding and using X11 specific methods that would capture/return the mappings done viasetxkbmapand expose them in some form in the results of_GetKeyMap - the work in
vscodewould involve making changes inmacLinuxKeyboardMapper.ts, where the values returned fromnative-keymapare consumed, and where all keybindings decisions are done for OSX and Linux.
I would be very appreciative if anyone figures out the X11 specific methods / submits a PR for native-keymap. I can tweak or refactor (if the current model is incorrect) in VS Code.
The way we handle keybindings decisions is documented here
Still experiencing weirdness with 1.21.1 in debian 9.
caps lock and ctrl swapping caused issues. seemed to partially help by swapping settings so that instead of "caps lock and control are swapped", I now have "caps lock is set as another control".
Great, now I can use vim mode :)
The workaround unfortunately breaks other things, notable the Ctrl + ` shortcut to toggle the integrated terminal. And yes, I'm using a standard-ish layout (those two keys aren't affected).
@jhpratt, Ctrl + ` works ( at least in my case it toggles the terminal without issues )
Awesome
same problem as @jhpratt, the workaround breaks a lot of shorcuts, (I use an ABNT2 (Brazil) keyboard)
~the workaround I found was:~
~1. open gnome tweak tool 1.1 disable the caps lock remap (re enabling caps lock default behavior) 2. open vscode 2.1. map "extension.vim_escape" to capslock 3. go back to gnome tweak tool 3.1 map caps lock to esc again~
edit: making the above disabled my actual top left physical Esc key. so I made the follwing instead:
- Reset the
extension.vim_escapekeybinding on the GUI Keyboards Shortcuts screen and remove everything related fromkeybinding.json - add the following to
keybinding.json:
,
{
"key": "capslock",
"command": "extension.vim_escape",
"when": "editorTextFocus && vim.active && !inDebugRepl"
},
now both my physical esc key and the xkbmap/gnome-tweak-took remapped caps lock key work as expected. my dconf settings are as follows:
org.gnome.desktop.input-sources.sources: "[('xkb', 'br')]" org.gnome.desktop.input-sources.xkb-options: "['shift:both_capslock', 'caps:escape']"
@alexandrudima, I just ran into this issue, too. Is there a good reason why vscode uses scan codes? I mean scan codes are not really meant to be used by a user application in Linux. And not using the key codes mapped by xkb, will just lead to a repeatedly running into problems for anyone using a rare keyboard or keyboard layout, or alternate input device pretending to be a keyboard.
Also this won't go away with wayland, as (at last the Wayland implementations I used) still use xkb internally.
We are dispatching by default based on scan codes because those are the only things we receive from Chromium/Electron which we can trust to reflect reality and which have not been processed through magic Chromium mapping tables.
AFAIK, the story goes like this:
- JS keyboard events get a
keyCodefield on Windows - this makes a lot of sense on Windows, as that is a concept that exists on Windows, and all applications on Windows should dispatch on KeyCodes. Exposing them from a browser to a web application seems natural...
- the problem is when the same concept is attempted to be supported on OSX and Linux, where there are kb maps but those concepts do not map clearly to the same
keyCodeconcept from Windows. - browsers have used creative solutions to come up with
keyCodevalues which appear to make sense on Linux and OSX, but they are inherently broken because the concept ofkeyCodedoes not exist natively on those operating systems. - we come along and need to render in the UI the key to be pressed to trigger a certain keybinding
- the creative solutions browsers came up with prevent us from building a reverse map from
keyCodeto produced character in order to display a good label in the UI. - we switch to dispatch on
code(scan code) which is a value that does not go through the creative solution and is passed to JS unprocessed. We implement https://github.com/Microsoft/node-native-keymap which uses OS APIs to map scan codes to produced characters. Unfortunately, the code we have on Linux, does not cover thesetxkbmapcustomizations, it appears we need to improve that code... - so, in cases where one is using
setxkbmapit is probably better to dispatch using the previouskeyCodesolution, especially when using an English keyboard layout where the creative solution from browsers is reversible and we can print decent labels in the UI. But, when not usingsetxkbmapand when using a different keyboard layout (like de-DE, etc.) it is preferable to run VS Code with dispatching oncode.
Because using setxkbmap is a hint for an advanced user, and using a regular keyboard layout (like de-DE) is not, we have made the decision to dispatch based on scan codes by default to cover most of the folks (including new Linux users). Advanced Linux users (that use setxkbmap) need to go through the hurdle of configuring the dispatch setting...
In the long term, it would be good if we'd improve https://github.com/Microsoft/node-native-keymap to also take into account setxkbmap customizations.
OMG this is so painful. Tried the keyCode workaround and @pumpkinlink workaround. Nothing works. (I'm using Xubuntu 18.04 btw). Is there a way to map the scan code to <Esc> ?
@andyl Configure "keyboard.dispatch": "keyCode". Restart VS Code.
@alexandrudima thanks for the long explanation.
This is quite a quirky problem, I guess to best (but unlikely to be doable) solution would be to fix how browsers handle keyboard events :sob: .
They are working on it, it just takes time... https://wicg.github.io/keyboard-map/
@alexandrudima - yeah I tried the "keyboard.dispatch": "keyCode" workaround and it doesn't work on my system. Learning more about the escape key than I ever thought possible. In settings.yml I mapped kj to <Esc> - which does work. But for the real escape key no luck. Interestingly enough: I disabled the setxkbmap modification and it still doesn't work! I also tried to set extension.vim_escape to various Keybindings - no luck. Maybe I am experiencing a voodoo curse or anomalous cosmic rays.
The "keyCode" workaround just stopped working for me.
Same here.
Ubuntu 18.04.1 here: "keyboard.dispatch": "keyCode" still works. (With swapescape)
Kubuntu 18.04 here: "keyboard.dispatch": "keyCode" doesn't work with capslock rebound to ctrl. VSCode still recognizes capslock, no other electron app / program does.
In Ubuntu 18.04, to make Caps Lock become an Escape, apply this patch:
--- a/etc/default/keyboard
+++ b/etc/default/keyboard
@@ -5,6 +5,6 @@
XKBMODEL="pc105"
XKBLAYOUT="us"
XKBVARIANT=""
-XKBOPTIONS=""
+XKBOPTIONS="caps:escape"
BACKSPACE="guess"
restart the computer and add the "keyboard.dispatch": "keyCode" into your vscode settings.