Skip to content
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

Add retro tapping support #55

Merged
merged 3 commits into from
Jan 25, 2024
Merged

Conversation

akaralar
Copy link
Contributor

@akaralar akaralar commented Jan 7, 2024

I tried to add support for features where a key is held and then released without pressing another key to fix #51

In this PR, we try to circumvent the Achordion timeout if no other keypress happens between the press and release of the tap-hold key. When a tap-hold is pressed and released without the user pressing any other key in between, Achordion normally waits until the timeout finishes to settle the key as held and to send the events back to QMK to be processed. With this PR, If no other keypress happens until the tap-hold key is released, we simulate a hold and then release event to make Achordion play nice with these features.

When a retro key is released during the state is UNSETTLED,
Achordion doesn't do any plumbing back and as a result the retro key is
not sent.

- If retro tapping is enabled, the code checks whether the key is a mod
tap or a layer tap key.
- If per key retro tapping is enabled the code checks for the function
that should have been defined in a user's keymap.c to check if retro
tapping is enabled for the key. If the function not defined the weak
overload returns false by default.

If the key is determined to be a retro key, the same plumbing is applied
as when the state is settled to be HOLDING, allowing the retro key to be
sent correctly.
Copy link
Owner

@getreuer getreuer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your contribution!

@@ -257,4 +264,10 @@ __attribute__((weak)) uint16_t achordion_streak_timeout(uint16_t tap_hold_keycod
}
#endif

#ifdef RETRO_TAPPING_PER_KEY
__attribute__((weak)) bool get_retro_tapping(uint16_t keycode, keyrecord_t *record) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this needed? Core QMK has a weak definition of get_retro_tapping() already:
https://github.com/qmk/qmk_firmware/blob/0c160e1fbafbf477c74e64fd8ab9a9121eb0f42a/quantum/action.c#L63-L67

Duplicate definitions of a function normally cause a linking error. I'm not sure how that goes for weak definitions.

Come to think of it, it's interesting that a weak definition exists at all. Arguably, a user who set RETRO_TAPPING_PER_KEY could be expected to make a (strong) definition of get_retro_tapping(). So the value in having a weak definition is only in the edge case of a mistaken configuration where that is forgotten.

The function get_retro_tapping() should be accessible in this file: achordion.h includes quantum.h, which in turn includes action_tapping.h where the function is declared.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right! This is removed in the newer version of this PR, since we no longer need to check the retro tapping key status.

// The active tap-hold key is being released.
if (achordion_state == STATE_HOLDING) {
if (achordion_state == STATE_HOLDING || is_retro_key) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is clever! It's a simpler change than I first expected.

I think the idea with the change on this line is that:

  • QMK core has determined the key as held, but Achordion is unsettled.
  • From QMK core's point of view, the key is held and no other keys have been pressed.

So by simply plumbing the hold release event, the subsequent retro tap handling in this condition will tap the tapping keycode. Is that accurate?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep this is accurate, and your explanation with the two bullet points is actually the core idea of the newer implementation. This was more specific for retro tapping only, the newer version supports all kinds of features where no other keypress happens between the press and release of the key.

@getreuer
Copy link
Owner

@akaralar thank you so much for this contribution! I very much appreciate this support for retro tap, this rounds out Achordion nicely.

The implementation looks good. Just a couple minor comments.

@akaralar
Copy link
Contributor Author

@getreuer Thanks for the review! I have since changed the implementation to be more generic in my userspace. As far as I understood the problem was that when there isn't a second keypress (Retro tapping, retro shift, autoshift, custom macros for hold action all fall in this category) Achordion holds back the hold event for TAPPING_TERM + get_achordion_timeout amount of time. I think this is less than ideal because we don't actually need Achordion when there isn't a second keypress. Let me push those changes to see if you think they would fit in this repo.

@akaralar
Copy link
Contributor Author

akaralar commented Jan 22, 2024

@getreuer I pushed a new commit, changed the PR description and added comments to the code to explain the changes, let me know what you think. Thanks for taking the time!

@wolfwood
Copy link

wolfwood commented Jan 23, 2024

current version works for me 👍

hitting a second key on the same hand while holding the first immediately resolves both as taps.

@getreuer
Copy link
Owner

@akaralar I agree with your points! I'll merge the PR in its current form. Thank you again for your contribution!

@getreuer getreuer merged commit 62eff1c into getreuer:main Jan 25, 2024
1 check passed
@akaralar
Copy link
Contributor Author

@getreuer glad I could help! thank you again for making such a great library and making home row mods tolerable 😃

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug] Achordion disables RETRO_TAPPING
3 participants