qmk_console.log
Describe the Bug
The root cause of this issue is that quantum/action.c manages the RETRO_TAPPING modifier state using a single global variable (retro_tap_curr_mods).
When a Layer-Tap key is tapped while a Mod-Tap key is being held, the unregister_mods(retro_tap_curr_mods); function at the end of the Retro Tapping process for the second key unintentionally clears the global modifier state. This results in the "killing" of the modifier for the first key, even though it is still physically held down.
Steps to Reproduce:
- Enable
#define RETRO_TAPPING.
- Hold a Mod-Tap key (e.g.,
LSFT_T(KC_SPC)) -> Shift is registered.
- While holding it, tap a Layer-Tap key (e.g.,
LT(_LAYER, KC_MINS)) -> Shifted minus is output correctly via Retro Tapping.
- Type a third normal key (e.g.,
KC_A) while still holding the first Mod-Tap key.
- Expected:
A (Shifted)
- Actual:
a (Unshifted - the modifier was cleared by the previous Retro Tapping process).
Evidence
I have attached the QMK console log. The log clearly shows a discrepancy between the physical switch state (matrix) and the HID report.
- Row 09 (Thumb Shift) remains active (
10000000) in the matrix scan throughout the session.
- However, after the second key (Layer-Tap) is released, the HID report for modifiers drops from
20 (Shift) to 00 (None) at line 39.
- This is because the
RETRO_TAPPING logic in action_tapping.c unconditionally calls unregister_mods(), effectively "killing" the physically held modifier.
Log Highlight:
> 09: 10000000
> keyboard_report: 20 | 00 00 00 00 00 00 # Thumb Shift hold confirmed
...
> keyboard_report: 20 | 2D 00 00 00 00 00 # Shift + Minus (Layer-Tap)
> keyboard_report: 20 | 00 00 00 00 00 00 # Minus released
> keyboard_report: 00 | 00 00 00 00 00 00 # <-- BUG: Shift is forcibly reset to 0x00 while Row 09 is still 10000000
> 09: 10000000 # Row 09 is still physically held!
Keyboard Used
salicylic_acid3/7skb
Link to product page (if applicable)
No response
Operating System
macOS Tahoe 26.31 (a)
qmk doctor Output
❯ qmk doctor
Ψ QMK Doctor is checking your environment.
Ψ Python version: 3.13.3
Ψ CLI version: 1.1.8
Ψ QMK home: /Users/bilzard/.go/src/github.com/qmk/qmk_firmware
Ψ Detected macOS 26.3.1 (Apple Silicon).
Ψ Testing userspace candidate: /Users/bilzard/.go/src/github.com/bilzard/qmk_userspace -- Valid `qmk.json`
Ψ QMK userspace: /Users/bilzard/.go/src/github.com/bilzard/qmk_userspace
Ψ Userspace enabled: True
Ψ Git branch: master
⚠ The official repository does not seem to be configured as git remote "upstream".
Ψ CLI installed in virtualenv.
Ψ All dependencies are installed.
Ψ Found arm-none-eabi-gcc version 15.2.0
☒ Failed to compile a simple program with arm-none-eabi-gcc, return code 1
☒ Command: arm-none-eabi-gcc -mcpu=cortex-m0 -mthumb -mno-thumb-interwork --specs=nosys.specs --specs=nano.specs -x c -o /var/folders/1x/gbcc0yx16s18r3yrbxn3sc4w0000gn/T/tmpa6f5_9_9/test.elf /var/folders/1x/gbcc0yx16s18r3yrbxn3sc4w0000gn/T/tmpa6f5_9_9/test.c
Ψ Found avr-gcc version 9.5.0
Ψ Successfully compiled using avr-gcc
Ψ Successfully tested avr-binutils using avr-size
Ψ Found avrdude version 8.
Ψ Found dfu-programmer version 1.1.0
Ψ Found dfu-util version 0.11
Ψ Found diff version Apple diff (based on FreeBSD diff)
Ψ Found dos2unix version 7.5.4
Ψ Found git version 2.48.1
Ψ Found gmake version 4.4.1
Ψ Submodules are up to date.
Ψ Submodule status:
Ψ - lib/chibios: 2025-05-15 08:25:11 +0000 -- (8bd61b804)
Ψ - lib/chibios-contrib: 2025-10-03 18:22:15 +0200 -- (8d863d9e)
Ψ - lib/googletest: 2021-06-11 06:37:43 -0700 -- (e2239ee6)
Ψ - lib/lufa: 2022-08-26 12:09:55 +1000 -- (549b97320)
Ψ - lib/vusb: 2022-06-13 09:18:17 +1000 -- (819dbc1)
Ψ - lib/printf: 2022-06-29 23:59:58 +0300 -- (c2e3b4e)
Ψ - lib/pico-sdk: 2025-04-20 21:24:29 +1000 -- (d0c5cac)
Ψ - lib/lvgl: 2022-04-11 04:44:53 -0600 -- (e19410f8)
Ψ Major problems detected, please fix these problems before proceeding.
Ψ If you're missing dependencies, try following the instructions on: https://docs.qmk.fm/newbs_getting_started
Ψ Additionally, check out the FAQ (https://docs.qmk.fm/#/faq_build) or join the QMK Discord (https://discord.gg/qmk) for help.
**Note on Doctor Output:** Please ignore the `arm-none-eabi-gcc` error. I am using an AVR-based board (ATmega32U4), and the firmware compiles/flashes successfully using `avr-gcc`.
Is AutoHotKey / Karabiner installed
Other keyboard-related software installed
No response
Additional Context
I have identified the problematic code in quantum/action.c:
// Inside process_action() for RETRO_TAPPING
register_mods(retro_tap_curr_mods);
wait_ms(TAP_CODE_DELAY);
tap_code(action.layer_tap.code);
wait_ms(TAP_CODE_DELAY);
unregister_mods(retro_tap_curr_mods); // <--- THIS LINE IS THE CAUSE
source:
|
unregister_mods(retro_tap_curr_mods); |
This unregister_mods call does not check if other dual-role keys are still being held. It forcibly clears the mods, breaking the state for the overlapping Mod-Tap key.
I also observed this behavior in the HID Console logs. When the Layer-Tap key is released, a keyboard_report of 00 | 00 00... is sent despite the thumb key (Row 9) still being physically active (10000000).
qmk_console.log
Describe the Bug
The root cause of this issue is that
quantum/action.cmanages theRETRO_TAPPINGmodifier state using a single global variable (retro_tap_curr_mods).When a Layer-Tap key is tapped while a Mod-Tap key is being held, the
unregister_mods(retro_tap_curr_mods);function at the end of the Retro Tapping process for the second key unintentionally clears the global modifier state. This results in the "killing" of the modifier for the first key, even though it is still physically held down.Steps to Reproduce:
#define RETRO_TAPPING.LSFT_T(KC_SPC)) -> Shift is registered.LT(_LAYER, KC_MINS)) -> Shifted minus is output correctly via Retro Tapping.KC_A) while still holding the first Mod-Tap key.A(Shifted)a(Unshifted - the modifier was cleared by the previous Retro Tapping process).Evidence
I have attached the QMK console log. The log clearly shows a discrepancy between the physical switch state (matrix) and the HID report.
10000000) in the matrix scan throughout the session.20(Shift) to00(None) at line 39.RETRO_TAPPINGlogic inaction_tapping.cunconditionally callsunregister_mods(), effectively "killing" the physically held modifier.Log Highlight:
Keyboard Used
salicylic_acid3/7skb
Link to product page (if applicable)
No response
Operating System
macOS Tahoe 26.31 (a)
qmk doctor Output
Is AutoHotKey / Karabiner installed
Other keyboard-related software installed
No response
Additional Context
I have identified the problematic code in
quantum/action.c:source:
qmk_firmware/quantum/action.c
Line 882 in 1426eed
This
unregister_modscall does not check if other dual-role keys are still being held. It forcibly clears the mods, breaking the state for the overlapping Mod-Tap key.I also observed this behavior in the HID Console logs. When the Layer-Tap key is released, a
keyboard_reportof00 | 00 00...is sent despite the thumb key (Row 9) still being physically active (10000000).