docs(gui_2): add Theme Color-Callable Pattern and Workspace Profile Defer-Not-Catch sections
This commit is contained in:
@@ -386,6 +386,39 @@ client.push_event("custom_callback", {"callback": "_my_method", "args": []})
|
||||
value = client.get_value("show_my_thing")
|
||||
```
|
||||
|
||||
### Theme Color-Callable Pattern
|
||||
|
||||
Theme color helpers in `src/theme_2.py` (`C_LBL`, `C_VAL`, `C_OUT`, `C_IN`, `C_OK`, `C_ERR`, etc.) are **callable functions, not `ImVec4` values**. This is intentional: it lets the active theme be swapped at runtime and have the new colors take effect on the next render frame, instead of capturing stale colors at module import time.
|
||||
|
||||
**Correct usage** — call the function at the use site:
|
||||
```python
|
||||
imgui.text_colored(C_LBL(), "Completed:")
|
||||
imgui.text_colored(C_VAL(), str(value))
|
||||
```
|
||||
|
||||
**Common bug** — storing the function in a dict keyed by name, then passing the function (not its result) to `imgui.text_colored`:
|
||||
```python
|
||||
DIR_COLORS = {
|
||||
"request": C_OUT,
|
||||
"response": C_IN,
|
||||
}
|
||||
# ... later ...
|
||||
d_col_fn = DIR_COLORS.get(direction, C_VAL) # WRONG: stores the function
|
||||
imgui.text_colored(d_col_fn(), direction) # CORRECT: calls it
|
||||
```
|
||||
|
||||
This pattern is used in `src/gui_2.py:3705-3707` (the `render_comms_history_panel` `DIR_COLORS`/`KIND_COLORS` dicts). The bug shipped in the multi-themes track commit `7ea52cbb` and was caught by `1469ecac` — `imgui.text_colored` was being passed a callable instead of an `ImVec4`, raising `TypeError` on every render frame.
|
||||
|
||||
When writing tests that assert theme color usage, **patch `src.theme_2.imgui`** so `theme.get_color()` returns the mock's `ImVec4`, and assert with `C_LBL()` (called), not `C_LBL` (the function).
|
||||
|
||||
### Workspace Profile Defer-Not-Catch
|
||||
|
||||
`_capture_workspace_profile` (line 601) calls `imgui.save_ini_settings_to_memory()` to serialize the current ImGui layout. This C function **crashes the Python process with `0xc0000005` access violation** when called in the first few render frames because ImGui's internal state (Fonts, DisplaySize, Settings) isn't yet fully initialized. The crash is **not catchable from Python** — it's a native access violation, not a Python exception.
|
||||
|
||||
The fix uses a **defer-not-catch** pattern: a one-shot `_ini_capture_ready` flag in the instance state. The first call (during initial startup) returns an empty profile and flips the flag; subsequent calls (when the user actually clicks "Save Profile") invoke the C function. The user's workflow is unaffected because the first call is non-blocking and the user cannot have clicked "Save Profile" before the GUI was fully rendered.
|
||||
|
||||
This pattern unblocks 4-5 live_gui tests that were crashing the GUI subprocess during the first render frames after a `save_workspace_profile` Hook API callback. See [guide_testing.md](guide_testing.md#known-gotchas-2026-06-05) for the broader pattern and how to recognize these crashes.
|
||||
|
||||
---
|
||||
|
||||
## See Also
|
||||
@@ -394,4 +427,5 @@ value = client.get_value("show_my_thing")
|
||||
- **[guide_command_palette.md](guide_command_palette.md)** — The 32 commands accessible via Ctrl+Shift+P
|
||||
- **[guide_testing.md](guide_testing.md)** — Test infrastructure for GUI tests
|
||||
- **[guide_hot_reload.md](guide_hot_reload.md)** — How Ctrl+Alt+R reloads this file
|
||||
- **[guide_themes.md](guide_themes.md)** — TOML theme system; defines the `C_*` callable color helpers used throughout `gui_2.py`
|
||||
- **[conductor/product-guidelines.md](../../conductor/product-guidelines.md)** — The UI delegation pattern rules
|
||||
|
||||
Reference in New Issue
Block a user