Autumn leaves

Killing screenkey on Lock

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 .config/autostart/ directory.

Image Credit: Stefan Lins
Image License: CC BY-NC 2.0

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.