Skip to content

feat(settings): add app presence modes - #112

Merged
trsdn merged 2 commits into
mainfrom
feat/app-presence-modes
Sep 24, 2026
Merged

trsdn merged 2 commits into
mainfrom
feat/app-presence-modes

Conversation

@trsdn

@trsdn trsdn commented Sep 24, 2026

Copy link
Copy Markdown
Owner

Summary

  • add persisted Menu Bar Only, Dock Only, and Dock and Menu Bar presence modes
  • switch NSApplication.ActivationPolicy through a testable, fail-closed adapter owned by AppViewModel
  • bind MenuBarExtra insertion to the selected mode and initialize independently of menu-bar visibility
  • document the new setting across the README, website, metadata, accessibility evidence, changelog, and agent guidance
  • add focused tests for surfaces, restoration, persistence, successful changes, and failed changes

Background-only mode is intentionally excluded per maintainer decision so OpenWritr always retains a persistent, discoverable UI entry point.

Closes #80

Validation

  • swift build -c release -Xswiftc -warnings-as-errors
  • swiftlint lint --strict
  • swift test — 42 tests passed
  • swift test --filter AppPresenceTests — 5 tests passed after the final documentation/test refinement
  • 16 deterministic UI snapshots rendered; Settings reviewed in light, dark, and larger accessibility text with no clipping
  • bash scripts/build-app.sh — signed app bundle built and signature verified

The built app was not opened for the final visible runtime mode-switch check because opening newly built software requires separate interactive approval, which was unavailable. The activation-policy boundary and persistence behavior are covered by injected unit tests.

Risk

  • Presence changes affect process-level activation policy and menu-bar insertion.
  • Failed policy changes retain the previous reachable mode and are not persisted.
  • The default remains Menu Bar Only for existing and new users without a stored choice.

Agent disclosure

Generated with GitHub Copilot CLI.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 4ea0580f-655c-457e-9b12-dd7e8dc1dfe5
Copilot AI lite review requested due to automatic review settings September 24, 2026 19:22
@trsdn
trsdn enabled auto-merge (squash) September 24, 2026 19:22

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Dock-only update installation and activation during persisted-mode restoration need correction.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 Medium severity · 1 Low severity

Open (2)
What changed in this PR

Adds persisted Menu Bar Only, Dock Only, and Dock and Menu Bar presence modes with runtime activation-policy handling.

Changes:

  • Added presence selection, persistence, fallback behavior, and tests.
  • Updated Settings and menu-bar scene integration.
  • Updated documentation, metadata, accessibility evidence, changelog, and agent guidance.
File Summary
Tests/​OpenWritrTests/​AppPresenceTests.swift Presence behavior tests
Sources/​OpenWritr/​UISnapshotRenderer.swift Deterministic snapshot configuration
Sources/​OpenWritr/​SettingsView.swift Presence picker and guidance
Sources/​OpenWritr/​OpenWritrApp.swift Presence state and activation-policy integration
README.md User-facing documentation
Info.plist Application metadata
docs/​self-assessment.md Project self-assessment
docs/​index.html Website description
docs/​accessibility.md Accessibility evidence
CHANGELOG.md Release notes
AGENTS.md Architecture guidance

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread Sources/OpenWritr/OpenWritrApp.swift Outdated
Comment thread AGENTS.md Outdated

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Surfaces reviewed: Settings (light, dark, large accessibility text), About (light, dark, large accessibility text), and overlay states — listening, transcribing, enhancing, done, error (light and dark) — all rendered snapshots, correlated with the PR diff for Info.plist, OpenWritrApp.swift, SettingsView.swift, and UISnapshotRenderer.swift.

Finding

  • 🟠 HIGH — Sources/OpenWritr/OpenWritrApp.swift, menuBarInsertion binding (new in this PR)
    Impact: The new MenuBarExtra(isInserted: menuBarInsertion) binding only handles two of the possible transitions:
    set: { isInserted in
        guard isInserted != viewModel.appPresence.showsMenuBar else { return }
        if isInserted {
            viewModel.setAppPresence(viewModel.appPresence.showsDock ? .dockAndMenuBar : .menuBarOnly)
        } else if viewModel.appPresence.showsDock {
            viewModel.setAppPresence(.dockOnly)
        }
    }
    
    When the app is in the default "Menu Bar Only" mode (showsDock == false) and the user removes the icon with the standard macOS Command-drag-out-of-menu-bar gesture, AppKit sets isInserted = false, but the else if branch does nothing because showsDock is already false. appPresence stays .menuBarOnly, the activation policy stays .accessory (no Dock icon), and the menu bar icon disappears — leaving the app with zero reachable UI surfaces (no menu, no Settings, no Quit) until force-quit via Activity Monitor. This is a regression introduced by this PR's new presence-switching logic and violates the requirement that windows/menus reliably remain reachable for an LSUIElement app.
    Correction: In the isInserted == false branch, also handle the !showsDock case (e.g., fall back to .dockOnly or otherwise ensure a Dock icon appears) whenever the menu bar icon is removed while there is no Dock presence, so the user always retains at least one way to reach the app.

No other high-confidence, actionable HIG defects were found. The Settings "App" section's new presence Picker and explanatory caption render correctly and legibly across light, dark, and the larger accessibility-text variant (the window grows proportionally with no clipping or overlap), and the About and overlay surfaces are unaffected by this PR's changes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 4ea0580f-655c-457e-9b12-dd7e8dc1dfe5
Copilot AI review requested due to automatic review settings September 24, 2026 19:51

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

Resolve the presence model build issue and provide user-facing handling for failed changes and Dock-only update installation.

Review effort: Lite
Findings: None

Resolved since last review (2)

@trsdn
trsdn merged commit d0b44b5 into main Sep 24, 2026
12 checks passed
@trsdn
trsdn deleted the feat/app-presence-modes branch September 24, 2026 19:58

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test placeholder - will not use

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Let the user choose Dock icon vs. menu bar vs. background-only presence

2 participants