Bringing a spawned application to front


#1

I’m launching a second instance of an application using :

File::startAsProcess();

Once the app has finished initialized, it calls toFront(true) on the window to bring itself to the fore, and gain focus. On Windows this works as expected. On OSX the new instance opens behind the primary instance, and focus remains with the primary instance.

Is there any way to have the new instance promote itself, or does OSX just not allow that kind of thing?


#2

toFront() will bring the window to the front, but not the process. [NSApp activateIgnoringOtherApps] might do the trick?


#3

The following hack worked for me on the mac (without using ObjC++):

File app = File::getSpecialLocation(File::currentApplicationFile); system(String::formatted(T("open %ls"), (const tchar*)app.getFullPathName()));
The ‘open’ command line program acts as if the app bundle was double clicked in the Finder, bringing it to the front.


#4

In juce_mac_NSViewComponentPeer.mm I added

    void toFront (bool makeActiveWindow) override
    {
        [NSApp activateIgnoringOtherApps: YES];  //  <<<------  Added this line

        if (isSharedWindow)
            [[view superview] addSubview: view
                              positioned: NSWindowAbove
                              relativeTo: nil];

        if (window != nil && component.isVisible())
        {
            ++insideToFrontCall;

            if (makeActiveWindow)
                [window makeKeyAndOrderFront: nil];
            else
                [window orderFront: nil];

            if (insideToFrontCall <= 1)
            {
                Desktop::getInstance().getMainMouseSource().forceMouseCursorUpdate();
                handleBroughtToFront();
            }

            --insideToFrontCall;
        }
    }

This works fine for this process – but I was wondering if JUCE should include something for achieving this so I don’t have to modify the source?

Thanks,

Rail


#5

If you call Process::makeForegroundProcess(), that actually makes exactly the same call internally. Maybe just call that before bringing the window to the front?


#6

Hi Jules,

I tried

[code] Process::makeForegroundProcess();

    window.toFront (false);[/code]

and that doesn’t do it… but the change above does :slight_smile:

void toFront (bool makeActiveWindow) override
    {
        if (! Process::isForegroundProcess())
            Process::makeForegroundProcess();
    
        if (isSharedWindow)

Cheers,

Rail


#7

I find that really hard to believe, as it’d do almost exactly the same thing! Literally the first call that Component::toFront() makes will invoke that ComponentPeer::toFront method. Maybe the difference is your test for isForegroundProcess() ?


#8