Goal
Produce docs/BACKEND_SETUP_AUDIT.md documenting the differences between TUI and GTK init code. This is the diagnostic step that informs the runner-crate API in B.5e — don't start B.5e without it.
Compare
- Event source. TUI: crossterm
event::read() blocking, wait_events queue. GTK: Relm4 widget signal callbacks, glib::timeout_add_local drain.
- Backend impl construction. TUI:
TuiBackend::new() in main, threading model TBD. GTK: GtkBackend::new() then wrapped in Rc<RefCell<>> shared with widget callbacks.
- Frame loop. TUI:
terminal.draw(|f| ...) synchronous. GTK: set_draw_func(da, |da, cr, _, _| ...) callback, fires when GTK queues a redraw.
- Native services. Clipboard (copypasta vs gtk4::Clipboard); file dialogs (TUI does inline, GTK uses native); URL opening (cross-platform crate).
- Per-backend signal-callback boilerplate. Every
connect_* in src/gtk/mod.rs::App::init() (key, mouse, scroll, resize, drag, gestures); every match crossterm_event arm in src/tui_main/mod.rs::event_loop().
- App-level state ownership. TUI:
Engine plus a few flags lives directly in event_loop. GTK: App struct has 80+ fields, half of them widget refs, half of them rendering caches.
- Cross-backend abstractions already in place.
Backend trait, ModalStack, DragState, dispatch_mouse_*, accelerator registry. What's NOT in place that would need to be for the runner.
Output
docs/BACKEND_SETUP_AUDIT.md — the comparison.
- A sketch of the runner-crate API for B.5e (e.g.
quadraui_tui::run<App: AppLogic>(...) signature). Ballpark target:
struct MyApp { /* state */ }
impl quadraui::AppLogic for MyApp {
fn render(&self, ctx: &mut RenderCtx) { /* paint */ }
fn handle(&mut self, event: UiEvent) -> Reaction { /* dispatch */ }
}
fn main() {
let app = MyApp::new();
#[cfg(feature = "gui")] quadraui_gtk::run(app);
#[cfg(feature = "tui")] quadraui_tui::run(app);
}
The audit decides what RenderCtx looks like, what Reaction carries, what callbacks AppLogic actually needs.
Pickup files
src/tui_main/mod.rs — run(), event_loop().
src/gtk/mod.rs — App::init(), the entire view!{} block.
src/main.rs — where the binaries dispatch to backend.
examples/ — if there are existing minimal apps already on quadraui (kubeui).
Depends on
- #B5c (the trait must be 100% before the audit; otherwise the audit's "what does the runner need" answer points at gaps that B.5c is going to fill).
PLAN.md "🎯 NEXT FOCUS" section has the full context.
Goal
Produce
docs/BACKEND_SETUP_AUDIT.mddocumenting the differences between TUI and GTK init code. This is the diagnostic step that informs the runner-crate API in B.5e — don't start B.5e without it.Compare
event::read()blocking,wait_eventsqueue. GTK: Relm4 widget signal callbacks,glib::timeout_add_localdrain.TuiBackend::new()in main, threading model TBD. GTK:GtkBackend::new()then wrapped inRc<RefCell<>>shared with widget callbacks.terminal.draw(|f| ...)synchronous. GTK:set_draw_func(da, |da, cr, _, _| ...)callback, fires when GTK queues a redraw.connect_*insrc/gtk/mod.rs::App::init()(key, mouse, scroll, resize, drag, gestures); everymatch crossterm_eventarm insrc/tui_main/mod.rs::event_loop().Engineplus a few flags lives directly inevent_loop. GTK:Appstruct has 80+ fields, half of them widget refs, half of them rendering caches.Backendtrait,ModalStack,DragState,dispatch_mouse_*, accelerator registry. What's NOT in place that would need to be for the runner.Output
docs/BACKEND_SETUP_AUDIT.md— the comparison.quadraui_tui::run<App: AppLogic>(...)signature). Ballpark target:The audit decides what
RenderCtxlooks like, whatReactioncarries, what callbacksAppLogicactually needs.Pickup files
src/tui_main/mod.rs—run(),event_loop().src/gtk/mod.rs—App::init(), the entireview!{}block.src/main.rs— where the binaries dispatch to backend.examples/— if there are existing minimal apps already on quadraui (kubeui).Depends on
PLAN.md "🎯 NEXT FOCUS" section has the full context.