Re: Subverting the first responder chain
Re: Subverting the first responder chain
- Subject: Re: Subverting the first responder chain
- From: John Stiles <email@hidden>
- Date: Thu, 27 Mar 2008 20:12:11 -0700
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.
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/HandlingKeyEvents/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@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