# Are there docs on key states, keyToggledOn, key\_is\_pressed, key\_toggled\_off anywhere?

**URL:** <https://community.keyboard.io/t/are-there-docs-on-key-states-keytoggledon-key-is-pressed-key-toggled-off-anywhere/890>\
**Category:** Programming\
**Created:** [December 20, 2017, 9:46pm UTC](https://community.keyboard.io/t/are-there-docs-on-key-states-keytoggledon-key-is-pressed-key-toggled-off-anywhere/890 "2017-12-20T21:46:41Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![fire](https://avatars.discourse-cdn.com/v4/letter/f/67e7ee/32.png) [@fire](https://community.keyboard.io/u/fire)\
**Post date:** [December 20, 2017, 9:46pm UTC](https://community.keyboard.io/t/are-there-docs-on-key-states-keytoggledon-key-is-pressed-key-toggled-off-anywhere/890/1 "2017-12-20T21:46:41Z")

</div>

My code is very buggy and doing all sorts of strange things.

I am trying to debug but I am having trouble understanding how the key states work. Are there docs anywhere or can anyone help?

What are keyToggledOn, key\_is\_pressed, key\_toggled\_off?  
When are they checked? How often?

Is it necessary for a macro to tell the keyboard that a key should still be pressed down, or is it sufficient to just do D(key) once and the key will stay pressed?

---

<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:** [December 21, 2017, 12:06am UTC](https://community.keyboard.io/t/are-there-docs-on-key-states-keytoggledon-key-is-pressed-key-toggled-off-anywhere/890/2 "2017-12-21T00:06:03Z")

</div>

> [@fire](#):
>
> What are keyToggledOn, key\_is\_pressed, key\_toggled\_off?

They are documented [in the source](https://github.com/keyboardio/Kaleidoscope/blob/2cba7e409cedb18da644e72041f26f23ec9d99da/src/keyswitch_state.h#L10-L36), but to summarize it here, this is how key states work:

Every scan cycle (every iteration of the `loop` function in your sketch), the key states are scanned. The firmware goes through every key on the keymap, compares its state to the previous one, and calls the event handlers. The key state will then describe the relation of the previous and the current state. If the key was not pressed, and still isn’t, then `keyToggledOn`, `keyIsPressed`, and `keyToggledOff` will all return false. If the key was not pressed before, but is now, then the first two will return true, `keyToggledOff` will return false. If the key was pressed before, and still is now, then only `keyIsPressed` will return true. If the key was pressed before, but isn’t now, then only `keyToggledOff` will return true.

> [@fire](#):
>
> When are they checked? How often?

The key states are checked each cycle, the previous and current states are stored. The various event handlers can use the helpers mentioned above to see what happened to keys. Which one, when, and how they use, is up to them.

> [@fire](#):
>
> Is it necessary for a macro to tell the keyboard that a key should still be pressed down, or is it sufficient to just do D(key) once and the key will stay pressed?

The key report is cleared each cycle, so unless you re-add a key, it will release. Mind you, if your macro returns a sequence regardless of key state, then `D(key)` will, indeed, keep the key pressed, until you stop sending it.

Does this help? Or should I try to explain differently? (This whole thing can be very confusing, and I have trouble explaining it to this day…)

---

<div class="post-metadata">

**Author:** ![fire](https://avatars.discourse-cdn.com/v4/letter/f/67e7ee/32.png) [@fire](https://community.keyboard.io/u/fire)\
**Post date:** [December 21, 2017, 12:33am UTC](https://community.keyboard.io/t/are-there-docs-on-key-states-keytoggledon-key-is-pressed-key-toggled-off-anywhere/890/3 "2017-12-21T00:33:08Z")

</div>

Thanks, that helps. I am still confused about the last part, though.

> [@algernon](#):
>
> The key report is cleared each cycle, so unless you re-add a key, it will release. Mind you, if your macro returns a sequence regardless of key state, then D(key) will, indeed, keep the key pressed, until you stop sending it.

Suppose a macro returns D(key) on keyToggledOn only. When does the key get released?  
Suppose a macro returns D(key) on keyIsPressed only. When does the key get released?

From the testing I’m doing it seems like the answer is “never” and I have to manually U(key) it.

---

<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:** [December 21, 2017, 12:37am UTC](https://community.keyboard.io/t/are-there-docs-on-key-states-keytoggledon-key-is-pressed-key-toggled-off-anywhere/890/4 "2017-12-21T00:37:04Z")

</div>

> [@fire](#):
>
> Suppose a macro returns D(key) on keyToggledOn only. When does the key get released?

It should be cleared on the next scan cycle.

> [@fire](#):
>
> Suppose a macro returns D(key) on keyIsPressed only. When does the key get released?

This should release the next cycle after you release the key.

> [@fire](#):
>
> From the testing I’m doing it seems like the answer is “never” and I have to manually U(key) it.

Can you show me your code? (Putting it on GitHub preferred, so I can clone it easily 🙂)

I’d have a look to see where things go wrong.

---

<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:** [December 21, 2017, 12:46am UTC](https://community.keyboard.io/t/are-there-docs-on-key-states-keytoggledon-key-is-pressed-key-toggled-off-anywhere/890/5 "2017-12-21T00:46:43Z")

</div>

Hey, @algernon – shouldn’t you be sleeping? 😉

---

<div class="post-metadata">

**Author:** ![fire](https://avatars.discourse-cdn.com/v4/letter/f/67e7ee/32.png) [@fire](https://community.keyboard.io/u/fire)\
**Post date:** [December 21, 2017, 2:04am UTC](https://community.keyboard.io/t/are-there-docs-on-key-states-keytoggledon-key-is-pressed-key-toggled-off-anywhere/890/6 "2017-12-21T02:04:36Z")

</div>

Ok, figured it out - you are right and the key releases the next cycle.

---

<div class="post-metadata">

**Author:** ![jhurwitz](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/jhurwitz/32/2046_2.png) [@jhurwitz](https://community.keyboard.io/u/jhurwitz)\
**Post date:** [July 10, 2018, 3:48am UTC](https://community.keyboard.io/t/are-there-docs-on-key-states-keytoggledon-key-is-pressed-key-toggled-off-anywhere/890/7 "2018-07-10T03:48:59Z")

</div>

> [@algernon](#):
>
> This should release the next cycle after you release the key.

My testing indicates that this is true if the macro is a single key, but not if the macro contains multiple keys.

For demonstration purposes, I’ve taken the default firmware (at commit 11676727) and made just a single change:

```
diff --git a/Model01-Firmware.ino b/Model01-Firmware.ino
index bc45ee3..6a182e0 100644
--- a/Model01-Firmware.ino
+++ b/Model01-Firmware.ino
@@ -236,7 +236,8 @@ const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) {
     break;

   case MACRO_ANY:
- anyKeyMacro(keyState);
+ if (keyIsPressed(keyState))
+ return MACRO(D(A));
     break;
   }
   return MACRO_NONE;

```

This works as expected. I’m on a Mac running [Key Codes](https://manytricks.com/keycodes/) to inspect keyboard inputs, and pressing the any key works identically to pressing the A key: I see a Key Down event, then a brief pause, then Key Down (Repeat) events, and finally (when I release the key) a Key Up event. I would also add that the Key Down (Repeat) events are on the order of magnitude of 10 per second.

Let’s instead change this macro to: `return MACRO(D(A), D(B));`. Now I get something completely different: A Key Down event for A when I first press any, and a Key Up event for A when I release any, but in the interim, I’m getting alternating Key Down and Key Up events for B on the order of magnitude of 100 per second or more – likely, one per scan cycle.

Now admittedly this is a contrived example, but modifier + key is significantly less contrived. If I repeat this experiment with: `return MACRO(D(LeftGui), D(A));` then I get a Modifier Change event when I press and release the any button, and then Key Down/Up events for A every cycle. And likewise, if I try `return MACRO(D(A), D(LeftGui));` then I get Key Down/Up for A when I press and release the any button, and two Modifier Change events every cycle.

What I’m ultimately trying to build at the moment is a macro that maps Ctrl+Tab to a certain combination of keys. (And then next I’m going to work on Cmd+Tab, but that’s significantly more complicated for several reasons, so I’m starting with Ctrl+Tab. And yes, I’ve already read the code examples for Cmd/Alt+Tab both [here](https://community.keyboard.io/t/just-act-normal-in-a-macro/892/13) and [here](https://github.com/keyboardio/Kaleidoscope/tree/master/examples/AppSwitcher).)

Let’s use Chrome on my Mac as an example. When I press _and hold_ Ctrl+Tab using the native keyboard, Chrome will switch to the next tab, pause momentarily, and then start to rapidly advance tabs repeatedly. When I look at the Key Codes app, this first tab switch corresponds to the initial Key Down event, and then the later (rapid) tab switches correspond to the approximately ~10 per second Key Down (Repeat) events. I’m not sure what layer (eg, I’m not even sure if it’s hardware or software) is responsible for generating these Key Down (Repeat) events – but whatever it is, I can’t seem to get that to happen when using Kaleidoscope macros with multiple keys.

---

<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:** [July 10, 2018, 5:24am UTC](https://community.keyboard.io/t/are-there-docs-on-key-states-keytoggledon-key-is-pressed-key-toggled-off-anywhere/890/8 "2018-07-10T05:24:07Z")

</div>

Can you report this as an issue against [Kaleidoscope-Macros](https://github.com/keyboardio/Kaleidoscope-Macros), please? A GitHub issue is much easier to remember and keep track of.

Thanks!

---

<div class="post-metadata">

**Author:** ![jhurwitz](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/jhurwitz/32/2046_2.png) [@jhurwitz](https://community.keyboard.io/u/jhurwitz)\
**Post date:** [July 10, 2018, 6:49am UTC](https://community.keyboard.io/t/are-there-docs-on-key-states-keytoggledon-key-is-pressed-key-toggled-off-anywhere/890/9 "2018-07-10T06:49:29Z")

</div>

Done. For future viewers who end up on this discussion thread and want to learn the outcome: [https://github.com/keyboardio/Kaleidoscope-Macros/issues/23](https://github.com/keyboardio/Kaleidoscope-Macros/issues/23)

---

<div class="post-metadata">

**Author:** ![jhurwitz](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/jhurwitz/32/2046_2.png) [@jhurwitz](https://community.keyboard.io/u/jhurwitz)\
**Post date:** [December 6, 2020, 7:03am UTC](https://community.keyboard.io/t/are-there-docs-on-key-states-keytoggledon-key-is-pressed-key-toggled-off-anywhere/890/10 "2020-12-06T07:03:49Z")

</div>

> This works as expected. I’m on a Mac running [Key Codes](https://manytricks.com/keycodes/) to inspect keyboard inputs, and pressing the any key works identically to pressing the A key: I see a Key Down event, then a brief pause, then Key Down (Repeat) events, and finally (when I release the key) a Key Up event. I would also add that the Key Down (Repeat) events are on the order of magnitude of 10 per second.

Came back to this 2.5 years later, and something has changed. Now, my example (from above) of `MACRO(D(A))` results in a key down and up every cycle, instead of a single down (which is then interpreted by my OS as key repeat events).

> Done. For future viewers who end up on this discussion thread and want to learn the outcome: [https://github.com/keyboardio/Kaleidoscope-Macros/issues/23](https://github.com/keyboardio/Kaleidoscope-Macros/issues/23)

Looks like that repo has been deleted (not archived) so that particular issue is gone, but it was migrated to [Macros: Key repeat broken for multi-key macros · Issue #368 · keyboardio/Kaleidoscope · GitHub](https://github.com/keyboardio/Kaleidoscope/issues/368), which led to `WITH_IMPLICIT_REPORT`/`WITH_EXPLICIT_REPORT` being added.

Interestingly, the behavior I just described above (of there being a key down and up every cycle) remains the same no matter whether I use explicit or implicit reporting.

I’ve already spent a while chasing down this rabbit hole, so figured I’d pause to ask for help. Do you know what’s changed, is this a bug or intentional, and why are explicit and implicit reporting resulting in the same outcome?
