-
Notifications
You must be signed in to change notification settings - Fork 71
Firngrod/passive timeout #1436
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
base: master
Are you sure you want to change the base?
Firngrod/passive timeout #1436
Conversation
| COMMAND = set secondaryRole.defaultStrategy { simple | advanced } | ||
| COMMAND = set secondaryRole.advanced.timeout <ms, 0-500 (INT)> | ||
| COMMAND = set secondaryRole.advanced.timeoutAction { primary | secondary | none } | ||
| COMMAND = set secondaryRole.advanced.timeoutType { active | passive } <defines whether the secondary role should perform it's timeout action when the timeout is reached or when the key is released after having been pressed beyond timeout without triggering secondary> |
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.
Naming is obviously up for debate. I see passive as the timeout passively change the primary action while active actively executes the timeout action. It is entirely reasonable to see it as passive as timeout executes passively while you do nothing and active is that the timeout executes on the activity of release. Probably different wording is in order.
| set secondaryRole.advanced.timeoutType passive | ||
| set secondaryRole.advanced.timeoutAction none |
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.
These are my settings, don't know if they should be recommended. The idea has been described on the Forum. Basically, mods only activate in combinations with a non-mod, otherwise not. If I need to activate a mod (combo) on it's own, I will activate it with a secondary key on the other half, but hold that key long enough to get a none timeout action. With active secondary timeout, I would definitely recommend these settings still.
| ``` | ||
| set secondaryRole.defaultStrategy advanced | ||
| set secondaryRole.advanced.timeout 500 | ||
| set secondaryRole.advanced.timeout 200 |
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 text below states 200 ms. On second thought, I should update the text instead. 200 ms timeout is aggressive.
|
|
||
| void PostponerQuery_FindFirstPressed(postponer_buffer_record_type_t** press, postponer_buffer_record_type_t** release, | ||
| key_state_t *opposingKey) | ||
| void PostponerQuery_FindFirstPressed(const postponer_buffer_record_type_t** press, const key_state_t *opposingKey) |
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.
Release doesn't matter for the trigger on press and vice versa. We only actually need the time of the event to enforce safety margin. I don't know if we should reduce the function to just return a timestamp?
| if ((*press)->event.type == PostponerEventType_PressKey | ||
| && (*press)->event.key.keyState == (*release)->event.key.keyState ) { | ||
| const postponer_buffer_record_type_t * const press = &buffer[POS(j)]; | ||
| if (press->event.type == PostponerEventType_PressKey |
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.
Here we still need to find the press to ensure that it's there.
| static bool currentlyResolving = false; | ||
|
|
||
|
|
||
| static key_state_t *previousResolutionKey; |
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.
These values were only used for doubletap, so save some RAM and cycles there
| } | ||
|
|
||
|
|
||
| #define RESOLVED(resolution) KEY_TIMING(KeyTiming_RecordComment(resolutionKey, resolution, __LINE__)) \ |
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.
Not quite as readable output as before, but a lot easier to use these macros.
| #define AWAITEVENT(timeout) sleepTimeoutStrategy(timeout); \ | ||
| return SecondaryRoleState_DontKnowYet; | ||
|
|
||
| static secondary_role_state_t resolveCurrentKeyRoleIfDontKnowTimeout() |
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.
Don't try to compare the new lines to the removed ones. The entire thing is rewritten.
| bool actionKeyWasPressedFirst = actionPress != NULL && dualRoleRelease != NULL && actionPress->time <= dualRoleRelease->time - Cfg.SecondaryRoles_AdvancedStrategySafetyMargin; | ||
| // see if we have an activating key event | ||
| const postponer_buffer_record_type_t *actionEvent = NULL; | ||
| const key_state_t * const opposingKey = acceptTriggersFromSameHalf ? NULL : resolutionKey; |
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.
Heavy const syntax
| if (actionEvent != NULL) { | ||
| RESOLVED(SecondaryRoleState_Secondary); | ||
| } |
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.
This was so anticlimactic to write once I got here.
| } | ||
|
|
||
| // otherwise, keep postponing until key action | ||
| return SecondaryRoleState_DontKnowYet; |
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 user can fill the queue while holding indefinitely. They will loose keystrokes. I'm okay with that.
|
Btw., a bit of commit message philosophy, since I am doing git archeology right now: it would be nice if I could tell straight away what part of the codebase a commit belongs to just from the message. In the case of your PRs, it might mean just prefixing messages with a short codeword like "hrm". E.g., "hrm: Embarrassing". This is just a general feedback. No need to rebase anything ;-). |
|
(I am guilty too though: "pick c6198af # Reword some code.".) |
|
Makes sense. Where I work, we do the related story prefix, so I always do a double take anyway while I try to remember what the story number was. Might as well harness that. :) |
I added a new feature to do timeout passively, as I mentioned on the forum, although I had not fully realized yet that it could be implemented this simply. Simply put, instead of applying the timeout action when timeout is reached, it will apply the timeout action once the key is released. If timeout action is primary or secondary, that will be a tap of the key, if timeout action is none, it will do nothing, The big difference here is that the key can be held for an arbitrarily long amount of time and still be used in a combo.
The main motivator is that I often press a secondary key to do a combo, then realize that it's on the same half. Now I can just wait for half a second and release without my screen drowning in menus and without having to time my combos tightly.
It also allows the timeout to be effectively disabled by setting passive timeout to primary.
One downside is that now we have some setting combinations which make little sense in practice. One that I can think of is passive timeout to secondary layer switch. It would effectively be identical to passive timeout to none. Maybe that could be added as a feature if someone wants it.
Also rewrote the main resolver to a fail fast style which removes a lot of ambiguity of where options apply.
EDIT: Oops, I used a word I didn't understand. It's not Fail Fast, it's just that I try to quit the function using as little info as possible. What do I know of programming terms, I never went to programming school.
This PR fixes everything mentioned in #1421