ktrl icon indicating copy to clipboard operation
ktrl copied to clipboard

TapHold modifiers used before hold time should queue key actions

Open obar opened this issue 5 years ago • 1 comments

It looks like there is a key queue being built up, but I think it should wait for either the hold time of the tap to be completed, or for key release on the TapHold key, whichever comes first.

With a minimal config; only one layer and these effects:

    KEY_F:  TapHold(Key(KEY_F), Key(KEY_LEFTSHIFT)),
    KEY_J:  TapHold(Key(KEY_J), Key(KEY_RIGHTSHIFT)),

Actual behavior

j pressed   "jg" emitted                          j released
v              v                                     v
---------------------------------------------------------> time
               ^            ^            ^
           g pressed     g released   hold time reached

Expected behavior

j pressed                           "S-g" emitted   j released
v                                        v           v
---------------------------------------------------------> time
               ^            ^            ^
           g pressed     g released   hold time reached


"S-g" = shift+g

OR

j pressed                 "jg" emitted
v                            v
---------------------------------------------------------> time
      ^          ^           ^           ^
  g pressed   g released   j released  hold time (not reached)

obar avatar Aug 04 '20 15:08 obar

Hey again Ori! :smile:
Sorry for my delayed response. Let me shed some more light on what's going on here.

Currently, ktrl operates in a 100% reactive mode with no timers. This means that all the TapHold decision making happens as a reaction to the last key up/down event.

This also means that ktrl doesn't send events asynchronously by itself. It only modifies existing events or appends new events onto the current one. This means the "s-g" emission in your 1st example is not possible with the current design. :sweat_smile:

When ktrl sees a keydown of a TapHold key, it temporarily "buffers" the event. It defers the decision of whether to send it as the tap or as a hold effect till the next event.

If the next keydown ("g") happens before the hold time, it flushes the "TapHold queue". If it happens after the hold time, it drops the queue and sends the hold effect instead.

We could theoretically queue all events until the TapHold key is released (which will be somewhat similar to your first expected behavior diagram), but this will likely make things feel quite jittery/laggy.

Let me know if you have any further suggestion/questions

ItayGarin avatar Aug 21 '20 13:08 ItayGarin