naughty: Add a new request::icon for the main icon.

My initial implementation was overly optimistic. It turns out there
is no end in sight to "correctly" support icons. Apps randomly use
XDG name, paths and URLs. Rather than baloon the size of the
implementation, this commit moves toward to request:: pattern
found in other APIs. This will allow people who wish to "fix"
specific icons to do so in a way that scales.

The next 2 commits will move the current implementation to request
handlers.
This commit is contained in:
Emmanuel Lepage Vallee 2020-03-15 03:35:40 -04:00
parent 9cf717b994
commit a3c37382be
3 changed files with 85 additions and 17 deletions

View File

@ -574,6 +574,43 @@ naughty.connect_signal("request::screen", naughty.default_screen_handler)
-- @tparam table hints
-- @tparam string args.id The action id. This will often by the (XDG) icon name.
--- Emitted when a notification icon could not be loaded.
--
-- When an icon is passed in some "encoded" formats, such as XDG icon names or
-- network URLs, AwesomeWM will not attempt to load it. If you wish to see the
-- icon displayed, you must provide an handler. It is highly recommended for
-- handler to only set `n.icon` when they *found* the icon. That way multiple
-- handlers can be attached for multiple protocols.
--
-- The `context` argument is the origin of the icon to decode. If an handler
-- only supports one if them, it should check the `context` and return if it
-- doesn't handle it. The currently valid contexts are:
--
-- * app_icon
-- * clients
-- * image
-- * images
--
-- For example, an implementation which uses the `app_icon` to perform an XDG
-- icon lookup will look like:
--
-- naughty.connect_signal("request::icon", function(n, context, hints)
-- if context ~= "app_icon" then return end
--
-- local path = menubar.utils.lookup_icon(hints.app_icon) or
-- menubar.utils.lookup_icon(hints.app_icon:lower())
--
-- if path then
-- n.icon = path
-- end
-- end)
--
-- @signal request::icon
-- @tparam notification n The notification.
-- @tparam string context The source of the icon to look for.
-- @tparam table hints The hints.
-- @tparam string hints.app_icon The name of the icon to look for.
--- Emitted when the screen is not defined or being removed.
-- @signal request::screen
-- @tparam table notification The `naughty.notification` object. This is

View File

@ -648,31 +648,54 @@ for _, prop in ipairs { "category", "resident" } do
end
function notification.get_icon(self)
-- Honor all overrides.
if self._private.icon then
return self._private.icon == "" and nil or self._private.icon
elseif self.image and self.image ~= "" then
return self.image
elseif self._private.app_icon and self._private.app_icon ~= "" then
return self._private.app_icon
end
local ret = nil
-- First, check if the image is passed as a surface or a path.
if self.image and self.image ~= "" then
ret = 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 _, c in ipairs(clients) do
if c.type == "normal" then
self._private.icon = gsurface(c.icon)
return self._private.icon
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
for _, c in ipairs(clients) do
if c.type == "dialog" then
self._private.icon = gsurface(c.icon)
return self._private.icon
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("request::icon", self, ctx, {
app_icon = self._private.app_icon,
image = self.image
})
end
return nil
return self._private.icon == "" and nil or self._private.icon
end
function notification.get_clients(self)

View File

@ -897,6 +897,10 @@ table.insert(steps, function()
a.icon = hints.id == "list-add" and small_icon or big_icon
end)
naughty.connect_signal("request::icon", function(n, context, hints)
icon_requests[n] = true
end)
local hints = {
["action-icons"] = GLib.Variant("b", true),
}
@ -912,6 +916,8 @@ table.insert(steps, function()
local n = active[1]
assert(not icon_requests[n])
assert(n._private.freedesktop_hints)
assert(n._private.freedesktop_hints["action-icons"] == true)
@ -952,9 +958,10 @@ table.insert(steps, function()
gdebug.deprecate = function() end
local n = naughty.notification {
title = "foo",
message = "bar",
timeout = 25000,
title = "foo",
message = "bar",
timeout = 25000,
app_icon = "baz"
}
-- Make sure the suspension don't cause errors
@ -980,6 +987,7 @@ table.insert(steps, function()
assert(not naughty.suspended)
-- Replace the text
assert(icon_requests[n])
assert(n.title == "foo")
assert(n.message == "bar")
assert(n.text == "bar")