Skip to content

Instantly share code, notes, and snippets.

@hencjo
Created February 13, 2018 13:27
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save hencjo/0710d51c5ba51e0aeb2d905f1e3a38f3 to your computer and use it in GitHub Desktop.
Save hencjo/0710d51c5ba51e0aeb2d905f1e3a38f3 to your computer and use it in GitHub Desktop.
Xorg: Two keyboards with different keyboard layout.
# Use xinput to find your keyboards.
$ xinput
⎡ Virtual core pointer id=2 [master pointer (3)]
⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)]
⎜ ↳ SynPS/2 Synaptics TouchPad id=11 [slave pointer (2)]
⎜ ↳ TPPS/2 IBM TrackPoint id=12 [slave pointer (2)]
⎜ ↳ Logitech Performance MX id=14 [slave pointer (2)]
⎜ ↳ E-Signal USB Gaming Keyboard id=16 [slave pointer (2)]
⎣ Virtual core keyboard id=3 [master keyboard (2)]
↳ Virtual core XTEST keyboard id=5 [slave keyboard (3)]
↳ Power Button id=6 [slave keyboard (3)]
↳ Video Bus id=7 [slave keyboard (3)]
↳ Sleep Button id=8 [slave keyboard (3)]
↳ Integrated Camera id=9 [slave keyboard (3)]
↳ AT Translated Set 2 keyboard id=10 [slave keyboard (3)]
↳ ThinkPad Extra Buttons id=13 [slave keyboard (3)]
↳ Sennheiser Sennheiser 3D G4ME1 id=15 [slave keyboard (3)]
↳ E-Signal USB Gaming Keyboard id=17 [slave keyboard (3)]
# My keyboards are id 10 (laptop integrated) and id 17 (external keyboard).
# Now, set my external keyboard to be Swedish layout, and my internal to Dvorak:
$ setxkbmap -device 17 se
$ setxkbmap -device 10 dvorak
# Done!
@mxa
Copy link

mxa commented Jun 13, 2019

Is there a way to put this into a udev rule so it is automatic every time?
Problem being that the id changes often when USB devices are plugged in or unplugged. For a udev rule a vendor/product id solution would be suitable.

@hencjo
Copy link
Author

hencjo commented Jun 13, 2019

Honestly, I have no idea because I don't know nearly enough about udev. I only use this sporadically when pairing, so I don't mind fiddling a bit beforehand. If you do find a persistent solution, I would be interested to learn how you did!

@epakai
Copy link

epakai commented May 13, 2021

I found a udev solution at: https://askubuntu.com/a/809398

Adjust to suit your vendor/product and layout preferences. This is my /etc/udev/rules.d/66-keyboard.rules

ACTION =="add", ATTRS{idVendor} =="081e", ATTRS{idProduct} =="bd04", ENV{XKBMODEL}="pc104", ENV{XKBLAYOUT}="us", ENV{XKBVARIANT}="", ENV{XKBOPTIONS}="ctrl:nocaps"

Reload rules with:
sudo udevadm control --reload-rules

Your Xorg log should reflect the correct layout when you plug in a matching keyboard.

@mxa
Copy link

mxa commented May 14, 2021

I found a udev solution at: https://askubuntu.com/a/809398

Is this working for you? On which OS / Version?

@epakai
Copy link

epakai commented May 14, 2021

Yes. I'm currently using it on Debian 10 (buster). When plugging the matching keyboard in /var/log/Xorg.0.log I see:


> 
> [1086675.797] (II) config/udev: Adding input device AlphaSmart, Inc. AlphaSmart (/dev/input/event256)
> [1086675.800] (**) AlphaSmart, Inc. AlphaSmart: Applying InputClass "evdev keyboard catchall"
> [1086675.800] (**) AlphaSmart, Inc. AlphaSmart: Applying InputClass "libinput keyboard catchall"
> [1086675.801] (II) Using input driver 'libinput' for 'AlphaSmart, Inc. AlphaSmart'
> [1086675.801] (**) AlphaSmart, Inc. AlphaSmart: always reports core events
> [1086675.801] (**) Option "Device" "/dev/input/event256"
> [1086675.801] (**) Option "_source" "server/udev"
> [1086675.806] (II) event256 - AlphaSmart, Inc. AlphaSmart: is tagged by udev as: Keyboard
> [1086675.806] (II) event256 - AlphaSmart, Inc. AlphaSmart: device is a keyboard
> [1086675.806] (II) event256 - AlphaSmart, Inc. AlphaSmart: device removed
> [1086675.852] (**) Option "config_info" "udev:/sys/devices/pci0000:00/0000:00:01.3/0000:02:00.2/0000:03:00.0/0000:04:00.0/usb3/3-2/3-2.1/3-2.1:1.0/0003:081E:BD04.003D/input/input96/event256"
> [1086675.852] (II) XINPUT: Adding extended input device "AlphaSmart, Inc. AlphaSmart" (type: KEYBOARD, id 26)
> [1086675.852] (**) Option "xkb_model" "pc104"
> [1086675.852] (**) Option "xkb_layout" "us"
> [1086675.852] (**) Option "xkb_options" "ctrl:nocaps"
> [1086675.889] (II) event256 - AlphaSmart, Inc. AlphaSmart: is tagged by udev as: Keyboard
> [1086675.889] (II) event256 - AlphaSmart, Inc. AlphaSmart: device is a keyboard

@mxa
Copy link

mxa commented May 14, 2021

In Kubuntu 21.04 with
ACTION =="add", ATTRS{idVendor} =="3938", ATTRS{idProduct} =="2202", ENV{XKBMODEL}="pc104", ENV{XKBLAYOUT}="kr", ENV{XKBVARIANT}="", ENV{XKBOPTIONS}="compose:caps"

my log shows indeed

[ 39777.230] (II) config/udev: Adding input device MAXTILL Blade Keyboard (/dev/input/event17)
[ 39777.230] (**) MAXTILL Blade Keyboard: Applying InputClass "libinput keyboard catchall"
[ 39777.230] (II) Using input driver 'libinput' for 'MAXTILL Blade Keyboard'
[ 39777.230] (**) MAXTILL Blade Keyboard: always reports core events
[ 39777.230] (**) Option "Device" "/dev/input/event17"
[ 39777.230] (**) Option "_source" "server/udev"
[ 39777.240] (II) event17 - MAXTILL Blade Keyboard: is tagged by udev as: Keyboard
[ 39777.241] (II) event17 - MAXTILL Blade Keyboard: device is a keyboard
[ 39777.241] (II) event17 - MAXTILL Blade Keyboard: device removed
[ 39777.250] (**) Option "config_info" "udev:/sys/devices/pci0000:00/0000:00:14.0/usb3/3-4/3-4.4/3-4.4.1/3-4.4.1:1.3/0003:3938:2202.0057/input/input221/event17"
[ 39777.250] (II) XINPUT: Adding extended input device "MAXTILL Blade Keyboard" (type: KEYBOARD, id 12)
[ 39777.250] (**) Option "xkb_model" "pc104"
[ 39777.250] (**) Option "xkb_layout" "kr"
[ 39777.250] (**) Option "xkb_options" "compose:caps"
[ 39777.255] (II) event17 - MAXTILL Blade Keyboard: is tagged by udev as: Keyboard
[ 39777.255] (II) event17 - MAXTILL Blade Keyboard: device is a keyboard

However, only the keyboard layout widget in the system tray can actually change the layout.

@doragasu
Copy link

Shouldn't it be possible to set the mapping in an evdev confg file in /etc/X11/xorg directory? If possible I think this is more natural than using an udev rule for this. Unfortunately I do not know how to achieve it.

@doragasu
Copy link

Well, it did not take long, I have tried myself doing a configuration that allows me changing between "us" and "us intl" in the internal laptop keyboard, and between "es", "us" and "us intl" for external USB keyboards. It works like a charm:

Section "InputClass"
        Identifier "evdev keyboard catchall"
        MatchIsKeyboard "on"
        MatchDevicePath "/dev/input/event*"
        Driver "evdev"
        Option "XkbLayout" "es,us,us"
		Option "XkbVariant" ",,intl"
		Option "XkbOptions" "grp:lalt_lshift_toggle"
EndSection
Section "InputClass"
        Identifier "evdev internal keyboard"
        MatchIsKeyboard "on"
        MatchDevicePath "/dev/input/event*"
	MatchProduct "AT Translated Set 2 keyboard"
        Driver "evdev"
        Option "XkbLayout" "us,us"
		Option "XkbVariant" ",intl"
		Option "XkbOptions" "grp:lalt_lshift_toggle"
EndSection

@mxa
Copy link

mxa commented Aug 27, 2021

Shouldn't it be possible to set the mapping in an evdev confg file in /etc/X11/xorg directory? If possible I think this is more natural than using an udev rule for this. Unfortunately I do not know how to achieve it.

I don't have a xorg folder in /etc/X11/ (ubuntu 21.04) should I create that?

@doragasu
Copy link

Sorry, the correct directory is /etc/X11/xorg.conf.d/, at least in ArchLinux

If you don't have neither directory, maybe you can try searching where the .conf files are in /etc/X11, I suppose there should be some .conf files in there.

@benjamin-asdf
Copy link

Hi, I'd like to make the space key of the second keyboard output hyper or some other key. Does somebody know how do do that?

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