Re-show my main Cocoa application Window - objective-c

Ok, as simple and silly as that may seem, this is my scenario :
The application window (there is just ONE main window) is minimized
The user clicks something on the dock menu
We want to bring that main window back
Simple?
Not quite.
I've tried accessing my main window via :
[[NSApplication sharedApplication] mainWindow]
[[NSApplication sharedApplication] windows]
and then sending a makeKeyAndOrderFront: message but it's simply NOT showing up.
I've even tried showing all windows (yep, it still sees as "windows" one-or-two (hidden) sheets I'm using...), but still nothing.
Could you suggest a way, I could finally show that window, WITHOUT having to set an outlet anywhere?
I don't know; I'm probably too tired to notice, but this thing is almost nerve-wrecking...

You can un-minimize a window like so:
if([aWindow isMiniaturized])
{
[aWindow deminiaturize:self];
}
However, the problem is that the window will lose main status when it is minimized, so you'll need some other way of identifying the window.
Why can't you just use an outlet?
You can make the app un-minimize all of its minimized windows like so:
for(NSWindow* win in [NSApp windows])
{
if([win isMiniaturized])
{
[win deminiaturize:self];
}
}
When the app launches, you could store a reference to the main window and register for the NSWindowDidMiniaturizeNotification. That will tell you when the main window minimizes, which might also help you.

Related

Where is my closed NSWindow?

I have an Application delegate that holds the reference to a NSWindow and the program (small test program so far) is generally working with Main Menu and views in the window.
However I discovered that if I close the window holding the views it's gone although the program is still running. As far as i can see the window reference is not nil but how do I restore it so it's visible and shown under the Windows menu again?
The program is not document based. All actions are performed in the window in question.
I created the window in the MainMenu.xib that was auto created by Xcode (this was in Xcode7 or 8 but now I've upgraded to 9).
I'm new to windows handling on Mac so I understand this is a very basic question but I'm totally stuck here. Having a window that is supposed to hold all functionality disappear without the user being able to restore it is bad I believe.
If you have a reference to the NSWindow, you just need to show it. For example:
[window makeKeyAndOrderFront:self];
But if the user closed the single window of your app, than the question is: How will the user trigger that code? The simplest answer is that the user will click your app's icon on the dock. To handle that click, implement the following method on you app delegate.
- (BOOL)applicationShouldHandleReopen:(NSApplication *)sender hasVisibleWindows:(BOOL)hasVisibleWindows
{
if (hasVisibleWindows) {
return YES;
}
[window makeKeyAndOrderFront:self];
return NO;
}

Show all NSWindows

Pretty simple idea here, I want to show all the NSWindows in an app. The idea being that there are two windows in the app, one his hidden the other is vissable. I want to show all the windows in the app and then hide one. I can hide the window I want to hide but I cant show the windows because I am unable to obtain a reference to it. is there anyway of getting a list of all the nswindows in the app then iterating through it and hiding them or something similar, I can use [NSApp windows] however trying to use
NSArray *windowArray = [NSApp windows];
[windowArray[0] makeKeyAndOrderFront:self];
[NSApp activateIgnoringOtherApps:YES];
does not work, nor does:
NSArray *windowArray = [NSApp windows];
NSWindow *tempWindow = windowArray[0];
[tempWindow makeKeyAndOrderFront:self];
[NSApp activateIgnoringOtherApps:YES];
any suggestions?
Well in hindsight I've been a bit stupid. I had two seep rate controller objects each running one window. One was hardly doing anything as the view inside it was being handled by a different object so I just removed that one and made the first controller object take care of both windows. Problem solved.

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.

Disabling Window Behind

These days, I develop iPad applications. Since I've run out of subjects to work on, I'm working on a simple OS X application to see how far I can go.
Anyway, what I want to do is show a Preferences window (PrefWindowController). It has a separate xib (PrefWindowController.xib) from MainMenu.xib. When it appears, I want the main window to go behind it. The following is what I have.
// AppDelegate.m
- (void)preferencesClicked:(id)sender {
if (!preferencesWindow) {
preferencesWindow = [[PrefWindowController alloc] initWithWindowNibName:#"PrefWindowController"];
}
[preferencesWindow showWindow:self];
}
// PrefWindowController.m
- (void)windowDidLoad {
[super windowDidLoad];
[NSApp runModalForWindow:self.window];
NSLog(#"Hello!?");
}
- (IBAction)closeClicked:(id)sender {
[NSApp stopModal];
[self close];
}
So I've learnt that I can use runModalForWindow to put the current window on top of the main window. The problem that I have is that this preferences window will reopen when I click on the close button (closeClicked). If I click on it again, it will close. If I open Preferences and click on the same button, it won't reopen. An interesting thing is that the application won't read NSLog(#"Hello!?") when the Preferences window first opens. It does when I clicked on the close button. Do you know what I'm doing wrong?
Thank you for your help.
Modal doesn't mean display on top. Modal means stop the user interacting with anything else other than this. It does this by creating a new run loop, which means that anything after runModelForWindow won't happen till after the modal window is closed. Exactly what you are seeing with the NSLog.
You probably don't want to use a modal window for preferences. The convention for OSX is that the main app window stays active when a preferences window is open.
If you just want to bring the window to the front, and don't care if the user later clicks on the main window to bring it to the front, then use -makeKeyAndOrderFront on the window you have. If on the other hand you want this preferences window to always be in front, then make it an NSPanel rather than an NSWindow.

How to display or not a NIB-created view based on a condition

Currently, I have the following situation: I have a nib file that opens a menu, and has a unique main window. When this NIB-created view finishes the startup, the window is already initialized and displayed.
Besides starting the application with its normal way, I also want to start it in a particular way in which the window nor the menu are displayed.
I other words, I need to be able to define a condition at the startup of my application and based on that condition, I want to open/initialize/display the app using the normal view/nib or I want not to display them (but I may need to create/initialize the view).
Any ideas how can I do this?
Thanks
in the IB, go into the inspector and turn off 'visible at launch' for the main window.
THEN in your AppDelegate, check what to do: show the main window or make let it remain invisible and show the special window!
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification{
if (myCondition == TRUE) {
//do something else...
} else {
[[NSApp mainWindow] makeKeyAndOrderFront:nil];
}
}