Skip to content

fix: leader sequences capture custom-keycode sm_td taps (#29) - #61

Merged
stasmarkin merged 1 commit into
mainfrom
stasmarkin/bug-leaders-not-working
Jun 17, 2026
Merged

stasmarkin merged 1 commit into
mainfrom
stasmarkin/bug-leaders-not-working

Conversation

@stasmarkin

Copy link
Copy Markdown
Owner

Problem

Fixes #29. QMK's leader feature (process_leader) runs after
process_record_user in the process_record_quantum chain, so it only ever
sees a tap that sm_td routes back through process_record().

  • Native keycodes (SMTD_MT(KC_A, MOD)) already take the pipeline path
    (smtd_emulate_key → process_record) since the Bug: Caps Word not working after CKC_SPACE #23 pipeline-taps change, so
    leader sequences worked for them.
  • Custom/derived keycodes (SMTD_MT_ON_MKEY(CUSTOM, KC_A, MOD)) cannot be
    pipelined and fell back to a direct tap_code16 send that bypasses
    process_record. The leader never saw the tap and KC_A leaked to the host —
    exactly the reporter's symptom ("the OS sees an 'a'").

Fix

smtd_tap_code16 now calls smtd_leader_consume(key) before the direct send,
guarded by #ifdef LEADER_ENABLE (zero effect when leader is off). It mirrors
process_leader: get_tap_keycode (unless LEADER_KEY_STRICT_KEY_PROCESSING),
leader_sequence_add, LEADER_PER_KEY_TIMING timer reset, and leader_end on a
full buffer.

Scope (YAGNI): only the tap path is covered — holding a custom mod-tap during a
leader sequence is not added to the buffer, since leader is a tap-sequence
feature. Documented in docs/030_known_problems.md.

Testing

New tests/integration/suites/smtd_leader/ runs against a real QMK checkout with
the actual leader feature:

  • native_keycode_tap_is_captured_by_leader — green before and after (proves the
    native case already worked).
  • custom_keycode_tap_is_captured_by_leader — characterizes the bug, now green
    with the fix.

No regressions: integration smtd_full (19) and smtd_caps_word (5) green,
python unit suite 119 OK.

QMK's process_leader runs after process_record_user in the quantum chain,
so it only sees taps that sm_td re-enters via process_record(). Native
keycodes already take that pipeline path; custom/derived keycodes fall back
to a direct tap_code16 send that bypasses process_record, so leader never
saw them and the tap key leaked to the host instead.

smtd_tap_code16 now routes the tap into the leader buffer via
smtd_leader_consume (guarded by LEADER_ENABLE), mirroring process_leader.
Only the tap path is covered, not holds during a sequence.

Adds the smtd_leader integration suite (native + custom keycode).
@stasmarkin
stasmarkin merged commit d32e0b1 into main Jun 17, 2026
4 checks passed
@stasmarkin
stasmarkin deleted the stasmarkin/bug-leaders-not-working branch June 17, 2026 12:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: leaders not working

1 participant