From 5104ff89656983d3e029c750182e25b20e24e268 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 14 Apr 2026 20:06:20 +0000 Subject: [PATCH] Fix Cmd+Shift+V: add timing-based same-hand hold for mod-taps in get_chordal_hold Agent-Logs-Url: https://github.com/timfee/qmk_userspace/sessions/682413db-c19e-483e-bdef-6b171183b6de Co-authored-by: timfee <3246342+timfee@users.noreply.github.com> --- users/timfee/timfee.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/users/timfee/timfee.c b/users/timfee/timfee.c index 4160e9d0..3a476b63 100644 --- a/users/timfee/timfee.c +++ b/users/timfee/timfee.c @@ -26,15 +26,35 @@ const char chordal_hold_layout[MATRIX_ROWS][MATRIX_COLS] PROGMEM = { }; // ── Chordal Hold per-key override ── -// Layer-tap keys (ESC_L2, MIN_L1) must always resolve as hold when -// another key is pressed so the layer activates — even for same-hand keys. -// Mod-tap keys use the default layout-based logic (cross-hand = hold). +// Layer-tap keys always resolve as hold so the layer activates for +// same-hand keys. Cross-hand mod-tap chords always resolve as hold. +// Same-hand mod-tap chords use a timing heuristic: if the other key +// arrives within 150 ms of the tap-hold key press it is a fast typing +// roll (tap); otherwise the user is deliberately holding a modifier +// for a shortcut like Cmd+V or Cmd+Shift+V (hold). +#define CHORDAL_SAME_HAND_MS 150 + bool get_chordal_hold(uint16_t tap_hold_keycode, keyrecord_t *tap_hold_record, uint16_t other_keycode, keyrecord_t *other_record) { + // Layer-tap: always hold (layers need same-hand access). if (IS_QK_LAYER_TAP(tap_hold_keycode)) { return true; } - return get_chordal_hold_default(tap_hold_record, other_record); + + // Cross-hand: always hold (standard chordal behaviour). + if (get_chordal_hold_default(tap_hold_record, other_record)) { + return true; + } + + // Same-hand mod-tap: timing decides tap vs hold. + if (IS_QK_MOD_TAP(tap_hold_keycode)) { + uint16_t elapsed = + other_record->event.time - tap_hold_record->event.time; + return elapsed >= CHORDAL_SAME_HAND_MS; + } + + // Any other same-hand combo: tap. + return false; } // ── Combos (matching Vial config) ──