diff --git a/Sources/QuitConfirmationAlertPresenter.swift b/Sources/QuitConfirmationAlertPresenter.swift index 6411a3938394..9a480d064dcf 100644 --- a/Sources/QuitConfirmationAlertPresenter.swift +++ b/Sources/QuitConfirmationAlertPresenter.swift @@ -58,6 +58,8 @@ final class QuitConfirmationAlertPresenter: NSObject, NSWindowDelegate { } private func presentStandalone() { + alert.layout() + let buttons = alert.buttons if buttons.indices.contains(0) { buttons[0].target = self diff --git a/cmuxTests/QuitConfirmationAlertPresenterTests.swift b/cmuxTests/QuitConfirmationAlertPresenterTests.swift index 11020133e84d..07d4c4c07754 100644 --- a/cmuxTests/QuitConfirmationAlertPresenterTests.swift +++ b/cmuxTests/QuitConfirmationAlertPresenterTests.swift @@ -98,6 +98,13 @@ struct QuitConfirmationAlertPresenterTests { #expect(!alert.didRunModal) #expect(completedResponse == nil) + // NSAlert starts with a lazy placeholder layout that stacks full-width + // buttons. The standalone presenter must resolve that layout before the + // alert becomes visible or the panel renders clipped and washed out. + let buttonFrames = alert.buttons.map(\.frame) + #expect(buttonFrames.count == 2) + #expect(abs(buttonFrames[0].midY - buttonFrames[1].midY) < 0.5) + alert.buttons[0].performClick(nil) #expect(completedResponse == .alertFirstButtonReturn)