Tiling Window Managers

I switched to linux about a year ago when I finished univeristy where I jumped around between different desktop environments until I finally settled on using window managers. I realised that I dont need all the features a desktop environment gives you and I always had issues with applications spawning off screen or in weird locations where I would have to do some wizardy to try grab the title bar and move it or give up on moving the window entirely where I would end up closing the app completely and praying that it would reopen in a decent location.

This is where tiling window managers comes in. The main feature that drew me in was that all application windows spawn in a known location. Theres nothing stopping it from spawning with the aspect ratio being weird for an app but you are always guaranteed that the window will spawn on screen. Since then, I have configured AwesomeWM and LeftWM. Awesome is configured in Lua and LeftWM is configured in a RON file and some bash/shell files and whatever file you use to configure your status bar. The thing I loved the most about Awesome and LeftWM is that you can customize them very "easily". For instance, Awesome has Awesome Copycats and LeftWM has LeftWM Community Themes to give you a starting point for building your own config and there are tons of configs you can find browsing the internet. The thing that always brings me back to Awesome, and subsequently why I keep leaving LeftWM even though I have it configured, is the way workspaces are managed by default. In Awesome, each monitor gets its own set of workspaces whereas, in window managers like LeftWM, the workspaces are shared across all monitors. Many people wont use 18 workspaces but sometimes I do and I appreciate how easy it is to manage workspaces in Awesome than in LeftWM.

Switching to i3

I always want to try out new tools and see how things are different compared to the tools and software that I use regularly so I ended up trying out i3. i3 is a manual tiling window manager where as Left and Awesome are dynamic tiling window managers. The difference between them is that with a manual tiler, you need to choose where a window will spawn before opening a window otherwise, the window manager spawns windows in a default layout (for i3 this is spawning all windows next to each other vertically). A dynamic tiler on the other hand spawns windows based on layouts that you can customize or which are predefined. As I prefer dynamic tilers, I knew using i3 would be quite difficult until I found this project which provides auto tiling to i3 and sway found here.

Things I like so far

Customizing i3 has been quite easy. The default bar is ok, you cant do alot with it buts its simple and gets the job done. The config for i3 is very simple. In contrast, my Awesome config spans over 5 or 6 lua files to make things easy to find while my LeftWM config spans multiple files (the majority of them being theme files) where the contents are stored in a mixture of RON and bash scripts. i3 makes this very simple by having nearly all config stored in the i3Status config and default i3 config

Things I dont like

  • I still dont like that workspaces are shared between monitors as I sometimes forget and have monitors swap places every so often. Its not a huge deal as I can swap them back but just something I dont particularly like
  • i3 feels slow. Compared to Awesome and Left there is a "slowness" that I feel when using i3 that I havent experienced in other window managers. It feels similar to when I was using KDE but it might just be the tools I am using or the way I have configured i3 or something to do with the hardware I am running but it does feel a little slower than Awesome and Left in comparison.
  • The status bar feels limiting. Customizing the status bar to have widgets or displaying titles of applications required writing custom bash scripts to handle populating the data in the bar or using a completely different bar entirely but at this point it is nitpicking when ideally I can use eww or polybar as my status bar and it would probably work fine.

Customizing i3

As stated before, customizing i3 was very simple and customizing most window managers is simple when you have a baseline to go from. The semantics for autostart programs, setting a background and configuring keybinds are very similar in most window managers. Unlike bspwm, you dont need to use sxhkd to handle keybinds but if you would like to use more advanced keychords, you can configure i3 to use this too.

Between window managers I use similar customizations. For instance, I always use picom as my compositor and rofi as my run menu so I use the same config in all window managers. I also use betterlockscreen across all of my window managers. The main difference between window managers is what bars are supported.

Choosing a bar

In awesomeWM, I use the default bar with minimal customizations as my network card is named differently but besides that, everything is pretty much default. For LeftWM, you need to use a third party bar as there is no bar that ships with the window manager. With i3, your package manager might install i3status as your default bar which is ok. It doesnt some with a lot of features out of the box and to handle mouse inputs and events you need to use the i3 bar protocol and create custom scripts to handle the events you want to trigger.

I wanted to do a bit more customization with the bar so I wanted to try out some others that are available. The options I went through were polybar, eww and i3status-rs. I immediately ruled out polybar as, even though I have a config for polybar, i3 feels quite slow already and I didnt want to make i3 feel any more sluggish by using a resource intensive bar like polybar. This left me with either eww or i3status-rs. Eww is an amazing bar that lets you customize it with SCSS and yuck files and the default config for it suited my needs however, tray icons arent supported as of yet so I ruled this out for now (I may return to eww when try icons are supported in the future but by then, I might not be using i3 at all). That left me with i3status-rs and the config for it is very simple, the developers have made it that you can configure the bar completely from a toml file with an easy way to execute custom scripts or programs and the default bar has been working nicely for me so far. I only added an additional powermenu block and pointed it to a custom rofi script but besides that, it works flawlessly.

Hotkeys

One thing I really missed about Awesome was the hotkey window. It renders all the keybinds you have available to you from inside the window manager and was like a "cheatsheet" whenever you forget a keybind which is really useful when trying out a window manager that you havent learnt all the keybinds for.

I found this video from linux dabbler which talks about how he got a hotkey popup window to render in spectrwm. I thought I could probably get something like that working in i3 so I gave it a shot.

This is the adapted shell script I ran to get all the keybinds I have inside my i3 config

#!/bin/bash

echo "Super/Windows keybinds"
grep bindsym ~/.config/i3/config | grep "mod\+" | awk '{for (i=3;i<=NF;i++) printf("%s ",$i)} {print "--- " $2 "\n"}' | column
echo ""

echo "Control keybinds"
grep bindsym ~/.config/i3/config | grep "Control\+" | awk '{for (i=3;i<=NF;i++) printf("%s ",$i)} {print "--- " $2 "\n"}' | column
echo ""

echo "Hints"
echo "\$mod is super/windows key"
echo "MOD1 is alt"
echo "to close this window, press the enter key"
read -r

To summarise what this does, it uses grep to find all locations of bindsym in my config, then greps for lines with mod or control in them (I did this so I could separate the keybinds I have for different modifier keys). Then I pipe this to awk to print out everything from the 3rd argument in the line to the end of the line where "---" is used to separate the keybind at position 2 with the thing that is executed from that keybind.

This essentially converts something like this in my config:

bindsym $mod+Return exec wezterm

to this when outputted from the shell script

exec wezterm --- $mod+Return

To get this to trigger in my i3 config, I had to add a keybind to execute the shell script in a floating window where the following keybind will create an alacritty window with a window class name of '__keybind_scratchpad' that executes the shell script with no no-startup-id:

bindsym $mod+s exec --no-startup-id "alacritty --class='__keybind_scratchpad' -e ~/.config/i3/keybinds.sh"

However, this will apply the same tiling rules that i3 uses for all windows instead of being a floating hotkey window. To make this window floating, I had to add this line to my config to make all windows with a class name of '__keybind_scratchpad' float:

for_window [class="__keybind_scratchpad"] floating enable

Thoughts

I think i3 is a pretty good window manager. There are certain things I like about it compared to awesome, the main one being getting up and running with i3 is very simple. With awesome, as its written in a real programming language, I've found that I try to break up my config by splitting it into multiple files which makes things very easy to find and modify in the future, but it is quite daunting for someone who has never used a window manager to come to and try to configure afterwards. I3 makes this very simple to configure by using a user friendly syntax so getting up and running is quite simple. I also like how when switching between tags on different monitors, if a monitor is on 1 monitor and you select it from another monitor, it takes you to that monitor instead of swapping the tags on each monitor (something I really dont like that LeftWM does).

That being said, there are 2 main reasons why I will not be using i3 as my daily driver:

  • It feels alot slower compared to my config for awesome even though my config for awesome loads in alot more programs and dependencies
  • Although I have dynamic tiling working now, i3 is mainly a manual tiler and the script I'm using to provide dynamic tiling could break whenever i3 updates how their tiling api works. Having this dependency on a third-party to provide this functionality doesnt feel great.
  • I dont like how the workspaces are shared across all monitors. I would much rather have what awesome does where each monitor gets 9 workspaces than 9 workspaces shared across 2 monitors

I highly recommend i3 for new users that have never used a tiling window manager before or for any users that havent tried out i3 and want to try something new. I dont particularly like manual tilers but as long as the autotiling project works, I will still use i3 whenever I get bored of awesome.

If I were to rank the window managers from most to least liked, I would rank them like this:

  • AwesomeWM
  • i3WM
  • LeftWM

I switched to i3 while trying out clojure and as I have finished trying out clojure, I'm thinking of trying out python next. I guess the next window manager I'm going to configure is QTile.