summaryrefslogtreecommitdiff
path: root/quantum/process_keycode
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/process_keycode')
-rw-r--r--quantum/process_keycode/process_repeat_key.c109
-rw-r--r--quantum/process_keycode/process_repeat_key.h62
2 files changed, 171 insertions, 0 deletions
diff --git a/quantum/process_keycode/process_repeat_key.c b/quantum/process_keycode/process_repeat_key.c
new file mode 100644
index 0000000000..f819aa226e
--- /dev/null
+++ b/quantum/process_keycode/process_repeat_key.c
@@ -0,0 +1,109 @@
1// Copyright 2022-2023 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "process_repeat_key.h"
16
17// Default implementation of remember_last_key_user().
18__attribute__((weak)) bool remember_last_key_user(uint16_t keycode, keyrecord_t* record, uint8_t* remembered_mods) {
19 return true;
20}
21
22static bool remember_last_key(uint16_t keycode, keyrecord_t* record, uint8_t* remembered_mods) {
23 switch (keycode) {
24 // Ignore MO, TO, TG, TT, and TL layer switch keys.
25 case QK_MOMENTARY ... QK_MOMENTARY_MAX:
26 case QK_TO ... QK_TO_MAX:
27 case QK_TOGGLE_LAYER ... QK_TOGGLE_LAYER_MAX:
28 case QK_LAYER_TAP_TOGGLE ... QK_LAYER_TAP_TOGGLE_MAX:
29 // Ignore mod keys.
30 case KC_LCTL ... KC_RGUI:
31 case KC_HYPR:
32 case KC_MEH:
33#ifndef NO_ACTION_ONESHOT // Ignore one-shot keys.
34 case QK_ONE_SHOT_LAYER ... QK_ONE_SHOT_LAYER_MAX:
35 case QK_ONE_SHOT_MOD ... QK_ONE_SHOT_MOD_MAX:
36#endif // NO_ACTION_ONESHOT
37#ifdef TRI_LAYER_ENABLE // Ignore Tri Layer keys.
38 case QK_TRI_LAYER_LOWER:
39 case QK_TRI_LAYER_UPPER:
40#endif // TRI_LAYER_ENABLE
41 return false;
42
43 // Ignore hold events on tap-hold keys.
44#ifndef NO_ACTION_TAPPING
45 case QK_MOD_TAP ... QK_MOD_TAP_MAX:
46# ifndef NO_ACTION_LAYER
47 case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:
48# endif // NO_ACTION_LAYER
49 if (record->tap.count == 0) {
50 return false;
51 }
52 break;
53#endif // NO_ACTION_TAPPING
54
55#ifdef SWAP_HANDS_ENABLE
56 case QK_SWAP_HANDS ... QK_SWAP_HANDS_MAX:
57 if (IS_SWAP_HANDS_KEYCODE(keycode) || record->tap.count == 0) {
58 return false;
59 }
60 break;
61#endif // SWAP_HANDS_ENABLE
62
63 case QK_REPEAT_KEY:
64#ifndef NO_ALT_REPEAT_KEY
65 case QK_ALT_REPEAT_KEY:
66#endif // NO_ALT_REPEAT_KEY
67 return false;
68 }
69
70 return remember_last_key_user(keycode, record, remembered_mods);
71}
72
73bool process_last_key(uint16_t keycode, keyrecord_t* record) {
74 if (get_repeat_key_count()) {
75 return true;
76 }
77
78 if (record->event.pressed) {
79 uint8_t remembered_mods = get_mods() | get_weak_mods();
80#ifndef NO_ACTION_ONESHOT
81 remembered_mods |= get_oneshot_mods();
82#endif // NO_ACTION_ONESHOT
83
84 if (remember_last_key(keycode, record, &remembered_mods)) {
85 set_last_record(keycode, record);
86 set_last_mods(remembered_mods);
87 }
88 }
89
90 return true;
91}
92
93bool process_repeat_key(uint16_t keycode, keyrecord_t* record) {
94 if (get_repeat_key_count()) {
95 return true;
96 }
97
98 if (keycode == QK_REPEAT_KEY) {
99 repeat_key_invoke(&record->event);
100 return false;
101#ifndef NO_ALT_REPEAT_KEY
102 } else if (keycode == QK_ALT_REPEAT_KEY) {
103 alt_repeat_key_invoke(&record->event);
104 return false;
105#endif // NO_ALT_REPEAT_KEY
106 }
107
108 return true;
109}
diff --git a/quantum/process_keycode/process_repeat_key.h b/quantum/process_keycode/process_repeat_key.h
new file mode 100644
index 0000000000..eddc50f254
--- /dev/null
+++ b/quantum/process_keycode/process_repeat_key.h
@@ -0,0 +1,62 @@
1// Copyright 2022-2023 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#pragma once
16
17#include "quantum.h"
18
19/**
20 * @brief Process handler for remembering the last key.
21 *
22 * @param keycode Keycode registered by matrix press, per keymap
23 * @param record keyrecord_t structure
24 * @return true Continue processing keycodes, and send to host
25 * @return false Stop processing keycodes, and don't send to host
26 */
27bool process_last_key(uint16_t keycode, keyrecord_t* record);
28
29/**
30 * @brief Optional callback defining which keys are remembered.
31 *
32 * @param keycode Keycode that was just pressed
33 * @param record keyrecord_t structure
34 * @param remembered_mods Mods that will be remembered with this key
35 * @return true Key is remembered
36 * @return false Key is ignored
37 *
38 * Modifier and layer switch keys are always ignored. For all other keys, this
39 * callback is called on every key press. Returning true means that the key is
40 * remembered, false means it is ignored. By default, all non-modifier,
41 * non-layer switch keys are remembered.
42 *
43 * The `remembered_mods` arg represents the mods that will be remembered with
44 * this key. It can be modified to forget certain mods, for instance to forget
45 * capitalization when repeating shifted letters:
46 *
47 * // Forget Shift on letter keys.
48 * if (KC_A <= keycode && keycode <= KC_Z && (*remembered_mods & ~MOD_MASK_SHIFT) == 0) {
49 * *remembered_mods = 0;
50 * }
51 */
52bool remember_last_key_user(uint16_t keycode, keyrecord_t* record, uint8_t* remembered_mods);
53
54/**
55 * @brief Process handler for Repeat Key feature.
56 *
57 * @param keycode Keycode registered by matrix press, per keymap
58 * @param record keyrecord_t structure
59 * @return true Continue processing keycodes, and send to host
60 * @return false Stop processing keycodes, and don't send to host
61 */
62bool process_repeat_key(uint16_t keycode, keyrecord_t* record);