Intercepting *all* keystrokes in NSView?

2014-08-04 Thread Alex Hall
Hello list,
I have a subclass of NSView that is set to be my window's first responder. It 
intercepts keystrokes by implementing keyUp: and performKeyEquivalent: but it 
doesn't do quite what I need.

I have to intercept as many keystrokes as I possibly can, including those bound 
to menu items or lower-level system calls. For instance, if the user presses 
cmd-q, I need to be able to intercept, and selectively block, that (no, 
implementing applicationShouldTerminate: won't do here, as this has to work for 
all menu items). Moreover, and this may be impossible, I want to intercept 
VoiceOver keystrokes. I know that VO keystrokes are intercepted well before my 
app can see them, which is normally a good thing since it means that they 
almost always work, no matter what an app is doing. In this case, though, it 
would be very helpful to be able to block them (part of the app is to train 
people on the use of VO, so I can't have them pressing incorrect keystrokes and 
not knowing what they did).

Anyway, the immediate concern for me is the menu items, and anything else I can 
intercept. I can have users disable VoiceOver if I have to, so catching VO 
keystrokes is secondary. Here's what I have so far:

-(void) keyUp:(NSEvent*) event{
if(! [self handleKeyUpAndKeyEquivalent:event]) [super keyUp:event];
}

-(BOOL) performKeyEquivalent:(NSEvent*) event{
[self handleKeyUpAndKeyEquivalent:event];
return NO;
return [super performKeyEquivalent:event];
}

-(BOOL) handleKeyUpAndKeyEquivalent:(NSEvent*) event{
NSLog(@Key pressed: %hu. Modifiers: %lu. Character: %@., [event 
keyCode], [event modifierFlags], [event charactersIgnoringModifiers]);
return [[self task] checkKeypress:event];
}

First, I know that second return statement in performKeyEquivalent: is never 
called. I was doing some testing, and I figured it couldn't hurt to leave the 
second return in there since it will never be called anyway. Second, that call 
to [[self task] checkKeypress:event] is simply giving a task class the event. 
The class checks to see if the event's key press is what it was looking for, 
and returns a boolean based on what it finds.

Everything works (well, basically) except those menu item hotkeys. I get a log 
of them, since my app logs every keystroke it detects, but they aren't stopped. 
If it matters, my UI is the default window, inside of whose view is my 
key-capturing NSView subclass instance, inside of which is a basic text field. 
Please let me know if you need any additional code snippets, and thank you in 
advance for any suggestions.


--
Have a great day,
Alex Hall
mehg...@icloud.com




___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Intercepting *all* keystrokes in NSView?

2014-08-04 Thread dangerwillrobinsondanger


 On 2014/05/29, at 13:57, Alex Hall mehg...@icloud.com wrote:
 
 Hello list,
 I have a subclass of NSView that is set to be my window's first responder. It 
 intercepts keystrokes by implementing keyUp: and performKeyEquivalent: but it 
 doesn't do quite what I need

You need to read the event programming guide and then read it again. 
Views don't receive all key events and they don't get first shot at them 
either. 

In short, you're going to want to look at either NSEvent's global or local 
monitor 
Or
CGEventTap

Most of what you do id the same either way. 

Biggest gotchas are that some key events are intercepted and handled at the 
IOKit level. (Media Keys)
And that Function and modifier keys are approached differently. 
And that arrow keys are numpad keys. 
And some keys exist on on some keyboard layouts and not others. Localized 
keyboards. 

Also carefully consider input methods, by intercepting events you can actually 
be intercepting them before they are converted to what the user intends with 
multistage input ( Japanese for example )
This may or may not be ok. 

Definitely be cautious in thinking in terms of key codes. 
Key codes by the way are mostly documented in Carbon headers but can be useful 
practically. 

It's not really well documented but there are a lot of responder methods that 
are part of the Cocoa text system that can enable a lot of customization. They 
also alleviate the sandbox issues that can arise with monitors and event taps. 
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Intercepting *all* keystrokes in NSView?

2014-08-04 Thread Ken Thomases
On May 28, 2014, at 11:57 PM, Alex Hall mehg...@icloud.com wrote:

 -(BOOL) performKeyEquivalent:(NSEvent*) event{
   [self handleKeyUpAndKeyEquivalent:event];
   return NO;
   return [super performKeyEquivalent:event];
 }

 Everything works (well, basically) except those menu item hotkeys. I get a 
 log of them, since my app logs every keystroke it detects, but they aren't 
 stopped.

If you want to stop the menu item hotkeys, why are you not returning YES from 
-performKeyEquivalent:?

But, as mentioned, your best bet for getting as many key events as possible is 
an event tap.

Regards,
Ken


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com