Caps Lock key has slight delay, even when remapped to "Control" or similar (MacBookPro 5,3, but probably applies to others)
Bug #585244 reported by
Glyph Lefkowitz
This bug affects 3 people
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Mactel Support |
New
|
Undecided
|
Unassigned |
Bug Description
It is a well documented fact that newer mac keyboards induce a slight delay when pressing capslock, to reduce accidental keypresses. However, on OS X, this delay is removed when remapping to another key such as Control. However, this does not appear to be the case in Ubuntu (specifically, Lucid Lynx). So it must be possible to disable the delay in software.
As noted here: <http://
To post a comment you must log in.
The code below disables the caps lock delay. In short, it sends a "Feature report" consisting of the bytes [0x9, 0x0, 0x0, 0x0] to the hidraw device given as parameter. (IMHO it would be nice if the hid_apple kernel module took care of that, but I'm not a kernel hacker.)
The right hidraw device can be found with:
dmesg | grep Apple | grep Keyboard | grep input0 | tail -1 | sed -e 's/.*hidraw\ ([[:digit: ]]\+\). */\/dev\ /hidraw\ 1/'
The code below compiles with GCC, must be run as root (due to device permissions), and must be re-run after every reboot (or keyboard re-plugging), e.g. from /etc/rc.local. I've tested it on Trusty with a wired Apple Aluminum keyboard, German version. Other models might need adaptation of the product ID and descriptor length.
#include <linux/hidraw.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv) { \([[:digit: ]]\\+\\ ).*/\\/ dev\\/hidraw\ \1/'\n" );
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\
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 "HIDIOCGRDESCSI ZE");
res = ioctl(fd, HIDIOCGRDESCSIZE, &desc_size);
if (res < 0)
perror(
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 "HIDIOCGRAWINFO "); "Error: Wrong vendor ID, make sure you got the right "
" hidraw device!\n"); "Warning: Unknown product ID 0x%x!\n", info.product);
res = ioctl(fd, HIDIOCGRAWINFO, &info);
if (res < 0) {
perror(
} else {
if (info.vendor != 0x05ac) {
printf(
return 1;
}
if (info.product != 0x0251) {
printf(
}
}
// Get Feature 256), buf); "HIDIOCGFEATURE ");
buf[0] = 0x09; // Report Number
res = ioctl(fd, HIDIOCGFEATURE(
if (res < 0) {
perror(
} else {
printf("HID Feature Report (before change):\n\t");
for (i = 0; i < res; i++) printf("%hhx ", buf[i]);
puts("\n");
}
// Set Feature "HIDIOCSFEATURE ");
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(
else
printf("Caps lock delay disabled.\n");
// Get Feature 256), buf); "HIDIOCGFEATURE ");
buf[0] = 0x09; // Report Number
res = ioctl(fd, HIDIOCGFEATURE(
if (res < 0) {
perror(
} 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;
}