Do not assume that the mouse location of any mouse tracking NSEvent is necessarily inside or outside of the tracking rectangle as specified by the NSTrackingArea. Use the -trackingArea method of NSEvent instead of NSPointInRect to check, which trackingArea has triggered the event.
Bad code
- (void) syncInsideWithEvent:(NSEvent *) event { NSPoint point; unsigned int i; point = [self convertPoint:[event locationInWindow] fromView:nil]; for( i = 0; i < N_AREAS; i++) inside_[ i] = NSPointInRect( point, area_[ i]); [self setNeedsDisplay:YES]; } - (void) mouseEntered:(NSEvent *) event { [self syncInsideWithEvent:event]; } - (void) mouseExited:(NSEvent *) event { [self syncInsideWithEvent:event]; }
Better code
- (void) syncInsideWithEvent:(NSEvent *) event invert:(BOOL) invert { NSTrackingArea *hit; NSTrackingArea *area; NSArray *areas; unsigned int i; hit = [event trackingArea]; areas = [self trackingAreas]; for( i = 0; i < N_AREAS; i++) { area = [areas objectAtIndex:i]; inside_[ i] = invert ? NO : (area == hit); } [self setNeedsDisplay:YES]; } - (void) mouseEntered:(NSEvent *) event { [self syncInsideWithEvent:event invert:NO]; } - (void) mouseExited:(NSEvent *) event { [self syncInsideWithEvent:event invert:YES]; }