1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
--- Separating Multiple Monitor functions as a separated module (taken from awesome wiki)
local awful = require("awful")
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 awful.util.table.hasitem(p, o) then
new[#new + 1] = awful.util.table.join(p, {o})
end
end
end
choices = awful.util.table.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 awful.util.table.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
awful.util.spawn(action, false)
-- See https://www.reddit.com/r/linux/comments/6odeur/i3_automatically_resize_wallpaperconky_on/
-- https://github.com/ritave/xeventbind
awful.spawn("xconky refresh")
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 = unpack(next)
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
}
|