In the (unofficial) #i3 IRC channel on freenode, someone recently asked if i3 has a command to switch between display outputs. Somewhat suprisingly, i3-msg doesn’t have such a command, but I realized that one could be written pretty easily by getting the list of workspaces and finding which one is visible but not focused, then switch to that workspace. Here’s the command I came up with, shown as a full binding from ~/.i3/config:

bindsym $mod+Next exec i3-msg workspace $(i3-msg -t get_workspaces|jq '.[] | select(.visible == 'true') | select(.focused == 'false') | .name')

You’ll need to have ‘jq’ installed.

The logic for this is pretty simple:

  • Get a list of all workspaces
  • Iterate through the list
  • Find workspaces that are visible
  • Find workspaces that are not focused
  • Print the workspace names

With two displays, you can only have two visible workspaces, and only one of those will be focused. I simply find a visible workspace that is not focused.

This won’t work as-is if you have more than 2 monitors, but you could easily have a different binding for each display, filtering for a specific “output” in place of the filter that looks for the non-focused workspace.

With a little more work, you could rotate through displays by parsing things out with python or awk (or whatever) and enumerating all the displays to determine which should be “next” or “prior”.

But, if you only have two displays, like I do, the above binding will let you easily jump back and forth between outputs.