When in -mouseEntered: don't use NSPointInRect for checking which tracking area is hit
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]; }