|
|
@@ -0,0 +1,142 @@ |
|
|
|
#!/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() |