i3 Window Navigation Tips

i3wmNavigating between windows, especially in a multi-monitor environment can pose a real challenge at times.

You work on a very important project and have a number of windows scattered over a few workspaces and monitors. Some of them are just opened for visual reference while others need to be regularly re-visited. An obvious solution would be to group windows in a logical way so that it is easy to switch between them. Depending on the number of windows and your working habits, this might not be enough. Fortunately, i3 offers some shortcuts or easy ways of creating such shortcuts. These might not look like life savers at first but, if used efficiently and on a regular basis, over time they can add hours or even days to you precious coding time. I will present a few tips with the best (IMHO) left till the end: the use of vim-like goto marks.

Going Back and Forth

Imagine you are working on one of your workspaces and you just quickly need to check something on workspace 4 so you press $mod+4 to switch to it. Once you have checked it, you don’t have to remember the number of the previous workspace. You just need to press $mod+4 again and you’ll return to whatever workspace you were working on. To enable this functionality, make sure you have the following line in ~/i3/config:

workspace_auto_back_and_forth yes

But it gets even better. The following key binding lets you switch back and forth between the last two workspaces that you visited pressing the $mod+z key combination.

bindsym $mod+z workspace back_and_forth

Furthermore, you can move windows back and forth with:

bindsym $mod+Shift+z move container to workspace back_and_forth

You could combine the two actions so that you move a window backwards and forwards and follow it.

bindsym $mod+Shift+z move container to workspace back_and_forth; workspace back_and_forth

Configure focus on keybindings;;dfafdad

Sometimes it would make sense to hard-code focusing on certain windows:

bindsym $mod+Shift+b [class="Firefox"] focus
bindsym $mod+Shift+i [class="Terminal" title="weechat"] focus

Using the last key binding will bring focus to an instance of Terminal running the weechat irc client. You can identify particular windows using the xprop client property displayer. Sometimes, however, it might not be easy to identify a client and that’s where vim like goto marks come in handy.

Goto marks in i3

Goto marks let you mark a window on the fly so that you can focus on it at a later time. Please bear in mind that they do not modify your config file so they will be lost if you exit i3. They are meant to be session specific or for windows that are difficult to identify. I will present a few ways you can use them to focus on windows.

The first method is by explicitly naming particular windows and calling them by name.

bindsym $mod+m exec i3-input -F 'mark %s' -P 'Mark name: '
bindsym $mod+Shift+m exec i3-input -F '[con_mark=%s] focus' -P 'Go to mark: '

When the focus is on the window that you’d like to mark, you can press $mod+m and type the mark name, for example: ks (short for the terminal window where you edit kernel source). You can name a few windows that you visit regularly giving them other, ideally short labels and the marks will be stored for the duration of the i3 session.

Then you can immediately access (ie. focus on) them from any workspace or display by pressing $mod+Shift+m and typing an appropriate mark name, eg. ks.

An alternative approach would be to use numbers or letters with Emacs-like modes.

mode "mark_window" {
                bindsym 1 mark m1
                bindsym 2 mark m2
                bindsym 3 mark m3
                bindsym 4 mark m4
                bindsym 5 mark m5
                bindsym a mark ma
                bindsym b mark mb
                bindsym c mark mc
                bindsym d mark md
                bindsym e mark me

                bindsym Return mode "default"
                bindsym Escape mode "default"

mode "go_to_window" {

                bindsym 1 [con_mark="m1"] focus
                bindsym 2 [con_mark="m2"] focus
                bindsym 3 [con_mark="m3"] focus
                bindsym 4 [con_mark="m4"] focus
                bindsym 5 [con_mark="m5"] focus
                bindsym Return mode "default"
                bindsym Escape mode "default"


bindsym $mod+g mode "go_to_window"
bindsym $mod+m mode "mark_window"

Pressing $mod+g you enter the mark_window mode where a new set of keybindings (defined above) applies. Please note that it’s essential that you specify a way of returning to the default mode. Otherwise, you might get stuck as standard i3 keybinding do not work inside modes unless explicitly set. After you’ve entered the “mark_window” mode, you can press, eg. 1 to set a mark on the currently focused window and press Esc or Enter/Return to exit to the default mode. Now whenever you want to jump to window marked as 1, you’d go to the go_to_window mode, press 1 and exit the mode: $mod+g 1 Esc.

All-in-one approach using an i3 mode

The most optimal option, however, could be combining all the above mentioned tips under one mode where you could define your hard coded keybindings, leave an option for adding on-the-fly window labels, as well as use numbers for tagging windows.

mode "focused" {

                # hardcoded focus keybindings
                bindsym b [class="(?i)firefox"] focus
                bindsym w [class="(?i)terminal" title="weechat"] focus
                bindsym m [class="(?i)thunderbird"] focus
                bindsym f [class="(?i)terminal" title="mc"] focus
                bindsym z [class="(?i)zathura"] focus

                # keybindings for marking and jumping to clients
                bindsym a exec i3-input -F 'mark %s' -P 'Mark name: '
                bindsym g exec i3-input -F '[con_mark=%s] focus' -P 'Go to mark: '

                # Assign marks to keys 1-5
                bindsym Shift+1 mark mark1
                bindsym Shift+2 mark mark2
                bindsym Shift+3 mark mark3
                bindsym Shift+4 mark mark4
                bindsym Shift+5 mark mark5

                # Jump to clients marked 1-5
                bindsym 1 [con_mark="mark1"] focus
                bindsym 2 [con_mark="mark2"] focus
                bindsym 3 [con_mark="mark3"] focus
                bindsym 4 [con_mark="mark4"] focus
                bindsym 5 [con_mark="mark5"] focus

                # Exit to the default mode
                bindsym Return mode "default"
                bindsym Escape mode "default"

bindsym $mod+n mode "focused"



7 Replies to “i3 Window Navigation Tips”

  1. Even though this post is two years old, I found this tips really helpful.

    Especially the “workspace back and forth” parts were unknown to me and I’m sure that I’ll try out the window marks in the near future.

    Thank you for sharing this!

  2. Instead of going back and forth with a window, you could also use a sticky one. I think this makes sense in floating mode only.

Leave a Reply

Your email address will not be published. Required fields are marked *