Skip to content

feat(lifecycle): theme quit and close-behavior confirms - #1714

Merged
vastsa merged 2 commits into
mainfrom
feat/1702-themed-quit-dialog
Oct 16, 2026
Merged

vastsa merged 2 commits into
mainfrom
feat/1702-themed-quit-dialog

Conversation

@vastsa

@vastsa vastsa commented Oct 16, 2026

Copy link
Copy Markdown
Owner

Closes #1702.

What changed

Quit confirmation and the first-close behavior choice now render as themed
in-app dialogs instead of Electron's native showMessageBox, so they follow the
light/dark theme and theme plugins like every other dialog in the app.

  • New main-process broker (bootstrap/lifecycle-dialog.ts) owns each decision
    and routes it to the main renderer after a readiness handshake.
  • New renderer dialog (LifecycleConfirmationDialog.tsx) uses OverlayBackdrop
    • role="dialog" + aria-modal + --ds-* tokens, keeps title and body
      distinct, focuses Cancel first, and cancels on Escape or a backdrop click.
  • Additive IPC only: window/lifecycleDialog/ready, window/lifecycleDialog/respond,
    window/event/lifecycleDialogRequest, window/event/lifecycleDialogDismiss.
  • Fallback path: an unanswered request uses the native dialog after 10s, and a
    failed native fallback still allows shutdown. A tray-hidden main window is
    restored before the quit confirmation, and a repeated before-quit can no
    longer bypass a pending confirmation.

Existing semantics are unchanged: the single quitConfirmed confirmation,
prompting again after Cancel, probe/update-restart exemptions, and the ordered
shutdown.

Specs / docs

ADR 0090, 04-ux/08-component-spec.md, 04-ux/09-interaction-patterns.md,
03-runtime/01-ipc-protocol.md, decisions D230/D363, and E2E-143/E2E-204
(including the zh-CN mirrors).

Validation

  • pnpm build:js
  • pnpm --filter @pi-desktop/desktop typecheck
  • pnpm lint and pnpm docs:check
  • New: lifecycle-dialog-broker.test.mjs, lifecycle-confirmation-dialog-user-path.test.mjs,
    lifecycle-close-behavior-runtime.test.mjs; extended close-behavior-tray.test.mjs,
    shutdown-regenerate-persistence.test.mjs, protocol.test.ts

Known environment-only failure: plugin-ui-slots-lab.test.mjs also fails on
main in a linked-dependency worktree because the example plugin resolves two
React copies; it passes in the primary checkout's own environment.

Copilot AI balanced review requested due to automatic review settings October 16, 2026 09:56

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 was unable to review this pull request because the user who requested the review has reached their quota limit.

Keep quit decisions in Electron main while rendering confirmations in
 the theme-aware main window. A readiness handshake and bounded native
 fallback preserve shutdown behavior when the renderer is unavailable.
Keep the idempotence contract test in sync with the confirmation
latch that now guards a pending renderer decision.
@vastsa
vastsa force-pushed the feat/1702-themed-quit-dialog branch from 98ee5f8 to b1b984b Compare October 16, 2026 10:13
@vastsa
vastsa merged commit 24493f9 into main Oct 16, 2026
9 of 10 checks passed
@vastsa
vastsa deleted the feat/1702-themed-quit-dialog branch October 16, 2026 10:27
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.

[Feature] 退出确认与首次关闭行为弹窗改用应用内主题化对话框 / theme the quit and close-behavior confirms in-app

2 participants