Catproofing my keyboard shortcuts
Problem
I have a number of global keyboard shortcuts configured in my desktop environment (currently Xfce). They are:
| Shortcut | Action |
|---|---|
| Alt+P | Open launcher |
| Alt+F | Open home folder |
| Alt+X | Open web browser |
| Alt+O | Open text editor |
| Shift+Alt+Return | Open terminal |
| Shift+Print | Screenshot full screen |
| Ctrl+Print | Screenshot selection |
| Shift+Ctrl+Print | Screenshot selection (to clipboard) |
| Alt+B | Music: next track |
| Alt+C | Music: play/pause |
| Alt+Z | Music: previous track |
| Alt+D | Music: show current track |
| Alt+F1 | Open applications menu |
| Alt+Q | Lock screen |
My cat likes to flop over on my keyboard, and this can wreak havoc due to the global shortcuts. The main culprits were:
- Alt+F, Alt+X, Alt+O, Shift+Alt+Return: If held down, opens a huge number of windows.
- Alt+B, Alt+C, Alt+Z, Alt+D: Starts making noise, which can be jarring if I'm trying to do something else.
Mitigation: rate limiting
The first mitigation I implemented was rate limiting: instead of opening hundreds of web browser windows, it's limited to a more manageable number. I hacked together a small Python script to do the rate limiting: ratelimit. It is invoked like so:
$ ratelimit --help
usage: ratelimit [-h] [-n N] [-i I] [-k KEY] [-v] cmd [args ...]
Only allow a program to run N times every I seconds
positional arguments:
cmd Command to run
args Arguments to command
options:
-h, --help show this help message and exit
-n, --count N Max executions per interval (default 3)
-i, --interval I Interval to limit execution count within (seconds, default 60)
-k, --key KEY Unique identifier for this command (defaults to command)
-v, --verbose Enable debug output
Mitigation: music player
To defuse the music player shortcuts, I modified them so they only act if the music player is currently running. Previously, they would launch the music player if it wasn't already running. Now, I must explicitly start the music player first.
I'm using Strawberry, so I changed the command from strawberry --play-pause to pgrep strawberry && strawberry --play-pause (and similar for the other shortcuts).
Final configuration
The configuration I ended up with is as follows:
| Shortcut | Command | Note |
|---|---|---|
| Alt+P | dmenu_run |
dmenu |
| Alt+F | ratelimit -- /usr/bin/caja --no-desktop /home/me |
|
| Alt+X | ratelimit -- /usr/bin/firefox |
|
| Alt+O | ratelimit -- /usr/bin/nvim-qt |
|
| Shift+Alt+Return | ratelimit -- /usr/bin/xfce4-terminal |
|
| Shift+Print | screenshot |
screenshot |
| Ctrl+Print | screenshot --select |
|
| Shift+Ctrl+Print | screenshot --select --clip |
|
| Alt+B | sh -c 'pgrep strawberry && ratelimit -- /usr/bin/strawberry --next' |
|
| Alt+C | sh -c 'pgrep strawberry && ratelimit -- /usr/bin/strawberry --play-pause' |
|
| Alt+Z | sh -c 'pgrep strawberry && ratelimit -- /usr/bin/strawberry --previous' |
|
| Alt+D | sh -c 'pgrep strawberry && ratelimit -- /usr/bin/strawberry --show-osd' |
|
| Alt+F1 | xfce4-popup-applicationsmenu |
|
| Alt+Q | xflock4 |
This has been working reasonably well for me.