diff --git a/BrewBar/SettingsWindowController.swift b/BrewBar/SettingsWindowController.swift index 48579c4..ef962c7 100644 --- a/BrewBar/SettingsWindowController.swift +++ b/BrewBar/SettingsWindowController.swift @@ -1,4 +1,5 @@ import Cocoa +import ServiceManagement class SettingsWindowController: NSWindowController { weak var appDelegate: AppDelegate? @@ -13,6 +14,7 @@ class SettingsWindowController: NSWindowController { var intervalPopup: NSPopUpButton! var customMinutesField: NSTextField! + var launchAtLoginCheckbox: NSButton! convenience init(appDelegate: AppDelegate) { let window = NSWindow( @@ -66,9 +68,17 @@ class SettingsWindowController: NSWindowController { ]) customRow.orientation = .horizontal + launchAtLoginCheckbox = NSButton( + checkboxWithTitle: "Launch BrewBar at login", + target: self, + action: #selector(toggleLaunchAtLogin(_:)) + ) + let stack = NSStackView(views: [ frequencyRow, customRow, + separator(), + launchAtLoginCheckbox, ]) stack.orientation = .vertical stack.alignment = .leading @@ -99,6 +109,16 @@ class SettingsWindowController: NSWindowController { intervalPopup.selectItem(at: presets.count) // Custom } customMinutesField.stringValue = "\(Int(interval / 60))" + + // SMAppService is the source of truth — the user may have changed + // this in System Settings > Login Items while we weren't looking + launchAtLoginCheckbox.state = SMAppService.mainApp.status == .enabled ? .on : .off + } + + func separator() -> NSBox { + let box = NSBox() + box.boxType = .separator + return box } // MARK: - Actions @@ -124,4 +144,22 @@ class SettingsWindowController: NSWindowController { appDelegate?.restartTimer() syncUI() } + + @objc func toggleLaunchAtLogin(_ sender: NSButton) { + do { + if sender.state == .on { + try SMAppService.mainApp.register() + } else { + try SMAppService.mainApp.unregister() + } + } catch { + sender.state = sender.state == .on ? .off : .on // revert on failure + + let alert = NSAlert() + alert.alertStyle = .warning + alert.messageText = "Could not change login item" + alert.informativeText = error.localizedDescription + alert.runModal() + } + } }