How to set the keyboard layout for a specific device
Tags: tutorial, linux, x11, windowmanager
Published: 2022-06-10 13:47:39

I have laptop with a Portuguese (PT) keyboard layout and recently I've bought a Keychron K2 which has an US layout. I find it annoying to have to change the keyboard layout to whatever keyboard I'm currently using so I started to try ways to set each keyboard it's proper layout automatically. 

After a lot of struggles trying to understand X11 config files I think I finally got it, and it all comes down to the creation of a `01-keyboard.conf` file at `/etc/X11/xorg.conf.d/` folder, with the following content:

```
Section "InputClass"
        Identifier "Keychron_K2"
        MatchVendor "Keychron"
        MatchProduct "Keychron K2"
        MatchIsKeyboard "on"
        Option "XkbLayout" "us"
        Option "XkbVariant" ",intl"
        Option "XkbOptions" "compose:ralt"
EndSection
```
With this configuration file X11, the thing that handles Monitors, Keyboards, Pointing and Touch Devices, is able to proper configure the keyboard layout whenever I have it plugged in.

## What is happening here?

Whenever you plug a device to a Linux machine, its driver gets loaded by the kernel. You can check the status of that loading processing, and its messages,  by running the `dmesg` command.

Running it on my machine gave me the following results: 

```
[...] usb 3-1: new full-speed USB device number 6 using xhci_hcd
[...] usb 3-1: New USB device found, idVendor=05ac, idProduct=024f, bcdDevice= 1.12
[...] usb 3-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[...] usb 3-1: Product: Keychron K2
[...] usb 3-1: Manufacturer: Keychron
[...] input: Keychron Keychron K2 as /devices/.../usb3/.../input/input33
[...] apple 0003:05AC:024F.000C: input,hidraw0: USB HID v1.11 Keyboard [Keychron Keychron K2] on usb-0000:04:00.3-1/input0
[...] apple 0003:05AC:024F.000D: Fn key not found (Apple Wireless Keyboard clone?), disabling Fn key handling
[...] input: Keychron Keychron K2 as /devices/.../usb3/.../input/input34
[...] apple 0003:05AC:024F.000D: input,hiddev98,hidraw5: USB HID v1.11 Keyboard [Keychron Keychron K2] on usb-0000:04:00.3-1/input1
```

As you can see, `dmesg` shows details about the device and its manufacturer. From here, it is just a matter of leveraging that information to specify which settings we want for your keyboard.
And for that you need to create a X.org configuration file.

You can check the [X.org conf documentation](https://www.x.org/releases/current/doc/man/man5/xorg.conf.5.xhtml) to better understand how it works but, for simplicity, think of it as a way to  select a device, based on its characteristics and features, to be able to a specify configuration or command for that set of devices.

The are a lot of possible settings for those Section file, but for the keyboard layout, I think the following are enough:

1. **Section "InputClass"**
The **InputClass** indicates that we are about to specify configurations for a input device.
2. **Identifier**
This entry is required and it should be an unique name. Kind of like an **Id** for this **InputClass**
3. **MatchVendor**
This entry tries to match the device vendors name with the specified name.
4. **MatchProduct**
This entry tries to match the device product name with the specified name.
5. **MatchIsKeyboard**
This is entry matches only if the device type is a keyboard.
6. **Option "`<OptionName>`" "`<OptionValue>`"**
These entries basically defines options for the xkb command, that should be executed for all of the matched devices. You can specify any option or layout that `xkb` accepts.

After creating that file you are pretty much done. Just logout or reboot you computer and it should assign the specified layout to each device you've identified.

## References
[Xorg Conf](https://wiki.gentoo.org/wiki/Xorg.conf)
[Input Device Configuration](https://fedoraproject.org/wiki/Input_device_configuration)
[Input Class Documentation](https://www.x.org/releases/current/doc/man/man5/xorg.conf.5.xhtml)
[Compose key](https://wiki.gentoo.org/wiki/Compose_key)
[Xkb Configuration](https://www.charvolant.org/doug/xkb/html/index.html)