diff options
Diffstat (limited to 'tmk_core')
| -rw-r--r-- | tmk_core/common/action.c | 37 | ||||
| -rw-r--r-- | tmk_core/common/action.h | 5 | ||||
| -rw-r--r-- | tmk_core/common/action_tapping.c | 41 | ||||
| -rw-r--r-- | tmk_core/common/action_tapping.h | 1 |
4 files changed, 68 insertions, 16 deletions
diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c index bd41d28b6..d19fd2a04 100644 --- a/tmk_core/common/action.c +++ b/tmk_core/common/action.c | |||
| @@ -55,6 +55,8 @@ __attribute__((weak)) bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrec | |||
| 55 | __attribute__((weak)) bool get_retro_tapping(uint16_t keycode, keyrecord_t *record) { return false; } | 55 | __attribute__((weak)) bool get_retro_tapping(uint16_t keycode, keyrecord_t *record) { return false; } |
| 56 | #endif | 56 | #endif |
| 57 | 57 | ||
| 58 | __attribute__((weak)) bool pre_process_record_quantum(keyrecord_t *record) { return true; } | ||
| 59 | |||
| 58 | #ifndef TAP_CODE_DELAY | 60 | #ifndef TAP_CODE_DELAY |
| 59 | # define TAP_CODE_DELAY 0 | 61 | # define TAP_CODE_DELAY 0 |
| 60 | #endif | 62 | #endif |
| @@ -106,9 +108,13 @@ void action_exec(keyevent_t event) { | |||
| 106 | #endif | 108 | #endif |
| 107 | 109 | ||
| 108 | #ifndef NO_ACTION_TAPPING | 110 | #ifndef NO_ACTION_TAPPING |
| 109 | action_tapping_process(record); | 111 | if (IS_NOEVENT(record.event) || pre_process_record_quantum(&record)) { |
| 112 | action_tapping_process(record); | ||
| 113 | } | ||
| 110 | #else | 114 | #else |
| 111 | process_record(&record); | 115 | if (IS_NOEVENT(record.event) || pre_process_record_quantum(&record)) { |
| 116 | process_record(&record); | ||
| 117 | } | ||
| 112 | if (!IS_NOEVENT(record.event)) { | 118 | if (!IS_NOEVENT(record.event)) { |
| 113 | dprint("processed: "); | 119 | dprint("processed: "); |
| 114 | debug_record(record); | 120 | debug_record(record); |
| @@ -206,7 +212,16 @@ void process_record(keyrecord_t *record) { | |||
| 206 | } | 212 | } |
| 207 | 213 | ||
| 208 | void process_record_handler(keyrecord_t *record) { | 214 | void process_record_handler(keyrecord_t *record) { |
| 215 | #ifdef COMBO_ENABLE | ||
| 216 | action_t action; | ||
| 217 | if (record->keycode) { | ||
| 218 | action = action_for_keycode(record->keycode); | ||
| 219 | } else { | ||
| 220 | action = store_or_get_action(record->event.pressed, record->event.key); | ||
| 221 | } | ||
| 222 | #else | ||
| 209 | action_t action = store_or_get_action(record->event.pressed, record->event.key); | 223 | action_t action = store_or_get_action(record->event.pressed, record->event.key); |
| 224 | #endif | ||
| 210 | dprint("ACTION: "); | 225 | dprint("ACTION: "); |
| 211 | debug_action(action); | 226 | debug_action(action); |
| 212 | #ifndef NO_ACTION_LAYER | 227 | #ifndef NO_ACTION_LAYER |
| @@ -994,6 +1009,24 @@ bool is_tap_key(keypos_t key) { | |||
| 994 | * | 1009 | * |
| 995 | * FIXME: Needs documentation. | 1010 | * FIXME: Needs documentation. |
| 996 | */ | 1011 | */ |
| 1012 | bool is_tap_record(keyrecord_t *record) { | ||
| 1013 | #ifdef COMBO_ENABLE | ||
| 1014 | action_t action; | ||
| 1015 | if (record->keycode) { | ||
| 1016 | action = action_for_keycode(record->keycode); | ||
| 1017 | } else { | ||
| 1018 | action = layer_switch_get_action(record->event.key); | ||
| 1019 | } | ||
| 1020 | #else | ||
| 1021 | action_t action = layer_switch_get_action(record->event.key); | ||
| 1022 | #endif | ||
| 1023 | return is_tap_action(action); | ||
| 1024 | } | ||
| 1025 | |||
| 1026 | /** \brief Utilities for actions. (FIXME: Needs better description) | ||
| 1027 | * | ||
| 1028 | * FIXME: Needs documentation. | ||
| 1029 | */ | ||
| 997 | bool is_tap_action(action_t action) { | 1030 | bool is_tap_action(action_t action) { |
| 998 | switch (action.kind.id) { | 1031 | switch (action.kind.id) { |
| 999 | case ACT_LMODS_TAP: | 1032 | case ACT_LMODS_TAP: |
diff --git a/tmk_core/common/action.h b/tmk_core/common/action.h index 8cb4722c6..3d357b33b 100644 --- a/tmk_core/common/action.h +++ b/tmk_core/common/action.h | |||
| @@ -53,6 +53,9 @@ typedef struct { | |||
| 53 | #ifndef NO_ACTION_TAPPING | 53 | #ifndef NO_ACTION_TAPPING |
| 54 | tap_t tap; | 54 | tap_t tap; |
| 55 | #endif | 55 | #endif |
| 56 | #ifdef COMBO_ENABLE | ||
| 57 | uint16_t keycode; | ||
| 58 | #endif | ||
| 56 | } keyrecord_t; | 59 | } keyrecord_t; |
| 57 | 60 | ||
| 58 | /* Execute action per keyevent */ | 61 | /* Execute action per keyevent */ |
| @@ -60,6 +63,7 @@ void action_exec(keyevent_t event); | |||
| 60 | 63 | ||
| 61 | /* action for key */ | 64 | /* action for key */ |
| 62 | action_t action_for_key(uint8_t layer, keypos_t key); | 65 | action_t action_for_key(uint8_t layer, keypos_t key); |
| 66 | action_t action_for_keycode(uint16_t keycode); | ||
| 63 | 67 | ||
| 64 | /* macro */ | 68 | /* macro */ |
| 65 | const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt); | 69 | const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt); |
| @@ -111,6 +115,7 @@ void clear_keyboard_but_mods(void); | |||
| 111 | void clear_keyboard_but_mods_and_keys(void); | 115 | void clear_keyboard_but_mods_and_keys(void); |
| 112 | void layer_switch(uint8_t new_layer); | 116 | void layer_switch(uint8_t new_layer); |
| 113 | bool is_tap_key(keypos_t key); | 117 | bool is_tap_key(keypos_t key); |
| 118 | bool is_tap_record(keyrecord_t *record); | ||
| 114 | bool is_tap_action(action_t action); | 119 | bool is_tap_action(action_t action); |
| 115 | 120 | ||
| 116 | #ifndef NO_ACTION_TAPPING | 121 | #ifndef NO_ACTION_TAPPING |
diff --git a/tmk_core/common/action_tapping.c b/tmk_core/common/action_tapping.c index 56044e096..1701ae471 100644 --- a/tmk_core/common/action_tapping.c +++ b/tmk_core/common/action_tapping.c | |||
| @@ -18,11 +18,16 @@ | |||
| 18 | # define IS_TAPPING_PRESSED() (IS_TAPPING() && tapping_key.event.pressed) | 18 | # define IS_TAPPING_PRESSED() (IS_TAPPING() && tapping_key.event.pressed) |
| 19 | # define IS_TAPPING_RELEASED() (IS_TAPPING() && !tapping_key.event.pressed) | 19 | # define IS_TAPPING_RELEASED() (IS_TAPPING() && !tapping_key.event.pressed) |
| 20 | # define IS_TAPPING_KEY(k) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (k))) | 20 | # define IS_TAPPING_KEY(k) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (k))) |
| 21 | #ifndef COMBO_ENABLE | ||
| 22 | # define IS_TAPPING_RECORD(r) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (r->event.key))) | ||
| 23 | #else | ||
| 24 | # define IS_TAPPING_RECORD(r) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (r->event.key)) && tapping_key.keycode == r->keycode) | ||
| 25 | #endif | ||
| 21 | 26 | ||
| 22 | __attribute__((weak)) uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) { return TAPPING_TERM; } | 27 | __attribute__((weak)) uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) { return TAPPING_TERM; } |
| 23 | 28 | ||
| 24 | # ifdef TAPPING_TERM_PER_KEY | 29 | # ifdef TAPPING_TERM_PER_KEY |
| 25 | # define WITHIN_TAPPING_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < get_tapping_term(get_event_keycode(tapping_key.event, false), &tapping_key)) | 30 | # define WITHIN_TAPPING_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < get_tapping_term(get_record_keycode(&tapping_key, false), &tapping_key)) |
| 26 | # else | 31 | # else |
| 27 | # define WITHIN_TAPPING_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < TAPPING_TERM) | 32 | # define WITHIN_TAPPING_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < TAPPING_TERM) |
| 28 | # endif | 33 | # endif |
| @@ -103,7 +108,7 @@ bool process_tapping(keyrecord_t *keyp) { | |||
| 103 | if (IS_TAPPING_PRESSED()) { | 108 | if (IS_TAPPING_PRESSED()) { |
| 104 | if (WITHIN_TAPPING_TERM(event)) { | 109 | if (WITHIN_TAPPING_TERM(event)) { |
| 105 | if (tapping_key.tap.count == 0) { | 110 | if (tapping_key.tap.count == 0) { |
| 106 | if (IS_TAPPING_KEY(event.key) && !event.pressed) { | 111 | if (IS_TAPPING_RECORD(keyp) && !event.pressed) { |
| 107 | // first tap! | 112 | // first tap! |
| 108 | debug("Tapping: First tap(0->1).\n"); | 113 | debug("Tapping: First tap(0->1).\n"); |
| 109 | tapping_key.tap.count = 1; | 114 | tapping_key.tap.count = 1; |
| @@ -122,14 +127,14 @@ bool process_tapping(keyrecord_t *keyp) { | |||
| 122 | # if defined(TAPPING_TERM_PER_KEY) || (TAPPING_TERM >= 500) || defined(PERMISSIVE_HOLD) || defined(PERMISSIVE_HOLD_PER_KEY) | 127 | # if defined(TAPPING_TERM_PER_KEY) || (TAPPING_TERM >= 500) || defined(PERMISSIVE_HOLD) || defined(PERMISSIVE_HOLD_PER_KEY) |
| 123 | else if ((( | 128 | else if ((( |
| 124 | # ifdef TAPPING_TERM_PER_KEY | 129 | # ifdef TAPPING_TERM_PER_KEY |
| 125 | get_tapping_term(get_event_keycode(tapping_key.event, false), keyp) | 130 | get_tapping_term(get_record_keycode(&tapping_key, false), keyp) |
| 126 | # else | 131 | # else |
| 127 | TAPPING_TERM | 132 | TAPPING_TERM |
| 128 | # endif | 133 | # endif |
| 129 | >= 500) | 134 | >= 500) |
| 130 | 135 | ||
| 131 | # ifdef PERMISSIVE_HOLD_PER_KEY | 136 | # ifdef PERMISSIVE_HOLD_PER_KEY |
| 132 | || get_permissive_hold(get_event_keycode(tapping_key.event, false), keyp) | 137 | || get_permissive_hold(get_record_keycode(&tapping_key, false), keyp) |
| 133 | # elif defined(PERMISSIVE_HOLD) | 138 | # elif defined(PERMISSIVE_HOLD) |
| 134 | || true | 139 | || true |
| 135 | # endif | 140 | # endif |
| @@ -177,7 +182,7 @@ bool process_tapping(keyrecord_t *keyp) { | |||
| 177 | } | 182 | } |
| 178 | // tap_count > 0 | 183 | // tap_count > 0 |
| 179 | else { | 184 | else { |
| 180 | if (IS_TAPPING_KEY(event.key) && !event.pressed) { | 185 | if (IS_TAPPING_RECORD(keyp) && !event.pressed) { |
| 181 | debug("Tapping: Tap release("); | 186 | debug("Tapping: Tap release("); |
| 182 | debug_dec(tapping_key.tap.count); | 187 | debug_dec(tapping_key.tap.count); |
| 183 | debug(")\n"); | 188 | debug(")\n"); |
| @@ -186,11 +191,15 @@ bool process_tapping(keyrecord_t *keyp) { | |||
| 186 | tapping_key = *keyp; | 191 | tapping_key = *keyp; |
| 187 | debug_tapping_key(); | 192 | debug_tapping_key(); |
| 188 | return true; | 193 | return true; |
| 189 | } else if (is_tap_key(event.key) && event.pressed) { | 194 | } else if (is_tap_record(keyp) && event.pressed) { |
| 190 | if (tapping_key.tap.count > 1) { | 195 | if (tapping_key.tap.count > 1) { |
| 191 | debug("Tapping: Start new tap with releasing last tap(>1).\n"); | 196 | debug("Tapping: Start new tap with releasing last tap(>1).\n"); |
| 192 | // unregister key | 197 | // unregister key |
| 193 | process_record(&(keyrecord_t){.tap = tapping_key.tap, .event.key = tapping_key.event.key, .event.time = event.time, .event.pressed = false}); | 198 | process_record(&(keyrecord_t){.tap = tapping_key.tap, .event.key = tapping_key.event.key, .event.time = event.time, .event.pressed = false, |
| 199 | #ifdef COMBO_ENABLE | ||
| 200 | .keycode = tapping_key.keycode, | ||
| 201 | #endif | ||
| 202 | }); | ||
| 194 | } else { | 203 | } else { |
| 195 | debug("Tapping: Start while last tap(1).\n"); | 204 | debug("Tapping: Start while last tap(1).\n"); |
| 196 | } | 205 | } |
| @@ -218,17 +227,21 @@ bool process_tapping(keyrecord_t *keyp) { | |||
| 218 | debug_tapping_key(); | 227 | debug_tapping_key(); |
| 219 | return false; | 228 | return false; |
| 220 | } else { | 229 | } else { |
| 221 | if (IS_TAPPING_KEY(event.key) && !event.pressed) { | 230 | if (IS_TAPPING_RECORD(keyp) && !event.pressed) { |
| 222 | debug("Tapping: End. last timeout tap release(>0)."); | 231 | debug("Tapping: End. last timeout tap release(>0)."); |
| 223 | keyp->tap = tapping_key.tap; | 232 | keyp->tap = tapping_key.tap; |
| 224 | process_record(keyp); | 233 | process_record(keyp); |
| 225 | tapping_key = (keyrecord_t){}; | 234 | tapping_key = (keyrecord_t){}; |
| 226 | return true; | 235 | return true; |
| 227 | } else if (is_tap_key(event.key) && event.pressed) { | 236 | } else if (is_tap_record(keyp) && event.pressed) { |
| 228 | if (tapping_key.tap.count > 1) { | 237 | if (tapping_key.tap.count > 1) { |
| 229 | debug("Tapping: Start new tap with releasing last timeout tap(>1).\n"); | 238 | debug("Tapping: Start new tap with releasing last timeout tap(>1).\n"); |
| 230 | // unregister key | 239 | // unregister key |
| 231 | process_record(&(keyrecord_t){.tap = tapping_key.tap, .event.key = tapping_key.event.key, .event.time = event.time, .event.pressed = false}); | 240 | process_record(&(keyrecord_t){.tap = tapping_key.tap, .event.key = tapping_key.event.key, .event.time = event.time, .event.pressed = false, |
| 241 | #ifdef COMBO_ENABLE | ||
| 242 | .keycode = tapping_key.keycode, | ||
| 243 | #endif | ||
| 244 | }); | ||
| 232 | } else { | 245 | } else { |
| 233 | debug("Tapping: Start while last timeout tap(1).\n"); | 246 | debug("Tapping: Start while last timeout tap(1).\n"); |
| 234 | } | 247 | } |
| @@ -248,12 +261,12 @@ bool process_tapping(keyrecord_t *keyp) { | |||
| 248 | } else if (IS_TAPPING_RELEASED()) { | 261 | } else if (IS_TAPPING_RELEASED()) { |
| 249 | if (WITHIN_TAPPING_TERM(event)) { | 262 | if (WITHIN_TAPPING_TERM(event)) { |
| 250 | if (event.pressed) { | 263 | if (event.pressed) { |
| 251 | if (IS_TAPPING_KEY(event.key)) { | 264 | if (IS_TAPPING_RECORD(keyp)) { |
| 252 | //# ifndef TAPPING_FORCE_HOLD | 265 | //# ifndef TAPPING_FORCE_HOLD |
| 253 | # if !defined(TAPPING_FORCE_HOLD) || defined(TAPPING_FORCE_HOLD_PER_KEY) | 266 | # if !defined(TAPPING_FORCE_HOLD) || defined(TAPPING_FORCE_HOLD_PER_KEY) |
| 254 | if ( | 267 | if ( |
| 255 | # ifdef TAPPING_FORCE_HOLD_PER_KEY | 268 | # ifdef TAPPING_FORCE_HOLD_PER_KEY |
| 256 | !get_tapping_force_hold(get_event_keycode(tapping_key.event, false), keyp) && | 269 | !get_tapping_force_hold(get_record_keycode(&tapping_key, false), keyp) && |
| 257 | # endif | 270 | # endif |
| 258 | !tapping_key.tap.interrupted && tapping_key.tap.count > 0) { | 271 | !tapping_key.tap.interrupted && tapping_key.tap.count > 0) { |
| 259 | // sequential tap. | 272 | // sequential tap. |
| @@ -271,7 +284,7 @@ bool process_tapping(keyrecord_t *keyp) { | |||
| 271 | // FIX: start new tap again | 284 | // FIX: start new tap again |
| 272 | tapping_key = *keyp; | 285 | tapping_key = *keyp; |
| 273 | return true; | 286 | return true; |
| 274 | } else if (is_tap_key(event.key)) { | 287 | } else if (is_tap_record(keyp)) { |
| 275 | // Sequential tap can be interfered with other tap key. | 288 | // Sequential tap can be interfered with other tap key. |
| 276 | debug("Tapping: Start with interfering other tap.\n"); | 289 | debug("Tapping: Start with interfering other tap.\n"); |
| 277 | tapping_key = *keyp; | 290 | tapping_key = *keyp; |
| @@ -303,7 +316,7 @@ bool process_tapping(keyrecord_t *keyp) { | |||
| 303 | } | 316 | } |
| 304 | // not tapping state | 317 | // not tapping state |
| 305 | else { | 318 | else { |
| 306 | if (event.pressed && is_tap_key(event.key)) { | 319 | if (event.pressed && is_tap_record(keyp)) { |
| 307 | debug("Tapping: Start(Press tap key).\n"); | 320 | debug("Tapping: Start(Press tap key).\n"); |
| 308 | tapping_key = *keyp; | 321 | tapping_key = *keyp; |
| 309 | process_record_tap_hint(&tapping_key); | 322 | process_record_tap_hint(&tapping_key); |
diff --git a/tmk_core/common/action_tapping.h b/tmk_core/common/action_tapping.h index 893ccb1ce..7de8049c7 100644 --- a/tmk_core/common/action_tapping.h +++ b/tmk_core/common/action_tapping.h | |||
| @@ -30,6 +30,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| 30 | #define WAITING_BUFFER_SIZE 8 | 30 | #define WAITING_BUFFER_SIZE 8 |
| 31 | 31 | ||
| 32 | #ifndef NO_ACTION_TAPPING | 32 | #ifndef NO_ACTION_TAPPING |
| 33 | uint16_t get_record_keycode(keyrecord_t *record, bool update_layer_cache); | ||
| 33 | uint16_t get_event_keycode(keyevent_t event, bool update_layer_cache); | 34 | uint16_t get_event_keycode(keyevent_t event, bool update_layer_cache); |
| 34 | void action_tapping_process(keyrecord_t record); | 35 | void action_tapping_process(keyrecord_t record); |
| 35 | 36 | ||
