Keeping a group active

I have a group called Pitch Pipe, which contains macros that are triggered by pressing A, B, C, D, E, F, or G. What these macros do is play a sound file associated with that musical pitch. I would like to have a macro with the Option Return hot key trigger, that activates the Pitch Pipe group, and as long as I press A, B, C, etc. on my computer keyboard, it keeps the group active. If none of those keys have been pressed for 10 seconds, then disable the Pitch Pipe group, so that KM no longer absorbs those keystrokes and they just type text as usual. Would anyone have any idea how I could accomplish such a thing? At this point, I'm sure it's possible, I just can't quite figure out how.

There are probably many ways to do this; here's what I came up with.

For purposes of demonstration, because I don't have any sound files, I used TextEdit. Here's the main macro:

Download Macro(s): 10 second looper.kmmacros (3.5 KB)

Macro screenshot

Macro notes
  • Macros are always disabled when imported into the Keyboard Maestro Editor.
    • The user must ensure the macro is enabled.
    • The user must also ensure the macro's parent macro-group is enabled.
System information
  • macOS 15.5
  • Keyboard Maestro v11.0.4

This macro sets a macro start time and the current time, and enables the "play pitch" macro group (which is TextEditTest in my case). It then enters a loop and resets the now time, then calculates the difference between now and macro start times. If that difference isn't at least 10 seconds, the loop continues.

Thanks to Peter's "oh yea, that seems MUCH better!" suggestion below, the main macro is incredibly simple now. It sets the macro start time, enables the "play pitch" group, then tries to pause for 10 seconds. It will exit unless you press one of the defined keys in the TextEditTest group during that 10 second period of time.

And here's the TextEditTest group:

app-TextEditTest Macros.kmmacros (8.3 KB)

These are the four macros that play each pitch, and they look like this:

Each one "plays" (by typing some text) the pitch, then (this is the critical bit) resets the global macro start time, which restarts the 10 second clock. If you never press keys A, B, C, or D, the start time isn't reset, and the loop exits in 10 seconds, disabling the play pitch macro group.

You just need to build similar logic into your macro, where the pitch playing macros reset the "ruling" macro's start time. Note that you have to use globals for the macro start time; I used them on all the variables just because I was feeling lazy :).

-rob.

2 Likes

Thanks for your reply.

After retrofitting this to my macro, it works great. I would only add that the loop should have a 1 second or so pause in it to slow it down a bit. Because after running this a few times, I see in the Macro Inspector that it has saved me a ridiculous 54 days, a number I think would be even higher if I had an ultrafast computer, which I don’t.

And this leads me to another question: Is there any way to reset the time saved, either on individual macros or the whole app? I would kind of like a fresh start.

I'm not sure I understand this—the loop simply waits for 10 seconds to pass; adding a pause wouldn't do anything to slow that down: The loop will still exit after 10 seconds.

What are you trying to achieve by adding a pause?

As for resetting it, it's apparently possible, but @peternlewis would have to tell us which preference it's saved in, per this reply in this thread:

-rob.

Well the thing is, the loop itself iterates so many times per second to see if the 10 seconds have elapsed, that it was making the time saved value increase almost a day per instance of running the macro.

Also, according to Activity Monitor, Keyboard Maestro Engine was using 85 percent CPU while the macro ran.

In my programming experience, it is bad practice to have an unbridled loop, especially one that might last a long time. The fan on my computer didn’t kick in, but I’ve seen it happen to other people.

Adding the pause to the loop makes it check less often, but doesn’t in fact change the ultimate results—it still works as expected, but is just a lot less resource hungry. In fact, after adding the pause, I saw that it used just 10 percent CPU.

So to answer your question, the pause was required for the purpose of making it less taxing on my computer.

Why not use something like

  • Pause Until Calculation NOW() - zzGlobal_startTime > 10

I don't believe the Pause Until action adds anything to the Time Saved.

2 Likes

Doh! That is so much smarter than looping when the loop isn't required! I've updated the macro in the first post with a much-simplified version.

-rob.

I too can confirm that the updated macro is much more efficient. Thanks everyone.

Now for how to reset the Time Saved? @peternlewis

It's not really supported, but I believe it is in the Keyboard Maestro Macro Stats.plist file. You would need to quit Keyboard Maestro Engine and Keyboard Maestro (editor) and then edit that file with BBEdit or the like and adjust the All keyed entry. Probably.