fix(layout): strip stale dockspace IDs from bundled INI; force live-session apply

Bundled layouts/default.ini (relocated from tests/artifacts/ in Phase 1)
contained a [Docking] data block with a hardcoded DockSpace ID 0xAFBEEF01
plus per-window DockId references to nodes 0x10 and 0x11. Those IDs were
captured at the time the layout was first generated; on any fresh session
HelloImgui computes dockspace IDs dynamically (typically a hash of the
dockspace name + creation order) so the hardcoded literal is stale by the
first render and the orphan docking instructions are silently dropped.

Result: window positions stored in the INI render the windows as
floating at their absolute Pos coordinates, but the auto-created
dockspace captures the full window body, hiding them all. User observed
empty dockspace with only the menu ribbon rendering.

Two-part fix:

1. layouts/default.ini: remove [Docking] data block and per-window DockId
   lines. Comment rewritten to explain why the auto-dock strategy is the
   only session-stable option. Each [Window] entry now has only Pos + Size
   + Collapsed=0, so HelloImgui's auto-dock layer places the panels as
   tabs in the central dockspace on first render.

2. _install_default_layout_if_empty: after writing the bundled INI to
   disk, also call imgui.load_ini_settings_from_memory(src_text) to force
   the live HelloImgui session to apply the new INI. Without this, the
   install only takes effect on the NEXT launch (since HelloImgui reads
   cwd/manualslop_layout.ini BEFORE the post_init callback fires). With it,
   first-launch panels appear immediately.

Tests:
- tests/test_default_layout_install.py assertions updated: instead of
  checking for a per-window DockId line, the install now verifies (a)
  [Window][Project Settings] entry exists, (b) the INI has at least one
  [Window] entry, (c) the INI has no [Docking] data block.
- New _assert_live_session_apply() on tests 1 and 2 verifies the
  "(and applied to live session)" log line appears in stderr, confirming
  imgui.load_ini_settings_from_memory was invoked.

17/17 tests pass (3 install + 2 reset_layout + 8 adjacent gui/commands).
This commit is contained in:
ed
2026-06-29 19:08:49 -04:00
parent 15cd12624f
commit e965451842
3 changed files with 95 additions and 77 deletions
+10 -2
View File
@@ -1478,7 +1478,11 @@ def _install_default_layout_if_empty(src_ini: Path, dst_ini: Path) -> Result[boo
Decision rule: dst_ini is "empty" when its content is fewer than 1000
bytes OR has no [Window][ header. On empty, copies src_ini -> dst_ini
and returns Result(data=True). On non-empty (user customized), returns
and ALSO calls imgui.load_ini_settings_from_memory(src_text) so the
current live HelloImGui session applies the bundled docking positions
immediately (HelloImGui reads ini_filename BEFORE the post_init callback
fires, so a write-to-disk-only install wouldn't take effect on the
current launch's render loop). On non-empty (user customized), returns
Result(data=False) without overwriting. On OSError reading src or
writing dst, returns Result(data=False, errors=[ErrorInfo]) so the
legacy wrapper in App._post_init can drain to _startup_timeline_errors.
@@ -1511,7 +1515,11 @@ def _install_default_layout_if_empty(src_ini: Path, dst_ini: Path) -> Result[boo
source="gui_2._install_default_layout_if_empty",
original=e,
)])
sys.stderr.write(f"[GUI] installed default layout: {src_ini} -> {dst_ini}\n")
try:
imgui.load_ini_settings_from_memory(src_text)
sys.stderr.write(f"[GUI] installed default layout: {src_ini} -> {dst_ini} (and applied to live session)\n")
except Exception as e:
sys.stderr.write(f"[GUI] installed default layout to disk: {src_ini} -> {dst_ini} (live-session apply failed: {e})\n")
return Result(data=True)
def _install_default_layout_if_empty_result(app: "App", src: Path, dst: Path) -> Result[bool]:
"""Drain-aware variant of _install_default_layout_if_empty.