Two different macros on one key with shift

Hi,

I recently upgraded my Model 01s with Model 100s and just ported my customizations. Took me a bit to find out that I had to disable some plugins to prevent all modifiers to become sticky. But went smooth otherwise. Now that I’m running a current Kaleidoscope and are into the code again I’d like to add some new features to my layout.

I have one key that I only use for macros. In the past I had one macro on the regular layer for this key and another on the fn layer. Now I’d like to add one more macro, this time differentiated by shift. But I don’t want to introduce an extra “shift” layer just for this one key. So I thought I could code this in macroAction() like this:

const macro_t *macroAction(uint8_t macro_id, KeyEvent &event)
{
    switch (macro_id)
    {
        case MACRO_TEST:
            if (keyToggledOn(event.state))
            {
                // Determine if one of the shift keys is being held.
                bool shift_held = false;
                bool shift_left = false;
                for (Key key : kaleidoscope::live_keys.all())
                {
                    if (key == Key_LeftShift)
                    {
                        shift_held = true;
                        shift_left = true;
                        break;
                    }
                    if (key == Key_RightShift)
                    {
                        shift_held = true;
                        shift_left = false;
                        break;
                    }
                }

                if (shift_held)
                {
                    // shift version of the macro
                    if (shift_left)
                    {
                        return MACRO(I(20),
                            U(LeftShift), T(X), T(Y), T(Z), D(LeftShift) );
                    }
                    else
                    {
                        return MACRO(I(20),
                            U(RightShift), T(X), T(Y), T(Z), D(RightShift) );
                    }
                }
                else
                {
                    // macro without shift
                    [...]
                }
            }

Detecting that a shift key is pressed works fine. But for my macro to work, the shift key must not be active. So I thought sending a “U(LeftShift)” would help, but it doesn’t. I still get “XYZ” printed, but I want “xyz” instead (this is just a minimized example of course).

Is there a way to accomplish this?

Would it be easier if I use for example control for this (but control must be deactivated too for my macro to work)?

Thanks.

Ok, it seems that actually pressed keys are always reported to the host, regardless of how you override them in the macro.

After a bit of fiddling with the internal data structures I found a solution for the problem by masking the key:

const macro_t *macroAction(uint8_t macro_id, KeyEvent &event)
{
    switch (macro_id)
    {
        case MACRO_TEST:
            if (keyToggledOn(event.state))
            {
                // Determine if a shift key is being held - mask it if yes
                bool shift_held = false;
                for (KeyAddr key_addr : KeyAddr::all())
                {
                    Key key = kaleidoscope::live_keys[key_addr];
                    if (key == Key_LeftShift)
                    {
                        shift_held = true;
                        kaleidoscope::live_keys.mask(key_addr);
                        // continue loop: both shift keys could be pressed
                    }
                    if (key == Key_RightShift)
                    {
                        shift_held = true;
                        kaleidoscope::live_keys.mask(key_addr);
                        // continue loop: both shift keys could be pressed
                    }
                }

                if (shift_held)
                {
                    // macro to call when shift pressed
                    return MACRO(I(5),
                        T(X), T(Y), T(Z) );
                }
                else
                {
                    // macro to call when shift not pressed
                    return MACRO(I(5),
                        T(A), T(B), T(C) );
                }
            }