How to permanently remap caps lock to esc in X11?

14,077

Solution 1

EDIT: As a helpful user has pointed out, my initial solution will not survive an update. His solution in the comments should work. If you prefer to swap Caps Lock and Escape instead, I would recommend adding the following commands from either your .xinitrc or from i3 config:

.xinitrc:

xmodmap -e "clear lock"
xmodmap -e "keycode 9 = Caps_Lock NoSymbol Caps_Lock"
xmodmap -e "keycode 66 = Escape NoSymbol Escape"

i3 config file (typically located at .config/i3/config or at .i3/config)

# swap caps lock and escape
exec_always --no-startup-id xmodmap -e "clear lock"
exec_always --no-startup-id xmodmap -e "keycode 9 = Caps_Lock NoSymbol Caps_Lock"
exec_always --no-startup-id xmodmap -e "keycode 66 = Escape NoSymbol Escape"

I realise this question is quite old, but thought I might add an answer for those of us still trying to figure this out.

After having similar issues with some DEs not loading ~/.xinitrc, I avoided xmodmap altogether, went to /usr/share/X11/xkb/symbols and modified the key=>symbol mapping directly.

To do so, I edited the config file for my keyboard located at /usr/share/X11/xkb/symbols. For most keyboards, this should be the pc file.

After opening the file, I manually switched around Escape and Caps_Lock for their respective keys the result is shown below). As this affects how X maps the hardware to the key Symbol, it should work regardless of whether you're on GNOME or i3 or anything like that.

A snippet of my resulting file is as follows:

default  partial alphanumeric_keys modifier_keys

xkb_symbols "pc105" {

    key <ESC>  {        [ Caps_Lock             ]       };

    // The extra key on many European keyboards:
    key <LSGT> {        [ less, greater, bar, brokenbar ] };

    // The following keys are common to all layouts.
    key <BKSL> {        [ backslash,    bar     ]       };
    key <SPCE> {        [        space          ]       };

    include "srvr_ctrl(fkey2vt)"
    include "pc(editing)"
    include "keypad(x11)"

    key <BKSP> {        [ BackSpace, BackSpace  ]       };

    key  <TAB> {        [ Tab,  ISO_Left_Tab    ]       };
    key <RTRN> {        [ Return                ]       };

    key <CAPS> {        [ Escape                ]       };
    key <NMLK> {        [ Num_Lock              ]       };

    key <LFSH> {        [ Shift_L               ]       };
    key <LCTL> {        [ Control_L             ]       };
    key <LWIN> {        [ Super_L               ]       };

    key <RTSH> {        [ Shift_R               ]       };
    key <RCTL> {        [ Control_R             ]       };
    key <RWIN> {        [ Super_R               ]       };
    key <MENU> {        [ Menu                  ]       };

This worked like a charm for me.

On looking around the related files, I found repeated mentions and partial implementations of some kind of flag used to switch around certain keys, such as swapping Escape and Caps Lock. I assume this is what the Gnome Tweak Tool and setxkbmap use; however, I couldn't figure out how to keep these flags on with i3 window manager. The above solution should work fine.

Hope this fixes the problem!

Solution 2

Two possibilities:

1) .xinitrc isn't being run - it's used by xinit, startx, and a few other methods for starting up X sessions, but isn't universally supported - you may be using a display manager that doesn't run it. Adding something to .xinitrc such as touch /tmp/xinitrc-was-run can help determine if that's the case.

2) Xorg automatically resets to default settings when no clients are connected - if the .xinitrc finishes before the window manager or anything else starts running, then the xmodmap or setxkbmap changes will be lost.

If there is an XKB option already defined that you want to use, instead of running programs to change the setting every time Xorg starts, you can just tell Xorg to start up with the right settings already. For instance, in order to enable the Ctrl-Alt-Backspace keys to kill my Xserver, I have installed a file named /etc/X11/xorg.conf.d/90-zap.conf which contains:

# This configuration snippet enables the Ctrl-Alt-Backspace server kill key
# 
# To use it, link or copy into /etc/X11/xorg.conf.d/
#
# Note that only the last XkbOptions setting seen for a device will be used,
# so to use multiple options, copy this file and add options into the Option
# string, such as "terminate:ctrl_alt_bksp,ctrl:swapcaps"

Section "InputClass"
    Identifier "keyboard zap by default"
    MatchIsKeyboard "on"

    Option "XKbOptions" "terminate:ctrl_alt_bksp"
EndSection

You can read more about this in the X.Org docs at https://www.x.org/releases/X11R7.7/doc/xorg-docs/input/XKB-Config.html.

Share:
14,077

Related videos on Youtube

ethanmad
Author by

ethanmad

Updated on September 18, 2022

Comments

  • ethanmad
    ethanmad over 1 year

    I want to remap caps lock to escape in X11 (i.e. pressing the physical caps lock button will be interpreted as esc by applications and esc's behavior will not change). The solution must survive an X restart. xmodmap and setxkbmap are acceptable solutions (as are similar programs). I don't want to deal with a GUI, as I want the solution to be portable and a part of my dotfiles. If I'm missing a better/easier/more obvious solution, please tell me, though do note that I am not using a DE (trying out i3wm).

    So far I've tried using xmodmap and setxkbmap with little success.

    Here's my attempt at using xmodmap:

    # ~/.xinitrc
    xmodmap ~/.xmodmap
    

    and

    # ~/.xmodmap
    remove Lock = Caps_Lock
    keysym Caps_Lock = Escape
    

    Running $ xmodmap ~/.xmodmap from the command line works and does what I want. The issue is that this gets reset every time x restarts. That's where I expect the xinitrc to come in--shouldn't it load every time x starts and run the xmodmap command? If the command works, why doesn't it do anything when read from a file?

    I've tried a couple of things with setxkbmap, neither of which worked. The two attempts below were in the file at separate times.

    # ~/.xinitrc
    setxkbmap -option caps:esc     # attempt 1
    setxkbmap -option esc:nocaps   # attempt 2
    

    Neither command did anything perceptible from the command line, so I'm assuming that I've got the command wrong. I like the idea of this solution because it's a one-liner and does not require anything in some other file. If only it worked.

    Is .xinitrc the wrong file to be using? I know startx is loading from ~/.xinitrc.

    I request that possible solutions contain the whole file(s), not just one line (if more than one is required in the file) so I don't mess up some intermediary step. For example, if I need something in .xinitrc and something in .xcapsrebind, please show both files and all of the required contents (I can also handle being told to append something to the end, but if an & or similar may be required, please tell me).

    • Admin
      Admin about 9 years
      In .xinitrc: setxkbmap -option caps:escape
    • Admin
      Admin about 9 years
      Running xmodmap in .xinitrc should work. It’s what I do. Maybe map something unusual, to make sure that it’s actually running when you start x? Also, what window manager/desktop environment do you use? KDE periodically “corrects” my keyboard mapping without me telling it to. Maybe check your desktop settings to make sure that nothing is running xmodmap behind your back.
    • Admin
      Admin about 9 years
      jasonwryan: Tried that in both the .xinitrc; didn't work. It did work from the command line! So there's a start. I think yellowantphil is right-- ~/.xinitrc isn't getting run. I'm using i3wm and no DE right now, though the same thing was happening in Pantheon when I tried. As far as I can tell, i3 doesn't mess with the xinitrc or load its own (but I'm a noob, so what do I know?).
    • Admin
      Admin over 8 years
      You may as well try to include Option "XkbOptions" "caps:escape" in a X keyboard config file, e.g. /etc/X11/xorg.conf.d/10-keyboard.conf
  • quixotic
    quixotic about 6 years
    in your i3 config: exec --no-startup-id setxkbmap -layout whatever -variant whatever -option caps:escape
  • quixotic
    quixotic about 6 years
    note your changes to the system ...xkb/symbols/pc file will be overwritten the next time xkeyboard-config or xkb-data packages are updated.