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

Keyboard mappings with `setxkbmap` on Linux not working #23991

Open
tallpants opened this Issue Apr 6, 2017 · 35 comments

Comments

@tallpants
Copy link

tallpants commented Apr 6, 2017

  • 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:

  1. Run setxkbmap -option caps:escape (binds caps to escape for the duration of the session)
  2. Hitting caps lock when in insert mode (with a Vim extension like VSCodeVim installed) no longer puts you normal mode.
  3. Hitting escape still works as expected and puts you in normal mode.
@jspaine

This comment has been minimized.

Copy link

jspaine commented Apr 6, 2017

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.

@alexandrudima

This comment has been minimized.

Copy link
Member

alexandrudima commented Apr 6, 2017

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

@tallpants

This comment has been minimized.

Copy link
Author

tallpants commented Apr 7, 2017

Thanks for the workaround! 👍

@graves501

This comment has been minimized.

Copy link

graves501 commented Apr 10, 2017

The workaround works like a charm, thanks!

@tobico

This comment has been minimized.

Copy link

tobico commented May 8, 2017

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.

@navdeepio

This comment has been minimized.

Copy link

navdeepio commented Jun 1, 2017

this workaround isn't working for me on vscode 1.12.2-1..

@alexandrudima

This comment has been minimized.

Copy link
Member

alexandrudima commented Jun 2, 2017

@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.

@Chillee

This comment has been minimized.

Copy link

Chillee commented Jun 21, 2017

@alexandrudima Do you guys plan on fixing this issue at some point? Or is the workaround satisfactory as a long term solution?

@alexandrudima

This comment has been minimized.

Copy link
Member

alexandrudima commented Jun 21, 2017

@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

@Chillee

This comment has been minimized.

Copy link

Chillee commented Jun 21, 2017

Is it tricky or is it feasible as a first time contribution?

timle1 added a commit to timle1/dotfiles that referenced this issue Aug 22, 2017

@alexandrudima alexandrudima changed the title 1.11 no longer respects keyboard mappings with `setxkbmap` on Linux Keyboard mappings with `setxkbmap` on Linux not working Nov 24, 2017

@kylebakerio

This comment has been minimized.

Copy link

kylebakerio commented Mar 19, 2018

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".

@dagolinuxoid

This comment has been minimized.

Copy link

dagolinuxoid commented Mar 27, 2018

Great, now I can use vim mode :)

@jhpratt

This comment has been minimized.

Copy link

jhpratt commented Apr 10, 2018

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).

@dagolinuxoid

This comment has been minimized.

Copy link

dagolinuxoid commented Apr 12, 2018

@jhpratt, Ctrl + ` works ( at least in my case it toggles the terminal without issues )

@Loridawn99

This comment has been minimized.

Copy link

Loridawn99 commented Apr 12, 2018

Awesome

@pumpkinlink

This comment has been minimized.

Copy link

pumpkinlink commented Jul 20, 2018

same problem as @jhpratt, the workaround breaks a lot of shorcuts, (I use an ABNT2 (Brazil) keyboard)

@pumpkinlink

This comment has been minimized.

Copy link

pumpkinlink commented Jul 20, 2018

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:

  1. Reset the extension.vim_escape keybinding on the GUI Keyboards Shortcuts screen and remove everything related from keybinding.json
  2. 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']"

@rustonaut

This comment has been minimized.

Copy link

rustonaut commented Aug 6, 2018

@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.

@alexandrudima

This comment has been minimized.

Copy link
Member

alexandrudima commented Aug 7, 2018

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 keyCode field 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 keyCode concept from Windows.
  • browsers have used creative solutions to come up with keyCode values which appear to make sense on Linux and OSX, but they are inherently broken because the concept of keyCode does 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 keyCode to 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 the setxkbmap customizations, it appears we need to improve that code...
  • so, in cases where one is using setxkbmap it is probably better to dispatch using the previous keyCode solution, 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 using setxkbmap and when using a different keyboard layout (like de-DE, etc.) it is preferable to run VS Code with dispatching on code.

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.

@andyl

This comment has been minimized.

Copy link

andyl commented Aug 7, 2018

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> ?

@alexandrudima

This comment has been minimized.

Copy link
Member

alexandrudima commented Aug 8, 2018

@andyl Configure "keyboard.dispatch": "keyCode". Restart VS Code.

@rustonaut

This comment has been minimized.

Copy link

rustonaut commented Aug 8, 2018

@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 😭 .

@alexandrudima

This comment has been minimized.

Copy link
Member

alexandrudima commented Aug 8, 2018

They are working on it, it just takes time... https://wicg.github.io/keyboard-map/

@andyl

This comment has been minimized.

Copy link

andyl commented Aug 8, 2018

@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.

@rustonaut

This comment has been minimized.

Copy link

rustonaut commented Sep 5, 2018

The "keyCode" workaround just stopped working for me.

@efredzb

This comment has been minimized.

Copy link

efredzb commented Sep 22, 2018

Same here.

@JoschD

This comment has been minimized.

Copy link

JoschD commented Oct 16, 2018

Ubuntu 18.04.1 here: "keyboard.dispatch": "keyCode" still works. (With swapescape)

@mlcamilli

This comment has been minimized.

Copy link

mlcamilli commented Oct 23, 2018

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.

@certik

This comment has been minimized.

Copy link

certik commented Oct 29, 2018

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.

@mlcamilli

This comment has been minimized.

Copy link

mlcamilli commented Oct 30, 2018

@certik did not work for me

@codethief

This comment has been minimized.

Copy link

codethief commented Nov 13, 2018

Since a lot of people here seem have esc bound to their caps lock keys, let me throw in the hat for the folks that have ctrl bound to the space key. Yes, the space key.(†) Needless to say, VS Code doesn't handle this well with dispatch set to code – every time I use space as ctrl it interprets it as a key chord of space and ctrl+<the other key I'm pressing>.

I'm mentioning this because I am not sure solutions that add setxkbmap support to VS Code will solve this, as most solutions that bind ctrl to the space key seem to work in a different way from what I've gathered. (Though I should mention that I don't understand too much about the mess that is xmodmap, setxkbmap et cetera, so I could easily be wrong.) Anyway, it would be great if at least one of the "ctrl->space" implementations (see below) were supported eventually. :) …or if at least the "keyCode" dispatch mode doesn't get deprecated afterwards.

Speaking of which, the latter actually seems to work fine for me on a "de-DE" keyboard. @alexandrudima: Is there a particular reason the "code" mode is recommended for German keyboards or is there anything that doesn't work in "keyCode" mode that I haven't noticed?

--

† For those who haven't heard of this: The space key basically acts as ctrl when held down and as space when hit quickly. Not only is this a lot more comfortable to use as your strongest finger – the thumb – is doing all the work; it can also really work wonders when you're dealing with RSI-related issues. In case anyone's interested, here're some solutions I'm aware of that implement this:

  • xcape (very simple installation and generally works great; though, when hot plugging another keyboard it sometimes needs to be restarted)
  • at-home-modifier-evdev (more involved installation but probably the best / most polished solution of the bunch)
  • Space2Ctrl (works ok-ish; hot plugging a keyboard trips it up in 99% of the cases)
  • keydouble (last time I tried this, keyboard input lagged but maybe I did something wrong)
@andyl

This comment has been minimized.

Copy link

andyl commented Nov 13, 2018

Yesterday I found that my problem was a bad setting in keybindings.json. Once I removed this, works fine on Xubuntu 18.04 configured using setxkbmap -option caps:swapescape.

@olofwalker

This comment has been minimized.

Copy link

olofwalker commented Jan 15, 2019

On Ubuntu 18.04, if you remap the Capslock to Ctrl, you always have to press enter when using the Ctrl+Tab to switch to a new editor. But this behavior is not unique to VS Code, it also happens in the Vivaldi browser that have a similar "switcher".

Using the record keys in Keyboard shortcuts, I can see that when pressing Ctrl+Tab (using the remapped CapsLock as Ctrl) it reports CapsLock Ctrl+Tab, which is different from the "normal" Ctrl+Tab.

@mlcamilli

This comment has been minimized.

Copy link

mlcamilli commented Jan 15, 2019

I experience exactly what @olofwalker described. All of my bindings with capslock bound to ctrl do not work because of this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment