NSWindow mouseEntered without subclassing?

Viewed 305

I've got a program that accepts the native window handle of an NSWindow (that's already been created but not yet visible). I do this to change some native window styles and behaviors. I can do everything I need to except I can't get mouseEnter/mouseExit to work because it seems to require subclassing before instantiation. Is there a way around this? I really don't want to continuously poll the mouse position just for detecting mouseEnter and mouseExit of a portion of my window.

Note: I have to do it this way because I want to detect hover while the window isn't focused.

I can attach the tracking area, but without subclassing it I'm not sure how to hook into the events:

NSTrackingArea *area = [[NSTrackingArea alloc] initWithRect:CGRectMake(0, 0, 120, 300) options:NSTrackingMouseEnteredAndExited | NSTrackingInVisibleRect | NSTrackingActiveAlways owner:window userInfo:nil];

[window.contentView addTrackingArea:area];

P.S. I'm open to using C or Swift if it'd help.

2 Answers

You don't need to create a view to do that, your can use any custom object, for instance your controller, as a kind of delegate for the tracking methods :

NSView * theView     = window.contentView;
NSTrackingArea *area = [[NSTrackingArea alloc] initWithRect: theView.bounds
                             options:(NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingActiveAlways)
                               owner:myController //<-- your controller
                            userInfo:nil];
 [theView addTrackingArea:area];

From there, the tracking methods will be sent to 'myController'

Thanks to @Willeke for suggesting subclassing something new instead of worrying about subclassing the window.

#include <Cocoa/Cocoa.h>

@interface TrackerView : NSView
    -(void)mouseEntered:(NSEvent *)theEvent;
    -(void)mouseExited:(NSEvent *)theEvent;
@end

@implementation TrackerView
    -(void)mouseEntered:(NSEvent *)theEvent {
        NSLog(@"Mouse entered");
    }
    -(void)mouseExited:(NSEvent *)theEvent {
        NSLog(@"Mouse exited");
    }
@end

void AddTrackingToWindow(void* windowPointer) {
        NSWindow* window = windowPointer;

        TrackerView *trackerView = [[TrackerView alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];
        [trackerView setWantsLayer:YES];
        trackerView.layer.backgroundColor = [[NSColor yellowColor] CGColor];

        [window.contentView addSubview:trackerView];

        NSTrackingArea *area = [[NSTrackingArea alloc] initWithRect:CGRectMake(0, 0, 50, 50) options:NSTrackingMouseEnteredAndExited | NSTrackingInVisibleRect | NSTrackingActiveAlways owner:trackerView userInfo:nil];
        [trackerView addTrackingArea:area];
}
Related