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).
App._post_init now resolves src = paths.get_layouts_dir()/default.ini
and dst = Path.cwd()/manualslop_layout.ini, then calls the drain-plane
helper before the warmup-complete registration block. Errors drain to
self._startup_timeline_errors per the data-oriented convention, so a
missing bundled layout (e.g. partial wheel install) does not crash the
GUI: panels just stay invisible until the user drops a real INI in.
Test fix: test_default_layout_install._GUI_SCRIPT was a relative path,
but the subprocess Popen runs with cwd = temp_workspace where sloppy.py
does not exist. Switched to an absolute path via _PROJECT_ROOT, the
same pattern conftest.py:648 uses for the live_gui fixture.
3 tests in tests/test_default_layout_install.py per spec G6/G7 acceptance:
- test_default_layout_installed_when_ini_missing
- test_default_layout_installed_when_ini_empty
- test_default_layout_NOT_installed_when_layout_present
Currently fail as expected (no install helper exists yet). Test 3 passes as
a positive control (custom user INI is preserved when no install logic
runs).
Subprocess spawn pattern: each test creates its own tmp_path workspace,
spawns sloppy.py without --enable-test-hooks (avoids port-8999 conflict
with the live_gui session fixture's subprocess), waits 5s, terminates
via taskkill /F /T, asserts on the saved INI content.
state.toml: phase 1 marked completed; tasks t1_1-t1_10 recorded with
SHA 7577d7d. plan.md updated for Phase 1 task completion.