Timeout with idle + display dialog

I have a script that opens a dialog requesting intervention. If it doesn’t receive a response (the display dialog times out), it goes ahead and does something. And it can be cancelled to quit the application and end the idle loop.

The problem is that I’m getting an AppleEvent Timed Out error when the dialog times out. The first idle handler fires off immediately, and I click “Idle” to continue the idle loop, but then the next dialog times out despite the auto-dismiss and with timeout statement.

My understanding is that a with timeout… statement isn’t necessary for pure AppleScript events (per this valuable thread), but I tried throwing one in anyhow, and it didn’t do anything for me.

The script is as follows:

on run
	return 300 -- Idle immediately
end run

on idle
	with timeout of 3600 seconds -- add a ridiculously long timeout to make sure things go right
		display dialog "We're going to time out around now" with title "Anybody there?" with icon caution buttons {"Cancel", "Idle"} cancel button "Cancel" giving up after (300)
	end timeout
	if button returned of result is "Idle" then
		return 5 -- Idle
	else if button returned of result is "Cancel" then
		quit
	else
		beep
	end if
end idle

on quit
	continue quit
end quit

Hi,

timeout blocks affect only applications which send Apple Events.
This should work, the try block catches the Cancel button


on idle
	try
		set {gave up:gaveUp} to display dialog "We're going to time out around now" with title "Anybody there?" with icon caution buttons {"Cancel", "Idle"} giving up after 300
		if gaveUp then
			beep
		else
			return 5 -- Idle
		end if
	on error number n
		if n = -128 then quit
	end try
end idle

Thanks, Stefan. I need to wrap that into the code and see what happens. (Kinda ran out of time)

The syntax you used there is unfamiliar to me, though. It looks like what you’re writing is shorthand for…

set gaveUp to gave up of (display dialog... giving up after 300)

Could you point me toward some more information on using that notation and where it’s applicable?

Thanks!

See the AppleScript Language Guide. Specifically the bits about variable patterns in the Using the copy and set Commands section of the Variables and Properties chapter.

the result of display dialog is a record {text returned:[text], button returned:[text], gave up:[boolean]}.
The presence of the single properties depend on the given parameters.

To assign variables to the record properties, you can use these forms


set resultRecord to (display dialog "")
set gaveUp to gave up of resultRecord
set buttonReturned to button returned of resultRecord

set {gaveUp, buttonReturned} to {gave up, button returned} of (display dialog "")
set {gave up:gaveUp, button returned:buttonReturned} to (display dialog "")

I prefer the third one, because it illustrates the record structure

Nice, thanks for the help!

I did a little more testing, and it looks like just assigning the display dialog to a variable fixes the problem, regardless of the syntax used – e.g. set x to display dialog… or set x to (button returned of display dialog…).

Displaying the dialog on its own line, and then grabbing the results will trigger the time out.

This seems totally inconsistent with the way these things are handled everywhere else. Am I missing something, or is this an oddity/bug/unexpected feature?

all syntax forms should behave the same way

Unfortunately, I’m still having trouble with the actual program, rather than the more limited code snippet.

The plan for the app is that it runs in the afternoon when it’s time to leave work. When I stop hitting the “snooze” button (i.e. the dialog times out), or when I give it the go-ahead, it quits a list of apps that cause me trouble if they stay open for one reason or another.

This script is still giving me an Apple Event Timed Out error when the dialog itself times out.

property appsToQuit : {"Adium", "Skype", "OmniFocus"}

on idle
	try
		
		beep
		set {button returned:theButton, gave up:gaveUp} to display dialog "It looks like you've gone home. Mind if I quit a few programs so they don't stay up all night?" with title "Anybody there?" with icon caution buttons {"Go Away!", "Snooze", "G'night!"} cancel button "Go Away!" default button "G'Night!" giving up after 600
		if gaveUp then
			my quitApps()
			quit
		else if theButton is "Snooze" then
			return 300
		else
			my quitApps()
			quit
		end if
	on error errMsg number errNum
		if errNum = -128 then
			quit
		else
			display alert errMsg & " (" & errNum & ")"
		end if
	end try
end idle

on run
	return 1 -- alert immediately
end run

on quitApps()
	repeat with anApp in appsToQuit
		tell application anApp to quit
	end repeat
end quitApps


on quit
	continue quit
	
end quit

I can’t really see anything wrong with your code. However, this Apple Event Timed Out error only occurs when the script is waiting for a response back from an application. The only place you target applications is in the quitApps() handler. So you might want to try it this way using ignoring application responses so that handler doesn’t wait for the applications to respond back before proceeding.

I know for example that if I have a document open in TextEdit, and that document has unsaved changes, then if I issue it a quit command in a script that TextEdit will not quit. TextEdit puts up a dialog asking if I want to save the unsaved changes. The script waits for TextEdit to finish before proceeding. In this scenario the script will wait indefinitely for me to go into TextEdit and do something about those unsaved changes… but not really indefinitely because you will get the timeout error if you wait too long.

Maybe that’s your problem.

on quitApps()
	repeat with anApp in appsToQuit
		ignoring application responses
			tell application anApp to quit
		end ignoring
	end repeat
end quitApps

Alternatively you might want to tell those applications (if appropriate) to issue a save command so that a document is saved if it has unsaved changes… and then issue the quit command.

Success! Thanks!

Glad it worked… it was just a guess. :cool: