Skip to content

Phase B.5e followup — quadraui::tui::run runner (after backend lift) #269

Description

@JDonaghy

Goal

Ship `quadraui::tui::run<A: AppLogic>(app)` — the actual TUI runner, blocked on the `TuiBackend` lift.

Scope

```rust
// quadraui/src/tui/run.rs
pub fn run<A: AppLogic>(mut app: A) -> std::io::Result<()> {
// 1. Terminal init: enable_raw_mode, EnterAlternateScreen,
// EnableMouseCapture, EnableBracketedPaste,
// PushKeyboardEnhancementFlags (best-effort).
//
// 2. Construct Terminal<CrosstermBackend> and TuiBackend.
//
// 3. Install panic hook (write crash info to a known path; emergency
// swap-flush hook is app-side, not runner-side — runner doesn't
// know about engine swap files).
//
// 4. app.setup(&mut backend).
//
// 5. Loop:
// - terminal.draw(|f| backend.enter_frame_scope(f, |b| app.render(b)))
// - for event in backend.wait_events(timeout): match app.handle(event, &mut backend) {
// Reaction::Continue => {},
// Reaction::Redraw => needs_redraw = true,
// Reaction::Exit => return,
// }
//
// 6. Tear-down: pop kbd flags, disable raw mode, leave alternate screen,
// show cursor.
}
```

Open design questions surfaced during the audit (#260):

  • How does the app communicate "needs redraw" between event handlers? `Reaction::Redraw` covers per-event; a handler that mutates state mid-frame needs a different path.
  • Should the runner take a `RunnerOptions` struct (enable mouse?, kitty kbd protocol?, panic hook path?) or sensible defaults only?
  • Single-DrawingArea / single-Frame scope — multi-area apps (vimcode) need a richer shape, separately filed.

Migration target

After this lands, kubeui's `main` collapses from ~200 lines to ~20:

```rust
struct KubeApp { state: AppState, rt: tokio::runtime::Runtime }

impl quadraui::AppLogic for KubeApp {
fn render(&self, backend: &mut dyn Backend) { /* paint primitives via backend / }
fn handle(&mut self, ev: UiEvent, _b: &mut dyn Backend) -> Reaction { /
... */ }
}

fn main() -> Result<()> {
kubeui_core::install_crypto_provider()?;
let rt = tokio::runtime::Runtime::new()?;
let state = bootstrap_state(&rt);
quadraui::tui::run(KubeApp { state, rt }).map_err(Into::into)
}
```

Depends on

  • Lift TuiBackend into quadraui::tui (separate stage, filed alongside this).

Surfaced during

#261 stage A — trait design landed; runner blocked on the lift.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions