Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Catch system event as Cmd-Tab or Spotlight in a Cocoa App

In a Cocoa App, I'm trying to find a way to catch system events like the app switcher usually launched with Cmd-Tab or spotlight, usually launched by Cmd-Space. I'm looking for either a way to catch the key event or any another way that would tell me that one of those event is about to happen, and ideally cancel it.

Apple Screen Sharing remote desktop app does it, so it should be possible. It catches those events and send them to the connected remote computer.

Here is what I already tried :

  • Catching events with the sendEvent method in NSApplication. I see all events like the Cmd keydown, the Tab keydown, but when both are pressed, I see nothing.
  • Registering a Carbon Hot key listener. I can register anything like Cmd+Q, but again, when I register Cmd+Tab, it does not respond.

Any other ideas ?

like image 898
Jeenyus Avatar asked Jun 02 '11 13:06

Jeenyus


3 Answers

See Event Taps.

like image 152
Joshua Nozzi Avatar answered Nov 07 '22 00:11

Joshua Nozzi


Found it! In my WindowViewController.m file

#import <Carbon/Carbon.h>

void *oldHotKeyMode;

- (void)windowDidBecomeKey:(NSNotification *)notification{
    oldHotKeyMode = PushSymbolicHotKeyMode(kHIHotKeyModeAllDisabled);
}
- (void)windowDidResignKey:(NSNotification *)notification{
    PopSymbolicHotKeyMode(oldHotKeyMode);
}

This is pretty magic ! and it passes the new Apple sandboxing requirement for the Mac App Store !

like image 2
Jeenyus Avatar answered Nov 07 '22 00:11

Jeenyus


I will describe you how to catch cmd+tab. But please note that will work only in fullscreen mode. I beleive there is no way to this in windowed mode. Code is pretty simple. It is a minor fix of SDL mac code - update for handling cmd+tab in fullscreen mode.

NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask 
    untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES ];
    if ( event == nil ) {
        break;
    }
if (([event type] == NSKeyDown) && 
    ([event modifierFlags] & NSCommandKeyMask)
 &&([[event characters] characterAtIndex:0] == '\t')
{
     do something here
}
like image 1
Alexander K. Avatar answered Nov 06 '22 22:11

Alexander K.