The Awesome window manager is a great scriptable tiling window manager. It uses Lua as its scripting language.
Sometimes you might want to control awesome from scripts or other external
processes. Thankfully it provides a handy utility for this: awesome-client
.
awesome-client
reads a chunk of Lua code from stdin, and sends it to awesome.
The code will be executed by awesome within the main awesome process. It then
sends the result of the code back to awesome-client, which will return the
result (if any).
Try it out for yourself. Run awesome-client
with no arguments, and you should get an
interactive prompt like this:
awesome#
It's waiting for some code. Enter the following Lua snikket: return client.get()[1].name
This means "return the name (title) of the first client (window)". You should see something like the following:
awesome# return client.get()[1].name
string "about - awesome window manager — Mozilla Firefox"
If you wanted to do this from a script, you can pass the Lua code on the command-line:
awesome-client 'return client.get()[1].name'
Alternatively, you can feed it via stdin:
echo 'return client.get()[1].name' | awesome-client
Sometimes you might have quite complex Lua code that you want to execute via awesome-client. Instead of feeding it to awesome-client at runtime, you can create a reusable function in rc.lua, like:
function set_wibar_colors(fg, bg)
for s in screen do
if s.mywibox do
s.mywibox.fg, s.mywibox.bg = fg, bg
end
end
end
function enable_dark_mode()
set_wibar_colors("white", "black")
end
function enable_light_mode()
set_wibar_colors("black", "white")
end
Now, to switch modes, you can simply run from an external script (or cron, or whatever):
awesome-client 'enable_dark_mode()'
There are a few things that people stumble upon when using awesome-client.
People often add print()
calls into their code, and then wonder why they
don't see anything.
As explained earlier, the code you write is executed by awesome, not by
awesome-client. That means you are telling awesome to call print() instead.
The output of awesome typically goes to ~/.xsession-errors
. Take a look!
If you want to send something back to awesome-client, you must return it.
You are able to return multiple values (e.g. return "one", "two", "three"
).
In Lua, local variables only exist within the block that declares them, and the blocks within those blocks. This is known as "lexical scoping".
Because you send a block of Lua code at a time to awesome, any local variables will only exist while your code is executing. After that, they will be gone. See the following:
awesome# local foo = "bar"
awesome# return foo
You will see nothing is returned. Drop the 'local' keyword and use a global variable, and you'll see the variable still exists in the next command block:
awesome# foo = "bar"
awesome# return foo
string "bar"
So use local variables for temporary variables, and use global variables if you need to store data, including data that you want to share with other things in your rc.lua.
By the way, this applies equally to variables defined in rc.lua. If you define
variables using local
in rc.lua, they won't be readable from code executed by
awesome-client, because this is a separate block of code to rc.lua.
Be wary of escaping things correctly when feeding Lua code to awesome-client.
For example, the following code:
echo "foo = "bar"" | awesome-client
...will actually send the code foo = bar
to awesome (which has quite a different
meaning from foo = "bar"
).