From 857cba9f458e5b5ecf1bf270bee28ac70f9ad5ef Mon Sep 17 00:00:00 2001 From: Nico Verbruggen Date: Wed, 15 Feb 2023 19:30:55 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20On=20macOS=2013=20and=20newer,=20ad?= =?UTF-8?q?d=20"Start=20at=20login"=20(#210)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PHP Monitor.xcodeproj/project.pbxproj | 10 +++ phpmon/Common/Helpers/LoginItemManager.swift | 25 ++++++ phpmon/Domain/Preferences/PrefsVC.swift | 6 +- .../Views/CheckboxPreferenceView.swift | 77 ++++++++++++++++--- .../Views/CheckboxPreferenceView.xib | 4 +- phpmon/Localizable.strings | 4 + 6 files changed, 112 insertions(+), 14 deletions(-) create mode 100644 phpmon/Common/Helpers/LoginItemManager.swift diff --git a/PHP Monitor.xcodeproj/project.pbxproj b/PHP Monitor.xcodeproj/project.pbxproj index 2707f6a..9508892 100644 --- a/PHP Monitor.xcodeproj/project.pbxproj +++ b/PHP Monitor.xcodeproj/project.pbxproj @@ -481,6 +481,10 @@ C47699EF28A2F2A30060FEB8 /* WarningManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C47699EE28A2F2A30060FEB8 /* WarningManager.swift */; }; C47699F128A2F3150060FEB8 /* Warning.swift in Sources */ = {isa = PBXBuildFile; fileRef = C47699F028A2F3150060FEB8 /* Warning.swift */; }; C476FF9822B0DD830098105B /* Alert.swift in Sources */ = {isa = PBXBuildFile; fileRef = C476FF9722B0DD830098105B /* Alert.swift */; }; + C47DF1AF299D5A3B0007055D /* LoginItemManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C47DF1AE299D5A3B0007055D /* LoginItemManager.swift */; }; + C47DF1B0299D5A3B0007055D /* LoginItemManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C47DF1AE299D5A3B0007055D /* LoginItemManager.swift */; }; + C47DF1B1299D5A3B0007055D /* LoginItemManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C47DF1AE299D5A3B0007055D /* LoginItemManager.swift */; }; + C47DF1B2299D5A3B0007055D /* LoginItemManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C47DF1AE299D5A3B0007055D /* LoginItemManager.swift */; }; C4811D2422D70A4700B5F6B3 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4811D2322D70A4700B5F6B3 /* App.swift */; }; C4811D2A22D70F9A00B5F6B3 /* MainMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4811D2922D70F9A00B5F6B3 /* MainMenu.swift */; }; C481F79726164A78004FBCFF /* PrefsVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5420395826135DC100FB00FA /* PrefsVC.swift */; }; @@ -857,6 +861,7 @@ C47699EE28A2F2A30060FEB8 /* WarningManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WarningManager.swift; sourceTree = ""; }; C47699F028A2F3150060FEB8 /* Warning.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Warning.swift; sourceTree = ""; }; C476FF9722B0DD830098105B /* Alert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Alert.swift; sourceTree = ""; }; + C47DF1AE299D5A3B0007055D /* LoginItemManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginItemManager.swift; sourceTree = ""; }; C4811D2322D70A4700B5F6B3 /* App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = ""; }; C4811D2922D70F9A00B5F6B3 /* MainMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainMenu.swift; sourceTree = ""; }; C48D0C9225CC804200CC7490 /* XibLoadable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XibLoadable.swift; sourceTree = ""; }; @@ -1440,6 +1445,7 @@ C4B5635D276AB09000F12CCB /* VersionExtractor.swift */, C4D3660A29113F20006BD146 /* System.swift */, C4D36614291160A1006BD146 /* WIP.swift */, + C47DF1AE299D5A3B0007055D /* LoginItemManager.swift */, ); path = Helpers; sourceTree = ""; @@ -2016,6 +2022,7 @@ files = ( C47699EF28A2F2A30060FEB8 /* WarningManager.swift in Sources */, C4ACA38F25C754C100060C66 /* PhpExtension.swift in Sources */, + C47DF1AF299D5A3B0007055D /* LoginItemManager.swift in Sources */, C4D3661A291173EA006BD146 /* DictionaryExtension.swift in Sources */, C4C8900728F0E3EF00CE5E97 /* ActiveFileSystem.swift in Sources */, C4D8016622B1584700C6DA1B /* Startup.swift in Sources */, @@ -2224,6 +2231,7 @@ C4D36617291160A1006BD146 /* WIP.swift in Sources */, C471E85728F9BB650021E251 /* DomainListTLSCell.swift in Sources */, C471E85828F9BB650021E251 /* DomainListNameCell.swift in Sources */, + C47DF1B1299D5A3B0007055D /* LoginItemManager.swift in Sources */, C471E85928F9BB650021E251 /* DomainListPhpCell.swift in Sources */, C471E85A28F9BB650021E251 /* DomainListTypeCell.swift in Sources */, C471E85B28F9BB650021E251 /* DomainListKindCell.swift in Sources */, @@ -2355,6 +2363,7 @@ C471E89528F9BB8F0021E251 /* MenuBarImageGenerator.swift in Sources */, C471E89628F9BB8F0021E251 /* PMWindowController.swift in Sources */, C471E89728F9BB8F0021E251 /* VersionExtractor.swift in Sources */, + C47DF1B2299D5A3B0007055D /* LoginItemManager.swift in Sources */, C4E2E86728FC2F1B003B070C /* XCPMApplication.swift in Sources */, C471E89828F9BB8F0021E251 /* ValetProxy.swift in Sources */, C471E89A28F9BB8F0021E251 /* DomainScanner.swift in Sources */, @@ -2565,6 +2574,7 @@ C4AF9F7B2754499000D44ED0 /* Valet.swift in Sources */, C4C1019C27C65C6F001FACC2 /* Process.swift in Sources */, C451AFF72969E40F0078E617 /* HelpButton.swift in Sources */, + C47DF1B0299D5A3B0007055D /* LoginItemManager.swift in Sources */, C4F780C025D80B6E000DBC97 /* Startup.swift in Sources */, C45B914A295607F400F4EC78 /* Service.swift in Sources */, C4C0E8E327F88B13002D32A9 /* ValetDomainScanner.swift in Sources */, diff --git a/phpmon/Common/Helpers/LoginItemManager.swift b/phpmon/Common/Helpers/LoginItemManager.swift new file mode 100644 index 0000000..bea1aa1 --- /dev/null +++ b/phpmon/Common/Helpers/LoginItemManager.swift @@ -0,0 +1,25 @@ +// +// LoginItemManager.swift +// PHP Monitor +// +// Created by Nico Verbruggen on 15/02/2023. +// Copyright © 2023 Nico Verbruggen. All rights reserved. +// + +import AppKit +import ServiceManagement + +@available(macOS 13.0, *) +class LoginItemManager { + func loginItemIsEnabled() -> Bool { + return SMAppService.mainApp.status == .enabled + } + + func disableLoginItem() { + try? SMAppService.mainApp.unregister() + } + + func enableLoginItem() { + try? SMAppService.mainApp.register() + } +} diff --git a/phpmon/Domain/Preferences/PrefsVC.swift b/phpmon/Domain/Preferences/PrefsVC.swift index 4bb5ab4..87594c7 100644 --- a/phpmon/Domain/Preferences/PrefsVC.swift +++ b/phpmon/Domain/Preferences/PrefsVC.swift @@ -231,7 +231,7 @@ class GeneralPreferencesVC: GenericPreferenceVC { // MARK: - Lifecycle public static func fromStoryboard() -> GenericPreferenceVC { - let vc = NSStoryboard(name: "Main", bundle: nil) + var vc = NSStoryboard(name: "Main", bundle: nil) .instantiateController(withIdentifier: "preferencesTemplateVC") as! GenericPreferenceVC vc.views = [ @@ -243,6 +243,10 @@ class GeneralPreferencesVC: GenericPreferenceVC { vc.getAutomaticUpdateCheckPV() ] + if #available(macOS 13, *) { + vc.views.append(CheckboxPreferenceView.makeLoginItemView()) + } + return vc } } diff --git a/phpmon/Domain/Preferences/Views/CheckboxPreferenceView.swift b/phpmon/Domain/Preferences/Views/CheckboxPreferenceView.swift index d70c7f2..eee6b21 100644 --- a/phpmon/Domain/Preferences/Views/CheckboxPreferenceView.swift +++ b/phpmon/Domain/Preferences/Views/CheckboxPreferenceView.swift @@ -10,18 +10,12 @@ import Foundation import Cocoa class CheckboxPreferenceView: NSView, XibLoadable { - @IBOutlet weak var labelSection: NSTextField! @IBOutlet weak var labelDescription: NSTextField! @IBOutlet weak var buttonCheckbox: NSButton! var action: (() -> Void)! - - var preference: PreferenceName! { - didSet { - self.buttonCheckbox.state = Preferences.isEnabled(self.preference) ? .on : .off - } - } + var behavior: CheckboxPreferenceViewBehavior! static func make( sectionText: String, @@ -31,17 +25,78 @@ class CheckboxPreferenceView: NSView, XibLoadable { action: @escaping () -> Void ) -> NSView { let view = Self.createFromXib()! + view.behavior = CheckboxPreferenceBehavior( + button: view.buttonCheckbox, + preference: preference + ) view.labelSection.stringValue = sectionText view.labelDescription.stringValue = descriptionText view.buttonCheckbox.title = checkboxText - view.preference = preference view.action = action return view } - @IBAction func toggled(_ sender: Any) { - Preferences.update(self.preference, value: buttonCheckbox.state == .on) - self.action() + @available(macOS 13.0, *) + static func makeLoginItemView() -> NSView { + let view = Self.createFromXib()! + view.behavior = CheckboxLaunchItemBehavior(button: view.buttonCheckbox) + view.labelSection.stringValue = "prefs.startup".localized + view.labelDescription.stringValue = "prefs.auto_start_desc".localized + view.buttonCheckbox.title = "prefs.auto_start_title".localized + view.action = {} + return view } + @IBAction func toggled(_ sender: Any) { + self.behavior.toggled(checked: buttonCheckbox.state == .on) + self.action() + } +} + +protocol CheckboxPreferenceViewBehavior { + func toggled(checked: Bool) +} + +class CheckboxPreferenceBehavior: CheckboxPreferenceViewBehavior { + var button: NSButton + var preference: PreferenceName { + didSet { + button.state = Preferences.isEnabled(self.preference) ? .on : .off + } + } + + init(button: NSButton, preference: PreferenceName) { + self.button = button + self.preference = preference + } + + public func toggled(checked: Bool) { + Preferences.update(self.preference, value: checked) + } +} + +@available(macOS 13.0, *) +class CheckboxLaunchItemBehavior: CheckboxPreferenceViewBehavior { + var manager = LoginItemManager() + var button: NSButton + + init(button: NSButton) { + self.button = button + + if manager.loginItemIsEnabled() { + self.button.state = .on + } else { + self.button.state = .off + } + } + + public func toggled(checked: Bool) { + if checked { + self.manager.enableLoginItem() + } else { + self.manager.disableLoginItem() + } + + self.button.state = self.manager.loginItemIsEnabled() ? .on : .off + } } diff --git a/phpmon/Domain/Preferences/Views/CheckboxPreferenceView.xib b/phpmon/Domain/Preferences/Views/CheckboxPreferenceView.xib index 589e766..42fd99a 100644 --- a/phpmon/Domain/Preferences/Views/CheckboxPreferenceView.xib +++ b/phpmon/Domain/Preferences/Views/CheckboxPreferenceView.xib @@ -1,8 +1,8 @@ - + - + diff --git a/phpmon/Localizable.strings b/phpmon/Localizable.strings index 4aa07bc..991894d 100644 --- a/phpmon/Localizable.strings +++ b/phpmon/Localizable.strings @@ -254,6 +254,10 @@ This has no effect on other terminals, only for the particular terminal session "prefs.notifications" = "Notifications:"; "prefs.warnings" = "Warnings:"; "prefs.menu_contents" = "Features in Menu:"; +"prefs.startup" = "Startup:"; + +"prefs.auto_start_desc" = "Automatically starts PHP Monitor when you log into your Mac."; +"prefs.auto_start_title" = "Start PHP Monitor at login"; "prefs.icon_options.php" = "Display PHP Icon"; "prefs.icon_options.elephant" = "Display Elephant Icon";