views:

64

answers:

3

Hello,

it may pre very simple, but cannot find it:

I have three windows in three separate NIBs in my application. One is opened when a new document is opened, the other two can be opened from the program's window menu.

The problem is: two windows (in them the one that is opened at the beginning) accepts the normal keystroke as for example command-s for save, and the other one does not and gives a warning sound instead. I cannot figure out the difference between the two windows or their controllers. I know it will have to do with the responder chain, but I am left clueless.

Any ideas?

Thanks, wackazong

A: 

Check to make sure that the window's delegate is set to the window controller, and that the window controller implements -saveDocument: (or whatever action the Save item is connected to).

Wevah
But I do not want to implement saveDocument, nor all the other keyboard shortcuts, I just want to pass them on to my document controller. Somehow they are not passed on.
wackazong
Clarification: The document is not the document controller. The document controller controls the documents.
Peter Hosey
A: 

Windows don't respond to key combinations. Menu items do. In response to being pressed (whether using the mouse, using a key combination, or using Accessibility), the menu item sends its action message down the responder chain.

You get a beep when nothing in the responder chain responds to the action message.

Assuming that this is an NSDocument-based application and you've started Apple's doc-based-app template, the menu item's action is saveDocument:, and the NSDocument object is the object that responds to that message. When your document windows are active, their documents are in the responder chain, so the menu item that sends that action message is enabled. When your third window is active, the document is not in the responder chain; nothing else responds to that message, so the menu item is disabled.

This problem isn't specific to Save—it affects all action messages that should go through to the document object. One important other example is Print: The user will probably mean to print the document, not the third window.

You've probably made this third window a kind of window that exists as a peer to the other windows. Besides this responder-chain problem you're having, the user will also probably not realize that they have left the document; they expect to still be able to do document things. Consider making it a utility panel instead.

If you really do have a good reason to make this window whatever kind of window it is, you'll need to keep the last-active document object in the responder chain when this third window becomes main, while at the same time handling the case where the window becomes main because a document window (possibly the last one) has closed.

Peter Hosey
Hey Peter,thanks a lot for the enlightenment. The third window is actually also part of the document, I have no idea how I managed to make it a non-document related window. It really should be a document window, like the second window is already.So the question is now: Why did that third window become a non-document-related window? I have now idea.
wackazong
Add the window's window controller to the document's array of them by sending the document a `addWindowController:` message. You may want to do this in your NSDocument subclass's `makeWindowControllers` method.
Peter Hosey
A: 

Well, it turns out that I implemented the third window in a way where I created it with its controller using initWithNibFile, ran a procedure in the controller and then sent it a [window close] command because I did not want it to appear on the screen yet. That somehow took it out of the document-associated window, no idea why. No I migrated that specific called procedure into the document controller itself, treat the window like the second window and voila, it works again.

wackazong
Yeah, you need to instantiate the window with a window controller, and add that to the document's window controllers. See my comment on my answer.
Peter Hosey
Well, I did exactly that before, too. The only difference I see is that I now create the window the first time it is opened. Before, I created it and then issued a close command to hide it again, because I did not want it to be displayed from the program start. The window would then show with the show command, but the connection to the window controller seems to be broken when you issue a close command.
wackazong