fix(window-state): eliminate "main" window label to fix stale geometry restore#906
Merged
fix(window-state): eliminate "main" window label to fix stale geometry restore#906
Conversation
…y restore
The tauri-plugin-window-state plugin persists window geometry by label.
The app reused Tauri's auto-created "main" window as the first notebook,
but this generic label accumulated stale geometry state — if it was ever
saved at a tiny size, every subsequent launch restored that tiny window.
All notebook windows (including the first) are now created explicitly
with proper "notebook-{hash}" labels through the same code path used by
create_notebook_window_for_daemon. This gives each notebook a
deterministic, content-based label for geometry persistence.
- Empty the windows array in tauri.conf.json (no auto-created window)
- Create first notebook window in setup with proper label
- Add "main" to window-state denylist (safety net for upgrades)
- Remove "main" special cases from close handler, file association,
dock reopen, and session restore
- Session restore uses first entry instead of finding label=="main"
- Add find_empty_window_label() for generic empty-window reuse
Closes #849
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes stale window-geometry restores caused by reusing Tauri’s auto-created "main" window label by ensuring all notebook windows are explicitly created with deterministic "notebook-*" labels, and adding safeguards for users upgrading from older sessions.
Changes:
- Removes the default auto-created Tauri window (
"windows": []) and creates the first notebook window explicitly with a"notebook-*"label. - Adds
"main"to thetauri-plugin-window-statedenylist and removes"main"-specific handling across startup/session restore and window lifecycle paths. - Updates session label behavior/tests to no longer treat
"main"as a special passthrough label.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| crates/notebook/tauri.conf.json | Removes auto-created default window to avoid the "main" label being used. |
| crates/notebook/src/session.rs | Removes "main" special-casing in label logic and updates tests accordingly. |
| crates/notebook/src/lib.rs | Creates the first notebook window explicitly with a "notebook-*" label; updates session restore and file-association behavior to be label-agnostic. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
Comment on lines
+3357
to
+3358
| // Use the first session window (was the primary window at save time). | ||
| if let Some(first_session) = session.windows.first() { |
| .filter(|w| w.label != "main") | ||
| .cloned() | ||
| .collect() | ||
| session.windows.iter().skip(1).cloned().collect() |
Address review feedback: HashMap iteration order is nondeterministic, so session.windows.first() and skip(1) were unreliable for identifying the primary window. - Sort windows by label during save for deterministic ordering - Add primary_label field to SessionState (skip_serializing_if None for backward compat with old session files) - Use primary_label to find the primary window during restore, falling back to first entry for old sessions - Filter additional session windows by primary_label instead of skip(1)
Instead of distinguishing a "primary" window (created in setup) from "additional" windows (deferred to after daemon ready), all session windows are now created immediately in the synchronous setup callback. Each shows a loading UI until the daemon is available, then all are synced in a single loop. This eliminates the need for primary_label, sorted session ordering, and the first-vs-additional window distinction. All notebook windows are treated equally — no special cases.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
tauri-plugin-window-statepersists window geometry by label. The app reused Tauri's auto-created"main"window as the first notebook, but this generic label accumulated stale geometry — if it was ever saved at a tiny size, every subsequent launch restored that tiny window."notebook-{hash}"labels through the same code path used bycreate_notebook_window_for_daemon. No more"main"special case.windowsarray intauri.conf.json(no auto-created default window)"main"to the window-state plugin denylist as a safety net for users upgrading from older versions"main"special cases from: window close handler, file association (Finder double-click), macOS dock reopen, and session restorelabel == "main"find_empty_window_label()to generically reuse any untitled window for file associationCloses #849
Test plan
notebook-*labelnotebook-{hash}label~/Library/Application Support/io.nteract.runt-nightly/.window-state.json, resize window tiny, quit, relaunch — does NOT restore tiny size (fresh label).ipynbin Finder) — opens in empty window or new window"main"insession.json— restores correctly with new label