Pause script until app exits

Occasionally I need to open an app (e.g. TextEdit) in a script and to momentarily pause operation of the script until the app quits. Right now I use the script shown below but I wondered if there might be a better way that avoids the repeat loop. I have also used System Events to see if TextEdit exists as a process but, once again, this involves a repeat loop. I googled this but could find nothing of help. Thanks.


tell application "TextEdit"
	activate
end tell

repeat
	if application "TextEdit" is not running then exit repeat
	delay 0.5
end repeat

say "OK"

Hello Peavine.
Your code is wrong.

You made the wrong test.
Run this slightly modified version ( the original one entered an infinite loop ) for see:


tell application "TextEdit"
	activate
end tell

repeat with i from 1 to 20
	log "pass " & i
	if (application "TextEdit" is not running) then exit repeat
	delay 0.5
end repeat

say "OK"

The events log will be:
[format]tell application “TextEdit”
activate
end tell
(pass 1)
(pass 2)
(pass 3)
(pass 4)
(pass 5)
(pass 6)
(pass 7)
(pass 8)
(pass 9)
(pass 10)
(pass 11)
(pass 12)
(pass 13)
(pass 14)
(pass 15)
(pass 16)
(pass 17)
(pass 18)
(pass 19)
(pass 20)
tell current application
say “OK”
end tell
[/format]
It’s logical because the app is already running when you enter the loop.

This one make the correct test and you will see that it exit the loop before executing it one time so, you may put a delay of 10 hours it will not wait.


tell application "TextEdit"
	activate
end tell

repeat with i from 1 to 20
	log "pass : " & i
	if (application "TextEdit" is running) then exit repeat
	delay 0.1
end repeat

say "OK"

Now you may be sure that

tell application "TextEdit"
	activate
end tell
repeat
	if (application "TextEdit" is running) then exit repeat
	say "Beurk, I must wait"
end repeat

will not waste your time.

Of course you may use :

tell application "TextEdit"
	activate
end tell

repeat while (application "TextEdit" is not running)
	say "Beurk, I must wait"
	delay 0.5
end repeat

say "OK"

or

tell application "TextEdit"
	activate
end tell

repeat until (application "TextEdit" is running)
	say "Beurk, I must wait"
	delay 0.5
end repeat

say "OK"

You will never ear “Beurk, I must wait”

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) vendredi 13 septembre 2019 17:57:18

Yvan. Thanks for the response. Either I did not explain properly (which I think is the case), or I do not understand what you are saying.

The workflow intended for the script is:

  1. The script opens TextEdit and the script stops at that point.

  2. The user enters some text in TextEdit.

  3. The user quits TextEdit and at that point operation of the script continues.

Your original code enter an infinite loop which I guess is not what you want.

An alternate way would be :

tell application "TextEdit"
	set myDoc to make new document
end tell

display dialog "press OK when you are ready to quit" giving up after 60 * 2 # you have 2 minutes to work upon the doc
# If you press OK, the script wil execute the code available below
say "OK, you have finished with TextEdit"

With it you may work upon the document created during up to 2 minutes then the script will execute the trailing instructions.
I ran it, typed some text in the document, saved it and quitted TextEdit
Of course it’s just an example.

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) vendredi 13 septembre 2019 18:52:11

The OP’s code is fine. It exists an infinite loop correct, when the user quits “TextEdit”.

A less expensive alternative is to save the script as stay-open application and add the on idle handler

If the applet is not quit in the continueScript handler the idle handler is still called

on run
	activate application "TextEdit"
end run

on idle
	if application "TextEdit" is not running then continueScript()
	return 2.0
end idle

on continueScript()
	say "OK"
	quit
end continueScript

StefanK. Thanks for the excellent suggestion. I compared it with my original script with the activity monitor open and your script does indeed use fewer resources. It’s nice to learn something new.

I tested 2 variants too.
Indeed, the on idle variant takes less CPU(%) and CPU time. In the CPU time the difference grows noticeably over time. So, this is a good example, indicating that, at least in AppleScript, it is better to use on idle instead of an infinite loop with exit by condition.

I was rewriting my full script using StefanK’s suggestion and, just to learn, read Bill Cheeseman’s post on stay-open Applescripts and idle handlers. It’s 13 years old but still very informative.

https://macscripter.net/viewtopic.php?id=24568

Anyways, I was interested to read the paragraph copied below. Bill is discussing scripts that are very complex, but the basic principle involved would seem to apply to my script.

“A common mistake is to overlook the idle handler and instead code a simple repeat loop that counts to a fixed number, testing for the desired condition at each iteration. The CPU then spends most of its time counting and testing, and the other processes will take much longer to complete–some, such as modem connections, may not work at all because of sensitive timing requirements. The speedup in other processes that is accomplished by using the idle handler to construct a wait loop can be astonishing.”