summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph Cullmann <christoph@cullmann.io>2024-09-15 16:45:49 +0200
committerChristoph Cullmann <christoph@cullmann.io>2024-09-15 16:45:49 +0200
commit0c9112bcaddd76cc5776e40a891cd2b6cde8a5cc (patch)
treef2db510aab096f8751ffcbd0630a4a768610386f
parentee341d225b572d30a5405c4fed85dd0e7d845d61 (diff)
update AchordionHEADmaster
-rw-r--r--common/achordion.c51
1 files changed, 33 insertions, 18 deletions
diff --git a/common/achordion.c b/common/achordion.c
index 07c1835..4968e9d 100644
--- a/common/achordion.c
+++ b/common/achordion.c
@@ -74,6 +74,16 @@ static void update_streak_timer(uint16_t keycode, keyrecord_t* record) {
}
#endif
+// Presses or releases eager_mods through process_action(), which skips the
+// usual event handling pipeline. The action is considered as a mod-tap hold or
+// release, with Retro Tapping if enabled.
+static void process_eager_mods_action(void) {
+ action_t action;
+ action.code = ACTION_MODS_TAP_KEY(
+ eager_mods, QK_MOD_TAP_GET_TAP_KEYCODE(tap_hold_keycode));
+ process_action(&tap_hold_record, action);
+}
+
// Calls `process_record()` with state set to RECURSING.
static void recursively_process_record(keyrecord_t* record, uint8_t state) {
achordion_state = STATE_RECURSING;
@@ -92,9 +102,11 @@ static void settle_as_hold(void) {
if (eager_mods) {
// If eager mods are being applied, nothing needs to be done besides
// updating the state.
+ dprintln("Achordion: Settled eager mod as hold.");
achordion_state = STATE_HOLDING;
} else {
// Create hold press event.
+ dprintln("Achordion: Plumbing hold press.");
recursively_process_record(&tap_hold_record, STATE_HOLDING);
}
}
@@ -102,14 +114,22 @@ static void settle_as_hold(void) {
// Sends tap press and release and settles the active tap-hold key as tapped.
static void settle_as_tap(void) {
if (eager_mods) { // Clear eager mods if set.
+#if defined(RETRO_TAPPING) || defined(RETRO_TAPPING_PER_KEY)
#ifdef DUMMY_MOD_NEUTRALIZER_KEYCODE
neutralize_flashing_modifiers(get_mods());
#endif // DUMMY_MOD_NEUTRALIZER_KEYCODE
- unregister_mods(eager_mods);
+#endif // defined(RETRO_TAPPING) || defined(RETRO_TAPPING_PER_KEY)
+ tap_hold_record.event.pressed = false;
+ // To avoid falsely triggering Retro Tapping, process eager mods release as
+ // a regular mods release rather than a mod-tap release.
+ action_t action;
+ action.code = ACTION_MODS(eager_mods);
+ process_action(&tap_hold_record, action);
eager_mods = 0;
}
dprintln("Achordion: Plumbing tap press.");
+ tap_hold_record.event.pressed = true;
tap_hold_record.tap.count = 1; // Revise event as a tap.
tap_hold_record.tap.interrupted = true;
// Plumb tap press event.
@@ -155,9 +175,16 @@ bool process_achordion(uint16_t keycode, keyrecord_t* record) {
if (is_mt) { // Apply mods immediately if they are "eager."
const uint8_t mod = mod_config(QK_MOD_TAP_GET_MODS(keycode));
- if (achordion_eager_mod(mod)) {
- eager_mods = ((mod & 0x10) == 0) ? mod : (mod << 4);
- register_mods(eager_mods);
+ if (
+#if defined(CAPS_WORD_ENABLE) && defined(CAPS_WORD_INVERT_ON_SHIFT)
+ // Since eager mods bypass normal event handling, eager Shift does
+ // not work with CAPS_WORD_INVERT_ON_SHIFT. So if this option is
+ // enabled, we don't apply Shift eagerly when Caps Word is on.
+ !(is_caps_word_on() && (mod & MOD_LSFT) != 0) &&
+#endif // defined(CAPS_WORD_ENABLE) && defined(CAPS_WORD_INVERT_ON_SHIFT)
+ achordion_eager_mod(mod)) {
+ eager_mods = mod;
+ process_eager_mods_action();
}
}
@@ -180,18 +207,8 @@ bool process_achordion(uint16_t keycode, keyrecord_t* record) {
if (keycode == tap_hold_keycode && !record->event.pressed) {
if (eager_mods) {
dprintln("Achordion: Key released. Clearing eager mods.");
- // If Retro Tapping and no other key was pressed, settle as tapped.
-#if defined(RETRO_TAPPING) || defined(RETRO_TAPPING_PER_KEY)
- if (!pressed_another_key_before_release
-#ifdef RETRO_TAPPING_PER_KEY
- && get_retro_tapping(tap_hold_keycode, &tap_hold_record)
-#endif // RETREO_TAPPING_PER_KEY
- ) {
- settle_as_tap();
- }
-#endif // defined(RETRO_TAPPING) || defined(RETRO_TAPPING_PER_KEY)
-
- unregister_mods(eager_mods);
+ tap_hold_record.event.pressed = false;
+ process_eager_mods_action();
} else if (achordion_state == STATE_HOLDING) {
dprintln("Achordion: Key released. Plumbing hold release.");
tap_hold_record.event.pressed = false;
@@ -238,7 +255,6 @@ bool process_achordion(uint16_t keycode, keyrecord_t* record) {
(!is_key_event || (is_tap_hold && record->tap.count == 0) ||
achordion_chord(tap_hold_keycode, &tap_hold_record, keycode,
record))) {
- dprintln("Achordion: Plumbing hold press.");
settle_as_hold();
#ifdef REPEAT_KEY_ENABLE
@@ -285,7 +301,6 @@ bool process_achordion(uint16_t keycode, keyrecord_t* record) {
void achordion_task(void) {
if (achordion_state == STATE_UNSETTLED &&
timer_expired(timer_read(), hold_timer)) {
- dprintln("Achordion: Timeout. Plumbing hold press.");
settle_as_hold(); // Timeout expired, settle the key as held.
}