aboutsummaryrefslogtreecommitdiff
path: root/.config/awesome/curious.lua
blob: 66c33da0a279e5e5118bb199ed6fc63073a14079 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
local lgi = require "lgi"
local Gio = lgi.Gio
local GObject = lgi.GObject
local GLib = lgi.GLib
local gpcall = require "gears.protected_call"
local gtimer = require "gears.timer"

local methods = {}

local interface = Gio.DBusInterfaceInfo {
    name = "com.twoexem.delta.Curious",
    methods = {
        Gio.DBusMethodInfo {
            name = "Select",
            out_args = {
                Gio.DBusArgInfo {
                    name = "widget_tree",
                    signature = "av",
                },
            },
        },
    },
}

-- iterate with ipairs, get the length of the array, check if key value from pairs is a number lower than the length and if so, use as a dict key cause it's not gonna work with :add anyway
local function serialize(builder, t)
    local array_length = 0
    for i, _ in ipairs(t) do
        array_length = i
    end

    for k, v in pairs(t) do
        local _type = type(v)
        local signature
        local data
        if _type == "number" then
            signature = "d"
            data = v
        elseif _type == "string" then
            signature = "s"
            data = v
        elseif _type == "boolean" then
            signature = "b"
            data = v
        elseif _type == "thread" or _type == "function" or (_type == "userdata" and not getmetatable(v).__tostring) then
            local address = tonumber(tostring(v):match "%a+: 0x(%w+)", 16)
            signature = "(s(t))"
            data = { _type, address }
        elseif _type == "userdata" then
            if getmetatable(v).emit_signal then -- One of the properties available on any awesome luaobject
                local _, _, content = tostring(v):match "%a+/(.*)"
                local stringified = tostring(v)
                if content then
                    stringified = content
                end
                local type, extra, address = stringified:match "(%a+)(.*): 0x(%w+)"
                if extra ~= "" then
                    extra:sub(2, -2)
                    signature = "(s(st))"
                    data = { type, extra, address }
                else
                    signature = "(s(t))"
                    data = { type, address }
                end
            else
                signature = "(s())"
                data = { _type, {} }
            end
        end

        if type(k) == "number" and k > array_length then
            builder:add("v", GLib.Variant(signature, data))
        else
            print(type(signature), type(data))
            local variant = GLib.Variant("{sd}", { "test", 4 })
            builder:add_value(GLib.Variant("v", variant))
        end
    end
end

function methods.Select(parameters, invocation)
    local builder = GLib.VariantBuilder(GLib.VariantType "av")
    serialize(builder, { "test", some_key = "some_value" })
    local tuple_builder = GLib.VariantBuilder(GLib.VariantType "(av)")
    tuple_builder:add_value(builder:_end())
    -- builder
    -- invocation:return_value(GLib.Variant("(av)", { builder }))
    invocation:return_value(tuple_builder:_end())
end

local function handle_call(_, _, _, _, method, parameters, invocation)
    if not methods[method] then
        print "invalid"
        return
    end
    gpcall(methods[method], parameters, invocation)
end

local function acquire(connection)
    connection:register_object("/com/twoexem/delta/Curious", interface, GObject.Closure(handle_call))
end

local connection = Gio.bus_own_name(
    Gio.BusType.SESSION,
    "com.twoexem.delta.Curious",
    Gio.BusNameOwnerFlags.NONE,
    GObject.Closure(acquire)
)