notification: Make the position index more robust.

If the notification screen or position changed, it would end up in the
wrong index and removing it would fail. This cannot happen anymore.
This commit is contained in:
Emmanuel Lepage Vallee 2019-07-09 01:29:33 -04:00
parent 4df8120acb
commit 12f1908ef8
2 changed files with 48 additions and 8 deletions

View File

@ -165,6 +165,35 @@ capi.screen.connect_signal("removed", function(scr)
naughty.notifications[scr] = nil
end)
local function get_screen(s)
return s and capi.screen[s]
end
local function remove_from_index(n)
for _, positions in pairs(naughty.notifications) do
for _, ns in pairs(positions) do
for k, n2 in ipairs(ns) do
if n2 == n then
table.remove(ns, k)
return
end
end
end
end
end
-- When id or screen are set after the object is created, update the indexing.
local function update_index(n)
-- Find the only index and remove it (there's an useless loop, but it's small).
remove_from_index(n)
-- Add to the index again
local s = get_screen(n.screen or n.preset.screen or screen.focused())
naughty.notifications[s] = naughty.notifications[s] or {}
table.insert(naughty.notifications[s][n.position], n)
end
--- Notification state.
--
-- This function is deprecated, use `naughty.suspended`.
@ -406,7 +435,7 @@ local function cleanup(self, reason)
local scr = self.screen
assert(naughty.notifications[scr][self.position][self.idx] == self)
table.remove(naughty.notifications[scr][self.position], self.idx)
remove_from_index(self)
-- Update all indices
for k, n in ipairs(naughty.notifications[scr][self.position]) do
@ -433,10 +462,6 @@ end
naughty.connect_signal("destroyed", cleanup)
local function get_screen(s)
return s and capi.screen[s]
end
-- Proxy the global suspension state on all notification objects
local function get_suspended(self)
return properties.suspended and not self.ignore_suspend
@ -482,7 +507,6 @@ end
-- Register a new notification object.
local function register(notification, args)
-- Add the some more properties
rawset(notification, "get_suspended", get_suspended)
@ -611,6 +635,9 @@ function naughty.notify(args)
return nnotif(args)
end
naughty.connect_signal("property::screen" , update_index)
naughty.connect_signal("property::position", update_index)
return setmetatable(naughty, {__index = index_miss, __newindex = set_index_miss})
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80

View File

@ -266,14 +266,27 @@ local function set_escaped_text(self)
if self.size_info then update_size(self) end
end
local function seek_and_destroy(n)
for _, positions in pairs(current_notifications) do
for _, pos in pairs(positions) do
for k, n2 in ipairs(pos) do
if n == n2 then
table.remove(pos, k)
return
end
end
end
end
end
local function cleanup(self, _ --[[reason]], keep_visible)
-- It is not a legacy notification
if not self.box then return end
local scr = self.screen
assert(current_notifications[scr][self.position][self.idx] == self)
table.remove(current_notifications[scr][self.position], self.idx)
-- Brute force find it, the position could have been replaced.
seek_and_destroy(self)
if (not keep_visible) or (not scr) then
self.box.visible = false