# Combining macros with modifiers

**URL:** <https://community.keyboard.io/t/combining-macros-with-modifiers/980>\
**Category:** Programming\
**Created:** [February 3, 2018, 2:42am UTC](https://community.keyboard.io/t/combining-macros-with-modifiers/980 "2018-02-03T02:42:59Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![CrzRussian252](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/crzrussian252/32/861_2.png) [@CrzRussian252](https://community.keyboard.io/u/CrzRussian252)\
**Post date:** [February 3, 2018, 2:42am UTC](https://community.keyboard.io/t/combining-macros-with-modifiers/980/1 "2018-02-03T02:42:59Z")

</div>

Hello all,

I am trying to map a macro for triggering 1Password to the Butterfly key in the QWERTY layout. If you are not familiar with 1Password shortcuts, in applications with native integrations the login box can be brought up with `Cmd` + `\`, while a more generic keyboard-emulating box can be brought up in any app with `Cmd` + `Opt` + `\`.

I accomplished triggering the first command with a `MACRODOWN(D(LeftGui), T(Backslash))` and naively assumes that tapping `Opt` + the butterfly key would translate to the more generic shortcut described above. Unfortunately it seems that triggering the macro resets the down state of the `Opt` modifier. I looked at the keyboard events as reported by the OS (MacOS 10.13) and the sequence looks as following:

```auto
Opt down
Opt up
Cmd down
\ down
\ up
Cmd up
Opt down

```

The OS sees me holding down the `Opt`, but the triggering of the macro resets the key state until the macro is done, at which point the down state of the `Opt` is re-detected.

_Question_: Is there a way to combine macros with other modifiers in a way that preserves their down states?

---

<div class="post-metadata">

**Author:** ![james.nvc](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/james.nvc/32/54_2.png) [@james.nvc](https://community.keyboard.io/u/james.nvc)\
**Post date:** [February 3, 2018, 4:07am UTC](https://community.keyboard.io/t/combining-macros-with-modifiers/980/2 "2018-02-03T04:07:04Z")

</div>

From looking at the source of the macros plugin, I think the issue is happening because it doesn’t mask the held modifiers, so when the macro sends the new keyboard report, it clears the previously-held keys (I think; my understanding of how key presses & reports work is not exactly 100%).

The easiest way I can think of to make this work is to replace the part of your config that has `return MACRODOWN(D(LeftGui)...)` with something like `return kaleidoscope::hid::wasModifierKeyActive(LeftAlt) ? MACRODOWN(D(LeftGui), D(LeftAlt), ...) : MACRODOWN(D(LeftGui), T(Backslash))`

---

<div class="post-metadata">

**Author:** ![merlin](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/merlin/32/3416_2.png) [@merlin](https://community.keyboard.io/u/merlin)\
**Post date:** [February 3, 2018, 5:25am UTC](https://community.keyboard.io/t/combining-macros-with-modifiers/980/3 "2018-02-03T05:25:14Z")

</div>

I’m betting this is (somewhat) dependent on key handling order. I think if you put the modifier (`option`) on a key that gets handled before the macro key (generally speaking, on a row closer to the top), you’d see the opt getting released after the first keypress event of the macro. It still wouldn’t work the way you’d like, though, and it’s debatable that the behaviour should be considered a bug (I would tend toward that opinion, though).

If I’m right, I can think of a way to make Kaleidoscope-Macros behave the way you were expecting — I might submit a PR in a couple of days that would make held keys stay held while a macro plays, without extra code in the macro functions.

---

<div class="post-metadata">

**Author:** ![merlin](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/merlin/32/3416_2.png) [@merlin](https://community.keyboard.io/u/merlin)\
**Post date:** [February 3, 2018, 3:33pm UTC](https://community.keyboard.io/t/combining-macros-with-modifiers/980/4 "2018-02-03T15:33:47Z")

</div>

@algernon: How do you feel about held keys (and OneShot modifiers) persisting in the keyboard report while Macros are playing? I think they should, and I’ve got a plan for how to do it, but I don’t want to bother doing the work on that unless you think it’s a good idea. If you do think it’s a good idea, I’ll write it up sometime next week and submit a PR to Kaleidoscope-Macros.

---

<div class="post-metadata">

**Author:** ![algernon](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/algernon/32/4404_2.png) [@algernon](https://community.keyboard.io/u/algernon)\
**Post date:** [February 4, 2018, 11:00am UTC](https://community.keyboard.io/t/combining-macros-with-modifiers/980/5 "2018-02-04T11:00:50Z")

</div>

Macros should not be clearing the report, so held keys should persist. What we see here is more likely an ordering issue.

Other than that - yes, held keys, OneShots and everything else that was active when the macro triggered, should persist throughout the macro.

---

<div class="post-metadata">

**Author:** ![merlin](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/merlin/32/3416_2.png) [@merlin](https://community.keyboard.io/u/merlin)\
**Post date:** [February 4, 2018, 1:38pm UTC](https://community.keyboard.io/t/combining-macros-with-modifiers/980/6 "2018-02-04T13:38:14Z")

</div>

Of course! I’m now wondering why I thought the report was cleared. I’ll submit a PR with a fix sometime this week unless you do it first.

---

<div class="post-metadata">

**Author:** ![merlin](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/merlin/32/3416_2.png) [@merlin](https://community.keyboard.io/u/merlin)\
**Post date:** [February 5, 2018, 7:49pm UTC](https://community.keyboard.io/t/combining-macros-with-modifiers/980/7 "2018-02-05T19:49:30Z")

</div>

I’m working on a PR to fix this problem: [https://github.com/keyboardio/Kaleidoscope-Macros/pull/20](https://github.com/keyboardio/Kaleidoscope-Macros/pull/20)

---

<div class="post-metadata">

**Author:** ![CrzRussian252](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/crzrussian252/32/861_2.png) [@CrzRussian252](https://community.keyboard.io/u/CrzRussian252)\
**Post date:** [February 7, 2018, 2:39am UTC](https://community.keyboard.io/t/combining-macros-with-modifiers/980/8 "2018-02-07T02:39:35Z")

</div>

Thanks for the help! In the mean time I’ve followed @james.nvc suggestion and augmented my macro to use `wasModifierKeyActive`, but unfortunately I am getting somewhat funky behavior:

```auto
case MACRO_1PASSWORD:
    if (kaleidoscope::hid::wasModifierKeyActive(Key_RightAlt)) {
      return MACRODOWN(D(RightGui), D(RightAlt), T(Backslash));
    }
    return MACRODOWN(D(RightGui), T(Backslash));
    break;
  }

```

Pressing just the butterfly key works as expected:

 ![19](https://canada1.discourse-cdn.com/flex031/uploads/keyboard/original/1X/2247903ac0cfe326fbe62f34f471e95ae2fe0777.png)

But when I execute Opt + Butterfly I get the following sequence:

 ![12](https://canada1.discourse-cdn.com/flex031/uploads/keyboard/original/1X/f28c88aae6d3f8ef0c8f3ce5d171bb13314a71d4.png)

It seems that the macro selects Cmd + \ + Opt, which is not idempotent with Cmd + Opt + . Is this another ordering issue and expected behavior?

---

<div class="post-metadata">

**Author:** ![merlin](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/merlin/32/3416_2.png) [@merlin](https://community.keyboard.io/u/merlin)\
**Post date:** [February 7, 2018, 5:03am UTC](https://community.keyboard.io/t/combining-macros-with-modifiers/980/9 "2018-02-07T05:03:32Z")

</div>

> [@CrzRussian252](#):
>
> Is this another ordering issue and expected behavior?

I’m not sure why you’re seeing those keys out of order in this case. If I get some time, I’ll try it out tomorrow myself.

---

<div class="post-metadata">

**Author:** ![merlin](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/merlin/32/3416_2.png) [@merlin](https://community.keyboard.io/u/merlin)\
**Post date:** [February 7, 2018, 6:15pm UTC](https://community.keyboard.io/t/combining-macros-with-modifiers/980/10 "2018-02-07T18:15:35Z")

</div>

I suspect that your keymap contains a `Key_LeftAlt` (i.e. left option), but not a `Key_RightAlt`, which is what you would need for that macro to work the way you want it to. If that’s the case, you can change the test in `MACRO_1PASSWORD` to check for `Key_LeftAlt`, and then it should work.

---

<div class="post-metadata">

**Author:** ![CrzRussian252](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/crzrussian252/32/861_2.png) [@CrzRussian252](https://community.keyboard.io/u/CrzRussian252)\
**Post date:** [February 8, 2018, 1:44am UTC](https://community.keyboard.io/t/combining-macros-with-modifiers/980/11 "2018-02-08T01:44:49Z")

</div>

@merlin You are right, the Alt key on the right side of the keyboard is actually a LeftAlt in the map. I corrected the macro and it now works as intended. Thank you so much!

---

<div class="post-metadata">

**Author:** ![JDH](https://avatars.discourse-cdn.com/v4/letter/j/67e7ee/32.png) [@JDH](https://community.keyboard.io/u/JDH)\
**Post date:** [February 21, 2018, 5:21am UTC](https://community.keyboard.io/t/combining-macros-with-modifiers/980/12 "2018-02-21T05:21:36Z")

</div>

Related question: is it possible for a macro to hold down a modifier key until the next keypress? My first usage scenario would be to make a macro that places a period, space, and holds down shift until the next letter (the start of the following sentence). I use OneShot for my shift keys, so it would be even better if I could just trigger my OSM(LeftShift).

I seem to remember another thread where someone did something similar, but I can’t seem to find it.

---

<div class="post-metadata">

**Author:** ![JDH](https://avatars.discourse-cdn.com/v4/letter/j/67e7ee/32.png) [@JDH](https://community.keyboard.io/u/JDH)\
**Post date:** [February 21, 2018, 5:42am UTC](https://community.keyboard.io/t/combining-macros-with-modifiers/980/13 "2018-02-21T05:42:26Z")

</div>

[Here](https://community.keyboard.io/t/thumb-key-choices/301/27) is the thread that mentioned this earlier.

---

<div class="post-metadata">

**Author:** ![algernon](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/algernon/32/4404_2.png) [@algernon](https://community.keyboard.io/u/algernon)\
**Post date:** [February 21, 2018, 10:37am UTC](https://community.keyboard.io/t/combining-macros-with-modifiers/980/14 "2018-02-21T10:37:03Z")

</div>

> [@JDH](#):
>
> is it possible for a macro to hold down a modifier key until the next keypress?

For a macro, no. Macro keys can only act when it is their turn, they can’t watch other keys. To do what you described, one would need to code a bit more. Or, in your specific case, the macro can do something like this:

```c++
Macros.play(T(Period), T(Space));
OneShot.inject(OSM(LeftShift), IS_PRESSED);
kaleidoscope::hid::sendKeyboardReport();
OneShot.inject(OSM(LeftShift), WAS_PRESSED);

```

---

<div class="post-metadata">

**Author:** ![JDH](https://avatars.discourse-cdn.com/v4/letter/j/67e7ee/32.png) [@JDH](https://community.keyboard.io/u/JDH)\
**Post date:** [February 22, 2018, 8:38pm UTC](https://community.keyboard.io/t/combining-macros-with-modifiers/980/15 "2018-02-22T20:38:10Z")

</div>

Sorry, coding amateur here. Can you tell me where I would insert that sequence? I tried this:

```auto
  case MACRO_SENTENCE:
  if (keyToggledOn(keyState)) {
      return Macros.play(T(Period), T(Space));
    OneShot.inject(OSM(LeftShift), IS_PRESSED);
    kaleidoscope::hid::sendKeyboardReport();
    OneShot.inject(OSM(LeftShift), WAS_PRESSED);
  }
    break;

```

What I get is an error, “No matching function for call to 'Macros\_::play(MacroActionStepType,…” What am I doing wrong?

---

<div class="post-metadata">

**Author:** ![algernon](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/algernon/32/4404_2.png) [@algernon](https://community.keyboard.io/u/algernon)\
**Post date:** [February 23, 2018, 12:00am UTC](https://community.keyboard.io/t/combining-macros-with-modifiers/980/16 "2018-02-23T00:00:52Z")

</div>

You don’t need the `return` before `Macros.play`. Returning will result in the code after not being run. It will also throw an error, because `Macros.play()` does not have a return value, while `return Macros.play()` in a function that _does_ have a return value makes the compiler think it should have one. But there is no version of that function that does, hence the error.

Instead, replace the `break` with `return MACRO_NONE` after removing the `return` before `Macros.play()`.

This is roughly what you should end up with:

```auto
 case MACRO_SENTENCE:
  if (keyToggledOn(keyState)) {
    Macros.play(T(Period), T(Space));
    OneShot.inject(OSM(LeftShift), IS_PRESSED);
    kaleidoscope::hid::sendKeyboardReport();
    OneShot.inject(OSM(LeftShift), WAS_PRESSED);
  }
  return MACRO_NONE;

```

---

<div class="post-metadata">

**Author:** ![JDH](https://avatars.discourse-cdn.com/v4/letter/j/67e7ee/32.png) [@JDH](https://community.keyboard.io/u/JDH)\
**Post date:** [March 12, 2018, 10:56pm UTC](https://community.keyboard.io/t/combining-macros-with-modifiers/980/17 "2018-03-12T22:56:02Z")

</div>

Sorry for the delayed reply. Work has been piling up. I still get an error for “no matching function for call to Macros\_::play…”

Any chance you see what I’m doing wrong? Here is my whole macroAction section of my firmware:

```
const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) {
  switch (macroIndex) {

  case MACRO_VERSION_INFO:
    versionInfoMacro(keyState);
    break;

  case MACRO_ANY:
    anyKeyMacro(keyState);
    break;

  case MACRO_SENTENCE:
    if (keyToggledOn(keyState)) {
      Macros.play(T(Period), T(Space));
      OneShot.inject(OSM(LeftShift), IS_PRESSED);
      kaleidoscope::hid::sendKeyboardReport();
      OneShot.inject(OSM(LeftShift), WAS_PRESSED);
  }
  return MACRO_NONE;

  }
  return MACRO_NONE;
}
```

---

<div class="post-metadata">

**Author:** ![Llamalland](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/llamalland/32/832_2.png) [@Llamalland](https://community.keyboard.io/u/Llamalland)\
**Post date:** [April 30, 2018, 6:48am UTC](https://community.keyboard.io/t/combining-macros-with-modifiers/980/18 "2018-04-30T06:48:25Z")

</div>

I’m having problems getting this to work too. Getting similar errors. Any chance you got this to work in the meantime (or anyone else has an answer)?
