Refactor divers

This commit is contained in:
Kawamashi 2025-10-17 14:24:45 +02:00
commit 64f5153f70
35 changed files with 834 additions and 345 deletions

View file

@ -83,7 +83,7 @@ void get_clever_keycode(uint16_t* ongoing_keycode, keyrecord_t* record) {
break;
case PG_P:
switch (*ongoing_keycode) {
switch (*ongoing_keycode) {
case PG_C:
// "pas"
return finish_word((uint16_t[]) {PG_A, PG_S}, 2, ongoing_keycode, record);
@ -97,6 +97,25 @@ void get_clever_keycode(uint16_t* ongoing_keycode, keyrecord_t* record) {
return finish_word((uint16_t[]) {PG_L, PG_U, PG_S}, 3, ongoing_keycode, record);
}
break;
case PG_M:
case PG_R:
case PG_A:
case PG_E:
case PG_EACU:
case PG_I:
case PG_O:
case PG_U:
case PG_Y:
switch (*ongoing_keycode) {
case PG_H:
update_bkspc_countdown(0);
return replace_ongoing_key(PG_B, ongoing_keycode, record);
case PG_B:
update_bkspc_countdown(0);
return replace_ongoing_key(PG_H, ongoing_keycode, record);
}
break;
}
@ -206,7 +225,7 @@ void get_clever_keycode(uint16_t* ongoing_keycode, keyrecord_t* record) {
}
break;
case PG_H:
/* case PG_H:
switch (prev_keycode) {
case PG_M:
case PG_R:
@ -219,7 +238,7 @@ void get_clever_keycode(uint16_t* ongoing_keycode, keyrecord_t* record) {
case PG_Y:
update_bkspc_countdown(0);
return replace_ongoing_key(PG_B, ongoing_keycode, record);
}
} */
/* if (prev_keycode == PG_M) {
// "mh" -> "mb"
update_bkspc_countdown(0);
@ -232,7 +251,8 @@ void get_clever_keycode(uint16_t* ongoing_keycode, keyrecord_t* record) {
case OU_GRV:
layer_off(_ODK);
return finish_word((uint16_t[]) {PG_O, PG_ODK, PG_N}, 3, ongoing_keycode, record);
//return finish_word((uint16_t[]) {PG_O, PG_ODK, PG_N}, 3, ongoing_keycode, record);
replace_ongoing_key(prev_keycode, ongoing_keycode, record);
case PG_APOS:
if (replace_apos()) { return replace_ongoing_key(PG_APOD, ongoing_keycode, record); }

View file

@ -52,15 +52,26 @@ uint16_t get_ongoing_keycode(uint16_t keycode, keyrecord_t* record) {
uint8_t mods = get_mods() | get_weak_mods() | get_oneshot_mods();
//if (mods & ~(MOD_MASK_SHIFT | MOD_BIT(KC_ALGR))) {
if (mods & ~MOD_MASK_SHIFT) {
clear_recent_keys(); // Avoid interfering with ctrl, alt, alt-gr and gui.
if (mods & ~(MOD_MASK_SHIFT | MOD_BIT(KC_ALGR))) {
clear_recent_keys(); // Avoid interfering with ctrl, alt and gui.
return KC_NO;
}
// Sticky keys don't type anything on their own.
if (IS_QK_ONE_SHOT_MOD(keycode) || IS_QK_ONE_SHOT_LAYER(keycode)) { return KC_NO; }
// Extract keycode from regular tap-hold keys.
if (IS_QK_MOD_TAP(keycode) || IS_QK_LAYER_TAP(keycode)) {
if (record->tap.count == 0) { return KC_NO; }
// Get tapping keycode.
keycode = tap_hold_extractor(keycode);
}
// Handles custom keycodes.
uint16_t custom_keycode = get_ongoing_keycode_user(keycode, record);
if (custom_keycode != KC_TRNS) { return custom_keycode; }
// Handle backspace.
if (keycode == KC_BSPC) {
bkspc_countdown--;
@ -77,36 +88,20 @@ uint16_t get_ongoing_keycode(uint16_t keycode, keyrecord_t* record) {
return KC_NO;
}
// Extract keycode from regular tap-hold keys.
if (IS_QK_MOD_TAP(keycode) || IS_QK_LAYER_TAP(keycode)) {
if (record->tap.count == 0) { return KC_NO; }
// Get tapping keycode.
keycode = tap_hold_extractor(keycode);
}
// Handles custom keycodes.
uint16_t custom_keycode = get_ongoing_keycode_user(keycode);
if (custom_keycode != KC_TRNS) { return custom_keycode; }
uint8_t basic_keycode = keycode;
// Handle keys carrying a modifier, for ex on layers(! and ?).
if (IS_QK_MODS(keycode)) { basic_keycode = QK_MODS_GET_BASIC_KEYCODE(keycode); }
uint8_t basic_keycode = QK_MODS_GET_BASIC_KEYCODE(keycode);
switch (basic_keycode) {
case KC_A ... KC_SLASH: // These keys type letters, digits, symbols.
case PG_E:
if (basic_keycode != keycode) {
// Handle keys carrying a modifier, for ex on symbols layer
return keycode;
//if (is_letter(basic_keycode) && (mods & ~MOD_BIT(KC_ALGR))) {
if (is_letter(basic_keycode)) {
// Shift doesn't matter for letters.
return basic_keycode;
} else if (basic_keycode != keycode) {
// For keys carrying a modifier, for ex on layers.
} else if (is_letter(basic_keycode)) {
return keycode;
} else {
// Handle shifted symbols (ex shift + '-' = '!')
// Convert 8-bit mods to the 5-bit format used in keycodes. This is lossy: if
// left and right handed mods were mixed, they all become right handed.
mods = ((mods & 0xf0) ? /* set right hand bit */ 0x10 : 0)

View file

@ -36,7 +36,7 @@ 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);
uint16_t get_ongoing_keycode_user(uint16_t keycode, keyrecord_t* record);
void store_keycode(uint16_t keycode, keyrecord_t* record);
void process_key(uint16_t keycode, keyrecord_t* record);

View file

@ -64,7 +64,7 @@ combo_t key_combos[] = {
[TAB] = COMBO(tab_combo, KC_TAB),
[ESC] = COMBO(esc_combo, KC_ESC),
[HELP] = COMBO(help_combo, AIDE_MEM),
[PANIC] = COMBO(panic_combo, RAZ),
[PANIC] = COMBO(panic_combo, KC_NO),
//[NUMWRD] = COMBO(numword_combo, NUMWORD),
[ALTTAB] = COMBO(alttab_combo, KC_NO),
[ALTESC] = COMBO(altesc_combo, LALT(KC_ESC))
@ -103,6 +103,20 @@ void process_combo_event(uint16_t combo_index, bool pressed) {
unregister_mods(MOD_LALT);
}
break;
case PANIC:
if (pressed) {
if (is_caps_lock_on()) { tap_code(KC_CAPS); }
if (!host_keyboard_led_state().num_lock) { tap_code(KC_NUM_LOCK); }
layer_clear();
clear_mods();
//clear_oneshot_mods();
//clear_weak_mods();
caps_word_off();
//disable_num_word();
clear_recent_keys();
}
break;
}
}

View file

@ -16,59 +16,65 @@
#include "macros.h"
static bool is_apos_dr = false;
bool replace_apos(void) {
return is_apos_dr;
static bool sel_word = false;
bool is_select_word(void) {
return sel_word;
}
bool process_macros(uint16_t keycode, keyrecord_t *record) {
void end_select_word(void) {
clear_weak_mods();
sel_word = false;
}
if (record->event.pressed) { // Handling of other macros (on press).
switch (keycode) {
/* case ALT_TAB:
return process_swapper(KC_TAB);
case REV_TAB:
return process_swapper(S(KC_TAB)); */
bool process_select_word(uint16_t keycode, keyrecord_t *record) {
case AIDE_MEM:
switch(get_highest_layer(layer_state|default_layer_state)) {
case _BASE:
tap_code(KC_F13);
return false;
/* case _SYMBOLS:
tap_code(KC_F14); */
return false;
case _SHORTNAV:
tap_code(KC_F15);
return false;
/* case _FUNCAPPS:
tap_code(KC_F16);
return false; */
}
case RAZ:
//led_t led_usb_state = host_keyboard_led_state();
if (is_caps_lock_on()) { tap_code(KC_CAPS); }
if (!host_keyboard_led_state().num_lock) { tap_code(KC_NUM_LOCK); }
layer_clear();
clear_oneshot_mods();
//clear_weak_mods();
caps_word_off();
disable_num_word();
clear_recent_keys();
break;
case TG_APOS:
is_apos_dr = !is_apos_dr;
return false;
case PG_DEG:
tap_code(PG_ODK);
tap_code(KC_9);
return false;
switch (keycode) {
case SEL_WORD:
if (record->event.pressed) { // Handling of other macros (on press).
if (!sel_word) {
tap_code16(C(KC_RIGHT));
tap_code16(C(KC_LEFT));
tap_code16(RCS(KC_RIGHT));
sel_word = true;
} else {
end_select_word();
}
}
}
return true; // Process all other keycodes normally
return false;
case SEL_LINE:
if (record->event.pressed) { // Handling of other macros (on press).
if (!sel_word) {
tap_code(KC_HOME);
tap_code16(S(KC_END));
sel_word = true;
} else {
end_select_word();
}
}
return false;
}
if (!sel_word) { return true;}
switch (keycode) {
case KC_LEFT:
case KC_RIGHT:
if (record->event.pressed) {
set_weak_mods(MOD_BIT_LCTRL);
}
case KC_DOWN:
case KC_UP:
if (record->event.pressed) {
add_weak_mods(MOD_BIT_LSHIFT);
} else {
clear_weak_mods();
}
return true;
}
end_select_word();
return true; // Process all other keycodes normally
}

View file

@ -23,8 +23,10 @@
extern "C" {
#endif
bool replace_apos(void);
bool process_macros(uint16_t keycode, keyrecord_t *record);
bool is_select_word(void);
void end_select_word(void);
bool process_select_word(uint16_t keycode, keyrecord_t *record);
#ifdef __cplusplus
}

View file

@ -5,7 +5,7 @@ oneshot_state os_ctrl_state = os_idle;
oneshot_state os_alt_state = os_idle;
oneshot_state os_win_state = os_idle;
bool process_oneshot(uint16_t keycode, keyrecord_t *record){
/* bool process_oneshot(uint16_t keycode, keyrecord_t *record){
uint8_t mods = one_shot_get_mod(keycode);
@ -103,7 +103,7 @@ void process_mods(uint16_t keycode, keyrecord_t *record, uint8_t mod, oneshot_st
}
}
}
}
} */
bool process_oneshot_old(uint16_t keycode, keyrecord_t *record){
// Handling Callum's OSM on OS4A layers
@ -112,24 +112,26 @@ bool process_oneshot_old(uint16_t keycode, keyrecord_t *record){
if (!update_oneshot(&os_alt_state, KC_LALT, OS_LALT, keycode, record)) { return false; }
if (!update_oneshot(&os_win_state, KC_LWIN, OS_WIN, keycode, record)) { return false; }
return true;
/* 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); */
/* update_oneshot_old(&os_shft_state, KC_LSFT, OS_SHFT, keycode, record);
update_oneshot_old(&os_ctrl_state, KC_LCTL, OS_CTRL, keycode, record);
update_oneshot_old(&os_alt_state, KC_LALT, OS_LALT, keycode, record);
update_oneshot_old(&os_win_state, KC_LWIN, OS_WIN, keycode, record); */
}
bool update_oneshot(oneshot_state *state, uint16_t mod, uint16_t trigger, uint16_t keycode, keyrecord_t *record) {
//const uint8_t mods = get_mods();
if (keycode == trigger) {
if (record->event.pressed) {
// Trigger keydown
if (*state == os_idle) {
register_code(mod);
*state = os_down_unused;
} else {
*state = os_idle;
unregister_code(mod);
}
*state = os_down_unused;
} else {
// Trigger keyup
switch (*state) {
@ -147,46 +149,124 @@ bool update_oneshot(oneshot_state *state, uint16_t mod, uint16_t trigger, uint16
}
}
return false;
}
} else if (*state != os_idle) {
if (*state == os_idle) { return true; }
if (is_oneshot_cancel_key(keycode)) {
if (record->event.pressed) {// && *state != os_idle) {
// Cancel oneshot on designated cancel keydown.
*state = os_idle;
unregister_code(mod);
if (is_oneshot_cancel_key(keycode)) {
if (record->event.pressed) {// && *state != os_idle) {
// Cancel oneshot on designated cancel keydown.
*state = os_idle;
unregister_code(mod);
}
return true;
}
if (!is_oneshot_ignored_key(keycode)) {
// Regular key released / roll between two regular keys
if (*state == os_up_queued_used) {
*state = os_idle;
unregister_code(mod);
return true;
} else if (record->event.pressed) {
// Regular key pressed
if (*state == os_up_queued) {
*state = os_up_queued_used;
}
return true;
} else if (!is_oneshot_ignored_key(keycode)) {
// Regular key released / roll between two regular keys
if (*state == os_up_queued_used) {
*state = os_idle;
unregister_code(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_idle;
unregister_code(mod);
break;
default:
break;
}
} 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_idle;
unregister_code(mod);
break;
default:
break;
}
}
}
return true;
}
void update_oneshot_old(oneshot_state *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_idle) {
register_code(mod);
*state = os_down_unused;
} else {
*state = os_idle;
unregister_code(mod);
}
} 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_idle;
unregister_code(mod);
break;
default:
break;
}
}
//return false;
}
//if (*state == os_idle) { return true; }
if (is_oneshot_cancel_key(keycode)) {
if (record->event.pressed && *state != os_idle) {
// Cancel oneshot on designated cancel keydown.
*state = os_idle;
unregister_code(mod);
}
} else if (!is_oneshot_ignored_key(keycode)) {
// Regular key released / roll between two regular keys
if (*state == os_up_queued_used) {
*state = os_idle;
unregister_code(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_idle;
unregister_code(mod);
break;
default:
break;
}
}
}
//return true;
}

View file

@ -29,6 +29,7 @@ bool update_oneshot(
uint16_t keycode,
keyrecord_t *record
);
void update_oneshot_old(oneshot_state *state, uint16_t mod, uint16_t trigger, uint16_t keycode, keyrecord_t *record);
// To be implemented by the consumer. Defines keys to cancel oneshot mods.
bool is_oneshot_cancel_key(uint16_t keycode);

View file

@ -20,6 +20,15 @@
static uint8_t os4a_layer = 0;
static bool exit_os4a_layer = false;
static uint16_t idle_timer = 0;
void os4a_task(void) {
if (os4a_layer != 0 && timer_expired(timer_read(), idle_timer)) {
os4a_layer_off(os4a_layer);
clear_mods();
}
}
uint8_t get_os4a_layer(void) {
return (os4a_layer);
}
@ -27,6 +36,7 @@ uint8_t get_os4a_layer(void) {
void os4a_layer_on(uint8_t layer) {
layer_on(layer);
os4a_layer = layer;
idle_timer = timer_read() + OS4A_EXIT_TIMEOUT;
}
void os4a_layer_off(uint8_t layer) {
@ -51,7 +61,7 @@ bool process_os4a_keys(uint16_t keycode, keyrecord_t *record) {
os4a_tap(keycode);
return false;
}
// normal processing if held
// normal processing otherwise
return true;
}
@ -99,6 +109,7 @@ bool process_os4a(uint16_t keycode, keyrecord_t *record) {
// Behaviour of the OS4A layers
if (record->event.pressed) {
idle_timer = record->event.time + OS4A_EXIT_TIMEOUT;
if (!should_stay_os4a_layer(keycode)) {
if (should_add_shift(keycode, record)) { set_oneshot_mods(MOD_BIT(KC_LSFT)); }

View file

@ -24,6 +24,8 @@
extern "C" {
#endif
void os4a_task(void);
uint8_t get_os4a_layer(void);
void os4a_layer_off(uint8_t layer);

View file

@ -17,25 +17,6 @@
#include "tap_hold_utilities.h"
void tap_converter(uint16_t keycode, keyrecord_t *record) {
if (IS_OS4A_KEY(keycode)) {
// Instant OS4A processing
os4a_tap(keycode);
} else {
if (IS_QK_MOD_TAP(keycode) || IS_QK_LAYER_TAP(keycode)) {
// Tranform the record to send the tap event
record->keycode = tap_hold_extractor(keycode);
}
process_record(record);
}
// Send the base keycode key up event
record->event.pressed = false;
process_record(record);
}
// Returns true if `pos` on the left hand of the keyboard, false if right.
bool on_left_hand(keypos_t pos) {
#ifdef SPLIT_KEYBOARD
@ -58,7 +39,7 @@ __attribute__((weak)) bool forbidden_chord(uint16_t tap_hold_keycode, keyrecord_
}
bool process_tap_hold(uint16_t keycode, keyrecord_t *record) {
bool process_custom_tap_hold(uint16_t keycode, keyrecord_t *record) {
if (record->event.pressed) { // On press
tap_code16(keycode);
return false;

View file

@ -27,9 +27,7 @@ bool on_left_hand(keypos_t pos);
bool same_side_combination(const keyrecord_t* tap_hold_record, const keyrecord_t* other_record);
void tap_converter(uint16_t keycode, keyrecord_t *record);
bool process_tap_hold(uint16_t keycode, keyrecord_t *record);
bool process_custom_tap_hold(uint16_t keycode, keyrecord_t *record);
#ifdef __cplusplus
}

View file

@ -16,6 +16,12 @@
#include "features_conf.h"
static bool is_apos_dr = false;
bool replace_apos(void) {
return is_apos_dr;
}
bool is_caps_lock_on(void) { return host_keyboard_led_state().caps_lock; }
@ -31,7 +37,7 @@ uint16_t tap_hold_extractor(uint16_t keycode) {
}
}
bool process_custom_tap_hold(uint16_t keycode, keyrecord_t *record) {
/* bool process_custom_tap_hold(uint16_t keycode, keyrecord_t *record) {
if (record->tap.count) { // Handling of special tap-hold keys (on tap).
switch (keycode) {
@ -53,6 +59,50 @@ bool process_custom_tap_hold(uint16_t keycode, keyrecord_t *record) {
alt_repeat_key_invoke(&record->event);
return false;
}
} else if (!record->event.pressed) {
if (keycode == LT_MGC && is_select_word()) {
end_select_word();
}
}
return true; // Process all other keycodes normally
} */
bool process_macros(uint16_t keycode, keyrecord_t *record) {
if (record->tap.count) { // Handling of special tap-hold keys (on tap).
switch (keycode) {
case RCTL_T(FEN_B):
return process_custom_tap_hold(LWIN(KC_DOWN), record);
case SFT_T(COPY):
return process_custom_tap_hold(C(PG_C), record);
case LT_NBSPC:
return process_custom_tap_hold(NNB_SPC, record);
case LT_REPT:
repeat_key_invoke(&record->event);
return false;
case LT_MGC:
alt_repeat_key_invoke(&record->event);
return false;
}
}
if (record->event.pressed) { // Handling of other macros (on press).
switch (keycode) {
case TG_APOS:
is_apos_dr = !is_apos_dr;
return false;
case PG_DEG:
tap_code(PG_ODK);
tap_code(KC_9);
return false;
}
}
return true; // Process all other keycodes normally
}
@ -60,26 +110,52 @@ bool process_custom_tap_hold(uint16_t keycode, keyrecord_t *record) {
// Clever keys configuration
uint16_t get_ongoing_keycode_user(uint16_t keycode) {
uint16_t get_ongoing_keycode_user(uint16_t keycode, keyrecord_t* record) {
// Handles custom keycodes to be processed for Clever Keys
if (is_send_string_macro(keycode)) { return keycode; }
if (IS_LAYER_ON(_ODK)) {
switch (keycode) {
case PG_K:
case PG_B:
case KC_SPC: // When space is added by clever keys, for ex. in order to uppercase K after '?' for ex.
return keycode;
switch (get_highest_layer(layer_state|default_layer_state)) {
case PG_POIN:
return PG_3PTS;
case _ODK:
switch (keycode) {
case PG_K:
case PG_B:
case KC_SPC: // When space is added by clever keys, for ex. in order to uppercase K after '?' for ex.
return keycode;
case PG_POIN:
return PG_3PTS;
default:
clear_recent_keys();
return KC_NO;
}
case _SHORTNAV:
switch (keycode) {
case KC_SPC:
return keycode;
default:
clear_recent_keys();
return KC_NO;
}
}
if (keycode == PG_E) { return PG_E; } // because PG_E is not a basic keycode
/* if (!IS_KEYEVENT(record->event)) {
switch (keycode) {
case KC_BSPC:
break;
default:
clear_recent_keys();
return KC_NO;
}
}
} */
return KC_TRNS;
}
@ -134,22 +210,6 @@ bool is_oneshot_cancel_key(uint16_t keycode) {
}
}
/* uint8_t one_shot_get_mod(uint16_t keycode) {
switch (keycode) {
case OS_SHFT:
return KC_LSFT;
case OS_CTRL:
return KC_LCTL;
case OS_LALT:
return KC_LALT;
case OS_WIN:
return KC_LWIN;
default:
return KC_NO;
}
} */
bool is_oneshot_ignored_key(uint16_t keycode) {
const uint8_t mods = get_mods() | get_weak_mods() | get_oneshot_mods();
@ -164,8 +224,7 @@ bool is_oneshot_ignored_key(uint16_t keycode) {
// sous peine de ne pas pouvoir faire shift + typo + touche de l'autre côté
if (mods & ~MOD_BIT(KC_ALGR)) { return true; }
break;
//case L_OS4A:
//case R_OS4A:
case OS_SHFT:
case OS_CTRL:
case OS_LALT:

View file

@ -19,7 +19,10 @@
#include "quantum.h"
#include "keymap.h"
bool replace_apos(void);
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);
bool process_custom_tap_hold(uint16_t keycode, keyrecord_t *record);
bool process_macros(uint16_t keycode, keyrecord_t *record);

View file

@ -68,6 +68,7 @@ bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) {
void matrix_scan_user(void) {
recent_keys_task();
caps_word_task();
os4a_task();
}
@ -94,6 +95,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
// Callum Mods
//if (!process_oneshot(keycode, record)) { return false; }
if (!process_oneshot_old(keycode, record)) { return false; };
//process_oneshot_old(keycode, record);
// Multi One-Shot Mods
if (!process_os4a(keycode, record)) { return false; }
@ -102,7 +104,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
if (!process_numword(keycode, record)) { return false; }
// Custom tap-hold keys
if (!process_custom_tap_hold(keycode, record)) { return false; }
if (!process_select_word(keycode, record)) { return false; }
// Caps List
if (!process_caps_list(keycode, record)) { return false; }
@ -277,10 +279,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* `----------------------------------' `----------------------------------'
*/
[_SHORTNAV] = LAYOUT(
_______, _______, LWIN(KC_TAB), LWIN(PG_V), RCS(PG_V), KC_VOLU, KC_PGUP, C(KC_LEFT), KC_UP, C(KC_RGHT), _______, _______,
_______, C(PG_A), C(PG_X), C(PG_V), SFT_T(COPY), KC_VOLD, KC_PGDN, KC_LEFT, KC_DOWN, KC_RIGHT, KC_F2 , _______,
_______, KC_SPC, KC_SPC, KC_MUTE, C(PG_Z), C(PG_Y), _______, _______, _______, _______, _______, C(KC_PGUP), C(KC_PGDN), C(PG_W), _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______
_______, SEL_LINE, LWIN(KC_TAB), LWIN(PG_V), RCS(PG_V), KC_VOLU, KC_PGUP, C(KC_LEFT), KC_UP, C(KC_RGHT), _______, _______,
_______, C(PG_A), C(PG_X), C(PG_V), SFT_T(COPY), KC_VOLD, KC_PGDN, KC_LEFT, KC_DOWN, KC_RIGHT, KC_F2 , _______,
_______, SEL_WORD, KC_SPC, KC_MUTE, C(PG_Z), C(PG_Y), _______, _______, _______, _______, _______, C(KC_PGUP), C(KC_PGDN), C(PG_W), _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______
),
/*

View file

@ -51,7 +51,6 @@ enum custom_keycodes {
COPY,
AIDE_MEM,
OS4A,
RAZ,
CAPSWORD,
OU_GRV,
MAGIC,
@ -61,7 +60,9 @@ enum custom_keycodes {
OS_WIN,
CNL_ODK,
TG_APOS,
PG_DEG
PG_DEG,
SEL_WORD,
SEL_LINE
};
// Layer changers

View file

@ -130,7 +130,7 @@ bool should_exit_num_word(uint16_t keycode, const keyrecord_t *record) {
case PG_IND:
case PG_H:
case PG_2PTS:
case NNB_SPC:
//case NNB_SPC:
// Misc
case KC_BSPC:

View file

@ -83,7 +83,7 @@ void get_clever_keycode(uint16_t* ongoing_keycode, keyrecord_t* record) {
break;
case PG_P:
switch (*ongoing_keycode) {
switch (*ongoing_keycode) {
case PG_C:
// "pas"
return finish_word((uint16_t[]) {PG_A, PG_S}, 2, ongoing_keycode, record);
@ -97,6 +97,25 @@ void get_clever_keycode(uint16_t* ongoing_keycode, keyrecord_t* record) {
return finish_word((uint16_t[]) {PG_L, PG_U, PG_S}, 3, ongoing_keycode, record);
}
break;
case PG_M:
case PG_R:
case PG_A:
case PG_E:
case PG_EACU:
case PG_I:
case PG_O:
case PG_U:
case PG_Y:
switch (*ongoing_keycode) {
case PG_H:
update_bkspc_countdown(0);
return replace_ongoing_key(PG_B, ongoing_keycode, record);
case PG_B:
update_bkspc_countdown(0);
return replace_ongoing_key(PG_H, ongoing_keycode, record);
}
break;
}
@ -171,9 +190,9 @@ void get_clever_keycode(uint16_t* ongoing_keycode, keyrecord_t* record) {
// "beaucoup"
return finish_word((uint16_t[]) {PG_E, PG_A, PG_U, PG_C, PG_O, PG_U, PG_P}, 7, ongoing_keycode, record);
case PG_D:
/* case PG_D:
// "déjà"
return finish_word((uint16_t[]) {PG_EACU, PG_J, PG_ODK, PG_A}, 4, ongoing_keycode, record);
return finish_word((uint16_t[]) {PG_EACU, PG_J, PG_ODK, PG_A}, 4, ongoing_keycode, record); */
default:
// "à"
@ -185,10 +204,10 @@ void get_clever_keycode(uint16_t* ongoing_keycode, keyrecord_t* record) {
if (!is_letter(get_recent_keycode(-2))) {
switch (prev_keycode) {
case PG_P:
/* case PG_P:
// "p@" -> "problème"
layer_off(_ODK);
return finish_word((uint16_t[]) {PG_R, PG_O, PG_B, PG_L, PG_ODK, PG_E, PG_M, PG_E}, 8, ongoing_keycode, record);
return finish_word((uint16_t[]) {PG_R, PG_O, PG_B, PG_L, PG_ODK, PG_E, PG_M, PG_E}, 8, ongoing_keycode, record); */
case PG_A:
// "a@" -> "aujourd'hui"
@ -206,17 +225,20 @@ void get_clever_keycode(uint16_t* ongoing_keycode, keyrecord_t* record) {
}
break;
case PG_H:
/* case PG_H:
switch (prev_keycode) {
case PG_M:
case PG_R:
case PG_A:
case PG_E:
case PG_EACU:
case PG_I:
case PG_O:
case PG_U:
case PG_Y:
update_bkspc_countdown(0);
return replace_ongoing_key(PG_B, ongoing_keycode, record);
}
} */
/* if (prev_keycode == PG_M) {
// "mh" -> "mb"
update_bkspc_countdown(0);

View file

@ -62,8 +62,10 @@
//#define ONESHOT_TAP_TOGGLE 5 /* Tapping this number of times holds the key until tapped once again. */
//#define ONESHOT_TIMEOUT 5000 /* Time (in ms) before the one shot key is released */
// Recent keys
#define RECENT_KEYS_TIMEOUT 5000 // Timeout in milliseconds.
// Timeouts in milliseconds.
#define RECENT_KEYS_TIMEOUT 5000
#define CAPS_WORD_IDLE_TIMEOUT 5000
#define OS4A_EXIT_TIMEOUT 3000
//Faire de la place !

View file

@ -1,24 +1,33 @@
#include "capslist.h"
//static bool caps_word_active = false;
static bool caps_word_active = false;
static bool caps_list_active = false;
static signed char capslist_countdown = 1;
static unsigned char countdown_end = 6;
static uint16_t idle_timer = 0;
//bool is_caps_word_on(void) { return caps_word_active; }
void caps_word_task(void) {
if (caps_word_active && timer_expired(timer_read(), idle_timer)) {
caps_word_off();
}
}
bool is_caps_word_on(void) { return caps_word_active; }
bool is_caps_list_on(void) { return caps_list_active; }
/* void caps_word_on(void) {
void caps_word_on(void) {
if (caps_word_active) { return; }
clear_mods();
clear_oneshot_mods();
caps_word_active = true;
} */
void enable_caps_list(void) {
idle_timer = timer_read() + CAPS_WORD_IDLE_TIMEOUT;
caps_word_active = true;
}
void caps_list_on(void) {
if (is_caps_lock_on()) { tap_code(KC_CAPS); }
caps_word_on();
caps_list_active = true;
@ -26,31 +35,31 @@ void enable_caps_list(void) {
countdown_end = 6;
}
/* void caps_word_off(void) {
void caps_word_off(void) {
if (!caps_word_active) { return; }
unregister_weak_mods(MOD_BIT(KC_LSFT)); // Make sure weak shift is off.
caps_word_active = false;
} */
}
void disable_caps_list(void) {
void caps_list_off(void) {
caps_word_off();
caps_list_active = false;
}
/* void caps_word_toggle(void) {
void caps_word_toggle(void) {
if (caps_word_active) {
caps_word_off();
} else {
caps_word_on();
}
} */
}
void toggle_caps_list(void) {
void caps_list_toggle(void) {
if (caps_list_active) {
disable_caps_list();
caps_list_off();
} else {
enable_caps_list();
caps_list_on();
}
}
@ -67,14 +76,14 @@ bool word_check(uint16_t keycodes[], uint8_t num_keycodes, unsigned char new_cou
return true;
}
/* bool process_caps_word(uint16_t keycode, keyrecord_t* record) {
bool process_caps_word(uint16_t keycode, keyrecord_t* record) {
if (keycode == CAPSWORD) {
// I can't use CW_TOGG because QMK dosn't reach process_record_user when processing it.
if (record->event.pressed) {
// Deactivating Caps Lock and Caps List when Caps Word activates.
if (is_caps_lock_on()) { tap_code(KC_CAPS); }
if (is_caps_list_on()) { disable_caps_list(); }
if (is_caps_list_on()) { caps_list_off(); }
caps_word_toggle();
}
return false;
@ -82,7 +91,7 @@ bool word_check(uint16_t keycodes[], uint8_t num_keycodes, unsigned char new_cou
} else if (keycode == KC_CAPS) {
if (record->event.pressed) {
caps_word_off();
disable_caps_list();
caps_list_off();
}
return true;
}
@ -90,52 +99,65 @@ bool word_check(uint16_t keycodes[], uint8_t num_keycodes, unsigned char new_cou
if (!caps_word_active) { return true; }
// Caps word is active //
clear_weak_mods();
if (record->event.pressed) {
// No action on keyrelease
if (!record->event.pressed) { return true; }
// if (!IS_LAYER_ON(_ODK)) {
// keycode = get_recent_keycode(-1);
// } else {
switch (keycode) {
case QK_ONE_SHOT_LAYER ... QK_ONE_SHOT_LAYER_MAX:
return true;
case QK_MOD_TAP ... QK_MOD_TAP_MAX:
case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:
// Earlier return if this has not been considered tapped yet
if (record->tap.count == 0) { return true; }
keycode = tap_hold_extractor(keycode); // Get tapping keycode.
break;
}
//}
//clear_weak_mods();
if (caps_word_press_user(keycode)) { return true; }
const uint8_t mods = get_mods() | get_oneshot_mods();
if (mods & ~(MOD_MASK_SHIFT | MOD_BIT(KC_ALGR))) {
// Avoid interfering with ctrl, alt and gui.
caps_word_off();
} else { // On release
return true;
}
idle_timer = record->event.time + CAPS_WORD_IDLE_TIMEOUT;
if (was_keycode_replaced()) {
keycode = get_recent_keycode(-1);
} else {
switch (keycode) {
case QK_ONE_SHOT_LAYER ... QK_ONE_SHOT_LAYER_MAX:
return true;
case QK_MOD_TAP ... QK_MOD_TAP_MAX:
case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:
// Earlier return if this has not been considered tapped yet
if (record->tap.count == 0) { return true; }
keycode = tap_hold_extractor(keycode); // Get tapping keycode.
break;
}
}
//clear_weak_mods();
if (caps_word_press_user(keycode)) {
// Invert on shift
if (get_oneshot_mods() & MOD_MASK_SHIFT) {
set_weak_mods(get_weak_mods() ^ MOD_BIT(KC_LSFT));
del_oneshot_mods(MOD_MASK_SHIFT);
}
send_keyboard_report();
return true;
}
caps_word_off();
return true;
} */
}
bool process_caps_list(uint16_t keycode, keyrecord_t *record) {
// Handle the custom keycodes that go with this feature
if (keycode == CAPSLIST) {
if (record->event.pressed) {
if (is_caps_lock_on()) { tap_code(KC_CAPS); }
toggle_caps_list();
caps_list_toggle();
}
return false;
}
if (keycode == CAPSWORD) {
/* if (keycode == CAPSWORD) {
// I can't use CW_TOGG because QMK dosn't reach process_record_user when processing it.
if (record->event.pressed) {
// Deactivating Caps Lock and Caps List when Caps Word activates.
if (is_caps_lock_on()) { tap_code(KC_CAPS); }
if (is_caps_list_on()) { disable_caps_list(); }
if (is_caps_list_on()) { caps_list_off(); }
caps_word_toggle();
}
return false;
@ -143,10 +165,10 @@ bool process_caps_list(uint16_t keycode, keyrecord_t *record) {
} else if (keycode == KC_CAPS) {
if (record->event.pressed) {
caps_word_off();
disable_caps_list();
caps_list_off();
}
return true;
}
} */
// Other than the custom keycodes, nothing else in this feature will activate
@ -157,6 +179,13 @@ bool process_caps_list(uint16_t keycode, keyrecord_t *record) {
// If Caps Word is on, Caps List stays on as well.
if (is_caps_word_on()) { return true; }
const uint8_t mods = get_mods() | get_oneshot_mods();
if (mods & ~(MOD_MASK_SHIFT | MOD_BIT(KC_ALGR))) {
// Avoid interfering with ctrl, alt and gui.
caps_word_off();
return true;
}
// Get the base keycode of a mod or layer tap key
switch (keycode) {
case QK_ONE_SHOT_LAYER ... QK_ONE_SHOT_LAYER_MAX:
@ -178,6 +207,6 @@ bool process_caps_list(uint16_t keycode, keyrecord_t *record) {
}
if (capslist_countdown < countdown_end) { return true; }
}
disable_caps_list();
caps_list_off();
return true;
}

View file

@ -6,9 +6,9 @@
bool is_caps_list_on(void);
void enable_caps_list(void);
void disable_caps_list(void);
void toggle_caps_list(void);
void caps_list_on(void);
void caps_list_off(void);
void caps_list_toggle(void);
bool update_capslist_countdown(signed char i);
bool word_check(uint16_t keycodes[], uint8_t num_keycodes, unsigned char new_countdown_end);

View file

@ -28,6 +28,10 @@ uint16_t get_recent_keycode(signed char i) {
return recent[RECENT_SIZE + i];
}
bool was_keycode_replaced(void) {
return processingCK;
}
void update_bkspc_countdown(unsigned char i) {
bkspc_countdown = i;
}

View file

@ -29,11 +29,14 @@ extern "C" {
uint16_t deadline;
uint16_t get_recent_keycode(signed char);
bool was_keycode_replaced(void);
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);

View file

@ -17,43 +17,47 @@
#include "macros.h"
static bool is_apos_dr = false;
static bool sel_word = false;
bool replace_apos(void) {
return is_apos_dr;
return is_apos_dr;
}
bool is_select_word(void) {
return sel_word;
}
void end_select_word(void) {
clear_mods();
sel_word = false;
}
bool process_macros(uint16_t keycode, keyrecord_t *record) {
if (record->event.pressed) { // Handling of other macros (on press).
switch (keycode) {
/* case ALT_TAB:
return process_swapper(KC_TAB);
case REV_TAB:
return process_swapper(S(KC_TAB)); */
case AIDE_MEM:
switch(get_highest_layer(layer_state|default_layer_state)) {
case _BASE:
tap_code(KC_F13);
return false;
/* case _SYMBOLS:
tap_code(KC_F14); */
return false;
case _SHORTNAV:
tap_code(KC_F15);
return false;
/* case _FUNCAPPS:
tap_code(KC_F16);
return false; */
case SEL_WORD:
if (!sel_word) {
register_mods(MOD_BIT_LCTRL);
tap_code(KC_RIGHT);
tap_code(KC_LEFT);
register_mods(MOD_BIT_LSHIFT);
//tap_code(KC_LEFT);
tap_code(KC_RIGHT);
sel_word = true;
} else {
end_select_word();
}
return false;
case RAZ:
//led_t led_usb_state = host_keyboard_led_state();
if (is_caps_lock_on()) { tap_code(KC_CAPS); }
if (!host_keyboard_led_state().num_lock) { tap_code(KC_NUM_LOCK); }
layer_clear();
clear_oneshot_mods();
clear_mods();
//clear_oneshot_mods();
//clear_weak_mods();
caps_word_off();
disable_num_word();

View file

@ -24,6 +24,8 @@ extern "C" {
#endif
bool replace_apos(void);
bool is_select_word(void);
void end_select_word(void);
bool process_macros(uint16_t keycode, keyrecord_t *record);
#ifdef __cplusplus

View file

@ -62,8 +62,10 @@ bool process_numword(uint16_t keycode, const keyrecord_t *record) {
// in case of rolled keys as well (take the press of the 2nd one into account!)
if (exit_num_word) {
disable_num_word();
return true;
}
} else if (record->event.pressed) {
if (record->event.pressed) {
// Get the base keycode of a mod or layer tap key
switch (keycode) {

View file

@ -1,14 +1,137 @@
#include "oneshot.h"
void update_oneshot(oneshot_state *state, uint16_t mod, uint16_t trigger, uint16_t keycode, keyrecord_t *record) {
oneshot_state os_shft_state = os_idle;
oneshot_state os_ctrl_state = os_idle;
oneshot_state os_alt_state = os_idle;
oneshot_state os_win_state = os_idle;
/* bool process_oneshot(uint16_t keycode, keyrecord_t *record){
uint8_t mods = one_shot_get_mod(keycode);
switch (mods) {
case KC_LSFT:
return process_oneshot_keys(record, KC_LSFT, &os_shft_state);
case KC_LCTL:
return process_oneshot_keys(record, KC_LCTL, &os_ctrl_state);
case KC_LALT:
return process_oneshot_keys(record, KC_LALT, &os_alt_state);
case KC_LWIN:
return process_oneshot_keys(record, KC_LWIN, &os_win_state);
}
mods = get_mods();
if (mods & MOD_BIT(KC_LSFT)) {
process_mods(keycode, record, KC_LSFT, &os_shft_state);
}
if (mods & MOD_BIT(KC_LCTL)) {
process_mods(keycode, record, KC_LCTL, &os_ctrl_state);
}
if (mods & MOD_BIT(KC_LALT)) {
process_mods(keycode, record, KC_LALT, &os_alt_state);
}
if (mods & MOD_BIT(KC_LWIN)) {
process_mods(keycode, record, 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_idle) {
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_idle;
unregister_code(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_idle) {
// Cancel oneshot on designated cancel keydown.
*state = os_idle;
unregister_code(mod);
}
} else if (!is_oneshot_ignored_key(keycode)) {
// Regular key released / roll between two regular keys
if (*state == os_up_queued_used) {
*state = os_idle;
unregister_code(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_idle;
unregister_code(mod);
break;
default:
break;
}
}
}
} */
bool process_oneshot_old(uint16_t keycode, keyrecord_t *record){
// Handling Callum's OSM on OS4A layers
if (!update_oneshot(&os_shft_state, KC_LSFT, OS_SHFT, keycode, record)) { return false; }
if (!update_oneshot(&os_ctrl_state, KC_LCTL, OS_CTRL, keycode, record)) { return false; }
if (!update_oneshot(&os_alt_state, KC_LALT, OS_LALT, keycode, record)) { return false; }
if (!update_oneshot(&os_win_state, KC_LWIN, OS_WIN, keycode, record)) { return false; }
return true;
/* update_oneshot_old(&os_shft_state, KC_LSFT, OS_SHFT, keycode, record);
update_oneshot_old(&os_ctrl_state, KC_LCTL, OS_CTRL, keycode, record);
update_oneshot_old(&os_alt_state, KC_LALT, OS_LALT, keycode, record);
update_oneshot_old(&os_win_state, KC_LWIN, OS_WIN, keycode, record); */
}
bool update_oneshot(oneshot_state *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) {
if (*state == os_idle) {
register_code(mod);
*state = os_down_unused;
} else {
*state = os_idle;
unregister_code(mod);
}
*state = os_down_unused;
} else {
// Trigger keyup
switch (*state) {
@ -18,35 +141,132 @@ void update_oneshot(oneshot_state *state, uint16_t mod, uint16_t trigger, uint16
break;
case os_down_used:
// If we did use the mod while trigger was held, unregister it.
*state = os_up_unqueued;
*state = os_idle;
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);
return false;
}
if (*state == os_idle) { return true; }
if (is_oneshot_cancel_key(keycode)) {
if (record->event.pressed) {// && *state != os_idle) {
// Cancel oneshot on designated cancel keydown.
*state = os_idle;
unregister_code(mod);
}
return true;
}
if (!is_oneshot_ignored_key(keycode)) {
// Regular key released / roll between two regular keys
if (*state == os_up_queued_used) {
*state = os_idle;
unregister_code(mod);
return true;
} else if (record->event.pressed) {
// Regular key pressed
if (*state == os_up_queued) {
*state = os_up_queued_used;
}
return true;
} 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;
}
// 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_idle;
unregister_code(mod);
break;
default:
break;
}
}
}
return true;
}
void update_oneshot_old(oneshot_state *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_idle) {
register_code(mod);
*state = os_down_unused;
} else {
*state = os_idle;
unregister_code(mod);
}
} 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_idle;
unregister_code(mod);
break;
default:
break;
}
}
//return false;
}
//if (*state == os_idle) { return true; }
if (is_oneshot_cancel_key(keycode)) {
if (record->event.pressed && *state != os_idle) {
// Cancel oneshot on designated cancel keydown.
*state = os_idle;
unregister_code(mod);
}
} else if (!is_oneshot_ignored_key(keycode)) {
// Regular key released / roll between two regular keys
if (*state == os_up_queued_used) {
*state = os_idle;
unregister_code(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_idle;
unregister_code(mod);
break;
default:
break;
}
}
}
//return true;
}

View file

@ -1,25 +1,35 @@
#pragma once
#include QMK_KEYBOARD_H
#include "keymap.h"
// Represents the four states a oneshot key can be in
// Represents the five states a oneshot key can be in
typedef enum {
os_up_unqueued,
os_idle,
os_up_queued,
os_up_queued_used,
os_down_unused,
os_down_used,
} oneshot_state;
uint8_t one_shot_get_mod(uint16_t keycode);
bool 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.
void update_oneshot(
bool update_oneshot(
oneshot_state *state,
uint16_t mod,
uint16_t trigger,
uint16_t keycode,
keyrecord_t *record
);
void update_oneshot_old(oneshot_state *state, uint16_t mod, uint16_t trigger, uint16_t keycode, keyrecord_t *record);
// To be implemented by the consumer. Defines keys to cancel oneshot mods.
bool is_oneshot_cancel_key(uint16_t keycode);

View file

@ -17,15 +17,18 @@
#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_altgr_state = os_up_unqueued;
oneshot_state os_win_state = os_up_unqueued;
static uint8_t os4a_layer = 0;
static bool exit_os4a_layer = false;
static uint16_t idle_timer = 0;
void os4a_task(void) {
if (os4a_layer != 0 && timer_expired(timer_read(), idle_timer)) {
os4a_layer_off(os4a_layer);
clear_mods();
}
}
uint8_t get_os4a_layer(void) {
return (os4a_layer);
}
@ -33,6 +36,7 @@ uint8_t get_os4a_layer(void) {
void os4a_layer_on(uint8_t layer) {
layer_on(layer);
os4a_layer = layer;
idle_timer = timer_read() + OS4A_EXIT_TIMEOUT;
}
void os4a_layer_off(uint8_t layer) {
@ -57,16 +61,12 @@ bool process_os4a_keys(uint16_t keycode, keyrecord_t *record) {
os4a_tap(keycode);
return false;
}
// normal processing if held
// normal processing otherwise
return true;
}
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; }
@ -94,28 +94,25 @@ 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);
//update_oneshot(&os_altgr_state, KC_RALT, OS_RALT, 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); }
if (os4a_layer == 0) { return true; }
// Behaviour of the OS4A layers
// Exiting OS4A layers on keyrelease or on 2nd keypress of a roll
if (exit_os4a_layer) {
os4a_layer_off(os4a_layer);
return true;
}
} else if (record->event.pressed) {
// Behaviour of the OS4A layers
if (record->event.pressed) {
idle_timer = record->event.time + OS4A_EXIT_TIMEOUT;
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;
}
@ -126,7 +123,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); }
}

View file

@ -24,6 +24,8 @@
extern "C" {
#endif
void os4a_task(void);
uint8_t get_os4a_layer(void);
void os4a_layer_off(uint8_t layer);
@ -32,13 +34,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
}

View file

@ -53,6 +53,10 @@ bool process_custom_tap_hold(uint16_t keycode, keyrecord_t *record) {
alt_repeat_key_invoke(&record->event);
return false;
}
} else if (!record->event.pressed) {
if (keycode == LT_MGC && is_select_word()) {
end_select_word();
}
}
return true; // Process all other keycodes normally
}
@ -99,7 +103,6 @@ bool should_stay_os4a_layer(uint16_t keycode) {
switch (keycode) {
case OS_SHFT:
case OS_CTRL:
case OS_RALT:
case OS_LALT:
case OS_WIN:
return true;
@ -135,6 +138,22 @@ bool is_oneshot_cancel_key(uint16_t keycode) {
}
}
/* uint8_t one_shot_get_mod(uint16_t keycode) {
switch (keycode) {
case OS_SHFT:
return KC_LSFT;
case OS_CTRL:
return KC_LCTL;
case OS_LALT:
return KC_LALT;
case OS_WIN:
return KC_LWIN;
default:
return KC_NO;
}
} */
bool is_oneshot_ignored_key(uint16_t keycode) {
const uint8_t mods = get_mods() | get_weak_mods() | get_oneshot_mods();
@ -149,11 +168,10 @@ bool is_oneshot_ignored_key(uint16_t keycode) {
// sous peine de ne pas pouvoir faire shift + typo + touche de l'autre côté
if (mods & ~MOD_BIT(KC_ALGR)) { return true; }
break;
case L_OS4A:
case R_OS4A:
//case L_OS4A:
//case R_OS4A:
case OS_SHFT:
case OS_CTRL:
case OS_RALT:
case OS_LALT:
case OS_WIN:
case OS_FA: // to be combined with Alt

View file

@ -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);
bool process_custom_tap_hold(uint16_t keycode, keyrecord_t *record);

View file

@ -67,6 +67,8 @@ bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) {
void matrix_scan_user(void) {
recent_keys_task();
caps_word_task();
os4a_task();
}
@ -90,8 +92,13 @@ 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; }
if (!process_oneshot_old(keycode, record)) { return false; };
//process_oneshot_old(keycode, record);
// 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; }
@ -111,7 +118,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
// Clever keys
if (!process_clever_keys(keycode, record)) { return false; }
//if (!process_caps_word(keycode, record)) {return false; }
if (!process_caps_word(keycode, record)) {return false; }
// Process all other keycodes normally
return true;
@ -272,10 +279,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* `----------------------------------' `----------------------------------'
*/
[_SHORTNAV] = LAYOUT(
_______, _______, LWIN(KC_TAB), LWIN(PG_V), RCS(PG_V), KC_VOLU, KC_PGUP, C(KC_LEFT), KC_UP, C(KC_RGHT), _______, _______,
_______, C(PG_A), C(PG_X), C(PG_V), SFT_T(COPY), KC_VOLD, KC_PGDN, KC_LEFT, KC_DOWN, KC_RIGHT, KC_F2 , _______,
_______, KC_SPC, KC_SPC, KC_MUTE, C(PG_Z), C(PG_Y), _______, _______, _______, _______, _______, C(KC_PGUP), C(KC_PGDN), C(PG_W), _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______
_______, KC_SPC, LWIN(KC_TAB), LWIN(PG_V), RCS(PG_V), KC_VOLU, KC_PGUP, C(KC_LEFT), KC_UP, C(KC_RGHT), _______, _______,
_______, C(PG_A), C(PG_X), C(PG_V), SFT_T(COPY), KC_VOLD, KC_PGDN, KC_LEFT, KC_DOWN, KC_RIGHT, KC_F2 , _______,
_______, SEL_WORD, KC_SPC, KC_MUTE, C(PG_Z), C(PG_Y), _______, _______, _______, _______, _______, C(KC_PGUP), C(KC_PGDN), C(PG_W), _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______
),
/*

View file

@ -57,12 +57,12 @@ enum custom_keycodes {
MAGIC,
OS_SHFT,
OS_CTRL,
OS_RALT,
OS_LALT,
OS_WIN,
CNL_ODK,
TG_APOS,
PG_DEG
PG_DEG,
SEL_WORD
};
// Layer changers

View file

@ -20,7 +20,7 @@ ENCODER_MAP_ENABLE = no
TAP_DANCE_ENABLE = no
DEFERRED_EXEC_ENABLE = no
KEY_OVERRIDE_ENABLE = no
CAPS_WORD_ENABLE = yes
CAPS_WORD_ENABLE = no
COMBO_ENABLE = yes
REPEAT_KEY_ENABLE = yes