Show the window after hide it by clicking the dock icon


#1

As you may know, in Mac OSX, when you close a window, it usually won’t quit the application. Instead, it hides the window and you can show it later by clicking the dock icon. In JUCE, I can hide the window by overriding:

void CMainWindow::closeButtonPressed()
{
#ifdef WIN32
	JUCEApplication::quit();
#else
	setVisible(false);
#endif
}

But I cannot find a place to show this window again upon dock window clicking. I tried focusGained but it won’t be called after the DocumentWindow is invisible. Any ideas? Thanks.


#2

Don’t think I added any kind of callback to catch clicks on the dock icon, though it’s probably not hard to do.


#3

there are some notifications in JuceAppDelegate

- (void) applicationDidBecomeActive: (NSNotification*) aNotification
{
    juce_HandleProcessFocusChange();
}

- (void) applicationWillUnhide: (NSNotification*) aNotification
{
    juce_HandleProcessFocusChange();
}

I think they will be called when clicking on dock icon, but the focus change process does not go to the JUCE window or application.


#4

Yes, you could grab that event - it gets sent to your JUCEApplication object. Not sure if it’ll still get called if the app already has focus when you click on the icon though.


#5

I am trying to achieve the same thing. Show the window after hiding it by clicking the dock icon. When the dock icon is clicked applicationDidBecomeActive is raised and focusChanged() is called. But the event is not reaching the window because it is not visible.

Would it be possible to call the existing

void JUCEApplication::suspended() {}
void JUCEApplication::resumed() {}

callbacks so that the event can be handled?


#6

After digging a bit deeper it seems the correct way to do this is to call [NSApp hide] when the user clicks the close button. This will also make a different process the foreground process. Then if the user clicks the Dock icon a call to [NSApp unhide] will restore the window to its previous state.

The native mac menu has an entry which calls [NSApp hide] but I see no way to access this functionality. I see no way at all to call [NSApp unhide].

So in summary what’s needed to make this work is:

A way to call [NSApp hide]
A way to call [NSApp unhide]
forwarding of applicationDidBecomeActive to JUCEApplication::resumed()

Can this be added to JUCE?


#7

It is simpler. If only a way to call [NSApp hide:nil] would be added to JUCE everything is available to implement the wanted functionality.

A new method Process::hide would be an easy possibility:

void Process::hide() { #if JUCE_MAC [NSApp hide:nil]; #endif }

Now closeButtonPressed() becomes:

void MainAppWindow::closeButtonPressed()
{
	Process::hide();
}

And if one wants to show the window programmatically this will work:

[code]if(! Process::isForegroundProcess())
Process::makeForegroundProcess();

toFront(true);
[/code]


#8

Any updates on this, I would like to have a properly supported way of closing an app’s window and showing it again after clicking the dock icon.


#9

What’s described above will work. The only missing piece in JUCE ist the Process::hide() method. I just double checked the tip and it seems Jules did not have time to add the method below:

void Process::hide() { #if JUCE_MAC [NSApp hide:nil]; #endif }

With Process::hide() you can hide instead of quit your app when the close button is clicked:

void MainAppWindow::closeButtonPressed()
{
Process::hide();
}

If the user clicks the dock icon again Mac OS does the right thing by default, it brings the app to the foreground again.

Be careful if you want to use this in a Mac App Store App. If you do this and you do not have a tray icon as well your app will be rejected because it does not conform to the user interface guidelines.


#10

Sorry - I meant to add that but forgot. Have done it now.


#11

Thanks a lot Jules, taking a look at using it now :slight_smile:


#12

Wonderful, working great! Another checkbox ticked!

Now if we could only get that SysTrayIcon working on OSX :slight_smile:


#13

e