local M = {} local awful = require("awful") local naughty = require("naughty") function M.tag_desk_idx(t) return tonumber('0x' .. t.name:sub(1, 2)) end function M.tag_page_idx(t) return tonumber('0x' .. t.name:sub(3, 4)) end -- mapping from logical screen indices to indices corresponding to their -- physical layout function M.screen_physical(n) local function screen_cmp(s1, s2) return s1.geometry.x < s2.geometry.x end local screens = {} for s in screen do screens[s.index] = s end table.sort(screens, screen_cmp) if screens[n] ~= nil then return screens[n] end return nil end function M.screen_focus_physical(n) local s = M.screen_physical(n) if s then awful.screen.focus(s) end end -- audio control functions function M.vol_control(wsp, n) local cmd = string.format("amixer set Master %d%%", math.abs(n)) .. (n < 0 and "-" or "+") awful.spawn.easy_async(cmd, function(stdout, stderr, exitreason, exitcode) if exitcode ~= 0 then naughty.notify({ preset = naughty.config.presets.warn, title = "Error changing the audio volume", text = stderr }) return end local volume = string.match(stdout, '%[(%d+%%)%]') local muted = string.match(stdout, '%[off%]') and ' (Muted)' or '' M.notify_singleton(wsp, 'volume', { title = "Audio volume", text = volume .. muted}) end) end function M.vol_mute_toggle(wsp) local control = 'Master' awful.spawn.easy_async("amixer sset " .. control .. " toggle", function(stdout, stderr, exitreason, exitcode) if exitcode ~= 0 then naughty.notify({ preset = naughty.config.presets.warn, title = "Error toggling the " .. control .. " control", text = stderr }) return end local text = string.match(stdout, '%[on%]') and 'Unmuted' or 'Muted' M.notify_singleton(wsp, 'mute', { title = "Audio", text = text }) end) end function M.auto_mute_toggle(wsp) local control = "'Auto-Mute Mode'" awful.spawn.easy_async("amixer sget " .. control, function(stdout, stderr, exitreason, exitcode) if exitcode ~= 0 then naughty.notify({ preset = naughty.config.presets.warn, title = "Error getting the auto-mute mode", text = stderr }) return end -- parse valid auto-mute items local items_raw = string.match(stdout, "\n%s*Items:%s*([^\n]+)\n") local items = {} for item in string.gmatch(items_raw, "'[^']+'") do table.insert(items, item) end -- parse current item local cur_item = string.match(stdout, "\n%s*Item0:%s*('[^'\n]+')\n") -- find the next item local next_item = nil for i, v in ipairs(items) do if v == cur_item then next_item = items[(i % #items) + 1] break end end if next_item == nil then return end -- set the next item awful.spawn.easy_async('amixer -q sset ' .. control .. ' ' .. next_item, function(stdout, stderr, exitreason, exitcode) if exitcode ~= 0 then naughty.notify({ preset = naughty.config.presets.warn, title = "Error setting the auto-mute mode", text = stderr }) return end M.notify_singleton(wsp, 'auto_mute', { title = "Auto-mute", text = next_item }) end ) end) end function M.spawn_current(command) awful.spawn(command, {tag = mouse.screen.selected_tag}) end function M.screen_lock() awful.spawn.easy_async("xscreensaver-command -lock", function(stdout, stderr, exitreason, exitcode) if exitcode ~= 0 then naughty.notify({ preset = naughty.config.presets.critical, title = "Error locking the screen", text = table.concat({stdout, stderr}, "\n") }) end end) end function M.notify_singleton(wsp, id, args) local prev_notify = wsp.notify_tbl[id] if prev_notify and prev_notify.box.visible then args.replaces_id = prev_notify.id end wsp.notify_tbl[id] = naughty.notify(args) end function M.log(component, msg, ...) local prefix = string.format('[awesome/%s] ', component) local str = string.format(msg, ...) print(prefix .. str) return prefix, str end function M.warn(component, msg, ...) local prefix, str = M.log(component, msg, ...) naughty.notify({ preset = naughty.config.presets.critical, title = prefix, text = str }) end return M