Cocoa: programmatically show the main window after closing it with X - objective-c

I want to programmatically re-open the main window of my Cocoa application after the user closed it with the X button.
I know it's still somewhere in memory but I don't know where.

If you're using the default Cocoa Application template, your app delegate has a reference to the window that's in MainMenu.xib. You can simply call
[window makeKeyAndOrderFront:self];
perhaps in an IBAction triggered by a menu item, to reopen the window. Note: be sure that the "Release when closed" and "One shot" boxes are unchecked in IB.

Surely, if the user closes a window they want it to go away. Reopening a window they just closed will most likely annoy them. If you, the programmer, disrespect their wishes, they will probably disrespect your program by moving it to the Trash.
If you want to make it impossible to close the main window, disable the close button. You can do this easily in interface builder on the Window attributes inspector.

Related

Cocoa HUD panel shows again after calling orderOut:

I'm using a NSPanel with HUD style to display some information.
There's a button inside the HUD panel, when the user clicks the button, I'll open a new window by calling:
[anotherWindowController showWindow:self];
[anotherWindowController.window makeKeyAndOrderFront];
And I want the panel disappear when the window shows, so I set the delegate of the main window, and in the windowDidResignMain callback, I called [hudPanel orderOut:nil].
The HUD panel did disappear (I can see it), but right after it closed, it reopens.
I've checked all possible orderFront: code, and none of them get called. So my hands are really tied. Is this a system level behaviour? Can anyone guide me through this?
EDIT:
I forgot to mention that, the button resides in a NSPopover. So, basically, there's a NSButton in the HUD panel. When user clicks the button, a NSPopover will show up, inside which, there's the button to bring up the new window.
Big thanks!
I had the problem. The following solved it:
[NSApp endSheet:yourPanel];
[yourPanel orderOut:self];
Use
[hudPanel performClose:nil]
(in Swift I have to use self instead of nil). I had a problem using orderOut with a popover and it was solved by using the above method.
Please add [hudPanel close] after [hudPanel orderOut:nil]
swift: hudPanel.close()
from the apple docs:
If the window is the key or main window, the window object immediately behind it is made key or main in its place. Calling orderOut(_:) causes the window to be removed from the screen, but does not cause it to be released. See the close() method for information on when a window is released.
Sometimes the window reappears during window controller inner logic, I think. I have an issue when long pressing keyboard button kills window, but shot keyDown event only hides it on the split second. After using close all goes smoothly.

How to avoid deallocating a NSPanel when closed by the user

I am developing a small and simple status menu application.
There is a menu and when the user clicks on it, a HUD window (NSPanel) should appear.
This is how I show the panel:
[hudWindow makeKeyAndOrderFront: self];
This is how I dismiss the window:
[hudWindow orderOut: nil];
So that's the events chain:
When the app starts I dismiss the window;
Then the user (that's me :-)) clicks on the menu item and makes the panel appear;
Then I click on the x and close the panel;
Then I click again on the menu item and the window doesn't appear again.
It doesn't appear again probably because it gets deallocated, and I have put a weak storage, otherwise with __unsafe_unretained it would crash at the second launch.
So I'm guessing if there's a way to avoid deallocating the window when the user clicks on it.
I have tried with a strong storage but this case at the second launch I'm unable to close it again and that's a problem.
There are many menu status applications that are able to display a window without that the user can "kill" it, I would make something of similar.
You should uncheck the "Release When Closed" checkbox in IB (or done the equivalent in code). That box is checked by default for panels.
Using a strong pointer probably doesn't work because the releasedWhenClosed setting overrides that. Having a strong pointer just means that the retain count will be at least one, but that doesn't prevent the system from explicitly sending a release message to the panel.
Can't you just change your property from weak to strong?

Launch method when window (and its views) appear in Cocoa

I have a multi Window (A,B,C) application. User can close Window A(transparent and buttonless) by pressing a specific button on interface, at some point he can reopen it by click another button.
It works great, by i need reset some values when window is opened again.
I know that awakeFromNib is called from window and from view but only once, it doesn't be call again at window reopen. Is there a method that Window (and Views ?) call when window reopen ? something like viewWDidAppear for IOS ?
You could register for the UIWindowDidBecomeVisibleNotification for that.

Message when a WebView's window is closed?

In my program I have an NSPanel containing a web view appear to a user to have them authenticate on a web page. I want to monitor if the user is closing the WebView before the authentication is complete.
I looked for messages in the WebFrameLoadDelegate protocol but I couldn't seem to find any message that would fire when the user clicks the close button for the NSPanel and only when the user clicks the close button.
I looked at subclassing NSWindowController and overriding the close method. Perhaps I did it wrong, because even when I removed the [super close] call, the panel still closed.
So, what is the correct procedure for executing extra code when the NSPanel containing the WebView closes?
If you want to stop the user from closing a window, you need to set the window's style mask to one that doesn't include NSCloseableWindowMask. This will disable the window's close button, so that it can only be closed programmatically. In the simplest case, you can just do [panel setStyleMask:[panel styleMask] ^ NSCloseableWindowMask].
Also, if you want to override a window's closing behavior, you either need to override NSWindow's (not NSWindowController's) close method, or implement windowShouldClose: on the window's delegate. I think the second way is better. At any rate, -[NSWindowController close] is just a convenience method to close the window. It isn't what's normally invoked when a window closes.

cocoa: how to re open a closed window

I successfully registered a hot key; its handler brings my app window to the front: [NSApp activateIgnoringOtherApps:YES]; (it is supposed to at least).
I have the expected behavior when my app window is in not in the front.
But it doesn't work when I close the window (clicking the red x) or when I minimize it (clicking the yellow -).
I still see the log though so the handler is called.
Any ideas?
Thanks.
-L
I would set the window to have the following attributes in the nib:
The key things are, if you plan on having the window open and closed several times, to make sure "Release when closed" is unchecked. You may also want to uncheck "Visible at Launch" to make it more clear that you'll handle the showing of the window yourself in code. (It's the presence of this flag which is likely responsible for your window being shown at all, immediately when the nib is loaded).
To show the window in code, just do something like the following (assuming you have an IBOutlet for window):
[window makeKeyAndOrderFront:nil];
You must explicitly tell the window to come onscreen. activateIgnoringOtherApps: does not open all previously closed windows.