mirror of https://gitlab.com/dabruh/dotfiles.git
112 lines
2.8 KiB
Bash
Executable File
112 lines
2.8 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# i3hwlock
|
|
#
|
|
# Allows locking i3 by the presence of a file. This file is intended to be
|
|
# created using udev rules so that you can trigger the lock when you remove
|
|
# a device such as a YubiKey. Example rule below.
|
|
#
|
|
# /etc/udev/rules.d/99-i3hwlock-yubikey.rules:
|
|
# ACTION=="add", SUBSYSTEM=="input", ENV{ID_VENDOR_ID}=="1050", RUN+="/usr/bin/rm /tmp/i3hwlock.trigger"
|
|
# ACTION=="remove", SUBSYSTEM=="input", ENV{ID_VENDOR_ID}=="1050", RUN+="/usr/bin/touch /tmp/i3hwlock.trigger"
|
|
|
|
LOCK_TIMEOUT=3 # How many seconds to wait before locking.
|
|
DMENU_FILE="/tmp/i3hwlock"
|
|
TRIGGER_FILE="$DMENU_FILE.trigger"
|
|
ABORT_FILE="$DMENU_FILE.abort"
|
|
CONTINUE_FILE="$DMENU_FILE.continue"
|
|
LOCKING_FILE="$DMENU_FILE.locking"
|
|
DMENU_ARGS="-i -nb #e74c3c -nf #303030 -sb #c0392b -sf #ecf0f1"
|
|
|
|
function check_prerequisites() {
|
|
[ -e "$ABORT_FILE" ] && rm "$ABORT_FILE"
|
|
|
|
if ! which inotifywait >/dev/null; then
|
|
echo "ERROR: inotifywait not found." 1>&2
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
function dmenu_selection() {
|
|
# shellcheck disable=SC2086
|
|
selection="$(xargs -n 1 <<<"Continue Abort" | dmenu $DMENU_ARGS -p "The screen is about to lock")"
|
|
[ -z "$selection" ] && return
|
|
file="$DMENU_FILE.${selection,,}"
|
|
echo "INFO: Touching $file"
|
|
touch "$file"
|
|
}
|
|
|
|
function abort_lock() {
|
|
[ -e "$ABORT_FILE" ] && rm "$ABORT_FILE"
|
|
|
|
if ! [ -f "$LOCKING_FILE" ]; then
|
|
echo "WARN: Abort initiated without file '$LOCKING_FILE'." 1>&2
|
|
return 0
|
|
fi
|
|
|
|
echo "INFO: Aborting lock."
|
|
killall dmenu
|
|
notify-send "Lock aborted." &
|
|
[ -e $LOCKING_FILE ] && rm "$LOCKING_FILE"
|
|
}
|
|
|
|
function lock() {
|
|
[ -e "$CONTINUE_FILE" ] && rm "$CONTINUE_FILE"
|
|
|
|
if ! [ -f "$LOCKING_FILE" ]; then
|
|
echo "WARN: Won't lock as file '$LOCKING_FILE' is missing." 1>&2
|
|
return 0
|
|
fi
|
|
|
|
echo "INFO: Locking now."
|
|
killall dmenu
|
|
i3exit lock 2>/dev/null || i3lock --color=29414f --nofork
|
|
[ -e $LOCKING_FILE ] && rm "$LOCKING_FILE"
|
|
}
|
|
|
|
function delayed_lock() {
|
|
echo "INFO: Delayed lock initiated."
|
|
touch "$DMENU_FILE.locking"
|
|
|
|
for i in $(seq $LOCK_TIMEOUT); do
|
|
notify-send "Locking in $((LOCK_TIMEOUT - i + 1))" -t 1000 &
|
|
sleep 1
|
|
|
|
if [ -e "$ABORT_FILE" ]; then
|
|
abort_lock
|
|
return 0
|
|
elif [ -e "$CONTINUE_FILE" ]; then
|
|
break
|
|
fi
|
|
done
|
|
|
|
! [ -e $LOCKING_FILE ] && return 0
|
|
lock
|
|
}
|
|
|
|
function listen() {
|
|
while read -r directory action file; do
|
|
if [[ "$file" == "${TRIGGER_FILE##*/}" ]]; then
|
|
if [[ "$action" == "CLOSE_WRITE,CLOSE" ]] && ! [ -e "$LOCKING_FILE" ]; then
|
|
$0 dmenu-selection &
|
|
$0 delayed-lock &
|
|
elif [[ "$action" == "DELETE" ]]; then
|
|
abort_lock
|
|
fi
|
|
fi
|
|
done < <(inotifywait -m "${TRIGGER_FILE%/*}")
|
|
}
|
|
|
|
check_prerequisites || exit 1
|
|
|
|
if [ -z "$1" ]; then
|
|
listen || exit 2
|
|
elif [[ "$1" == delayed-lock ]]; then
|
|
delayed_lock || exit 3
|
|
elif [[ "$1" == dmenu-selection ]]; then
|
|
dmenu_selection || exit 4
|
|
else
|
|
echo "ERROR: Unrecognized action: '$1'." 1>&2
|
|
exit 127
|
|
fi
|