For some reason my laptop is stuck in Caps Lock. I have the Caps Lock key mapped by xmodmap
to hyper_l
, so I don't have a caps_lock
key to turn it off. Is there a way I can turn it off by command line? It would be nice if I could reset the lock state without resetting my computer, especially for future reference. This has happened before, but I would like to know now how to do it properly this time.
-
[echo -e "$(dumpkeys | grep ^keymaps)\nkeycode 58 = Escape" | sudo loadkeys][1] [Adding the following line to .profile or .bash_profile should disable caps lock:][2] [xmodmap -e "remove lock = Caps_Lock"][3] [1]: askubuntu.com/questions/43986/… [2]: askubuntu.com/questions/43986/… [3]: askubuntu.com/questions/43986/…– One ZeroNov 17, 2011 at 18:02
-
2setxkbmap -option caps:none– Pavlos TheodorouFeb 1, 2017 at 9:56
-
2@PavlosTheodorou, that will disable CAPS key, it will not toggle its status as the OP requirement.– user.dzFeb 1, 2017 at 10:02
-
1there is a bug there. there is no command currently to do that. you could use setleds +caps or -caps but its not working. the only thing u can do is already answered. you can remap caps– Pavlos TheodorouFeb 1, 2017 at 14:18
5 Answers
I don't know of any command line tool for that in Ubuntu. (For Num Lock, there is numlockx .) Here's a one-liner that you can copy-paste into a terminal window:
python -c 'from ctypes import *; X11 = cdll.LoadLibrary("libX11.so.6"); display = X11.XOpenDisplay(None); X11.XkbLockModifiers(display, c_uint(0x0100), c_uint(2), c_uint(0)); X11.XCloseDisplay(display)'
Here it is again in a more expanded form. We use the Python ctypes library to call C functions from the X library directly. The function XkbLockModifiers
changes the state of the keyboard locks, on the core keyboard (XkbUseCoreKbd
= 0x0100), affecting Caps Lock (2), setting it to 0 (off).
#!/usr/bin/env python
from ctypes import *
X11 = cdll.LoadLibrary("libX11.so.6")
display = X11.XOpenDisplay(None)
X11.XkbLockModifiers(display, c_uint(0x0100), c_uint(2), c_uint(0))
X11.XCloseDisplay(display)
If you have a stuck modifier, change 2 to the mask of the modifiers you want to turn off. The modifiers are 1=Shift, 2=Lock (Caps Lock), 4=Control, 8=Mod1, 16=Mod2, 32=Mod3, 64=Mod4, 128=Mod5. Run xmodmap -pm
to see what Mod1 through Mod5 correspond to. For example, to turn off all modifiers, call X11.XkbLockModifiers(display, c_uint(0x0100), c_uint(255), c_uint(0))
. To turn on Num Lock which is on Mod2 and at the same time turn off Caps Lock, call X11.XkbLockModifiers(display, c_uint(0x0100), c_uint(2 | 16), c_uint(16))
.
Here's a C version if you want to make a small binary instead of invoking Python. Compile with gcc -O -Wall -o caps_lock_off caps_lock_off.c -lX11
, with the packages build-essentials
and libx11-dev
installed.
#include <stdio.h>
#include <X11/X.h>
#include <X11/XKBlib.h>
int main()
{
Display *display = XOpenDisplay(NULL);
if (display == NULL) {
fprintf(stderr, "Couldn't open display\n");
return 2;
}
Bool sent = XkbLockModifiers(display, XkbUseCoreKbd, LockMask, 0);
if (!sent) {
fprintf(stderr, "Couldn't send LatchLockState\n");
return 1;
}
#ifdef REPORT_STATE
XkbStateRec xkb_state;
Status status = XkbGetState(display, XkbUseCoreKbd, &xkb_state);
if (status) {
fprintf(stderr, "XkbGetState returned %d\n", status);
return 1;
}
printf("state.group=%02x\n", xkb_state.group);
printf("state.locked_group=%02x\n", xkb_state.locked_group);
printf("state.base_group=%02x\n", xkb_state.base_group);
printf("state.latched_group=%02x\n", xkb_state.latched_group);
printf("state.mods=%02x\n", xkb_state.mods);
printf("state.base_mods=%02x\n", xkb_state.base_mods);
printf("state.latched_mods=%02x\n", xkb_state.latched_mods);
printf("state.locked_mods=%02x\n", xkb_state.locked_mods);
printf("state.compat_state=%02x\n", xkb_state.compat_state);
printf("state.grab_mods=%02x\n", xkb_state.grab_mods);
printf("state.compat_grab_mods=%02x\n", xkb_state.compat_grab_mods);
printf("state.lookup_mods=%02x\n", xkb_state.lookup_mods);
printf("state.compat_lookup_mods=%02x\n", xkb_state.compat_lookup_mods);
printf("state.ptr_buttons=%02x\n", xkb_state.ptr_buttons);
#endif
int err = XCloseDisplay(display);
if (err) {
fprintf(stderr, "XCloseDisplay returned %d\n", err);
return 1;
}
return 0;
}
Also possibly of interest is a way to temporarily ignore Caps Lock:
xkbset nullify lock
After this, Caps Lock will effectively be permanently off, until you reenable it with xkbset nullify -lock
.
-
I'll have a go when I'm next on my laptop. I'm on my desktop for now.– EchogeneNov 17, 2011 at 23:50
-
Hmm, the python method used to work for me, but after upgrading to Yakkety it does not. The bug where caps lock gets stuck persists of course! Nov 4, 2016 at 20:09
-
4I get a segfault: terminated by signal SIGSEGV (Address boundary error) Segmentation fault… Nov 5, 2016 at 5:19
-
2
-
2The python code used to work but now does not. See the @diegogs answer below for one that still does.
xset nullify lock
fixed the problem on some applications (emacs) but not others (terminator). It does not work either before or after. xdotool works. Sep 9, 2019 at 21:52
Using Xorg automation
Xorg automation tools could be used for sending the required key events.
Note:
For first use, This solution needs you to tape the correct password to install new tool, if your CAPS is currently active:
- Use SHIFT key to type lowercase letters.
- Enable accessibility, overlay virtual keyboard.
- Re-plug an external keyboard. (Thanks to chris455)
- Open office writer, write password there, change the letter case, copy it, then paste it to password dialog.
If all previous options are not possible or don't work, Go with Gilles' answer / python script. It does not need to install any additional tool, it uses only
python
&libX11
shared lib which are pre-installed.
Using xdotool
Install it
sudo apt-get install xdotool
Send a CAPS down/up event
xdotool key Caps_Lock
Another tool is xte
Install it
sudo apt-get install xautomation
Send a CAPS lock down/up event
xte "key Caps_Lock"
References:
-
-
3This is the only one that worked for me. nullify and others didn't work.– lnostdalJul 8, 2015 at 10:15
-
18
-
2You can use Shift keys for inputting lowercase letters while Caps Lock is enabled.– chris544Feb 24, 2018 at 21:43
-
1If you use an external keyboard another option could be re-plugging it; Caps Lock modifier might get reset, so you can input lowercase letters.– chris544Feb 24, 2018 at 21:54
As for Gilles' Python version not working in newer Ubuntus, setting the correct return for the open display seems to do the trick:
#!/usr/bin/env python
from ctypes import *
class Display(Structure):
""" opaque struct """
X11 = cdll.LoadLibrary("libX11.so.6")
X11.XOpenDisplay.restype = POINTER(Display)
display = X11.XOpenDisplay(c_int(0))
X11.XkbLockModifiers(display, c_uint(0x0100), c_uint(2), c_uint(0))
X11.XCloseDisplay(display)
(Code adapted from https://stackoverflow.com/questions/29638210/how-can-i-use-python-xlib-to-generate-a-single-keypress)
If you can't access CAPS because you remapped it in .bashrc, like I did, then simply switching to a virtual terminal (alt+ctl+fN) and then switching back worked for me.
-
1Switching didn't quite do it, but it did get me to a point where I could press caps lock to get thing right. Feb 16, 2018 at 13:33
I had this problem and was able to fix it by using the OnBoard keyboard (in Ubuntu Mate, under Universal Access).
Once turned on you should see the CapsLock key is red, or somehow indicated that it is locked on. Then you can press to toggle off.
-
1Great solution, thank you. I installed "onboard" which is a very simple onscreen keyboard and that solved it.– JaviApr 29, 2020 at 18:08