-
Notifications
You must be signed in to change notification settings - Fork 22
Expand file tree
/
Copy pathfilterpaper.c
More file actions
134 lines (113 loc) · 5.06 KB
/
filterpaper.c
File metadata and controls
134 lines (113 loc) · 5.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// Copyright @filterpaper
// SPDX-License-Identifier: GPL-2.0+
#include QMK_KEYBOARD_H
#include "autocorrect.h"
// Convert 5-bit to 8-bit packed modifiers by extracting the
// upper bit and shift by 4 if bit 12 is set, otherwise by 8
#define MOD_TAP_GET_MOD_BITS(k) (((k) & 0x0F00) >> (((k) & 0x1000) ? 4 : 8))
#define GET_TAP_KEYCODE(k) ((k) & 0xFF)
#define IS_TAP_HOLD(k) (IS_QK_MOD_TAP((k)) || IS_QK_LAYER_TAP((k)))
#define IS_SHIFT_TAP(k) (((k) & QK_LSFT) && IS_QK_MOD_TAP((k)))
// Alpha row key detection using bitmask 0x77 for rows 0-2 and 4-6
#define IS_ALPHA_ROW(r) ((1U << (r)->event.key.row) & 0x77)
// Checks for a non-Shift tap-hold key pressed in rapid succession
// after a letter key (A–Z) within a short interval
#define IS_QUICK_SUCCESSION_INPUT(k, r, ctx) ( \
IS_TAP_HOLD((k)) && !IS_SHIFT_TAP((k)) && IS_ALPHA_ROW((r)) \
&& GET_TAP_KEYCODE((ctx).keycode) <= KC_Z \
&& last_matrix_activity_elapsed() <= QUICK_TAP_TERM \
)
// Same-hand key press detection by comparing two rows using bitmasks
// where row 1 matches rows 0-2 (0x07) and row 5 matches rows 4-6 (0x70)
#define LATERAL_MASK(n) ((n) == 1 ? 0x07 : ((n) == 5 ? 0x70 : 0x00))
#define IS_UNILATERAL(r1, r2) (LATERAL_MASK(r1) & (1U << (r2)))
// Checks for a home row key overlapping another non-Shift key on the same
// side of the keyboard, or a shortcut tap-hold key overlapping with any key
#define IS_CHORDAL_TAP_INPUT(k, r, ctx) ( \
(IS_UNILATERAL((r)->event.key.row, (ctx).row) && !IS_SHIFT_TAP((ctx).keycode)) \
|| (IS_QK_LAYER_TAP((k)) && QK_LAYER_TAP_GET_LAYER((k)) == 0) \
)
// Checks for Shift-tap exemption when the contextual
// tap-hold state matches an active Shift modifier state
#define IS_SHIFT_EXEMPT(k, ctx) ( \
IS_SHIFT_TAP((k)) \
&& (IS_TAP_HOLD((ctx).keycode) == (bool)(get_mods() & MOD_MASK_SHIFT)) \
)
// Tap keycode pressed state tracker
static bool tapped[UINT8_MAX + 1];
// Contextual input cache
static struct {
uint16_t keycode;
uint8_t row;
} context;
bool pre_process_record_user(uint16_t keycode, keyrecord_t *record) {
const uint8_t tap_keycode = GET_TAP_KEYCODE(keycode);
if (record->event.pressed) {
// Force tap on rapid input to prevent unintended holds when typing
if (IS_QUICK_SUCCESSION_INPUT(keycode, record, context)) {
tapped[tap_keycode] = true;
record->keycode = tap_keycode;
}
// Store the intermediate input for contextual processing
context.keycode = keycode;
context.row = record->event.key.row;
} else {
// Clear tapped flag and set tap count for release handling
if (tapped[tap_keycode]) {
tapped[tap_keycode] = false;
record->tap.count = 1;
}
}
return true;
}
bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) {
// Force tap on same-hand chord overlap or shortcut tap-hold key press
if (IS_CHORDAL_TAP_INPUT(keycode, record, context)) {
if (!IS_SHIFT_EXEMPT(keycode, context)) {
tapped[GET_TAP_KEYCODE(keycode)] = true;
}
record->tap.interrupted = false;
record->tap.count = 1;
return true;
}
// Activate layer hold with another key press
return IS_QK_LAYER_TAP(keycode) && QK_LAYER_TAP_GET_LAYER(keycode);
}
uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) {
return IS_SHIFT_TAP(keycode) && IS_ALPHA_ROW(record) ? SHIFT_TAP_TERM : TAPPING_TERM;
}
static inline bool process_caps_word(uint16_t keycode, keyrecord_t *record) {
if (!host_keyboard_led_state().caps_lock) return true;
// Get tap keycode from tap-hold keys
if (IS_TAP_HOLD(keycode)) {
if (record->tap.count == 0) return true;
keycode = GET_TAP_KEYCODE(keycode);
}
// Letter and word-related keys that retain caps lock
bool is_word_key = keycode <= KC_0
|| keycode == KC_BSPC
|| keycode == KC_MINS
|| keycode == KC_UNDS
|| keycode == KC_CAPS;
// Toggle caps lock at a word boundary if the key is not
// a word key or if any non-Shift modifiers are active
if (!is_word_key || (get_mods() & ~MOD_MASK_SHIFT)) {
tap_code(KC_CAPS);
}
return true;
}
// Send shortcut keycode for held key
#define PROCESS_SHORTCUT(k, r) ((r)->tap.count ? true : (tap_code16((k)), false))
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
if (record->event.pressed) {
if (!process_autocorrect(keycode, record) || !process_caps_word(keycode, record)) {
return false;
}
// Handle clipboard tap-hold shortcuts
if (keycode == TH_M) return PROCESS_SHORTCUT(Z_PST, record);
else if (keycode == TH_COMM) return PROCESS_SHORTCUT(Z_CPY, record);
else if (keycode == TH_DOT) return PROCESS_SHORTCUT(Z_CUT, record);
else if (keycode == TH_SLSH) return PROCESS_SHORTCUT(Z_UND, record);
}
return true;
}