Quit app if idle for X minutes

Marco has an app called Quitter which will hide or quit applications if you have not used them in X minutes.

This seems like something that I ought to be able to do with Keyboard Maestro instead of needing a separate app for it, but I'm not sure how to do it.

It occurs to me that someone may have already invented this wheel, and if so I'm hoping they'll read this and share their solution.

Here are the two ideas that I've come up with… in a theoretical sense (versus the "I have actually written this and have it working" sense):

The Easy-But-Annoying Way…

It seems like the easiest way to do this it to have Keyboard Maestro do some sort of Pause for X seconds when an app loses focus, and then quit the app.

Create another macro for when the app gains focus which cancels the previous macro, and it seems like you're on your way.

BUT! …the thing I wouldn't like about this method is that Keyboard Maestro's menu bar icon would be flashing the entire time that the first macro running Pause for X seconds. That would be annoying.

The Write A Timestamp To A Temp File Way…

The only other idea that I have is for 1 macro which would write a timestamp to a temp file, and then have another macro which would check the temp file to see if the elapsed time since that timestamp had exceeded the idle time.

Assuming that the second macro ran, say, once a minute, you might end up with your app running for, say, almost 11 minutes when you wanted it to quit after 10, but that doesn't seem like a huge deal.

You'd also need a third macro that would delete the temp file whenever the app took focus.

BUT… this seems hacky and terrible, like there has to be a more elegant way to do it.


Anyone cracked this nut?

(Yes, I realize I could have downloaded, installed, and configured “Quitter” in the time it wrote to write this post. But it's the principle of the thing…)

Solutions can have false positives and false negatives, or be perfect. In this case a false positive would be to occasionally not detect that someone used the app and close it despite the fact that the app was briefly used in the last 10 minutes. A false negative would be to not close the app in 10 minutes, but maybe in 15 or 20 minutes. Are any of these deficiencies acceptable? And would you consider it acceptable for a solution to require a macro for each app that you want to shut down after 10 minutes? Or is that not acceptable? Would you consider it acceptable for the solution to be running and using a heavy amount of CPU, or do you require that it use only KM's triggers? And what about apps that refuse to close, do you need those to be Forced Quit?

For me, this app seems fairly non-critical, so false negatives aren't important, and false positives aren't too bad. And a separate macro for each app seems reasonable to me. So here's how I would do it.

Step 1. I would create a macro that triggers on the launch of the app. When the app launches, say Safari, a global variable called Safari countdown would be set to 10. (ie, minutes).

Step 2. I would create a macro that triggers every one minute while Safari was active (there is a builtin trigger for that) and decrements the counter by 1 if Safari is NOT the front window (and puts it back to 10 if the window is in front.) If the counter reaches 0 it terminates the program.

The main problem with this approach is that it doesn't terminate any app that's in the front, because it assumes that apps that are in the front are active. So that's a false negative. It will also cause some false positives because the user might be busy switching between windows a lot. But I would say the odds of that happening ten times in ten minutes are extremely low.

So in short, this is a very CPU-efficient solution. It has a very low rate of false positives but there's always going to be one false negative.

Personally, I think you're going about it the wrong way. In my opinion the computer is inactive if there has been no mouse or keyboard action in a period of time. Therefore the simple solution is to just create a KM macro with a trigger that triggers if the IDLE() function is above 10 minutes (then optionally send some warning beeps to the user so he can avoid the next step if he's present) then the macro can delete any or all running apps, or could even shut down the computer.

Hmm, stop the press. I think I have an even better solution. One that will be much more accurate. Let me do some tests.

Here's a whole new approach. It works on all applications. It does have one deficiency, which I will explain later, but I think that can be addressed. For now, let me show you my approach. My approach requires three macros.

The first macro looks like this:

Examine it carefully. That macro stores the current time, in milliseconds, (Edit: change that to TIME, not MS) of any process "that's deactivated", into a dictionary. They key for the dictionary entry is the full path of the app. I think that's exactly what we need. What a great idea.

The second macro removes the item from the dictionary any time the process is activated. It will look almost the same but instead of "Deactivates" it will be "Activates" and instead of setting the dictionary value to MS it will set it to an empty string. (Correction, it needs to be TIME, not MS, since MS resets at midnight.)

The third macro is to occasionally (perhaps every minute, or less often) loop through the dictionary to find out if the last time it was deactivated was over ten minutes ago. If it was deactivated over ten minutes ago then the app, whose path is the key, is to be terminated. However the termination can't be performed using KM's action because KM's action requires that the app paths be hidden, so we will have to use an Execute Shell Script action.

However I refuse to upload a macro that contains a kill command since this is a very dangerous command that could easily kill KM itself, or do a variety of other nasty things. It will be up to you to fix the syntax. But this screenshot should give you the general idea. If you don't know the correct syntax for killing a process by name you can google it. But it's your neck on the block if you make a mistake.

Again, this set of macros, while very good, does fail to take action on any process that has never been activated (which may be exactly what you want!) And it will also fail to take action on the current process since by being activated its counter has been reset to zero. However this last issue is easily fixed if you want to fix it. I'll let you ponder how to do that.

Overall I think this is one amazing little collection of macros. However bear in mind that I didn't test it. I'm not interested in testing something that kills processes on my computer.

1 Like