aboutsummaryrefslogtreecommitdiff
path: root/quantum/action.c
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/action.c')
-rw-r--r--quantum/action.c223
1 files changed, 133 insertions, 90 deletions
diff --git a/quantum/action.c b/quantum/action.c
index 208690f5e..ceaaa551f 100644
--- a/quantum/action.c
+++ b/quantum/action.c
@@ -18,6 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
18#include "keycode.h" 18#include "keycode.h"
19#include "keyboard.h" 19#include "keyboard.h"
20#include "mousekey.h" 20#include "mousekey.h"
21#include "programmable_button.h"
21#include "command.h" 22#include "command.h"
22#include "led.h" 23#include "led.h"
23#include "action_layer.h" 24#include "action_layer.h"
@@ -26,6 +27,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
26#include "action_util.h" 27#include "action_util.h"
27#include "action.h" 28#include "action.h"
28#include "wait.h" 29#include "wait.h"
30#include "keycode_config.h"
29 31
30#ifdef BACKLIGHT_ENABLE 32#ifdef BACKLIGHT_ENABLE
31# include "backlight.h" 33# include "backlight.h"
@@ -86,19 +88,21 @@ void action_exec(keyevent_t event) {
86 keyrecord_t record = {.event = event}; 88 keyrecord_t record = {.event = event};
87 89
88#ifndef NO_ACTION_ONESHOT 90#ifndef NO_ACTION_ONESHOT
91 if (!keymap_config.oneshot_disable) {
89# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) 92# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
90 if (has_oneshot_layer_timed_out()) { 93 if (has_oneshot_layer_timed_out()) {
91 clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); 94 clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
92 } 95 }
93 if (has_oneshot_mods_timed_out()) { 96 if (has_oneshot_mods_timed_out()) {
94 clear_oneshot_mods(); 97 clear_oneshot_mods();
95 } 98 }
96# ifdef SWAP_HANDS_ENABLE 99# ifdef SWAP_HANDS_ENABLE
97 if (has_oneshot_swaphands_timed_out()) { 100 if (has_oneshot_swaphands_timed_out()) {
98 clear_oneshot_swaphands(); 101 clear_oneshot_swaphands();
99 } 102 }
100# endif 103# endif
101# endif 104# endif
105 }
102#endif 106#endif
103 107
104#ifndef NO_ACTION_TAPPING 108#ifndef NO_ACTION_TAPPING
@@ -194,7 +198,7 @@ void process_record(keyrecord_t *record) {
194 198
195 if (!process_record_quantum(record)) { 199 if (!process_record_quantum(record)) {
196#ifndef NO_ACTION_ONESHOT 200#ifndef NO_ACTION_ONESHOT
197 if (is_oneshot_layer_active() && record->event.pressed) { 201 if (is_oneshot_layer_active() && record->event.pressed && !keymap_config.oneshot_disable) {
198 clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); 202 clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
199 } 203 }
200#endif 204#endif
@@ -259,7 +263,7 @@ void process_action(keyrecord_t *record, action_t action) {
259# ifdef SWAP_HANDS_ENABLE 263# ifdef SWAP_HANDS_ENABLE
260 && !(action.kind.id == ACT_SWAP_HANDS && action.swap.code == OP_SH_ONESHOT) 264 && !(action.kind.id == ACT_SWAP_HANDS && action.swap.code == OP_SH_ONESHOT)
261# endif 265# endif
262 ) { 266 && !keymap_config.oneshot_disable) {
263 clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); 267 clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
264 do_release_oneshot = !is_oneshot_layer_active(); 268 do_release_oneshot = !is_oneshot_layer_active();
265 } 269 }
@@ -273,8 +277,8 @@ void process_action(keyrecord_t *record, action_t action) {
273 if (event.pressed) { 277 if (event.pressed) {
274 if (mods) { 278 if (mods) {
275 if (IS_MOD(action.key.code) || action.key.code == KC_NO) { 279 if (IS_MOD(action.key.code) || action.key.code == KC_NO) {
276 // e.g. LSFT(KC_LGUI): we don't want the LSFT to be weak as it would make it useless. 280 // e.g. LSFT(KC_LEFT_GUI): we don't want the LSFT to be weak as it would make it useless.
277 // This also makes LSFT(KC_LGUI) behave exactly the same as LGUI(KC_LSFT). 281 // This also makes LSFT(KC_LEFT_GUI) behave exactly the same as LGUI(KC_LEFT_SHIFT).
278 // Same applies for some keys like KC_MEH which are declared as MEH(KC_NO). 282 // Same applies for some keys like KC_MEH which are declared as MEH(KC_NO).
279 add_mods(mods); 283 add_mods(mods);
280 } else { 284 } else {
@@ -303,41 +307,68 @@ void process_action(keyrecord_t *record, action_t action) {
303# ifndef NO_ACTION_ONESHOT 307# ifndef NO_ACTION_ONESHOT
304 case MODS_ONESHOT: 308 case MODS_ONESHOT:
305 // Oneshot modifier 309 // Oneshot modifier
306 if (event.pressed) { 310 if (keymap_config.oneshot_disable) {
307 if (tap_count == 0) { 311 if (event.pressed) {
308 dprint("MODS_TAP: Oneshot: 0\n"); 312 if (mods) {
309 register_mods(mods | get_oneshot_mods()); 313 if (IS_MOD(action.key.code) || action.key.code == KC_NO) {
310 } else if (tap_count == 1) { 314 // e.g. LSFT(KC_LGUI): we don't want the LSFT to be weak as it would make it useless.
311 dprint("MODS_TAP: Oneshot: start\n"); 315 // This also makes LSFT(KC_LGUI) behave exactly the same as LGUI(KC_LSFT).
312 set_oneshot_mods(mods | get_oneshot_mods()); 316 // Same applies for some keys like KC_MEH which are declared as MEH(KC_NO).
313# if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1 317 add_mods(mods);
314 } else if (tap_count == ONESHOT_TAP_TOGGLE) { 318 } else {
315 dprint("MODS_TAP: Toggling oneshot"); 319 add_weak_mods(mods);
316 clear_oneshot_mods(); 320 }
317 set_oneshot_locked_mods(mods); 321 send_keyboard_report();
318 register_mods(mods); 322 }
319# endif 323 register_code(action.key.code);
320 } else { 324 } else {
321 register_mods(mods | get_oneshot_mods()); 325 unregister_code(action.key.code);
326 if (mods) {
327 if (IS_MOD(action.key.code) || action.key.code == KC_NO) {
328 del_mods(mods);
329 } else {
330 del_weak_mods(mods);
331 }
332 send_keyboard_report();
333 }
322 } 334 }
323 } else { 335 } else {
324 if (tap_count == 0) { 336 if (event.pressed) {
325 clear_oneshot_mods(); 337 if (tap_count == 0) {
326 unregister_mods(mods); 338 dprint("MODS_TAP: Oneshot: 0\n");
327 } else if (tap_count == 1) { 339 register_mods(mods | get_oneshot_mods());
328 // Retain Oneshot mods 340 } else if (tap_count == 1) {
341 dprint("MODS_TAP: Oneshot: start\n");
342 set_oneshot_mods(mods | get_oneshot_mods());
329# if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1 343# if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1
330 if (mods & get_mods()) { 344 } else if (tap_count == ONESHOT_TAP_TOGGLE) {
331 clear_oneshot_locked_mods(); 345 dprint("MODS_TAP: Toggling oneshot");
332 clear_oneshot_mods(); 346 clear_oneshot_mods();
333 unregister_mods(mods); 347 set_oneshot_locked_mods(mods);
334 } 348 register_mods(mods);
335 } else if (tap_count == ONESHOT_TAP_TOGGLE) {
336 // Toggle Oneshot Layer
337# endif 349# endif
350 } else {
351 register_mods(mods | get_oneshot_mods());
352 }
338 } else { 353 } else {
339 clear_oneshot_mods(); 354 if (tap_count == 0) {
340 unregister_mods(mods); 355 clear_oneshot_mods();
356 unregister_mods(mods);
357 } else if (tap_count == 1) {
358 // Retain Oneshot mods
359# if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1
360 if (mods & get_mods()) {
361 clear_oneshot_locked_mods();
362 clear_oneshot_mods();
363 unregister_mods(mods);
364 }
365 } else if (tap_count == ONESHOT_TAP_TOGGLE) {
366 // Toggle Oneshot Layer
367# endif
368 } else {
369 clear_oneshot_mods();
370 unregister_mods(mods);
371 }
341 } 372 }
342 } 373 }
343 break; 374 break;
@@ -379,7 +410,7 @@ void process_action(keyrecord_t *record, action_t action) {
379 } else { 410 } else {
380 if (tap_count > 0) { 411 if (tap_count > 0) {
381 dprint("MODS_TAP: Tap: unregister_code\n"); 412 dprint("MODS_TAP: Tap: unregister_code\n");
382 if (action.layer_tap.code == KC_CAPS) { 413 if (action.layer_tap.code == KC_CAPS_LOCK) {
383 wait_ms(TAP_HOLD_CAPS_DELAY); 414 wait_ms(TAP_HOLD_CAPS_DELAY);
384 } else { 415 } else {
385 wait_ms(TAP_CODE_DELAY); 416 wait_ms(TAP_CODE_DELAY);
@@ -522,39 +553,47 @@ void process_action(keyrecord_t *record, action_t action) {
522# ifndef NO_ACTION_ONESHOT 553# ifndef NO_ACTION_ONESHOT
523 case OP_ONESHOT: 554 case OP_ONESHOT:
524 // Oneshot modifier 555 // Oneshot modifier
525# if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1 556 if (keymap_config.oneshot_disable) {
526 do_release_oneshot = false; 557 if (event.pressed) {
527 if (event.pressed) {
528 del_mods(get_oneshot_locked_mods());
529 if (get_oneshot_layer_state() == ONESHOT_TOGGLED) {
530 reset_oneshot_layer();
531 layer_off(action.layer_tap.val);
532 break;
533 } else if (tap_count < ONESHOT_TAP_TOGGLE) {
534 layer_on(action.layer_tap.val); 558 layer_on(action.layer_tap.val);
535 set_oneshot_layer(action.layer_tap.val, ONESHOT_START); 559 } else {
560 layer_off(action.layer_tap.val);
536 } 561 }
537 } else { 562 } else {
538 add_mods(get_oneshot_locked_mods()); 563# if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1
539 if (tap_count >= ONESHOT_TAP_TOGGLE) { 564 do_release_oneshot = false;
540 reset_oneshot_layer(); 565 if (event.pressed) {
541 clear_oneshot_locked_mods(); 566 del_mods(get_oneshot_locked_mods());
542 set_oneshot_layer(action.layer_tap.val, ONESHOT_TOGGLED); 567 if (get_oneshot_layer_state() == ONESHOT_TOGGLED) {
568 reset_oneshot_layer();
569 layer_off(action.layer_tap.val);
570 break;
571 } else if (tap_count < ONESHOT_TAP_TOGGLE) {
572 layer_on(action.layer_tap.val);
573 set_oneshot_layer(action.layer_tap.val, ONESHOT_START);
574 }
543 } else { 575 } else {
544 clear_oneshot_layer_state(ONESHOT_PRESSED); 576 add_mods(get_oneshot_locked_mods());
577 if (tap_count >= ONESHOT_TAP_TOGGLE) {
578 reset_oneshot_layer();
579 clear_oneshot_locked_mods();
580 set_oneshot_layer(action.layer_tap.val, ONESHOT_TOGGLED);
581 } else {
582 clear_oneshot_layer_state(ONESHOT_PRESSED);
583 }
545 } 584 }
546 }
547# else 585# else
548 if (event.pressed) { 586 if (event.pressed) {
549 layer_on(action.layer_tap.val); 587 layer_on(action.layer_tap.val);
550 set_oneshot_layer(action.layer_tap.val, ONESHOT_START); 588 set_oneshot_layer(action.layer_tap.val, ONESHOT_START);
551 } else { 589 } else {
552 clear_oneshot_layer_state(ONESHOT_PRESSED); 590 clear_oneshot_layer_state(ONESHOT_PRESSED);
553 if (tap_count > 1) { 591 if (tap_count > 1) {
554 clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); 592 clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
593 }
555 } 594 }
556 }
557# endif 595# endif
596 }
558 break; 597 break;
559# endif 598# endif
560 default: 599 default:
@@ -570,7 +609,7 @@ void process_action(keyrecord_t *record, action_t action) {
570 } else { 609 } else {
571 if (tap_count > 0) { 610 if (tap_count > 0) {
572 dprint("KEYMAP_TAP_KEY: Tap: unregister_code\n"); 611 dprint("KEYMAP_TAP_KEY: Tap: unregister_code\n");
573 if (action.layer_tap.code == KC_CAPS) { 612 if (action.layer_tap.code == KC_CAPS_LOCK) {
574 wait_ms(TAP_HOLD_CAPS_DELAY); 613 wait_ms(TAP_HOLD_CAPS_DELAY);
575 } else { 614 } else {
576 wait_ms(TAP_CODE_DELAY); 615 wait_ms(TAP_CODE_DELAY);
@@ -747,37 +786,37 @@ void register_code(uint8_t code) {
747 return; 786 return;
748 } 787 }
749#ifdef LOCKING_SUPPORT_ENABLE 788#ifdef LOCKING_SUPPORT_ENABLE
750 else if (KC_LOCKING_CAPS == code) { 789 else if (KC_LOCKING_CAPS_LOCK == code) {
751# ifdef LOCKING_RESYNC_ENABLE 790# ifdef LOCKING_RESYNC_ENABLE
752 // Resync: ignore if caps lock already is on 791 // Resync: ignore if caps lock already is on
753 if (host_keyboard_leds() & (1 << USB_LED_CAPS_LOCK)) return; 792 if (host_keyboard_leds() & (1 << USB_LED_CAPS_LOCK)) return;
754# endif 793# endif
755 add_key(KC_CAPSLOCK); 794 add_key(KC_CAPS_LOCK);
756 send_keyboard_report(); 795 send_keyboard_report();
757 wait_ms(100); 796 wait_ms(100);
758 del_key(KC_CAPSLOCK); 797 del_key(KC_CAPS_LOCK);
759 send_keyboard_report(); 798 send_keyboard_report();
760 } 799 }
761 800
762 else if (KC_LOCKING_NUM == code) { 801 else if (KC_LOCKING_NUM_LOCK == code) {
763# ifdef LOCKING_RESYNC_ENABLE 802# ifdef LOCKING_RESYNC_ENABLE
764 if (host_keyboard_leds() & (1 << USB_LED_NUM_LOCK)) return; 803 if (host_keyboard_leds() & (1 << USB_LED_NUM_LOCK)) return;
765# endif 804# endif
766 add_key(KC_NUMLOCK); 805 add_key(KC_NUM_LOCK);
767 send_keyboard_report(); 806 send_keyboard_report();
768 wait_ms(100); 807 wait_ms(100);
769 del_key(KC_NUMLOCK); 808 del_key(KC_NUM_LOCK);
770 send_keyboard_report(); 809 send_keyboard_report();
771 } 810 }
772 811
773 else if (KC_LOCKING_SCROLL == code) { 812 else if (KC_LOCKING_SCROLL_LOCK == code) {
774# ifdef LOCKING_RESYNC_ENABLE 813# ifdef LOCKING_RESYNC_ENABLE
775 if (host_keyboard_leds() & (1 << USB_LED_SCROLL_LOCK)) return; 814 if (host_keyboard_leds() & (1 << USB_LED_SCROLL_LOCK)) return;
776# endif 815# endif
777 add_key(KC_SCROLLLOCK); 816 add_key(KC_SCROLL_LOCK);
778 send_keyboard_report(); 817 send_keyboard_report();
779 wait_ms(100); 818 wait_ms(100);
780 del_key(KC_SCROLLLOCK); 819 del_key(KC_SCROLL_LOCK);
781 send_keyboard_report(); 820 send_keyboard_report();
782 } 821 }
783#endif 822#endif
@@ -843,34 +882,34 @@ void unregister_code(uint8_t code) {
843 return; 882 return;
844 } 883 }
845#ifdef LOCKING_SUPPORT_ENABLE 884#ifdef LOCKING_SUPPORT_ENABLE
846 else if (KC_LOCKING_CAPS == code) { 885 else if (KC_LOCKING_CAPS_LOCK == code) {
847# ifdef LOCKING_RESYNC_ENABLE 886# ifdef LOCKING_RESYNC_ENABLE
848 // Resync: ignore if caps lock already is off 887 // Resync: ignore if caps lock already is off
849 if (!(host_keyboard_leds() & (1 << USB_LED_CAPS_LOCK))) return; 888 if (!(host_keyboard_leds() & (1 << USB_LED_CAPS_LOCK))) return;
850# endif 889# endif
851 add_key(KC_CAPSLOCK); 890 add_key(KC_CAPS_LOCK);
852 send_keyboard_report(); 891 send_keyboard_report();
853 del_key(KC_CAPSLOCK); 892 del_key(KC_CAPS_LOCK);
854 send_keyboard_report(); 893 send_keyboard_report();
855 } 894 }
856 895
857 else if (KC_LOCKING_NUM == code) { 896 else if (KC_LOCKING_NUM_LOCK == code) {
858# ifdef LOCKING_RESYNC_ENABLE 897# ifdef LOCKING_RESYNC_ENABLE
859 if (!(host_keyboard_leds() & (1 << USB_LED_NUM_LOCK))) return; 898 if (!(host_keyboard_leds() & (1 << USB_LED_NUM_LOCK))) return;
860# endif 899# endif
861 add_key(KC_NUMLOCK); 900 add_key(KC_NUM_LOCK);
862 send_keyboard_report(); 901 send_keyboard_report();
863 del_key(KC_NUMLOCK); 902 del_key(KC_NUM_LOCK);
864 send_keyboard_report(); 903 send_keyboard_report();
865 } 904 }
866 905
867 else if (KC_LOCKING_SCROLL == code) { 906 else if (KC_LOCKING_SCROLL_LOCK == code) {
868# ifdef LOCKING_RESYNC_ENABLE 907# ifdef LOCKING_RESYNC_ENABLE
869 if (!(host_keyboard_leds() & (1 << USB_LED_SCROLL_LOCK))) return; 908 if (!(host_keyboard_leds() & (1 << USB_LED_SCROLL_LOCK))) return;
870# endif 909# endif
871 add_key(KC_SCROLLLOCK); 910 add_key(KC_SCROLL_LOCK);
872 send_keyboard_report(); 911 send_keyboard_report();
873 del_key(KC_SCROLLLOCK); 912 del_key(KC_SCROLL_LOCK);
874 send_keyboard_report(); 913 send_keyboard_report();
875 } 914 }
876#endif 915#endif
@@ -913,9 +952,9 @@ void tap_code_delay(uint8_t code, uint16_t delay) {
913 952
914/** \brief Tap a keycode with the default delay. 953/** \brief Tap a keycode with the default delay.
915 * 954 *
916 * \param code The basic keycode to tap. If `code` is `KC_CAPS`, the delay will be `TAP_HOLD_CAPS_DELAY`, otherwise `TAP_CODE_DELAY`, if defined. 955 * \param code The basic keycode to tap. If `code` is `KC_CAPS_LOCK`, the delay will be `TAP_HOLD_CAPS_DELAY`, otherwise `TAP_CODE_DELAY`, if defined.
917 */ 956 */
918void tap_code(uint8_t code) { tap_code_delay(code, code == KC_CAPS ? TAP_HOLD_CAPS_DELAY : TAP_CODE_DELAY); } 957void tap_code(uint8_t code) { tap_code_delay(code, code == KC_CAPS_LOCK ? TAP_HOLD_CAPS_DELAY : TAP_CODE_DELAY); }
919 958
920/** \brief Adds the given physically pressed modifiers and sends a keyboard report immediately. 959/** \brief Adds the given physically pressed modifiers and sends a keyboard report immediately.
921 * 960 *
@@ -995,6 +1034,10 @@ void clear_keyboard_but_mods_and_keys() {
995 mousekey_clear(); 1034 mousekey_clear();
996 mousekey_send(); 1035 mousekey_send();
997#endif 1036#endif
1037#ifdef PROGRAMMABLE_BUTTON_ENABLE
1038 programmable_button_clear();
1039 programmable_button_send();
1040#endif
998} 1041}
999 1042
1000/** \brief Utilities for actions. (FIXME: Needs better description) 1043/** \brief Utilities for actions. (FIXME: Needs better description)
@@ -1035,7 +1078,7 @@ bool is_tap_action(action_t action) {
1035 case ACT_LAYER_TAP: 1078 case ACT_LAYER_TAP:
1036 case ACT_LAYER_TAP_EXT: 1079 case ACT_LAYER_TAP_EXT:
1037 switch (action.layer_tap.code) { 1080 switch (action.layer_tap.code) {
1038 case KC_NO ... KC_RGUI: 1081 case KC_NO ... KC_RIGHT_GUI:
1039 case OP_TAP_TOGGLE: 1082 case OP_TAP_TOGGLE:
1040 case OP_ONESHOT: 1083 case OP_ONESHOT:
1041 return true; 1084 return true;
@@ -1043,7 +1086,7 @@ bool is_tap_action(action_t action) {
1043 return false; 1086 return false;
1044 case ACT_SWAP_HANDS: 1087 case ACT_SWAP_HANDS:
1045 switch (action.swap.code) { 1088 switch (action.swap.code) {
1046 case KC_NO ... KC_RGUI: 1089 case KC_NO ... KC_RIGHT_GUI:
1047 case OP_SH_TAP_TOGGLE: 1090 case OP_SH_TAP_TOGGLE:
1048 return true; 1091 return true;
1049 } 1092 }