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) |
