diff options
Diffstat (limited to 'qmk/keyboards/sofle_choc/keymaps/custom/tap_hold_dance.c')
| -rw-r--r-- | qmk/keyboards/sofle_choc/keymaps/custom/tap_hold_dance.c | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/qmk/keyboards/sofle_choc/keymaps/custom/tap_hold_dance.c b/qmk/keyboards/sofle_choc/keymaps/custom/tap_hold_dance.c new file mode 100644 index 0000000..907a0f2 --- /dev/null +++ b/qmk/keyboards/sofle_choc/keymaps/custom/tap_hold_dance.c @@ -0,0 +1,103 @@ +#include QMK_KEYBOARD_H +#include "quad_tapdance.h" +#include "tap_hold_dance.h" + +/* timer for last keyboard activity, use 32bit value and function to make + * longer idle time possible + */ +static uint32_t key_timer; + +uint16_t tap_hold_dance_tapping_term(uint16_t keycode, keyrecord_t *record) { + /* + * If no keys where pressed before, reduce the time before activating the + * tapdance. + * The feedback is given with the LED in the keyboard. + */ + if (timer_elapsed32(key_timer) > (TAPPING_TERM * 2)) { + return TAPPING_TERM / 2; + } + return TAPPING_TERM; +} + +bool is_blocking_keycode(uint16_t keycode) { + + uint8_t current_layer = get_highest_layer(layer_state); + if (current_layer != LAYER_BASE) { + return false; + } + + switch (keycode) { + /* List the keys to ignore and should not considered inside a typing + * session. + */ + case LY_KEYPAD: + case LY_ARROW: + case KC_ESC: + case KC_RIGHT: + case KEY_DOWN: + case KC_LEFT ... KC_UP: + case KC_PGUP: + case KC_PGDN: + case KEY_PGDN: + case KC_HOME: + case KC_END: + case KC_TAB: + return false; + case AL_ENT: + case KC_BSPC: + case KC_DELETE: + case KC_A ... KC_0: + default: + return true; + } + +} + +void tap_hold_dance_process_record(uint16_t keycode, keyrecord_t *record) { + + if (record->event.pressed) { + return; + } + if (is_blocking_keycode(keycode)) + key_timer = timer_read32(); +} + +void tap_hold_dance_released(tap_dance_state_t *state, void *user_data) { + if (state->finished || state->interrupted) return; + tap_hold_dance_t *tap_hold_dance = (tap_hold_dance_t *)user_data; + tap_code(tap_hold_dance->tap); +} + +void tap_hold_dance_finished(tap_dance_state_t *state, void *user_data) { + + tap_hold_dance_t *tap_hold_dance = (tap_hold_dance_t *)user_data; + tap_hold_dance->state = cur_dance(state); + switch (tap_hold_dance->state) { + case TD_SINGLE_HOLD: + /* If a key is pressed before the TAPPING_TERM delay, consider a + * tap instead of switching to the mod. + */ + if (state->interrupted && is_blocking_keycode(state->interrupting_keycode)) { + tap_hold_dance->held = tap_hold_dance->tap; + } else { + tap_hold_dance->held = tap_hold_dance->hold; + } + register_code(tap_hold_dance->held); + break; + case TD_DOUBLE_HOLD: + tap_hold_dance->held = tap_hold_dance->tap; + register_code(tap_hold_dance->tap); + default: + break; + + } +} +void tap_hold_dance_reset(tap_dance_state_t *state, void *user_data) { + tap_hold_dance_t *tap_hold_dance = (tap_hold_dance_t *)user_data; + + if (tap_hold_dance->state != TD_NONE && tap_hold_dance->held) { + unregister_code(tap_hold_dance->held); + tap_hold_dance->held = 0; + } + tap_hold_dance->state = TD_NONE; +} |
