I teach a lecture on object-oriented programming in Java, and I spend a lot of time writing code in my favorite terminal editor, kakoune, in front of my class. My students asked me to find a utility that I like for displaying the keys that I press so that they can learn the commands and shortcuts that I use.
After searching for a good application for a while, I found
screenkey, which is available in the default Debian repositories. It creates a nice banner across the screen that displays recently pressed keys. It like it because it shows a history (for a short time) instead of simply the keys being pressed now. This should allow students to write down patterns for their future reference.
I was thrilled with
screenkey until the first time that I unlocked my machine while it was running. Once my lock screen cleared, I was greeted with my password displayed in plaintext on the screen.
I suppose that
screenkey has access to the input even while the screen is locked. I don’t know enough X internals to know why. In any event, I resolved that screenkey should automatically be killed if/when my screen locks.
I’m currently running GNOME, so I spent some time looking for how to execute a hook on lock in GNOME. Sadly, there isn’t any official support for that (at least, not that I could find). Instead, I found this AskUbuntu question that gave me the hint that I needed. Apparently,
dbus sends an event when the screen is locked. I can write a script that listens for that event and takes an action when it occurs. After some experimentation, I came up with the following script:
#!/bin/bash dbus-monitor --session "interface='org.gnome.ScreenSaver'" | \ ( while true do read X if echo "$X" | grep "interface=org.gnome.ScreenSaver" &> /dev/null; then pkill screenkey &> /dev/null fi done )
It simply looks for
dbus messages that contain the
member=Lock attribute (which are always issued when the screen is locked) and kills all instances of
screenkey. You would think that the argument to
dbus-monitor would filter down to only the requested events, but the pipe to
grep is actually necessary in order to only trigger this when a screen-saving-related message appears on the bus. This worked well for me, but I had to launch it manually. To make it launch on login I had to create a GNOME (well XDG, but whatever) autostart desktop file at
~/.config/autostart/lock-hook.desktop that looks like this:
[Desktop Entry] Name=Lock Hook Type=Application Comment=A script to run custom commands on screen lock Exec=/home/chris/.local/bin/lock-hook.sh
I had to spend some time with the official spec to get all of the required keys in place, but we got there eventually. Once I moved the script above to the path referenced in the desktop file, this setup worked flawlessly.
I can now launch
screenkey with the assurance that it will be dead as soon as I lock the screen. It might be better to do with this a userspace
systemd service (so that it would restart itself automatically if it somehow crashed), but this setup works for now.
Many thanks to Andrew Thorp for his help with the Xorg suspension process and a tip about the