UX: Redesign deferred settings commits for Obsidian v1.13+ window lifecycle
Description
With the introduction of the declarative settings API in Obsidian v1.13, the lifecycle of the settings interface has fundamentally changed. We need to redesign how "heavy" configuration changes (like index wipes and worker restarts) are committed, as the current deferred-commit architecture relies on a UI paradigm that Obsidian has moved away from.
Context: The v1.12 vs. v1.13 Lifecycle
Historically (Obsidian v1.12 and earlier), the plugin settings existed in a modal dialog. When a user changed a heavy setting—such as the embeddingProvider or chatModel—we set a deferred flag (requiresIndexWipeOnExit or requiresWorkerRestartOnExit).
When the user closed the modal, it represented an unambiguous "I'm done" action. This triggered the hide() hook, which we used to consume those flags and safely execute commitConfigChange() without locking up the UI while the user was actively toggling settings.
In Obsidian v1.13+, the settings interface has been moved to a separate, persistent background window.
- The
hide() hook no longer fires when a user simply finishes adjusting our settings.
- It only fires when the user completely closes the settings window or navigates away to another plugin's configuration tab.
The Problem
Because users can now leave the settings window open indefinitely while returning to their vault, the deferred commits are delayed unpredictably.
- User Confusion: A user might change their embedding model, see the warning, click back to their vault, and wonder why the background re-indexing hasn't started yet.
- Spurious Commits: The commit might eventually fire unexpectedly much later when the user casually switches to another plugin's settings tab.
- Loss of "Exit" Semantics: The separation between "editing settings" and "applying settings" is no longer intuitive.
(Note: We implemented a dirty-state snapshotting fix in Issue #595 to dismiss the warning if the user reverts their changes before navigating away, but the underlying commit lifecycle remains tied to the delayed hide() hook).
Potential Solutions
We need a broader architectural discussion to replace the hide()-based deferred commit pattern. Potential options include:
1. Explicit "Apply Changes" pattern
Introduce a sticky or floating "Apply Changes and Restart" / "Apply Changes and Re-index" button that appears whenever requiresIndexWipeOnExit or requiresWorkerRestartOnExit is true.
- Pros: Totally unambiguous. Gives the user explicit control over when heavy processing starts.
- Cons: Diverges from Obsidian's standard "auto-save" settings paradigm.
2. Debounced Eager Commits
Instead of waiting for hide(), we could eagerly trigger the commitConfigChange directly from the onChange handlers, but wrapped in a heavy debounce (e.g., 3 to 5 seconds).
- Pros: Aligns with auto-save expectations.
- Cons: Risky. If the background worker restarts or wipes the index while the user is actively clicking other settings, it could cause UI lockups or race conditions.
3. Page Unmount Hooks (Declarative API)
Investigate if the Obsidian v1.13 declarative API offers an unmount or blur hook at the page level (e.g., leaving the "Explorer" tab for the "Researcher" tab), rather than waiting for the entire plugin settings tab to fire hide().
Related Issues
UX: Redesign deferred settings commits for Obsidian v1.13+ window lifecycle
Description
With the introduction of the declarative settings API in Obsidian v1.13, the lifecycle of the settings interface has fundamentally changed. We need to redesign how "heavy" configuration changes (like index wipes and worker restarts) are committed, as the current deferred-commit architecture relies on a UI paradigm that Obsidian has moved away from.
Context: The v1.12 vs. v1.13 Lifecycle
Historically (Obsidian v1.12 and earlier), the plugin settings existed in a modal dialog. When a user changed a heavy setting—such as the
embeddingProviderorchatModel—we set a deferred flag (requiresIndexWipeOnExitorrequiresWorkerRestartOnExit).When the user closed the modal, it represented an unambiguous "I'm done" action. This triggered the
hide()hook, which we used to consume those flags and safely executecommitConfigChange()without locking up the UI while the user was actively toggling settings.In Obsidian v1.13+, the settings interface has been moved to a separate, persistent background window.
hide()hook no longer fires when a user simply finishes adjusting our settings.The Problem
Because users can now leave the settings window open indefinitely while returning to their vault, the deferred commits are delayed unpredictably.
(Note: We implemented a dirty-state snapshotting fix in Issue #595 to dismiss the warning if the user reverts their changes before navigating away, but the underlying commit lifecycle remains tied to the delayed
hide()hook).Potential Solutions
We need a broader architectural discussion to replace the
hide()-based deferred commit pattern. Potential options include:1. Explicit "Apply Changes" pattern
Introduce a sticky or floating "Apply Changes and Restart" / "Apply Changes and Re-index" button that appears whenever
requiresIndexWipeOnExitorrequiresWorkerRestartOnExitis true.2. Debounced Eager Commits
Instead of waiting for
hide(), we could eagerly trigger thecommitConfigChangedirectly from theonChangehandlers, but wrapped in a heavy debounce (e.g., 3 to 5 seconds).3. Page Unmount Hooks (Declarative API)
Investigate if the Obsidian v1.13 declarative API offers an unmount or blur hook at the page level (e.g., leaving the "Explorer" tab for the "Researcher" tab), rather than waiting for the entire plugin settings tab to fire
hide().Related Issues