Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I listen for a mouse event in Python on Mac?

I need to listen for global mouse events(not bound to an app) on my Mac in an app written in Python.

I'm using PyObjC, but I can't figure out how to do it. Plain ObjC examples or other Python techniques also appreciated.

My code so far:

from Quartz import *
def MyFunction(proxy, type, event):
    print event

CGEventTapCreate(kCGHIDEventTap, kCGTailAppendEventTap, kCGEventTapOptionListenOnly, kCGEventLeftMouseDown, MyFunction)

== Segmentation fault

I know I need to add it to an event source later on, but I need to get this working first.

[update]

Using PyObjC form Macports solved the segfault, so now I wrote this:

from Quartz import *

def MyFunction(p, t, e, c):
    print e

tap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, kCGEventTapOptionListenOnly, kCGEventLeftMouseDown, MyFunction, None)

runLoopSource = CFMachPortCreateRunLoopSource(None, tap, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopDefaultMode);
CGEventTapEnable(tap, True);

CFRunLoopRun();

But this just runs forever and does not respond to mouse events, what is wrong?

like image 743
Pepijn Avatar asked Feb 25 '10 20:02

Pepijn


People also ask

How do you use the mouse event in Python?

The modifiers parameter is as for the keyboard events, see Working with the keyboard. When the user begins a drag operation (i.e., pressing and holding a mouse button and then moving the mouse), the window in which they began the drag will continue to receive the on_mouse_drag event as long as the button is held down.

How do you check if the mouse is clicked in Python?

import pymouse width, height = m. screen_size() midWidth = (width + 1) / 2 midHeight = (height + 1) / 2 m = PyMouse() k = PyKeyboard() def onClick(): m. move(midWidth, midHeight) try: while True: # if button is held down: # continue # onClick() except KeyboardInterrupt: print('\nDone.


1 Answers

The fourth parameter of CGEventTapCreate is CGEventMask eventsOfInterest, and you gave it kCGEventLeftMouseDown which is an enum of type _CGEventType. Instead of the integer constant, you need to flip the appropriate bit in the bitmask. You can do this using CGEventMaskBit

So instead of this:

tap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap,
    kCGEventTapOptionListenOnly, kCGEventLeftMouseDown, MyFunction, None)

We can do this:

tap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap,
    kCGEventTapOptionListenOnly, CGEventMaskBit(kCGEventLeftMouseDown),
    MyFunction, None)

or equivalently:

tap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap,
    kCGEventTapOptionListenOnly, (1 << kCGEventLeftMouseDown),
    MyFunction, None)
like image 99
Felix Fung Avatar answered Oct 21 '22 03:10

Felix Fung