It is now possible to add and remove rules. This is superior to how
`awful.rules` originally handled rules because modules can now
assume adding and removing rules works.
The reason for the methods rather than `table.insert` is partially
because future commits will add signals. In turn, this will allow
`gears.matcher` to be extended by module using it using the extra
"introspection" made possible by the signals.
Since commit 3295e9f33d, the imagebox tries to use libRSVG via
lgi.Rsvg to load SVG files without rasterising them immediately.
Instead, they are directly drawn at the expected size.
Signed-off-by: Uli Schlachter <psychon@znc.in>
Add a test which recreates the titlebar for an existing client and
checks that widgets from the old titlebar instance can be GC'd.
Signed-off-by: Sergey Vlasov <sigprof@gmail.com>
Some titlebar widgets (`awful.titlebar.widget.titlewidget`,
`awful.titlebar.widget.button` and other specific button widgets) could
not be garbage collected until the associated client was unmanaged,
because the signal connection used to update the widget was never
destroyed, and the signal handling function was keeping a reference to
the widget in its environment. This resulted in high memory usage when
the titlebar widgets were recreated multiple times for the same client
(this does not happen with the default Awesome configuration, but may be
needed for dynamic titlebar reconfiguration in a custom config).
Modify the code to use weak tables instead of direct signal connections
to avoid keeping strong references to widgets. The widget update
functions still keep strong references to the widget itself (creating a
reference loop, but the Lua GC should handle it correctly) and the
client object, but this should not be a problem.
One publicly visible change is that `awful.titlebar.widget.titlewidget`
now has an `update` function, like the button widgets.
Signed-off-by: Sergey Vlasov <sigprof@gmail.com>
This is needed because if async code is run inside of a tooltip timer func the started property may not still be false.
The current version causes random spurious timer already started errors.
This is configurable globally or per-notification. When it is
replaced over dbus, it has a new timeout and *that* should be the
new timeout (starting when the notification is replaced).
Closes#2821
For dubious reasons, ldoc uses the human readable name for the URLs
instead of the machine readable one. If the name has multiple words,
this causes the URLs to have spaces or %20 in them.
This commits remove all spaces from the "kinds" and then use `:gsub()`
in the template to convert underscores to spaces.
**WARNING** This breaks all URLs again. But this is necessary to prevent
broken links when the user paste them with spaces instead of %20.
Test the behavior of awful.placement.no_overlap when placing clients on
unselected tags. Currently this tests only the most common case with
only a single selected tag and a single tag set for each client.
Signed-off-by: Sergey Vlasov <sigprof@gmail.com>
The awful.placement.no_overlap function always looked at the currently
visible clients when placing a new client. This produced a confusing
result when using awful.rules or the sn_rules argument of awful.spawn to
place the client on an unselected tag (the client was placed as if it
would be placed on a currently selected tag; if multiple clients were
placed on the same unselected tag, in many cases they were placed at the
same position, overlapping each other).
Make awful.placement.no_overlap check tags of the placed client and
handle the case of placement on an unselected tag in a more useful way:
- If the client is sticky or at least one of the client tags is
selected, keep the previous behavior: avoid overlap with all other
floating clients which are currently visible, and use the currently
active layout to determine the floating status.
An explicit check based on `c:tags()` is made instead of using
`c:isvisible()`, so that the previous behavior is kept even if the
client is hidden or minimized for some reason.
- If all client tags are unselected, avoid overlap with all other
floating clients which either are sticky or share at least one tag
with the placed client, and use the layout of the first tag of the
placed client to determine the floating status.
Signed-off-by: Sergey Vlasov <sigprof@gmail.com>
Clients which are sticky should be taken into account by
awful.placement.no_overlap even if they seem to be on a different tag;
add a test to verify this behavior.
Signed-off-by: Sergey Vlasov <sigprof@gmail.com>
Clients which are hidden or minimized should be ignored by
awful.placement.no_overlap; add a test to verify this behavior.
Signed-off-by: Sergey Vlasov <sigprof@gmail.com>
In order to test the behavior of awful.placement.no_overlap with
unselected tags, the test sequence must be able to run multiple times.
Fix the test code to make this possible (currently it just performs the
same sequence 3 times, the code to actually test the behavior with
different tags will be added later).
Indentation is unchanged to make the changes obvious in diff; the next
commit will contain formatting changes without anything else.
Signed-off-by: Sergey Vlasov <sigprof@gmail.com>
A call to cairo_close_path() adds a straight line to the beginning of
the current sub-path. This is used in some of the shapes to, well, close
the shapes.
Sub-paths can be created explicitly via cairo_new_sub_path(), but also
implicitly via cairo_move_to(). When a new sub-path is started, there is
no current point on the path. This means that e.g. cairo_line_to() is in
this start equivalent to cairo_move_to() (= no line is created) and that
cairo_curve_to() first does a cairo_move_to() to the beginning of the
curve. Similarly, cairo_arc() and cairo_arc_negative() first do a
line_to() to the beginning of the arc, and this line_to() can be
implicitly turned into a curve_to().
The problem with the code in gears.shape is that parts of the code
(implicitly) assume that there is not yet any path when the shape
function is called. If this assumption is broken, the call to
close_path() could go to the wrong point, because the path did not start
at the expected position.
Most of the functions in gears.shape already implicitly start a new
sub-path via a call to cairo_move_to(). Those that do not (necessarily)
begin with a call to cairo_move_to() are handled in this commit: They
get an explicit call to cairo_new_sub_path().
This change fixes the issue reported at
https://github.com/awesomeWM/awesome/pull/2804, because the shapes will
no longer be influenced by the pre-existing path. The move_to() that was
left around and caused that issue turns into a degenerate part (it only
has a move_to(), so nothing can be drawn) and is then discarded by
cairo.
Signed-off-by: Uli Schlachter <psychon@znc.in>
Cairo's save/restore methods handle all properties except for the
current path. The path is just left as-is.
A widget's draw method could create some path without consuming it. This
path would then interfere with random things later which did not expect
a path to already exist.
This commits adds calls to cairo_new_path() in the relevant positions to
clean things up.
This not only applies to a widget's draw method, but also
{before,after}_draw_{child,children}. However, these methods could (for
whatever reason) create paths that are to be consumed in one of the
other methods. To keep this working, the path is only cleared after all
of these methods ran.
I do not expect this commit to break anything, because a widget cannot
really assume much about what widget is drawn after it. Especially so,
because partial redraws could mean that some later widget is skipped and
not redrawn.
This should fix the issue reported at
https://github.com/awesomeWM/awesome/pull/2804.
Signed-off-by: Uli Schlachter <psychon@znc.in>
This function checks if a given cairo context has an empty clip. It was
written with the assumption that cairo_clip_extents() produces the x, y,
width, height of the clip extents. However, that function actually
produces x1, y1, x2, y2, where (x1, y1) and (x2, y2) are the corners of
the rectangles.
Due to the way the function is written, it will return non-zero numbers
when there is a translation (cr:translate()). Thus, this function worked
basically never.
Fix this by checking if both points have the same X- or Y-coordinate.
Signed-off-by: Uli Schlachter <psychon@znc.in>
With draw_empty=false, :fit() can return 0,0. Then, when :layout() is
called, it will compute negative widths and heights. This can then cause
lots of problems later on.
Avoid this by having :layout() return nothing instead of producing
negative sizes.
Fixes: https://github.com/awesomeWM/awesome/issues/2799
Signed-off-by: Uli Schlachter <psychon@znc.in>