qmk/qmk_firmware

[Bug] Caps Word doesn't work with Tap Dance keys

Open

#19,574 建立於 2023年1月12日

在 GitHub 查看
 (10 留言) (12 反應) (0 負責人)C (43,867 fork)batch import
bughelp wanted

倉庫指標

Star
 (20,368 star)
PR 合併指標
 (平均合併 20天 9小時) (30 天內合併 27 個 PR)

描述

Describe the Bug

Problem definition

When the Caps Word feature is enabled, pressing any Tap Dance keys:

  1. Turns Caps Word off;
  2. Does not capitalize the letter on the key.

Steps to reproduce

  1. Using the documentation for Caps Word, enable the Caps Word feature. It doesn't matter how you turn this mode on when typing.
  2. Add a tap dance key for any Latin letter that types this letter on tap and sends a modifier on hold. For example, add a tap dance to W; W on tap, and Ctrl+W on hold.
  3. Enable Caps Word and type any word that contains the letter from step 2 (e.g. , owl). When pressing W, Caps Word would be disabled, and Owl would be typed instead of OWL.

I used the default Moonlander firmware with Caps Word mode enabled and Ctrl+... on hold to reproduce the issue.

Why this might happen

Tap dance keys are defined as TD(DANCE_n).

TD(n) is a macro: #define TD(n) (QK_TAP_DANCE | ((n)&0xFF))

process_caps_word (caps_word_press_user, in particular) checks only basic keycodes like KC_A ... KC_Z and KC_MINS:

__attribute__((weak)) bool caps_word_press_user(uint16_t keycode) {
    switch (keycode) {
        // Keycodes that continue Caps Word, with shift applied.
        case KC_A ... KC_Z:
        case KC_MINS:
            add_weak_mods(MOD_BIT(KC_LSFT)); // Apply shift to next key.
            send_keyboard_report();
            return true;

        // Keycodes that continue Caps Word, without shifting.
        case KC_1 ... KC_0:
        case KC_BSPC:
        case KC_DEL:
        case KC_UNDS:
            return true;

        default:
            return false; // Deactivate Caps Word.
    }
}

So when keycode is QC_TAP_DANCE ... QC_TAP_DANCE_MAX, nothing happens to the typed letter.

Also, it seems that QC_TAP_DANCE ... QC_TAP_DANCE_MAX are not ignored in process_caps_word: link to the code

Tap dance code from the Moonlander firmware that I used:

void on_dance_5(qk_tap_dance_state_t *state, void *user_data) {
    if(state->count == 3) {
        tap_code16(KC_W);
        tap_code16(KC_W);
        tap_code16(KC_W);
    }
    if(state->count > 3) {
        tap_code16(KC_W);
    }
}

void dance_5_finished(qk_tap_dance_state_t *state, void *user_data) {
    dance_state[5].step = dance_step(state);
    switch (dance_state[5].step) {
        case SINGLE_TAP: register_code16(KC_W); break;
        case SINGLE_HOLD: register_code16(LCTL(KC_W));
            break;
        case DOUBLE_TAP: register_code16(KC_W); register_code16(KC_W); break;
        case DOUBLE_SINGLE_TAP: tap_code16(KC_W); register_code16(KC_W);
    }
}

void dance_5_reset(qk_tap_dance_state_t *state, void *user_data) {
    wait_ms(10);
    switch (dance_state[5].step) {
        case SINGLE_TAP: unregister_code16(KC_W); break;
        case SINGLE_HOLD: unregister_code16(LCTL(KC_W)); break;
        case DOUBLE_TAP: unregister_code16(KC_W); break;
        case DOUBLE_SINGLE_TAP: unregister_code16(KC_W); break;
    }
    dance_state[5].step = 0;
}

qk_tap_dance_action_t tap_dance_actions[] = {
    [DANCE_5] = ACTION_TAP_DANCE_FN_ADVANCED(on_dance_5, dance_5_finished, dance_5_reset),
};

Keyboard Used

Moonlander

Link to product page (if applicable)

No response

Operating System

Windows 10

qmk doctor Output

No response

Is AutoHotKey / Karabiner installed

  • AutoHotKey (Windows)
  • Karabiner (macOS)

Other keyboard-related software installed

No response

Additional Context

No response

貢獻者指南