Python CGEventTap Bus Error

315 views Asked by At

I get a bus error whenever I run this Python CGEventTap code:

def callback(ent):
    loc = CGEventGetLocation(ent)
    print loc

tap = CGEventTapCreate(
    kCGSessionEventTap,
    kCGHeadInsertEventTap, 
    kCGEventTapOptionDefault,
    CGEventMaskBit(kCGEventMouseMoved),
    callback(CGEventRef) )

loop = CFMachPortCreateRunLoopSource(None, tap, 0)
CFRunLoopAddSource(CFRunLoopGetCurrent(), loop, kCFRunLoopCommonModes)

RunApplicationEventLoop()

Is there something obvious that I'm missing?

1

There are 1 answers

7
jscs On

I have tried all of the following:... Which of these do I need and not need? And what do you mean by linking? – Teak

Replying to your comment with an answer because it won't fit in a comment. Sorry.

The situation is perhaps a little convoluted. PyObjC has a whole bunch of information (metadata and some helper code) about the functions, objects, etc. in Apple's frameworks, but it doesn't contain the code itself (because it's Apple's code, and PyObjC can't just go around copying it). The functions you're using are in Apple's ApplicationServices framework. PyObjC keeps its information about that framework in its Quartz module. So Part I is: to use these functions in Python, you need to get PyObjC's info: from Quartz import *.

Part II is that, like I said, your application here needs to know, not just where PyObjC's metadata is, but where Apple's code that you're trying to use is. This is the linking part. (It doesn't look like you're using Xcode, since you're setting up your own run loop, but in Xcode, you would go to the Linked Frameworks group in your project and add ApplicationServices to it.)

I guess you're using py2app? I'm afraid I'm not 100% sure how to do it that way, but this SO question might get you started: Problem using py2app

Hope that points you in a helpful direction.

(By the way, when I set up a project with your code, in Xcode and with the ApplicationServices framework linked in, it locked up my input devices so that the only thing I could do was reboot. I may have done something wrong, but be warned that when you get this linked, there may be other problems with the tap you're setting up. You might possibly want to try doing this in C/Obj-C first and then translating into Python when you know it works.)