Adding a repurposed caps lock as a third mod key in i3
When the i3 window manager is run for the first time, a configuration wizard runs and allows you to set the modifier, or mod key, that you want to use for your keybindings. The configuration wizard allows you to choose either the Alt key or the Super key, i.e. one or the other, but not more than one. i3 though has support for all five modifier keys, and these can be set in your i3 config file. My i3 config file was set up to use two mod keys: mod4, the Super key, and mod1, the Alt key. For a while, I was happily using two mod keys, but recently I have found myself needing to use a third. This quick and dirty post will explain how, and why I repurposed my Caps Lock key as mod3.
Disclaimer: what follows is what worked for me, and what I did, and in the order I did it, to use the Caps Lock key for use as mod3 in i3.
Here is the relevant excerpt from my i3 config file, from when I was using just two mod keys:
set $mod Mod4
set $mod1 Mod1
And here is the xmodmap -pm command output (before repurposing the Caps Lock Key) showing the default assignments for mod1 through mod5:
xmodmap -pm
xmodmap: up to 5 keys per modifier, (keycodes in parentheses):
shift Shift_L (0x32), Shift_R (0x3e)
lock
control Control_L (0x25), Control_R (0x69)
mod1 Alt_L (0x40), Alt_R (0x6c), Meta_L (0xcd)
mod2 Num_Lock (0x4d)
mod3
mod4 Hyper_L (0x42), Super_L (0x85), Super_R (0x86), Super_L (0xce), Hyper_L (0xcf)
mod5 ISO_Level3_Shift (0x5c), Mode_switch (0xcb)
As you can see in the above output, mod3 is empty and mod4, in addition to the Super key, also includes the Hyper key.
The first thing I did was run the following setxkbmap command to change the Caps Lock key to the Hyper key:
setxkbmap -option caps:hyper
This might seem like enough, but it’s not; next a ~/.Xmodmap file needs to be created to clear out the mod4 designations, add the mod3 designation, and then re-add the mod4 designations. Here is the contents of the ~/.Xmodmap file I created:
clear mod4
keycode 66 = Hyper_L NoSymbol Hyper_L
add mod3 = Hyper_L
add mod4 = Super_L Super_R
Note: the keycode for the Caps Lock key can be obtained using the xev command like this:
xev -event keyboard
After creating the .Xmodmap file you either need to restart X or source the .Xmodmap file. Here is the command to source the new file:
xmodmap ~/.Xmodmap
After running that above command, re-running the xmodmap -pm command outputs the following:
xmodmap -pm
xmodmap: up to 3 keys per modifier, (keycodes in parentheses):
shift Shift_L (0x32), Shift_R (0x3e)
lock
control Control_L (0x25), Control_R (0x69)
mod1 Alt_L (0x40), Alt_R (0x6c), Meta_L (0xcd)
mod2 Num_Lock (0x4d)
mod3 Hyper_L (0x42), Hyper_L (0xcf)
mod4 Super_L (0x85), Super_R (0x86), Super_L (0xce)
mod5 ISO_Level3_Shift (0x5c), Mode_switch (0xcb)
As you can see mod4 now only includes Super, and mod3 is no longer empty, but contains Hyper.
Next (since I don’t run a display manager) I added the following to my ~/.xinitrc:
[[ -f ~/.Xmodmap ]] && xmodmap ~/.Xmodmap
This will source my custom ~/.Xmodmap file when I run startx.
And the last thing I did was add the following to my i3 config file:
set $mod3 Mod3
exec --no-startup-id setxkbmap -option caps:hyper
For clarity, I put the set $mod3 Mod3 line in the same section of the file where I had set $mod and $mod4; and I put the exec –no-startup-id setxkbmap command in the section of the file where I put the programs that I want started when i3 starts up.
With the above changes made, I now have three modifier keys that I can use for keybindings in i3. This gives me another whole level of keybinding flexibility.
The main reason I did this though, is that a third mod key made it more simple and intuitive to add and use an additional 10 workspaces, for a easily accessed total of 30. With i3 configured this way I can now access workspaces 1-10 with Super+numbers 1-0; workspaces 11-20 with Alt+numbers 1-0; and workspaces 21-30 with Caps Lock+numbers 1-0.
Here is the excerpt from my i3 config with 30 workspaces:
# Define names for default workspaces for which we configure key bindings later on.
# We use variables to avoid repeating the names in multiple places.
set $ws1 "1"
set $ws2 "2"
set $ws3 "3"
set $ws4 "4"
set $ws5 "5"
set $ws6 "6"
set $ws7 "7"
set $ws8 "8"
set $ws9 "9"
set $ws10 "10"
set $ws11 "11"
set $ws12 "12"
set $ws13 "13"
set $ws14 "14"
set $ws15 "15"
set $ws16 "16"
set $ws17 "17"
set $ws18 "18"
set $ws19 "19"
set $ws20 "20"
set $ws21 "21"
set $ws22 "22"
set $ws23 "23"
set $ws24 "24"
set $ws25 "25"
set $ws26 "26"
set $ws27 "27"
set $ws28 "28"
set $ws29 "29"
set $ws30 "30"
# switch to workspace
bindsym $mod+1 workspace number $ws1
bindsym $mod+2 workspace number $ws2
bindsym $mod+3 workspace number $ws3
bindsym $mod+4 workspace number $ws4
bindsym $mod+5 workspace number $ws5
bindsym $mod+6 workspace number $ws6
bindsym $mod+7 workspace number $ws7
bindsym $mod+8 workspace number $ws8
bindsym $mod+9 workspace number $ws9
bindsym $mod+0 workspace number $ws10
bindsym $mod1+1 workspace number $ws11
bindsym $mod1+2 workspace number $ws12
bindsym $mod1+3 workspace number $ws13
bindsym $mod1+4 workspace number $ws14
bindsym $mod1+5 workspace number $ws15
bindsym $mod1+6 workspace number $ws16
bindsym $mod1+7 workspace number $ws17
bindsym $mod1+8 workspace number $ws18
bindsym $mod1+9 workspace number $ws19
bindsym $mod1+0 workspace number $ws20
bindsym $mod3+1 workspace number $ws21
bindsym $mod3+2 workspace number $ws22
bindsym $mod3+3 workspace number $ws23
bindsym $mod3+4 workspace number $ws24
bindsym $mod3+5 workspace number $ws25
bindsym $mod3+6 workspace number $ws26
bindsym $mod3+7 workspace number $ws27
bindsym $mod3+8 workspace number $ws28
bindsym $mod3+9 workspace number $ws29
bindsym $mod3+0 workspace number $ws30
# move focused container to workspace
bindsym $mod+Shift+1 move container to workspace number $ws1
bindsym $mod+Shift+2 move container to workspace number $ws2
bindsym $mod+Shift+3 move container to workspace number $ws3
bindsym $mod+Shift+4 move container to workspace number $ws4
bindsym $mod+Shift+5 move container to workspace number $ws5
bindsym $mod+Shift+6 move container to workspace number $ws6
bindsym $mod+Shift+7 move container to workspace number $ws7
bindsym $mod+Shift+8 move container to workspace number $ws8
bindsym $mod+Shift+9 move container to workspace number $ws9
bindsym $mod+Shift+0 move container to workspace number $ws10
bindsym $mod1+Shift+1 move container to workspace number $ws11
bindsym $mod1+Shift+2 move container to workspace number $ws12
bindsym $mod1+Shift+3 move container to workspace number $ws13
bindsym $mod1+Shift+4 move container to workspace number $ws14
bindsym $mod1+Shift+5 move container to workspace number $ws15
bindsym $mod1+Shift+6 move container to workspace number $ws16
bindsym $mod1+Shift+7 move container to workspace number $ws17
bindsym $mod1+Shift+8 move container to workspace number $ws18
bindsym $mod1+Shift+9 move container to workspace number $ws19
bindsym $mod1+Shift+0 move container to workspace number $ws20
bindsym $mod3+Shift+1 move container to workspace number $ws21
bindsym $mod3+Shift+2 move container to workspace number $ws22
bindsym $mod3+Shift+3 move container to workspace number $ws23
bindsym $mod3+Shift+4 move container to workspace number $ws24
bindsym $mod3+Shift+5 move container to workspace number $ws25
bindsym $mod3+Shift+6 move container to workspace number $ws26
bindsym $mod3+Shift+7 move container to workspace number $ws27
bindsym $mod3+Shift+8 move container to workspace number $ws28
bindsym $mod3+Shift+9 move container to workspace number $ws29
bindsym $mod3+Shift+0 move container to workspace number $ws30
-dsyates
(o\_!_/o)