NSWindowController can't capture ESC without W

2019-06-26 04:04发布

问题:

I create a subclass of NSWindowController from File->New, and with the "With XIB for user interface" option checked. So I create 3 new files. Then I use Interface Builder to add exactly ONE view into the window.

And have this code in MyWindowController.m:

- (void)keyDown:(NSEvent *)theEvent{
    NSLog(@"%@", theEvent);
}
  1. First test, add one NSButton, and run the project.
  2. Second test, add one WebView(NSButton deleted), and run the project.

In both tests, the window shows up correctly. But the diffrence is:

  1. (NSButton)I can see log output when I press keys like 'a', 'b', ..., but not the ESC key
  2. (WebView)I can see log output when I press keys like 'a', 'b', ..., and the ESC key as well

I change NSButton to other view type, and also my custom view, all act like the first case.

My qustion is:

  1. Why can't NSWindowController capture the ESC key down in the first case?
  2. Why the NSWindowController capture a ESC key down with WebView as first responder.
  3. How can NSWindowController capture the ESC key without a WebView?

回答1:

See NSResponder cancelOperation: docs: https://developer.apple.com/library/mac/ipad/#documentation/Cocoa/Reference/ApplicationKit/Classes/NSResponder_Class/Reference/Reference.html

This method is bound to the Escape and Command-. (period) keys. The key window first searches the view hierarchy for a view whose key equivalent is Escape or Command-., whichever was entered. If none of these views handles the key equivalent, the window sends a default action message of cancelOperation: to the first responder and from there the message travels up the responder chain. If no responder in the responder chain implements cancelOperation:, the key window searches the view hierarchy for a view whose key equivalent is Escape (note that this may be redundant if the original key equivalent was Escape). If no such responder is found, then a cancel: action message is sent to the first responder in the responder chain that implements it.

And if you want to handle Esc key in your NSWindowController subclass just define a cancel: method in it.



回答2:

Well, I use a Event Monitor to capture the ESC key press, see detail here: http://www.ideawu.com/blog/post/54.html

But still don't get the WevView test.



回答3:

I would suggest to tell the window to make the view of interest the first responder in order to catch key events

    [[self window]makeFirstResponder:_viewControllerOfInterest];