Is it possible to create a binding between two properties of the same GObject subclass?

Following GJS resources on GObject, I’m trying to bind the active property of the following class to the value of n-windows:

import GObject from 'gi://GObject';

import * as Main from 'resource:///org/gnome/shell/ui/main.js';

const MyClass = GObject.registerClass({
    GTypeName: 'MyClass',
    Properties: {
        'active': GObject.ParamSpec.boolean(
            'active', 'active', 'On/off status',
            GObject.ParamFlags.READABLE, false
        'n-windows': GObject.ParamSpec.uint64(
            'n-windows', 'n-windows', 'Number of windows',
            GObject.ParamFlags.READABLE, 0
}, class MyClass extends GObject.Object {

    constructor() {

        this._active = false;
        this._n_windows = 0;

        this._id = global.display.connect_after('window-created', this.refresh.bind(this));

        this._binding = this.bind_property_full('n-windows', this, 'active', GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.DEFAULT,
            (binding, n_windows) => {
                console.debug('Updating active status!');
                return [true, !!n_windows];
            }, null);


    refresh() {
        const n_windows = return 10 * Math.random();  // debug

        this.notify('active');    // required?

However, this does not seem to work, the property values is never updated and the transformation function does not seem to be called ever. What am I missing?

A property binding works by reading the source property and writing the target property. That is, the target property must be WRITABLE, but here active is read-only.

You’ll have to do something like

    get n_windows() {
        return this._n_windows;

    get active() {
        return !!this._n_windows;

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