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.
This commit is contained in:
parent
fedc7dc69d
commit
83c31f948b
|
@ -33,39 +33,71 @@ function fixed:layout(context, width, height)
|
||||||
spacing_widget = spacing ~= 0 and self._private.spacing_widget or nil
|
spacing_widget = spacing ~= 0 and self._private.spacing_widget or nil
|
||||||
|
|
||||||
for k, v in pairs(self._private.widgets) do
|
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 is_y then
|
||||||
if k ~= widgets_nr or not self._private.fill_space then
|
if k ~= widgets_nr or not self._private.fill_space then
|
||||||
h = select(2, base.fit_widget(self, context, v, w, h))
|
h = select(2, base.fit_widget(self, context, v, w, h))
|
||||||
|
zero = h == 0
|
||||||
end
|
end
|
||||||
|
|
||||||
if y - spacing >= height then
|
if y - spacing >= height then
|
||||||
-- pop the spacing widget added in previous iteration if used
|
-- pop the spacing widget added in previous iteration if used
|
||||||
if spacing_widget then
|
if spacing_widget then
|
||||||
table.remove(result)
|
table.remove(result)
|
||||||
|
|
||||||
|
-- Avoid adding zero-sized widgets at an out-of-bound
|
||||||
|
-- position.
|
||||||
|
y = y - spacing
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Never display "random" widgets as soon as a non-zero sized
|
||||||
|
-- one doesn't fit.
|
||||||
|
if not zero then
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
end
|
||||||
else
|
else
|
||||||
if k ~= widgets_nr or not self._private.fill_space then
|
if k ~= widgets_nr or not self._private.fill_space then
|
||||||
w = select(1, base.fit_widget(self, context, v, w, h))
|
w = select(1, base.fit_widget(self, context, v, w, h))
|
||||||
|
zero = w == 0
|
||||||
end
|
end
|
||||||
|
|
||||||
if x - spacing >= width then
|
if x - spacing >= width then
|
||||||
-- pop the spacing widget added in previous iteration if used
|
-- pop the spacing widget added in previous iteration if used
|
||||||
if spacing_widget then
|
if spacing_widget then
|
||||||
table.remove(result)
|
table.remove(result)
|
||||||
|
|
||||||
|
-- Avoid adding zero-sized widgets at an out-of-bound
|
||||||
|
-- position.
|
||||||
|
x = x - spacing
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Never display "random" widgets as soon as a non-zero sized
|
||||||
|
-- one doesn't fit.
|
||||||
|
if not zero then
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
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))
|
table.insert(result, base.place_widget_at(v, x, y, w, h))
|
||||||
|
|
||||||
x = is_x and x + w + spacing or x
|
x = is_x and x + w + local_spacing or x
|
||||||
y = is_y and y + h + spacing or y
|
y = is_y and y + h + local_spacing or y
|
||||||
|
|
||||||
-- Add the spacing widget (if needed)
|
-- Add the spacing widget (if needed)
|
||||||
if k < widgets_nr and spacing_widget then
|
if k < widgets_nr and spacing_widget then
|
||||||
|
|
|
@ -78,6 +78,7 @@ describe("wibox.layout.fixed", function()
|
||||||
assert.widget_layout(layout, { 100, 20 }, {
|
assert.widget_layout(layout, { 100, 20 }, {
|
||||||
p(first, 0, 0, 100, 10),
|
p(first, 0, 0, 100, 10),
|
||||||
p(second, 0, 10, 100, 10),
|
p(second, 0, 10, 100, 10),
|
||||||
|
p(third, 0, 20, 100, 0),
|
||||||
})
|
})
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
@ -121,6 +122,7 @@ describe("wibox.layout.fixed", function()
|
||||||
p(first, 0, 0, 100, 10),
|
p(first, 0, 0, 100, 10),
|
||||||
p(spacing_widget, 0, 10, 100, 10),
|
p(spacing_widget, 0, 10, 100, 10),
|
||||||
p(second, 0, 20, 100, 15),
|
p(second, 0, 20, 100, 15),
|
||||||
|
p(third, 0, 35, 100, 0),
|
||||||
})
|
})
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
Loading…
Reference in New Issue