diff --git a/phpmon/Common/Core/Actions.swift b/phpmon/Common/Core/Actions.swift index 24234b7..3963ded 100644 --- a/phpmon/Common/Core/Actions.swift +++ b/phpmon/Common/Core/Actions.swift @@ -88,23 +88,23 @@ class Actions { NSWorkspace.shared.activateFileViewerSelecting(files as [URL]) } - public static func openGlobalComposerFolder() { - let file = URL(string: "~/.composer/composer.json".replacingTildeWithHomeDirectory)! - NSWorkspace.shared.activateFileViewerSelecting([file] as [URL]) - } - public static func openPhpConfigFolder(version: String) { let files = [NSURL(fileURLWithPath: "\(Paths.etcPath)/php/\(version)/php.ini")] NSWorkspace.shared.activateFileViewerSelecting(files as [URL]) } + public static func openGlobalComposerFolder() { + let file = URL(string: "file://~/.composer/composer.json".replacingTildeWithHomeDirectory)! + NSWorkspace.shared.activateFileViewerSelecting([file] as [URL]) + } + public static func openValetConfigFolder() { - let file = URL(string: "~/.config/valet".replacingTildeWithHomeDirectory)! + let file = URL(string: "file://~/.config/valet".replacingTildeWithHomeDirectory)! NSWorkspace.shared.activateFileViewerSelecting([file] as [URL]) } public static func openPhpMonitorConfigFile() { - let file = URL(string: "~/.config/phpmon".replacingTildeWithHomeDirectory)! + let file = URL(string: "file://~/.config/phpmon".replacingTildeWithHomeDirectory)! NSWorkspace.shared.activateFileViewerSelecting([file] as [URL]) } diff --git a/phpmon/Common/PHP/PhpExtension.swift b/phpmon/Common/PHP/PhpExtension.swift index 7c9d397..bd7b71e 100644 --- a/phpmon/Common/PHP/PhpExtension.swift +++ b/phpmon/Common/PHP/PhpExtension.swift @@ -90,7 +90,7 @@ class PhpExtension { // When running unit tests, the MainMenu will not be available // TODO: Fix this dependency issue, set up a notification mechanism Task { @MainActor in - MainMenu.shared.rebuild(async: false) + MainMenu.shared.rebuild() } } diff --git a/phpmon/Domain/App/AppDelegate+InterApp.swift b/phpmon/Domain/App/AppDelegate+InterApp.swift index 3c1f089..715502b 100644 --- a/phpmon/Domain/App/AppDelegate+InterApp.swift +++ b/phpmon/Domain/App/AppDelegate+InterApp.swift @@ -20,8 +20,7 @@ extension AppDelegate { Please note that PHP Monitor needs to be running in the background for this to work. */ - func application(_ application: NSApplication, open urls: [URL]) { - + @MainActor func application(_ application: NSApplication, open urls: [URL]) { if !Preferences.isEnabled(.allowProtocolForIntegrations) { Log.info("Acting on commands via phpmon:// has been disabled.") return diff --git a/phpmon/Domain/App/InterAppHandler.swift b/phpmon/Domain/App/InterAppHandler.swift index f5d638b..c8bb0a5 100644 --- a/phpmon/Domain/App/InterAppHandler.swift +++ b/phpmon/Domain/App/InterAppHandler.swift @@ -21,46 +21,42 @@ class InterApp { let action: (String) -> Void } - static func getCommands() -> [InterApp.Action] { return [ + @MainActor static func getCommands() -> [InterApp.Action] { return [ InterApp.Action(command: "list", action: { _ in DomainListVC.show() }), InterApp.Action(command: "services/stop", action: { _ in - Task { // Stopping services as standalone task - await MainMenu.shared.stopValetServices() - } + Task { MainMenu.shared.stopValetServices() } }), InterApp.Action(command: "services/restart/all", action: { _ in - Task { // Restarting services as standalone task - await MainMenu.shared.restartValetServices() - } + Task { MainMenu.shared.restartValetServices() } }), InterApp.Action(command: "services/restart/nginx", action: { _ in - MainMenu.shared.restartNginx() + Task { MainMenu.shared.restartNginx() } }), InterApp.Action(command: "services/restart/php", action: { _ in - MainMenu.shared.restartPhpFpm() + Task { MainMenu.shared.restartPhpFpm() } }), InterApp.Action(command: "services/restart/dnsmasq", action: { _ in - MainMenu.shared.restartDnsMasq() + Task { MainMenu.shared.restartDnsMasq() } }), InterApp.Action(command: "locate/config", action: { _ in - MainMenu.shared.openActiveConfigFolder() + Task { MainMenu.shared.openActiveConfigFolder() } }), InterApp.Action(command: "locate/composer", action: { _ in - MainMenu.shared.openGlobalComposerFolder() + Task { MainMenu.shared.openGlobalComposerFolder() } }), InterApp.Action(command: "locate/valet", action: { _ in - MainMenu.shared.openValetConfigFolder() + Task { MainMenu.shared.openValetConfigFolder() } }), InterApp.Action(command: "phpinfo", action: { _ in - MainMenu.shared.openPhpInfo() + Task { MainMenu.shared.openPhpInfo() } }), InterApp.Action(command: "switch/php/", action: { version in if PhpEnv.shared.availablePhpVersions.contains(version) { - MainMenu.shared.switchToPhpVersion(version) + Task { MainMenu.shared.switchToPhpVersion(version) } } else { - Task { @MainActor in + Task { BetterAlert().withInformation( title: "alert.php_switch_unavailable.title".localized, subtitle: "alert.php_switch_unavailable.subtitle".localized(version) diff --git a/phpmon/Domain/Menu/MainMenu.swift b/phpmon/Domain/Menu/MainMenu.swift index 4d95035..8ec944e 100644 --- a/phpmon/Domain/Menu/MainMenu.swift +++ b/phpmon/Domain/Menu/MainMenu.swift @@ -7,6 +7,7 @@ import Cocoa +@MainActor class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate, PhpSwitcherDelegate { static let shared = MainMenu() @@ -31,38 +32,22 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate, PhpSwitcherDelegate Rebuilds the menu (either asynchronously or synchronously). Defaults to rebuilding the menu asynchronously. */ - func rebuild(async: Bool = true) { - if !async { - self.rebuildMenu() - return - } - - // Update the menu item on the main thread + func rebuild() { Task { @MainActor [self] in - self.rebuildMenu() + let menu = StatusMenu() + menu.addMenuItems() + menu.items.forEach({ (item) in + item.target = self + }) + statusItem.menu = menu + statusItem.menu?.delegate = self } } - /** - Update the menu's contents, based on what's going on. - This will rebuild the entire menu, so this can take a few moments. - - Use `rebuild(async:)` to ensure the rebuilding happens in the background. - */ - private func rebuildMenu() { - let menu = StatusMenu() - menu.addMenuItems() - menu.items.forEach({ (item) in - item.target = self - }) - statusItem.menu = menu - statusItem.menu?.delegate = self - } - /** Sets the status bar image based on a version string. */ - @MainActor func setStatusBarImage(version: String) { + func setStatusBarImage(version: String) { setStatusBar( image: (Preferences.preferences[.iconTypeToDisplay] as! String != MenuBarIcon.noIcon.rawValue) ? MenuBarImageGenerator.textToImageWithIcon(text: version) @@ -74,7 +59,7 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate, PhpSwitcherDelegate Sets the status bar image, based on the provided NSImage. The image will be used as a template image. */ - @MainActor func setStatusBar(image: NSImage) { + func setStatusBar(image: NSImage) { if let button = statusItem.button { image.isTemplate = true button.image = image @@ -89,7 +74,7 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate, PhpSwitcherDelegate PhpEnv.shared.currentInstall = ActivePhpInstallation() updatePhpVersionInStatusBar() } else { - Log.perf("Skipping version refresh due to busy status") + Log.perf("Skipping version refresh due to busy status!") } } @@ -103,13 +88,15 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate, PhpSwitcherDelegate Reloads the menu in the foreground. This mimics the exact behaviours of `asyncExecution` as set in the method below. */ - @MainActor @objc func reloadPhpMonitorMenuInForeground() async { - refreshActiveInstallation() - refreshIcon() - Task { @MainActor in - self.rebuild(async: false) + @objc func reloadPhpMonitorMenuInForeground() { + Log.perf("The menu will be reloaded...") + Task { [self] in + self.refreshActiveInstallation() + self.refreshIcon() + self.rebuild() + await ServicesManager.loadHomebrewServices() + Log.perf("The menu has been reloaded!") } - await ServicesManager.loadHomebrewServices() } /** diff --git a/phpmon/Domain/Warnings/WarningManager.swift b/phpmon/Domain/Warnings/WarningManager.swift index b0b8b1a..516e0e7 100644 --- a/phpmon/Domain/Warnings/WarningManager.swift +++ b/phpmon/Domain/Warnings/WarningManager.swift @@ -70,7 +70,7 @@ class WarningManager { await loopOverEvaluations() } - MainMenu.shared.rebuild() + await MainMenu.shared.rebuild() } private func loopOverEvaluations() async { diff --git a/phpmon/Domain/Watcher/App+ConfigWatch.swift b/phpmon/Domain/Watcher/App+ConfigWatch.swift index 5640df9..8423d68 100644 --- a/phpmon/Domain/Watcher/App+ConfigWatch.swift +++ b/phpmon/Domain/Watcher/App+ConfigWatch.swift @@ -21,7 +21,7 @@ extension App { let distance = self.watcher.lastUpdate?.distance(to: Date().timeIntervalSince1970) if distance == nil || distance != nil && distance! > 0.75 { Log.perf("Refreshing menu...") - MainMenu.shared.reloadPhpMonitorMenuInBackground() + Task { @MainActor in MainMenu.shared.reloadPhpMonitorMenuInBackground() } self.watcher.lastUpdate = Date().timeIntervalSince1970 } }