I have an application only for the status bar in which I am trying to show a panel on mouseOver. I have a custom status element (and its associated view) that is connected and working, but the tracking rectangle only receives events for every dozens or so launches. It makes me think that a race condition is happening somewhere, but I canβt find it. In my view, the status bar position:
- (id)initWithStatusItem:(NSStatusItem *)statusItem { CGFloat itemWidth = [statusItem length]; CGFloat itemHeight = [[NSStatusBar systemStatusBar] thickness]; NSRect itemRect = NSMakeRect(0.0, 0.0, itemWidth, itemHeight); NSLog(@"itemRect: %@", NSStringFromRect(itemRect)); if ((self = [super initWithFrame:itemRect])) { _statusItem = statusItem; _statusItem.view = self; NSTrackingAreaOptions options = NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingActiveAlways; NSTrackingArea *trackingArea = [[NSTrackingArea alloc] initWithRect:itemRect options:options owner:self userInfo:nil]; [self addTrackingArea:trackingArea]; [self.window setIgnoresMouseEvents:NO]; [self.window setAcceptsMouseMovedEvents:YES]; self.wantsLayer = YES; } return self; } - (void)mouseEntered:(NSEvent *)theEvent { [[NSNotificationCenter defaultCenter] postNotificationName:UAStatusItemMouseEnteredNotification object:nil]; } - (void)mouseExited:(NSEvent *)theEvent { [[NSNotificationCenter defaultCenter] postNotificationName:UAStatusItemMouseExitedNotification object:nil]; }
In most launches, the application does not respond to mouse tracking events, but each so often the mouseEntered: and mouseExited: called properly, they completely confuse me. What is going on here and what am I doing wrong?
EDIT 07/17/2012
I changed the code based on @Streams answer, but saw the same problem:
- (id)initWithStatusItem:(NSStatusItem *)statusItem { CGFloat itemWidth = [statusItem length]; CGFloat itemHeight = [[NSStatusBar systemStatusBar] thickness]; NSRect itemRect = NSMakeRect(0.0, 0.0, itemWidth, itemHeight); NSLog(@"itemRect: %@", NSStringFromRect(itemRect)); if ((self = [super initWithFrame:itemRect])) { _statusItem = statusItem; _statusItem.view = self; [self updateTrackingAreas]; [self.window setIgnoresMouseEvents:NO]; [self.window setAcceptsMouseMovedEvents:YES]; self.wantsLayer = YES; } return self; } - (void)updateTrackingAreas { if (self.trackingArea) [self removeTrackingArea:self.trackingArea]; [super updateTrackingAreas]; self.trackingArea = [[NSTrackingArea alloc] initWithRect:CGRectZero options:NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingInVisibleRect | NSTrackingActiveAlways owner:self userInfo:nil]; [self addTrackingArea:self.trackingArea]; }
EDIT 07/18/2012
Here is a simple example sample project that uses the well-known github project (written by @Stream) to show the problem. It cannot reliably receive mouseover events, if at all.
source share