Quit app if idle for >20m

I sat down to write a macro for to quit Mail if not opened for >20 minutes. (I want to be able to count how many times I reopen Mail each day.)

Then I realized it was a lot harder than I thought—not the actual assembling of the macro, but the logic behind it. How would you guys do this?

The closet I could think of was two macros:

  1. Trigger every time Mail deactivates : Set VarX to the current time
  2. Trigger every minute (or every 5): if VarX + 20m < Current Time (and if Mail isn’t active now), quit Mail

Is it “bad programming” to have something checking every minute or 5? Is there a better way to do this?

1 Like

You could also ask the shell for 'elapsed running time' strings:

(.js)

var a = Application.currentApplication(),
	sa = (a.includeStandardAdditions = true && a); 
	
sa.doShellScript(
	'ps -ax -o etime,command -c | grep "Mail"'
).split(/[\n\r]+/);

1 check every 5 mins sounds quite cheap ...

(perhaps more specifically, some variant of:

ps -ax -o etime,command -c | grep -w "Mail"
1 Like

Closer reading of bash docs would probably yield a more direct and elegant parse of the elapsed time string, but in q&d .js, perhaps something like:

How many minutes has Mail been running ?.kmmacros (2.3 KB)

(function () {
  var a = Application.currentApplication(),
    sa = (a.includeStandardAdditions = true && a);

  return Math.round(
    // ^dd-hh:mm:ss  (first 11 chars give elapsed time)
    sa.doShellScript(
      'ps -ax -o etime,command -c | grep -w "Mail"'
      
    // every 3rd char is a delimiter
    ).substr(0, 11).match(/.{3}/g).reduce(
    
      function (lst, x, i) {
        // Numeric value of first 2 chars,
        // multiplied by matching element in the
        // [days, hours, mins, secs] array below
        
        lst[i] = Number(x.substr(0, 2)) * lst[i];
        return lst;
      },
      [24 * 60, 60, 1, 1 / 60]
      
    // sum up the [days, hours, mins, secs] as minutes
    ).reduce(
      function (lngTotal, x) {
        return lngTotal + x;
      }, 0
    )
  );
})();

Hey Jack,

You mean opened OR activated — yes?

I think Rob's idea of using the system to provide the uptime of the app is a good one.

On my system I have more than one process that has 'mail' in it, but this produces only Mail.app:

ps -ax -o etime,command -c | egrep -o "[0-9:]+ Mail$"

I think you could use a macro in a global group with an application activation trigger.

You could write the date-time and mail-uptime to a log file every time Mail was activated, and that would give you some usage pattern.

An off-the-top-of-my-head run-through of the logic:

Mail Activates
    Set/reset timer-variable to ps Mail minutes.

Run `ps` every 5 minutes
    Save ps Mail minutes to elapsed-time variable
	
Subract timer from elapsed-time.
    If value > 20 minutes then quit Mail.

There's a whole lot you can do with KM if you're a mind-to, but if you want really comprehensive usage information you might want to consider an app like Time Sink ($5.00 US).

-Chris

1 Like

There is nothing wrong with having a macro that triggers every five minutes. It will use a minuscule amount of CPU/Energy.

Create a group that is active whenever Mail is running (or alternatively, you can have a macro on Mail launch that enables the macro, or you can just have it run all the time) and within that a macro that runs every five minutes thaty basically does:

  • If Mail is at the front
    • Set variable Mail Count to 0
  • Else
    • Set Variable Mail Count to calculation Mail Count + 1
    • If Calculation Mail Count > 4 Then
      • Quit Mail
6 Likes

Thanks, all! Very helpful.