Stream Deck: KM Link Multi-Press

Armed with insight from @peternlewis, I've managed to refine this somewhat.

KM Link - Multipress Macros.kmmacros (118.2 KB)

Stream Deck TEST Profile (1.9 KB)

  1. Download the macros and profile above and ensure that KM Link - Multipress Trigger is selected in KM Link's macro dropdown.
  • The parameter field contains an arbitrary term to identify the subroutine to be triggered. In this example, I've used Test 1.
  • KM Link can pass further parameter values to KM, separated by comma delimiters. Here I've added two types of fruit.

CleanShot 2023-04-24 at 11.26.09@2x

  1. I've added an entry for the subroutine to be triggered to the Switch/Case group in KM Link - Multipress Switch.

  1. The subroutine Test 1 can now perform different actions for single/multiple taps, as well as access values passed from KM Link to KM.


It makes more sense to run the tap count as a submacro, so I tried this:

KM Link - Multipress Template.kmmacros (41 KB)

Macro screenshot

KM Link - Tap Counter.kmmacros (38 KB)

Macro screenshot

This works nicely for hotkeys, but for some reason the Semaphore Lock fails when KM Link is the trigger, and the actions are run twice. @peternlewis?

I just tested with this macro and can confirm that the Semaphore Lock doesn't like KM Link. @corcules, any thoughts?

Fails how?

I don't know what you mean, but the Semaphore Lock action does not care about the trigger at all.

It fails to lock the macro to prevent multiple instances running at the same time.

As I said, if you trigger via a hotkey, no problem. As soon as you trigger via KM Link, both instances run.

That's not what the action does.

The action wont prevent multiple instances from running at the same time.

It will simply prevent more than one macro instance from progressing passed an equally named Semaphore Lock action until the lock is released (which happens automatically if the macro instance terminates).

I installed KMLink (which is really awesome BTW). It triggers macros via AppleScript, but as I said, it makes no difference how macros are triggered.

Here is a test macro.

Test Lock.kmmacros (3.2 KB)

Trigger it three times in rapid succession, and look in the Engine.log file and you will see each one runs in sequence.

If you had three different copies of this macro on three different stream deck buttons (or triggered any other way), you would get the same result - all three trigger as normal, but only one can progress past the a Semaphore Lock with the name "Unique Lock Name" and the lock is released when that instance ends (or when an equivalent Semaphore Unlock action is executed) at which point the next macro stuck at a Semaphore Lock with name "Unique Lock Name" will be allowed to proceed.

2023-04-24 16:29:07 Execute macro “Test Lock” from trigger Do Script
2023-04-24 16:29:07 Log: E3E97587-78B1-4695-8FB9-B3D37CEABF0E — 1
2023-04-24 16:29:08 Log: E3E97587-78B1-4695-8FB9-B3D37CEABF0E — 2
2023-04-24 16:29:09 Log: E3E97587-78B1-4695-8FB9-B3D37CEABF0E — 3
2023-04-24 16:29:10 Log: E3E97587-78B1-4695-8FB9-B3D37CEABF0E — 4
2023-04-24 16:29:11 Log: E3E97587-78B1-4695-8FB9-B3D37CEABF0E — 5
2023-04-24 16:29:12 Log: E3E97587-78B1-4695-8FB9-B3D37CEABF0E — 6
2023-04-24 16:29:13 Log: E3E97587-78B1-4695-8FB9-B3D37CEABF0E — 7
2023-04-24 16:29:14 Log: E3E97587-78B1-4695-8FB9-B3D37CEABF0E — 8
2023-04-24 16:29:15 Log: E3E97587-78B1-4695-8FB9-B3D37CEABF0E — 9
2023-04-24 16:29:16 Log: E3E97587-78B1-4695-8FB9-B3D37CEABF0E — 10
2023-04-24 16:29:18 Execute macro “Test Lock” from trigger Do Script
2023-04-24 16:29:18 Log: 98DEFFDF-6C9B-4974-808A-670779BB014B — 1
2023-04-24 16:29:19 Log: 98DEFFDF-6C9B-4974-808A-670779BB014B — 2
2023-04-24 16:29:20 Log: 98DEFFDF-6C9B-4974-808A-670779BB014B — 3
2023-04-24 16:29:21 Log: 98DEFFDF-6C9B-4974-808A-670779BB014B — 4
2023-04-24 16:29:22 Log: 98DEFFDF-6C9B-4974-808A-670779BB014B — 5
2023-04-24 16:29:23 Log: 98DEFFDF-6C9B-4974-808A-670779BB014B — 6
2023-04-24 16:29:24 Log: 98DEFFDF-6C9B-4974-808A-670779BB014B — 7
2023-04-24 16:29:25 Log: 98DEFFDF-6C9B-4974-808A-670779BB014B — 8
2023-04-24 16:29:26 Log: 98DEFFDF-6C9B-4974-808A-670779BB014B — 9
2023-04-24 16:29:27 Log: 98DEFFDF-6C9B-4974-808A-670779BB014B — 10
2023-04-24 16:29:28 Execute macro “Test Lock” from trigger Do Script
2023-04-24 16:29:28 Log: B82DF12F-8724-40A6-ADC8-57338EFD4D71 — 1
2023-04-24 16:29:29 Log: B82DF12F-8724-40A6-ADC8-57338EFD4D71 — 2
2023-04-24 16:29:30 Log: B82DF12F-8724-40A6-ADC8-57338EFD4D71 — 3
2023-04-24 16:29:31 Log: B82DF12F-8724-40A6-ADC8-57338EFD4D71 — 4
2023-04-24 16:29:32 Log: B82DF12F-8724-40A6-ADC8-57338EFD4D71 — 5
2023-04-24 16:29:33 Log: B82DF12F-8724-40A6-ADC8-57338EFD4D71 — 6
2023-04-24 16:29:34 Log: B82DF12F-8724-40A6-ADC8-57338EFD4D71 — 7
2023-04-24 16:29:35 Log: B82DF12F-8724-40A6-ADC8-57338EFD4D71 — 8
2023-04-24 16:29:36 Log: B82DF12F-8724-40A6-ADC8-57338EFD4D71 — 9
2023-04-24 16:29:37 Log: B82DF12F-8724-40A6-ADC8-57338EFD4D71 — 10

I think I understand how it works, but perhaps I explained the issue poorly.

Crucially, the semaphore lock in the macro I posted above is set with a 1/100th of a second timeout, and you'll see there is a 0.2 second pause in the macro, which means the timeout should elapse on run 2 while run 1 is still in progress, the macro should be aborted and, in practical terms, multiple instances should be prevented.

This works as I describe when triggering via hotkeys but not via KM Link. If I assign the same macro to two KM Link buttons and press them both at the same time, two instances of that macro will run, even if I increase the pause to something extreme like 2sec.

The difference is that KMLink is executing the macro via AppleScript, and it is synchronous, so the two macros execute in sequence because of that.

If you add a Log action at the start of the macro you will see the macro is triggered and the second one does not trigger until the first one completes (increase the Pause to make it more obvious).

The solution is to add a third macro that is triggered by KMLink that does nothing but execute Asynchronously the Multipress Template macro.

0.2 seconds is probably too quick, and 0.01 seconds is definitely very fast (Keyboard Maestro only executes 1000 actions per second, so 0.001 seconds, and that is across all macros and actions). I'd suggest the Pause be 0.3 seconds and the timeout be 0.1 seconds.

Also executing the Tap Counter macro asynchronously is probably counter productive.

1 Like

The AppleScript thing makes sense. Thanks for that. The idea was to be able to use one macro to count taps so that you didn't need to create two macros every time you wanted a KM Link button to respond to double clicks, so it looks like that isn't going to be possible.

As I said, it works great with hotkeys.

There's method in my madness. The tap count is asynchronous so that both taps are counted before the first run of the template arrives at the actions to be run. The tap count variable is then used as a condition.

The fact that KM Link's AppleScript trigger runs synchronously is the only point of failure for the idea. I've learned something so thanks again. This probably explains why the first macro I posted works when it shouldn't!

Looks like I'll have to go back to that initial idea which triggers a tap count macro that, in turn, triggers another macro containing the actions to be run.

I'm going to see if I can use KM Link's parameter so that all Stream Deck buttons trigger the same tap counter but run different action macros depending on %TriggerValue%.

Edit: SUCCESS! I'll edit my initial post!

Hello Neil (@noisneil)

Since Peter said that KM Link‘s AppleScript trigger is synchronous and not asynchronous my head went spinning :face_with_spiral_eyes:

But I’ve got an idea how it could work.

Put a Parameter it’s your AppleScript for KM Link - something like the Button ID of your Stream Deck

On KM‘s side of the automation use a trigger macro that grabs the param using %TriggerValue% puts that in a Variable and executes the Multipress Template asynchronously using this Variable.

For the template choosing Dan‘s Multi Press is the right way - but change the template to receive a parameter and the right value of the parameter to continue instead of the check for the hotkey.

Here is a hint - if you use the same Funktion on multiple buttons (like favorites), don’t forget to set this up in both macros.

This should work out of the box. I am not at home and have currently none of my macs with me so I am sorry to give you only the theory.

Greetings from Germany


I appreciate the thoughts, and they're not a million miles away from the solution I already came to:

Well - the new solution you have now seems to be a very solid one …

Based on this solution from you - my thoughts were based on the single press trigger setting of KM Link.

It seems to me that I have an older Version of KM Link that hasn’t the multi press setting. Am I right about the fact that you‘ll have to setup more than one script to trigger a KM Macro in the multi press setting?

If that is true - my solution would be better because with the single press setting you have only one AppleScript per Button Setup - less more Code to maintain on the outside of KM.

And if I go further only in my thoughts there are maybe more benefits in setting up Trigger Macros as well … but that is only my theory because I am not able to test anything at the moment.

Greetings from Germany


No... I no doubt have the same version as you do. KM Link triggers KM macros via AS, but there are no scripts to be written by the user. Your thoughts were very similar to my own... If you were at home to test, you'd see that your logic was sound. :+1:t3:

It's the same solution. Great minds think alike!

Maybe you’re right and I’ve missed that … But my Stream Deck setup is working for longer than a half year now and I’ve never changed anything since then. It could be a possible thing that the action was updated as well the Version of the Stream Deck Application at least one ore more times in the last half year … I’ve maybe downloaded the new Versions but never dir an update … so that it is a possibility that we have different Versions.

The other thing came to me that you’re right and KM Link is set up inside the Stream Deck Application‘s Settings window.

I’ve looked into my configuration docs for my setup and I saw that I am using mixed profiles where I’ve also used the AppleScript Plug-in where I’ve built in GUI and modifier detection using AppleScript Objective-C in combination with Macros.

Most of the code was set up and written together with a friend of mine … who died a few months ago. May he rest in peace …

I’ve got so much in my head at the moment that I combined some of the facts that I should probably know better … sorry for that.

A little question OT - may I contact you the next few days via PM? I've got some things about our Macro Templates in mind…

Greetings from Germany


1 Like

I'm very sorry to hear you lost someone. I've been through that too recently. :heart:

Yes of course, feel free to message any time.

Just to clarify, KM Link hasn't changed since 2020 and it has always triggered a single macro with a parameter.

1 Like