ifShift behavior

I’m trying to get the ifShift command to perform as if it were a separate key entirely, but it’s performing “as expected”, if that makes any sense. See my script below:

ifHold final tapKey 2 // OK
ifGesture timeoutIn 300 $thisKeyId final tapKey 3 // OK
ifShift final tapKey 4 // )
ifShift ifHold final tapKey 6 // @
tapKey 0 // OK

So, if the isShift command is used, it performs the “non-shift key, shifted”, and not the desired key. Is this intentional, or should I try setting the keymaps from Agent if the Shift layer?

Edit: Tried playing around with the Shift key. My current setup has this keymap, which is used to generate the results above:

ifHold final holdKey leftShift
tapKey enter

But if I change the key to just Shift with no macro, this changes:

ifShift final tapKey 4 // $

If you are using a macro to produce shift, then the correct command is holdKey iLS or holdKey iRS (for right shift) in order to behave as a normal shift. (Macro shifts are intentionally handled differently. Search the reference manual for (modifier) “composition modes”.)

Furthermore, ifShift just reads current state without doing any time machine magic, so this can suffer from delays introduced by other keys. Please give a try to the following:

ifNotShift ifHold final tapKey 2 // OK
ifNotShift ifGesture timeoutIn 300 $thisKeyId final tapKey 3 // OK
ifShift final tapKey 4 // )
ifShift ifHold final tapKey 6 // @
tapKey 0 // OK

Also, we don’t automatically suppress modifiers, so if you want the cases to produce 4 and 6 instead of ) and @, then you need to add the suppressMods modifier:

ifNotShift ifHold final tapKey 2 // OK
ifNotShift ifGesture timeoutIn 300 $thisKeyId final tapKey 3 // OK
ifShift final suppressMods tapKey 4 // )
ifShift ifHold final suppressMods tapKey 6 // @
tapKey 0 // OK

Have I answered the question? If no, please clarify - ideally in terms what you do, what output is desired and what you are getting instead. I admit that I don’t understand much.

1 Like

Thanks for the clarification and response.

For sanity purposes, I’ve edited the script to give it some order.

ifNotShift ifHold final tapKey 2
ifShift final suppressMods tapKey 3
ifShift ifHold final suppressMods tapKey 4
tapKey 1

This is a revised version of your suggested solution. I removed the double tap, since there’s no problem with that keymap, and reordered the numbers.

Using this new script, I’m running into 2 issues.

  1. Using a macro for shift key. If I use the enter/shift macro above, I get the following results:
ifNotShift ifHold final tapKey 2 // 2
ifShift final suppressMods tapKey 3 // !
ifShift ifHold final suppressMods tapKey 4 // @
tapKey 1 // 1
  1. Using standard shift key (no macro). If I rebind this macro to behave as a normal shift key, I get the following result:
ifNotShift ifHold final tapKey 2 // 2
ifShift final suppressMods tapKey 3 // 3
ifShift ifHold final suppressMods tapKey 4 // 3
tapKey 1 // 1

I tried the following combinations with no desired outcome:
ifHold ifShift final suppressMods tapKey
ifNotShift tapKey 1

Ideally, I would like to use the macro to toggle the shift key. My desired result is something like this:

ifNotShift ifHold final tapKey CA-h // ctrl-opt-h
ifShift final suppressMods tapKey CAGS-h // ctrl-opt-cmd-shift-h
ifShift ifHold final suppressMods tapKey CAG-h // ctrl-opt-cmd-h
tapKey CAS-h // ctrl-opt-shift-h

or

ifNotShift ifHold final tapKey ) // closing 
ifShift final suppressMods tapKeySeq ( ) leftArrow // open+close (move cursor inside)
ifShift ifHold final suppressMods tapKeySeq ( ) // open+close (no reposition)
tapKey ( // openisg

or

ifNotShift ifHold final tapKey G-v // paste
ifShift final suppressMods tapKey GA-c // copy properties
ifShift ifHold final suppressMods final GA-v // paste properties
tapKey G-c // copy

Looking back at my previous post, I’m thinking I should try something like @maexxx suggested, but to use the ifInterrupted in place of the ifShift. In theory, this should perform the same way, or similar.

A few issues here:

First, I think suppressMods is somehow broken, and I guess when you activate leftShift from another macro, then it does not get suppressed here.

You could try working around that with releaseKey leftShift, i.e. use longer sequences like:

ifShift {
   releaseKey leftShift
   tapKey 3
   break
}

I’m not completely sure if that will work, but give it a try.

Second,

You can never reach the ifShift ifHold in line 3 because as long as Shift is held line 2 already triggers and final makes execution stop after tapping key (=sending scancode) 3.

Third,

I would check ifHold once and only once at the beginning as this uses the time machine and will hold the execution of your macro until it is resolved. I am not sure what happens if you check it again in the same macro. You can use blocks of code in braces {} for further separation depending on Shift/NotShift. Something like this:

ifHold {
    ifShift final doSomething   // shift & hold
    final doSomethingElse   // hold (but without shift)
}
ifShift final doSomethingHere   // only shift (no hold)
doSomethingPlain    // no shift, no hold, just a simple tap

If you need to avoid the finals because you want more complex things, then use more braces:

ifHold {
    ifShift {
        doAThing
        doSomething   // shift & hold
        break
    }
    doAnotherThing
    doSomethingElse   // hold (but without shift)
    break
}
ifShift {
    doAThingHere
    doSomethingHere   // only shift (no hold)
    break
}
doSomethingPlain    // no shift, no hold, just a simple tap

BTW, I avoid else in code with braces, because it can go wrong. The else only checks the result of any if… that was executed before, and depending on which path you took through the nested ifs, it can give you unexpected results.

For another different and totally ugly approach, use goTo:

ifHold {
    ifShift goTo shiftAndHold
    goTo holdWithoutShift
}
ifShift goTo shiftWithoutHold
doSomethingPlain
goTo theEnd

shiftAndHold:
doAThing
doSomething
goto theEnd

holdWithoutShift:
doAnotherThing
doSomethingElse
goTo theEnd

shiftWithoutHold:
doAThingHere
doSomethingHere   // only shift (no hold)

theEnd:

I remember I have seen that reported somewhere suppressMods not kicking in, but I don’t recall the resolution. Do you have any idea where it was @maexxx?

I got it working with this script

ifHold {
    ifShift final suppressMods tapKey 4 // physical: OK, macro: #
    final tapKey 3 // OK
}
ifShift final suppressMods tapKey 2 // physical: OK, macro: ! 
final tapKey 1 // OK

but it only works with the physical shift and not the shift keymap via macro. Any way around this? Only 1 and 3 work

Edit: This did not work, same results as above.

Tried with script below, with and without suppressMods

ifHold {
    ifShift {
        releaseKey leftShift
        suppressMods tapKey 4
        break
    }
    final tapKey 3
}
ifShift {
    releaseKey leftShift
    suppressMods tapKey 2
    break
}
final tapKey 1

Edit 2: Okay I finally got it working, for myself. Not sure if it completely resolves this if someone else is trying to replicate this keybind, but maybe with a different key combination, but I did it by setting the Secondary role instead of a macro. So for my use case in this example, it’s working as desired. Thanks for both of y’alls help!

1 Like

but it only works with the physical shift and not the shift keymap via macro

What do you mean by “shift keymap”?

If shift that is produced by a macro, then you need the holdKey iLS. If something else, please feel free to post either your user config, or a screenshot

This is what I mean:

It’s a macro keymap pressing the shift key, and not the shift keypress. Sorry if my verbiage if off.

As you can see, I used leftShift instead of the iLS as you mentioned. Maybe this was the issue? I got it working so far for now, but will test again soon and report back.

Okay, went back and made this change. Now, using the macro and new keymap works as expected. To conclude, the following scripts worked to resolve my issue.

ifHold {
    ifShift {
        releaseKey leftShift
        suppressMods tapKey 4
        break
    }
    final tapKey 3
}
ifShift {
    releaseKey leftShift
    suppressMods tapKey 2
    break
}
final tapKey 1
ifSecondary final holdKey iLS
tapKey enter
4 Likes

No resolution, but a guy named @kareltucek thinking it may be a bug in the firmware. :wink:

1 Like

Chm. He sounds quite knowledgable. I hope he will also fix it…

1 Like