aboutsummaryrefslogtreecommitdiff
path: root/qmk/keyboards/sofle_choc/keymaps/custom/shift_dance.c
diff options
context:
space:
mode:
Diffstat (limited to 'qmk/keyboards/sofle_choc/keymaps/custom/shift_dance.c')
-rw-r--r--qmk/keyboards/sofle_choc/keymaps/custom/shift_dance.c114
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};