diff options
-rw-r--r-- | docs/feature_macros.md | 40 | ||||
-rw-r--r-- | docs/understanding_qmk.md | 9 | ||||
-rw-r--r-- | quantum/quantum.c | 20 | ||||
-rw-r--r-- | quantum/quantum.h | 2 | ||||
-rw-r--r-- | tmk_core/common/action.c | 8 | ||||
-rw-r--r-- | tmk_core/common/action.h | 2 |
6 files changed, 77 insertions, 4 deletions
diff --git a/docs/feature_macros.md b/docs/feature_macros.md index 99dd564bf..1bd2d74e7 100644 --- a/docs/feature_macros.md +++ b/docs/feature_macros.md | |||
@@ -88,6 +88,46 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
88 | }; | 88 | }; |
89 | ``` | 89 | ``` |
90 | 90 | ||
91 | ### Advanced Macros | ||
92 | |||
93 | In addition to the `process_record_user()` function, is the `post_process_record_user()` function. This runs after `process_record` and can be used to do things after a keystroke has been sent. This is useful if you want to have a key pressed before and released after a normal key, for instance. | ||
94 | |||
95 | In this example, we modify most normal keypresses so that `F22` is pressed before the keystroke is normally sent, and release it __only after__ it's been released. | ||
96 | |||
97 | ```c | ||
98 | static uint8_t f22_tracker; | ||
99 | |||
100 | bool process_record_user(uint16_t keycode, keyrecord_t *record) { | ||
101 | switch (keycode) { | ||
102 | case KC_A ... KC_F21: //notice how it skips over F22 | ||
103 | case KC_F23 ... KC_EXSEL: //exsel is the last one before the modifier keys | ||
104 | if (record->event.pressed) { | ||
105 | register_code(KC_F22); //this means to send F22 down | ||
106 | f22_tracker++; | ||
107 | register_code(keycode); | ||
108 | return false; | ||
109 | } | ||
110 | break; | ||
111 | } | ||
112 | return true; | ||
113 | } | ||
114 | |||
115 | void post_process_record_user(uint16_t keycode, keyrecord_t *record) { | ||
116 | switch (keycode) { | ||
117 | case KC_A ... KC_F21: //notice how it skips over F22 | ||
118 | case KC_F23 ... KC_EXSEL: //exsel is the last one before the modifier keys | ||
119 | if (!record->event.pressed) { | ||
120 | f22_tracker--; | ||
121 | if (!f22_tracker) { | ||
122 | unregister_code(KC_F22); //this means to send F22 up | ||
123 | } | ||
124 | } | ||
125 | break; | ||
126 | } | ||
127 | } | ||
128 | ``` | ||
129 | |||
130 | |||
91 | ### TAP, DOWN and UP | 131 | ### TAP, DOWN and UP |
92 | 132 | ||
93 | You may want to use keys in your macros that you can't write down, such as `Ctrl` or `Home`. | 133 | You may want to use keys in your macros that you can't write down, such as `Ctrl` or `Home`. |
diff --git a/docs/understanding_qmk.md b/docs/understanding_qmk.md index 81cedfcf5..939642425 100644 --- a/docs/understanding_qmk.md +++ b/docs/understanding_qmk.md | |||
@@ -162,6 +162,15 @@ The `process_record()` function itself is deceptively simple, but hidden within | |||
162 | 162 | ||
163 | At any step during this chain of events a function (such as `process_record_kb()`) can `return false` to halt all further processing. | 163 | At any step during this chain of events a function (such as `process_record_kb()`) can `return false` to halt all further processing. |
164 | 164 | ||
165 | After this is called, `post_process_record()` is called, which can be used to handle additional cleanup that needs to be run after the keycode is normally handled. | ||
166 | |||
167 | * [`void post_process_record(keyrecord_t *record)`]() | ||
168 | * [`void post_process_record_quantum(keyrecord_t *record)`]() | ||
169 | * [Map this record to a keycode]() | ||
170 | * [`void post_process_clicky(uint16_t keycode, keyrecord_t *record)`]() | ||
171 | * [`void post_process_record_kb(uint16_t keycode, keyrecord_t *record)`]() | ||
172 | * [`void post_process_record_user(uint16_t keycode, keyrecord_t *record)`]() | ||
173 | |||
165 | <!-- | 174 | <!-- |
166 | #### Mouse Handling | 175 | #### Mouse Handling |
167 | 176 | ||
diff --git a/quantum/quantum.c b/quantum/quantum.c index 49767819d..d7dbc49dc 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c | |||
@@ -120,6 +120,14 @@ __attribute__((weak)) bool process_record_kb(uint16_t keycode, keyrecord_t *reco | |||
120 | 120 | ||
121 | __attribute__((weak)) bool process_record_user(uint16_t keycode, keyrecord_t *record) { return true; } | 121 | __attribute__((weak)) bool process_record_user(uint16_t keycode, keyrecord_t *record) { return true; } |
122 | 122 | ||
123 | __attribute__ ((weak)) | ||
124 | void post_process_record_kb(uint16_t keycode, keyrecord_t *record) { | ||
125 | post_process_record_user(keycode, record); | ||
126 | } | ||
127 | |||
128 | __attribute__ ((weak)) | ||
129 | void post_process_record_user(uint16_t keycode, keyrecord_t *record) {} | ||
130 | |||
123 | void reset_keyboard(void) { | 131 | void reset_keyboard(void) { |
124 | clear_keyboard(); | 132 | clear_keyboard(); |
125 | #if defined(MIDI_ENABLE) && defined(MIDI_BASIC) | 133 | #if defined(MIDI_ENABLE) && defined(MIDI_BASIC) |
@@ -172,9 +180,15 @@ uint16_t get_event_keycode(keyevent_t event) { | |||
172 | return keymap_key_to_keycode(layer_switch_get_layer(event.key), event.key); | 180 | return keymap_key_to_keycode(layer_switch_get_layer(event.key), event.key); |
173 | } | 181 | } |
174 | 182 | ||
175 | /* Main keycode processing function. Hands off handling to other functions, | 183 | /* Get keycode, and then call keyboard function */ |
176 | * then processes internal Quantum keycodes, then processes ACTIONs. | 184 | void post_process_record_quantum(keyrecord_t *record) { |
177 | */ | 185 | uint16_t keycode = get_record_keycode(record); |
186 | post_process_record_kb(keycode, record); | ||
187 | } | ||
188 | |||
189 | /* Core keycode function, hands off handling to other functions, | ||
190 | then processes internal quantum keycodes, and then processes | ||
191 | ACTIONs. */ | ||
178 | bool process_record_quantum(keyrecord_t *record) { | 192 | bool process_record_quantum(keyrecord_t *record) { |
179 | uint16_t keycode = get_record_keycode(record); | 193 | uint16_t keycode = get_record_keycode(record); |
180 | 194 | ||
diff --git a/quantum/quantum.h b/quantum/quantum.h index 191407fab..4b94ebcc0 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h | |||
@@ -257,6 +257,8 @@ uint16_t get_event_keycode(keyevent_t event); | |||
257 | bool process_action_kb(keyrecord_t *record); | 257 | bool process_action_kb(keyrecord_t *record); |
258 | bool process_record_kb(uint16_t keycode, keyrecord_t *record); | 258 | bool process_record_kb(uint16_t keycode, keyrecord_t *record); |
259 | bool process_record_user(uint16_t keycode, keyrecord_t *record); | 259 | bool process_record_user(uint16_t keycode, keyrecord_t *record); |
260 | void post_process_record_kb(uint16_t keycode, keyrecord_t *record); | ||
261 | void post_process_record_user(uint16_t keycode, keyrecord_t *record); | ||
260 | 262 | ||
261 | #ifndef BOOTMAGIC_LITE_COLUMN | 263 | #ifndef BOOTMAGIC_LITE_COLUMN |
262 | # define BOOTMAGIC_LITE_COLUMN 0 | 264 | # define BOOTMAGIC_LITE_COLUMN 0 |
diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c index 174faf856..19c3569d5 100644 --- a/tmk_core/common/action.c +++ b/tmk_core/common/action.c | |||
@@ -151,6 +151,8 @@ void process_record_nocache(keyrecord_t *record) { process_record(record); } | |||
151 | 151 | ||
152 | __attribute__((weak)) bool process_record_quantum(keyrecord_t *record) { return true; } | 152 | __attribute__((weak)) bool process_record_quantum(keyrecord_t *record) { return true; } |
153 | 153 | ||
154 | __attribute__((weak)) void post_process_record_quantum(keyrecord_t *record) {} | ||
155 | |||
154 | #ifndef NO_ACTION_TAPPING | 156 | #ifndef NO_ACTION_TAPPING |
155 | /** \brief Allows for handling tap-hold actions immediately instead of waiting for TAPPING_TERM or another keypress. | 157 | /** \brief Allows for handling tap-hold actions immediately instead of waiting for TAPPING_TERM or another keypress. |
156 | * | 158 | * |
@@ -185,6 +187,11 @@ void process_record(keyrecord_t *record) { | |||
185 | 187 | ||
186 | if (!process_record_quantum(record)) return; | 188 | if (!process_record_quantum(record)) return; |
187 | 189 | ||
190 | process_record_handler(record); | ||
191 | post_process_record_quantum(record); | ||
192 | } | ||
193 | |||
194 | void process_record_handler(keyrecord_t *record) { | ||
188 | action_t action = store_or_get_action(record->event.pressed, record->event.key); | 195 | action_t action = store_or_get_action(record->event.pressed, record->event.key); |
189 | dprint("ACTION: "); | 196 | dprint("ACTION: "); |
190 | debug_action(action); | 197 | debug_action(action); |
@@ -988,7 +995,6 @@ bool is_tap_action(action_t action) { | |||
988 | * FIXME: Needs documentation. | 995 | * FIXME: Needs documentation. |
989 | */ | 996 | */ |
990 | void debug_event(keyevent_t event) { dprintf("%04X%c(%u)", (event.key.row << 8 | event.key.col), (event.pressed ? 'd' : 'u'), event.time); } | 997 | void debug_event(keyevent_t event) { dprintf("%04X%c(%u)", (event.key.row << 8 | event.key.col), (event.pressed ? 'd' : 'u'), event.time); } |
991 | |||
992 | /** \brief Debug print (FIXME: Needs better description) | 998 | /** \brief Debug print (FIXME: Needs better description) |
993 | * | 999 | * |
994 | * FIXME: Needs documentation. | 1000 | * FIXME: Needs documentation. |
diff --git a/tmk_core/common/action.h b/tmk_core/common/action.h index 15f4ce15c..dd22023f9 100644 --- a/tmk_core/common/action.h +++ b/tmk_core/common/action.h | |||
@@ -84,6 +84,8 @@ void process_hand_swap(keyevent_t *record); | |||
84 | 84 | ||
85 | void process_record_nocache(keyrecord_t *record); | 85 | void process_record_nocache(keyrecord_t *record); |
86 | void process_record(keyrecord_t *record); | 86 | void process_record(keyrecord_t *record); |
87 | void process_record_handler(keyrecord_t *record); | ||
88 | void post_process_record_quantum(keyrecord_t *record); | ||
87 | void process_action(keyrecord_t *record, action_t action); | 89 | void process_action(keyrecord_t *record, action_t action); |
88 | void register_code(uint8_t code); | 90 | void register_code(uint8_t code); |
89 | void unregister_code(uint8_t code); | 91 | void unregister_code(uint8_t code); |