Skip to content

Commit 59d8462

Browse files
fix(macos): open dashboard when Dock or Finder relaunches app (#97637)
* fix(macos): open dashboard on Dock reopen * fix(macos): preserve visible-window Dock reopen * style(macos): satisfy deep link switch formatting
1 parent 2001b15 commit 59d8462

3 files changed

Lines changed: 53 additions & 9 deletions

File tree

apps/macos/Sources/OpenClaw/DeepLinks.swift

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,18 +59,21 @@ final class DeepLinkHandler {
5959
deepLinkLogger.debug("ignored url \(url.absoluteString, privacy: .public)")
6060
return
6161
}
62-
guard !AppStateStore.shared.isPaused else {
63-
self.presentAlert(title: "OpenClaw is paused", message: "Unpause OpenClaw to run agent actions.")
64-
return
65-
}
66-
6762
switch route {
63+
case .dashboard:
64+
await self.openDashboard()
65+
return
6866
case let .agent(link):
67+
guard !AppStateStore.shared.isPaused else {
68+
self.presentAlert(title: "OpenClaw is paused", message: "Unpause OpenClaw to run agent actions.")
69+
return
70+
}
6971
await self.handleAgent(link: link, originalURL: url)
7072
case .gateway:
71-
break
72-
case .dashboard:
73-
await self.openDashboard()
73+
guard !AppStateStore.shared.isPaused else {
74+
self.presentAlert(title: "OpenClaw is paused", message: "Unpause OpenClaw to run agent actions.")
75+
return
76+
}
7477
}
7578
}
7679

apps/macos/Sources/OpenClaw/MenuBar.swift

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,8 +274,10 @@ private struct SettingsWindowOpenRegistrar: View {
274274

275275
@MainActor
276276
final class AppDelegate: NSObject, NSApplicationDelegate {
277+
private static let dashboardURL = URL(string: "openclaw://dashboard")!
277278
private var state: AppState?
278279
private let webChatAutoLogger = Logger(subsystem: "ai.openclaw", category: "Chat")
280+
var openDashboardAction: @MainActor () -> Void = { AppNavigationActions.openDashboard() }
279281
let updaterController: UpdaterProviding = makeUpdaterController()
280282

281283
func applicationDockMenu(_: NSApplication) -> NSMenu? {
@@ -313,7 +315,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
313315

314316
@objc
315317
private func openDashboardFromDockMenu(_: Any?) {
316-
AppNavigationActions.openDashboard()
318+
self.openDashboardAction()
317319
}
318320

319321
@objc
@@ -339,9 +341,18 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
339341
}
340342
}
341343

344+
func applicationShouldHandleReopen(_: NSApplication, hasVisibleWindows flag: Bool) -> Bool {
345+
if flag {
346+
return true
347+
}
348+
self.openDashboardAction()
349+
return false
350+
}
351+
342352
@MainActor
343353
func applicationDidFinishLaunching(_ notification: Notification) {
344354
if self.isDuplicateInstance() {
355+
NSWorkspace.shared.open(Self.dashboardURL)
345356
NSApp.terminate(nil)
346357
return
347358
}

apps/macos/Tests/OpenClawIPCTests/MenuContentSmokeTests.swift

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,34 @@ struct MenuContentSmokeTests {
5050
#expect(titles.contains("Open Canvas") || titles.contains("Close Canvas"))
5151
#expect(titles.contains("Settings…"))
5252
}
53+
54+
@Test func `dock reopen opens dashboard and suppresses default handling`() {
55+
let delegate = AppDelegate()
56+
var didOpenDashboard = false
57+
delegate.openDashboardAction = {
58+
didOpenDashboard = true
59+
}
60+
61+
let shouldUseDefaultHandling = delegate.applicationShouldHandleReopen(
62+
NSApplication.shared,
63+
hasVisibleWindows: false)
64+
65+
#expect(shouldUseDefaultHandling == false)
66+
#expect(didOpenDashboard)
67+
}
68+
69+
@Test func `dock reopen keeps default handling when windows are visible`() {
70+
let delegate = AppDelegate()
71+
var didOpenDashboard = false
72+
delegate.openDashboardAction = {
73+
didOpenDashboard = true
74+
}
75+
76+
let shouldUseDefaultHandling = delegate.applicationShouldHandleReopen(
77+
NSApplication.shared,
78+
hasVisibleWindows: true)
79+
80+
#expect(shouldUseDefaultHandling)
81+
#expect(!didOpenDashboard)
82+
}
5383
}

0 commit comments

Comments
 (0)