For cursor update events (with NSTrackingArea) how to know if it's coming or going?

I've added an NSTrackingArea to my NSView because I want a certain rectangular area to show a different cursor. As expected, my view gets a call to it's cursorUpdate:(NSEvent*) method, but how do I tell whether it's an "enter" or "leave".

- (void)cursorUpdate:(NSEvent *)event {    
    // Do I push or pop my custom NSCursor?
}

I notice the event.modifierFlags changes from 8 to 9. But I don't see any public enum constants to test that, so I don't know if I can depend on that. The public enum contains stuff like this, in the higher bits.

typedef NS_OPTIONS(NSUInteger, NSEventModifierFlags) {
    NSEventModifierFlagCapsLock           = 1 << 16,
    NSEventModifierFlagShift              = 1 << 17,
    ...

The tracking area setup code:

NSRect nsRect = ...
NSTrackingAreaOptions options = NSTrackingCursorUpdate | NSTrackingActiveInKeyWindow;
NSTrackingArea *trackingArea = [[NSTrackingArea alloc] initWithRect: nsRect options: options owner: owner userInfo: userInfo];
[myView addTrackingArea: trackingArea];

Replies

It's Swift, but immediate to convert to objC.

In this example I subclass NSTextField or NSButton

class TextFieldWithHelp: NSTextField { }

I override 2 func:

    override func mouseEntered(with theEvent: NSEvent) {
        
        super.mouseEntered(with: theEvent)
        myCursor!.set()     // Set cursor
    }
    
    
    override func mouseExited(with theEvent: NSEvent) {
        
        super.mouseExited(with: theEvent)
        arrowCursor!.set()       // restore the default arrow
    }

Then I use trackingArea, with mouseEnteredAndExited and cursorUpdate options (helperButton is of the subclass)

        if helperButtonTrackingArea == nil {
            helperButtonTrackingArea = NSTrackingArea(rect: helperButton.bounds, options: [NSTrackingArea.Options.mouseEnteredAndExited, NSTrackingArea.Options.cursorUpdate, NSTrackingArea.Options.activeInKeyWindow], owner: helperButton, userInfo: nil)
            helperButton.addTrackingArea(helperButtonTrackingArea!)
        }
  • (I'm editing this comment after you added some content to your post.) I see now, you're using the mouseEnter/Exit flags with the tracking area. I'll try that now.

  • I complemented my answer. Hope that's clearer.

  • Okay, I got it working now. Strangely, your example (translated to Obj-C) did not work for me until I removed the NSTrackingCursorUpdate flag from the tracking area. If I have that flag, then I have to set the cursor in the cursorUpdate method. My calls to set or push an NSCursor in the mouseEntered/Exited are ignored. If I remove that flag, then the calls in mouseEntered/Exited work as you have them here. Thanks!

Add a Comment