Receiving dbus signals with pythion

682 views Asked by At

I'm trying to write some python to listen to signals.

Using dbus-monitor, as shown below, I can filter the signals I want.

dbus-monitor "type='signal',sender='org.kde.KWin',path='/ColorCorrect',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged'"

signal time=1653997355.732016 sender=:1.4 -> destination=(null destination) serial=13165 path=/ColorCorrect; interface=org.freedesktop.DBus.Properties; member=PropertiesChanged
   string "org.kde.kwin.ColorCorrect"
   array [
      dict entry(
         string "enabled"
         variant             boolean false
      )
   ]
   array [
   ]

But when I try the same thing with python, see below, nothing gets printed.

import dbus
from gi.repository import GLib
from dbus.mainloop.glib import DBusGMainLoop


def signal_handler(*args, **kwargs):
    for i, arg in enumerate(args):
        print("arg:%d        %s" % (i, str(arg)))
    print('kwargs:')
    print(kwargs)
    print('---end----')


DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus()

# register your signal callback
bus.add_signal_receiver(signal_handler,
                        bus_name='org.kde.KWin',
                        interface_keyword='org.freedesktop.DBus.Properties',
                        member_keyword='PropertiesChanged',
                        path_keyword='/ColorCorrect'
                        # message_keyword='msg')
                        )

loop = GLib.MainLoop()
loop.run()
2

There are 2 answers

0
hc_dev On BEST ANSWER

You might be interested in: NightColor.py for Setting Temp From Terminal which explains using pydbus to communicate the Night Color effect done by KWin using codename “ColorCorrect”.

Solution

See the docs of pydbus, Connecting to the Bus:

There are generally two bus daemons you may be interested in. Each user login session should have a session bus, which is local to that session. It's used to communicate between desktop applications. Connect to the session bus by creating a SessionBus object:

from pydbus import SessionBus

session_bus = SessionBus()

Session bus in KDE

Default: session bus

From the dbus-monitor manpage:

Options --system Monitor the system message bus. --session Monitor the session message bus. (This is the default.)

So, the message you saw in the output was apparently form default session-bus.

Same default bus explained in KDE's Developer guide: Accessing D-Bus Interfaces:

A QDBusInterface object represents a given D-Bus interface. The constructor accepts as parameters (in order) a service name, an object path, an optional interface and optionally which bus (e.g. system or session) to use. If no bus is explicitly defined, it defaults to the session bus. If no interface is given, the returned object will be used to call all interfaces on the bus.

Note

The given DBus-Service name for KDE's Plasma Desktop window manager KWin (org.kde.KWin) can also have a suffix, see environment-variable KWIN_DBUS_SERVICE_SUFFIX

Suffix for the DBus-Service name "org.kde.KWin". If set, the name will be changed to "org.kde.KWin.${KWIN_DBUS_SERVICE_SUFFIX}".

1
Jürgen Hötzel On

Your are using the system bus. org.kde.KWin is a service of the session bus. Try:

bus = dbus.SessionBus()