anotherInstanceStarted is not called after launching


#1

Double clicking on a file in Finder launches the application but the anotherInstanceStarted member function is not called. It’ s interesting because it is called as expected if the application is already running. What could be the problem?
Thanks is advance,
Ninja


#2

Well, if the application isn’t already running, then you’re not starting “another” instance, so that function would make no sense…?


#3

Meanwhile I recognized what the reason is: a splashscreen is displayed in the Application::initialise member and it prevents the system to call anotherInstanceStarted. This is a bug in JUCE, because a usual MAC feature can not be implemented.
Ninja


#4

It seems that runDispatchLoopUntil causes the problem but I don’t know why.
Ninja


#5

It’s not a bug. Like I said, anotherInstanceStarted() will not be called unless there actually is another instance running…


#6

You are not right. The OpenFile method of the application delegate calls the anotherInstanceStarted and it works correctly in most cases. Except if RunDispatchLoop is running.


#7

Yes, sorry - you’re right about it getting called for the first instance too.

It looks like what you’re seeing is because during initialisation, the OS thinks (quite reasonably) that the app hasn’t finished launching yet, so it doesn’t send an openFile: message…

I don’t think this is a bug or anything that needs fixing, though - it actually makes a lot of sense to avoid opening documents until the app has finished initialising. If for example during start-up you need to show a modal dialog or something, then you don’t want the OS to start making it open documents while it’s busy interacting with the user.

A splash screen shouldn’t really be shown modally anyway! And any kind of modal loop during the initialisation stage feels a bit dodgy to me anyway. If you want to e.g. delay your main window appearing for a few seconds to make sure the users see your splash, then you should use a timer to reveal the window later, rather than blocking the initialisation process and waiting for it.

Alternatively, you could move all your initialisation into an asynchronous callback, running it after the main initialise() method has returned. By that time, the app will be in its “launched” state and the OS will presumably think it’s ok to ask it to open documents.


#8

Actually, I was going to ask for this: Jules, please could you add an option for an async startup? I tend to do it a lot in various apps. It would probably involve a different startup method to override, and a flag so that other stuff can see if it’s happened.

The main reason is that iOS will prevent an application from running if it takes too long to startup, so any time consuming process, such as opening a long file, or loading big resources (or bugs in each), can prevent an iOS app even starting. Of course, that’s a nightmare to troubleshoot - you can’t even see why.

I do a lot of RealBasic apps, and I always end up with a timer about a second after the app gets going, to open sockets, get things rolling.

Bruce


#9

Seems like a pretty trivial thing to do yourself, isn’t it? Just a case of…

[code]class MyApp : public JUCEApplication, public AsyncUpdater
{
void initialise()
{
triggerAsyncUpdate();
}

void handleAsyncUpdate()
{
    etc..
}

[/code]

…which isn’t really significantly more work than if I added something to do it automatically.


#10

Isn’t an asyncupdate generic? So I’d need a specific object to catch that update just the once (in case the main class also needs to handle async updates, or a flag to say ‘do startup this time, or else do the other stuff’.

I tend to do a specific timer that fires once. But I’m wondering if having an async startup isn’t something that most apps need? And if most apps do it, it might be better as a standard function. On iOS, it seems like the way to go for any medium complexity app.

No, it’s not that hard though. Just common.

Bruce


#11

It’s a fair point - maybe it’d be best to always make the initialise() method get called asynchronously. Can’t think of any arguments against doing it that way…


#12

Thanks for your tip. I reorganized my startup process as you suggested and it works now.
Ninja