Description of the connectObject and disconnectObject methods

As stated in the documentation, GNOME Shell 42 uses connectObject() and disconnectObject() convenience methods instead of connect() and disconnect() methods. Unfortunately, I can’t find any information about this methods. Can anyone point to the documentation for these methods, or at least describe their arguments and how they differ from connect() and disconnect()?

There is no documentation, as far as I know. These are generally intended to be versions of g_signal_connect_object(), which ensures a signal is disconnected if the connecting object (the object calling foo.connect()) destroyed. This should ensure there are no dangling signal handlers that call freed objects, but this only works for object with a destroy signal, as far as I know.

The source can be found here.

From the description of the MR with some addition:

In its simplest form, connectObject() looks like the regular connect() method, except for an additional parameter:

    this._button.connectObject('clicked',
        () => this._onButtonClicked(), this);

The additional object should always go last and is optional, it can be used to disconnect all handlers on the instance that were connected with that object, similar to g_signal_handlers_disconnect_by_data() (which cannot be used from introspection):

    this._button.disconnectObject(this);

For objects that are subclasses of Clutter.Actor, that will happen automatically when the actor is destroyed, similar to g_signal_connect_object().

Finally, connectObject() allows to conveniently connect multiple signals at once, similar to g_object_connect():

    this._toggleButton.connect(
        'clicked', () => this._onClicked(),
        'notify::checked', () => this._onChecked(), this);

You can also optionally pass the GObject.ConnectFlags.AFTER flag (and only it), it must go after the handler:

    this._toggleButton.connect(
        'clicked', () => this._onClicked(), GObject.ConnectFlags.AFTER,
        'notify::checked', () => this._onChecked(), this);
1 Like

To make it possible for other types you need to:

  1. ensure the type inherits from GObject.Object
  2. ensure the type provides the destroy signal
  3. register the type as destroyable with SignalTracker.registerDestroyableType()

Here’s example:

const MyObject = GObject.registerClass({
    Signals: {
        'destroy': {},
    },
}, class MyObject extends GObject.Object {
    destroy() { // this function should be called manually
        this.emit('destroy');
    }
});

SignalTracker.registerDestroyableType(MyObject);

Note that the destroy signal in the class above will not be emitted automatically. So if you’re expecting connectObject() to work as it does with Clutter.Actor, this won’t happen.

The reason why objects like Clutter.Actor can guarantee destroy is emitted, is because they are written in C and can implement the dispose() vfunc. This can’t be done safely in GJS (or likely other language bindings), since the JavaScript engine needs to control the disposal of the object.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.