Remapping CAPS_LOCK

setup
 
linux
 
bash
 
windows
 

Throughout the history of keyboards, CAPS LOCK’s key’s placement (and maybe existence) might have been the single biggest mistake of keyboard designs - it occupies one of the most expensive real estate in the keyboard-land yet serves very limited purpose. In this post, we discuss how to gentrify and repurpose the CAPS LOCK key.

Note: users might have preference on what to remap, but in this post, I’ll cover one of the mainstream setups: remap CAPS LOCK so that it serves as ESC when pressed and release alone, and as CTRL when together with other keys.


Linux

In Linux, Xmodmap and xcape are the tools for this purpose.

Xmodmap

Commands

Xmodmap is the Xorg utility for modifying key mappings. To modify key mappings, either pass expressions with -e option

xmodmap -e "keysym BackSpace = Delete" 

or put expressions in a file and

xmodmap .Xmodmap

To undo changes, execute

setxkbmap

. To print the mappings for normal key mappings,

xmodmap -pke

and for modifier keys (SHIFT, CTRL, etc).

xmopmap -pm

Concepts

Xmodmap has the following concepts:

  • keycode: numeric representations of the physical keys. They are the values that the kernel receives when keys are pressed.
  • keysym: values assigned to the keys. They are the represented value of the keys, or the symbolic value of the keys.
  • modifier keys: special keys that alter values of the other keys when pressed along. These require special handling, and have different configuration instructions than the ordinary keys.

Setting Up

The reason I decided to go a little deeper at this is that some setups floating on the Internet worked better for some of my systems, but less than satisfactory for others. A quick walk through Xmodmap syntax:

  • To update the mapped value of a key:
! target is the physical key with key_code
keycode key_code = key_mapping
! target is the key whose value is key_symbol
keysym key_symbol = key_mapping
  • To update modifiers:
! remove all keys from modifier
clear modifier
! add key as modifier
add modifier = key
! remove key from modifier 
remove modifier = key

xcape

xcape is the perfect tool to complement Xmodmap:

xcape allows you to use a modifier key as another key when pressed and released on its own.

Solution and Issues

The solution has 3 steps (for .Xmodmap and an additional step for xcape: xcape -e 'Control_L=Escape'):

! 1. make caps_lock an additional control
clear lock 
clear control
keycode 66 = Control_L
add Control = Control_L Control_R

! 2. make escape be caps_lock
keysym Escape = Caps_Lock
add Lock = Caps_Lock

! 3. make a fake escape key (so we can map it with xcape)
keycode 999 = Escape 
  • The step two that makes ESC a CAPS LOCK stopped working after recent Ubuntu upgrades. So I removed step two from some of my system as I rarely use CAPS LOCK.
  • Before step two became a persistent issue, when putting both xmodmap and xcape in a script I needed to add a sleep 5 between them for them to work correctly;
  • xmodmap keycodes are a mistery. sudo showkey -s seems to show totally unrelated values to xmodmap.

Moving forward, xmodmap is becoming rather outdated, and a xkb solution should be the long-term plan. I will try to re-visit this topic sometime in the future.


Windows

There are plenty of posts about tweaking Windows Registry to achieve this goal, but there is another tool, a very simple one, to achieves the same goal: AutoHotkey.

*CapsLock::
    Send {Blind}{Ctrl Down}
    cDown := A_TickCount
Return

*CapsLock up::
    If ((A_TickCount-cDown)<125)  ; Modify press time as needed (milliseconds)
        Send {Blind}{Ctrl Up}{Esc}
    Else
        Send {Blind}{Ctrl Up}
Return

Notice that you might need to tweak the press time value (shown as 125 ms in the script above) to better suit your personal taste.