Merge commit '6d0a62920410f50d7f6707960ca1ca0c8fd1d1fa' into firmware21
This commit is contained in:
@@ -18,14 +18,33 @@
|
||||
|
||||
# include <stdbool.h>
|
||||
# include <stdio.h>
|
||||
|
||||
# include "process_auto_shift.h"
|
||||
|
||||
static uint16_t autoshift_time = 0;
|
||||
static uint16_t autoshift_timeout = AUTO_SHIFT_TIMEOUT;
|
||||
static uint16_t autoshift_lastkey = KC_NO;
|
||||
# ifndef AUTO_SHIFT_DISABLED_AT_STARTUP
|
||||
# define AUTO_SHIFT_STARTUP_STATE true /* enabled */
|
||||
# else
|
||||
# define AUTO_SHIFT_STARTUP_STATE false /* disabled */
|
||||
# endif
|
||||
|
||||
// Stores the last Auto Shift key's up or down time, for evaluation or keyrepeat.
|
||||
static uint16_t autoshift_time = 0;
|
||||
# if defined(RETRO_SHIFT) && !defined(NO_ACTION_TAPPING)
|
||||
// Stores the last key's up or down time, to replace autoshift_time so that Tap Hold times are accurate.
|
||||
static uint16_t retroshift_time = 0;
|
||||
// Stores a possibly Retro Shift key's up or down time, as retroshift_time needs
|
||||
// to be set before the Retro Shift key is evaluated if it is interrupted by an
|
||||
// Auto Shifted key.
|
||||
static uint16_t last_retroshift_time;
|
||||
# endif
|
||||
static uint16_t autoshift_timeout = AUTO_SHIFT_TIMEOUT;
|
||||
static uint16_t autoshift_lastkey = KC_NO;
|
||||
static keyrecord_t autoshift_lastrecord;
|
||||
// Keys take 8 bits if modifiers are excluded. This records the shift state
|
||||
// when pressed for each key, so that can be passed to the release function
|
||||
// and it knows which key needs to be released (if shifted is different base).
|
||||
static uint16_t autoshift_shift_states[((1 << 8) + 15) / 16];
|
||||
static struct {
|
||||
// Whether autoshift is enabled.
|
||||
// Whether Auto Shift is enabled.
|
||||
bool enabled : 1;
|
||||
// Whether the last auto-shifted key was released after the timeout. This
|
||||
// is used to replicate the last key for a tap-then-hold.
|
||||
@@ -34,43 +53,157 @@ static struct {
|
||||
bool in_progress : 1;
|
||||
// Whether the auto-shifted keypress has been registered.
|
||||
bool holding_shift : 1;
|
||||
} autoshift_flags = {true, false, false, false};
|
||||
// Whether the user is holding a shift and we removed it.
|
||||
bool cancelling_lshift : 1;
|
||||
bool cancelling_rshift : 1;
|
||||
// clang-format wants to remove the true for some reason.
|
||||
// clang-format off
|
||||
} autoshift_flags = {AUTO_SHIFT_STARTUP_STATE, false, false, false, false, false};
|
||||
// clang-format on
|
||||
|
||||
/** \brief Called on physical press, returns whether key should be added to Auto Shift */
|
||||
__attribute__((weak)) bool get_custom_auto_shifted_key(uint16_t keycode, keyrecord_t *record) { return false; }
|
||||
|
||||
/** \brief Called on physical press, returns whether is Auto Shift key */
|
||||
__attribute__((weak)) bool get_auto_shifted_key(uint16_t keycode, keyrecord_t *record) {
|
||||
switch (keycode) {
|
||||
# ifndef NO_AUTO_SHIFT_ALPHA
|
||||
case AUTO_SHIFT_ALPHA:
|
||||
# endif
|
||||
# ifndef NO_AUTO_SHIFT_NUMERIC
|
||||
case AUTO_SHIFT_NUMERIC:
|
||||
# endif
|
||||
# ifndef NO_AUTO_SHIFT_SPECIAL
|
||||
case AUTO_SHIFT_SPECIAL:
|
||||
# endif
|
||||
return true;
|
||||
}
|
||||
return get_custom_auto_shifted_key(keycode, record);
|
||||
}
|
||||
|
||||
/** \brief Called to check whether defines should apply if PER_KEY is set for it */
|
||||
__attribute__((weak)) bool get_auto_shift_repeat(uint16_t keycode, keyrecord_t *record) { return true; }
|
||||
__attribute__((weak)) bool get_auto_shift_no_auto_repeat(uint16_t keycode, keyrecord_t *record) { return true; }
|
||||
|
||||
/** \brief Called when an Auto Shift key needs to be pressed */
|
||||
__attribute__((weak)) void autoshift_press_user(uint16_t keycode, bool shifted, keyrecord_t *record) {
|
||||
if (shifted) {
|
||||
add_weak_mods(MOD_BIT(KC_LSFT));
|
||||
}
|
||||
register_code16((IS_RETRO(keycode)) ? keycode & 0xFF : keycode);
|
||||
}
|
||||
|
||||
/** \brief Called when an Auto Shift key needs to be released */
|
||||
__attribute__((weak)) void autoshift_release_user(uint16_t keycode, bool shifted, keyrecord_t *record) { unregister_code16((IS_RETRO(keycode)) ? keycode & 0xFF : keycode); }
|
||||
|
||||
/** \brief Sets the shift state to use when keyrepeating, required by custom shifts */
|
||||
void set_autoshift_shift_state(uint16_t keycode, bool shifted) {
|
||||
keycode = keycode & 0xFF;
|
||||
if (shifted) {
|
||||
autoshift_shift_states[keycode / 16] |= (uint16_t)1 << keycode % 16;
|
||||
} else {
|
||||
autoshift_shift_states[keycode / 16] &= ~((uint16_t)1 << keycode % 16);
|
||||
}
|
||||
}
|
||||
|
||||
/** \brief Gets the shift state to use when keyrepeating, required by custom shifts */
|
||||
bool get_autoshift_shift_state(uint16_t keycode) {
|
||||
keycode = keycode & 0xFF;
|
||||
return (autoshift_shift_states[keycode / 16] & (uint16_t)1 << keycode % 16) != (uint16_t)0;
|
||||
}
|
||||
|
||||
/** \brief Restores the shift key if it was cancelled by Auto Shift */
|
||||
static void autoshift_flush_shift(void) {
|
||||
autoshift_flags.holding_shift = false;
|
||||
del_weak_mods(MOD_BIT(KC_LSFT));
|
||||
if (autoshift_flags.cancelling_lshift) {
|
||||
autoshift_flags.cancelling_lshift = false;
|
||||
add_mods(MOD_BIT(KC_LSFT));
|
||||
}
|
||||
if (autoshift_flags.cancelling_rshift) {
|
||||
autoshift_flags.cancelling_rshift = false;
|
||||
add_mods(MOD_BIT(KC_RSFT));
|
||||
}
|
||||
send_keyboard_report();
|
||||
}
|
||||
|
||||
/** \brief Record the press of an autoshiftable key
|
||||
*
|
||||
* \return Whether the record should be further processed.
|
||||
*/
|
||||
static bool autoshift_press(uint16_t keycode, uint16_t now, keyrecord_t *record) {
|
||||
if (!autoshift_flags.enabled) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
if ((get_mods()
|
||||
# if !defined(NO_ACTION_ONESHOT) && !defined(NO_ACTION_TAPPING)
|
||||
| get_oneshot_mods()
|
||||
# endif
|
||||
) & (~MOD_BIT(KC_LSFT))
|
||||
) {
|
||||
// clang-format on
|
||||
// Prevents keyrepeating unshifted value of key after using it in a key combo.
|
||||
autoshift_lastkey = KC_NO;
|
||||
# ifndef AUTO_SHIFT_MODIFIERS
|
||||
if (get_mods()) {
|
||||
return true;
|
||||
}
|
||||
// We can't return true here anymore because custom unshifted values are
|
||||
// possible and there's no good way to tell whether the press returned
|
||||
// true upon release.
|
||||
set_autoshift_shift_state(keycode, false);
|
||||
autoshift_press_user(keycode, false, record);
|
||||
# if !defined(NO_ACTION_ONESHOT) && !defined(NO_ACTION_TAPPING)
|
||||
set_oneshot_mods(get_oneshot_mods() & (~MOD_BIT(KC_LSFT)));
|
||||
clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
|
||||
# endif
|
||||
return false;
|
||||
# endif
|
||||
# ifdef AUTO_SHIFT_REPEAT
|
||||
const uint16_t elapsed = TIMER_DIFF_16(now, autoshift_time);
|
||||
# ifndef AUTO_SHIFT_NO_AUTO_REPEAT
|
||||
if (!autoshift_flags.lastshifted) {
|
||||
# endif
|
||||
if (elapsed < TAPPING_TERM && keycode == autoshift_lastkey) {
|
||||
// Allow a tap-then-hold for keyrepeat.
|
||||
if (!autoshift_flags.lastshifted) {
|
||||
register_code(autoshift_lastkey);
|
||||
} else {
|
||||
// Simulate pressing the shift key.
|
||||
add_weak_mods(MOD_BIT(KC_LSFT));
|
||||
register_code(autoshift_lastkey);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
# ifndef AUTO_SHIFT_NO_AUTO_REPEAT
|
||||
}
|
||||
|
||||
// Store record to be sent to user functions if there's no release record then.
|
||||
autoshift_lastrecord = *record;
|
||||
autoshift_lastrecord.event.pressed = false;
|
||||
autoshift_lastrecord.event.time = 0;
|
||||
// clang-format off
|
||||
# if defined(AUTO_SHIFT_REPEAT) || defined(AUTO_SHIFT_REPEAT_PER_KEY)
|
||||
if (keycode == autoshift_lastkey &&
|
||||
# ifdef AUTO_SHIFT_REPEAT_PER_KEY
|
||||
get_auto_shift_repeat(autoshift_lastkey, record) &&
|
||||
# endif
|
||||
# if !defined(AUTO_SHIFT_NO_AUTO_REPEAT) || defined(AUTO_SHIFT_NO_AUTO_REPEAT_PER_KEY)
|
||||
(
|
||||
!autoshift_flags.lastshifted
|
||||
# ifdef AUTO_SHIFT_NO_AUTO_REPEAT_PER_KEY
|
||||
|| get_auto_shift_no_auto_repeat(autoshift_lastkey, record)
|
||||
# endif
|
||||
) &&
|
||||
# endif
|
||||
TIMER_DIFF_16(now, autoshift_time) <
|
||||
# ifdef TAPPING_TERM_PER_KEY
|
||||
get_tapping_term(autoshift_lastkey, record)
|
||||
# else
|
||||
TAPPING_TERM
|
||||
# endif
|
||||
) {
|
||||
// clang-format on
|
||||
// Allow a tap-then-hold for keyrepeat.
|
||||
if (get_mods() & MOD_BIT(KC_LSFT)) {
|
||||
autoshift_flags.cancelling_lshift = true;
|
||||
del_mods(MOD_BIT(KC_LSFT));
|
||||
}
|
||||
if (get_mods() & MOD_BIT(KC_RSFT)) {
|
||||
autoshift_flags.cancelling_rshift = true;
|
||||
del_mods(MOD_BIT(KC_RSFT));
|
||||
}
|
||||
// autoshift_shift_state doesn't need to be changed.
|
||||
autoshift_press_user(autoshift_lastkey, autoshift_flags.lastshifted, record);
|
||||
return false;
|
||||
}
|
||||
# endif
|
||||
|
||||
// Use physical shift state of press event to be more like normal typing.
|
||||
# if !defined(NO_ACTION_ONESHOT) && !defined(NO_ACTION_TAPPING)
|
||||
autoshift_flags.lastshifted = (get_mods() | get_oneshot_mods()) & MOD_BIT(KC_LSFT);
|
||||
set_oneshot_mods(get_oneshot_mods() & (~MOD_BIT(KC_LSFT)));
|
||||
# else
|
||||
autoshift_flags.lastshifted = get_mods() & MOD_BIT(KC_LSFT);
|
||||
# endif
|
||||
// Record the keycode so we can simulate it later.
|
||||
autoshift_lastkey = keycode;
|
||||
autoshift_time = now;
|
||||
@@ -84,51 +217,70 @@ static bool autoshift_press(uint16_t keycode, uint16_t now, keyrecord_t *record)
|
||||
|
||||
/** \brief Registers an autoshiftable key under the right conditions
|
||||
*
|
||||
* If the autoshift delay has elapsed, register a shift and the key.
|
||||
* If autoshift_timeout has elapsed, register a shift and the key.
|
||||
*
|
||||
* If the autoshift key is released before the delay has elapsed, register the
|
||||
* If the Auto Shift key is released before the delay has elapsed, register the
|
||||
* key without a shift.
|
||||
*
|
||||
* Called on key down with keycode=KC_NO, auto-shifted key up, and timeout.
|
||||
*/
|
||||
static void autoshift_end(uint16_t keycode, uint16_t now, bool matrix_trigger) {
|
||||
// Called on key down with KC_NO, auto-shifted key up, and timeout.
|
||||
if (autoshift_flags.in_progress) {
|
||||
static void autoshift_end(uint16_t keycode, uint16_t now, bool matrix_trigger, keyrecord_t *record) {
|
||||
if (autoshift_flags.in_progress && (keycode == autoshift_lastkey || keycode == KC_NO)) {
|
||||
// Process the auto-shiftable key.
|
||||
autoshift_flags.in_progress = false;
|
||||
|
||||
// Time since the initial press was recorded.
|
||||
const uint16_t elapsed = TIMER_DIFF_16(now, autoshift_time);
|
||||
if (elapsed < autoshift_timeout) {
|
||||
register_code(autoshift_lastkey);
|
||||
autoshift_flags.lastshifted = false;
|
||||
} else {
|
||||
// Simulate pressing the shift key.
|
||||
add_weak_mods(MOD_BIT(KC_LSFT));
|
||||
register_code(autoshift_lastkey);
|
||||
autoshift_flags.lastshifted = true;
|
||||
# if defined(AUTO_SHIFT_REPEAT) && !defined(AUTO_SHIFT_NO_AUTO_REPEAT)
|
||||
if (matrix_trigger) {
|
||||
// Prevents release.
|
||||
return;
|
||||
}
|
||||
// clang-format off
|
||||
autoshift_flags.lastshifted =
|
||||
autoshift_flags.lastshifted
|
||||
|| TIMER_DIFF_16(now, autoshift_time) >=
|
||||
# ifdef AUTO_SHIFT_TIMEOUT_PER_KEY
|
||||
get_autoshift_timeout(autoshift_lastkey, record)
|
||||
# else
|
||||
autoshift_timeout
|
||||
# endif
|
||||
;
|
||||
// clang-format on
|
||||
set_autoshift_shift_state(autoshift_lastkey, autoshift_flags.lastshifted);
|
||||
if (get_mods() & MOD_BIT(KC_LSFT)) {
|
||||
autoshift_flags.cancelling_lshift = true;
|
||||
del_mods(MOD_BIT(KC_LSFT));
|
||||
}
|
||||
if (get_mods() & MOD_BIT(KC_RSFT)) {
|
||||
autoshift_flags.cancelling_rshift = true;
|
||||
del_mods(MOD_BIT(KC_RSFT));
|
||||
}
|
||||
autoshift_press_user(autoshift_lastkey, autoshift_flags.lastshifted, record);
|
||||
|
||||
// clang-format off
|
||||
# if (defined(AUTO_SHIFT_REPEAT) || defined(AUTO_SHIFT_REPEAT_PER_KEY)) && (!defined(AUTO_SHIFT_NO_AUTO_REPEAT) || defined(AUTO_SHIFT_NO_AUTO_REPEAT_PER_KEY))
|
||||
if (matrix_trigger
|
||||
# ifdef AUTO_SHIFT_REPEAT_PER_KEY
|
||||
&& get_auto_shift_repeat(autoshift_lastkey, record)
|
||||
# endif
|
||||
# ifdef AUTO_SHIFT_NO_AUTO_REPEAT_PER_KEY
|
||||
&& !get_auto_shift_no_auto_repeat(autoshift_lastkey, record)
|
||||
# endif
|
||||
) {
|
||||
// Prevents release.
|
||||
return;
|
||||
}
|
||||
# endif
|
||||
// clang-format on
|
||||
# if TAP_CODE_DELAY > 0
|
||||
wait_ms(TAP_CODE_DELAY);
|
||||
# endif
|
||||
unregister_code(autoshift_lastkey);
|
||||
del_weak_mods(MOD_BIT(KC_LSFT));
|
||||
|
||||
autoshift_release_user(autoshift_lastkey, autoshift_flags.lastshifted, record);
|
||||
autoshift_flush_shift();
|
||||
} else {
|
||||
// Release after keyrepeat.
|
||||
unregister_code(keycode);
|
||||
autoshift_release_user(keycode, get_autoshift_shift_state(keycode), record);
|
||||
if (keycode == autoshift_lastkey) {
|
||||
// This will only fire when the key was the last auto-shiftable
|
||||
// pressed. That prevents aaaaBBBB then releasing a from unshifting
|
||||
// later Bs (if B wasn't auto-shiftable).
|
||||
del_weak_mods(MOD_BIT(KC_LSFT));
|
||||
// pressed. That prevents 'aaaaBBBB' then releasing a from unshifting
|
||||
// later 'B's (if 'B' wasn't auto-shiftable).
|
||||
autoshift_flush_shift();
|
||||
}
|
||||
}
|
||||
send_keyboard_report(); // del_weak_mods doesn't send one.
|
||||
// Roll the autoshift_time forward for detecting tap-and-hold.
|
||||
autoshift_time = now;
|
||||
}
|
||||
@@ -141,24 +293,29 @@ static void autoshift_end(uint16_t keycode, uint16_t now, bool matrix_trigger) {
|
||||
*/
|
||||
void autoshift_matrix_scan(void) {
|
||||
if (autoshift_flags.in_progress) {
|
||||
const uint16_t now = timer_read();
|
||||
const uint16_t elapsed = TIMER_DIFF_16(now, autoshift_time);
|
||||
if (elapsed >= autoshift_timeout) {
|
||||
autoshift_end(autoshift_lastkey, now, true);
|
||||
const uint16_t now = timer_read();
|
||||
if (TIMER_DIFF_16(now, autoshift_time) >=
|
||||
# ifdef AUTO_SHIFT_TIMEOUT_PER_KEY
|
||||
get_autoshift_timeout(autoshift_lastkey, &autoshift_lastrecord)
|
||||
# else
|
||||
autoshift_timeout
|
||||
# endif
|
||||
) {
|
||||
autoshift_end(autoshift_lastkey, now, true, &autoshift_lastrecord);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void autoshift_toggle(void) {
|
||||
autoshift_flags.enabled = !autoshift_flags.enabled;
|
||||
del_weak_mods(MOD_BIT(KC_LSFT));
|
||||
autoshift_flush_shift();
|
||||
}
|
||||
|
||||
void autoshift_enable(void) { autoshift_flags.enabled = true; }
|
||||
|
||||
void autoshift_disable(void) {
|
||||
autoshift_flags.enabled = false;
|
||||
del_weak_mods(MOD_BIT(KC_LSFT));
|
||||
autoshift_flush_shift();
|
||||
}
|
||||
|
||||
# ifndef AUTO_SHIFT_NO_SETUP
|
||||
@@ -173,78 +330,158 @@ void autoshift_timer_report(void) {
|
||||
|
||||
bool get_autoshift_state(void) { return autoshift_flags.enabled; }
|
||||
|
||||
uint16_t get_autoshift_timeout(void) { return autoshift_timeout; }
|
||||
uint16_t get_generic_autoshift_timeout() { return autoshift_timeout; }
|
||||
__attribute__((weak)) uint16_t get_autoshift_timeout(uint16_t keycode, keyrecord_t *record) { return autoshift_timeout; }
|
||||
|
||||
void set_autoshift_timeout(uint16_t timeout) { autoshift_timeout = timeout; }
|
||||
|
||||
bool process_auto_shift(uint16_t keycode, keyrecord_t *record) {
|
||||
// Note that record->event.time isn't reliable, see:
|
||||
// https://github.com/qmk/qmk_firmware/pull/9826#issuecomment-733559550
|
||||
const uint16_t now = timer_read();
|
||||
// clang-format off
|
||||
const uint16_t now =
|
||||
# if !defined(RETRO_SHIFT) || defined(NO_ACTION_TAPPING)
|
||||
timer_read()
|
||||
# else
|
||||
(record->event.pressed) ? retroshift_time : timer_read()
|
||||
# endif
|
||||
;
|
||||
// clang-format on
|
||||
|
||||
if (record->event.pressed) {
|
||||
if (autoshift_flags.in_progress) {
|
||||
// Evaluate previous key if there is one. Doing this elsewhere is
|
||||
// more complicated and easier to break.
|
||||
autoshift_end(KC_NO, now, false);
|
||||
// Evaluate previous key if there is one.
|
||||
autoshift_end(KC_NO, now, false, &autoshift_lastrecord);
|
||||
}
|
||||
// For pressing another key while keyrepeating shifted autoshift.
|
||||
del_weak_mods(MOD_BIT(KC_LSFT));
|
||||
|
||||
switch (keycode) {
|
||||
case KC_ASTG:
|
||||
autoshift_toggle();
|
||||
return true;
|
||||
break;
|
||||
case KC_ASON:
|
||||
autoshift_enable();
|
||||
return true;
|
||||
break;
|
||||
case KC_ASOFF:
|
||||
autoshift_disable();
|
||||
return true;
|
||||
break;
|
||||
|
||||
# ifndef AUTO_SHIFT_NO_SETUP
|
||||
case KC_ASUP:
|
||||
autoshift_timeout += 5;
|
||||
return true;
|
||||
break;
|
||||
case KC_ASDN:
|
||||
autoshift_timeout -= 5;
|
||||
return true;
|
||||
|
||||
break;
|
||||
case KC_ASRP:
|
||||
autoshift_timer_report();
|
||||
return true;
|
||||
break;
|
||||
# endif
|
||||
}
|
||||
// If Retro Shift is disabled, possible custom actions shouldn't happen.
|
||||
// clang-format off
|
||||
if (IS_RETRO(keycode)
|
||||
# if defined(RETRO_SHIFT) && !defined(NO_ACTION_TAPPING)
|
||||
// Not tapped or #defines mean that rolls should use hold action.
|
||||
&& (
|
||||
record->tap.count == 0
|
||||
# ifdef RETRO_TAPPING_PER_KEY
|
||||
|| !get_retro_tapping(keycode, record)
|
||||
# endif
|
||||
|| (record->tap.interrupted && (IS_LT(keycode)
|
||||
# if defined(HOLD_ON_OTHER_KEY_PRESS) || defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY)
|
||||
# ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY
|
||||
? get_hold_on_other_key_press(keycode, record)
|
||||
# else
|
||||
? true
|
||||
# endif
|
||||
# else
|
||||
? false
|
||||
# endif
|
||||
# if defined(IGNORE_MOD_TAP_INTERRUPT) || defined(IGNORE_MOD_TAP_INTERRUPT_PER_KEY)
|
||||
# ifdef IGNORE_MOD_TAP_INTERRUPT_PER_KEY
|
||||
: !get_ignore_mod_tap_interrupt(keycode, record)
|
||||
# else
|
||||
: false
|
||||
# endif
|
||||
# else
|
||||
: true
|
||||
# endif
|
||||
))
|
||||
)
|
||||
# endif
|
||||
) {
|
||||
// clang-format on
|
||||
autoshift_lastkey = KC_NO;
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (keycode == KC_LSFT) {
|
||||
autoshift_flags.cancelling_lshift = false;
|
||||
} else if (keycode == KC_RSFT) {
|
||||
autoshift_flags.cancelling_rshift = false;
|
||||
}
|
||||
// Same as above (for pressed), additional checks are not needed because
|
||||
// tap.count gets set to 0 in process_action
|
||||
// clang-format off
|
||||
else if (IS_RETRO(keycode)
|
||||
# if defined(RETRO_SHIFT) && !defined(NO_ACTION_TAPPING)
|
||||
&& (
|
||||
record->tap.count == 0
|
||||
# ifdef RETRO_TAPPING_PER_KEY
|
||||
|| !get_retro_tapping(keycode, record)
|
||||
# endif
|
||||
)
|
||||
# endif
|
||||
) {
|
||||
// Fixes modifiers not being applied to rolls with AUTO_SHIFT_MODIFIERS set.
|
||||
# if !defined(IGNORE_MOD_TAP_INTERRUPT) || defined(IGNORE_MOD_TAP_INTERRUPT_PER_KEY)
|
||||
if (autoshift_flags.in_progress
|
||||
# ifdef IGNORE_MOD_TAP_INTERRUPT_PER_KEY
|
||||
&& !get_ignore_mod_tap_interrupt(keycode, record)
|
||||
# endif
|
||||
) {
|
||||
autoshift_end(KC_NO, now, false, &autoshift_lastrecord);
|
||||
}
|
||||
# endif
|
||||
// clang-format on
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!autoshift_flags.enabled) {
|
||||
return true;
|
||||
}
|
||||
if (get_auto_shifted_key(keycode, record)) {
|
||||
if (record->event.pressed) {
|
||||
return autoshift_press(keycode, now, record);
|
||||
} else {
|
||||
autoshift_end(keycode, now, false);
|
||||
autoshift_end(keycode, now, false, record);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Prevent keyrepeating of older keys upon non-AS key event.
|
||||
// Not commented at above returns but they serve the same function.
|
||||
if (record->event.pressed) {
|
||||
autoshift_lastkey = KC_NO;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
__attribute__((weak)) bool get_auto_shifted_key(uint16_t keycode, keyrecord_t *record) {
|
||||
switch (keycode) {
|
||||
# ifndef NO_AUTO_SHIFT_ALPHA
|
||||
case KC_A ... KC_Z:
|
||||
# endif
|
||||
# ifndef NO_AUTO_SHIFT_NUMERIC
|
||||
case KC_1 ... KC_0:
|
||||
# endif
|
||||
# ifndef NO_AUTO_SHIFT_SPECIAL
|
||||
# ifndef NO_AUTO_SHIFT_TAB
|
||||
case KC_TAB:
|
||||
# endif
|
||||
case KC_MINUS ... KC_SLASH:
|
||||
case KC_NONUS_BSLASH:
|
||||
# endif
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
# if defined(RETRO_SHIFT) && !defined(NO_ACTION_TAPPING)
|
||||
// Called to record time before possible delays by action_tapping_process.
|
||||
void retroshift_poll_time(keyevent_t *event) {
|
||||
last_retroshift_time = retroshift_time;
|
||||
retroshift_time = timer_read();
|
||||
}
|
||||
// Used to swap the times of Retro Shifted key and Auto Shift key that interrupted it.
|
||||
void retroshift_swap_times() {
|
||||
if (last_retroshift_time != 0 && autoshift_flags.in_progress) {
|
||||
uint16_t temp = retroshift_time;
|
||||
retroshift_time = last_retroshift_time;
|
||||
last_retroshift_time = temp;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -22,13 +22,31 @@
|
||||
# define AUTO_SHIFT_TIMEOUT 175
|
||||
#endif
|
||||
|
||||
#define IS_LT(kc) ((kc) >= QK_LAYER_TAP && (kc) <= QK_LAYER_TAP_MAX)
|
||||
#define IS_MT(kc) ((kc) >= QK_MOD_TAP && (kc) <= QK_MOD_TAP_MAX)
|
||||
#define IS_RETRO(kc) (IS_MT(kc) || IS_LT(kc))
|
||||
#define DO_GET_AUTOSHIFT_TIMEOUT(keycode, record, ...) record
|
||||
// clang-format off
|
||||
#define AUTO_SHIFT_ALPHA KC_A ... KC_Z
|
||||
#define AUTO_SHIFT_NUMERIC KC_1 ... KC_0
|
||||
#define AUTO_SHIFT_SPECIAL \
|
||||
KC_TAB: \
|
||||
case KC_MINUS ... KC_SLASH: \
|
||||
case KC_NONUS_BSLASH
|
||||
// clang-format on
|
||||
|
||||
bool process_auto_shift(uint16_t keycode, keyrecord_t *record);
|
||||
void retroshift_poll_time(keyevent_t *event);
|
||||
void retroshift_swap_times(void);
|
||||
|
||||
void autoshift_enable(void);
|
||||
void autoshift_disable(void);
|
||||
void autoshift_toggle(void);
|
||||
bool get_autoshift_state(void);
|
||||
uint16_t get_autoshift_timeout(void);
|
||||
uint16_t get_generic_autoshift_timeout(void);
|
||||
// clang-format off
|
||||
uint16_t (get_autoshift_timeout)(uint16_t keycode, keyrecord_t *record);
|
||||
void set_autoshift_timeout(uint16_t timeout);
|
||||
void autoshift_matrix_scan(void);
|
||||
bool get_auto_shifted_key(uint16_t keycode, keyrecord_t *record);
|
||||
bool get_custom_auto_shifted_key(uint16_t keycode, keyrecord_t *record);
|
||||
// clang-format on
|
||||
|
||||
@@ -18,10 +18,9 @@
|
||||
#include "process_combo.h"
|
||||
#include "action_tapping.h"
|
||||
|
||||
|
||||
#ifdef COMBO_COUNT
|
||||
__attribute__((weak)) combo_t key_combos[COMBO_COUNT];
|
||||
uint16_t COMBO_LEN = COMBO_COUNT;
|
||||
__attribute__((weak)) combo_t key_combos[COMBO_COUNT];
|
||||
uint16_t COMBO_LEN = COMBO_COUNT;
|
||||
#else
|
||||
extern combo_t key_combos[];
|
||||
extern uint16_t COMBO_LEN;
|
||||
@@ -46,64 +45,86 @@ __attribute__((weak)) bool process_combo_key_release(uint16_t combo_index, combo
|
||||
#endif
|
||||
|
||||
#ifndef COMBO_NO_TIMER
|
||||
static uint16_t timer = 0;
|
||||
static uint16_t timer = 0;
|
||||
#endif
|
||||
static bool b_combo_enable = true; // defaults to enabled
|
||||
static uint16_t longest_term = 0;
|
||||
static bool b_combo_enable = true; // defaults to enabled
|
||||
static uint16_t longest_term = 0;
|
||||
|
||||
typedef struct {
|
||||
keyrecord_t record;
|
||||
uint16_t combo_index;
|
||||
uint16_t keycode;
|
||||
uint16_t combo_index;
|
||||
uint16_t keycode;
|
||||
} queued_record_t;
|
||||
static uint8_t key_buffer_size = 0;
|
||||
static uint8_t key_buffer_size = 0;
|
||||
static queued_record_t key_buffer[COMBO_KEY_BUFFER_LENGTH];
|
||||
|
||||
typedef struct {
|
||||
uint16_t combo_index;
|
||||
} queued_combo_t;
|
||||
static uint8_t combo_buffer_write= 0;
|
||||
static uint8_t combo_buffer_read = 0;
|
||||
static uint8_t combo_buffer_write = 0;
|
||||
static uint8_t combo_buffer_read = 0;
|
||||
static queued_combo_t combo_buffer[COMBO_BUFFER_LENGTH];
|
||||
|
||||
#define INCREMENT_MOD(i) i = (i + 1) % COMBO_BUFFER_LENGTH
|
||||
|
||||
#define COMBO_KEY_POS ((keypos_t){.col=254, .row=254})
|
||||
|
||||
#define COMBO_KEY_POS ((keypos_t){.col = 254, .row = 254})
|
||||
|
||||
#ifndef EXTRA_SHORT_COMBOS
|
||||
/* flags are their own elements in combo_t struct. */
|
||||
# define COMBO_ACTIVE(combo) (combo->active)
|
||||
# define COMBO_ACTIVE(combo) (combo->active)
|
||||
# define COMBO_DISABLED(combo) (combo->disabled)
|
||||
# define COMBO_STATE(combo) (combo->state)
|
||||
# define COMBO_STATE(combo) (combo->state)
|
||||
|
||||
# define ACTIVATE_COMBO(combo) do {combo->active = true;}while(0)
|
||||
# define DEACTIVATE_COMBO(combo) do {combo->active = false;}while(0)
|
||||
# define DISABLE_COMBO(combo) do {combo->disabled = true;}while(0)
|
||||
# define RESET_COMBO_STATE(combo) do { \
|
||||
combo->disabled = false; \
|
||||
combo->state = 0; \
|
||||
}while(0)
|
||||
# define ACTIVATE_COMBO(combo) \
|
||||
do { \
|
||||
combo->active = true; \
|
||||
} while (0)
|
||||
# define DEACTIVATE_COMBO(combo) \
|
||||
do { \
|
||||
combo->active = false; \
|
||||
} while (0)
|
||||
# define DISABLE_COMBO(combo) \
|
||||
do { \
|
||||
combo->disabled = true; \
|
||||
} while (0)
|
||||
# define RESET_COMBO_STATE(combo) \
|
||||
do { \
|
||||
combo->disabled = false; \
|
||||
combo->state = 0; \
|
||||
} while (0)
|
||||
#else
|
||||
/* flags are at the two high bits of state. */
|
||||
# define COMBO_ACTIVE(combo) (combo->state & 0x80)
|
||||
# define COMBO_ACTIVE(combo) (combo->state & 0x80)
|
||||
# define COMBO_DISABLED(combo) (combo->state & 0x40)
|
||||
# define COMBO_STATE(combo) (combo->state & 0x3F)
|
||||
# define COMBO_STATE(combo) (combo->state & 0x3F)
|
||||
|
||||
# define ACTIVATE_COMBO(combo) do {combo->state |= 0x80;}while(0)
|
||||
# define DEACTIVATE_COMBO(combo) do {combo->state &= ~0x80;}while(0)
|
||||
# define DISABLE_COMBO(combo) do {combo->state |= 0x40;}while(0)
|
||||
# define RESET_COMBO_STATE(combo) do {combo->state &= ~0x7F;}while(0)
|
||||
# define ACTIVATE_COMBO(combo) \
|
||||
do { \
|
||||
combo->state |= 0x80; \
|
||||
} while (0)
|
||||
# define DEACTIVATE_COMBO(combo) \
|
||||
do { \
|
||||
combo->state &= ~0x80; \
|
||||
} while (0)
|
||||
# define DISABLE_COMBO(combo) \
|
||||
do { \
|
||||
combo->state |= 0x40; \
|
||||
} while (0)
|
||||
# define RESET_COMBO_STATE(combo) \
|
||||
do { \
|
||||
combo->state &= ~0x7F; \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
static inline void release_combo(uint16_t combo_index, combo_t *combo) {
|
||||
if (combo->keycode) {
|
||||
keyrecord_t record = {
|
||||
.event = {
|
||||
.key = COMBO_KEY_POS,
|
||||
.time = timer_read()|1,
|
||||
.pressed = false,
|
||||
},
|
||||
.event =
|
||||
{
|
||||
.key = COMBO_KEY_POS,
|
||||
.time = timer_read() | 1,
|
||||
.pressed = false,
|
||||
},
|
||||
.keycode = combo->keycode,
|
||||
};
|
||||
#ifndef NO_ACTION_TAPPING
|
||||
@@ -123,18 +144,17 @@ static inline bool _get_combo_must_hold(uint16_t combo_index, combo_t *combo) {
|
||||
#elif defined(COMBO_MUST_HOLD_PER_COMBO)
|
||||
return get_combo_must_hold(combo_index, combo);
|
||||
#elif defined(COMBO_MUST_HOLD_MODS)
|
||||
return (KEYCODE_IS_MOD(combo->keycode) ||
|
||||
(combo->keycode >= QK_MOMENTARY && combo->keycode <= QK_MOMENTARY_MAX));
|
||||
return (KEYCODE_IS_MOD(combo->keycode) || (combo->keycode >= QK_MOMENTARY && combo->keycode <= QK_MOMENTARY_MAX));
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline uint16_t _get_wait_time(uint16_t combo_index, combo_t *combo ) {
|
||||
static inline uint16_t _get_wait_time(uint16_t combo_index, combo_t *combo) {
|
||||
if (_get_combo_must_hold(combo_index, combo)
|
||||
#ifdef COMBO_MUST_TAP_PER_COMBO
|
||||
|| get_combo_must_tap(combo_index, combo)
|
||||
|| get_combo_must_tap(combo_index, combo)
|
||||
#endif
|
||||
) {
|
||||
) {
|
||||
if (longest_term < COMBO_HOLD_TERM) {
|
||||
return COMBO_HOLD_TERM;
|
||||
}
|
||||
@@ -144,9 +164,8 @@ static inline uint16_t _get_wait_time(uint16_t combo_index, combo_t *combo ) {
|
||||
}
|
||||
|
||||
static inline uint16_t _get_combo_term(uint16_t combo_index, combo_t *combo) {
|
||||
|
||||
#if defined(COMBO_TERM_PER_COMBO)
|
||||
return get_combo_term(combo_index, combo);
|
||||
return get_combo_term(combo_index, combo);
|
||||
#endif
|
||||
|
||||
return COMBO_TERM;
|
||||
@@ -154,7 +173,7 @@ static inline uint16_t _get_combo_term(uint16_t combo_index, combo_t *combo) {
|
||||
|
||||
void clear_combos(void) {
|
||||
uint16_t index = 0;
|
||||
longest_term = 0;
|
||||
longest_term = 0;
|
||||
for (index = 0; index < COMBO_LEN; ++index) {
|
||||
combo_t *combo = &key_combos[index];
|
||||
if (!COMBO_ACTIVE(combo)) {
|
||||
@@ -175,7 +194,7 @@ static inline void dump_key_buffer(void) {
|
||||
key_buffer_next = key_buffer_i + 1;
|
||||
|
||||
queued_record_t *qrecord = &key_buffer[key_buffer_i];
|
||||
keyrecord_t *record = &qrecord->record;
|
||||
keyrecord_t * record = &qrecord->record;
|
||||
|
||||
if (IS_NOEVENT(record->event)) {
|
||||
continue;
|
||||
@@ -185,9 +204,9 @@ static inline void dump_key_buffer(void) {
|
||||
process_combo_event(qrecord->combo_index, true);
|
||||
} else {
|
||||
#ifndef NO_ACTION_TAPPING
|
||||
action_tapping_process(*record);
|
||||
action_tapping_process(*record);
|
||||
#else
|
||||
process_record(record);
|
||||
process_record(record);
|
||||
#endif
|
||||
}
|
||||
record->event.time = 0;
|
||||
@@ -242,7 +261,9 @@ void apply_combo(uint16_t combo_index, combo_t *combo) {
|
||||
/* Apply combo's result keycode to the last chord key of the combo and
|
||||
* disable the other keys. */
|
||||
|
||||
if (COMBO_DISABLED(combo)) { return; }
|
||||
if (COMBO_DISABLED(combo)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// state to check against so we find the last key of the combo from the buffer
|
||||
#if defined(EXTRA_EXTRA_LONG_COMBOS)
|
||||
@@ -254,12 +275,11 @@ void apply_combo(uint16_t combo_index, combo_t *combo) {
|
||||
#endif
|
||||
|
||||
for (uint8_t key_buffer_i = 0; key_buffer_i < key_buffer_size; key_buffer_i++) {
|
||||
|
||||
queued_record_t *qrecord = &key_buffer[key_buffer_i];
|
||||
keyrecord_t *record = &qrecord->record;
|
||||
uint16_t keycode = qrecord->keycode;
|
||||
keyrecord_t * record = &qrecord->record;
|
||||
uint16_t keycode = qrecord->keycode;
|
||||
|
||||
uint8_t key_count = 0;
|
||||
uint8_t key_count = 0;
|
||||
uint16_t key_index = -1;
|
||||
_find_key_index_and_count(combo->keys, keycode, &key_index, &key_count);
|
||||
|
||||
@@ -271,7 +291,7 @@ void apply_combo(uint16_t combo_index, combo_t *combo) {
|
||||
KEY_STATE_DOWN(state, key_index);
|
||||
if (ALL_COMBO_KEYS_ARE_DOWN(state, key_count)) {
|
||||
// this in the end executes the combo when the key_buffer is dumped.
|
||||
record->keycode = combo->keycode;
|
||||
record->keycode = combo->keycode;
|
||||
record->event.key = COMBO_KEY_POS;
|
||||
|
||||
qrecord->combo_index = combo_index;
|
||||
@@ -283,19 +303,15 @@ void apply_combo(uint16_t combo_index, combo_t *combo) {
|
||||
// by making it a TICK event.
|
||||
record->event.time = 0;
|
||||
}
|
||||
|
||||
}
|
||||
drop_combo_from_buffer(combo_index);
|
||||
}
|
||||
|
||||
static inline void apply_combos(void) {
|
||||
// Apply all buffered normal combos.
|
||||
for (uint8_t i = combo_buffer_read;
|
||||
i != combo_buffer_write;
|
||||
INCREMENT_MOD(i)) {
|
||||
|
||||
for (uint8_t i = combo_buffer_read; i != combo_buffer_write; INCREMENT_MOD(i)) {
|
||||
queued_combo_t *buffered_combo = &combo_buffer[i];
|
||||
combo_t *combo = &key_combos[buffered_combo->combo_index];
|
||||
combo_t * combo = &key_combos[buffered_combo->combo_index];
|
||||
|
||||
#ifdef COMBO_MUST_TAP_PER_COMBO
|
||||
if (get_combo_must_tap(buffered_combo->combo_index, combo)) {
|
||||
@@ -310,15 +326,15 @@ static inline void apply_combos(void) {
|
||||
clear_combos();
|
||||
}
|
||||
|
||||
combo_t* overlaps(combo_t *combo1, combo_t *combo2) {
|
||||
combo_t *overlaps(combo_t *combo1, combo_t *combo2) {
|
||||
/* Checks if the combos overlap and returns the combo that should be
|
||||
* dropped from the combo buffer.
|
||||
* The combo that has less keys will be dropped. If they have the same
|
||||
* amount of keys, drop combo1. */
|
||||
|
||||
uint8_t idx1 = 0, idx2 = 0;
|
||||
uint8_t idx1 = 0, idx2 = 0;
|
||||
uint16_t key1, key2;
|
||||
bool overlaps = false;
|
||||
bool overlaps = false;
|
||||
|
||||
while ((key1 = pgm_read_word(&combo1->keys[idx1])) != COMBO_END) {
|
||||
idx2 = 0;
|
||||
@@ -335,7 +351,7 @@ combo_t* overlaps(combo_t *combo1, combo_t *combo2) {
|
||||
}
|
||||
|
||||
static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *record, uint16_t combo_index) {
|
||||
uint8_t key_count = 0;
|
||||
uint8_t key_count = 0;
|
||||
uint16_t key_index = -1;
|
||||
_find_key_index_and_count(combo->keys, keycode, &key_index, &key_count);
|
||||
|
||||
@@ -369,12 +385,9 @@ static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *
|
||||
|
||||
// disable readied combos that overlap with this combo
|
||||
combo_t *drop = NULL;
|
||||
for (uint8_t combo_buffer_i = combo_buffer_read;
|
||||
combo_buffer_i != combo_buffer_write;
|
||||
INCREMENT_MOD(combo_buffer_i)) {
|
||||
|
||||
queued_combo_t *qcombo = &combo_buffer[combo_buffer_i];
|
||||
combo_t *buffered_combo = &key_combos[qcombo->combo_index];
|
||||
for (uint8_t combo_buffer_i = combo_buffer_read; combo_buffer_i != combo_buffer_write; INCREMENT_MOD(combo_buffer_i)) {
|
||||
queued_combo_t *qcombo = &combo_buffer[combo_buffer_i];
|
||||
combo_t * buffered_combo = &key_combos[qcombo->combo_index];
|
||||
|
||||
if ((drop = overlaps(buffered_combo, combo))) {
|
||||
DISABLE_COMBO(drop);
|
||||
@@ -387,21 +400,19 @@ static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *
|
||||
INCREMENT_MOD(combo_buffer_read);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (drop != combo) {
|
||||
// save this combo to buffer
|
||||
combo_buffer[combo_buffer_write] = (queued_combo_t){
|
||||
.combo_index=combo_index,
|
||||
.combo_index = combo_index,
|
||||
};
|
||||
INCREMENT_MOD(combo_buffer_write);
|
||||
|
||||
// get possible longer waiting time for tap-/hold-only combos.
|
||||
longest_term = _get_wait_time(combo_index, combo);
|
||||
}
|
||||
} // if timer elapsed end
|
||||
|
||||
} // if timer elapsed end
|
||||
}
|
||||
} else {
|
||||
// chord releases
|
||||
@@ -416,7 +427,7 @@ static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *
|
||||
else if (get_combo_must_tap(combo_index, combo)) {
|
||||
// immediately apply tap-only combo
|
||||
apply_combo(combo_index, combo);
|
||||
apply_combos(); // also apply other prepared combos and dump key buffer
|
||||
apply_combos(); // also apply other prepared combos and dump key buffer
|
||||
# ifdef COMBO_PROCESS_KEY_RELEASE
|
||||
if (process_combo_key_release(combo_index, combo, key_index, keycode)) {
|
||||
release_combo(combo_index, combo);
|
||||
@@ -424,10 +435,7 @@ static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
} else if (COMBO_ACTIVE(combo)
|
||||
&& ONLY_ONE_KEY_IS_DOWN(COMBO_STATE(combo))
|
||||
&& KEY_NOT_YET_RELEASED(COMBO_STATE(combo), key_index)
|
||||
) {
|
||||
} else if (COMBO_ACTIVE(combo) && ONLY_ONE_KEY_IS_DOWN(COMBO_STATE(combo)) && KEY_NOT_YET_RELEASED(COMBO_STATE(combo), key_index)) {
|
||||
/* last key released */
|
||||
release_combo(combo_index, combo);
|
||||
key_is_part_of_combo = true;
|
||||
@@ -435,9 +443,7 @@ static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *
|
||||
#ifdef COMBO_PROCESS_KEY_RELEASE
|
||||
process_combo_key_release(combo_index, combo, key_index, keycode);
|
||||
#endif
|
||||
} else if (COMBO_ACTIVE(combo)
|
||||
&& KEY_NOT_YET_RELEASED(COMBO_STATE(combo), key_index)
|
||||
) {
|
||||
} else if (COMBO_ACTIVE(combo) && KEY_NOT_YET_RELEASED(COMBO_STATE(combo), key_index)) {
|
||||
/* first or middle key released */
|
||||
key_is_part_of_combo = true;
|
||||
|
||||
@@ -489,21 +495,21 @@ bool process_combo(uint16_t keycode, keyrecord_t *record) {
|
||||
|
||||
if (record->event.pressed && is_combo_key) {
|
||||
#ifndef COMBO_NO_TIMER
|
||||
# ifdef COMBO_STRICT_TIMER
|
||||
# ifdef COMBO_STRICT_TIMER
|
||||
if (!timer) {
|
||||
// timer is set only on the first key
|
||||
timer = timer_read();
|
||||
}
|
||||
# else
|
||||
# else
|
||||
timer = timer_read();
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
if (key_buffer_size < COMBO_KEY_BUFFER_LENGTH) {
|
||||
key_buffer[key_buffer_size++] = (queued_record_t){
|
||||
.record = *record,
|
||||
.keycode = keycode,
|
||||
.combo_index = -1, // this will be set when applying combos
|
||||
.record = *record,
|
||||
.keycode = keycode,
|
||||
.combo_index = -1, // this will be set when applying combos
|
||||
};
|
||||
}
|
||||
} else {
|
||||
@@ -532,7 +538,7 @@ void combo_task(void) {
|
||||
if (combo_buffer_read != combo_buffer_write) {
|
||||
apply_combos();
|
||||
longest_term = 0;
|
||||
timer = 0;
|
||||
timer = 0;
|
||||
} else {
|
||||
dump_key_buffer();
|
||||
timer = 0;
|
||||
@@ -546,9 +552,9 @@ void combo_enable(void) { b_combo_enable = true; }
|
||||
|
||||
void combo_disable(void) {
|
||||
#ifndef COMBO_NO_TIMER
|
||||
timer = 0;
|
||||
timer = 0;
|
||||
#endif
|
||||
b_combo_enable = false;
|
||||
b_combo_enable = false;
|
||||
combo_buffer_read = combo_buffer_write;
|
||||
clear_combos();
|
||||
dump_key_buffer();
|
||||
|
||||
@@ -43,8 +43,8 @@ typedef struct {
|
||||
#ifdef EXTRA_SHORT_COMBOS
|
||||
uint8_t state;
|
||||
#else
|
||||
bool disabled;
|
||||
bool active;
|
||||
bool disabled;
|
||||
bool active;
|
||||
# if defined(EXTRA_EXTRA_LONG_COMBOS)
|
||||
uint32_t state;
|
||||
# elif defined(EXTRA_LONG_COMBOS)
|
||||
|
||||
50
quantum/process_keycode/process_dynamic_tapping_term.c
Normal file
50
quantum/process_keycode/process_dynamic_tapping_term.c
Normal file
@@ -0,0 +1,50 @@
|
||||
/* Copyright 2020 Vladislav Kucheriavykh
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "quantum.h"
|
||||
#include "process_dynamic_tapping_term.h"
|
||||
|
||||
#ifndef DYNAMIC_TAPPING_TERM_INCREMENT
|
||||
# define DYNAMIC_TAPPING_TERM_INCREMENT 5
|
||||
#endif
|
||||
|
||||
static void tapping_term_report(void) {
|
||||
const char *tapping_term_str = get_u16_str(g_tapping_term, ' ');
|
||||
// Skip padding spaces
|
||||
while (*tapping_term_str == ' ') {
|
||||
tapping_term_str++;
|
||||
}
|
||||
send_string(tapping_term_str);
|
||||
}
|
||||
|
||||
bool process_dynamic_tapping_term(uint16_t keycode, keyrecord_t *record) {
|
||||
if (record->event.pressed) {
|
||||
switch (keycode) {
|
||||
case DT_PRNT:
|
||||
tapping_term_report();
|
||||
return false;
|
||||
|
||||
case DT_UP:
|
||||
g_tapping_term += DYNAMIC_TAPPING_TERM_INCREMENT;
|
||||
return false;
|
||||
|
||||
case DT_DOWN:
|
||||
g_tapping_term -= DYNAMIC_TAPPING_TERM_INCREMENT;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
26
quantum/process_keycode/process_dynamic_tapping_term.h
Normal file
26
quantum/process_keycode/process_dynamic_tapping_term.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/* Copyright 2020 Vladislav Kucheriavykh
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "action.h"
|
||||
|
||||
#ifndef DYNAMIC_TAPPING_TERM_INCREMENT
|
||||
# define DYNAMIC_TAPPING_TERM_INCREMENT 5
|
||||
#endif
|
||||
|
||||
bool process_dynamic_tapping_term(uint16_t keycode, keyrecord_t *record);
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "process_haptic.h"
|
||||
#include "quantum_keycodes.h"
|
||||
#include "action_tapping.h"
|
||||
#include "usb_device_state.h"
|
||||
|
||||
__attribute__((weak)) bool get_haptic_enabled_key(uint16_t keycode, keyrecord_t *record) {
|
||||
switch (keycode) {
|
||||
@@ -30,8 +31,9 @@ __attribute__((weak)) bool get_haptic_enabled_key(uint16_t keycode, keyrecord_t
|
||||
case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:
|
||||
if (record->tap.count == 0) return false;
|
||||
break;
|
||||
case KC_LCTRL ... KC_RGUI:
|
||||
case KC_LEFT_CTRL ... KC_RIGHT_GUI:
|
||||
case QK_MOMENTARY ... QK_MOMENTARY_MAX:
|
||||
case QK_LAYER_MOD ... QK_LAYER_MOD_MAX:
|
||||
#endif
|
||||
#ifdef NO_HAPTIC_FN
|
||||
case KC_FN0 ... KC_FN31:
|
||||
@@ -42,34 +44,34 @@ __attribute__((weak)) bool get_haptic_enabled_key(uint16_t keycode, keyrecord_t
|
||||
#ifdef NO_HAPTIC_PUNCTUATION
|
||||
case KC_ENTER:
|
||||
case KC_ESCAPE:
|
||||
case KC_BSPACE:
|
||||
case KC_BACKSPACE:
|
||||
case KC_SPACE:
|
||||
case KC_MINUS:
|
||||
case KC_EQUAL:
|
||||
case KC_LBRACKET:
|
||||
case KC_RBRACKET:
|
||||
case KC_BSLASH:
|
||||
case KC_LEFT_BRACKET:
|
||||
case KC_RIGHT_BRACKET:
|
||||
case KC_BACKSLASH:
|
||||
case KC_NONUS_HASH:
|
||||
case KC_SCOLON:
|
||||
case KC_SEMICOLON:
|
||||
case KC_QUOTE:
|
||||
case KC_GRAVE:
|
||||
case KC_COMMA:
|
||||
case KC_SLASH:
|
||||
case KC_DOT:
|
||||
case KC_NONUS_BSLASH:
|
||||
case KC_NONUS_BACKSLASH:
|
||||
#endif
|
||||
#ifdef NO_HAPTIC_LOCKKEYS
|
||||
case KC_CAPSLOCK:
|
||||
case KC_SCROLLLOCK:
|
||||
case KC_NUMLOCK:
|
||||
case KC_CAPS_LOCK:
|
||||
case KC_SCROLL_LOCK:
|
||||
case KC_NUM_LOCK:
|
||||
#endif
|
||||
#ifdef NO_HAPTIC_NAV
|
||||
case KC_PSCREEN:
|
||||
case KC_PRINT_SCREEN:
|
||||
case KC_PAUSE:
|
||||
case KC_INSERT:
|
||||
case KC_DELETE:
|
||||
case KC_PGDOWN:
|
||||
case KC_PGUP:
|
||||
case KC_PAGE_DOWN:
|
||||
case KC_PAGE_UP:
|
||||
case KC_LEFT:
|
||||
case KC_UP:
|
||||
case KC_RIGHT:
|
||||
@@ -130,7 +132,7 @@ bool process_haptic(uint16_t keycode, keyrecord_t *record) {
|
||||
}
|
||||
}
|
||||
|
||||
if (haptic_get_enable()) {
|
||||
if (haptic_get_enable() && ((!HAPTIC_OFF_IN_LOW_POWER) || (usb_device_state == USB_DEVICE_STATE_CONFIGURED))) {
|
||||
if (record->event.pressed) {
|
||||
// keypress
|
||||
if (haptic_get_feedback() < 2 && get_haptic_enabled_key(keycode, record)) {
|
||||
|
||||
@@ -146,7 +146,7 @@ bool process_music(uint16_t keycode, keyrecord_t *record) {
|
||||
|
||||
if (music_activated || midi_activated) {
|
||||
if (record->event.pressed) {
|
||||
if (keycode == KC_LCTL) { // Start recording
|
||||
if (keycode == KC_LEFT_CTRL) { // Start recording
|
||||
music_all_notes_off();
|
||||
music_sequence_recording = true;
|
||||
music_sequence_recorded = false;
|
||||
@@ -155,7 +155,7 @@ bool process_music(uint16_t keycode, keyrecord_t *record) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (keycode == KC_LALT) { // Stop recording/playing
|
||||
if (keycode == KC_LEFT_ALT) { // Stop recording/playing
|
||||
music_all_notes_off();
|
||||
if (music_sequence_recording) { // was recording
|
||||
music_sequence_recorded = true;
|
||||
@@ -165,7 +165,7 @@ bool process_music(uint16_t keycode, keyrecord_t *record) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (keycode == KC_LGUI && music_sequence_recorded) { // Start playing
|
||||
if (keycode == KC_LEFT_GUI && music_sequence_recorded) { // Start playing
|
||||
music_all_notes_off();
|
||||
music_sequence_recording = false;
|
||||
music_sequence_playing = true;
|
||||
|
||||
@@ -31,7 +31,7 @@ uint8_t shifted_numbers[10] = {0x21, 0x40, 0x23, 0x24, 0x25, 0x5E, 0x26, 0x2A, 0
|
||||
|
||||
// uint8_t keycode_to_ascii[0xFF][2];
|
||||
|
||||
// keycode_to_ascii[KC_MINS] = {0x2D, 0x5F};
|
||||
// keycode_to_ascii[KC_MINUS] = {0x2D, 0x5F};
|
||||
|
||||
void print_char(char c) {
|
||||
USB_Disable();
|
||||
@@ -90,8 +90,8 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {
|
||||
case KC_PIPE:
|
||||
case KC_TILD:
|
||||
keycode &= 0xFF;
|
||||
case KC_LSFT:
|
||||
case KC_RSFT:
|
||||
case KC_LEFT_SHIFT:
|
||||
case KC_RIGHT_SHIFT:
|
||||
if (record->event.pressed) {
|
||||
character_shift++;
|
||||
} else {
|
||||
@@ -107,13 +107,13 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {
|
||||
print_box_string("This is a line of text!");
|
||||
}
|
||||
return false;
|
||||
case KC_ESC:
|
||||
case KC_ESCAPE:
|
||||
if (record->event.pressed) {
|
||||
print_char(0x1B);
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case KC_SPC:
|
||||
case KC_SPACE:
|
||||
if (record->event.pressed) {
|
||||
print_char(0x20);
|
||||
}
|
||||
@@ -139,7 +139,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case KC_ENT:
|
||||
case KC_ENTER:
|
||||
if (record->event.pressed) {
|
||||
if (character_shift) {
|
||||
print_char(0x0C);
|
||||
@@ -149,7 +149,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case KC_BSPC:
|
||||
case KC_BACKSPACE:
|
||||
if (record->event.pressed) {
|
||||
if (character_shift) {
|
||||
print_char(0x18);
|
||||
@@ -169,7 +169,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case KC_COMM:
|
||||
case KC_COMMA:
|
||||
if (record->event.pressed) {
|
||||
if (character_shift) {
|
||||
print_char(0x3C);
|
||||
@@ -179,7 +179,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case KC_SLSH:
|
||||
case KC_SLASH:
|
||||
if (record->event.pressed) {
|
||||
if (character_shift) {
|
||||
print_char(0x3F);
|
||||
@@ -189,7 +189,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case KC_QUOT:
|
||||
case KC_QUOTE:
|
||||
if (record->event.pressed) {
|
||||
if (character_shift) {
|
||||
print_char(0x22);
|
||||
@@ -199,7 +199,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case KC_GRV:
|
||||
case KC_GRAVE:
|
||||
if (record->event.pressed) {
|
||||
if (character_shift) {
|
||||
print_char(0x7E);
|
||||
@@ -209,7 +209,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case KC_MINS:
|
||||
case KC_MINUS:
|
||||
if (record->event.pressed) {
|
||||
if (character_shift) {
|
||||
print_char(0x5F);
|
||||
@@ -219,7 +219,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case KC_EQL:
|
||||
case KC_EQUAL:
|
||||
if (record->event.pressed) {
|
||||
if (character_shift) {
|
||||
print_char(0x2B);
|
||||
@@ -229,7 +229,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case KC_LBRC:
|
||||
case KC_LEFT_BRACKET:
|
||||
if (record->event.pressed) {
|
||||
if (character_shift) {
|
||||
print_char(0x7B);
|
||||
@@ -239,7 +239,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case KC_RBRC:
|
||||
case KC_RIGHT_BRACKET:
|
||||
if (record->event.pressed) {
|
||||
if (character_shift) {
|
||||
print_char(0x7D);
|
||||
@@ -249,7 +249,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case KC_BSLS:
|
||||
case KC_BACKSLASH:
|
||||
if (record->event.pressed) {
|
||||
if (character_shift) {
|
||||
print_char(0x7C);
|
||||
|
||||
@@ -45,7 +45,7 @@ uint8_t shifted_numbers[10] = {0x21, 0x40, 0x23, 0x24, 0x25, 0x5E, 0x26, 0x2A, 0
|
||||
|
||||
// uint8_t keycode_to_ascii[0xFF][2];
|
||||
|
||||
// keycode_to_ascii[KC_MINS] = {0x2D, 0x5F};
|
||||
// keycode_to_ascii[KC_MINUS] = {0x2D, 0x5F};
|
||||
|
||||
void print_char(char c) {
|
||||
uint8_t b = 8;
|
||||
@@ -84,8 +84,8 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {
|
||||
case KC_PIPE:
|
||||
case KC_TILD:
|
||||
keycode &= 0xFF;
|
||||
case KC_LSFT:
|
||||
case KC_RSFT:
|
||||
case KC_LEFT_SHIFT:
|
||||
case KC_RIGHT_SHIFT:
|
||||
if (record->event.pressed) {
|
||||
character_shift++;
|
||||
} else {
|
||||
@@ -101,13 +101,13 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {
|
||||
print_string("This is a line of text!\n\n\n");
|
||||
}
|
||||
return false;
|
||||
case KC_ESC:
|
||||
case KC_ESCAPE:
|
||||
if (record->event.pressed) {
|
||||
print_char(0x1B);
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case KC_SPC:
|
||||
case KC_SPACE:
|
||||
if (record->event.pressed) {
|
||||
print_char(0x20);
|
||||
}
|
||||
@@ -133,7 +133,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case KC_ENT:
|
||||
case KC_ENTER:
|
||||
if (record->event.pressed) {
|
||||
if (character_shift) {
|
||||
print_char(0x0C);
|
||||
@@ -143,7 +143,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case KC_BSPC:
|
||||
case KC_BACKSPACE:
|
||||
if (record->event.pressed) {
|
||||
if (character_shift) {
|
||||
print_char(0x18);
|
||||
@@ -163,7 +163,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case KC_COMM:
|
||||
case KC_COMMA:
|
||||
if (record->event.pressed) {
|
||||
if (character_shift) {
|
||||
print_char(0x3C);
|
||||
@@ -173,7 +173,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case KC_SLSH:
|
||||
case KC_SLASH:
|
||||
if (record->event.pressed) {
|
||||
if (character_shift) {
|
||||
print_char(0x3F);
|
||||
@@ -183,7 +183,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case KC_QUOT:
|
||||
case KC_QUOTE:
|
||||
if (record->event.pressed) {
|
||||
if (character_shift) {
|
||||
print_char(0x22);
|
||||
@@ -193,7 +193,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case KC_GRV:
|
||||
case KC_GRAVE:
|
||||
if (record->event.pressed) {
|
||||
if (character_shift) {
|
||||
print_char(0x7E);
|
||||
@@ -203,7 +203,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case KC_MINS:
|
||||
case KC_MINUS:
|
||||
if (record->event.pressed) {
|
||||
if (character_shift) {
|
||||
print_char(0x5F);
|
||||
@@ -213,7 +213,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case KC_EQL:
|
||||
case KC_EQUAL:
|
||||
if (record->event.pressed) {
|
||||
if (character_shift) {
|
||||
print_char(0x2B);
|
||||
@@ -223,7 +223,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case KC_LBRC:
|
||||
case KC_LEFT_BRACKET:
|
||||
if (record->event.pressed) {
|
||||
if (character_shift) {
|
||||
print_char(0x7B);
|
||||
@@ -233,7 +233,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case KC_RBRC:
|
||||
case KC_RIGHT_BRACKET:
|
||||
if (record->event.pressed) {
|
||||
if (character_shift) {
|
||||
print_char(0x7D);
|
||||
@@ -243,7 +243,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case KC_BSLS:
|
||||
case KC_BACKSLASH:
|
||||
if (record->event.pressed) {
|
||||
if (character_shift) {
|
||||
print_char(0x7C);
|
||||
|
||||
31
quantum/process_keycode/process_programmable_button.c
Normal file
31
quantum/process_keycode/process_programmable_button.c
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
Copyright 2021 Thomas Weißschuh <thomas@t-8ch.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "process_programmable_button.h"
|
||||
#include "programmable_button.h"
|
||||
|
||||
bool process_programmable_button(uint16_t keycode, keyrecord_t *record) {
|
||||
if (keycode >= PROGRAMMABLE_BUTTON_MIN && keycode <= PROGRAMMABLE_BUTTON_MAX) {
|
||||
uint8_t button = keycode - PROGRAMMABLE_BUTTON_MIN + 1;
|
||||
if (record->event.pressed) {
|
||||
programmable_button_on(button);
|
||||
} else {
|
||||
programmable_button_off(button);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
23
quantum/process_keycode/process_programmable_button.h
Normal file
23
quantum/process_keycode/process_programmable_button.h
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
Copyright 2021 Thomas Weißschuh <thomas@t-8ch.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "quantum.h"
|
||||
|
||||
bool process_programmable_button(uint16_t keycode, keyrecord_t *record);
|
||||
@@ -27,53 +27,53 @@
|
||||
|
||||
// Shift / Enter setup
|
||||
#ifndef SFTENT_KEY
|
||||
# define SFTENT_KEY KC_ENT
|
||||
# define SFTENT_KEY KC_ENTER
|
||||
#endif
|
||||
|
||||
#ifdef DISABLE_SPACE_CADET_MODIFIER
|
||||
# ifndef LSPO_MOD
|
||||
# define LSPO_MOD KC_TRNS
|
||||
# define LSPO_MOD KC_TRANSPARENT
|
||||
# endif
|
||||
# ifndef RSPC_MOD
|
||||
# define RSPC_MOD KC_TRNS
|
||||
# define RSPC_MOD KC_TRANSPARENT
|
||||
# endif
|
||||
#else
|
||||
# ifndef LSPO_MOD
|
||||
# define LSPO_MOD KC_LSFT
|
||||
# define LSPO_MOD KC_LEFT_SHIFT
|
||||
# endif
|
||||
# ifndef RSPC_MOD
|
||||
# define RSPC_MOD KC_RSFT
|
||||
# define RSPC_MOD KC_RIGHT_SHIFT
|
||||
# endif
|
||||
#endif
|
||||
// **********************************************************
|
||||
|
||||
// Shift / paren setup
|
||||
#ifndef LSPO_KEYS
|
||||
# define LSPO_KEYS KC_LSFT, LSPO_MOD, LSPO_KEY
|
||||
# define LSPO_KEYS KC_LEFT_SHIFT, LSPO_MOD, LSPO_KEY
|
||||
#endif
|
||||
#ifndef RSPC_KEYS
|
||||
# define RSPC_KEYS KC_RSFT, RSPC_MOD, RSPC_KEY
|
||||
# define RSPC_KEYS KC_RIGHT_SHIFT, RSPC_MOD, RSPC_KEY
|
||||
#endif
|
||||
|
||||
// Control / paren setup
|
||||
#ifndef LCPO_KEYS
|
||||
# define LCPO_KEYS KC_LCTL, KC_LSFT, KC_9
|
||||
# define LCPO_KEYS KC_LEFT_CTRL, KC_LEFT_SHIFT, KC_9
|
||||
#endif
|
||||
#ifndef RCPC_KEYS
|
||||
# define RCPC_KEYS KC_RCTL, KC_RSFT, KC_0
|
||||
# define RCPC_KEYS KC_RIGHT_CTRL, KC_RIGHT_SHIFT, KC_0
|
||||
#endif
|
||||
|
||||
// Alt / paren setup
|
||||
#ifndef LAPO_KEYS
|
||||
# define LAPO_KEYS KC_LALT, KC_LSFT, KC_9
|
||||
# define LAPO_KEYS KC_LEFT_ALT, KC_LEFT_SHIFT, KC_9
|
||||
#endif
|
||||
#ifndef RAPC_KEYS
|
||||
# define RAPC_KEYS KC_RALT, KC_RSFT, KC_0
|
||||
# define RAPC_KEYS KC_RIGHT_ALT, KC_RIGHT_SHIFT, KC_0
|
||||
#endif
|
||||
|
||||
// Shift / Enter setup
|
||||
#ifndef SFTENT_KEYS
|
||||
# define SFTENT_KEYS KC_RSFT, KC_TRNS, SFTENT_KEY
|
||||
# define SFTENT_KEYS KC_RIGHT_SHIFT, KC_TRANSPARENT, SFTENT_KEY
|
||||
#endif
|
||||
|
||||
static uint8_t sc_last = 0;
|
||||
|
||||
@@ -67,7 +67,7 @@ static const uint8_t boltmap[64] PROGMEM = {TXB_NUL, TXB_NUM, TXB_NUM, TXB_NUM,
|
||||
|
||||
#ifdef STENO_COMBINEDMAP
|
||||
/* Used to look up when pressing the middle row key to combine two consonant or vowel keys */
|
||||
static const uint16_t combinedmap_first[] PROGMEM = {STN_S1, STN_TL, STN_PL, STN_HL, STN_FR, STN_PR, STN_LR, STN_TR, STN_DR, STN_A, STN_E};
|
||||
static const uint16_t combinedmap_first[] PROGMEM = {STN_S1, STN_TL, STN_PL, STN_HL, STN_FR, STN_PR, STN_LR, STN_TR, STN_DR, STN_A, STN_E};
|
||||
static const uint16_t combinedmap_second[] PROGMEM = {STN_S2, STN_KL, STN_WL, STN_RL, STN_RR, STN_BR, STN_GR, STN_SR, STN_ZR, STN_O, STN_U};
|
||||
#endif
|
||||
|
||||
@@ -174,11 +174,10 @@ bool process_steno(uint16_t keycode, keyrecord_t *record) {
|
||||
return false;
|
||||
|
||||
#ifdef STENO_COMBINEDMAP
|
||||
case QK_STENO_COMB ... QK_STENO_COMB_MAX:
|
||||
{
|
||||
case QK_STENO_COMB ... QK_STENO_COMB_MAX: {
|
||||
uint8_t result;
|
||||
result = process_steno(combinedmap_first[keycode-QK_STENO_COMB], record);
|
||||
result &= process_steno(combinedmap_second[keycode-QK_STENO_COMB], record);
|
||||
result = process_steno(combinedmap_first[keycode - QK_STENO_COMB], record);
|
||||
result &= process_steno(combinedmap_second[keycode - QK_STENO_COMB], record);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -257,12 +257,12 @@ bool process_terminal(uint16_t keycode, keyrecord_t *record) {
|
||||
process_terminal_command();
|
||||
return false;
|
||||
break;
|
||||
case KC_ESC:
|
||||
case KC_ESCAPE:
|
||||
SEND_STRING("\n");
|
||||
enable_terminal();
|
||||
return false;
|
||||
break;
|
||||
case KC_BSPC:
|
||||
case KC_BACKSPACE:
|
||||
str_len = strlen(buffer);
|
||||
if (str_len > 0) {
|
||||
buffer[str_len - 1] = 0;
|
||||
@@ -284,7 +284,7 @@ bool process_terminal(uint16_t keycode, keyrecord_t *record) {
|
||||
str_len = strlen(buffer);
|
||||
for (int i = 0; i < str_len; ++i) {
|
||||
send_string(SS_TAP(X_BSPACE)); // clear w/e is on the line already
|
||||
// process_terminal(KC_BSPC,record);
|
||||
// process_terminal(KC_BACKSPACE,record);
|
||||
}
|
||||
strncpy(buffer, cmd_buffer[current_cmd_buffer_pos], 80);
|
||||
|
||||
@@ -299,7 +299,7 @@ bool process_terminal(uint16_t keycode, keyrecord_t *record) {
|
||||
str_len = strlen(buffer);
|
||||
for (int i = 0; i < str_len; ++i) {
|
||||
send_string(SS_TAP(X_BSPACE)); // clear w/e is on the line already
|
||||
// process_terminal(KC_BSPC,record);
|
||||
// process_terminal(KC_BACKSPACE,record);
|
||||
}
|
||||
strncpy(buffer, cmd_buffer[current_cmd_buffer_pos], 79);
|
||||
|
||||
@@ -311,7 +311,7 @@ bool process_terminal(uint16_t keycode, keyrecord_t *record) {
|
||||
default:
|
||||
if (keycode <= 58) {
|
||||
char_to_add = 0;
|
||||
if (get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT))) {
|
||||
if (get_mods() & (MOD_BIT(KC_LEFT_SHIFT) | MOD_BIT(KC_RIGHT_SHIFT))) {
|
||||
char_to_add = shifted_keycode_to_ascii_lut[keycode];
|
||||
} else if (get_mods() == 0) {
|
||||
char_to_add = keycode_to_ascii_lut[keycode];
|
||||
|
||||
@@ -46,7 +46,7 @@ static bool is_uni_seq(char *seq) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return qk_ucis_state.codes[i] == KC_ENT || qk_ucis_state.codes[i] == KC_SPC;
|
||||
return qk_ucis_state.codes[i] == KC_ENTER || qk_ucis_state.codes[i] == KC_SPACE;
|
||||
}
|
||||
|
||||
__attribute__((weak)) void qk_ucis_symbol_fallback(void) {
|
||||
@@ -72,7 +72,7 @@ bool process_ucis(uint16_t keycode, keyrecord_t *record) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool special = keycode == KC_SPC || keycode == KC_ENT || keycode == KC_ESC || keycode == KC_BSPC;
|
||||
bool special = keycode == KC_SPACE || keycode == KC_ENTER || keycode == KC_ESCAPE || keycode == KC_BACKSPACE;
|
||||
if (qk_ucis_state.count >= UCIS_MAX_SYMBOL_LENGTH && !special) {
|
||||
return false;
|
||||
}
|
||||
@@ -81,7 +81,7 @@ bool process_ucis(uint16_t keycode, keyrecord_t *record) {
|
||||
qk_ucis_state.count++;
|
||||
|
||||
switch (keycode) {
|
||||
case KC_BSPC:
|
||||
case KC_BACKSPACE:
|
||||
if (qk_ucis_state.count >= 2) {
|
||||
qk_ucis_state.count -= 2;
|
||||
return true;
|
||||
@@ -90,16 +90,16 @@ bool process_ucis(uint16_t keycode, keyrecord_t *record) {
|
||||
return false;
|
||||
}
|
||||
|
||||
case KC_SPC:
|
||||
case KC_ENT:
|
||||
case KC_ESC:
|
||||
case KC_SPACE:
|
||||
case KC_ENTER:
|
||||
case KC_ESCAPE:
|
||||
for (uint8_t i = 0; i < qk_ucis_state.count; i++) {
|
||||
register_code(KC_BSPC);
|
||||
unregister_code(KC_BSPC);
|
||||
register_code(KC_BACKSPACE);
|
||||
unregister_code(KC_BACKSPACE);
|
||||
wait_ms(UNICODE_TYPE_DELAY);
|
||||
}
|
||||
|
||||
if (keycode == KC_ESC) {
|
||||
if (keycode == KC_ESCAPE) {
|
||||
qk_ucis_state.in_progress = false;
|
||||
qk_ucis_cancel();
|
||||
return false;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
unicode_config_t unicode_config;
|
||||
uint8_t unicode_saved_mods;
|
||||
bool unicode_saved_caps_lock;
|
||||
bool unicode_saved_num_lock;
|
||||
|
||||
#if UNICODE_SELECTED_MODES != -1
|
||||
static uint8_t selected[] = {UNICODE_SELECTED_MODES};
|
||||
@@ -79,13 +80,14 @@ void persist_unicode_input_mode(void) { eeprom_update_byte(EECONFIG_UNICODEMODE,
|
||||
|
||||
__attribute__((weak)) void unicode_input_start(void) {
|
||||
unicode_saved_caps_lock = host_keyboard_led_state().caps_lock;
|
||||
unicode_saved_num_lock = host_keyboard_led_state().num_lock;
|
||||
|
||||
// Note the order matters here!
|
||||
// Need to do this before we mess around with the mods, or else
|
||||
// UNICODE_KEY_LNX (which is usually Ctrl-Shift-U) might not work
|
||||
// correctly in the shifted case.
|
||||
if (unicode_config.input_mode == UC_LNX && unicode_saved_caps_lock) {
|
||||
tap_code(KC_CAPS);
|
||||
tap_code(KC_CAPS_LOCK);
|
||||
}
|
||||
|
||||
unicode_saved_mods = get_mods(); // Save current mods
|
||||
@@ -99,8 +101,13 @@ __attribute__((weak)) void unicode_input_start(void) {
|
||||
tap_code16(UNICODE_KEY_LNX);
|
||||
break;
|
||||
case UC_WIN:
|
||||
register_code(KC_LALT);
|
||||
tap_code(KC_PPLS);
|
||||
// For increased reliability, use numpad keys for inputting digits
|
||||
if (!unicode_saved_num_lock) {
|
||||
tap_code(KC_NUM_LOCK);
|
||||
}
|
||||
register_code(KC_LEFT_ALT);
|
||||
wait_ms(UNICODE_TYPE_DELAY);
|
||||
tap_code(KC_KP_PLUS);
|
||||
break;
|
||||
case UC_WINC:
|
||||
tap_code(UNICODE_KEY_WINC);
|
||||
@@ -117,13 +124,16 @@ __attribute__((weak)) void unicode_input_finish(void) {
|
||||
unregister_code(UNICODE_KEY_MAC);
|
||||
break;
|
||||
case UC_LNX:
|
||||
tap_code(KC_SPC);
|
||||
tap_code(KC_SPACE);
|
||||
if (unicode_saved_caps_lock) {
|
||||
tap_code(KC_CAPS);
|
||||
tap_code(KC_CAPS_LOCK);
|
||||
}
|
||||
break;
|
||||
case UC_WIN:
|
||||
unregister_code(KC_LALT);
|
||||
unregister_code(KC_LEFT_ALT);
|
||||
if (!unicode_saved_num_lock) {
|
||||
tap_code(KC_NUM_LOCK);
|
||||
}
|
||||
break;
|
||||
case UC_WINC:
|
||||
tap_code(KC_ENTER);
|
||||
@@ -139,26 +149,44 @@ __attribute__((weak)) void unicode_input_cancel(void) {
|
||||
unregister_code(UNICODE_KEY_MAC);
|
||||
break;
|
||||
case UC_LNX:
|
||||
tap_code(KC_ESC);
|
||||
tap_code(KC_ESCAPE);
|
||||
if (unicode_saved_caps_lock) {
|
||||
tap_code(KC_CAPS);
|
||||
tap_code(KC_CAPS_LOCK);
|
||||
}
|
||||
break;
|
||||
case UC_WINC:
|
||||
tap_code(KC_ESC);
|
||||
tap_code(KC_ESCAPE);
|
||||
break;
|
||||
case UC_WIN:
|
||||
unregister_code(KC_LALT);
|
||||
unregister_code(KC_LEFT_ALT);
|
||||
if (!unicode_saved_num_lock) {
|
||||
tap_code(KC_NUM_LOCK);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
set_mods(unicode_saved_mods); // Reregister previously set mods
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
|
||||
static void send_nibble_wrapper(uint8_t digit) {
|
||||
if (unicode_config.input_mode == UC_WIN) {
|
||||
uint8_t kc = digit < 10
|
||||
? KC_KP_1 + (10 + digit - 1) % 10
|
||||
: KC_A + (digit - 10);
|
||||
tap_code(kc);
|
||||
return;
|
||||
}
|
||||
send_nibble(digit);
|
||||
}
|
||||
|
||||
// clang-format on
|
||||
|
||||
void register_hex(uint16_t hex) {
|
||||
for (int i = 3; i >= 0; i--) {
|
||||
uint8_t digit = ((hex >> (i * 4)) & 0xF);
|
||||
send_nibble(digit);
|
||||
send_nibble_wrapper(digit);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,10 +199,10 @@ void register_hex32(uint32_t hex) {
|
||||
uint8_t digit = ((hex >> (i * 4)) & 0xF);
|
||||
if (digit == 0) {
|
||||
if (!onzerostart) {
|
||||
send_nibble(digit);
|
||||
send_nibble_wrapper(digit);
|
||||
}
|
||||
} else {
|
||||
send_nibble(digit);
|
||||
send_nibble_wrapper(digit);
|
||||
onzerostart = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,13 +24,13 @@
|
||||
|
||||
// Keycodes used for starting Unicode input on different platforms
|
||||
#ifndef UNICODE_KEY_MAC
|
||||
# define UNICODE_KEY_MAC KC_LALT
|
||||
# define UNICODE_KEY_MAC KC_LEFT_ALT
|
||||
#endif
|
||||
#ifndef UNICODE_KEY_LNX
|
||||
# define UNICODE_KEY_LNX LCTL(LSFT(KC_U))
|
||||
#endif
|
||||
#ifndef UNICODE_KEY_WINC
|
||||
# define UNICODE_KEY_WINC KC_RALT
|
||||
# define UNICODE_KEY_WINC KC_RIGHT_ALT
|
||||
#endif
|
||||
|
||||
// Comma-delimited, ordered list of input modes selected for use (e.g. in cycle)
|
||||
|
||||
Reference in New Issue
Block a user