首页 > 解决方案 > 哪个 gnome 函数负责切换工作区?

问题描述

Gio open "http://..." from terminal 从当前工作区切换到默认浏览器所在的工作区。当从其他应用程序(电子邮件等)打开链接时也会发生同样的情况。

我想写一个扩展,我试图覆盖 js/ui 中的很多函数。其中一些会阻止工作区切换,例如通过键盘进行切换,但似乎没有什么能阻止工作区随着这些链接而改变。我想 d-bus 激活与此有关,但由于这是我对 gnome 的第一次探索,我觉得这里有点失落。

所以,我想覆盖一个负责工作区切换的 gnome 函数。基本上我想阻止所有切换,然后从那里继续。在 Mutter 参考手册中说,当活动工作空间发生变化时,首先调用 meta_compositor_switch_workspace()。Javascript 版本位于 js/ui/windowManager.js:_switchWorkspace(shellwm, from, to, direction) 中。

如果我覆盖该函数,则不会发生任何事情。没有错误。这是一个错误的功能吗?难道我做错了什么?我是否应该自己覆盖 meta_compositor_switch_workspace 而不是 _switchWorkSpace?如果我应该这样做,有什么帮助吗?

const Meta = imports.gi.Meta;
const Main = imports.ui.main;
const WindowManager = imports.ui.windowManager;


function mySwitchWorkspace(shellwm, from, to, direction) {
    log("in my switchWorkspace");
    //if ... {
    //        shellwm.completed_switch_workspace();
            return;
    //    }
    }

let old_sw = {};

function init() {
    old_sw = WindowManager.WindowManager.prototype._switchWorkspace;
    log(old_sw);
}

function enable() {
    WindowManager.WindowManager.prototype._switchWorkspace = mySwitchWorkspace;
    log(WindowManager.WindowManager.prototype._switchWorkspace);
}

function disable() {
    WindowManager.WindowManager.prototype._switchWorkspace = old_sw;
}

标签: javascriptoverridinggnomegjs

解决方案


GNOME Shell 的体系结构以及它与扩展的关系并不是很明显,所以当你走在正确的轨道上时,你在这里错过了一些视角。

Mutter 是一个窗口管理器库,而 GNOME Shell 在技术上是一个 Mutter 插件。GNOME Shell 中的实现Meta.PluginShell.WM. windowManager.js在指向Shell.WMis的变量的 JavaScript 代码中windowManager._shellwm

// windowManager.js Line #590
this._shellwm.connect('switch-workspace', this._switchWorkspace.bind(this));

// windowManager.js Line #1799
_switchWorkspace(shellwm, from, to, direction) {
}

Shell.WM::switch-workspace在上面的代码中,您可以看到绑定this._switchWorkspace(). 尽管您已经覆盖了该函数,但Function.prototype.bind()创建了一个新的函数实例,因此将调用原始回调的副本而不是您的。

在这种情况下,没有存储处理程序 ID,因此您必须使用gjs >= 1.64(GNOME 3.36) 中的新助手断开信号:

let shellwm = global.window_manager
let handler = GObject.signal_handler_find(shellwm, {signalId: 'switch-workspace'});
shellwm.disconnect(handler);

完成后,您应该能够像普通信号回调一样连接您的覆盖,然后替换原始处理程序。

// Replacing the original handler when your extension is disabled
function disable() {
    shellwm = global.window_manager;
    wm = imports.ui.main.wm;
    shellwm.connect('switch-workspace', wm._switchWorkspace.bind(wm));
}

推荐阅读