Skip to content

Commit

Permalink
Insert delay between shifted chars in send_string_with_delay
Browse files Browse the repository at this point in the history
When using `send_string_with_delay`, if the string contains capital
letters, it gets sent to `send_char`, which does not insert the delay
between pressing the modifier keys needed to type the shifted letter.
This results in key codes being sent unshifted in some situations, such
as ssh connections where the keyboard is too fast for the modifier taps
to register.

This commit inesrts a delay between every modifier tap when they are
detected.
  • Loading branch information
dead10ck committed Dec 14, 2022
1 parent 962e4c0 commit 7026db7
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 16 deletions.
4 changes: 1 addition & 3 deletions quantum/action.c
Original file line number Diff line number Diff line change
Expand Up @@ -988,9 +988,7 @@ __attribute__((weak)) void unregister_code(uint8_t code) {
*/
__attribute__((weak)) void tap_code_delay(uint8_t code, uint16_t delay) {
register_code(code);
for (uint16_t i = delay; i > 0; i--) {
wait_ms(1);
}
wait_ms(delay);
unregister_code(code);
}

Expand Down
36 changes: 25 additions & 11 deletions quantum/send_string/send_string.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ __attribute__((weak)) const uint8_t ascii_to_keycode_lut[128] PROGMEM = {
#define PGM_LOADBIT(mem, pos) ((pgm_read_byte(&((mem)[(pos) / 8])) >> ((pos) % 8)) & 0x01)

void send_string(const char *string) {
send_string_with_delay(string, 0);
send_string_with_delay(string, TAP_CODE_DELAY);
}

void send_string_with_delay(const char *string, uint8_t interval) {
Expand All @@ -156,6 +156,7 @@ void send_string_with_delay(const char *string, uint8_t interval) {
if (!ascii_code) break;
if (ascii_code == SS_QMK_PREFIX) {
ascii_code = *(++string);

if (ascii_code == SS_TAP_CODE) {
// tap
uint8_t keycode = *(++string);
Expand All @@ -172,28 +173,30 @@ void send_string_with_delay(const char *string, uint8_t interval) {
// delay
int ms = 0;
uint8_t keycode = *(++string);

while (isdigit(keycode)) {
ms *= 10;
ms += keycode - '0';
keycode = *(++string);
}
while (ms--)
wait_ms(1);

wait_ms(ms);
}

wait_ms(interval);
} else {
send_char(ascii_code);
send_char_with_delay(ascii_code, interval);
}

++string;
// interval
{
uint8_t ms = interval;
while (ms--)
wait_ms(1);
}
}
}

void send_char(char ascii_code) {
send_char_with_delay(ascii_code, TAP_CODE_DELAY);
}

void send_char_with_delay(char ascii_code, uint8_t interval) {
#if defined(AUDIO_ENABLE) && defined(SENDSTRING_BELL)
if (ascii_code == '\a') { // BEL
PLAY_SONG(bell_song);
Expand All @@ -208,19 +211,30 @@ void send_char(char ascii_code) {

if (is_shifted) {
register_code(KC_LEFT_SHIFT);
wait_ms(interval);
}

if (is_altgred) {
register_code(KC_RIGHT_ALT);
wait_ms(interval);
}
tap_code(keycode);

tap_code_delay(keycode, interval);
wait_ms(interval);

if (is_altgred) {
unregister_code(KC_RIGHT_ALT);
wait_ms(interval);
}

if (is_shifted) {
unregister_code(KC_LEFT_SHIFT);
wait_ms(interval);
}

if (is_dead) {
tap_code(KC_SPACE);
wait_ms(interval);
}
}

Expand Down
14 changes: 12 additions & 2 deletions quantum/send_string/send_string.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ extern const uint8_t ascii_to_keycode_lut[128];
/**
* \brief Type out a string of ASCII characters.
*
* This function simply calls `send_string_with_delay(string, 0)`.
* This function simply calls `send_string_with_delay(string, TAP_CODE_DELAY)`.
*
* Most keycodes from the basic keycode range are also supported by way of a special sequence - see `send_string_keycodes.h`.
*
Expand All @@ -59,17 +59,27 @@ void send_string(const char *string);
* \brief Type out a string of ASCII characters, with a delay between each character.
*
* \param string The string to type out.
* \param interval The amount of time, in milliseconds, to wait before typing the next character.
* \param interval The amount of time, in milliseconds, to wait before typing the next character. Note this can be set to 0 to ensure no delay, regardless of what TAP_CODE_DELAY is set to.
*/
void send_string_with_delay(const char *string, uint8_t interval);

/**
* \brief Type out an ASCII character.
*
* This function simply calls `send_char_with_delay(string, TAP_CODE_DELAY)`.
*
* \param ascii_code The character to type.
*/
void send_char(char ascii_code);

/**
* \brief Type out an ASCII character, with a delay between any modifiers.
*
* \param ascii_code The character to type.
* \param interval The amount of time, in milliseconds, to wait in between key presses. Note this can be set to 0 to ensure no delay, regardless of what TAP_CODE_DELAY is set to.
*/
void send_char_with_delay(char ascii_code, uint8_t interval);

/**
* \brief Type out an eight digit (unsigned 32-bit) hexadecimal value.
*
Expand Down

0 comments on commit 7026db7

Please sign in to comment.