2017-04-24 15 views
0

Awesome WMから他のアプリケーションにdbusメッセージを送信したい。しかし、Awesomeのdbusインタフェクトのドキュメントはかなり単純で、例は見つけられません。どうやってするか?たとえば、org.freedesktop.login1Inhibit関数を使用したいとします。Awesome WMでdbusメソッドを呼び出すには?

+0

D-Feetを使用して、利用可能なインターフェイスとそのメソッドの素敵なリストを取得し、これらのメソッドでも遊ぶことができます。 – AndreLDM

答えて

1

恐ろしいDバスは、内蔵の通知デーモン(いたずら)仕事持っているため、内蔵貧乏人のDバスラッパーがかろうじて十分なサポートが含まれています:https://github.com/awesomeWM/awesome/blob/259c4f716fbd08b4507ebb4cb4d40fe5cbabed0f/dbus.c#L858-L870

このAPIを使用すると、Dバスを経由して利用できるオブジェクトを実装し、放出することを可能にしますしかし、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)() 

あなたがしたい場合は、何かに上記を変えることができますasync_fooへの呼び出しをfoo_syncへの呼び出しと置き換えることによって同期します。それはまた、bus_get_async()を働かせるためのハックを取り除き、すべての周りにGio.Async.callラッパーを作ることを可能にします。

関連する問題