Skip to content

#600: #595 Stage 1 — TUI paint centralization: route rasteriser calls through Backend::draw_*, collapse enter_frame_scope - #606

Merged
JDonaghy merged 2 commits into
developfrom
issue-600-595-stage-1-tui-paint-centralization-rou
Jul 23, 2026
Merged

#600: #595 Stage 1 — TUI paint centralization: route rasteriser calls through Backend::draw_*, collapse enter_frame_scope#606
JDonaghy merged 2 commits into
developfrom
issue-600-595-stage-1-tui-paint-centralization-rou

Conversation

@JDonaghy

Copy link
Copy Markdown
Owner

Closes #600

Automated merge from the coordinator for assignment 131d9772692e on issue #600.

Worker branch: issue-600-595-stage-1-tui-paint-centralization-roudevelop.

JDonaghy and others added 2 commits July 23, 2026 16:27
Pure threading refactor toward #595's ShellApp migration (Stage 1 of the
staged plan): no behavior/visual change, verified by the existing
snapshot/render test suite staying green.

1. Convert ~13 free-rasteriser call sites (draw_editor, draw_toast_stack,
   draw_drop_overlay, draw_tooltip x3, draw_dialog x2, draw_context_menu,
   draw_find_replace, draw_command_center, draw_completions,
   draw_rich_text_popup x2) in render_impl.rs/panels.rs onto their existing
   Backend::draw_* trait equivalents -- same underlying quadraui rasteriser
   either way, just reachable through &mut dyn Backend now. draw_activity_bar
   and draw_message_list are left as free-function calls: their trait
   counterparts use self.current_theme/derived colors and (for
   draw_activity_bar) a keyboard-focus side effect that don't match these
   call sites' bespoke color overrides -- converting them would be a real
   behavior change, not a mechanical swap.

2. Collapse the ~30 backend.enter_frame_scope()/set_current_theme() call
   sites scattered across render_impl.rs + panels.rs down to exactly one
   entry per draw closure, per the issue's acceptance bar. mod.rs's two
   event_loop() terminal.draw(|frame| ...) closures now each make a single
   call via a new with_frame_scope() helper, which relays `frame` into the
   enter_frame_scope closure through a raw pointer -- the same type-erasure
   technique TuiBackend::enter_frame_scope already uses internally,
   applied one layer up so the closure can reach both `backend` and `frame`
   at once (Rust's borrow checker otherwise rejects a closure that both
   captures the outer `frame` binding and receives it as enter_frame_scope's
   own sibling argument -- E0382). This preserves the exact current
   interleaved paint order (several raw buffer writes read/depend on
   what a preceding Backend::draw_* call already painted) with zero risk
   of a reorder-induced z-order regression.

   draw_frame and its helpers (render_window, render_tab_bar,
   draw_breadcrumb_bar, render_source_control, render_debug_sidebar, etc.)
   now call backend.draw_*() directly instead of re-entering their own
   scope; several helpers that no longer touch `frame` at all had that
   parameter dropped (render_search_panel, render_debug_sidebar,
   render_tab_bar, draw_breadcrumb_bar, render_picker_popup,
   render_window_status_line, render_bottom_panel_tabs,
   render_quickfix_panel, render_terminal_toolbar). Two in-crate test
   harnesses (render_impl.rs's render_tui/render_tui_buffer,
   panels.rs's sc_panel_tests::render_sc) that called draw_frame /
   render_source_control directly now wrap those calls in
   with_frame_scope too, since the callees no longer open their own scope.

   quadraui_tui.rs's now-dead draw_context_menu/draw_completions/
   draw_dialog/draw_tooltip/draw_find_replace/draw_rich_text_popup wrapper
   functions are removed; draw_activity_bar (still needed) and q_theme
   remain.

Refs GOALS.md / PLAN.md Stage 1; unblocks Stage 2 (wiring
TuiShellApp::render_content to this now-portable paint path).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
render_sidebar's default (file-explorer) branch was still opening its own
enter_frame_scope, nesting inside the single with_frame_scope now owned by
the draw_frame caller (mod.rs's terminal.draw closures). Functionally
harmless (current_frame_ptr round-trips to the same value) but it violated
the Stage 1 "entered once per draw closure" invariant and was the one
panel branch left in the old shape after the sibling panels
(search/debug/source-control/ext) were converted to call
.render(backend, q_rect) directly.

Also documents the two non-blocking draw_settings_chrome/
draw_terminal_divider call sites as intentionally out of scope (no
Backend::draw_* trait equivalent exists), matching the existing
draw_activity_bar doc-comment convention, per reviewer suggestion.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

#595 Stage 1 — TUI paint centralization: route rasteriser calls through Backend::draw_*, collapse enter_frame_scope

1 participant