f5cecffab2
It so happens that when releasing the control key prior to the main key (C-h, C-i, C-n, ...), the substituted keycode was continuously sent in a loop after that (even when releasing said key). The workaround so far was to type any other key to stop the loop. This commit fixes such behavior by resetting the substitution keycode sent when the ctrl released situation conditional is detected (and that the substitution keycode was on).
138 lines
5.7 KiB
C
138 lines
5.7 KiB
C
// Copyright (C) 2019, 2020 Keyboard.io, Inc
|
|
// 2021 Antoine R. Dumont (@ardumont) <antoine.romain.dumont@gmail.com>
|
|
//
|
|
// this is the style you want to emulate.
|
|
// This is the canonical layout file for the Quantum project. If you want to add another keyboard,
|
|
|
|
#include QMK_KEYBOARD_H
|
|
|
|
// Each layer gets a name for readability, which is then used in the keymap matrix below.
|
|
// The underscores don't mean anything - you can have a layer called STUFF or any other name.
|
|
// Layer names don't all need to be of the same length, obviously, and you can also skip them
|
|
// entirely and just use numbers.
|
|
enum layer_names {
|
|
_QW,
|
|
_RS,
|
|
_LW,
|
|
};
|
|
|
|
// tap: z // hold: SHIFT
|
|
#define Z_SFT SFT_T(KC_Z)
|
|
// tap: / // hold: SHIFT
|
|
#define SLSH_SFT SFT_T(KC_SLSH)
|
|
|
|
// tap: ` // hold: SHIFT
|
|
#define GRAVE_SFT SFT_T(KC_GRAVE)
|
|
// tap: [ // hold: SHIFT
|
|
#define RBRC_SFT SFT_T(KC_RBRC)
|
|
|
|
// Layer movment
|
|
#define FN0 MO(_RS) // move to layer 1 (L1)
|
|
#define FN1 TG(_LW) // move to layer 2 (L2)
|
|
#define FN2 TO(_QW) // move to layer 0 (L0)
|
|
|
|
/*
|
|
* q w e r t || y u i/tab o p
|
|
* a s d f g || h j k l ;
|
|
* z/sft x c v b ` || \ n m , . //sft
|
|
* ctl esc super alt L1 spc || spc L1 alt - ' ctl
|
|
*/
|
|
|
|
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
|
[_QW] = LAYOUT( /* Qwerty */
|
|
KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P ,
|
|
KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN ,
|
|
Z_SFT, KC_X, KC_C, KC_V, KC_B, KC_GRAVE, KC_BSLS, KC_N, KC_M, KC_COMM, KC_DOT, SLSH_SFT,
|
|
KC_LCTRL, KC_ESC, KC_LGUI, KC_LALT, KC_SPC, FN0, FN0, KC_SPC, KC_LALT, KC_MINS, KC_QUOT, KC_LCTRL
|
|
),
|
|
|
|
/*
|
|
* 1 2 3 4 5 || 6 7 8 9 0
|
|
* ! @ # $ % || ^ & * ( )
|
|
* `/sft ~ ? ? ? ~ || | + - / [ ]/sft
|
|
* ctl esc super alt spc L2 || L2 spc alt = esc ctl
|
|
*/
|
|
[_RS] = LAYOUT( /* [> RAISE <] */
|
|
KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0 ,
|
|
KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN ,
|
|
GRAVE_SFT, KC_TILD, KC_NO, KC_NO, KC_NO, _______, _______, KC_PLUS, KC_MINS, KC_SLSH, KC_LBRC, RBRC_SFT,
|
|
_______, _______, _______, _______, _______, FN1, FN1, _______, _______, KC_EQL, _______, _______
|
|
),
|
|
|
|
/*
|
|
* F1 F2 F3 F4 F5 || F6 F7 F8 F9 F10
|
|
* __ __ __ __ F11 || F12 __ __ __ __
|
|
* __ __ __ dbg rst eep-rst || __ __ __ __ __ __
|
|
* ctl esc super alt __ L0 || L0 __ alt __ esc ctl
|
|
*/
|
|
[_LW] = LAYOUT( /* [> LOWER <] */
|
|
KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10,
|
|
KC_NO, KC_NO, KC_NO, KC_NO, KC_F11, KC_F12, KC_NO, KC_NO, KC_NO, KC_NO ,
|
|
KC_NO, KC_NO, KC_NO, DEBUG, RESET, EEP_RST, _______, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO ,
|
|
_______, _______, _______, _______, _______, FN2, FN2, _______, _______, KC_NO, KC_ESC, _______
|
|
)
|
|
};
|
|
|
|
// Initialize variable holding the binary
|
|
// representation of active modifiers.
|
|
uint8_t mod_state;
|
|
|
|
bool substitute_keycode(uint16_t keycode, keyrecord_t *record, uint8_t mod_state, uint16_t substitute_keycode) {
|
|
/* Substitute keycode if condition matches */
|
|
// Initialize a boolean variable that keeps track
|
|
// of the delete key status: registered or not?
|
|
static bool key_registered;
|
|
// ctrl activated?
|
|
if ((mod_state & MOD_BIT(KC_LCTRL)) == MOD_BIT(KC_LCTRL)) {
|
|
if (record->event.pressed) {
|
|
// No need to register KC_LCTRL because it's already active.
|
|
unregister_code(KC_LCTRL);
|
|
// Send substitute code
|
|
register_code(substitute_keycode);
|
|
// Update the boolean variable to reflect the status of the register
|
|
key_registered = true;
|
|
// Reapplying modifier state so that the held shift key(s)
|
|
// still work even after having tapped the Backspace/Delete key.
|
|
set_mods(mod_state);
|
|
// Do not let QMK process the keycode further
|
|
return false;
|
|
} else {
|
|
// In case substitude_keycode is still even after release of the key
|
|
if (key_registered) {
|
|
unregister_code(substitute_keycode);
|
|
key_registered = false;
|
|
// Do not let QMK process the keycode further
|
|
return false;
|
|
}
|
|
}
|
|
} else { // ctrl got released
|
|
// In case substitude_keycode is still sent after release of the ctrl key
|
|
if (key_registered) {
|
|
unregister_code(substitute_keycode);
|
|
key_registered = false;
|
|
}
|
|
}
|
|
// Else, let QMK process the keycode as usual
|
|
return true;
|
|
}
|
|
|
|
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
|
// Store the current modifier state in the variable for later reference
|
|
mod_state = get_mods();
|
|
switch (keycode) {
|
|
case KC_I:
|
|
return substitute_keycode(keycode, record, mod_state, KC_TAB);
|
|
case KC_M:
|
|
return substitute_keycode(keycode, record, mod_state, KC_ENTER);
|
|
case KC_H:
|
|
return substitute_keycode(keycode, record, mod_state, KC_BSPC);
|
|
case KC_D:
|
|
return substitute_keycode(keycode, record, mod_state, KC_DEL);
|
|
case KC_N:
|
|
return substitute_keycode(keycode, record, mod_state, KC_DOWN);
|
|
case KC_P:
|
|
return substitute_keycode(keycode, record, mod_state, KC_UP);
|
|
}
|
|
return true;
|
|
};
|