keymapper icon indicating copy to clipboard operation
keymapper copied to clipboard

timing issues on group keypress

Open kbilsted opened this issue 1 year ago • 22 comments
trafficstars

Hi I really like the simplicity of keymapper and have spent a lot of time remapping stuff around. I'm facing some issues with chording timing on windows 11 using the latest release.

I want to shortcut enter by pressing two keys. The doc told me to do (J K ) >> Enter unfortunately it forces me to type very slowly when e.g. spelling the name "kjeld".

I then tried

(J K ){!110ms} >> Enter

where I across keyboards see the same pattern

  • It is very rare I can trigger when i simultaneously press j and k
  • I cannot trigger when i first press and hold j and then press and hold k. Even if I try this pattern using two hands to make sure i do it fast enough
  • I can reliably trigger when i first press and hold k and then press and hold j

If I change the configuration to

(K J ){!110ms} >> Enter

I observe the opposite. Now I cannot trigger it using K->J but I can do it with J->K

When I Instead use a more verbose syntax

K !160ms J >> Enter
J !160ms K >> Enter

it seems to work differently and a bit better. Now I'm able to trigger with both keys simultaneously and k->j.. but not j->k only if i press j release j press k it triggers.

Another difference I observe is a delay to the screen when typing j and k on their own.. but that I'm sure is not a problem once you get used to it.

kbilsted avatar Mar 23 '24 10:03 kbilsted

I already noticed that timings after groups do not work correctly and will try to fix it soon. You can also try this configuration. This should prevent triggering it accidentally while typing:

J{K !K} >> Enter
K{J !J} >> Enter

houmain avatar Mar 24 '24 07:03 houmain

Thanks for a quick reply! What does J{K !K} >> Enter Mean?

I read it as j followed by k and not another k after that? Why is this helping me?;)

anyways I tried your suggestion and it was almost impossible for me to trigger anything.

kbilsted avatar Mar 24 '24 08:03 kbilsted

J{K !K} means that K needs to be pressed and released while J is hold. Maybe a group timeout is really what you need but this usecase reminded me of this discussion.

houmain avatar Mar 24 '24 15:03 houmain

@kbilsted Have you tried this:

J{K} >> Enter
K{J} >> Enter

For me this works reliably to trigger enter. It breaks key repeat though. I was able to get key repeat working for J with this config:

J !50ms J >> J
J{K}      >> Enter
# K !50ms K >> K
K{J}      >> Enter

Curiously if I include the commented out line, I can't anymore get enter to trigger reliably without either j or k being included in the output.

Edit: While the first config works reliably, it seems like a bad idea for anything that uses Vim-bindings. The idea is interesting though. I've now been using a US ANSI keyboard for 3.5 months (after >30 years of ISO Nordic) and I still fail to hit Enter at times. I'm going to see if this trick would work for me, but with this instead:

J{F} >> Enter
F{J} >> Enter

ristomatti avatar Mar 24 '24 23:03 ristomatti

@ristomatti I'm not sure where from i got the idea. But I think I will really enjoy it. I also tinker with the idea that it should map to ";" ENTER instead. Since I do a lot of that combination ;) The current setup right now

  • J-K -> Enter
  • J-L -> ;
  • J-Æ -> $"" ArrowRight
  • J-I -> {
  • J-O -> [

kbilsted avatar Mar 25 '24 13:03 kbilsted

@kbilsted Might want to make it >> End ';' Enter, so that you can also use it to complete a line regardles of the location. But note that there might be such a feature in your editor already. WebStorm/IDEA does:

image

ristomatti avatar Mar 25 '24 16:03 ristomatti

Groups with timeouts like (J K ){!110ms} >> Enter should work in the 4.0.0 release.

houmain avatar Mar 28 '24 17:03 houmain

Thanks for the new release! Really appreciate all your work

Using v4.0.0 on windows

using (J K ){!110ms} >> Enter i experience some weird stuff

  • pressing KJ simultaneously usually does not trigger enter
  • Pressing K Then J (or the reverse) triggers the newline.
  • Immediately after this, pressing both keys simultanously fires the trigger
  • Waiting a few seconds and pressing KJ simultaneously usually does not trigger

kbilsted avatar Mar 28 '24 19:03 kbilsted

Currently it should trigger when both keys are pressed and then one of them is released within 110ms.

Maybe you are more after something like the following:

J !50ms K >> Enter
K !50ms J >> Enter

houmain avatar Mar 29 '24 09:03 houmain

I'll try.. but for now the original behaviour is irradic

kbilsted avatar Mar 30 '24 11:03 kbilsted

These both ways seem to work reliably for me on v4.0.0:

NoModifier = !ControlLeft !ControlRight !MetaLeft !MetaRight !AltLeft !AltRight !ShiftLeft !ShiftRight

[default]
  J{F}      >> Enter
  F{J}      >> Enter

# I have this "FJ"-experiment on top of my config, so this NoModifier trick
# was required to avoid breaking mappings later on in the config.
[modifier="NoModifier"]
  J !75ms F >> Enter
  F !75ms J >> Enter

ristomatti avatar Mar 30 '24 20:03 ristomatti

Thanks. Will try out soon. I REALLY like these sort of combos over going to another layer

kbilsted avatar Mar 31 '24 10:03 kbilsted

awesome idea with the NoModifier should go to the readme

kbilsted avatar Apr 02 '24 18:04 kbilsted

@kbilsted Here's a few more utility aliases:

# Exact modifiers
_Meta           = !ControlLeft !ControlRight           !MetaRight !AltLeft !AltGr MetaLeft
_MetaRight      = !ControlLeft !ControlRight !MetaLeft            !AltLeft !AltGr MetaRight
_Alt            = !ControlLeft !ControlRight !MetaLeft !MetaRight          !AltGr AltLeft
_AltGr          = !ControlLeft !ControlRight !MetaLeft !MetaRight !AltLeft        AltGr
_Control        =              !ControlRight !MetaLeft !MetaRight !AltLeft !AltGr ControlLeft
_ControlRight   = !ControlLeft               !MetaLeft !MetaRight !AltLeft !AltGr ControlRight
_Shift          = !ControlLeft !ControlRight !MetaLeft !MetaRight !AltLeft !AltGr ShiftLeft
_ShiftRight     = !ControlLeft !ControlRight !MetaLeft !MetaRight !AltLeft !AltGr ShiftRight

# Modifier groups
EitherControl   = ControlLeft | ControlRight
EitherAlt       = AltLeft | AltGr
EitherMeta      = MetaLeft | MetaRight
EitherShift     = ShiftLeft | ShiftRight

Modifier        = ControlLeft | ControlRight | MetaLeft | MetaRight | AltLeft | AltRight | ShiftLeft | ShiftRight
NoModifier      = !ControlLeft !ControlRight !MetaLeft !MetaRight !AltLeft !AltRight !ShiftLeft !ShiftRight

# Key groups
MouseButton     = ButtonLeft | ButtonRight | ButtonMiddle | ButtonBack | ButtonForward
Digit           = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
Letter          = A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
FunctionKey     = F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | F11 | F12

# Function key symbols on Keychron keyboards
FnRewind        = F7
FnPlayPause     = F8
FnFastForward   = F9
FnMute          = F10
FnVolumeDown    = F11
FnVolumeUp      = F12

# Directional navigation
KeyUp           = I
KeyLeft         = J
KeyDown         = K
KeyRight        = L
Direction       = KeyUp | KeyLeft | KeyDown | KeyRight

Exact modifiers are to prevent the mapped keys from affecting the output. For example if I map AltGr{T} >> Control{T} on Chrome, it won't work as Chrome will actually receive AltGr{Control{T}}.

The Fn* aliases are used to map directly to equivalent media keys on specific apps.

Directional aliases I've used for example to map Escape !200ms Direction >> (Control Alt){Direction} on WebStorm. I've then configured the Control+Alt+IJKL keys to pane navigation within WebStorm as it cannot handle Escape in it's keymaps.

ristomatti avatar Apr 02 '24 19:04 ristomatti

If its ok with you ill grab these for my keyboard github https://github.com/kbilsted/KeyboardLayoutGalore . all contributions welcome. I still need to learn a lot like how to properly do alt-tab... and alt-tab-hold-alt ... but then again i just learned about windowd+ which is amazing when you toggle a lot.

kbilsted avatar Apr 02 '24 20:04 kbilsted

Go right ahead. I'm been planning on posting some of my keeper config hacks here https://github.com/houmain/keymapper/discussions/categories/show-and-tell but I never seem to find time (even though I seem to have infinite amount of time with Keymapper and other OS tweaking). :grin:

I did update my keymapper.conf gist just now though.

ristomatti avatar Apr 02 '24 20:04 ristomatti

@ristomatti thanks i just got bit by not having the [modifier="NoModifier"] enabled

do you use [default] to go back to "normal"

kbilsted avatar Apr 09 '24 12:04 kbilsted

Yup.. Or any other context block.

ristomatti avatar Apr 09 '24 12:04 ristomatti

I wonder if it would be practical to step debug through the code. With a lot of googling and handhelding from JetBrains CLion IDE I might even be able to set it up. At least I've managed to setup on-chip step debugging for some Arduino C++ in the past (pretty much automated by PlatformIO). :thinking:

I'm not exactly sure how it could help but it might still be an interesting experiment. Keymapper's source looks completely foreign to a measly CRUD developer like myself. :grin:

ristomatti avatar Apr 09 '24 13:04 ristomatti

I agree there should be a logging commandline parameter - in .net you can specify logging on different levels so verbosity and where in the code are two different dimensions of configuring the logging. That way you can say e.g. VERBOSE logging.. but only in the ConfigurationEvaluator

but notice that logging may encur time differences that may make debugging difficult especially here where we keypress simultanously.

kbilsted avatar Apr 09 '24 13:04 kbilsted

Yep surely adding verbose logging would be the most practical approach (behind a build flag not to affect performance). It'd clutter the codebase though so I can imagine why it's not there.

ristomatti avatar Apr 09 '24 14:04 ristomatti

yes it could be built as 2 different exe files so both were in the release zip.

kbilsted avatar Apr 09 '24 19:04 kbilsted