diff --git a/Sources/ConfigureSheetController.swift b/Sources/ConfigureSheetController.swift index 387d5fd..a505735 100644 --- a/Sources/ConfigureSheetController.swift +++ b/Sources/ConfigureSheetController.swift @@ -18,7 +18,7 @@ final class ConfigureSheetController: NSObject { let window: NSWindow - private var settings = MacstifySettings.load() + private var settings = MacstifySettings.standard private let onDismiss: (_ saved: Bool) -> Void private var rows: [Row] = [] @@ -32,7 +32,18 @@ final class ConfigureSheetController: NSObject { ) super.init() window.title = "Macstify" + // ARC owns this window through `window`; leaving the default on would + // let a host that closes the sheet release it a second time. + window.isReleasedWhenClosed = false buildInterface() + reload() + } + + /// Re-reads the saved settings into the controls. The same sheet is handed + /// to the host every time it asks, so this is what makes the second opening + /// show what is stored rather than where the first one was left. + func reload() { + settings = .load() refresh() } diff --git a/Sources/MacstifyView.swift b/Sources/MacstifyView.swift index e0db4ac..b4027b8 100644 --- a/Sources/MacstifyView.swift +++ b/Sources/MacstifyView.swift @@ -8,8 +8,9 @@ import ScreenSaver @objc(MacstifyView) final class MacstifyView: ScreenSaverView { private let engine: MacstifyEngine - /// Held strongly: the host releases its reference once the sheet is up, - /// and a deallocated controller takes the sheet's targets with it. + /// Built once and kept: the host releases its reference once the sheet is + /// up, and a deallocated controller takes the sheet's window and targets + /// with it. private var sheetController: ConfigureSheetController? override init?(frame: NSRect, isPreview: Bool) { @@ -54,18 +55,25 @@ final class MacstifyView: ScreenSaverView { true } + /// Hosts read this more than once, and can replace the view between reading + /// it and presenting it. Building a controller per read would hand back a + /// window whose only owner was dropped by the very next read — and the sheet + /// then simply never appears. One controller, kept, re-reading the settings + /// each time it is handed over. override var configureSheet: NSWindow? { - let controller = ConfigureSheetController { [weak self] saved in - guard let self else { return } - if saved { - engine.apply(Self.settings(isPreview: isPreview)) - } - sheetController = nil - } + let controller = sheetController ?? makeSheetController() sheetController = controller + controller.reload() return controller.window } + private func makeSheetController() -> ConfigureSheetController { + ConfigureSheetController { [weak self] saved in + guard let self, saved else { return } + engine.apply(Self.settings(isPreview: isPreview)) + } + } + private static func settings(isPreview: Bool) -> MacstifySettings { let settings = MacstifySettings.load() return isPreview ? settings.previewAdjusted : settings