Skip to content

Instantly share code, notes, and snippets.

@bendavis78
Last active October 25, 2023 22:11
Show Gist options
  • Star 17 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save bendavis78/e8cc8371499b52ac276fbe864247fdb7 to your computer and use it in GitHub Desktop.
Save bendavis78/e8cc8371499b52ac276fbe864247fdb7 to your computer and use it in GitHub Desktop.
Mapping Caps Lock to simultaneous Esc and Super (Mod4)

Mapping Caps Lock to simultaneous Esc and Super (Mod4)

The CAPS key can be mapped to an escape key when pressed once, and a super (mod4) key when used in combination with other keys.

Create the file /usr/share/X11/xkb/symbols/custom_opts with the following:

// Make Caps an additional Escape
hidden partial modifier_keys
xkb_symbols "super_esc" {
    key <CAPS> { [ Escape ] };
    modifier_map Mod4 { <CAPS> };
};

Edit /usr/share/X11/xkb/rules/evdev and add a new line in the ! option = symbols section:

  custom:super_esc = +custom_opts(super_esc)

Edit /usr/share/X11/xkb/rules/evdev.lst and add a new line the ! option section:

  custom:super_esc  Make Caps Lock an additional ESC and Mod4

Restart your X session and apply the setting using your DE's keyboard layout options.

Updating the keyboard layout option

Gnome

Open dconf-editor, and navigate to org.gnome.desktop.input-sources. Add 'custom:super_esc' to the xkb-options list. For example, if you have no other options set, just use ['custom:super_esc']. If you have other options set, separate using commas like so: ['compose:ralt', 'custom:super_esc'].

You can also use the gsettings command to do this via commandline.

XFCE

Edit /etc/default/keyboard and add custom:super_esc to the XKBOPTIONS variable (comma-separated).

Other options

Most laptops have the alt key really close to the windows key, which can result in accidental keypresses. I like to use the altwin:alt_win xkb option (Alt is mapped to Win and the usual Alt) to make both keys work as alt.

@arialdomartini
Copy link

@bendavis78 That's brilliant!
Any chance to have a similar behavior with an ordinary key? I would like to have the J key to emit a J when pressed, and to act as a Shift when held down. Would it be possible?

@purpleidea
Copy link

Sweet! Anyone know how to do this with wayland? Maybe libinput settings somehow?

@mar04
Copy link

mar04 commented Nov 24, 2018

Nice idea, I've tried it but with ctrl instead of super to replace my current setup using interception tools and it kinda works but esc press and release events are generated respectively before and after I try to use caps key with other keys as ctrl. That's a deal breaker for me, ideally it should generate esc events only when not used in combination with other keys.

@arialdomartini
Copy link

Hi @mar04. Thank you! Can please you share the configuration you used?

I'm currently using a keyboard layout where all the modifier have been remapped on ordinary keys, so that never ever have to move my hands from the home row (e.g. j and f produce j and f when pressed once, but act as Shift when held; I do the same with Control, Super, Esc, cursors, and the like). But so far, this require a keyboard supporting the QMK firmware.
On macOS I got the same result using Karabine.

But I would really love to do it with Linux. May be the interception tools you suggested are the solution.

@arnoudspammer
Copy link

wow thank you. Your instruction made it simple to implement but it's still hard to figure out yourself without intimate knowledge of the system i guess.

@mrkvn
Copy link

mrkvn commented Jan 7, 2021

This has been so very helpful. The exact setup I'm looking for. But in any way, how can I do the same on KDE? Thanks.

@mrkvn
Copy link

mrkvn commented Jan 22, 2021

This has been working for me but I just now realized that escape is always pressed even if i use it in combination with other keys. So for example, if I press <Caps>e, what will actually happen is <Esc><Super>e. This is also without even releasing the <Caps> key. While still holding the <Caps> key, <Esc> will already be initiated. Do you have the same behavior? Does anyone know how to fix this? Thanks.

@arnoudspammer
Copy link

arnoudspammer commented Jan 22, 2021 via email

@mrkvn
Copy link

mrkvn commented Jan 23, 2021

I have not tried it yet to test it. Hope Ben Davis knows more about this.

Thanks. I'm aware that if you press , it will be invoked even without releasing it so most probably it's the same behavior if you just move it to . But if there's a way to change that behavior, I would prefer that.

@bendavis78
Copy link
Author

@mrkvn I've noticed the same thing with some applications, but not everywhere. I think it has to do with whether or no the application checks for "key down" vs "key pressed". It hasn't been enough of an issue for me to bother investigating it, but you might be able to get more info using xev to see exactly what keyboard events are being sent.

@wardw
Copy link

wardw commented Jul 5, 2021

Just tried this: if I do ctrl-v at a terminal to capture the next key press I can see that escape (for me reported as the literal escape character ^[) is sent immediately on the key-down of capslock, i.e. before you even get to pressing the second key of the key-chord (which then also takes effect). So I suspect that escape is always being sent? As you say that may not be a problem should most applications simply choose to ignore it but perhaps at least one thing to be mindful of.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment