Applet won't quit

The pared down code below behaves as per my actual applet in that it won’t quit. Clicking any of the 3 buttons in the try block doesn’t quit the app but rather it runs the code after the try block; to my understanding that should only happen if “Yes” is clicked. What am I missing? Here’s the code:


on run
	tell application "Finder"
		try
			set dialogAnswer to "Ask a question?" display dialog buttons {"Yes", "No", "Cancel"} ¬
				default button "Yes"
			if button returned of dialogAnswer is "Yes" then
				-- carry on
			else
				tell me to quit
			end if
		on error number -128 -- userCanceledErr
			tell me to quit
		end try
		display dialog "Carrying on..." buttons {"OK"}
	end tell
end run

on quit
	continue quit
end quit

Behaviour is the same whether as a Carbon or Bundle AS applet. Applet is not stay-open. I’m saving from Script Debugger v4.0.8 FWIW.

I’ve also tried using the name of off my applet in the quit calls, with no joy either:


			else
				tell application "TestApp" to quit
			end if

Am I overlooking something obvious? I thought adding the ‘on quit’ handler with ‘continue quit’ was supposed to resolve this sort of issue.

TIA,

Mark

Model: Powerbook G4 1.67GHz PPC, 2GB RAM
AppleScript: 1.10.7
Browser: Safari 525.18
Operating System: Mac OS X (10.4)

Try this instead:

Peter B.



on run
	tell application "Finder"
		
		display dialog "Ask a question?" buttons {"Yes", "No", "Cancel"} default button 1
		
		set dialogAnswer to button returned of result as text
		
		if dialogAnswer is "Yes" then
			-- carry on
		else
			error number -128
		end if
		
		display dialog "Carrying on..." buttons {"OK"} default button 1
		
	end tell
end run

Interesting; I grant that it does resolve the ‘not quitting’ but appears to do so by using an unhandled error that thankfully we don’t see. The syntax books and guides indicate I should be able to use an on quit handler - not least so as to trap issues like cleanup routines running. So how do I trap quit correctly?

Thanks Peter for the quick fix - that I’ll use for now - but I’m interested to know why my earlier code was wrong, given that I believe it follows official syntax.


Mark

To be honest, I’m kind of a ‘seat of the pants’ scripter… if something works for my needs, I use it.

I’ve had difficulty with the same sort of routine in past… including efforts to quit (or simply STOP) stay open apps, where ‘tell me to quit’ (or something of the like) is needed.

I’ve also run across situations where I had to (counter-intuitively) use both ‘tell me to quit’ followed immediately by ‘error number -128’ to get the dang thing not to move on to the next routine.

I think there are (more erudite) discussions about the use of quit and error -128 in the forum archives if you search for them.

Peter B.


I hear you - AS can be quite impenetrable for the occasional scripter! Interestingly, following your suggestion, I found that if I put an error code -128 in my ‘on quit’ handler instead of the continue quit statement, a quit occurred as intended. Go figure…

I’ll search on the error code in the forums and see what comes up. Thanks again.


Mark

Aha, post #8 from this thread http://bbs.macscripter.net/viewtopic.php?id=24649 makes sense. The quit doesn’t apply to a script but rather to applications and the latter doesn’t include script applets. Run from a Script Editor IDE, ‘quit me’ quits the the script by quitting the Script Editor app running the script.

Looks like applets (and probably droplets) are a gap in the documentation no one’s bothered to plug over time. I was surprised to find neither of the otherwise good O’Reilly AS books touched on this issue. Oh well.

So the self-quit command for an applet script is the unintuitive ‘error -128’ who’d have thought. I hope noting this here saves someone else the time I’ve wasted!


Mark

Hello

No need to generate a fake error, just “return”


on run
	tell application "Finder"
		
		display dialog "Ask a question?" buttons {"Yes", "No", "Cancel"} default button 1
		
		set dialogAnswer to button returned of result as text
		
		if dialogAnswer is "Yes" then
			-- carry on
		else
			return -- HERE it is
		end if
		
		display dialog "Carrying on..." buttons {"OK"} default button 1
		
	end tell
end run

Yvan KOENIG (from FRANCE mercredi 7 mai 2008 19:38:10)

Interestingly it works in the try block but not if delegated to an on quit handler - but, aha, in our example ‘return’ in the Try block is simply exiting the (notional) on run handler. If on quit has a return, it bounces the user back to the calling - ‘on run’ handler so the code continues.

This all works:


on run
	tell application "Finder"
		try
			set dialogAnswer to "Ask a question?" display dialog buttons {"Yes", "No", "Cancel"} ¬
				default button "Yes"
			if button returned of dialogAnswer is "Yes" then
				-- carry on
			else
				return -- exits 'on run' falls into 'on quit'
				-- 'error code -128' also works here
			end if
		on error number -128 -- userCanceledErr
			return -- exits 'on run' falls into 'on quit'
		end try
		display dialog "Carrying on..." buttons {"OK"}
	end tell
end run

on quit
	-- do on-quit stuff here
	continue quit
end quit
 

What the examples I’ve seen al day consistently get wrong is use of ‘tell me to quit’ or ‘quit me’ in try blocks without explaining that this doesn’t work for an applet. The latter appears to have no addressable app (you can’t call the alpet’s name - I tried that).

Oh well, I’ve learnt a bit more about handlers! I note the O’R books sadly fail to explain ‘return’ properly.

Yes it does; but, as I hope that post makes clear, the applet doesn’t finally quit until it’s finished running the script code.

When you click the “No” button in the script at the top of this thread, the applet’s told to quit. It receives that command immediately, but still has the other ‘display dialog’ to execute, so it does that before quitting (as part of the quitting process).

When you click the “Cancel” button, the “User canceled” error (number -128) is generated. Normally, this would stop the script immediately and the applet, having nothing else to do, would quit of its own accord. But you’ve trapped the error (effectually cancelling it) and issued a ‘quit’ command in its place, so the applet behaves exactly as with “No.”

A ‘quit’ handler that only contains ‘continue quit’ is a waste of space. :slight_smile:

on run
	tell application "Finder"
		set dialogAnswer to "Ask a question?" display dialog buttons {"Yes", "No", "Cancel"} ¬
			default button "Yes"
		-- Script stops here if "Cancel" clicked and the user language is English. Non-stay-open applet then quits.
		if button returned of dialogAnswer is "Yes" then
			-- carry on
		else -- "No" clicked.
			tell me to quit -- Only necessary if this is a stay-open applet.
			error number -128 -- Stop the script. (Same as clicking "Cancel".) Applet then quits as just told.
			(* Or:
			return -- return from this 'run' handler. Non-stay-open applet then quits.
			*)
		end if
		display dialog "Carrying on..." buttons {"OK"}
	end tell
end run

Thanks, I appreciate the walk through of the logic. Thank heavens for forums! I’ve tried to pick this up from books/web but it’s invariably glossed over as ‘too basic’ to require coverage yet AS is so free-form it’s hard to guess the right solution.


Mark

I’ve never seen that before where the dialog text is written before the display dialog command like you have been using… i.e. “Ask a question?” display dialog buttons {“Yes”, “No”, “Cancel”} default button “Yes”. I can’t believe that works!

But back to the question at hand, remember that display dialogs also have a cancel button parameter… so the easiest is to use something like this to generate the error number -128

display dialog "Ask a question?" buttons {"Yes", "No", "Quit"} default button "Yes" cancel button "Quit"
if button returned of result is "Yes" then
	set buttonPressed to "Yes"
else
	set buttonPressed to "No"
end if
display dialog "The button you pressed was " & buttonPressed buttons {"OK"} default button 1

I didn’t even see it when I was editing the script! :lol:

Since AS 1.10 in Tiger.

I think the syntax was a typo that worked, I’d meant to put:


set dialogAnswer to display dialog "Ask a question?" buttons {"Yes", "No", "Cancel"}

The morale of this tale for me is there are subtle differences when you want to quit the current script in these contexts:

  • a script run via Script Editor (or SD, etc.)
  • a non stay-open applet (droplet probably fits here too - not sure)
  • a stay-open applet
    … and frustratingly there’s no reference that explicitly explains the differences; it’s the classic scenario that to know the answer you need to understand a lot of the underlying principles, in which case you don’t need to ask the question! Murphy’s Law means that my scenario - #2 - is the least intuitive to a occasional scripter like me who’s not got experience with AS handlers. Anyay, thanks to all for nudging me in the right direction.

In my limited experience I have found that usually it is not possible to just quit a stay open application which had an ‘on idle’ block.

I put the following in my on idle / on run / on quit / wherever handler:

	tell application "System Events" to tell process myName to set myPID to unix id
	do shell script "kill -9 " & myPID

In the ‘on run’ handler I would have filled myName with:

tell application "System Events" to set myName to item 1 of (get name of processes whose frontmost is true)

or

tell application "Finder" to set myName to name of (first process whose frontmost is true)

The top two script lines are all that is necessary in the quit handler. Don’t even both with ‘continue’.