Handling of keyboard modifiers in Haiku
The hardware
In the beginning was the Macintosh
Well, not really. There were many keyboards before the Macintosh already. But it is where the keyboard modifiers in BeOS started from, as several of the early BeOS people were formerly working at Apple.
Apple keyboards have modifier keys set up like so (since the "Apple Extended" keyboard, introduced in 1987):
Control
Option
Command
space bar
Command
Option
Control
This is what Be developers were used to use at Apple, and so, this is what they wanted to preserve in the Be Box.
The PC organ bank
For the Be Box, in order to keep costs low, no custom keyboard was manufactured. Instead, keyboards from the IBM PC compatible market were used. At the time, the reference for these would be the IBM Model M keyboard, introduced in 1986. This keyboard is generally similar to the Apple Extended one. This is not by chance or because one company copied the other: at that time, there was work in progress on the ISO IEC 9995 specification and its predecessor ANSI X3.154-1988. This allowed Be to get a somewhat similar layout on PC and Apple keyboards.
However, the specification initially only gave rules for the physical layout, and also it was not completed when these two types of keyboards were commercialized.
On the Model M keyboard, the bottom row looks like this:
Control
Alt
space bar
Alt
Control
There are only two modifiers: Control and Alt. This means one of the keys from the Apple keyboard had to go, or some trick be used.
Also, the Be engineer wanted to preserve their muscle memory and ergonomics. On Apple machines, the Command key is the one used for most keyboard shortcuts. In fact, older Apple keyboards didn't have a Control key at all (for example on the Macintosh Plus). So, the Alt key on these keyboards was used as a Command key, because it sits in the same convenient place, near the space bar.
International variants
So far we have only looked at US keyboards. These work fine for typing english, but other languages require more symbols (accented letters, or even completely different alphabets). This is accomplished by adding an extra "group" of symbols (just like the Shift key can be used to switch between the lowercase and uppercase groups).
This is where problems really start.
On Apple keyboards, the extra group is reachable using the Option key. This leaves both the control and command keys available for their designated uses. But on IBM keyboards, there is no separate command key. So, IBM decided to repurpose the right Alt key for this role. On these keyboards, the key is renamed to Alt Gr and fills this role of accessing a separate symbol group.
These keyboards look like this:
Control
Alt
space bar
Alt Gr
Control
Notice how this keyboard type is asymertric: the key left of the space bar is Alt, and the key to the right is Alt Gr. These are expected to behave differently.
In BeOS, at the time, this was assigned the same role as the "option" key on Apple keyboards, and this worked fine and everyone was happy.
Note: there is another variant of keyboards used in Japan, with more modifier keys. I am not able to comment on these due to not being familiar with them.
Microsoft breaks everything
Well, not really. In 1995, the ISO specification for keyboards was finally completed. At that time, IBM was not in control of the PC market anymore, with a lot of "clones" or "PC compatible" machines being way more popular than the original. Microsoft, providing the operating system for these machines, was able to decide for some things and tell manufacturers what they should do.
In 1995, they were also about to release a major update to Windows with Windows 95. At about the same time, they introduced the Microsoft Natural Keyboard, which featured extra keys in the space left by IBM between Control and Alt.
These keyboards look like this:
Control
Windows
Alt
space bar
Alt
Windows
Menu
Control
The new key was used extensively in the Windows operating system.
BeOS adjusted to this by assigning new key codes for these new keys, as you can see from the diagram here: https://www.haiku-os.org/legacy-docs/bebook/TheKeyboard_KeyCodes.html they do not follow the nice left-to-right numbering of the other keys, since they were added a little later.
On US keyboards, these new keys were also assigned the same role as the "Option" key on Apple keyboards, since they are physically located at the same place. Finally, BeOS users could get the same experience no matter if they used a PC keyboard (on a Be Box) or an Apple one (on a Macintosh, to which the OS would be ported at about the same time.
But this creates a problem: now, both the "Windows" and "Alt Gr" keys are used by BeOS as Option keys. This is left unsolved to this day. So this is our first problem: we only have one role (OPTION) for two different keys ("Windows" and Alt Gr) which should have different roles.
The current default roles assigned to the keys are as follows:
- Left Control is assigned to the CONTROL role
- Left Windows is assigned to the OPTION role
- Left Alt is assigned to the COMMAND role
- Right AltGr is assigned to the OPTION role
- Right Windows is assigned to the COMMAND role
- Right Control is assigned to the CONTROL role
In Haiku, the OPTION role is used not only to access the extra group of special characters in the keymap, but also for various keyboard shortcuts in applications and in the OS (such as Stack and Tile). This compromise setup on keyboards with AltGr allows to use the AltGr key to access the extra group of special characters, and still use the left windows key for the keyboard shortcuts. On many laptops and "compact" keyboard layouts, the right Windows key does not exist at all, and so, the fact that it is surprisingly assigned the COMMAND role is not often noticed. Still, it would be nice to fix this and have separate, clearly defined roles for the Windows and AltGr keys: one of them exclusively for keyboard shortcuts, the other one exclusively for the special characters.
USB keyboards, and x86 Apple machines
A few years later, both Apple and PC manufacturers switched to using USB for their keyboards. This, at first, seems unrelated to our problems, surely, changing the keyboard protocol will not affect the key positions nad behavior?
Well, not really. But, what it does is allow using a PC keyboard on a Mac, and conversely.
The USB specification does not attribute key codes depending on the physical position of the keys as BeOS does. Instead, it attributes them to key "roles" like so (HID usage tables, section 10):
Usage ID | Usage Name | Usage Type | AT-101 | PC-AT | Mac | Unix | Boot |
---|---|---|---|---|---|---|---|
E0 | LeftControl | DV | 58 | ✓ | ✓ | ✓ | 4/101/104 |
E1 | LeftShift | DV | 44 | ✓ | ✓ | ✓ | 4/101/104 |
E2 | LeftAlt | DV | 60 | ✓ | ✓ | ✓ | 4/101/104 |
E3 | Left GUI | DV | 127 | ✓ | ✓ | ✓ | 104 |
E4 | RightControl | DV | 64 | ✓ | ✓ | ✓ | 101/104 |
E5 | RightShift | DV | 57 | ✓ | ✓ | ✓ | 4/101/104 |
E6 | RightAlt | DV | 62 | ✓ | ✓ | ✓ | 101/104 |
E7 | Right GUI | DV | 128 | ✓ | ✓ | ✓ | 104 |
With notes for the two "GUI" keys: "Windows key for Windows 95, and Compose. Windowing environment key, examples are Microsoft Left Win key, Mac Left Apple key, Sun Left Meta key.
What this means is, from an USB keyboard, all we know is that the user pressed the "Left Alt" key. But, on an Apple keyboard, this would be the second modifier key (the one we want to use as OPTION), or on a PC keyboard, it would be the third (which we want to use as COMMAND). And there is no direct way to know.
This makes the default settings in Haiku extremely confusing if you use an Apple keyboard. The hardware swapping of the keys by Apple (compared to a normal PC keyboard) counteracts the software swapping done by Haiku (to use the Alt key as a COMMAND key and the GUI key as an OPTION key). Both Apple and Haiku try to have the COMMAND key just to the left of the space bar, for better ergonomics ans in contradiction to the ISO 9995 specification which mandates the Alt key should be there. And this is our second problem: on Apple keyboards, the keys are not physically located where Haiku thinks they are
The software and user settings
Unfortunately, our problems do not stop at the hardware level.
After just a few years of being a PowerPC only system, BeOS was also ported to Intel machines ("PC compatibles"). This means it will often be used in dual boot with Windows or Linux, and some users will not want to use the Apple-style disposition of the keyboard shortcuts. They instead want their Control key to trigger keyboard shortcuts, as it does in Windows and Linux.
To allow for this, we have added an easy way to switch between the two modes in the Keymap preferences.
The default setting is as follows (without and with an AltGr key respectively:
CONTROL
OPTION
COMMAND
space bar
COMMAND
OPTION
Menu
CONTROL
CONTROL
OPTION
COMMAND
space bar
OPTION
COMMAND
Menu
CONTROL
And the switch to "Windows" mode results in
COMMAND
OPTION
CONTROL
space bar
CONTROL
OPTION
Menu
COMMAND
COMMAND
OPTION
CONTROL
space bar
OPTION
CONTROL
Menu
COMMAND
This means the key labelled "Control" is now the one used for keyboard shortcuts (if you don't have an AltGr key). This layout does not exactly matches how Windows and Linux behaves, since it is just a swapping around of the key roles (based on Apple culture) to different places, but it is close enough that muscle memory will work for users used to Windows and Linux.
If you have an AltGr key and use this mode, your keyboard layout is now completely nonsensical on the right side of the spacebar. And if you also use an Apple keyboard, this swaps the two keys on each side of the spacebar, which can make this even more confusing.
But the confusion on the software side does not stop there. When using a PC keyboard, it would be somewhat confusing to refer to the keys as "Option" and "Command" when they are in fact labelled with a Windows logo and "Alt". So, BeOS (and also Haiku) tries to draw the correct label for example in shortcuts displayed in menus. If you use "Apple" mode, shortcuts assigned to the "COMMAND" key will show an "Alt" icon. If you use Windows mode, they show a "Ctrl" icon instead. But, what if you use an Apple keyboard, where the keys acutally *are* labelled "Alt Option" and "Command"? And, unfortunately, it does not stop there in terms of key labelling. On PC keyboards, for example, German keyboards will label the Control key as Strg (an abbreviation of the German translation of Ctrl). But Apple made a different choice, on their international (non-US) keyboards, they use the ⌥ symbol for the Option key, while on US keyboards they write Option. The Command key is always labelled with both the Apple logo and the ⌘ logo, the latter being used in the GUI. This was picked during the design of the original Macintosh to avoid having the Apple logo everywhere.
So, to render the correct icon in our menus, we need to do the following checks:
- Is the keymap configured in Apple or Windows mode? (already done)
- Is the keyboard an Apple or PC one? (not done yet, it can probably be detected by having a list of USB device and vendor IDs for Apple style keyboards)
- If it's an Apple keyobard, is it an US or international one? (fortunately this can also be detected: Apple keyboards are ones of the very few that are able to report language/keyboard layout information through USB descriptors).
So here is our third problem: We don't detect which type of keyboard is connected to adjust what symbols are shown in menus
I am leaving aside the Alt Gr case here: since it results in identically labelled keys (left and right "Windows" keys) to have different roles, it is not possible to show the fully correct icon in the menus for keymaps with an AltGr key.
The interface kit has a get_keyboard_type function to get the keyboard type, but there is no documentation as to what this exactly means. And the return value is a 16-bit integer, which can't be used to return even the USB device and vendor IDs (that would need 32 bits, and would not include support for non-USB keyboards). So we likely have to make some changes to that function.
And then there's documentation
The user guide is made of static screenshots and text, and so it cannot be adjusted dynamically like the menus in the real GUI. So it has to make a choice on how it refers to the shortcut keys.
There are two options:
- Refer to the key "role", for example, tell users that most shortcuts are reachable using the "Command" key, and let them figure out which key that is,
- Refer to the key label in the default setting and with the most common keyboard layout, that is, shortcuts set in Apple mode while using a PC keyboard.
The user guide currently goes with the second option, and so, the main shortcut key is referred as "Alt".
On the other hand, the developer documentation and API refers to the key role. So there are constants for B_COMMAND_KEY and B_OPTION_KEY, but no mention of "Alt" or "Windows" keys anywhere.
This result on a fourth and final problem: The developer and user documentations don't refer to keys in the same way. But I don't know if this one is worth fixing.