We already have a variant of this function for transforming an actual
matrix. This adds the corresponding static factory.
Signed-off-by: Uli Schlachter <psychon@znc.in>
For some reason, the code here tried to handle widget::redraw_needed
signals even though it should apparently/obviously only produce a
current snapshot of the widget's look.
Fix this by just removing the redraw code.
While here, also factor out the widget context table into a local
variable and re-use it for the initial layout and for the later draw.
Signed-off-by: Uli Schlachter <psychon@znc.in>
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>
Previously, gears.object.properties used a weak table for adding
additional information to a C object. However, weak tables can easily
cause leaks when the value references the key.
This commit makes the code instead use the new .data property that is
available on all C objects. This means we have no more magic with a weak
table and instead only use "regular" tables instead.
Signed-off-by: Uli Schlachter <psychon@znc.in>
All other shape did it. While it usually have no side effects,
as seen in #920 screenshot from @actionless, there is instances
where this produce a invalid rectangle.
The requirement to call add_signal() was added to catch typos. However, this
requirement became increasingly annoying with property::<name> signals and e.g.
gears.object allowing arbitrary properties to be changed.
All of this ended up in a single commit because tests/examples fails if I first
let add_signal() emit a deprecation warning.
Signed-off-by: Uli Schlachter <psychon@znc.in>
Similar systems already exist un luaobject, wibox and the declarative
widget system. This close the gap and also bring the property based
syntax to wibox and other gears.object users.
While this need to be enabled explicitly for legacy reasons, it
doesn't break the API.
Once widespread, this implementation will replace the one found
in wibox.widget.base_widget.
The code in gears.wallpaper currently sets a wallpaper in a deferred fashion.
Only a while after it is told to do something does it actually do the wallpaper
change. This is to incorporate many wallpaper changes right after another. These
changes happens during startup where the wallpaper for each screen is set one
after another.
However, since we no longer restart on RandR changes, the screen configuration
could change while we have a pending wallpaper. In this case, part of the
wallpaper could be "chopped off", because the surface that we draw the wallpaper
to is too small.
This commit makes gears.wallpaper track the size of the pending wallpaper and
create a new surface if the already-pending one is too small.
Signed-off-by: Uli Schlachter <psychon@znc.in>
gears modules usually don't depend on Awesome C-API. This code has
been placed there for unclear reasons.
Also, there is ongoing work to unify each "concepts" API into one
single page. Having `gears.screen` go against this effort.
This adds gears.screen which contains a wrapper around
screen.connect_signal("added", func) that also calls the callback function for
each screen that already exists. This is added in gears.screen so that it can
also be used from e.g. wibox, if needed. Feel free to move this elsewhere if
that's a bad idea (I'm not really convinced of it).
Signed-off-by: Uli Schlachter <psychon@znc.in>
Instead of using a special _call field on gears.matrix instances which has to be
copied around suitably, this commit changes the code so that the magic is
restricted to a single function in gears.shape.transform. With some metatable
magic, suitable redirection to everything is added.
Signed-off-by: Uli Schlachter <psychon@znc.in>
Wallpapers are usually big images that use up a lot of memory. This commit makes
gears.wallpaper call :finish() on all involved surface to make them free their
memory.
This is a lot faster than waiting for the garbage collector to collect these
surfaces. Due to the large size of wallpapers, such a special case makes sense
for this code.
Hopefully-helps: https://github.com/awesomeWM/awesome/issues/368
Signed-off-by: Uli Schlachter <psychon@znc.in>
Loading a file normally has the same behaviour as before. First the cache is
checked and if nothing is found, the file is loaded and cached.
This commit changes the behaviour of loading a file uncached. This no longer
removes the file from the cache if it is cached (why should it?) and also does
not put it in the cache.
This means that users of load_uncached and load_uncached_silently can now freely
modify the resulting surface without interfering with other API users.
Signed-off-by: Uli Schlachter <psychon@znc.in>
This library is a wrapper around pcall() / xpcall() that prints an error message
via gears.debug.print_error() in case of errors.
Signed-off-by: Uli Schlachter <psychon@znc.in>
It's unused since commit 0aa4304bda. Before this was a stable sorting
algorithm since table.sort is allowed to be unstable. Apparently we don't need a
stable sorting algorithm anymore.
Signed-off-by: Uli Schlachter <psychon@znc.in>
It is an internal API and is used by `gears.shape`, `gears.pattern`
and `gears.composition` only.
This commit also add `:rotate_at` and `:copy` methods.
This code is imported from Elv13 config and make it very easy
to create shaped objects.
If accepted upstream, other shapes, such as arrow and powerline
will also be added. This commit introsuce the 2 most common
shapes, rounded rectangle and rounded bar.
gears.surface now returns a fallback image surface that is good enough for what
this code tries to do here.
Signed-off-by: Uli Schlachter <psychon@znc.in>
Before this, calling one of the loading functions with a nil argument always
made it return the default 0x0 surface. With this change, the passed-in default
value is now properly applied.
Signed-off-by: Uli Schlachter <psychon@znc.in>
Oh hey, Pango exports an API that allows to query for named colors based on the
famous rgb.txt! Let's use that!
Signed-off-by: Uli Schlachter <psychon@znc.in>
This adds support to gears.color.parse_color to parse things like "#fff" (one
character per color component, without alpha) and "#ffff0000ffff0000" (four
characters per component, with alpha).
This makes sense on its own, but should also help with
https://github.com/awesomeWM/awesome/issues/585.
Signed-off-by: Uli Schlachter <psychon@znc.in>
Previously, a Lua error was thrown when loading a file failed. Most callers are
not prepared for this and the result is less than optimal.
This commit makes the functions print the errors and return nil instead. For
callers that want to handle errors themselves, "_silent" variants of the
functions are introduced which just return errors to the caller.
Signed-off-by: Uli Schlachter <psychon@znc.in>
Lua will remove objects as values from a weak table before these objects are
finalized, but as values only in the next garbage collection cycle after the
object was finalized. Up to now, gears.object uses a table with weak keys so
that :disconnect_signal() works. This means that a signal can still call methods
which were already considered garbage by the garbage collector and thus can use
userdata from the C side which was already finalized. Crashes and other bugs
result.
This commit changes the code so that the function is also a value in the weak
table. Thus, the GC will remove the entry before the object is finalized.
Special magic is needed for Lua 5.1, because there only userdata has the
behavior that we want while we have a function. We do some magic with function
environments to make this work...
Closes https://github.com/awesomeWM/awesome/pull/567.
Signed-off-by: Uli Schlachter <psychon@znc.in>
Usually users want a wallpaper on all their screens. With the current code, this
resulted in a loop of upload-wallpaper, {download-wallpaper, add-new-part,
upload-wallpaper}*.
Fix this by being more intelligent: Instead of setting the wallpaper
immediately, this now uses gears.timer.delayed_call() to set the wallpaper. All
following modifications which come in before the delayed call runs will still be
part of the current update. This should mean that during startup, there is just
a single upload of a wallpaper.
(The above is what happens if there is no wallpaper yet. If there is already
one, we use :create_similar() and thus should only upload the part of the
wallpaper that changed, but this doesn't really make a difference.)
As a side-effect, the new code no longer draws to the old wallpaper to modify
it, but always creates a copy of it. This means that:
Fixes https://github.com/awesomeWM/awesome/issues/288.
Closes https://github.com/awesomeWM/awesome/pull/530.
Signed-off-by: Uli Schlachter <psychon@znc.in>
This makes the timer emit signals for when it is started and stopped. This does
not add a signal for :again(), because that function just calls the other two
functions and thus already emits start and stop.
Signed-off-by: Uli Schlachter <psychon@znc.in>
This has some positive results on the "benchmark test". Each single number is
the best one out of three runs.
Before:
create wibox: 0.0826502 sec/iter ( 13 iters, 1.157 sec for benchmark)
update textclock: 0.0186952 sec/iter ( 57 iters, 2.473 sec for benchmark)
relayout textclock: 0.0158112 sec/iter ( 64 iters, 1.028 sec for benchmark)
redraw textclock: 0.0015197 sec/iter (662 iters, 1.861 sec for benchmark)
After:
create wibox: 0.0825672 sec/iter ( 13 iters, 1.154 sec for benchmark)
update textclock: 0.00378412 sec/iter (277 iters, 4.216 sec for benchmark)
relayout textclock: 0.00259056 sec/iter (420 iters, 1.09 sec for benchmark)
redraw textclock: 0.00105128 sec/iter (958 iters, 1.79 sec for benchmark)
We see no significant change in the creation of wiboxes (99.9% compared to
before). Update (20% of the previous run time), relayout (16%) and redraw (69%)
are all sped up by this change.
Signed-off-by: Uli Schlachter <psychon@znc.in>
Instead of going through LGI to call cairo, this now implements the various
matrix operations directly in Lua. The plan is to avoid the overhead that we hit
due to LGI.
Signed-off-by: Uli Schlachter <psychon@znc.in>
With the second argument being 2, the traceback will not include the error
handling function, but instead end at the actual place of the error.
Signed-off-by: Uli Schlachter <psychon@znc.in>
This adds gears.timer.start(timeout, callback) that creates a timer object and
connects a callback to it, all in one go.
Additionally, this adds gears.timer.weak_start(timeout, callback). The weak
version still allows the callback function to be garbage collected and will then
stop the timer.
This was tested with the following code:
require("gears.timer").start(0.3, function()
print("ping")
if collectgarbage("step", 500) then
print("collection done")
error("err")
end
return true end)
require("gears.timer").weak_start(0.1, function()
io.stdout:write(".")
return true
end)
After a full collection cycle, both timers are stopped. The first one is stopped
because of the error() that it generated. The second one is stopped because the
callback function was garbage collected.
Ref: https://github.com/awesomeWM/awesome/issues/216
Signed-off-by: Uli Schlachter <psychon@znc.in>
Connecting to a signal weakly has the same effect as connecting to it strongly,
but it allows the garbage collector to disconnect the signal in case nothing
else references this function.
Signed-off-by: Uli Schlachter <psychon@znc.in>
The whole point of this pcall() is that we do not have unprotected Lua errors,
because those kill awesome. So instead of assert()ing, let's just print a
message.
Signed-off-by: Uli Schlachter <psychon@znc.in>
This uses busted (http://olivinelabs.com/busted/) to implement unit testing.
This is wired up to "make check" and/or "make test".
This commit also adds tests for the more complicated parts of the gears and
wibox.layout libraries.
Signed-off-by: Uli Schlachter <psychon@znc.in>
maximized() used to align the image with (0,0) so that it is shifted to the right or bottom. Most wallpapers are designed from the center, so this behavior is not desired usually. With this commit the wallpaper is centered when no offset is set. To get the old behavior use {x=0, y=0} for the offset parameter.
It doesn't make sense for surface.load_uncached() to load a file without
inserting into the cache. The next "cached" load will have to load it again.
So move cache insertion into surface.load_uncached() and the only thing that
surface.load() does differently is checking if we have a suitable cache entry
before calling load_uncached().
So load_uncached() does the cache insertion and load() reads from the cache.
Signed-off-by: Uli Schlachter <psychon@znc.in>
This makes gears.color() cache patterns in a weak table and returns that cached
pattern when we get called with the same argument again.
To benchmark this change, the following code was used:
local time = require("socket").gettime
function benchmark(func)
local begin = time()
local iter = 0
while time() - begin < 1 do
func()
iter = iter + 1
end
return iter
end
for _, arg in pairs({
"#00aa00",
"solid:#00aa00",
"radial:50,50,10:55,55,30:0,#ff0000:0.5,#00ff00:1,#0000ff",
"linear:1,2:3,4:0,#000000:1,#ffffff",
"png:/home/psychon/Wallpaper/Bars.png",
{ type = "solid", color = "#00aa00" },
{ type = "radial", from = { 50, 50, 10 }, to = { 55, 55, 30 }, stops = { { 0, "#ff0000" }, { 0.5, "#00ff00" }, { 1, "#0000ff" } } },
{ type = "linear", from = { 1, 2 }, to = { 3, 4 }, stops = { { 0, "#000000" }, { 1, "#ffffff" } } },
{ type = "png", file = "/home/psychon/Wallpaper/Bars.png" },
}) do
collectgarbage("collect")
print(benchmark(function() gears.color.create_pattern(arg) end), arg)
end
Before this change (larger numbers are better, this measures how many times we
can create the given pattern per second):
29525 #00aa00
29344 solid:#00aa00
3446 radial:50,50,10:55,55,30:0,#ff0000:0.5,#00ff00:1,#0000ff
4845 linear:1,2:3,4:0,#000000:1,#ffffff
32855 png:/home/psychon/Wallpaper/Bars.png
29883 table: 0x1bb67e0
3868 table: 0x1bb6830
5339 table: 0x1bb6c60
32772 table: 0x1bb6fe0
After this change:
126188 #00aa00
125962 solid:#00aa00
125125 radial:50,50,10:55,55,30:0,#ff0000:0.5,#00ff00:1,#0000ff
125213 linear:1,2:3,4:0,#000000:1,#ffffff
113659 png:/home/psychon/Wallpaper/Bars.png
125586 table: 0x1232680
125249 table: 0x12326d0
125468 table: 0x1232b00
113711 table: 0x1232e80
As you see, this makes some cases about 35 times faster (although I have to
admit that something like this can be expected from such a synthetic benchmark).
Signed-off-by: Uli Schlachter <psychon@znc.in>
Instead of loading files from disk every time we need them, add a cache to
gears.surface as a weak table that maps strings to cairo surfaces.
If this cache should be avoided, there is a new gears.surface.load_uncached()
function which works just like gears.surface.load() worked before.
Signed-off-by: Uli Schlachter <psychon@znc.in>
Before commit 1b2826 in lgi, the get_rgba() function on cairo SolidPatterns was
specified like this:
get_rgba = { ret = cairo.Status,
{ ti.double, dir = 'out' },
{ ti.double, dir = 'out' },
{ ti.double, dir = 'out' } },
The above commit fixed this (without saying so) and the code became:
get_rgba = { ret = cairo.Status,
{ ti.double, dir = 'out' },
{ ti.double, dir = 'out' },
{ ti.double, dir = 'out' },
{ ti.double, dir = 'out' } },
The prototype for the corresponding cairo function is:
cairo_public cairo_status_t
cairo_pattern_get_rgba (cairo_pattern_t *pattern,
double *red, double *green,
double *blue, double *alpha);
As you see, this functions gets four double* as arguments and it will save its
result via those pointers. Old versions of lgi call this function with too few
arguments and this will cause a segmentation fault when cairo dereferences an
invalid pointer.
Signed-off-by: Uli Schlachter <psychon@znc.in>
If a drawable has an opaque background, we don't need pseudo transparency and
thus its content don't change when it is moved. However, when we need pseudo
transparency, then we have to redraw the drawable to apply the new background.
Previously we just always did the redraw. This commit adds a helper function
gears.color.create_opaque_pattern() that analyzes a cairo pattern for
transparency. We use this new function to only redraw-on-move when there is
actual pseudo transparency in effect. Otherwise, this redraw can be skipped.
Signed-off-by: Uli Schlachter <psychon@znc.in>
When no wallpaper exists yet, instead of creating a black image surface which
covers all the screens, just create a surface for the screen which we need. This
means that way less pixels have to be uploaded to the X11 server, which should
be faster.
Signed-off-by: Uli Schlachter <psychon@znc.in>