Carbon/Cocoa hover over dock event

433 views Asked by At

I'm working on an application that uses bits of Carbon and Cocoa to handle some C++ code that was written for Windows. I've currently got an issue whereby, when the user either cmd+tabs out of the window, or just hovers their mouse over the dock (not just the app's icon - anywhere on the dock), the cursor (using the Cocoa NSCursor class) changes from a custom cursor to the normal OS X cursor.

Basically, does anyone know what gets sent to an app (by both Carbon and Cocoa) when the user hovers over the dock?

1

There are 1 answers

0
MAH On

This is because the Dock overrides any cursor changes. What you need to do is set a timer that repeatedly fires to change the cursor.

First create a method that lets you change your cursor and then set the customCursor

func changeCursor() { 
    /* Code here to create custom cursor */
    customCursor.set() 
}

Then when you are ready to change the cursor, you need to star the timer and let it repeatedly fire

//cursorTimer is an NSTimer object that you need to keep track of
self.cursorTimer = NSTimer.scheduledTimerWithTimeInterval(0.001, target:self, selector: "changeCursor", userInfo: nil, repeats: true)

And when you're done, you can invalidate the timer

self.cursorTimer.invalidate()

Also this will only work if your app is the front most. If someone presses command+tab, your app will no longer be able to set the cursor. To enable your app to control the cursor while in the background you have to use private APIs, so no Mac App Store.

In your bridging header you can add the following code

typedef int CGSConnectionID;
CGError CGSSetConnectionProperty(CGSConnectionID cid, CGSConnectionID targetCID, CFStringRef key, CFTypeRef value);
int _CGSDefaultConnection();

And then in your AppDelegate you can add this code in applicationDidFinishLaunching

let propertyString = CFStringCreateWithCString(kCFAllocatorDefault, "SetsCursorInBackground", 0)
CGSSetConnectionProperty(_CGSDefaultConnection(), _CGSDefaultConnection(), propertyString, kCFBooleanTrue)