Here’s the layout of the bottom row of my laptop’s keyboard:

+-----+-----+-----+-----+-------------------+-----+-----+-----+
|     |     |     |     |                   |     |     |     |
|Fn   |Ctrl |Win  |Alt  |       Space       |Alt  |PrtSc|Ctrl | [arrows]
+-----+-----+-----+-----+-------------------+-----+-----+-----+

The Control key is used for the common standard keyboard shortcuts (Ctrl-a to select all, Ctrl-v to paste, etc), but Emacs makes especially heavy use of it (Ctrl-x and Ctrl-c for prefix keys, Ctrl-g to quit, etc). With my hands on the home row, running those commands with that keyboard requires extending my pinkies out and back. Ouch!

Besides being painful, the arrangement of those modifier keys also leads to constantly tripping over PrtSc and capturing a screenshot. Why is the Print Screen key easier to reach than the Control key? Who needs such quick, convenient access to screenshots? I don’t know. What I do know is that Emacs also has a bunch of keybindings that use the control and alt keys together, e.g. Ctrl-Alt-f1 for forward-sexp, and that trying to hit both of those modifier keys at the same time invariably leads to littering my desktop with screenshots.

In Linux, the solution to a shitty keyboard layout is xmodmap. I don’t understand all the intricacies involved, but I have a file called xmodmap-print that looks like this2:

clear lock
clear control
clear mod1
clear mod4

! ! is for comments, in this case showing the keys' original values

! keycode  64 = Alt_L Meta_L Alt_L Meta_L
keycode 64 = Control_L
! keycode 133 = Super_L NoSymbol Super_L
keycode 133 = Alt_L
! keycode  37 = Control_L NoSymbol Control_L
keycode 37 = Super_L

! keycode 108 = Alt_R Meta_R Alt_R Meta_R
keycode 108 = Control_R
! keycode 107 = Print Sys_Req Print Sys_Req
keycode 107 = Alt_R
! keycode 105 = Control_R NoSymbol Control_R
keycode 105 = Super_R

add control = Control_L Control_R Caps_Lock
add mod1 = Alt_L Alt_R
add mod4 = Super_L Super_R

Running xmodmap xmodmap-print shuffles my modiers into a much more pleasant arrangment:

+-----+-----+-----+-----+-------------------+-----+-----+-----+
|     |     |     |     |                   |     |     |     |
|Fn   |Win  |Alt  |Ctrl |       Space       |Ctrl |Alt  |Win  | [arrows]
+-----+-----+-----+-----+-------------------+-----+-----+-----+
  • Control keys are placed on either side of the space bar, where I can bang on them with my thumbs instead of my pinkies.

  • Control and Alt keys are next to each other, and I can again use my thumbs to bash both of them at the same time (in practice, I only use my right thumb for this).

  • PrtSc goes in the trash, and is replaced with another Windows / Super key. No more unwanted screenshots for me!

  • CapsLock also goes in the trash, and is replaced with another Control key. You can never have too many modifiers, and CapsLock is a dumbass key anyway.

Keyboard problem solved!? Well, not quite. Soon after I developed this keyboard setup, my computer started rebooting without warning. I don’t mean freezing or hibernating or anything like that, I mean shutting clean off and then restarting. No messages, no blue screen, nothing.

Needless to say, that’s a frustrating sort of issue to debug. I don’t remember how, but eventually I discovered that the culprit was something called the magic SysRq key.

To explain what this thing does, I’m going to try and describe what I think is happening when keystrokes are processed. I don’t know if my mental model is entirely accurate, but it seems to match the observed behavior. My terminology is definitely not right. (Please send corrections!)

  1. There’s me, the user, and whatever application I’m using – editor, browser, whatever. The user application is the last thing to receive keystrokes.

  2. Prior to the application, keystrokes are processed by the desktop / window environment. I don’t know exactly what this is called, but on Ubuntu it’s Gnome or Unity or whatever. Or X? I’m not sure. In any case, something gets to handle keystrokes before the application, and if it does, the application doesn’t get them. For example, Emacs binds the function down-list to Ctrl-Alt-d. But on Ubuntu 18, that same keybinding is used to switch to the desktop. If the keystroke is something that the window system thinks it should handle, it will, and it won’t pass it along to the application afterwards. Because I’ve been too lazy to fix this, I cannot use Ctrl-Alt-d in Emacs.

  3. Prior even to the desktop / window system is the kernel. The kernel talks directly to the hardware, and therefore has first dibs on all keystrokes. Again, any keystrokes it handles will not get passed along downstream.

So we have the application, the desktop, and the kernel. It’s obvious what the first two can do with keystrokes, as they cover everything that most users want to do with their computers. The list of things the kernel can do with keystrokes, on the other hand, is rather short, and it includes things like terminating processes and displaying register and memory information. In particular, there are also keystrokes to shut off and reboot the system. The latter is bound to the keystroke Alt-SysRq-b.

I still haven’t said where the SysRq key actually is. If you look at my keyboard, you won’t find it, but on older keyboards it can sometimes be found up in the corner among those weird keys that you’ve always wondered about but never used (Scroll Lock?). A typical SysRq key looks something like this:

+-------+
| PrtSc |
| ----- |
| SysRq |
+-------+

According to the labeling there, PrtSc and SysRq inhabit the same key. They inhabit the same key on my keyboard too, but it isn’t labeled. If you take another look at the first keyboard diagram above, you’ll notice that Alt and PrtSc are right next to each other, and it is thus easy to hit them at the same time, potentially triggering a kernel command.

But I remapped my keys, so that shouldn’t be a problem, right? Wrong. xmodmap belongs to the window manager, and that doesn’t handle keystrokes until after the kernel has already passed on them. So when I hit what to me should be Ctrl-Alt-b to run Emacs’s backward-sexp command, the kernel sees that as Alt-SysRq-b before the xmodmap has had a chance to rebind it and reboots the system.

The kernel can be warded off from incoming keystrokes with the incantation

sysctl -w kernel.sysrq=0

This disables all kernel keyboard commands by writing 0 into the file /proc/sys/kernel/sysrq. It would be nice to be able to keep kernel commands, but just rebind them to other keys. Is that possible? I don’t know.

Update

Some reader ideas:

  • Trevor Saunders suggests that loadkeys and dumpkeys might be able to remap keys at the kernel level. I haven’t been able to figure these out yet.
  • Greg Hendershott points out the following from the Wikipedia SysRq page: On Ubuntu [the number written to /proc/sys/kernel/sysrq ] is set at boot time to the value defined in /etc/sysctl.d/10-magic-sysrq.conf. I’d like to say that that was added after I wrote this post, but it fact it was added almost exactly one year ago today <2019-04-12 Fri>, and I just missed it. Anyway, it works, and I no longer have to run that sysctl command every time I turn on my computer.

Footnotes

1 Generally speaking Emacs refers to the Alt key as the Meta key. Emacs also uses a compact notation for keybindings: C-M-f for Ctrl-Meta-f.

2 A program called xev displays information about key codes.