等待新 window 打开的 GNOME Shell 扩展
GNOME Shell extension that waits for a new window to be opened
我正在 JavaScript 中编写 GNOME Shell 扩展,它修改所有应用程序 windows。
作为练习,我想首先获取一个打开的应用程序名称 window 并将其显示在面板中。
现在,在 Looking Glass 中,我可以通过键入
来获取所有打开的 windows
>>> global.screen.get_active_workspace().list_windows()
r(0) = [object instance proxy GType:MetaWindowX11 ...], ...
我可以通过键入
来获取列表中第一个 window 的名称
>>> Shell.WindowTracker.get_default().get_window_app(r(0)[0]).get_name()
r(1) = <name of application>
但是,当我尝试在扩展的 extension.js
文件中执行此操作然后重新启动 GNOME Shell 时,我无法获取打开的 window 的名称,因为结果global.screen.get_active_workspace().list_windows()
的 undefined
。
我认为这可能是因为我的扩展在创建 windows 之前被执行,所以我开始研究如何等到 window 创建后再对 windows.
这是我真正陷入困境的地方。
在我的扩展程序的 init()
函数中,我试图添加一个事件侦听器,当它接收到 window-created
信号时运行我的函数 update()
。
window-created
信号来自 MetaDisplay 对象。
到目前为止我的代码是这样的:
let display = global.display;
display.connect('window-created', Lang.bind(this, this.update));
代码编译没有错误,但是在创建新 windows 时我的函数 update()
没有被调用。
有人知道这里发生了什么吗?我的语法错了吗?我应该使用不同的信号吗?
如有任何帮助,我们将不胜感激。
完整 extension.js 文件
const St = imports.gi.St;
const Main = imports.ui.main;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
let text, button;
function init() {
button = new St.Bin({ style_class: 'panel-button',
reactive: true,
can_focus: true,
x_fill: true,
y_fill: false,
track_hover: true });
let display = global.display;
display.connect('window-created', Lang.bind(this, this.update));
}
function update() {
let window = global.screen.get_active_workspace().list_windows()[0];
let name = Shell.WindowTracker.get_default().get_window_app(window).get_name();
text = new St.Label({ text: name });
button.set_child(text);
}
function enable() {
Main.panel._rightBox.insert_child_at_index(button, 0);
}
function disable() {
Main.panel._rightBox.remove_child(button);
}
我最终弄清楚了如何解决我的问题。问题在于我在监听哪些信号以及我在何处监听它们。经过大量研究,我还注意到大多数扩展都是面向对象的,因此我更改了代码以反映这一点。下面是我新的、有效的、面向对象的代码。
const St = imports.gi.St;
const Main = imports.ui.main;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
let button;
function MyApplication() {
this._init();
}
MyApplication.prototype = {
_init: function() {
button = new St.Bin({ style_class: 'panel-button',
reactive: true,
can_focus: true,
x_fill: true,
y_fill: false,
track_hover: true });
},
_update: function() {
text = new St.Label({ text: Shell.WindowTracker.get_default().focus_app.get_name() });
button.set_child(text);
},
enable: function() {
Main.panel._rightBox.insert_child_at_index(button, 0);
let callbackID = global.display.connect('notify::focus-window', Lang.bind(this, this._update));
},
disable: function() {
Main.panel._rightBox.remove_child(button);
}
};
function init() {
return new MyApplication();
}
我正在 JavaScript 中编写 GNOME Shell 扩展,它修改所有应用程序 windows。
作为练习,我想首先获取一个打开的应用程序名称 window 并将其显示在面板中。
现在,在 Looking Glass 中,我可以通过键入
来获取所有打开的 windows>>> global.screen.get_active_workspace().list_windows()
r(0) = [object instance proxy GType:MetaWindowX11 ...], ...
我可以通过键入
来获取列表中第一个 window 的名称>>> Shell.WindowTracker.get_default().get_window_app(r(0)[0]).get_name()
r(1) = <name of application>
但是,当我尝试在扩展的 extension.js
文件中执行此操作然后重新启动 GNOME Shell 时,我无法获取打开的 window 的名称,因为结果global.screen.get_active_workspace().list_windows()
的 undefined
。
我认为这可能是因为我的扩展在创建 windows 之前被执行,所以我开始研究如何等到 window 创建后再对 windows.
这是我真正陷入困境的地方。
在我的扩展程序的 init()
函数中,我试图添加一个事件侦听器,当它接收到 window-created
信号时运行我的函数 update()
。
window-created
信号来自 MetaDisplay 对象。
到目前为止我的代码是这样的:
let display = global.display;
display.connect('window-created', Lang.bind(this, this.update));
代码编译没有错误,但是在创建新 windows 时我的函数 update()
没有被调用。
有人知道这里发生了什么吗?我的语法错了吗?我应该使用不同的信号吗?
如有任何帮助,我们将不胜感激。
完整 extension.js 文件
const St = imports.gi.St;
const Main = imports.ui.main;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
let text, button;
function init() {
button = new St.Bin({ style_class: 'panel-button',
reactive: true,
can_focus: true,
x_fill: true,
y_fill: false,
track_hover: true });
let display = global.display;
display.connect('window-created', Lang.bind(this, this.update));
}
function update() {
let window = global.screen.get_active_workspace().list_windows()[0];
let name = Shell.WindowTracker.get_default().get_window_app(window).get_name();
text = new St.Label({ text: name });
button.set_child(text);
}
function enable() {
Main.panel._rightBox.insert_child_at_index(button, 0);
}
function disable() {
Main.panel._rightBox.remove_child(button);
}
我最终弄清楚了如何解决我的问题。问题在于我在监听哪些信号以及我在何处监听它们。经过大量研究,我还注意到大多数扩展都是面向对象的,因此我更改了代码以反映这一点。下面是我新的、有效的、面向对象的代码。
const St = imports.gi.St;
const Main = imports.ui.main;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
let button;
function MyApplication() {
this._init();
}
MyApplication.prototype = {
_init: function() {
button = new St.Bin({ style_class: 'panel-button',
reactive: true,
can_focus: true,
x_fill: true,
y_fill: false,
track_hover: true });
},
_update: function() {
text = new St.Label({ text: Shell.WindowTracker.get_default().focus_app.get_name() });
button.set_child(text);
},
enable: function() {
Main.panel._rightBox.insert_child_at_index(button, 0);
let callbackID = global.display.connect('notify::focus-window', Lang.bind(this, this._update));
},
disable: function() {
Main.panel._rightBox.remove_child(button);
}
};
function init() {
return new MyApplication();
}