如何检查已定义Gjs类?

时间:2017-03-09 18:30:55

标签: gnome gnome-shell-extensions gjs

我正在编写首选项视图GNOME shell扩展,并且在使用imports.lang函数以面向对象的方式编写应用程序时会遇到问题。

const Gtk = imports.gi.Gtk
const Lang = imports.lang
Gtk.init(null)
const MyWindow = new Lang.Class({...})

首次打开首选项窗口,但后续的会抛出以下错误:Error: Type name Gjs_MyWindow is already registered。在第一次关闭窗口时,我收到此错误:TypeError: prefsModule.init is not a function

以下更强制性的代码有效:

const Gtk = imports.gi.Gtk
Gtk.init(null)
const window = new Gtk.Window({ type: Gtk.WindowType.TOPLEVEL })

基于抛出的错误,我的猜测是该类正在被重新定义。如何避免重新定义并接收定义的类别? (我可以参考哪些文档?)

2 个答案:

答案 0 :(得分:1)

看起来正确答案在this discussion

  

如果你扩展一个GObject类(St,Clutter,Gtk等等),那么你正在注册一个新的GType,而这对扩展来说是不可能的。

     

...

     

扩展是动态模块,它们可以加载和卸载 - 但这对GType来说根本不可能。

所以,不要扩展GTypes。相反,使用“委托模式”,看起来像这样。

const Class = new Lang.Class({
  Name: "Class",

  _init: function() {
    this.actor = new St.Button();
  }
)};

这就是说,如果您查看系统上安装的扩展并执行grep -rn 'Extends: Gtk' /usr/share/gnome-shell/extensions/之类的操作,您会发现某些扩展仍然会扩展GType,并且不会导致任何错误。但是你会发现它永远不会在extension.js文件中完成......

不要在这里询问更多细节,这就是我今天所知道的全部细节!

答案 1 :(得分:0)

如果你想在GJS中坚持GObject / Gtk类,请检查testGObjectClass.jstestGtk.js(实际上整个目录都是黄金)。

如果这是prefs.js,则需要一个名为buildPrefsWidget()的函数,该函数应返回要添加到窗口的窗口小部件实例,而不是Gtk.Window实例。否则,您应该定义您的班级:

const MyWindow = new Lang.Class({
    Name: "MyWindow",
    Extends: Gtk.Window,

    _init: function (params) {
        this.parent(params);

        ...
    }
});

然后在定义之后,创建一个实例并使用它:

Gtk.init(null);
let window = new MyWindow({ type: Gtk.WindowType.TOPLEVEL });
window.show_all();
Gtk.main();