Re: Responder-Chain question.
Re: Responder-Chain question.
- Subject: Re: Responder-Chain question.
- From: Quincey Morris <email@hidden>
- Date: Wed, 14 Sep 2011 12:06:17 -0700
On Sep 14, 2011, at 04:01 , Motti Shneor wrote:
> On 9/13/11 5:01 AM, Motti Shneor wrote:
>> Hello everyone.
>>
>> I need to insert some controllers I have into the responder chain,
>> in such a place that their functionality (IBActions and menu
>> validation) will be available regardless of specific view focus,
>> etc.
I *think* you've just talked yourself into a corner. I *think* the answers here are more straightforward than you think.
>>
>> Event Programming guide says:
>>
>> "You should never send setNextResponder: to an NSView object. You
>> can safely add responders to the top end of a window’s responder
>> chain—the NSWindow object itself if it has no delegate or, if it
>> has a delegate, after the delegate.
>>
>> However --- the window delegate isn't an NSResponder to start
>> with, and is only being delegated responder methods from the window
>> --- it is never in the responder chain per se. (same goes for the
>> App delegate).
>>
>> I have two questions: 1. Is it a typo, and the doc really means
>> "windowController" instead of "delegate" ?? this makes much more
>> sense.
It's not a typo. Look 3 paragraphs later (in "Responder Chain for Action Messages") and you'll see a picture showing the window delegate as the next object in the responder chain. Look a bit further down and you'll see a picture with both a window controller *and* a window delegate in the responder chain.
Also, note this text 1 paragraph later: "You can insert other responders between NSView objects and even above the NSWindow object near the top of the chain."
So what's going on here? I *think* it's mostly a case of obscurely-written documentation.
First, it isn't illegal to insert a NSResponder object into the responder chain after a NSView using 'setNextResponder:'. What "You should never send setNextResponder: to an NSView object." means is, I *think*, "You should never send setNextResponder: to an NSView object in order to set the view's place in the responder chain relative to other views and the window, because that placement is necessarily handled automatically for you." It's legal AFAIK (and Matt already confirmed that developers have been doing this for years, and the 2nd doc fragment I quoted explicitly allows it) to use 'setNextResponder:' to insert a non-NSView responder into the existing chain.
Second, the point about the window delegate, I *think*, is that the sequence of objects <window ++ window controller ++ window delegate>, which may reduce to only 1 or 2 objects depending on what objects are actually present, should not be broken by inserting foreign objects into that subchain. There is a small mystery here, about whether the delegate is linked into the chain explicitly by a 'nextResponder' reference or implicitly. I don't know the answer because I've never needed to muck with this part of the chain, but I can't see any feasible answer than "implicitly", which means that 'setNextResponder:' on the NSWindow should be sufficient to insert an object *after the window delegate*. In that case, the doc fragment you quoted isn't telling which object to call 'setNextResponder:' on, it's just trying to clarify which object your inserted object will implicitly follow in the new responder chain.
> I tried to simplify my issue to get clearer answers, but It seems I need to disclose more of my design.
>
> 1. I thoroughly read (and tried) most everything around this subject, including Matt Ghallager's , Katie-Dev and "The Mental Blog" attempts on better NSViewController integration into responder-chain.
>
> 2. My app is quite complicated and modular. Modules are bit-like browser plug-ins. They are self-contained bundles, and are responsible for specific views within the application's view hierarchy. They are controlled by NSViewController subclass of our own.
>
> 3. Modules are responsible for user actions on the objects they display. Therefore, they should validate menu items, and perform IBActions for these object even when the view is not visible, or not in focus (i.e., not in the current responder chain).
>
> For this reason, I need to attach my controllers to the responder chain in different places. Sometimes right after their view, sometimes right after their window, and sometimes, right after the Application object ( to provide application-wide actions which should be available even when there are no visible windows).
I think you're making this too hard.
In *most* cases, validation and actions go in one of two places. If they're window-specific, they go in the window controller; if they're not window-specific, they go in the app delegate. (This is over-simplified, of course. They may be handed off to other objects, but in *most* cases that doesn't involve changing the responder chain to get the handoff to occur.) If you want, you can add view controllers to this pattern, but in this case you must manually add the view controller to the responder chain -- using the 3 lines of code that Matt specified.
Now, in your application, you don't really have a reason to invent a new pattern that involves changing the responder chain (and, as you've discovered, there is some fragility and obscurity involved). I *think* what you should do is to use a delegation pattern from your app's delegate and window controllers, that give the plug-ins a chance to contribute at the window and app delegate levels.
> I have another problem ---- supporting FullScreen mode. When you use Cocoa's fullscreen API's what happens is that Appkit creates a new fullscreen window, tears your "fullScreen view" from its original window, and installs it into the fullscreen window. When you go out of fullscreen mode, it tears the view and installs it back where it was.
>
> So --- My controllers may need to move to new windows as well.
>
> That's quite complicated, and I managed to set up a decent implementation for all this --- except that I don't have the answer to the questions I sent...
>
> 1. Why Apple says "After the Delegate" when delegate isn't a responder, and is never in the responder chain.
> 2. Who (and how) is reconstructing the chain (if it all...) when user switches windows. How can I deduce from the documentation what is safe to do, and how to avoid my controllers being thrown out of the responder chain without my knowledge.
>
> Thanks again!
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden