diff options
Diffstat (limited to 'qmk/keyboards/sofle_choc/keymaps/custom/shift_dance.c')
| -rw-r--r-- | qmk/keyboards/sofle_choc/keymaps/custom/shift_dance.c | 114 | 
1 files changed, 114 insertions, 0 deletions
| diff --git a/qmk/keyboards/sofle_choc/keymaps/custom/shift_dance.c b/qmk/keyboards/sofle_choc/keymaps/custom/shift_dance.c new file mode 100644 index 0000000..82448a4 --- /dev/null +++ b/qmk/keyboards/sofle_choc/keymaps/custom/shift_dance.c @@ -0,0 +1,114 @@ +#include QMK_KEYBOARD_H +#include "keymap_bepo.h" +#include "quad_tapdance.h" +#include "shift_dance.h" +// +// Definition for the key W. +// +// The main usage is to send the letter W when pressed, but the key is also +// used to activate the SHIFT mode when pressed. +// +static td_tap_t w_tap_state = { +    .state = TD_NONE +}; + +// Do not switch the supended mode when the key is released. +// This allow to remove the mod earler without reactivating automatically. +static bool inhibit_mod = 0; + +// Flag telling if the suspended mode is active or not. +static bool activated = 0; + +// If there is any other keypress before releasing the key, do not keep the +// layer once the key is release. +// +// This function is a callbackk called from process_record_user +void shift_dance_process_record(uint16_t keycode, keyrecord_t *record) { +    if (w_tap_state.state == TD_SINGLE_HOLD && record->event.pressed) { +        inhibit_mod = 1; +    } +    switch (keycode) { +        case KC_LSFT: +            activated = 0; +            break; +        // Leave the suspended mode on ESC +        case KC_ESC: +            if (activated) { +                set_mods(get_mods() & (!MOD_MASK_SHIFT)); +                activated = 0; +            } +            break; +        default: +            break; +    } +    return; +} + +void w_finished(tap_dance_state_t *state, void *user_data) { +    w_tap_state.state = cur_dance(state); +    switch (w_tap_state.state) { +        case TD_SINGLE_HOLD: +            caps_word_off(); +            if (get_mods() & MOD_MASK_SHIFT) { +                del_mods(MOD_MASK_SHIFT); +                inhibit_mod = 1; +            } +            register_code(KC_RIGHT_SHIFT); +            break; +        default: break; +    } +} + +void w_released(tap_dance_state_t *state, void *user_data) { +    if (state->finished && state->count > 1) +        // Exit prevently, we are sure in the next conditions we don’t fall in +        // this case. +        return; +    else if (!state->finished) +        tap_code16(BP_W); +    else if (!state->interrupted && !inhibit_mod) { +        // Final case, the key was keeped pressed without any other action +        // in this case, inverse the Shift mode, and update the activation flag +        set_mods(get_mods() ^ MOD_MASK_SHIFT); +        activated = get_mods() & MOD_MASK_SHIFT; +    } +    inhibit_mod = 0; +} + +void w_reset(tap_dance_state_t *state, void *user_data) { +    switch (w_tap_state.state) { +        case TD_SINGLE_HOLD: +            unregister_code(KC_RIGHT_SHIFT); +            break; +        default: break; +    } +    w_tap_state.state = TD_NONE; +} + + +// Deactivate the shift mode for the space key when the suspended mode is +// active. This allow to insert a normal space character instead of a +// unbreakable space. +const key_override_t shift_space_override = +    {.trigger_mods          = MOD_MASK_SHIFT, +    .layers                 = ~0, +    .suppressed_mods        = MOD_MASK_SHIFT, +    .options                = ko_options_default, +    .negative_mod_mask      = (uint8_t)0, +    .custom_action          = NULL, +    .context                = NULL, +    .trigger                = AL_SPC, +    .replacement            = AL_SPC, +    .enabled                = &activated}; + +const key_override_t shift_o_override = +    {.trigger_mods          = MOD_MASK_SHIFT, +    .layers                 = ~0, +    .suppressed_mods        = MOD_MASK_SHIFT, +    .options                = ko_options_default, +    .negative_mod_mask      = (uint8_t)0, +    .custom_action          = NULL, +    .context                = NULL, +    .trigger                = KC_O, +    .replacement            = KC_O, +    .enabled                = &activated}; | 
