Mnemonic Layout , Non-Querty Keyboards, and Keyman Web Revisited


I’m recalling an exchange with @Marc some years back about a potential change of interpretation of the &mnemonicLayout store might be changing. It has been a few years and I’ve forgotten specifics and certainly Keyman has evolved a good deal since then, so I would like to revisit the topic.

My recollection was that &mnemonicLayout would be interpreted differently, or ignored, with a Touch or Web environment. Thus the special variables $keymanonly should be used with any operations that would rely on a mnemonic interpretation. A small example keyboard fragment:

store(euro)    'ÇçÐðÝýÿßÑñ'
store(euroMap) 'ጭችድድይይይጽኝኝ'
$keymanonly: + any(euro) > index(euroMap,1)

Would the above still be appropriate for Keyman 13 & 14 where the expectation is that the mapping on the third line only applies in a non-touch, and non-web environment?

A 2nd questions on mnemonics, I’m not familiar with most European keyboards, so I don’t truly know that any of the letters in ‘ÇçÐðÝýÿßÑñ’ are found on physical keyboards. I added the mapping just in case they might be. Is there any downside to this approach?

Finally, what reasons are there not to use &mnemonicLayout set to true in the current keyman language when targetting “any” platform?


Yes, that would still be correct for Keyman 14.

There’s no real downside to this. Most of those keys would be found on one or other European layouts (I haven’t checked them all).

Mnemonic layouts are currently really only supported on Windows. We have plans to extend mnemonic layout support to other platforms (we have a pathway for support for macOS and Linux), but it’s a lot of work. It’s not a straightforward problem cross-platform – especially for web.

If the platform does not support mnemonic layouts, then the keyboard is treated as English US in all cases, so there’s no real downside on platforms other than Windows.

Mnemonic layouts are well suited to most phonetic-style keyboards. Some punctuation marks become tricky as they can be a bit buried on some layouts – for example [ and ] are very accessible on English US but on German QWERTZ are AltGr+8 and AltGr+9. This is exacerbated if you use modifiers along with punctuation, e.g. + [RALT '['] makes sense for English US but is ambiguous for German QWERTZ.

We don’t really support mixing mnemonic and positional style rules – this leads to potential conflicts and is not a tested scenario.

@Lorna may have some additional thoughts here.

Thanks for the explanations @Marc. A small follow up, with the mnemonic layout set to true, is there a way with version 10 of the Keyman language to express a shift-code sequence? I get these warning messages, for the two forms I understand from the virtual keys documentation:


“Virtual key used instead of a virtual character key with mnemonic layout”

[SHIFT ' ']

“Virtual character key used with positional layout instead of mnemonic layout”


Use [SHIFT K_SPACE] if &mnemoniclayout is set to 0 or not present. That means, Shift + the key identified by K_SPACE .

Use [SHIFT ' '] if &mnemoniclayout is set to 1. That means, Shift + the key that generates ' ' on the base keyboard (in this case, almost certainly the space bar). It’s a subtle difference but comes into play more with other keys.

Thanks @Marc , I finally realized that the warning that I received (with &menemoniclayout set to 1) came from a missing $keymanonly: statement. My final solution below which I hope might help out someone in the future:

$keymanonly:  store(&mnemonicLayout) "1"
$keymanonly:  + [SHIFT ' '] > '፡'
1 Like

Revisiting this topic, given the availability now of platform() , should I replace lines using $keymanonly: and $keymanweb: with platform() statements?

Or even create groups that are used for a target platform?

@dyacob, it’s possible. There are certain things that can only be done with the compiler version targets, such as setting system store values (store(&mnemoniclayout) '1' is a good example of this). In other cases, using the platform statements can be more flexible.

When using groups for a target platform, you need to have a starting group which directs to the appropriate group, something like:

begin Unicode > use(select-platform)

group(select-platform)  c note, not 'using keys'
  platform('desktop') > use(desktop)
  nomatch > use(main)

group(desktop) using keys
  c ...

group(main) using keys
  c ...

Thank you @Marc , I gave it a try and found the group switching based on platform settings worked nicely. I realize better now that what I want to do in the separate groups (for desktop, or touch for example) is only to define families of variables with different values. But a store for the same variable occurring in two places leads to an error (I forget that they are global).

Starting with:

$keymanonly: store(vowels) 'abc'
$keymanweb: store(vowels) 'xyz'

is there a means in the current version of the Keyman language to conditionally assign variables that is now recommended? I had imagined platform statements might also be an option, in a form like:

platform('desktop') store(vowels) 'abc'
platform('touch') store(vowels) 'xyz'

but this leads to other errors. If there is not a better/preferred way to achieve conditional assignment, that is fine, I’m mostly thinking about future-proofing the keyboard code.



Yes the if and platform statements are only applicable within rules.

1 Like