diff options
| -rw-r--r-- | common/action_tapping.c | 36 | ||||
| -rw-r--r-- | common/keyboard.h | 19 |
2 files changed, 37 insertions, 18 deletions
diff --git a/common/action_tapping.c b/common/action_tapping.c index 542949ddd..826c23309 100644 --- a/common/action_tapping.c +++ b/common/action_tapping.c | |||
| @@ -1,7 +1,9 @@ | |||
| 1 | #include <stdint.h> | 1 | #include <stdint.h> |
| 2 | #include <stdbool.h> | 2 | #include <stdbool.h> |
| 3 | #include "action.h" | 3 | #include "action.h" |
| 4 | #include "action_layer.h" | ||
| 4 | #include "action_tapping.h" | 5 | #include "action_tapping.h" |
| 6 | #include "keycode.h" | ||
| 5 | #include "timer.h" | 7 | #include "timer.h" |
| 6 | 8 | ||
| 7 | #ifdef DEBUG_ACTION | 9 | #ifdef DEBUG_ACTION |
| @@ -95,22 +97,40 @@ bool process_tapping(keyrecord_t *keyp) | |||
| 95 | return false; | 97 | return false; |
| 96 | } | 98 | } |
| 97 | #if TAPPING_TERM >= 500 | 99 | #if TAPPING_TERM >= 500 |
| 98 | /* This can settle mod/fn state fast but may prevent from typing fast. */ | 100 | /* Process a key typed within TAPPING_TERM |
| 99 | else if (!event.pressed && waiting_buffer_typed(event)) { | 101 | * This can register the key before settlement of tapping, |
| 100 | // other key typed. not tap. | 102 | * useful for long TAPPING_TERM but may prevent fast typing. |
| 103 | */ | ||
| 104 | else if (IS_RELEASED(event) && waiting_buffer_typed(event)) { | ||
| 101 | debug("Tapping: End. No tap. Interfered by typing key\n"); | 105 | debug("Tapping: End. No tap. Interfered by typing key\n"); |
| 102 | process_action(&tapping_key); | 106 | process_action(&tapping_key); |
| 103 | tapping_key = (keyrecord_t){}; | 107 | tapping_key = (keyrecord_t){}; |
| 104 | debug_tapping_key(); | 108 | debug_tapping_key(); |
| 105 | |||
| 106 | // enqueue | 109 | // enqueue |
| 107 | return false; | 110 | return false; |
| 108 | } | 111 | } |
| 109 | #endif | 112 | #endif |
| 110 | /* release a key pressed before tapping */ | 113 | /* Process release event of a key pressed before tapping starts |
| 111 | else if (!event.pressed && !waiting_buffer_typed(event)) { | 114 | * Without this unexpected repeating will occur with having fast repeating setting |
| 112 | /* Unexpected repeating occurs unless this event is processed immedately. */ | 115 | * https://github.com/tmk/tmk_keyboard/issues/60 |
| 113 | debug("Tapping: release a key pressed before tapping\n"); | 116 | */ |
| 117 | else if (IS_RELEASED(event) && !waiting_buffer_typed(event)) { | ||
| 118 | // Modifier should be retained till end of this tapping. | ||
| 119 | action_t action = layer_switch_get_action(event.key); | ||
| 120 | switch (action.kind.id) { | ||
| 121 | case ACT_LMODS: | ||
| 122 | case ACT_RMODS: | ||
| 123 | if (action.key.mods && !action.key.code) return false; | ||
| 124 | if (IS_MOD(action.key.code)) return false; | ||
| 125 | break; | ||
| 126 | case ACT_LMODS_TAP: | ||
| 127 | case ACT_RMODS_TAP: | ||
| 128 | if (action.key.mods && keyp->tap.count == 0) return false; | ||
| 129 | if (IS_MOD(action.key.code)) return false; | ||
| 130 | break; | ||
| 131 | } | ||
| 132 | // Release of key should be process immediately. | ||
| 133 | debug("Tapping: release event of a key pressed before tapping\n"); | ||
| 114 | process_action(keyp); | 134 | process_action(keyp); |
| 115 | return true; | 135 | return true; |
| 116 | } | 136 | } |
diff --git a/common/keyboard.h b/common/keyboard.h index 78cb24034..d1a922420 100644 --- a/common/keyboard.h +++ b/common/keyboard.h | |||
| @@ -42,16 +42,15 @@ typedef struct { | |||
| 42 | /* equivalent test of key_t */ | 42 | /* equivalent test of key_t */ |
| 43 | #define KEYEQ(keya, keyb) ((keya).row == (keyb).row && (keya).col == (keyb).col) | 43 | #define KEYEQ(keya, keyb) ((keya).row == (keyb).row && (keya).col == (keyb).col) |
| 44 | 44 | ||
| 45 | /* (time == 0) means no event and assumes matrix has no 255 line. */ | 45 | /* Rules for No Event: |
| 46 | #define IS_NOEVENT(event) ((event).time == 0 || ((event).key.row == 255 && (event).key.col == 255)) | 46 | * 1) (time == 0) to handle (keyevent_t){} as empty event |
| 47 | 47 | * 2) Matrix(255, 255) to make TICK event available | |
| 48 | #define NOEVENT (keyevent_t){ \ | 48 | */ |
| 49 | .key = (key_t){ .row = 255, .col = 255 }, \ | 49 | static inline bool IS_NOEVENT(keyevent_t event) { return event.time == 0 || (event.key.row == 255 && event.key.col == 255); } |
| 50 | .pressed = false, \ | 50 | static inline bool IS_PRESSED(keyevent_t event) { return (!IS_NOEVENT(event) && event.pressed); } |
| 51 | .time = 0 \ | 51 | static inline bool IS_RELEASED(keyevent_t event) { return (!IS_NOEVENT(event) && !event.pressed); } |
| 52 | } | 52 | |
| 53 | 53 | /* Tick event */ | |
| 54 | /* tick event */ | ||
| 55 | #define TICK (keyevent_t){ \ | 54 | #define TICK (keyevent_t){ \ |
| 56 | .key = (key_t){ .row = 255, .col = 255 }, \ | 55 | .key = (key_t){ .row = 255, .col = 255 }, \ |
| 57 | .pressed = false, \ | 56 | .pressed = false, \ |
