#!/usr/bin/python # Copyright (C) 2011 Noel J. Bergman # Licensed under the Apache Software License v2 import dbus class Inhibitor(object): ''' Uses the Gnome SessionManager D-Bus interface to inhibit session idling and other inhibitable activities. References: http://svn.gnome.org/viewvc/gnome-session/trunk/gnome-session/org.gnome.SessionManager.xml?view=markup http://blogs.gnome.org/hughsie/2009/01/28/inhibits-and-the-new-world-order/ http://git.gnome.org/browse/gnome-power-manager/tree/applets/inhibit/inhibit-applet.c?h=gnome-2-32 http://git.gnome.org/browse/gnome-session/tree/gnome-session/gsm-manager.c http://en.wikibooks.org/wiki/Python_Programming/Dbus ''' LOGGING_OUT=1 USER_SWITCHING=2 SUSPENDING=4 IDLE=8 def __init__(self): self.bus = dbus.SessionBus() self.session_manager = self.bus.get_object("org.gnome.SessionManager","/org/gnome/SessionManager") self.session_manager_interface = dbus.Interface(self.session_manager, "org.gnome.SessionManager") def inhibit(self, flags = 8, app_id="PyInhibit", toplevel_xid=0, reason="OnDemand"): self.uninhibit() if 0 < flags <= (Inhibitor.LOGGING_OUT + Inhibitor.USER_SWITCHING + Inhibitor.SUSPENDING + Inhibitor.IDLE): self.cookie = self.session_manager_interface.Inhibit(app_id, toplevel_xid, reason, flags) def uninhibit(self): if "cookie" in self.__dict__: self.session_manager_interface.Uninhibit(self.cookie) del self.cookie def isInhibited(self, flags): return self.session_manager_interface.IsInhibited(flags) def introspect(self): introspector = dbus.Interface(self.session_manager, dbus.INTROSPECTABLE_IFACE) interface = introspector.Introspect() print interface try: import pygtk pygtk.require('2.0') import gtk, appindicator except AssertionError as e: print "Necessary version of GTK not found: ", e raise SystemExit except ImportError as e: print "Necessary import not found: ", e print "Will try running as a GNOME Applet instead of an AppIndicator" else: class InhibitIndicator(object): """ AppIndicator UI for the Inhibitor. Conditionally built and executed if the appindicator package is present. You can set this to run at session startup (Preferences->Startup Applications), or run it manually (e.g., ALT-F2). References: http://design.canonical.com/2010/04/notification-area/ https://wiki.ubuntu.com/DesktopExperienceTeam/ApplicationIndicators http://www.eurion.net/python-snippets/snippet/Create%20an%20Application%20Indicator.html http://blog.strycore.com/2010/01/using-the-application-indicator-in-python/ http://www.jonobacon.org/2009/12/17/application-indicators-in-python/ http://people.canonical.com/~ted/libappindicator/current/AppIndicator.html """ def __init__(self): self.ind = appindicator.Indicator ("inhibit-indicator-menu", "gpm-inhibit", appindicator.CATEGORY_SYSTEM_SERVICES) self.ind.set_status (appindicator.STATUS_ACTIVE) # self.ind.set_icon("gpm-inhibit") -- redundant with constructor # create a menu self.menu = gtk.Menu() # create items for the menu check = gtk.CheckMenuItem("Inhibit Logout") check.connect("activate", self.inhibit, Inhibitor.LOGGING_OUT) check.show() self.menu.append(check) check = gtk.CheckMenuItem("Inhibit User Switching") check.connect("activate", self.inhibit, Inhibitor.USER_SWITCHING) check.show() self.menu.append(check) check = gtk.CheckMenuItem("Inhibit Suspending") check.connect("activate", self.inhibit, Inhibitor.SUSPENDING) check.show() self.menu.append(check) check = gtk.CheckMenuItem("Inhibit Idle") check.connect("activate", self.inhibit, Inhibitor.IDLE) check.show() self.menu.append(check) item = gtk.ImageMenuItem(gtk.STOCK_QUIT) item.connect("activate", self.quit) item.show() self.menu.append(item) self.flags = 0 self.inhibitor = Inhibitor() def inhibit(self, widget, data = None): self.flags += data if widget.active else -data self.inhibitor.inhibit(self.flags) # self.reportStatus() def reportStatus(self): with open("/tmp/inhibitlog", "a") as log: print >> log, "Logging out {0} inhibited.".format("is" if self.inhibitor.isInhibited(Inhibitor.LOGGING_OUT) else "is not") print >> log, "User switching {0} inhibited.".format("is" if self.inhibitor.isInhibited(Inhibitor.USER_SWITCHING) else "is not") print >> log, "Suspending {0} inhibited.".format("is" if self.inhibitor.isInhibited(Inhibitor.SUSPENDING) else "is not") print >> log, "Session idle {0} inhibited.".format("is" if self.inhibitor.isInhibited(Inhibitor.IDLE) else "is not") def quit(self, widget, data=None): gtk.main_quit() def run(self): self.menu.show() self.ind.set_menu(self.menu) gtk.main() if __name__ == "__main__": indicator = InhibitIndicator() indicator.run() raise SystemExit try: import gnomeapplet, sys, os.path except ImportError as e: print "Necessary import not found: ", e else: class InhibitApplet(gnomeapplet.Applet): ''' GNOME Applet UI for the Inhibitor. References: http://www.znasibov.info/blog/post/gnome-applet-with-python-part-1.html http://saravananthirumuruganathan.wordpress.com/2010/01/15/creating-gnome-panel-applets-in-python/ http://www.pygtk.org/articles/applets_arturogf/ http://cafbit.com/resource/ffselect.py http://www.mythtv.org/wiki/Mythstatus.py ''' def __init__(self, applet, iid): self.flags = 0 self.inhibitor = Inhibitor() self.applet = applet icon = gtk.Image() try: pixbuf = gtk.gdk.pixbuf_new_from_file("/usr/share/gnome-power-manager/icons/hicolor/scalable/status/gpm-inhibit.svg") except gobject.GError: icon = None else: scaled_buf = pixbuf.scale_simple(24,24,gtk.gdk.INTERP_BILINEAR) icon.set_from_pixbuf(scaled_buf) icon.show() if icon: self.applet.add(icon) else: label = gtk.Label("Inhibit") self.applet.add(label) self.setup_menu() self.applet.show_all() def setup_menu(self): xml = '' xml += '' if not (self.flags & Inhibitor.LOGGING_OUT) else '' xml += '' if not (self.flags & Inhibitor.USER_SWITCHING) else '' xml += '' if not (self.flags & Inhibitor.SUSPENDING) else '' xml += '' if not (self.flags & Inhibitor.IDLE) else '' xml += '' verbs = [('LogoutOff', self.inhibit), ('SwitchOff', self.inhibit), ('SuspendOff', self.inhibit), ('IdleOff', self.inhibit), ('LogoutOn', self.inhibit), ('SwitchOn', self.inhibit), ('SuspendOn', self.inhibit), ('IdleOn', self.inhibit)] self.applet.setup_menu(xml, verbs, None) def inhibit(self, obj, verb, *data): flag = {'LogoutOff': Inhibitor.LOGGING_OUT, 'SwitchOff': Inhibitor.USER_SWITCHING, 'SuspendOff': Inhibitor.SUSPENDING, 'IdleOff': Inhibitor.IDLE, 'LogoutOn': -Inhibitor.LOGGING_OUT, 'SwitchOn': -Inhibitor.USER_SWITCHING, 'SuspendOn': -Inhibitor.SUSPENDING, 'IdleOn': -Inhibitor.IDLE } self.flags += flag[verb] self.inhibitor.inhibit(self.flags) self.setup_menu() @staticmethod def applet_factory(applet, iid): InhibitApplet(applet, iid) return True import sys if __name__ == "__main__": if not os.path.exists("/usr/lib/bonobo/servers/InhibitApplet.server"): oaf = ''' ''' try: with open("/usr/lib/bonobo/servers/InhibitApplet.server", "w") as oaf_file: oaf_file.write(oaf) except Exception as e: print "Cannot register applet -- try running as root:", e else: print "Registered applet. You must restart gnome-panel, e.g., killall gnome-panel" elif len(sys.argv) > 1 and sys.argv[1] == '-d': mainWindow = gtk.Window() mainWindow.set_title('Applet window') mainWindow.connect('destroy', gtk.main_quit) applet = gnomeapplet.Applet() InhibitApplet.applet_factory(applet, None) applet.reparent(mainWindow) mainWindow.show_all() gtk.main() sys.exit() else: gnomeapplet.bonobo_factory('OAFIID:InhibitApplet_Factory', gnomeapplet.Applet.__gtype__, 'Inhibit Applet', '1.0', InhibitApplet.applet_factory)