You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Decide what a theme switch does to a stage the user framed themselves #36
Should a theme switch preserve the camera the user framed themselves, and if so, at what cost?
A palette change is a stage construction, and fitView() runs unconditionally there (TreeScene.tsx:655, CityScene.tsx:618) — so switching theme re-frames both scenes over whatever the user had. The guard against exactly this already exists twice on other paths: the resize handler and the tallest-column refit both decline to re-frame when userTookCameraRef.current or a live selection pan says the camera is spoken for.
What makes it a question rather than a third copy of that guard is that palette is also a dependency of the mount effect (CityScene.tsx:442, TreeScene.tsx:408). A theme switch therefore tears down the renderer, the OrbitControls, and the WebGL context itself, and re-runs userTookCameraRef.current = false on the way back up. The flag that would drive the guard is wiped by the same rebuild it is meant to survive, so preserving the framing means either lifting that state out of the rebuild or narrowing what a palette change is allowed to reconstruct.
Worth weighing against: rebuilding wholesale is a deliberate choice, on the grounds that "it happens once in a blue moon, and the alternative is a second code path that has to stay in step with scene construction forever" (CityScene.tsx:107). Re-fitting a rebuilt stage is defensible if a rebuild is read as a fresh stage — and the counter-argument is that the user does not experience a theme switch as a fresh stage.
Found resolving #27, and deliberately left out of it: selection state is re-applied across a rebuild now, but the user's own framing is not selection state.
A second case for this same question, found by the cold review pass on #27 and verified against the source.
When a rebuild lands while the host reports zero size — an inactive surface tab, a background pane — fitView() returns false and the fit is deferred into fitPendingRef (CityScene.tsx:618, TreeScene.tsx:655). The resize handler later runs that pending fit unguarded (CityScene.tsx:323), which is right in itself: there is no valid framing yet, so something has to fit. But the selection effect does not re-run at that later moment, so the pan #27 restored is not re-issued, and the selected column comes back under the inspector.
Note the guard the very next line already makes for the ordinary refit — else if (!userTookCameraRef.current && !preSelectCameraRef.current) — does not and should not apply to the pending branch, so this is not the same one-line fix.
Reachability is narrow: it needs a theme switch while a file is selected and the surface is hidden. The marker is unaffected either way (ring.visible does not depend on canvas size; ensureVisible is the only part that no-ops at zero size, sceneUtils.ts:103).
It belongs here rather than as its own ticket because it is the same question in a different guise — what a rebuild owes the camera — and any answer that lifts camera state out of the rebuild would cover both.
Activity
Dillpickleschmidt commentedon Aug 3, 2026
A second case for this same question, found by the cold review pass on #27 and verified against the source.
When a rebuild lands while the host reports zero size — an inactive surface tab, a background pane —
fitView()returns false and the fit is deferred intofitPendingRef(CityScene.tsx:618,TreeScene.tsx:655). The resize handler later runs that pending fit unguarded (CityScene.tsx:323), which is right in itself: there is no valid framing yet, so something has to fit. But the selection effect does not re-run at that later moment, so the pan #27 restored is not re-issued, and the selected column comes back under the inspector.Note the guard the very next line already makes for the ordinary refit —
else if (!userTookCameraRef.current && !preSelectCameraRef.current)— does not and should not apply to the pending branch, so this is not the same one-line fix.Reachability is narrow: it needs a theme switch while a file is selected and the surface is hidden. The marker is unaffected either way (
ring.visibledoes not depend on canvas size;ensureVisibleis the only part that no-ops at zero size,sceneUtils.ts:103).It belongs here rather than as its own ticket because it is the same question in a different guise — what a rebuild owes the camera — and any answer that lifts camera state out of the rebuild would cover both.