python monitor X idle time

I had this requirement, to monitor when no user interaction has been detected for X amount of time, and then reload some running app.

first i looked into the Xubuntu (since the bis has it) repository for any idle monitoring, and the best i could find (if not the only) is "xautolock" a great utility

Xautolock monitors the user activity on an X Window display. If none is
detected within mins minutes, a program is started as specified by the
-locker option. Xautolock will typically be used to lock the screen
(hence its primary name) but it really doesn't care what program you
make it start.

tested it, like this

xautolock -time 1 -locker /usr/bin/appreset

where appreset is a simple bash script that will reload the specific app.

it worked like a charm, but it only accepts time in minutes and the requirement was to detec idle state for 90 seconds.

searching around for other utilities i found a couple but i had to compile them myself and go through all the dependencies manually and such. not my favouritre choice, then i found "xprintidle" which basically when run will just print the idle time, so i though i would write a small script using this tool trying it and looking at python too.

i came across this page http://schurger.org/wordpress/?p=47

sweet...so python can do it, so i built my script around that codehere it is

#!/usr/bin/python

import ctypes, os, time
from ConfigParser import ConfigParser

class XScreenSaverInfo(ctypes.Structure):
""" typedef struct { ... } XScreenSaverInfo; """
_fields_ = [('window', ctypes.c_ulong), # screen saver window
('state', ctypes.c_int), # off,on,disabled
('kind', ctypes.c_int), # blanked,internal,external
('since', ctypes.c_ulong), # milliseconds
('idle', ctypes.c_ulong), # milliseconds
('event_mask', ctypes.c_ulong)] # events

class XScreenSaverSession(object):
def __init__( self):
self.xlib = ctypes.cdll.LoadLibrary( 'libX11.so')
#display_num = os.environ['DISPLAY']
display_num = ":0"
self.dpy = self.xlib.XOpenDisplay(display_num)
if not self.dpy:
raise Exception('Cannot open display')
self.root = self.xlib.XDefaultRootWindow( self.dpy)
self.xss = ctypes.cdll.LoadLibrary( 'libXss.so.1')
self.xss.XScreenSaverAllocInfo.restype = ctypes.POINTER(XScreenSaverInfo)
self.xss_info = self.xss.XScreenSaverAllocInfo()

def get_idle( self):
self.xss.XScreenSaverQueryInfo( self.dpy, self.root, self.xss_info)
return int(self.xss_info.contents.idle / 1000)

class Config():
def __init__(self):
file = open('/home/xlab/idled.ini','r')
self.config = ConfigParser()
self.config.readfp(file)

def get(self):
if self.config.has_option('main','time'):
timeout = self.config.get('main','time')
if self.config.has_option('main','exec'):
executable = self.config.get('main','exec')
return int(timeout), executable

if __name__ == "__main__":
cfg = Config()
timeout, executable = cfg.get()
s = XScreenSaverSession()
ignore = True
while True:
idle_time = s.get_idle()
if idle_time < timeout:
ignore = False
if not ignore and idle_time > timeout:
os.system(executable)
ignore = True
time.sleep(1)