0

I'm trying to toggle all the titlebars when I press some keys. For this I want to iterate over all clients. I tries to do it several ways, including:

for s in screen do
 for c in s.clients do
  awful.titlebar.toggle(c)
 end
end

and

for c in client.get() do
 awful.titlebar.toggle(c)
end

Every time this code it executed I get an error: for iterator 'for iterator' is not callable (a table value).

This makes no sense to me. Can you explain why this happens and how to solve my problem?

I am running Awesome 4.3 with Lua 5.4.3.

Also, if you have an elegant way of toggling the titlebars that also impacts new clients, I'm taking. Thanks.

edit: I'd like to precise that the error occurs even without awful.titlebar.toggle(c) in the for-loops

Dario
  • 37
  • 8

2 Answers2

1

@Piglet answer is correct, but here's the actual "how to fix it":

for index, c in ipairs(client.get()) do
    awful.titlebar.toggle(c)
end

The problem/confusion here is mostly historical. Someone made the screen into a loop iterator because they were thinking it was a cool time saver.

However, it is the only object in the whole API which work that way (and there wont be more). Other object use module_name() as a constructor, not a loop iterator. This is unfixable without breaking the API, so it persist. We cannot break APIs we document because it would break people configs when they upgrade.

Every other table/list in the AwesomeWM API requires either ipairs() or pairs() to iterate. ipairs is for ordered list/tables while pairs is for dictionaries.

  • "because they were thinking it was a cool time saver." Either that or it was back when I was trying to get rid of screen indicies because an index can change when screens are added/removed. :-P Oh and you can always just add `screen.get()` doing nothing (just returning `screen`) (or returning some table with screens) just for symmetry with `client.get()`. – Uli Schlachter Jan 07 '22 at 16:28
0

the loops you're using are generic for loops. they expect a list of expressions after the keyword in. The first one must be an iterator function.

In your code this is missing. Instead there is a non callable table.

From the Lua Reference Manual:

A for statement like

 for var_1, ···, var_n in explist do body end works as follows.

The names var_i declare loop variables local to the loop body. The first of these variables is the control variable.

The loop starts by evaluating explist to produce four values: an iterator function, a state, an initial value for the control variable, and a closing value.

I don't know your variables screen, s.clients and the return value of client.get but as the error is complaining about a table value you probably just forgot to call pairs with that table as argument.

This makes no sense to me.

Because you don't know the very basics of Lua. Read the manual. How can you expect to use something complex as a generic for loop properly without referring to the manual?

Piglet
  • 27,501
  • 3
  • 20
  • 43