X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=common%2Faction_tapping.c;h=826c2330966a00050565b1358e6ee43f0baa0814;hb=92004d67869a371f1a8ff4d67ffb49f52141b768;hp=8b466079d21394ba134fd3d26f5576cc41a5a1a2;hpb=ff2d276b193632136c785d92ed01df48aea8461f;p=tmk_firmware.git diff --git a/common/action_tapping.c b/common/action_tapping.c index 8b46607..826c233 100644 --- a/common/action_tapping.c +++ b/common/action_tapping.c @@ -1,7 +1,9 @@ #include #include #include "action.h" +#include "action_layer.h" #include "action_tapping.h" +#include "keycode.h" #include "timer.h" #ifdef DEBUG_ACTION @@ -27,9 +29,7 @@ static uint8_t waiting_buffer_tail = 0; static bool process_tapping(keyrecord_t *record); static bool waiting_buffer_enq(keyrecord_t record); static void waiting_buffer_clear(void); -#if TAPPING_TERM >= 500 static bool waiting_buffer_typed(keyevent_t event); -#endif static bool waiting_buffer_has_anykey_pressed(void); static void waiting_buffer_scan_tap(void); static void debug_tapping_key(void); @@ -88,29 +88,58 @@ bool process_tapping(keyrecord_t *keyp) // first tap! debug("Tapping: First tap(0->1).\n"); tapping_key.tap.count = 1; - tapping_key.tap.interrupted = (waiting_buffer_has_anykey_pressed() ? true : false); debug_tapping_key(); process_action(&tapping_key); - // enqueue + // copy tapping state keyp->tap = tapping_key.tap; + // enqueue return false; } #if TAPPING_TERM >= 500 - /* This can prevent from typing some tap keys in a row at a time. */ - else if (!event.pressed && waiting_buffer_typed(event)) { - // other key typed. not tap. + /* Process a key typed within TAPPING_TERM + * This can register the key before settlement of tapping, + * useful for long TAPPING_TERM but may prevent fast typing. + */ + else if (IS_RELEASED(event) && waiting_buffer_typed(event)) { debug("Tapping: End. No tap. Interfered by typing key\n"); process_action(&tapping_key); tapping_key = (keyrecord_t){}; debug_tapping_key(); - // enqueue return false; } #endif + /* Process release event of a key pressed before tapping starts + * Without this unexpected repeating will occur with having fast repeating setting + * https://github.com/tmk/tmk_keyboard/issues/60 + */ + else if (IS_RELEASED(event) && !waiting_buffer_typed(event)) { + // Modifier should be retained till end of this tapping. + action_t action = layer_switch_get_action(event.key); + switch (action.kind.id) { + case ACT_LMODS: + case ACT_RMODS: + if (action.key.mods && !action.key.code) return false; + if (IS_MOD(action.key.code)) return false; + break; + case ACT_LMODS_TAP: + case ACT_RMODS_TAP: + if (action.key.mods && keyp->tap.count == 0) return false; + if (IS_MOD(action.key.code)) return false; + break; + } + // Release of key should be process immediately. + debug("Tapping: release event of a key pressed before tapping\n"); + process_action(keyp); + return true; + } else { - // other key events shall be enq'd till tapping state settles. + // set interrupted flag when other key preesed during tapping + if (event.pressed) { + tapping_key.tap.interrupted = true; + } + // enqueue return false; } } @@ -124,7 +153,7 @@ bool process_tapping(keyrecord_t *keyp) debug_tapping_key(); return true; } - else if (is_tap_key(keyp->event.key) && event.pressed) { + else if (is_tap_key(event.key) && event.pressed) { if (tapping_key.tap.count > 1) { debug("Tapping: Start new tap with releasing last tap(>1).\n"); // unregister key @@ -143,7 +172,7 @@ bool process_tapping(keyrecord_t *keyp) return true; } else { - if (!IS_NOEVENT(keyp->event)) { + if (!IS_NOEVENT(event)) { debug("Tapping: key event while last tap(>0).\n"); } process_action(keyp); @@ -168,7 +197,7 @@ bool process_tapping(keyrecord_t *keyp) tapping_key = (keyrecord_t){}; return true; } - else if (is_tap_key(keyp->event.key) && event.pressed) { + else if (is_tap_key(event.key) && event.pressed) { if (tapping_key.tap.count > 1) { debug("Tapping: Start new tap with releasing last timeout tap(>1).\n"); // unregister key @@ -187,7 +216,7 @@ bool process_tapping(keyrecord_t *keyp) return true; } else { - if (!IS_NOEVENT(keyp->event)) { + if (!IS_NOEVENT(event)) { debug("Tapping: key event while last timeout tap(>0).\n"); } process_action(keyp); @@ -197,28 +226,43 @@ bool process_tapping(keyrecord_t *keyp) } } else if (IS_TAPPING_RELEASED()) { if (WITHIN_TAPPING_TERM(event)) { - if (tapping_key.tap.count > 0 && IS_TAPPING_KEY(event.key) && event.pressed) { - // sequential tap. - keyp->tap = tapping_key.tap; - keyp->tap.count += 1; - debug("Tapping: Tap press("); debug_dec(keyp->tap.count); debug(")\n"); - process_action(keyp); - tapping_key = *keyp; - debug_tapping_key(); - return true; - } else if (event.pressed && is_tap_key(event.key)) { - // Sequential tap can be interfered with other tap key. - debug("Tapping: Start with interfering other tap.\n"); - tapping_key = *keyp; - waiting_buffer_scan_tap(); - debug_tapping_key(); - return true; + if (event.pressed) { + if (IS_TAPPING_KEY(event.key)) { + if (!tapping_key.tap.interrupted && tapping_key.tap.count > 0) { + // sequential tap. + keyp->tap = tapping_key.tap; + if (keyp->tap.count < 15) keyp->tap.count += 1; + debug("Tapping: Tap press("); debug_dec(keyp->tap.count); debug(")\n"); + process_action(keyp); + tapping_key = *keyp; + debug_tapping_key(); + return true; + } else { + // FIX: start new tap again + tapping_key = *keyp; + return true; + } + } else if (is_tap_key(event.key)) { + // Sequential tap can be interfered with other tap key. + debug("Tapping: Start with interfering other tap.\n"); + tapping_key = *keyp; + waiting_buffer_scan_tap(); + debug_tapping_key(); + return true; + } else { + // should none in buffer + // FIX: interrupted when other key is pressed + tapping_key.tap.interrupted = true; + process_action(keyp); + return true; + } } else { - if (!IS_NOEVENT(keyp->event)) debug("Tapping: other key just after tap.\n"); + if (!IS_NOEVENT(event)) debug("Tapping: other key just after tap.\n"); process_action(keyp); return true; } } else { + // FIX: process_aciton here? // timeout. no sequential tap. debug("Tapping: End(Timeout after releasing last tap): "); debug_event(event); debug("\n"); @@ -227,7 +271,7 @@ bool process_tapping(keyrecord_t *keyp) return false; } } - // not tapping satate + // not tapping state else { if (event.pressed && is_tap_key(event.key)) { debug("Tapping: Start(Press tap key).\n"); @@ -270,7 +314,6 @@ void waiting_buffer_clear(void) waiting_buffer_tail = 0; } -#if TAPPING_TERM >= 500 bool waiting_buffer_typed(keyevent_t event) { for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) { @@ -280,7 +323,6 @@ bool waiting_buffer_typed(keyevent_t event) } return false; } -#endif bool waiting_buffer_has_anykey_pressed(void) {