aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFredric Silberberg <fred@silberberg.xyz>2017-08-06 14:14:27 -0700
committerJack Humbert <jack.humb@gmail.com>2017-08-08 10:02:53 -0400
commita3e1d9a8cc8b3d376d52f86aacae6315b15efebf (patch)
tree19784f99eab3fa0b03b96402f7e2b62599d17a0a
parent02f405708bb3a486224b857feb1f03f883f55ffe (diff)
downloadqmk_firmware-a3e1d9a8cc8b3d376d52f86aacae6315b15efebf.tar.gz
qmk_firmware-a3e1d9a8cc8b3d376d52f86aacae6315b15efebf.zip
Added support for locking One Shot modifiers.
-rw-r--r--docs/key_lock.md2
-rw-r--r--keyboards/nyquist/keymaps/333fred/Makefile1
-rw-r--r--quantum/process_keycode/process_key_lock.c41
-rw-r--r--quantum/process_keycode/process_key_lock.h2
-rw-r--r--quantum/quantum.c2
5 files changed, 34 insertions, 14 deletions
diff --git a/docs/key_lock.md b/docs/key_lock.md
index 03cea2089..e424061a9 100644
--- a/docs/key_lock.md
+++ b/docs/key_lock.md
@@ -8,4 +8,4 @@ Here's how to use it:
82. Enable key lock by including `KEY_LOCK_ENABLE = yes` in your Makefile. 82. Enable key lock by including `KEY_LOCK_ENABLE = yes` in your Makefile.
93. That's it! 93. That's it!
10 10
11Important: switching layers does not cancel the key lock. Additionally, key lock is only able to hold standard action keys. This does not include any of the QMK special functions, or shifted versions of keys such as KC_LPRN. If it's in the [basic_keycodes](basic_keycodes.md) list, it can be held. If it's not, then it can't be. 11Important: switching layers does not cancel the key lock. Additionally, key lock is only able to hold standard action keys and One Shot modifier keys (for example, if you have your shift defined as `OSM(KC_LSFT)`; see [One Shot Keys](quantum_keycodes.md#one-shot-keys)). This does not include any of the QMK special functions (except One Shot modifiers), or shifted versions of keys such as KC_LPRN. If it's in the [basic_keycodes](basic_keycodes.md) list, it can be held. If it's not, then it can't be.
diff --git a/keyboards/nyquist/keymaps/333fred/Makefile b/keyboards/nyquist/keymaps/333fred/Makefile
index 576bb3c30..f85443280 100644
--- a/keyboards/nyquist/keymaps/333fred/Makefile
+++ b/keyboards/nyquist/keymaps/333fred/Makefile
@@ -1,5 +1,6 @@
1KEY_LOCK_ENABLE = yes 1KEY_LOCK_ENABLE = yes
2NKRO_ENABLE = yes 2NKRO_ENABLE = yes
3CONSOLE_ENABLE = yes
3 4
4ifndef QUANTUM_DIR 5ifndef QUANTUM_DIR
5 include ../../../../Makefile 6 include ../../../../Makefile
diff --git a/quantum/process_keycode/process_key_lock.c b/quantum/process_keycode/process_key_lock.c
index e3632b74f..b1ba397a0 100644
--- a/quantum/process_keycode/process_key_lock.c
+++ b/quantum/process_keycode/process_key_lock.c
@@ -50,7 +50,16 @@
50uint64_t key_state[4] = { 0x0, 0x0, 0x0, 0x0 }; 50uint64_t key_state[4] = { 0x0, 0x0, 0x0, 0x0 };
51bool watching = false; 51bool watching = false;
52 52
53bool process_key_lock(uint16_t keycode, keyrecord_t *record) { 53// Translate any OSM keycodes back to their unmasked versions.
54uint16_t inline translate_keycode(uint16_t keycode) {
55 if (keycode > QK_ONE_SHOT_MOD && keycode <= QK_ONE_SHOT_MOD_MAX) {
56 return keycode ^ QK_ONE_SHOT_MOD;
57 } else {
58 return keycode;
59 }
60}
61
62bool process_key_lock(uint16_t *keycode, keyrecord_t *record) {
54 // We start by categorizing the keypress event. In the event of a down 63 // We start by categorizing the keypress event. In the event of a down
55 // event, there are several possibilities: 64 // event, there are several possibilities:
56 // 1. The key is not being locked, and we are not watching for new keys. 65 // 1. The key is not being locked, and we are not watching for new keys.
@@ -76,44 +85,54 @@ bool process_key_lock(uint16_t keycode, keyrecord_t *record) {
76 // 2. The key is being locked. In this case, we will mask the up event 85 // 2. The key is being locked. In this case, we will mask the up event
77 // by returning false, so the OS never sees that the key was released 86 // by returning false, so the OS never sees that the key was released
78 // until the user pressed the key again. 87 // until the user pressed the key again.
88
89 // We translate any OSM keycodes back to their original keycodes, so that if the key being
90 // one-shot modded is a standard keycode, we can handle it. This is the only set of special
91 // keys that we handle
92 uint16_t translated_keycode = translate_keycode(*keycode);
93
79 if (record->event.pressed) { 94 if (record->event.pressed) {
80 // Non-standard keycode, reset and return 95 // Non-standard keycode, reset and return
81 if (!(IS_STANDARD_KEYCODE(keycode) || keycode == KC_LOCK)) { 96 if (!(IS_STANDARD_KEYCODE(translated_keycode) || translated_keycode == KC_LOCK)) {
82 watching = false; 97 watching = false;
83 return true; 98 return true;
84 } 99 }
85 100
86 // If we're already watching, turn off the watch. 101 // If we're already watching, turn off the watch.
87 if (keycode == KC_LOCK) { 102 if (translated_keycode == KC_LOCK) {
88 watching = !watching; 103 watching = !watching;
89 return false; 104 return false;
90 } 105 }
91 106
92 if (IS_STANDARD_KEYCODE(keycode)) { 107 if (IS_STANDARD_KEYCODE(translated_keycode)) {
93 // We check watching first. This is so that in the following scenario, we continue to 108 // We check watching first. This is so that in the following scenario, we continue to
94 // hold the key: KC_LOCK, KC_F, KC_LOCK, KC_F 109 // hold the key: KC_LOCK, KC_F, KC_LOCK, KC_F
95 // If we checked in reverse order, we'd end up holding the key pressed after the second 110 // If we checked in reverse order, we'd end up holding the key pressed after the second
96 // KC_F press is registered, when the user likely meant to hold F 111 // KC_F press is registered, when the user likely meant to hold F
97 if (watching) { 112 if (watching) {
98 watching = false; 113 watching = false;
99 SET_KEY_STATE(keycode); 114 SET_KEY_STATE(translated_keycode);
115 // We need to set the keycode passed in to be the translated keycode, in case we
116 // translated a OSM back to the original keycode.
117 *keycode = translated_keycode;
100 // Let the standard keymap send the keycode down event. The up event will be masked. 118 // Let the standard keymap send the keycode down event. The up event will be masked.
101 return true; 119 return true;
102 } 120 }
103 121
104 if (KEY_STATE(keycode)) { 122 if (KEY_STATE(translated_keycode)) {
105 UNSET_KEY_STATE(keycode); 123 UNSET_KEY_STATE(translated_keycode);
106 // The key is already held, stop this process. The up event will be sent when the user 124 // The key is already held, stop this process. The up event will be sent when the user
107 // releases the key. 125 // releases the key.
108 return false; 126 return false;
109 } 127 }
110 } 128 }
111 129
112 // Either the key isn't a standard key, or we need to send the down event. Continue standard 130 // Either the key isn't a standard key, or we need to send the down event. Continue standard
113 // processing 131 // processing
114 return true; 132 return true;
115 } else { 133 } else {
116 // Stop processing if it's a standard key and we're masking up. 134 // Stop processing if it's a standard key and we're masking up.
117 return !(IS_STANDARD_KEYCODE(keycode) && KEY_STATE(keycode)); 135 return !(IS_STANDARD_KEYCODE(translated_keycode) && KEY_STATE(translated_keycode));
118 } 136 }
119} 137}
138
diff --git a/quantum/process_keycode/process_key_lock.h b/quantum/process_keycode/process_key_lock.h
index 237e103bc..876db4a32 100644
--- a/quantum/process_keycode/process_key_lock.h
+++ b/quantum/process_keycode/process_key_lock.h
@@ -19,6 +19,6 @@
19 19
20#include "quantum.h" 20#include "quantum.h"
21 21
22bool process_key_lock(uint16_t keycode, keyrecord_t *record); 22bool process_key_lock(uint16_t *keycode, keyrecord_t *record);
23 23
24#endif // PROCESS_KEY_LOCK_H 24#endif // PROCESS_KEY_LOCK_H
diff --git a/quantum/quantum.c b/quantum/quantum.c
index c71a97bf2..0243a7e01 100644
--- a/quantum/quantum.c
+++ b/quantum/quantum.c
@@ -195,7 +195,7 @@ bool process_record_quantum(keyrecord_t *record) {
195 if (!( 195 if (!(
196 #if defined(KEY_LOCK_ENABLE) 196 #if defined(KEY_LOCK_ENABLE)
197 // Must run first to be able to mask key_up events. 197 // Must run first to be able to mask key_up events.
198 process_key_lock(keycode, record) && 198 process_key_lock(&keycode, record) &&
199 #endif 199 #endif
200 process_record_kb(keycode, record) && 200 process_record_kb(keycode, record) &&
201 #if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED) 201 #if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED)