* 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
Issues involve:
- :layout() had the wrong signature and expected a cr argument that was left
from when this was still the :draw() function.
- horizontal and vertical reflection were mixed up (I guess it has always been
this way?)
- The return value should be a table of widget placements. Instead it was just a
single widget placement.
This is broken since commit 85ab3f045b.
Fixes: https://github.com/awesomeWM/awesome/issues/718
Signed-off-by: Uli Schlachter <psychon@znc.in>
There seem to be a little race condition (either in my layout code or
elsewhere) when playing with multiple screens. As most properties do
not depend on the tag, there is no point in returning early anyway.
Instead of true/false `merge` can be a callback now, which allows for
more dynamic handling of the client not being visible, e.g. moving it to
the current tag, instead of merging.
It was missing apps/entries from /usr/share/applications/kde4.
This patch also makes sure that entries are unique (by Exec/Name).
Closes https://github.com/awesomeWM/awesome/pull/711.
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 makes awful.tooltip create its tooltip lazily when it is first needed
instead of immediately when the tooltip is created.
Fixes: https://github.com/awesomeWM/awesome/issues/591
Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit makes these methods invoke the method on a widget in a protected
context. Thanks to this, e.g. the wibox and other widgets are protected from
errors in a child widget.
Additionally, fit_widget() now assumes 0 if a widget's :fit() method didn't
provide a number.
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>
I just spent too much time tracking down a bug that happened while drawing a
widget. This is the reason why we should apply sanity checks while widgets are
constructed, so that we get a useful backtrace.
Signed-off-by: Uli Schlachter <psychon@znc.in>
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>
Because all our Lua code can now work with screen objects, most of the uses of
s.index that the previous patches added for reaching this goal can be removed
again.
Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit makes the code in awful.client work with screen objects where
possible (which is not possible in awful.client.movetoscreen() because it uses
screen_idx + 1).
Signed-off-by: Uli Schlachter <psychon@znc.in>
This commits makes a random selection of modules in awful support screen objects
and accept them as parameters everywhere where a screen index is accepted.
Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit documents that a textbox already accepts a screen object where a
screen index is expected. Also, this changes the widget API in that a widget's
context.screen is now a screen object instead of a screen index.
Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit makes awful.ewmh re-apply the maximized geometry to any maximized
clients when the workarea of a screen changes. This happens e.g. when a wibox
that is docked to the edge of the screen is hidden.
Fixes: https://github.com/awesomeWM/awesome/issues/705
Signed-off-by: Uli Schlachter <psychon@znc.in>
This avoids having to mock half the C API just because all of awful is loaded
needlessly in this unit test and is generally a good idea.
Signed-off-by: Uli Schlachter <psychon@znc.in>
Since commit b2aaefd095, we correctly handle window gravities when
the border width of a client changes. Since most windows out there have a
NorthWest gravity, this means that most windows do not have this problem.
However, e.g. mplayer uses gravity "Static" and this causes this issue (any
gravity other than NorthWest will do).
This affects the fullscreen handling in awful.ewmh. The code has to set the
border width before it changes a client's geometry so that the move when the
border width changes doesn't matter.
No new integration test for this since I didn't find anything usable with a
non-NorthWest gravity. A test would be easy to write, just test if `c.fullscreen
= true ; c.fullscreen = false` restores the previous window geometry.
Fixes: https://github.com/awesomeWM/awesome/issues/697
Signed-off-by: Uli Schlachter <psychon@znc.in>
awful.layout.suit.corner does awful.tag.getmfpol(t), but doesn't actually have a
variable t in scope. I just copied the needed stuff from the tile layout.
Signed-off-by: Uli Schlachter <psychon@znc.in>
No idea what the correct value for this argument is supposed to be, but since
there is no variable "m" in scope, this always uses nil as the value.
Signed-off-by: Uli Schlachter <psychon@znc.in>
There is no "s" variable. This code wants "screen" instead. The effect of this
typo was that with multiple taglists, only the one that was created last got
updated.
Signed-off-by: Uli Schlachter <psychon@znc.in>
This module is partly broken since 2009 (the way to use it that is mentioned in
the docs doesn't actually work) because the mousefinder object doesn't have a
find()-method (the line doing "self.find = find" should do "self.finder =
finder.find"). Since no one really noticed, this module is apparently not used
much.
When someone wants to still use this, they are free to copy this to their own
config. It's not much code, but it's enough code that I am annoyed that we ship
something broken to users. Everyone who copies it to their own config will make
sure it works the way they want.
Signed-off-by: Uli Schlachter <psychon@znc.in>
This layout allow each widgets to take 'r' percent of the total
space, where 'r' is configurable.
It re-implement the 'wfact' system used by `awful.layout.suit.tile`
This layout display the widgets on top of each other. It can also optionally
display only the first one.
The most common use case is to create a composited widget. Other use case
include the creation of a "paged" stack to only display the most
relevant widget without adding extra complexity to the parent layout.
This new syntax is inspired by the Awesome widget 3.2-3.4 API. It
allow cleaner widgets declaration. The produced code is usually much
shorted and easier to read than wibox.widget imperative syntax.
There is already a hack into `awful.widget.common`. This system aim
to make the hack obselete while preserving the useful part.
I think this is also necessary to properly support SVG (with DPI
and resize).
Finally, Qt handle this using the QBrush concept, where you can have
programmatic patterns. Cairo doesn't have this concept, so there is no
"clean" way to have programmatic brushes.
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>
Any awful.titlebar.widget.button widget (e.g. floatingbutton or closebutton)
decides on the currently visible symbol based on several factors. One of them is
"is the client currently focused?" and thus the button has to be updated when
the client is focused/unfocused.
The way the code did this was to use client.connect_signal("focus", f) and
client.connect_signal("unfocus", f). However, these signals are never
disconnected and kept alive forever. The callback function had a strong
reference to the client (as an upvalue) and thus this also prevented the client
from being garbage collected.
Fix this by using c:connect_signal("focus/unfocis", f) instead. These kind of
signals are only kept alive by the client object and don't prevent it from being
garbage collected.
This fixes the new test that the previous commit added.
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
Go around a limitation of the lua language spec. The return value
of this method guaranteed `ipairs()` correctness.
Please note that both the official Lua and Luajit implementation
provide a sparse table compatible `ipairs()` and __len implementation
by default.
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.
It is necessary to have it beforehand when creating layout objects
for unselected layouts.
In the current layout system, there is no layout object, but to allow
tabs and dynamic tagging features like ion3, layouts cannot be stateless.
Before, it was the caller job to make sure the client wasn't floating.
This limitation is unecessary. awful.client.idx now return nil instead
of an error. awful.rules setting the master width factor are now
foolproof.
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.
This allow the most basic kind of stateful layouts to be created.
It is now possible to have layout instances instead of global
stateless layout arrange functions.
This allow layout "arrange" to be called less often and react on
the cause of the change itself rather than it's consequences
(usually, the "focus" signal).
Previously, the layout were re-arranged everytime the focus changed.
Now, with "raised" and "lowered", it require less "arrange".
"swapped" allow smarted layouts. Currently, swapped cause a full
re-arrange. It re-read the "index" list from scratch and create
a "new" layout. With "swapped", incremental layout changes are
possible.
Fixes https://github.com/awesomeWM/awesome/issues/616
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>
A nil-value is no longer simply passed through, so this has to do some "special
things" to work properly.
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>
Instead of throwing a Lua error, the code now just prints an error message to
stderr on invalid markup. For callers which want to handle this case specially,
we add :set_markup_silently() which returns error messages.
Fixes: https://github.com/awesomeWM/awesome/issues/546
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>
*WARNING* This introduce a minor API break as awful.tag.setscreen
arguments are now swapped for consistency
This allow to introduce logic for each properties and improve
awful.tag.add and execute logic when setting properties.
The code here doesn't always work, so it's best to just don't mess with
awesome.version, but return it directly.
Fixes: https://github.com/awesomeWM/awesome/issues/569
Signed-off-by: Uli Schlachter <psychon@znc.in>
Since some commits, surface.load_uncached() handles errors itself and thus we
don't have to print an error message here any more.
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>
Having many arguments can easily get confusing and hard to understand. This
commit uses a table instead so that we have names that identify what each
callback does.
Signed-off-by: Uli Schlachter <psychon@znc.in>
This adds functions for getting directories according to the XDG base dir
specification. This might be useful in general.
This also adds a function for getting the cache dir, because I like an explicit
function call more than something which "switches" based on a string argument.
Better error messages if you mis-type something. :-)
Finally, this adds a function for getting the directory containing the rc.lua
file. Sadly, awful.util.getdir("config") did not actually do that. See #218.
Fixes: https://github.com/awesomeWM/awesome/issues/218
Signed-off-by: Uli Schlachter <psychon@znc.in>
Without this fix `wibox.widget.textbox` ignores current theme font
setting and resets it to the initial one.
It becomes handy when the initial theme is tweaked during runtime, ie.
in `rc.lua`. Other AwesomeWM components like `awful` (taglist,
tasklist, menu) are aware and do respect the actual theme settings.
Closes https://github.com/awesomeWM/awesome/pull/89.
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>
This adds new functions to all widgets that allow to force a specific
width/height. These values override the result from :fit().
Signed-off-by: Uli Schlachter <psychon@znc.in>
When emitting layout_changed, the widget is relayouted. If this doesn't actually
change anything, nothing will be redrawn. Thus, this also emits redraw_needed to
force redraws.
This fixes a race condition with some weird tray icons. A new tray icon is
created and the systray is updated. Then this new icon is destroyed immediately
again and at the same time another icon is created. Then, the systray isn't
updated since the number of icons (=the layout) did not actually change.
However, it needs to be updated and so we ended up with broken/missing icons.
Fixes: https://github.com/awesomeWM/awesome/issues/487
Signed-off-by: Uli Schlachter <psychon@znc.in>
This adds support for the callback that was added in the previous commit to this
function. We can just pass on the function that the caller gives us.
Fixes: https://github.com/awesomeWM/awesome/issues/185
Signed-off-by: Uli Schlachter <psychon@znc.in>
This allows scrolling a widget if there is too few space available. There are
several different modes available for how the scrolling "looks like".
Signed-off-by: Uli Schlachter <psychon@znc.in>
This is a weak table whose entries might be removed by the garbage collector.
I'm not sure if this will every cause problems, but it's better to be prepared
for tables having "nil holes" (which would mean ipairs ignores some entries).
Signed-off-by: Uli Schlachter <psychon@znc.in>
The code already tried to handle this correctly, but at some point it used the
wrong variable as the screen number...
Signed-off-by: Uli Schlachter <psychon@znc.in>
Example:
awful.prompt.run({ prompt = "Run: ", hooks = {
{{ },"Return",function(command)
local result = awful.util.spawn(command)
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Mod1" },"Return",function(command)
local result = awful.util.spawn(command,{sticky=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Shift" },"Return",function(command)
local result = awful.util.spawn(command,{ontop=true,floating=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end}
}
},...)
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>
Thanks to the way that X11 works, geometries consider the size of the client
without the border width, but the position of the top-left corner of the border.
This commit adds a new function get_area() which returns the area that is
actually covered by a client. Then, all the code is changed to use this new
function (even the part of the code which did get this border thing correct).
Closes https://github.com/awesomeWM/awesome/pull/541.
Signed-off-by: Uli Schlachter <psychon@znc.in>
None of this code wants to resize clients. Thus, it makes sense to only set the
position of a client and ignore its size.
Also, this sneaks in a fix for no_offscreen which is documented to return the
client's new position, but didn't actually do so.
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 changes the code in naughty so that it first decides on a width for the
notification and then uses the new function :get_height_for_width() to find a
suitable height.
This makes a difference in the following example where before this change the
text is cut off and afterwards it is shown completely:
naughty.notify({
text = string.rep("abcdefghijklmnopqrstuvwxyz\n", 4),
width = 75
})
Signed-off-by: Uli Schlachter <psychon@znc.in>
This adds :get_preferred_size() and :get_preferred_size_at_dpi() which return
the size (=width, height) that the textbox would need if unlimited space is
available.
This also adds :get_height_for_width() and :get_height_for_width_at_dpi() which
return the height that the textbox would need if the given width is available.
Signed-off-by: Uli Schlachter <psychon@znc.in>