From c01796d907a1a1b2aecafff67d2e717999aa5599 Mon Sep 17 00:00:00 2001 From: simsalaba Date: Thu, 30 Apr 2026 13:46:58 +0200 Subject: [PATCH] fix: improve typing reliability with better debounce and layer-tap timing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three changes to address letter transpositions, accidental modifier/layer activation, and double letters during fast typing: 1. Press debounce 1ms → 5ms (ZMK default) — 1ms was too aggressive to filter switch bounce (5-20ms), causing double letters and scan-order transpositions like 'left' → 'lfet'. 2. New 'ltl' layer-tap behavior for E/NAV, R/WIN, B/FUNC — the default < had no require-prior-idle, so fast rolls through these keys could accidentally activate layers and produce unexpected characters. The new behavior mirrors the timeless HRM approach (balanced, 280ms tapping-term, 175ms require-prior-idle, opposite-hand trigger positions). 3. HRM require-prior-idle 150ms → 175ms — slightly wider idle window reduces accidental modifier activation during fast typing bursts. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .gitignore | 2 ++ KEYMAP.md | 6 +++--- config/corne.conf | 2 +- config/corne.keymap | 27 ++++++++++++++++++++------- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index e43b0f9..2d1aae7 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ .DS_Store +.zmk_build/ +firmware/ diff --git a/KEYMAP.md b/KEYMAP.md index b409097..699a731 100644 --- a/KEYMAP.md +++ b/KEYMAP.md @@ -66,7 +66,7 @@ The middle three keys on each home row side double as modifiers when **held**: - `hold-trigger-on-release`: allows combining multiple mods on the same hand - `tapping-term`: 280ms — intentionally large; makes behavior timer-insensitive - `quick-tap`: 175ms — rapid same-key repeats always produce taps (e.g., `ll`) -- `require-prior-idle`: 150ms — if you typed any key less than 150ms ago, it always types the letter +- `require-prior-idle`: 175ms — if you typed any key less than 175ms ago, it always types the letter --- @@ -250,8 +250,8 @@ Located in `config/corne.conf`: | Setting | Value | Purpose | |---------|-------|---------| -| Press debounce | 1ms | Near-instant key registration (eager debounce) | -| Release debounce | 5ms | Standard release filtering | +| Press debounce | 5ms | Filters switch bounce while staying responsive | +| Release debounce | 5ms | Symmetric release filtering | | BT min interval | 6 | Locks BT polling for consistent wireless latency | | Sleep timeout | 30 min | Deep sleep after inactivity to save battery | diff --git a/config/corne.conf b/config/corne.conf index 7cefbb9..0324be9 100644 --- a/config/corne.conf +++ b/config/corne.conf @@ -18,7 +18,7 @@ CONFIG_ZMK_SLEEP=y CONFIG_ZMK_IDLE_SLEEP_TIMEOUT=1800000 -CONFIG_ZMK_KSCAN_DEBOUNCE_PRESS_MS=1 +CONFIG_ZMK_KSCAN_DEBOUNCE_PRESS_MS=5 CONFIG_ZMK_KSCAN_DEBOUNCE_RELEASE_MS=5 CONFIG_BT_PERIPHERAL_PREF_MIN_INT=6 CONFIG_BT_PERIPHERAL_PREF_MAX_INT=6 diff --git a/config/corne.keymap b/config/corne.keymap index 94abe1e..4b3131e 100644 --- a/config/corne.keymap +++ b/config/corne.keymap @@ -38,12 +38,12 @@ // - hold-trigger-on-release: allows combining mods on same hand, prevents rolling misfires // - 280ms tapping-term: large value makes behavior timer-insensitive // - 175ms quick-tap: rapid same-key repeats always produce taps -// - 150ms require-prior-idle: eliminates delay during fast typing +// - 175ms require-prior-idle: eliminates HRM misfires during fast typing ZMK_BEHAVIOR(hml, hold_tap, // left-hand HRMs flavor = "balanced"; tapping-term-ms = <280>; quick-tap-ms = <175>; - require-prior-idle-ms = <150>; + require-prior-idle-ms = <175>; bindings = <&kp>, <&kp>; hold-trigger-key-positions = ; hold-trigger-on-release; @@ -53,12 +53,25 @@ ZMK_BEHAVIOR(hmr, hold_tap, // right-hand HRMs flavor = "balanced"; tapping-term-ms = <280>; quick-tap-ms = <175>; - require-prior-idle-ms = <150>; + require-prior-idle-ms = <175>; bindings = <&kp>, <&kp>; hold-trigger-key-positions = ; hold-trigger-on-release; ) +// Layer-taps with timeless settings (prevents accidental layer activation during fast typing) +// Same approach as HRMs: require-prior-idle prevents misfires, balanced flavor +// ensures layer only activates on deliberate hold + opposite-hand keypress +ZMK_BEHAVIOR(ltl, hold_tap, // left-hand layer-taps (E/NAV, R/WIN, B/FUNC) + flavor = "balanced"; + tapping-term-ms = <280>; + quick-tap-ms = <175>; + require-prior-idle-ms = <175>; + bindings = <&mo>, <&kp>; + hold-trigger-key-positions = ; + hold-trigger-on-release; +) + // combos #undef COMBO_TERM @@ -79,13 +92,13 @@ ZMK_LAYER(Main, // DEFAULT LAYER // .--------------------------------------------------------------. .-----------------------------------------------------------. // | ESC | Q | W | E/NAV | R/WIN | T | | Y | U | I | O | P | BKSP | - &kp ESC &kp Q &kp W < 3 E < 6 R &kp T &kp Y &kp U &kp I &kp O &kp P &kp DEL + &kp ESC &kp Q &kp W <l 3 E <l 6 R &kp T &kp Y &kp U &kp I &kp O &kp P &kp DEL // |--------------+---------+--------+--------+---------+---------| |-------+---------+---------+---------+----------+----------| // | CTRL/Tab | A | S | D | F | G | | H | J | K | L | Ö | Ä | &mt LCTRL TAB &kp A &hml LALT S &hml LSHIFT D &hml LCTRL F &kp G &kp H &hmr RCTRL J &hmr RSHIFT K &hmr RALT L &kp SEMI &kp LBKT // |--------------+---------+--------+--------+---------+---------| |-------+---------+---------+---------+----------+----------| // | SHFT | Z | X | C | V | B/FUNC | | N | M | . | , | | Ä | - &kp LSHIFT &kp Z &kp X &kp C &kp V < 5 B &kp N &kp M &kp DOT &kp COMMA ___ &kp SQT + &kp LSHIFT &kp Z &kp X &kp C &kp V <l 5 B &kp N &kp M &kp DOT &kp COMMA ___ &kp SQT // '---------------------------------+--------+---------+---------+ |-------+---------+---------+-------------------------------' // | GUI | NUM | SPC | | ENT | CHARS | BKSP | &kp LGUI &mo 1 &kp SPACE &kp RET &mo 2 &kp BSPC @@ -206,13 +219,13 @@ ZMK_LAYER(Game, // DEFAULT LAYER // .--------------------------------------------------------------. .-----------------------------------------------------------. // | ESC | Q | W | E/NAV | R/NAV | T | | Y | U | I | O | P | BKSP | - &kp ESC &kp Q &kp W &kp E < 3 R &kp T &kp Y &kp U &kp I &kp O &kp P &kp DEL + &kp ESC &kp Q &kp W &kp E <l 3 R &kp T &kp Y &kp U &kp I &kp O &kp P &kp DEL // |--------------+---------+--------+--------+---------+---------| |-------+---------+---------+---------+----------+----------| // | CTRL/Tab | A | S | D | F | G | | H | J | K | L | Ö | Ä | &mt LCTRL TAB &kp A &kp S &kp D &kp F &kp G &kp H &hmr RCTRL J &hmr RSHIFT K &hmr RALT L &kp SEMI &kp LBKT // |--------------+---------+--------+--------+---------+---------| |-------+---------+---------+---------+----------+----------| // | SHFT | Z | X | C | V | B/FUNC | | N | M | . | , | | Ä | - &kp LSHIFT &kp Z &kp X &kp C &kp V < 5 B &kp N &kp M &kp DOT &kp COMMA ___ &kp SQT + &kp LSHIFT &kp Z &kp X &kp C &kp V <l 5 B &kp N &kp M &kp DOT &kp COMMA ___ &kp SQT // '---------------------------------+--------+---------+---------+ |-------+---------+---------+-------------------------------' // | GUI | NUM | SPC | | ENT | CHARS | BKSP | &kp LGUI &mo 1 &kp SPACE &kp RET &mo 2 &kp BSPC