From faf66a4c256ff9ca0e9887e97d9ee871e862fef6 Mon Sep 17 00:00:00 2001 From: Markus Katharina Brechtel Date: Mon, 13 Jan 2020 11:53:45 +0100 Subject: [PATCH] mate-screensaver-helper-inhibition script --- files/mate-screensaver-helper-inhibition.py | 142 ++++++++++++++++++++ tasks/main.yaml | 9 ++ 2 files changed, 151 insertions(+) create mode 100644 files/mate-screensaver-helper-inhibition.py diff --git a/files/mate-screensaver-helper-inhibition.py b/files/mate-screensaver-helper-inhibition.py new file mode 100644 index 0000000..8b541b6 --- /dev/null +++ b/files/mate-screensaver-helper-inhibition.py @@ -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() diff --git a/tasks/main.yaml b/tasks/main.yaml index 7adc736..83abff5 100644 --- a/tasks/main.yaml +++ b/tasks/main.yaml @@ -12,6 +12,7 @@ pkg: - mate-screensaver - xscreensaver-gl + - python3 - name: gdmflexiserver dummy script copy: @@ -19,6 +20,14 @@ dest: /usr/local/bin/gdmflexiserver mode: 0755 +# Bug: https://github.com/mate-desktop/mate-screensaver/issues/57 +# https://gist.github.com/alexander255/9b991816418e4e60ee7c +- name: mate-screensaver-helper-inhibition script + copy: + src: mate-screensaver-helper-inhibition.py + dest: /usr/local/bin/mate-screensaver-helper-inhibition + mode: 0755 + - import_role: name: dconf-lock vars: