From 83c31f948b57f3dfb75d343a084ef1509d740902 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Mon, 31 May 2021 01:19:25 -0700 Subject: [PATCH] fixed: Try to handle zero sized widgets again. The newly changed code doesn't handle this well: local w = wibox.widget { { --add anything here widget = wibox.layout.fixed.horizontal }, widget = wibox.layout.fixed.horizontal, } This will cause the "inner" fixed layout to have the minimum size it supports. In that case, if the last widget has "no size" because it supports up to 0x0, then it isn't added to the layout. This was done "on purpose" because if there is a spacing, then `:fit` would have returned a size "too small" because the last spacing area would be (correctly) missing. But if the zero sized widget isn't added to the layout, then it's size isn't tracker. So if it emits a layout_changed signal, nothing catches it. The "fix" is rather hacky and probably a little incorrect. It rely on the behavior of `:fit()` to avoid adding the "wrong" widgets to the layout, which is fragile. However, I don't have a better idea. --- lib/wibox/layout/fixed.lua | 44 +++++++++++++++++++++++++++----- spec/wibox/layout/fixed_spec.lua | 2 ++ 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/lib/wibox/layout/fixed.lua b/lib/wibox/layout/fixed.lua index ee910a34..58779174 100644 --- a/lib/wibox/layout/fixed.lua +++ b/lib/wibox/layout/fixed.lua @@ -33,39 +33,71 @@ function fixed:layout(context, width, height) spacing_widget = spacing ~= 0 and self._private.spacing_widget or nil for k, v in pairs(self._private.widgets) do - local w, h = width - x, height - y + local w, h, local_spacing = width - x, height - y, spacing + + -- Some widget might be zero sized either because this is their + -- minimum space or just because they are really empty. In this case, + -- they must still be added to the layout. Otherwise, if their size + -- change and this layout is resizable, they are lost "forever" until + -- a full relayout is called on this fixed layout object. + local zero = false if is_y then if k ~= widgets_nr or not self._private.fill_space then h = select(2, base.fit_widget(self, context, v, w, h)) + zero = h == 0 end if y - spacing >= height then -- pop the spacing widget added in previous iteration if used if spacing_widget then table.remove(result) + + -- Avoid adding zero-sized widgets at an out-of-bound + -- position. + y = y - spacing + end + + -- Never display "random" widgets as soon as a non-zero sized + -- one doesn't fit. + if not zero then + break end - break end else if k ~= widgets_nr or not self._private.fill_space then w = select(1, base.fit_widget(self, context, v, w, h)) + zero = w == 0 end if x - spacing >= width then -- pop the spacing widget added in previous iteration if used if spacing_widget then table.remove(result) + + -- Avoid adding zero-sized widgets at an out-of-bound + -- position. + x = x - spacing + end + + -- Never display "random" widgets as soon as a non-zero sized + -- one doesn't fit. + if not zero then + break end - break end end - -- Place widget + if zero then + local_spacing = 0 + end + + -- Place widget, even if it has zero width/height. Otherwise + -- any layout change for zero-sized widget would become invisible. table.insert(result, base.place_widget_at(v, x, y, w, h)) - x = is_x and x + w + spacing or x - y = is_y and y + h + spacing or y + x = is_x and x + w + local_spacing or x + y = is_y and y + h + local_spacing or y -- Add the spacing widget (if needed) if k < widgets_nr and spacing_widget then diff --git a/spec/wibox/layout/fixed_spec.lua b/spec/wibox/layout/fixed_spec.lua index 3d50163e..a272b791 100644 --- a/spec/wibox/layout/fixed_spec.lua +++ b/spec/wibox/layout/fixed_spec.lua @@ -78,6 +78,7 @@ describe("wibox.layout.fixed", function() assert.widget_layout(layout, { 100, 20 }, { p(first, 0, 0, 100, 10), p(second, 0, 10, 100, 10), + p(third, 0, 20, 100, 0), }) end) end) @@ -121,6 +122,7 @@ describe("wibox.layout.fixed", function() p(first, 0, 0, 100, 10), p(spacing_widget, 0, 10, 100, 10), p(second, 0, 20, 100, 15), + p(third, 0, 35, 100, 0), }) end) end)