wibox.layout.flex: Do not leave empty space behind

It is not possible to distribute 100px to three widgets equally. The
current version of wibox.layout.flex tries to do that anyway, by giving
each widget 33px and leaving one pixel outside of any widget. Thus, if
the widgets e.g. have a common background, this leads to a one pixel gap
in the background.

This patch changes the flex layout so that the extra pixel is assigned
to some widget instead. It does so by basically keeping a sum of
space_per_item for the widgets that was assigned so far. This sum is
rounded and when this leads to rounding, the corresponding child widget
gets an extra pixel.

More precisely, this tracks a pos as before. Widgets get their position
still assigned based on rounding pos. However, this now also remembers
this rounded position for the next iteration of the loop. This allows to
assign the size of widgets based on the difference between the current
and last rounded position.

(Possibly) fixes: https://github.com/awesomeWM/awesome/issues/2461
Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2018-11-05 09:34:17 +01:00
parent b6b6bc0bd6
commit c80bf6f46e
2 changed files with 16 additions and 11 deletions

View File

@ -10,7 +10,6 @@ local base = require("wibox.widget.base")
local fixed = require("wibox.layout.fixed")
local table = table
local pairs = pairs
local floor = math.floor
local gmath = require("gears.math")
local gtable = require("gears.table")
@ -68,7 +67,7 @@ local flex = {}
function flex:layout(_, width, height)
local result = {}
local pos,spacing = 0, self._private.spacing
local spacing = self._private.spacing
local num = #self._private.widgets
local total_spacing = (spacing*(num-1))
local spacing_widget = self._private.spacing_widget
@ -88,17 +87,23 @@ function flex:layout(_, width, height)
space_per_item = math.min(space_per_item, self._private.max_widget_size)
end
local pos, pos_rounded = 0, 0
for k, v in pairs(self._private.widgets) do
local x, y, w, h
local next_pos = pos + space_per_item
local next_pos_rounded = gmath.round(next_pos)
if is_y then
x, y = 0, gmath.round(pos)
w, h = width, floor(space_per_item)
x, y = 0, pos_rounded
w, h = width, next_pos_rounded - pos_rounded
else
x, y = gmath.round(pos), 0
w, h = floor(space_per_item), height
x, y = pos_rounded, 0
w, h = next_pos_rounded - pos_rounded, height
end
pos = pos + space_per_item + spacing
pos = next_pos + spacing
pos_rounded = next_pos_rounded + spacing
table.insert(result, base.place_widget_at(v, x, y, w, h))

View File

@ -47,7 +47,7 @@ describe("wibox.layout.flex", function()
it("layout", function()
assert.widget_layout(layout, { 100, 100 }, {
p(first, 0, 0, 100, 33),
p(second, 0, 33, 100, 33),
p(second, 0, 33, 100, 34),
p(third, 0, 67, 100, 33),
})
end)
@ -61,7 +61,7 @@ describe("wibox.layout.flex", function()
it("layout", function()
assert.widget_layout(layout, { 5, 100 }, {
p(first, 0, 0, 5, 33),
p(second, 0, 33, 5, 33),
p(second, 0, 33, 5, 34),
p(third, 0, 67, 5, 33),
})
end)
@ -74,9 +74,9 @@ describe("wibox.layout.flex", function()
it("layout", function()
assert.widget_layout(layout, { 100, 20 }, {
p(first, 0, 0, 100, 6),
p(first, 0, 0, 100, 7),
p(second, 0, 7, 100, 6),
p(third, 0, 13, 100, 6),
p(third, 0, 13, 100, 7),
})
end)
end)