├── README ├── lightson+ └── lightson+cmd /README: -------------------------------------------------------------------------------- 1 | tools: 2 | lightson+ daemon which checks if screensaver should be inhibited 3 | lightson+cmd tool which inhibits screensaver manually 4 | 5 | 6 | this program is based on: 7 | https://github.com/iye/lightsOn 8 | 9 | Credits for some fixes: 10 | https://bbs.archlinux.org/viewtopic.php?id=130447 11 | -------------------------------------------------------------------------------- /lightson+: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # lightson+ 3 | 4 | # Copyright (c) 2018 spinal.by at gmail com 5 | # Copyright (c) 2014 devkral at web de 6 | # url: https://github.com/devkral/lightsonplus 7 | 8 | #based on 9 | # Copyright (c) 2011 iye.cba at gmail com 10 | # url: https://github.com/iye/lightsOn 11 | # This script is licensed under GNU GPL version 2.0 or above 12 | 13 | # Description: Bash script that prevents the screensaver and display power 14 | # management (DPMS) from being activated while watching fullscreen videos 15 | # on Firefox, Chrome and Chromium. Media players like mplayer, VLC and minitube 16 | # can also be detected. 17 | # One of {x, k, gnome-}screensaver must be installed. 18 | 19 | # HOW TO USE: 20 | # "./lightson+ -d 2 &" will check every 2 minutes if Mplayer, VLC, Firefox or 21 | # Chromium are fullscreen and delay screensaver and Power Management if so. 22 | # If you don't pass an argument, the checks are done every minute. 23 | 24 | 25 | # Select the programs to be checked 26 | mpv_detection=0 27 | mplayer_detection=0 28 | plex_detection=0 29 | vlc_detection=1 30 | totem_detection=1 31 | firefox_flash_detection=1 32 | chromium_flash_detection=1 33 | #chrome_app_name="Netflix" 34 | webkit_flash_detection=1 35 | html5_detection=1 36 | steam_detection=0 37 | minitube_detection=0 38 | audio_detection=0 39 | #minload=1.5 40 | delay=1 41 | # You can find the value for this with `xprop WM_NAME` 42 | # (click on the window once the mouse is a crosshair) 43 | window_name="" 44 | 45 | # realdisp 46 | realdisp=`echo "$DISPLAY" | cut -d. -f1` 47 | 48 | inhibitfile="/tmp/lightsoninhibit-$UID-$realdisp" 49 | pidfile="/tmp/lightson-$UID-$realdisp.pid" 50 | 51 | # YOU SHOULD NOT NEED TO MODIFY ANYTHING BELOW THIS LINE 52 | die() { 53 | echo "$@" >&2 54 | exit 1 55 | } 56 | 57 | pidcreate() { 58 | # just one instance can run simultaneously 59 | if [ ! -e "$pidfile" ]; then 60 | echo "$$" > "$pidfile" 61 | else 62 | if [ -d "/proc/$(cat "$pidfile")" ]; then 63 | die "Another instance is running, abort!" 64 | else 65 | echo "$$" > "$pidfile" 66 | fi 67 | fi 68 | } 69 | 70 | pidremove() { 71 | if [ ! -e "$pidfile" ]; then 72 | echo "Error: missing pidfile" >&2 73 | elif [ ! -f "$pidfile" ]; then 74 | echo -e "Error: \"$pidfile\" is not a file\n" >&2 75 | else 76 | if [ "$(cat "$pidfile")" != "$$" ]; then 77 | die "Another instance is running, abort!" 78 | else 79 | rm -f "$pidfile" 80 | fi 81 | fi 82 | exit 0 83 | } 84 | 85 | pidcreate 86 | trap "pidremove" EXIT 87 | 88 | # Enumerate all the attached screens 89 | displays="" 90 | while read id; do 91 | displays="$displays $id" 92 | done< <(xvinfo | sed -n 's/^screen #\([0-9]\+\)$/\1/p') 93 | 94 | # Detect screensaver being used 95 | 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 96 | screensaver="freedesktop-screensaver" 97 | #elif [ `pgrep -c gnome-shell` -ge 1 ] ;then 98 | # screensaver="xdofallback" 99 | elif [ `pgrep -c xscreensaver` -ge 1 ]; then 100 | screensaver="xscreensaver" 101 | elif [ `pgrep -c mate-screensaver` -ge 1 ]; then 102 | screensaver="mate-screensaver" 103 | elif [ `pgrep -c xautolock` -ge 1 ]; then 104 | screensaver="xautolock" 105 | elif [ -e "/usr/bin/xdotool" ]; then 106 | screensaver="xdofallback" 107 | else 108 | screensaver="" 109 | die "No screensaver detected" 110 | fi 111 | 112 | checkFullscreen() { 113 | # loop through every display looking for a fullscreen window 114 | for display in $displays; do 115 | # get id of active window and clean output 116 | active_win_id=`DISPLAY=$realdisp.${display} xprop -root _NET_ACTIVE_WINDOW` 117 | active_win_id=${active_win_id##*# } 118 | active_win_id=${active_win_id:0:9} # eliminate potentially trailing spaces 119 | 120 | top_win_id=`DISPLAY=$realdisp.${display} xprop -root _NET_CLIENT_LIST_STACKING` 121 | top_win_id=${active_win_id##*, } 122 | top_win_id=${top_win_id:0:9} # eliminate potentially trailing spaces 123 | 124 | # Check if Active Window (the foremost window) is in fullscreen state 125 | if [ ${#active_win_id} -ge 3 ] && [ "$active_win_id" != 0x0 ]; then 126 | isActiveWinFullscreen=`DISPLAY=$realdisp.${display} xprop -id $active_win_id | grep _NET_WM_STATE_FULLSCREEN` 127 | else 128 | isActiveWinFullscreen="" 129 | fi 130 | if [ ${#top_win_id} -ge 3 ] && [ "$top_win_id" != 0x0 ]; then 131 | isTopWinFullscreen=`DISPLAY=$realdisp.${display} xprop -id $top_win_id | grep _NET_WM_STATE_FULLSCREEN` 132 | else 133 | isTopWinFullscreen="" 134 | fi 135 | 136 | if [ -n "$window_name" ]; then 137 | isNamedFullscreen=`DISPLAY=$realdisp.${display} xprop -name "$window_name" | grep _NET_WM_STATE_FULLSCREEN` 138 | else 139 | isNamedFulscreen="" 140 | fi 141 | 142 | if [[ "$isActiveWinFullscreen" = *NET_WM_STATE_FULLSCREEN* ]] || [[ "$isTopWinFullscreen" = *NET_WM_STATE_FULLSCREEN* ]]; then 143 | isAppRunning && delayScreensaver 144 | fi 145 | 146 | # If we are detecting by named application, then we need to detect if any audio is playing. 147 | # Detecting by name is used for multiple monitors where the video might be playing, but 148 | # not in focus. 149 | if [[ "$isNamedFullscreen" = *NET_WM_STATE_FULLSCREEN* ]]; then 150 | checkAudioPlaying && delayScreensaver 151 | fi 152 | done 153 | } 154 | 155 | # Check if active window is mplayer, vlc or firefox 156 | # Then change IFs to detect more specifically the apps "" and if process name exist 157 | 158 | isAppRunning() { 159 | # Get title of active window 160 | active_win_title=`xprop -id $active_win_id | grep "WM_CLASS(STRING)" | sed 's/^.*", //;s/"//g'` 161 | 162 | case "$active_win_title" in 163 | *[Cc]hromium*) 164 | [ "$chromium_flash_detection" = 1 ] && [ `pgrep -fc "chromium --type=ppapi"` -ge 1 ] && return 0 165 | [ "$html5_detection" = 1 ] && [ `pgrep -c chromium` -ge 1 ] && checkAudio "chromium" && return 0 166 | ;; 167 | *[Cc]hrome*) 168 | [ "$chromium_flash_detection" = 1 ] && [ `pgrep -fc "chrome --type=ppapi"` -ge 1 ] && return 0 169 | [ "$html5_detection" = 1 ] && [ `pgrep -c chrome` -ge 1 ] && checkAudio "chrom" && return 0 170 | ;; 171 | *[Ff]irefox*) 172 | [ "$html5_detection" = 1 ] && [ `pgrep -fc firefox` -ge 1 ] && checkAudio "firefox" && return 0 173 | ;; 174 | *[Bb]rave*) 175 | [ "$chromium_flash_detection" = 1 ] && [ `pgrep -fc "brave --type=ppapi"` -ge 1 ] && return 0 176 | [ "$html5_detection" = 1 ] && [ `pgrep -c brave` -ge 1 ] && checkAudio "brave" && return 0 177 | ;; 178 | *opera*) 179 | [ "$html5_detection" = 1 ] && [ `pgrep -c opera` -ge 1 ] && checkAudio "opera" && return 0 180 | ;; 181 | *epiphany*) 182 | [ "$html5_detection" = 1 ] && [ `pgrep -c epiphany` -ge 1 ] && checkAudio "epiphany" && return 0 183 | ;; 184 | *unknown*|*plugin-container*) 185 | [ "$firefox_flash_detection" = 1 ] && [ `pgrep -c plugin-container` -ge 1 ] && return 0 186 | ;; 187 | *WebKitPluginProcess*) 188 | [ "$webkit_flash_detection" = 1 ] && [ `pgrep -fc ".*WebKitPluginProcess.*flashp.*"` -ge 1 ] && return 0 189 | ;; 190 | *MPlayer|mplayer*) 191 | [ "$mplayer_detection" = 1 ] && [ `pgrep -c mplayer` -ge 1 ] && checkAudio mplayer && return 0 192 | ;; 193 | *mpv*|*MPV*) 194 | [ "$mpv_detection" = 1 ] && [ `pgrep -c mpv` -ge 1 ] && checkAudio mpv && return 0 195 | ;; 196 | *plexmediaplayer*) 197 | [ "$plex_detection" = 1 ] && [ `pgrep -c plexmediaplayer` -ge 1 ] && checkAudio "Plex Media Player" && return 0 198 | ;; 199 | *vlc*|*VLC*) 200 | [ $vlc_detection = 1 ] && [ `pgrep -c vlc` -ge 1 ] && checkAudio vlc && return 0 201 | ;; 202 | *totem*) 203 | [ $totem_detection = 1 ] && [ `pgrep -c totem` -ge 1 ] && checkAudio totem && return 0 204 | ;; 205 | *steam*) 206 | [ $steam_detection = 1 ] && [ `pgrep -c steam` -ge 1 ] && return 0 207 | ;; 208 | *minitube*) 209 | [ $minitube_detection = 1 ] && [ `pgrep -c minitube` -ge 1 ] && return 0 210 | ;; 211 | *) 212 | if [ -n "$chrome_app_name" ]; then 213 | # Check if google chrome is running in app mode 214 | [[ "$active_win_title" == *$chrome_app_name* ]] && [ `pgrep -fc "chrome --app"` -ge 1 ] && return 0 215 | fi 216 | ;; 217 | esac 218 | 219 | [ -n "$minload" ] && [ "$(echo "$(sed 's/ .*$//' /proc/loadavg) > $minload" | bc -q)" -eq "1" ] && return 0 220 | 221 | false 222 | } 223 | 224 | checkAudioPlaying() { 225 | # Check if any application is playing sounds in pulse 226 | # This is useful if your application keeps the stream in pulse open 227 | # but, lists it as CORKED for example. 228 | # It's also useful if you watch videos on multiple monitors and might not 229 | # have the video in focus. 230 | [ $audio_detection = 0 ] && return 0 231 | pacmd list-sink-inputs | grep -Eiq "RUNNING" 232 | } 233 | 234 | checkAudio() { 235 | # Check if application is streaming sound to PulseAudio 236 | [ $audio_detection = 0 ] && return 0 237 | pacmd list-sink-inputs | grep -Eiq "application.name = .*$1.*" 238 | } 239 | 240 | delayScreensaver() { 241 | # Reset inactivity time counter so screensaver is not started 242 | case $screensaver in 243 | "xscreensaver" ) 244 | xscreensaver-command -deactivate > /dev/null;; 245 | "mate-screensaver" ) 246 | mate-screensaver-command --poke > /dev/null;; 247 | "xautolock" ) 248 | xautolock -disable 249 | xautolock -enable;; 250 | "xdofallback" ) 251 | xdotool key shift 252 | ;; 253 | "freedesktop-screensaver" ) 254 | dbus-send --session --reply-timeout=2000 --type=method_call --dest=org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.SimulateUserActivity;; 255 | esac 256 | 257 | # Check if DPMS is on. If it is, deactivate and reactivate again. If it is not, do nothing. 258 | dpmsStatus=`xset -q | grep -c 'DPMS is Enabled'` 259 | [ "$dpmsStatus" = 1 ] && xset -dpms && xset dpms 260 | } 261 | 262 | help() { 263 | echo "USAGE: $ lighsonplus [FLAG1 ARG1] ... [FLAGn ARGn]" 264 | echo "FLAGS (ARGUMENTS must be 0 or 1, except stated otherwise):" 265 | echo "" 266 | echo " -d, --delay Time interval in minutes, default is 1 min" 267 | echo " -pa, --audio Audio detection" 268 | echo " -m, --mpv mpv detection" 269 | echo " -mp, --mplayer mplayer detection" 270 | echo " -v, --vlc VLC detection" 271 | echo " -t, --totem Totem detection" 272 | echo " -pl, --plex-media-player Plex Media Player detection" 273 | echo " -ff, --firefox-flash Firefox flash plugin detection" 274 | echo " -cf, --chromium-flash Chromium flash plugin detection" 275 | echo " -ca, --chrome-app Chrome app detection, app name must be passed" 276 | echo " -wf, --webkit-flash Webkit flash detection" 277 | echo " -h5, --html5 HTML5 detection" 278 | echo " -s, --steam Steam detection" 279 | echo " -mt, --minitube MiniTube detection" 280 | echo " -la, --minload Load average detection" 281 | echo " -wn, --window-name Detect by window name" 282 | } 283 | 284 | checkBool() { 285 | [ -n "$2" ] && [[ $2 = [01] ]] || die "Invalid argument. 0 or 1 expected after \"$1\" flag." 286 | } 287 | 288 | while [ -n "$1" ]; do 289 | case $1 in 290 | "-d" | "--delay" ) 291 | [[ -z "$2" || "$2" = *[^0-9]* ]] && die "Invalid argument. Time in minutes expected after \"$1\" flag. Got \"$2\"" || delay=$2;; 292 | "-ca" | "--chrome-app" ) 293 | [ -n "$2" ] && chrome_app_name="$2" || die "Missing argument. Chrome app name expected after \"$1\" flag.";; 294 | "-wn" | "--window-name" ) 295 | [ -n "$2" ] && window_name="$2" || die "Missing argument. Window name expected after \"$1\" flag.";; 296 | "-la" | "--minload" ) 297 | [ -n "$2" ] && [[ "$(echo "$2 > 0" | bc -q)" -eq 1 ]] && minload=$2 || die "Invalid argument. >0 expected after \"$1\" flag.";; 298 | "-pa" | "--audio" ) 299 | checkBool "$@"; audio_detection=$2;; 300 | "-m" | "--mpv" ) 301 | checkBool "$@"; mpv_detection=$2;; 302 | "-mp" | "--mplayer" ) 303 | checkBool "$@"; mplayer_detection=$2;; 304 | "-v" | "--vlc" ) 305 | checkBool "$@"; vlc_detection=$2;; 306 | "-t" | "--totem" ) 307 | checkBool "$@"; totem_detection=$2;; 308 | "-pl" | "--plex-media-player" ) 309 | checkBool "$@"; plex_detection=$2;; 310 | "-ff" | "--firefox-flash" ) 311 | checkBool "$@"; firefox_flash_detection=$2;; 312 | "-cf" | "--chromium-flash" ) 313 | checkBool "$@"; chromium_flash_detection=$2;; 314 | "-wf" | "--webkit-flash" ) 315 | checkBool "$@"; webkit_flash_detection=$2;; 316 | "-h5" | "--html5" ) 317 | checkBool "$@"; html5_detection=$2;; 318 | "-s" | "--steam" ) 319 | checkBool "$@"; steam_detection=$2;; 320 | "-mt" | "--minitube" ) 321 | checkBool "$@"; minitube_detection=$2;; 322 | "-h" | "--help" ) 323 | help && exit 0;; 324 | * ) 325 | die "Invalid argument. See -h, --help for more information.";; 326 | esac 327 | 328 | # Arguments must always be passed in tuples 329 | shift 2 330 | done 331 | 332 | # Convert delay to seconds. We substract 10 for assurance. 333 | delay=$[delay*60-10] 334 | echo "Start lightson+ mainloop" 335 | while true; do 336 | [ -f "$inhibitfile" ] && delayScreensaver || checkFullscreen 337 | sleep $delay 338 | done 339 | 340 | exit 0 341 | -------------------------------------------------------------------------------- /lightson+cmd: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | #copyright devkral at web de 4 | # This script is licensed under GNU GPL version 2.0 or above 5 | 6 | # Description: extension to lightson+ 7 | 8 | #realdisp 9 | realdisp=`echo "$DISPLAY" | cut -d. -f1` 10 | inhibitfile="/tmp/lightsoninhibit-$UID-$realdisp" 11 | 12 | inhibit() { 13 | [ ! -e "$inhibitfile" ] && (touch "$inhibitfile" && echo "inhibit screensaver" | wall) || echo "screensaver is already inhibited" 14 | } 15 | uninhibit() { 16 | [ -e "$inhibitfile" ] && (rm "$inhibitfile" && echo "uninhibit screensaver" | wall) || echo "screensaver is already uninhibited" 17 | } 18 | 19 | case $1 in 20 | "" ) 21 | [ -f $inhibitfile ] && uninhibit || inhibit;; 22 | "on" | "true" | "yes" ) 23 | inhibit;; 24 | "off" | "false" | "no" ) 25 | uninhibit;; 26 | "status" ) 27 | [ -e $inhibitfile ] && echo "screensaver is inhibited" || echo "screensaver is uninhibited";; 28 | * ) 29 | echo -e "usage: $0 [command]\non: inhibits\noff: uninhibits\nstatus: print status\nnothing: switches";; 30 | esac 31 | --------------------------------------------------------------------------------