Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link
Owner Author

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

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

@doragasu

This comment has been minimized.

Copy link

@doragasu doragasu commented Aug 27, 2021

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

@doragasu doragasu commented Aug 27, 2021

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.

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