Author Topic: Custom multi-layer, dual-mode layout around basic hand positions - experiences?  (Read 6272 times)

0 Members and 1 Guest are viewing this topic.

Offline daneb

  • Thread Starter
  • Posts: 23
Hi,
I am thinking about creating my custom multi-layer layout and would like to ask for your experiences, ideas, warnings. My idea is having all important symbols, diacritics, navigation, maybe even ctrl/alt keys easily reachable from "basic" hand positions (e.g ASDF and +-1 row around for left hand) - I am not speaking now about basic alpha-num layout (qwertz in my language), it would stay the same. I am speaking about modifers, symbols, diacritics, navigation....

LAYERS

Basic layer will stay the same (qwertz which is default in my language + numbers in top row), but I would like to create new layers which would move symbols, parenthesis etc towards home row (to keys around ASDF JKL; clusters), instead of using distant keys (my language also heavily uses diacritics so I have even more characters to add to layout). For example:

- there could be layer 2 with parenthesis, e.g. [()] parenthesis would be under JKL; keys, <> under NM etc.
- layer 3 would move some other important symbols under the same easily reachable keys - JKLNMUIO etc.
- layer 4 could be used for navigation, vim-like: hjkl for arrows etc

DUAL-MODE KEYS AS MODIFIERS

And now I would like to switch to these layers using dual-mode keys = keys which will function normally as alphas, except when pressed together with other keys they would work as modifiers. I do not want to use normal modifiers from ergonomical reasons - reaching for them. Plus I would like to leave normal modifiers intact so as not to disrupt predefined key combos with many programs.

- I would like to use keys, which are easily reachable, but not used heavily in my language, as I am aware that these letters will appear at the screen with some short delay - not until release of the button (because of evaluating whether I will use key combination or I want to use this key alone). It is possible to program Karabiner in this way and I tested it and delay is almost  not noticeable and I can write normal text without hassle. So no problem here.

- I would like to use F G and H (maybe ; ) for such dual-mode modifiers/keys and these keys would thus switch to layer 2, layer 3 etc. (if used with combination with other keys)
- I am aware that from ergonomic reasons I should not press two keys with one hand, so layers would be created only in one half of the keyboard (e.g. layer switched by F key would be only in right side, so I can push F by left hand and "layered" keys by right hand)

MY QUESTION

It can be done in Karabiner, by "complex modifications", no problem for me how to do it technically. (I want to use it as default layout in all my apps, I know that e.g. in emacs you can define something similar, but that would not be solution for me)

So my question is not about how to implement it but if it is good idea/if you have some experiences with similar solutions or if I omit something important/do not see something. Or are there already similar, ready solutions with layers and dual-mode keys?

Thank your for your comments

EDIT: I have noticed that similar discussion already runs here: https://geekhack.org/index.php?topic=41685.0;all . I will check posts there so you do not have to repeat what is written there. But if you have special tip for my situation, I will be glad if you share it here.
« Last Edit: Wed, 24 October 2018, 13:27:57 by daneb »

Offline ErgoMacros

  • Posts: 313
  • Location: SF Bay Area
L
« Reply #1 on: Thu, 25 October 2018, 00:10:45 »
Keeping in mind that I've thought about this, but never tried it.
I was going to put the modifiers under the home row.

I was thinking of using (Mac):
  G or H for "Hyper-function"
  F or J for Cmd
  D or K for Option
  S or L for Control, and
  A or ";" for Shift

Although these would be mapped to two distinct layers, say #1 and #2, everything on layer 1 & 2 (except 5 of the home row keys on each side) would be the same.
So, in your case if you wanted diacritics on the Q thru P keys both layers would have the same diacritics on each key.

Usually if you wanted the diacritic under the Q you'd hold "H" (hyper-function) and tap Q. You wouldn't want to hold "G" and tap "Q" anyway so it wouldn't matter.

Something like this: http://www.keyboard-layout-editor.com/#/gists/87c93bb700d98b6c57a7b90309ba09e5



« Last Edit: Thu, 25 October 2018, 00:12:41 by ErgoMacros »
Today's quote: '...“but then the customer successfully broke that.”

Offline vvp

  • Posts: 886
It may not work as well as you hope especially when you increase your typing speed.
See this message: https://geekhack.org/index.php?topic=95683.msg2617113#msg2617113

Edit: Post your experience if you try ti.
« Last Edit: Thu, 25 October 2018, 04:06:33 by vvp »

Offline ErgoMacros

  • Posts: 313
  • Location: SF Bay Area
Thanks for the reply and pointer. I type pretty slowly so I may get "lucky."  ;)
Will report if/when I get around to it.
Today's quote: '...“but then the customer successfully broke that.”

Offline geek128

  • Posts: 8
It may not work as well as you hope especially when you increase your typing speed.
See this message: https://geekhack.org/index.php?topic=95683.msg2617113#msg2617113

When I first tried QMK with mod-tap on the home-row a year ago, it was unusable. There were quite some changes since then... and there are rumors, it's now ok.

Though, I already coded my own mod-tap for ctrl/alt/win(/shift) on my home row. My implementations requires a short delay to get the modifier - to keep it from interfering with regular use. This disqualifies it for 'fast' modifieres: For Shift + symbol layer I use thumb keys with oneshot. Shift on home-row is just for strange hotkeys/modifier combinations.

This allows me to have max 1 key travel distance. BTW: For historic reasons my keymaps have other keys mapped.

summary: https://github.com/rclasen/qmk_firmware/blob/master/readme.md
example keymap: https://github.com/rclasen/qmk_firmware/blob/master/keyboards/ergodox_ez/keymaps/rclasen/keymap.c

Offline daneb

  • Thread Starter
  • Posts: 23
Thank you for your replies. So I would like to experiment more with times/delays of key-down and key-up events to be able to set the correct threshold to distinguish between modifier/normal role of the key. Do you know if any utility/app exists (for mac) which would map key-down / key-up events in real time? = which would also log the exact time of key-down / key-up events? Karabiner shows events and key codes, but not exact times when it happened. If I could analyse such time log - what is normal use and what normal latencies/overlaps are, I might be able to set the correct thresholds. (I am on mac) Thanks for your tips

Offline daneb

  • Thread Starter
  • Posts: 23
So after experiment a bit I seem to have a solution. It works smoothly even with quick typing.

PROBLEM

If you would like to distinguish just based on if there is key pushed alone (to fire original key code) versus if it is pressed in combination with other key (to fire modifier key code) you will encounter a problem with quick typing. I have analysed that very often you push subsequent key without releasing previous key, e.g. when writing "hello" your keycode sequence can be something like (uppercase = key down code, normal = key up code): HhELelLOlo - note that after pressing "E" you also press "L" before releasing "E" (situation noted here as "e"). In case you would have "E" programmed as dual modifier, lets say "shift", it would erroneously send code as "shift L" and you would obtain "hLlo".

SOLUTION

Solution is to change algorithm how to identify key as dual mode versus normal mode. You have to 1) evaluate key combination ( = keys pressed simultaneously) as for strictness/order of appearance. Because there is never situation during normal typing, that you would release some keys out of order - e.g. you never type like HhELleLlOo - note "ELle" sequence where you would release next letter ("L") before you release previous letter "E" - that never happens during  normal typing (or - it never happened to me even when I tried). So that could be the crucial difference:

- any simultaneous sequence of two keys (simultaneous = pressed at one moment) with strict order and released in the same order should be encoded as original letters (HEhe as "he")
- any simultaneous sequence of two keys pressed in one order but released in reverse order should be encoded as modifier plus original key (if applicable, if this key is dual modifier) - (HEeh as "H as modifier, e.g. shift" + "e")

It is already well implemented in Karabiner for mac. Please consult there "complex modifications" and look at "VI mode, revision 5" - it is exactly what we want. It is also necessary to program the situation when key is pressed alone (key which should work with our modifier) and modifier is held down in between (not pressed moment before, but held down). It is described also in Karabiner documentation - by using variables. Please consult https://pqrs.org/osx/karabiner/json.html#virtual-modifier

As my code is quite complex, I will show here just one small part - code for changing "J" to work as "(" if pressed together with "f" (which is dual modifier, acting as ALT if pressed together with other key). Note that both F and J (if pressed alone, or if pressed in sequence like "FJfj") works normally. I have remapped my input keyboard, so that when I press "alt + J", it releases "(" character - so it is done in my mac keyboard layout level, not in Karabiner. Karabiner only codes the situation of F+J press as ALT+J. IT means that "J" has a role as standard ALT. I suppose that the principle is obvious even from this short code:

(this is just fragment of the code of Karabiner json file - note that first, we solve situation where "J" is pressed alone with "F" already held down (using condition and variable which is set to 1 - see Karabiner help, link above), then we solve the situation of combination of "F" and "J" in strict order with condition of release in strict inverse order
Code: [Select]
"manipulators": [
        {
          "type": "basic",
          "from": {
            "key_code": "j",
            "modifiers": {
              "optional": [
                "any"
              ]
            }
          },
          "to": [
            {
              "key_code": "j",
              "modifiers": [
                "left_option"
              ]
            }
          ],
          "conditions": [
            {
              "type": "variable_if",
              "name": "alt_mode",
              "value": 1
            }
          ]
        },
        {
          "type": "basic",
          "from": {
            "simultaneous": [
              {
                "key_code": "f"
              },
              {
                "key_code": "j"
              }
            ],
            "simultaneous_options": {
              "key_down_order": "strict",
              "key_up_order": "strict_inverse",
              "detect_key_down_uninterruptedly": true,
              "to_after_key_up": [
                {
                  "set_variable": {
                    "name": "alt_mode",
                    "value": 0
                  }
                }
              ]
            },
            "modifiers": {
              "optional": [
                "any"
              ]
            }
          },
          "to": [
            {
              "set_variable": {
                "name": "alt_mode",
                "value": 1
              }
            },
            {
              "key_code": "j",
              "modifiers": [
                "left_option"
              ]
            }
          ]
        },

The only downsize is that code is pretty exhaustive - what is shown above is just code for one key. Multiply it by number of keys you want to modify. I prepared my json file using ruby script but doing it manually would be fatiguing.

EDIT: After careful testing I must admit that this solution also does not work as expected for dual-mode keys which are frequently used. Often, the other function of the modifier/key is unintentionally initiated during quick typing. So I was not correct that combination of keys XYyx never happened   during typing (where I supposed only XYxy sequence). I will try to remap the dual-mode keys for keys with less-frequent characters, however I am quite pessimistic at the moment (even if such mistake I described above happens very rarely - once per 100 key presses or so - it is still annoying and cannot be considered normal use)
« Last Edit: Fri, 02 November 2018, 05:01:36 by daneb »