Activate a different Layer when both function keys are depressed

Is it possible to toggle a new layer based on both function keys being depressed? (prefably which still allows the use of oneshot at all layers, where either function activates a different layer)

I was thinking I could define two distinct layers for left and right function and within those layers if the alternate function key was depressed I would activate the 3rd layer.

I would prefer not to have different layers activated when either function is pressed, but rather either goes to layer 2, and both go to layer 3.

Looking for a bit of inspiration before I attempt to do it in the least elegant way.

2 Likes

Lets say you have four layers, Base, L1, L2 and L3. On the Base layer, assign OSL(L1) to the left palm key, OSL(L2) to the right. On L1, assign OSL(L3) to the right one, and on L2, OSL(L3) to the left one. This should work.

It may not work right now, but it should, and I’ll get around to fixing whatever bug is causing it not to work. Mind you, the bug I see is from a little more complicated setup, so might not apply to this simple case.

Another option is to use MagicCombo, and have it do the switching to L3.

3 Likes

I will look at the Magic Combo option as my requirement is to avoid having two identical layers for layers 2,3.

My goal for the time being is a 3 layer setup:

On Base if I press either palm function key I want to go to L1, if I press both its L2.

Thanks for the suggestion, I will take a look at it now!

In that case, you should be able to make the palm key OSL(L2) on L1.

Thanks (again)

I had a quick look at magiccombos and I think that might be an easier way to go, most of my layer3 options are going to be macros for specific things, Ctrl-Alt-Delete and tmux motion commands/vim motion commands.

I will try it both ways and see which works better.

Your solution does work, and it’s the one I currently use, but it has one annoying side effect: If you get to L3 by pressing L1 and L2 (no matter in what order), you cannot get out of L3 unless you release both FN/layer keys. So if you want to get back from L3 to, say, L1 by releasing the right FN key, you still remain in L3.

@nevd I think MagicCombo does not have this problem. I’ll have to try it too.

Edit: MagicCombo works nicely. It solved the problem of getting stuck in a layer as mentioned above. Here’s the code I’m using:

enum MC {
         SwitchToLayerLFNandRFN
};

void switchToLayerLFNandRFN(uint8_t combo_index) {
  ShiftToLayer(LFNandRFN);
}

USE_MAGIC_COMBOS(
[MC::SwitchToLayerLFNandRFN] = {
  .action = switchToLayerLFNandRFN,
  .keys = {R3C6, R3C9} // Left Fn + Right Fn
});
1 Like

I cannot seem to make Magic Combo activate a layer.

I ended up using the KindOfMagic from MagicCombos to prove to myself the Plugin was working at all.

When I did this I noticed something that would be unwanted. Both the string and the 2nd layer function of mouse movement occurred at the same time! I assume that is not occurring when you switch to a layer.

My 3 lines of code at this point look like this

enum { STL_DOUBLEFUNK };

void stl_DoubleFunk(uint8_t combo_index) { ShiftToLayer(DOUBLE_FUNK); }

USE_MAGIC_COMBOS([STL_DOUBLEFUNK] = {.action = stl_DoubleFunk, .keys = {R3C6, R3C9}});

Any chance I could get some assistance?

This is the issue: ShiftToLayer is a markup only useful in the keymap. It translates to a keycode, and that’s about it. The above code is essentially this:

void stl_DoubleFunk(uint8_t combo_index) { 
  (Key){.flags = SYNTHETIC | SWITCH_TO_KEYMAP,
        .keyCode = DOUBLE_FUNK + LAYER_SWITCH_OFFSET};
}

…and this isn’t exactly useful in this context. You’ll need to use the Layer.on()/Layer.off() functions directly:

void stl_DoubleFunk(uint8_t combo_index) {
  if (Layer.isOn(DOUBLE_FUNK)) {
    Layer.off(DOUBLE_FUNK);
  } else {
    Layer.on(DOUBLE_FUNK);
  }
}

Mind you, you can only toggle layers with MagicCombo, you can’t do momentary layers as with ShiftToLayer, due to technical reasons. If that’s what you want, we’ll have to find another solution :confused:

Updates: I have found an issue : oneshotlayer (OSL) breaks when you map both function keys in the 2nd layer to a 3rd. Neither function will act as a one shot layer anymore when you do this. Not sure whether to create a bug report or feature request for OneShot?
My request would be the following:
If either fn is in OSL lock mode to layer 2, locking the other side fn would lock to layer3.
If either fn is in OSL lock mode to layer2, taping the other fn would give you a oneshot in layer 3 and then drop you back to lock in layer2.
If you one shot both functions one after another you get a one shot action in layer 3, and then you drop back to layer 1.
I think that is all the situations apart from the standard behaviours for OneShot.

For now I am rething my double function layer entirely, I may try a leader instead or perhaps I will use the butterfly for the layer instead of doublefunk!

@rumpel if you really do have a MC that does something better please reply and let me know what you did.

Original:

@algernon thanks for the reply. I implemented the layer design as you first mentioned and it functions as expected. I found that I can release one of the function keys and I will drop back to the 2nd layer, but it is dependent on what side fn key was pushed first.

I am still interested to see what @rumpel managed to do with his MC, but for now I have a solution which works well enough.

1 Like

I’m not sure what you mean, my original post contained the MC code all along. Is there something else you would like to know?

I never managed to get the Magic Combo code to work at all. ( I used the code fragment but updated for my layer name etc etc )

During the time we were discussing this, the keyboard’s API was updated, which also affected the MC plugin. At first, my post contained the older version of the MC code (I think). Shortly after I updated the code to use the new API. That alone would not be enough to get it to work, though. The entire Kaleidoscope library, including most of the plugins, had to be updated as well, or the Keyboard would get stuck when using the newer MC code. Maybe this is why it didn’t work for you?

Edit: There were a few occasions when I couldn’t get my sketch code to work on my keyboard. I’d make a few, seemingly harmless changes, compile and upload, and the keyboard would get stuck. When I say stuck I mean that when I plug it in, the keyboard does not register anything and my operating system hangs for 5 seconds. I’d undo the changes, recompile and upload, but the problem would still persist. I have a non-working sketch code right now that worked just fine a month ago. Finding the problem is cumbersome, it entails me using a divide and conquer approach, basically cutting out parts of the code and see if it’ll work until I can pinpoint the exact line of code that’s causing this problem.

A tip: keep backups of your hex files.

1 Like

Hi, I’ve updated my firmware from a pretty old version to the latest one, 1.96.0.

My implementation
(Activate a different Layer when both function keys are depressed)
for this to stopped working. I’ve tried Algernon’s solution
(Activate a different Layer when both function keys are depressed)
like this (had to rename the methods according to the updated ones):

if (Layer.isActive(LFNandRFN)) {
  Layer.deactivate(LFNandRFN);
} else {
  Layer.activate(LFNandRFN);
}

But that does not seem to work anymore either. When I press both FN keys, they keyboard shifts to the LFNandRFN layer as intended, but it stays stuck in that layer.

Any ideas on how to do this with the latest firmware? Are there any new plugins solving this that I’ve missed?

Edit: Found this basic solution. I haven’t tested it that much yet, but it seems to be clean. You do not get stuck in any sort of leftover layers.

Solution: I basically shift my way (using ShiftToLayer) to the target layer depending on what layer I’m on. This is how my left FN (LFN) and right FN (RFN) keys are set up to get me to the target layer “LFNandRFN”. Each FN key has its own layer when pressed on its own. When both LFN and RFN are pressed, I get LFNandRFN.

These are the layer definitions (all keys except LFN and RFN are omitted):

KEYMAPS
(
  [DVORAK] = KEYMAP_STACKED
  (...,
   ShiftToLayer(LFN),

   ...,
   ShiftToLayer(RFN)),

  [LFN] =  KEYMAP_STACKED
  (...,
   ___,

   ...,
   ShiftToLayer(LFNandRFN)),

  
  [RFN] = KEYMAP_STACKED
  (...,
   ShiftToLayer(LFNandRFN),
 
   ...,
   ___),

  [LFNandRFN] = KEYMAP_STACKED
  (/*...*/),
)

I do a four layer solution from the fn pair :smile:

Layer 1 : left fn held
Layer 2 : right fn held
Layer 3 : left fn held followed by right fn held
Layer 4 : right fn held followed by left fn held

I actually do another layer off right fn + semi-colon (right hand, which activates a mouse warp layer over the top of the normal mouse move I have on my left hand which is right fn on its own.

I know it’s an old thread, but wondering if there’s been any recent progress. I made no progress using MagicCombo. I did make progress with @algernon’s marked solution, but it still has the hysteresis issue @numpel identified. Does anyone have any other suggestions or options here?

Thanks!

algernon’s solution:

Lets say you have four layers, Base , L1 , L2 and L3 . On the Base layer, assign OSL(L1) to the left palm key, OSL(L2) to the right. On L1 , assign OSL(L3) to the right one, and on L2 , OSL(L3) to the left one. This should work.

rumpel’s issue:

Your solution does work, and it’s the one I currently use, but it has one annoying side effect: If you get to L3 by pressing L1 and L2 (no matter in what order), you cannot get out of L3 unless you release both FN/layer keys . So if you want to get back from L3 to, say, L1 by releasing the right FN key, you still remain in L3.

With the current version of Kaleidoscope, you should not have to release both layer shift keys in the above example to get back to the first layer shift. This was true at one time, but it is no longer the case. If you press a ShiftToLayer(N) key, that key will retain that value as long as it’s held, regardless of subsequent layer shifts. If you press L1, then L2, you’ll still have layer 3 on top if you release L1, but if you release L2 first, layer 1 will become the top layer again.

1 Like

You can refer to the solution I found, it’s in the same post that you replied to:

Solution: I basically shift my way (using ShiftToLayer) to the target layer depending on what layer I’m on. This is how my left FN (LFN) and right FN (RFN) keys are set up to get me to the target layer “LFNandRFN”. Each FN key has its own layer when pressed on its own. When both LFN and RFN are pressed, I get LFNandRFN.

See the example code in my post. It’s probably the same thing that merlin is talking about, because I upgraded to a newer version for it to work.

1 Like