Browse Source

Fix up process_leader to be a bit more optimized (#4662)

* Fix up process_leader to be a bit more optimized

* Process dual function keys better

* Make leader start a callable function

* Fix per key timer call location

* Add escape if already leading

* Return false for KC_LEAD

* Add documentation
pjones-keymap
Drashna Jaelre 7 months ago
parent
commit
afd5cda4a0

+ 2
- 0
docs/config_options.md View File

@@ -146,6 +146,8 @@ If you define these options you will enable the associated feature, which may in
146 146
     * If you're having issues finishing the sequence before it times out, you may need to increase the timeout setting. Or you may want to enable the `LEADER_PER_KEY_TIMING` option, which resets the timeout after each key is tapped. 
147 147
 * `#define LEADER_PER_KEY_TIMING`
148 148
   * sets the timer for leader key chords to run on each key press rather than overall
149
+* `#define LEADER_KEY_STRICT_KEY_PROCESSING`
150
+  * Disables keycode filtering for Mod-Tap and Layer-Tap keycodes. Eg, if you enable this, you would need to specify `MT(MOD_CTL, KC_A)` if you want to use `KC_A`.
149 151
 * `#define ONESHOT_TIMEOUT 300`
150 152
   * how long before oneshot times out
151 153
 * `#define ONESHOT_TAP_TOGGLE 2`

+ 6
- 0
docs/feature_leader_key.md View File

@@ -72,6 +72,12 @@ SEQ_THREE_KEYS(KC_C, KC_C, KC_C) {
72 72
 }
73 73
 ```
74 74
 
75
+## Strict Key Processing
76
+
77
+By default, the Leader Key feature will filter the keycode out of [`Mod-Tap`](feature_advanced_keycodes.md#mod-tap) and [`Layer Tap`](feature_advanced_keycodes.md#switching-and-toggling-layers) functions when checking for the Leader sequences. That means if you're using `LT(3, KC_A)`, it will pick this up as `KC_A` for the sequence, rather than `LT(3, KC_A)`, giving a more expected behavior for newer users.
78
+
79
+While, this may be fine for most, if you want to specify the whole keycode (eg, `LT(3, KC_A)` from the example above) in the sequence, you can enable this by added `#define LEADER_KEY_STRICT_KEY_PROCESSING` to your `config.h` file.  This well then disable the filtering, and you'll need to specify the whole keycode.
80
+
75 81
 ## Customization 
76 82
 
77 83
 The Leader Key feature has some additional customization to how the Leader Key feature works.  It has two functions that can be called at certain parts of the process.  Namely `leader_start()` and `leader_end()`.

+ 31
- 20
quantum/process_keycode/process_leader.c View File

@@ -35,31 +35,42 @@ uint16_t leader_time = 0;
35 35
 uint16_t leader_sequence[5] = {0, 0, 0, 0, 0};
36 36
 uint8_t leader_sequence_size = 0;
37 37
 
38
+void qk_leader_start(void) {
39
+  if (leading) { return; }
40
+  leader_start();
41
+  leading = true;
42
+  leader_time = timer_read();
43
+  leader_sequence_size = 0;
44
+  leader_sequence[0] = 0;
45
+  leader_sequence[1] = 0;
46
+  leader_sequence[2] = 0;
47
+  leader_sequence[3] = 0;
48
+  leader_sequence[4] = 0;
49
+}
50
+
38 51
 bool process_leader(uint16_t keycode, keyrecord_t *record) {
39 52
   // Leader key set-up
40 53
   if (record->event.pressed) {
54
+    if (leading) {
55
+      if (timer_elapsed(leader_time) < LEADER_TIMEOUT) {
56
+#ifndef LEADER_KEY_STRICT_KEY_PROCESSING
57
+        if ((keycode >= QK_MOD_TAP && keycode <= QK_MOD_TAP_MAX) || (keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX)) {
58
+          keycode = keycode & 0xFF;
59
+        }
60
+#endif // LEADER_KEY_STRICT_KEY_PROCESSING
61
+        leader_sequence[leader_sequence_size] = keycode;
62
+        leader_sequence_size++;
41 63
 #ifdef LEADER_PER_KEY_TIMING
42
-    leader_time = timer_read();
64
+        leader_time = timer_read();
43 65
 #endif
44
-    if (!leading && keycode == KC_LEAD) {
45
-      leader_start();
46
-      leading = true;
47
-#ifndef LEADER_PER_KEY_TIMING
48
-      leader_time = timer_read();
49
-#endif
50
-      leader_time = timer_read();
51
-      leader_sequence_size = 0;
52
-      leader_sequence[0] = 0;
53
-      leader_sequence[1] = 0;
54
-      leader_sequence[2] = 0;
55
-      leader_sequence[3] = 0;
56
-      leader_sequence[4] = 0;
57
-      return false;
58
-    }
59
-    if (leading && timer_elapsed(leader_time) < LEADER_TIMEOUT) {
60
-      leader_sequence[leader_sequence_size] = keycode;
61
-      leader_sequence_size++;
62
-      return false;
66
+        return false;
67
+      }
68
+    } else {
69
+      if (keycode == KC_LEAD) {
70
+        qk_leader_start();
71
+        return false;
72
+      }
73
+      break;
63 74
     }
64 75
   }
65 76
   return true;

+ 1
- 1
quantum/process_keycode/process_leader.h View File

@@ -24,7 +24,7 @@ bool process_leader(uint16_t keycode, keyrecord_t *record);
24 24
 
25 25
 void leader_start(void);
26 26
 void leader_end(void);
27
-
27
+void qk_leader_start(void);
28 28
 
29 29
 #define SEQ_ONE_KEY(key) if (leader_sequence[0] == (key) && leader_sequence[1] == 0 && leader_sequence[2] == 0 && leader_sequence[3] == 0 && leader_sequence[4] == 0)
30 30
 #define SEQ_TWO_KEYS(key1, key2) if (leader_sequence[0] == (key1) && leader_sequence[1] == (key2) && leader_sequence[2] == 0 && leader_sequence[3] == 0 && leader_sequence[4] == 0)

Loading…
Cancel
Save