diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c index 947e5118f..33d920554 100644 --- a/tmk_core/common/action.c +++ b/tmk_core/common/action.c @@ -93,6 +93,7 @@ void action_exec(keyevent_t event) #ifdef SWAP_HANDS_ENABLE bool swap_hands = false; +bool swap_held = false; void process_hand_swap(keyevent_t *event) { static swap_state_row_t swap_state[MATRIX_ROWS]; @@ -132,6 +133,27 @@ bool process_record_quantum(keyrecord_t *record) { return true; } +#ifndef NO_ACTION_TAPPING +// Allows for handling tap-hold actions immediately instead of waiting for TAPPING_TERM or another keypress. +void process_record_tap_hint(keyrecord_t *record) +{ + action_t action = layer_switch_get_action(record->event.key); + + switch (action.kind.id) { +#ifdef SWAP_HANDS_ENABLE + case ACT_SWAP_HANDS: + switch (action.swap.code) { + case OP_SH_TAP_TOGGLE: + default: + swap_hands = !swap_hands; + swap_held = true; + } + break; +#endif + } +} +#endif + void process_record(keyrecord_t *record) { if (IS_NOEVENT(record->event)) { return; } @@ -551,23 +573,37 @@ void process_action(keyrecord_t *record, action_t action) #ifndef NO_ACTION_TAPPING case OP_SH_TAP_TOGGLE: /* tap toggle */ - if (tap_count > 0) { - if (!event.pressed) { + + if (event.pressed) { + if (swap_held) { + swap_held = false; + } else { swap_hands = !swap_hands; } } else { - swap_hands = event.pressed; + if (tap_count < TAPPING_TOGGLE) { + swap_hands = !swap_hands; + } } break; default: + /* tap key */ if (tap_count > 0) { + if (swap_held) { + swap_hands = !swap_hands; // undo hold set up in _tap_hint + swap_held = false; + } if (event.pressed) { register_code(action.swap.code); } else { unregister_code(action.swap.code); + *record = (keyrecord_t){}; // hack: reset tap mode } } else { - swap_hands = event.pressed; + if (swap_held && !event.pressed) { + swap_hands = !swap_hands; // undo hold set up in _tap_hint + swap_held = false; + } } #endif } diff --git a/tmk_core/common/action.h b/tmk_core/common/action.h index 87027dede..acc55c7d3 100644 --- a/tmk_core/common/action.h +++ b/tmk_core/common/action.h @@ -96,6 +96,10 @@ void clear_keyboard_but_mods(void); void layer_switch(uint8_t new_layer); bool is_tap_key(keypos_t key); +#ifndef NO_ACTION_TAPPING +void process_record_tap_hint(keyrecord_t *record); +#endif + /* debug */ void debug_event(keyevent_t event); void debug_record(keyrecord_t record); diff --git a/tmk_core/common/action_code.h b/tmk_core/common/action_code.h index 05bc84573..fe2735b97 100644 --- a/tmk_core/common/action_code.h +++ b/tmk_core/common/action_code.h @@ -186,7 +186,7 @@ typedef union { } func; struct action_swap { uint8_t code :8; - uint8_t opt :4; + uint8_t opt :4; uint8_t kind :4; } swap; } action_t; @@ -243,7 +243,7 @@ enum usage_pages { -/* +/* * Layer Actions */ enum layer_param_on { @@ -257,7 +257,7 @@ enum layer_param_bit_op { OP_BIT_XOR = 2, OP_BIT_SET = 3, }; -enum layer_pram_tap_op { +enum layer_param_tap_op { OP_TAP_TOGGLE = 0xF0, OP_ON_OFF, OP_OFF_ON, @@ -329,7 +329,7 @@ enum function_opts { #define ACTION_FUNCTION_TAP(id) ACTION(ACT_FUNCTION, FUNC_TAP<<8 | (id)) #define ACTION_FUNCTION_OPT(id, opt) ACTION(ACT_FUNCTION, (opt)<<8 | (id)) /* OneHand Support */ -enum swap_hands_pram_tap_op { +enum swap_hands_param_tap_op { OP_SH_TOGGLE = 0xF0, OP_SH_TAP_TOGGLE, OP_SH_ON_OFF, diff --git a/tmk_core/common/action_tapping.c b/tmk_core/common/action_tapping.c index 531a3ca34..6280c6c36 100644 --- a/tmk_core/common/action_tapping.c +++ b/tmk_core/common/action_tapping.c @@ -263,7 +263,7 @@ bool process_tapping(keyrecord_t *keyp) return true; } } else { - // FIX: process_aciton here? + // FIX: process_action here? // timeout. no sequential tap. debug("Tapping: End(Timeout after releasing last tap): "); debug_event(event); debug("\n"); @@ -277,6 +277,7 @@ bool process_tapping(keyrecord_t *keyp) if (event.pressed && is_tap_key(event.key)) { debug("Tapping: Start(Press tap key).\n"); tapping_key = *keyp; + process_record_tap_hint(&tapping_key); waiting_buffer_scan_tap(); debug_tapping_key(); return true;