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
141
142
143
144
145
146
147
|
local awful = require("awful")
local beautiful = require("beautiful")
local shape = require("gears.shape")
local wibox = require("wibox")
local M = {}
local function client_get_desk_idx(c)
if c.first_tag then
local desk_idx = tonumber('0x' .. c.first_tag.name:sub(1, 2))
if desk_idx ~= nil and desk_idx >= 0 then
return desk_idx
else
print('cannot get desk idx: ' .. c.first_tag.name)
end
end
return false
end
local function urgent_widget_create(name)
local textbox = wibox.widget.textbox(' ' .. name .. ' ')
local cont_bg = wibox.container.background(textbox)
cont_bg.bg = beautiful.bg_urgent
cont_bg.fg = beautiful.fg_urgent
cont_bg:set_shape(shape.rounded_rect, 5)
cont_bg.shape_border_width = 1
cont_bg.shape_border_color = beautiful.border_focus
return cont_bg
end
local UrgentWidget = {}
function UrgentWidget:_desk_client_add(desk_idx, c)
-- create the client list, if it does not exist already
if self._desktops[desk_idx] == nil then
self._desktops[desk_idx] = {}
end
self._desktops[desk_idx][c] = true
if self._desktop_widgets[desk_idx] == nil then
self._desktop_widgets[desk_idx] = urgent_widget_create(desk_idx)
end
for k, w in pairs(self._layout:get_children()) do
if w == self._desktop_widgets[desk_idx] then
return
end
end
self._layout:add(self._desktop_widgets[desk_idx])
end
function UrgentWidget:_desk_client_remove(desk_idx, c)
self._desktops[desk_idx][c] = nil
-- remove the widget if there are no clients left
local count = 0
for c, v in pairs(self._desktops[desk_idx]) do
if v then
count = count + 1
end
end
if count == 0 then
self._layout:remove_widgets(self._desktop_widgets[desk_idx])
end
end
function UrgentWidget:_client_remove(c)
if self._clients[c] then
self:_desk_client_remove(self._clients[c], c)
end
self._clients[c] = nil
end
function UrgentWidget:_client_add(c)
local desk_idx = client_get_desk_idx(c)
self._clients[c] = desk_idx
if desk_idx then
self:_desk_client_add(desk_idx, c)
end
-- handle client state changes:
-- lose the urgency flag
c:connect_signal('property::urgent',
function (c)
if not c.urgent then
self:_client_remove(c)
end
end)
-- client destroyed
c:connect_signal('unmanage',
function (c)
self:_client_remove(c)
end)
-- client moved
c:connect_signal('untagged',
function(c, t)
local desk_idx = self._clients[c]
if desk_idx then
self:_desk_client_remove(desk_idx, c)
end
self._clients[c] = false
end)
c:connect_signal('tagged',
function(c, t)
local desk_idx = client_get_desk_idx(c)
self._clients[c] = desk_idx
if desk_idx then
self:_desk_client_add(desk_idx, c)
end
end)
end
function UrgentWidget:new()
local ret = setmetatable({}, self)
self.__index = self
ret._layout = wibox.layout.fixed.horizontal()
ret.widget = awful.widget.only_on_screen(ret._layout, "primary")
-- maps from clients to their desk num (or false, when no desk num
-- can be determined)
ret._clients = {}
-- contains a table of urgent clients per each desktop number
ret._desktops = {}
ret._desktop_widgets = {}
-- signal handler for adding new clients
client.connect_signal('property::urgent',
function (c)
-- only do something when urgency flag is on
if c.urgent then
ret:_client_add(c)
end
end)
return ret
end
M.UrgentWidget = UrgentWidget
return M
|