• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Subverting the first responder chain
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Subverting the first responder chain


  • Subject: Re: Subverting the first responder chain
  • From: John Stiles <email@hidden>
  • Date: Fri, 28 Mar 2008 14:35:59 -0700

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/EventHandlingBasics/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/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

_______________________________________________

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
_______________________________________________

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


  • Follow-Ups:
    • RE: Subverting the first responder chain
      • From: "Allen Smith" <email@hidden>
References: 
 >Subverting the first responder chain (From: John Stiles <email@hidden>)
 >Re: Subverting the first responder chain (From: Ken Thomases <email@hidden>)
 >Re: Subverting the first responder chain (From: John Stiles <email@hidden>)
 >Re: Subverting the first responder chain (From: Allen Smith <email@hidden>)

  • Prev by Date: Re: better way to search list archives?
  • Next by Date: Re: better way to search list archives?
  • Previous by thread: Re: Subverting the first responder chain
  • Next by thread: RE: Subverting the first responder chain
  • Index(es):
    • Date
    • Thread