Toki Talks - I abandoned AwesomeWM…

2025/08/26

Introduction

Welcome to this week’s installment of Toki Talks! I know that my video last week was supposed to cement/solidify that I am all about stability and simplicity instead of experimentation. With that being said, I left AwesomeWM.

Why I left AwesomeWM…

To be quite honest, Awesome is much more than “just a window manager”. It’s a way of life. I mean this in the sense that the whole window manager feels less like a window manager and more like a customization framework. That’s cool and all, but it’s done in Lua, and the way that it’s implemented is probably really nice if you LIKE writing in Lua, and REALLY want to have total control over your environment. I used Awesome as a better OOTB DWM experience, and I can safely say that it does a good job of doing that.

Going back to Lua, I am indifferent to it, but holy hell the syntax/formatting is ugly as all hell. Especially in the default rc.lua, which is the first taste of Lua you get when first using this window manager. I’ll say it right now, I can see Awesome turning away a lot of people who want to experiment with it. This I believe isn’t for most people though. I am not one of those people.

Let’s look at how Awesome defines tag-switching:

for i = 1, 9 do
    globalkeys = gears.table.join(globalkeys,
        -- View tag only.
        awful.key({ modkey }, "#" .. i + 9,
                  function ()
                        local screen = awful.screen.focused()
                        local tag = screen.tags[i]
                        if tag then
                           tag:view_only()
                        end
                  end,
                  {description = "view tag #"..i, group = "tag"}),
        -- Toggle tag display.
        awful.key({ modkey, "Control" }, "#" .. i + 9,
                  function ()
                      local screen = awful.screen.focused()
                      local tag = screen.tags[i]
                      if tag then
                         awful.tag.viewtoggle(tag)
                      end
                  end,
                  {description = "toggle tag #" .. i, group = "tag"}),
        -- Move client to tag.
        awful.key({ modkey, "Shift" }, "#" .. i + 9,
                  function ()
                      if client.focus then
                          local tag = client.focus.screen.tags[i]
                          if tag then
                              client.focus:move_to_tag(tag)
                          end
                     end
                  end,
                  {description = "move focused client to tag #"..i, group = "tag"}),
        -- Toggle tag on focused client.
        awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9,
                  function ()
                      if client.focus then
                          local tag = client.focus.screen.tags[i]
                          if tag then
                              client.focus:toggle_tag(tag)
                          end
                      end
                  end,
                  {description = "toggle focused client on tag #" .. i, group = "tag"})
    )
end

Let’s look at how defining keymaps looks like too.

lientkeys = gears.table.join(
    awful.key({ modkey,           }, "f",
        function (c)
            c.fullscreen = not c.fullscreen
            c:raise()
        end,
        {description = "toggle fullscreen", group = "client"}),
    awful.key({ modkey, "Shift"   }, "c",      function (c) c:kill()                         end,
              {description = "close", group = "client"}),
    awful.key({ modkey, "Control" }, "space",  awful.client.floating.toggle                     ,
              {description = "toggle floating", group = "client"}),
    awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end,
              {description = "move to master", group = "client"}),
    awful.key({ modkey,           }, "o",      function (c) c:move_to_screen()               end,
              {description = "move to screen", group = "client"}),
    awful.key({ modkey,           }, "t",      function (c) c.ontop = not c.ontop            end,
              {description = "toggle keep on top", group = "client"}),
    awful.key({ modkey,           }, "n",
        function (c)
            -- The client currently has the input focus, so it cannot be
            -- minimized, since minimized clients can't have the focus.
            c.minimized = true
        end ,
        {description = "minimize", group = "client"}),
    ...

This is ugly as hell. I hate the empty space, I hate the indentation, I hate when programmers try to format their code to make it more “readable” and to follow a consistent structure. It just makes it look worse to me. It’s weird obfuscation that makes it harder to read this. Just to be clear. I can read this. I understand what this is doing. It’s just a lot of visual clutter that I don’t want to deal with when either reading or writing code, especially something as important as the window manager I use.

During some other time of me using Awesome, I did take the time to reformat EVERY SINGLE awful.key() mapping. The syntax just feels and looks abysmal, even with treesitter. I know that this is all personal preference, but due to the fact that Lua only has ONE data structure (a table) makes Lua both very flexible, but also a pain in the ass. This is coming from someone pretty normie-pilled and uses tabstop=2 instead of tabstop=4. I think the point of all of this is this: I don’t want to have to configure my window manager or workflow all that often. BUT I still want to be able to quickly hack away at it and add what I would like to it WHEN I want to without having to go through the headache of both reading a large amount of Lua, and figuring what the hell is going on with that said Lua.

Resistance is futile, so I’m back on Qtile.

Qtile is configured in Python, which makes some believe that it’s a slow window manager. I will say with 100% confidence that I have NEVER had a slow-down due to the performance on Python. It’s not even fully written in Python either. It’s still written in C, just like almost every other WM, but has its configuration language set to Python. It is written in C, but has Python bindings. Let’s look at the Qtile equivalents for the two examples above.

for i in groups:
    keys.extend(
        [
            Key(
                [mod],
                i.name,
                lazy.group[i.name].toscreen(),
                desc=f"Switch to group {i.name}",
            ),
            Key(
                [mod, "shift"],
                i.name,
                lazy.window.togroup(i.name, switch_group=True),
                desc=f"Switch to & move focused window to group {i.name}",
            ),
        ]
    )

Alright, already more clean to read. How about defining keymaps?

keys = [
    Key([mod], "h", lazy.layout.left(), desc="Move focus to left"),
    Key([mod], "l", lazy.layout.right(), desc="Move focus to right"),
    Key([mod], "j", lazy.layout.down(), desc="Move focus down"),
    Key([mod], "k", lazy.layout.up(), desc="Move focus up"),
    Key([mod], "space", lazy.layout.next(), desc="Move window focus to other window"),
]

That’s it. It’s just one array. It’s not overly complicated, and it doesn’t by default expose multiple libraries to the end-user that they most likely won’t end up using. I had my hiccoughs with Qtile in the past, but going back to something that’s so easy and just works feels really nice. You can literally just hack together whatever script you want into the bar and it works flawlessly.

                widget.GenPollText(
                    name='minutesleft',
                    update_interval=60,
                    fmt='(Only {} minutes left!)',
                    func=lambda: subprocess.check_output(
                        os.path.expanduser('~/code/builds/goltime/bin/goltime')
                        ).decode('utf-8').strip(),
                    ),

I was able to bring back this part of my bar without having to spend an entire day figuring out how to make a widget in Awesome.

What this all boils down to

I think at the end of the day. This all boils down to both preference and skill issues. I am not a good programmer by any stretch of the imagination, and I have certain criteria that have to be met in my head in order for things to function. I just didn’t end up liking Awesome that much, and since I see myself moving to Wayland in the future, it would be nice to have a window manager that works on BOTH x11 and wayland. That’s the kind of compatibility that I really like about Qtile. I can just use Qtile, and not have to think about using ANYTHING else.

Conclusion

That’s all for this week. Thanks for sticking by! If you have any questions, please contact me through Discord or my Email address linked in the contacts page of my website. Bye bye!