2

我按照这个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;

为什么我的覆盖没有被调用,我该如何实现?

4

1 回答 1

2

不会调用覆盖有两个常见原因。如果在应用覆盖之前调用了该方法,或者该函数是一个回调集,使用Function.prototype.bind()它创建一个新的闭包。

在这种情况下,在_setupKeyboard()应用您的覆盖之前调用该函数。当 GNOME Shell 启动时,它会创建一个Keyboard.KeyboardManager here的实例:

// main.js, line #204
keyboard = new Keyboard.KeyboardManager();

在将keyboard变量分配给实例时,Keyboard.Keyboard已经创建了一个默认类并且_setupKeyboard()已经调用了函数Keyboard._init(),这比加载扩展要快得多。

由于无法轻松解决此问题,因此您最好的选择是重新创建要运行的代码的一部分:

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, 'emoji-visible',
                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 上是有原因的。

于 2020-08-18T06:50:18.580 回答