naughty: Move the get_icon implementation to 2 request handlers.

They can now be disconnected or extended.
This commit is contained in:
Emmanuel Lepage Vallee 2020-03-15 06:04:42 -04:00
parent 9e19e7a18c
commit 32fd11a220
3 changed files with 72 additions and 39 deletions

View File

@ -18,6 +18,7 @@ local gdebug = require("gears.debug")
local screen = require("awful.screen") local screen = require("awful.screen")
local gtable = require("gears.table") local gtable = require("gears.table")
local gobject = require("gears.object") local gobject = require("gears.object")
local gsurface = require("gears.surface")
local naughty = {} local naughty = {}
@ -590,6 +591,7 @@ naughty.connect_signal("request::screen", naughty.default_screen_handler)
-- --
-- * app_icon -- * app_icon
-- * clients -- * clients
-- * path
-- * image -- * image
-- * images -- * images
-- --
@ -607,11 +609,18 @@ naughty.connect_signal("request::screen", naughty.default_screen_handler)
-- end -- end
-- end) -- end)
-- --
-- The `images` context has no handler. It is part of the specification to
-- handle animations. This is not supported by default.
--
-- @signal request::icon -- @signal request::icon
-- @tparam notification n The notification. -- @tparam notification n The notification.
-- @tparam string context The source of the icon to look for. -- @tparam string context The source of the icon to look for.
-- @tparam table hints The hints. -- @tparam table hints The hints.
-- @tparam string hints.app_icon The name of the icon to look for. -- @tparam string hints.app_icon The name of the icon to look for.
-- @tparam string hints.path The path of the icon.
-- @tparam string hints.image The path or pixmap of the icon.
-- @see naughty.icon_path_handler
-- @see naughty.client_icon_handler
--- Emitted when the screen is not defined or being removed. --- Emitted when the screen is not defined or being removed.
-- @signal request::screen -- @signal request::screen
@ -762,9 +771,39 @@ function naughty.notify(args)
return nnotif(args) return nnotif(args)
end end
--- Request handler to get the icon using the clients icons.
-- @signalhandler naughty.client_icon_handler
function naughty.client_icon_handler(self, context)
if context ~= "clients" then return end
local clients = self:get_clients()
for _, t in ipairs { "normal", "dialog" } do
for _, c in ipairs(clients) do
if c.type == t then
self._private.icon = gsurface(c.icon) --TODO support other size
return
end
end
end
end
--- Request handler to get the icon using the image or path.
-- @signalhandler naughty.icon_path_handler
function naughty.icon_path_handler(self, context, hints)
if context ~= "image" and context ~= "path" then return end
self._private.icon = gsurface.load_uncached_silently(
hints.path or hints.image
)
end
naughty.connect_signal("property::screen" , update_index) naughty.connect_signal("property::screen" , update_index)
naughty.connect_signal("property::position", update_index) naughty.connect_signal("property::position", update_index)
naughty.connect_signal("request::icon", naughty.client_icon_handler)
naughty.connect_signal("request::icon", naughty.icon_path_handler )
--@DOC_signals_COMMON@ --@DOC_signals_COMMON@
return setmetatable(naughty, {__index = index_miss, __newindex = set_index_miss}) return setmetatable(naughty, {__index = index_miss, __newindex = set_index_miss})

View File

@ -18,8 +18,8 @@
local capi = { screen = screen } local capi = { screen = screen }
local gobject = require("gears.object") local gobject = require("gears.object")
local gtable = require("gears.table") local gtable = require("gears.table")
local gsurface = require("gears.surface")
local timer = require("gears.timer") local timer = require("gears.timer")
local gfs = require("gears.filesystem")
local cst = require("naughty.constants") local cst = require("naughty.constants")
local naughty = require("naughty.core") local naughty = require("naughty.core")
local gdebug = require("gears.debug") local gdebug = require("gears.debug")
@ -658,48 +658,42 @@ function notification.get_icon(self)
return self._private.icon == "" and nil or self._private.icon return self._private.icon == "" and nil or self._private.icon
end end
local ret = nil
-- First, check if the image is passed as a surface or a path. -- First, check if the image is passed as a surface or a path.
if self.image and self.image ~= "" then if self.image and self.image ~= "" then
ret = self.image naughty._emit_signal_if("request::icon", request_filter, self, "image", {
elseif self._private.app_icon and self._private.app_icon ~= "" then
ret = self._private.app_icon
end
local s, err = nil, nil
-- See if this is a valid path.
if ret and ret ~= "" then
s, err = gsurface.load_silently(ret)
end
if s and not err then
return s
end
-- The second fallback are the client(s) icon(s).
local clients = notification.get_clients(self)
for _, t in ipairs { "normal", "dialog" } do
for _, c in ipairs(clients) do
if c.type == t then
self._private.icon = gsurface(c.icon) --TODO support other size
return self._private.icon
end
end
end
-- Now, it might be an XDG icon name or something a request handler can
-- understand.
if err then
local ctx = self._private.app_icon and "app_icon" or "image"
naughty._emit_signal_if("request::icon", request_filter, self, ctx, {
app_icon = self._private.app_icon,
image = self.image image = self.image
}) })
elseif self.images then
naughty._emit_signal_if("request::icon", request_filter, self, "images", {
images = self.images
})
end end
if self._private.icon then
return self._private.icon == "" and nil or self._private.icon
end
-- Second level of fallback, icon paths.
if self._private.app_icon and gfs.file_readable(self._private.app_icon) then
naughty._emit_signal_if("request::icon", request_filter, self, "path", {
path = self._private.app_icon
})
end
if self._private.icon then
return self._private.icon == "" and nil or self._private.icon
end
-- Third level fallback is `app_icon`.
if self._private.app_icon then
naughty._emit_signal_if("request::icon", request_filter, self, "app_icon", {
app_icon = self._private.app_icon
})
end
-- Finally, the clients.
naughty._emit_signal_if("request::icon", request_filter, self, "clients", {})
return self._private.icon == "" and nil or self._private.icon return self._private.icon == "" and nil or self._private.icon
end end

View File

@ -968,7 +968,7 @@ table.insert(steps, function()
local n = active[1] local n = active[1]
assert(not icon_requests[n]) assert(icon_requests[n])
assert(n._private.freedesktop_hints) assert(n._private.freedesktop_hints)
assert(n._private.freedesktop_hints["action-icons"] == true) assert(n._private.freedesktop_hints["action-icons"] == true)