A couple of months ago it occurred to me that I’ve been manually tiling my windows. That is, I use all the screen real estate, and don’t have windows overlapping each other.

In various window manages (and on Windows) I have used Super+Left and Super+Right to divide the screen 50/50.

So why am I not running a tiling window manager? That’s literally what they do, and they allow more flexibility in how to tile, without wasting space.

Switching to tiling

A quick googling says that i3 is what I want. Fast, small, efficient. No bells and whistles.

I used it for a little while, but then because I wanted to make it even harder on myself, err… I mean to join the 21st century, I thought I’d switch from X11 to Wayland, too. Luckily there’s a Wayland Compositor that’s equilavent to the i3 Window Manager called Sway.

It’s great! I knew X11 and Gnome had issues, but I didn’t realize just how much better I feel when I don’t have to deal with their deficiencies.

Like:

  • screen tearing when scrolling in terminal windows
  • changing focus can take up to a second, sometimes
  • X11 resets keyboard settings when it bloody feels like it, in addition to every single time you plug/unplug a keyboard

Wayland’s not been entirely smooth sailing though:

Terminals

Now that the biggest issues with performance were gone, it became more noticeable that gnome-terminal is pretty slow too. Reading my email in my text client I noticed that merely scrolling through an email could take 45% CPU on a modern machine. That’s ridiculous, even if it’s a full height window on a 4k monitor, thus many pixels.

At first I thought it was due to my email client not being efficient at rendering. After all, it redraws the whole text buffer from scratch when you scroll. So I implemented scrolling using terminal escape codes.

Curiously that didn’t help at all. Oh well, at least it improves screen tearing on X11, and reduces network use when run through SSH.

I got a recommendation to use the terminal foot. Terrible name. But in the spirit of i3 and Sway (and being native Wayland), it looked pretty neat. And yes, much faster.

I had to adjust the colors. The default ones were very muted.

One mayor drawback though is that it does not support tabs. But Sway does support tabs for windows, so why do I need tabs both in the WM (ehem, compositor) and in the terminal?

After trying it as-is, it turns out that I really want to be able to cycle through the tabs inside the same “visual space”, and moving to another window is something else to me entirely. Similar to how when I move away from the browser window, I move away from all the browser tabs, but moving between browser tabs is a completely different conceptual thing.

What I want shortcuts for:

  • “if focus is inside a tabbed container, go out of that tabbed container and to the left” (or up, down, right, whatever)
  • “go to the next tab. If it’s the last tab, cycle back to the first one”
  • “jump directly to tab number N”

Neither foot nor Sway support this. But Sway supports dumping a JSON representation of the layout, and it supports sending navigation commands.

So I made a shell script that takes the JSON layout, locates the currently focused window, and does what I want.

I felt kinda icky having Sway execute my script, which in turn does three more exec() calls (and all the other syscalls to fork() and shuffle data between them), just to “focus next window”. Running the script took about 50ms, too. Not really a problem, but could be noticeable on a loaded system with many more windows.

So I rewrote it in C++, using simdjson. Turns out the JSON parsing and querying of jq was the biggest time thief. But now it’s down to being so fast time often claims it’s 0.000s of CPU time.

Possibly the jq query could be optimized, but I wanted to not even waste time loading four binaries (swaymsg, bash, jq, and swaymsg again) to select the next window. I don’t even particularly like the one exec() call.

And now I can configure moving around the way I want it.

And if I have other fancy nav things I want to do I have the library to get started.

In conclusion

I highly recommend tiling window managers, and i3 and Sway in particular. I run Sway both on my laptop and on my dual monitor desktop. Sway also handles unplugging/replugging the extra monitor much better, where Gnome just left a horrible mess.

And I recommend simdjson for all your JSON parsing needs. It’s really fast, and a nice modern C++ API.