]> git.donarmstrong.com Git - qmk_firmware.git/commitdiff
Added support for locking One Shot modifiers.
authorFredric Silberberg <fred@silberberg.xyz>
Sun, 6 Aug 2017 21:14:27 +0000 (14:14 -0700)
committerJack Humbert <jack.humb@gmail.com>
Tue, 8 Aug 2017 14:02:53 +0000 (10:02 -0400)
docs/key_lock.md
keyboards/nyquist/keymaps/333fred/Makefile
quantum/process_keycode/process_key_lock.c
quantum/process_keycode/process_key_lock.h
quantum/quantum.c

index 03cea208907ec1f604b4ee3eead33ebded28019d..e424061a9a6ec1b8f6d3908e11353881f32f4115 100644 (file)
@@ -8,4 +8,4 @@ Here's how to use it:
 2. Enable key lock by including `KEY_LOCK_ENABLE = yes` in your Makefile.
 3. That's it!
 
-Important: 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.
+Important: 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.
index 576bb3c30e1748b7261da04a539c926c36849084..f8544328074c247054873bb7270ac73690f7d78d 100644 (file)
@@ -1,5 +1,6 @@
 KEY_LOCK_ENABLE = yes
 NKRO_ENABLE = yes
+CONSOLE_ENABLE = yes
 
 ifndef QUANTUM_DIR
        include ../../../../Makefile
index e3632b74fb11037824356491fd520189b9565861..b1ba397a026576d2b321601d2ee31b1dfc8b7a37 100644 (file)
 uint64_t key_state[4] = { 0x0, 0x0, 0x0, 0x0 };
 bool watching = false;
 
-bool process_key_lock(uint16_t keycode, keyrecord_t *record) {
+// Translate any OSM keycodes back to their unmasked versions.
+uint16_t inline translate_keycode(uint16_t keycode) {
+    if (keycode > QK_ONE_SHOT_MOD && keycode <= QK_ONE_SHOT_MOD_MAX) {
+        return keycode ^ QK_ONE_SHOT_MOD;
+    } else {
+        return keycode;
+    }
+}
+
+bool process_key_lock(uint16_t *keycode, keyrecord_t *record) {
     // We start by categorizing the keypress event. In the event of a down
     // event, there are several possibilities:
     // 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) {
     // 2. The key is being locked. In this case, we will mask the up event
     //    by returning false, so the OS never sees that the key was released
     //    until the user pressed the key again.
+
+    // We translate any OSM keycodes back to their original keycodes, so that if the key being
+    // one-shot modded is a standard keycode, we can handle it. This is the only set of special
+    // keys that we handle
+    uint16_t translated_keycode = translate_keycode(*keycode);
+
     if (record->event.pressed) {
         // Non-standard keycode, reset and return
-        if (!(IS_STANDARD_KEYCODE(keycode) || keycode == KC_LOCK)) {
+        if (!(IS_STANDARD_KEYCODE(translated_keycode) || translated_keycode == KC_LOCK)) {
             watching = false;
             return true;
         }
 
         // If we're already watching, turn off the watch.
-        if (keycode == KC_LOCK) {
+        if (translated_keycode == KC_LOCK) {
             watching = !watching;
             return false;
         }
-        
-        if (IS_STANDARD_KEYCODE(keycode)) {
+
+        if (IS_STANDARD_KEYCODE(translated_keycode)) {
             // We check watching first. This is so that in the following scenario, we continue to
             // hold the key: KC_LOCK, KC_F, KC_LOCK, KC_F
             // If we checked in reverse order, we'd end up holding the key pressed after the second
             // KC_F press is registered, when the user likely meant to hold F
             if (watching) {
                 watching = false;
-                SET_KEY_STATE(keycode);
+                SET_KEY_STATE(translated_keycode);
+                // We need to set the keycode passed in to be the translated keycode, in case we
+                // translated a OSM back to the original keycode.
+                *keycode = translated_keycode;
                 // Let the standard keymap send the keycode down event. The up event will be masked.
                 return true;
             }
-            
-            if (KEY_STATE(keycode)) {
-                UNSET_KEY_STATE(keycode);
+
+            if (KEY_STATE(translated_keycode)) {
+                UNSET_KEY_STATE(translated_keycode);
                 // The key is already held, stop this process. The up event will be sent when the user
                 // releases the key.
                 return false;
             }
         }
-        
+
         // Either the key isn't a standard key, or we need to send the down event. Continue standard
         // processing
         return true;
     } else {
         // Stop processing if it's a standard key and we're masking up.
-        return !(IS_STANDARD_KEYCODE(keycode) && KEY_STATE(keycode));
+        return !(IS_STANDARD_KEYCODE(translated_keycode) && KEY_STATE(translated_keycode));
     }
 }
+
index 237e103bcdba894a099844ca89a26405f7a15105..876db4a324c440f3dca4658091ec7738f047ab4f 100644 (file)
@@ -19,6 +19,6 @@
 
 #include "quantum.h"
 
-bool process_key_lock(uint16_t keycode, keyrecord_t *record);
+bool process_key_lock(uint16_t *keycode, keyrecord_t *record);
 
 #endif // PROCESS_KEY_LOCK_H
index c71a97bf283337df3433ef1aea161e13743803e8..0243a7e0126ecf06d1eb8f1b166b9e655dad87c4 100644 (file)
@@ -195,7 +195,7 @@ bool process_record_quantum(keyrecord_t *record) {
   if (!(
   #if defined(KEY_LOCK_ENABLE)
     // Must run first to be able to mask key_up events.
-    process_key_lock(keycode, record) &&
+    process_key_lock(&keycode, record) &&
   #endif
     process_record_kb(keycode, record) &&
   #if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED)