I'm sorry, my memory seems to have gotten muddled since I investigated this
issue. Upon revisiting my old test program, I realized -[super keyDown:]
*will* ultimately trigger menu items, barring weird issues like a superclass
or higher responder that intercepts the key. Apparently I believed that the
message to super didn't work precisely because the next responder in my main
application was accidentally swallowing all keyDowns. I apologize for the
misinformation, but thank you for helping me find a bug.

Allen


-----Original Message-----
From: John Stiles [mailto:[EMAIL PROTECTED]
Sent: Fri 3/28/2008 2:35 PM
To: Allen Smith
Cc: cocoa dev
Subject: Re: Subverting the first responder chain
 
I did a test and if I call
        [[self nextResponder] keyDown:theEvent];

from inside the -keyDown: method, it does in fact trigger the 
appropriate hotkey on the menu. (On the other hand, the documentation 
recommends your technique of handing off to super here:
    
http://developer.apple.com/documentation/Cocoa/Conceptual/EventOverview/Event
HandlingBasics/chapter_4_section_2.html
which is probably a good idea if you want your view's superclass to take 
a stab at the event, but in this case I have no interest in doing that. 
I want the menu bar to get the event, not any views in the middle.)

So now I "just" keep a hash table of all the application's hotkeys and 
query that at the top of -keyDown:. If the pressed key matches, I punt 
the event to next responder, and everything works again. It's 
disappointing and ugly, but it turned out to be less code than I 
thought. Walking the menus and submenus recursively to build the table 
is pretty simple, and I've already got a good hash table class which I 
was able to put to good use.

Maybe I'll file a bug on this...


Allen Smith wrote:
>
> On Mar 27, 2008, at 8:12 PM, John Stiles wrote:
>
>> Wow, this sounds like a disaster.
>>
>> Maybe in my -keyDown: call I can walk the menus in the menu bar and 
>> call -performKeyEquivalent on all of them. It's probably not fast :| 
>> I was in the process of writing code that stores the menu bar's key 
>> equivalents in a hash table and checks the hash table before handling 
>> -keyDown:, maybe I'll just keep doing that. It's gross but I guess 
>> all the potential solutions are gross.
>
> Also be aware that if any other view in your application becomes first 
> responder, it too will swallow up your key equivalents. Short of 
> overriding -[NSApp sendEvent:], I don't know of universal fix. Calling 
> -[super keyDown:] as another poster suggested doesn't work; by the 
> time an event is routed to -keyDown:, the system no longer appears to 
> consider it a candidate for menu actions.
>
> Allen
>
>>
>> Ken Thomases wrote:
>>> On Mar 27, 2008, at 7:52 PM, John Stiles wrote:
>>>
>>>> I am implementing a custom NSView subclass (actually a simple 
>>>> subclass of NSOpenGLView) that implements -keyDown: in order to 
>>>> respond to user typing. Typically, this works great.
>>>>
>>>> However, I have a few menu items which respond to atypical hotkeys 
>>>> (e.g. one responds to "space", another to "option+X"). In this 
>>>> case, I've found that the view gets a -keyDown: event, which it 
>>>> dutifully handles, and the menu hotkey is never handled. I'd prefer 
>>>> it if the menu action were triggered and no -keyDown: event were 
>>>> generated, and that's exactly what happens with more typical menu 
>>>> hotkeys like command+letters. But my view doesn't know what is in 
>>>> the menubar and so, without adding a lot of ugly special-case code, 
>>>> from within the view's -keyDown: handler, it would be difficult to 
>>>> know whether I need to send the event to the next responder or 
>>>> handle the key myself.
>>>>
>>>> Is there any elegant solution to this problem? The last thing I 
>>>> want to do is reimplement hotkey handling on my own, but I can't 
>>>> think of any workarounds to this issue that don't involve my view 
>>>> taking on a lot of extra knowledge about what's in the menubar, or 
>>>> completely hacking the responder chain in some ugly way. It seems 
>>>> that I can't forward on to the next responder and then ask "did you 
>>>> handle it?"-if the responder chain fails to handle the event, 
>>>> apparently it just calls -noResponderFor: on the window and that is 
>>>> that-there's no return value of "YES" or "NO" or anything like that.
>>>
>>> From 
>>>
<http://developer.apple.com/documentation/Cocoa/Conceptual/EventOverview/Hand
lingKeyEvents/chapter_6_section_4.html>: 
>>>
>>>
>>> "An application routes a key-equivalent event by sending it first 
>>> down the view hierarchy of a window. The global NSApplication object 
>>> dispatches events it recognizes as potential key equivalents (based 
>>> on the presence of modifier flags) in its sendEvent: method. It 
>>> sends a performKeyEquivalent: message to the key NSWindow object.  
>>> [...]  If no object in the view hierarchy handles the key 
>>> equivalent, NSApp then sends performKeyEquivalent: to the menus in 
>>> the menu bar."
>>>
>>> So, NSApplication requires modifier flags on the key event to 
>>> recognize it as a potential key equivalent.  Unfortunately, I find 
>>> no documented way of changing the application object's criteria for 
>>> recognizing key equivalents.
>>>
>>> So, I think you'll need to subclass NSApplication, override 
>>> sendEvent:, check for key events which you think should be candidate 
>>> key equivalents, and pass them to the key window and then the menu 
>>> bar via performKeyEquivalent:.  If either returns YES, stop 
>>> processing the event.  Otherwise, pass the event to [super sendEvent:].
>>>
>>> Cheers,
>>> Ken
>> _______________________________________________
>>
>> Cocoa-dev mailing list ([email protected])
>>
>> 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:
>> http://lists.apple.com/mailman/options/cocoa-dev/allen.smith%40efi.com
>>
>> This email sent to [EMAIL PROTECTED]
>
> _______________________________________________
>
> Cocoa-dev mailing list ([email protected])
>
> 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:
> http://lists.apple.com/mailman/options/cocoa-dev/jstiles%40blizzard.com
>
> This email sent to [EMAIL PROTECTED]

_______________________________________________

Cocoa-dev mailing list ([email protected])

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]

Reply via email to