Apple - Linux on Mac hardware: How to remove caps lock delay on Apple MacBook Pro aluminum keyboard when booted to Linux
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:
- save the code below as
disable-capslock-delay.c
gcc -o disable-capslock-delay disable-capslock-delay.c
HIDDEVICE=$(dmesg | grep Apple | grep Keyboard | grep input0 | tail -1 | sed -e 's/.*hidraw\([[:digit:]]\+\).*/\/dev\/hidraw\1/')
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;
}
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.
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
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.