NSTackingRect on user view in NSMenuItem does not always fire mouseExited event

I subclassed NSView and created NSTrackingArea using the following:

-(void)setUpTrackingArea { if(trackingArea != nil) { [self removeTrackingArea:trackingArea]; } int opts = (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways | NSTrackingEnabledDuringMouseDrag); trackingArea = [ [NSTrackingArea alloc] initWithRect:[self bounds] options:opts owner:self userInfo:nil]; [self addTrackingArea:trackingArea]; NSLog(@"update tracking area %@", trackingArea); NSPoint mouseLocation = [[self window] mouseLocationOutsideOfEventStream]; mouseLocation = [self convertPoint: mouseLocation fromView: nil]; if (NSPointInRect(mouseLocation, [self bounds])) { [self mouseEntered: nil]; } else { [self mouseExited: nil]; } } 

I also redefine:

 - (void)mouseEntered:(NSEvent *)theEvent - (void)mouseExited:(NSEvent *)theEvent 

to set the selection property, which then calls

 [self setNeedsDisplay:YES]; 

which calls drawrect to highlight the menu, as you would expect a menu.

The problem is that the event that leaves the mouse does not always fire, leaving some custom views highlighted after the mouse is gone.

Any ideas what I'm doing wrong?

I created a demo project that presents this problem.

see https://github.com/antokne/APGCustomMenuItemView

Thants.

+6
source share
1 answer

I had the same problem a while ago; the reason was that as soon as you have a tracking zone with the "input / output" and "always" settings, it stops working reliably. My admittedly very rude - the solution was to create two tracking zones on top of each other, for example:

 NSTrackingArea *mouseOverTracker = [[NSTrackingArea alloc] initWithRect:self.view.bounds options:(NSTrackingActiveAlways|NSTrackingMouseMoved) owner:self userInfo:nil]; NSTrackingArea *mouseOverTracker2 = [[NSTrackingArea alloc] initWithRect:self.view.bounds options:(NSTrackingMouseEnteredAndExited|NSTrackingActiveAlways) owner:self userInfo:nil]; [self.view addTrackingArea:mouseOverTracker]; [self.view addTrackingArea:mouseOverTracker2]; 

It worked for me.

Hooray!

+1
source

Source: https://habr.com/ru/post/956521/


All Articles