我正在尝试开发 gnome 的扩展,这样我就可以直接从状态栏关闭盖子时抑制系统睡眠,而无需打开调整。
到目前为止,我有一个基本的 js 脚本,可以成功连接到 gdbus 并能够执行命令,但我无法让抑制器工作。我认为问题是我没有以正确的方式处理抑制函数返回的文件描述符,因为文档表示只有当文件描述符被引用并打开时,抑制器才会保留在原位。但也可能是我没有正确调用该函数。
如果有人能给我一些建议,我将不胜感激。我正在运行 Ubuntu 18.04.4 和 gnome 3.28.2
/* -*- mode: js2 - indent-tabs-mode: nil - js2-basic-offset: 4 -*- */
/*jshint multistr:true */
/*jshint esnext:true */
/*global imports: true */
/*global global: true */
/*global log: true */
'use strict';
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Mainloop = imports.mainloop;
const Atk = imports.gi.Atk;
const DBusInterface = '<node>\
<interface name="org.freedesktop.login1.Manager">\
<method name="Inhibit">\
<arg type="s" direction="in" />\
<arg type="s" direction="in" />\
<arg type="s" direction="in" />\
<arg type="s" direction="in" />\
<arg type="h" direction="out" />\
</method>\
<method name="ListInhibitors">\
<arg type="a(ssssuu)" direction="out" />\
</method>\
</interface>\
</node>';
const DBusProxy = Gio.DBusProxy.makeProxyWrapper(DBusInterface);
let proxy = new DBusProxy(
Gio.DBus.system,
"org.freedesktop.login1",
"/org/freedesktop/login1"
);
let inhibitors = proxy.ListInhibitorsSync();
print(inhibitors);
let fd = proxy.InhibitSync('handle-lid-switch',
'gnome-extension-lid-inhibitor',
'user preference',
'block');
inhibitors = proxy.ListInhibitorsSync();
print(inhibitors);
let loop = new GLib.MainLoop(null, false);
loop.run();
答案1
好的,我说得对,FD 在函数结束时被关闭,从而释放了抑制。我找不到让 FD 保持打开状态的方法,但我能够异步使用它来保持函数运行。
下一步是将其集成到我的扩展中。
这是新的代码:
/*jshint multistr:true */
/*jshint esnext:true */
/*global imports: true */
/*global global: true */
/*global log: true */
'use strict';
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Mainloop = imports.mainloop;
const Atk = imports.gi.Atk;
const DBusInterface = '<node>\
<interface name="org.freedesktop.login1.Manager">\
<method name="Inhibit">\
<arg type="s" direction="in" />\
<arg type="s" direction="in" />\
<arg type="s" direction="in" />\
<arg type="s" direction="in" />\
<arg type="h" direction="out" />\
</method>\
</interface>\
</node>';
const DBusProxy = Gio.DBusProxy.makeProxyWrapper(DBusInterface);
let proxy = new DBusProxy(
Gio.DBus.system,
"org.freedesktop.login1",
"/org/freedesktop/login1"
);
var inhibitor = {loop:''};
/* Inhibit remote starts the inhibitor asynchronously and locks itself with
a GLib.MainLoop assigned to inhibitor.loop.
To release the inhibit just quit the loop at inhibitor.loop
*/
proxy.InhibitRemote('handle-lid-switch', 'lidsleep-inhibitor',
'el diego de la gente lo quiere', 'block',
(fileDescriptor) => {
if (fileDescriptor) {
let loop = new GLib.MainLoop(null, false);
inhibitor.loop = loop;
log("Inhibitor added to array");
loop.run();
log("Shutting down completed");
return;
}
else {
logError("Inhibit returned null");
return;
}
});
/* A ten second timer function */
Promise.timeoutSeconds = function(priority = GLib.PRIORITY_DEFAULT, interval = 10) {
return new Promise(resolve => GLib.timeout_add_seconds(priority, interval, resolve));
};
/* A function that calls a timer and wait for it to finish. Then, if the arg
cont is true it releases the inhibit and return false. Otherwise it quits
the main loop.
*/
async function asyncCall(cont) {
try {
log('Waiting 10 sec');
await Promise.timeoutSeconds();
if (cont){
log('10 sec completed, inhibitor shut down starting');
inhibitor.loop.quit();
return !cont;
} else {
log('Quitting main loop');
loop.quit();
return;
}
} catch (e) {
throw e;
}
}
let loop = new GLib.MainLoop(null, false);
/* asyncCall is called twice.
The first run releases the inhibit.
The second run quits the main loop.
*/
asyncCall(true).
then(asyncCall);
log("Starting main loop");
loop.run();