2017-04-24 47 views
0

我想DBUS消息从真棒WM发送给其他应用程序。然而,Awesome的dbus interfact文档非常简约,我找不到任何示例。怎么做?例如,我想使用org.freedesktop.login1中的Inhibit函数。如何在Awesome WM中调用dbus方法?

+0

使用d-脚得到可用的接口和方法的一个很好的列表,让您同时使用这些方法玩。 – AndreLDM

回答

1

真棒内置的可怜人的DBus包装几乎包含了足够的支持的DBus有其内置的通知守护进程(淘气)工作:https://github.com/awesomeWM/awesome/blob/259c4f716fbd08b4507ebb4cb4d40fe5cbabed0f/dbus.c#L858-L870

该API允许你实现提供对象通过的DBus和发射信号,但不能调用DBus方法。看着some docs,它好像Inhibit界面是你要调用的方法。更糟 - 它返回一个文件描述符!

随着大量的GIO的文档的阅读,我想出了以下(希望不言自明;同时也请阅读https://github.com/pavouk/lgi/blob/master/docs/gio.md)例如:

local lgi = require("lgi") 
local Gio = lgi.require("Gio") 
local GLib = lgi.require("GLib") 

-- Workaround for https://github.com/pavouk/lgi/issues/142 
local function bus_get_async(type) 
    Gio.bus_get(type, nil, coroutine.running()) 
    local a, b = coroutine.yield() 
    return Gio.bus_get_finish(b) 
end 

local function inhibit(bus, what, who, why, mode) 
    local name = "org.freedesktop.login1" 
    local object = "/org/freedesktop/login1" 
    local interface = "org.freedesktop.login1.Manager" 
    local message = Gio.DBusMessage.new_method_call(name, object, interface, "Inhibit") 
    message:set_body(GLib.Variant("(ssss)", 
     { what, who, why, mode })) 

    local timeout = -1 -- Just use the default 
    local result, err = bus:async_send_message_with_reply(message, Gio.DBusSendMessageFlags.NONE, 
     timeout, nil) 

    if err then 
     print("error: " .. tostring(err)) 
     return 
    end 

    if result:get_message_type() == "ERROR" then 
     local _, err = result:to_gerror() 
     print("error: " .. tostring(err)) 
     return 
    end 

    local fd_list = result:get_unix_fd_list() 
    local fd, err = fd_list:get(0) 
    if err then 
     print("error: " .. tostring(err)) 
     return 
    end 

    -- Now... somehow turn this fd into something we can close 
    return Gio.UnixInputStream.new(fd, true) 
end 

Gio.Async.call(function() 
    local bus = bus_get_async(Gio.BusType.SYSTEM) 
    local a = inhibit(bus, "shutdown:sleep", "hi, it's me!", "Just because", "delay") 
    print("got lock") 
    io.popen("sleep 10"):read("*a") 
    a:async_close() 
    -- Speed up deletion of the GDBusMessage that still references the FD 
    collectgarbage("collect") 
    collectgarbage("collect") 

    print("released lock") 
    io.popen("sleep 10"):read("*a") 
end)() 

如果你愿意,你可以把上面的到的东西通过调用foo_sync更换呼叫async_foo同步。这也让摆脱黑客攻击,使bus_get_async()工作和周围的一切的Gio.Async.call包装。