diff --git a/Base.lproj/SplashWindow.xib b/Base.lproj/SplashWindow.xib index dc2a318..39a70a6 100644 --- a/Base.lproj/SplashWindow.xib +++ b/Base.lproj/SplashWindow.xib @@ -14,7 +14,7 @@ - + diff --git a/SplashWindowController.m b/SplashWindowController.m index 61684c7..7e260d4 100644 --- a/SplashWindowController.m +++ b/SplashWindowController.m @@ -49,6 +49,20 @@ - ( void ) windowDidLoad { [ super windowDidLoad ]; + /* The main window's NIB sets "released when closed" to NO, but the splash + * window's NIB does not, so the splash window defaults to releasing itself + * on close. On modern macOS that is fatal: when the splash window is the + * key window and is closed, it is deallocated, yet AppKit's automatic + * focus-ring machinery still references it when first-responder status + * moves back to the main window. The result is a use-after-free crash in + * +[_NSAutomaticFocusRing _clearOldFocusRing] -> -[NSWindow + * _setNeedsDisplayInRegion:]. This controller owns the window for the + * lifetime of the application, so keep it alive on close, matching the + * behaviour already configured for the main window. + */ + + [ [ self window ] setReleasedWhenClosed: NO ]; + [ [ self window ] center ]; [ [ self window ] makeKeyAndOrderFront: nil ]; } @@ -65,7 +79,13 @@ - ( void ) windowDidLoad - ( IBAction ) closeWindow: ( NSButton * ) sender { ( void ) sender; - [ self close ]; + + /* Resign first responder before the window goes away so that AppKit tears + * down any focus ring while the window is still a valid object. + */ + + [ [ self window ] makeFirstResponder: nil ]; + [ self close ]; } @end