Wednesday 3 September 2008

Python hacks: stopping gnome-screensaver while watching videos

I got really tired of pressing keys while watching a movie when the screen goes black so today I made those two python scripts.

First one simply shuts down gnome-screensaver daemon, runs gmplayer command, and than turns the screensaver back on after gmplayer exits. Here is the first:

#!/usr/bin/python

import subprocess

# close gnome-screensaver
subprocess.Popen(["gnome-screensaver-command", "--exit"])

# run gmplayer (put command which runs your favorite video player instead "gmplayer"
player = subprocess.Popen("gmplayer")

# wait till mplayer exits
player.wait()

# start gnome-screensaver again
subprocess.Popen("gnome-screensaver")


Module subprocess contains neat Popen object that can run Linux commands within python code. This scripts simple calls gnome-screensaver-commad --exit, gmplayer and gnome-screensaver command sequence like you would type it in the terminal.
But this script has one flaw. It doesn't stop gnome-power-manager so it will put display to sleep according to preferences. More lines can be added here that handles shutting the power manager and than turning it back on... you can do that.

Note: As pointed out by user Styelz, the script below uses 100% CPU cause it constantly polls the subprocess to complete. Lately I made the new script that uses the --inhibit to stop the screensaver and powermanager at the same time. Read about it here

But the smarter idea came to my mind exploring the gnome-screensaver-command. There is a way to notify gnome-screensaver of user activity with the -p (or --poke) option. Next script opens up a player and runs "gnome-screensaver-command -p" in intervals till the video player closes:

#!/usr/bin/python

import time, subprocess

# set interval in which screensaver should be poked
poke_interval = 540

# which command to use for starting a player
player_command = "gmplayer"

# run player
try:
player = subprocess.Popen(player_command)
except OSError:
print "Could not open player"

# run "gnome-screensaver-command -p" in intervals
t = time.time()

while player.poll() == None:
if t + poke_interval < time.time():
poke = subprocess.Popen(["gnome-screensaver-command","-p"])
poke.wait()
t=time.time()


Note that this two hacks works only for gnome-screensaver and MPlayer, but you can customize it for your own setup, you just need to figure out the right commands and replace them.

3 comments:

Unknown said...

This is really great! I was just thinking how much I needed this a few weeks ago and figured there was no way to do it with Python :-(, You have proved me wrong.

How did you go about solving this problem? Where did you find the information?

Tvrtko said...

Well I simply googled for tutorials on system calls in python and I found this 'subprocess' module which seemed like the best choice for my mission with its Popen class. Later I just read the documentation and wrote this. It took me a few hours to do it, but actually its nothing special at all. I'm just a python beginner.

Anyways, thanks!

Styelz said...

When running your script it uses up 100% CPU usage as you are constantly polling for the subprocess to complete. I suggest you use the polling interval as a time.sleep(polling_interval) instead. Like so..


#!/usr/bin/python

import time, subprocess

# set interval in which screensaver should be poked
poke_interval = 120

# which command to use for starting a player
player_command = "mplayer"

# run player
try:
    player = subprocess.Popen(player_command)
except OSError:
    print "Could not open player\n"

# run "gnome-screensaver-command -p" in intervals
while player.poll() == None:
    time.sleep(poke_interval)
    poke = subprocess.Popen(["gnome-screensaver-command","-p"])
    poke.wait()