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); |
