#!/bin/sh
# Helper script to start/lock the screen with an available screen locker.
# Copyright (C) 2015 Simon Ruderich
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
set -eu
usage() {
printf 'usage: %s start \n' "$0"
printf ' %s lock\n' "$0"
exit 1
}
installed() {
type "$1" >/dev/null 2>&1
}
if test $# -eq 0; then
usage
fi
if test x"$1" = xstart; then
if test $# -ne 3; then
usage
fi
lock_time_minutes="$2"
lock_binary="$3"
# NOTE: We must redirect stdout of the spawned background processes to
# /dev/null or a potential caller which uses our output will wait forever
# on the inherited stdin (and we become a zombie)! Thanks to Beano on [1]
# for the idea, read on 2015-08-23.
#
# [1]: https://stackoverflow.com/questions/3748432/insane-crond-behavior-keeps-making-defunct-bash-processes/3750028#3750028
if installed xscreensaver; then
printf 'xscreensaver.timeout: %d
xscreensaver.lock: True
xscreensaver.lockTimeout: 0
' "$lock_time_minutes" | xrdb -merge
xscreensaver >/dev/null &
echo xscreensaver
elif installed xautolock; then
if installed "$lock_binary"; then
# Terminate a running xautolock because we might have to replace
# its timeout and other settings with our values.
pkill -u "$USER" xautolock || true
xautolock -secure -time "$lock_time_minutes" \
-locker "$lock_binary" \
>/dev/null &
echo xautolock
else
echo "Locker '$lock_binary' not installed. Auto lock won't work!"
exit 1
fi
else
echo "No locker found. Auto lock won't work!"
exit 1
fi
elif test x"$1" = xlock; then
if test $# -ne 1; then
usage
fi
if installed xscreensaver; then
# Start xscreensaver if it's not already running. xscreensaver-command
# ensures xscreensaver is available for the current X session.
xscreensaver-command -time >/dev/null 2>&1 || xscreensaver &
# It can take a while for xscreensaver to start, wait until it's
# ready. a || b && c behaves like (a || b) && c.
while :; do
xscreensaver-command -lock || test $? -ne 255 && break
done
elif installed xtrlock; then
# Sleep is necessary to allow xtrlock to grab the keyboard input.
sleep 1
exec xtrlock
elif installed xlock; then
exec xlock
elif installed i3lock; then
exec i3lock
else
echo 'No screen locker found!'
exit 1
fi
else
usage
fi