test-leaks: Fix with Lua 5.1
I have no idea why this needs collectgarbage() to be called twice. On the other hand, I can explain the change in tooltip.lua. Lua 5.2 introduced "ephermeron tables". This means that in the following sitation, lua 5.2 can collect the entry from the table, while 5.1 keeps the entry alive, because the table has a strong reference to the value and that in turn has a strong reference to the key: t = setmetatable({}, { __mode = "k"}) do local k = {} t[k] = function() print(k) end end collectgarbage("collect") print(next(t, nil)) To handle this incompatibility, this commit just removes the whole indirection through the module-level variable "data". Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
parent
94271e8c91
commit
3e9fdea650
|
@ -59,17 +59,6 @@ local ipairs = ipairs
|
||||||
-- @tfield boolean visible True if tooltip is visible.
|
-- @tfield boolean visible True if tooltip is visible.
|
||||||
local tooltip = { mt = {} }
|
local tooltip = { mt = {} }
|
||||||
|
|
||||||
--- Tooltip private data.
|
|
||||||
-- @local
|
|
||||||
-- @table tooltip.data
|
|
||||||
-- @tfield string fg tooltip foreground color.
|
|
||||||
-- @tfield string font Tooltip font.
|
|
||||||
-- @tfield function hide The hide() function.
|
|
||||||
-- @tfield function show The show() function.
|
|
||||||
-- @tfield gears.timer timer The text update timer.
|
|
||||||
-- @tfield function timer_function The text update timer function.
|
|
||||||
local data = setmetatable({}, { __mode = 'k' })
|
|
||||||
|
|
||||||
-- Place the tooltip on the screen.
|
-- Place the tooltip on the screen.
|
||||||
-- @tparam tooltip self A tooltip object.
|
-- @tparam tooltip self A tooltip object.
|
||||||
local function place(self)
|
local function place(self)
|
||||||
|
@ -98,10 +87,10 @@ end
|
||||||
local function show(self)
|
local function show(self)
|
||||||
-- do nothing if the tooltip is already shown
|
-- do nothing if the tooltip is already shown
|
||||||
if self.visible then return end
|
if self.visible then return end
|
||||||
if data[self].timer then
|
if self.timer then
|
||||||
if not data[self].timer.started then
|
if not self.timer.started then
|
||||||
data[self].timer_function()
|
self.timer_function()
|
||||||
data[self].timer:start()
|
self.timer:start()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
set_geometry(self)
|
set_geometry(self)
|
||||||
|
@ -116,9 +105,9 @@ end
|
||||||
local function hide(self)
|
local function hide(self)
|
||||||
-- do nothing if the tooltip is already hidden
|
-- do nothing if the tooltip is already hidden
|
||||||
if not self.visible then return end
|
if not self.visible then return end
|
||||||
if data[self].timer then
|
if self.timer then
|
||||||
if data[self].timer.started then
|
if self.timer.started then
|
||||||
data[self].timer:stop()
|
self.timer:stop()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
self.visible = false
|
self.visible = false
|
||||||
|
@ -154,8 +143,8 @@ end
|
||||||
-- @tparam tooltip self A tooltip object.
|
-- @tparam tooltip self A tooltip object.
|
||||||
-- @tparam number timeout The timeout value.
|
-- @tparam number timeout The timeout value.
|
||||||
tooltip.set_timeout = function(self, timeout)
|
tooltip.set_timeout = function(self, timeout)
|
||||||
if data[self].timer then
|
if self.timer then
|
||||||
data[self].timer.timeout = timeout
|
self.timer.timeout = timeout
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -165,8 +154,8 @@ end
|
||||||
-- @tparam gears.object object An object with `mouse::enter` and
|
-- @tparam gears.object object An object with `mouse::enter` and
|
||||||
-- `mouse::leave` signals.
|
-- `mouse::leave` signals.
|
||||||
tooltip.add_to_object = function(self, object)
|
tooltip.add_to_object = function(self, object)
|
||||||
object:connect_signal("mouse::enter", data[self].show)
|
object:connect_signal("mouse::enter", self.show)
|
||||||
object:connect_signal("mouse::leave", data[self].hide)
|
object:connect_signal("mouse::leave", self.hide)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Remove tooltip from an object.
|
--- Remove tooltip from an object.
|
||||||
|
@ -175,8 +164,8 @@ end
|
||||||
-- @tparam gears.object object An object with `mouse::enter` and
|
-- @tparam gears.object object An object with `mouse::enter` and
|
||||||
-- `mouse::leave` signals.
|
-- `mouse::leave` signals.
|
||||||
tooltip.remove_from_object = function(self, object)
|
tooltip.remove_from_object = function(self, object)
|
||||||
object:disconnect_signal("mouse::enter", data[self].show)
|
object:disconnect_signal("mouse::enter", self.show)
|
||||||
object:disconnect_signal("mouse::leave", data[self].hide)
|
object:disconnect_signal("mouse::leave", self.hide)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -213,24 +202,24 @@ tooltip.new = function(args)
|
||||||
delay_timeout:stop()
|
delay_timeout:stop()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
data[self] = {
|
function self.show()
|
||||||
show = function()
|
if not delay_timeout.started then
|
||||||
if not delay_timeout.started then
|
delay_timeout:start()
|
||||||
delay_timeout:start()
|
end
|
||||||
end
|
end
|
||||||
end,
|
function self.hide()
|
||||||
hide = function()
|
if delay_timeout.started then
|
||||||
if delay_timeout.started then
|
delay_timeout:stop()
|
||||||
delay_timeout:stop()
|
end
|
||||||
end
|
hide(self)
|
||||||
hide(self)
|
end
|
||||||
end,
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
data[self] = {
|
function self.show()
|
||||||
show = function() show(self) end,
|
show(self)
|
||||||
hide = function() hide(self) end,
|
end
|
||||||
}
|
function self.hide()
|
||||||
|
hide(self)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- export functions
|
-- export functions
|
||||||
|
@ -242,11 +231,11 @@ tooltip.new = function(args)
|
||||||
|
|
||||||
-- setup the timer action only if needed
|
-- setup the timer action only if needed
|
||||||
if args.timer_function then
|
if args.timer_function then
|
||||||
data[self].timer = timer { timeout = args.timeout and args.timeout or 1 }
|
self.timer = timer { timeout = args.timeout and args.timeout or 1 }
|
||||||
data[self].timer_function = function()
|
self.timer_function = function()
|
||||||
self:set_markup(args.timer_function())
|
self:set_markup(args.timer_function())
|
||||||
end
|
end
|
||||||
data[self].timer:connect_signal("timeout", data[self].timer_function)
|
self.timer:connect_signal("timeout", self.timer_function)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Set default properties
|
-- Set default properties
|
||||||
|
@ -274,7 +263,7 @@ tooltip.new = function(args)
|
||||||
|
|
||||||
-- Close the tooltip when clicking it. This gets done on release, to not
|
-- Close the tooltip when clicking it. This gets done on release, to not
|
||||||
-- emit the release event on an underlying object, e.g. the titlebar icon.
|
-- emit the release event on an underlying object, e.g. the titlebar icon.
|
||||||
self.wibox:buttons(abutton({}, 1, nil, function() data[self].hide() end))
|
self.wibox:buttons(abutton({}, 1, nil, function() self.hide() end))
|
||||||
|
|
||||||
-- Re-place when the geometry of the wibox changes.
|
-- Re-place when the geometry of the wibox changes.
|
||||||
self.wibox:connect_signal("property::width", function() place(self) end)
|
self.wibox:connect_signal("property::width", function() place(self) end)
|
||||||
|
|
|
@ -29,6 +29,7 @@ local function collectable(a, b, c, d, e, f, g, h, last)
|
||||||
prepare_for_collect = nil
|
prepare_for_collect = nil
|
||||||
end
|
end
|
||||||
collectgarbage("collect")
|
collectgarbage("collect")
|
||||||
|
collectgarbage("collect")
|
||||||
-- Check if the table is now empty
|
-- Check if the table is now empty
|
||||||
for k, v in pairs(objs) do
|
for k, v in pairs(objs) do
|
||||||
print("Some object was not garbage collected!")
|
print("Some object was not garbage collected!")
|
||||||
|
|
Loading…
Reference in New Issue