Linux – i3wm: more than 10 workspaces with double modifier key

arch linuxi3keyboard shortcutslinuxworkspaces

Recently, I started to use i3wm and fell in love with it. However, one thing bothers me: controlling more than 10 workspaces.

In my config $mod+1 to $mod+9 switches between the workspaces 1 to 9 (and $mod+0 for 10), but sometimes 10 workspaces just aren't enough.

At the moment I reach out to workspace 11 to 20 with $mod+mod1+1 to $mod+mod1+0, i.e. hitting mod+alt+number. Of course this works without any problems, but it is quite a hassle to switch workspaces like that, since the keys aren't hit easily. Additionally, moving applications between workspaces 11 to 20 requires to mod+shift+alt+number -> ugly.

In my Vim bindings (I have lots of plugins) I started to use double modifier shortcuts, like modkey + r for Plugin 1 and modkey + modkey + r for Plugin 2. This way I can bind every key twice and hitting the mod key twice is easy and fast.

Can I do something similar in i3wm?

How do you make use of more than 10 workspaces in i3wm? Any other solutions?

Best Answer

i3 does not really support key sequences like vim. Any key binding consists of a single key preceded by an optional list of distinct (so no Shift+Shift) modifiers. And all of the modifiers need to be pressed down at the time the main key is pressed.

That being said, there are two main ways to have a lot of workspaces without having to bind them to long lists of modifiers:

1. Dynamically create and access workspaces with external programs

You can do not have to define a shortcut for every single workspace, you can just create them on the fly by sending a workspace NEW_WS to i3, for example with the i3-msg program:

i3-msg workspace NEW_WS
i3-msg move container to workspace NEW_WS

i3 also comes with the i3-input command, which opens a small input field then runs a command with the given input as parameter

i3-input -F 'workspace %s' -P 'go to workspace: '
i3-input -F 'move container to workspace %s' -P 'move to workspace: '

Bind these these two commands to shortcuts and you can access an arbitrary number of workspaces by just pressing the shortcut and then entering the name (or number) of the workspace you want. (If you only work with numbered workspaces, you might want to use workspace number %s instead of just workspace %s)

2. Statically bind workspaces to simple Shortcuts within key binding modes

Alternatively, for a more static approach, you could use modes in your i3 configuration. You could have separate modes for focusing and moving to workspaces:

set $mode_workspace "goto_ws"
mode $mode_workspace {
    bindsym 1 workspace 1; mode "default"
    bindsym 2 workspace 2; mode "default"
    # […]
    bindsym a workspace a; mode "default"
    bindsym b workspace b; mode "default"
    # […]
    bindsym Escape mode "default"
}
bindsym $mod+w mode $mode_workspace

set $mode_move_to_workspace "moveto_ws"
mode $mode_move_to_workspace {
    bindsym 1 move container to workspace 1; mode "default"
    bindsym 2 move container to workspace 2; mode "default"
    # […]
    bindsym a move container to workspace a; mode "default"
    bindsym b move container to workspace b; mode "default"
    # […]
    bindsym Escape mode "default"
}
bindsym $mod+shift+w mode $mode_move_to_workspace

Or you could have separate bindings for focusing and moving within a single mode:

set $mode_ws "workspaces"
mode $mode_ws {
    bindsym 1 workspace 1; mode "default"
    bindsym Shift+1 move container to workspace 1; mode "default"
    bindsym 2 workspace 2; mode "default"
    bindsym Shift+2 move container to workspace 2; mode "default"
    # […]
    bindsym a workspace a; mode "default"
    bindsym Shift+a move container to workspace a; mode "default"
    bindsym b workspace b; mode "default"
    bindsym Shift+b move container to workspace b; mode "default"
    # […]
    bindsym Escape mode "default"
}
bindsym $mod+shift+w mode $mode_move_to_workspace

In both examples the workspace or move commands are chained with mode "default", so that i3 automatically returns back to the default key binding map after each command.

Related Question