From 6f2e7bba25d2d6ccab635e86d16cdd5584b5fb31 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sun, 27 Sep 2015 13:19:12 +0200 Subject: [PATCH] Make layoutbox kind-of garbage-collectable Instead of connecting to the needed tag-update-signal again for every layoutbox, this now just creates a single connection and updates all layoutboxes from here. A new weak table is used to find the layoutboxes from these callbacks. Additionally, layoutboxes are now per-screen unique. So even if you try to create three layoutboxes for screen 1, the code will now always return the same instance. This kind-of fixes the leak test for layoutboxes. The problem is that the default config also creates a layoutbox and adds it to a wibox. Since this is now the same layoutbox, the test still fails. Just removing the layoutbox-part from the default config makes this problem go away. Signed-off-by: Uli Schlachter --- lib/awful/widget/layoutbox.lua | 37 +++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/lib/awful/widget/layoutbox.lua b/lib/awful/widget/layoutbox.lua index 2c0a698c2..2434ab77d 100644 --- a/lib/awful/widget/layoutbox.lua +++ b/lib/awful/widget/layoutbox.lua @@ -18,29 +18,46 @@ local imagebox = require("wibox.widget.imagebox") local layoutbox = { mt = {} } -local function update(w, screen, tooltip) +local boxes = nil + +local function update(w, screen) local layout = layout.getname(layout.get(screen)) - tooltip:set_text(layout or "[no name]") + w._layoutbox_tooltip:set_text(layout or "[no name]") w:set_image(layout and beautiful["layout_" .. layout]) end +local function update_from_tag(t) + local screen = tag.getscreen(t) + local w = boxes[screen] + if w then + update(w, screen) + end +end + --- Create a layoutbox widget. It draws a picture with the current layout -- symbol of the current tag. -- @param screen The screen number that the layout will be represented for. -- @return An imagebox widget configured as a layoutbox. function layoutbox.new(screen) local screen = screen or 1 - local w = imagebox() - local tooltip = tooltip({ objects = {w}, delay_show = 1 }) - update(w, screen, tooltip) - - local function update_on_tag_selection(t) - return update(w, tag.getscreen(t), tooltip) + -- Do we already have the update callbacks registered? + if boxes == nil then + boxes = setmetatable({}, { __mode = "v" }) + tag.attached_connect_signal(nil, "property::selected", update_from_tag) + tag.attached_connect_signal(nil, "property::layout", update_from_tag) + layoutbox.boxes = boxes end - tag.attached_connect_signal(screen, "property::selected", update_on_tag_selection) - tag.attached_connect_signal(screen, "property::layout", update_on_tag_selection) + -- Do we already have a layoutbox for this screen? + local w = boxes[screen] + if not w then + w = imagebox() + w._layoutbox_tooltip = tooltip({ objects = {w}, delay_show = 1 }) + + update(w, screen) + boxes[screen] = w + end return w end