Files
manual_slop/docs/superpowers/specs/2026-05-11-imgui-context-managers-design.md
T

3.1 KiB

ImGui Context Manager Suite Design

Status

Proposed — 2026-05-11

Context

The src/gui_2.py file contains ~50 imgui.begin() / imgui.end() pairs scattered across 5900+ lines. Dear PyGui (and ImGui) uses a procedural API where every begin_X() requires a matching end_X(). This creates two problems:

  1. Error-prone for AI agents — forgetting an end() call causes UI nesting bugs that are hard to trace
  2. Visual sprawl — the begin/end pairing is separated by potentially hundreds of lines, making scope boundaries unclear

Decision

Implement a context manager suite that pairs begin and end calls on the same line using Python's with statement.

Implementation

Core Base Class

class ImGuiScope:
    def __init__(self, begin_fn, end_fn, *args, **kwargs):
        self._begin_fn = begin_fn
        self._end_fn = end_fn
        self._args = args
        self._kwargs = kwargs
        self._opened = None
        self._entered = False

    def __enter__(self):
        result = self._begin_fn(*self._args, **self._kwargs)
        if isinstance(result, tuple):
            self._opened = result[0]
        else:
            self._opened = result
        self._entered = bool(self._opened)
        return self._opened

    def __exit__(self, *args):
        if self._entered:
            self._end_fn()
        return False

Scope Helpers

Function Wraps Signature
imgui_window(name, visible=True, flags=0) imgui.begin __enter__ returns opened bool
imgui_table(name, columns, flags=0) imgui.begin_table __enter__ returns opened bool
imgui_menu_bar() imgui.begin_menu_bar No args
imgui_menu(label) imgui.begin_menu __enter__ returns opened bool
imgui_child(id, width=0, height=0, flags=0) imgui.begin_child __enter__ returns opened bool
imgui_group() imgui.begin_group No args
imgui_popup(id) imgui.begin_popup __enter__ returns opened bool
imgui_tooltip() imgui.begin_tooltip No args
imgui_clipper(count) clipper.begin __enter__ returns opened count
node_editor_scope(name) ed.begin __enter__ returns opened bool

Usage Pattern

# Before
exp, opened = imgui.begin("AI Settings", self.show_windows["AI Settings"])
if exp:
    imgui.text("Settings")
    imgui.separator()
    # ... 50 more lines ...
    imgui.end()

# After
if imgui_window("AI Settings", self.show_windows["AI Settings"], flags):
    imgui.text("Settings")
    imgui.separator()
    # ... 50 more lines ...
# imgui.end() called automatically

File Location

src/imgui_scopes.py

Migration Strategy

  1. New code MUST use context managers
  2. Existing code migrates incrementally during bug fixes and feature work
  3. No强制性 — old begin()/end() calls remain valid

Consequences

  • Reduced scope pairing errors
  • Improved code legibility for AI agents
  • Slight line count reduction (one imgui.end() line saved per scope)
  • No runtime performance impact (imperceptible nanoseconds vs C++ binding calls)