Fix notification click launching second app instance#30
Conversation
- Add single-instance guard in ShellraiserApp.init() that activates the existing instance and exits if another copy with the same bundle ID is already running — guards against Launch Services conflicts from builds across checkouts - Switch WindowGroup to Window (semantically correct for single-window) - Add applicationShouldHandleReopen to restore window on dock-click - Remove -n flag from Makefile run-isolated to prevent duplicate launches - Add tests for applicationShouldHandleReopen covering both hasVisibleWindows states
📝 WalkthroughWalkthroughThe changes implement single-instance application behavior for Shellraiser. The app now detects existing instances with the same bundle ID, activates them, and exits. Dock icon clicks bring the main window to front. The main window is explicitly named and identified, and build configuration is updated to reuse existing app instances during development. Changes
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
📝 Coding Plan
Comment Tip You can customize the tone of the review comments and chat replies.Configure the |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
Sources/Shellraiser/App/ShellraiserApp.swift (1)
126-136: Single-instance guard implementation is functional but consider activation edge cases.The logic correctly detects and activates an existing instance. A few observations:
existing.activate()returns aBoolindicating success — currently ignored. If activation fails (e.g., the other instance is hung), the new process still exits, potentially leaving users without a responsive window.Using
exit(0)ininit()is unconventional but acceptable here since it's before any resources are allocated.Consider optionally handling the activation failure case:
🔧 Optional: Handle activation failure
if let existing = others.first { - existing.activate() - exit(0) + if existing.activate() { + exit(0) + } + // If activation failed, proceed to launch this instance }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Sources/Shellraiser/App/ShellraiserApp.swift` around lines 126 - 136, The single-instance guard currently activates an existing app via existing.activate() and unconditionally calls exit(0); change this so you check the Bool result of existing.activate() and only call exit(0) when activation succeeded; if activate() returns false (activation failed or the other instance is hung) allow the initializer to continue launching (or implement a retry/alert path) so the new process doesn't exit blindly. Locate the logic in init() where NSRunningApplication.runningApplications(withBundleIdentifier:) is filtered, inspect the existing.activate() call and replace the unconditional exit(0) with a conditional exit based on the activation result (or alternative fallback behavior).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@Sources/Shellraiser/App/ShellraiserApp.swift`:
- Around line 126-136: The single-instance guard currently activates an existing
app via existing.activate() and unconditionally calls exit(0); change this so
you check the Bool result of existing.activate() and only call exit(0) when
activation succeeded; if activate() returns false (activation failed or the
other instance is hung) allow the initializer to continue launching (or
implement a retry/alert path) so the new process doesn't exit blindly. Locate
the logic in init() where
NSRunningApplication.runningApplications(withBundleIdentifier:) is filtered,
inspect the existing.activate() call and replace the unconditional exit(0) with
a conditional exit based on the activation result (or alternative fallback
behavior).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: bd4de059-cd22-4016-b918-1cfd1513bf25
📒 Files selected for processing (3)
MakefileSources/Shellraiser/App/ShellraiserApp.swiftTests/ShellraiserTests/ShellraiserAppTests.swift
Summary by CodeRabbit
New Features
Bug Fixes