--]]
-local beautiful = require("beautiful")
-local tostring = tostring
+local string = { format = string.format }
local setmetatable = setmetatable
-- Lain markup util submodule
-- lain.util.markup
local markup = {}
-local fg = {}
-local bg = {}
-
-- Convenience tags.
-function markup.bold(text) return '<b>' .. tostring(text) .. '</b>' end
-function markup.italic(text) return '<i>' .. tostring(text) .. '</i>' end
-function markup.strike(text) return '<s>' .. tostring(text) .. '</s>' end
-function markup.underline(text) return '<u>' .. tostring(text) .. '</u>' end
-function markup.monospace(text) return '<tt>' .. tostring(text) .. '</tt>' end
-function markup.big(text) return '<big>' .. tostring(text) .. '</big>' end
-function markup.small(text) return '<small>' .. tostring(text) .. '</small>' end
+function markup.bold(text) return '<b>' .. text .. '</b>' end
+function markup.italic(text) return '<i>' .. text .. '</i>' end
+function markup.strike(text) return '<s>' .. text .. '</s>' end
+function markup.underline(text) return '<u>' .. text .. '</u>' end
+function markup.monospace(text) return '<tt>' .. text .. '</tt>' end
+function markup.big(text) return '<big>' .. text .. '</big>' end
+function markup.small(text) return '<small>' .. text .. '</small>' end
-- Set the font.
function markup.font(font, text)
- return '<span font="' .. tostring(font) .. '">' .. tostring(text) ..'</span>'
+ return '<span font="' .. font .. '">' .. text ..'</span>'
end
-- Set the foreground.
-function fg.color(color, text)
- return '<span foreground="' .. tostring(color) .. '">' .. tostring(text) .. '</span>'
+function markup.fgcolor(color, text)
+ return '<span foreground="' .. color .. '">' .. text .. '</span>'
end
-- Set the background.
-function bg.color(color, text)
- return '<span background="' .. tostring(color) .. '">' .. tostring(text) .. '</span>'
+function markup.bgcolor(color, text)
+ return '<span background="' .. color .. '">' .. text .. '</span>'
end
--- Context: focus
-function fg.focus(text) return fg.color(beautiful.fg_focus, text) end
-function bg.focus(text) return bg.color(beautiful.bg_focus, text) end
-function markup.focus(text) return bg.focus(fg.focus(text)) end
-
--- Context: normal
-function fg.normal(text) return fg.color(beautiful.fg_normal, text) end
-function bg.normal(text) return bg.color(beautiful.bg_normal, text) end
-function markup.normal(text) return bg.normal(fg.normal(text)) end
-
--- Context: urgent
-function fg.urgent(text) return fg.color(beautiful.fg_urgent, text) end
-function bg.urgent(text) return bg.color(beautiful.bg_urgent, text) end
-function markup.urgent(text) return bg.urgent(fg.urgent(text)) end
-
-markup.fg = fg
-markup.bg = bg
+-- Set foreground and background.
+function markup.color(fg, bg, text)
+ return string.format('<span foreground="%s" background="%s">%s</span>', fg, bg, text)
+end
--- link markup.{fg,bg}(...) calls to markup.{fg,bg}.color(...)
-setmetatable(markup.fg, { __call = function(_, ...) return markup.fg.color(...) end })
-setmetatable(markup.bg, { __call = function(_, ...) return markup.bg.color(...) end })
+-- Set font, foreground and background.
+function markup.fontcolor(font, fg, bg, text)
+ return string.format('<span font="%s" foreground="%s" background="%s">%s</span>', font, fg, bg, text)
+end
-- link markup(...) calls to markup.fg.color(...)
return setmetatable(markup, { __call = function(_, ...) return markup.fg.color(...) end })
--]]
local helpers = require("lain.helpers")
-
local awful = require("awful")
local beautiful = require("beautiful")
local naughty = require("naughty")
local wibox = require("wibox")
-
local math = { modf = math.modf }
local string = { format = string.format,
match = string.match,
rep = string.rep }
local tonumber = tonumber
local type = type
-
local setmetatable = setmetatable
-- ALSA volume bar
local newtimer = require("lain.helpers").newtimer
local read_pipe = require("lain.helpers").read_pipe
local wibox = require("wibox")
-
local setmetatable = setmetatable
-- Basic template for custom widgets
local first_line = require("lain.helpers").first_line
local make_widget = require("lain.helpers").make_widget_textbox
local newtimer = require("lain.helpers").newtimer
-
local naughty = require("naughty")
local wibox = require("wibox")
-
local math = { abs = math.abs,
floor = math.floor,
log10 = math.log10,
min = math.min }
local string = { format = string.format }
-
local ipairs = ipairs
local type = type
local tonumber = tonumber
--]]
+local async = require("lain.helpers").async
local icons_dir = require("lain.helpers").icons_dir
-
+local markup = require("lain.util.markup")
local awful = require("awful")
-local beautiful = require("beautiful")
local naughty = require("naughty")
-
-local io = { popen = io.popen }
-local os = { date = os.date }
+local os = { date = os.date }
local string = { format = string.format,
- sub = string.sub,
gsub = string.gsub }
local tonumber = tonumber
-
local setmetatable = setmetatable
-- Calendar notification
-- lain.widgets.calendar
-local calendar = {}
-local cal_notification = nil
+local calendar = { offset = 0 }
function calendar.hide()
- if cal_notification ~= nil then
- naughty.destroy(cal_notification)
- cal_notification = nil
- end
+ if not calendar.notification then return end
+ naughty.destroy(calendar.notification)
+ calendar.notification = nil
end
function calendar.show(t_out, inc_offset, scr)
calendar.hide()
- local f, c_text
- local offs = inc_offset or 0
- local tims = t_out or 0
- local today = tonumber(os.date('%d'))
+ local today = os.date("%d")
+ local offs = inc_offset or 0
+ local f
calendar.offset = calendar.offset + offs
- if offs == 0 or calendar.offset == 0
- then -- current month showing, today highlighted
+ local current_month = (offs == 0 or calendar.offset == 0)
+
+ if current_month then -- today highlighted
calendar.offset = 0
calendar.notify_icon = string.format("%s%s.png", calendar.icons, today)
-
- -- bg and fg inverted to highlight today
- f = io.popen(calendar.cal_format(today))
+ f = calendar.cal
else -- no current month showing, no day to highlight
- local month = tonumber(os.date('%m'))
- local year = tonumber(os.date('%Y'))
+ local month = tonumber(os.date("%m"))
+ local year = tonumber(os.date("%Y"))
month = month + calendar.offset
end
calendar.notify_icon = nil
- f = io.popen(string.format('%s %s %s', calendar.cal, month, year))
+ f = string.format("%s %s %s", calendar.cal, month, year)
end
- c_text = "<tt><span font='" .. calendar.font .. " "
- .. calendar.font_size .. "'><b>"
- .. f:read() .. "</b>\n\n"
- .. f:read() .. "\n"
- .. f:read("*all"):gsub("\n*$", "")
- .. "</span></tt>"
- f:close()
-
if calendar.followtag then
- scrp = awful.screen.focused()
+ calendar.notification_preset.screen = awful.screen.focused()
else
- scrp = scr or calendar.scr_pos
+ calendar.notification_preset.screen = src or 1
end
- cal_notification = naughty.notify({
- text = c_text,
- icon = calendar.notify_icon,
- position = calendar.position,
- fg = calendar.fg,
- bg = calendar.bg,
- timeout = tims,
- screen = scrp
- })
+ async(string.format("%s -c '%s'", awful.util.shell, f), function(ws)
+ fg, bg = calendar.notification_preset.fg, calendar.notification_preset.bg
+ ws = ws:gsub("%c%[7m%d+%c%[27m", markup.bold(markup.color(bg, fg, today)))
+ calendar.notification = naughty.notify({
+ preset = calendar.notification_preset,
+ text = ws:gsub("\n*$", ""),
+ icon = calendar.notify_icon,
+ timeout = t_out or calendar.notification.preset.timeout or 5
+ })
+ end)
end
function calendar.attach(widget, args)
- local args = args or {}
-
- calendar.cal = args.cal or "/usr/bin/cal"
- calendar.cal_format = args.cal_format or function(today)
- return string.format("%s | sed -r -e 's/_\\x08//g' -e '0,/(^| )%d($| )/ s/(^| )%d($| )/\\1<b><span foreground=\"%s\" background=\"%s\">%d<\\/span><\\/b>\\2/'",
- calendar.cal, today, today, calendar.bg, calendar.fg, today)
+ local args = args or {}
+ calendar.cal = args.cal or "/usr/bin/cal --color=always"
+ calendar.followtag = args.followtag or false
+ calendar.icons = args.icons or icons_dir .. "cal/white/"
+ calendar.notification_preset = args.notification_preset
+
+ if not calendar.notification_preset then
+ calendar.notification_preset = naughty.config.defaults
+ calendar.notification_preset.font = "Monospace 10"
+ calendar.notification_preset.fg = "#FFFFFF"
+ calendar.notification_preset.bg = "#000000"
end
- calendar.icons = args.icons or icons_dir .. "cal/white/"
- calendar.font = args.font or beautiful.font:gsub(" %d.*", "")
- calendar.font_size = tonumber(args.font_size) or 11
- calendar.fg = args.fg or beautiful.fg_normal or "#FFFFFF"
- calendar.bg = args.bg or beautiful.bg_normal or "#000000"
- calendar.position = args.position or "top_right"
- calendar.scr_pos = args.scr_pos or 1
- calendar.followtag = args.followtag or false
-
- calendar.offset = 0
- calendar.notify_icon = nil
widget:connect_signal("mouse::enter", function () calendar.show(0, 0, calendar.scr_pos) end)
widget:connect_signal("mouse::leave", function () calendar.hide() end)
local helpers = require("lain.helpers")
local json = require("lain.util.dkjson")
-
local focused = require("awful.screen").focused
local pread = require("awful.util").pread
local naughty = require("naughty")
local wibox = require("wibox")
-
local next = next
local os = { getenv = os.getenv }
-local setmetatable = setmetatable
local table = table
+local setmetatable = setmetatable
-- Google Play Music Desktop infos
-- lain.widget.contrib.gpmdp
--]]
local helpers = require("lain.helpers")
-
local awful = require("awful")
local wibox = require("wibox")
-
local string = { format = string.format,
match = string.match }
local execute = os.execute
-
local setmetatable = setmetatable
-- Keyboard layout switcher
-- lain.widgets.contrib.kblayout
+local kbdlayout = helpers.make_widget_textbox()
local function worker(args)
- local kbdlayout = {}
- local layouts = args.layouts
+ local args = args or {}
+ local layouts = args.layouts or {}
local settings = args.settings or function () end
local add_us_secondary = true
local timeout = args.timeout or 5
if args.add_us_secondary == false then add_us_secondary = false end
- kbdlayout.widget = wibox.widget.textbox()
-
- -- Mouse bindings
- kbdlayout.widget:buttons(awful.util.table.join(
- awful.button({ }, 1, function () kbdlayout.next() end),
- awful.button({ }, 3, function () kbdlayout.prev() end)))
-
- local function run_settings(layout, variant)
+ local function kbd_run_settings(layout, variant)
kbdlayout_now = {
layout = string.match(layout, "[^,]+"), -- Make sure to match the primary layout only.
variant = variant
function kbdlayout.update()
helpers.async(string.format("%s -c 'setxkbmap -query'", awful.util.shell),
function(status)
- run_settings(string.match(status, "layout:%s*([^\n]*)"),
+ kbd_run_settings(string.match(status, "layout:%s*([^\n]*)"),
string.match(status, "variant:%s*([^\n]*)"))
end)
end
function kbdlayout.set(i)
+ if #layouts == 0 then return end
idx = ((i - 1) % #layouts) + 1 -- Make sure to wrap around as needed.
local to_execute = "setxkbmap " .. layouts[idx].layout
end
if execute(to_execute) then
- run_settings(layouts[idx].layout, layouts[idx].variant)
+ kbd_run_settings(layouts[idx].layout, layouts[idx].variant)
end
end
- function kbdlayout.next()
- kbdlayout.set(idx + 1)
- end
+ function kbdlayout.next() kbdlayout.set(idx + 1) end
+ function kbdlayout.prev() kbdlayout.set(idx - 1) end
- function kbdlayout.prev()
- kbdlayout.set(idx - 1)
- end
+ -- Mouse bindings
+ kbdlayout.widget:buttons(awful.util.table.join(
+ awful.button({ }, 1, function () kbdlayout.next() end),
+ awful.button({ }, 3, function () kbdlayout.prev() end)))
helpers.newtimer("kbdlayout", timeout, kbdlayout.update)
--]]
local helpers = require("lain.helpers")
-
local shell = require("awful.util").shell
local focused = require("awful.screen").focused
local escape_f = require("awful.util").escape
local naughty = require("naughty")
local wibox = require("wibox")
-
local os = { getenv = os.getenv }
local string = { format = string.format,
gmatch = string.gmatch }
-
local setmetatable = setmetatable
-- MOC audio player
--]]
-local awful = require("awful")
-local os = os
-
-local setmetatable = setmetatable
+local async = require("lain.helpers").async
+local awful = require("awful")
+local execute = os.execute
+local type = type
-- Redshift
-- lain.widgets.contrib.redshift
-local redshift = {}
-
-local attached = false -- true if attached to a widget
-local active = false -- true if redshift is active
-local running = false -- true if redshift was initialized
-local update_fnct = function() end -- Function that is run each time redshift is toggled. See redshift:attach().
-
-local function init()
- -- As there is no way to determine if redshift was previously
- -- toggled off (i.e Awesome on-the-fly restart), kill redshift to make sure
- os.execute("pkill redshift")
- -- Remove existing color adjustment
- awful.spawn.with_shell("redshift -x")
- -- (Re)start redshift
- awful.spawn.with_shell("redshift")
- running = true
- active = true
-end
-
-function redshift:toggle()
- if running then
- -- Sending -USR1 toggles redshift (See project website)
- os.execute("pkill -USR1 redshift")
- active = not active
- else
- init()
- end
- update_fnct()
-end
-
-function redshift:off()
- if running and active then
- redshift:toggle()
+local redshift = { active = false, pid = nil }
+
+function redshift:start()
+ execute("pkill redshift")
+ awful.spawn.with_shell("redshift -x") -- clear adjustments
+ redshift.pid = awful.spawn.with_shell("redshift")
+ redshift.active = true
+ if type(redshift.update_fun) == "function" then
+ redshift.update_fun(redshift.active)
end
end
-function redshift:on()
- if not active then
- redshift:toggle()
- end
-end
-
-function redshift:is_active()
- return active
+function redshift:toggle()
+ async(string.format("%s -c 'ps -p %d -o pid='", awful.util.shell, redshift.pid), function(f)
+ if f and #f > 0 then -- redshift is running
+ -- Sending -USR1 toggles redshift (See project website)
+ execute("pkill -USR1 redshift")
+ redshift.active = not redshift.active
+ else -- not started or killed, (re)start it
+ redshift:start()
+ end
+ redshift.update_fun(redshift.active)
+ end)
end
-- Attach to a widget
-- Provides a button which toggles redshift on/off on click
-- @param widget: Widget to attach to.
--- @param fnct: Function to be run each time redshift is toggled (optional).
+-- @param fun: Function to be run each time redshift is toggled (optional).
-- Use it to update widget text or icons on status change.
-function redshift:attach(widget, fnct)
- update_fnct = fnct or function() end
- if not attached then
- init()
- attached = true
- update_fnct()
- end
- widget:buttons(awful.util.table.join( awful.button({}, 1, function () redshift:toggle() end) ))
+function redshift:attach(widget, fun)
+ redshift.update_fun = fun or function() end
+ if not redshift.pid then redshift:start() end
+ widget:buttons(awful.util.table.join(awful.button({}, 1, function () redshift:toggle() end)))
end
-return setmetatable(redshift, { _call = function(_, ...) return create(...) end })
+return redshift
local lines_match = require("lain.helpers").lines_match
local newtimer = require("lain.helpers").newtimer
-
local wibox = require("wibox")
-
local math = { ceil = math.ceil }
local string = { format = string.format,
gmatch = string.gmatch }
local tostring = tostring
-
local setmetatable = setmetatable
-- CPU usage
local helpers = require("lain.helpers")
local shell = require("awful.util").shell
-local beautiful = require("beautiful")
local focused = require("awful.screen").focused
local wibox = require("wibox")
local naughty = require("naughty")
fs.options = args.options
fs.followtag = args.followtag or false
- fs.notification_preset = args.notification_preset or { fg = beautiful.fg_normal }
+ fs.notification_preset = args.notification_preset or naughty.config.defaults
fs.widget = wibox.widget.textbox()
if notify == "on" and tonumber(fs_now.used) >= 99 and not helpers.get_map(partition) then
naughty.notify({
- title = "warning",
+ title = "Warning",
text = partition .. " is empty!",
timeout = 8,
fg = "#000000",
--]]
local helpers = require("lain.helpers")
-
local shell = require("awful.util").shell
local naughty = require("naughty")
local wibox = require("wibox")
-
local string = { format = string.format,
gsub = string.gsub }
local tonumber = tonumber
-
local setmetatable = setmetatable
-- Mail IMAP check
helpers.async(curl, function(f)
_, mailcount = string.gsub(f, "%d+", "")
+ _ = nil
widget = imap.widget
settings()
local awful = require("awful")
local wibox = require("wibox")
local helpers = require("lain.helpers")
-
local io = { popen = io.popen }
local os = { getenv = os.getenv }
local string = { format = string.format,
match = string.match }
-
local setmetatable = setmetatable
-- Maildir check (synchronous)
--]]
local newtimer = require("lain.helpers").newtimer
-
local wibox = require("wibox")
-
local io = { lines = io.lines }
local math = { floor = math.floor }
local string = { gmatch = string.gmatch }
-
local setmetatable = setmetatable
-- Memory usage (ignoring caches)
local timeout = args.timeout or 2
local settings = args.settings or function() end
- mem.widget = wibox.widget.textbox('')
+ mem.widget = wibox.widget.textbox()
function update()
mem_now = {}
- for line in io.lines("/proc/meminfo")
- do
- for k, v in string.gmatch(line, "([%a]+):[%s]+([%d]+).+")
- do
+ for line in io.lines("/proc/meminfo") do
+ for k, v in string.gmatch(line, "([%a]+):[%s]+([%d]+).+") do
if k == "MemTotal" then mem_now.total = math.floor(v / 1024)
elseif k == "MemFree" then mem_now.free = math.floor(v / 1024)
elseif k == "Buffers" then mem_now.buf = math.floor(v / 1024)
--]]
local helpers = require("lain.helpers")
-
local shell = require("awful.util").shell
local escape_f = require("awful.util").escape
local focused = require("awful.screen").focused
local naughty = require("naughty")
local wibox = require("wibox")
-
local os = { getenv = os.getenv }
local string = { format = string.format,
gmatch = string.gmatch,
match = string.match }
-
local setmetatable = setmetatable
-- MPD infos
local helpers = require("lain.helpers")
local naughty = require("naughty")
local wibox = require("wibox")
-
local shell = require("awful.util").shell
-
local string = { format = string.format,
match = string.match }
-
local setmetatable = setmetatable
-- Network infos
local read_pipe = require("lain.helpers").read_pipe
local newtimer = require("lain.helpers").newtimer
local wibox = require("wibox")
-
local string = { gmatch = string.gmatch,
match = string.match,
format = string.format }
-
local setmetatable = setmetatable
-- PulseAudio volume
local scallback = args.scallback
pulseaudio.cmd = args.cmd or string.format("pacmd list-sinks | sed -n -e '0,/*/d' -e '/base volume/d' -e '/volume:/p' -e '/muted:/p' -e '/device\\.string/p'")
- pulseaudio.widget = wibox.widget.textbox('')
+ pulseaudio.widget = wibox.widget.textbox()
function pulseaudio.update()
if scallback then pulseaudio.cmd = scallback() end
local newtimer = require("lain.helpers").newtimer
local read_pipe = require("lain.helpers").read_pipe
-
local awful = require("awful")
local beautiful = require("beautiful")
local naughty = require("naughty")
local wibox = require("wibox")
-
local math = { modf = math.modf }
local mouse = mouse
local string = { format = string.format,
match = string.match,
rep = string.rep }
local tonumber = tonumber
-
local setmetatable = setmetatable
-- Pulseaudio volume bar
--]]
local newtimer = require("lain.helpers").newtimer
-
local wibox = require("wibox")
-
local io = { open = io.open }
local string = { match = string.match }
-
local setmetatable = setmetatable
-- System load
local timeout = args.timeout or 2
local settings = args.settings or function() end
- sysload.widget = wibox.widget.textbox('')
+ sysload.widget = wibox.widget.textbox()
function update()
local f = io.open("/proc/loadavg")
--]]
local newtimer = require("lain.helpers").newtimer
-
local wibox = require("wibox")
-
local io = { open = io.open }
local tonumber = tonumber
-
local setmetatable = setmetatable
-- coretemp
local tempfile = args.tempfile or "/sys/class/thermal/thermal_zone0/temp"
local settings = args.settings or function() end
- temp.widget = wibox.widget.textbox('')
+ temp.widget = wibox.widget.textbox()
function update()
local f = io.open(tempfile)
+ local coretemp_now
if f then
coretemp_now = tonumber(f:read("*all")) / 1000
f:close()
local newtimer = require("lain.helpers").newtimer
local lain_icons = require("lain.helpers").icons_dir
local json = require("lain.util").dkjson
-
local focused = require("awful.screen").focused
local naughty = require("naughty")
local wibox = require("wibox")
-
local math = { floor = math.floor }
local os = { time = os.time,
date = os.date,
difftime = os.difftime }
local string = { format = string.format,
gsub = string.gsub }
-
-local mouse = mouse
local tonumber = tonumber
local setmetatable = setmetatable
-Subproject commit bfdf6d24310d0822bac3447c39bb93cb83a75f77
+Subproject commit eb533f62754d1403e01048b7f2006ab2d8c94b11