Handler problem ...

Hi,

I want a handler to execute after a delay of 15 minutes of idle time. I thought that an IDLE handler only executes after a predetermine delay, but it seems to execute immediately the first time. In order for the handler to not execute itself the first time how do I script that ? This is my handler …

on idle
	tell application "Finder"
		tell application "System Events" to exists process "HP Communications"
			if result is true then
				try
					with timeout of 5 seconds
						quit application "HP Communications"
					end timeout
				end try
			end if
		end if
		return 900
	end tell
end idle

Thanks in advance.

Robert

Model: iMac G5 1.6 MHZ - 2GB
AppleScript: 1.10.7
Browser: Safari 419.3
Operating System: Mac OS X (10.4)

One way: delay the start, then compensate in the return



on idle
do shell script "sleep 15" -- this delays the process for 15 seconds; more efficient than delay if not a short time.
	tell application "System Events" to if exists process "HP Communications" then
				try
					with timeout of 5 seconds
						quit application "HP Communications"
					end timeout
				end try
		end if
		return 885
end idle

Hi Robert,

try this, it uses a simple flag

property flag : false

on run
	set flag to false
end run

on idle
	if flag then
		tell application "System Events" to exists process "HP Communications"
		if result then
			try
				with timeout of 5 seconds
					quit application "HP Communications"
				end timeout
			end try
		end if
	else
		set flag to true
	end if
	return 900
end idle

Notes:
¢ The Finder is not needed
¢ If result then is the same as if result is true then

With Adam’s method, you could put the delay in the run handler.

gl,

Very much better - only runs once


on run
do shell script "sleep 15" -- this delays the process for 15 seconds; more efficient than delay if not a short time.
end run

on idle
	tell application "System Events" to if exists process "HP Communications" then
				try
					with timeout of 5 seconds
						quit application "HP Communications"
					end timeout
				end try
		end if
		return 900
end idle

Hi Adam and StefanK,

Am I wrong to say that a ON IDLE handler executes only after the computer has been idle for a certain period ? Or is IDLE only a name given to a handler that will execute when called from within a script ?

If I am wrong, is there a way to have a background script that executes after a certain amount of computer inactivity ?

Thanks in advance.

Robert Lespérance

Hi Robert,

in a stay open script, the idle handler will be executed right after the explicit or implicit run handler.
If there is no run handler, the idle handler will be executed immediately.
Returning a (integer) number of seconds, the idle handler will be executed periodically with the number as interval
with minimal consumption of system resources.

This example checks every 30 seconds the computer idle time and “does something” after an idle time of 5 minutes

on idle
	set idleTime to (do shell script "ioreg -c IOHIDSystem | perl -ane 'if (/Idle/) {$idle=(pop @F)/1000000000; print $idle,\"\";last}'") as integer
	if idleTime > 5 * minutes then
		-- do something
	end if
	return 30
end idle

You don’t have any choice about the first on idle run time: first the run handler runs when the app is started and that is followed immediately by the on idle’s first run (how else will the system know when to return?).

I have often posted this example of a stay-open application with an on idle handler:

on run
	(*do setup - this runs when the application is started to set things up. It is not necessary to have an 'on run' handler because the on idle handler runs immediately after this anyway. If you want this to run all the time after every login, list it your startup items. You quit it from it's dock icon.*)
end run

(*'on idle' runs immediately following the 'run' handler if there is one, and thereafter on the interval specified in the return at the end. (An 'on run' handler is not required, so omit if there is no setup)*)
on idle
	-- In this section, you do your script operations every interval
	return xx -- do this every xx *seconds*.
end idle

on quit
	(*do stuff - assumes you want to clean things up or save preferences or variables before the program quits. This section runs only if the application is quit from the dock, or by any other means. It is not necessary to have one.*)
	
	(*if there is an on quit handler, then 'continue quit' must be the last statement or the script will not stop! The presence of an 'on quit' handler 'grabs' the system command to stop, so it will not complete the quit process until notified to do so. 'continue quit' does that.*)
	continue quit
end quit

StefanK,

I understand that the term IDLE in an ON IDLE handler is only a name and that it has no implicite function. It could have been called ON INACTIVITY. The handler is being determined by the scripting between the ON and the END statement.

With that in mind I wrote this handler:

on idle
	---Calculate the idle time of the computer
	set idleTime to (do shell script "ioreg -c IOHIDSystem | perl -ane 'if (/Idle/) {$idle=(pop @F)/1000000000; print $idle,\"\";last}'") as integer
	---If the idle time is more than 15  minutes quit "HP Communications"
	if idleTime > 2 * minutes then
		tell application "Finder"
			tell application "System Events" to exists process "HP Communications"
			if result is true then
				try
					with timeout of 5 seconds
						quit application "HP Communications"
					end timeout
				end try
			end if
		end tell
	else
		---If the idle time is less than 15  minutes activate "HP Communications"
		tell application "System Events" to exists process "HP Communications"
		if result is false then
			try
				with timeout of 5 seconds
					activate application "HP Communications"
				end timeout
			end try
		end if
	end if
	return 30
end idle

It seems to be working. I still have these 2 questions:

(1) Could I be running this handler at every 15 seconds without being obstrusive to my normal work ?
(2) I would like to quit all copies of “HP Communications” running in any open session. I was told that I need to SHELL SCRIPT this command and I don’t know how to do that. Can you tell me what would be the SHELL SCRIPT to replace the line below ?

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

Thank you both for your comments … :):):slight_smile:

Thanks in advance.

Robert

Model: iMac G5 1.6 MHZ - 2GB
AppleScript: 1.10.7
Browser: Safari 419.3
Operating System: Mac OS X (10.4)

remember my notes in the first post :wink:

a bit but not really, calling a shell script takes a few millisecs, the rest is negligible

I don’t understand, what you mean with all copies of

I think he wants to quit all instances running for any user. Don’t know if that’s a good idea, I’d just run the script in each user’s account as a startup item.

Hi StefanK and Adam,

The “HP COMMUNICATIONS” app open automatically at startup on any opened user session. After a session is left inactive a few hours , “HP COMMUNICATIONS” generates a kernell panic with the screen saver and this could occur on any open session. If I can quit that app after, lets say 45 minutes, that never happens.

So my problem is to automatically quit that app after a certain amount of idle time, on any open session. I presumed, wrongly, that a background handler would not run in a background session. It does work. So if I run the handler as a startup item, it runs in background on any open session and quits “HP COMMUNICATIONS” after a period of idle time. The funny things, is that when I move the mouse on my session, “HP COMMUNICATIONS” opens even on the other background session. In any event, it does what I was looking for.

Here is my final handler (for StefanK) ;);):wink: :



on idle
	---Calculate the idle time of the computer
	set idleTime to (do shell script "ioreg -c IOHIDSystem | perl -ane 'if (/Idle/) {$idle=(pop @F)/1000000000; print $idle,\"\";last}'") as integer
	---If the idle time is more than 45  minutes quit "HP Communications"
	if idleTime > 45 * minutes then
		tell application "Finder"
			tell application "System Events" to exists process "HP Communications"
			if result then
				try
					with timeout of 5 seconds
						quit application "HP Scan"
						delay 2
						quit application "HP Communications"
					end timeout
				end try
			end if
		end tell
	else
		---If the idle time is less than 45  minutes activate "HP Communications"
		tell application "System Events" to exists process "HP Communications"
		if result is false then
			try
				with timeout of 3 seconds
					activate application "HP Communications"
				end timeout
			end try
		end if
	end if
	return 5
end idle


Thanks for helping.

Hi,

The script works well. It runs when the computer has been inactive for a while. I would like to have it executed when the screen saver turns on. Can somebody help me with this script ?

Thanks in advance.

Hi Robert,

checking if the screensaver is running can be done with:

tell application "System Events"
	if process "ScreenSaverEngine" exists then
		-- do something
	end if
end tell

Hi StefanK (the great helper),

Thank you for the clue. It is even simpler to activate the script this way. Is there a way to hide the script icon in the dock, since it is a process that works in background ?

Regards.

Use James Sentman’s Drop Script Backgrounder

I should have remembered … Thank you Adam.

Hi StefanK,

I want my script to execute when a user is in ScreenSaverMode or either is active but not the frontmost. The script below works for the frontmost user in ScreenSaverMode. If User2 is opened but not the frontmost user, how can I have this script to execute since their seems to be no ScreenSaverEngine activated on User2 when it is not the frontmost user ?

tell application "System Events"
   if process "ScreenSaverEngine" exists then
       -- do something
   end if
end tell

Thanks in advance.

Robert

Model: iMac G5 1.6 MHZ - 2GB
AppleScript: 1.10.7
Browser: Safari 419.3
Operating System: Mac OS X (10.4)