From ffaafb833088e7fa04c79c4c25b130df86291a7e Mon Sep 17 00:00:00 2001 From: Sébastien Dailly Date: Tue, 4 Aug 2026 15:27:25 +0200 Subject: QMK: Dedicated file for the taphold mecanism --- .../sofle_choc/keymaps/custom/callbacks.c | 15 +++ qmk/keyboards/sofle_choc/keymaps/custom/config.h | 2 +- qmk/keyboards/sofle_choc/keymaps/custom/keycodes.c | 49 ---------- qmk/keyboards/sofle_choc/keymaps/custom/keycodes.h | 10 +- qmk/keyboards/sofle_choc/keymaps/custom/keymap.c | 11 +-- .../sofle_choc/keymaps/custom/layer_dance.h | 3 +- qmk/keyboards/sofle_choc/keymaps/custom/lighting.c | 7 +- qmk/keyboards/sofle_choc/keymaps/custom/rules.mk | 1 + .../sofle_choc/keymaps/custom/tap_hold_dance.c | 103 +++++++++++++++++++++ .../sofle_choc/keymaps/custom/tap_hold_dance.h | 25 +++++ 10 files changed, 162 insertions(+), 64 deletions(-) create mode 100644 qmk/keyboards/sofle_choc/keymaps/custom/tap_hold_dance.c create mode 100644 qmk/keyboards/sofle_choc/keymaps/custom/tap_hold_dance.h diff --git a/qmk/keyboards/sofle_choc/keymaps/custom/callbacks.c b/qmk/keyboards/sofle_choc/keymaps/custom/callbacks.c index 305bacc..c45e960 100644 --- a/qmk/keyboards/sofle_choc/keymaps/custom/callbacks.c +++ b/qmk/keyboards/sofle_choc/keymaps/custom/callbacks.c @@ -3,8 +3,22 @@ #include "lighting.h" #include "enter_dance.h" #include "shift_dance.h" +#include "tap_hold_dance.h" #include "keycodes.h" +uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { +// case KEY_LOK: +// case TD_ENTER: +// return 2 * TAPPING_TERM; + case KEY_F: + case KEY_J: + return tap_hold_dance_tapping_term(keycode, record); + default: + return TAPPING_TERM; + } +} + void keyboard_post_init_user(void) { lighting_init(); star_key_init(); @@ -25,6 +39,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { star_key_process_record(keycode, record); shift_dance_process_record(keycode, record); enter_dance_process_record(keycode, record); + tap_hold_dance_process_record(keycode, record); return keycodes_process_record(keycode, record); } diff --git a/qmk/keyboards/sofle_choc/keymaps/custom/config.h b/qmk/keyboards/sofle_choc/keymaps/custom/config.h index 6f4ea1c..fb98e6f 100644 --- a/qmk/keyboards/sofle_choc/keymaps/custom/config.h +++ b/qmk/keyboards/sofle_choc/keymaps/custom/config.h @@ -55,7 +55,7 @@ #define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_TIMEOUT 200U // Timeout window in ms in which the double tap can occur. #define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_LED D5 // Specify an optional status LED by GPIO number which blinks when entering the bootloader -#define TAPPING_TERM 200 +#define TAPPING_TERM 300 #define TAPPING_TERM_PER_KEY #define DEBOUNCE 10 diff --git a/qmk/keyboards/sofle_choc/keymaps/custom/keycodes.c b/qmk/keyboards/sofle_choc/keymaps/custom/keycodes.c index b0f36a1..e2fb583 100644 --- a/qmk/keyboards/sofle_choc/keymaps/custom/keycodes.c +++ b/qmk/keyboards/sofle_choc/keymaps/custom/keycodes.c @@ -1,41 +1,9 @@ #include QMK_KEYBOARD_H #include "keycodes.h" -uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case KEY_F: - return 230; - case KEY_LOK: - case TD_ENTER: - return 2 * TAPPING_TERM; - default: - return TAPPING_TERM; - } -} - -static uint32_t key_timer; // timer for last keyboard activity, use - // 32bit value and function to make longer - // idle time possible - -static bool left_part; - bool keycodes_process_record(uint16_t keycode, keyrecord_t *record) { - if (!record->event.pressed) { - switch (keycode) { - case KC_ESC: - case AL_ENT: - break; - default: - // store time of last key release. This is used as a counter in order to - // know if we are inside a typing sequence or not. - key_timer = timer_read32(); - } - } - - left_part = record->event.key.row < (MATRIX_ROWS / 2); - switch (keycode) { case KC_ESC: case AL_ENT: @@ -46,23 +14,6 @@ bool keycodes_process_record(uint16_t keycode, keyrecord_t *record) { } return true; - // If a key where released just before, consider we are typing some text - // and do not start the tap tempo. - case KEY_F: - if (record->event.pressed && left_part && timer_elapsed32(key_timer) < (TAPPING_TERM * 2)) { - //register_code(KC_F); - tap_code16(KC_F); - return false; - } - return true; - case KEY_J: - if (record->event.pressed && !left_part && timer_elapsed32(key_timer) < (TAPPING_TERM * 2)) { - //register_code(KC_J); - tap_code16(KC_J); - return false; - } - return true; - // Override the key APP when hold into AltGR + Layer 1 when hold case KEY_APP: if (!record->tap.count && record->event.pressed) { diff --git a/qmk/keyboards/sofle_choc/keymaps/custom/keycodes.h b/qmk/keyboards/sofle_choc/keymaps/custom/keycodes.h index 3d3f40f..c37a563 100644 --- a/qmk/keyboards/sofle_choc/keymaps/custom/keycodes.h +++ b/qmk/keyboards/sofle_choc/keymaps/custom/keycodes.h @@ -9,6 +9,8 @@ enum { TD_LAYER_KEYPAD, TD_LAYER_ARROW, TD_ENTER, + TD_KEY_F, + TD_KEY_J, }; enum { @@ -22,10 +24,14 @@ enum { #define KEY_PRC TD(TD_PRC) #define AL_ENT MT(MOD_RALT, KC_ENT) #define AL_SPC MT(MOD_LALT, KC_SPC) -#define KEY_F MT(MOD_LCTL, KC_F) -#define KEY_J MT(MOD_RCTL, KC_J) #define KEY_INS MT(MOD_RGUI, KC_INS) #define TD_ENTR TD(TD_ENTER) +#define KEY_F TD(TD_KEY_F) +#define KEY_J TD(TD_KEY_J) + +#define LY_KEYPAD TD(TD_LAYER_KEYPAD) +#define LY_ARROW TD(TD_LAYER_ARROW) + // In the number layout, I keep the mod-tap modifiers applies to the middle // letters : diff --git a/qmk/keyboards/sofle_choc/keymaps/custom/keymap.c b/qmk/keyboards/sofle_choc/keymaps/custom/keymap.c index 401e262..5b222d2 100644 --- a/qmk/keyboards/sofle_choc/keymaps/custom/keymap.c +++ b/qmk/keyboards/sofle_choc/keymaps/custom/keymap.c @@ -16,10 +16,10 @@ #include "keymap_common.h" #include "quantum_keycodes.h" #include "process_tap_dance.h" -#include "process_key_override.h" #include "keycodes.h" #include "quad_tapdance.h" +#include "tap_hold_dance.h" #include "enter_dance.h" #include "shift_dance.h" #include "layer_dance.h" @@ -33,18 +33,15 @@ tap_dance_action_t tap_dance_actions[] = { [TD_CAPSLOCK] = ACTION_TAP_DANCE_FN_ADVANCED_WITH_RELEASE(NULL, right_shift_released, right_shift_finished, right_shift_reset), [TD_LAYER_KEYPAD] = ACTION_TAP_DANCE_LAYER(LAYER_KEYPAD), [TD_LAYER_ARROW] = ACTION_TAP_DANCE_LAYER(LAYER_ARROW), + [TD_KEY_F] = ACTION_TAP_HOLD_DANCE(KC_F, KC_LCTL, 1), + [TD_KEY_J] = ACTION_TAP_HOLD_DANCE(KC_J, KC_RCTL, 0), [TD_ENTER] = ACTION_TAP_DANCE_FN_ADVANCED_WITH_RELEASE(NULL, enter_released, enter_finished, enter_reset), }; - -#define LY_KEYPAD TD(TD_LAYER_KEYPAD) -#define LY_ARROW TD(TD_LAYER_ARROW) - #define RGB_UP QK_RGB_MATRIX_VALUE_UP #define RGB_DOWN QK_RGB_MATRIX_VALUE_DOWN - const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { /* * QWERTY @@ -65,7 +62,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [LAYER_BASE] = LAYOUT( KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KEY_PRC, KC_GRV, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC, - KC_TAB, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KEY_J, KC_K, KC_L, KC_SCLN, KC_QUOT, + KC_TAB, KC_A, KC_S, KC_D, KEY_F, KC_G, KC_H, KEY_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_MUTE, KC_MPLY,KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KEY_LOK, KC_LCTL, KC_DELETE,KC_LGUI,LY_ARROW, AL_SPC, TD_ENTR,LY_KEYPAD, KEY_APP, KEY_INS, KC_RCTL ), diff --git a/qmk/keyboards/sofle_choc/keymaps/custom/layer_dance.h b/qmk/keyboards/sofle_choc/keymaps/custom/layer_dance.h index efa1f7a..7d44c3f 100644 --- a/qmk/keyboards/sofle_choc/keymaps/custom/layer_dance.h +++ b/qmk/keyboards/sofle_choc/keymaps/custom/layer_dance.h @@ -1,5 +1,6 @@ #pragma once #include QMK_KEYBOARD_H +#include "quad_tapdance.h" /** * State of the tapdance, hold both the tapdance state, and the layer we need @@ -7,7 +8,7 @@ */ typedef struct { td_state_t state; - uint8_t layer; + const uint8_t layer; } tap_dance_layer_t; void tap_dance_layer_finished(tap_dance_state_t *state, void *user_data); diff --git a/qmk/keyboards/sofle_choc/keymaps/custom/lighting.c b/qmk/keyboards/sofle_choc/keymaps/custom/lighting.c index df3b5ec..f4a58d7 100644 --- a/qmk/keyboards/sofle_choc/keymaps/custom/lighting.c +++ b/qmk/keyboards/sofle_choc/keymaps/custom/lighting.c @@ -111,9 +111,6 @@ bool rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) { set_color(index, 42, 255, 255); } - //if (layer == 0 && ! flags) - // continue; - switch (keycode) { case KC_F1 ... KC_F11: set_color(index, 0, 0, 128); @@ -121,7 +118,9 @@ bool rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) { case KC_P1 ... KC_P0: case KC_1 ... KC_0: case KEY_6: - set_color(index, 42, 255, 255); + if (!is_star) { + set_color(index, 42, 255, 255); + } break; case KC_BACKSLASH: case KC_EQUAL: diff --git a/qmk/keyboards/sofle_choc/keymaps/custom/rules.mk b/qmk/keyboards/sofle_choc/keymaps/custom/rules.mk index 39886cd..33799c2 100644 --- a/qmk/keyboards/sofle_choc/keymaps/custom/rules.mk +++ b/qmk/keyboards/sofle_choc/keymaps/custom/rules.mk @@ -16,6 +16,7 @@ SRC += star_key.c \ enter_dance.c \ shift_dance.c \ layer_dance.c \ + tap_hold_dance.c \ keycodes.c \ overrides.c \ lighting.c \ 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; +} diff --git a/qmk/keyboards/sofle_choc/keymaps/custom/tap_hold_dance.h b/qmk/keyboards/sofle_choc/keymaps/custom/tap_hold_dance.h new file mode 100644 index 0000000..4c895d5 --- /dev/null +++ b/qmk/keyboards/sofle_choc/keymaps/custom/tap_hold_dance.h @@ -0,0 +1,25 @@ +#pragma once +#include QMK_KEYBOARD_H +#include "quad_tapdance.h" + +typedef struct { + td_state_t state; + const uint16_t tap; + const uint16_t hold; + uint16_t held; + bool left; +} tap_hold_dance_t; + +void tap_hold_dance_each(tap_dance_state_t *state, void *user_data); +void tap_hold_dance_finished(tap_dance_state_t *state, void *user_data); +void tap_hold_dance_reset(tap_dance_state_t *state, void *user_data); +void tap_hold_dance_released(tap_dance_state_t *state, void *user_data); +void tap_hold_dance_process_record(uint16_t keycode, keyrecord_t *record); +uint16_t tap_hold_dance_tapping_term(uint16_t keycode, keyrecord_t *record); + +#define ACTION_TAP_HOLD_DANCE(tap, hold, left) \ + { \ + .fn = {NULL, tap_hold_dance_finished, tap_hold_dance_reset, tap_hold_dance_released}, \ + .user_data = (void *)&((tap_hold_dance_t){TD_NONE, tap, hold, 0, 0}), \ + } + -- cgit v1.2.3