Introducing tofi (toffee) launcher!

tofi terminal preview

I’ve started getting into using swaywm as well as i3wm. The issue I’ve ran into is finding a consistent launcher experience. I really like rofi, but rofi doesn’t work as nicely on sway (when you have multiple monitors). I’ve tried wofi, but it’s way of finding apps doesn’t find all registered apps (it uses a list of directories to search, where with gio it’s possible to just request registered applciations (which is nice with things like flatpaks.

With the naming of rofi and wofi, I thought tofi would be fun. At first I was trying to figure out how to write a GUI, and then a TUI… And then I thought fzf might be fun to look into (turns out it wasn’t an original idea). Some of the crazy fun stuff is from some of the additional features in fzf (like reload). With reload, we can add “modes” by having multiple reload bindings that run tofi with different options. Another cool add is using fzf’s preview to execute tofi in the background as the user browses through results of the different modes.

The tofi launcher script is really just configuring fzf around my python script:

#!/bin/env sh

SCRIPT=`readlink -f "$0"`
SCRIPT_DIR=`dirname "$SCRIPT"`
TOFI="$SCRIPT_DIR/tofib"

$TOFI --applications | sort -u -r | \
fzf --bind "ctrl-w:reload(python '$TOFI' --windows | sort -u -r)" \
    --bind "ctrl-a:reload(python '$TOFI' --applications | sort -u -r)" \
    --preview "echo '{}' | '$TOFI' --preview" \
    --preview-window ":0" | \
$TOFI

The most confusing part is the --preview-window ":0", which is colon delimited (which took me a while to figure out…).

The next bit is launching alacritty with a --class set to filter on in sway and i3.

For sway:

for_window [app_id="tofi"] floating enable, border pixel 2, sticky enable
set $menu exec alacritty --class tofi -d 80 10 -e sh -c '${HOME}/GitHub/tofi/tofi'

For i3:

for_window [instance="tofi"] floating enable, border pixel 2, sticky enable
set $menu exec alacritty --class tofi -d 80 10 -e sh -c '${HOME}/GitHub/tofi/tofi'

You’ll notice that one uses app_id and the other uses instance. The backend script also has to be slightly aware of additional things between i3 and sway. But with this, you can make all kinds of custom terminal based tools/apps and have them feel “integrated” with i3 and sway.

tofib (tofi backend) is a python script that acts as the heavily lifter, write now it’s not well organized, and there’s some additions I plan on making. It currently only has modes for launching applications and switching focus between windows. I plan on adding a recently used documents launcher, and other things that come up. The best part with using fzf, is it’s really easy to extend and add functionality.

Hopefully if you check it out you like it! And if not, hopefully the way it works inspires you to make something that fits your needs.