This repository has been archived on 2024-04-07. You can view files and clone it, but cannot push or open issues or pull requests.
dotfiles/scripts/lightson

294 lines
10 KiB
Bash
Executable File

#!/usr/bin/env bash
# lightson+
# Copyright (c) 2018 spinal.by at gmail com
# Copyright (c) 2014 devkral at web de
# url: https://github.com/devkral/lightsonplus
#based on
# Copyright (c) 2011 iye.cba at gmail com
# url: https://github.com/iye/lightsOn
# This script is licensed under GNU GPL version 2.0 or above
# Description: Bash script that prevents the screensaver and display power
# management (DPMS) from being activated while watching fullscreen videos
# on Firefox, Chrome and Chromium. Media players like mplayer, VLC and minitube
# can also be detected.
# One of {x, k, gnome-}screensaver must be installed.
# HOW TO USE:
# "./lightson+ -d 2 &" will check every 2 minutes if Mplayer, VLC, Firefox or
# Chromium are fullscreen and delay screensaver and Power Management if so.
# If you don't pass an argument, the checks are done every minute.
# Select the programs to be checked
mplayer_detection=1
vlc_detection=1
totem_detection=1
firefox_flash_detection=1
chromium_flash_detection=1
#chrome_app_name="Netflix"
webkit_flash_detection=1
html5_detection=1
steam_detection=0
minitube_detection=0
audio_detection=0
#minload=1.5
delay=1
# realdisp
realdisp=`echo "$DISPLAY" | cut -d. -f1`
inhibitfile="/tmp/lightsoninhibit-$UID-$realdisp"
pidfile="/tmp/lightson-$UID-$realdisp.pid"
# YOU SHOULD NOT NEED TO MODIFY ANYTHING BELOW THIS LINE
die() {
echo "$@" >&2
exit 1
}
pidcreate() {
# just one instance can run simultaneously
if [ ! -e "$pidfile" ]; then
echo "$$" > "$pidfile"
else
if [ -d "/proc/$(cat "$pidfile")" ]; then
die "Another instance is running, abort!"
else
echo "$$" > "$pidfile"
fi
fi
}
pidremove() {
if [ ! -e "$pidfile" ]; then
echo "Error: missing pidfile" >&2
elif [ ! -f "$pidfile" ]; then
echo -e "Error: \"$pidfile\" is not a file\n" >&2
else
if [ "$(cat "$pidfile")" != "$$" ]; then
die "Another instance is running, abort!"
else
rm -f "$pidfile"
fi
fi
exit 0
}
pidcreate
trap "pidremove" EXIT
# Enumerate all the attached screens
displays=""
while read id; do
displays="$displays $id"
done< <(xvinfo | sed -n 's/^screen #\([0-9]\+\)$/\1/p')
# Detect screensaver being used
if [ `dbus-send --session --print-reply=literal --type=method_call --dest=org.freedesktop.ScreenSaver /ScreenSaver/ org.freedesktop.ScreenSaver.GetActive &> /dev/null; echo $?` -eq 0 ]; then
screensaver="freedesktop-screensaver"
#elif [ `pgrep -c gnome-shell` -ge 1 ] ;then
# screensaver="xdofallback"
elif [ `pgrep -c xscreensaver` -ge 1 ]; then
screensaver="xscreensaver"
elif [ `pgrep -c mate-screensaver` -ge 1 ]; then
screensaver="mate-screensaver"
elif [ `pgrep -c xautolock` -ge 1 ]; then
screensaver="xautolock"
elif [ -e "/usr/bin/xdotool" ]; then
screensaver="xdofallback"
else
screensaver=""
die "No screensaver detected"
fi
checkFullscreen() {
# loop through every display looking for a fullscreen window
for display in $displays; do
# get id of active window and clean output
active_win_id=`DISPLAY=$realdisp.${display} xprop -root _NET_ACTIVE_WINDOW`
active_win_id=${active_win_id##*# }
active_win_id=${active_win_id:0:9} # eliminate potentially trailing spaces
top_win_id=`DISPLAY=$realdisp.${display} xprop -root _NET_CLIENT_LIST_STACKING`
top_win_id=${active_win_id##*, }
top_win_id=${top_win_id:0:9} # eliminate potentially trailing spaces
# Check if Active Window (the foremost window) is in fullscreen state
if [ ${#active_win_id} -ge 3 ]; then
isActiveWinFullscreen=`DISPLAY=$realdisp.${display} xprop -id $active_win_id | grep _NET_WM_STATE_FULLSCREEN`
else
isActiveWinFullscreen=""
fi
if [ ${#top_win_id} -ge 3 ]; then
isTopWinFullscreen=`DISPLAY=$realdisp.${display} xprop -id $top_win_id | grep _NET_WM_STATE_FULLSCREEN`
else
isTopWinFullscreen=""
fi
if [[ "$isActiveWinFullscreen" = *NET_WM_STATE_FULLSCREEN* ]] || [[ "$isTopWinFullscreen" = *NET_WM_STATE_FULLSCREEN* ]]; then
isAppRunning && delayScreensaver
fi
done
}
# Check if active window is mplayer, vlc or firefox
# Then change IFs to detect more specifically the apps "<vlc>" and if process name exist
isAppRunning() {
# Get title of active window
active_win_title=`xprop -id $active_win_id | grep "WM_CLASS(STRING)" | sed 's/^.*", //;s/"//g'`
case "$active_win_title" in
*[Cc]hromium*)
[ "$chromium_flash_detection" = 1 ] && [ `pgrep -fc "chromium --type=ppapi"` -ge 1 ] && return 0
[ "$html5_detection" = 1 ] && [ `pgrep -c chromium` -ge 1 ] && checkAudio "chromium" && return 0
;;
*[Cc]hrome*)
[ "$chromium_flash_detection" = 1 ] && [ `pgrep -fc "chrome --type=ppapi"` -ge 1 ] && return 0
[ "$html5_detection" = 1 ] && [ `pgrep -c chrome` -ge 1 ] && checkAudio "chrom" && return 0
;;
*Firefox*)
[ "$html5_detection" = 1 ] && [ `pgrep -c firefox` -ge 1 ] && checkAudio "firefox" && return 0
;;
*opera*)
[ "$html5_detection" = 1 ] && [ `pgrep -c opera` -ge 1 ] && checkAudio "opera" && return 0
;;
*epiphany*)
[ "$html5_detection" = 1 ] && [ `pgrep -c epiphany` -ge 1 ] && checkAudio "epiphany" && return 0
;;
*unknown*|*plugin-container*)
[ "$firefox_flash_detection" = 1 ] && [ `pgrep -c plugin-container` -ge 1 ] && return 0
;;
*WebKitPluginProcess*)
[ "$webkit_flash_detection" = 1 ] && [ `pgrep -fc ".*WebKitPluginProcess.*flashp.*"` -ge 1 ] && return 0
;;
*MPlayer|mplayer*)
[ "$mplayer_detection" = 1 ] && [ `pgrep -c mplayer` -ge 1 ] && checkAudio mplayer && return 0
;;
*vlc*|*VLC*)
[ $vlc_detection = 1 ] && [ `pgrep -c vlc` -ge 1 ] && checkAudio vlc && return 0
;;
*totem*)
[ $totem_detection = 1 ] && [ `pgrep -c totem` -ge 1 ] && checkAudio totem && return 0
;;
*steam*)
[ $steam_detection = 1 ] && [ `pgrep -c steam` -ge 1 ] && return 0
;;
*minitube*)
[ $minitube_detection = 1 ] && [ `pgrep -c minitube` -ge 1 ] && return 0
;;
*)
if [ -n "$chrome_app_name" ]; then
# Check if google chrome is running in app mode
[[ "$active_win_title" == *$chrome_app_name* ]] && [ `pgrep -fc "chrome --app"` -ge 1 ] && return 0
fi
;;
esac
[ -n "$minload" ] && [ "$(echo "$(sed 's/ .*$//' /proc/loadavg) > $minload" | bc -q)" -eq "1" ] && return 0
false
}
checkAudio() {
# Check if application is streaming sound to PulseAudio
[ $audio_detection = 0 ] && return 0
pacmd list-sink-inputs | grep -Eiq "application.name = .*$1.*"
}
delayScreensaver() {
# Reset inactivity time counter so screensaver is not started
case $screensaver in
"xscreensaver" )
xscreensaver-command -deactivate > /dev/null;;
"mate-screensaver" )
mate-screensaver-command --poke > /dev/null;;
"xautolock" )
xautolock -disable
xautolock -enable;;
"xdofallback" )
xdotool key shift
;;
"freedesktop-screensaver" )
dbus-send --session --reply-timeout=2000 --type=method_call --dest=org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.SimulateUserActivity;;
esac
# Check if DPMS is on. If it is, deactivate and reactivate again. If it is not, do nothing.
dpmsStatus=`xset -q | grep -c 'DPMS is Enabled'`
[ "$dpmsStatus" = 1 ] && xset -dpms && xset dpms
}
help() {
echo "USAGE: $ lighsonplus [FLAG1 ARG1] ... [FLAGn ARGn]"
echo "FLAGS (ARGUMENTS must be 0 or 1, except stated otherwise):"
echo ""
echo " -d, --delay Time interval in minutes, default is 1 min"
echo " -pa, --audio Audio detection"
echo " -mp, --mplayer mplayer detection"
echo " -v, --vlc VLC detection"
echo " -t, --totem Totem detection"
echo " -ff, --firefox-flash Firefox flash plugin detection"
echo " -cf, --chromium-flash Chromium flash plugin detection"
echo " -ca, --chrome-app Chrome app detection, app name must be passed"
echo " -wf, --webkit-flash Webkit flash detection"
echo " -h5, --html5 HTML5 detection"
echo " -s, --steam Steam detection"
echo " -mt, --minitube MiniTube detection"
echo " -la, --minload Load average detection"
}
checkBool() {
[ -n "$2" ] && [[ $2 = [01] ]] || die "Invalid argument. 0 or 1 expected after \"$1\" flag."
}
while [ -n "$1" ]; do
case $1 in
"-d" | "--delay" )
[[ -z "$2" || "$2" = *[^0-9]* ]] && die "Invalid argument. Time in minutes expected after \"$1\" flag. Got \"$2\"" || delay=$2;;
"-ca" | "--chrome-app" )
[ -n "$2" ] && chrome_app_name="$2" || die "Missing argument. Chrome app name expected after \"$1\" flag.";;
"-la" | "--minload" )
[ -n "$2" ] && [[ "$(echo "$2 > 0" | bc -q)" -eq 1 ]] && minload=$2 || die "Invalid argument. >0 expected after \"$1\" flag.";;
"-pa" | "--audio" )
checkBool "$@"; audio_detection=$2;;
"-mp" | "--mplayer" )
checkBool "$@"; mplayer_detection=$2;;
"-v" | "--vlc" )
checkBool "$@"; vlc_detection=$2;;
"-t" | "--totem" )
checkBool "$@"; totem_detection=$2;;
"-ff" | "--firefox-flash" )
checkBool "$@"; firefox_flash_detection=$2;;
"-cf" | "--chromium-flash" )
checkBool "$@"; chromium_flash_detection=$2;;
"-wf" | "--webkit-flash" )
checkBool "$@"; webkit_flash_detection=$2;;
"-h5" | "--html5" )
checkBool "$@"; html5_detection=$2;;
"-s" | "--steam" )
checkBool "$@"; steam_detection=$2;;
"-mt" | "--minitube" )
checkBool "$@"; minitube_detection=$2;;
"-h" | "--help" )
help && exit 0;;
* )
die "Invalid argument. See -h, --help for more information.";;
esac
# Arguments must always be passed in tuples
shift 2
done
# Convert delay to seconds. We substract 10 for assurance.
delay=$[delay*60-10]
echo "Start lightson+ mainloop"
while true; do
[ -f "$inhibitfile" ] && delayScreensaver || checkFullscreen
sleep $delay
done
exit 0