Ask Different is a question and answer site for power users of Apple hardware and software. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Apple's MacBook Pro has a slight delay on the caps lock key. That is, the caps lock key has to be held down slightly longer than normal to register the key press required to engage the caps lock.

This is super annoying. Does anyone know how to stop it from happening?

(Above copied over from stackoverflow as it was closed there as "off topic".)

To elaborate further: Apple deems this a feature, and their knowledge base article does not disclose how to disable this delay.

However, I have reason to believe it is possible to do so.

Notably, I have found that, at least in my experience, if you remap the caps-lock key on Mac OS X (in System Preferences .. Keyboard .. Modifier Keys), and e.g. map it to Control, then the delay goes away while I am logged into Mac OS X.

My problem is that the delay remains when I boot into Ubuntu Linux, and in that context, even when I remap the Caps Lock key to Control, the delay is still present.

So, the question is: How is Apple disabling the delay, and more importantly, how can one replicate that act in the context of a Linux installation atop the laptop?

Update: There is a thread on superuser that may provide workarounds. I have not yet tried the suggestions there (namely: (1) toggling CapsLock-NoAction off/on, and (2) a firmware upgrade). I cannot tell from the context of that thread whether the workarounds have been tested on an Ubuntu installation.

share|improve this question
I have never noticed this before now, but I have had a play with mine and I can see what you mean. If you tap the caps lock key too quickly it does nothing. I never found it a problem before but just tried the disable/re-enable the caps lock key trick and it has made it instant! now no matter quickly I hit the key it always toggles caps lock. Very strange! – tom1990 Mar 8 '13 at 23:21
Always thought I was just going crazy :p I can see its benefit, but in some situations it really annoys me. Would be good to know if its possible! – OrangeBox Apr 1 '13 at 22:47
Indeed, the disable/re-enable caps lock trick (on the Mac OS X side), does seem to make the problem go away once one subsequently reboots to Linux. But it is not clear to me if the effect is permanent -- I left my machine powered-off for some time (weeks or perhaps even more than a month), and when I booted it straight to Linux this morning, it seemed like the delay had returned. Still quite mysterious to me. – pnkfelix Apr 28 '13 at 16:47
So just to check, there doesn't appear to be a fix for linux for this issue? – Mike H-R Jul 29 '15 at 18:47
I have not yet found one. haven't looked for a fix recently, but I am going to try to run Linux natively more often now (rather than in a VM, where the issue does not arise) so that I can use rr to do debugging, and so maybe I'll again try to find a fix. – pnkfelix Aug 4 '15 at 11:33

I've figured out how to do this. In short, you must send a "Feature Report" consisting of the bytes 0x9, 0x0, 0x0, 0x0 to the appropriate hidraw device as root.

You can find the right hidraw device with this command:

dmesg | grep Apple | grep Keyboard | grep input0 | tail -1 | sed -e 's/.*hidraw\([[:digit:]]\+\).*/\/dev\/hidraw\1/'

The code to send the magic control packet is below. Compiles with gcc, takes the hidraw device as parameter. So the entire flow is:

  1. save the code below as disable-capslock-delay.c
  2. gcc -o disable-capslock-delay disable-capslock-delay.c
  3. HIDDEVICE=$(dmesg | grep Apple | grep Keyboard | grep input0 | tail -1 | sed -e 's/.*hidraw\([[:digit:]]\+\).*/\/dev\/hidraw\1/')
  4. sudo ./disable-capslock-delay $HIDDEVICE

Steps 3 and 4 have to be done every time you reboot (or unplug and re-plug the keyboard); you can put them into /etc/rc.local (or your distro's equivalent) to execute them at boot (you don't need sudo in that case; and you might want to move the compiled binary into /usr/local/sbin/ or something).

I've put in some safety checks for vendor ID, device ID, and report descriptor length. You may have to change the latter two if your model differs from mine.

#include <linux/hidraw.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv) { if (argc != 2 || strcmp(argv[1], "-h") == 0) { printf("Pass a hidraw device as the first and only parameter!\n"); printf("You may find the right device with:\n"); printf(" dmesg | grep Apple | grep Keyboard | grep input0 | tail -1 | " "sed -e 's/.hidraw\([[:digit:]]\+\)./\/dev\/hidraw\1/'\n"); return 1; } int fd, i, res, desc_size = 0; char buf[256]; struct hidraw_devinfo info; char *device = argv[1]; fd = open(device, O_RDWR | O_NONBLOCK); if (fd < 0) { perror("Unable to open device"); return 1; } memset(&info, 0, sizeof(info)); memset(buf, 0, sizeof(buf)); // Get Report Descriptor Size res = ioctl(fd, HIDIOCGRDESCSIZE, &desc_size); if (res < 0) { perror("HIDIOCGRDESCSIZE"); } if (desc_size != 75) { printf("Error: unexpected descriptor size %d; you've probably got " "the wrong hidraw device!\n", desc_size); return 1; } // Get Raw Info res = ioctl(fd, HIDIOCGRAWINFO, &info); if (res < 0) { perror("HIDIOCGRAWINFO"); } else { if (info.vendor != 0x05ac) { printf("Error: Wrong vendor ID, make sure you got the right " "hidraw device!\n"); return 1; } if (info.product != 0x0250) { printf("Warning: Unknown product ID 0x%x!\n", info.product); } } // Get Feature buf[0] = 0x09; // Report Number res = ioctl(fd, HIDIOCGFEATURE(256), buf); if (res < 0) { perror("HIDIOCGFEATURE"); } else { printf("HID Feature Report (before change):\n\t"); for (i = 0; i < res; i++) printf("%hhx ", buf[i]); puts("\n"); } // Set Feature buf[0] = 0x09; // Report Number buf[1] = 0x00; // Report data buf[2] = 0x00; // padding buf[3] = 0x00; // padding res = ioctl(fd, HIDIOCSFEATURE(4), buf); if (res < 0) { perror("HIDIOCSFEATURE"); } else { printf("Caps lock delay disabled.\n"); } // Get Feature buf[0] = 0x09; // Report Number res = ioctl(fd, HIDIOCGFEATURE(256), buf); if (res < 0) { perror("HIDIOCGFEATURE"); } else { printf("HID Feature Report (after change):\n\t"); for (i = 0; i < res; i++) printf("%hhx ", buf[i]); puts("\n"); } close(fd); return 0; }

share|improve this answer
This looks great, thanks! out of interest, how did you find this (the magic bytes required to be sent)? – Mike H-R Sep 16 '15 at 9:25
@MikeH-R: I've spent a day learning how the HID protocol works: essentially, devices describe what data packets ("reports") they understand. Unfortunately the Apple keyboard doesn't mention the report in question in its HID descriptors. However I found a dump of a MacBook's internal keyboard's HID descriptors that someone had posted which did contain the right report description, and I simply tried that and found that it works for the external wired keyboard as well. – jmrk Sep 16 '15 at 19:05
Oh wow I have to try this out! – pnkfelix Apr 5 at 8:35
(I do seem to get different descriptor sizes, at the very least. Still I'll adjust them and see how it works out.) – pnkfelix May 21 at 17:38

EDIT: Seems like there are people coming here from Google trying to generically fix the caps lock delay bug. This fix works in El Capitan too!

First of all let me tell you that there is definitely a way of removing the caps lock delay. I myself prefer to use caps lock over shift just from a comfort perspective, with caps lock being closer to my pinky finger than shift the majority of the time.

The solution is quite elusive, and you wouldn't really know you removed it unless you were specifically trying to get rid of it in the first place. The way I am going to show you is purely for the (current)latest version of OSX, Yosemite. However you can absolutely apply this method to previous and future versions.

The solution is simple. If you navigate to Keyboard in the System preferences via the apple logo in the top left hand corner you will reach this screen enter image description here

If you click the modifier keys button, you are able to change the function of each of the keys which are programmable. All you have to do is set the caps lock key to no action and press ok to bring you back to the keyboard menu. Once done, go back into the modifier keys and change the caps lock key back to caps lock and this will remove the delay! Do note that this fix remains in place until you sleep, restart or power down the device. At which point the delay is reinstated.

It's a strange fix, and it begs the question why do they not provide an option to remove the delay when this fix is purely software based. But hey, at least there is a way!

Happy capsing.

share|improve this answer
How does this solve my problem in Linux? – pnkfelix May 20 '15 at 11:39
To be clearer: the original question said: "... the delay goes away while I am logged into Mac OS X. My problem is that the delay remains when I boot into Ubuntu Linux, and in that context, even when I remap the Caps Lock key to Control, the delay is still present." – pnkfelix May 20 '15 at 11:39
Ah! I see, I guess I should read OP questions more carefully. I found on OSX that unbinding the caps key completely and rebinding solved the issue. Maybe the delay remains because you're binding to control instead? Worth trying everything if you don't yet have a work around :) – Bradley May 20 '15 at 21:33

I do know for certain that the caps lock delay is a feature of the firmware on the keyboard itself - so you can be confident that the delay timing happens no matter what OS the keyboard is driving at the moment.

I also know that Apple does not offer a path to flash the firmware to a lower level so we all will have to wait until someone with enough hardware experience blogs the tools and steps they performed to trick the hardware into loading the older firmware (or provide what looks like a newer firmware that regresses the delay to how it worked before without any delay.)

I apologize for the non-answer, but the path to accomplish this is well lit and it may help others take action (selecting an older keyboard - or refraining from upgrading the firmware) in the mean time while we wait for a real solution to implement a short or no timer on the caps lock key.

share|improve this answer
One detail I am confused about in your answer: Are you saying it is false that when one remaps the caps-lock key in Mac OS X, the delay goes away? (I do not know how else to interpret your statement "the delay timing happens no matter what OS the keyboard is driving at the moment"; but that contradicts my direct experience -- unless Apple is using some undocumented API to the firmware to adjust the timing?) – pnkfelix Apr 15 '13 at 3:30
I have mine remapped to ESC and the slightly longer hold is still necessary. I did this using a third-party app called Seil, though, and not via any functionality built in to OSX. Annoying, to be sure — don't their developers use Vim? Geez. – intuited Dec 19 '14 at 22:59

The "toggling CapsLock-NoAction off/on" solution that the OP refers to works on both my wired Mac keyboard and my MacBookPro keyboard. Bradley says this only works on Yosemite, but I've used it successfully on Snow Leopard (10.6.8) and Mavericks (10.9.5). I have also tested this inside a Kubuntu VM and Caps Lock continued working correctly inside the VM.

  • Open the Keyboard System Preference, and click on Modifier Keys...:

enter image description here

  • Set the Caps Lock key to No Action, and click OK:

                    enter image description here

  • Click on Modifier Keys... again, and set the Caps Lock key to Caps Lock, and click OK:

                    enter image description here

This only remains in effect until the next reboot.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.