I3WM has stuck with me for so long that it feels like since forever. I don’t remember why I chose it among other “tiling” window managers when I was only getting to know the term. Anyway, here it stays - quietly and assiduously in the background while I do all kinds of stuff with the computer. On rare occassions, I get curious about the window managers other people mentioned and have a look at them. But none effectively convinced me. I am already content with i3:
- I3 is lightweight and stable. I can’t stress this enough for a window manager.
- I3’s workspaces map nicely to real monitors. People may have very creative ways to arrange their workspaces across screen real estates. Not me.
- I don’t really need so-called “tiling” window feature. I just have programs take over the whole screen of each monitor in a layout mode that i3 calls “tabbed”.
- As I don’t do any fancy layout management, i3’s IPC is adequate for my needs: navigate or move windows.
- I installed autotiling which helps with sensible tiling layout without me specifying anything. Though it’s great, honestly I still don’t find the chance to really include it in my workflow.
- Besides i3’s IPC, I also use
wmctrl for
scripting window-management stuff. In particular, onething that I
use extensively is a script I call
aol
(“activate-or-launch”). This script will activate (bring to focus) the window of a program if it’s found, otherwise launch it, wait for the window to appear and activate it:
import sys
import csv
import subprocess
import time
id = sys.argv[1]
wmClass = None
command = None
with open('/etc/nixos/aol.tsv') as csvfile:
reader = csv.DictReader(csvfile, delimiter='\t')
for row in reader:
if row['id'] == id:
wmClass = row['class']
command = row['command'] or id
if wmClass:
def checkExistingWindow():
"""
Try to switch to existing window. Return True if switched
successfully, False otherwise.
"""
result = subprocess.run(['wmctrl', '-x', '-a', wmClass])
return result.returncode == 0
if not(checkExistingWindow()):
print('existing window not found, trying to launch a new one now...')
subprocess.Popen(['bash', '-c', command])
i = 0
while i < 10:
time.sleep(1)
if checkExistingWindow():
break
else:
i+=1
As you can see, I put data in a “Tab-Separated Values” (TSV) file which looks something like this:
(I omitted custom scripts from this aol file for obvious reasons.)
That way I have “activate-or-launch” commands for all programs I frequently use and bind them to convenient hot keys. An example in i3 config file, though you can use any hot key configuration tool from your Desktop Manager/Window Manager:
bindsym $mod+a exec aol anki
bindsym $mod+g exec aol geany
Before implementing this “aol” script, I used to switch windows or
launch programs with rofi. Now
that the “activate-or-lauch” of frequently-used programs are triggered
in under a second with the keyboard, rofi
is only used to launch
rarely-used apps or pinpoint the desired window when the app’s class
is not enough (eg given multiple windows of Firefox, you’d need to
select them by title.)
Though not obvious, i3 has its role with this “aol” script, too. In my
i3 config, I assign all programs to a specific “workspace”, and each
specific workspace to a monitor. Things are so predictable that
whenever I summon a program with aol
, I know immediately where to
cast my eyes over.
This setting saves my brain some memory to do other tasks. I hope you find it helpful :)