qmk-keymap
qmk-keymap copied to clipboard
[Bug] Double mod keypress when using eager mods
Hi, I'm using manna harbours miryoku layout on skeletyl keyboard + achordion library to fix some issues with home row mods. I'm quiet happy with current configuration except the eager mods feature from achordion library.
OS: archlinux. using gmk tool version: 1.1.2 I have custom branch based on commit 31a9d2d00dc732ca29be2213dbf915d6f6ffc76d
Problem: When I tap and hold WIN(also alt,win,shift are affected) key, the event is quickly registered by OS as hold(I can move/resize my window by mouse dragging). But after couple of milliseconds(~200-300) there is second hold event sent to the OS, which breaks current dragging/resizing of the window and I need to mouse click and drag/resize window again.
I also provide screen record of xev output which demonstrates the problem little bit.
https://github.com/getreuer/qmk-keymap/assets/755186/6a239179-3bc0-4fe8-bb54-3ae45ca7bf35
Information
Do the keys involved use any of the following features?
- [* ] Achordion (from this repo)
- [ ] Auto Shift
- [ ] Combos
- [ ] Key Overrides
- [* ] Mod-tap or Layer-tap keys
- [ ] Other custom userspace code:
@JanValiska thank you for the detailed bug report! Your explanation and video make the problem very clear.
Problem
In hindsight, I can see why this defect occurs. The sequence of events:
- The mod-tap key is held.
- QMK passes the hold press event to Achordion. Achordion applies the eager mod.
- After
achordion_timeout()
(default 1000 ms), Achordion settles the key as held. In doing so, it clears the eager mod and plumbs the hold press event. Specifically in this code. - The hold press event sets the mod again.
From the computer's point of view, the mod is held, briefly released, then held again. This release would be a few milliseconds, the time needed for QMK to send another keyboard report to the computer.
Sketch of potential solution
I don't know when I will have a chance to fix this. I'd like to at least describe a potential solution, in case someone is willing to pick this up.
The essential problem is this hand-off from Achordion to QMK core in holding the eager mod. To avoid having a hand-off and to ensure the mod is held continuously, either Achordion or QMK core, and not both, should hold the mod. I'd prefer the latter if possible in principle, since deferring work to QMK is generally a good approach for interoperability with other features.
QMK core holding the mod
- The mod-tap key is held.
- QMK passes the hold press event to Achordion. Achordion allows the event to continue immediately to eagerly apply the mod.
- If Achordion later settles the key as tapped, it plumbs the hold release, to clear the mod, then plumbs the tap event. If instead Achordion settles the key as held, this is a no-op.
Achordion holding the mod
- The mod-tap key is held.
- QMK passes the hold press event to Achordion. Achordion never plumbs events for this key, rather it handles the mod directly. The eager mod is applied.
- When the key is released or settled as a tap, Achordion clears the eager mod.
@JanValiska, I just pushed https://github.com/getreuer/qmk-keymap/commit/744119420424f567bc937075fadd9772867d472e to fix the mods hand-off problem in how eager mods are handled:
-
When an eager mod
MT
is settled as held, Achordion continues to hold the mod. The hold event is no longer plumbed to subsequent handlers. -
When an eager mod
MT
is settled as tapped, then Achordion clears the mod, now using flashing mods neutralization as suggested in issue 68. A tap event is then plumbed to subsequent handlers.
Thank you for your help in investigating this issue!
A heads up: commit https://github.com/getreuer/qmk-keymap/commit/744119420424f567bc937075fadd9772867d472e introduced a bug, so don't use that one. Please use commit https://github.com/getreuer/qmk-keymap/commit/37586e3de2de15b915855ecc866b46cbfbd63d23 instead.