Getting around a keyboard maestro bug- run a macro from applescript, kill, then repeat

This is going to be somewhat of a strange question and situation to communicate. I have had a problem with keyboard maestro ever since I started using it, about 4-5 years now. After it runs for a around a day or more it can really slow down the UI/graphics performance of my Mac immensely.

Eventually, this means that the keyboard maestro macro itself will fail when expecting to click somewhere and miss its opportunity to do what its supposed to do.

The only workaround I know of is to close the Keyboard Maestro Engine process and reopen it again, and then my display performance is great again. Although I’ve provided screen capture evidence of this via support, its still a persistent issue. I’ve had this issue on 4 different Macbook pros at this point.

So the workaround I’m working on is to run keyboard maestro and then a macro from apple script (applescript is the host here), when its done then kill keyboard maestro, and repeat.

Problem is I’m not able to know when Keyboard Maestro finished the macro. At that point I want to kill the Keyboard Maestro Application before I repeat everything all over again.
this is what my apple script function looks like so far. I have not made the loop yet, because I don’t think there’s any point until I figure out how to get keyboard maestro to tell AppleScript that its done its thing.

do shell script "pkill ‘Keyboard Maestro’"
delay 10
tell application “Keyboard Maestro” to activate
delay 3
tell application “Finder” to set visible of process “Keyboard Maestro” to false
delay 3
tell application "Keyboard Maestro Engine"
do script "Loop - save shell"
end tell

Since most of us, including me, have not experienced this unusual behavior, it suggests that there is some common setup, setting, and/or software that you are using on all of your Macs that is causing this issue.

Have you tried booting into Safe Mode, and starting ONLY the KM Engine to see if the issue then presents itself?

Thanks for the suggestion JMichaelTX, but I cannot test my macros in safe mode because they require Ableton Live to be open which cannot function in safe mode. Display performance is already terrible in safe mode anyway, so its pretty hard to tell. Additionally, the issue does not occur unless Keyboard Maestro is executing a loop for a long time. so running Keyboard Maestro for a long time alone will not allow me to replicate the issue. I have a suspicion it has to do with image recognition and GPU functions in keyboard maestro. These are central to want I’m doing and I’ve long had issues with battery consumption and Keyboard Maestro if its left running in the background, even if the macro is not running anymore. The latest updates have helped with battery consumption in the background a lot, but not with reduced display performance when running a loop for a long period of time as described. It seems like some kind of open CL process that gets backgrounded can loop on top of itself or something like that, but who can say…

If we can initially try to resolve this by looking at how AppleScript can get feedback from keyboard maestro to know when to execute its next step, this would be useful. This is the short path I have the most hope for, though if we can figure out the performance issue as a longer term discussion then it would be great as well…

Thanks for any help!

Since that is a known cause of the issue, have you tried alternatives?

Instead of a loop, how about periodic executions, or perhaps triggers by some event?

One approach is for your KM Macro to set some KM Variable indicating its status, and then have an external AppleScript read the KM Variable, and take appropriate action.

How can an external applescript read a km variable? I’d love to see a snippet of this, sounds like it might help. I would also be able to remove the loop from km maestro as a further debug step by running the loop in applescript. even if I dont kil the kmaestro process it could help to provide some more info on the issue.

it looks like this might help me a bit to start-

You are on the right track.

Also, keep in mind that an AppleScript run outside of KM can do the following:

  1. Enable/Disable a specific macro
  2. Execute a specific macro
  3. Set a KM Variable that is used in a KM Macro loop to tell the macro to exit.

To see all of the scripting commands KM supports, open the Script Editor, and then open the Scripting Dictionary for Keyboard Maestro Engine. You will see a window like this:

This is the result I came up with to get everything going as I needed it to. Thanks for the pointers.

set myKMVar to "true"

repeat until myKMVar is "false"
	set myKMVar to "false"
	log "start"
	#kill keyboard maestro	
	do shell script "pkill 'Keyboard Maestro'"
	delay 2
	#reopen kmaestro
	tell application "Keyboard Maestro" to activate
	delay 3
	#hide in background
	tell application "Finder" to set visible of process "Keyboard Maestro" to false
	#open foreground app
	tell application "Ableton Live 9 Suite" to activate
	delay 3
	#run the script
	tell application "Keyboard Maestro Engine"
		log "start macro"
		#with timeout of 10 seconds
		ignoring application responses
			do script "Loop - save shell"
		end ignoring
		log "end tell"
	end tell
	#keep checking if it is not runing a macro.  if the kmaestro set the var finishedBatch to true then it completed without errors and the whole loop can repeat.
	tell application "Keyboard Maestro Engine"
		setvariable "finishedBatch" to "false"
		#repeat until myKMVar is "true"
		set isExecuting to "true"
		set timer to 0
		repeat until isExecuting is false
			delay 3
			set timer to timer + 3
			set myKMVar to getvariable "finishedBatch"
			set isExecuting to executing
			#log myKMVar
		end repeat
		log "finishedBatch " & myKMVar
		log "isExecuting " & isExecuting
		log "finished after " & timer & "secs"
	end tell
end repeat

Looks like you’re moving out quickly.

One suggestion:
When you post a script to the forum, use the code block like this:

 -- your code here

I edited your post to change from a block quote to a code block.