pausing main script while window is open

Hi,

My current app waits for a said application to run, then it shows a window to select some settings. For the rest of the script to work correctly I need the values that will be entered into this window.

How would I pause the main script until the window is closed(User hits the OK button). I hope there is a better way than loop checking a variable until it’s set to true.

Thanks,

It’s hard to answer this question without some more information about how the flow of your program is controlled. How does it know when the other application has finished running, and to open your window? Normally, you would have a method that would be called when you close your window which would get the values the user entered there, and then that same method could call the next method in your script to continue onward.

Ric

This is what I have for my main script.
The first time it runs it shows the pref window. Inside the pref window the user selects an app, which gives the variable “appName” a value. Currently when run it gives me an error saying that appName has no value. This is because the script continues and does not give enough time for the user to enter his options.

   on applicationDidFinishLaunching_(aNotification)
        if virgin or (current application's NSEvent's modifierFlags() is equal to current application's NSAlternateKeyMask) then 
            fadeIn(winPref)
            set virgin to false
        end if
        repeat
            if application appName is running then
                tell me to activate
                fadeIn(winAsk)
            end if
            if running then
                delay 3
            else
                delay 0.2
            end if
        end repeat	
    end applicationDidFinishLaunching_

Hopefully this makes a little more sense.

It looks to me that you have several problems with this code. Your repeat loop doesn’t have any exit, so it will run forever. Where does the variable virgin come from – are you using userDefaults? Using delay statements is not a good practice either – it would be better to use an NSTimer to repeatedly call a method on a timed basis to check whether an App is running. I don’t know what “tell me to activate” is supposed to do – “me” is your script, and it is already running so there is no need to activate it. I think you need to try something like the following program – I tried it using Mail as the app (I had it running when I started the program), and I got the behavior that I think you’re looking for.

script AppRunnerAppDelegate
	property parent : class "NSObject"
	property winPref : missing value --connected to the winPref window (its visibleAtLaunch behavior should be unchecked in IB)
	property tf : missing value --connected to the text field in prefWin
	property appName : missing value
	property ud : missing value
	property virgin : 1
	
	on applicationDidFinishLaunching_(aNotification)
		set ud to current application's NSUserDefaults's standardUserDefaults()
		if ud's objectForKey_("firstTime") is not missing value then
			set virgin to ud's objectForKey_("firstTime")
		end if
		if virgin = 1 or (current application's NSEvent's modifierFlags() is equal to current application's NSAlternateKeyMask) then
			ud's setObject_forKey_(0, "firstTime")
			fadeIn(winPref)
		else
			nextMethod()
		end if
	end applicationDidFinishLaunching_
	
	on fadeIn(winPref)
		winPref's setAlphaValue_(0)
		winPref's makeKeyAndOrderFront_(me)
		winPref's animator's setAlphaValue_(1)
	end fadeIn
	
	on winPrefClosed_(sender) --this should be the action of the "OK" button that closes the winPref
		set appName to tf's stringValue() as string
		ud's setObject_forKey_(appName, "appName")
		winPref's orderOut_(me)
		current application's NSTimer's scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_(1, me, "checkApp:", missing value, 1)
	end winPrefClosed_
	
	on checkApp_(sender)
		if application appName is running then
			log "The chosen App is running"
		else
			log "App not running"
			sender's invalidate() --This turns off the timer
			nextMethod() -- Here is where you run the rest of your program
		end if
	end checkApp_
	
	on nextMethod()
		set appName to ud's objectForKey_("appName")
		log appName
		log "running the rest of the program"
	end nextMethod
	
end script

Ric

Hi Ric,

take a look at the NSWorkspaceDidLaunchApplicationNotification of NSWorkspace.
It’s much more convenient than a timed loop.

Vielen Dank! Stefan,

I thought there should be something out there that would check whether other apps were running or not, but I didn’t know what. I’ll check out this class for all its possibilities (I already tried your suggestion, and that worked great).

Ric

After checking the documentations it looks like this using the NSWorkspace would be the best way to do this. Although I have no idea on how to make this work.

This is what I found, and if I’m correct returns an array. How would I use this to check whether an app was launched in applescript ?

[[workspace notificationCenter] addObserver:self 
                                   selector:@selector(applicationLaunched:) 
                                       name:NSWorkspaceDidLaunchApplicationNotification 
                                     object:workspace];

Thanks !

You have to get the sharedWorkspace first and then the notificationCenter:

set noter to current application's NSWorkspace's sharedWorkspace()'s notificationCenter()
		noter's addObserver_selector_name_object_(me, "watch:", current application's NSWorkspaceDidTerminateApplicationNotification, missing value)

this one is looking at when an application closes, you could add another observer with NSWorkspaceDidLaunchApplicationNotification to watch for application opening if you want. To use these, in my example, the method watch: could look something like this:

on watch_(aNotification)
		set appName to ud's objectForKey_("appName") as string
		if aNotification's userInfo's NSApplicationName as string is appName then
			nextMethod() -- Here is where you run the rest of your program
		end if
	end watch_

This method will get a notification any time an application is closed, but will only run the rest of your code if that application is the one whose name is appName

Ric