WindowController


Gerriet M. Denkmann
 

This works:

- (void)showPreferences: (NSMenuItem *)sender;
{
(void)sender;

// if ( self.prefController == nil ) // this line should not be commented out
{
self.prefController = [ [ NSWindowController alloc ] initWithWindowNibName: @"PrefWindow" ];
};

[ self.prefController showWindow: self ];
}

But when I *not* comment out the if… line it works exactly once.

How can I convince my NSWindowController to keep its window?

Gerriet.


 


On Jul 17, 2017, at 7:12 AM, Gerriet M. Denkmann <g@...> wrote:

How can I convince my NSWindowController to keep its window?

Have you made sure the “release on close” checkbox isn’t set in IB?

(But do you really want the prefs controller to hang around when it’s closed? Seems like a waste of memory to me.)

—Jens


Jack Brindle
 

Is there a corresponding line of code that sets self.prefController to nil when the window is closed?
As I understand it, the property will only be set to nil if it is declared as weak, which is most likely
not what you want.

I get the feeling I’m missing something here, though. This is not something you would normally miss…

- Jack

On Jul 17, 2017, at 7:12 AM, Gerriet M. Denkmann <g@...> wrote:

This works:

- (void)showPreferences: (NSMenuItem *)sender;
{
(void)sender;

// if ( self.prefController == nil ) // this line should not be commented out
{
self.prefController = [ [ NSWindowController alloc ] initWithWindowNibName: @"PrefWindow" ];
};

[ self.prefController showWindow: self ];
}

But when I *not* comment out the if… line it works exactly once.

How can I convince my NSWindowController to keep its window?

Gerriet.




Quincey Morris
 

On Jul 17, 2017, at 07:12 , Gerriet M. Denkmann <g@...> wrote:

it works exactly once

You haven’t really done “due diligence” with this problem description. What does “works” mean? That the window doesn’t reappear after it’s made to disappear?

When you call that action method again, is self.prefController nil or not? Or does the “showWindow” not make the window visible? Does the action method get called at all, after the first time? What kind of object is “self”? How is the “prefController” property declared? How did you hide the window (orderOut: or close)? Is it a NSWindow or a NSPanel?

A window controller has an owning reference to its window, so it should be impossible for the window object to disappear while the controller still exists, even if the window is closed. However, the semantics of the NSWindow “close” method are unclear, and it may be that you can’t show the window again afterwards, without creating a new window (or using orderOut: instead).


Gerriet M. Denkmann
 

On 18 Jul 2017, at 00:30, Quincey Morris <quinceymorris@...> wrote:

On Jul 17, 2017, at 07:12 , Gerriet M. Denkmann <g@...> wrote:

it works exactly once
You haven’t really done “due diligence” with this problem description. What does “works” mean?
“Works” means that showWindow does indeed show a window.

That the window doesn’t reappear after it’s made to disappear?
Yes. After the red button got clicked on the PrefWindow, it never will appear again.


When you call that action method again, is self.prefController nil or not?
The first time prefController is of course nil.
The next time it is not.

Is there a corresponding line of code that sets self.prefController to nil when the window is closed?
No.

Or does the “showWindow” not make the window visible?
Exactly: this is the problem.

Does the action method get called at all, after the first time?
It gets called.

What kind of object is “self”?
App delegate.

How is the “prefController” property declared?
strong

How did you hide the window (orderOut: or close)?
Clicking the red button.

Is it a NSWindow or a NSPanel?
Same problem for both.


Have you made sure the “release on close” checkbox isn’t set in IB?
It is not checked.


(But do you really want the prefs controller to hang around when it’s closed? Seems like a waste of memory to me.)
Yes. But loading the window again would be a waste of Cpu time.
Not sure what is worse.

Kind regards,

Gerriet.


Quincey Morris
 

On Jul 17, 2017, at 11:27 , Gerriet M. Denkmann <g@...> wrote:

The first time prefController is of course nil.
The next time it is not.

I would suggest that you look in the debugger at whether the window controller *has* a window the second time around. (Note that the “window” property automatically loads the window if necessary, which means that looking can sometimes affect what you’re looking at, though I suspect not in this case.)

If it has a window, try looking at its size and frame, whether it is hidden, etc.


Gerriet M. Denkmann
 

On 18 Jul 2017, at 03:35, Quincey Morris <quinceymorris@...> wrote:

On Jul 17, 2017, at 11:27 , Gerriet M. Denkmann <g@...> wrote:

The first time prefController is of course nil.
The next time it is not.
I would suggest that you look in the debugger at whether the window controller *has* a window the second time around.
It never has. Even after the first time where showWindow will succeed.

Kind regards,

Gerriet.


Quincey Morris
 

On Jul 17, 2017, at 14:08 , Gerriet M. Denkmann <g@...> wrote:

It never has. Even after the first time where showWindow will succeed.

This is — in some sense — impossible. There is a window. (You can see it.) Either the debugger is lying to you, or the window is unrelated to the window controller. Whichever it is, it’s worth investigating further.

BTW, in your XIB file for the preferences window, did you leave “Visible at launch” checked? It shouldn’t be, if you’re using a window controller, but OTOH I can’t see it having this result if you did.


Gerriet M. Denkmann
 

On 18 Jul 2017, at 04:18, Quincey Morris <quinceymorris@...> wrote:

On Jul 17, 2017, at 14:08 , Gerriet M. Denkmann <g@...> wrote:

It never has. Even after the first time where showWindow will succeed.
This is — in some sense — impossible. There is a window. (You can see it.) Either the debugger is lying to you, or the window is unrelated to the window controller. Whichever it is, it’s worth investigating further.
if ( self.prefController == nil )
{
self.prefController = [ [ NSWindowController alloc ] initWithWindowNibName: @"PrefWindow" ];
NSLog(@"%s prefController %@",__FUNCTION__, self.prefController);
};

[ self.prefController showWindow: self ];
NSLog(@“%s window %@“,__FUNCTION__, self.prefController.window);

prints prefController once
window = nil always


BTW, in your XIB file for the preferences window, did you leave “Visible at launch” checked? It shouldn’t be, if you’re using a window controller, but OTOH I can’t see it having this result if you did.
Without “Visible At Launch” I never see a window - not even the first time.

Kind regards,

Gerriet.


Jon Gotow
 

Is the 'window' outlet of the XIB file's owner set to point to the window in the XIB? It doesn't sound like it.

- Jon

On Jul 17, 2017, at 3:44 PM, Gerriet M. Denkmann <g@...> wrote:


On 18 Jul 2017, at 04:18, Quincey Morris <quinceymorris@...> wrote:

On Jul 17, 2017, at 14:08 , Gerriet M. Denkmann <g@...> wrote:

It never has. Even after the first time where showWindow will succeed.
This is — in some sense — impossible. There is a window. (You can see it.) Either the debugger is lying to you, or the window is unrelated to the window controller. Whichever it is, it’s worth investigating further.
if ( self.prefController == nil )
{
self.prefController = [ [ NSWindowController alloc ] initWithWindowNibName: @"PrefWindow" ];
NSLog(@"%s prefController %@",__FUNCTION__, self.prefController);
};

[ self.prefController showWindow: self ];
NSLog(@“%s window %@“,__FUNCTION__, self.prefController.window);

prints prefController once
window = nil always


BTW, in your XIB file for the preferences window, did you leave “Visible at launch” checked? It shouldn’t be, if you’re using a window controller, but OTOH I can’t see it having this result if you did.
Without “Visible At Launch” I never see a window - not even the first time.

Kind regards,

Gerriet.





Gerriet M. Denkmann
 

On 18 Jul 2017, at 04:55, Jon Gotow <gotow@...> wrote:

Is the 'window' outlet of the XIB file's owner set to point to the window in the XIB? It doesn’t sound like it.
Indeed it was not. After connecting it as it should have been, now all works perfectly as expected.
Thanks a lot for this brilliant idea!

This brings up another question:
I seem to remember that once Xcode allowed me to create a window + window-controller together (with all connections nicely set).
Today I could not found this (Xcode 8.3.3).
Can this be done; if yes: then how?




On Jul 17, 2017, at 3:44 PM, Gerriet M. Denkmann <g@...> wrote:


On 18 Jul 2017, at 04:18, Quincey Morris <quinceymorris@...> wrote:

On Jul 17, 2017, at 14:08 , Gerriet M. Denkmann <g@...> wrote:

It never has. Even after the first time where showWindow will succeed.
This is — in some sense — impossible. There is a window. (You can see it.) Either the debugger is lying to you, or the window is unrelated to the window controller. Whichever it is, it’s worth investigating further.
if ( self.prefController == nil )
{
self.prefController = [ [ NSWindowController alloc ] initWithWindowNibName: @"PrefWindow" ];
NSLog(@"%s prefController %@",__FUNCTION__, self.prefController);
};

[ self.prefController showWindow: self ];
NSLog(@“%s window %@“,__FUNCTION__, self.prefController.window);

prints prefController once
window = nil always


BTW, in your XIB file for the preferences window, did you leave “Visible at launch” checked? It shouldn’t be, if you’re using a window controller, but OTOH I can’t see it having this result if you did.
Without “Visible At Launch” I never see a window - not even the first time.

Kind regards,

Gerriet.







Jon Gotow
 

On Jul 17, 2017, at 4:06 PM, Gerriet M. Denkmann <g@...> wrote:

Indeed it was not. After connecting it as it should have been, now all works perfectly as expected.
Thanks a lot for this brilliant idea!
Glad that fixed it!

This brings up another question:
I seem to remember that once Xcode allowed me to create a window + window-controller together (with all connections nicely set).
Today I could not found this (Xcode 8.3.3).
Can this be done; if yes: then how?
When you create a new source file for a class that's derived from NSWindowController, Xcode will offer to make the class files as well as a XIB file (all wired up) for you. Unfortunately, there's no way to get it to do this after you've created the class - it's a 'creating-a-new-class' workflow and that's it.

- Jon


Marco S Hyman
 

On Mon, Jul 17, 2017 at 11:27 am, Gerriet M. Denkmann wrote:



How did you hide the window (orderOut: or close)?
Clicking the red button.
Which probably does a close which is not what you want. Assuming that your window controller is your window delegate (I think that is set up automagically) you want to add a method to your controller. Something like this:

// window delegate function... orderOut instead of close

func windowShouldClose(sender: AnyObject!) -> Bool {
if let window = window {
window.orderOut(sender)
}
return false
}