on idle Handler

I am trying to get a simple on idle script to run but it doesn’t seem to work.

Maybe I am misunderstanding what the on idle handler does but basically I want to check to see if an application is running or not. If it isn’t running then I want to activate a script.

Just to test I copied a script I found online to just launch an application every 10 seconds of idle but it never launches the application.

on idle
   -- The AppleScript only calls attention to itself when the idle period is up
   
   tell application "Safari"
      activate
   end tell
   
   return 10
end idle

I have tried both running this in the script editor and saving as an application and running the application but neither seems to loop on idle. Is there a trick to get the on idle handler to launch the script every x seconds of idle time?

Thanks,

Tanner

is your script also saved as a stay-open application?

idle handler in a nutshell:
Idle handler is an applescript function that will be called every 30 seconds by default. The handler will also be called at launched so it don’t need to be called at launch or run time. When you want to change the interval of the idle handler simply return an integer to tell the application that idle need to run number of seconds later again.

So when saved the file correctly your script would start Safari immediatly if it’s not running and make it the foreground application. Ten seconds later it will do exactly the same again, and again, etc…

Sweet, checking the box to stay open did the trick. I guess it makes sense that the application would need to be open to continue checking for idle :slight_smile:

I have noticed a block of code in a lot of peoples idle scripts:

set idleTime to (do shell script "ioreg -c IOHIDSystem | perl -ane 'if (/Idle/) {$idle=(pop @F)/1000000000; print $idle,\"\";last}'")
return idleTime

Does anyone happen to know the purpose of this?

Here is the full script I found online if that helps for reference.

set quit_after to 900
set check_every to 10

display dialog "Check is performed every " & check_every & " seconds. Things will be quit after " & quit_after & " seconds of system inactivity."

on reopen
   display dialog "Check is performed every " & check_every & " seconds. Things will be quit after " & quit_after & " seconds of system inactivity."
end reopen

on idle
   set idletime to do shell script "echo $((`ioreg -c IOHIDSystem | sed -e '/HIDIdleTime/ !{ d' -e 't' -e '}' -e 's/.* = //g' -e 'q'` / 1000000000))"
   if (idletime as integer) > quit_after then
      tell application "System Events"
         if ((name of processes) contains "Things") then
            tell application "Things" to quit
         end if
      end tell
   end if
   return check_every
end idle

Hi,

the idle handler in a stay open AppleScript will be called periodically whenever the script does nothing (else).
the idle shell script returns the idle time while the user does nothing

Hello,

I am trying the same exact thing. But when I run it in AppleScript Editor the program does not activate.

on idle
	tell application "Terminal"
		do script "open -n /Applications/Safari"
		delay 7
		do script "pkill -o 'Safari'"
		delay 3
		quit
	end tell
	return 5 # it's this value which defines the time to wait before next pass.
end idle

I have the idle time to 5 just to see if it works. But when I run it, it doesn’t even do the code at launch let alone the code at idle. How is one supposed to run this again?

This code when run by itself works until I put “on idle” wrapper around it.

Hi musician1.

‘idle’ handlers are only used in scripts which are saved and run as stay-open applications. They’re executed immediately after the (implicit or explicit) ‘run’ handler and are then repeatedly paged by the system at intervals requested by the ‘return’ value at the end. You can get them to run in Script Editor by calling them with an ‘idle’ command, but they don’t then repeat.

idle

on idle
	beep
	return 5
end idle

Thank you. So how do I get it to be a “stay open” application and do the actual idle repeat?

Did you follow the advice above about saving it as a Stay Open application ? EDIT: My post crossed with Nigel’s who got in while I was still typing. I’ve since seen you ask how to create a Stay Open application: in Script Editor, when you save a script, select “Application” as the type, and check the box below it that describes the application as “Stay Open”

Getting Terminal to launch Safari, kill Safari, and quit may simply be an experiment, but just in case it isn’t, a few brief notes:

▸ You don’t need to use the -n flag with the shell open command. It crops up a lot needlessly in online scripts. It is used should one, for some reason, wish you launch a new, separate instance of an application that already has an instance of it running. So, never, basically.

▸ If you don’t explicitly need a terminal to execute your shell commands in, you can use do shell script to create a shell process without having to open up the Terminal application, e.g. do shell script “open -a Safari”

▸ You don’t need a shell process to launch and quit applications from an AppleScript, which can do these things natively, e.g. activate application “Safari”

I might construct a Stay Open application script to do what yours does in the following way:

property idle_time : 5 -- seconds
property A : "Contacts"

on idle
		activate application A
		delay 7
		quit application A
		
		return idle_time
end idle

on quit
		quit application A
		continue quit
end quit

This actually opens ands quits the Contacts app rather than Safari, partly because I was using Safari at the time, but also because, unless you specifically have Safari set to reopen windows from a previous session, then launching Safari anew from AppleScript will open the application, but not necessarily create a Safari window, which would have made it appear as though the script wasn’t working (unless you pay attention to the menu bar). Contacts, however, appears and disappears demonstrably.

Thank you!

That answers a lot of things. And yes, once I saved the script as an application it allowed me to save it as a stay open application and the idle command worked as expected. I will also include the changes you listed to see if it works any better. Thanks again.