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} and ${MUTEX}"
rm -rf "${NOLOCK}"
rm -rf "${MUTEX}"
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 and one that removes the lock after a reboot.
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
}

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
Reply