April 10, 2014

Hacking Your Linux Keyboard with xkb

The humble computer keyboard supports multiple languages, layouts, and custom hotkeys, and Linux has the tools to hotrod it to your heart's content.

The difference between the typewriter and computer keyboard is the computer keyboard is programmable. Two different systems control keyboard input in Linux. The kernel manages console keyboard input, and in X it's managed by xkb, X Keyboard. xkb controls keymapping, keyboard models, and layouts. Today we'll learned how to make customizations with the stock xkb configuration. Messing with keyboard hacking is addictive, so in a few weeks we'll look at making our own customizations.

Keyboards and Wheels

Until the glorious day of talking computers arrives, and by that I mean easy and universal voice recognition and good speech output replacing the rinky-dinky hacks we have now that have not advanced since the early 2000s, our main interface with computers is the keyboard. Ponder this for a moment. The keyboard, descended from the typewriter. The concept of the typewriter goes back to the 1700s, and maybe even further back in time. Typewriters have been in service since the 1800s. Old technology isn't necessarily bad technology; after all, we still use the wheel, and Linux is a libre Unix variant. Philosophical digressions aside, good touch-typing skills are still essential to using a computer.

cm keyboard

If you work on your computer a lot, a nice keyboard matters. You can get a decent rubber-dome keyboard for way cheap these days. You can also get a nice mechanical keyboard for not much more money. A mechanical keyboard has easily-replaceable keycaps and switches, and options for key switches with different levels of responsiveness and clickiness. My keyboard is a Cooler Master Storm QuickFire Rapid Tenkeyless Mechanical Keyboard with Cherry Brown switches (figure 1). Which is a long name for a compact keyboard. It costs under $100, and you have your choice of blue, brown, red, or green Cherry MX switches. The colors represent different levels of tactile and clicky feedback.

Red switches have a low actuation level, so they are fast and responsive with a light touch, and they are quiet. These are marketed as gaming switches.

Blue switches are a little bit stiffer than red switches, and make loud clickies.

Brown switches are nice and tactile, take a light touch, and are fairly quiet, but you still get the good clicky feedback.

Green switches are stiff and loud. Some manufacturers use these for select keys such as spacebars and backspace keys.

Mechanical keyboards range in price from around $80 to several hundred dollars. They last forever, and some vendors offer customizations so you can have them exactly the way you want.

Making Caps Lock Obey

The infamous Caps Lock key is a reliable source of woe, even to fabulous touch-typists such as me. My left little finger is my weakest and most wayward finger, and it sometimes presses Caps Lock instead of the A key. Emery Fletcher showed us how to tame it with xmodmap. We're going to use xkbxmodmap is fine for simple tweaks; xkb gives us great keyboard-hacking powers.

Sometimes I needs Caps Lock, so I don't want to disable it completely. So first I disable it, and then toggle both Shift keys to turn Caps Lock on and off. My pinky can pound Caps Lock all it wants to and nothing will happen. Brilliant, yes? Try it with the setxkbmap command first. This is great for testing, as it does not survive reboots:

$ setxkbmap -option "caps:none"
$ setxkbmap -option "shift:both_capslock"

Now pressing Caps Lock does nothing, and pressing both Shift keys toggles Caps Lock, something I'm not likely to do accidentally. Hurrah! We have conquered Caps Lock and bent it to our will. Now how to make these settings persistent? By creating the /etc/X11/xorg.conf.d/10-keyboard.conf file ( /usr/share/X11/xorg.conf.d/10-keyboard.conf for Debian/Ubuntu users), and entering our customizations in it. This is what mine looks like:

Section "InputClass"
        Identifier "system-keyboard"
        MatchIsKeyboard "on"
        Option "XkbLayout" "us"
        Option "XkbModel" "pc104"
        Option "XkbOptions" "shift:both_capslock,caps:none"

shift:both_capslock must come first, or nothing will happen.

Option "XkbLayout" is your country code. Option "XkbModel" selects your keyboard model. xkb includes layouts for a number of keyboard models such as Dell, Logitech, Apple, and HP. Read man xkeyboard-config to see all of your configuration options including country code, keyboard models, layouts, and key mappings.

Killing X

ctrl+alt+backspace is the traditional keypress combination to stop the X server, but a number of distros (mainly Ubuntu and its derivatives) have disabled it. Because we dumb users might do something awful with it, I guess. It's not the best way to stop X, so use it when nothing else works. I put it back on my Kubuntu system by adding it to the Option line in the10-keyboard.conf file. This must be on a single line:

 Option "XkbOptions" "terminate:ctrl_alt_bksp,shift:both_capslock,caps:none"

Exit your X session and log back in to activate your changes. Verify by testing them, and setxkbmap displays your settings:

$ setxkbmap -query
rules:      evdev
model:      pc104
layout:     us
options:    terminate:ctrl_alt_bksp,shift:both_capslock,caps:none

evdev is the kernel's input driver. You can clear all of your options, including the ones you added to your 10-keyboard.conf file, by running setxkbmap with an empty option set:

$ setxkbmap -option ""

This is useful while you're testing. Logging out of X/logging back in puts your options back. Or you can use setxkbmap again:

$ setxkbmap -option "terminate:ctrl_alt_bksp,shift:both_capslock,caps:none"

Making Caps Lock Useful

Maybe you don't want your Caps Lock key to be useless. You can assign other actions to it, such as caps:swapescape. This swaps Caps Lock with the ESC key. If you use Caps Lock a lot, try caps:shift_nocancel, which disables the Shift key from overriding Caps Lock. caps:shiftlock forces all keys into uppercase when Caps Lock is pressed. The normal behavior is for Caps Lock to only affect the letter keys, and not numbers and punctuation. You can also reassign Caps Lock to act as the Hyper, Super, or Backspace key.


Two more great customizations you can make with xkb are installing and quickly switching between multiple layouts, and doing per-user customizations that are not in man xkeyboard-config. Stay tuned for a nice how-to in the near future.


man setxkbmap

man xkeyboard-config