Skip to content

feat(desktop): add confirm-on-quit setting with behavior settings page#524

Merged
Kitenite merged 5 commits into
superset-sh:mainfrom
andreasasprou:feat/confirm-on-quit
Dec 28, 2025
Merged

feat(desktop): add confirm-on-quit setting with behavior settings page#524
Kitenite merged 5 commits into
superset-sh:mainfrom
andreasasprou:feat/confirm-on-quit

Conversation

@andreasasprou
Copy link
Copy Markdown
Contributor

@andreasasprou andreasasprou commented Dec 28, 2025

Summary

  • Adds a "Confirm before quitting" toggle in a new Behavior settings section
  • Shows native OS confirmation dialog when pressing CMD+Q (or quitting the app)
  • Enabled by default - users can disable in Settings → Behavior

Changes

  • Database: Added confirmOnQuit boolean column to settings table with migration
  • tRPC: Added getConfirmOnQuit/setConfirmOnQuit procedures
  • Settings UI: New "Behavior" section in sidebar with toggle switch
  • Main process: Implemented quit confirmation dialog with state machine

Test plan

  • Open Settings → Behavior
  • Verify "Confirm before quitting" toggle is visible and enabled by default
  • Press CMD+Q → should show confirmation dialog
  • Click "Cancel" → app should not quit
  • Click "Quit" → app should quit
  • Disable the toggle in settings
  • Press CMD+Q → app should quit immediately without dialog

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added a "Behavior" section in Settings with a "Confirm before quitting" toggle (defaults to enabled).
    • App now shows a quit confirmation dialog when enabled and respects the toggle across restarts.
    • Update/install flows and programmatic quits can skip the confirmation to avoid blocking updates.
  • Chores

    • Persisted the new setting so its value is saved and restored.

✏️ Tip: You can customize this high-level summary in your review settings.

- Add confirmOnQuit boolean column to settings table with migration
- Add getConfirmOnQuit/setConfirmOnQuit tRPC procedures
- Create new "Behavior" section in settings sidebar
- Add BehaviorSettings component with toggle switch
- Implement native quit confirmation dialog in main process
- Default to enabled (confirm before quitting)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Dec 28, 2025

📝 Walkthrough

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and accurately summarizes the main changes: adding a confirm-on-quit setting and a new Behavior settings page.
Description check ✅ Passed The description covers all required template sections with clear details about changes, testing, and implementation across database, API, and UI layers.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9a4c23f and 0274eaf.

📒 Files selected for processing (5)
  • apps/desktop/src/lib/trpc/routers/settings/index.ts
  • apps/desktop/src/main/index.ts
  • apps/desktop/src/main/lib/auto-updater.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/BehaviorSettings.tsx
  • apps/desktop/src/shared/constants.ts
🧰 Additional context used
📓 Path-based instructions (6)
apps/desktop/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

apps/desktop/**/*.{ts,tsx}: For Electron interprocess communication, ALWAYS use tRPC as defined in src/lib/trpc
Use alias as defined in tsconfig.json when possible
Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary.
For tRPC subscriptions with trpc-electron, ALWAYS use the observable pattern from @trpc/server/observable instead of async generators, as the library explicitly checks isObservable(result) and throws an error otherwise

Files:

  • apps/desktop/src/lib/trpc/routers/settings/index.ts
  • apps/desktop/src/main/lib/auto-updater.ts
  • apps/desktop/src/main/index.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/BehaviorSettings.tsx
  • apps/desktop/src/shared/constants.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use type safety and avoid any types unless absolutely necessary in TypeScript files

Files:

  • apps/desktop/src/lib/trpc/routers/settings/index.ts
  • apps/desktop/src/main/lib/auto-updater.ts
  • apps/desktop/src/main/index.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/BehaviorSettings.tsx
  • apps/desktop/src/shared/constants.ts
apps/desktop/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Move Node.js functionality needed in Electron renderer to src/main/lib/ and communicate via IPC

Files:

  • apps/desktop/src/lib/trpc/routers/settings/index.ts
  • apps/desktop/src/main/lib/auto-updater.ts
  • apps/desktop/src/main/index.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/BehaviorSettings.tsx
  • apps/desktop/src/shared/constants.ts
apps/desktop/src/main/index.ts

📄 CodeRabbit inference engine (AGENTS.md)

Load environment variables in src/main/index.ts with override: true before any other imports in the desktop app

Files:

  • apps/desktop/src/main/index.ts
apps/**/src/**/**/[A-Z]*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

Structure component folders with one component per file using format ComponentName/ComponentName.tsx with index.ts barrel export

Files:

  • apps/desktop/src/renderer/screens/main/components/SettingsView/BehaviorSettings.tsx
apps/desktop/src/{shared/ipc-channels.ts,main/**/*ipcs.ts,renderer/**/*.tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Define all Electron IPC channel types in apps/desktop/src/shared/ipc-channels.ts before implementing handlers

Files:

  • apps/desktop/src/renderer/screens/main/components/SettingsView/BehaviorSettings.tsx
🧠 Learnings (3)
📚 Learning: 2025-12-28T01:56:39.021Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T01:56:39.021Z
Learning: Applies to apps/desktop/src/main/index.ts : Load environment variables in `src/main/index.ts` with `override: true` before any other imports in the desktop app

Applied to files:

  • apps/desktop/src/lib/trpc/routers/settings/index.ts
  • apps/desktop/src/main/lib/auto-updater.ts
📚 Learning: 2025-12-28T01:56:39.021Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T01:56:39.021Z
Learning: Applies to apps/desktop/src/{shared/ipc-channels.ts,main/**/*ipcs.ts,renderer/**/*.tsx} : Define all Electron IPC channel types in `apps/desktop/src/shared/ipc-channels.ts` before implementing handlers

Applied to files:

  • apps/desktop/src/lib/trpc/routers/settings/index.ts
  • apps/desktop/src/main/lib/auto-updater.ts
  • apps/desktop/src/main/index.ts
📚 Learning: 2025-12-28T01:56:39.021Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T01:56:39.021Z
Learning: Applies to apps/desktop/src/**/*.{ts,tsx} : Move Node.js functionality needed in Electron renderer to `src/main/lib/` and communicate via IPC

Applied to files:

  • apps/desktop/src/main/index.ts
🧬 Code graph analysis (2)
apps/desktop/src/lib/trpc/routers/settings/index.ts (4)
packages/trpc/src/index.ts (1)
  • publicProcedure (12-12)
apps/desktop/src/shared/constants.ts (1)
  • DEFAULT_CONFIRM_ON_QUIT (48-48)
apps/desktop/src/main/lib/local-db/index.ts (1)
  • localDb (82-82)
packages/local-db/src/schema/schema.ts (1)
  • settings (117-130)
apps/desktop/src/main/lib/auto-updater.ts (1)
apps/desktop/src/main/index.ts (1)
  • setSkipQuitConfirmation (120-122)
🔇 Additional comments (16)
apps/desktop/src/shared/constants.ts (1)

47-48: LGTM! Centralized default prevents duplication.

The constant follows existing patterns and addresses the previously noted concern about duplicate defaults between different locations.

apps/desktop/src/main/lib/auto-updater.ts (2)

5-5: LGTM!

Import is correctly placed and the function is properly exported from the source module.


53-54: LGTM! Proper integration with auto-update flow.

The skip-confirmation call is correctly placed before quitAndInstall to ensure the update can proceed without prompting the user.

apps/desktop/src/lib/trpc/routers/settings/index.ts (3)

3-3: LGTM! Resolves duplicate default issue.

The import correctly references the centralized constant, addressing the past review concern about duplicate defaults.


163-167: LGTM! Follows established patterns.

The query procedure correctly reads the setting and applies the default fallback, consistent with other settings procedures in this file.


169-182: LGTM! Consistent with existing patterns.

The mutation procedure correctly validates input and uses the established upsert pattern for settings updates.

apps/desktop/src/renderer/screens/main/components/SettingsView/BehaviorSettings.tsx (3)

6-8: LGTM! Proper tRPC query setup.

The query hook is correctly configured and follows established patterns in the codebase.


9-29: LGTM! Robust optimistic update pattern.

The mutation correctly implements cancel-snapshot-update-rollback-invalidate pattern, ensuring good UX with proper error handling.


54-59: LGTM! Proper default and state handling.

The Switch correctly defaults to true when data is undefined, matching the backend default, and properly disables during loading/mutation states.

apps/desktop/src/main/index.ts (7)

6-7: LGTM! Necessary imports for quit confirmation.

All imports are correctly placed and used in the quit management implementation.

Also applies to: 9-9


95-103: LGTM! Well-designed state machine.

The QuitState union and state variables provide clear tracking of the quit flow phases.


108-115: LGTM! Robust settings retrieval with safe fallback.

The try-catch ensures database errors don't break the quit flow, and the fallback to DEFAULT_CONFIRM_ON_QUIT provides sensible default behavior.


120-130: LGTM! Clean API for bypassing confirmation.

Both exported functions provide necessary control over the quit confirmation flow for special cases like auto-updates.


132-189: LGTM! Robust state machine with proper error handling.

The quit flow correctly implements a state machine with:

  • Early returns for terminal states
  • Prevention of re-entry during transitions
  • Try-catch around dialog to avoid stuck states
  • Proper cleanup sequencing before final quit

The decision to proceed with quit on dialog failure (line 167) is correct—it prevents the app from being stuck in an unquittable state.


205-206: LGTM! Correct use of app.exit(0) for second instance.

Using app.exit(0) instead of app.quit() properly avoids triggering the before-quit handler and confirmation dialog when another instance is already running, preventing the issues mentioned in the PR commits.


171-173: Verify the recursive app.quit() call is intentional.

Calling app.quit() from within the before-quit handler (line 172) will re-trigger the handler. This appears intentional to advance through the state machine, but please confirm this recursive pattern is working as expected in testing.

The flow should be:

  1. First call: idle → confirmed → quit()
  2. Second call: confirmed → cleaning → cleanup → quit()
  3. Third call: ready-to-quit → proceed

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
apps/desktop/src/renderer/screens/main/components/SettingsView/BehaviorSettings.tsx (1)

5-8: Consider adding error handling and user feedback.

The component doesn't handle query errors or provide feedback on mutation success/failure. Users toggling the switch would have no indication if the update failed or succeeded.

Consider destructuring error states and providing user feedback:

🔎 Suggested enhancement
 export function BehaviorSettings() {
-	const { data: confirmOnQuit, isLoading } =
+	const { data: confirmOnQuit, isLoading, error } =
 		trpc.settings.getConfirmOnQuit.useQuery();
 	const setConfirmOnQuit = trpc.settings.setConfirmOnQuit.useMutation();

 	const handleToggle = (enabled: boolean) => {
 		setConfirmOnQuit.mutate({ enabled });
 	};
+
+	// Show error state if query fails
+	if (error) {
+		return (
+			<div className="p-6 max-w-4xl w-full">
+				<p className="text-sm text-destructive">
+					Failed to load behavior settings
+				</p>
+			</div>
+		);
+	}

Additionally, consider using onSuccess/onError callbacks on the mutation or a toast notification to inform users of the result.

apps/desktop/src/main/index.ts (1)

99-111: Consider logging database errors for debugging.

The function correctly defaults to true on any database error, providing a safe fallback. However, silently catching errors could make troubleshooting difficult.

🔎 Optional enhancement
 function getConfirmOnQuitSetting(): boolean {
 	try {
 		const row = localDb.select().from(settings).get();
 		// Default to true if not set
 		return row?.confirmOnQuit ?? true;
-	} catch {
+	} catch (error) {
+		console.error("[main] Failed to read confirmOnQuit setting:", error);
 		// If we can't read the setting, default to showing the dialog
 		return true;
 	}
 }
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4c6f71c and 9a4c23f.

📒 Files selected for processing (10)
  • apps/desktop/src/lib/trpc/routers/settings/index.ts
  • apps/desktop/src/main/index.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/BehaviorSettings.tsx
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsx
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar/GeneralSettings.tsx
  • apps/desktop/src/renderer/stores/app-state.ts
  • packages/local-db/drizzle/0003_add_confirm_on_quit_setting.sql
  • packages/local-db/drizzle/meta/0003_snapshot.json
  • packages/local-db/drizzle/meta/_journal.json
  • packages/local-db/src/schema/schema.ts
🧰 Additional context used
📓 Path-based instructions (6)
apps/desktop/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

apps/desktop/**/*.{ts,tsx}: For Electron interprocess communication, ALWAYS use tRPC as defined in src/lib/trpc
Use alias as defined in tsconfig.json when possible
Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary.
For tRPC subscriptions with trpc-electron, ALWAYS use the observable pattern from @trpc/server/observable instead of async generators, as the library explicitly checks isObservable(result) and throws an error otherwise

Files:

  • apps/desktop/src/renderer/screens/main/components/SettingsView/BehaviorSettings.tsx
  • apps/desktop/src/renderer/stores/app-state.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsx
  • apps/desktop/src/lib/trpc/routers/settings/index.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar/GeneralSettings.tsx
  • apps/desktop/src/main/index.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use type safety and avoid any types unless absolutely necessary in TypeScript files

Files:

  • apps/desktop/src/renderer/screens/main/components/SettingsView/BehaviorSettings.tsx
  • apps/desktop/src/renderer/stores/app-state.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsx
  • apps/desktop/src/lib/trpc/routers/settings/index.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar/GeneralSettings.tsx
  • packages/local-db/src/schema/schema.ts
  • apps/desktop/src/main/index.ts
apps/**/src/**/**/[A-Z]*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

Structure component folders with one component per file using format ComponentName/ComponentName.tsx with index.ts barrel export

Files:

  • apps/desktop/src/renderer/screens/main/components/SettingsView/BehaviorSettings.tsx
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsx
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar/GeneralSettings.tsx
apps/desktop/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Move Node.js functionality needed in Electron renderer to src/main/lib/ and communicate via IPC

Files:

  • apps/desktop/src/renderer/screens/main/components/SettingsView/BehaviorSettings.tsx
  • apps/desktop/src/renderer/stores/app-state.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsx
  • apps/desktop/src/lib/trpc/routers/settings/index.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar/GeneralSettings.tsx
  • apps/desktop/src/main/index.ts
apps/desktop/src/{shared/ipc-channels.ts,main/**/*ipcs.ts,renderer/**/*.tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Define all Electron IPC channel types in apps/desktop/src/shared/ipc-channels.ts before implementing handlers

Files:

  • apps/desktop/src/renderer/screens/main/components/SettingsView/BehaviorSettings.tsx
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsx
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar/GeneralSettings.tsx
apps/desktop/src/main/index.ts

📄 CodeRabbit inference engine (AGENTS.md)

Load environment variables in src/main/index.ts with override: true before any other imports in the desktop app

Files:

  • apps/desktop/src/main/index.ts
🧠 Learnings (3)
📚 Learning: 2025-12-21T04:39:28.543Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-12-21T04:39:28.543Z
Learning: Applies to apps/desktop/**/*.{ts,tsx} : Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary.

Applied to files:

  • apps/desktop/src/renderer/screens/main/components/SettingsView/BehaviorSettings.tsx
📚 Learning: 2025-12-28T01:56:39.021Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T01:56:39.021Z
Learning: Applies to packages/db/src/schema/**/*.ts : Create database migrations by changing Drizzle schema and running `drizzle-kit generate --name="<sample_name_snake_case>"` on a new Neon branch

Applied to files:

  • packages/local-db/drizzle/meta/0003_snapshot.json
📚 Learning: 2025-12-28T01:56:39.021Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T01:56:39.021Z
Learning: Applies to apps/desktop/src/**/*.{ts,tsx} : Move Node.js functionality needed in Electron renderer to `src/main/lib/` and communicate via IPC

Applied to files:

  • apps/desktop/src/main/index.ts
🧬 Code graph analysis (4)
apps/desktop/src/renderer/screens/main/components/SettingsView/BehaviorSettings.tsx (2)
packages/ui/src/components/ui/label.tsx (1)
  • Label (24-24)
packages/ui/src/components/ui/switch.tsx (1)
  • Switch (31-31)
apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsx (1)
apps/desktop/src/renderer/screens/main/components/SettingsView/BehaviorSettings.tsx (1)
  • BehaviorSettings (5-43)
apps/desktop/src/lib/trpc/routers/settings/index.ts (3)
packages/trpc/src/index.ts (1)
  • publicProcedure (12-12)
apps/desktop/src/main/lib/local-db/index.ts (1)
  • localDb (82-82)
packages/local-db/src/schema/schema.ts (1)
  • settings (117-130)
apps/desktop/src/main/index.ts (4)
apps/desktop/src/main/lib/local-db/index.ts (1)
  • localDb (82-82)
packages/local-db/src/schema/schema.ts (1)
  • settings (117-130)
apps/desktop/src/main/lib/terminal/manager.ts (1)
  • terminalManager (437-437)
apps/desktop/src/main/lib/analytics/index.ts (1)
  • posthog (4-4)
🔇 Additional comments (14)
packages/local-db/drizzle/meta/0003_snapshot.json (1)

330-336: LGTM!

The snapshot correctly captures the new confirm_on_quit column as an integer type with nullable constraint, consistent with the SQL migration and schema definition.

apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsx (1)

4-4: LGTM!

The import and conditional rendering follow the established pattern for settings sections. Integration with BehaviorSettings is clean and consistent.

Also applies to: 25-25

packages/local-db/drizzle/0003_add_confirm_on_quit_setting.sql (1)

1-1: LGTM!

The migration correctly adds the column. The lack of a database default is acceptable since the tRPC layer provides an application-level default of true when the value is null.

apps/desktop/src/renderer/stores/app-state.ts (1)

12-13: LGTM!

The SettingsSection type is cleanly extended to include "behavior". The zustand store structure remains consistent with existing patterns.

packages/local-db/drizzle/meta/_journal.json (1)

26-31: LGTM!

The journal entry correctly records the new migration with proper sequencing and metadata.

apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar/GeneralSettings.tsx (1)

3-3: LGTM!

The new "Behavior" section entry follows the established pattern with appropriate icon choice and consistent styling.

Also applies to: 47-51

apps/desktop/src/lib/trpc/routers/settings/index.ts (1)

162-181: LGTM!

The new getConfirmOnQuit and setConfirmOnQuit procedures correctly follow the established patterns in this router:

  • Query uses getSettings() helper with nullish coalescing for the default value
  • Mutation uses upsert semantics consistent with other settings mutations
  • Zod validation is properly applied
packages/local-db/src/schema/schema.ts (1)

129-129: LGTM!

The schema correctly defines confirmOnQuit as an integer with boolean mode, which is the standard Drizzle ORM pattern for SQLite boolean columns. The nullable design aligns with the application-level default handling in the tRPC router.

apps/desktop/src/renderer/screens/main/components/SettingsView/BehaviorSettings.tsx (3)

1-3: LGTM: Imports follow project conventions.

The imports correctly use UI components from the shared package and the TRPC client via the configured alias.


10-12: LGTM: Handler correctly invokes the mutation.

The toggle handler properly passes the new state to the mutation.


35-35: Default value consistency verified.

The UI defaults to true when confirmOnQuit is undefined. This aligns with the TRPC getConfirmOnQuit query which explicitly defaults to true, and the main process getConfirmOnQuitSetting() function which also defaults to true. No issues found.

apps/desktop/src/main/index.ts (3)

6-7: LGTM: Imports are appropriate for the feature.

The dialog module from Electron is needed for the confirmation prompt, and settings schema is required for reading the user preference from the database.


95-96: LGTM: Clear state machine design.

The QuitState type defines a clear lifecycle for the quit process. The state transitions will be validated in the handler review.


113-165: State machine logic is sound and handles quit flow correctly.

Verification confirms the state machine properly coordinates confirmation and cleanup:

  • idle → confirming → confirmed → cleaning → ready-to-quit transitions work as intended
  • User confirmation dialog prevents concurrent quit attempts (lines 117-120)
  • Cleanup runs before allowing app exit (lines 159-164)
  • Recursive app.quit() calls handled correctly by state checks
  • Dependencies (terminalManager, posthog, localDb) are properly imported and available

The empty before-quit handler in setup.ts (line 67) is overridden by the index.ts handler and has no impact.

No automated tests exist for this quit flow. Given the complexity and multiple state transitions, consider adding tests covering:

  1. Quit with confirmation enabled → confirm → app quits
  2. Quit with confirmation enabled → cancel → app stays open
  3. Quit with confirmation disabled → app quits immediately
  4. Rapid multiple quit attempts during confirmation dialog
  5. Cleanup failures and error recovery

@saddlepaddle
Copy link
Copy Markdown
Collaborator

Great idea! Honestly we should pretty much always ask to quit since it can be pretty destructive (lots of terminals to close), wanna switch this to always asking on close?

Thanks for the PR btw!

@andreasasprou
Copy link
Copy Markdown
Contributor Author

andreasasprou commented Dec 28, 2025

Great idea! Honestly we should pretty much always ask to quit since it can be pretty destructive (lots of terminals to close), wanna switch this to always asking on close?

Thanks for the PR btw!

@saddlepaddle Enabled by default! https://github.com/superset-sh/superset/pull/524/changes#diff-d21adf32a04f683039509115823792173782ddfe72680f3fd546a2bf18af75dfR162

image

@andreasasprou andreasasprou marked this pull request as draft December 28, 2025 17:00
- P0: Use app.exit(0) for !gotTheLock to avoid confirmation dialog on
  second instance (prevents headless zombie process)
- P1: Wrap dialog.showMessageBox in try/catch to prevent stuck
  "confirming" state if dialog fails
- P1: Add optimistic update with rollback for Switch toggle so UI
  updates immediately
- Add setSkipQuitConfirmation() for auto-updater to bypass confirmation
  during quitAndInstall

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Comment thread apps/desktop/src/lib/trpc/routers/settings/index.ts Outdated
…tion

- Add DEFAULT_CONFIRM_ON_QUIT to shared/constants.ts
- Update main/index.ts to use shared constant instead of hardcoded true
- Update trpc settings router to use shared constant
- Prevents maintenance issues when default value needs to change
- Addresses PR review comment about duplicate defaults
- Fix import order in apps/desktop/src/main/index.ts
- Fix import order in apps/desktop/src/main/lib/auto-updater.ts
- Run biome check --write to automatically organize imports
@andreasasprou andreasasprou marked this pull request as ready for review December 28, 2025 17:32
Copy link
Copy Markdown
Collaborator

@Kitenite Kitenite left a comment

Choose a reason for hiding this comment

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

Works great, thanks @andreasasprou !

@Kitenite Kitenite merged commit 85064bf into superset-sh:main Dec 28, 2025
11 of 13 checks passed
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.

3 participants