-
Notifications
You must be signed in to change notification settings - Fork 0
/
init.lua
139 lines (122 loc) · 3.24 KB
/
init.lua
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 gears = require("gears")
local awful = require("awful")
local theme = require("beautiful")
local cairo = require("lgi").cairo
local module = {}
-- luacheck: globals client
local client = client
local icons, dynamic_icons, dynamic_classes, delay
local function len(T)
local count = 0
for _ in pairs(T) do
count = count + 1
end
return count
end
local function contains(T, V)
for _, v in ipairs(T) do
if v == V then
return true
end
end
return false
end
local function icon_copy(icon)
if not icon then
return nil
end
local s = gears.surface(icon)
local img = cairo.ImageSurface.create(cairo.Format.ARGB32, s:get_width(), s:get_height())
local cr = cairo.Context(img)
cr:set_source_surface(s, 0, 0)
cr:paint()
return img
end
local function set_icon(c, icon)
if c and c.valid then
if not c.icon_backup then
c.icon_backup = icon_copy(icons[c.class]) or icon_copy(c.icon)
end
icon = icon_copy(icon)
if icon then
c.icon = icon._native
end
end
end
local function set_dynamic_icon(c)
if c.name then
for regex, icon in pairs(dynamic_icons) do
if string.find(c.name, regex) then
set_icon(c, icon)
return
end
end
end
if c.icon_backup then
c.icon = c.icon_backup._native or nil
end
end
local function setup(config)
local cfg = config or {}
icons = cfg.icons or theme.ic_icons or {}
dynamic_icons = cfg.dynamic_icons or theme.ic_dynamic_icons or {}
dynamic_classes = cfg.dynamic_classes or theme.ic_dynamic_classes or {}
delay = cfg.delay or 0.5
local fallback_icon = cfg.fallback_icon or theme.ic_fallback_icon or nil
if type(icons) ~= "table" then
icons = {}
end
if type(dynamic_icons) ~= "table" then
dynamic_icons = {}
end
if type(dynamic_classes) ~= "table" then
dynamic_classes = {}
end
if type(delay) ~= "number" then
delay = 0.5
end
client.connect_signal("manage", function(c)
-- set icon based on c.class
awful.spawn.easy_async_with_shell("sleep " .. delay, function()
if c and c.valid then
if icons[c.class] then
set_icon(c, icons[c.class])
elseif not c.icon and fallback_icon then
set_icon(c, fallback_icon)
end
-- fix #2: Dynamic icons not working without changing the window name
if contains(dynamic_classes, c.class) then
set_dynamic_icon(c)
end
end
end)
if len(dynamic_icons) == 0 then
-- user has not defined any dynamic_icons; exit
return
end
-- dynamic classes are only being checked if defined explicitly by the user
if len(dynamic_classes) > 0 then
if not contains(dynamic_classes, c.class) then
-- client is not in dynamic_classes; exit
return
end
end
-- the client name is now being monitored
c:connect_signal("property::name", set_dynamic_icon)
end)
end
return setmetatable(module, {
__call = function(_, ...)
setup(...)
-- we have to update all clients icons manually when the user restarts awesomewm
-- since there is no "property::name" signal emitted by already running clients.
-- the set delay has to be higher than the regular delay, otherwise a race condition between both signals exists.
awful.spawn.easy_async_with_shell("sleep " .. (delay + 0.5), function()
for _, c in ipairs(client.get()) do
if c and c.valid then
c:emit_signal("property::name")
end
end
end)
end,
})