The goal is to catch cases where the return value exists, but is
forgotten. There was a large enough number of them to turn this
into a real check. Initially, I just wanted to implement it to fix
the problems, then delete the code. But since this is so common, I
think it is worth the annoyance.
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.
For each widget, the layout function checks whether placing it would
make the function exceed the allowed geometry.
If not, the function places both the widget and a spacing widget.
This check ignores the size of the spacing widget itself, this can cause
overloading of widgets on top of each other.
For example, the following scenario with these widgets:
widgets: widget1 { width = 10, height = 10 }
widget2 { width = 10, height = 10 }
widget3 { width = 10, height = 10 }
and a call to horizontal layout with the
{ width = 10, height = 10, spacing = -5 } parameters.
The function would layout the widgets the following way:
{
widget1: { x = 0, y = 0, width = 10, height = 10 }
spacing: { x = 5, y = 0, width = 5, height = 10 }
widget2: { x = 5, y = 0, width = 5, height = 10 }
spacing: { x = 5, y = 0, width = 5, height = 10 }
widget3: { x = 5, y = 0, width = 5, height = 10 }
}
This behaviour would be the same for any number of widgets for negative
layout.
This patch changes the layout function to check whether the current
widget uses up the whole space.
It also removes 'pos' variable. Its purpose isn't intuitive in the
presence of x and y. This helps to understand where each widget is
placed now that x, y don't hold the end location of the widget in the
previous loop iteration.
The result of the previous example becomes:
{
widget1: { x = 0, y = 0, width = 10, height = 10 }
}
While this might not be the wanted behaviour exactly, distinguishing
between the scenario where 2 widgets are drawn and a scenario where 3
are drawn might complicate the layout function too much.
This patch also adds unit testing that catches the described behaviour.
Signed-off-by: Shay Agroskin <agrosshay@gmail.com>
The fit function is called twice in row.
- The first time it gets the maximum available width, and returns how
much of it it needs (with 0 spacing it would be 477)
- The second time the available width it gets is the same as it returned
last phase (and probably is expected to return the same result again)
The width fit requests is the total width of all widgets together + the
spacing (e.g. if each tag widget is 53 px and spacing is -10 then the
requested width 53 * 9 - 80).
The function tries to first fit all its widgets (the tag numbers) in the
amount of width it received, and only then adds the spacing to it. This
is problematic because in the second phase the widgets need to fit
themselves in the same width they requested earlier minus the spacing
(in case of negative spacing). This is of course impossible and so some
widgets are just not being drawn correctly.
This patch makes fit function take into account the spacing while
placing the widgets and not afterwards.
Also add unit-testing that test the bug described.
Signed-off-by: Shay Agroskin <agrosshay@gmail.com>
The function has several expressions of the form
if self._private.dir == "y" then
This patch stores the result of
self._private.dir == "y"
to avoid code duplication.
Also remove the 'used_in_dir' and 'in_dir' variables since their values
can be calculated using other variables in the function and updating
them individually is error prone.
This patch doesn't do any functional changes.
Signed-off-by: Shay Agroskin <agrosshay@gmail.com>
Now always call both check_widget and make_widget_from_value. This
should make it a lot less confusing when randomly trying to create
a widget as all ways to do it slowly converge toward an unified
one.
ldoc has a magical `@classmod` module type which tries to detect
what is a method and what is a static function. It fails about as
often as it works. This commit makes everything explicit to remove
such issues.
Fixes#2640
Ref #1373
The ratio, fixed and flex layout can now display a widget between
each layout elements.
The align layout was left out because it doesn't support spacing
* Move table functions out of awful.util into new gears.table
* travis: Use v9999 prefix for full requests
Make sure no newly deprecated functions are used
* Move all `awful.util.table.*` calls to `gears.table.*` calls
Move table test functions from awful/util_spec to new gears/table_spec
Change awful.util.subsets call to gears.math.subsets in awful/key.lua
It does not provide much value. The version number is already known to
ldoc globally in the "description" variable.
Signed-off-by: Uli Schlachter <psychon@znc.in>
* Better widget names when using the declarative syntax
* Add ratio.get_ratio to avoid using the private API
* Also support `set_widget` when swapping widgets
This makes the code use the existing functions for setting widgets. That way,
all the sanity checks that the existing functions have are applied for this code
as well.
I just spent half an hour tracking down a bug where a boolean ended up as a
"widget" in a fixed layout. The symptom was that while drawing the widget, an
error happened. Via this change, the error would instead be flagged while
constructing the widget.
Signed-off-by: Uli Schlachter <psychon@znc.in>
Until now, this layout was "append only". There was no official
APIs to remove, replace, insert and swap widgets. This is fine
for the usual wibox + sensors widget used by the majority of
users, but lack flexibility necessary to use the layout system
to place dynamic elements such as clients.
The methods introduced by this commit are also recursive. This
allow widgets to be decorated, wrapped and splitted without
having to add boilerplate code everywhere.
This remove duplicated code and will allow more "collection"
style layouts to be implemented without logic duplication.
This commit also do some small cleanup to remove duplicated
code now present in `awful.util`.
Fixes https://github.com/awesomeWM/awesome/issues/617
Before this, dependencies between widgets where implicitly discovered by
recursive calls to base.fit_widget() and base.layout_widget(). However, it is
too easy to get this wrong (just call one of these functions from outside of a
widget's :fit() / :layout() function) and the resulting mess would be hard to
debug.
Thus, this commit changes the API so that callers have to identify themselves
and we can explicitly record the dependency between the widgets involved.
This also fixes a bug where no dependencies were tracked for widgets after
:set_visible(false). Whoops...
Sorry for breaking the API for adding this.
Signed-off-by: Uli Schlachter <psychon@znc.in>
This way "that other widget" doesn't prevent the current widget from being
garbage collected.
Please note that this in all of these cases the widget under consideration does
have a strong reference to the callback function. This means that the callback
cannot be garbage collected until "this widget" itself is collected. Thanks to
this, this change is safe.
Signed-off-by: Uli Schlachter <psychon@znc.in>