Search code examples
luacairoconky

Lua script for conky runs without errors but doesn't draw anything


I am new to lua and was trying to get more into it by creating scripts for conky. In my example, I was trying to encapsulate cairo functionality into a Canvas object and drawable objects (i.e. Text object) that can be added to the canvas.

When I tried to store cairo_surface and cairo objects in a table I wasn't able to use them anymore. Even though no error occured (no message or segfault or leaks) no text was displayed in the second example.

This example works:

Canvas = {
    init = function (w)
        local cs = cairo_xlib_surface_create(w.display,w.drawable,w.visual,w.width,w.height)
        local cr = cairo_create(cs)
        return cr, cs
    end,

    destroy = function (cr, cs)
        cairo_destroy(cr)
        cairo_surface_destroy(cs)
    end
}

function conky_main ()
    if conky_window == nil then
        return
    else
        local cr, cs = Canvas.init(conky_window)
        local tx = Text:new{text="Hello World!"}
        tx:draw(cr)
        Canvas.destroy(cr, cs)
    end
end

This example doesn't work:

Canvas = {
    init = function (w) -- returns table instead of 2 variables
        return {
            cs = cairo_xlib_surface_create(w.display,w.drawable,w.visual,w.width,w.height),
            cr = cairo_create(cs)
        }
    end,

    destroy = function (cnv)
        cairo_destroy(cnv.cr)
        cairo_surface_destroy(cnv.cs)
    end
}

function conky_main ()
    if conky_window == nil then
        return
    else
        local cnv = Canvas.init(conky_window)
        local tx = Text:new{text="Hello World!"}
        tx:draw(cnv.cr) -- access table member instead of variable
        Canvas.destroy(cnv)
    end
end

Solution

  • return {
        cs = cairo_xlib_surface_create(w.display,w.drawable,w.visual,w.width,w.height),
        cr = cairo_create(cs)
    }
    

    In Lua table constructor there is no way to access another fields of the table being constructed.
    cs in expression cr = cairo_create(cs) refers to (global) variable cs instead of table field cs.
    Workaround: introduce local variable cs and initialize it prior to creating a table.

    local cs = cairo_xlib_surface_create(w.display,w.drawable,w.visual,w.width,w.height)
    return { cs = cs, cr = cairo_create(cs) }