Problem
draw() requires FnOnce + 'static (container.rs:1183):
pub fn draw(self, f: impl FnOnce(&mut Buffer, Rect) + 'static)
This forces users to .clone() all captured state every frame, since local borrows can't satisfy 'static. For data-dense UIs (e.g., a 12×16 step grid), this means cloning the entire pattern state into the closure 60 times per second.
Root Cause
The closure is stored in ctx.deferred_draws as Box<dyn FnOnce(&mut Buffer, Rect)>, executed after the UI closure returns during run_frame_kernel (lib.rs:1073-1089). Since it runs after the UI closure's stack frame is gone, it can't borrow from it.
However, the closures are consumed within the same run_frame_kernel call (line 1078: c.take() followed by cb(buffer, rdr.rect)). They never escape the function.
Proposed Solution
A frame-scoped lifetime bound instead of 'static:
pub fn draw<'frame>(self, f: impl FnOnce(&mut Buffer, Rect) + 'frame)
This would require architectural changes to the command/layout pipeline to support bounded lifetimes on stored closures, but would dramatically improve ergonomics for custom drawing.
Alternative: draw_ref()
A simpler short-term fix: add a draw_ref() that executes the closure immediately during the command-building phase (before layout), writing to a temporary buffer that gets composited during layout. This avoids the deferred execution entirely:
pub fn draw_ref(self, f: impl FnOnce(&mut Buffer, Rect)) // no 'static needed
Source Reference
container.rs:1183 — draw() signature with 'static
core.rs:44 — deferred_draws: Vec<Option<RawDrawCallback>>
lib.rs:1073-1089 — deferred draw execution
Problem
draw()requiresFnOnce + 'static(container.rs:1183):This forces users to
.clone()all captured state every frame, since local borrows can't satisfy'static. For data-dense UIs (e.g., a 12×16 step grid), this means cloning the entire pattern state into the closure 60 times per second.Root Cause
The closure is stored in
ctx.deferred_drawsasBox<dyn FnOnce(&mut Buffer, Rect)>, executed after the UI closure returns duringrun_frame_kernel(lib.rs:1073-1089). Since it runs after the UI closure's stack frame is gone, it can't borrow from it.However, the closures are consumed within the same
run_frame_kernelcall (line 1078:c.take()followed bycb(buffer, rdr.rect)). They never escape the function.Proposed Solution
A frame-scoped lifetime bound instead of
'static:This would require architectural changes to the command/layout pipeline to support bounded lifetimes on stored closures, but would dramatically improve ergonomics for custom drawing.
Alternative:
draw_ref()A simpler short-term fix: add a
draw_ref()that executes the closure immediately during the command-building phase (before layout), writing to a temporary buffer that gets composited during layout. This avoids the deferred execution entirely:Source Reference
container.rs:1183—draw()signature with'staticcore.rs:44—deferred_draws: Vec<Option<RawDrawCallback>>lib.rs:1073-1089— deferred draw execution