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.
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>
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.
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.
Now always call both check_widget and make_widget_from_value. This
should make it a lot less confusing when randomly trying to create
a widget as all ways to do it slowly converge toward an unified
one.
There is no better place to put it and need to always be required
for backward compatibility. Given Awesome no longer works properly
without `awful`, I put the code there.
The reason for this is that as more of CAPI is brought in line with the
current API guidelines, it is more and more likely the tests will hit
APIs shims (either to test them or because the prototype remains the
same and only the implementation moved to Lua).
The use case for this will be to detech which screen is connected to
an output from the screen rules.
It is in millimeters because this is what the output provides and in
inches because the DPI is based on that unit and screens are sold with
the size in inches on the box.
Identical viewports are already handled before getting into Lua,
but sometime xrandr gives another viewport that encompass all
others. It has to be removed.
When the screens are created from the viewport in Lua, the signal is
sent too early and the DPI and outputs have not yet been added. This
cause the `connect_for_each_screen` callbacks to be called with a
partially initialized screen object. It also causes the drawables to be
repainted too early.
CAPI now emits "_added" and "awful.screen" takes care of emitting
"added".
With this, there is plenty of palces where the DPI can be set before
those signals are sent. This allows wallpaper with the proper DPI to
work with screens created using `fake_add`. In turn, this will allow
screen rules to control the DPI. In "the past", the DPI used for those
handler was the native DPI of the screen with no opportunity to change
it before hand.
This is easier than messing with the `fake_resize()` method. This will
eventually have an awful.screen.rules equivalent to auto-split the
screen from the rules.
This doesn't mean removing all screens is supported. It isn't and never
will be. The only reason this commit exist is to allow some
initialization and error handling code to be tested.
Add `dpi.lua` to config.ld even if it isn't added yet. This is
because the way the test run has it cached in the build dir. A full
rebuild would take too long and timeout on travis for semi-large PRs.
Technically this doesn't solve any memory leak, but AwesomeWM uses in
average less memory when changing the selected tab in quick succession.
This is because it has less "temporary" tables to track.
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.
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>
This way their name doesn't get mangle by the broken magic. It will also
eventually allow to `error()` in the template when the implicit
`@function` is used.
This commit also fixes a large number of issues found while
proof-reading everything.
ldoc has a magical `@classmod` module type which tries to detect
what is a method and what is a static function. It fails about as
often as it works. This commit makes everything explicit to remove
such issues.
Fixes#2640
Ref #1373
Even thought `awful.key` handles optional "release" parameter well,
parameters are also get used before passing them. In case (only)
optional "data" is provided, it faulty gets called on a release event.
* Add a request to handle the wallpaper when a screen is added or
resized.
* Add a request for screen decorations such as bars or gizmos when
a screen is added.
Both are also sent when a new handler is connected.
Previously, it would use the "real" args passed to the constructor.
It was a bad decision since:
* It doesn't allow the tag/tasklist to add properties internally
* It forces the widget to be created with a constructor rather than
the alternate declarative syntax
* It doesn't allow a tag/tasklist to be part of a widget_template
Technically this is a behavior change, but I doubt anybody will notice
given it is a dark and little documented corner of the API. Chances are
nobody have been using this API for years.
With this helper, it becomes possible to avoid manually setting common
properties such as the client in the tasklist of tag in the taglist when
the children widgets of the template have a set_+property_name.
This decision was taken out of necessity. While adding more style
elements to `awful.widget.common` isn't something I want, there is
little else to do here. The problem is that popup based lists only
have size constraints in one direction. So without a way to limit
the icon size, it will take 9999 pixels.
Instead of having the default template hardcoded as code, this turns the
template into a descriptive version. This makes it easier to come up
with own templates: Just copy the default template and make a slight
change to it.
No functional changes are intended, but I cannot rule out that I did no
mistakes.
Signed-off-by: Uli Schlachter <psychon@znc.in>
There is not much good reason why this should be required and making it
optional is almost trivial, as this patch shows.
Signed-off-by: Uli Schlachter <psychon@znc.in>
The current `awful.widget.layoutlist` is a fork of the so far uncommitted `naughty.widget.actionlist`. It was created because some of the support code for the new `naughty` implementation needed "easier to merge" usage examples. The `layoutlist` was chosen because it was both a low hanging fruit and genuinely useful.
This module is half way between the tooltip and the raw wibox.
It supports the following features:
* Auto resize to its widget size
* Support parent objects and placement
Fix#1683
If the `layouts` are set during initialization, `t.layout` will
return `floating` if `t.layouts` is added before `t.layout`. By
using the raw layout, the fallback doesn't kicks in.
Given noone understand this code, this will prevent some semi likely
regressions from going unnoticed. The main risk is the shims not
producing the exact same results as the real implementation and
cause different code paths to be taken.
As of this commit, both the "real" and "shim" implementation were given
the same set of tests with print() at every step of next_to. The
resulting log was then checksummed to ensure both are identical.
It also add some properties such as `border_width`, `border_color`
and `preferred_alignments`.
It also fix a documentation bug where the `margin_topleft` was called
`margins_topleft`. To conform to the documentation, both are now valid
but one should be removed the next time the API changes.
Fixes#1978
By passing the geometry, important information used by
awful.placement.next_to were "lost". Given `next_to` supports both
widget position, the mouse and client/wibox relative positioning, it
has to know the object type.
Update lib/awful/hotkeys_popup/widget.lua
Update lib/awful/hotkeys_popup/widget.lua
fix(awful: hotkeys_popup): caching issue if showing the same widget instance with and without AwesomeWM hotkeys
doc(awful: hotkeys_popup): extend docstring for args.show_awesome_keys
In the earlier revision of the keygrabber PR, there was a `release_key`
and it was suggested to rename it `stop_key`. However its sibling
`release_event` wasn't, so it is now confusing.
The commit adds a mild deprecation codepath to avoid breaking configs
based on git-master. However it isn't a "long term" deprecation notice
and the code can probably be removed in 5.0 without further delay.
Previously, the layout list was global. However it wasn't covering all
possible use cases and make using `awful.widget.layoutlist` hard since
a layout could be excluded from the `awful.layout.layouts` but still
used for a tag (by setting it explicitly).
Until now there wasn't much documentation available about how to use
these properties. With the new work on `awful.spawn` that rely more and
more on `awful.rules` integration, it is worth fixing.
This commit add a new documentation section and a future commit will
aggregate them to generate an index.
The toggle/show/hide function were incompatible with the current
`rc.lua` is `titlebars_enabled` was removed from the rules because
they were never created. This has always been the case but the
introduction os `request::titlebars` in Awesome 4.0 allows to solve
this longstanding issue. However until now it didn't.
Fix#2419
If the history file (or its parents) can't be created, running a command
will fail entirely. Since saving command history is not an integral part
of running a command, it would be nicer if it carried on, just without
saving history. This is what shells usually do.
This patch removes assertions in the history saving function and
instead adds an early return, so if the history isn't saved the command
invocation simply carries on.
Signed-off-by: Alyssa Ross <hi@alyssa.is>
This commit adds a way to leverage the xproperty and startup_id APIs
to persist an execution token across restarts. It allows to use
`awful.rules` on clients that were executed by a previous Awesome
instance.
The main limitations of these methods is the lack of entropy used to
build the token. If the command is the same in multiple
`awful.spawn.once`, then it will not work as expected. To mitigate this
issue, the system try to concatenate the `awful.rules` table after the
command and hash the resulting string. Given rules are a table, it can
have loops and/or issues with keys ordering. The hash function sort and
limite recursion to prevent a stack overflow. Another issue is the
unreliability of startup notifications.
The awful.placement.no_offscreen function did not work properly when
composed with other placement functions; in particular, the default
configuration (awful.placement.no_overlap+awful.placement.no_offscreen)
was broken. The compose function sets args.pretend=true and puts the
result of the previous placement function into args.override_geometry
before calling the next placement function, but no_offscreen did not use
args.override_geometry, therefore the result of the previous placement
function was discarded.
All other placement functions use `geometry_common(c, args)` to get the
current client geometry; `area_common(c)` should be used only when
getting geometry of other clients.
This change also fixes the problem with margin handling (adding margins
should not affect the window size, only the window position should
change); the test output which was adjusted in commit 0275d3537d
is adjusted again to account for this change.
Signed-off-by: Sergey Vlasov <sigprof@gmail.com>
The awful.placement.no_overlap function was adding the window border
width to the client width and height (this is performed in
area_common(), which is called by geometry_common()), but did not
reverse this operation by calling remove_border() before returning the
final geometry; because of this, using no_overlap resulted in increasing
the window width and height by 2*border_width.
The bug was probably introduced in commit ebcc19844e (before
that commit no_overlap changed the window position directly instead of
relying on the new placement infrastructure), but was not noticed
because of other problems (e.g., in the default configuration the result
of no_overlap was overridden by the buggy no_offscreen).
Signed-off-by: Sergey Vlasov <sigprof@gmail.com>
The current taglist/tasklist allow filter function to remove elements
from the list. However they don't allow sorting or additional entries
to be listed.
This commit introduced such a concept. It will later be used by the
layoutlist where it becomes more relevant since layouts are used created
"objects".
This property is based on Motif WM hints and checks if the client
requests that it is not decorated with a titlebar.
Signed-off-by: Uli Schlachter <psychon@znc.in>
When a tag is specified by name, awful.rules only searched for the tag
on the client's screen. This commit extends the search to all screens,
but only if no specific screen was specified for the new client by some
rule.
Signed-off-by: Uli Schlachter <psychon@znc.in>
The typo was introduced in commit a1941efc9.
Its effect should be minimal: :item_enter() itself does not care about
the 'mouse' option, but it forwards to :exec(). Here, an action is
invoked either if it was not caused by the mouse, or if it was caused by
the mouse and either auto_expand is enabled (which is the default), or
the item-to-be-executed is actually the active item.
In other words, it is quite non-trivial to come up with a case where
this typo made a difference. But of course that's no reason to leave the
typo in.
Fixes: https://github.com/awesomeWM/awesome/issues/2347
Signed-off-by: Uli Schlachter <psychon@znc.in>
The old keygrabber API wasn't doing what the users want from a
keygrabber module. With tons of boilerplate code, everything could
be done, but it wasn't trivial.
This commit add a default grabber function that implements the
keybinding API already used by `awful.key` and `awful.prompt`.
It also add syntax candy left and right to make the module "feel"
like a native CAPI object.
Nothing is perfect and some parts, like adding root keybindings, are not
vevy pleasing. However it fulfill its goal when it comes to make
previously non-trivial use case very easy to implement and deploy.
This code was attached to mouse::enter in `rc.lua` instead of being part
of the unified request::activate architecture.
There is currently no way to detach this focus filter because it is
generally correct.
There is currently no centralized way to manage active keybindings so
the description data case be used to fill part of that role until an
official API is added.
Layouts work with the client's geometry in "space on screen that is
assigned to this client". This means that the geometry should include
decoration (titlebar and borders) and useless gaps.
Everything else (especially the C code) works with client's geometry in
"space that the client can draw on". This means that the titlebar,
borders and the useless gaps are not included into this size.
Thus, when applying size hints, the tile layout has to convert between
these two representations. Otherwise, size hints are applied incorrectly
and to a wrong geometry.
Fixes: https://github.com/awesomeWM/awesome/issues/1418
Signed-off-by: Uli Schlachter <psychon@znc.in>
I do not know how a GDataInputStream / GBufferedInputStream decides
about the size of its internal buffer when reading input by line, but in
issue #2288, an example where the output of date (about 30 bytes) was
read ten times per second caused ten megabytes of memory usage for this
internal buffer. Try to save some memory by explicitly shrinking the
buffer size when we are done reading from the stream.
Reference: https://github.com/awesomeWM/awesome/issues/2288
Signed-off-by: Uli Schlachter <psychon@znc.in>
This change makes errors messages show up in the replies, too.
Before (notice how the third command does not generate output):
$ awesome-client 'return 42' ; awesome-client 'sdfsdf' ; awesome-client 'error("foo")'
double 42
string "[string "sdfsdf"]:1: syntax error near <eof>"
After:
$ awesome-client 'return 42' ; awesome-client 'sdfsdf' ; awesome-client 'error("foo")'
double 42
string "[string "sdfsdf"]:1: syntax error near <eof>"
string "Error during execution: [string "error("foo")"]:1: foo"
Signed-off-by: Uli Schlachter <psychon@znc.in>
For "stuff around screen's 'removed' signal", it might make sense to
temporarily set a tags screen to nil. The idea is that it will only
later be assigned to a new screen, not immediately.
However, currently a tag with screen nil causes quite some problems in
the set_screen() function. This commit works around this with a generous
amount of "wrap this in if".
Signed-off-by: Uli Schlachter <psychon@znc.in>
Before this commit, there was a conflict between the spawn and
awful.rules rules.
Also, modules such as Tryannical monkey-patched this function to
add their own rules to the mix. This commit introduce a proper
API to add handlers.
The order is crutial for this to work, so a dependency system is
also added.
Fix#1482
The code here has things like "if cache.bgb" which suggests that "bgb"
(great name, by the way) is supposed to be optional. However,
31b8623ff6 made this thing definitely not optional by making it
*the* widget that is displayed. That feels wrong.
Also, after the above commit, the ".primary" entry is no longer used,
which is at least surprising for something which is called "primary".
None of this is explicitly documented (I didn't find anything when
looking for "primary" in common.lua nor tasklist.lua; I know that there
are examples for using this, but still that doesn't say how this is
supposed to work), so I'm not quite sure how this was intended to work.
Instead, I am just proposing this commit as a better fix with the above
rational and see what feedback I get...
Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit allow user defined delegates to be used as list elements.
This put an end to the endless attempt to cram more features into this
code.
A widget template (non-instantiated) is passed to the arguments and
is created by the common code. It also supports "roles" where some
user defined widgets can replace the old textbox or imagebox.
The old function didn't scale at all. As no replacements are going
to be merged anytime soon, start to make it meta-extensible.
This is the first step to be able to let the widget be extended
directly from rc.lua without adding yet more silly parameters.
It never scaled and has reached the point of no return a very long
time ago.
My first ever contribution to Awesome was to attempt to fix this,
but the solution was a bad hack. The radical module later solved
this by delegating the style, layout, theme, item layout and item
style to various "visitor" objects. While this is superior to this
commit, it was also a very large and complicated codebase. After
5 years, it is now obvious it will never be merged "whole".
Do it now since the future awful.popup and notification widget
also uses it.
The `load_ldoc.cmake` changes allow to include `.ldoc` blocks in
existing ldoc comments. Previously, it added some extra newlines
and an autogenerated comments saying the content below was imported.
The problem is that this prevented the system to be used for shared
function arguments.
This commit also renames the `wibar` argument table from `arg` to
`args` as the name has to be the same in the `wibox` and `wibar`
constructor for this to work.
As long as Awesome provides APIs that uses pixels are points, this
cannot be enabled by default.
For example, a wibar size defined in pixels may be too small to
render the text once a dense display is connected.
If a tag is specified by name, but no such tags exist, awful.rules would
cause an error (attempt to index a nil value). Fix this and add a test
for this case.
Fixes: https://github.com/awesomeWM/awesome/issues/2087
Signed-off-by: Uli Schlachter <psychon@znc.in>
For example, Xephyr reports its output with a size of 0x0. Since a
division by zero is in no one's interest, just ignore such outputs when
trying to compute the DPI value.
Thanks to @timroes for pointing this out:
c8fac753c4 (commitcomment-25072296)
Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit makes awesome automatically compute the DPI of a screen
based on its RandR outputs. If multiple outputs exist, the lowest DPI is
used.
Signed-off-by: Uli Schlachter <psychon@znc.in>
Once upon a time, beautiful.xresources.get_dpi was added to query
Xft.dpi. That made sense since this queried an xresources property. Over
time, other, non-xresources-based ways to query DPI were added to this
function. Now, it makes no more sense to have this function here.
Also, recently it became possible to add new properties to C objects
from Lua code. Thus, we no longer need to have a get_dpi() function
somewhere, but can add s.dpi directly.
Thus, this commit adds s.dpi and makes everything use it. No functional
changes are intended.
Signed-off-by: Uli Schlachter <psychon@znc.in>
To apply the shape of a client, we have to create an image and draw the
shape we want to it. Since clients can be quite large, we have to make
sure that we do not keep this image alive unnecessarily long.
The code in awful.client.shape.get_transformed() however needs another
temporary surface in case the client has its own shape and another one
was set in Lua (side note: currently the code also creates this extra
temporary surface if the client does not have its own shape; that might
be worth fixing). This temporary surface is then used as the source of a
cairo context to draw it to the image that will be used as the client's
final source.
After we are done, the temporary surface is still kept alive since it is
the current source of the cairo context. The cairo context in turn is
only freed when Lua's garbage collector collects it, which may take
quite a while.
Improve this by setting a different source to the cairo context. Thus,
it now releases the temporary surface as soon as possible and it is only
allocated for a short time.
Fixes: https://github.com/awesomeWM/awesome/issues/2050
Signed-off-by: Uli Schlachter <psychon@znc.in>
The magnifier layout handles the currently focused client specially.
However, if the currently floating client is floating, it should not be
handled by the layout at all. A bug caused the magnifier layout to
handle a focused and floating client anyway if it was the only tiled
client.
Fix this by removing the '#cls > 0'-case. If #cls == 0, then no client
is available to be managed. Thus, cls[1] will be nil, which is fine
since, well, no client is available to be managed. This only made a
difference in the specific bug that I described above. Thus, drop this
case.
Fixes: https://github.com/awesomeWM/awesome/issues/2045
Signed-off-by: Uli Schlachter <psychon@znc.in>