Awesome calendar widget

One of the things I was missing in my favourite windowmanager awesome was a calendar widget. So I spent some minutes and coded it. Moving the mouse over the time widget will show a naughty popup with the current month, use your mouse buttons (and the shift key) to scroll trough the months. The only annoying thing was to figure out how to change the text of an existing notification: notification.box.widgets[2].text = "new test" is neither easy to figure out nor to use.

But here’s the code for your rc.lua - in case you want to have a license for it - the code is published as public domain or under the ISC license, what ever you prefer.

Update: With thanks to a hint from madduck, the naughty popup is now aware of the screen your mouse is pointing to.

function displayMonth(month,year,weekStart)
    local t,wkSt=os.time{year=year, month=month+1, day=0},weekStart or 1
    local d=os.date("*t",t)
    local mthDays,stDay=d.day,(d.wday-d.day-wkSt+1)%7

    local lines = {}

    for x=0,6 do
        lines[x+1] = os.date("%a ",os.time{year=2006,month=1,day=x+wkSt})
    end
    lines[8] = "    "

    local writeLine = 1
    while writeLine < (stDay + 1) do
        lines[writeLine] = lines[writeLine] .. "   "
        writeLine = writeLine + 1
    end
        
    for x=1,mthDays do
        if writeLine == 8 then
            writeLine = 1
        end
        if writeLine == 1 or x == 1 then
            lines[8] = lines[8] .. os.date(" %V",os.time{year=year,month=month,day=x})
        end
        if (#(tostring(x)) == 1) then
            x = " " .. x
        end
        lines[writeLine] = lines[writeLine] .. " " .. x
        writeLine = writeLine + 1
    end
    local header = os.date("%B %Y\n",os.time{year=year,month=month,day=1})
    header = string.rep(" ", math.floor((#(lines[1]) - #header) / 2 )) .. header

    return header .. table.concat(lines, '\n')
end

local calendar = {}
function switchNaughtyMonth(switchMonths)
    if (#calendar < 3) then return end
    local swMonths = switchMonths or 1
    calendar[1] = calendar[1] + swMonths
    calendar[3].box.widgets[2].text = displayMonth(calendar[1], calendar[2], 2)
end

mytextbox.mouse_enter = function ()
    local month, year = os.date('%m'), os.date('%Y')
    calendar = { month, year, 
                naughty.notify({
                    text = displayMonth(month, year, 2),
                    timeout = 0, hover_timeout = 0.5,
                    width = 200, screen = mouse.screen
                })
               }
end 
mytextbox.mouse_leave = function () naughty.destroy(calendar[3]) end

mytextbox:buttons({
    button({ }, 1, function()
        switchNaughtyMonth(-1)
    end),
    button({ }, 3, function()
        switchNaughtyMonth(1)
    end),
    button({ }, 4, function()
        switchNaughtyMonth(-1)
    end),
    button({ }, 5, function()
        switchNaughtyMonth(1)
    end),
    button({ 'Shift' }, 1, function()
        switchNaughtyMonth(-12)
    end),
    button({ 'Shift' }, 3, function()
        switchNaughtyMonth(12)
    end),
    button({ 'Shift' }, 4, function()
        switchNaughtyMonth(-12)
    end),
    button({ 'Shift' }, 5, function()
        switchNaughtyMonth(12)
    end)
})