我想写一个gnome-shell扩展,它涉及在gjs中调用一些dbus。
我已经了解到Gio.DBus是正确使用的模块,但我无法正常运行。为了证明我的意思,我准备了以下“不正确”的代码,它试图在org.freedesktop.DBus接口中调用ListNames方法。当我运行这个错误的代码时,我没有看到任何输出。
代码不正确:
const Gio = imports.gi.Gio;
const DBusDaemonIface = <interface name='org.freedesktop.DBus'>
<method name='ListNames'>
<arg type='as' direction='out'/>
</method>
</interface>;
const DBusDaemonProxy = Gio.DBusProxy.makeProxyWrapper(DBusDaemonIface);
let main = function () {
var gdbusProxy = new DBusDaemonProxy(Gio.DBus.session, 'org.freedesktop.DBus', '/org/freedesktop/DBus');
gdbusProxy.ListNamesRemote(function(result, error){ print(result); });
};
main();
为了进行比较,以下代码有效。我做的不同是定义一个扩展Gio.Application的TestApp类,它在main()函数中实例化。
正确的代码:
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const DBusDaemonIface = <interface name='org.freedesktop.DBus'>
<method name='ListNames'>
<arg type='as' direction='out'/>
</method>
</interface>;
const DBusDaemonProxy = Gio.DBusProxy.makeProxyWrapper(DBusDaemonIface);
TestApp = new Lang.Class({
Name: 'TestApp',
Extends: Gio.Application,
_init: function() {
this.parent({application_id: 'testapp_id',
flags: Gio.ApplicationFlags.NON_UNIQUE });
this._gdbusProxy = new DBusDaemonProxy(Gio.DBus.session,
'org.freedesktop.DBus', '/org/freedesktop/DBus');
this._gdbusProxy.ListNamesRemote(Lang.bind(this, this._listNames));
},
_listNames: function(result, error) {
print(result);
},
vfunc_activate: function() {
this.hold();
},
});
let main = function () {
let app = new TestApp();
return app.run(ARGV);
};
main();
所以我的猜测是让GDBus工作,你需要运行Gio.Application吗?这可能是一个非常愚蠢的问题,因为我没有为GNOME编程的经验。感谢。
答案 0 :(得分:1)
代码很好,除了你没有运行主循环,因此应用程序只在ListNamesRemote
回调有时间运行之前退出。 app.run(ARGV)
会给你一个主循环,但你也可以使用普通的GLib来完成它:
const GLib = imports.gi.GLib;
// ... then in the end of your main() function:
var main_loop = new GLib.MainLoop(null, true);
main_loop.run();