holdKey & ifDoubleTap delay after upgrade

I’ve just upgraded my UHK60 from R11 to R16 (in steps, not in one hit lol), and pretty much everything is working OK!!

One issue I’ve got is my Left Ctrl macro. I do have a workaround but would like to see if it can be fixed.

The macro (which worked perfectly on R11) is:
holdKey leftShift
ifDoubleTap tapKey capsLock

This was assigned to Left Shift key, and aside from instances where I typed “Hi John” where the H and J were tapped inside the time window (resulting in “Hi JOHN”), it was great.

Now there’s a short delay on the Shift kicking in, so when I go to capitalise a word, most of the time it doesn’t fire and I have to go back and hold the Shift key a fraction longer for it to kick in.

Having said that, I’ll probably move the Caps Lock to an unused key, as I rarely if ever use it, but wanted to post this here in case there’s a better way to do this function. I have played with the timers, and I think dropping the Timeout to 200ms helped a bit, but I don’t have any empirical evidence of this.

Does it make a difference if you swap the parts around?

ifDoubleTap final tapKey capsLock
holdKey leftShift

Both ways work fine with no noticeable delay here on UHK80 (as long as you fix the uppercase T typo in ifDoubleTap :wink:).

BUT, while checking this, I noticed that Agent didn’t give me an error notification for the ifDoubleTap typo when saving to keyboard without first mapping it to a key. After mapping the macro to a key, and then saving to keyboard, it throws the error…

I’m using latest master branch FW v16.1.1 #c90ed9e, and latest master Agent v9.0.1 8c78f8c. I see there’s been a lot going on lately, so I’m not sure when it started (or if it’s just me).

This was assigned to Left Shift key, and aside from instances where I typed “Hi John” where the H and J were tapped inside the time window (resulting in “Hi JOHN”), it was great.

This is interesting. Are you saying that your flow was:

  • tap shift+h
  • write 'i ’
  • tap shift+j, this activates the doubletap caps lock
  • you write OHN using the caps lock rather than shift

If so, we may have simply fixed doubletap to get broken by an intermediate action.

BUT, while checking this, I noticed that Agent didn’t give me an error notification for the ifDoubleTap typo when saving to keyboard without first mapping it to a key. After mapping the macro to a key, and then saving to keyboard, it throws the error…

Macro args. Macros with args need to be validated in context of their arguments, so at the moment we only validate macro bindings.

I see this is nonintuitive and problematic and will come up with a fix soon.

1 Like

Thanks everyone for the input, and the ifDoubleTap typo was mine in this post - the macro is correct.

I’ve swapped the order, and while the “Hi JOHN” behaviour is still happening, it may have fixed the delay issue. I’ll test further during the day and advise.

EDIT: Confirming behaviour is still happening. Maybe just needed the coffee to kick in so I type faster :rofl:

Wont work long though. Firngrod is onto fixing this bug/“bug”.

1 Like

The doubletap thing is fixed now, but I also experience an issue lately with holdKey seeming slow to take effect from macros. Either that or macros starting slower?

I’m trying to use a holdKey variant of Laszlo’s “Lazy Double-Tap” macro. I want to be able to use OS (Windows) key repeat on both single-tap and double-tap.

In the following macro, holdKey works fine for singletap-and-hold, but not on doubletap-and-hold:

ifGesture timeoutIn 200 $thisKeyId final holdKey &macroArg.2  // double-tap
holdKey &macroArg.1  // single-tap

Is this a bug, or do I just not understand how ifGesture works (as usual :sweat_smile:)?

I saw you’d made some changes to doubletap stuff recently, so I’m using master branch FW v16.2.0 #01421a1.

The changes to doubletap behavior should only affect ifDoubletap. There should be no changes to ifGesture.

1 Like

I’m trying to use a holdKey variant of Laszlo’s “Lazy Double-Tap” macro. I want to be able to use OS (Windows) key repeat on both single-tap and double-tap.

This is an interesting point.

What goes on:

  • ifGesture looks into the queue and sees the queue matches its own keyid list
  • so it evaluates itself as success
  • it removes the matched keypress from the queue
  • then it continues executing the macro, within its original context, which is the context of the first tap.
  • the first tap was already released, so the holdKey exits immediately.
  • (Phil is now confused, because he still holds the second tap and expects the holdKey to evaluate as still held because of it.)

So the behavior is correct by specification, but I do see that in this case, the specification is probably wrong.

It is possible to amend the ifGesture behavior so that it inherits keystate of some of the matched keys and so inherits its key held / released semantics in this special case. However, a question is what the generic behavior should be.

Consider:

  • gg mapping - this is the above discussed case
  • gd mapping - in this case, should we inherit the d key state?
  • gde mapping - what if there is multiple keys.
  • should we inherit the scope of the longest active matched key? They may not be released yet, so we don’t know. So clearly not.
  • should we inherit the scope of the last key in the list? But there is the orGate option.
  • if we simply overwrite the owner key, can something go wrong? Can we fail some test further down the macro because of that?

@Firngrod, @maexxx your opinions are desired.

1 Like

@firngrod, please, provide more details. Maybe in a new thread (git or forum).

Given this prompt, my guess would be that the fix of Macros_CurrentMacroKeyIsActive has made some macros postpone for longer (as they should), which in turn makes your keys postponed for longer?

@kareltucek My first shot at this is: keep the pressed state (of the macro) as long as at least one key in the ifGesture key list including the original macro key remains pressed.

I think that would solve the (probably common) case of @pcooke9 while still keeping other uses functioning reasonably similar as now.

I will. I have some data I think, just haven’t had time to post it yet.

That is not a simple fix as it needs us to keep track of all the keypresses.

Oh, having another look at the code I see what you mean. The ifGesture command has finished, so its thoroughly parsed and re-parsed list of keyids is no longer available.

I think the next best choice would be to use the pressed/released status of the last key pressed that caused the ifGesture to complete.

1 Like

Turns out that it was my lazy fix to the postponed ifRelease bug which caused the issue I observed. It might still become an issue in the future in very specific circumstances.

Basically, the macro was detected as ended because I switched the logic in Macros_CurrentMacroKeyIsActive from checking local macro postponing state (which does not currently work) to just global postponer state. So the macro’s holdKey was terminated though the release had been postponed.

This will still be an issue if the local macro postponing check is fixed if the holdKey is done under postpone or something. I think it might be worth considering making the external checks for macro key released respect postponing of releases in all cases, only letting macro internal stuff register pending releases.

On the plus side, I now have solid reasons why releases should not be allowed to skip the postpone. :smiley:

Macros_CurrentMacroKeyIsActive from checking local macro postponing state (which does not currently work) to just global postponer state.

Alright, this is concerning. Will check that “soon”.

Am I correct that you suggests that never quitting should be considered the correct behavior in the ticket?

Am I correct that you suggest that a postponeKeys holdKey a macro should freeze the entire keyboard until reset?

No, that would obviously be bad.

But there is something to look into. In order to not sidetrack this topic further, I have created an issue in which we can discuss this further:

1 Like