A Weird Imagination

Reacting to screensaver starting/stopping

Posted in

The problem#

I want my computer to act differently when I'm actively using it as opposed to away from. I almost always lock the screen when I step away from my computer, so I want to have the same signal do more than just start the screensaver.

The solution#

Save the follow script which is slightly modified from the example in the man page for xscreensaver-command as watch-xscreensaver.pl:

#!/usr/bin/perl

my $blanked = 0;
open (IN, "xscreensaver-command -watch |");
while (<IN>) {
    print;
    if (m/^(BLANK|LOCK)/) {
        if (!$blanked) {
            system "on-xscreensaver-lock";
            $blanked = 1;
        }
    } elsif (m/^UNBLANK/) {
        system "on-xscreensaver-unlock";
        $blanked = 0;
    }
}
if ($blanked) {
    system "on-xscreensaver-unlock";
}

Either call it from your ~/.xsessionrc file or just manually run from a terminal in your X session. I run it from a screen session so I can reattach to it and see the output:

screen -d -m -S xscreensaver-watch watch-xscreensaver.pl

My on-xscreensaver-lock and on-xscreensaver-unlock scripts are below and may be a good starting place, but yours will probably be different depending on your needs.

The details#

My lock/unlock scripts#

on-xscreensaver-lock#

#!/bin/sh

echo "In on-xscreensaver-lock..."
for pidfile in ~/tmp/run/kill-on-lock/*.pid
do
    kill "$(cat "$pidfile")"
    rm "$pidfile"
done

# Mute audio
pactl set-sink-mute 0 1

PIDDIR=~/tmp/run/kill-on-unlock
mkdir -p $PIDDIR

cpulimit-all.sh --limit=1 -e firefox \
    -e firefox-esr -e chromium -e chrome &
echo $! > "$PIDDIR/cpulimit-all-browsers.pid"

on-xscreensaver-unlock#

#!/bin/sh

echo "In on-xscreensaver-unlock..."
for pidfile in ~/tmp/run/kill-on-unlock/*.pid
do
    kill "$(cat "$pidfile")"
    rm "$pidfile"
done

PIDDIR=~/tmp/run/kill-on-lock
mkdir -p $PIDDIR

unmute-on-netflix-focused &
echo $! > "$PIDDIR/unmute-on-netflix-focused.pid"

joystickwake &
echo $! > "$PIDDIR/joystickwake.pid"

PID file handling#

The two scripts communicate via directories containing PID files: all of the long-running tasks that run only while the screensaver is active are killed when it is stopped and vice versa. That way the tasks can be ended without the scripts needing to know which tasks the other one runs.

If there were many long-running scripts to run, I could have listed them in a directory instead of directly putting them in the script:

for script in on-xscreensaver-lock.d/*
do
    "$script" &
    echo $! > "$PIDDIR/$(basename "$script").pid"
done

... but that seemed like over-engineering for what the script actually does.

CPU limiting#

The main reason I have this script is to use my browser CPU limiting script to stop web browsers from using my processor while the screensaver is on. Web browsers are entirely for content I am actively reading and interacting with: any computation a web browser is doing while I'm not at my computer is wasted. That argument applies to most other applications as well, but I've only encountered problems with web browsers and can easily add more programs to the list if necessary. Also note that I don't bother using the --watch-interval option because no new web browser processes are likely to start while I'm not actively using the web browser.

Sound handling#

I never want my computer to play sound when I'm not actively using it, so I mute the sound when the screensaver activates. To make this less of an inconvenience, when the screensaver stops, I run the script to automatically unmute the sound when Netflix is active.

Comments

Have something to add? Post a comment by sending an email to comments@aweirdimagination.net. You may use Markdown for formatting.

There are no comments yet.