-
-
Notifications
You must be signed in to change notification settings - Fork 39.9k
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
LT too slow #303
Comments
I see where LT is defined as a bitmask but where is it handled? |
Ok, I have observed in more detail what is making me accidentally type characters from the base layer instead of the target layer: If you press the LT-key first, then the key in the target layer and then release the LT first and then the target key (and all of this with rapid speed). |
Unfortunately, that's just the design/implementation of the LT shortcut, which is really just |
Any easy way to change this so that the order of key release doesn't matter? |
Ianguitar, you are using a Layer Tap feature which is handled with the code that eltang linked to. The thing missing from that code is the 'interrupted' feature. When you tap a key, the event that gets processed tells you whether another key was pressed during the timeout period: if so, then the 'interrupted' flag is true. But in the code eltang linked to, there is no check for the interrupted flag. That means, if you press the key and a second key quickly, the code produces the Tap character and then produces the second character for the other button. What you are saying is instead if interrupted is true, you want to switch layers. You can do that with a custom handler. Try this. Define an integer X. In the layout, call F(X), then in fn_actions define [X] = ACTION_MACRO_TAP(X), then in action_get_macro write a block to handle it:
The default handling is probably more popular with people. I am currently writing some code to handle layer-switching keys and I experimented with 'interrupted' and finally settled on code semantically identical to the default code. My problem is because the key in question is my apostrophe key, so when I type it's isn't can't I kept getting symbols from my second layer, which is not what I want. |
@nrrkeene Instead of testing |
To be honest I don't really understand tap count so I haven't monkeyed around with that value. |
That's just a variable that counts the number of taps! You can see where it gets incremented here. |
Like number of taps of that one key? Like if I tapped it twice super fast, the count would be two? Would I get two events (a 1 event then a 2 event) or just one event? |
Yup! There would be two events! |
So if I tap twice super fast I get Event: mouse down, tap 1 If I set the first event tap count to zero, is it zero for all of the remaining three events? |
Nope! The tapping restarts. |
I bet in that situation Ianguitar would expect two characters but if I understand correctly he wouldn't get it if tapping restarts. |
Since I haven't had a look into the details of the firmware: is the snippet above still the recommended approach to try this? |
I'm stuck on this problem again. I have my custom tap-macro handler which either shifts layers or outputs a key. The problem is when I want to use shift in conjunction with the output key (to get double quotes instead of single quotes). Similar to what languitar describes, but the opposite: If I press shift, then my key, then release shift, then release my key. When I do that I get the lower-case symbol but I want the upper-case symbol. I think what is happening is that
If that is right then the problem is that shift is already released before my code receives the two events. I thought I could fix this by using the oneshot feature but it didn't work for me. When I handle the shift event I tried calling set_oneshot_mods(KC_LSHFT) but that caused me to get no symbol output at all. |
I tried that yesterday and it didn't help, but I diffed it against my version and all I saw was something about special keys? What does that do? |
Usually, the tapping code can detect when you try to modify a tap key and retains the modifiers. Any other keys are released before the tapping starts. Your Shift macro is not recognized by the tapping code and is therefore released before the apostrophe is sent. I tried to make the tapping code recognize the keys in those positions as modifiers, but somehow that didn't work. I'll need to look further to see what went wrong. |
Oh! That makes sense. Now I understand that code, I see what you are doing with the keypos_t's. To tell the whole truth I had trouble compiling it yesterday and the 'fixes' I made, I bet, were catastrophic. Now I understand better but I don't have my keyboard to test. I'll let you know in the coming days if this feature works for me - thank you! |
I've tried it again with this tweaked function
and, no, I get the same behavior. I get single-quote instead of double-quote if I release (my simulated version of) Shift before releasing the quote key. |
@nrrkeene I didn't realize that your Shift keys are tap keys themselves. That throws some extra wrenches into the works. Can you explain how they work? I'll try to make an implementation that does not have to use the tapping code. Edit: Your apostrophe key is a tap key too? :O |
I spent some more time reading action.c and action_tapping.c and I haven't yet figured out why my code doesn't have the same behavior as just pressing LSFT. When I change the key to KC_LSFT, though, it functions the way I want my macro to function. So I'm looking for the right way to emulate the LSFT key. Should I set a weak_mod or macro_mod? Should I instantiate a keyevent_t object and call action_exec()? |
My shift keys are not in fact tap keys. I have the tap-macros defined but I call the code with M() not F() so it doesn't go through the tapping code. (Right?) |
Oops, some stuff in your |
I see you are looking at my code carefully -- so am I! An hour ago I took out that tap.count check form line 241 because it was vestigial. I'm out of time today, but I've been looking carefully at action.c in the case ACT_LMODS block. I see in there it add_mods() before calling register_code(), so maybe I need to do that. Unless you think otherwise, I'm assuming that my problem is due to incorrectly using the keyboard API, so I'm not expecting a code change on your part. I'm just trying to understand the platform well enough to use it. |
In your case, |
Since I am still struggling with this: any progress here? ;-) |
I haven't done any work on this for a month. My life has been busy. But I've been using the keyboard every day and the quotation-mark problem is the only beef I have with my layout. eltang asked me when my shift key stops being engaged but I don't think it does. I have my red LED light up when I press shift and it stays illuminated when I do the key combo with my fake shift key and my tap-quote key. Eric, I've never used the 'keyboard viewer" how do I do that? |
@nrrkeene That is extremely strange. Your computer should be printing a quotation mark instead of an apostrophe if it detects that Shift is pressed. |
The shift key is up by the time the keyboard sends the quote character, but On Thu, Jun 2, 2016 at 1:02 PM, Eric Tang [email protected] wrote:
|
So what is the solution? I still struggle with this issue. |
Sorry, might have closed this too soon. Can you try this in your #define LT_CUSTOM 0x7100
bool layer_interrupted = false;
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch(keycode) {
case LT_CUSTOM: {
if (record->event.pressed) {
layer_interrupted = false;
layer_on(3);
} else {
if (!layer_interrupted) {
register_code(KC_V);
unregister_code(KC_V);
}
layer_off(3);
}
return false;
break;
}
default: {
layer_interrupted = true;
break;
}
} You'll need to put the |
Keyboard is at work. I'll try that on Monday. |
I just can't get it this working. Once I set a key to |
Is the rest of your code up to date? This might require some of the more recent changes. If you could share your keymap where you have it implemented, that might help too. One more caveat with this is that it requires you to release the key before typing another, otherwise the second key will get the layer modifier applied to it. |
Right, my fork was too old. Now this snippet works and the behavior seems much better to my mind. Is there any way to get this in a more general form? I'd also need this for other layers and more keys, and also |
Sweet! You can copy and paste it as much as you'd like, but you'll need unique names for the enum custom_keycodes {
LT_CUSTOM = 0x7100,
LT_CUSTOM2,
LT_CUSTOM3
}; Eventually the |
Ok, I was hoping there was a more automatic solution ;-) How do I do this for CTL_T? |
Something like this should work (haven't tested this one, unlike the first): #define CTL_T_CUSTOM 0x7101
bool ctl_t_interrupted = false;
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch(keycode) {
case CTL_T_CUSTOM: {
if (record->event.pressed) {
ctl_t_interrupted = false;
register_code(KC_LCTL);
} else {
unregister_code(KC_LCTL);
if (!ctl_t_interrupted) {
register_code(KC_V);
unregister_code(KC_V);
}
}
return false;
break;
}
default: {
ctl_t_interrupted = true;
break;
}
} |
Ok, one more final thing: with the current |
Not with this implementation - it'd be possible to do something like this though! I believe you'd have to implement a timer of sorts. |
Yes, probably. there is also another minor issue that now the layer led blinks each time i press the key. Maybe these are things to collect for the new implementation of the LT macro. |
That's pretty interesting :) Do you have your full code on github? |
https://github.com/languitar/qmk_firmware/tree/issue-303 The keymap is called languitar ;-) |
Nice! Well this is why your LEDs light up :) it should stay on for as long as your hold the key though. The layer is active from the second you press the key, which is why the LED lights up when you press it. You could add a cycle delay to the LED lighting up if it's super annoying, but then it would always be a little delayed (possibly more annoying). |
If this wasn't implemented as a single keycode, shouldn't it be possible then to postpone the layer activation to the point where the next key is pressed? |
With the existing LT the layer also only becomes active if it is not a single key stroke. Therefore this didn't matter so far. |
Yeap! This is just modelled off of the modifier control, which you usually want to activate as soon as you press the key. |
Ok. maybe I find some time to experiment a bit more how to get this more into the direction I was thinking about. |
Any progress on modeling the default LT this way? |
I ran into this exact issue, I was trying to make my layer keys (e.g. RAISE) act as another key (e.g. KC_SPC) when tapped, and soon realized I could no longer rapidly insert symbols (e.g. releasing RAISE before KC_J would result in "j" instead of "-"). The solution suggested by jackhumbert seems to work fine (thank you for this). For reference, this is how I adapted it to my use case: yroeht@cc78964 Having to implement custom keycodes for this feels cumbersome though. Is there any interest in changing LT's behaviour, or implementing a new alternative? Or is this issue being closed a sign that developing this would not be welcome? |
@yroeht this issue is 3 years old. Take a look at https://github.com/qmk/qmk_firmware/blob/master/docs/config_options.md#behaviors-that-can-be-configured TAPPING_TERM or TAPPING_TERM_PER_KEY |
* fix: italian keymap it quot is redefined * fix: missing deprecated swedish key code * Adds Moonlander to the list of supported keyboards * Sorts list and adds EZ suffix to Planck in Readme * Update Mouse Wheel config Co-authored-by: Florian Didron <[email protected]> Co-authored-by: Erez Zukerman <[email protected]>
* Capture KC_APP properly * Use a lookup table on ev.key
* [Keyboard] Add FL-Esports FL980 * update license headers
I am using
LT
to temporarily switch to other layers and often end up in the situation that I pressed the following key too early, which just results in two keypresses, one from theLT
usual key and one from the other key but in the base layer.Is there any way to speed up the reactions of LT? I don't even need the real toggling into the target layer. Instead something like "if this key is pressed and while being hold, another key is pressed, use the keycode from the target layer" would be sufficient for me.
The text was updated successfully, but these errors were encountered: