Search code examples
pythonlinuxscreensaverxorg

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.


Solution

  • 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()