3

I'm trying to make my GTK app responsive to network connection state changes. My approach is what I said in the question: Listen on a (NetworkManager) DBus signal.

I have a python3 GTK app (a very minimal one, I should add), using python-gi. As python-dbus (aka "import dbus") is deprecated to the best of my knowledge, I'd like to use Gio via python-gi.

I have an older script that listens for the signal I'm interested in on the system DBus which uses "import dbus" with this code:

dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus()
bus.add_signal_receiver(NMSignalHandler,
                        dbus_interface=NM_INTERFACE,
                        signal_name='StateChanged')

(followed by a gobject.MainLoop().run())

I thought this would be relatively straightforward to "port" to Gio, but even after two hours of reading the docs, I don't see how to do that. Any help would be appreciated.

I already tried using Gio.NetworkMonitor.get_default() and its 'network-changed' signal, but it appears to report with net_available (second parameter) always being true and the default monitor doesn't seem to report a sensible result either.

I would deeply appreciate any help.

incase1
  • 174
  • 2
  • 4

1 Answers1

0

To do the equivalent of your python-dbus script with python-gi, the following worked for me:

from gi.repository import GLib, Gio


def network_changed_hndlr(network_monitor, network_available):
    print(network_monitor)
    print(network_available)


default = Gio.NetworkMonitor.get_default()
default.connect('network-changed', network_changed_hndlr)
mainloop = GLib.MainLoop()
try:
    mainloop.run()
except KeyboardInterrupt:
    mainloop.quit()

This was using the documentation at: https://lazka.github.io/pgi-docs/Gio-2.0/structs/NetworkMonitor.html

For the NetworkManager there are a lot more object paths and interfaces.

For example, if I look at the output from this busctl tree org.freedesktop.NetworkManager there are 48 items I could monitor.

If I wanted to monitor the output of the active connection it would be:

from gi.repository import GLib, Gio

ACTIVE_IFACE = 'org.freedesktop.NetworkManager.Connection.Active'


def active_network_hndlr(dbus_proxy, properties_changed, properties_removed):
    props = properties_changed.unpack()
    print(props)


def network_proxy(connection):
    """
    Provide proxy for comfortable and pythonic method calls
    """
    return Gio.DBusProxy.new_for_bus_sync(
            bus_type=Gio.BusType.SYSTEM,
            flags=Gio.DBusProxyFlags.NONE,
            info=None,
            name='org.freedesktop.NetworkManager',
            object_path=connection,
            interface_name=ACTIVE_IFACE,
            cancellable=None)

net_mngr = network_proxy('/org/freedesktop/NetworkManager/ActiveConnection/8')
net_mngr.connect('g-properties-changed', active_network_hndlr)

mainloop = GLib.MainLoop()
try:
    mainloop.run()
except KeyboardInterrupt:
    mainloop.quit()

With the DBusProxy doing most of the heavy lifting. This is documented at: https://lazka.github.io/pgi-docs/Gio-2.0/classes/DBusProxy.html

ukBaz
  • 6,985
  • 2
  • 8
  • 31