Avoid Timeout with "choose from list"

To avoid a timeout error while displaying a normal dialog box i can use “giving up after” but, this is not accepted by the “choose from list” dialog. How can I avoid a timeout error while displaying a “choose from list” dialog box?

Can somebody help me please with a script snippet?

Model: 2008 iMac 20" 2.4GHz C2D
AppleScript: 2.1.2
Browser: Safari 533.17.8
Operating System: Mac OS X (10.6)

See if you can understand this script. It uses the fact that you can run a shell command and not wait for the shell command to finish. So we start a shell process which will “keystroke return” after 5 seconds. Then we immediately show our “choose from list” window and if there’s no response within 5 seconds then the “keystroke return” will dismiss it.

-- setup a 5 second script to press the default button
set a to "delay 5"
set b to "tell application \"System Events\""
set c to "set theProcess to first process whose frontmost is true"
set d to "set winName to name of window 1 of theProcess"
set e to "if winName is \"Choose From List\" then keystroke return"
set f to "end tell"
do shell script "osascript -e " & quoted form of a & " -e " & quoted form of b & " -e " & quoted form of c & " -e " & quoted form of d & " -e " & quoted form of e & " -e " & quoted form of f & " > /dev/null 2>&1 &"

-- show the list
set theList to {"yes", "no", "maybe"}
tell me
	activate
	choose from list theList with title "Choose From List" with prompt "PickOne" default items "maybe" OK button name "Select" cancel button name "Quit"
end tell
tell result
	if it is false then error number -128 -- cancel
	set choice to first item
end tell

Hank’s script is a neat way of geting ‘giving up after’ functionality with ‘choose from list’.

If you just want to avoid or delay the two-minute timeout error, there are two further answers:

  1. You don’t need to if the application running the script is the one displaying the dialog.

  2. You can extend the timeout interval by using a ‘with timeout’ statement:


try
	with timeout of 3600 seconds -- Wait up to an hour before timing out.
		tell application "Finder"
			activate
			choose from list {"yes", "no", "maybe"}
		end tell
	end timeout
on error
	-- Perhaps use Hank's method to close the dialog.
end try

Hank, thank you. I like this as a general solution for providing “giving up after” to “choose from list”. Great.

Nigel, thanks as well. I did try the 3600 timeout but, difficult to believe (or not), I had users starting a script, then going to lunch or a very long “short” coffee, and then complaining they had an AppleScript crush.

Regarding your first option, I don’t quite understand what you mean. Can you please elaborate? Maybe, a short example?

Hi. Yes.

A script has to be run by an application of some kind “ such as AppleScript Editor, Script Menu, or whatever. If you save the script as an application, it’ll have its own application mechanism built into it. The application which runs the script is called the “current application”.

Any commands that aren’t in a ‘tell’ statement addressed to another application are performed by the current application itself. Application and OSAX commands which are in a ‘tell’ statement are performed by the “told” application.

It’s only when the current application tells another application to do something, and doesn’t get a response from that application within a set time (default two minutes), that a timeout occurs. So if you run the following script and just let the it sit there with the dialog showing on the screen, it should display a timeout message after a couple of minutes.


set t to (current date)
tell application "Finder"
	activate
	try
		choose from list {"yes", "no", "maybe"}
	on error
		display dialog "This script timed out after " & ((current date) - t) & " seconds."
	end try
end tell

But if the current application performs the ‘choose from list’ itself, it’ll quite happily sit there forever without erroring until someone thinks to do something about it.


set t to (current date)
activate
try
	choose from list {"yes", "no", "maybe"}
on error
	display dialog "This script timed out after " & ((current date) - t) & " seconds."
end try

Timeouts are basically safeguards in case of communication failures between the script application and other applications.

Nigel, many thanks. Logical. Wish, I thought of this myself some time ago. All I needed was to move “choose from list” out from under tell Finder. Thanks again.

Thanks all, this thread helped me with one of my projects too. I especially liked Hanks button clicker. Here’s a version I stored in my directory of useful things. I hope others may find this version to be useful too. It offers a list of choices, then times out quickly, closes it’s own window, and alerts the user that it gave up.


set WINDOW_NAME to "Choose From List"
set OK_BUTTON to "Select"
set CANCEL_BUTTON to "Quit"

try
	with timeout of 2 seconds
		set USERS_CHOICES to choose from list {1, 2, 3} with prompt "Hurry!" with title WINDOW_NAME ¬
			default items {"1"} OK button name OK_BUTTON cancel button name CANCEL_BUTTON
	end timeout

on error
set thisAPP to name of current application
	tell application "System Events"
		try
			click button CANCEL_BUTTON of window WINDOW_NAME of application process thisAPP
		end try
	end tell
	
	say "Nevermind."
	display dialog "You weren't fast enough." giving up after 4
	set USERS_CHOICES to "gave up"
end try

return USERS_CHOICES

Browser: Safari 537.36
Operating System: Mac OS X (10.10)

Some months ago I helped a user which was able to leave its mac for hours with a script running.
So I used :

with timeout of 3600 * 24 seconds -- Wait up to 24 hours before timing out.
	tell application "SystemUIServer"
		choose from list {"yes", "no", "maybe"}
	end tell
end timeout

With that he was satisfied :wink:

Yvan KOENIG running Yosemite 10.10.5 in French (VALLAURIS, France) dimanche 23 août 2015 16:46:45