fix(layout): restore [Docking] structure + per-window DockId references in bundled INI
Tier 2's commite9654518stripped the [Docking] data block and all per-window DockId lines from layouts/default.ini based on the wrong theory that HelloImgui would "auto-dock" panels via its central dockspace. Empirically verified against tier2 branch HEAD (e9654518): manualslop_layout.ini after first launch: 1447 bytes (Docking block with DockSpace ID=0xAFC85805 + CentralNode=1, no DockNode children, no per-window DockId lines) User-visible result: empty dockspace with only the menu ribbon; 9 default-visible panels are NOT rendered. Compared with the user's working manualslop_layout.ini on master (2150 bytes: full [Docking] hierarchy + 2 DockNode children + every visible window has DockId=0x00000001,N or 0x00000002,N): panels render. Root cause: the literal DockSpace ID in the bundled INI is matched by imgui-bundle's HelloImgui against the dockspace it creates during the session (ID computed deterministically from MainDockSpace name hash, which is stable across sessions -- the SplitIds line in every HelloImui-generated INI records 2949142533 = 0xAFC85805). The Phase 1 bundled INI had DockSpace ID=0xAFBEEF01 (one increment off the correct ID) and Tier 2 stripped the entire docking structure on the wrong theory that ids are session-incompatible. They aren't, as long as the bundled INI's literal ID matches the runtime's computed ID. This fix restores the docking structure in layouts/default.ini: - 8 [Window][...] entries (Project Settings, Files & Media, AI Settings, Theme, Operations Hub, Discussion Hub, Log Management, Diagnostics) each with Pos + Size + Collapsed=0 AND a DockId= line referencing 0x00000001 (left column) or 0x00000002 (right column) - [Docking][Data] block with DockSpace ID=0xAFC85805 + 2 DockNode children (CentralNode=1 at 0x00000001 left, sibling at 0x00000002 right) - HelloImGui_Misc block + SplitIds line - Comment block explaining the mechanism (replaces the misleadinge9654518"auto-dock layer" claim) - Omits Response (in _STALE_WINDOW_NAMES from src/gui_2.py:603-607) so _diag_layout_state does not emit a stale-name warning The fix is the GOOD half ofe9654518-- the live-session imgui.load_ini_settings_from_memory(src_text) apply after the copy stays (it ensures the install takes effect on the current launch rather than the next one). Only the INI content + the matching test assertions change. Tests: - _has_docking_block_with_docknodes (replaces _has_no_docking_block): asserts the bundled INI has [Docking][Data] with DockSpace AND >=1 DockNode ID= line - _every_window_has_dockid (new): asserts every [Window][...] header is followed by a DockId= line in its block - _has_no_stale_window_names (new): asserts no _STALE_WINDOW_NAMES entry is in the bundled INI 17/17 tests pass (3 install + 2 reset_layout + 8 adjacent gui + 4 commands). Empirical verification: - delete cwd/manualslop_layout.ini - uv run python sloppy.py (no --enable-test-hooks; without this flag the app uses its regular GUI rendering pipeline) - log line: "[GUI] installed default layout: ...layouts/default.ini -> ...manualslop_layout.ini (and applied to live session)" - log line: "[GUI] visible-by-default windows: AI Settings, Diagnostics, Discussion Hub, Files & Media, Log Management, Operations Hub, Project Settings, Response, Theme" - saved manualslop_layout.ini post-launch: 3072 bytes with 2 DockNodes, 8 [Window] entries (matches bundled INI minus runtime additions), 0 stale window names
This commit is contained in:
+71
-64
@@ -1,94 +1,101 @@
|
|||||||
;;;
|
;;;
|
||||||
;;; Manual Slop default docking layout for live_gui test sessions
|
;;; Manual Slop default docking layout for live_gui test sessions AND
|
||||||
|
;;; first-run production launches (when cwd/manualslop_layout.ini is
|
||||||
|
;;; missing/empty/small).
|
||||||
;;;
|
;;;
|
||||||
;;; Layout strategy: each window entry has Pos + Size + Collapsed=0 set
|
;;; Mechanism: HelloImGui reads this INI at app startup via the
|
||||||
;;; explicitly so the window is registered at a known absolute position.
|
;;; ini_folder_type/ini_filename on the RunnerParams. The DockSpace ID,
|
||||||
;;; No docking data block and no DockId references -- HelloImgui dockspace
|
;;; DockNode IDs, and per-window DockId lines below tell HelloImgui where
|
||||||
;;; IDs are computed dynamically per session (typically a hash of the
|
;;; to place each panel. The literal IDs (0xAFC85805, 0x00000001,
|
||||||
;;; dockspace name and creation order), so any DockSpace ID literal baked
|
;;; 0x00000002) match the runtime-generated MainDockSpace ID (decimal
|
||||||
;;; into an INI is stale by the next render of a fresh session and its
|
;;; 2949142533) that HelloImGui computes deterministically per session.
|
||||||
;;; docking instructions are dropped as orphan. Letting HelloImgui's
|
|
||||||
;;; auto-dock layer handle the layout (placing windows as tabs in the
|
|
||||||
;;; central dockspace) is the only session-stable option.
|
|
||||||
;;;
|
;;;
|
||||||
;;; Window list (matches src/app_controller.py:_default_windows defaults
|
;;; Window list matches the post-config-merge effective visibility set
|
||||||
;;; plus the four Tier panels that the user prefers visible):
|
;;; (8 default-true windows excluding Response (stale) and the four
|
||||||
;;; Pos=0,29 Size=600,400 : Project Settings, Files and Media,
|
;;; Tier panels (disabled in config.toml)):
|
||||||
;;; AI Settings, Operations Hub, Theme
|
;;; Project Settings, Files & Media, AI Settings, AI operations,
|
||||||
;;; Pos=600,29 Size=600,400 : Discussion Hub, Log Management,
|
;;; Discussion Hub, Operations Hub, Theme, Log Management, Diagnostics.
|
||||||
;;; Diagnostics
|
;;; Per-window DockId:
|
||||||
;;; Pos=0,432 Size=400,300 : Tier 1 Strategy, Tier 2 Tech Lead,
|
;;; 0x00000001,0..4 = left column tabs (Theme, Project Settings,
|
||||||
;;; Tier 3 Workers, Tier 4 QA
|
;;; AI Settings, Files & Media, Operations Hub)
|
||||||
|
;;; 0x00000002,0..2 = right column tabs (Discussion Hub, Log Management,
|
||||||
|
;;; Diagnostics)
|
||||||
;;;
|
;;;
|
||||||
;;; All Collapsed=0 so the windows expand immediately on first render.
|
;;; All Collapsed=0 so the windows expand immediately on first render.
|
||||||
;;;
|
;;;
|
||||||
;;; To iterate on this layout: open sloppy.py, arrange windows as
|
;;; This INI does NOT include any of the _STALE_WINDOW_NAMES from
|
||||||
;;; desired, quit (HelloImgui auto-saves), then copy the resulting
|
;;; src/gui_2.py:603-607 (Projects, Files, Screenshots, Discussion History,
|
||||||
;;; cwd/manualslop_layout.ini over this one. Strip the docking data
|
;;; Provider, Message, Response, Tool Calls, Comms History, System Prompts).
|
||||||
;;; block from the saved INI before copy (or just keep this default
|
;;; _diag_layout_state will not emit a "stale window name" warning.
|
||||||
;;; which auto-docks cleanly).
|
|
||||||
;;;
|
;;;
|
||||||
;;; Scrubbed entries: no Text Viewer / Tool Script / Inject File /
|
;;; To iterate on this layout: open sloppy.py, arrange windows as
|
||||||
;;; AST Inspector / Context Preview / Patch modal etc. (transient or
|
;;; desired, quit (HelloImGui auto-saves), then copy the resulting
|
||||||
;;; modal-by-default).
|
;;; cwd/manualslop_layout.ini over this one. (HelloImGui adds SplitsIds,
|
||||||
|
;;; Tables, and other internal sections on save; the bundled default
|
||||||
|
;;; version is the minimal scaffold needed for first-run visibility.)
|
||||||
;;;
|
;;;
|
||||||
|
|
||||||
[Window][Project Settings]
|
[Window][Project Settings]
|
||||||
Pos=0,29
|
Pos=0,28
|
||||||
Size=400,400
|
Size=481,1172
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
DockId=0x00000001,1
|
||||||
|
|
||||||
[Window][Files & Media]
|
[Window][Files & Media]
|
||||||
Pos=0,432
|
Pos=0,28
|
||||||
Size=400,400
|
Size=481,1172
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
DockId=0x00000001,3
|
||||||
|
|
||||||
[Window][AI Settings]
|
[Window][AI Settings]
|
||||||
Pos=410,29
|
Pos=0,28
|
||||||
Size=400,400
|
Size=481,1172
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
DockId=0x00000001,2
|
||||||
|
|
||||||
[Window][Operations Hub]
|
[Window][Operations Hub]
|
||||||
Pos=410,432
|
Pos=0,28
|
||||||
Size=400,400
|
Size=481,1172
|
||||||
Collapsed=0
|
|
||||||
|
|
||||||
[Window][Discussion Hub]
|
|
||||||
Pos=820,29
|
|
||||||
Size=400,600
|
|
||||||
Collapsed=0
|
|
||||||
|
|
||||||
[Window][Log Management]
|
|
||||||
Pos=820,640
|
|
||||||
Size=400,200
|
|
||||||
Collapsed=0
|
|
||||||
|
|
||||||
[Window][Diagnostics]
|
|
||||||
Pos=820,850
|
|
||||||
Size=400,250
|
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
DockId=0x00000001,4
|
||||||
|
|
||||||
[Window][Theme]
|
[Window][Theme]
|
||||||
Pos=1230,29
|
Pos=0,28
|
||||||
Size=400,300
|
Size=481,1172
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
DockId=0x00000001,0
|
||||||
|
|
||||||
[Window][Tier 1: Strategy]
|
[Window][Discussion Hub]
|
||||||
Pos=1230,340
|
Pos=483,28
|
||||||
Size=400,250
|
Size=1197,1172
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
DockId=0x00000002,0
|
||||||
|
|
||||||
[Window][Tier 2: Tech Lead]
|
[Window][Log Management]
|
||||||
Pos=1230,600
|
Pos=483,28
|
||||||
Size=400,250
|
Size=1197,1172
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
DockId=0x00000002,1
|
||||||
|
|
||||||
[Window][Tier 3: Workers]
|
[Window][Diagnostics]
|
||||||
Pos=1230,860
|
Pos=483,28
|
||||||
Size=400,200
|
Size=1197,1172
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
DockId=0x00000002,2
|
||||||
|
|
||||||
[Window][Tier 4: QA]
|
[Docking][Data]
|
||||||
Pos=1640,29
|
DockSpace ID=0xAFC85805 Window=0x079D3A04 Pos=0,28 Size=1680,1172 Split=X
|
||||||
Size=400,300
|
DockNode ID=0x00000001 Parent=0xAFC85805 SizeRef=481,1172 CentralNode=1 Selected=0x3F1379AF
|
||||||
Collapsed=0
|
DockNode ID=0x00000002 Parent=0xAFC85805 SizeRef=1197,1172 Selected=0xB4CBF21A
|
||||||
|
|
||||||
|
;;;<<<HelloImGui_Misc>>>;;;
|
||||||
|
[Layout]
|
||||||
|
Name=Default
|
||||||
|
[StatusBar]
|
||||||
|
Show=false
|
||||||
|
ShowFps=true
|
||||||
|
[Theme]
|
||||||
|
Name=ImGuiColorsDark
|
||||||
|
|
||||||
|
;;;<<<SplitIds>>>;;;
|
||||||
|
{"gImGuiSplitIDs":{"MainDockSpace":2949142533}}
|
||||||
|
|||||||
@@ -98,8 +98,51 @@ def _has_window_with_collapsed_zero(text: str) -> bool:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def _has_no_docking_block(text: str) -> bool:
|
def _has_docking_block_with_docknodes(text: str) -> bool:
|
||||||
return "[Docking][Data]" not in text
|
if "[Docking][Data]" not in text:
|
||||||
|
return False
|
||||||
|
if "DockSpace" not in text:
|
||||||
|
return False
|
||||||
|
docknode_count: int = 0
|
||||||
|
for line in text.splitlines():
|
||||||
|
if line.strip().startswith("DockNode") and "ID=" in line:
|
||||||
|
docknode_count += 1
|
||||||
|
return docknode_count >= 1
|
||||||
|
|
||||||
|
|
||||||
|
def _every_window_has_dockid(text: str) -> bool:
|
||||||
|
lines: list[str] = text.splitlines()
|
||||||
|
blocks: dict[str, list[str]] = {}
|
||||||
|
for idx, line in enumerate(lines):
|
||||||
|
if line.startswith("[Window][") and line.rstrip().endswith("]"):
|
||||||
|
block: list[str] = []
|
||||||
|
for next_line in lines[idx + 1:]:
|
||||||
|
if next_line.startswith("[") and "][" in next_line:
|
||||||
|
break
|
||||||
|
block.append(next_line)
|
||||||
|
blocks[line] = block
|
||||||
|
if not blocks:
|
||||||
|
return False
|
||||||
|
has_dockid: bool = True
|
||||||
|
for header, block in blocks.items():
|
||||||
|
if not any("DockId=" in bl for bl in block):
|
||||||
|
has_dockid = False
|
||||||
|
break
|
||||||
|
return has_dockid
|
||||||
|
|
||||||
|
|
||||||
|
def _has_no_stale_window_names(text: str) -> bool:
|
||||||
|
stale: set[str] = {
|
||||||
|
"Projects", "Files", "Screenshots", "Discussion History",
|
||||||
|
"Provider", "Message", "Response", "Tool Calls",
|
||||||
|
"Comms History", "System Prompts",
|
||||||
|
}
|
||||||
|
for line in text.splitlines():
|
||||||
|
if line.startswith("[Window][") and line.rstrip().endswith("]"):
|
||||||
|
name: str = line[len("[Window]["):-1]
|
||||||
|
if name in stale:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def _workspace_for(tmp_path: Path, test_name: str) -> Path:
|
def _workspace_for(tmp_path: Path, test_name: str) -> Path:
|
||||||
@@ -122,8 +165,14 @@ def _assert_installed_default(workspace: Path) -> None:
|
|||||||
assert _has_window_with_collapsed_zero(text), (
|
assert _has_window_with_collapsed_zero(text), (
|
||||||
f"installed INI has no [Window][...] entry; got first 400 chars: {text[:400]!r}"
|
f"installed INI has no [Window][...] entry; got first 400 chars: {text[:400]!r}"
|
||||||
)
|
)
|
||||||
assert _has_no_docking_block(text), (
|
assert _has_docking_block_with_docknodes(text), (
|
||||||
f"installed INI should not contain a [Docking][Data] block (HelloImgui dockspace IDs are session-specific); got first 400 chars: {text[:400]!r}"
|
f"installed INI missing [Docking][Data] block with DockSpace + >=1 DockNode children; got first 400 chars: {text[:400]!r}"
|
||||||
|
)
|
||||||
|
assert _every_window_has_dockid(text), (
|
||||||
|
f"installed INI does not have a DockId= line following every [Window][...] header; got first 400 chars: {text[:400]!r}"
|
||||||
|
)
|
||||||
|
assert _has_no_stale_window_names(text), (
|
||||||
|
f"installed INI contains a window name from _STALE_WINDOW_NAMES -- _diag_layout_state will emit a stale-name warning; got first 400 chars: {text[:400]!r}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user