参考 Gnome-shell 中的“window”以用于 Gnome 扩展

问题描述

我想了解具有 MetaWindow 属性的变量“window”如何在不同的函数和变量中使用,而没有被显式定义,例如 let app = this._tracker.get_window_app(window);,然后通过回调。此处参考代码windowAttentionHandler.js

喜欢这里:

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,window);
            notification.update(title,banner);
        }));
    }
};

解决方法

变量window在建议的代码中没有定义为MetaWindow,因为它使用.bind方法从模块window-demands-attention中的监听信号global.display中借用了这样的状态1}}。方法 .bind 负责将类型 MetaWindow 发送为 this 允许它在其他函数中使用,并参考首先触发函数 _onWindowDemandsAttention 的窗口:

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

bind() 方法允许对象从 另一个对象而不复制该方法。这被称为 JavaScript 中的函数借用。

这是一个基于建议代码的示例,用于在窗口需要注意时获取焦点:

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);
    }
}

该函数之前无法工作,因为我错过了 .bind