Quit in Idle Handler

Something I don’t understand. Take this stay-open script.


global a

on run
	set a to ""
	set a to choose folder
end run

on idle
	if a is "" then
		quit me
	end if
	display dialog a
	return 5
end idle

If I run it as a stay-open app, and click “Cancel” in the choose folder dialogue, the idle handler goes on to display the dialgoue, instead of quitting right away, as I expected. Why?

Thanks

Hi, alexn.

There are two things to consider here: the script and the built-in, stay-open application that’s running it.

If you click the ‘Cancel’ in the ‘choose folder’ dialog, a “User canceled” error is generated which immediately stops the execution of the script. (If there were any commands after ‘choose folder’ in the ‘run’ handler, they wouldn’t be carried out.) However, the script application stays open (because it’s a stay-open application) and it immediately gets a signal to execute the first run of the script’s ‘idle’ handler.

The ‘quit’ command is aimed at the application, not the script. The application gets the command, but doesn’t act on it until it’s finished what it’s doing, ie. running the ‘idle’ handler. Once that’s out of the way, the application quits. (Actually, I think it quits before doing anything else the next time it gets the signal to execute the ‘idle’ handler.)

The only way I know to stop and quit a stay-open script immediately is to issue a ‘quit’ command and “User canceled” error in quick succession.

global a

on run
	set a to ""
	set a to choose folder
	say "Hello" -- Not executed if the "Cancel" button's clicked.
end run

on idle
	if a is "" then
		quit -- Quit when the script finishes,
		error number -128 -- Stop the script now.
	end if
	display dialog a
	return 5
end idle

Thanks, that’s it. I think that’s the paradigm (if I may be excused for the cliché) I wasn’t getting – “quit” is for the app, not for the handler. I think that it follows that the solution is to add a “return 1” after the “quit”. The return ends the handler; on the next loop, quit ends the application… Back to the drawing board…

Hi,

What I do to get around this initial firing of the idle handler is to place all statements in the if statement. Something like this:

global a

on run
set a to “”
set a to choose file
end run

on idle
if a is “” then
quit
else
display dialog (a as string)
end if
return 2
end idle

Edited: BTW, this happens even after the initial run when you quit, so always write the idle handler like this.

gl,

this works


global a

on run
	try
		set a to ""
		set a to (choose folder) as string
	on error number -128
		quit me
	end try
end run

on idle
	display dialog a
	
	return 5
end idle

Hi Mark,

As I wrote in the previous post, this behavior doesn’t only happen on the initial run. It’s better to keep your idle handler statements within the if stament.

gl,

I must be missing the point.?

I thought the point was to stop the app and quit the app if no folder is not selected in the run handler.

Your and my script do this with no problems that i can see.

So what is my script not doing??

Hi,

The purpose of the idle handler is to run and not to quit as soon as you run it.

gl,

I know what an idle handler is for.

But again was not the point to quit the app if no folder is selected on the initial run of the app.
Therefore it does not matter what the next handler is or what it should do.

Hi Mark,

Here’s my question. How many times would you run an app pressing the cancel button and it not doing anything?

Later,

I assume you are talking about the dialogue with the name of the file/folder and not the choose one.
I thought that was odd that they wanted that to pop up all the time. I put it down to it being a test.

By the way your app does nothing my app does not do.
If I click cancel on the dialogue with the name of the file/folder it pops up again after the 5 second return in the idle handler.