Trying out Spectrwm

Spectrwm

As of writing this, I'm currently using I3WM but I wanted to rice out spectrwm to be my next window manager that I try out/move to.

Initial pain point

Not completely sure why but when trying to set a wallpaper, feh isnt able to detect the wallpaper from ~/.config/spectrwm/wallpaper.png but is able to detect it when I specify it from /home/tr1x/.config/spectrwm/wallpaper.png. I think this might be because its a startup process where my user hasnt been determined while the window manager is starting up as rofi, which runs after I log in, is able to load my rofi config correctly which is mapped using a relative path instead of an absolute path to its directory

Major pain point

I want to start this off by saying customizing spectrwm is somewhat easy. Normally, the config for most applications by default lives in /etc where I could find the default spectrwm.conf. This default config contains everything about starting up programs and customizing the window manager. The only problem is that the additional config files (keybinds and the bar which ill go into depth on later) wasnt in /etc for some reason which may be due to how the window manager is packaged for opensuse tumbleweed but it was quite annoying trying to find the config for the keybinds and bar on the spectrwm github repository.

The biggest issue I had setting up spectrwm was when customizing the bar. You can customize the bar by using a bash script to grab the items you want to render in the bar but the format of the bar is very weird. I think the syntax for specifying placement and fonts in the bar from the shell script make sense for instance:

+@fg=1; +@fn=2;󰄦+@fn=1; $(cpu)
  • fg = foreground where you specify the position you want to place an item in the bar
  • fn = the font you want to select for that block This means this is the first element in the bar where the icon is given font 2 and the cpu variable is given font 1. The thing I dont like is the accompanying config to display these elements in the bar from the spectrwm config:
+|L+1<+N:+I +S (+D) +W +|R+A+1<+@fg=5;+@fn=2;󰃰+@fn=1; %a %d %b, %I:%M

This specifies that you want the workspace and window name to appear on the left and on the right side of the bar, you want to populate the contents of the bar shell script to occupy 5 positions in the bar where the remaining item in the bar is a calendar using font 2 for the icon and font 1 for rendering the date time information. This syntax is detailed in the man page of the spectrwm config but the syntax is not very easy to wrap your head around when you see it for the first time.

Moving from AwesomeWM to i3WM

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.