How To: Fix USB Keyboards Missing the First Keypress in Linux

I use my laptop as a desktop with an external monitor, mouse & keyboard, and found that recently the keyboard would keep missing the first character of input – and it was driving me nuts. After much googling I found a blog post over at wulftone.com that narrowed the issue down to a USB sleep problem, and described how to blacklist a USB keyboard from going into sleep mode – and it works great!

The way to fix this issue is:

1 – Find the details of your USB keyboard via the lsusb command, like this:

$ lsusb
Bus 002 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 004: ID 1bcf:2885 Sunplus Innovation Technology Inc. ASUS Webcam
Bus 001 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 003: ID 046d:c52b Logitech, Inc. Unifying Receiver
Bus 003 Device 002: ID 045e:00dd Microsoft Corp. Comfort Curve Keyboard 2000 V1.0  <--- Ch-ching!
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

2 – Once you can see your keyboard, if you can’t remember which way the vendor ID and product ID go (it’s that very order), you can get the details (in this case looking at the Microsoft keyboard on bus 003, device 002) like this:

$ lsusb -v -s 003:002
 
Bus 003 Device 002: ID 045e:00dd Microsoft Corp. Comfort Curve Keyboard 2000 V1.0
Couldn't open device, some information will be missing
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0         8
  idVendor           0x045e Microsoft Corp.                   <--- Vendor ID.  Do not take the 0x prefix.
  idProduct          0x00dd Comfort Curve Keyboard 2000 V1.0  <--- Product ID. Do not take the 0x prefix.
  bcdDevice            1.73
  ... More details than most people are interested in ...

3 – Next, edit (or create if necessary) the file: /etc/udev/rules.d/91-local.rules and place the following contents into it:

ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="YOUR-KEYBOARD-VENDOR-ID", ATTR{idProduct}=="YOUR-KEYBOARD-PRODUCT_ID", TEST=="power/control", ATTR{power/control}="on"

So for my USB keyboard I entered:

ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="045E", ATTR{idProduct}=="00DD", TEST=="power/control", ATTR{power/control}="on"

4 – Finally, with that done you can reload the udev rules with the following and you should be all set:

sudo udevadm control --reload-rules

As a final note, I found that this (bizarrely) didn’t work when I used the lowercase hex codes (i.e. 045e & 00dd) – I had to put them to uppercase (045E & 00DD) for it to kick in!

Sanity restored! =D

P.S. If you want to disable your first (i.e. laptop) keyboard and/or are using laptop-mode-tools then the wulftone article has you covered. So many thanks to Trevor Bortin for this fix!

How To: Install the Leap Motion Driver & SDK outside of Ubuntu/Debian Linux

The Leap Motion Leap sensor forms part of some research I’m working on atm, but the drivers only come as .debs packaged for Ubuntu or other Debian-based distros. As I’m on Arch (and don’t really want to run dpkg alongside pacman), I wanted a way to pull out the files from the .deb bundle and stick them in the right place. Luckily, it’s pretty easy to do – here’s how…

Download and Extraction

So, let’s say you go to https://developer.leapmotion.com/downloads and get yourself a copy of the most recent Linux driver, which at the time of writing is: Leap_Packages_1.0.9+8411_Linux.tgz.

Extracting the archive will give you two files:
Leap-1.0.9+8411-x64.deb, and
Leap-1.0.9+8411-x86.deb.

If you look at either of those two files with Archive Manager you’ll see the file data.tar.gz within ’em. Pick your flavour (32-bit is x86, while 64-bit is x64) and extract it.

Inside the data folder you’ve just extracted you’ll find three directories:
etc,
lib, and
usr.

Scripted Install

In the folder with the above etc, lib and usr folders, create a file (call it anything you like, install-leap.sh for example) and dump the following into it:

# ----- Install -----
# Initialisation
sudo mv ./etc/init/leapd.conf /etc/
 
# Device rules
sudo mv ./lib/udev/rules.d/25-com-leapmotion-leap.rules /lib/udev/rules.d/
 
# Daemon
sudo mv ./usr/sbin/leapd /usr/local/sbin
 
# Executables
sudo mv ./usr/bin/LeapControlPanel /usr/local/bin/
sudo mv ./usr/bin/Recalibrate /usr/local/bin/
sudo mv ./usr/bin/Visualizer /usr/local/bin/
 
# Move libs folder
sudo mv ./usr/lib/Leap /usr/lib/
 
# Move shared folder
sudo mv ./usr/share/Leap /usr/share/

Now chmod +x the file so it’s executable and we’re almost ready to go. Unfortunately this doesn’t allow for that easy uninstallation, but you can just manually ‘nix it by throwing the following into another script:

# ----- Removal -----
# Initialisation
sudo rm /etc/init/leapd.conf
 
# Device rules
sudo rm /lib/udev/rules.d/25-com-leapmotion-leap.rules
 
# Daemon
sudo rm /usr/local/sbin/leapd
 
# Executables
sudo rm /usr/local/bin/LeapControlPanel
sudo rm /usr/local/bin/Recalibrate
sudo rm /usr/local/bin/Visualizer
 
# Remove libs folder
sudo rm -rf /usr/lib/Leap
 
# Remove shared folder
sudo rm -rf /usr/share/Leap

Optional: Reload udev rules

Try skipping this section for now and come back to it if your device doesn’t register, ok?

Apparently udev uses the inotify mechanism so you don’t need this (source: http://unix.stackexchange.com/questions/39370/how-to-reload-udev-rules-without-reboot) but I did this anyway and it worked:

udevadm control --reload-rules

Start the daemon & visualiser

Now that’s all done, you should be able to start the Leap daemon with:

sudo leapd

Then plug your leap sensor in and it should work when you run ‘Visualizer’ or such. Cheers!

Leap visualiser on Linux

Update – July 2016

Doing this again today, I needed to move the contents of the /usr/share/Leap folder (i.e. *.ldat) to the /usr/local/sbin folder for leapd to start without errors – also, as mentioned, be sure to run leapd as sudo or it’ll launch (with websocket errors) but it won’t work. Also, I moved the *.so files, “platform” folder and “Playground_Data” folders into /usr/local/bin, which has made that folder a bit of a dog’s breakfast, but it works… Probably a better idea to use “alien” to install the deb, or make a PKGBUILD on arch than this hacky way of cobbling it together.