Keylock Indicator Alternative (DIY in Bash).

I have been, for many years, a happy user from Thea Barnes's keylock-indicator. The thing is, my good Manjaro XFCE broke down recently and I had to reinstall it from scratch, and then found that this package in AUR is throwing an error message when you compile it. I tried then xfce4-kbdleds-plugin which works but gives almost no options to customize and also doesn't include indicator's Notify on the top right of my screen.

Then it hit me: "I can do this in plain Bash the way I want it".

So, my humble idea is simple: create a script that reads Caps Lock and Num Lock status, send a Desktop Notification every time they change and finally, if you wish so, load that script at boot time.

If you are going to use the script verbatim, install first the Numix icon set from AUR (numix-icon-theme-git). Then create a new file and save it in your profile, say, a folder in /home/youruser/scripts and some name like Copy/paste this code, save and exit the text editor:


# Initialize both keys status
read -r CurrentCapsStatus CurrentNumStatus <<< "$(awk '/Caps Lock/ {print $4" "$8}' <<< "$(xset q)")"

while true; do
  # Read status again
  read -r CapsStatus NumStatus <<< "$(awk '/Caps Lock/ {print $4" "$8}' <<< "$(xset q)")"
  # Now look for changes and react accordingly
  if [ "$CapsStatus" != "$CurrentCapsStatus" ]; then
	 case $CapsStatus in
	    "on"  ) NotifyIcon="changes-prevent";;
		"off" ) NotifyIcon="changes-allow";;
	 notify-send -t 1 -i "$NotifyIcon" "Caps Lock ""$CapsStatus"
  if [ "$NumStatus" != "$CurrentNumStatus" ]; then
	 case $NumStatus in
	    "on"  ) NotifyIcon="changes-prevent";;
		"off" ) NotifyIcon="changes-allow";;
	 notify-send -t 1 -i "$NotifyIcon" "Num Lock ""$NumStatus"

Change the file's attributes so it can run in your console:

chmod 755

Now run the script, keep it in background:

./ &

And voilà, every time you press one of those keys you'll get a brief Desktop Notification :grin:

The script, as you can see, is quite simple. "xset q" prints several key status which then are parsed with awk. An infinite loop keeps reading (and printing) any change. I choose "changes-prevent" and "changes-allow" icons (a nice open/closed yellow padlock) but you can look for another ones if you like, they are usually on /usr/share/icons folder.

Finally, if you want the script to load at boot, go to Settings Manager --> Session and Startup --> Application Autostart Tab. Click on Add and create a new item specifying the full script's path in Command (ie, /home/myuser/scripts/ &).


1 Like

Moved to Showcase category, since this is not a request for Technical Assistance.

Nice script! There is probably room for optimisation, though, because running awk in an infinite loop seems slightly excessive.

Also, there seems to be a syntax error in the awk script, with unmatched quotes:

awk '/Caps Lock/ {print $4" "$8"}'
1 Like

Ups, thank you for nothing this, fixed. :sweat_smile:

I went ahead with awk because (I think) is a more compact and elegant approach than the usual grep/cut one.

Usually one does not need to be very concerned with performance, but if you have a script that is constantly running in an infinite loop, performance can be an issue. awk is not very light on CPU. I think in this case, the lightest option would be Bash substring commands, as that does not run an external process like awk, grep, or cut. It's a messy code, but one that runs fast and without consuming too much resources. You basically only need to catch the "n" in "on" and the "f" in "off".

Another thing you could do to improve the performance of your script is to add a sleep command inside that loop (for example, check the status of keylocks every second or so). That would mean that the notifications about keylocks would lag a bit, but it would reduce the cpu footprint of the script significantly.

Forum kindly sponsored by