diff options
Diffstat (limited to 'quantum/action.c')
-rw-r--r-- | quantum/action.c | 254 |
1 files changed, 152 insertions, 102 deletions
diff --git a/quantum/action.c b/quantum/action.c index be135f18f..5c33bd6d2 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 | } |
@@ -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; |
@@ -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: |
@@ -782,9 +821,10 @@ void register_code(uint8_t code) { | |||
782 | } | 821 | } |
783 | #endif | 822 | #endif |
784 | 823 | ||
785 | else if IS_KEY (code) { | 824 | else if |
786 | // TODO: should push command_proc out of this block? | 825 | IS_KEY(code) { |
787 | if (command_proc(code)) return; | 826 | // TODO: should push command_proc out of this block? |
827 | if (command_proc(code)) return; | ||
788 | 828 | ||
789 | #ifndef NO_ACTION_ONESHOT | 829 | #ifndef NO_ACTION_ONESHOT |
790 | /* TODO: remove | 830 | /* TODO: remove |
@@ -801,33 +841,35 @@ void register_code(uint8_t code) { | |||
801 | } else | 841 | } else |
802 | */ | 842 | */ |
803 | #endif | 843 | #endif |
804 | { | 844 | { |
805 | // Force a new key press if the key is already pressed | 845 | // Force a new key press if the key is already pressed |
806 | // without this, keys with the same keycode, but different | 846 | // without this, keys with the same keycode, but different |
807 | // modifiers will be reported incorrectly, see issue #1708 | 847 | // modifiers will be reported incorrectly, see issue #1708 |
808 | if (is_key_pressed(keyboard_report, code)) { | 848 | if (is_key_pressed(keyboard_report, code)) { |
809 | del_key(code); | 849 | del_key(code); |
850 | send_keyboard_report(); | ||
851 | } | ||
852 | add_key(code); | ||
810 | send_keyboard_report(); | 853 | send_keyboard_report(); |
811 | } | 854 | } |
812 | add_key(code); | 855 | } |
856 | else if | ||
857 | IS_MOD(code) { | ||
858 | add_mods(MOD_BIT(code)); | ||
813 | send_keyboard_report(); | 859 | send_keyboard_report(); |
814 | } | 860 | } |
815 | } else if IS_MOD (code) { | ||
816 | add_mods(MOD_BIT(code)); | ||
817 | send_keyboard_report(); | ||
818 | } | ||
819 | #ifdef EXTRAKEY_ENABLE | 861 | #ifdef EXTRAKEY_ENABLE |
820 | else if IS_SYSTEM (code) { | 862 | else if |
821 | host_system_send(KEYCODE2SYSTEM(code)); | 863 | IS_SYSTEM(code) { host_system_send(KEYCODE2SYSTEM(code)); } |
822 | } else if IS_CONSUMER (code) { | 864 | else if |
823 | host_consumer_send(KEYCODE2CONSUMER(code)); | 865 | IS_CONSUMER(code) { host_consumer_send(KEYCODE2CONSUMER(code)); } |
824 | } | ||
825 | #endif | 866 | #endif |
826 | #ifdef MOUSEKEY_ENABLE | 867 | #ifdef MOUSEKEY_ENABLE |
827 | else if IS_MOUSEKEY (code) { | 868 | else if |
828 | mousekey_on(code); | 869 | IS_MOUSEKEY(code) { |
829 | mousekey_send(); | 870 | mousekey_on(code); |
830 | } | 871 | mousekey_send(); |
872 | } | ||
831 | #endif | 873 | #endif |
832 | } | 874 | } |
833 | 875 | ||
@@ -872,22 +914,26 @@ void unregister_code(uint8_t code) { | |||
872 | } | 914 | } |
873 | #endif | 915 | #endif |
874 | 916 | ||
875 | else if IS_KEY (code) { | 917 | else if |
876 | del_key(code); | 918 | IS_KEY(code) { |
877 | send_keyboard_report(); | 919 | del_key(code); |
878 | } else if IS_MOD (code) { | 920 | send_keyboard_report(); |
879 | del_mods(MOD_BIT(code)); | 921 | } |
880 | send_keyboard_report(); | 922 | else if |
881 | } else if IS_SYSTEM (code) { | 923 | IS_MOD(code) { |
882 | host_system_send(0); | 924 | del_mods(MOD_BIT(code)); |
883 | } else if IS_CONSUMER (code) { | 925 | send_keyboard_report(); |
884 | host_consumer_send(0); | 926 | } |
885 | } | 927 | else if |
928 | IS_SYSTEM(code) { host_system_send(0); } | ||
929 | else if | ||
930 | IS_CONSUMER(code) { host_consumer_send(0); } | ||
886 | #ifdef MOUSEKEY_ENABLE | 931 | #ifdef MOUSEKEY_ENABLE |
887 | else if IS_MOUSEKEY (code) { | 932 | else if |
888 | mousekey_off(code); | 933 | IS_MOUSEKEY(code) { |
889 | mousekey_send(); | 934 | mousekey_off(code); |
890 | } | 935 | mousekey_send(); |
936 | } | ||
891 | #endif | 937 | #endif |
892 | } | 938 | } |
893 | 939 | ||
@@ -988,6 +1034,10 @@ void clear_keyboard_but_mods_and_keys() { | |||
988 | mousekey_clear(); | 1034 | mousekey_clear(); |
989 | mousekey_send(); | 1035 | mousekey_send(); |
990 | #endif | 1036 | #endif |
1037 | #ifdef PROGRAMMABLE_BUTTON_ENABLE | ||
1038 | programmable_button_clear(); | ||
1039 | programmable_button_send(); | ||
1040 | #endif | ||
991 | } | 1041 | } |
992 | 1042 | ||
993 | /** \brief Utilities for actions. (FIXME: Needs better description) | 1043 | /** \brief Utilities for actions. (FIXME: Needs better description) |