ifSecondary config to match deprecated resolveSecondary

I’ve been using resolveSecondary on my home row for a while, and it’s been great. Rollover works fine. I use Colemak, so “A,R,S,T” on the left hand - especially “RST” is a common set of letters.

I saw that it is now deprecated, so I’ve tried replacing it with ifSecondary with advancedStrategy. But rollover doesn’t work as well. The “T” in “RST” goes to the secondary action too often. So perhaps someone can help me.

To test this, I created a macros for each. For resolveSecondary, I have this:

resolveSecondary 200 100 primary secondary

primary:
write primary,
clearStatus
statsRuntime
printStatus
break

secondary:
write secondary,
clearStatus
statsRuntime
printStatus
break

And then for the ifSecondary, I have this in the $onInit:

set secondaryRole.advanced.timeout 200
set secondaryRole.advanced.timeoutAction secondary

and this is the macro:

ifSecondary advancedStrategy goTo secondaryaction

primaryaction:
write primary,
clearStatus
statsRuntime
printStatus
break

secondaryaction:
write secondary,
clearStatus
statsRuntime
printStatus
break

And I get this for resolveSecondary:

primary,macro runtime is:  160 ms
primary,macro runtime is:  16 ms
primary,macro runtime is:  17 ms

But this for ifSecondary:

primary,macro runtime is:  176 ms
primary,macro runtime is:  17 ms
secondary,macro runtime is:  17 ms

I’m not actually sure if the timing is helpful (difficult to know when that starts), but it shows that I am pressing them the same, but getting secondary with ifSecondary, when I would expect the primary.

I’ve tried set secondaryRole.advanced.triggerByRelease 1 with various safetyMargin values but it doesn’t seem to help.

Am I doing something wrong?

So what is the tested setup? This macro on all “R, S, T” keys, and quickly tapping (/rolling) over all the three “R, S, T” keys?

That’s right.

I have noticed that the false secondary is less likely to occur with the above macro than a simple “tapKey” for primary, and “holdLayer” for secondary (my usual setup). Perhaps the time the macro itself takes affects it? If I type my usual “rst”, it happens nearly every time, but a lot less with the above macro.

Well, I admit that those 16ms delays are suspiciously high…

Anyway, I will look into it, just probably not today.

Actually, you could reduce that delay by replacing write secondary, by setStatus secondary, and removing those printStatus commands, and printing the full log from another macro.

But I don’t think that is needed or helpful. If I need more detailed timing information I will write some better means to get them…

I’ll certainly try that. I was wondering if there was another way of timing the presses and overlap period. I suppose that answers that…!

Anyway, thanks for the response. There’s no rush on this - I can just go back to the old method.

Keep up the good work - loving my UHK!

1 Like

I was wondering if there was another way of timing the presses and overlap period.

Not really. It will still tell almost nothing about real time of presses and releases, so really no need to bother. In order to figure out what is going on, we would really need some new feature programmed in the UHK.

Keep up the good work - loving my UHK!

Happy to hear that!

Have you looked also into setting the safety margin and trigger parameters?

set secondaryRole.advanced.safetyMargin 100
set secondaryRole.advanced.triggerByRelease 1

I believe your second parameter from resolveSecondary (set to 100) has not been mapped into the parameters for the advanced role resolution.

I personally have had good results with this in my $onInit:

set secondaryRole.defaultStrategy advanced
set secondaryRole.advanced.timeout 250
set secondaryRole.advanced.timeoutAction secondary
set secondaryRole.advanced.triggerByRelease 1
set secondaryRole.advanced.safetyMargin 50

Oh, and BTW, congrats on your choice of Colemak :wink:

1 Like

Well, I did try triggerByRelease with safetyMargins of -50 to 50, which I thought was the range in the docs. But I’ve just taken a look in the source code, and can’t see the range being applied, so I think I misread that. I’ll try 100 and see how it goes.

Interestingly, the safetyMargin (default 50) is applied, even if triggerByRelease is off, basically by being added to the timeout. But then I don’t fully understand the code yet (and I’ve only just got it compiled, so haven’t checked yet), so don’t quote me on that.

As for Colemak, I thought that if I’m learning a whole new way of interacting with the keyboard, with layers, secondary keys on home keys and no letters on the keycaps, then I might as well jump in the deep end with a new layout too. Colemak-DH seemed to fit the best. I’m really liking it - it seems a much more natural way of typing.

Ah, I see, you’re starting with this now. I’ve been typing Colemak for years, and moved to the UHK already with decent Colemak typing skills. Also, I’ve been using layers before (using AutoHotKey on Windows, and xkb or keyd on Linux), so I’ve now migrated and enhanced my layers on the UHK.

I’ve described my setup here, in case you are interested: GitHub - mhantsch/maxtend: Extended keyboard layers for easy navigation and functionality based on Colemak

Values in docs are recommended, not strictly enforced. If 100 works for you, then go for it.

Interestingly, the safetyMargin (default 50) is applied, even if triggerByRelease is off

This may (or may not) be just my error.

Indeed there was a problem. (Namely, the time machine did not increment time properly, so the last of the three keys behaved as if it was pressed at the time of the first key press.) Nice catch, thanks for report!

Should be fixed by Postponed time fix by kareltucek · Pull Request #669 · UltimateHackingKeyboard/firmware · GitHub

Please, test with this firmware: https://github.com/UltimateHackingKeyboard/firmware/files/12384087/uhk-firmware-10.1.0-postponed_time_fix.tar.gz


Regarding the safety Margin, you are probably right that it is not necessary at that place and probably could be removed. However, it still follows the logic that increasing the margin favors primary role and decreasing it favors secondary role. Either way, I think it is not a big deal and would prefer to remain with the current behavior, as I trust more in my past self who wrote it than I trust in my current self :sweat_smile:.

Fantastic! Thanks @kareltucek - I’m now using ifSecondary without an issue. The quick response is much appreciated.

It might be my imagination, but I seem to be having less false primaries and secondaries with ifSecondary compared to resolveSecondary.

As an aside - the docs for the compilation of the agent and firmware are great (although there is a slight difference in how to build the agent in the firmware README.md and the agent’s - one says npm install and the other npm ci; the first didn’t work for me, but the second did … I know nothing about npm!). Because it’s such a simple process, I was in the midst of debugging this timing issue (and learning the code) when you solved it. Thanks for taking the time to write those docs. Just makes me appreciate the UHK more, knowing I can play around in the source code (… how careful do I need to be not to brick the thing…?).

I trust more in my past self who wrote it than I trust in my current self

oh man, I know that feeling. “Why on earth did I do that? It looks wrong, but it’s worked for the last 5 years…”

Happy to help!

It is possible. Current ifSecondary is implemented anew, and respects original timing when the command gets postponed for some reason. Original resolveSecondary always worked with time as it saw it.

ci stands for clean and install. For clean installation it should not make difference. But npm is npm, can’t say that I am surprised :person_shrugging:.

Well, a badly written loop can brick it quite easily…

But you can always unbrick it. It is pain though, as you need to disassemble the right half…

Also, having a backup keyboard around is a good idea for when your code edits do unexpected things…

Please make sure it’s marked in the docs as a recommendation. I also was not sure when I configured it whether the firmware would accept it. I originally read the docs as “the firmware won’t allow numbers outside that range”. Just by experimentation I learned that it works with 100 or 150 too.

Brilliant, thanks. I was another one like @simk who’d been using resolveSecondary extensively to give me god-like powers of holding down (e.g.) the “s” key for 200ms then sending ctrl-s (or “s” if less). This had the bonus feature of diagnosing when I’m tired and typing slower, as me typing w would close a window or typing an ‘a’ would select all text then replace it with whatever character I typed next lmfao.

The default ifSecondary/Primary wasn’t working perfectly and was giving me many false secondaries. Adding the code to $onInit seems to have sorted the falsehoods, fingers crossed :smiley:

I LOVE my UHK, and now I love it more!!!

1 Like