Hacking i3: Window Swallowing

(Day 5 of 30 Days of Blogging)

Tiling window managers are a big reason why I use Linux. Not having to manually drag windows around is absolutely game changing, especially on a laptop with a small screen.

Tiling WMs work by resizing other windows when a new window is opened, so that no windows ever overlap. Most of the time this is perfect, but there’s a certain case where it’s not so great, which is when opening a GUI application from a terminal to quickly view a file:

Notice how the original terminal that opened sxiv (a bad name for a good image viewer) remains open, taking up space and not showing anything useful. Even worse, we can’t close that terminal without also killing the image window.

In this case what you really want is to have the image window “on top” of the terminal window, hiding it until it closes. I think DWM was the first to implement this type of feature, calling it “window swallowing”. I use i3, so I tried some other solutions like i3-swallow and devour. Unfortunately nothing I found really worked 100%, having layout flickering or restoring the terminal window to the wrong spot.

It occurred to me that i3 has a feature which I never use that could work here: tabs. So I wrote a script which creates a temporary tab layout on the current window in a way that replicates “swallowing”. No flickering or jank. As a small bonus, you can still view the terminal window if needed by switching tabs.

The final step is hiding the i3 tab buttons in the config. This is optional but I find i3 tab buttons pretty ugly so I turn them off by putting font pango:mono 0 in the config. Unfortunately this is a dirty hack as setting the font size seems to be the only way to shrink the tab bar. This is the same font that i3 uses to display error messages, so don’t mess up! Or comment it out if you need to see errors.

Here’s the final result:

Beautiful 😍 All you need to do is prefix a command with i3-tabbed to let it do its thing. This can be made automatic by using a shell alias: alias sxiv="i3-tabbed sxiv".

If you want to grab the script, make sure you have python3 and i3ipc which can be installed with pip install i3ipc.