- switch to regular while the workspace window is open (Dock icon, app switcher, default menu bar) and back to accessory when it closes; driven by NSWindow didBecomeKey/willClose with an anchor-view identity filter (scenePhase follows the app rather than windows on macOS, so it fires no event on close) - add silent launch preference (settings-general, off by default, persisted in its own silent-launch.json since settings.json is rewritten whole from the controller's in-memory snapshot): suppressed launches keep the menu-bar baseline and proxy runtime restoration is unaffected - docs: CONTEXT.md adaptive app form / silent launch terms and invariants; ADR 0017 superseding 0016 (scene-based model and reopening carry over)
2.9 KiB
Menu-bar-only app form; workspace window as a scene
The GUI is a menu-bar-only app at all times: LSUIElement stays in effect and the app never switches its activation policy at runtime. The main workspace window is a SwiftUI Window scene presented automatically at every launch (defaultLaunchBehavior(.presented)); the status menu's "open main window" item reopens it after it is closed. Closing the window never terminates the GUI process — the status menu (and the launchd-hosted proxy agent with it) stays available.
Status
Accepted (2026-09-28). Superseded by ADR-0017 (2026-09-29), which replaces the constant menu-bar-only form with the adaptive app form (window-following activation policy plus an opt-out silent launch); the scene model, launch presentation, and status-menu reopening below carry over unchanged. Supersedes the earlier hybrid form (2026-09-24): LSUIElement plus runtime accessory⇄regular activation-policy switching, launch-time auto-presentation implemented through an AppKit-owned NSWindow, and the window-opening intents built around it.
Considered options
- Keep the hybrid form (activation-policy switching plus AppKit window ownership): rejected because the AppKit window adapter existed only to serve the policy dance and the launch intents; the plain scene model provides both launch presentation and reopening without it.
- Menu-bar-only with no launch presentation (window opens only from the status menu): considered as an intermediate step on 2026-09-28 and reversed the same day — scene-based launch presentation was verified to work under
LSUIElement(defaultLaunchBehavior(.presented)), so the launch-presentation behavior returns without bringing the AppKit adapter back. - Keep an AppKit-direct window adapter solely to reuse a retained window across close/open: rejected; the scene window survives close by being re-shown with its content state intact, so the adapter's remaining value was the activation-policy switching this decision removes.
Consequences
- The app never gains a Dock icon or app-switcher presence, including while the workspace window is open; launch presents the window without a Dock icon appearing.
- Reopening from the status menu activates the app before
openWindow, so the window lands above the frontmost app. - Keyboard shortcuts that rely on owning the menu bar (for example ⌘W or Edit-menu shortcuts) are unavailable while the workspace window is frontmost; the close button and mouse interaction are unaffected. If this proves unacceptable, the fix is a product decision to re-introduce a foreground form, not a partial AppKit adapter.
- The launch intent, reopen intent, presentation intents, and the
WorkspaceWindowOpeningseam are removed;WorkspaceRouteis navigation state only, and the scene id is defined once there. - Window title follows the workspace destination via
navigationTitleinstead of an AppKit title binding.