summaryrefslogtreecommitdiffstats
path: root/common/action_tapping.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/action_tapping.c')
-rw-r--r--common/action_tapping.c39
1 files changed, 31 insertions, 8 deletions
diff --git a/common/action_tapping.c b/common/action_tapping.c
index a6292535ed..826c233096 100644
--- a/common/action_tapping.c
+++ b/common/action_tapping.c
@@ -1,7 +1,9 @@
#include <stdint.h>
#include <stdbool.h>
#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);
@@ -97,18 +97,43 @@ bool process_tapping(keyrecord_t *keyp)
return false;
}
#if TAPPING_TERM >= 500
- /* This can settle mod/fn state fast but may prevent from typing fast. */
- 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 {
// set interrupted flag when other key preesed during tapping
if (event.pressed) {
@@ -289,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) {
@@ -299,7 +323,6 @@ bool waiting_buffer_typed(keyevent_t event)
}
return false;
}
-#endif
bool waiting_buffer_has_anykey_pressed(void)
{