iye/lightsOn

The proposed changes

Opened this issue · 3 comments

Hello! iye.cba . A few days ago I got this script on github. I like the script very much. It taught me a lot, gave me another idea to solve the problem. But I am sorry that I do not like some places in the script.
So I modified some code that makes the script more powerful and more elegant.

#!/bin/bash
# lightsOn.sh
# Copyright (c) 2013 iye.cba at gmail com
# url: https://github.com/iye/lightsOn
# This script is licensed under GNU GPL version 2.0 or above

flash_detection=1
mplayer_detection=1
vlc_detection=1
minitube_detection=1
gnome_mplayer_detection=1
smplayer_detection=1
totem_detection=1
delay_progs=()

displays=""
while read id
do
    displays="$displays $id"
done < <(xvinfo | sed -n 's/^screen #\([0-9]\+\)$/\1/p')

# I think "pidof name" is better than "pgrep -lfc name |grep -wc name". It only output the PIDs when detects the process,
# but output nothing when no process.Most importantly, it is shorter.
if [ `pidof xscreensaver` ]; then
    screensaver=xscreensaver
elif [ `pidof gnome-screensaver` ]; then        # Most desktop enviromments use gnome-screensaver.
    screensaver=gnome-screensaver
elif [ `pidof cinnamon-screensaver` ]; then       # cinnamon desktop enviromment is getting more and more popular.
    screensaver=cinnamon-screensaver
elif [ `pidof kscreensaver` ]; then        # This can not effect on latest KDE version.
    screensaver=kscreensaver
elif [ -f $HOME/.kde*/share/config/kscreensaverrc ] && [ -z `grep -iw "enabled=false" $HOME/.kde*/share/config/kscreensaverrc` ]; then       #Effect on new KDE version.
    screensaver=kscreensaver
else
    screensaver=None
    echo "No screensaver detected"
fi

checkDelayProgs()
{
    for prog in "${delay_progs[@]}"; do
        if [ `pidof "$prog"` ]; then
            echo "Delaying the screensaver because a program on the delay list, \"$prog\", is running..."
            delayScreensaver
            break
        fi
    done
}

checkFullscreen()
{
    for display in $displays
    do
        activ_win_id=`DISPLAY=:0.${display} xprop -root _NET_ACTIVE_WINDOW`
        activ_win_id=${activ_win_id:40:9}
        if [ "$activ_win_id" = "0x0" ]; then   # Skip invalid window ids (It returns "0x0" when ScreenSaver is actived)
         continue
        fi
        isActivWinFullscreen=`DISPLAY=:0.${display} xprop -id $activ_win_id | grep _NET_WM_STATE_FULLSCREEN`
            if [ "$isActivWinFullscreen" ];then
                isAppRunning
                var=$?
                if [[ $var -eq 1 ]];then
                    delayScreensaver
                fi
            fi
    done
}

isAppRunning()
{
    #Get PID of active window, I think it makes the code easier. 
    activ_win_pid=`xprop -id $activ_win_id | grep "_NET_WM_PID(CARDINAL)"`
    activ_win_pid=${activ_win_pid##* }
    if [ $flash_detection == 1 ]; then
        if [[ `lsof -p $activ_win_pid | grep flashplayer.so` ]]; then    #  match all browers (which use libflashplayer.so , libpepflashplayer.so & operapluginwrapper-native)
            return 1
        fi
    fi
    if [ $mplayer_detection == 1 ];then
        if [[ `ps p $activ_win_pid o comm=` = "mplayer" ]];then    # Which is more simple and accurate.
            return 1
        fi
    fi
    if [ $vlc_detection == 1 ];then
        if [[ `ps p $activ_win_pid o comm=` = "vlc" ]];then
            return 1
        fi
    fi
    if [ $minitube_detection == 1 ];then
        if [[ `ps p $activ_win_pid o comm=` = "minitube" ]];then
            return 1
        fi
    fi    
    if [ $gnome_mplayer_detection == 1 ];then                  # It is easy to add video player detection.
        if [[ `ps p $activ_win_pid o comm=` = "gnome-mplayer" ]];then
            return 1
        fi
    fi
    if [ $smplayer_detection == 1 ];then
        if [[ `ps p $activ_win_pid o comm=` = "smplayer" ]];then
            return 1
        fi
    fi
    if [ $totem_detection == 1 ];then
        if [[ `ps p $activ_win_pid o comm=` = "totem" ]];then
            return 1
        fi
    fi
    return 0
}

delayScreensaver()
{
    if [ "$screensaver" == "xscreensaver" ]; then
        xscreensaver-command -deactivate > /dev/null
    elif [ "$screensaver" == "gnome-screensaver" ]; then
        gnome-screensaver-command --deactivate > /dev/null           # It is similar to xscreensaver.
    elif [ "$screensaver" == "cinnamon-screensaver" ]; then
        cinnamon-screensaver-command --deactivate > /dev/null         # I have not tried, but I guess it do so.
    elif [ "$screensaver" == "kscreensaver" ]; then
        qdbus org.freedesktop.ScreenSaver /ScreenSaver SimulateUserActivity > /dev/null
    fi
    dpmsStatus=`xset -q | grep -ce 'DPMS is Enabled'`
    if [ $dpmsStatus == 1 ];then
            xset -dpms
            xset dpms
    fi
}

delay=$1
if [ -z "$1" ];then
    delay=50
fi
if [[ $1 = *[^0-9]* ]]; then
    echo "The Argument \"$1\" is not valid, not an integer"
    echo "Please use the time in seconds you want the checks to repeat."
    echo "You want it to be ~10 seconds less than the time it takes your screensaver or DPMS to activate"
    exit 1
fi

while true
do
    checkDelayProgs
    checkFullscreen
    sleep $delay
done

exit 0
iye commented

Great, good job! Using pidof is much better. Give me a few day and will move your changes to master.

Update on Apirl 7th

    activ_win_pid=`xprop -id $activ_win_id | grep "_NET_WM_PID(CARDINAL)"`
    activ_win_pid=${activ_win_pid##* }       ##Accidentally forgot to add this phrase before.

Update on Apirl 10th

        activ_win_id=${activ_win_id:40:9}
        if [ "$activ_win_id" = "0x0" ]; then   # Skip invalid window ids (It returns "0x0" when ScreenSaver actives)
         continue
        fi
        isActivWinFullscreen=`DISPLAY=:0.${display} xprop -id $activ_win_id | grep _NET_WM_STATE_FULLSCREEN`

Sadly, this does not work for Cinnamon 2.0 (Mint 16 Petra, based on Ubuntu 13.10), BUT it doesn't display the "no screensaver" error message. Something must be wrong, but I can't tell yet, it should work...