Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inhibit screensaver with Python

What's the better cross-DE way to disable the screensaver in Linux? I found something here but it's only for gnome-screensaver. I'm wondering if there's any way to simulate a keystroke or some X.Org API to disable screensaver activation.

like image 546
ov1d1u Avatar asked Jun 04 '12 17:06

ov1d1u


People also ask

Does Python run when computer is locked?

You can walk away from the computer or lock it and the scripts continue to execute.

How do I put laptop to sleep in Python?

To shut down the computer/PC/laptop by using a Python script, you have to use the os. system() function with the code “ shutdown /s /t 1 ” . Note: For this to work, you have to import os library in the ide.


2 Answers

I have been looking into this a while ago and finally ended up using xdg-screensaver which I call via subprocess.

import subprocess

def suspend_screensaver():
    window_id = subprocess.Popen('xwininfo -root | grep xwininfo | cut -d" " -f4', stdout=subprocess.PIPE, shell=True).stdout.read().strip()

    #run xdg-screensaver on root window
    subprocess.call(['xdg-screensaver', 'suspend', window_id])

def resume_screensaver(window_id):
    subprocess.Popen('xdg-screensaver resume ' + window_id, shell=True)

This is not ideal but apparently there is no other solution that would not involve messing around with DE-specific stuff like dbus or gnome-screensaver-command.

I don't really like the call to xwininfo and wish there was a cleaner way but so far could not find anything better. Another issue with the xwininfo approach is that it uses the id of the root window instead of the app window. Using the app window id instead of the root window would remove the need for the resume_screensaver method since it would then resume as soon as the window is destroyed.

And if you want to simulate keystrokes here is a naive bash script I have been using for some time. It does require xdotool which has to be installed separately.

#!/bin/bash
while : 
do
   sleep 200
   nice -n 1 xdotool key shift
   echo .
done

UPDATE

After having used the python solution above for over a year, it was found to occasionally create zombie processes and/or too many instances of xdg-screensaver, so after digging around, I found a simpler alternative which is Gnome-specific, but works for me even in a non-Gnome DE (XFCE) since the core Gnome libraries are required by many GTK-based apps even if you don't have a Gnome desktop.

import subprocess

def suspend_screensaver():
    'suspend linux screensaver'
    proc = subprocess.Popen('gsettings set org.gnome.desktop.screensaver idle-activation-enabled false', shell=True)
    proc.wait()

def resume_screensaver():
    'resume linux screensaver'
    proc = subprocess.Popen('gsettings set org.gnome.desktop.screensaver idle-activation-enabled true', shell=True)
    proc.wait()
like image 103
ccpizza Avatar answered Oct 16 '22 02:10

ccpizza


I know this question is old, but there is a more modern answer to it: now most DE on linux use dbus to communicate, and you can use this:

in shell, using kde tools:

qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.Inhibit "myapps" "because I want it"

this dbus call will return a cookie (a number) that will be needed to uninhibit the screesaver:

qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.UnInhibit $COOKIE

In python, it will be something like

import dbus

bus = dbus.SessionBus()
saver = bus.get_object('org.freedesktop.ScreenSaver', '/ScreenSaver')
saver_interface = dbus.Interface(saver, dbus_interface='org.freedesktop.ScreenSaver')

# now we can inhibit the screensaver
cookie=saver_interface.Inhibit("myapps", "because I want it")


# we can also restore it
saver_interface.UnInhibit(cookie)
like image 33
Rémi Avatar answered Oct 16 '22 02:10

Rémi