Skip to content

Technical Notes: Keylayout Files

Alexei Baboulevitch edited this page Jan 22, 2014 · 3 revisions

There's another way to use custom keyboards on OSX, and that's using a .keylayout file. These files can contain complex state information based on key sequences, which makes them well-suited for transliteration. Why use this method over a compiled input method binary? For me, I prefer to stay away from custom code as much as possible, and instead rely on the OS to do the heavy lifting for me. When all my behavior is specified in a text file, there's a lot fewer things that can go wrong. Furthermore, the .keylayout format is pretty clearly specified. Another advantage is that existing state information — for example, Option-e followed by a vowel — can theoretically be preserved, though I haven't written the code to do that yet. (A fun exercise in dependency management!) Finally, with the .keylayout approach, you're free to generate keyboards from any layout you choose, and without the need for a compiler.

There were a few problems with this approach. First of all, Apple's XML is non-compliant; control characters can be encoded as hex sequences (�), and that's strictly disallowed by the XML standard. Unfortunately, most XML parsers refuse to deal with illegal XML. I had to regex-replace these hex characters with placeholders and then stick them back in once I finished with the XML.

(I say "Apple's XML", when really, I was using Ukelele's "New From Current Input Source" command. However, resolving the character sequences broke the keyboard, so I'm pretty sure this is the standard way to do it.)

Apple also seems to be picky about the XML formatting. For example, I couldn't get anything other than shortened tags (<tag attr="name" />) to work. Fortunately, NSXMLDocument allows you to preserve formatting.

When writing my converter, I discovered that apparently Apple expects all Command shortcuts to use Latin characters. This required some careful state massaging.

To install and use .keylayout files, you still have to do the same login-logout dance as with the input method, though at least you can still delete them. Unfortunately, it seems that all .keylayout keyboards show up under "Other" and don't display the keyboard layout. As far as I can tell, this can't be fixed.

One final issue is that Terminal behaves oddly when you have multiple state changes in a row. In this case, the input method is superior, since you can specify exactly how it behaves based on user actions.

Clone this wiki locally