romgrk / node-gtk

GTK+ bindings for NodeJS (via GObject introspection)
MIT License
494 stars 41 forks source link

Gtk will not register custom getters for built-in properties #293

Closed binyamin closed 3 years ago

binyamin commented 3 years ago

When a custom class extends a GtkWidget, and I write a custom getter for a built-in property, the property's value changes, but Gtk will not read it.

Example :point_down:

// [1] When a custom class extends a GtkWidget
class CustomClass extends Gtk.Label {
    constructor(text) {
    super();
        this._text = text;
    }

    // [2] And it overrides a built-in getter/setter
    get label() {
        return "My name is: " + this._text;
    }
}

const test = new CustomClass("Bob");

// [3] Instantiated classes will return the new `label`
console.log(test.label); // => "My name is: Bob"

// [4] But windows will not use the new `label` when rendering the widget.
const app = new Gtk.Window();
app.add(test)
app.showAll();
// => window is blank
romgrk commented 3 years ago

First, when you override a GTK widget, you need to use gi.registerClass(CustomClass), as it provides better interoperability with the GTK tools, for example the built-in inspector (ctrl-shift-d) will show the object with its real name and GLib will be aware that it's a different class.

Second, what you're trying to do will not work out of the box. What GTK uses for its object are GObject properties. Those properties live in the C side, and are accessible through JS but they are not JS properties. When you do customInstance.label = 'abc', you're not setting the C property, you're just setting a property on the JS side. For the moment, the only way to implement what you want would be something like this:

class CustomClass extends Gtk.Label {
    constructor(text) {
    super();
        this.label = text; // Note: this is calling the setter below
    }

    set label(text) {
        this.setProperty("label", "My name is: " + text);
    }

    get label() {
        return this.getProperty("label");
    }
}
gi.registerClass(CustomClass)
romgrk commented 3 years ago

I'll close as this is not something that I plan to implement.