aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMorton Jonuschat <mjonuschat@gmail.com>2020-02-13 19:30:32 -0800
committerGitHub <noreply@github.com>2020-02-14 03:30:32 +0000
commit806cd392e70b81bbefdc06f111d2562ead4094ba (patch)
treecb049878003333b7eba63b01ce7d95810f672e3e
parent9241d11dc5f98a862fb58cb0c125d14451568e78 (diff)
downloadqmk_firmware-806cd392e70b81bbefdc06f111d2562ead4094ba.tar.gz
qmk_firmware-806cd392e70b81bbefdc06f111d2562ead4094ba.zip
[osx_neo2] Bugfixes and improvements to Ergodox macOS Neo2 keymap (#8154)
* Use TAPPING_TERM constant (and redefine value to 200ms) * change TAPPING_TOGGLE to 2 to require two taps to lock in layer 4 * add support for Shift-Command 3/4/5 key combinations that are used in macOS Catalina * avoid false positive tap detecion for RMOD3 when the whole sequence of pressing RMOD3, tapping another key and releasing RMOD3 took less than TAPPING_TERM milliseconds. * replace SEND_STRING with tap_code()/tap_code16(), saving ~860 bytes in compiled firmware size.
-rw-r--r--layouts/community/ergodox/osx_neo2/config.h7
-rw-r--r--layouts/community/ergodox/osx_neo2/keymap.c113
2 files changed, 79 insertions, 41 deletions
diff --git a/layouts/community/ergodox/osx_neo2/config.h b/layouts/community/ergodox/osx_neo2/config.h
new file mode 100644
index 000000000..faa79da02
--- /dev/null
+++ b/layouts/community/ergodox/osx_neo2/config.h
@@ -0,0 +1,7 @@
1#pragma once
2
3#undef TAPPING_TERM
4#define TAPPING_TERM 200
5
6#undef TAPPING_TOGGLE
7#define TAPPING_TOGGLE 2
diff --git a/layouts/community/ergodox/osx_neo2/keymap.c b/layouts/community/ergodox/osx_neo2/keymap.c
index 9e379c73f..3dbfceabc 100644
--- a/layouts/community/ergodox/osx_neo2/keymap.c
+++ b/layouts/community/ergodox/osx_neo2/keymap.c
@@ -5,6 +5,9 @@
5// Timer to detect tap/hold on NEO_RMOD3 key 5// Timer to detect tap/hold on NEO_RMOD3 key
6static uint16_t neo3_timer; 6static uint16_t neo3_timer;
7// State bitmap to track which key(s) enabled NEO_3 layer 7// State bitmap to track which key(s) enabled NEO_3 layer
8// Bit 1 = LMOD state
9// Bit 2 = RMOD state
10// Bit 3 = Seen other keypress
8static uint8_t neo3_state = 0; 11static uint8_t neo3_state = 0;
9// State bitmap to track key combo for CAPSLOCK 12// State bitmap to track key combo for CAPSLOCK
10static uint8_t capslock_state = 0; 13static uint8_t capslock_state = 0;
@@ -453,6 +456,7 @@ void tap_with_modifiers(uint16_t keycode, uint8_t force_modifiers) {
453bool process_record_user_shifted(uint16_t keycode, keyrecord_t *record) { 456bool process_record_user_shifted(uint16_t keycode, keyrecord_t *record) {
454 uint8_t active_modifiers = get_mods(); 457 uint8_t active_modifiers = get_mods();
455 uint8_t shifted = active_modifiers & MOD_MASK_SHIFT; 458 uint8_t shifted = active_modifiers & MOD_MASK_SHIFT;
459 uint8_t command = active_modifiers & MOD_MASK_GUI;
456 460
457 // Early return on key release 461 // Early return on key release
458 if (!record->event.pressed) { 462 if (!record->event.pressed) {
@@ -465,67 +469,81 @@ bool process_record_user_shifted(uint16_t keycode, keyrecord_t *record) {
465 switch (keycode) { 469 switch (keycode) {
466 case NEO2_1: 470 case NEO2_1:
467 // degree symbol 471 // degree symbol
468 SEND_STRING(SS_DOWN(X_LALT) SS_DOWN(X_LSHIFT) SS_TAP(X_8) SS_UP(X_LSHIFT) SS_UP(X_LALT)); 472 tap_code16(S(A(KC_8)));
469 break; 473 break;
470 case NEO2_2: 474 case NEO2_2:
471 // section symbol 475 // section symbol
472 SEND_STRING(SS_DOWN(X_LALT) SS_TAP(X_6) SS_UP(X_LALT)); 476 tap_code16(A(KC_6));
473 break; 477 break;
474 case NEO2_3: 478 case NEO2_3:
475 // There is no OSX key combination for the script small l character 479 if (command) {
480 tap_code16(S(G(KC_3)));
481 } else {
482 // There is no OSX key combination for the script small l character
483 }
476 break; 484 break;
477 case NEO2_4: 485 case NEO2_4:
478 // right angled quote 486 if (command) {
479 SEND_STRING(SS_DOWN(X_LALT) SS_DOWN(X_LSHIFT) SS_TAP(X_BSLASH) SS_UP(X_LSHIFT) SS_UP(X_LALT)); 487 tap_code16(S(G(KC_4)));
488 } else {
489 tap_code16(S(A(KC_BSLASH)));
490 }
480 break; 491 break;
481 case NEO2_5: 492 case NEO2_5:
482 // left angled quote 493 if (command) {
483 SEND_STRING(SS_DOWN(X_LALT) SS_TAP(X_BSLASH) SS_UP(X_LALT)); 494 tap_code16(S(G(KC_5)));
495 } else {
496 // left angled quote
497 tap_code16(A(KC_BSLASH));
498 }
484 break; 499 break;
485 case NEO2_6: 500 case NEO2_6:
486 // dollar sign 501 // dollar sign
487 SEND_STRING(SS_DOWN(X_LSHIFT) SS_TAP(X_4) SS_UP(X_LSHIFT)); 502 tap_code16(S(KC_4));
488 break; 503 break;
489 case NEO2_7: 504 case NEO2_7:
490 // euro sign 505 // euro sign
491 SEND_STRING(SS_DOWN(X_LALT) SS_DOWN(X_LSHIFT) SS_TAP(X_2) SS_UP(X_LSHIFT) SS_UP(X_LALT)); 506 tap_code16(S(A(KC_2)));
492 break; 507 break;
493 case NEO2_8: 508 case NEO2_8:
494 // low9 double quote 509 // low9 double quote
495 SEND_STRING(SS_DOWN(X_LALT) SS_DOWN(X_LSHIFT) SS_TAP(X_W) SS_UP(X_LSHIFT) SS_UP(X_LALT)); 510 tap_code16(S(A(KC_W)));
496 break; 511 break;
497 case NEO2_9: 512 case NEO2_9:
498 // left double quote 513 // left double quote
499 SEND_STRING(SS_DOWN(X_LALT) SS_TAP(X_LBRACKET) SS_UP(X_LALT)); 514 tap_code16(A(KC_LBRACKET));
500 break; 515 break;
501 case NEO2_0: 516 case NEO2_0:
502 // right double quote 517 // right double quote
503 SEND_STRING(SS_DOWN(X_LALT) SS_DOWN(X_LSHIFT) SS_TAP(X_LBRACKET) SS_UP(X_LSHIFT) SS_UP(X_LALT)); 518 tap_code16(S(A(KC_LBRACKET)));
504 break; 519 break;
505 case NEO2_MINUS: 520 case NEO2_MINUS:
506 // em dash 521 // em dash
507 SEND_STRING(SS_DOWN(X_LALT) SS_DOWN(X_LSHIFT) SS_TAP(X_MINUS) SS_UP(X_LSHIFT) SS_UP(X_LALT)); 522 tap_code16(S(A(KC_MINUS)));
508 break; 523 break;
509 case NEO2_COMMA: 524 case NEO2_COMMA:
510 // en dash 525 // en dash
511 SEND_STRING(SS_DOWN(X_LALT) SS_TAP(X_MINUS) SS_UP(X_LALT)); 526 tap_code16(A(KC_MINUS));
512 break; 527 break;
513 case NEO2_DOT: 528 case NEO2_DOT:
514 // bullet 529 // bullet
515 SEND_STRING(SS_DOWN(X_LALT) SS_TAP(X_8) SS_UP(X_LALT)); 530 tap_code16(A(KC_8));
516 break; 531 break;
517 case NEO2_SHARP_S: 532 case NEO2_SHARP_S:
518 // german sharp s 533 // german sharp s
519 SEND_STRING(SS_DOWN(X_LALT) SS_TAP(X_S) SS_UP(X_LALT)); 534 tap_code16(S(KC_S));
520 break; 535 break;
521 case NEO2_UE: 536 case NEO2_UE:
522 SEND_STRING(SS_DOWN(X_LALT) SS_DOWN(X_U) SS_UP(X_U) SS_UP(X_LALT) SS_DOWN(X_LSHIFT) SS_TAP(X_U) SS_UP(X_LSHIFT)); 537 tap_code16(A(KC_U));
538 tap_code16(S(KC_U));
523 break; 539 break;
524 case NEO2_OE: 540 case NEO2_OE:
525 SEND_STRING(SS_DOWN(X_LALT) SS_DOWN(X_U) SS_UP(X_U) SS_UP(X_LALT) SS_DOWN(X_LSHIFT) SS_TAP(X_O) SS_UP(X_LSHIFT)); 541 tap_code16(A(KC_U));
542 tap_code16(S(KC_O));
526 break; 543 break;
527 case NEO2_AE: 544 case NEO2_AE:
528 SEND_STRING(SS_DOWN(X_LALT) SS_DOWN(X_U) SS_UP(X_U) SS_UP(X_LALT) SS_DOWN(X_LSHIFT) SS_TAP(X_A) SS_UP(X_LSHIFT)); 545 tap_code16(A(KC_U));
546 tap_code16(S(KC_A));
529 break; 547 break;
530 default: 548 default:
531 set_mods(active_modifiers); 549 set_mods(active_modifiers);
@@ -537,56 +555,59 @@ bool process_record_user_shifted(uint16_t keycode, keyrecord_t *record) {
537 } else { 555 } else {
538 switch (keycode) { 556 switch (keycode) {
539 case NEO2_1: 557 case NEO2_1:
540 SEND_STRING(SS_TAP(X_1)); 558 tap_code(KC_1);
541 break; 559 break;
542 case NEO2_2: 560 case NEO2_2:
543 SEND_STRING(SS_TAP(X_2)); 561 tap_code(KC_2);
544 break; 562 break;
545 case NEO2_3: 563 case NEO2_3:
546 SEND_STRING(SS_TAP(X_3)); 564 tap_code(KC_3);
547 break; 565 break;
548 case NEO2_4: 566 case NEO2_4:
549 SEND_STRING(SS_TAP(X_4)); 567 tap_code(KC_4);
550 break; 568 break;
551 case NEO2_5: 569 case NEO2_5:
552 SEND_STRING(SS_TAP(X_5)); 570 tap_code(KC_5);
553 break; 571 break;
554 case NEO2_6: 572 case NEO2_6:
555 SEND_STRING(SS_TAP(X_6)); 573 tap_code(KC_6);
556 break; 574 break;
557 case NEO2_7: 575 case NEO2_7:
558 SEND_STRING(SS_TAP(X_7)); 576 tap_code(KC_7);
559 break; 577 break;
560 case NEO2_8: 578 case NEO2_8:
561 SEND_STRING(SS_TAP(X_8)); 579 tap_code(KC_8);
562 break; 580 break;
563 case NEO2_9: 581 case NEO2_9:
564 SEND_STRING(SS_TAP(X_9)); 582 tap_code(KC_9);
565 break; 583 break;
566 case NEO2_0: 584 case NEO2_0:
567 SEND_STRING(SS_TAP(X_0)); 585 tap_code(KC_0);
568 break; 586 break;
569 case NEO2_MINUS: 587 case NEO2_MINUS:
570 SEND_STRING(SS_TAP(X_MINUS)); 588 tap_code(KC_MINUS);
571 break; 589 break;
572 case NEO2_COMMA: 590 case NEO2_COMMA:
573 SEND_STRING(SS_TAP(X_COMMA)); 591 tap_code(KC_COMMA);
574 break; 592 break;
575 case NEO2_DOT: 593 case NEO2_DOT:
576 SEND_STRING(SS_TAP(X_DOT)); 594 tap_code(KC_DOT);
577 break; 595 break;
578 case NEO2_SHARP_S: 596 case NEO2_SHARP_S:
579 // german sharp s 597 // german sharp s
580 SEND_STRING(SS_DOWN(X_LALT) SS_TAP(X_S) SS_UP(X_LALT)); 598 tap_code16(A(KC_S));
581 break; 599 break;
582 case NEO2_UE: 600 case NEO2_UE:
583 SEND_STRING(SS_DOWN(X_LALT) SS_DOWN(X_U) SS_UP(X_U) SS_UP(X_LALT) SS_TAP(X_U)); 601 tap_code16(A(KC_U));
602 tap_code(KC_U);
584 break; 603 break;
585 case NEO2_OE: 604 case NEO2_OE:
586 SEND_STRING(SS_DOWN(X_LALT) SS_DOWN(X_U) SS_UP(X_U) SS_UP(X_LALT) SS_TAP(X_O)); 605 tap_code16(A(KC_U));
606 tap_code(KC_O);
587 break; 607 break;
588 case NEO2_AE: 608 case NEO2_AE:
589 SEND_STRING(SS_DOWN(X_LALT) SS_DOWN(X_U) SS_UP(X_U) SS_UP(X_LALT) SS_TAP(X_A)); 609 tap_code16(A(KC_U));
610 tap_code(KC_A);
590 break; 611 break;
591 default: 612 default:
592 return true; 613 return true;
@@ -619,7 +640,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
619 neo3_state |= (1 << 1); 640 neo3_state |= (1 << 1);
620 } else { 641 } else {
621 // Turn off NEO_3 layer unless it's enabled through NEO2_RMOD3 as well. 642 // Turn off NEO_3 layer unless it's enabled through NEO2_RMOD3 as well.
622 if ((neo3_state & ~(1 << 1)) == 0) { 643 if ((neo3_state & (1 << 2)) == 0) {
623 layer_off(NEO_3); 644 layer_off(NEO_3);
624 } 645 }
625 neo3_state &= ~(1 << 1); 646 neo3_state &= ~(1 << 1);
@@ -629,28 +650,38 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
629 if (record->event.pressed) { 650 if (record->event.pressed) {
630 neo3_timer = timer_read(); 651 neo3_timer = timer_read();
631 neo3_state |= (1 << 2); 652 neo3_state |= (1 << 2);
653 // Reset tap detection state
654 neo3_state &= ~(1 << 3);
632 layer_on(NEO_3); 655 layer_on(NEO_3);
633 } else { 656 } else {
634 // Turn off NEO_3 layer unless it's enabled through NEO2_LMOD3 as well. 657 // Turn off NEO_3 layer unless it's enabled through NEO2_LMOD3 as well.
635 if ((neo3_state & ~(1 << 2)) == 0) { 658 if ((neo3_state & (1 << 1)) == 0) {
636 layer_off(NEO_3); 659 layer_off(NEO_3);
637 } 660 }
638 neo3_state &= ~(1 << 2); 661 neo3_state &= ~(1 << 2);
639 662
640 // Was the NEO2_RMOD3 key TAPPED? 663 // Was the NEO2_RMOD3 key TAPPED?
641 if (timer_elapsed(neo3_timer) <= 150) { 664 if (timer_elapsed(neo3_timer) <= TAPPING_TERM) {
642 if (neo3_state > 0) { 665 if ((neo3_state & ~(1 << 3)) > 0) {
643 // We are still in NEO_3 layer, send keycode and modifiers for @ 666 // We are still in NEO_3 layer, send keycode and modifiers for @
644 tap_with_modifiers(KC_2, MOD_MASK_SHIFT); 667 tap_with_modifiers(KC_2, MOD_MASK_SHIFT);
645 return false; 668 return false;
646 } else { 669 } else {
647 // Do the normal key processing, send y 670 // Do the normal key processing, send y
648 tap_with_modifiers(KC_Y, MOD_MASK_NONE); 671 if ((neo3_state & (1 << 3)) == 0) {
672 tap_with_modifiers(KC_Y, MOD_MASK_NONE);
673 }
649 return false; 674 return false;
650 } 675 }
651 } 676 }
652 } 677 }
653 break; 678 break;
679 default:
680 if (record->event.pressed && neo3_state > 0) {
681 // Track that we've seen a separate keypress event
682 neo3_state |= (1 << 3);
683 }
684 break;
654 } 685 }
655 686
656 if ((capslock_state & MOD_MASK_SHIFT) == MOD_MASK_SHIFT) { 687 if ((capslock_state & MOD_MASK_SHIFT) == MOD_MASK_SHIFT) {