JS 脚本在盖子关闭时禁止睡眠不起作用。文件描述符管理问题还是其他问题?

JS 脚本在盖子关闭时禁止睡眠不起作用。文件描述符管理问题还是其他问题?

我正在尝试开发 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();

相关内容