CGEventTap blocks application input

2019-05-03 23:13发布

I'm trying to use CGCreateEventTap to monitor global mouse clicks, however when I do this it seems to block interaction with my own app. Mouse clicks in other running apps work fine, but my own app (that is the DemoAppDelegate app) does not respond completely. I can drag the main window for the app, but the red/yellow/green window buttons are greyed out. And the DemoApp's menu is unclickable as well.

This seems really strange to me, and I've been unable to figure it out. Examples of using event taps are few and far between, so any advice is greatly appreciated.

#import "DemoAppDelegate.h"

CGEventRef myCGEventCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) {
    CGPoint location = CGEventGetLocation(event);
    NSLog(@"location:  (%f, %f) - %@\n", location.x, location.y, (NSString*)refcon);
    return event;
}

@implementation DemoAppDelegate
@synthesize window;

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    CFMachPortRef eventTap;
    CGEventMask        eventMask;
    CFRunLoopSourceRef runLoopSource;
    eventMask = 1 << kCGEventLeftMouseDown;
    eventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap,
                                1, eventMask, myCGEventCallback, @"mydata");
    runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);
    CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource,
                       kCFRunLoopCommonModes);
    CGEventTapEnable(eventTap, true);
    CFRunLoopRun();
}
@end

1条回答
一夜七次
2楼-- · 2019-05-03 23:27

When you create a Cocoa application, -[NSApplication run] is responsible for running the event loop — it runs the run loop, and dispatches events. This means that you should remove that

CFRunLoopRun();

call at the bottom of your -applicationDidFinishLaunching: method implementation, since it prevents -applicationDidFinishLaunching: from returning and also prevents NSApplication from dispatching events.

查看更多
登录 后发表回答