views:

377

answers:

3

Is there a way to register for global mouse moved events in Cocoa? I was able to register for the events using Carbon's InstallEventHandler(), but would prefer a Cocoa equivalent. I have looked for NSNotificationCenter events, but there doesn't seem to be any public event names (are there private ones?)

Alternatively, is there a way to use NSTrackingArea for views with a clearColor background?

The app is Snow Leopard only.

+2  A: 

If you want to track the mouse no matter where it is, you want a CGEventTap. There is no Cocoa equivalent. If you just want to track it in your application then you should explain why you're finding yourself unable to do so a little more thoroughly.

Azeem.Butt
Event taps are definitely the way to go. Works perfectly for me.
Leibowitzn
This did work perfectly for me, but Ben's answer was definitely exactly what I was looking for.
Colin Gislason
+4  A: 

In SnowLeopard there is a new class method on NSEvent which does exactly what you want: + (id)addGlobalMonitorForEventsMatchingMask:(NSEventMask)mask handler:(void (^)(NSEvent*))block. You’ll want mask = NSMouseMovedMask .

Ben Stiglitz
Perfect, exactly what I was looking for. Bonus for using blocks. 3 lines of code where the others took 20ish.
Colin Gislason
+1  A: 

A similar question was already asked on StackOverflow: http://stackoverflow.com/questions/435685/how-to-make-a-transparent-nsview-subclass-handle-mouse-events/436153#436153

To summarize, the tansparent view method didn't work. Quartz Event Taps seem to be the best answer.

Here are some hints on working with taps:

  1. Create the tap with CGEventTapCreate.
    a) For the location (first) parameter you'll probably want to use kCGSessionEventTap.
    b) For the placement (second) parameter you'll probably want kCGHeadInsertEventTap.
    c) For the event mask parameter, try (1 << kCGEventMouseMoved).

  2. Create a run loop source with CFMachPortCreateRunLoopSource, passing the event tap as the second parameter.

  3. Add the run loop source to your run loop. Assuming you want it added to the main run loop, do: CFRunLoopAddSource(CFRunLoopGetMain(), SOURCE CREATED IN STEP 2, kCFRunLoopDefaultMode);

  4. Enable the event tap with CGEventTapEnable

Doug Richardson
Thanks for the help. I understand event taps a bit better now. I ended up using Ben's NSEvent method, though.
Colin Gislason

related questions