gears.color: Fix color serialization.

Some widgets like the tasklist serialize the theme colors to use them
in Pango markup. If the theme color were already converted to pattern,
that blew up. With this fix, pattern can be converted back into strings
correctly.
This commit is contained in:
Emmanuel Lepage Vallee 2021-12-11 09:29:27 -08:00
parent b6214af364
commit 91fe314e0b
1 changed files with 48 additions and 0 deletions

View File

@ -53,6 +53,7 @@ local surface = require("gears.surface")
local color = { mt = {} } local color = { mt = {} }
local pattern_cache local pattern_cache
local color_string_cache = setmetatable({}, { __mode = "k" })
--- Parse a HTML-color. --- Parse a HTML-color.
-- This function can parse colors like `#rrggbb` and `#rrggbbaa` and also `red`. -- This function can parse colors like `#rrggbb` and `#rrggbbaa` and also `red`.
@ -354,12 +355,59 @@ function color.recolor_image(image, new_color)
return image return image
end end
--- Convert a color back to an hexadecimal color code.
--
-- This takes an input color, pattern or gradient and attempt to convert it
-- to a color. If this fails, `fallback` is returned. This is useful when a
-- color needs to be concatenated into a Pango markup string.
--
-- @staticfct gears.color.to_rgba_string
-- @tparam pattern|string|gradient color Note that only solid colors can be
-- convedted to the `RGBA` format.
-- @tparam[opt=nil] pattern|string|gradient fallback The color to return
-- if `color` cannot be converted to a string.
-- @treturn string The color in `#rrggbbaa` format.
-- @see gears.color.ensure_pango_color
function color.to_rgba_string(col, fallback)
if (not col) and (not fallback) then return nil end
-- Prevent infinite recursion.
if not col then return color.to_rgba_string(fallback) end
if color_string_cache[col] then
return color_string_cache[col]
end
col = color.create_pattern(col)
local error1, error2, r, g, b, a = pcall(function () return col:get_rgba() end)
-- Surface patterns don't have an RGBA representation.
if (not error1) or error2 ~= "SUCCESS" then return color.to_rgba_string(fallback) end
color_string_cache[col] = string.format(
"#%02x%02x%02x%02x",
math.floor(r*255),
math.floor(g*255),
math.floor(b*255),
math.floor(a*255)
)
return color_string_cache[col]
end
--- Get a valid color for Pango markup --- Get a valid color for Pango markup
-- @param check_color The color to check. -- @param check_color The color to check.
-- @tparam string fallback The color to return if the first is invalid. (default: black) -- @tparam string fallback The color to return if the first is invalid. (default: black)
-- @treturn string color if it is valid, else fallback. -- @treturn string color if it is valid, else fallback.
-- @staticfct gears.color.ensure_pango_color -- @staticfct gears.color.ensure_pango_color
function color.ensure_pango_color(check_color, fallback) function color.ensure_pango_color(check_color, fallback)
-- This will happen if `gears.color` has been called in the theme.
if type(check_color) == "userdata" then
return color.to_rgba_string(check_color, fallback)
end
check_color = tostring(check_color) check_color = tostring(check_color)
-- Pango markup supports alpha, PangoColor does not. Thus, check for this. -- Pango markup supports alpha, PangoColor does not. Thus, check for this.
local len = #check_color local len = #check_color