Using the Apple Aluminium Bluetooth Keyboard with Linux

Introduction

I like keyboards without numeric keypads because you don't need to reach as far to get to the mouse. The first keyboard like this that I saw was the "Happy Hacker" keyboard, but I never bought one because there didn't seem to be a version with a UK layout. Eventually I found the range sold by The Keyboard Company, and I bought one of their "Shortboards". This was OK, but it seemed to be unusually thick: the tops of the middle row of keys are about 35 mm above the desk, compared to 28 mm on my previous full-width keyboard. It lasted for a couple of years and then the spacebar stuck; I replaced it with another one the same and then about a week later Apple launched their aluminium keyboards, and opened a shop in Cambridge. Having first established that the one sold in the UK does actually have a UK layout (the pictures on their website and the package are all of the US version) I bought one.

The keyboard is nice and thin: only about 12 mm to the tops of the middle row, which is ergonomically good. The key spacing is the same as a normal keyboard. The feel of the keys is more like a laptop than a regular desktop keyboard, and not everyone will like it: if you're not sure, try it out if you can before you buy one. I wasn't sure at first but now I'm convinced, and using a normal keyboard seems incredibly clanky and clunky in comparison.

The key layout is not as good as the Shortboard, which had a column to the right of enter including home, end, page up and page down, plus insert and delete at the top-right. The Apple keyboard doesn't have any of those; you can get home, end, page up and page down by pressing FN and the cursor keys and delete by pressing FN and backspace, but there is no insert keys at all. It also has some layout oddities which I presume are Apple vs. Microsoft things, and perhaps specific to this UK layout: \, |, `, #, ~, ", @, €, alt and "cmd" are all in different places from a PC keyboard - and in the case of #, it doesn't exist at all! (I can understand that some of these differences have existed forever and cannot now be fixed, but why is € in a different place for heaven's sake? That's only existed for a few years; couldn't they have standardised it then?) See below for fixes to some of these issues.

The main misfeature of the keyboard, however, is that is a bluetooth device. The full width version is USB (only), and the narrow version is bluetooth (only). Quite why Apple believe that users of the narrow version will all want it to be wireless, and none of the users of the full-width one will, is beyond me. The problem with bluetooth, of course, is that it's yet another bit of Linux that will need to be understood and set up correctly. Oh, and it means that it needs batteries: it takes 3 AA cells, and they seem to last only a couple of months.

It took me a ridiculously long time to get this device working properly with my Linux system, which is why I've written this page. Hopefully, if the search engines find it, it will save some other people from some of this agro. The following sections describe how I set up the bluetooth system, the kernel, the console keymaps and X to work with it.

I hear that users of the full-width USB version of the keyboard have encountered their own problems, mainly related to num-lock. This page won't be of much use to them however; if you're not using the narrow bluetooth version, stop reading now.

Bluetooth

The first thing that you need to get is a USB bluetooth dongle. There used to be a web page, maintained by Marcel Holtmann, listing devices that did and didn't work with Linux; however the "Bluetooth SIG" (the industry group backing bluetooth) complained that publishing the list was a violation of some license agreement. This alone is a sufficient reason to not use bluetooth, in my humble opinion; if this page makes you think "WHY CAN'T I JUST HAVE A FRICKING WIRE ?????" then you've understood my mood. Anyway, it looks as if most or all of the commonly-available dongles will work with Linux to some extent. I bought two on Ebay; the first one, marked simply "Bluetooth 2.0 EDR", mostly worked but seemed to benefit from replugging occassionally. The second, marked "Edimax", seems reliable.

If you're really lucky you may find a bluetooth dongle that has "HID proxy mode". In this mode, the dongle appears to the PC as a USB keyboard and all of the actual bluetooth complexity is hidden. This would be ideal, but the presence of this feature is not something that is ever mentioned in the product descriptions and no-one on the bluetooth mailing list was able to suggest any particular models that have it. I bought the Edimax dongle in the hope that it would have HID proxy mode (it was advertised as having a CSR chip, and CSR were the first to introduce the feature); but it didn't. So you'll probably need to set it up the hard way, as I did.

(Another benefit of using HID proxy mode is that you'll be able to use your keyboard in the BIOS setup screens. If you don't have HID proxy mode you'll need to keep another keyboard around for the BIOS.)

So, to make bluetooth work you'll need various kernel modules and some user-space tools. The kernel modules that I have include rfcomm, hidp, l2cap, hci_usb and bluetooth; I'm not sure what they all do. Most likely you'll already have them if you're using a distribution-supplied kernel. Plug in your dongle and see what gets loaded.

In Debian, the user-space tools are in the package bluez-utils. Other distributions will no doubt have something similar. There is some concise documentation in /usr/share/doc/bluez-utils/README.Debian.gz; this includes a section about configuring keyboards and mice which worked well for me. However, according to the expers on the bluez mailing lists, the method described in this Debian documentation is now deprecated. In summary, you need to:

The keyboard should now be working, and should automatically connect on subsequent boots without the need to re-do any of that configuration.

Kernel Support

These keyboards have a couple of "quirks" that the kernel includes support for. On the UK and I believe other European keyboards, the keys to the left of Z and 1 are transposed. (Some of the wrongness of the symbols on those keys is a deliberate Apple/Microsoft thing; but if you look closely you'll probably agree that they would be slightly less wrong if swapped.) This is HID_QUIRK_APPLE_ISO_KEYBOARD. The other is the generation of home, end, page up and page down when you press FN and the cursor keys, plus various other FN related stuff. This is HID_QUIRK_APPLE_HAS_FN and is enabled (in 2.6.25) only if CONFIG_USB_HIDINPUT_POWERBOOK is set. In the regular 2.6.25 kernel, these quirks will be enabled only if the keyboard appears to the kernel as a USB device, i.e. if your bluetooth dongle is operating in HID proxy mode. Otherwise, you need to apply the following patch to net/bluetooth/hidp/core.c:

--- linux-2.6.25/net/bluetooth/hidp/core.c	2008-04-17 03:49:44.000000000 +0100
+++ /usr/local/src/linux-2.6.25/net/bluetooth/hidp/core.c	2008-05-25 13:26:32.000000000 +0100
@@ -678,6 +678,8 @@
 } hidp_blacklist[] = {
 	/* Apple wireless Mighty Mouse */
 	{ 0x05ac, 0x030c, HID_QUIRK_MIGHTYMOUSE | HID_QUIRK_INVERT_HWHEEL },
+        /* Apple Bluetooth alu ISO keyboard */
+        { 0x05ac, 0x022d, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD },
 
 	{ }	/* Terminating entry */
 };

The organisation of these quirks tables will probably have changed by the time 2.6.26 comes out (look for a new file drivers/hid/hid-apple.c). With luck, this feature will have been included (I've posted it to the linux-input list). If not I'll post another patch here.

With these quirks enabled, you should find that your keyboard behaves basically like a PC keyboard would: the keys should produce the symbols that the keys in similar places on a PC keyboard would produce. Furthermore, FN plus the cursor keys should do the right things. One remaining thing that you might want to configure is the default behaviour of the function keys: when pressed, should they generate the F1..F12 codes or the codes for the mutimedia functions also printed on them? The latter is the default; if you want the former, you should echo 2 > /sys/module/hid/parameters/pb_fnmode (and somehow arange for this to happen at boot). In either case, the other behaviour can be obtained by pressing FN.

Keymaps

If you want the keys to produce the symbols that are printed on them, rather than the symbols at the corresponding positions on a PC keyboard, then you'll need to arrange for suitable keymaps to be loaded. (Personally, I've learnt the PC layout and I'm sticking with it, even if the keys now have the wrong thing printed on them (but see below).)

If you decide to make the keymap match the keyboard, it needs to be done twice, once for the console and a second time for X. (I'm sure I was once told that X would read and use the console keymap, but it never seems to have done so for me.) On Debian, the right way to set up the console is to run install-keymap; see its man page for details. In any case, the keymap somehow needs to be loaded using loadkeys at boot.

I forget how the X keymap should be set. As I say, I've left it configured as a UK PC keyboard.

You might imagine that it would be possible to detect the type of keyboard and automatically select a suitable keymap at boot. My guess is that this is not possible with PS/2 keyboards and so is not done, even though it would presumably be possible for USB and bluetooth devices. (One issue is that it would be necessary to have large amounts of keymap data available in the boot partition.)

Swapping Keycaps

Note that to a certain extent it's possible to change the keyboard to match the keymap: the keys are easily popped off and swapped around. Not when you want to move the shifted symbol but not the lower-case one, however. I have swapped the \| (left of enter) and `~ (left of Z) keycaps, and now the only symbols in the wrong places are ", @, #, ` and €. Perhaps I should attack those keys with a marker pen.

Swapping Modifiers

There are a couple of arguments for swapping some of the modifier keys at the bottom-left of the keyboard. Firstly, alt and "cmd" (the "logo key") are reversed compared to a PC keyboard. The same applies to those to the right of the spacebar. Unfortunately these keys are different sizes so swapping the keycaps is not an option. I use them sufficiently rarely that I'm not bothered about swapping them and haven't done so.

The second possibility is to swap FN and ctrl. If you're used to a desktop keyboard with no FN key, you're probably used to pressing the bottom-left key for ctrl. Laptops differ about which way around these keys are, and normally it's not possible to swap them as FN is handled in the keyboard hardware. However in this case FN is handled in software and could in principle be swapped; furthermore the keycaps are the same size and so could be exchanged.

I haven't swapped mine, because I don't use the bottom-left control key; I have for years re-bound caps lock as control. I do however use FN to get home, end, page up and page down. If you wanted to swap them, you'd need to hack the kernel code that implements HID_QUIRK_APPLE_HAS_FN. (This raises the issue of why this is done in the kernel, rather than in the keymap.)

Delete, and Control-Alt-Delete

I've recently been told that delete is obtained by pressing FN and backspace, so presumably ctrl-alt-del can be got by ctrl-alt-fn-backspace - if you have enough fingers! The following describes how I dealt with the missing delete key before I knew this:

Having no delete key is a pain, especially as it means there's no way to send the "three fingered salute"! For a few weeks I had a second keyboard plugged in just to use its delete key to shutdown. The obvious solution is to use the eject key, at the top-right of the keyboard, for delete. (And I believe that ctrl-eject may mean power off on some Apple systems.) Initially I assumed that this would require a fix in the kernel, but it turns out that the console keymap can be used to make any key a "reboot" key. The eject key has keycode 161, so simply adding this to the console keymap is sufficient:

keycode 161 = Remove
        Control Alt keycode 161 = Boot

Note that it's called Remove, not Delete, for some reason.

Of course you'll need to duplicate this for the benefit of X. I've put this in my ~/.xmodmap file; it would probably be better to make it global - and keyed to the particular keyboard - but I don't know how to do that.

keycode 107 =
keycode 204 = Delete

Here it's Delete not Remove, and the keycode number is different. Great eh? 107 is the keycode for the real, non-existant, delete key; most programs seem happy to have both bindings present but bbkeys (see below) isn't.

That should be sufficient to make control-alt-delete work from within X, if it was doing what you wanted anyway. I've written another whole page about control-alt-delete; I use bbkeys to bind it to a utility that pops up a "shutdown, reboot, or cancel?" menu.

Conclusion

Was it worth it? Probably; I do like the keyboard. But it took an inordinate amount of time; I probably wouldn't have started if I'd known. Anyway, I hope it will be easier for the next people to try.

2nd June 2008

Feedback here