294 lines
10 KiB
Bash
Executable File
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
|