Curious key behavior in macros under colemak-dh on mac

I am trying to do some macro shortcuts as described in the user-guide and noticing that something is off in the way keys behavior.

For example: ifShortcut v final tapKey G-v should trigger paste, however the output is zv. In Colemak-DH the 3rd row is ZXCDV compared to QWR ZXCVB. So instead I tried without any change in the macro zdand paste worked.
The same happens with all combos, i have to refer to the qwr key positions to make it work.

Anyone experiencing similar behavior? i presume is either that I am missing in the configuration, either is something with the way keyboard interacts with the operating system. However, this happens on uhk only. Other keyboards with zmk work flawlessly.

Cheers.

Yes, this is by design. The key abbreviations refer to hardware positions according to en us qwerty layout.

can’t the abbreviations be customized depending on what keymap is active? HW positions are fixed but at the end of the day they are placeholders that shouldn’t be tightly associated to any keymap but the active one.

Better yet, maybe we could use in the macros the hw positions without any abreviation?

How do you envision such customization?

You sure can customize it in the source code.

Doing that dynamically via Agent would mean having to implement a dynamic indirection, furthermore gui to set up those alternative abbreviations, having to serialize that, deserialize that, maintain all that code… In short, a lot of trouble for little benefit.

1 Like

You can use the hw positions without any abbreviations.

Just enter the numeric id if the key. (Use a zero prefixed number for single digit keys.)

is there a hw positions matrix available? that would make many macros pretty independent of keymap making things much easier and transparent … i think.

Yes, I am sure there is somewhere on the forum (or maybe github), just use search.

Or you can simply use the resolveNextKeyId macro.

i think i found it here. Ill try with resolveNextKeyId.

Because all KEYID_ABBREV are always in the US QWERTY layout, they are also independent of the actual keymap used. They are semantically the same as the KEYID numbers.

But yes, I also agree it is somewhat irritating. When you write “abcd” you would expect that string, but rather you get the local host-keymap-specific intepretation of the US keys a b c d. (Same for tapKey etc.)

2 Likes

so for example on querty my key would be in position 88 and in colemak is in position 89.

if i try ifShortcut v final tapKey G-$keyid.89 instead of ifShortcut v final tapKey G-v all i get is unrecognized key abbreviation. I tried as in documentation keyid (89) but getting same error.

You are mixing key ids with scancodes.

Please read this article https://uhk.io/blog/2018/06/23/how-can-i-type-accented-characters-with-my-uhk and then review the grammar in the reference manual while noting which commands take SHORTCUT/SCANCODE/SCANCODE_ABBREV, and which take KEYID/KEYID_ABBREV

1 Like

Have you set your MacOS keymap to Colemak-DH, or is your MacOS set to US QWERTY?

If your Mac uses Colemak-DH, then you need to use the US QWERTY key names for the keys on the positions that will be sent, even if the result are eventually converted to Colemak-DH characters.

The key that on Colemak-DH produces the V character is labelled B on US QWERTY. So you need to use tapKey G-b to create GUI-V. What happens is that the UHK will send the scancode for B (with the GUI modifier), and the OS keymap will convert the scancode to the character V, resulting in GUI-V.

Is your ifShortcut … macro bound to the Z key on the UHK? Can you describe exactly what you want to achieve (which keys do you want to press, and what action to you want to see happen)?

Mac set-up is in fact qwerty. I do have c-dh set-up via carabiner, coz DH is not in the native keymaps. Also when i have colemac-dh active on laptop as well the characters output do not match.

solution that works in this case is ifShortcut b final tapKey LG-v. ok, that i can play with, will try on windows as well, but in all honesty seem special. I feel there is a gap somewhere.

yes, ifshortcut is bound to z but planing to move it to iso key so that i can use with LG-z as well.

The idea behind physical position is actually to not care about the qwerty/colemak/anymap. It should be completely agnostic, pretty much as on zmk.

In fact physical position should be the only reference point and should generate separate scancodes depending only on active keymap.

Still unclear how i can use this in macros, keyid as well since macro syntax seem to accept abbreviations only. Maybe physical positions as abbreviations?

As @kareltucek mentioned earlier, you need to be careful where KEYID/KEYID_ABBREV is used, and which commands need SHORTCUT/SCANCODE/SCANCODE_ABBREV. These are two different types of parameters.

ifShortcutneeds a KEYID (or KEYID_ABBREV) because it refers to a physical key that it will check for. So that will be either the numeric KEYID or the named KEYID_ABBREV as named on US QWERTY. Your ifShortcut b will always refer to the key that is labelled B on a US QWERTY keyboard – no matter what action it does or what scancode it produces in your configuration. This KEYID refers to an absolute key position independent of your keymap, or karabiner, or the host keymap.

tapKey on the other hand needs a SCANCODE or SCANCODE_ABBREV or SHORTCUT. This refers to the code it will send to the host. SCANCODEs are what you configure in Agent for a key press action, or what you will send out in macros using tapKey, tapKeySeq, or write. These SCANCODEs are again labelled according to US QWERTY, but they will be interpreted by your host OS as “the key that is called XXX on a US QWERTY keymap was pressed” and the OS will convert it to whatever your host keymap (or Karabiner) does with it.

So imagine you set your host keymap to Colemak (which is what I do on my laptops). All I have to do on the UHK is use a QWR keymap, because each KEYID will send out a matching SCANCODE. The KEYID f will be the key labelled F on a US keyboard (which is actually a T on Colemak, but the keyboard doesn’t know about it). On the QWR keymap, the key will be mapped to SCANCODE F which is some code that is understood by the host OS that the US keyboard key F was pressed. The host will then convert it according to its local Colemak keymap and map it to the T character which is then actually sent down the line to the current application. Thus, you type on Colemak although your keyboard behaves as a standard US QWERTY keyboard. Your host does the conversion.

Now imagine you set your host keymap to US QWERTY, and you want to type Colemak with your UHK. So the CMK keymap on the UHK will now map KEYIDs to different SCANCODEs. The KEYID f is still the key labelled F on a US keyboard (which will map to T on Colemak in the next step). On the UHK with an active CMK keymap, that key will be mapped to SCANCODE T which is some code that is understood by the host OS that the US keyboard key T was pressed. The host will then convert it according to its local US QWERTY keymap and map it to the T character, which is then sent to the current application. Thus, you type on Colemak although your host understands only standard US QWERTY keyboard. Your keyboard does the conversion.

So you need to think “which US QWERTY key would need to be pressed on a US QWERTY keyboard so that my host conversion yields the character I want”. If your host does some Karabiner magic, then which US QWERTY key do you need to send so you get what you want? That’s the SCANCODE that the UHK needs to send. It is either selected in Agent as the key press action for a key, or it is sent in tapKey, tapKeySeq or write. What the UHK sends to the host are always SCANCODEs.

When you decide which key to press on the UHK to activate a function, that’s when you are referring to the physical key. That’s where the KEYID is used in a macro (like with ifShortcut or ifGesture), or where you click on the key in Agent to select the physical key.

Hope that makes it clearer.

4 Likes

to a very large extent it does bring light.

made it work with keyid as well. like ifShortcut (84) final tapKey LG-z. I made a layer specially to input directly whatever keyid i want to use, somehow resembles me to zmk configurator…sort off.

also, is there a way to use keyid on the 2nd part of the expression?

No.

kindly thank you for the detailed answers. truly appreciate!

I have forgotten we have these:


Add following offsets to the per-slot keyids to get actual keyid:

  RightKeyboardHalf = 0
  LeftKeyboardHalf  = 64
  LeftModule        = 128
  RightModule       = 192
4 Likes