I think your best option* would be +[NSEvent addLocalMonitorForEventsMatchingMask:handler:]
. This creates an object which will call a block handler whenever your application receives an event of the specified type. The handling takes place right before your NSApplication
dispatches the event to a window, and you have the opportunity to modify the event or stop it from proceeding further.
You can thus catch key down events as they get passed to your app and do whatever you like with them before any controls get a chance to see them. I posted this originally in another question, but here's a snippet for doing things with arrow key presses:
NSEvent * (^monitorHandler)(NSEvent *);
monitorHandler = ^NSEvent * (NSEvent * theEvent){
switch ([theEvent keyCode]) {
case 123: // Left arrow
NSLog(@"Left behind.");
break;
case 124: // Right arrow
NSLog(@"Right as always!");
break;
case 125: // Down arrow
NSLog(@"Downward is Heavenward");
break;
case 126: // Up arrow
NSLog(@"Up, up, and away!");
break;
default:
break;
}
// Return the event, a new event, or, to stop
// the event from being dispatched, nil
return theEvent;
};
// Creates an object we do not own, but must keep track of so that
// it can be "removed" when we're done; therefore, put it in an ivar.
eventMon = [NSEvent addLocalMonitorForEventsMatchingMask:NSKeyDownMask
handler:monitorHandler];
See the Event-Handling Guide for some details about what you're supposed to do with that monitor object. Specifically, Apple apparently "discourages" removing it inside of dealloc
, but doesn't give a reason.
*So long as you can require Snow Leopard, at least.