ubuntuusers.de

simple Alternative zu Caffeine

Status: Gelöst | Ubuntu-Version: Ubuntu 12.04 (Precise Pangolin)
Antworten |

spawn

Anmeldungsdatum:
22. September 2012

Beiträge: 108

Hallo, habe vor kurzem (ursprünglich in Debian Wheezy, in Ubuntu 12.04 habe ich es aber auch erfolgreich getestet) ein Skript geschrieben, das die idletime des xservers resettet, wenn bestimmte Programme (wie z.B. Flash in Firefox oder vlc, beliebig erweiterbar) laufen und dadurch Bildschirmschoner/standby etc. verhindert. Es gibt wohl, wie ich nun erfahren habe, laut Wiki das Programm Caffeine, das wohl Ähnliches tut, da es aber noch nicht in den offiziellen Paketquellen ist, ist vlt. dieses simple bash-Skript auch für den ein oder anderen hier interessant.

Viel Spaß

spawn

#!/bin/bash

# (yet another) small script to reset X idletime and by that inhibit screensaver/powersaver when specific applications run.
# Please share it, if you find it useful!

# Examples:
# flash in firefox: /usr/lib/firefox/plugin-container
# flash in iceweasel: plugin-containe 
# banshee: banshee
# vlc: vlc

# With the following command you can find out the process name of a the active window (6 seconds delay); xdotool must be installed:
# sleep 6 && cat /proc/$(xdotool getwindowpid $(xdotool getwindowfocus))/comm

# seperate applications with	|
applications='/usr/lib/firefox/plugin-container|vlc'


# sleepingtime (every n seconds is checked, if one of the above applications is running
sleepingtime=59

sleep $sleepingtime # sleep a bit, we don't need it directly after login...

i_am=$(whoami)
idletimereset="xset s reset"	# the actual idletime reset command
xinitpid=$(pgrep -u $i_am -f '/usr/bin/dbus-launch --exit-with-session')	# get pid of current userloginsession


function xsessioncheck	# unfortunately necessary, because otherwise the script won't exit on userlogout
{
	if ps -p $xinitpid > /dev/null ;then	# users xsession still running?
	:		
#	echo "$i_am's session is running"
	else
		echo "$i_am's session is NOT running, exiting"
		exit 0
	fi
}


while : ; do
		if  pgrep -u $i_am -f "$applications" >/dev/null ;then	# is one of the above apps running?
			eval $idletimereset
			echo "idletime reset"
			notify-send -i dialog-information "Energieverwaltung deaktiviert"
			sleep $sleepingtime
			while pgrep -u $i_am -f "$applications" >/dev/null >/dev/null ;do
				xsessioncheck						   
				echo "Flash, etc. is running"
				eval $idletimereset
				echo "idletime reset"
				sleep $sleepingtime				   						   
			done
			notify-send -i dialog-information "Energieverwaltung wieder aktiviert"
		else
			echo "Flash, etc. is NOT running"
			xsessioncheck
			sleep $sleepingtime
		fi
done

spawn

(Themenstarter)

Anmeldungsdatum:
22. September 2012

Beiträge: 108

Neue, stark verbesserte Version, die zusätzlich checkt, ob das aktive Fenster im Vollbildmodus ist oder Sound läuft und dann ebenfalls die idlezeit resettet. Außerdem werden die checks nur ausgeführt, wenn die idlezeit einen Mindestwert erreicht. Der (unzuverlässige) Check, ob die Sitzung noch läuft, entfällt nun.

Benötigte Pakete (s. auch Skript):

 sudo apt-get install xprintidle libnotify-bin procps x11-utils coreutils inotify-tools 

Das Skript:

#!/bin/bash

# (yet another) small script to reset X idletime and by that inhibit
# screensaver/powersaver when specific applications run, the active
# window is in fullscreen mode, or any sound is playing for more or 
# equal 10 seconds.
# Please share it, if you find it useful!

# required packages: xprintidle libnotify-bin procps x11-utils coreutils inotify-tools

# Examples:
# flash in firefox: /usr/lib/firefox/plugin-container
# flash in iceweasel: plugin-containe 
# banshee: banshee
# vlc: vlc
# Virtualbox: VirtualBox

# With the following command you can find out the process name of a the active window (6 seconds delay); xdotool must be installed:
# sleep 6 && cat /proc/$(xdotool getwindowpid $(xdotool getwindowfocus))/comm

# seperate applications with	|
applications='VirtualBox'	# remove comment in loop at bottom to take effect

# how many seconds sound has to play, until idletimereset gets active
maxsoundplaytime=10	# 10 could be a good value

# sleepingtime (every n seconds is checked, if one of the above applications is running
sleepingtime=48	# 48 could be a good value, DO NOT choose less than 4...

########################################################################################################


function applicationcheck
{
	if  pgrep -u $i_am -f "$applications" >/dev/null ; then	# is one of the above apps, owned by current user, running?
		eval $idletimereset
		echo "one or more of the following applications reset the idletime: $applications"
		notify-send -i dialog-information "$powermanager_deactivated"
		sleep $sleepingtime
		while pgrep -u $i_am -f "$applications" >/dev/null >/dev/null ; do						   
			echo "one or more of the following applications reset the idletime: $applications"
			eval $idletimereset
			sleep $sleepingtime				   						   
		done
		notify-send -i dialog-information "$powermanager_activated"
	else 
		echo "$applications is/are NOT running!"
	fi
}

function fullscreencheck
{
	active_window=$(xprop -id $(xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2) _NET_WM_NAME)
	active_window=${active_window##*= \"}
	active_window=${active_window%\"}
	if xprop -name "$active_window" _NET_WM_STATE | grep -q _NET_WM_STATE_FULLSCREEN ; then
		eval $idletimereset
		echo "active window is in fullscreen, idletime reset!"
		notify-send -i dialog-information "$powermanager_deactivated"
		sleep $sleepingtime
		while xprop -name "$active_window" _NET_WM_STATE | grep -q _NET_WM_STATE_FULLSCREEN ; do
			eval $idletimereset
			echo "active window is in fullscreen, idletime reset!"
			sleep $sleepingtime	
		done
		notify-send -i dialog-information "$powermanager_activated"
	else
		echo "active window is NOT in fullscreen!"
	fi	
}

function soundcheck
{
	soundplaytime=0
	while eval $soundsystemcheck > /dev/null && [ $soundplaytime -lt $maxsoundplaytime ] ; do
		echo "sound is playing..."
		sleep 2		
		soundplaytime=$(($soundplaytime + 2))					
	done
	if [ $soundplaytime -ge $maxsoundplaytime ] ; then
	
		echo "sound has been playing for more or equal $maxsoundplaytime sec!" # and so, most probably, no system sound or similar has been registered
		eval $idletimereset
		echo "idletime reset!"
		notify-send -i dialog-information "$powermanager_deactivated"
		sleep $sleepingtime
		while eval $soundsystemcheck > /dev/null; do
			eval $idletimereset			
			echo "sound is playing, idletime reset!"
			sleep $sleepingtime	
		done
		notify-send -i dialog-information "$powermanager_activated"
	else
		echo "NO sound is playing!"
	fi	
}

# main..

displaynumber=$DISPLAY
displaynumber=${displaynumber%.*}
displaynumber=${displaynumber#*:}
if test -e /tmp/.X11-unix/X$displaynumber ;then  # exit if not running X..
	echo "Your xserver's displaynumber: $displaynumber"
else
	echo "Fatal! Cannot find a file in /tmp/.X11-unix/X$displaynumber! Are you running X?"
	notify-send -t 0 -i dialog-information "idletimereset kann so leider nicht funktionieren..."
	exit 1
fi
xprintidle_sleepingtime=$(($sleepingtime * 500 - 1000)) # 1000/2 because in worst case it waits for (almost) twice the sleepingtime
i_am=$(whoami)
idletimereset="xset s reset"	# the actual idletime reset command
powermanager_activated="Energieverwaltung wieder aktiviert"
powermanager_deactivated="Energieverwaltung deaktiviert"


# detect which (if any) soundsystem is running:
if pulseaudio --check ; then
	echo "your session is using pulseaudio, using it for sound detection!"
	soundsystemcheck="pactl list | grep RUNNING"
elif ! dpkg -s alsa-base |grep installed ; then
	echo  "Could not find alsa-base sound system, cannot use the sound-detect function"
	soundsystemcheck="could_not_find_a_soundsystem!" 
else
	echo "pulseaudio NOT detected but alsa-base seems to be installed, using fuser /dev/snd/timer for sound detection!"
	soundsystemcheck="fuser /dev/snd/timer"
fi


echo "start loop"
while sleep $sleepingtime; printf "\n----------------------\n" ; do
		if [ $(xprintidle) -le $xprintidle_sleepingtime ] ; then	# only get active, if the user is actually idle
			echo "the user has not been idle for more than $(($sleepingtime / 2 - 1 )) seconds, no action applied."
		else		
#			applicationcheck # remove comment to take effect
			fullscreencheck
			soundcheck	
		fi				
done &
loopPID=$!
inotifywait /tmp/.X11-unix/X$displaynumber
kill -SIGTERM $loopPID
echo "xsession has ended, exiting"
exit 0

Wenn ihr etwas besser (oder anders..) machen würdet, fühlt euch gern frei, es mir mitzuteilen (da ich, wie man sieht, noch Anfänger bin)

Gruß

spawn

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13224

spawn schrieb:

Wenn ihr etwas besser (oder anders..) machen würdet, fühlt euch gern frei, es mir mitzuteilen (da ich, wie man sieht, noch Anfänger bin)

Da Du das vermutlich nur für bestimmte Programme machen willst, schreib Dir doch ein Skript, das ein anders Programm startet und während dessen Laufzeit den Idle-Reset macht. Z.B. so

1
2
3
4
5
6
7
8
9
#!/bin/sh

"$@" &
pid=$!

while kill -0 $pid 2>/dev/null; do
  sleep 60
  idlereset
done

Oder auch

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#!/bin/sh

"$@" &
pid=$!

while kill -0 $pid 2>/dev/null; do
  sleep 60
  idlereset
done &

wait $pid

spawn

(Themenstarter)

Anmeldungsdatum:
22. September 2012

Beiträge: 108

Da Du das vermutlich nur für bestimmte Programme machen willst, schreib Dir doch ein Skript, das ein anders Programm startet und während dessen Laufzeit den Idle-Reset macht. Z.B. so

Jo danke, das wäre sicherlich, was die Prozessorlast angeht, effizienter und auch, da ja die pid genutzt wird, spezifischer. Alledings habe ich das Skript vor allem für Leute geschrieben, bei denen ich Ubuntu installiert hatte und bei denen während Flash-videos oder Bilder-Diashow im Vollbildmodus der Bildschirmschoner anging- (du siehst, in der alten Version wurde sich ausschließlich auf den Prozessnamen verlassen, in der neuen ist diese Funktion standardmässig auskommentiert). Vor allem im Hinblick hierauf finde ich es unpraktisch, extra für jede Anwendung ein Skript (oder noch schlimmer: Skript und .desktop-Datei) anzulegen (was beim Flashplayer glaub ich auch gar nicht geht, weil ja "der Browser" diesen startet). 😉 Ich finde den Anwendungscheck auch unpraktisch, weil z.B. Flash häufig einen Prozess hat, wenn man gar nichts guckt oder hört^^

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13224

spawn schrieb:

Jo danke, das wäre sicherlich, was die Prozessorlast angeht, effizienter und auch, da ja die pid genutzt wird, spezifischer. Alledings habe ich das Skript vor allem für Leute geschrieben, bei denen ich Ubuntu installiert hatte und bei denen während Flash-videos oder Bilder-Diashow im Vollbildmodus der Bildschirmschoner anging- (du siehst, in der alten Version wurde sich ausschließlich auf den Prozessnamen verlassen, in der neuen ist diese Funktion standardmässig auskommentiert). Vor allem im Hinblick hierauf finde ich es unpraktisch, extra für jede Anwendung ein Skript (oder noch schlimmer: Skript und .desktop-Datei) anzulegen

Das hast Du vielleicht falsch verstanden: das Skript brauchst Du nur ein Mal. Du startest es mit der zu startenden Kommandozeile als Argumente. Du wirst aber mehrere .desktop-Dateien brauchen.

(was beim Flashplayer glaub ich auch gar nicht geht, weil ja "der Browser" diesen startet). 😉 Ich finde den Anwendungscheck auch unpraktisch, weil z.B. Flash häufig einen Prozess hat, wenn man gar nichts guckt oder hört^^

Tja. Vielleicht gibt es ja noch eine andere Möglichkeit, dem X-Server oder Windowmanager zu entlocken, ob gerade ein Fenster im Vollbildmodus läuft. Dann könnte man das verallgemeinern und müsste gar nicht auf spezifische Prozesse schauen. Eigentlich wäre das sogar die bessere Lösung.

spawn

(Themenstarter)

Anmeldungsdatum:
22. September 2012

Beiträge: 108

Tja. Vielleicht gibt es ja noch eine andere Möglichkeit, dem X-Server oder Windowmanager zu entlocken, ob gerade ein Fenster im Vollbildmodus läuft. Dann könnte man das verallgemeinern und müsste gar nicht auf spezifische Prozesse schauen. Eigentlich wäre das sogar die bessere Lösung.

Nanu, aber das macht doch gerade der "fullscreencheck" ^^. Und für Sound ist der "soundcheck" zuständig (sowohl mit alsa, als auch mit pulse)

function fullscreencheck
{
	active_window=$(xprop -id $(xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2) _NET_WM_NAME)
	active_window=${active_window##*= \"}
	active_window=${active_window%\"}
	if xprop -name "$active_window" _NET_WM_STATE | grep -q _NET_WM_STATE_FULLSCREEN ; then
		eval $idletimereset
		echo "active window is in fullscreen, idletime reset!"
		notify-send -i dialog-information "$powermanager_deactivated"
		sleep $sleepingtime
		while xprop -name "$active_window" _NET_WM_STATE | grep -q _NET_WM_STATE_FULLSCREEN ; do
			eval $idletimereset
			echo "active window is in fullscreen, idletime reset!"
			sleep $sleepingtime	
		done
		notify-send -i dialog-information "$powermanager_activated"
	else
		echo "active window is NOT in fullscreen!"
	fi	
}

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13224

spawn schrieb:

Tja. Vielleicht gibt es ja noch eine andere Möglichkeit, dem X-Server oder Windowmanager zu entlocken, ob gerade ein Fenster im Vollbildmodus läuft. Dann könnte man das verallgemeinern und müsste gar nicht auf spezifische Prozesse schauen. Eigentlich wäre das sogar die bessere Lösung.

Nanu, aber das macht doch gerade der "fullscreencheck" ^^. Und für Sound ist der "soundcheck" zuständig (sowohl mit alsa, als auch mit pulse)

Ja, dann ist doch gut. Ich habe mich wohl im anderen Thema verhaspelt.

pilzgrow

Avatar von pilzgrow

Anmeldungsdatum:
25. März 2008

Beiträge: 633

Hallo spawn,

Besten Dank für dein script.

Ist es möglich, den "fullscreencheck" auch auf nicht-aktive Fenster anzuwenden? Bei 2 Monitoren kann es ja auch vorkommen, daß das Vollbild-Video Fenster nicht den Focus hat. Um den "soundcheck" abzuschalten, habe ich Zeile 137 des scripts auskommentiert → wenn Musik läuft, können/sollen die Monitore ruhig ausgeschaltet werden.

Gruß pilzgrow

Antworten |