How to get notified of a DBus property change in Vala?

Hi,

this seems like a very basic question, but weirdly I haven’t been able to find an answer in the documentation. I’m trying to write a DBus client in Vala and I’d like to be notified when a property on a DBus object changes (assuming that it sends out the PropertiesChanged signal as expected). Following the many examples, I define an interface in Vala:

[DBus (name = "org.example.SimpleService", timeout = 120000)]
public interface SimpleService : GLib.Object {
	[DBus (name = "ExampleProperty")]
	public abstract bool example_property { get; set; }
}

This works, and I can retrieve and change example_property – also, if its value changes, it is properly updated. However, I have a hard time figuring out how to connect to a changed signal for the property. I’ve tried the following (where obj is an instance of the above class):

  • obj.notify[“example_property”].connect(…) compiles, but no notification
  • obj.notify.connect(…) compiles, but no notification
  • obj.g_properties_changed.connect(…) does not compile (signal not known)
  • obj.example_property.notify.connect(…) does not compile (bool does not have signals)
  • obj.example_property_changed.connect(…) does not compile (just tried at random)

What works however:

  • defining the g_properties_changed()signal myself as a member of the SimpleService class (feels very weird)
  • deriving the SimpleService class from GLib.DBusProxy instead of GLib.Object. This makes more sense, but all examples I have seen always derive the proxy object from GLib.Object so I’m wondering if this introduces additional problems (I’ve tried looking at the generated C code, and it seems fine, although I don’t fully understand it. Also, this requires “unpacking” the changed properties from a GLib.Variant, which seems contrary to the goal of using a proxy object.

So my question is: is there a Vala-native (or at least more Vala-like) way of getting notified of DBus property changes? If not, is deriving the proxy object explicitly from GLib.DBusProxy the recommended way to do this?

Thanks!

I’m wondering if this is actually the same as the following issue:

which has an MR as well: Draft: dbus: Bind properties with the GDBusProxy directly (!155) · Merge requests · GNOME / vala · GitLab

Yes, that’s exactly the issue you’re hitting, and the patch that would fix it.

You can work around the lack of support with something like this:

((DBusProxy) object).g_properties_changed.connect ((obj, changed_properties, invalidated_properties) => {
	if ("ExampleProperty" in invalidated_properties) {
		print ("ExampleProperty invalidated\n");
	} else if (changed_properties.lookup_value ("ExampleProperty", null) != null) {
		print ("ExampleProperty changed\n");
	}
});

Thank you for confirming!