Re-open an NSWindow after it has been closed? - macos

I have a subclass of an NSWindowController called UpgradeWindowController.
So far this works for the first click; the window launches. However if you close that window, and click the button again to show upgrade window, nothing happens.
- (IBAction)showUpgradeWindow:(id)sender {
if (!self.upgradeController){
self.upgradeController = [[UpgradeWindowController alloc] initWithWindowNibName:#"UpgradeWindow"];
}
[self.upgradeController showWindow:self];
}
Any ideas? Thanks

Ok, the problem was the XIB. The file's owner needed to be connected to the Window.

Give you a suggestion, the window can be objects stored in a variable or array, although this is closed, but is actually hidden, the next time we need to use it, can go to check the window if the object is loaded, if loaded to call and display it. This can be more interesting and convenient.

Related

NSWindowController displays nib before windowDidLoad finishes

When I try launching my app through Spotlight without building it through XCode, the NSWindowController displays the unmodified nib (with the standard gray background color, etc) for a split second before windowDidLoad finishes. This looks awful, since views are in the wrong places and aren't colored correctly.
I tried removing everything from windowDidLoad to see if something in there was slowing it down, but that didn't improve things. I also tried moving the setting of the background color to initWithWindowNibName, but that didn't help either.
Is there a way to delay showing the window while it finishes loading?
Here's the code I'm using to initialize the NSWindowController:
self.windowController = [[WindowController alloc] initWithWindowNibName:#"WindowController"];
[self.windowController showWindow:self];
[[self.windowController window] makeKeyAndOrderFront:nil];
Disable NSWindowController's "visible at launch" property in Interface Builder.
(Of course, I post the question then immediately figure out the answer.)

OSX: Prevent an window from closing when user hits cmd+w key

In my MAC app, in one use case, I prompt an window to the user and give him 2 options (say buttons Save and Cancel). I want to force the user to select either of the 2 buttons to close the window.
But currently I find that if the user hits "Command + w" key when window has the focus, the window gets closed. In the .xib resource file, I uncheck the "close" option but that only disables the close option in the window UI.
How do I make sure that my window ignores the "Command+w" key and stays as is without closing.
Have also tried removing the notification by adding below code in awakeFromNib method but did not help.
[[NSNotificationCenter defaultCenter] removeObserver:NSWindowWillCloseNotification ];
Have also tried to implement "windowShouldClose" delegate method and return NO, but this method is never called. The documentation too says that this method is not reliable.
You should use an NSAlert for this sort of prompt, probably run as a sheet on the window. That would avoid the problem of closing it.
In any case, the window's delegate can implement -windowShouldClose: to control if a window is allowed to close. You can make an object (often the window controller) be its delegate by declaring that it adopts the NSWindowDelegate protocol and connecting the window's delegate outlet to that object.
I recently had to solve a similar problem. I'm not sure that this is the 'right' way to do it. But it worked for my purposes, and might work for you.
By default, I think, the 'Close Window' (CMD+W) menu item is bound to the action 'performClose' on first-responder. If you remove this binding and instead bind to a custom IBAction on your application delegate or main window controller, it allows you to conditionally call the close method of the current key-window if it is not matching the instance that you want to keep alive.
#property (strong, nonatomic) MyWindowController *unstoppable;
-(IBAction)killActiveWindow:(id)sender
{
NSWindow *keyWindow = [[NSApplication sharedApplication]keyWindow];
if ([keyWindow isNotEqualTo: unstoppable.window]){
NSLog(#" CMD+W Closing Window %#",keyWindow.title);
[keyWindow close];
}
}

Child Windows Not Being Added Properly

I'm trying to add a secondary window to bottom of my main window in an OS X application, with the hopes of eventually making it so it animates out from underneath the window when a toggle button is pressed. As far as I can tell, the best way to do this with the SDK is to add a window as a child window using - [NSWindow addChildWindow:ordered:]. However, when I call that function, although the secondary window is displayed, it isn't added as a child window. Here's the function called when I press the button:
- (IBAction)childToggleButtonPressed:(id)sender {
[self.window addChildWindow:_secondaryWindowController.window ordered:NSWindowBelow];
NSLog(#"Child Windows: %#", [[self.window childWindows] count]);
}
(I haven't added the code to dismiss it yet because I'm making sure it shows up in the first place first.)
And here's the output to the console:
2011-08-31 12:37:25.312 Playground[1712:707] Child Windows: (null)
Does anyone know why the window isn't being added as a child and what I can do to fix this?
Some additional context that might help is that I'm drawing a custom window using an image as the background for both the window itself and the title bar. The code I'm modifying can be found at http://cocoawithlove.com/2008/12/drawing-custom-window-on-mac-os-x.html.
Thank you!
EDIT: I tried overriding the - [NSWindow addChildWindow:ordered:] function and logging any information I could find, and it turns out the window itself isn't passed to the function. Hopefully this will help someone find out the problem!
I ended up solving this problem by making it so that the child windows did not have NSWindowControllers. Apparently you can't assign the window of an NSWindowController to be a child window. As soon as I turned them into NSWindow subclasses, I could add them as child windows using the code I showed above (replacing _secondaryWindowController.window with the window, of course).
In short, don't use an NSWindowController's window as a child window, use just an NSWindow.

Stopping a popover window becoming the key window

I am trying to write a Mac application which runs in the menubar, which when clicked, displays an iOS-like popover. Similar to Flexibit's Fantastical, or The Iconfactory's Take Five.
I am using INPopoverController which seems to work great.
My problem is that when the user clicks on anything in the popover view, the popover becomes the key window. Is there a way to stop this from happening?
In INPopoverWindow:
- (BOOL)canBecomeKeyWindow
{
return YES;
}
means that the popover can become a key window. You can either change it to return NO, or subclass INPopoverWindow and override that method to return NO.

Closing an NSWindow

I have a NSWindow that hosts a WebView that Ive hooked up to a script handler.
Now, when the user clicks a button on a control on the WebView it calls a Objective C method on my object.
In this specific case, the action of the button is to try and close the window hosting the WebView
[[webView window] close];
This usually works, but sometimes i get a SEGFAULT or some other access violation as a result of the event loop trying to dispatcha mouse message to the now destroyed view.
The callstack is horrible when I try to close the window, the even loop has called the window has called the webView, has called my script delegate when I try and close the window. Destruction of an object from a callback from that object is generally, well, dangerous, but I can't figure out how windows should safely be closed as a result of users interacting with views on them.
Istead of closing, can't you try out the API
- (void)orderOut:(id)sender
just check whether your window is visible and orderout that window
if([[webView window] isVisible])
[[webView window] orderOut:self];
The callstack is horrible when I try to close the window, the even loop has called the window has called the webView, has called my script delegate when I try and close the window. Destruction of an object from a callback from that object is generally, well, dangerous, but I can't figure out how windows should safely be closed as a result of users interacting with views on them.
You can use performSelector:withObject:afterDelay: to put off closing the window until 0.0 seconds after the button hit.
In this specific case, the action of the button is to try and close the window hosting the WebView
[[webView window] close];
This usually works, but sometimes i get a SEGFAULT or some other access violation as a result of the event loop trying to dispatcha mouse message to the now destroyed view.
That's not likely. The event loop will only dispatch an event for a window that exists; if you have closed and thereby destroyed a window, no event can arrive at that window, nor at any view that may once have been in it.
It would help if you would edit your question to include the stack trace for that crash.
I know this is an old question, but I'm having a similar issue and I suspect the accepted answer is missing the point. I believe the window hosting the WebView is still one or more of the delegates of the WebView, and delegate methods are being called after the WebView finishes loading, which is after the window is closed.
I was looking for the right way to resolve this… I'll keep looking. :-)

Resources