awesome-www/recipes/xrandr.lua

137 lines
3.5 KiB
Lua
Raw Permalink Normal View History

--- Separating Multiple Monitor functions as a separeted module (taken from awesome wiki)
local gtable = require("gears.table")
local spawn = require("awful.spawn")
local naughty = require("naughty")
-- A path to a fancy icon
local icon_path = ""
-- Get active outputs
local function outputs()
local outputs = {}
local xrandr = io.popen("xrandr -q --current")
if xrandr then
for line in xrandr:lines() do
local output = line:match("^([%w-]+) connected ")
if output then
outputs[#outputs + 1] = output
end
end
xrandr:close()
end
return outputs
end
local function arrange(out)
-- We need to enumerate all permutations of horizontal outputs.
local choices = {}
local previous = { {} }
for i = 1, #out do
-- Find all permutation of length `i`: we take the permutation
-- of length `i-1` and for each of them, we create new
-- permutations by adding each output at the end of it if it is
-- not already present.
local new = {}
for _, p in pairs(previous) do
for _, o in pairs(out) do
if not gtable.hasitem(p, o) then
new[#new + 1] = gtable.join(p, {o})
end
end
end
choices = gtable.join(choices, new)
previous = new
end
return choices
end
-- Build available choices
local function menu()
local menu = {}
local out = outputs()
local choices = arrange(out)
for _, choice in pairs(choices) do
local cmd = "xrandr"
-- Enabled outputs
for i, o in pairs(choice) do
cmd = cmd .. " --output " .. o .. " --auto"
if i > 1 then
cmd = cmd .. " --right-of " .. choice[i-1]
end
end
-- Disabled outputs
for _, o in pairs(out) do
if not gtable.hasitem(choice, o) then
cmd = cmd .. " --output " .. o .. " --off"
end
end
local label = ""
if #choice == 1 then
label = 'Only <span weight="bold">' .. choice[1] .. '</span>'
else
for i, o in pairs(choice) do
if i > 1 then label = label .. " + " end
label = label .. '<span weight="bold">' .. o .. '</span>'
end
end
menu[#menu + 1] = { label, cmd }
end
return menu
end
-- Display xrandr notifications from choices
local state = { cid = nil }
local function naughty_destroy_callback(reason)
if reason == naughty.notificationClosedReason.expired or
reason == naughty.notificationClosedReason.dismissedByUser then
local action = state.index and state.menu[state.index - 1][2]
if action then
spawn(action, false)
state.index = nil
end
end
end
local function xrandr()
-- Build the list of choices
if not state.index then
state.menu = menu()
state.index = 1
end
-- Select one and display the appropriate notification
local label, action
local next = state.menu[state.index]
state.index = state.index + 1
if not next then
label = "Keep the current configuration"
state.index = nil
else
label, action = next[1], next[2]
end
state.cid = naughty.notify({ text = label,
icon = icon_path,
timeout = 4,
screen = mouse.screen,
replaces_id = state.cid,
destroy = naughty_destroy_callback}).id
end
return {
outputs = outputs,
arrange = arrange,
menu = menu,
xrandr = xrandr
}