Keyboard options were introduced in Keyman Desktop 8.0 in response to a common issue – many keyboard packages include multiple keyboards to cater for minor configuration changes. For instance a Tigrigna package has both Eritrean and Ethiopian keyboard layouts, with only a single character difference – the question mark symbol which differs between the two countries. Or Greek keyboards which differ in how the diacritics are typed.
With keyboard options, the keyboard developer can present the user with a dialog box to let them choose how they wish to use the keyboard. This is both less confusing and more flexible than having multiple keyboards.
Now when reviewing this feature a couple of weeks ago, we realized that with some small tweaks, it would become even more useful.
Proposed New Features
Three small updates to the keyboard options feature are proposed:
Testing for base layout. This would enable you to have rules conditional for a French base layout, for example. This, combined with the improvements to mnemonic layouts in Keyman Desktop 8.0, should make it possible to cater for all European base layouts with a single keyboard.
Add feedback on option changes via bubble and icon. While this needn't be limited to notification of option changes, some sort of feedback is really pretty essential for keyboard options to be most useful.
Testing for Base Layout
The test for base layout could be implemented with a special system store, for example:
if(&baselayout = 'FR') + 'q' > 'that key next to Caps Lock' if(&baselayout = 'EN-US') + 'q' > 'that key next to Tab'
Determining how to identify the base layout has not yet been discussed.
Testing for On Screen Keyboard-specific rules
Again, this could be implemented with a special system store. In the following example, the 'Q' key would always show with a capital Q, even though the output would be lower case:
if(&osk = '1') + 'q' > 'Q' if(&osk = '0') + 'q' > 'q' c not technically necessary but shown for completeness
Giving feedback via balloon or icon change
The details of how additional icons could be stored in the keyboard (and the preferred image formats) are not settled. However, in principle it could work as per this example:
store(happy-face-icon) "happy-face.png" store(happy-message) "Keyman is now happy" store(sad-face-icon) "sad-face.png" store(sad-message) "Keyman is now sad"
Determining the icon to use when the keyboard is initially selected would also need to be covered. At this stage, it is not anticipated that the icon would change in the menus or in the configuration screens, but feel free to ask for this – now's a good time to ask!
Keyman 8.0 improved mnemonic keyboards by remapping the On Screen Keyboard to the underlying hardware layout. Previous versions of Keyman did not do this well. This has been a big improvement and makes mnemonic keyboards much more useful with European hardware layouts.
However, apart from this one change, we had to postpone some of the design features that we wanted to add to the On Screen Keyboard. A couple of weeks ago we had a great discussion on how we could improve the On Screen Keyboard by making it more dynamic. While dynamic updates to the keyboard have been on the future feature list for some time, details of how this could work had never been properly explored.
We also linked this discussion to some tweaks to the keyboard options feature introduced in Keyman Desktop 8.0. These were tweaks primarily around testing for base layouts and providing feedback to users when options are selected. The extensions to keyboard options have some relationship to a dynamic On Screen Keyboard but will be expanded on further in a separate blog.
Dynamic On Screen Keyboard
The big breakthrough we made in our discussion was in how we could instruct the On Screen Keyboard to dynamically update. Initially we just thought we could use the existing rules in the keyboard source code to tell the keyboard how to dynamically update. This seemed logical, but the more we looked at it, the more we realised that this would end up being confusing for the end user. There were a few reasons:
Keyman Desktop keyboard rules have to deal not only with basic mapping but also with character reordering and normalisation. These rules would probably be confusing when displayed on the keys.
Some rules make changes to multiple characters in the context but displaying the full output would not be helpful to the end user.
Some rules may input an invisible character but the On Screen Keyboard should instead show a hint for that letter
So we came up with the idea of a new begin statement to cater for the On Screen Keyboard (OSK). This could point to the same group as the normal begin unicode statement, or to a separate group designed to update the On Screen Keyboard. This group could use all the same context matching and finesse that the normal groups could, but the output would only be going to the On Screen Keyboard. So one trick to remember is that the output of the On Screen Keyboard rules will not affect the context for the next keystroke. The new OSK begin rule would be written as follows:
begin OSK > use(osk)
group(osk) using keys
The processing of any groups fired by the begin OSK statement have an important nuance: every matching context rule will be processed in order to render the On Screen Keyboard, for each keystroke. This means that effectively the On Screen Keyboard would run the group 47 or 48 times when updating. This shouldn't have a significant performance cost on computers today. If no rule matches for a given key, then Keyman would render the default output based on either the underlying layout or the US base key (depending on whether the keyboard is mnemonic or positional).
Keeping this in mind, we realised that colour, highlighting, graphics and font hints could be added to the output with a few additional simple statements. These additional formatting hints would be ignored by the keystroke processor, and would just be used by the On Screen Keyboard engine.
bg(colour | default), or background(colour | default)
This would set the background colour for the whole key. The last colour set in the execution of the statements would be the one that would take effect. The colour reference will probably be either a #rrggbb triplet or a standard web colour name.
bg(colour | default), or background(colour | default)
This would set the foreground colour for the subsequent letters to be printed on the key cap. In some scenarios, for example with combining diacritics, this may not be possible, and needs to be investigated.
font(name, size, style)
There are some issues with specifying the size due to the resizeability of the on screen keyboard. It may be specified as a percentage of default size.
image(source-image)
Source-image would refer to a store name which would then cause the image to be embedded in the keyboard file for use in the On Screen Keyboard. Suggested file format would be PNG to allow for alpha transparency. There are issues about sizing and mixing images and text that would need to be resolved.
hint(text)
If the user hovered the mouse cursor over the key, the hint text would be displayed in a balloon. There may be some visual indication on the key of the availability of a hint.
As there may no longer be a static On Screen Keyboard, we may need to specify font and other preferences such as 101 or 102 key layout as well. This is also a topic for further discussion.
Example Dynamic On Screen Keyboard Source File
The following straightforward keyboard will be used as an example of how we envisage dynamic on screen keyboards working.
For simplicity in this example I have not tried to use any pre-composed letters but just left the combining diacritics in place. You'll note that we are using the same rule set for the Unicode rules as for the OSK rules, despite the discussion above. This is because this example is demonstrating the concepts rather than being a comprehensive and complete keyboard layout.
Given the keyboard source above, the Dynamic On Screen Keyboard would display initially as the image below. There isn't anything extraordinary there. The key difference is that there is no static definition for the On Screen Keyboard; rather, Keyman uses the begin OSK statement to define the display of the On Screen Keyboard. Deadkeys (as per the dk(diac) statements) would not be highlighted in any way on the On Screen Keyboard by default. This is because the deadkey statement in Keyman keyboards tends to be used for state management and not purely as a deadkey flags.
Let's look at how the keyboard could be modified to highlight deadkeys. The formatting hints given the example above would be ignored by Keyman Engine for keystroke processing, so let's keep the rules together for now.
Now with an empty context the keyboard would display something like the following mockup:
Finally, let's tweak the keyboard to make the dynamic keys with context highlighted so they are more visible. I'm not going to make the example comprehensive – it'll only cover the grave accent key.
The concepts outlined here present a simple model of how on screen keyboards could give feedback to the end user and help make keyboards more self-documenting. I'd be very interested in any feedback or suggestions you may have – just put them in a comment on the blog.
In the next blog post, I'll discuss how the tweaks to options we discussed can also be used for integration of the On Screen Keyboard.
Updated 23 Aug 2011: In examples, replaced any(diaK) with any(diaO) in context, and replaced deadkey usage with ZWNJ to avoid side-effects with typing diacritic after another letter.
Keyman Developer 8.0 includes the facility to create a combined keyboard and Keyman Desktop installer. However, it is not immediately obvious how to do this. In particular, it may be hard to know where to find the install package for Keyman Desktop, as Keyman Desktop is distributed in through an .exe installer but Keyman Developer asks for an .msi installer! So here's a quick walkthrough.
You'll need to extract the Keyman Desktop .msi file from the .exe installer to your hard drive in order to bundle it in your own .exe installer. Assuming you saved the installer into your Downloads folder, start a command prompt, change directory to the Downloads folder, and run the installer with the -x targetfolder parameter (make sure you create the targetfolder before running the command). In the following example, the installer will extract into C:\Users\mcdurdin\Downloads\keyman.
A couple of dialog boxes later, you'll be left with the .msi file and a couple of other bits and pieces in the folder you chose to extract to:
Now load up your keyboard package in Keyman Developer, and jump to the Compile tab. Click Select Product Installer and choose the .msi file in the targetfolder.
Finally, click Compile Installer. You'll end up with an .exe installer named keymandesktop80-packagename.exe. You can rename this file to whatever makes sense for you.
Starting the installer will present the following splash screen. Note the blurb on the left hand side which lists the keyboards included in the installer.
One final note: if you are planning to distribute your keyboard through the Tavultesoft website, we will automatically bundle your keyboard package with the latest version of Keyman Desktop, so you only need to worry about sending us your .kmp package file.
When using Windows Live Mail 11 with the European Latin keyboard, you may find extra apostrophes appearing when trying to type words such as café. This would appear as caf'é. Similarly, typing a Hungarian word such as ősi would appear as"ősi.
This issue occurs because Windows Live Mail dynamically converts "straight quotes" into “smart quotes” when you type them. This issue is exacerbated because pressing backspace after typing the quote character restores the straight quote, rather than deleting the character you just typed.
To prevent this behaviour, you need to turn off smart quotes in Windows Live Mail. First, close Windows Live Mail (you need to close the icon in the system tray as well), then follow the steps below:
Click Start, type regedit and press ENTER.
Navigate to HKEY_CURRENT_USER\Software\Microsoft\Windows Live Mail\Compose\Preferences\PostEditor\Autoreplace.
If an entry named SmartQuotes does not exist, select Edit > New > DWORD Value, call this new entry SmartQuotes, and press ENTER.
Right-click on the entry SmartQuotes, and select Modify.
Enter the value to 0 and click OK.
Close Registry Editor.
This issue is also documented in Tavultesoft Knowledge Base article KMKB0073. Here's to ending frustrations!
<h1>Symptoms</h1>
<p>When using Windows Live Mail with the European Latin keyboard, you may find extra apostrophes appearing when trying to type words such as <b>café</b>. This would appear as <b>caf'é</b>. Similarly, typing a Hungarian word such as <b>ősi</b> would appear as <b>"ősi</b>.</p>
<p><b>Note: similar symptoms may also appear with some other keyboard layouts that use the quote keys and these instructions should resolve the problem for these other keyboard layouts in the same way.</b></p>
<h1>Background</h1>
<p>This issue occurs because Windows Live Mail dynamically converts "straight quotes" into “smart quotes” when you type them. This issue is exacerbated because pressing backspace after typing the quote character restores the straight quote, rather than deleting the character you just typed.
<h1>Resolution</h1>
<p>To prevent this behaviour, you need to turn off smart quotes in Windows Live Mail. First, close Windows Live Mail (you need to close the icon in the system tray as well), then follow the steps below:</p>
<ol> <li>Click Start, type <b>regedit</b> and press <b>ENTER</b>.</li> <li>Navigate to HKEY_CURRENT_USER\Software\Microsoft\Windows Live Mail\Compose\Preferences\PostEditor\Autoreplace</li> <li>If an entry named <b>SmartQuotes</b> does not exist, select Edit > New > DWORD Value, and call it <b>SmartQuotes</b>.</li> <li>Right-click on the entry <b>SmartQuotes</b>, and select <b>Modify</b>.</li> <li>Enter the value to 0 and click <b>OK</b>.</li> <li>Close Registry Editor.</li> </ol>
With the release of Keyman Desktop 8.0, I wanted to do something special for the team, and so late one evening put together some mug and t-shirt designs with Zazzle:
As I have rather limited graphic design ability, I was actually quite pleased with the designs, and ordered a few of these mugs and t-shirts to give as a surprise gifts to Peirce, John and Gary in celebration of the release of Keyman Desktop 8.0.
I'm happy to say that they liked the mugs and t-shirts, and I now drink all my tea and coffee, at the office at least, out of a mug-of-many-languages. I have to admit that even I, the designer of the graphic, cannot readily identify each and every one of the scripts. I have to look some of them up… Can you identify them all?
Then one evening, John (my father) and my mother took up the challenge of identifying each and every one of the characters on the mug. And discovered a mistake!
Can you spot the mistake? I'll give you a hint: one of the larger letters on the t-shirt is rotated. And on the mug too, of course.
That's what comes of trying to do these things late at night -- by the time I got to the letter in question, I was cross-eyed from looking at so many different writing systems, I just didn't even see that it was sideways.
The letter in question is the Mongolian vowel OE (U+1825):
With a little imagination, one could believe it looks like a pregnant horse when rotated:
So, how did this happen? Well Mongolian is traditionally written vertically from top to bottom in columns running from left to right. Curiously, when embedding Mongolian in a horizontal script such as Latin, the script is rotated 90 degrees. In computing terms, vertical text is not well supported, so the 90 degree rotation became the default Mongolian font on my computer.
Perhaps this is an acceptable way to write this Mongolian letter on the mugs and t-shirts. Nevertheless, I've rotated the letter on the designs, and now you also can buy the t-shirts online.
I'll give a free t-shirt or mug, your choice, to the first person who correctly identifies all the scripts in the design!
For a limited time, we will offer these t-shirts and mugs for sale through Zazzle:
The Keyman keyboard language has two basic types of keyboard layout: positional and mnemonic. In this blog post, I describe the differences between these two types of keyboard layouts, along with notes on now to develop the two layout types. But first, for those who have trouble with the word mnemonic:
For this blog post, I'll use Greek as an example keyboard layout, because the similarities between Greek and Latin letters are familiar to many, and will help in explaining the principles of mnemonic layouts. The same concepts apply to more dissimilar scripts such as Tamil, Lao or Korean.
Positional layouts
So what is a mnemonic layout? Well, I'm actually going to start by defining a positional layout. I think it is important to understand Keyman's basic keyboard layout model, and the nuances of that model, before moving on to the more complex mnemonic layout model.
A positional layout, in Keyman terms, is a Keyman keyboard that defines its rules according to the position of keys on a physical keyboard. With a positional layout, Keyman does not care what is printed on the key cap of each key; it only cares where on the keyboard that key is. We sometimes call positional layouts "typewriter layouts", in reference to the fixed layout of a typewriter.
Here is an example Keyman Greek positional keyboard layout running on various Windows base layouts:
Greek Positional on English (US) system layout
Greek Positional on English (UK) system layout
Greek Positional on French (France) system layout
Greek Positional on Swedish system layout
Greek Positional on Thai system layout
You'll note that the Greek letters are essentially in the same place on each keyboard, apart from one exception. Now, what appears to be an exception is the backslash (on US) and the extra "102nd" key on European keyboards. The image below shows that the backslash (\) key cap actually changes to a pound (#) key cap on the UK keyboard, whereas the 102nd key on the UK keyboard has a backslash on its cap.
The answer is that the key identified by K_BKSLASH on the US English keyboard moves down one row and to the left of the Enter key. The 102nd key, despite having a backslash on its cap, is a new key cap with a different keycode of K_oE2. So while this initially may confuse, remembering this single exception is the key to joy with positional layouts! Actually, the backslash key moves around even on US English layouts – sometimes it is next to the backspace, sometimes below!
Programming a positional layout
Because Keyman's original design was based on US English (as was Windows itself), the positional layout is defined in terms of a US English keyboard, using the names for the keys that logically match the US English keyboard layout, such as K_A, K_SLASH and K_COLON. These names should not be read as having a more literal meaning and could just as easily have been called C01, B10 or C10 (which would be their names in the ISO 9995 keyboard layout standard). However I think that Keyman's key names, while less precise, are much easier to work with on a practical day-to-day basis! We call these 'virtual keys', due to their similarity to Windows' Virtual Key codes. Don't rely on them being identical to Windows Virtual Key codes, however, because they aren't! A couple of examples may be warranted:
+ [K_A] > 'key to right of caps lock, unshifted' + [SHIFT K_A] > 'key to right of caps lock, shifted' + [CTRL ALT K_A] > 'key to right of caps lock, with ctrl+alt'
The alternative method of defining keys in a Keyman keyboard is to use a single character. Internally, the Keyman keyboard compiler will translate these to the applicable virtual keys. With this model, extra shift states such as Ctrl or Alt cannot be accessed. For example:
+ 'a' > 'key to right of caps lock, unshifted' + 'A' > 'key to right of caps lock, shifted'
The Layout tab of the Keyboard Editor works only with Positional Layouts.
Mnemonic layouts
A mnemonic layout, unlike a positional layout, does not care what the physical keyboard is. Instead it reconfigures itself to map to the key caps of the selected Windows base keyboard (usually the same as the hardware keyboard). Taking our Greek keyboard above, and turning it into a mnemonic layout, gives us the following.
Greek Mnemonic on English (US) system layout
Greek Mnemonic on English (UK) system layout
Greek Mnemonic on French (France) system layout
Greek Mnemonic on Swedish system layout
Note how the Alpha α has moved from the 3rd row to the 2nd row on the French layout: that is, it is placed with the letter A on the French keyboard.
The key advantage of a mnemonic layout is that the keyboard developer can create a single keyboard layout that transparently maps onto almost any Latin script layout. Previously, keyboard layouts would need to be redesigned for each base layout that they were to be used with. This leads to a multiplicity of keyboard layouts to support and difficulty for the end user who may not be sure which base layout they use. There are at least 75 different Latin script keyboard layouts included with Windows 7!
A mnemonic layout also relies on the basic idea that the letters A-Z (and a-z), digits 0-9, and all punctuation available on a US English keyboard will somehow be available on any Latin script keyboard. This is true, as far as we are aware, for all Microsoft Latin script keyboard layouts. This means that the mnemonic layout does not translate across scripts, into Thai or Russian physical keyboards, for example. It would certainly be possible to design a mnemonic layout for a Cyrillic base script, which would then work across the various Cyrillic hardware layouts that are available.
Greek Mnemonic on Thai system layout
The example above may clarify the limitation of using a mnemonic layout with a base script keyboard for which it has not been designed. The reality is, however, that the vast majority of the world's keyboards have access to the Latin alphabet via one method or other. For instance, with Thai, the US English key caps are also printed on nearly all Thai keyboards, so switching to a US English base keyboard is all that is needed to resolve this problem.
There are some additional complexities with mnemonic layouts and on screen keyboards. While Keyman does its best to translate a mnemonic layout for display in an on screen interface, deadkeys can make it difficult to display some aspects accurately across all hardware layouts. It can also be hard to find some of the more buried punctuation on some European layouts.
Planning a Mnemonic Layout
There are a few things it helps to be aware of when developing a mnemonic layout. First is to consider the frequency of access for various keys on the keyboard. For instance, many Greek keyboards use vertical bar (|) to access the iota subscript character <<IOTA SUBSCRIPT>>. The problem here is that vertical bar is not easy to access on many European layouts, being accessible only via AltGr+Shift combination on some layouts.
Next, some punctuation characters are available only via deadkeys in some European layouts. For example, ^ is only available via a deadkey at the top left of a German layout. This means to access this character (and hence the translation for the Keyman keyboard), the user must type ^ <space>, rather than just ^.
The following table provides some hints as to the best characters to use when designing your mnemonic layout. In general, the further down the table, the more likely you are to have usability issues with deadkeys or AltGr on some layouts. Thus use of these characters should be balanced with the frequency of use and their mnemonic utility.
Once you set this flag, Keyman will no longer use Virtual Keys codes. Instead it will use characters – the characters from the key caps. The Layout mode of the Keyboard Editor will no longer be accessible, and you will need to design your keyboard in Source Mode.
When coding your layout, remember that keys are no longer defined via shift states and key codes. Instead they are defined by the characters on the key caps. For alphabetic keys, the shifted and unshifted letters are not unified: in the unlikely event that 'a' and 'A' were on separate keys, Keyman could handle this situation.
For most rules, using the character-based rules is sufficient. However, it is still often useful to access extended characters with modifier keys. In most cases, we recommend overloading only the A-Z alphabetic keys with Ctrl+Alt, AltGr or similar modifiers, as many European layouts use AltGr (which Windows maps to Ctrl+Alt) to access additional punctuation. For the greatest compatibility do not use modifiers at all.
To use modifiers, the syntax is similar to the virtual key syntax for positional layouts. The key difference is how the key is identified: instead of using a virtual key code, you can use any of the characters that the key itself would produce. For example, the following rules would both match Ctrl+A:
+ [CTRL 'a'] > 'Ctrl A' + [CTRL 'A'] > 'Ctrl A'
It is important to recognise that the second example above does not match Ctrl+Shift+A. Again, by example:
+ ['a'] > 'key that produces an A' + ['A'] > 'key that produces an A, same as previous rule'
+ [SHIFT 'a'] > 'shift + key that produces an A' + [SHIFT 'A'] > 'shift + key that produces an A, same as previous rule'
The current release of Keyman Developer will warn you if you use the function keys or other non-character keys on your keyboard as virtual keys (e.g. K_F1). Non-character keys are those keys that do not normally produce a character and do not differ from language to language (except perhaps in the name on the key cap). Technically this should still work in Keyman Engine. A future update of Keyman Developer may allow you to use non-character keys on a mnemonic layout.
There are of course additional keys on some keyboards, such as Japanese or Brazilian keyboards. In most cases, it is best to avoid designing a Keyman keyboard that relies on these additional keys, as that restricts the usage of the keyboard to users from that region. The same rule applies to the 102nd key on European layouts, of course!
Software Developers Only
A little side note for Windows developers: Windows' use of virtual key codes is inconsistent and confusing when it comes to European layouts. The names of the keys shift, logically, in many cases; for instance the VK_Q and VK_A swap places between US QWERTY and French AZERTY layouts. However, the defined virtual key codes for punctuation in many cases change unexpectedly; for example VK_COLON does not produce a ; on a French keyboard! For this reason, Keyman does not use virtual key codes for mapping mnemonic layouts but instead translates the layout based on the Windows keyboard definition itself.
The Future
We are working on the On Screen Keyboard in Keyman Desktop to improve support for mnemonic layouts and keyboard options. A future version of Keyman Engine may include support, via the keyboard options feature, for providing knowledge of the underlying layout to the keyboard layout. This would allow you to optimise access to Iota Subscript, for example, when it is harder to access on a specific system layout.