aboutsummaryrefslogtreecommitdiff
path: root/quantum/action.c
diff options
context:
space:
mode:
authorDrashna Jaelre <drashna@live.com>2021-11-01 09:41:24 -0700
committerGitHub <noreply@github.com>2021-11-01 09:41:24 -0700
commit2980c63d3d4480a10bb1f7e6cf417bc9c9b65b72 (patch)
treed8ea4fd23db524ca69c1c518153e72a70d5642b9 /quantum/action.c
parentf7e94f6624cc06a0403ec3b20e12ff558132459d (diff)
downloadqmk_firmware-2980c63d3d4480a10bb1f7e6cf417bc9c9b65b72.tar.gz
qmk_firmware-2980c63d3d4480a10bb1f7e6cf417bc9c9b65b72.zip
Fix issues with Oneshot disabling (#14934)
Diffstat (limited to 'quantum/action.c')
-rw-r--r--quantum/action.c166
1 files changed, 102 insertions, 64 deletions
diff --git a/quantum/action.c b/quantum/action.c
index 95f39d23d..8c34b84ef 100644
--- a/quantum/action.c
+++ b/quantum/action.c
@@ -27,6 +27,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
27#include "action_util.h" 27#include "action_util.h"
28#include "action.h" 28#include "action.h"
29#include "wait.h" 29#include "wait.h"
30#include "keycode_config.h"
30 31
31#ifdef BACKLIGHT_ENABLE 32#ifdef BACKLIGHT_ENABLE
32# include "backlight.h" 33# include "backlight.h"
@@ -87,19 +88,21 @@ void action_exec(keyevent_t event) {
87 keyrecord_t record = {.event = event}; 88 keyrecord_t record = {.event = event};
88 89
89#ifndef NO_ACTION_ONESHOT 90#ifndef NO_ACTION_ONESHOT
91 if (!keymap_config.oneshot_disable) {
90# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) 92# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
91 if (has_oneshot_layer_timed_out()) { 93 if (has_oneshot_layer_timed_out()) {
92 clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); 94 clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
93 } 95 }
94 if (has_oneshot_mods_timed_out()) { 96 if (has_oneshot_mods_timed_out()) {
95 clear_oneshot_mods(); 97 clear_oneshot_mods();
96 } 98 }
97# ifdef SWAP_HANDS_ENABLE 99# ifdef SWAP_HANDS_ENABLE
98 if (has_oneshot_swaphands_timed_out()) { 100 if (has_oneshot_swaphands_timed_out()) {
99 clear_oneshot_swaphands(); 101 clear_oneshot_swaphands();
100 } 102 }
101# endif 103# endif
102# endif 104# endif
105 }
103#endif 106#endif
104 107
105#ifndef NO_ACTION_TAPPING 108#ifndef NO_ACTION_TAPPING
@@ -195,7 +198,7 @@ void process_record(keyrecord_t *record) {
195 198
196 if (!process_record_quantum(record)) { 199 if (!process_record_quantum(record)) {
197#ifndef NO_ACTION_ONESHOT 200#ifndef NO_ACTION_ONESHOT
198 if (is_oneshot_layer_active() && record->event.pressed) { 201 if (is_oneshot_layer_active() && record->event.pressed && !keymap_config.oneshot_disable) {
199 clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); 202 clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
200 } 203 }
201#endif 204#endif
@@ -260,7 +263,7 @@ void process_action(keyrecord_t *record, action_t action) {
260# ifdef SWAP_HANDS_ENABLE 263# ifdef SWAP_HANDS_ENABLE
261 && !(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)
262# endif 265# endif
263 ) { 266 && !keymap_config.oneshot_disable) {
264 clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); 267 clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
265 do_release_oneshot = !is_oneshot_layer_active(); 268 do_release_oneshot = !is_oneshot_layer_active();
266 } 269 }
@@ -304,41 +307,68 @@ void process_action(keyrecord_t *record, action_t action) {
304# ifndef NO_ACTION_ONESHOT 307# ifndef NO_ACTION_ONESHOT
305 case MODS_ONESHOT: 308 case MODS_ONESHOT:
306 // Oneshot modifier 309 // Oneshot modifier
307 if (event.pressed) { 310 if (keymap_config.oneshot_disable) {
308 if (tap_count == 0) { 311 if (event.pressed) {
309 dprint("MODS_TAP: Oneshot: 0\n"); 312 if (mods) {
310 register_mods(mods | get_oneshot_mods()); 313 if (IS_MOD(action.key.code) || action.key.code == KC_NO) {
311 } 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.
312 dprint("MODS_TAP: Oneshot: start\n"); 315 // This also makes LSFT(KC_LGUI) behave exactly the same as LGUI(KC_LSFT).
313 set_oneshot_mods(mods | get_oneshot_mods()); 316 // Same applies for some keys like KC_MEH which are declared as MEH(KC_NO).
314# if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1 317 add_mods(mods);
315 } else if (tap_count == ONESHOT_TAP_TOGGLE) { 318 } else {
316 dprint("MODS_TAP: Toggling oneshot"); 319 add_weak_mods(mods);
317 clear_oneshot_mods(); 320 }
318 set_oneshot_locked_mods(mods); 321 send_keyboard_report();
319 register_mods(mods); 322 }
320# endif 323 register_code(action.key.code);
321 } else { 324 } else {
322 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 }
323 } 334 }
324 } else { 335 } else {
325 if (tap_count == 0) { 336 if (event.pressed) {
326 clear_oneshot_mods(); 337 if (tap_count == 0) {
327 unregister_mods(mods); 338 dprint("MODS_TAP: Oneshot: 0\n");
328 } else if (tap_count == 1) { 339 register_mods(mods | get_oneshot_mods());
329 // Retain Oneshot mods 340 } else if (tap_count == 1) {
341 dprint("MODS_TAP: Oneshot: start\n");
342 set_oneshot_mods(mods | get_oneshot_mods());
330# if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1 343# if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1
331 if (mods & get_mods()) { 344 } else if (tap_count == ONESHOT_TAP_TOGGLE) {
332 clear_oneshot_locked_mods(); 345 dprint("MODS_TAP: Toggling oneshot");
333 clear_oneshot_mods(); 346 clear_oneshot_mods();
334 unregister_mods(mods); 347 set_oneshot_locked_mods(mods);
335 } 348 register_mods(mods);
336 } else if (tap_count == ONESHOT_TAP_TOGGLE) {
337 // Toggle Oneshot Layer
338# endif 349# endif
350 } else {
351 register_mods(mods | get_oneshot_mods());
352 }
339 } else { 353 } else {
340 clear_oneshot_mods(); 354 if (tap_count == 0) {
341 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 }
342 } 372 }
343 } 373 }
344 break; 374 break;
@@ -523,39 +553,47 @@ void process_action(keyrecord_t *record, action_t action) {
523# ifndef NO_ACTION_ONESHOT 553# ifndef NO_ACTION_ONESHOT
524 case OP_ONESHOT: 554 case OP_ONESHOT:
525 // Oneshot modifier 555 // Oneshot modifier
526# if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1 556 if (keymap_config.oneshot_disable) {
527 do_release_oneshot = false; 557 if (event.pressed) {
528 if (event.pressed) {
529 del_mods(get_oneshot_locked_mods());
530 if (get_oneshot_layer_state() == ONESHOT_TOGGLED) {
531 reset_oneshot_layer();
532 layer_off(action.layer_tap.val);
533 break;
534 } else if (tap_count < ONESHOT_TAP_TOGGLE) {
535 layer_on(action.layer_tap.val); 558 layer_on(action.layer_tap.val);
536 set_oneshot_layer(action.layer_tap.val, ONESHOT_START); 559 } else {
560 layer_off(action.layer_tap.val);
537 } 561 }
538 } else { 562 } else {
539 add_mods(get_oneshot_locked_mods()); 563# if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1
540 if (tap_count >= ONESHOT_TAP_TOGGLE) { 564 do_release_oneshot = false;
541 reset_oneshot_layer(); 565 if (event.pressed) {
542 clear_oneshot_locked_mods(); 566 del_mods(get_oneshot_locked_mods());
543 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 }
544 } else { 575 } else {
545 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 }
546 } 584 }
547 }
548# else 585# else
549 if (event.pressed) { 586 if (event.pressed) {
550 layer_on(action.layer_tap.val); 587 layer_on(action.layer_tap.val);
551 set_oneshot_layer(action.layer_tap.val, ONESHOT_START); 588 set_oneshot_layer(action.layer_tap.val, ONESHOT_START);
552 } else { 589 } else {
553 clear_oneshot_layer_state(ONESHOT_PRESSED); 590 clear_oneshot_layer_state(ONESHOT_PRESSED);
554 if (tap_count > 1) { 591 if (tap_count > 1) {
555 clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); 592 clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
593 }
556 } 594 }
557 }
558# endif 595# endif
596 }
559 break; 597 break;
560# endif 598# endif
561 default: 599 default: