Does anyone know the best way to prevent an escape key from closing an NSPanel
when it's the key window? My panel is a child window and I want it to behave a little more like semi-permanent part of the window, more like a drawer, and for the text controls in it I want to have the Escape key cancel editing.
I recently found more about windows and the Escape key in the Cocoa documentation. In NSResponder class reference under cancelOperation:
where it says "the window sends a default action message of cancelOperation:
to the first responder and from there the message travels up the responder chain". It seems to be different for an NSPanel
, and the window closes without the first responder getting the cancelOperation:
call or NSTextView delegates getting their doCommandBySelector:
call.
My knowledge of in's & out's of the responder chain is shameful considering that I've been doing OS X work for as long as I have. I was thinking that I need to make keyDown:
in my NSPanel
subclass behave like that of a normal window. I tried overriding the NSPanel
and can catch keyDown:
, forwarding the call to NSWindow
's keyDown:
instead of super
, but there was no change, Escape still closed the window without messages to the first responder. Was that even reasonable to try?
I then tried to completely reimplement my panel subclass' keyDown:
, making it do this:
[self.firstResponder cancelOperation:self]
I would think this would let my text field handle the escape how it normally expects, and maybe if no text field was first responder then the call would dead end. However, I tried it and the panel simply closes just like before. Obviously I'm not intercepting things at the right level.
Does anyone know what the sequence of methods that run inbetween the low level key press events and the panel closing, or what I'd need to override to intercept it and ensure cancelOperation:
goes to my first responder?
Swift port of keith-knauber’s answer:
}
Don’t forget to set the ValueEditor instance as the delegate of your NSTextView objects!