aboutsummaryrefslogtreecommitdiff
path: root/quantum/action.c
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/action.c')
-rw-r--r--quantum/action.c254
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)