Wait for dbus session lock / unlock messages

Viewed 1206

I am trying to implement a dbus listener in Python, that executes a function, whenever the session is locked and another function, when the session is unlocked. Basically, I want to turn the following command into a Python program (obviously, that command doesn't have a callback):

gdbus monitor -y -d org.freedesktop.login1 | grep LockedHint

This command returns the following:

/org/freedesktop/login1/session/_32: org.freedesktop.DBus.Properties.PropertiesChanged ('org.freedesktop.login1.Session', {'LockedHint': <true>}, @as [])
/org/freedesktop/login1/session/_32: org.freedesktop.DBus.Properties.PropertiesChanged ('org.freedesktop.login1.Session', {'LockedHint': <false>}, @as [])

The Python MWE is here. However, it doesn't get any messages (tried starting it with sudo and as the user itself):

#!/usr/bin/env python

from datetime import datetime
import dbus
import gobject
from dbus.mainloop.glib import DBusGMainLoop

def locker_callback(*args):
    print "%s    Lock%s" % (datetime.now().ctime(), args)

DBusGMainLoop(set_as_default=True)                        # integrate into gobject main loop
bus = dbus.SystemBus()                                    # connect to system wide dbus
bus.add_signal_receiver(                                  # define the signal to listen to
    locker_callback,                                      # callback function
    'LockedHint',                                         # signal name
    'org.freedesktop.DBus.Properties.PropertiesChanged',  # interface
    'org.freedesktop.login1'                              # bus name
)

loop = gobject.MainLoop()
loop.run()

Just for reference, I run xfce on Ubuntu 18.04, with XScreenSaver.

1 Answers

"LockedHint" is not a signal, it's a property. The signal is "PropertiesChanged" in the interface org.freedesktop.DBus.Properties. It's usually easiest to look these up using d-feet (a graphical D-Bus 'debugger') but I'm sure the API docs show this as well.

Here's the same code with working property notification:

#!/usr/bin/env python

from datetime import datetime
import dbus
import gobject
from dbus.mainloop.glib import DBusGMainLoop

def properties_changed_callback(*args):
    print "%s %s" % (datetime.now().ctime(), args)

DBusGMainLoop(set_as_default=True)
dbus.SystemBus().add_signal_receiver(
    properties_changed_callback,
    'PropertiesChanged',
    'org.freedesktop.DBus.Properties',
    'org.freedesktop.login1'
)

gobject.MainLoop().run()

This will print a line for every property change of course, not just "LockedHint". Also, note that dbus module is legacy by now: you may want to look at pydbus for new code.

If you want to run your handler inside your user session and are only interested in your own session getting locked, you probably don't want to use the logind API: take a look at org.freedesktop.ScreenSaver (in the session bus) for an alternative (it'll be a lot simpler as the name is well-known and there's a "ActiveChanged" signal you can use). Again I suggest using d-feet to browse the API.

Related