Reference to "window" in Gnome-shell for use in Gnome extensions

624 Views Asked by At

I want to understand how the variable "window" which has the attribute MetaWindow can be used in different functions and vars while not being explicitly defined such as let app = this._tracker.get_window_app(window); and then passed on to other functions through a callback. Reference code here: windowAttentionHandler.js

Like here:

var WindowAttentionHandler = class {
    constructor() {
        this._tracker = Shell.WindowTracker.get_default();
        this._windowDemandsAttentionId = global.display.connect('window-demands-attention',
                                                                this._onWindowDemandsAttention.bind(this));
        this._windowMarkedUrgentId = global.display.connect('window-marked-urgent',
                                                            this._onWindowDemandsAttention.bind(this));
    }

    _getTitleAndBanner(app, window) {
        let title = app.get_name();
        let banner = _("“%s” is ready").format(window.get_title());
        return [title, banner];
    }

    _onWindowDemandsAttention(display, window) {
        // We don't want to show the notification when the window is already focused,
        // because this is rather pointless.
        // Some apps (like GIMP) do things like setting the urgency hint on the
        // toolbar windows which would result into a notification even though GIMP itself is
        // focused.
        // We are just ignoring the hint on skip_taskbar windows for now.
        // (Which is the same behaviour as with metacity + panel)

        if (!window || window.has_focus() || window.is_skip_taskbar())
            return;

        let app = this._tracker.get_window_app(window);
        let source = new WindowAttentionSource(app, window);
        Main.messageTray.add(source);

        let [title, banner] = this._getTitleAndBanner(app, window);

        let notification = new MessageTray.Notification(source, title, banner);
        notification.connect('activated', () => {
            source.open();
        });
        notification.setForFeedback(true);

        source.showNotification(notification);

        source.signalIDs.push(window.connect('notify::title', () => {
            [title, banner] = this._getTitleAndBanner(app, window);
            notification.update(title, banner);
        }));
    }
};
1

There are 1 best solutions below

34
On

The variable window is not defined as MetaWindow in the suggested code because it borrows such status using the method .bind from the listening signal window-demands-attention in the module global.display. The method .bind is responsible for sending the type MetaWindow as this allowing it to be used in other functions with reference to the window which triggered the function _onWindowDemandsAttention in the first place:

global.display.connect('window-demands-attention', this._onWindowDemandsAttention.bind(this));

The bind() method allows an object to borrow a method from another object without making a copy of that method. This is known as function borrowing in JavaScript.

Here is an example based on the suggested code for getting the focus when the window demands the attention:

var GetFocus = class {
    constructor() {
      this.focusID = global.display.connect('window-demands-attention', this._onWindowDemandsAttention.bind(this));
    }

    _onWindowDemandsAttention(display, window) {
         Main.activateWindow(window);
    }

    _destroy() {
        global.display.disconnect(this.focusID);
    }
}

The function was not working before because I was missing the .bind.