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
14
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://colemak.com/Mac>, apparently PCKeyboardHack, an OS X program for which source is available (<http://pqrs.org/macosx/keyremap4macbook/extra.html>) can disable this delay; perhaps that would be helpful.

Revision history for this message
Jakob Kummerow (jakob-kummerow) wrote :

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) {
  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 != 0x0251) {
      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;
}

Revision history for this message
Glyph Lefkowitz (glyph) wrote :

Thank you so much for posting this workaround, Jakob! I hope this can be integrated into Ubuntu somehow, but until then, I will be far happier when I have to use Linux on a Mac laptop keyboard :).

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.