Make AppleScript wait for an Application to finish loading
I have an applescript to initiate my work environment, but have a small quibble with it. I want the script to launch several programs, and then hide them, once they started. The code looks like this currently:
tell application "Firefox" to activate
delay 0.5
tell application "Finder"
set visible of process "Firefox" to false
end tell
Obviously, delay 0.5 is just a placeholder, ideally I would want to hide the program as soon as it finished loading. Unfortunately, my load times vary a lot (from 0.2 - 5s) Is there something like a callback or a function to monitor the events of applications?
Query the visibility status in a loop, repeating to set it to invisible until it works:
set appname to "Firefox"
tell application appname to launch
tell application "System Events"
repeat until visible of process appname is false
set visible of process appname to false
end repeat
end tell
Monitoring the event log of AppleScript Editor, it's obvious that it might take a few tries; the following was repeated 1490 times when I tried it with Xcode:
set visible of process "Xcode" to false
get visible of process "Xcode"
--> true
Before it finally worked:
set visible of process "Xcode" to false
get visible of process "Xcode"
--> false
You don't usually need to add any delays, but in this case even if you set the visibile property to false, it gets set back to true after the application finishes opening. So you can't check its value or if the process exists.
You could use launch
or open -jg
to open an application without visible windows. launch
opens a new window if the application wasn't open before. open -jg
opens a new window if the application is open but has no visible windows.
set b to "com.apple.TextEdit"
tell application "System Events"
if bundle identifier of processes contains b then
launch application id b
else
do shell script "open -jgb " & b
end if
end tell
A few applications like Alfred, Growl, nvALT, The Unarchiver, and X11 didn't work with either of them. You might just need to add a fixed delay before setting visible
to false.