43
votes

I'm surprised this doesn't happen automatically, but I would like my applications window to open automatically when the Dock icon is clicked.

Just to clarify, when i open the app, the window automatically opens, but when I click the cross for the window but leave the App running, the window won't open when i click the dock icon.

6
This does happen automatically. Can you be more specific?Jason Coco

6 Answers

67
votes

Implement - (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag in your app delegate. Check the documentation for the details of the return value.

Document based apps and non-document based apps behave slightly differently. If there are no open windows when the dock icon of a document based app is clicked then it will create a new document. If there are no open windows when the dock icon of a non-document based app is clicked then it will do nothing.

13
votes
- (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag
{
    if (flag) {
        return NO;
    }
    else
    {
       [YourWindow makeKeyAndOrderFront:self];// Window that you want open while click on dock app icon
        return YES;
    }
}
12
votes

This is what I'm doing to get the main window of a non-document based app back to screen once it has been closed. I know this might not be the right way to do it but It's working for me so far.

Implemented this on the AppDelegate, window is defined as instance variable of the same object.

- (BOOL) applicationShouldOpenUntitledFile:(NSApplication *)sender
{
    [window makeKeyAndOrderFront:self];
    return NO;
}

If anyone has a better solution please reply. Thanks!

8
votes

As others pointed, using applicationShouldHandleReopen method for reopening closed windows in non-document apps is the right way. The only change I want to add is a more flexible way to check what window must be re-displayed, by iterating through the NSApplication's list of visible and invisible .windows and checking for the required window.

func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool {

    if flag == false {

        for window in sender.windows {

            if (window.delegate?.isKind(of: WelcomeWindowController.self)) == true {
                window.makeKeyAndOrderFront(self)
            }
        }
    }

    return true
}

Appendix

a) If window was hidden then it will be showed automatically when user will click on app's Dock icon, so no need to implement applicationShouldHandleReopen method.

b) Checked "Release when closed" option doesn't affect in any way the above behaviour.

4
votes

A document based application will automatically open a new untitled document when the app becomes active, so I am assuming you are referring to a non-document based app.

Implement the applicationDidBecomeActive: method in your application delegate and open/show the window.

Edit:

Some information on Delegates.

Some information on Opening and Closing Windows and the NSWindow API

3
votes

A solutions to add to the accepted answer:

With the accepted answer the reopened window did not react to mouse events anymore.

When using the accepted answer you also have to make sure to uncheck "Release when closed" in the Attributes Inspector of the window in IB. This fixes the unresponsive window problem.