Warning: 20A4 Left and right modifiers should not both be used in the same rule character offset: 3

Trying to create my first keyboard and I get this message a number of times in the Messages window when I try to test it. I’m guessing it is because for a number of my characters, they are using the same character (but with some modifying characters to go along with them), and Keyman Developer isn’t liking that I’m doing that. These errors are on for my lines 6, 7, 8, 9, 10, 16, 17, 18, 19, and 20. I’ll include my code, lines 6 through 20. Any help would be greatly appreciated!

+ [SHIFT RCTRL LALT K_U] > 'Ų̀'
+ [SHIFT RCTRL LALT K_O] > 'Ǫ̀'
+ [SHIFT RCTRL LALT K_I] > 'Į̀'
+ [SHIFT RCTRL LALT K_E] > 'Ę̀'
+ [SHIFT RCTRL LALT K_A] > 'Ą̀'
+ [SHIFT RCTRL K_U] > 'Ù'
+ [SHIFT RCTRL K_O] > 'Ò'
+ [SHIFT RCTRL K_I] > 'Ì'
+ [SHIFT RCTRL K_E] > 'È'
+ [SHIFT RCTRL K_A] > 'À'
+ [RCTRL LALT K_U] > 'ų̀'
+ [RCTRL LALT K_O] > 'ǫ̀'
+ [RCTRL LALT K_I] > 'į̀'
+ [RCTRL LALT K_E] > 'ę̀'
+ [RCTRL LALT K_A] > 'ą̀'

You should use either left OR right, not both. We recommend RALT as it has fewer problems with shortcut keys in applications

I’m looking to somehow accommodate a number of characters, specifically characters that have the ogonek an acute and grave accent marks. I’d thought I’d had them all neatly assigned, but then I get errors kicked out. Is there a way around these errors and still use these keys? If that is a bad idea, how would you recommend I accommodate these characters?

You may want to use the “deadkey” approach where a key such ` is a “deadkey” (produces nothing) but impacts the following key:

+ "`" > deadkey(grave)
+ "~" > deadkey(ogonek)
dk(grave) + [SHIFT K_U] > "Ù"
dk(grave) dk(agonek) + [SHIFT K_U] > "Ų̀"> 

I didn’t test this, but I think it would work.

For some reasons that we discourage use of mixed left & right modifiers:

  • Probably the most significant: there’s a “fun” internal Windows limitation

    • AltGr on Windows internally emits LCtrl+RAlt (yes really) on European keyboards, so that causes confusion with rule matching
  • Many computers don’t have RCtrl. Take a look at a macbook keyboard for example.

  • Some computers don’t have RAlt, but this is less common.

In fact… because of the limitations imposed by the last two points, we only recommend use of Shift and RAlt for use for best compat on Win and mac. LCtrl, LAlt, RCtrl, Ctrl, Alt are all discouraged.

  • It’s good to leave LAlt unused due to Alt’s frequent use in keyboard shortcuts in many applications.
  • For keyboards that actually don’t include a RAlt key, we allow simulating this by using both LCtrl and LAlt. So, don’t expect any rules relying on LCtrl + LAlt to work as expected.
  • On some platforms, Ctrl is used for numerous keyboard shortcuts; it’s generally wise to avoid interfering with them.

We’re willing to let some use of unrecommended modifiers slide without warnings, but the trickiest cases result in the warning you’ve reported here. There are also a few practicality concerns:

  • Consider actually having to type RCtrl+LAlt+Y. Like, position your hand to type it, then consider how it would feel to actually have to use that on a regular basis.
    • Do you find it comfortable to use? Do you believe others would find it comfortable to use?
    • Do you think the average person that would use your keyboard will even remember that the key exists?
      • How often do you make use of keyboard shortcuts in applications? Do you use only the most common ones?
      • Take that and consider how well other people you know tend to use shortcuts. If a simple copy and paste command is something they consider “tricky” and “advanced”… well, good luck getting them to use a complex combination of keys.

Many of our recommendations and warnings exist because they generally result in keyboards that most people will find easier to use.

Which brings us to Lorna’s suggestion: by using the deadkey approach, users can “build” the letters they want to type, piece by piece. A slight twist on her suggestion even allows people to “see” the pieces.

+ "`" > "`" deadkey(grave)
+ "~" > "~" deadkey(ogonek)
"`" dk(grave) + [SHIFT K_U] > "Ù"
"`" dk(grave) "~" dk(agonek) + [SHIFT K_U] > "Ų̀"> 

This would provide visual feedback that your keyboard’s future users may find useful.

I’d still suggest maintaining the use of deadkeys from her suggestion; it prevents Keyman from getting too aggressive about converting “`” or “~” in text when proofreading or making final touches to a document.

Thanks for the suggestions! The deadkey approach seems to work for me, but I won’t know for sure until I test it a bit. I am cautiously optimistic :slight_smile:

Here is the code I ended up using. I used the grave and tilde keys as suggested, but ended up using double quotes as a deadkey for the accent mark since a single quote/apostrophe is used to indicate glottal stops and “sonant surds.”

+ U+0022 > U+0022 deadkey(accent)
+ "`" > "`" deadkey(grave)
+ "~" > "~" deadkey(ogonek)

"~" dk(ogonek) + [K_A] > "ą"
"~" dk(ogonek) + [SHIFT K_A] > "Ą"
U+0022 dk(accent) + [K_A] > "á"
U+0022 dk(accent) + [SHIFT K_A] > "Á"
"`" dk(grave) + [K_A] > "à"
"`" dk(grave) + [SHIFT K_A] > "À"
U+0022 dk(accent) "~" dk(ogonek) + [K_A] > "ą́"
U+0022 dk(accent) "~" dk(ogonek) + [SHIFT K_A] > "Ą́"
"`" dk(grave) "~" dk(ogonek) + [K_A] > "ą̀"
"`" dk(grave) "~" dk(ogonek) + [SHIFT K_A] > "Ą̀"

"~" dk(ogonek) + [K_E] > "ę"
"~" dk(ogonek) + [SHIFT K_E] > "Ę"
U+0022 dk(accent) + [K_E] > "é"
U+0022 dk(accent) + [SHIFT K_E] > "É"
"`" dk(grave) + [K_E] > "è"
"`" dk(grave) + [SHIFT K_E] > "È"
U+0022 dk(accent) "~" dk(ogonek) + [K_E] > "ę́"
U+0022 dk(accent) "~" dk(ogonek) + [SHIFT K_E] > "Ę́"
"`" dk(grave) "~" dk(ogonek) + [K_E] > "ę̀"
"`" dk(grave) "~" dk(ogonek) + [SHIFT K_E] > "Ę̀"

"~" dk(ogonek) + [K_I] > "į"
"~" dk(ogonek) + [SHIFT K_I] > "Į"
U+0022 dk(accent) + [K_I] > "í"
U+0022 dk(accent) + [SHIFT K_I] > "Í"
"`" dk(grave) + [K_I] > "ì"
"`" dk(grave) + [SHIFT K_I] > "Ì"
U+0022 dk(accent) "~" dk(ogonek) + [K_I] > "į́"
U+0022 dk(accent) "~" dk(ogonek) + [SHIFT K_I] > "Į́"
"`" dk(grave) "~" dk(ogonek) + [K_I] > "į̀"
"`" dk(grave) "~" dk(ogonek) + [SHIFT K_I] > "Į̀"

"~" dk(ogonek) + [K_O] > "ǫ"
"~" dk(ogonek) + [SHIFT K_O] > "Ǫ"
U+0022 dk(accent) + [K_O] > "ó"
U+0022 dk(accent) + [SHIFT K_O] > "Ó"
"`" dk(grave) + [K_O] > "ò"
"`" dk(grave) + [SHIFT K_O] > "Ò"
U+0022 dk(accent) "~" dk(ogonek) + [K_O] > "ǫ́"
U+0022 dk(accent) "~" dk(ogonek) + [SHIFT K_O] > "Ǫ́"
"`" dk(grave) "~" dk(ogonek) + [K_O] > "ǫ̀"
"`" dk(grave) "~" dk(ogonek) + [SHIFT K_O] > "Ǫ̀"

"~" dk(ogonek) + [K_U] > "ų"
"~" dk(ogonek) + [SHIFT K_U] > "Ų"
U+0022 dk(accent) + [K_U] > "ú"
U+0022 dk(accent) + [SHIFT K_U] > "Ú"
"`" dk(grave) + [K_U] > "ù"
"`" dk(grave) + [SHIFT K_U] > "Ù"
U+0022 dk(accent) "~" dk(ogonek) + [K_U] > "ų́"
U+0022 dk(accent) "~" dk(ogonek) + [SHIFT K_U] > "Ų́"
"`" dk(grave) "~" dk(ogonek) + [K_U] > "ų̀"
"`" dk(grave) "~" dk(ogonek) + [SHIFT K_U] > "Ų̀"

Now that we’ve made you create a bunch of rules, you could simplify them by using stores.

store(keys)     [K_A]     [K_E]
store(grave)    U+00E0 U+00E8 
store(acute)    U+00E1 U+00E9 
store(ogonek)   U+0105 U+0119 

+ U+0022 > U+0022 deadkey(acute)
+ "`" > "`" deadkey(grave)
+ "~" > "~" deadkey(ogonek)
"`" dk(grave) + any(keys) > index(grave,3)
"~" dk(ogonek) + any(keys) > index(ogonek,3)
U+0022 dk(acute) + any(keys) > index(acute,3)
U+0022 dk(acute) "~" dk(ogonek) + any(keys) > index(ogonek,5) U+0301
"~" dk(ogonek) U+0022 dk(acute) + any(keys) > index(ogonek,5) U+0301

This would simplify your code. You would want to add all the “keys” to the key store (including the uppercase).
Then add the corresponding codepoints for the grave, acute, ogonek stores.
The last two rules allow someone to type the ogonek or acute in either order.

I think I see what you’re going with this, but I’m not familiar with this kind of coding. My code is:

store(keys)     [K_A] [SHIFT K_A] [K_E] [SHIFT K_E] [K_I] [SHIFT K_I] [K_O] [SHIFT K_O] [K_U] [SHIFT K_U]
store(grave)    U+00E0 U+00E8 
store(acute)    U+00E1 U+00E9 
store(ogonek)   U+0105 U+0119

+ U+0022 > U+0022 deadkey(acute)
+ "`" > "`" deadkey(grave)
+ "~" > "~" deadkey(ogonek)

"`" dk(grave) + any(keys) > index(grave,3)
"~" dk(ogonek) + any(keys) > index(ogonek,3)
U+0022 dk(acute) + any(keys) > index(acute,3)
U+0022 dk(acute) "~" dk(ogonek) + any(keys) > index(ogonek,5) U+0301
"~" dk(ogonek) U+0022 dk(acute) + any(keys) > index(ogonek,5) U+0301

And I’m getting the error “Warning: 2085 The store referenced in index() is shorter than the store referenced in any()” for the final 5 lines and won’t compile.

Yes, you need to make sure all 4 stores have the same number of characters. So, what you have in the third position for gave would be the lowercase e with grave (U+00E8), lowercase e with acute (U+00E9), lowercase e with ogonek (U+0119). Since you inserted the [SHIFT K_A] in there, you’ll need to insert the correct codepoints for that. So, maybe this:

store(grave)    U+00E0 U+00C0 U+00E8 
store(acute)    U+00E1 U+00C1 U+00E9 
store(ogonek)   U+0105 U+0104 U+0119

I won’t try to produce the correct stores. I’ll let you figure them out. Basically, what you have in the keys store needs to have the correct character in the same position in the store that is output

You’re on the right track, just need to fill in the grave, acute, and ogonek stores properly. If you don’t know all the codepoints, this page is your friend: Collation Charts
It is organized by A…Z shapes.

I think I have the stores setup properly. The grave and ogonek combo wasn’t working so I had to add a couple extra lines of code at the end. Barring any other problems, I think I have this issue taken care of. I’ll show my code below. One last thing though. I’m wanting to include the schwa character. Would there be an issue with using CTRL or ALT along with “e” as far as creating Windows shortcut issues? I do have the lowercase “L” available and could use that if necessary.

store(keys)     [K_A] [SHIFT K_A] [K_E] [SHIFT K_E] [K_I] [SHIFT K_I] [K_O] [SHIFT K_O] [K_U] [SHIFT K_U]
store(grave)    U+00E0 U+00C0 U+00E8 U+00C8 U+00EC U+00CC U+00F2 U+00D2 U+00F9 U+00D9
store(acute)    U+00E1 U+00C1 U+00E9 U+00C9 U+00ED U+00CD U+00F3 U+00D3 U+00FA U+00DA
store(ogonek)   U+0105 U+0104 U+0119 U+0118 U+012F U+012E U+01EB U+01EA U+0173 U+0172

+ U+0022 > U+0022 deadkey(acute)
+ "`" > "`" deadkey(grave)
+ "~" > "~" deadkey(ogonek)

"`" dk(grave) + any(keys) > index(grave,3)
"~" dk(ogonek) + any(keys) > index(ogonek,3)
U+0022 dk(acute) + any(keys) > index(acute,3)
U+0022 dk(acute) "~" dk(ogonek) + any(keys) > index(ogonek,5) U+0301
"~" dk(ogonek) U+0022 dk(acute) + any(keys) > index(ogonek,5) U+0301
"`" dk(grave) "~" dk(ogonek) + any(keys) > index(ogonek,5) U+0300
"~" dk(ogonek) "`" dk(grave) + any(keys) > index(ogonek,5) U+0300

You could use [RALT K_E] for schwa if you wanted. We don’t recommend just ALT, it’s better to use RALT. Also you can’t add it to your stores because there are no precomposed schwa characters with grave, acute, ogonek. You’ll need write a different set of rules.

Thankfully I don’t need to add accents and such to the schwa. I’ll think about if I want to go with lowercase L or the RALT K_E you suggested. Thank you!

This conversation has been resolved.