Регистрация EventHotKey CMD+TAB в Mountain Lion

Согласно этому посту:

ShortcutRecorder запись CMD+Tab

призвание setCanCaptureGlobalHotKeys:YES элемент управления ShortCutRecorder должен позволять вам захватывать CMD+TAB. Тем не менее, это не похоже на работу. Я сам создал это небольшое приложение, чтобы увидеть, что происходит:

OSStatus myHotKeyHandler(EventHandlerCallRef nextHandler, EventRef anEvent, void *userData)
{
    NSLog(@"YEAY WE DID A GLOBAL HOTKEY");
    return noErr;
}

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    EventHotKeyRef myHotKeyRef;
    EventHotKeyID myHotKeyID;
    EventTypeSpec eventType;

    eventType.eventClass = kEventClassKeyboard;
    eventType.eventKind = kEventHotKeyPressed;

    myHotKeyID.signature = 'mhk1';
    myHotKeyID.id = 1;

    InstallApplicationEventHandler(&myHotKeyHandler, 1, &eventType, NULL, NULL);

    OSStatus status = RegisterEventHotKey(kVK_Tab,
                                          cmdKey,
                                          myHotKeyID,
                                          GetApplicationEventTarget(),
                                          0,
                                          &myHotKeyRef);

    NSLog(@"status:%d", status);
}

@end

Если я использую cmdKey + optionKeyтогда это работает.

Есть ли другой способ захвата CMD + TAB в моем собственном приложении на Mountain Lion? CMD+OPTION+TAB не достаточно хорош для меня.

1 ответ

С тех пор, как этот вопрос был задан в 2010 году, ситуация немного изменилась! Ck обнаружен Dock.app с помощью события "Tap", и это событие больше не возвращает его обратно в приложение.

Вы все еще можете поймать ⌘⇥, но вам нужно победить Dock с помощью Event Tap. Вот пример кода, любезно предоставленный osxbook.com:

// alterkeys.c
// http://osxbook.com
//
// Complile using the following command line:
//     gcc -Wall -o alterkeys alterkeys.c -framework ApplicationServices
//
// You need superuser privileges to create the event tap, unless accessibility
// is enabled. To do so, select the "Enable access for assistive devices"
// checkbox in the Universal Access system preference pane.

#include <ApplicationServices/ApplicationServices.h>

// This callback will be invoked every time there is a keystroke.
//
CGEventRef
myCGEventCallback(CGEventTapProxy proxy, CGEventType type,
                  CGEventRef event, void *refcon)
{
    // Paranoid sanity check.
    if ((type != kCGEventKeyDown) && (type != kCGEventKeyUp))
        return event;

    // The incoming keycode.
    CGKeyCode keycode = (CGKeyCode)CGEventGetIntegerValueField(
                                       event, kCGKeyboardEventKeycode);

    // Swap 'a' (keycode=0) and 'z' (keycode=6).
    if (keycode == (CGKeyCode)0)
        keycode = (CGKeyCode)6;
    else if (keycode == (CGKeyCode)6)
        keycode = (CGKeyCode)0;

    // Set the modified keycode field in the event.
    CGEventSetIntegerValueField(
        event, kCGKeyboardEventKeycode, (int64_t)keycode);

    // We must return the event for it to be useful.
    return event;
}

int
main(void)
{
    CFMachPortRef      eventTap;
    CGEventMask        eventMask;
    CFRunLoopSourceRef runLoopSource;

    // Create an event tap. We are interested in key presses.
    eventMask = ((1 << kCGEventKeyDown) | (1 << kCGEventKeyUp));
    eventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, 0,
                                eventMask, myCGEventCallback, NULL);
    if (!eventTap) {
        fprintf(stderr, "failed to create event tap\n");
        exit(1);
    }

    // Create a run loop source.
    runLoopSource = CFMachPortCreateRunLoopSource(
                        kCFAllocatorDefault, eventTap, 0);

    // Add to the current run loop.
    CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource,
                       kCFRunLoopCommonModes);

    // Enable the event tap.
    CGEventTapEnable(eventTap, true);

    // Set it all running.
    CFRunLoopRun();

    // In a real program, one would have arranged for cleaning up.

    exit(0);
}

Недостатком этого является то, что вы не можете изолировать или отправить приложение, которое использует ⌘⇥, в App Store. Мало того, что должно быть очевидно, почему прослушивание событий не разрешено в этих средах (они дают вам возможность завершать - и даже изменять - события), но и функциональность, которую Dock предоставляет для ⌘⇥, чертовски полезна и не может быть переназначена для другие сочетания клавиш, поэтому даже Witch и Switch не используют его по умолчанию.

Другие вопросы по тегам