Cache TUI flex heights across frame passes (#34348)

## Why

Sizing, rendering, and cursor placement can query the same chat widget layout
multiple times in one frame, repeatedly measuring active transcript cells.

## What changed

- Build one chat widget renderable tree per frame and reuse it for sizing,
  rendering, and cursor placement.
- Cache each flex child's desired height by width for the lifetime of that tree.
- Reuse the bottom pane's renderable directly instead of forwarding each
  renderable operation through a wrapper.

## Testing

- Verify flex layouts measure a child once across frame passes and remeasure it
  when the width changes.
- Verify a chat widget frame measures its active transcript cell once.

GitOrigin-RevId: 5ad1a6711f4011c699b5d002b13dc3319cb4db8e
This commit is contained in:
Charlie Marsh authored and copyberry committed 2026-07-20 13:58:17 +00:00
1 parent ada5a79ddf
commit eceb3eeaf3
7 files changed
+141 -90

No files matched your search

+1 -38
View File
@@ -1692,7 +1692,7 @@ impl BottomPane {
self.as_renderable_with_composer_right_reserve(/*composer_right_reserve*/ 0)
}
fn as_renderable_with_composer_right_reserve(
pub(crate) fn as_renderable_with_composer_right_reserve(
&'_ self,
composer_right_reserve: u16,
) -> RenderableItem<'_> {
@@ -1750,43 +1750,6 @@ impl BottomPane {
}
}
pub(crate) fn render_with_composer_right_reserve(
&self,
area: Rect,
buf: &mut Buffer,
composer_right_reserve: u16,
) {
self.as_renderable_with_composer_right_reserve(composer_right_reserve)
.render(area, buf);
}
pub(crate) fn desired_height_with_composer_right_reserve(
&self,
width: u16,
composer_right_reserve: u16,
) -> u16 {
self.as_renderable_with_composer_right_reserve(composer_right_reserve)
.desired_height(width)
}
pub(crate) fn cursor_pos_with_composer_right_reserve(
&self,
area: Rect,
composer_right_reserve: u16,
) -> Option<(u16, u16)> {
self.as_renderable_with_composer_right_reserve(composer_right_reserve)
.cursor_pos(area)
}
pub(crate) fn cursor_style_with_composer_right_reserve(
&self,
area: Rect,
composer_right_reserve: u16,
) -> crossterm::cursor::SetCursorStyle {
self.as_renderable_with_composer_right_reserve(composer_right_reserve)
.cursor_style(area)
}
pub(crate) fn set_status_line(&mut self, status_line: Option<Line<'static>>) {
if self.composer.set_status_line(status_line) {
self.request_redraw();