#!/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 . 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