125 lines
3.3 KiB
Bash
Executable File
125 lines
3.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
# This file is part of I38.
|
|
|
|
# I38 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.
|
|
|
|
# I38 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 I38. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
autolockSeconds="${1:-0}"
|
|
scriptPath="$(readlink -f "$0")"
|
|
scriptDir="${scriptPath%/*}"
|
|
runtimeDir="${XDG_RUNTIME_DIR:-/tmp}"
|
|
lockDir="${runtimeDir}/i38-screenlock-autolock"
|
|
pollSeconds=5
|
|
lockCommand=("${@:2}")
|
|
|
|
if [[ ${#lockCommand[@]} -eq 0 ]]; then
|
|
lockCommand=("${scriptDir}/screenlock.sh")
|
|
fi
|
|
|
|
notify_autolock_disabled() {
|
|
local message="$1"
|
|
|
|
if command -v notify-send &> /dev/null; then
|
|
notify-send "I38 autolock disabled" "$message"
|
|
fi
|
|
}
|
|
|
|
video_is_playing() {
|
|
local playerStatus playerUrl
|
|
|
|
if ! command -v playerctl &> /dev/null; then
|
|
return 1
|
|
fi
|
|
|
|
while IFS='|' read -r _ playerStatus playerUrl; do
|
|
if [[ "$playerStatus" != "Playing" ]]; then
|
|
continue
|
|
fi
|
|
|
|
if [[ "$playerUrl" =~ \.(avi|flv|m4v|mkv|mov|mp4|mpeg|mpg|ogm|ogv|webm|wmv)(\?.*)?$ ]]; then
|
|
return 0
|
|
fi
|
|
done < <(playerctl -a metadata --format '{{playerName}}|{{status}}|{{xesam:url}}' 2> /dev/null || true)
|
|
|
|
return 1
|
|
}
|
|
|
|
focused_window_is_fullscreen() {
|
|
if ! command -v i3-msg &> /dev/null || ! command -v jq &> /dev/null; then
|
|
return 1
|
|
fi
|
|
|
|
i3-msg -t get_tree \
|
|
| jq -e 'any(.. | objects; (.focused? == true) and ((.fullscreen_mode? // 0) != 0))' \
|
|
&> /dev/null
|
|
}
|
|
|
|
screenlock_is_running() {
|
|
case "${lockCommand[0]##*/}" in
|
|
i38lock)
|
|
pgrep -x i38lock &> /dev/null
|
|
;;
|
|
*)
|
|
pgrep -f "${lockCommand[0]}" &> /dev/null
|
|
;;
|
|
esac
|
|
}
|
|
|
|
cleanup() {
|
|
rm -rf "$lockDir"
|
|
}
|
|
|
|
stop_autolock() {
|
|
cleanup
|
|
exit 0
|
|
}
|
|
|
|
if [[ ! "$autolockSeconds" =~ ^[0-9]+$ ]] || [[ "$autolockSeconds" -le 0 ]]; then
|
|
exit 0
|
|
fi
|
|
|
|
if [[ -z "${DISPLAY:-}" ]]; then
|
|
notify_autolock_disabled "No X display was found."
|
|
exit 0
|
|
fi
|
|
|
|
if ! command -v xprintidle &> /dev/null; then
|
|
notify_autolock_disabled "Install xprintidle to use screen lock autolock."
|
|
exit 0
|
|
fi
|
|
|
|
if [[ -d "$lockDir" ]]; then
|
|
if [[ -f "${lockDir}/pid" ]]; then
|
|
read -r existingPid < "${lockDir}/pid"
|
|
if [[ "$existingPid" =~ ^[0-9]+$ ]] && kill -0 "$existingPid" 2> /dev/null; then
|
|
exit 0
|
|
fi
|
|
fi
|
|
rm -rf "$lockDir"
|
|
fi
|
|
|
|
if ! mkdir "$lockDir" 2> /dev/null; then
|
|
exit 0
|
|
fi
|
|
printf "%s\n" "$$" > "${lockDir}/pid"
|
|
trap cleanup EXIT
|
|
trap stop_autolock INT TERM
|
|
|
|
while : ; do
|
|
idleMilliseconds="$(xprintidle 2> /dev/null || echo 0)"
|
|
if [[ "$idleMilliseconds" =~ ^[0-9]+$ ]] && [[ "$idleMilliseconds" -ge $((autolockSeconds * 1000)) ]]; then
|
|
if ! screenlock_is_running && ! video_is_playing && ! focused_window_is_fullscreen; then
|
|
"${lockCommand[@]}"
|
|
sleep "$pollSeconds"
|
|
fi
|
|
fi
|
|
|
|
sleep "$pollSeconds"
|
|
done
|