Stream Deck (or any USB Device Key) "Pressed" vs "Tapped" vs "Tapped Once"

I'm just not sure what the difference is to Keyboard Maestro between a "Press" and a "Tapped" and a "Tapped Once".

I've never really used Device Key triggers before. I did check the Wiki but didn't see an answer.

As the wiki mentions, "because Keyboard Maestro can't see the future", any "Is Tapped Twice" (or 3x or 4x) action will also trigger the "Is Tapped Once" feature, which I understand. But does Keyboard Maestro distinguish between "Press" and "Tap" ? If so, is that an issue of duration (e.g. a 'press' is a longer 'tap')?

I'll speculate that "press" triggers the moment the key is pressed, while "tap" waits until the key is both pressed AND released. That's why you can have "tapped twice" but not "pressed twice."

This is how I recall it works for keyboard keys, so I'm speculating it works for USB devices the same way.

  • Press: when it is pressed down
  • Release: when it is released
  • Tapped: when it is pressed and released in relatively quick succession
  • Tapped Once: when it is pressed and released in relatively quick succession and hasn't been tapped recently.
  • Tapped Twice: when it is pressed and released in relatively quick succession twice, but not more than twice in quick succession.
  • Tapped Tree Times: when it is pressed and released in relatively quick succession tree times, but not more than three times in quick succession.

So lets say you tap the button three times, you will get triggers:

  • Press
  • Release & Tapped & Tapped Once
  • Press
  • Release & Tapped & Tapped Twice
  • Press
  • Release & Tapped & Tapped Three Times

Now imagine if you tapped it and then pressed it and then held it down for a period and then released it. Triggers would be:

  1. Press
  2. Release & Tapped & Tapped Once
  3. Press
  4. Release

Clearly, since your behaviour up to the second press is identical, and Keyboard Maestro is not prescient, the triggers are the same. Only when the release comes later can the triggers be different.


Is it feasible to distinguish between short and long? Or indeed to measure time?

Martin, here is a hack that I've thrown together for detecting short and long key presses. Someone will probably have a better macro for this.

Unfortunately it won't work with the Stream Deck because the Execute Actions Until Conditions Met loop doesn't have a condition for USB Device Key state. @peternlewis, feature request? :slight_smile:

Basically the macro triggers with a keypress, gets the current time with milliseconds, waits for the key to be up, gets the time again, calculates the difference, and shows a text box saying if it was a long or short press.

The diff>500 calculation is an example of 1/2 of a second. Adjust it based on your typical duration of a long press.

Note the call to python to get the time is needed because neither KM's internal datetime function nor OSX's date shell command can return the sub-second precision needed. Calling up python would be skewing the duration but only by a few milliseconds. :wink:


1 Like

The best way to track press and release time and duration is by using a trigger on each.

The SECONDS function returns fractional seconds since boot.


Basically, yes, you trigger on press and release. On press, you store the pressed time in a variable using the SECONDS function, and on release, you check the difference between SECONDS() and your variable to know how long the press is.


Thanks Peter for the very fast and helpful reply! I was only aware of the ICU formatted date time. The SECONDS function is a much better option.

Martin, here is another thread with the same question, with a simple 1/2 second example.
With the above info, it could easily be modified to be more dynamic in the keypress hold times if needed (ie short, medium, long, very long, etc). Good luck!

1 Like

Thanks @Onan and @peternlewis.

I wonder if this wouldn’t be better as a built in capability - a “long press” trigger.

Just a thought.

1 Like

Maybe I'm doing this wrong– I'm finding if I assign one macro to be triggered by Tapped Once and another macro to be triggered by Tapped Twice on the same key, the Tapped Twice never triggers– Tapped once triggers both times, or each time if I press more.
Bear in mind– For that in this use case (delete one character with one tap and delete whole word ie. opt-delete with two taps) it's not a problem to have the Tapped Once macro trigger every time I want to trigger the Tapped Twice macro.

Tapped Once should be executed on the first tap, and Tapped Twice should be executed on the second tap, assuming the taps are in quick succession (the actual timing is dependent on your system double click speed)

I just verified this behaviour in Steam Deck triggered macros without any issues.

1 Like

Thank you for looking into that. Interesting– Tried lenghtening double-click speed to it's slowest but still deleting one character at a time– Until there are only two characters left in a word. Then it seems to delete the last two together. I'll keep trying...

Hi Peter,

I know KM can’t “know the future” when tapping, but isn’t the simple solution a user defined delay on each tap, with the macro listening for another tap? That’s how Controllermate solves it (although it is an ordeal to setup tapping, compared to KM’s simple selection)

So it would go like this

  1. Tap once, macro waits .1 seconds, no second tap, then initiate macro 1.

  2. Tap once, macro waits .1 seconds, second tap, wait .1 seconds, no third tap, initiate macro 2.

And so forth.

I tried inserting delays at the head of the second macro but that didn’t work.

Short of this, we need better documentation of successful ways to defeat the errors that happen when the first tap launches macro 1 and then second tap launches macro 2.

I can’t find the pattern.

I struggle for hours trying to defeat it. Eventually I figure out the right combo so that the macros flow smoothly together, but sometimes identically solutions for seemingly identical UI fails. I even have a tap once for mouse click on one part of the GUI, and tap twice click on an identical function a few pixels away and it fails. Nothing else in the macro.

I’ve tried inserting timing changes everywhere.


I've been working on some multi-press macros and decided to make one for USB Device Keys. It accepts single/double/triple-tap and long press. Just replace the press and release triggers at the top with whatever you like.

Multipress - USB Key.kmmacros (71.6 KB)


This thread resurfaced - and it reminds me of something I've been wanting to do with StreamDeck and / or Keyboard Maestro:

I'd like to be able to hold down a button on StreamDeck or a key on the keyboard and have it fire continual triggers. An obvious example would be an "increase volume" macro. (That wouldn't be an actual case as that can be done anyway - on most keyboards.)

Is this feasible?

(This would obviate the need for eg Metagrid Pro (on iPad).)

How about this for hotkeys?

6 - Hold to Repeat - Hotkeys.kmmacros (30 KB)


Or this for Stream Deck buttons?

6 - Hold to Repeat - USB Key v2 (Standalone).kmmacros (34 KB)


Or if you don't like using Cancel all Macros and don't mind using two macros, how about this?

6 - Hold to Repeat - USB Key v1.kmmacros (33 KB)


This one starts triggering and stops when a variable changes.

6 - Hold to Repeat - USB Key v1 - Detect.kmmacros (29 KB)


This one changes the variable on key release.


Lovely, thank you!

How in the WORLD did I never think of using pressed/released for my Stream Deck triggers?!?!

I have a macro that toggles my microphone, and this is how i've been simulating a "hold to mute/hold to unmute" feature... (Screenshot: click to expand/collapse)

But it never worked with the SD buttons because KM can't detect if they're being held down. But NOW I realize I can just set two triggers, press and release, and eliminate the pause action and it works BEAUTIFULLY! This has greatly improved my mute button on my SD! :grin:


Awesome! Which version do you prefer? The standalone one or the two-macro one?

1 Like

Well I ended up just modifying my existing macro's triggers and disabling the now superfluous pause action. So it's based on your standalone example. It works great and it has the added benefit of the Engine not running continuously while I hold down the button like it would do before!

Screenshot (click to expand/collapse)