#!/usr/bin/python3 import os import sys import time import dbus import dbus.service import dbus.mainloop.glib dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) from gi.repository import GObject as gobject # DBus connection information for MATE screensaver DBUS_MSCR_WAIT = 60 DBUS_MSCR_DBUS = dbus.SessionBus() DBUS_MSCR_NAME = "org.mate.ScreenSaver" DBUS_MSCR_PATH = "/" DBUS_MSCR_IFACE_MAIN = "org.mate.ScreenSaver" # DBus listening information for the Idle Inhibition Spec DBUS_IIS_DBUS = dbus.SessionBus() DBUS_IIS_NAME = "org.freedesktop.ScreenSaver" DBUS_IIS_PATH = "/org/freedesktop/ScreenSaver" DBUS_IIS_PATH2= "/ScreenSaver" DBUS_IIS_IFACE_MAIN = "org.freedesktop.ScreenSaver" # Connect to the system and session bus bus_system = dbus.SystemBus() bus_session = dbus.SessionBus() # Connect to MATE screensaver print("Waiting for screensaver...") for i in range(DBUS_MSCR_WAIT): try: mate_screensaver = dbus.Interface( bus_session.get_object(DBUS_MSCR_NAME, DBUS_MSCR_PATH), DBUS_MSCR_IFACE_MAIN ) except dbus.exceptions.DBusException: # Screensaver not running yet if i < (DBUS_MSCR_WAIT - 1): time.sleep(1) else: print("MATE screensaver not running, aborting!", file=sys.stderr) sys.exit(2) else: print("MATE screensaver connected!") break class IdleInhibitor(object): """ Represents a single client that inhibits the screensaver """ def __init__(self, screensaver, name, reason, cookie, unique_name): self.screensaver = screensaver self.name = name self.reason = reason self.cookie = cookie self.unique_name = unique_name # Tell MATE screensaver about the application we are proxying self._cookie = self.screensaver.Inhibit(name, reason) def destroy(self): # Stop bothering MATE screensaver self.screensaver.UnInhibit(self._cookie) # Create DBus interface class IdleInhibitionService(dbus.service.Object): def __init__(self, mate_screensaver): # Store connection to screensaver self.screensaver = mate_screensaver # Counter for inhibition requests (used for cookies) self.counter = 1 # Storage for clients self.inhibitors = [] # Store constants self.bus = DBUS_IIS_DBUS self.path = DBUS_IIS_PATH self.path2 = DBUS_IIS_PATH2 # Claim bus name with both paths used by GNOME dbus.service.Object.__init__(self, self.bus, self.path, dbus.service.BusName(DBUS_IIS_NAME, self.bus) ) dbus.service.Object.__init__(self, self.bus, self.path2, dbus.service.BusName(DBUS_IIS_NAME, self.bus) ) def on_name_change(self, sender, unique_name): print("mate-screensaver-helper-inhibition: on_name_change: '%s', '%s'" % (sender, unique_name)) if sender != unique_name: for inhibitor in self.inhibitors: if inhibitor.unique_name == sender: self.UnInhibit(inhibitor.cookie, sender) @dbus.service.method(DBUS_IIS_IFACE_MAIN, "ss", "u", sender_keyword="sender") def Inhibit(self, application_name, reason_for_inhibit, sender): print("mate-screensaver-helper-inhibition: Inhibit: '%s', '%s' -> %d (from '%s')" % (application_name, reason_for_inhibit, self.counter + 1, sender)) # Create new cookie self.counter += 1 # Add inhibitor self.inhibitors.append(IdleInhibitor( self.screensaver, application_name, reason_for_inhibit, self.counter, sender )) # Watch if bus name owner disappears self.bus.watch_name_owner(sender, lambda name: self.on_name_change(sender, name)) return self.counter @dbus.service.method(DBUS_IIS_IFACE_MAIN, "u", "", sender_keyword="sender") def UnInhibit(self, cookie, sender): print("mate-screensaver-helper-inhibition: UnInhibit: %d (from '%s')" % (cookie, sender)) for inhibitor in self.inhibitors: if inhibitor.cookie == cookie and inhibitor.unique_name == sender: # Stop inhibiting inhibitor.destroy() # Remove inhibitor from list self.inhibitors.remove(inhibitor) # Create service service = IdleInhibitionService(mate_screensaver) # Wait for stuff to happen gobject.MainLoop().run()