diff --git a/NotchBuddy/Sources/App/AppGridView.swift b/NotchBuddy/Sources/App/AppGridView.swift index 0fb700f..7eea6ff 100644 --- a/NotchBuddy/Sources/App/AppGridView.swift +++ b/NotchBuddy/Sources/App/AppGridView.swift @@ -9,17 +9,19 @@ import AppKit struct DesktopAppSlot: Identifiable { let id: String let name: String - let bundleId: String + /// Tried in order: the first installed one wins. + let bundleIds: [String] let color: String let downloadURL: String } enum DesktopApps { static let claude = DesktopAppSlot(id: "app_claude", name: "Claude", - bundleId: "com.anthropic.claudefordesktop", + bundleIds: ["com.anthropic.claudefordesktop"], color: "#D97757", downloadURL: "https://claude.ai/download") static let chatGPT = DesktopAppSlot(id: "app_chatgpt", name: "ChatGPT", - bundleId: "com.openai.chat", + // New ChatGPT app first (its id is com.openai.codex), Classic as fallback. + bundleIds: ["com.openai.codex", "com.openai.chat"], color: "#10A37F", downloadURL: "https://chatgpt.com/download") } @@ -128,14 +130,19 @@ struct AppPill: View { } } + /// The first installed bundle id of the slot. + private var bundleId: String? { + app.bundleIds.first { NSWorkspace.shared.urlForApplication(withBundleIdentifier: $0) != nil } + } + private func refresh() { - appURL = NSWorkspace.shared.urlForApplication(withBundleIdentifier: app.bundleId) - isRunning = NSWorkspace.shared.runningApplications.contains { $0.bundleIdentifier == app.bundleId } + appURL = bundleId.flatMap { NSWorkspace.shared.urlForApplication(withBundleIdentifier: $0) } + isRunning = NSWorkspace.shared.runningApplications.contains { $0.bundleIdentifier == bundleId } } private func open() { SoundEngine.shared.play("blip") - if let running = NSWorkspace.shared.runningApplications.first(where: { $0.bundleIdentifier == app.bundleId }) { + if let running = NSWorkspace.shared.runningApplications.first(where: { $0.bundleIdentifier == bundleId }) { running.activate(options: .activateIgnoringOtherApps) } else if let appURL { NSWorkspace.shared.openApplication(at: appURL, configuration: .init(), completionHandler: nil)