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
|
local awful = require("awful")
local beautiful = require("beautiful")
local shape = require("gears.shape")
local wibox = require("wibox")
local utils = require("utils")
local M = {}
local function client_get_desk_idx(c)
if c.first_tag then
local desk_idx = utils.tag_desk_idx(c.first_tag)
if desk_idx ~= nil and desk_idx >= 0 then
return desk_idx
else
utils.warn('UrgentWgt', '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_add(c)
function handler_client_show(c)
if not c.urgent then
return
end
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
function handler_client_hide(c)
if self._clients[c] then
self:_desk_client_remove(self._clients[c], c)
end
end
function handler_client_remove(c)
c:disconnect_signal('untagged', handler_client_hide)
c:disconnect_signal('tagged', handler_client_show)
c:disconnect_signal('unmanage', handler_client_remove)
c:disconnect_signal('property::urgent', handler_client_remove)
handler_client_hide(c)
self._clients[c] = nil
end
-- handle client state changes:
-- client moved: hide it on its previous desktop, show on the new one
c:connect_signal('untagged', handler_client_hide)
c:connect_signal('tagged', handler_client_show)
-- unurgent or destroyed: forget about client
c:connect_signal('property::urgent', handler_client_remove)
c:connect_signal('unmanage', handler_client_remove)
-- show the client on its desk right now
handler_client_show(c)
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
|