As you may have noticed, we recently made some changes to how certain multi-function keys work. We didn't make any big announcements about it because we really thought it would go nearly unnoticed by most and appreciated by a few, but that's not quite how it went down, so let's talk about what happened.
The sub-categories of multi-function keys
As you may or may not know, there are actually two different kinds of multi-function keys you can create in Oryx: dual-function keys and tap dance keys. Despite some overlapping use cases, they work quite differently.
Dual-function keys have strict requirements. They need a simple, standard function (like a letter or number) on tap and either a modifier or a layer switching key on hold. No other combination of functions can be used to create a dual-function key.
Tap dance keys are more freeform. You can assign lots of different functions to them, and they work with a variety of combinations of taps and holds. Our specific implementation of four possible actions per key is actually only one way tap dance can work. There are tons of other possibilities if you want to dig into the official QMK docs.
Since these two kinds of keys fill a similar niche, Oryx doesn't make you pick them in advance. You just tell it what functions you want on a key, and it automatically configures it as a tap dance or a dual-function key for you. If you turn on the "Advanced view" in Oryx, you'll see dual-function keys get a little "D" label while a tap dance key will get a "T" or “+" depending on how many functions you assigned to it. Easy.
Where is gets a little bit complicated is tap dance keys with two functions. These keys look just like dual-function keys, but they don't always act like them. To explain why, we have to dig into the inner workings of these keys a bit.
How multi-function keys work
If you step back and really think about it, how would you make a multi-function key actually function? It's kind of a tricky problem. How do you differentiate between the various actions a user can take when all a key can do is go down and go up?
Some smart people thought about this when working on QMK, and they came up with a solution: tapping term.
The tapping term is a set period of time that begins when a multi-function key is pressed. During this period of time, the firmware is waiting to see what the user does to determine which of the multiple functions associated with that key it should send.
Dual-function keys can be handled simply and elegantly. If you release a dual-function key within the tapping term, it's clear you meant to tap the key because that's what you did. The key went down and it went up — that's a tap. If the key is still held at the end of the tapping term, well, you must have meant to hold it. Because there are only these two options, the tapping term can be cut short and the tapped action can be sent immediately on key up (i.e, when you let go of the key).
With the flexibility of tap dance keys comes an important question, though: How should the tapping term work? If there is the potential for other actions besides just tap and hold, then the dual-function key method can't work anymore.
The solution is simply waiting. When a tap dance key is pressed, the tapping term begins just like a dual-function key, but it is never cut short. If the firmware sees a key up event, it knows you tapped the key once, but you could be tapping it again, so it will always wait the full tapping term to make sure you have time to input the action you're trying to input.
The change we tried
This is how our tap dance keys and dual-function keys worked in Oryx since tap dance keys were introduced. It was fine for the most part, but things got weird when setting up a variety of two-function keys where some would end up as dual-function keys and some would end up as tap dance. The dual-function keys worked one way, but the tap dance keys worked another, and it was noticeable.
Recently, we decided to try changing two-function tap dance keys to work just like dual-function keys. With this change, no matter what you assigned to a two-function key, releasing it would cut the tapping term short and send the tapped action, and holding it would send the held action. Two-function tap dance keys would also now respect the "Permissve hold" setting just like dual-function keys. Turning Permissive hold on would make these kinds of keys prefer the held action and turning if off would make them prefer the tapped action no matter what. Simple. Consistent. Great.
The complicated problem
Well, not so great, actually. Some users quickly noticed something was different, but not in any of the ways we anticipated. There are even more quirks to tap dance keys and how they interact with the tapping term. We had heard about the negatives of these quirks from users for years, but the positives went unmentioned because it seemed like things were working well. Why ask about something that's working?
Explaining the specific quirks and interactions here would make this article much longer. If you're really interested in the specifics, you can always email us. Long story short though, the change that fixed issues for some users brought up new, significant issues for other users who were already used to the old way.
We debated about what to do about this. After all, the new behavior was more consistent. If we were launching Oryx today, there wouldn't have been much question that it was the correct thing to do. But, Oryx is not launching today. There are already thousands of layouts and users who were used to how things were. So, we talked about it and decided to change our minds.
We're changing things back with a twist
We're doing something we don't often do: We're having it both ways. We are going back to the old behavior, but we are adding a toggle in Oryx's settings for this new behavior. It's called "Prefer tap action in Tap-Hold tap dances" and you'll find it in the "Tapping" sub-section. This setting is enabled by default (giving you the old behavior) and you can disable it to get the new behavior.
What this means is, if your layout was working a certain way that you liked, just recompile and it will be back to normal. If you don't have multi-function keys that you're used to using, or you didn't like the old behavior, just toggle this setting off and your multi-function keys with two functions will work the same way regardless of what you assign to them. "Permissve hold" will also affect all two-function keys with this setting off instead of dual-function keys only.
In general, we like to be opinionated. Oryx has always been about delivering a streamlined version of the customization that's possible with QMK. That means we include some things and say no to others; we take a stance on what using layouts created in Oryx ought to be like.
That said, this is one case where taking a stance either way feels wrong. We get plenty of confused emails about the original multi-function key behavior, and after making this change, we got plenty of confused emails about the new behavior. Ultimately, multi-function keys are a complicated feature, but they're important to us and you. We want them to feel good to use whether you already have a setup you like or are just getting started with them.
So, fittingly, we've decided to make multiple-function keys multiple-choice.