A udev event monitor to configure X

We investigate the problem of re-configuring X settings, like keyboard settings, when input devices are plugged in, e.g., a USB keyboard. Instead of deploying system-wide udev rules for a specific user, we present a solution based on udev monitoring and user-specific systemd services.

Motivation

Highly effective keyboard users typically customize their keyboard rate settings to lower the delay and increase the repeat frequency like xset r rate 200 60. Either such settings are supported by a desktop environment, like Gnome or Plasma, or one can simply add the above command to a ~/.xinitrc or ~/.xprofile file.

However, when a keyboard is plugged in dynamically – e.g., when a laptop is plugged into a docking station – then these settings are not used and we need to re-apply these settings.1

We have different ways to handle this situation:

  • Make system-wide decision on settings in /etc/X11/xorg.conf.d or so. But this affects all users. (And if I recall right then still there are issues when plugging a keyboard later.)

  • Likewise, add a system-wide udev rule that calls a user script when a corresponding device is added. But this ugly and hacky – not least, we still have user-specific configs in system-wide directories.

  • Others wrote scripts that would apply the settings every 5 seconds or so.

What we want:

  • A solution that can be done with user privileges rather than system-wide settings.

  • Event-based trigger to apply settings rather than periodic re-applying of settings based on magic sleeps.

Solution

The source for an event-based solution is UDEV, which notices when an input device (e.g., keyboard) is plugged in. There is a tool udevadm than can be put in monitor mode and reports UDEV events. In particular, we can call udevadm monitor -u -s input to learn about all UDEV events concerning the input subsystem.

The following code would fire notifications for every such event:

udevadm monitor -u -s input | grep --line-buffered add | while read line; do
    notify-send ">> $line"
done

So instead of notify-send you can place your respective settings into a ~/.xprofile-udevinput script – e.g., to call xset or whatever – and execute it.

All we now need is a method to fire up the above monitor script. Nowadays, the answer to this is systemd service files that can be installed and enabled per user.

Download

The entire code can be found in the git repo shutils, including an install.sh.

  1. Unless the desktop environment takes care for exactly this logic.