36

I know how to use xmodmap to remap the Caps lock key so it acts as a Control key, or as an Escape key. I would like to combine both features as follows:

When I push, then release, the Caps lock key, it sends Escape. When I hold down Caps lock and push another key (say A), it send Control-A.

Is there some combination of xkb, xmodmap and something else that could make Caps lock behave this way in X?

I'm using Ubuntu Precise on a Macbook Air 3,1.

7 Answers7

46

I have this setup on my Mac and I had tried to find a way for Ubuntu without luck.

Well, it's now working. Thanks tungd for ponting me to xcape. What I have done is really simple and straightforward.

  1. Under System PreferencesKeyboard LayoutOptions...Ctrl key position, I checked Caps Lock as Ctrl.

  2. In a terminal run:

    xcape -e 'Control_L=Escape' 
    

Done, Caps Lock works as Ctrl when used like a modifier, and as Esc when pressed alone (there's a slight delay of a few hundred milliseconds, as noted on the xcape README file, so it's still not as optimal as the Mac solution which uses KeyRemap4MacBook.)

  • 5
    I've used gnome-tweak-tool to map Caps Lock to Ctrl as there is no Keyboard layout in System Settings on Ubuntu 14.04. Then xcape -e 'Control_L=Escape' didn't work, but after using xcape -d I've discovered that Caps Lock generates keycode 66 and remapped it respectively: xcape -e '#66=Escape'. – Sergiy Belozorov Sep 04 '14 at 10:08
  • 4
    As per this blog post, it is possible to do this with xcape alone:

    setxkbmap -option 'caps:ctrl_modifier' xcape -e 'Caps_Lock=Escape' setxkbmap -option 'caps:ctrl_modifier' xcape -e 'Caps_Lock=Escape;Control_L=Escape;Control_R=Escape'

    – Louis Simoneau Aug 04 '15 at 10:06
  • This should really have been the accepted answer @user372737 – Assaf Lavie Nov 05 '15 at 17:29
  • @LouisSimoneau this this a thousand times this. – Spencer May 21 '16 at 21:22
  • 1
    Any progress with the delay problem? – Toothrot May 22 '16 at 12:54
  • @vic-goldfeld How did you get it working on your mac? – Scott Tesler Sep 22 '16 at 02:42
  • @Shloopy use Karabiner – ocodo Nov 20 '16 at 23:55
  • @vic-goldfeld I added a note to your answer, tweaking the timeout option will improve the delay. It defaults to 500ms which is pretty high. It's best to experiment with lower values until you hit the sweet spot. – ocodo Nov 21 '16 at 00:02
  • @toothrot see above. – ocodo Nov 21 '16 at 00:03
  • Just one question, how can I make this command to run each time I log in to X? – Mohamad Mar 26 '17 at 12:58
  • On Ubuntu 18.04 I had to do Tweaks -> Keyboard & Mouse -> Additional Layout Options -> Ctrl position -> Caps Lock as Ctrl and then xcape -e 'Control_L=Escape' – glortho Apr 27 '18 at 18:06
10

Install xcape

sudo apt-get install xcape

Add the two lines in your ~/.profile

/usr/bin/setxkbmap -option 'caps:ctrl_modifier'⏎
/usr/bin/xcape -e 'Caps_Lock=Escape' -t 100

Notice the part -t 100, if you don't set it, you may notice a delay in Esc if you use vim.

Zanna
  • 70,465
Searene
  • 4,350
8

I'm looking for this too. As of a week ago I found my self a partial solution using xmodmap:

add Control = Caps_Lock
remove Lock = Caps_Lock
keysym Caps_Lock = Escape

This is of course not working perfectly, it effectively send both Escape and Ctrl at the same time when I press CapsLock, but I was happy with it for a while.

Finally I found this little utility https://github.com/alols/xcape. So now I can simply remap CapsLock to Ctrl and let xcape do its job.

tungd
  • 180
  • Another option is At-Home-Modifier. It's not in active development, and differs slightly from xcape by installing at root. However, it triggers through xorg.conf, and hence can act only on specific keyboards, while using other keyboards simultaneously. – Sparhawk Aug 01 '13 at 23:13
7

EDIT: Fixed this for most smart (newer) display managers.

Per Louis and Sergiy's comments I have come up with this solution that is working for me on Ubuntu 16.04 (Xenial) with LightDM and Unity.

I put the following line of code into my .xprofile file in my home directory.

setxkbmap -option 'caps:ctrl_modifier' && xcape -e 'Caps_Lock=Escape' &

The trailing & puts the xcape command into the background so that it doesn't block your session. The setxkbmap makes its change immediately.

Sergiy:

I've used gnome-tweak-tool to map Caps Lock to Ctrl as there is no Keyboard layout in System Settings on Ubuntu 14.04. Then xcape -e 'Control_L=Escape' didn't work, but after using xcape -d I've discovered that Caps Lock generates keycode 66 and remapped it respectively: xcape -e '#66=Escape'. – Sergiy Byelozyorov Sep 4 '14 at 10:08

Louis:

As per this blog post, it is possible to do this with xcape alone: setxkbmap -option 'caps:ctrl_modifier' xcape -e 'Caps_Lock=Escape' setxkbmap -option 'caps:ctrl_modifier' xcape -e 'Caps_Lock=Escape;Control_L=Escape;Control_R=Escape' – Louis Simoneau Aug 4 '15 at 10:06

dragon788
  • 1,556
1

If you are using Gnome, you may find that other answers here result in the key mapping being dropped whenever you connect to bluetooth.

To prevent that from occurring, use the following:

sudo apt install xcape -y; # install the xcape utility, which will be used for caps_lock -> escape

update gnome settings to track the keyboard modifier permanently

gsettings set org.gnome.desktop.input-sources xkb-options "['caps:ctrl_modifier']"; # make caps work as ctrl; https://unix.stackexchange.com/a/66657/77522

make ctrl key work as caps if pressed on its own

xcape -e 'Caps_Lock=Escape' &

sources:

Ulad Kasach
  • 1,686
1

I've built a tool in C specially for this purpose that overcome many of the issues with the xcape/xmodmap solution:

oblitum
  • 1,687
  • 2
  • 16
  • 27
  • Is there any way to turn off the "swap" of Esc to Caps, I prefer to not have a Caps at all and keep the old and new Esc both behaving as Escape. – dragon788 May 15 '17 at 14:42
  • @dragon788 removing these lines: https://github.com/oblitum/caps2esc/blob/v1.0.3/caps2esc.c#L75-L76 and https://github.com/oblitum/caps2esc/blob/v1.0.3/caps2esc.c#L88-L89. – oblitum May 15 '17 at 16:40
  • Thanks, I'm going to have to put a link to auto compile this into my dotfiles. I may also PR the README.md as on Ubuntu 16.04 it required libudev-dev and libevdev-dev in order to compile. – dragon788 May 15 '17 at 18:41
  • 1
    @dragon788 come to Arch (you could even try Antergos). I've moved out from Ubuntu years back and will never go back, it's just way better. – oblitum May 15 '17 at 20:15
-4

You can do the first (mapping Caps Lock to Esc) but you cannot do the second.

Simple Explanation: Caps Lock is just not designed to do something when pressed.

Elaborate Explanation: There are many types of keys. Two of them are Modifier Keys and Lock Keys.

Caps Lock is a Lock Key while keys such as Ctrl, Alt, and Shift are Modifier Keys.

It's apparent from their names that Modifier Keys modify the function of the next key(s) pressed, and Lock Keys act as a toggle switch to turn on or off some particular function.

Now, since Caps Lock is a Lock Key, you cannot have it behave like a Modifier Key without mapping it to one. Caps Lock by itself cannot function as a Modifier Key.

green
  • 14,306
  • Thank you for confirming that X is not designed to do what I want. If an X guru wants to hack something to make it work, please get in touch with me. – user372737 Aug 25 '12 at 23:52
  • 8
    As the unaccepted answer below, you certainly can do the second part with numerous utilities such as xcape or At-Home-Modifier. – Sparhawk Aug 01 '13 at 11:48