Linux Keyboard Layout – Can Two Keyboards Have Different Layouts?

debiankeyboard-layoutlinux

I prefer a Dvorak layout, so I have a nice USB Das Keyboard and I have assigned it a layout that works for me on Virtual Console and in X11. I used loadkeys and install-keymap to arrange for it to take effect from boot onwards, and I'm very happy with that.

However, most of my colleagues prefer Qwerty layout, and this is an impediment to pair programming. I do have a selection of usable USB keyboards that I could attach for this task, but they all pick up my Dvorak layout when they are plugged in.

Is there a way that I can tell udev (or even just X11) to use a Qwerty layout for my additional keyboards? They have distinct USB vendor and device identifiers that I can use to distinguish them.

My system is Debian Testing, with udev version 232. It got infected with systemd when I reinstalled after a disk failure, so the standard (SysV-style) approaches I'm used to won't work.

The similar question Different keyboard layout for each keyboard didn't provide any help to me.

Best Answer

General background: Keys get assigned three different sets of "codes", first the scancode (arbitrary hardware dependent number the represents the key on the keyboard), then the keycode (more abstract number that represents a particular key, e.g. shift or 1 / !), and finally the keysym (key symbol, the actual symbol like á produced by a key or combination of keys).

I recently learned that each /dev/input/event* device carries its own scancode-to-keycode mapping. These mappings can be read and altered by iotcls (EVIOCGKEYCODE_V2, EVIOCSKEYCODE_V2), but funnily enough, there don't seem to be general tools available to access these mappings (I quickly wrote a simple C program dump it, as I was curious).

Both the Linux kernel and X then map keycodes to keysyms. For the kernel, there's just one global mapping, the kbd handler (or at least one global mapping for very virtual console, I'm not sure if different virtual consoles can have different mappings). X maintains a mapping for each device.

So if you want differences between keyboards on the virtual console, the only choice left is to use the scancode-to-keycode mapping. For Dvorak vs. Qwerty this might actually work as long as you just remap letter keys, and don't want to remap symbols in shifted and non-shifted state differently.

More recent versions of udev use a hardware database (/etc/udev/hwdb.d) to initialize special scancode-to-keycode mappings, and you can add your own custom versions.

The alternative is to live with either Dvorak or Qwerty on the virtual console, but setup X to use different keycode-to-keysym mappings for each, as described in the answer you linked that didn't help you (probably because you don't want this variant). The advantage of this method is that you can also map symbols, dead keys, compositions etc. differently.

Related Question