From 7d6772299abc6ea8f7257f08ccb7832f4ba8112d Mon Sep 17 00:00:00 2001 From: Patrick Spek Date: Wed, 17 Mar 2021 09:37:04 +0100 Subject: Introduce xblank --- .config/sxhkd/sxhkdrc | 3 + .local/bin/xblank | 204 +++++++++++++++++++++++++++++++++++++++++++++++ .local/bin/xblank-toggle | 66 +++++++++++++++ .local/etc/x/xinitrc | 9 ++- 4 files changed, 278 insertions(+), 4 deletions(-) create mode 100755 .local/bin/xblank create mode 100755 .local/bin/xblank-toggle diff --git a/.config/sxhkd/sxhkdrc b/.config/sxhkd/sxhkdrc index aae73ee..85ccdc6 100644 --- a/.config/sxhkd/sxhkdrc +++ b/.config/sxhkd/sxhkdrc @@ -31,6 +31,9 @@ XF86MonBrightness{Up,Down} super + shift + s physlock +shift + Pause + xblank-toggle + # printscreens Print sscrot diff --git a/.local/bin/xblank b/.local/bin/xblank new file mode 100755 index 0000000..dc675d9 --- /dev/null +++ b/.local/bin/xblank @@ -0,0 +1,204 @@ +#!/bin/sh + +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU Affero General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# This program 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 Affero General Public License for more +# details. + +readonly PROGRAM_NAME="$(basename "$0")" + +main() +{ + # Handle opts + while getopts ":C:S:c:ht:v" opt + do + case "$opt" in + S) rundir=$OPTARG ;; + d) command_dir=$OPTARG ;; + h) usage && exit 0 ;; + v) verbose=1 ;; + *) + printf "Invalid option passed: %s\n" "$OPTARG" >&2 + ;; + esac + done + + shift $(( OPTIND - 1 )) + + # Set default values + [ -z "$rundir" ] && rundir="$XDG_RUNTIME_DIR/$PROGRAM_NAME" + + time_old=0 + time_now="$(xprintidle)" + + # Check availability of dependencies + for i in xprintidle xset + do + command -v "$i" >/dev/null && continue + + log "Missing dependency $i" + exit 3 + done + + # Ensure $DISPLAY is set + if [ -z "$DISPLAY" ] + then + log "\$DISPLAY is unset" + exit 4 + fi + + # Initialize the rundir + log "Create rundir ($rundir)" + mkdir -p -- "$rundir" + + printf "0\n" > "$rundir/paused" + [ ! -f "$rundir/state" ] && printf "active\n" > "$rundir/state" + + # Enter the loop + while : + do + # Do nothing if the program is paused + if is_paused + then + log "$PROGRAM_NAME is paused ($rundir)" + + sleep 1 + continue + fi + + # Get the time the system has been idle in milliseconds + time_old=$time_now + time_now="$(($(xprintidle) / 1000))" + + # Run command_active upon detecting activity + if [ "$((time_now))" -lt "$((time_old))" ] + then + log "Detected activity ($time_now < $time_old)" + cmd="$(get_script active)" + + if [ "$cmd" = "" ] + then + log "No executable found for activation" + + sleep 1 + continue + fi + + log "> $cmd" + $cmd + fi + + # Run command based on inactivity duration + loop_index=$(($time_old)) + + log "Running (potential) scripts $time_old through $time_now" + + while [ "$(($loop_index))" -lt "$(($time_now))" ] + do + loop_index="$(($loop_index + 1))" + + log "Running script for $loop_index" + + cmd=$(get_script idle_$loop_index) + + if [ "$cmd" = "" ] + then + log "No executable found for idling (${loop_index}s)" + + continue + fi + + log "> $cmd" + $cmd + done + + # Sleep to not burn your CPU + sleep 1 + done +} + +get_script() +{ + if [ -n "$command_dir" ] + then + if [ -x "$command_dir/$1" ] + then + printf "%s\n" "$command_dir/$1" + return + fi + + # Don't continue if a command_dir was explicitly set + return + fi + + set -f + OIFS=$IFS + IFS=: + + dirs="$XDG_CONFIG_HOME:$XDG_CONFIG_DIRS:$HOME/.config" + + for dir in $dirs + do + [ "$dir" = "" ] && continue + + if [ -x "$dir/$PROGRAM_NAME/$1" ] + then + printf "%s\n" "$dir/$PROGRAM_NAME/$1" + return + fi + done + + IFS=$OIFS + set +f +} + +is_paused() +{ + if [ "$(head -n 1 "$rundir/paused")" = "0" ] + then + return 1 + fi + + return 0 +} + +log() +{ + [ -z "$verbose" ] && return + + printf "[%s] %s\n" "$(prettify_time "$time_now")" "$*" >&2 +} + +prettify_time() +{ + printf "%03dh %02dm %02ds\n" \ + "$(( $1 / 60 / 60 ))" \ + "$(( $1 / 60 % 60 ))" \ + "$(( $1 % 60 ))" +} + +usage() +{ + cat <] [-R ] [-c ] [-t ] [-v] + +Force-blank the screen after a certain timeout. + +Options: + -C Set the command to run when X is becoming active. + -R Set the location of the rundir. + -c Set the command to run when X is going idle. + -h Show this help text and exit. + -t Set the timeout in seconds. Defaults to 60. + -v Add verbosity. +EOF +} + +main "$@" diff --git a/.local/bin/xblank-toggle b/.local/bin/xblank-toggle new file mode 100755 index 0000000..f013b93 --- /dev/null +++ b/.local/bin/xblank-toggle @@ -0,0 +1,66 @@ +#!/bin/sh + +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU Affero General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# This program 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 Affero General Public License for more +# details. + +main() +{ + # Handle opts + while getopts ":S:h" opt + do + case "$opt" in + S) rundir=$OPTARG ;; + h) usage && exit 0 ;; + *) + printf "Invalid option passed: %s\n" "$OPTARG" >&2 + ;; + esac + done + + shift $(( OPTIND - 1 )) + + # Set default values + [ -z "$rundir" ] && rundir="$XDG_RUNTIME_DIR/xblank" + + # Check if xblank is currently paused + if [ "$(head -n 1 "$rundir/paused")" = "0" ] + then + # xblank is currently not paused + printf "1\n" > "$rundir/paused" + notify "stock_lock-open" "xblank" "Paused" + else + # xblank is already paused + printf "0\n" > "$rundir/paused" + notify "stock_lock" "xblank" "Unpaused" + fi +} + +notify() +{ + icon=$1 + shift + + notify-send -i "$icon" -n 26012 -s -t 3 "$@" +} + +usage() +{ + cat <