Search code examples
luaawesome-wm

Can I run interval timers in AwesomeWM?


I am using Awesome 4.3 on Manjaro Linux (Arch) I changed from a KDE desktop to an XFCE desktop. I wrote a wallpaper switcher that will change the wallpaper randomly on four separate screens. I wrote the randomize routine in a standard Lua file for development purposes. I added it to rc.lua, but it doesn't seem that the Lua timers (luv) are running in rc.lua. I checked all the methods separately to load the wallpaper from my randomize routines, and they work perfectly when I call directly for one set of files for the four screens. As soon as I add the interval timers, nothing happens, no error, nothing at all.

This is the code simplified to load only one screen, am I missing something, taking out the awesome objects and replacing with print statements and it works perfectly in a standard Lua file

thanks any help is appreciated

local lfs = require('lfs') -- lua file system
local uv = require('luv') -- lua timer
local dir = "/home/jerry/Documents/wallpaper"
local images = {} -- images collection
local idx = 0
math.randomseed(os.time())

local function tablelength(T)
    local count = 0
    for _ in pairs(T) do count = count + 1 end
    return count
end

local function readImages(path)
    for file in lfs.dir(path) do
        if file ~= "." and file ~= ".." then
            images[idx] = path .. '/' .. file
            idx = idx + 1
        end
    end
end

readImages(dir);
imageCount = tablelength(images)

local function getImage()
    number = math.random(1, imageCount)
    return images[number]
end

local function setInterval(interval, callback)
    local timer = uv.new_timer()
    uv.timer_start(timer, 0, interval, callback)
    return timer
end

local function cb()
    local path = getImage()
    gears.wallpaper.maximized(path, screen[1], true)
end


timer1 = setInterval(1000, cb)
 local function cb(gears, getImage, screen, screenIndex)
    return function()
        print(gears)
        print(getImage())
        print(screen)
        print("Screen " .. screenIndex)
        return gears.wallpaper.maximized(getImage(), screen[screenIndex], true)
    end
end 

Solution

  • You forgot to call uv.run(). That call runs the timers. However, it would also does not run anything else, so AwesomeWM would stop working.

    uv.run() runs a main loop. This loop waits for events (like: A timer expires) and then handles that event. AwesomeWM also uses a main loop. It runs GLib's GMainLoop.

    Since you cannot run two main loops at the same time, you'll have to use GLib's and AwesomeWMs facilities. I found some docs for luv's timer_start: https://github.com/luvit/luv/blob/master/docs.md#uvtimer_starttimer-timeout-repeat-callback According to this, your timer_start(timer, 0, interval, callback) means that the timer triggers immediately and then every second. The AwesomeWM version of this is:

    local gears = require("gears") -- This is part of AwesomeWM
    local timer1 = gears.start_new(1, function()
        print("I run once per second")
        return true -- Signal that the timer should continue running
    end)
    timer1:emit_signal("timeout") -- Cause the callback function to run right now
    

    gears.timer uses GLib to run the timer: https://github.com/awesomeWM/awesome/blob/87e7b84ff54c050f86541421ec0aa93e325dd49d/lib/gears/timer.lua#L94