From c65beba3bba9a31a819c079d4049be1879e27fc7 Mon Sep 17 00:00:00 2001 From: bluepython508 Date: Tue, 5 Mar 2024 20:37:49 +0000 Subject: [PATCH] Better OSM: callum mods this removes the delay, and improves composition --- .../kyria/rev3/keymaps/bluepython508/config.h | 3 - .../kyria/rev3/keymaps/bluepython508/keymap.c | 119 ++++++++++++++++-- 2 files changed, 112 insertions(+), 10 deletions(-) diff --git a/keyboards/splitkb/kyria/rev3/keymaps/bluepython508/config.h b/keyboards/splitkb/kyria/rev3/keymaps/bluepython508/config.h index d57ed26..87f737c 100644 --- a/keyboards/splitkb/kyria/rev3/keymaps/bluepython508/config.h +++ b/keyboards/splitkb/kyria/rev3/keymaps/bluepython508/config.h @@ -15,6 +15,3 @@ */ #pragma once -#define TAPPING_TERM 500 -#define DOUBLE_TAP_SHIFT_TURNS_ON_CAPS_WORD -#define HOLD_ON_OTHER_KEYPRESS diff --git a/keyboards/splitkb/kyria/rev3/keymaps/bluepython508/keymap.c b/keyboards/splitkb/kyria/rev3/keymaps/bluepython508/keymap.c index 9fb8c0d..75c9f22 100644 --- a/keyboards/splitkb/kyria/rev3/keymaps/bluepython508/keymap.c +++ b/keyboards/splitkb/kyria/rev3/keymaps/bluepython508/keymap.c @@ -16,6 +16,13 @@ #include "keycodes.h" #include QMK_KEYBOARD_H +enum keycodes { + OS_LSFT = SAFE_RANGE, + OS_LCTL, + OS_LALT, + OS_LGUI, +}; + enum layers { _COLEMAK_DH = 0, _GAME, @@ -25,7 +32,6 @@ enum layers { _FUN, }; - // Aliases for readability #define SYM MO(_SYM) #define NUM MO(_NUM) @@ -34,11 +40,6 @@ enum layers { #define TYPING DF(_COLEMAK_DH) #define GAME DF(_GAME) -#define OS_LGUI OSM(MOD_LGUI) -#define OS_LALT OSM(MOD_LALT) -#define OS_LCTL OSM(MOD_LCTL) -#define OS_LSFT OSM(MOD_LSFT) - #define C_SPC C(KC_SPACE) #define C_RET C(KC_ENTER) /* TODO: @@ -147,7 +148,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [_GAME] = LAYOUT( KC_Q , KC_W , KC_E , KC_R , KC_T , KC_Y , KC_U , KC_I , KC_UP , KC_O , KC_P , KC_ESC , KC_A , KC_S , KC_D , KC_F , KC_G , KC_H , KC_K , KC_LEFT, KC_DOWN, KC_RGHT, KC_L , KC_M , - KC_Z , KC_X , KC_C , KC_V , KC_B , KC_N , XXXXXXX, TYPING , XXXXXXX, XXXXXXX, KC_SCLN, KC_QUOT, KC_COMM, KC_DOT , KC_SLSH, KC_J, + KC_Z , KC_X , KC_C , KC_V , KC_B , KC_N , KC_TAB , TYPING , XXXXXXX, XXXXXXX, KC_SCLN, KC_QUOT, KC_COMM, KC_DOT , KC_SLSH, KC_J, XXXXXXX, XXXXXXX, OS_LSFT, KC_ENT , XXXXXXX, KC_BSPC, KC_SPC , KC_RSFT, KC_ENT, XXXXXXX ), /* @@ -197,3 +198,107 @@ void keyboard_pre_init_user(void) { setPinOutput(24); writePinHigh(24); } + +typedef enum { + os_up_unqueued = 0, + os_up_queued, + os_down_unused, + os_down_used, +} oneshot_state_t; + +oneshot_state_t oneshot_state[4] = {0}; +uint16_t mods[] = {KC_LSFT, KC_LCTL, KC_LALT, KC_LGUI}; + +bool is_oneshot_ignored_key(uint16_t keycode) { + switch (keycode) { + case OS_LSFT: + case OS_LCTL: + case OS_LALT: + case OS_LGUI: + case NAV: + case SYM: + case NUM: + case FUN: + return true; + default: + return false; + } +} + +bool is_oneshot_cancel_key(uint16_t keycode) { + switch (keycode) { + case NAV: + case SYM: + case NUM: + case FUN: + return true; + default: + return false; + } +} +// From https://github.com/qmk/qmk_firmware/blob/user-keymaps-still-present/users/callum/oneshot.c +void update_oneshot( + oneshot_state_t *state, + uint16_t mod, + uint16_t trigger, + uint16_t keycode, + keyrecord_t *record +) { + if (keycode == trigger) { + if (record->event.pressed) { + // Trigger keydown + if (*state == os_up_unqueued) { + register_code(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_code(mod); + break; + default: + break; + } + } + } else { + if (record->event.pressed) { + if (is_oneshot_cancel_key(keycode) && *state != os_up_unqueued) { + // Cancel oneshot on designated cancel keydown. + *state = os_up_unqueued; + unregister_code(mod); + } + } else { + if (!is_oneshot_ignored_key(keycode)) { + // On non-ignored keyup, consider the oneshot used. + switch (*state) { + case os_down_unused: + *state = os_down_used; + break; + case os_up_queued: + *state = os_up_unqueued; + unregister_code(mod); + break; + default: + break; + } + } + } + } +} + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + update_oneshot(&oneshot_state[0], mods[0], OS_LSFT, keycode, record); + update_oneshot(&oneshot_state[1], mods[1], OS_LCTL, keycode, record); + update_oneshot(&oneshot_state[2], mods[2], OS_LALT, keycode, record); + update_oneshot(&oneshot_state[3], mods[3], OS_LGUI, keycode, record); + + return true; +} +