refactor(window-presenter): single source of truth for user-facing window state
Adds a WindowPresenter that resolves a window's user-facing
appearance — address (page-host inner URL or host URL), canvas-aware
bounds, maximize state, favicon, thumbnail — from authoritative
in-memory state (windowRegistry.info.params, BrowserWindow), without
any caller having to know about the page-host shell URL or its
search-param bootstrap.
Why:
- Session save was parsing peek://app/page/?url=...&x=...&maximized=1
search params to recover the inner URL and canvas bounds. Each
consumer (session save, reopen-last-closed, tile:window:list) was
rediscovering the same parsing rules and drifting apart.
- The page-host already maintained the inner URL on
info.params.currentUrl (set by main.ts's did-attach-webview on
every navigation). The URL-search-param dance was a vestigial
source of truth.
Changes:
- backend/electron/window-address.ts (new): pure
resolveWindowAddress(hostUrl, params) helper. No Electron deps so
it is unit-testable under ELECTRON_RUN_AS_NODE.
- backend/electron/window-presenter.ts (new): WindowPresentation
interface + getWindowPresentation(windowId). One entry point;
consumers do not touch URL parsing.
- session.ts: deleted extractRealUrl / extractCanvasBounds; reads
presenter. Adds overlay carve-out — windows hidden by an active
overlay (Windows switcher, etc.) are still saved, while overlay
descriptors themselves are skipped at save AND restore.
- main.ts close handler: captures lastPresentation pre-destruction
so reopen-last-closed gets canvas-aware bounds and maximize state
without re-parsing the host URL.
- tile-ipc.ts: tile:window:list returns presenter.address as the
url field.
- ipc.ts, tile-api.d.ts, tile-preload.cts, app/page/page.js: thread
through info.params updates so currentUrl stays authoritative.
- features/windows: shows favicon + presenter-resolved title/url.
- session.test.ts: regression tests for overlay-hidden window save,
overlay descriptor skip at save AND restore.
- window-address.test.ts: 8 unit tests for the resolver.
- tests/desktop/session-restore-page-host.spec.ts: integration test
for the cmd+n -> type URL -> quit -> restart restore path.
This is a binary file and will not be displayed.