Migrating GObject.registerClass to GNOME 45

Goal: Migrating (an unmaintained) pre-45 gnome shell extension to 45.

I believe I’ve fixed the imports:

//const { GLib, GObject, Meta } = imports.gi;
import GLib from 'gi://GLib';
import GObject from 'gi://GObject';
import Meta from 'gi://Meta';

//const CloseDialog = imports.ui.closeDialog;
import CloseDialog from "resource:///org/gnome/shell/ui/closeDialog.js";

But, how do I migrate the rest (without minimum of theory), please?

let DisableCloseDialog = GObject.registerClass({
    Implements: [ Meta.CloseDialog ],
    Properties: {
        window: GObject.ParamSpec.override('window', Meta.CloseDialog)
    }
}, class DisableCloseDialog extends GObject.Object {
    _init(window) {
        super._init();
        this._window = window;
    }

    get window() {
        return this._window;
    }

    vfunc_show() {
        GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
            this.response(Meta.CloseDialogResponse.WAIT);
            return GLib.SOURCE_REMOVE;
        });
    }

    vfunc_hide() {
    }

    vfunc_focus() {
    }
});

class Extension {
    constructor() {
        this._origCloseDialog = CloseDialog.CloseDialog;
    }

    enable() {
        CloseDialog.CloseDialog = DisableCloseDialog;
    }

    disable() {
        CloseDialog.CloseDialog = this._origCloseDialog;
    }
}

function init() {
    return new Extension();
}

// Neither of the following works:
//
// export DisableCloseDialog;
// export default DisableCloseDialog;
// export default class DisableCloseDialog;

(GitHub - peter-kehl/gnome-disable-force-quit-popup: Disable '"XYZ" is not responding.' popup in GNOME. I’m on GNOME 45 on current Manjaro x64 Linux. If there’s a better “category”, please suggest so.)
Thank you in advance.

GObject.registerClass isn’t your problem, it’s this:

   CloseDialog.CloseDialog = DisableCloseDialog;

With standard modules, exported symbols can only be modified by the exporting module, they are always read-only for the importing side.

That is, you can modify the exported class, but you cannot outright replace it with something else.

I recommend taking a look at the InjectionManager class. It works with vfuncs, so you should be able to override the original vfunc_show with something like

    import {CloseDialog} from 'resource:///org/gnome/shell/ui/closeDialog.js';

// ...
    enable() {
        this._injectionManager.overrideMethod(CloseDialog.prototype, 'vfunc_show', () => {
            return function() {
                GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
                   this.respose(Meta.CloseDialogResponse.WAIT);
                   return GLib.SOURCE_REMOVE;
               });
            };
        });
    }

Last but not least, there is a check-alive-timeout setting in org.gnome.mutter that can be set to 0 to disable the dialog without any extensions.

1 Like

Last but not least, there is a check-alive-timeout setting in org.gnome.mutter that can be set to 0 to disable the dialog without any extensions.

That first needs a release with delete: Don't wrongly set window as not alive when pings are disabled (!3367) · Merge requests · GNOME / mutter · GitLab to work on Wayland again.

1 Like

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