From 51e4a47938d67045797df1dc99a166ed5a416f4f Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sat, 11 Mar 2017 18:14:38 +0100 Subject: [PATCH] Partly fix removal of systray from a wibox This commit changes the systray widget, wibox.drawable and the C code to fix the following bug: When the systray widget is removed from a drawable without being moved somewhere else, the systray stayed visible. This was because the systray is not drawn by awesome, but only placed. When the widget is no longer "drawn", it stays wherever it was placed last. This change works by detecting the situation when the systray is removed. Then, the C code is specifically told to remove the systray window from the drawable. Note that this is only a partial fix. This change works correctly when the widget is removed completely, because it is no longer placed by its parent widget. However, for example, when you do wibox.widget.systray().visible = false, the effect is just that the systray widget gets size 0x0. This is not really visible, but as far as this change is concerned, the widget is still part of the drawable. Signed-off-by: Uli Schlachter --- lib/wibox/drawable.lua | 14 ++++++++++++++ lib/wibox/widget/systray.lua | 10 ++++++++++ objects/drawin.c | 6 ++++++ objects/drawin.h | 2 +- systray.c | 5 ++++- 5 files changed, 35 insertions(+), 2 deletions(-) diff --git a/lib/wibox/drawable.lua b/lib/wibox/drawable.lua index 09e91136..e3e3eb50 100644 --- a/lib/wibox/drawable.lua +++ b/lib/wibox/drawable.lua @@ -25,6 +25,8 @@ local unpack = unpack or table.unpack -- luacheck: globals unpack (compatibility local visible_drawables = {} +local systray_widget + -- Get the widget context. This should always return the same table (if -- possible), so that our draw and fit caches can work efficiently. local function get_widget_context(self) @@ -76,8 +78,15 @@ local function do_redraw(self) if self._need_relayout or self._need_complete_repaint then self._need_relayout = false if self._widget_hierarchy and self.widget then + local had_systray = systray_widget and self._widget_hierarchy:get_count(systray_widget) > 0 + self._widget_hierarchy:update(context, self.widget, width, height, self._dirty_area) + + local has_systray = systray_widget and self._widget_hierarchy:get_count(systray_widget) > 0 + if had_systray and not has_systray then + systray_widget:_kickout(context) + end else self._need_complete_repaint = true if self.widget then @@ -209,6 +218,11 @@ function drawable:find_widgets(x, y) return result end +-- Private API. Not documented on purpose. +function drawable._set_systray_widget(widget) + hierarchy.count_widget(widget) + systray_widget = widget +end --- Set the widget that the drawable displays function drawable:set_widget(widget) diff --git a/lib/wibox/widget/systray.lua b/lib/wibox/widget/systray.lua index 2cbd20e8..6bc42095 100644 --- a/lib/wibox/widget/systray.lua +++ b/lib/wibox/widget/systray.lua @@ -5,6 +5,7 @@ --------------------------------------------------------------------------- local wbase = require("wibox.widget.base") +local drawable = require("wibox.drawable") local beautiful = require("beautiful") local gtable = require("gears.table") local capi = { @@ -72,6 +73,13 @@ function systray:draw(context, cr, width, height) base, is_rotated, bg, reverse, spacing) end +-- Private API. Does not appear in LDoc on purpose. This function is called +-- some time after the systray is removed from some drawable. It's purpose is to +-- really remove the systray. +function systray:_kickout(context) + capi.awesome.systray(context.wibox.drawin) +end + function systray:fit(context, width, height) if not should_display_on(context.screen) then return 0, 0 @@ -171,6 +179,8 @@ local function new(revers) end end) + drawable._set_systray_widget(ret) + return ret end diff --git a/objects/drawin.c b/objects/drawin.c index 6d9abccb..3d5d35f1 100644 --- a/objects/drawin.c +++ b/objects/drawin.c @@ -166,6 +166,12 @@ drawin_systray_kickout(drawin_t *w) } } +void +luaA_drawin_systray_kickout(lua_State *L) +{ + drawin_systray_kickout(luaA_checkudata(L, 1, &drawin_class)); +} + static void drawin_wipe(drawin_t *w) { diff --git a/objects/drawin.h b/objects/drawin.h index 1bd19bb4..31f315aa 100644 --- a/objects/drawin.h +++ b/objects/drawin.h @@ -47,8 +47,8 @@ struct drawin_t ARRAY_FUNCS(drawin_t *, drawin, DO_NOTHING) drawin_t * drawin_getbywin(xcb_window_t); - void drawin_refresh_pixmap_partial(drawin_t *, int16_t, int16_t, uint16_t, uint16_t); +void luaA_drawin_systray_kickout(lua_State *); void drawin_class_setup(lua_State *); diff --git a/systray.c b/systray.c index f0d7369d..93182f37 100644 --- a/systray.c +++ b/systray.c @@ -337,7 +337,10 @@ luaA_systray(lua_State *L) { systray_register(); - if(lua_gettop(L) != 0) + if(lua_gettop(L) == 1) + luaA_drawin_systray_kickout(L); + + if(lua_gettop(L) > 1) { size_t bg_len; drawin_t *w = luaA_checkudata(L, 1, &drawin_class);