Thanks to suggestions by Willeke (thanks so much for your help!), there is a solution. It involved subclassing NSView (I called it MyView), moving all of the tracking area handling into that view, and removing it from the ViewController. MyView.m is:
//
// MyView.m
// Repro
//
#import "MyView.h"
@implementation MyView
{
NSTrackingArea *trackingArea;
}
- (void)viewWillMoveToWindow:(NSWindow *)newWindow
{
if (newWindow)
{
newWindow.styleMask |= NSWindowStyleMaskFullSizeContentView;
[self setupTrackingArea:newWindow];
}
[super viewWillMoveToWindow:newWindow];
return;
}
- (void)updateTrackingAreas
{
[self setupTrackingArea:self.window];
[super updateTrackingAreas];
return;
}
- (void)setupTrackingArea:(NSWindow *)window
{
if (trackingArea)
[self removeTrackingArea:trackingArea];
NSTrackingAreaOptions options = NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways;
trackingArea = [[NSTrackingArea alloc]initWithRect:self.bounds
options:options
owner:self
userInfo:nil];
[self addTrackingArea:trackingArea];
return;
}
- (void)mouseEntered:(NSEvent *)event
{
[self showTitleBar];
[self showWindowButtons:self.window];
return;
}
- (void)mouseExited:(NSEvent *)event
{
[self hideTitleBar];
[self hideWindowButtons:self.window];
return;
}
- (void)showTitleBar
{
self.window.titlebarAppearsTransparent = false;
self.window.title = [NSProcessInfo processInfo].processName;
return;
}
- (void)hideTitleBar
{
self.window.titlebarAppearsTransparent = true;
self.window.title = @"";
return;
}
- (void)hideWindowButtons:(NSWindow *)window
{
// hide the minimize and zoom buttons (yellow and green)
[window standardWindowButton:NSWindowZoomButton].hidden = true;
[window standardWindowButton:NSWindowMiniaturizeButton].hidden = true;
[window standardWindowButton:NSWindowCloseButton].hidden = true;
return;
}
- (void)showWindowButtons:(NSWindow *)window
{
[window standardWindowButton:NSWindowZoomButton].hidden = false;
[window standardWindowButton:NSWindowMiniaturizeButton].hidden = false;
[window standardWindowButton:NSWindowCloseButton].hidden = false;
return;
}
@end