32

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.

  • 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
  • 1
    Here is a fix that works for macOS and can be run under macOS. – fel1x Feb 22 at 7:12
22

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; }

  • 2
    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
  • 6
    @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 '16 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 '16 at 17:38
  • I'm going to accept this answer because it comes the closest to actually acknowledging the problem as described and providing a believable solution to it (even though in my own case the descriptor sizes are different). – pnkfelix Nov 19 '16 at 2:05
13

Here is the fix for macOS Sierra.

Go to System Preferences > Accessibility

When the accessibility window is open — on the left part of the window – click Keyboard

Then there will be the 2 options — for sticky keys, and for slow keys — click the box next to slow keys to enable it — then click the Options... button – a new window will come up with a slider to change the acceptance delay — by default this is in the middle. Slide the button all the way to the left, so that it is the shortest time possible.

Now it should be fixed. Have not experimented to see if the fix stays upon restart, but I’m hopeful that it will.

  • I got excited for a sec but when I went to look here, slow keys wasn't enabled so only works for people who use slow keys :( one day I will have my precious caps lock key back! – Bradley Jan 4 '18 at 9:56
  • 4
    This does reduce it a bit, but it's still slower to to turn on caps-lock than turn off. Also the key repeat rate slows down to a crawl, even though the setting is on fastest. (Sierra 10.12.6) – scipilot Jan 6 '18 at 0:22
  • 1
    this isn't a proper solution to the problem at hand as it slows down keyrepat and you no longer can properly delete stuff when holding backspace. – Denialos May 30 '18 at 6:14
7

EDIT: This seems to be a popular landing question for users looking to remove the delay on the caps lock key in OS X. As of OS X Mojave,

Go to System Preferences; Accessibility; Keyboard; enable Slow Keys and go into options; turn the delay down to the minimum. The only unwanted side-effect I've noticed so far is slow backspace action when holding it down. Generally I use CMD+A / CMD+SHIFT+L/R / CMD+SHIFT+CTRL+L/R anyway so it's not a big issue.

As of El Capitan and earlier,

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][1]

[1]: http://i.stack.imgur.com/DIbZD.png

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.

They're strange fixes, 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.

  • 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
  • 1
    This approach didn't have any effect for me. (Sierra 10.12.6) – scipilot Jan 6 '18 at 0:23
3

Go to system preferences > accessibility > keyboard > enable slow keys > change acceptance delay all the way to the left (short)! This worked for me.

  • Are you describing a step in Mac OS X? How does this solve the problem in Ubuntu Linux, as described in the question? – pnkfelix Nov 19 '16 at 2:03
  • Yes, correct. I don't know Ubuntu Linux, sorry. I think I'm solving the main title "How to remove caps lock delay on Apple MacBook Pro aluminum keyboard*" and maybe the question "How is Apple disabling the delay". :-) Best Regards Thomas, Sweden *That question is the reason I found and read this tread and nothing helped so I solved it myself :P – Thomas Carl-Erik Jönsson Dec 6 '16 at 14:28
  • 2
    As per Michelle's answer: This does reduce it a bit, but it's still slower to to turn on caps-lock than turn off. Also the key repeat rate slows down to a crawl, even though the setting is on fastest. (Sierra 10.12.6) – scipilot Jan 6 '18 at 0:23
2

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.

  • 2
    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
0

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.

  • 1
    This had no effect for me. (Sierra 10.12.6, Mac USB keyboard and internal on MBPro) – scipilot Jan 6 '18 at 0:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .