diff options
| -rw-r--r-- | quantum/action.c | 8 | ||||
| -rw-r--r-- | quantum/action_tapping.c | 10 | ||||
| -rw-r--r-- | quantum/process_keycode/process_combo.c | 1 | ||||
| -rw-r--r-- | tests/combo/config.h | 8 | ||||
| -rw-r--r-- | tests/combo/test.mk | 4 | ||||
| -rw-r--r-- | tests/combo/test_combo.cpp | 72 |
6 files changed, 97 insertions, 6 deletions
diff --git a/quantum/action.c b/quantum/action.c index 9a6bbcca11..41c204f689 100644 --- a/quantum/action.c +++ b/quantum/action.c | |||
| @@ -187,7 +187,7 @@ bool is_swap_hands_on(void) { | |||
| 187 | */ | 187 | */ |
| 188 | void process_hand_swap(keyevent_t *event) { | 188 | void process_hand_swap(keyevent_t *event) { |
| 189 | keypos_t pos = event->key; | 189 | keypos_t pos = event->key; |
| 190 | if (pos.row < MATRIX_ROWS && pos.col < MATRIX_COLS) { | 190 | if (IS_KEYEVENT(*event) && pos.row < MATRIX_ROWS && pos.col < MATRIX_COLS) { |
| 191 | static uint8_t matrix_swap_state[((MATRIX_ROWS * MATRIX_COLS) + (CHAR_BIT)-1) / (CHAR_BIT)]; | 191 | static uint8_t matrix_swap_state[((MATRIX_ROWS * MATRIX_COLS) + (CHAR_BIT)-1) / (CHAR_BIT)]; |
| 192 | size_t index = (size_t)(pos.row * MATRIX_COLS) + pos.col; | 192 | size_t index = (size_t)(pos.row * MATRIX_COLS) + pos.col; |
| 193 | bool do_swap = should_swap_hands(index, matrix_swap_state, event->pressed); | 193 | bool do_swap = should_swap_hands(index, matrix_swap_state, event->pressed); |
| @@ -200,7 +200,7 @@ void process_hand_swap(keyevent_t *event) { | |||
| 200 | } | 200 | } |
| 201 | } | 201 | } |
| 202 | # ifdef ENCODER_MAP_ENABLE | 202 | # ifdef ENCODER_MAP_ENABLE |
| 203 | else if (pos.row == KEYLOC_ENCODER_CW || pos.row == KEYLOC_ENCODER_CCW) { | 203 | else if (IS_ENCODEREVENT(*event) && pos.row == KEYLOC_ENCODER_CW || pos.row == KEYLOC_ENCODER_CCW) { |
| 204 | static uint8_t encoder_swap_state[((NUM_ENCODERS) + (CHAR_BIT)-1) / (CHAR_BIT)]; | 204 | static uint8_t encoder_swap_state[((NUM_ENCODERS) + (CHAR_BIT)-1) / (CHAR_BIT)]; |
| 205 | size_t index = pos.col; | 205 | size_t index = pos.col; |
| 206 | bool do_swap = should_swap_hands(index, encoder_swap_state, event->pressed); | 206 | bool do_swap = should_swap_hands(index, encoder_swap_state, event->pressed); |
| @@ -242,6 +242,10 @@ __attribute__((weak)) void post_process_record_quantum(keyrecord_t *record) {} | |||
| 242 | * FIXME: Needs documentation. | 242 | * FIXME: Needs documentation. |
| 243 | */ | 243 | */ |
| 244 | void process_record_tap_hint(keyrecord_t *record) { | 244 | void process_record_tap_hint(keyrecord_t *record) { |
| 245 | if (!IS_KEYEVENT(record->event)) { | ||
| 246 | return; | ||
| 247 | } | ||
| 248 | |||
| 245 | action_t action = layer_switch_get_action(record->event.key); | 249 | action_t action = layer_switch_get_action(record->event.key); |
| 246 | 250 | ||
| 247 | switch (action.kind.id) { | 251 | switch (action.kind.id) { |
diff --git a/quantum/action_tapping.c b/quantum/action_tapping.c index 362b15105c..f94e5e6f69 100644 --- a/quantum/action_tapping.c +++ b/quantum/action_tapping.c | |||
| @@ -167,8 +167,10 @@ bool process_tapping(keyrecord_t *keyp) { | |||
| 167 | 167 | ||
| 168 | // state machine is in the "reset" state, no tapping key is to be | 168 | // state machine is in the "reset" state, no tapping key is to be |
| 169 | // processed | 169 | // processed |
| 170 | if (IS_NOEVENT(tapping_key.event) && IS_EVENT(event)) { | 170 | if (IS_NOEVENT(tapping_key.event)) { |
| 171 | if (event.pressed && is_tap_record(keyp)) { | 171 | if (!IS_EVENT(event)) { |
| 172 | // early return for tick events | ||
| 173 | } else if (event.pressed && is_tap_record(keyp)) { | ||
| 172 | // the currently pressed key is a tapping key, therefore transition | 174 | // the currently pressed key is a tapping key, therefore transition |
| 173 | // into the "pressed" tapping key state | 175 | // into the "pressed" tapping key state |
| 174 | ac_dprintf("Tapping: Start(Press tap key).\n"); | 176 | ac_dprintf("Tapping: Start(Press tap key).\n"); |
| @@ -176,13 +178,13 @@ bool process_tapping(keyrecord_t *keyp) { | |||
| 176 | process_record_tap_hint(&tapping_key); | 178 | process_record_tap_hint(&tapping_key); |
| 177 | waiting_buffer_scan_tap(); | 179 | waiting_buffer_scan_tap(); |
| 178 | debug_tapping_key(); | 180 | debug_tapping_key(); |
| 179 | return true; | ||
| 180 | } else { | 181 | } else { |
| 181 | // the current key is just a regular key, pass it on for regular | 182 | // the current key is just a regular key, pass it on for regular |
| 182 | // processing | 183 | // processing |
| 183 | process_record(keyp); | 184 | process_record(keyp); |
| 184 | return true; | ||
| 185 | } | 185 | } |
| 186 | |||
| 187 | return true; | ||
| 186 | } | 188 | } |
| 187 | 189 | ||
| 188 | TAP_DEFINE_KEYCODE; | 190 | TAP_DEFINE_KEYCODE; |
diff --git a/quantum/process_keycode/process_combo.c b/quantum/process_keycode/process_combo.c index b1b49d3019..2670ccabed 100644 --- a/quantum/process_keycode/process_combo.c +++ b/quantum/process_keycode/process_combo.c | |||
| @@ -335,6 +335,7 @@ void apply_combo(uint16_t combo_index, combo_t *combo) { | |||
| 335 | // this in the end executes the combo when the key_buffer is dumped. | 335 | // this in the end executes the combo when the key_buffer is dumped. |
| 336 | record->keycode = combo->keycode; | 336 | record->keycode = combo->keycode; |
| 337 | record->event.type = COMBO_EVENT; | 337 | record->event.type = COMBO_EVENT; |
| 338 | record->event.key = MAKE_KEYPOS(0, 0); | ||
| 338 | 339 | ||
| 339 | qrecord->combo_index = combo_index; | 340 | qrecord->combo_index = combo_index; |
| 340 | ACTIVATE_COMBO(combo); | 341 | ACTIVATE_COMBO(combo); |
diff --git a/tests/combo/config.h b/tests/combo/config.h new file mode 100644 index 0000000000..8052932634 --- /dev/null +++ b/tests/combo/config.h | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | // Copyright 2023 Stefan Kerkmann (@KarlK90) | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "test_common.h" | ||
| 7 | |||
| 8 | #define TAPPING_TERM 200 | ||
diff --git a/tests/combo/test.mk b/tests/combo/test.mk new file mode 100644 index 0000000000..ce6f9fc2b0 --- /dev/null +++ b/tests/combo/test.mk | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | # Copyright 2023 Stefan Kerkmann (@KarlK90) | ||
| 2 | # SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | COMBO_ENABLE = yes | ||
diff --git a/tests/combo/test_combo.cpp b/tests/combo/test_combo.cpp new file mode 100644 index 0000000000..b7aea27f4c --- /dev/null +++ b/tests/combo/test_combo.cpp | |||
| @@ -0,0 +1,72 @@ | |||
| 1 | // Copyright 2023 Stefan Kerkmann (@KarlK90) | ||
| 2 | // Copyright 2023 @filterpaper | ||
| 3 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 4 | |||
| 5 | #include "keyboard_report_util.hpp" | ||
| 6 | #include "quantum.h" | ||
| 7 | #include "keycode.h" | ||
| 8 | #include "test_common.h" | ||
| 9 | #include "test_driver.hpp" | ||
| 10 | #include "test_fixture.hpp" | ||
| 11 | #include "test_keymap_key.hpp" | ||
| 12 | |||
| 13 | extern "C" { | ||
| 14 | enum combos { modtest, osmshift, COMBO_LENGTH }; | ||
| 15 | uint16_t COMBO_LEN = COMBO_LENGTH; | ||
| 16 | |||
| 17 | uint16_t const modtest_combo[] = {KC_Y, KC_U, COMBO_END}; | ||
| 18 | uint16_t const osmshift_combo[] = {KC_Z, KC_X, COMBO_END}; | ||
| 19 | |||
| 20 | // clang-format off | ||
| 21 | combo_t key_combos[] = { | ||
| 22 | [modtest] = COMBO(modtest_combo, RSFT_T(KC_SPACE)), | ||
| 23 | [osmshift] = COMBO(osmshift_combo, OSM(MOD_LSFT)) | ||
| 24 | }; | ||
| 25 | // clang-format on | ||
| 26 | } | ||
| 27 | |||
| 28 | using testing::_; | ||
| 29 | using testing::InSequence; | ||
| 30 | |||
| 31 | class Combo : public TestFixture {}; | ||
| 32 | |||
| 33 | TEST_F(Combo, combo_modtest_tapped) { | ||
| 34 | TestDriver driver; | ||
| 35 | KeymapKey key_y(0, 0, 1, KC_Y); | ||
| 36 | KeymapKey key_u(0, 0, 2, KC_U); | ||
| 37 | set_keymap({key_y, key_u}); | ||
| 38 | |||
| 39 | EXPECT_REPORT(driver, (KC_SPACE)); | ||
| 40 | EXPECT_EMPTY_REPORT(driver); | ||
| 41 | tap_combo({key_y, key_u}); | ||
| 42 | VERIFY_AND_CLEAR(driver); | ||
| 43 | } | ||
| 44 | |||
| 45 | TEST_F(Combo, combo_modtest_held_longer_than_tapping_term) { | ||
| 46 | TestDriver driver; | ||
| 47 | KeymapKey key_y(0, 0, 1, KC_Y); | ||
| 48 | KeymapKey key_u(0, 0, 2, KC_U); | ||
| 49 | set_keymap({key_y, key_u}); | ||
| 50 | |||
| 51 | EXPECT_REPORT(driver, (KC_RIGHT_SHIFT)); | ||
| 52 | EXPECT_EMPTY_REPORT(driver); | ||
| 53 | tap_combo({key_y, key_u}, TAPPING_TERM + 1); | ||
| 54 | VERIFY_AND_CLEAR(driver); | ||
| 55 | } | ||
| 56 | |||
| 57 | TEST_F(Combo, combo_osmshift_tapped) { | ||
| 58 | TestDriver driver; | ||
| 59 | KeymapKey key_z(0, 0, 1, KC_Z); | ||
| 60 | KeymapKey key_x(0, 0, 2, KC_X); | ||
| 61 | KeymapKey key_i(0, 0, 3, KC_I); | ||
| 62 | set_keymap({key_z, key_x, key_i}); | ||
| 63 | |||
| 64 | EXPECT_NO_REPORT(driver); | ||
| 65 | tap_combo({key_z, key_x}); | ||
| 66 | VERIFY_AND_CLEAR(driver); | ||
| 67 | |||
| 68 | EXPECT_REPORT(driver, (KC_I, KC_LEFT_SHIFT)); | ||
| 69 | EXPECT_EMPTY_REPORT(driver); | ||
| 70 | tap_key(key_i); | ||
| 71 | VERIFY_AND_CLEAR(driver); | ||
| 72 | } | ||
