From cf990bc6af73148df216152420ffca004892b61f Mon Sep 17 00:00:00 2001 From: Kawamashi Date: Mon, 13 Oct 2025 13:46:42 +0200 Subject: [PATCH] =?UTF-8?q?=C3=A7a=20marche?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../features/clever_keys_utilities.h | 2 + .../base/keymaps/Kawamashi/features/oneshot.c | 113 ++++++++++++++++++ .../base/keymaps/Kawamashi/features/oneshot.h | 8 ++ .../base/keymaps/Kawamashi/features/os4a.c | 25 +--- .../base/keymaps/Kawamashi/features/os4a.h | 9 +- .../base/keymaps/Kawamashi/features_conf.c | 16 +++ .../base/keymaps/Kawamashi/features_conf.h | 9 +- .../rev1/base/keymaps/Kawamashi/keymap.c | 5 +- 8 files changed, 153 insertions(+), 34 deletions(-) diff --git a/keyboards/splitkb/kyria/rev1/base/keymaps/Kawamashi/features/clever_keys_utilities.h b/keyboards/splitkb/kyria/rev1/base/keymaps/Kawamashi/features/clever_keys_utilities.h index f96cd55c..1701e59c 100644 --- a/keyboards/splitkb/kyria/rev1/base/keymaps/Kawamashi/features/clever_keys_utilities.h +++ b/keyboards/splitkb/kyria/rev1/base/keymaps/Kawamashi/features/clever_keys_utilities.h @@ -34,7 +34,9 @@ void update_bkspc_countdown(unsigned char i); void clear_recent_keys(void); void recent_keys_task(void); + uint16_t get_ongoing_keycode(uint16_t keycode, keyrecord_t* record); +uint16_t get_ongoing_keycode_user(uint16_t keycode); void store_keycode(uint16_t keycode, keyrecord_t* record); void process_key(uint16_t keycode, keyrecord_t* record); diff --git a/keyboards/splitkb/kyria/rev1/base/keymaps/Kawamashi/features/oneshot.c b/keyboards/splitkb/kyria/rev1/base/keymaps/Kawamashi/features/oneshot.c index e9bf9a46..dd922068 100644 --- a/keyboards/splitkb/kyria/rev1/base/keymaps/Kawamashi/features/oneshot.c +++ b/keyboards/splitkb/kyria/rev1/base/keymaps/Kawamashi/features/oneshot.c @@ -1,5 +1,118 @@ #include "oneshot.h" +oneshot_state os_shft_state = os_up_unqueued; +oneshot_state os_ctrl_state = os_up_unqueued; +oneshot_state os_alt_state = os_up_unqueued; +oneshot_state os_win_state = os_up_unqueued; + +bool process_oneshot(uint16_t keycode, keyrecord_t *record){ + + uint8_t mods = one_shot_get_mod(keycode); + + switch (mods) { + case MOD_BIT(KC_LSFT): + return process_oneshot_keys(record, MOD_BIT(KC_LSFT), &os_shft_state); + case MOD_BIT(KC_LCTL): + return process_oneshot_keys(record, MOD_BIT(KC_LCTL), &os_ctrl_state); + case MOD_BIT(KC_LALT): + return process_oneshot_keys(record, MOD_BIT(KC_LALT), &os_alt_state); + case MOD_BIT(KC_LWIN): + return process_oneshot_keys(record, MOD_BIT(KC_LWIN), &os_win_state); + } + + mods = get_mods(); + + if (mods & MOD_BIT(KC_LSFT)) { + process_mods(keycode, record, MOD_BIT(KC_LSFT), &os_shft_state); + } + if (mods & MOD_BIT(KC_LCTL)) { + process_mods(keycode, record, MOD_BIT(KC_LCTL), &os_ctrl_state); + } + if (mods & MOD_BIT(KC_LALT)) { + process_mods(keycode, record, MOD_BIT(KC_LALT), &os_alt_state); + } + if (mods & MOD_BIT(KC_LWIN)) { + process_mods(keycode, record, MOD_BIT(KC_LWIN), &os_win_state); + } + return true; +} + +bool process_oneshot_keys(keyrecord_t *record, uint8_t mod, oneshot_state *state) { + + if (record->event.pressed) { + // Trigger keydown + if (*state == os_up_unqueued) { + register_mods(mod); + } + *state = os_down_unused; + } else { + // Trigger keyup + switch (*state) { + case os_down_unused: + // If we didn't use the mod while trigger was held, queue it. + *state = os_up_queued; + break; + case os_down_used: + // If we did use the mod while trigger was held, unregister it. + *state = os_up_unqueued; + unregister_mods(mod); + break; + default: + break; + } + } + return false; +} + +void process_mods(uint16_t keycode, keyrecord_t *record, uint8_t mod, oneshot_state *state) { + + if (is_oneshot_cancel_key(keycode)) { + if (record->event.pressed && *state != os_up_unqueued) { + // Cancel oneshot on designated cancel keydown. + *state = os_up_unqueued; + unregister_mods(mod); + } + + } else if (!is_oneshot_ignored_key(keycode)) { + + // Regular key released / roll between two regular keys + if (*state == os_up_queued_used) { + *state = os_up_unqueued; + unregister_mods(mod); + + } else if (record->event.pressed) { + // Regular key pressed + if (*state == os_up_queued) { + *state = os_up_queued_used; + } + + } else { + // Regular key release + switch (*state) { + // When the mod key is still pressed + case os_down_unused: + *state = os_down_used; + break; + // Roll between a mod key and a regular key + case os_up_queued: + *state = os_up_unqueued; + unregister_mods(mod); + break; + default: + break; + } + } + } +} + +void process_oneshot_old(uint16_t keycode, keyrecord_t *record){ +// Handling Callum's OSM on OS4A layers + update_oneshot(&os_shft_state, KC_LSFT, OS_SHFT, keycode, record); + update_oneshot(&os_ctrl_state, KC_LCTL, OS_CTRL, keycode, record); + update_oneshot(&os_alt_state, KC_LALT, OS_LALT, keycode, record); + update_oneshot(&os_win_state, KC_LWIN, OS_WIN, keycode, record); +} + void update_oneshot(oneshot_state *state, uint16_t mod, uint16_t trigger, uint16_t keycode, keyrecord_t *record) { if (keycode == trigger) { diff --git a/keyboards/splitkb/kyria/rev1/base/keymaps/Kawamashi/features/oneshot.h b/keyboards/splitkb/kyria/rev1/base/keymaps/Kawamashi/features/oneshot.h index 6b82abcd..9b20c155 100644 --- a/keyboards/splitkb/kyria/rev1/base/keymaps/Kawamashi/features/oneshot.h +++ b/keyboards/splitkb/kyria/rev1/base/keymaps/Kawamashi/features/oneshot.h @@ -1,6 +1,7 @@ #pragma once #include QMK_KEYBOARD_H +#include "keymap.h" // Represents the five states a oneshot key can be in typedef enum { @@ -11,6 +12,13 @@ typedef enum { os_down_used, } oneshot_state; +uint8_t one_shot_get_mod(uint16_t keycode); + +void process_oneshot_old(uint16_t keycode, keyrecord_t *record); +bool process_oneshot(uint16_t keycode, keyrecord_t *record); +bool process_oneshot_keys(keyrecord_t *record, uint8_t mod, oneshot_state *state); +void process_mods(uint16_t keycode, keyrecord_t *record, uint8_t mod, oneshot_state *state); + // Custom oneshot mod implementation that doesn't rely on timers. If a mod is // used while it is held it will be unregistered on keyup as normal, otherwise // it will be queued and only released after the next non-mod keyup. diff --git a/keyboards/splitkb/kyria/rev1/base/keymaps/Kawamashi/features/os4a.c b/keyboards/splitkb/kyria/rev1/base/keymaps/Kawamashi/features/os4a.c index feb4ac12..7d2a0530 100644 --- a/keyboards/splitkb/kyria/rev1/base/keymaps/Kawamashi/features/os4a.c +++ b/keyboards/splitkb/kyria/rev1/base/keymaps/Kawamashi/features/os4a.c @@ -17,11 +17,6 @@ #include "os4a.h" -oneshot_state os_shft_state = os_up_unqueued; -oneshot_state os_ctrl_state = os_up_unqueued; -oneshot_state os_alt_state = os_up_unqueued; -oneshot_state os_win_state = os_up_unqueued; - static uint8_t os4a_layer = 0; static bool exit_os4a_layer = false; @@ -61,11 +56,7 @@ bool process_os4a_keys(uint16_t keycode, keyrecord_t *record) { } -bool add_shift(uint16_t keycode, keyrecord_t *record) { - - // Testing exit_os4a_layer is necessary to prevent OS shift to be added in case of rolled keys - // or when other features invoke keycodes to be processed (ex: custom altgr, clever keys). - //if (exit_os4a_layer) { return false; } +bool should_add_shift(uint16_t keycode, keyrecord_t *record) { // Shift shouldn't be added if other mods are active if ((get_mods() | get_oneshot_mods()) != 0) { return false; } @@ -93,13 +84,7 @@ void mouse_mods_key_up(uint16_t keycode, keyrecord_t *record) { } } -bool process_mods(uint16_t keycode, keyrecord_t *record) { - - // Handling Callum's OSM on OS4A layers - update_oneshot(&os_shft_state, KC_LSFT, OS_SHFT, keycode, record); - update_oneshot(&os_ctrl_state, KC_LCTL, OS_CTRL, keycode, record); - update_oneshot(&os_alt_state, KC_LALT, OS_LALT, keycode, record); - update_oneshot(&os_win_state, KC_LWIN, OS_WIN, keycode, record); +bool process_os4a(uint16_t keycode, keyrecord_t *record) { // Handling OS4A keys if (IS_OS4A_KEY(keycode)) { return process_os4a_keys(keycode, record); } @@ -116,7 +101,7 @@ bool process_mods(uint16_t keycode, keyrecord_t *record) { if (record->event.pressed) { if (!should_stay_os4a_layer(keycode)) { - if (add_shift(keycode, record)) { set_oneshot_mods(MOD_BIT(KC_LSFT)); } + if (should_add_shift(keycode, record)) { set_oneshot_mods(MOD_BIT(KC_LSFT)); } exit_os4a_layer = true; } @@ -127,7 +112,3 @@ bool process_mods(uint16_t keycode, keyrecord_t *record) { return true; } - -void os4a_layer_exit_check(void) { - if (os4a_layer != 0 && exit_os4a_layer) { os4a_layer_off(os4a_layer); } -} diff --git a/keyboards/splitkb/kyria/rev1/base/keymaps/Kawamashi/features/os4a.h b/keyboards/splitkb/kyria/rev1/base/keymaps/Kawamashi/features/os4a.h index fb1d63c1..02538a4b 100644 --- a/keyboards/splitkb/kyria/rev1/base/keymaps/Kawamashi/features/os4a.h +++ b/keyboards/splitkb/kyria/rev1/base/keymaps/Kawamashi/features/os4a.h @@ -32,13 +32,16 @@ void os4a_layer_on(uint8_t layer); void os4a_tap(uint16_t keycode); bool process_os4a_keys(uint16_t keycode, keyrecord_t *record); -bool add_shift(uint16_t keycode, keyrecord_t *record); +bool should_add_shift(uint16_t keycode, keyrecord_t *record); void mouse_mods_key_up(uint16_t keycode, keyrecord_t *record); -bool process_mods(uint16_t keycode, keyrecord_t *record); +bool process_os4a(uint16_t keycode, keyrecord_t *record); -void os4a_layer_exit_check(void); +uint8_t os4a_layer_from_trigger(uint16_t keycode); +bool should_stay_os4a_layer(uint16_t keycode); +bool not_to_be_shifted(uint16_t keycode); +//bool mods_for_mouse(uint16_t keycode); #ifdef __cplusplus } diff --git a/keyboards/splitkb/kyria/rev1/base/keymaps/Kawamashi/features_conf.c b/keyboards/splitkb/kyria/rev1/base/keymaps/Kawamashi/features_conf.c index 77e7897f..d9f1a597 100644 --- a/keyboards/splitkb/kyria/rev1/base/keymaps/Kawamashi/features_conf.c +++ b/keyboards/splitkb/kyria/rev1/base/keymaps/Kawamashi/features_conf.c @@ -134,6 +134,22 @@ bool is_oneshot_cancel_key(uint16_t keycode) { } } +uint8_t one_shot_get_mod(uint16_t keycode) { + switch (keycode) { + case OS_SHFT: + return MOD_BIT(KC_LSFT); + case OS_CTRL: + return MOD_BIT(KC_LCTL); + case OS_LALT: + return MOD_BIT(KC_LALT); + case OS_WIN: + return MOD_BIT(KC_LWIN); + + default: + return 0; + } +} + bool is_oneshot_ignored_key(uint16_t keycode) { const uint8_t mods = get_mods() | get_weak_mods() | get_oneshot_mods(); diff --git a/keyboards/splitkb/kyria/rev1/base/keymaps/Kawamashi/features_conf.h b/keyboards/splitkb/kyria/rev1/base/keymaps/Kawamashi/features_conf.h index dbe83caa..7fabede6 100644 --- a/keyboards/splitkb/kyria/rev1/base/keymaps/Kawamashi/features_conf.h +++ b/keyboards/splitkb/kyria/rev1/base/keymaps/Kawamashi/features_conf.h @@ -22,11 +22,4 @@ bool is_caps_lock_on(void); uint16_t tap_hold_extractor(uint16_t keycode); -bool process_custom_tap_hold(uint16_t keycode, keyrecord_t *record); - -uint16_t get_ongoing_keycode_user(uint16_t keycode); - -uint8_t os4a_layer_from_trigger(uint16_t keycode); -bool should_stay_os4a_layer(uint16_t keycode); -bool not_to_be_shifted(uint16_t keycode); -//bool mods_for_mouse(uint16_t keycode); \ No newline at end of file +bool process_custom_tap_hold(uint16_t keycode, keyrecord_t *record); \ No newline at end of file diff --git a/keyboards/splitkb/kyria/rev1/base/keymaps/Kawamashi/keymap.c b/keyboards/splitkb/kyria/rev1/base/keymaps/Kawamashi/keymap.c index c17bfdb2..560f6154 100644 --- a/keyboards/splitkb/kyria/rev1/base/keymaps/Kawamashi/keymap.c +++ b/keyboards/splitkb/kyria/rev1/base/keymaps/Kawamashi/keymap.c @@ -91,8 +91,11 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { global_quick_tap_timer = timer_read(); } + // Callum Mods + if (!process_oneshot(keycode, record)) { return false; } + // Multi One-Shot Mods - if (!process_mods(keycode, record)) { return false; } + if (!process_os4a(keycode, record)) { return false; } // Numword if (!process_numword(keycode, record)) { return false; }