My screen locking configuration

My i3 desktop

Inspired by a comment on reddit I am sharing my screen locking configuration in this post, I use i3, xautolock and a custom lock script.

2020-06-02

I use i3 as a window manager and have it configured so that I can quickly lock the screen, and so that my screen locks automatically when I idle for a few minutes. The manual locking is done by hitting the Print key twice, I use a mode for this as shown below. The mode is called "switch" because that's what I use it mostly for, to switch between workspaces, but that's not relevant for this post.

mode "switch" {
        bindsym Print exec ~/local/scripts/lock.sh force; mode "default"
        # Abort
        bindsym Return mode "default"
        bindsym Escape mode "default"
}
bindsym Print mode "switch"

A lockfile can be used to disable the automatic locking, so the i3 exec passes the force argument to the lock script.

The lock script itself is shown below. It guarantees that only one instance of i3lock is started but could call any other locking tool.

#!/bin/bash

MUTEX="${HOME}/.config/i3/i3-lock"
LOG="${HOME}/.config/i3/lock-log"
NOLOCK="${HOME}/.config/i3/NOLOCK"

VERSION="0.5"

log () {
	when=$(date "+%Y-%m-%d %H:%M:%S")
	msg="[lock ${VERSION}] ${when} $1"
	echo "${msg}" >> "${LOG}"
}

lock () {
	if [ ! -f "${NOLOCK}" ]; then
		i3lock --nofork --image ~/.config/i3/i3lock.png --tiling --ignore-empty-password --show-failed-attempts
	else
		log "${NOLOCK} found, not locking"
	fi
}

if [ "$1" = force ]; then
	log "Forcing lock, removing ${NOLOCK}"
	rm -rf "${NOLOCK}"
fi

# See https://mywiki.wooledge.org/BashFAQ/045
if /bin/mkdir "$MUTEX"; then
	log "Successfully acquired lock"

	trap 'rm -rf "$MUTEX"' 0	# remove mutex when script finishes

	lock
else
	log "cannot acquire lock, giving up on $MUTEX"
	exit 0
fi

This code was originally published on My i3lock wrapper script.

The automatic locking is enabled with the following line in my .xsession file. I use that file to start my X session and launch assorted tools and not i3's built-in ability to do the same because I tend to switch window managers every few years and want to keep everything portable.

xautolock -time 3 -locker ~/local/scripts/lock.sh &

I also have a shell function in my .bashrc to toggle the auto-locking feature temporarily, and a cronjob to ensure that I don't accidentally leave my workstation unlocked for a long time.

nolock () 
{ 
    lock="${HOME}/.config/i3/NOLOCK";
    if [ -f "${lock}" ]; then
        rm -f "${lock}";
    else
        touch "${lock}";
    fi
}

I use the function below in my bash prompt to keep track of the current automatic lock status, it shows either a red X (locking disabled) or a green L (locking enabled) in my prompt.

fred="\033[31m"
freset="\033[0m"
fgreen="\033[32m"

lockstatus () {
        NOLOCK="${HOME}/.config/i3/NOLOCK"
        if [ -f "$NOLOCK" ]; then
                echo -ne "[${fred}X${freset}]"
        else
                echo -ne "[${fgreen}L${freset}]"
        fi
}
nolock

That's it. My moderately secure screen locking setup.

The image ~/.config/i3/i3lock.png that i3lock displays is updated every day and is always the same as the desktop background, I like to keep those in sync and use the script below to accomplish this.

#!/bin/sh

backgrounds="${HOME}/Pictures/backgrounds/"
BG_CMD="feh --no-xinerama --bg-center"

get_fitting_image () {
	# We check a directory that contains WIDTHxHEIGHT named subdirectories
	# So if your screen size is 1920x1080 you should have
	# "${backgrounds}/1920x1080"
	resolution=$(xdpyinfo | awk '/dimensions/{print $2}')
	find "${backgrounds}${resolution}" -type f | shuf -n1
}

set_screensaver () {
	# Convert images to png for i3lock if necessary
	# The image is only converted once and cached in the i3 directory
	img=$1
	echo "Set ${img} as i3lock wallpaper"
	png="${img%.*}.png"
	target="${HOME}/.config/i3/$(sha1sum "${img}" | awk '{ print $1 }').png"
	if [ ! -f "$target" ]; then
		if [ "$img" != "$png" ]; then
			echo "Converting source $img to $target"
			convert "$img" "$target"
		else
			cp "$img" "$target"
		fi
	fi
	ln -sf "$target" "${HOME}/.config/i3/i3lock.png"
}

set_background () {
	echo "Set ${1} as desktop wallpaper"
	$BG_CMD "$1"
}

for cmd in xdpyinfo feh convert; do
	if ! command -v "$cmd" >/dev/null 2>&1; then
		echo "$cmd is not installed, this won't work"
		exit 1
	fi
done

if ! xdpyinfo -display "$DISPLAY" >/dev/null 2>&1; then
	echo "I can't seem to connect to display '$DISPLAY'"
	exit 2
fi

img="$(get_fitting_image)"

case ${1:-background} in
	screensaver*)
		set_screensaver "$img"
		;;
	background*)
		set_background "$img"
		;;
	both*)
		set_background "$img"
		set_screensaver "$img"
		;;
esac

This code was originally published on Set random background image and i3lock wallpaper.

0 comments

Start a new thread

Cancel reply
DjangoPythonBitcoinTuxDebianHTML5 badgeSaltStackUpset confusedMoneyHackerUpset confusedX.OrggitFirefoxWindowMakerBashIs it worth the time?i3 window managerWagtailContainerNginxSilenceTorWorldInternet securityFont