问题描述
我遵循了这个https://wiki.gnome.org/Projects/GnomeShell/Extensions/StepByStepTutorial来覆盖函数。
例如,我想覆盖_setupKeyboard()
类上的函数Keyboard
,但是没有调用我的覆盖。我要更改的特定部分是这样,以删除if
防护:
if (Meta.is_wayland_compositor()) {
this._connectSignal(this._keyboardController,'emoji-visible',this._onEmojikeyvisible.bind(this));
}
我从源代码中复制了该函数,删除了我不需要的部分,然后像这样设置替换函数:
const Keyboard = imports.ui.keyboard;
Keyboard.Keyboard.prototype._setupKeyboard = myOverride;
为什么不调用我的覆写,如何实现呢?
解决方法
有两个常见的原因不会调用覆盖。如果在应用覆盖之前调用了该方法,或者该函数是使用Function.prototype.bind()
设置的回调函数,则会创建新的闭包。
在这种情况下,将在应用覆盖之前调用函数_setupKeyboard()
。 GNOME Shell启动时,它将创建Keyboard.KeyboardManager
here的实例:
// main.js,line #204
keyboard = new Keyboard.KeyboardManager();
在将keyboard
变量分配给实例之前,已经创建了默认的Keyboard.Keyboard
类,并且已经在Keyboard._init()
中调用了函数_setupKeyboard()
,这比扩展程序的加载要早得多。
由于无法轻松解决此问题,因此最好的选择是重新创建要运行的代码的一部分:
const Meta = imports.gi.Meta;
const Main = imports.ui.main;
const Keyboard = imports.ui.keyboard.Keyboard;
const originalSetup = Keyboard.prototype._setupKeyboard;
const modifiedSetup = function () {
originalSetup.call(this);
if (!Meta.is_wayland_compositor()) {
this._connectSignal(this._keyboardController,'emoji-visible',this._onEmojiKeyVisible.bind(this));
}
this._relayout();
};
function init() {
}
// Your extension's enable function (might be a class method)
function enable() {
let kbd = Main.keyboard.keyboardActor;
if (kbd !== null) {
if (!Meta.is_wayland_compositor()) {
kbd.__mySignalId = kbd._connectSignal(kbd._keyboardController,kbd._onEmojiKeyVisible.bind(kbd));
}
}
Keyboard.prototype._setupKeyboard = modifiedSetup;
}
function disable() {
let kbd = Main.keyboard.keyboardActor;
if (kbd !== null && kbd.__mySignalId) {
kbd.disconnect(kbd.__mySignalId);
kbd.__mySignalId = 0;
}
Keyboard.prototype._setupKeyboard = originalSetup;
}
这不是很漂亮,但这通常是修补私人代码的代价。我也不能保证该代码能满足您的要求,因为我怀疑表情符号键是出于某种原因隐藏在X11上。