Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent 'not allowed' beep after keystroke in NSView

In my Mac app, I override and accept certain keystrokes via the keyUp function in an NSView, which isn't meant to accept keystrokes.

When a key is pressed, the keyUp function is called, and I do process the keystroke, without even calling super keyUp:, and everything works, except that it also makes that default 'doonk' sound that happens when you press a key somewhere you shouldn't.

Is there any way to indicate that the keystroke was handled and accepted, and that I don't need a beep to tell the user it wasn't?

like image 826
Greg Avatar asked Jan 15 '12 12:01

Greg


3 Answers

I think (but am not 100% certain, it's been a bit of time since I did this) you also need to override the NSView and/or NSResponder performKeyEquivalent: method. There, you'll return a YES to indicate to the caller that you did indeed handle the event.

And that will keep the "dooonk" sound from happening.

like image 55
Michael Dautermann Avatar answered Sep 18 '22 19:09

Michael Dautermann


Instead of using keyUp:, you may want to use the moveUp: action, as it takes all of the hassle of determining which key to handle out of the mix. There are also similarly named routines for down and a variety for handling movement with selections, etc.

For further documentation on this, please see the Cocoa Event-Handling Guide, and in particular "Handling Keyboard Actions and Inserting Text", where it discusses the use of these commands in "Applications other that those that deal with text".

In particular, the other benefit to using these actions is that it avoids any problems with either key interpretation or special keyboards and keyboard layouts.

like image 1
gaige Avatar answered Sep 19 '22 19:09

gaige


The accepted answer might do the trick but I would like to suggest a more correct way to solve the problem :)

Using keyUp: and keyDown: is totally fine, but most importantly, your view must also follow the AppKit responder pattern (You can learn more about NSResponder on the official documentation).

In your case, the view would need to signal itself as a valid first responder in the event chain. Assuming you have an NSView subclass, you will need to implement the following method:

@implementation MyNSView

//...

- (BOOL)acceptsFirstResponder {
    return YES;
}

@end
like image 1
Mr_Pouet Avatar answered Sep 20 '22 19:09

Mr_Pouet