1 - I see the app is doing its work in an "on idle" handler. I assume that means it is running that code all the time, right? Any issues with it slowing things down? I realize that most of the time the first "if" is false, so it doesn't do much, but it still does something.
Is it possible to do this on a timer? In a JavaScript web app, I could call "settimeout(function, milliseconds)", which would call "function" after the specified milliseconds. The advantage of this is the "idle" code doesn't run constantly. Even if you use something like 10 milliseconds, it drastically cuts down on the number of times the function gets called.
Is something like this available, and does it even matter?
These next two questions are just because I'm curious, and my mind is always spinning with ideas, even if I never end up using said ideas:
2 - Is there any way to call a KM macro from the app? Even if it is only via the URL scheme?
3 - Is there any way KM can talk to the app? Any kind of thing that would cause a handler of some kind to fire?
I really appreciate your help here. It feels a little odd to be asking someone else to do this kind of thing for me, since it's almost always been me doing it for other people in the past. But I'm just going to say "thank you" and accept your help, even if a little guiltily.
I'd like to add that you should probably use UUIDs instead of macro names, since macro names may not be unique. And also, if you change a macro's name and forget where you referenced the name, that reference will break. UUIDs don't change unless you duplicate the macro, or something like that.
Got that! I just wanted to give you a script that’d run assuming you’d installed Nige’s test macro!
BTW - and this is a bit off to the side - I’m assuming that the UUIDs of macros on my system will be different to the UUIDs of the same macros on your system. Is that correct do you know?
If you already have a Macro in your Library with the same UUID as a Macro you are importing, the imported version will be given a new UUID.
But if you have no Macro in your Library with that UUID, the imported Macro will retain its UUID in your Library.
Keyboard Maestro always keeps the imported Macro's name the same (even if you already have a Macro with that name). And it keeps the unique UUID that was in the export version unless it conflicts with a Macro already in your Library.
Everything @Zabobon said is true, and I'll add one more thing: Let's say you're importing macros A and B, where A calls B. If the UUID for B already exists, it gets a new UUID, as @Zabobon said. But also, macro A will be modified to reference B's new UUID.
The idle handler runs every x seconds, where x is the last number returned in the handler. I used an explicit return 1 but (I think!) if the last statement of the handler was set myVar to 10 then the idle period would be 10 seconds.
Perhaps a silly little demo will answer your questions (and, probably, raise a few more ). Another stay-open AppleScript called "testApp" and a macro.
AppleScript
property beepTimes : 1
property idleTime : 5
on idle
beep beepTimes
if button returned of (display dialog "Change beeps?" giving up after 2) is "OK" then
tell application "Keyboard Maestro Engine"
do script "Change Things"
end tell
end if
return idleTime
end idle
on changeThings(newTimes, newIdle)
set beepTimes to (0 + newTimes)
set idleTime to (0 + newIdle)
return 0
end changeThings
on quit
continue quit
end quit
Launch the AppleScript, leaving it frontmost, and ignore it for a while and it'll do 1 beep every 7 seconds. But we set idleTime to 5! That's because the dialog is giving up after 2 seconds -- the dialog being up doesn't count as idle so the clock starts when it goes away.
Hit the "OK" button and the script will run the macro. Use the defaults in the KM prompt and the AppleScript will change to 2 beeps every 12 seconds (again, 10+2), etc.
It's a quick hack, as evidenced by the macro's AS ignoring application responses rather than me trying to work out how to do it properly, but I think it shows at least the start of what you could do.
I didn't quite understand your example, but I (now) completely understand that the value I "return" is the number of seconds before the next idle loop, and that's what I needed to know. Thanks!