forked from qmk/qmk_firmware
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add combo key repress feature (qmk#22858)
Co-authored-by: jack <[email protected]>
- Loading branch information
1 parent
182f429
commit 3a84f51
Showing
6 changed files
with
295 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
// Copyright 2024 @Filios92 | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
|
||
#pragma once | ||
|
||
#include "test_common.h" | ||
|
||
#define TAPPING_TERM 200 | ||
|
||
#define COMBO_PROCESS_KEY_REPRESS |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Copyright 2024 @Filios92 | ||
# SPDX-License-Identifier: GPL-2.0-or-later | ||
|
||
COMBO_ENABLE = yes | ||
|
||
INTROSPECTION_KEYMAP_C = test_combos_repress.c |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
// Copyright 2024 @Filios92 | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
|
||
#include "keyboard_report_util.hpp" | ||
#include "quantum.h" | ||
#include "keycode.h" | ||
#include "test_common.h" | ||
#include "test_driver.hpp" | ||
#include "test_fixture.hpp" | ||
#include "test_keymap_key.hpp" | ||
|
||
using testing::_; | ||
using testing::InSequence; | ||
|
||
class ComboRepress : public TestFixture {}; | ||
|
||
TEST_F(ComboRepress, combo_repress_tapped) { | ||
TestDriver driver; | ||
KeymapKey key_f(0, 0, 0, KC_F); | ||
KeymapKey key_g(0, 0, 1, KC_G); | ||
set_keymap({key_f, key_g}); | ||
|
||
EXPECT_REPORT(driver, (KC_LEFT_ALT)).Times(2); | ||
EXPECT_REPORT(driver, (KC_TAB, KC_LEFT_ALT)); | ||
EXPECT_EMPTY_REPORT(driver); | ||
tap_combo({key_f, key_g}, 20); | ||
VERIFY_AND_CLEAR(driver); | ||
} | ||
|
||
TEST_F(ComboRepress, combo_repress_held_released_one_key_and_repressed) { | ||
TestDriver driver; | ||
KeymapKey key_f(0, 0, 0, KC_F); | ||
KeymapKey key_g(0, 0, 1, KC_G); | ||
KeymapKey key_h(0, 0, 2, KC_H); | ||
KeymapKey key_j(0, 0, 3, KC_J); | ||
set_keymap({key_f, key_g, key_h, key_j}); | ||
|
||
/* Press combo F+G */ | ||
EXPECT_REPORT(driver, (KC_LEFT_ALT)).Times(2); | ||
EXPECT_REPORT(driver, (KC_TAB, KC_LEFT_ALT)); | ||
key_f.press(); | ||
run_one_scan_loop(); | ||
key_g.press(); | ||
run_one_scan_loop(); | ||
idle_for(COMBO_TERM + 1); | ||
VERIFY_AND_CLEAR(driver); | ||
|
||
/* Release G */ | ||
EXPECT_NO_REPORT(driver); | ||
key_g.release(); | ||
idle_for(80); | ||
VERIFY_AND_CLEAR(driver); | ||
|
||
/* Tap G */ | ||
EXPECT_REPORT(driver, (KC_TAB, KC_LEFT_ALT)); | ||
EXPECT_REPORT(driver, (KC_LEFT_ALT)); | ||
tap_key(key_g, TAPPING_TERM + 1); | ||
VERIFY_AND_CLEAR(driver); | ||
|
||
/* Tap G, but hold for longer */ | ||
EXPECT_REPORT(driver, (KC_TAB, KC_LEFT_ALT)); | ||
EXPECT_REPORT(driver, (KC_LEFT_ALT)); | ||
tap_key(key_g, TAPPING_TERM * 2); | ||
VERIFY_AND_CLEAR(driver); | ||
|
||
idle_for(500); | ||
|
||
/* Tap other combo while holding F */ | ||
EXPECT_REPORT(driver, (KC_ESCAPE, KC_LEFT_ALT)); | ||
EXPECT_REPORT(driver, (KC_LEFT_ALT)); | ||
tap_combo({key_h, key_j}, TAPPING_TERM + 1); | ||
VERIFY_AND_CLEAR(driver); | ||
|
||
/* G press and hold */ | ||
EXPECT_REPORT(driver, (KC_TAB, KC_LEFT_ALT)); | ||
EXPECT_REPORT(driver, (KC_LEFT_ALT)); | ||
key_g.press(); | ||
run_one_scan_loop(); | ||
VERIFY_AND_CLEAR(driver); | ||
|
||
/* F release and tap */ | ||
EXPECT_REPORT(driver, (KC_LEFT_ALT, KC_LEFT_SHIFT)).Times(2); | ||
EXPECT_REPORT(driver, (KC_TAB, KC_LEFT_ALT, KC_LEFT_SHIFT)); | ||
EXPECT_REPORT(driver, (KC_LEFT_ALT)); | ||
key_f.release(); | ||
run_one_scan_loop(); | ||
tap_key(key_f); | ||
VERIFY_AND_CLEAR(driver); | ||
|
||
/* Release G */ | ||
EXPECT_EMPTY_REPORT(driver); | ||
key_g.release(); | ||
run_one_scan_loop(); | ||
VERIFY_AND_CLEAR(driver); | ||
} | ||
|
||
TEST_F(ComboRepress, combo_repress_normal_combo) { | ||
TestDriver driver; | ||
KeymapKey key_f(0, 0, 0, KC_F); | ||
KeymapKey key_g(0, 0, 1, KC_G); | ||
KeymapKey key_h(0, 0, 2, KC_H); | ||
KeymapKey key_j(0, 0, 3, KC_J); | ||
set_keymap({key_f, key_g, key_h, key_j}); | ||
|
||
/* Press combo H+J */ | ||
EXPECT_REPORT(driver, (KC_ESCAPE)); | ||
key_h.press(); | ||
run_one_scan_loop(); | ||
key_j.press(); | ||
run_one_scan_loop(); | ||
idle_for(COMBO_TERM + 10); | ||
VERIFY_AND_CLEAR(driver); | ||
|
||
/* Release H */ | ||
EXPECT_NO_REPORT(driver); | ||
key_h.release(); | ||
idle_for(80); | ||
VERIFY_AND_CLEAR(driver); | ||
|
||
/* Tap H */ | ||
EXPECT_REPORT(driver, (KC_H, KC_ESCAPE)); | ||
EXPECT_REPORT(driver, (KC_ESCAPE)); | ||
tap_key(key_h); | ||
VERIFY_AND_CLEAR(driver); | ||
|
||
/* Tap H, but hold for longer */ | ||
EXPECT_REPORT(driver, (KC_H, KC_ESCAPE)); | ||
EXPECT_REPORT(driver, (KC_ESCAPE)); | ||
tap_key(key_h, TAPPING_TERM + 1); | ||
VERIFY_AND_CLEAR(driver); | ||
|
||
idle_for(500); | ||
|
||
/* Tap other combo while holding K */ | ||
EXPECT_REPORT(driver, (KC_ESCAPE, KC_LEFT_ALT)).Times(2); | ||
EXPECT_REPORT(driver, (KC_ESCAPE, KC_TAB, KC_LEFT_ALT)); | ||
EXPECT_REPORT(driver, (KC_ESCAPE)); | ||
tap_combo({key_f, key_g}, TAPPING_TERM + 1); | ||
VERIFY_AND_CLEAR(driver); | ||
|
||
/* H press and hold */ | ||
EXPECT_REPORT(driver, (KC_H, KC_ESCAPE)); | ||
key_h.press(); | ||
run_one_scan_loop(); | ||
VERIFY_AND_CLEAR(driver); | ||
|
||
/* J release and tap */ | ||
EXPECT_REPORT(driver, (KC_H)); | ||
key_j.release(); | ||
run_one_scan_loop(); | ||
VERIFY_AND_CLEAR(driver); | ||
|
||
/* Release G */ | ||
EXPECT_EMPTY_REPORT(driver); | ||
key_h.release(); | ||
run_one_scan_loop(); | ||
VERIFY_AND_CLEAR(driver); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
// Copyright 2024 @Filios92 | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
#include "quantum.h" | ||
|
||
enum combos { alttab, esc }; | ||
|
||
uint16_t const alttab_combo[] = {KC_F, KC_G, COMBO_END}; | ||
uint16_t const esc_combo[] = {KC_H, KC_J, COMBO_END}; | ||
|
||
// clang-format off | ||
combo_t key_combos[] = { | ||
[alttab] = COMBO(alttab_combo, KC_NO), | ||
[esc] = COMBO(esc_combo, KC_ESC) | ||
}; | ||
// clang-format on | ||
|
||
void process_combo_event(uint16_t combo_index, bool pressed) { | ||
switch (combo_index) { | ||
case alttab: | ||
if (pressed) { | ||
register_mods(MOD_LALT); | ||
tap_code(KC_TAB); | ||
} else { | ||
unregister_mods(MOD_LALT); | ||
} | ||
break; | ||
} | ||
} | ||
|
||
bool process_combo_key_repress(uint16_t combo_index, combo_t *combo, uint8_t key_index, uint16_t keycode) { | ||
switch (combo_index) { | ||
case alttab: | ||
switch (keycode) { | ||
case KC_F: | ||
tap_code16(S(KC_TAB)); | ||
return true; | ||
case KC_G: | ||
tap_code(KC_TAB); | ||
return true; | ||
} | ||
} | ||
return false; | ||
} |