Switching i3wm Workspaces with Alt + Tab
2017-12-07
When I started using i3, one feature I missed from more
traditional window managers such as Gnome's Mutter, KDE's KWin, or even
Microsoft Windows was the ability to quickly switch between applications using
the Alt + Tab
keyboard shortcut. I recently added a key binding to my Vim
configuration for switching between tabs with Ctrl + Tab
to match Firefox, and
that gave me the idea to implement a similar key binding for i3.
After some DuckDuckGo searches and reading the i3-msg
man pages, I came up
with a short Bash script to make it happen. I usually have only one or two
windows open per workspace in i3, though, and I already use the h/j/k/l keys
with $mod
for changing the window focus, so I decided to map Alt + Tab
and
Alt + Shift + Tab
to cycle forwards and backwards between open workspaces
instead.
The i3-msg
command has the ability to send a few different commands to i3
using the -t
option. Running i3-msg -t get_workspaces
returns a JSON list
describing each workspace, including which one is focused. I'm using
jq to parse the results. The i3-msg workspace <workspace_number>
command tells i3 to switch to a particular workspace. And a short
i3-workspace-switcher
Bash script ties it all together:
#!/bin/bash
direction=$1
workspaces=(`i3-msg -t get_workspaces | jq -r 'map(.num)' | jq -r '.[]'`)
current=$(i3-msg -t get_workspaces | jq -r 'map(select(.focused))' | jq -r '.[]' | jq -r '.num')
current_index=0
last_index=0
i=0
for n in "${workspaces[@]}"
do
last_index=$i
if [ $n == $current ]; then
current_index=$i
fi
((i++))
done
next_index=0
if [ $direction == "backward" ]; then
if [ $current_index == 0 ]; then
next_index=$last_index
else
next_index=$(($current_index - 1))
fi
else
if [ $current_index == $last_index ]; then
next_index=0
else
next_index=$(($current_index + 1))
fi
fi
next=${workspaces[$next_index]}
i3-msg workspace $next
Lastly, I have the following two key bindings in my ~/.config/i3/config
file.
Since I'm using a Chromebook that doesn't have a meta
key, I have $mod
bound to Alt
.
bindsym $mod+Tab exec "i3-workspace-switcher"
bindsym $mod+Shift+Tab exec "i3-workspace-switcher backward"
And now I can cycle through my workspaces quickly using Alt + Tab
and Alt + Shift + Tab
.