only operate on surface copies
Working with icons is tricky because their surfaces do not use reference counting correctly. If gears.surface(c.icon) is called multiple time on the same icon, it will cause a double-free error and Awesome will crash.
This commit is contained in:
parent
7b37f7eece
commit
0afab7248e
48
init.lua
48
init.lua
|
@ -1,16 +1,20 @@
|
|||
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
|
||||
for _ in pairs(T) do
|
||||
count = count + 1
|
||||
end
|
||||
return count
|
||||
end
|
||||
|
||||
|
@ -23,14 +27,26 @@ local function contains(T, V)
|
|||
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 = icons[c.class] and gears.surface(icons[c.class]) or gears.surface(c.icon)
|
||||
c.icon_backup = icon_copy(icons[c.class]) or icon_copy(c.icon)
|
||||
end
|
||||
icon = icon_copy(icon)
|
||||
if icon then
|
||||
icon = gears.surface(icon)
|
||||
c.icon = icon and icon._native or nil
|
||||
c.icon = icon._native
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -46,7 +62,7 @@ local function set_dynamic_icon(c)
|
|||
end
|
||||
|
||||
if c.icon_backup then
|
||||
c.icon = c.icon_backup and c.icon_backup._native or nil
|
||||
c.icon = c.icon_backup._native or nil
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -58,10 +74,18 @@ local function setup(config)
|
|||
dynamic_classes = cfg.dynamic_classes or theme.ic_dynamic_classes or {}
|
||||
delay = cfg.delay or 0.5
|
||||
|
||||
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
|
||||
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
|
||||
|
@ -89,7 +113,8 @@ local function setup(config)
|
|||
end)
|
||||
end
|
||||
|
||||
return setmetatable(module, { __call = function(_, ...)
|
||||
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.
|
||||
|
@ -101,4 +126,5 @@ return setmetatable(module, { __call = function(_, ...)
|
|||
end
|
||||
end
|
||||
end)
|
||||
end })
|
||||
end
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue