Skip to content

UX: Redesign deferred settings commits for Obsidian v1.13+ window lifecycle #596

Description

@cybaea

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.

  1. 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.
  2. Spurious Commits: The commit might eventually fire unexpectedly much later when the user casually switches to another plugin's settings tab.
  3. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions