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:
parent
9cf717b994
commit
a3c37382be
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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")
|
||||
|
|
Loading…
Reference in New Issue