dariogoetz / keyboard_layout_optimizer

A keyboard layout optimizer supporting multiple layers. Implemented in Rust.
https://dariogoetz.github.io/keyboard_layout_optimizer/
GNU General Public License v3.0
92 stars 18 forks source link

Support combos #44

Open rayduck opened 2 years ago

rayduck commented 2 years ago

Combos are a feature in QMK/ZMK where two or more keys pressed in a small window of time results in a specific output. For example, looking at the "mine" layout on the webapp, a combo may be hitting both G+Y to output ß. The keyboard yml suggests that the total keycost will be 5+14 < 25 and there seems to be room for significant reductions in costs. Another example may be changing an u to ü when combo'd with another key. In my experience, combos never misfire and are easy to press without disrupting the flow (esp. middle and ring finger combos since those fingers like to move together).

I'm not well versed in rust at all, hence I can't comment much about the implementation, but combos seem straight forward as a key with 2+ fingers in 2+ positions. Single finger bigram penalties will then be extended to avoiding bigrams that share the same fingers. I suppose just having all two finger combos as extra key positions will allow the simulated annealing algo to choose which ones they like.

This seems to be the best layout optimizer project that I have found and is actively developed. So it will be great if combos can be incorporated into the layouts!

dariogoetz commented 2 years ago

Hi rayduck, Thank you for the interest in the project. I have heard about combos, but never actually tried them myself.

I believe that implementing combos in the evaluator/optimizer is, in theory, possible. Having thought about it a little, it will not be that easy however. The current evaluator takes higher layers that are accessed by modifier keys into account. These behave somewhat similar to the combos that you describe as several keys need to be pressed simultaneously. (The difference is that modifiers are usually pressed before and released after the other keys.) However, in the current implementation, a "modified symbol" is not considered by itself as a separate "two-finger-key". Instead, higher layer symbols (those requiring a modifier) are "expanded" into the modifier and the other key, e.g. A -> [shift, a].

For bigrams, this means that both the modifier and the other key are to be considered "consecutive". For instance for typing Ab, we expand this into [shift-a, shift-b, a-b]. For trigrams this becomes even more complex. This way, the evaluation is in the end only concerned with keys on the base layer.

In the case of combos I believe that something similar would need to be done. With a slight difference that both keys are treated symmetrically (modifiers are treated somewhat special in our code).

Now to actually implementing this. The project is still somewhat maintained (in particular by the awesome contributions of @Glitchy-Tozier ). I myself, however, find less and less time to spend on it (my family taking priority), so that I won't be able to carry out the implementations myself. I hope that @Glitchy-Tozier will be able to do so, but as this topic touches some quite technical parts of the code, I would understand if that turns out not feasible.

Glitchy-Tozier commented 2 years ago

In the case of combos I believe that something similar would need to be done. With a slight difference that both keys are treated symmetrically (modifiers are treated somewhat special in our code).

I had the same thought!

Now to actually implementing this. The project is still somewhat maintained (in particular by the awesome contributions of @Glitchy-Tozier ). I myself, however, find less and less time to spend on it (my family taking priority), so that I won't be able to carry out the implementations myself. I hope that @Glitchy-Tozier will be able to do so, but as this topic touches some quite technical parts of the code, I would understand if that turns out not feasible.

Unfortunately, I'm not available for similar reasons as @dariogoetz.

  1. I've never tried out (or felt the need to try out) special QMK-features, so my motivation is not at 100%
  2. There's a lot going on at the moment, so I'm not able to put time into this issue.

We can leave the request up though, for other people who discover this project may be able to implement this functionality.