-
-
Notifications
You must be signed in to change notification settings - Fork 40k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Core] Add TAPPING_RELEASE_HOLD_TERM option for Tapping Force Hold #15508
Conversation
a463422
to
a5dcd01
Compare
cb469ec
to
36d36c1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code looks good to me but in my opinion, the logic should be reversed. When tap-then-holding a key quickly, I would prefer to force the hold (e.g. writing the word "camelCase" with L as a shift modtap). If I want to auto-repeat a key, that's a much more deliberate action so that should be the thing that requires TAPPING_FORCE_HOLD_TERM
to pass. It would also make more sense in regards to the proposed name : "The tapping force hold term is the time window in which the hold is forced".
However, I can see how my suggestion could be problematic in an example scenario like this:
Assume I have LALT_T(KC_A)
in my keymap. Let's say I typed the letter 'a' in a text editor and I then got up and left the room for 10 minutes. When I come back, I want to Alt+Tab out of my text editor so I hold LALT_T(KC_A)
but I get a bunch of spammed A's instead.
This could be solved by a time-out but that would further increase the complexity of the already very complex tap-hold mechanics.
docs/tap_hold.md
Outdated
#define TAPPING_FORCE_HOLD_TERM TAPPING_TERM - 100 | ||
``` | ||
|
||
When a tap-hold key is held again after tapping within `TAPPING_FORCE_HOLD_TERM` in milliseconds, force hold will be interrupted. This will provide user the ability to deliberately override force hold with quick tap and hold action to auto-repeat a key. `TAPPING_FORCE_HOLD_TERM` must be less than `TAPPING_TERM` or tapping force hold will be disabled. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When a tap-hold key is held again after tapping within `TAPPING_FORCE_HOLD_TERM` in milliseconds, force hold will be interrupted. This will provide user the ability to deliberately override force hold with quick tap and hold action to auto-repeat a key. `TAPPING_FORCE_HOLD_TERM` must be less than `TAPPING_TERM` or tapping force hold will be disabled. | |
When a tap-hold key is held again after tapping within `TAPPING_FORCE_HOLD_TERM` in milliseconds, the hold action is selected. If you want to auto-repeat the keycode associated to the dual-role key, you'd need to tap the dual-role key and then wait for the `TAPPING_FORCE_HOLD_TERM` to expire before holding it. | |
`TAPPING_FORCE_HOLD_TERM` must be less than `TAPPING_TERM` or else tapping force hold will be disabled. |
quantum/action_tapping.c
Outdated
(!get_tapping_force_hold(tapping_keycode, keyp) || WITHIN_FORCE_HOLD_TERM(event)) && | ||
# elif defined(TAPPING_FORCE_HOLD_PER_KEY) && !defined(TAPPING_FORCE_HOLD_TERM) | ||
!get_tapping_force_hold(tapping_keycode, keyp) && | ||
# elif !defined(TAPPING_FORCE_HOLD_PER_KEY) && defined(TAPPING_FORCE_HOLD_TERM) | ||
WITHIN_FORCE_HOLD_TERM(event) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(!get_tapping_force_hold(tapping_keycode, keyp) || WITHIN_FORCE_HOLD_TERM(event)) && | |
# elif defined(TAPPING_FORCE_HOLD_PER_KEY) && !defined(TAPPING_FORCE_HOLD_TERM) | |
!get_tapping_force_hold(tapping_keycode, keyp) && | |
# elif !defined(TAPPING_FORCE_HOLD_PER_KEY) && defined(TAPPING_FORCE_HOLD_TERM) | |
WITHIN_FORCE_HOLD_TERM(event) && | |
(!get_tapping_force_hold(tapping_keycode, keyp) || !WITHIN_FORCE_HOLD_TERM(event)) && | |
# elif defined(TAPPING_FORCE_HOLD_PER_KEY) && !defined(TAPPING_FORCE_HOLD_TERM) | |
!get_tapping_force_hold(tapping_keycode, keyp) && | |
# elif !defined(TAPPING_FORCE_HOLD_PER_KEY) && defined(TAPPING_FORCE_HOLD_TERM) | |
!WITHIN_FORCE_HOLD_TERM(event) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code looks good to me but in my opinion, the logic should be reversed.
I agree that your logic solves a different use-case. This PR solves a personal use-case where slow same finger bigram on mod-tap keys are prevented from auto-repeating unless they are deliberately double-tap-held.
That said, logic for TAPPING_FORCE_HOLD_TERM
can be reversed by introducing another flag/definition (in a subsequent PR) to swap that if
condition.
In any case, I don't think we should use "double-tap" to describe the action:
Because a "tap" means pressing and releasing the key while in this scenario, you tap once and follow the tap with a press of the key (that you keep held down for a relatively long time). |
I had these in my notes as well:
|
dd014ad
to
1dc9ec4
Compare
1dc9ec4
to
d3b9131
Compare
Thank you for your contribution! |
Co-authored-by: Drashna Jaelre <[email protected]>
Please add to the testing suite. Eg, see |
I hope that's the right syntax for a test case. |
4c2d404
to
75595fe
Compare
IIRC, mods cause issues with the testing stuff. using layers may be ... better. |
The unit test |
2856e79
to
16914bb
Compare
16914bb
to
d7aa032
Compare
d7aa032
to
db8443a
Compare
I'm being annoying but do you really want to keep the name "TAPPING_RELEASE_HOLD_TERM"? It sounds like "the time window in which you must tap (i.e. press and release) the key in order to 'release' (i.e. send a key-up event) of the 'hold' action of the dual-role key". That's not really its true meaning. I like "DOUBLE_PRESS_AUTO_REPEAT_TERM" because you can infer from the name that it is "the time window in which you must double press — as opposed to a double tap which is a different thing — the key in order for it to auto-repeat". While thinking about it, I also came to realise that the current default behaviour is akin to As for code size considerations, the compiler can easily infer that |
You are not being annoying—the point of PRs is to solicit review and feedback. To be honest, this simple change is a partial implementation of a feature I use in ZMK. What you proposed above is exactly how |
Oh neat, I like how they generalised the idea even further and found a way to reduce visual lag along the way. |
As it stands now, the presence of
I'm in favour of replacing |
@precondition Iteration of this feature is now in #17007 |
Description
This change adds
TAPPING_RELEASE_HOLD_TERM
option to the Tapping Force Hold function. It will allow force hold to be interrupted when user holds a tap-hold key (quickly) after tapping withinTAPPING_RELEASE_HOLD_TERM
duration in milliseconds.When used together with
TAPPING_FORCE_HOLD_PER_KEY
, it will only apply to tap-hold keycodes define by theget_tapping_force_hold
function. The value must be less thanTAPPING_TERM
, or Force Hold will be disabled completely.Test cases
TAPPING_FORCE_HOLD
:TAPPING_FORCE_HOLD
only:TAPPING_FORCE_HOLD_PER_KEY
:get_tapping_force_hold
should never trigger auto-repeat.TAPPING_RELEASE_HOLD_TERM 100
:TAPPING_RELEASE_HOLD_TERM
to50
should make them even harder to trigger.TAPPING_FORCE_HOLD_PER_KEY
andTAPPING_RELEASE_HOLD_TERM 100
:get_tapping_force_hold
should trigger auto-repeat with quick deliberate action.TAPPING_RELEASE_HOLD_TERM
to50
should make those keycodes even harder to trigger.TAPPING_RELEASE_HOLD_TERM
values.Types of Changes
Checklist