Squashed commit of the following:
commit 69821f51fe1e8652715658543e50631ece495090
Author: Alex Belykh <albel727@ngs.ru>
Date: Mon May 10 19:17:55 2021 +0700
Refactor property handling in wibox.widget.graph
In addition, baseline_value, step_width and
step_spacing properties are all set to their default
non-nil numeric values during instance creation now.
commit 842eb429bf5df4b2ba46b2e6f7646afe89b1a3c3
Author: Alex Belykh <albel727@ngs.ru>
Date: Sun May 9 06:18:45 2021 +0700
Make graph:draw_values() private
There's no documentation nor confidence that it's a good API,
so I'm hiding it for now.
commit 720746780574e4bad14a71fc4174955139c2eb50
Author: Alex Belykh <albel727@ngs.ru>
Date: Fri May 7 04:04:13 2021 +0700
Document graph_should_draw_data_group() for posterity
commit 7c73f3754ce6ba86b118f1170a6f9e406ab4841d
Author: Alex Belykh <albel727@ngs.ru>
Date: Fri May 7 03:59:21 2021 +0700
Make graph:should_draw_data_group() private
There's no confidence whether it's a good API,
so I'm hiding it for now.
commit b3539e20adb6423118af726ae4f8751ef864b5d2
Author: Alex Belykh <albel727@ngs.ru>
Date: Fri May 7 03:36:44 2021 +0700
Make graph:preprocess_values() private
There's no confidence whether it's a good API,
so I'm hiding it for now.
commit 2df4400e780a6260f8d0ab1c60734fbb11bf3c4f
Author: Alex Belykh <albel727@ngs.ru>
Date: Thu May 6 10:05:23 2021 +0700
Add spec/wibox/widget/graph_spec.lua
commit ce01a9771ab439b8df841f1565aa4aa8a44a5e0d
Author: Alex Belykh <albel727@ngs.ru>
Date: Wed May 5 08:16:18 2021 +0700
Improve graph.capacity documentation
commit e28fade8f655802f5bf89154169f68d256b8e332
Author: Alex Belykh <albel727@ngs.ru>
Date: Wed May 5 07:36:01 2021 +0700
Document graph:compute_drawn_values_num()
commit dd68332292465422d08b48e9f0229f143beccbc6
Author: Alex Belykh <albel727@ngs.ru>
Date: Wed May 5 05:24:23 2021 +0700
Document graph:pick_data_group_color() method
commit ca6dc55f77aca88a6e9cc90bb6fd0045739f41f5
Author: Alex Belykh <albel727@ngs.ru>
Date: Sun May 2 04:13:58 2021 +0700
Guard against setting data groups sparsely in graph:add_value()
commit cdea5f126f7984e72924f6dffbd312c4fe3b032f
Author: Alex Belykh <albel727@ngs.ru>
Date: Sun May 2 02:36:12 2021 +0700
Refactor scaling and baseline choice out of graph:draw()
commit 10135deafe8a9390ba66ab657ebb1fb41d549e8c
Author: Alex Belykh <albel727@ngs.ru>
Date: Sat May 1 21:34:48 2021 +0700
Document graph.nan_color and graph.stack properties
commit 0d73bb84ac66b87e16aee472bd1f299549f66a1c
Author: Alex Belykh <albel727@ngs.ru>
Date: Sat May 1 20:49:24 2021 +0700
Use a better example in docs for the graph.stack property
commit c27d160a0826d033d49d6141608c40aa8a0642fa
Author: Alex Belykh <albel727@ngs.ru>
Date: Sat May 1 16:05:38 2021 +0700
Document graph.baseline_value property
commit 459bc8176c13d4ea32af0dcdc2399d3b929b1c6a
Author: Alex Belykh <albel727@ngs.ru>
Date: Sat May 1 15:53:47 2021 +0700
Document graph.clamp_bars property
commit e732ee0b3b007d213e689b98cc00ae7cb141ae08
Author: Alex Belykh <albel727@ngs.ru>
Date: Sat May 1 15:28:34 2021 +0700
Improve graph:add_value() and :clear() documentation
commit ae73e3aa9f8d60409cbe4cb4da9612f31af4f38e
Author: Alex Belykh <albel727@ngs.ru>
Date: Sat May 1 15:28:11 2021 +0700
Improve graph min_value/max_value/scale documentation
commit a7350996a9def773b91b1631e6c0507e33d8f93b
Author: Alex Belykh <albel727@ngs.ru>
Date: Sat May 1 15:27:36 2021 +0700
Cleanup graph examples to show only relevant things in docs
commit 30740c26f4f41c16f4c8a3c339bcb7bd299e14cd
Author: Alex Belykh <albel727@ngs.ru>
Date: Sat May 1 14:04:36 2021 +0700
Rename graph.stack_colors property to `group_colors`
The colors are used for stacked and non-stacked graphs alike,
so the name didn't make sense.
Also document and clarify some color stuff.
commit 1ea01bfd410971cf0d0c25fd74cd764d5eb7279d
Author: Alex Belykh <albel727@ngs.ru>
Date: Fri Apr 30 21:25:41 2021 +0700
Add an example file for code coverage of some fringe graph cases
commit eae68e39553f88a6275a0c65bf040b5d4c262b54
Author: Alex Belykh <albel727@ngs.ru>
Date: Fri Apr 30 20:23:32 2021 +0700
Add step_shape to the graph/nan_color example for code coverage
commit 8027147bc2eab34a97b49a428fb8cef27f122bed
Author: Alex Belykh <albel727@ngs.ru>
Date: Fri Apr 30 19:55:18 2021 +0700
Add example files for graph.nan_color/nan_indication properties
commit 89a25a165c52b2c15b6c4d95ecb777a9067e66f9
Author: Alex Belykh <albel727@ngs.ru>
Date: Fri Apr 30 19:33:07 2021 +0700
Make widget graph:add_value(v) default v to NaN
0 as a default makes no sense and silences the error
that is failing to specify a value, to which the user
should rather be alerted. The graph widget has sane
NaN handling now and will do just that.
commit 2835d552440be48d356a7f7b1d64963696dd550b
Author: Alex Belykh <albel727@ngs.ru>
Date: Fri Apr 30 19:20:48 2021 +0700
Implement graph.nan_color and nan_indication properties
Now, whenever there's a NaN among values and
graph.nan_indication is set, the corresponding area,
where the value bar should have been drawn, is filled
with the nan_color from top to bottom.
The painting is done after all data is rendered,
to make sure that it won't be overpainted and go unnoticed.
NaNs among graph's values are inevitably a sign of
some error and it is arguably not a sane default behavior
to simply not render them at all. The user should take
immediate note of any errors by default, instead of
wondering at a mysteriously empty graph widget, which
is why nan_indication is set to true by default.
If the user wants to silence NaNs, they can always simply
set it to false.
nan_color if unset, defaults to a noticeable yellow-black
pattern.
As a direct and planned consequence, stacked graphs
with negative values in them trigger the NaN handling too.
But silencing NaN handling for those graphs is also possible
and semi-sane, because then NaNs and negatives are ignored
and the graph behaves (almost) like they were zeros.
commit 9c1f8f08b400e01e19c534f3810c9c9ab485760c
Author: Alex Belykh <albel727@ngs.ru>
Date: Mon Apr 26 08:10:19 2021 +0700
Refactor out graph_map_value_to_widget_coordinates() function
commit 1905991ddecabdae3e15ffb8ee5b18a1bee1a711
Author: Alex Belykh <albel727@ngs.ru>
Date: Wed Apr 28 13:39:29 2021 +0700
Add an example file for graph.baseline_value property
commit b31b39d66f4c037a9484b71a3f910703ae01fac0
Author: Alex Belykh <albel727@ngs.ru>
Date: Thu Apr 22 07:03:49 2021 +0700
Add an example file for graph.clamp_bars=false/true comparison
commit a1fc850e3047f9ee2c9ddeffacfbabf3ded34171
Author: Alex Belykh <albel727@ngs.ru>
Date: Thu Apr 22 04:06:45 2021 +0700
Add an example file for graphs with negative values and shapes
commit 2f012f8ff1bb5094c14e724a61e59a2a3a296bc8
Author: Alex Belykh <albel727@ngs.ru>
Date: Thu Apr 22 01:06:05 2021 +0700
Add an example file for a graph displaying negative values
commit 7b14fbd59a4c4c51962fd3110a1a900dd5f4eb98
Author: Alex Belykh <albel727@ngs.ru>
Date: Wed Apr 21 11:18:26 2021 +0700
Add an example file for graphs with step_width < 1
commit dfd9a54544b637e2fbe3d1325f9cc24b3f4d2313
Author: Alex Belykh <albel727@ngs.ru>
Date: Wed Apr 21 10:17:38 2021 +0700
Add an example file for graph.stack=false/true comparison
Should also demonstrate that multiple data groups
are possible for non-stacked graphs too.
commit 5b532106c3fd255f9b66a66cfb88d977b489ab5d
Author: Alex Belykh <albel727@ngs.ru>
Date: Wed Apr 21 09:34:14 2021 +0700
Add an example file for disabling graph data groups with nil colors
commit ac6f1083c02fcb428f089a616f9b0ebaa5496b6c
Author: Alex Belykh <albel727@ngs.ru>
Date: Wed Apr 21 08:57:25 2021 +0700
Add an example file for step_shape/width/spacing on stacked graphs
commit b3703db6a5139e73e72c1cfd198ece2cd9be7df2
Author: Alex Belykh <albel727@ngs.ru>
Date: Wed Apr 21 08:43:56 2021 +0700
Add an example file for scale=false/true on stacked graph
commit b000aed4a12cb44fb501e1c8432a71a14b2f8f3f
Author: Alex Belykh <albel727@ngs.ru>
Date: Tue Apr 20 08:22:19 2021 +0700
Document deprecation of graph's width and height
commit cb0ad617bd6c83a499896797318e3b0b588c3566
Author: Alex Belykh <albel727@ngs.ru>
Date: Mon Apr 19 07:53:37 2021 +0700
Deprecate width and height properties of wibox.widget.graph
commit 8c64e14ad91a074b784166a7054e53444cccb9d2
Author: Alex Belykh <albel727@ngs.ru>
Date: Mon Apr 19 04:37:59 2021 +0700
Refactor graph:draw() to separate concerns
Firstly, summation of group values for stacked graphs
is extracted into graph:preprocess_values().
This makes graph:draw() smaller and exposes the fact, that
stacked graphs are almost entirely just a form of
a more general concept: pre-render data manipulation.
It's something a user might want to customize,
and now they can do it by monkey-patching the method.
Secondly, the logic for deciding, if and with which color
a data group should be drawn, is extracted into
graph:should_draw_data_group() and get_data_group_color()
methods respectively.
This makes it customizable too and makes more obvious
the fact, that it is a general thing that has nothing
to do with stacked graphs in particular.
With this there are only 5 lines remaining in graph:draw(),
that could be said to be specific to stacked graphs,
all pertaining to the `prev_y` variable, which merely
preserves the bar coordinates from a previous data group.
commit 2a32b6305d893f413303728a0a3da1dcd9a5591e
Author: Alex Belykh <albel727@ngs.ru>
Date: Fri Apr 16 22:52:37 2021 +0700
Pointlessly optimize graph:add_value()
1) Purge old values first, then insert the new one, if needed.
Since Lua grows arrays in power of two steps, and our
guess_capacity() also takes care to return even integers,
it would be a shame to overstep the capacity by one by
inserting first and thus getting the table size doubled
only to never use the most of it.
2) Use a removal procedure that doesn't call
the slow length operator at all. Previous code called it
twice (once in table.remove) for every removed value.
commit 680ea8f5d81e9040afb4662b3229e937e4b89e02
Author: Alex Belykh <albel727@ngs.ru>
Date: Fri Apr 16 16:23:38 2021 +0700
Set graph data series color before the painting loop
commit b970f0f221ae76250f2a94433ff79d653caa6e21
Author: Alex Belykh <albel727@ngs.ru>
Date: Fri Apr 16 16:05:37 2021 +0700
Drop a large no longer necessary `if` in graph:draw_values()
This commit is almost purely a whitespace change.
commit 6b4f0541c70ec99d7f6e276bae64939f337120d6
Author: Alex Belykh <albel727@ngs.ru>
Date: Fri Apr 16 16:00:50 2021 +0700
Extract values rendering code into graph:draw_values() method
This is to avoid ungodly if nesting levels, which are needed
to bail out of drawing values early and skip to drawing the border.
The next commit will get rid of the if.
commit e0950e4f99d1ea1c4b8cea2cc67629fa40030c2a
Author: Alex Belykh <albel727@ngs.ru>
Date: Fri Apr 16 14:50:20 2021 +0700
Track graph draw() usage to guess necessary array capacity
The last step of divorcing add_values() from width calculations,
while ensuring that user doesn't observe a lack of data to draw.
The widget now tracks an approximate number of values that
it has been asked to draw() in _private.last_drawn_values_num,
and truncates its values array based on that
(if not overridden by the capacity property).
commit 2e3d542282f35e7c0fed454da0f2eada0fcf3b78
Author: Alex Belykh <albel727@ngs.ru>
Date: Fri Apr 16 13:35:12 2021 +0700
Add `capacity` property to graph widget
This is the second step of divorcing add_values()
from calculations involving widths.
How many values are stored and how many values are drawn
are distinct concepts. There isn't even a single definitive
"how many values are drawn" because the widget could
be rendered in several places with distinct widths simultaneously,
and in every such place the data must be drawn appropriately,
e.g. with auto-scaling, that takes only the visible data points
into account. And the draw() method can do that now.
The default capacity value of nil uses heuristics
based on widget's _private.width to guess some capacity
that would tolerate some dynamic widget resizing.
If the user finds the heuristic failing them, they
can set the capacity property to the desired maximum number
of values that will be kept in the _private.values array
(in each data group).
commit 08d4a80686f7fe363551c35589a460839f60853e
Author: Alex Belykh <albel727@ngs.ru>
Date: Fri Apr 16 03:27:18 2021 +0700
Extract values size computation into compute_drawn_values_num()
This is the first step of making add_values() not
concern itself (directly) with widget dimensions.
The user can monkey-patch the method to override
how many values are (logically) drawn, because
it affects graph auto-scaling and can be useful for rendering
of step_shape-s that paint outside of their step_width.
I didn't make it a full-blown function-valued property,
because it seems a fringe functionality,
which I'm too lazy to document.
commit 3c5617c98ab1147618ed22e8414a77fc56b45f6e
Author: Alex Belykh <albel727@ngs.ru>
Date: Fri Apr 16 02:32:29 2021 +0700
Copy graph widget prototype methods over in bulk
commit 169538837ece41a03d02ba8fbc0e4097062b67a3
Author: Alex Belykh <albel727@ngs.ru>
Date: Sun Apr 25 05:58:01 2021 +0700
Remove graph.baseline_y property
After giving it some thought I've concluded, that it is unlikely
to be useful as it is now. I'd better reserve the name for
some more sensible functionality, like fixing the baseline_value
defined axis at the given widget coordinate, adjusting the scaling
accordingly, so min_value/max_value won't generally correspond
to widget top and bottom anymore.
commit 202ffaa9a0b820c7c471e1121d01b91f8f76cd38
Author: Alex Belykh <albel727@ngs.ru>
Date: Thu Apr 15 12:06:55 2021 +0700
Add baseline_y and baseline_value properties to graph widget
Now values in graph have a *baseline*, tunable with
baseline_y and baseline_value properties.
It is the (for now invisible) horizontal line from which
all bars in the graph grow. I call it a "baseline"
instead of "axis", because it doesn't actually have to correspond
to the 0 value. But it can, and actually does now by default.
baseline_y and baseline_value properties determine
the vertical placement of the baseline in the widget.
baseline_y is the position of the baseline in normalized
widget coordinates, e.g. 0 corresponds to widget's top,
1 - to widget's bottom, and 0.5 - to widget's middle.
So if e.g. one sets baseline_y = 0, then no matter how the widget
is resized and how its values are scaled, bars in it will be drawn
starting from the top.
baseline_value is the position of the baseline in
value coordinates.
So if one sets baseline_value = 10, then no matter what happens,
bars for values greater than 10 will be drawn as growing up from
this line, and bars for values smaller as growing down.
Where and if it will be seen in the widget, depends on the scaling.
baseline_value = 0 is the familiar zero axis.
baseline_y is unset by default and has priority, i.e.
if it's set, then baseline_value is ignored.
baseline_value defaults to 0.
Prior to this commit, bars were always drawn from the bottom edge
of the widget, or, in the new terms, the widget had baseline_y = 1.
But it was indistinguishable from baseline_value = 0, because
the widget clamped all negative values to 0, so the difference
between the two could never be observed. baseline_value = 0 is
clearly more useful and familiar to people, so now it is in force
by default.
commit df7e19abaebf0a871b5ca217b4cc3365533267a6
Author: Alex Belykh <albel727@ngs.ru>
Date: Thu Apr 15 11:18:12 2021 +0700
Move value clamping from graph:add_value() into draw()
Previously all values were forcibly clamped between
0 (not tunable at all) and max_value (1 by default).
Thus graphs with negative values were not an option.
NaN values were conflated with zeros, even though
it may be useful to maintain the distinction and render
them differently. And if user happened to dynamically
change the max_value property, they discovered,
that their data got truncated.
Preserving user data as it was given is more flexible and
makes things easier to debug. This commit does exactly that.
So what happens now to the newly allowed values during draw()?
There are 3 new cases to consider:
1) NaNs
2) Negatives
3) Values outside of min_value..max_value range
NaNs are presently simply not drawn. An empty place is reserved
where the value should've been, but nothing else is done.
This is distinct from how a zero is handled,
e.g. if step_shape is set, it is called with the height
parameter = 0, which can still end up drawing something,
depending on the shape.
One could also consider addition of nan_color/nan_shape
properties which could be drawn to alert user
to a gap in their data.
Negative values necessitate introduction of the concept of
the zero axis, from which they will be drawn DOWN, in contrast to
positive values. Where should this axis be drawn?
How should step_shape-s with inherent direction, e.g. arrows,
be drawn for negatives? This will be addressed in the next commit.
Values outside of min/max_value range can imply shapes that
go beyond widget dimensions. An arrow shape that goes beyond
the roof is visibly different from an arrow that saturates and
merely touches the widget top, and the user may reasonably desire
either behavior. Therefore this commit introduces
a boolean clamp_bars property, which defaults to true
for reasons of robustness and backward compatibility with
the behaviour prior to this commit. The property of course affects
only the display of the values, the actual user data stays intact.
commit c9c24fb1ab741cd6bb8074971d568e0646c51532
Author: Alex Belykh <albel727@ngs.ru>
Date: Thu Apr 15 09:29:01 2021 +0700
Use rectangles for drawing graph bars of all sizes
I have benchmarked various bar drawing strategies
and graph sizes and found out that drawing graph bars
with rectangles is as fast or even marginally faster
than using fat lines.
Thus the code that tries to special-case 1px bars
as lines seems to be not worth the additional complexity
it introduces, and this commit removes it.
Incidentally, I've also established, that rectangles
are more robust. If one draws graph bars and feeds
cairo very large coordinates (~2^62), then corresponding
rectangles fail to render, but all the other rectangles
in the same series get rendered successfully,
whereas a single large coordinate in a move_to/line_to()
sequence is enough to cause all lines in the batch
to fail to render.
commit bc7f4be5e06405b5aa7fb443a5ace2b9b9575b1f
Author: Alex Belykh <albel727@ngs.ru>
Date: Thu Apr 15 09:01:42 2021 +0700
Cache cairo methods used in the inner loop of graph:draw()
I have benchmarked the draw() method, both
on cairo xcb and on argb32 image surfaces, and have discovered
that cairo context method calls are unnaturally slow,
to the point, that almost nothing else in the function matters.
For example, drawing bars with vertical lines made
the whole draw() function almost 2 times slower
than doing the same with rectangles, merely because
the former requires two method calls (move_to/line_to),
and the latter only one.
Simply caching hotpath cairo methods in local variables,
reduced the difference between the drawing methods
to a negligible one and made the whole function
4 times faster on a typical 100-bar graph,
(1.4ms to 0.33ms on my laptop) thus bringing closer
my secret dream of drawing live audio data with
awesome graphs (kidding).
I guess, LGI does something not very optimal there,
like gobject-introspecting the method every time,
or something. There might be some untapped optimization
potential, possibly in upstream, like a method cache,
from which everything in awesome could benefit,
even though I imagine not many things are so
call-intensive as the graph widget, to really feel
the difference.
commit 538df25bdf02b53d0bbe81809eef2e6fdb05ff6f
Author: Alex Belykh <albel727@ngs.ru>
Date: Thu Apr 15 07:32:37 2021 +0700
Use 1-based index in the inner graph draw loop
It's used there only once for a calculation and
then several times to index some tables,
and index 0 is bad for lua tables performance-wise.
commit 7412546916cd0a0a490130a120255ffb719398b8
Author: Alex Belykh <albel727@ngs.ru>
Date: Tue Apr 13 21:55:12 2021 +0700
Leave graph.max_value uninitialized at construction
This is a user-visible change, but the previous behavior
was probably not what user expected anyway, namely
with graph.scale set the graph mysteriously couldn't
zoom in onto values that are smaller than 1.
commit eb81d7929a161e79c13262cfa73ac2e6a820e8ed
Author: Alex Belykh <albel727@ngs.ru>
Date: Tue Apr 13 21:48:29 2021 +0700
Allow graph.max_value be nil
This makes its behave symmetrically to min_value.
Now it defaults to 1, when graph.scale is not set,
and to the maximum value in the graph data, when graph.scale is set.
commit f622a8430cbfde7007b58d7f4c9c76b08c91e997
Author: Alex Belykh <albel727@ngs.ru>
Date: Tue Apr 13 12:01:13 2021 +0700
Calculate max values num in graph:add_value() more precisely
At most so many values were kept in the widget values array,
as there are pixels of usable widget width (i.e. sans border).
This is exactly right for the surely most common case
of graphs with 1px-wide bars, but is more than needed for
graphs with step_width+step_spacing>1, and not enough for
graphs with subpixel bars.
Moreover this made graph autoscaling behave weirdly in
graphs with thicker bars, because
old values survived longer in the array and
kept affecting min_value/max_value calculations
even after they were shifted off-screen.
The maximum number of kept values is now calculated exactly
as the number of values that can be displayed at once,
taking step_width and step_spacing into account.
It might be worth adding a max_values_num property to the graph
to let user override this calculation, in case they draw
shapes in step_shape() outside of its supposed rectangle,
so our assumptions of visibility are wrong, or
the widget often gets resized, resulting in the annoyance of
visibly truncated series.
commit 0aa63249a18641251a1bf77423739164f0eab39f
Author: Alex Belykh <albel727@ngs.ru>
Date: Tue Apr 13 02:30:13 2021 +0700
Fix border_color/border_width bugs in graph widget
add_value() wrongly assumed that border_width is always set,
when border_color is, so if user set only the latter,
an error occurred.
add_value() assumed that border_width is always < width
which led to awesome hanging up in an infinite loop,
should that fail to be the case.
The graph border_width property was driven
by the border_color property, instead of the other way round.
If border_color wasn't set, the border wasn't drawn all,
even if user sets non-zero border_width, which is
a confusing behavior, in contrast to all other widgets,
which simply use a plethora of fallback colors
to draw the border, when needed.
This also meant that, despite being documented,
the beautiful.graph_border_color fallback color
could not and was not ever used.
If the border_color was set though, an unset
border_width was immediately assumed to be 1 instead of 0,
also contrary to what other widgets do.
Theme colors shouldn't influence widget layout,
so this commit fixes this behavior to:
1) border_width always defaults to 0, if unset.
2) border_color falls back to
beautiful.graph_border_color or white.
Maybe one should also add a beautiful.graph_border_width
theme variable, like some widgets do.
commit dad4a3253b8fef971fb82720d2a407fcc0a879ad
Author: Alex Belykh <albel727@ngs.ru>
Date: Wed Apr 14 03:11:27 2021 +0700
Implement multiple data series drawing for non-stacked graph
The widget can already hold and draw multiple data groups,
so it makes little sense to limit drawing only to the first group
when graph.stack = false, probably leading to user's confusion.
Now user can call add_value(v, group) with group > 1 and
the data series will be drawn (over groups with lesser id-s)
with graph.stack_colors[group] color, if stack_colors is set, or
with graph.color, if stack_colors isn't set.
Thus nothing visibly changes for all current users
of non-stacked graphs with only single data series,
but the new functionality is now there for those who need it.
One can't fully emulate this functionality, e.g. with
multiple graphs widgets in a wibox.layout.stack, because
data series in a single widget can enjoy a common auto-scaling.
commit 3e645c976184ab5f50d625271c25062db9ab7ed9
Author: Alex Belykh <albel727@ngs.ru>
Date: Tue Apr 13 01:59:12 2021 +0700
Don't draw a stacked graph data group if there's no color for it
If stack_colors[idx] is nil for the group `idx`,
don't draw it at all (as opposed, e.g. to the effect
of drawing it with a transparent color, or as though
it had all values == 0, which both produce different results).
This code is still subtly different from prior behavior,
because now user can have a non-contiguous stack_colors table
and turn the display of any data group on and off at will,
whereas the code two commits earlier would just stop
rendering as soon as ipairs(stack_colors) does, i.e.
no data series were drawn past the first nil hole.
This commit only looks large, but is mostly a whitespace change
due to nesting from a pair of wrapping ifs.
commit 8c0273786de1ade66bdd977699f98b588da9f487
Author: Alex Belykh <albel727@ngs.ru>
Date: Tue Apr 13 01:32:42 2021 +0700
Unify stacked and non-stacked graph rendering
Now stacked graphs support everything the nonstacked do,
like step_width ~= 1 and custom step_shape-s.
Technical notes:
This code no longer calls cr:stroke() for every single value
in a stacked graph, but rather paints a whole series and
then cr:stroke/fill()-s it at all once with its color,
improving performance considerably.
Additionally the graph no longer relies on the presence
of the stack_colors property to render series.
It draws all data that it has, and, if there's no corresponding
color in stack_colors, falls back to graph.color.
This will be changed in the next commit to
the prior behavior of only drawing those series
for which there's a color in the stack_colors table,
but that would've made this commit's diff much larger due to
required nesting ifs over large code chunks.
This commit also takes care to properly handle NaNs
and negative values.
Those are currently (almost) guaranteed to not occur in
the values array due to clipping in graph:add_value(),
but I intend to eventually drop the clipping, because it
does nothing that draw() really relies upon,
and allowing unclipped and NaN values is more flexible and less
surprising, e.g. when user dynamically toggles graph.scale.
Eventually I intend to implement drawing negative values
in non-stacked graphs and possibly even in the stacked ones.
commit 38c6589c51b2aa057d7c2f40182ecf32b5b2ff5e
Author: Alex Belykh <albel727@ngs.ru>
Date: Fri Apr 16 10:04:15 2021 +0700
Convert graph:draw() to use `self`
commit f21f1b2550426df1c4ea8abde079b1ccef84b394
Author: Alex Belykh <albel727@ngs.ru>
Date: Mon Apr 12 12:27:26 2021 +0700
Fix scaling for stacked graphs
Stacked graphs have cumulative heights,
values from all groups that end up in the same graph bar are
effectively summed. Previous code didn't take that into account
when calculating min/max_value for the purposes of rescaling, but
simply examined every value separately.
This code adds up all values up front and finds min/max among those,
to determine proper scaling that would fit the graph exactly.
commit 1ce4c7bf63bdd6c99c195d668347bec49355e921
Author: Alex Belykh <albel727@ngs.ru>
Date: Mon Apr 12 09:49:35 2021 +0700
Draw shaped graph bars only up to the baseline
Prior to this commit, every step_shape bar was,
for some reason, drawn with height = full widget's height,
regardless of the value it represents.
So for the most bars their lower end was far outside the box
and therefore clipped off. So e.g. one couldn't see the
lower round edges of rounded rectangles.
This commit fixes that by appropriately varying the height
that is passed into step_shape(), so that lower edges of the bars
always exactly touch the lower edge of the graph.
If the user wants to restore the prior behavior, they can simply
ignore the passed-in height in step_shape() and
just always draw their shape with height = full widget height.
But they couldn't replicate the effect of this commit in
their rc.lua without essentially writing their own graph widget.
commit e25185b08da23745b5815f85f6e9e43222ed2294
Author: Alex Belykh <albel727@ngs.ru>
Date: Mon Apr 12 08:42:54 2021 +0700
Avoid incremental transform shifting during graph bar rendering
Instead of letting addition errors and cognitive load accumulate
simply use the same offset calculation that is used for lines and
reset the transform back to the top-left corner after every drawn bar.
It's conceptually simpler, and will be useful later for
stacked graphs and more.
It also fixes a discrepancy between plain and step_shape rendering.
Prior to this commit, bar coloring occurred with a disturbed transform,
which was centered at the last drawn bar, wherever it happened to be.
This meant that nontrivial colors, like gradients and images,
were arbitrarily offset when step_shape was used.
commit f3e98866d8583c35d0b557c09f529299edc9ba2c
Author: Alex Belykh <albel727@ngs.ru>
Date: Mon Apr 12 06:45:29 2021 +0700
Refactor out graph bar height expression into a variable
commit f54528d6892f5aaa4595917853c9e2130f743fdb
Author: Alex Belykh <albel727@ngs.ru>
Date: Mon Apr 12 06:20:25 2021 +0700
Draw graph bars with lines only when step_width == 1
Before this commit graph bars of step_width < 1
were drawn with lines of width 1, but that's a bit unfortunate,
because it led to much overpainting, while still ending up
with a graphically incorrect result.
Let's draw such bars with rectangles and let cairo
do things with subpixels, getting more graphically
accurate result, while still keeping the common case
of step_width == 1 (supposedly) fast-drawn with lines.
commit b6515dca67c18b78eb5657378131a62ab43d4cfc
Author: Alex Belykh <albel727@ngs.ru>
Date: Mon Apr 12 05:54:07 2021 +0700
Fix unsharp edges when drawing graph bars with rectangles
The 0.5 offset is only helpful for 1-width strokes, not for fills.
commit 7f3db8f07e82f821bcd1dc418d66564f537609d6
Author: Alex Belykh <albel727@ngs.ru>
Date: Mon Apr 12 05:21:01 2021 +0700
Do coordinate transformations even if the value isn't drawn
The graph presently doesn't draw values < 0, but there was
a discrepancy between drawing with and without step_shape.
The default line/rectangle drawing reserves an empty place
where the skipped value should've been,
but no such empty place is reserved, when step_shape is used.
This commit fixes that.
Skipped values always have their empty space now.
commit 7b731ebfe96af7a9dba9c57371da6761cf22c00c
Author: Alex Belykh <albel727@ngs.ru>
Date: Mon Apr 12 05:03:30 2021 +0700
Fix graph bar scaling when min_value is not 0
Previous calculation lead to underscaling of values
so that even value = max_value wasn't drawn to full height.
commit dca59fd8b7fff0e7e646f2dfc6bd92047028e5a8
Author: Alex Belykh <albel727@ngs.ru>
Date: Mon Apr 12 04:18:40 2021 +0700
Calculate the horizontal graph bar offset only when needed
commit 940ddf4b9825e9c3a91d276208c089d8c74e49db
Author: Alex Belykh <albel727@ngs.ru>
Date: Mon Apr 12 04:17:23 2021 +0700
Call cr:move_to() only when drawing the graph with lines
It's redundant otherwise and might even interfere
with user's drawing in step_shape().
commit b5d5cd10ca29fb29cd751faaa95137c2fe89ff63
Author: Alex Belykh <albel727@ngs.ru>
Date: Mon Apr 12 04:04:06 2021 +0700
Fix wrong horizontal offset calculations in widget.graph
Indices in the loop are zero-based, so
things like i-1 and i>1 aren't necessary and
actually wouldn't have been correct even in a 1-based loop.
step_shape = gears.shape.rectangle and
step_shape = nil, which is supposed to default to rectangle
according to docs, were drawn differently due
to mismatched offset calculations, which led to problems
especially noticeable when step_spacing is not zero, e.g:
1) whole graph shifted left too much, drawn partially off-screen.
2) whole graph shifted right too much,
and the first bar placed closer to the rest than others.
commit dc369fa198281e000afc1bd17326f3a264adf7d1
Author: Alex Belykh <albel727@ngs.ru>
Date: Mon Apr 12 02:09:21 2021 +0700
Fix the "border_width affects graph bar width" bug
Graph bars were drawn with lines of border_width thickness
instead of 1, i.e. possibly too fat to be readable.
commit 1ba73378cf29ed27a6ecd18716394779ceb543d9
Author: Alex Belykh <albel727@ngs.ru>
Date: Wed Apr 14 00:13:03 2021 +0700
Simplify internal values representation in graph even more
New values in graph._private.values were pushed to the end,
and old values were removed from the beginning of the table.
In draw() however newer values are drawn first,
at the left edge of the graph, necessitating
annoying idx = #values - idx conversions everywhere.
In particular in stacked graph that means that
values that are drawn together may have different indices.
One has to shift the values array in add_value()
either way, so one might as well insert
new values at the beginning of the array
and simplify the rest of the code.
This doesn't seem like much yet, but it will prove
to be much more convenient and less error-prone in
what I'm going to do later.
commit f70523ee68dbd6b67050ace4b82903a9b22440c7
Author: Alex Belykh <albel727@ngs.ru>
Date: Tue Apr 13 13:35:10 2021 +0700
Simplify internal values representation in graph widget
graph._private.values was either a table of values or
a table of tables of values, depending on whether
"stack" property is enabled, ... or a mix of both
if user forgot to pass the second "group" parameter
to graph:add_value().
This resulted in pretty fragile and confusing behavior,
e.g. leaving user to wonder, why they see nothing more
after setting stack=true for a graph in a previously working
rc.lua, and demanding a very careful use of
add_value() from the user, or else some values or
even entire stacks would mysteriously vanish
and errors in draw() get triggered,
sometimes after a period of seemingly normal functioning.
Now `values` is always a table of tables and
the group parameter in add_value() defaults to 1,
thus making the non-stacked graph a trivial variant
of the stacked graph.
* horizontal/vertical scaling/stretch
* max scaling factor
* vertical/horizontal align instead of hardcoded top-left
* scaling_quality, if Cairo cooperates
It also fixes the clip_shape when resize = false.
Add an explicite `@property` tag to the `wibox.layout.flex` doc
comments to override the `fill_space` property from
`wibox.layout.fixed` and mark it as hidden thanks to `@hidden`.
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>
When wrapping container widgets to create reusable composite widgets,
`drill` will be called twice on the same widget definition. The first
call happens within the wrapping function and applies the children
widgets fine. The second call happens when the composite widget is used,
but since there are no children widgets defined, the call to
`set_children` sets the existing child to `nil` instead.
Fixes#3213.
Signed-off-by: Lucas Schwiderski <lucas@lschwiderski.de>
There seem to be two issues here. First, the if-statement at the
beginning of the function will return prematurely if
`self._private.widgets[index]` exists. There seems to be a
missing `not` there.
Second, index 1 is interpreted as the top of the stack (although the
documentation says otherwise), but the widget is inserted at the end of
`self._private.widgets`, so it gets pushed to the bottom
instead of the top.
If the user copy/pasted `naughty.config.*` into their config rather
than set values 1 by 1, we could no longer add new values since they
would get removed. To prevent more users being affected by this, we
now silently ignore the new table while still setting all the values.
Fix#3145
At some point we added an unified `maximized` property to the
client class. Originally it was just setting both horizontal
and vertical maximization. LAter on, this was rewritten to
make the state change more atomic and reversible.
Soon after, we added `immobilized_horizontal` and
`immobilized_vertical` to make most `if` simpler.
`screen.tiled_clients` was missed in that refactoring.
Fix#3169
Signed-off-by: ArenaL5 <arenal5@gmx.com>
Extend `fkeys` to F35
Signed-off-by: ArenaL5 <arenal5@gmx.com>
Reducing `numpad` to its most aggreable subset
Signed-off-by: ArenaL5 <arenal5@gmx.com>
Add method to select a layout directly
using the Super key + the numeric keypad. This method uses the layout list from the currently selected tag in the currently focused screen. (If there is no selected tag, it does nothing.)
To allow this, the keygroups `numpad` and `fkeys` were added to `awful.key.keygroups`.
Refit to avoid error by nil and to remove imperative code, as per recommendation from @Elv13.
Signed-off-by: ArenaL5 <arenal5@gmx.com>
When adding human-readable key names to `lib/awful/hotkeys_popup/widget.lua`, I forgot to add the Enter key in the numeric keypad to the list.
Signed-off-by: ArenaL5 <arenal5@gmx.com>
This allows to control which kind of icon actions can be done
on individual notifications. Once the second part of the permission
system will be merged, this will mostly be used in `ruled.notification`.
Currently, emit_signal always call all connected function. However,
it is very wasteful for some I/O intensive operations like icon
lookup. This commit adds a trick (private API) to stop once
a condition is met.
It will also in the future be used for the permission system, but
this is not yet implementd.
My initial implementation was overly optimistic. It turns out there
is no end in sight to "correctly" support icons. Apps randomly use
XDG name, paths and URLs. Rather than baloon the size of the
implementation, this commit moves toward to request:: pattern
found in other APIs. This will allow people who wish to "fix"
specific icons to do so in a way that scales.
The next 2 commits will move the current implementation to request
handlers.
Most of the notification code is from 2017. Soon after being written,
the permission system started to take shape. This required to
standardize the `request::` signals into the "object, context, args"
style. The notification code wasn't merged during that refactoring
and was accidently merged without the fixes.
Since this is still unreleased, I break the API now before it is too
late. Sorry about this.
Since it is used only one, use require() directly. This allows
to require it from `beautiful` without a circular dependency.
In turn, this allows to set colors using the rules rather than
adding an endless amount of theme variables.
This commit introduce the new "ruled" module. This new top level
module will eventually host all "rules" related modules.
As for the content of the commit, it adds rules for notification. They
are mostly identical to the client rules and can be used to customize
or filter the notifications. It replaces the old "preset" API. The
preset API inner working was mostly a duplication of the early
`awful.rules` API, but was never as flexible. Thus the idea behind this
work is to converge all "core" classes to use a similar declarative API.
When less space is available than was asked, systray:draw() has to
compute the right base size so that all the icons fit into the available
space. This computation so far ignored the icon spacing, resulting in a
too large base size.
Fixes: https://github.com/awesomeWM/awesome/issues/2981
Signed-off-by: Uli Schlachter <psychon@znc.in>
The tag history kept a strong reference to a screen even after that
screen was removed. This prevented the garbage collector from cleaning
up.
Fix this by getting rid of the tag history on screen removal.
Related-to: https://github.com/awesomeWM/awesome/issues/2983#issuecomment-584249568
Signed-off-by: Uli Schlachter <psychon@znc.in>
The function returns the geometry of the parent object. As it was used,
it was passed the parent object directly. The means the parent geometry
of the parent object was used instead of the geometry of the parent
object. This worked "fine" as long as the mouse was in the same screen,
but it was just hiding the bug.
Because it was using a metatable proxy instead of a full copy,
`pairs()` wasn't working and thus any code based on it was
blind to the `args`.
Fixes#2956
The original idea was to decouple the notification and the screens, but
this causes the default `rc.lua` to behave in very unexpected ways.
This commit re-implement the `legacy` logic for the `box` layout.
This caused a behavior change it wasn't clear how to use the
permission API to change the focus mode.
The change will only take effect if the user override the API
level.
Just like clients and other CAPI classes, it is now possible to
connect to all instance signals. There was already a couple of
`request::geometry`, but no way to forward them, so it was
de-facto broken.
The next commit will all class level signals. The current design
is used in widgets, but is a bad fit for wiboxes. They should
behave more like client. In v5, setting methods on `wibox` directly
will be deprecated. `wibox.object` is already supported. I don't
think anyone really do that anyway and isn't documented.
This commit mostly rewrite the client documentation and pay the
technical debt accumulated over the years. Most of the client
documentation was still one-liners from the luadoc era. It now
has all the new tags, type. It also has actual description of
what the properties do beyond the name.
From now on, all core object will have their own rules. `awful.rules`
hardcodes some client specific code. All `rules` module have some form
of class specific code. This code will now be part of a new module
called `ruled`. Since a year or so, a lot of work has been done to
refactor the rules on top of the shared `gears.matcher` class. This way
there wont be as much duplication.
This has to be in its own commit otherwise Travis will fail. This
is because it will keep the file in the build directory when
iterating all commits. Then `ldoc` will fail because the file doesn't
have documentation. If `config.ld` is updated first, then it will
fail because `ruled/init.lua` doesn't exist yet. When it is done
in a separate commit, then `config.ld` is already updated and comes
with `init.lua`.
Another pull request at some point will add proper API levels,
it will then become possible to fix these without breaking
the API for everybody. However right now there is no way around
the problems.
This also pulls in part of the permission framework to ensure
backward compatibility is kept.
`awful.autofocus` was always weird. It is a module part of `awful`,
but it was never part of `awful` `init.lua`. Rather, `rc.lua` was
the sole place it was used. It behave exactly like a request, but
predate them by years. As I cleanup the request:: API before the
permissions API gets formalized, this has to be fixed now.
It isn't deprecated in this commit because it makes too many tests
fail. Another pull request will solve that by adding the "API level"
concept to AwesomeWM so I can change the behavior without breaking
existing configs. With that, the behavior of `autofocus` will be
enabled by default with the permissions to disable it.
This will allow the default client layout list to be manipulated by
modules without the risk of overwriting each other.
The commit also add a new `--{{{ Tag --}}}` section to `rc.lua`. It will
be expanded once the tag rules get merged.
The default `rc.lua` was using the focus/unfocus signals to set
the border color along with `awful.rules`. This logic block was
no longer aligned with the rest of `rc.lua` since it was
the only place where `beautiful` variables where only used by
`rc.lua`.
On top of this, the new request handler also has extra contexts
for the urgent and floating/maximixed use cases. So it can be used
by themes to implement much smarter borders than just focus based
ones. They were previously limited by the fact most of the
(un-monkey-patchable) logic was in `rc.lua`.
Note that this commit also shuffle the awful.rules order between
the titlebar and the border and changes the tests accordignly.
After some consideration, I came to the conclusion the previous
behavior was bogus and the fact that the placement tests required
to know about the titlebar height is simply a proof of that. The
change was required in this commit because since the border is no
longer in the default rules, a new buggy edge case surfaced.
They currently fit the general concept of a `request::` in the sense
that they are not property related and have "request handlers".
The commit also add deprecation for signals.
The reason for this fits within the larger standardization project.
Non-namespaced signals will eventually be renamed. This has started
a long time ago.
What is old is new again. Once upon a time, there was a `startup`
parameter to the `manage` signal. It is now back in the form of
a context.
Finally, this commit removes the `manage` section of `rc.lua`. It no
longer did anything worthy of being in the config. Each of its
important parts have been moved out over the years and the last
remaining bit is always required anyway. The code has been moved
to `client.lua`.
This method aims to provide a centralized, declarative API to focus
clients. Currently, there is tons of code using "request::activate",
including `rc.lua` and have extra boilerplate code around it to
handle some corner case (such as minimization and clients already
having the focus).
This code takes room, is repetitive and force some imperative logic
to be in `rc.lua`.
Commit f025409 avoided negative dimensions but
also stopped allowing width and height to be zero.
For widgets like awful.widget.watch it is reasonable
to allow dimensions to be zero because in many cases when
the margin container is being calculated the watch widget is
still computing and therefore has width and height zero.
Just like 5 years ago, the dependency mess caused by the giant
`awful.client`, `awful.tag` and `awful.placement` requires to
split the code into small files with less dependencies and include
those.
In this case, the goal is to use the `awful.mouse.client` functions
from `awful.client`.
`awful.client` was only used once and the function exists as a
screen method. This will help untangle the dependencies a bit...
To tangle them even more after that...
This is the first commit of a new API to add and remove buttons
and keys from clients. The goal is to get rid of the default `rc.lua`
"hardcoded" list of client buttons and keys to allow modules to modify
the defaults. This is part of the larger effort to make `rc.lua`
modular.
This hass the following tags:
* @interface
* @tparam
* @propbeautiful
* @propemits
* @renamedin
Beside tags, it adds some comments, fix formatting and add
new lines and dots where they belong.
Also add some signals to standardize everything.
This hass the following tags:
* @interface
* @tparam
* @propbeautiful
* @propemits
* @renamedin
Beside tags, it adds some comments, fix formatting and add
new lines and dots where they belong.
Also add some signals to standardize everything.
* Add the ldoc stop marker `.` to each functions, properties and methods definition ;
* Improve a little summaries ;
* Improve properties vs access methods documentation ;
* Change all documented parameters and return values to typed values.
* Add a better descrition for the `imagebox` role in the wiboxes system ;
* Improve image + code render and integration into the descrition ;
* Add a second code exemple to show both coding style (imperative and declarative).
I think the user can now have a better overview of what's a `wibox.widget.imagebox` and how to use it.
Change how wibox are drawn to build a more flexible function reusable in the context of clients.
Add `clients` option to the template. This new option needs an associative table `{ ['label'] = client }` to work. Where label will be a text rendered on the middle of the client area.
Add a new example: `texts/examples/screen/tiled_clients.lua`.
Before this commit, the code directly modified the table where the tag's
properties were saved. This commit changes the code to call
awful.tag.setproperty() instead. This function ensures that
property::screen is now also emitted.
Signed-off-by: Uli Schlachter <psychon@znc.in>
get_children's return value should not be called "The". That was a
mistake because ldoc requires a name for return values and parameters.
If a name isn't provided, it thinks the first word of the description
is the name.
* Add format docs to the constructor.
* Add timezone docs to the property.
* Give the argument to set_refresh a name other than "How".
* Fix bug in constructor argument "format" rendering.
Having the new object layout will be important soon when the
append/remove methods start to get added to the client and the
reborn `awful.keyboard` module.
Another step in moving these APIs toward the common object oriented and
declarative paradigms used by other APIs.
This commit introduces the `awful.keyboard` module. It currenly only
exists as a placeholder for the first few append/remove function, but
will grow in scope in another pull request to expose the currently
private modifier APIs and to provide keybindings collision detection
and replace some of `awful.hotkey_popup` business logic.
The `keygrabber` tests which uses root keybindings are disabled for
now to keep the commit size small. This is necessary since the shims
will need many iterations of changes before this work again with the
new syntax.
It might not be the most pretty of change, but it works. With this
change, it is possible to have multiple "things" in the "same"
section having the "same" name.
This allows for C/C++ style functions with the same name but different
signatures. Lua doesn't handle this well, so it should usually be
avoided. However, constructors might be a valid exception. Most older
widget (and object) constructors have multiple random argument while
newer one use `args`. Deprecating the old ones for the sake of
standardization might be a bit too much for users upgrading from v3.5.
Given the only reason all of those deprecation would happen is because
"its pretty that way", then lets allow 2 constructors and avoid outrage.
The fix focuses on ewmh.merge_maximization function, which handles client intentions to change maximization states.
The fix includes:
1. Fixing the `get_value` helper function to return the proper resulting state that client wanted to change.
For example, when `c.maximized and not c.maximized_horizontal and not c.maximized_vertical` holds,
the client would observe the `MAXIMIZED_VERT` and `MAXIMIZED_HORZ` atoms in X11, but get_value would compute
the result values based on `c.maximized_{horizontal,vertical}`, which are all false. The fix makes the computation
consistent to clients' view.
2. Interpret a client's maximization intentions based on the client's view of how the X11 atoms changes.
This function is not documented to handle userdata, but historically it
would just pass all arguments to gears.surface.load(), which interpreted
userdata as cairo surfaces. After 3295e9f33d, userdata
objects are restricted.
Accept userdata objects again by explicitly passing them to
gears.surface.load().
Fixes: https://github.com/awesomeWM/awesome/issues/2903
Signed-off-by: Uli Schlachter <psychon@znc.in>
The `:keys()` and `:buttons()` APIs moved from get/set single methods
to properties. It works fine if you use the new or old API, but has
limitations when mixing them. `awful.rules` calls properties in a loop
after checking if it is a function. Thus it triggers the secondary
codepath to try to handle this case.
This codepath was tested with gears.objects based components
(ie. widgets). It was not tested with clients and tags, and it
didn't work because they use `awful.tag.getproperty` and
`awful.client.property.get` instead of `._private` like all
newer components. Those old functions are officially deprecated,
but used by tons of configs and modules ported from v3.5 and thus
still the default way to access Lua properties in our implementation.
This commit adds a `_private` to anything that doesn't have one to
at least make the error stop. It will "mostly" work until a more
complete solution is added. Reverting the 2 PRs that changed this
would delay getting more feedbacks.
Having buttons without an awful.util.table.join/gears.table.join
has never been officially documented to be supported. I hope there
isn't too many of those and they wont try to mix the new and old
API syntax, because that will totally break.