Make AppleScript wait for an Application to finish loading

7

4

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?

Christian Macht

Posted 2012-09-03T18:22:57.383

Reputation: 375

Why not just call open -aw Firefox and then hide the app using AppleScript? – slhck – 2012-09-03T19:11:46.207

@slhck Sorry, I don't understand. Parameter -a requires a specific app to open with, and -W waits until the app that was open is closed. My understanding from man open is that it has no options that might be useful for this? – Christian Macht – 2012-09-03T19:39:39.087

Whoops, sorry, I misunderstood that. – slhck – 2012-09-03T19:45:57.570

Answers

6

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

Daniel Beck

Posted 2012-09-03T18:22:57.383

Reputation: 98 421

Great, this works! I had to add a delay before System Events performs its checks or it would return --> true before Firefox even opened (slow machine ;) ). However, is there no "smoother" way of the app calling back once it finished loading? – Christian Macht – 2012-09-03T19:42:36.753

It didn't work for me either. The visibility gets set to true again once Firefox finishes opening. – Lri – 2012-09-04T13:21:30.487

2

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.

Lri

Posted 2012-09-03T18:22:57.383

Reputation: 34 501

Oh I wish this would work, but unfortunately open -j doesn't exist, at least on 10.6.8 / Bash 3.2.48. Which version are you on? – Christian Macht – 2012-09-04T11:43:30.117

10.8.1. I don't know if it was available in 10.7 or earlier versions, but it's missing from the man page and only shown in the help message. – Lri – 2012-09-04T12:12:48.607

I tried, and it's invalid option -j . Could you tell me your bash -version as well? It would be down to that right? – Christian Macht – 2012-09-04T13:09:50.450

The shell wouldn't affect /usr/bin/open, and do shell script uses sh anyway. – Lri – 2012-09-04T13:25:22.183

Is there any way for me to get the open executable that supports -j ? – Christian Macht – 2012-09-04T17:50:40.427