getreuer / qmk-keymap

My keymap & reusable QMK gems
Apache License 2.0
301 stars 45 forks source link

Advice on same side rolling issues and home row mod activation #33

Open mejobloggs opened 1 year ago

mejobloggs commented 1 year ago

I roll a lot when typing, plus I'm using Canary layout which I think increases rolls.

w l y p b   z f o u '
c r s t g   m n e i a
q j v d k   x h / , .

On the right hand, sometimes when typing:

If I go crazy and type a bunch of same-hand home row letters fast, it occasionally triggers ctrl or shift etc.

I thought same hand activations were blocked? Well... they seem mostly blocked because if I intentionally try to e.g same-hand uppercase a letter with shift, it doesn't work.

Is this just how it works and I need to learn to roll less? Or perhaps I've made a mistake in the config implementation?

My config: https://github.com/mejobloggs/qmk-crkbd-keymap-mejobloggs-achordion

By the way, thank you very much for your keyboard related writings on your website. I have really appreciated reading through

mejobloggs commented 1 year ago

Ah maybe this should have been in the discussion section. Sorry I am new to github etiquette

getreuer commented 1 year ago

No worries about bug vs. discussion thread, either is fine by me.

Thanks for checking out Achordion and reporting this! You are right, this is a limitation with Achordion, and come to think of it, this isn't made clear in the documentation.

For "ien", this being an ideal one-hand inward roll, it's safe to say that you press all three keys to go down rapidly before the tapping term. Form there, here is what I speculate happens from my own experience.

  1. While the roll is super fast to press, it is slow to release. Maybe it takes a little too long to release i and the e back up and QMK is considering both of them as "held" and the n as "tapped". Or maybe all three are "held".

    +--------------!--+
    | I            !  |  -> Held
    +--------------!--+
       +---------!----+
       | E       !    |  -> Held
       +---------!----+
            +----!------ . .
            | N  !     
            +----!------ . .
                 !
    |--------------!--------------> Time
                 !
                Tapping term
  2. QMK sends the first hold press for i to Achordion. Achordion buffers it and waits on deciding what to do with it.

  3. QMK sends the second hold press for e to Achordion. This is where the problem is. As a simplifying design choice, Achordion considers at most one tap-hold key at a time in an "unsettled" state, where it is still deciding whether the key is being tapped vs. held. This works fine most of the time, but not in this scenario. If two tap-hold keys are held at the same time, then Achordion settles them both as held (this way chording multiple homerow modifiers works) and sends on the hold events for both keys. In effect, this holds the Shift and Alt mods.

  4. QMK sends the event press for n. Depending on whether QMK thinks it is tapped vs. held, the end result is Shift+Alt+n or Ctrl+Shift+Alt.

Similarly for "ion", I speculate that all three keys are being held longer the tapping term:

+--------------!--+
| I            !  |  -> Held
+--------------!--+
     +---------!------+
     | O       !      |  (Regular key)
     +---------!------+
          +----!----------+
          | N  !          | -> Held
          +----!----------+
               !
|--------------!--------------> Time
               !
              Tapping term
  1. QMK considers i as held, and Achordion buffers it.
  2. o is a regular (non-tap-hold) key. Since it is on the same hand, Achordion settles i as tapped and "io" is typed.
  3. QMK considers n as held. At this point, Achordion is still occupied with the i key, since it hasn't been released yet, and n is settled as held. The end result is typing "io" and holding Ctrl.

If you'd like to confirm, type these sequences on the QMK Configurator key tester and see what key events it prints out.

Unfortunately, I'm not sure when or if I can properly fix this. Extending Achorion to consider multiple tap-hold keys at a time would be complicated, and it likely would introduce new edge cases. I need to think about how that might be done. But it's not all bad news! A tweak that has eliminated this problem for me is to use a per-key tapping term and increase it a bit, say +15 ms, on those slower ring and pinky fingers.

config.h

#define TAPPING_TERM 175
#define TAPPING_TERM_PER_KEY

keymap.c

uint16_t get_tapping_term(uint16_t keycode, keyrecord_t* record) {
  switch (keycode) {
    // Increase the tapping term a little for slower ring and pinky fingers.
    case HOME_S:
    case HOME_T:
    case HOME_A:
    case HOME_I:
    case QHOME_A:
    case QHOME_S:
    case QHOME_L:
    case QHOME_SC:
      return TAPPING_TERM + 15;

    default:
      return TAPPING_TERM;
  }
}