Pushing custom signals between different classes

I’m trying to trigger specific routines in different GObject subclasses by emitting a custom signal, following GJS examples:

export const MyEmittingType = GObject.registerClass({
    GTypeName: 'MyEmittingType',
    Signals: {
        'start': { },
        'stop': { },
    },
}, class MyEmittingType extends GObject.Object {

    // ...

    func() {
        this.emit('start');
    }

});


export const MyOtherType = GObject.registerClass({
    GTypeName: 'MyOtherType',
}, class MyOtherType extends GObject.Object {

    // ...

    func() {
        this.connect('start', () => { console.debug('start!'); });
    }

    // defauilt handler -> not working
    on_start() {
        console.debug('start!');
    }

    // ...

});

However, this does not seem to be working, the callback/handler functions is never called unless when signal is emitted from the same class. Is there any particular aspect I’m missing? Do I need to import or re-declare those signals from the the ‘receiving’ class?

You’re trying to connect to a signal on a different object type. You want something like this:

export const MyEmittingType = GObject.registerClass({
    GTypeName: 'MyEmittingType',
    Signals: {
        'start': { },
        'stop': { },
    },
}, class MyEmittingType extends GObject.Object {

    // ...

    func() {
        this.emit('start');
    }

    // Default handlers are for the emitting class
    on_start() {
        console.debug('class handler: start!');
    }
});


export const MyOtherType = GObject.registerClass({
    GTypeName: 'MyOtherType',
}, class MyOtherType extends GObject.Object {

    // ...

    func() {
        this._emittingType = new MyEmittingType();
        this._emittingType.connect('start', () => {
            console.debug('user handler: start!');
        });
    }
});

Or maybe you’re looking to subclass:

export const MyEmittingType = GObject.registerClass({
    GTypeName: 'MyEmittingType',
    Signals: {
        'start': { },
        'stop': { },
    },
}, class MyEmittingType extends GObject.Object {

    // ...

    func() {
        this.emit('start');
    }

});

export const MyOtherType = GObject.registerClass({
    GTypeName: 'MyOtherType',
}, class MyOtherType extends MyEmittingType {

    // ...

    func() {
        this.connect('start', () => { console.debug('start!'); });
    }

    // You can override the default handler for a super-class
    on_start() {
        console.debug('start!');
    }

    // ...

});

I see, connect needs to be called on the emitting class (which, looking back, it’s pretty obvious looking at some of the menu/button examples).

Just a follow-up though, is an instance of MyEmittingType (whether through composition or inheritance) always necessary? Or can one bind the handler in ‘static’ fashion i.e. just by declaring the type?

You need an emitting instance, since something needs to emit the signal. That instance is what stores the list of connected handlers, closures, default handler and so on.

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