Skip to content

Wire toast rendering + click dispatch in GTK backend #454

Description

@JDonaghy

Background

#450 added toast infrastructure (engine queue, render adapter, click dispatch). TUI is fully wired (render in tui_main/render_impl.rs::draw_frame, mouse-down hit-test in tui_main/mouse.rs). GTK is not — toasts pushed via :Toast or any future producer simply don't appear.

What's already shared (no work needed)

  • Engine.toasts queue + push_toast / prune_toasts / handle_toast_hit / dismiss_toast_by_widget in src/core/engine/mod.rs.
  • Engine.toast_layout cache field (RefCell<Option<ToastStackLayout>>).
  • render::build_toast_stack(engine) -> Option<quadraui::ToastStack> adapter.
  • quadraui::gtk::draw_toast_stack rasteriser (exists in quadraui).
  • ToastStackLayout::hit_test(x, y) -> ToastHit — backend-agnostic shared dispatch.

What needs adding (per the same pattern TUI uses)

1. Render

In src/gtk/draw.rs (the cairo paint closure), after every other surface is drawn:

if let Some(stack) = crate::render::build_toast_stack(engine) {
    let q_theme = /* ...convert theme to quadraui::Theme... */;
    let area = /* full canvas rect in DIPs */;
    let layout = quadraui::gtk::draw_toast_stack(cr, area, &stack, &q_theme);
    engine.toast_layout.replace(Some(layout));
} else {
    engine.toast_layout.replace(None);
}

2. Click

In the GTK left-mouse-down dispatcher (src/gtk/mod.rs somewhere — see how completion / context-menu hits are dispatched), before any underlying handler:

let toast_hit = self.engine.borrow()
    .toast_layout.borrow()
    .as_ref()
    .map(|l| l.hit_test(x as f32, y as f32));
if let Some(hit) = toast_hit {
    if self.engine.borrow_mut().handle_toast_hit(hit) {
        self.draw_needed.set(true);
        return;
    }
}

Test plan

  • :Toast hello from inside GTK vimcode → expect a toast in the bottom-right corner.
  • Click the × → toast dismisses.
  • Push multiple via :Toast a, :Toast b, etc. → all stack visibly, each individually dismissible.
  • Wait 5s without interaction → toasts auto-dismiss (existing prune_toasts in poll_idle).

Why deferred

#450 was developed on a TUI-only server. Wiring GTK without smoke-testing risked landing broken code. The TUI-only landing kept the change set small and verifiable. The GTK wiring is mechanical (~15 lines total) and matches the exact pattern of CompletionsLayout / ContextMenuLayout that already exist in the GTK backend.

Update (diagnostic session, 2026-07-11) — completed work found orphaned, do NOT redo from scratch

A prior work assignment (ac75ad009663, machine precision, 2026-05-31) actually finished this and posted a "done" completion comment below, but no PR was ever opened and the assignment record has since aged out of the coordinator DB. The issue fell back to Backlog with no active work/test/review assignment, which is why it stalled — not a code problem.

The branch is still there and still looks landable:

  • Branch: issue-454-wire-toast-rendering-click-dispatch-in-g (pushed to origin, never merged, no PR).
  • Commit: 9793a48 — "feat(gtk): wire toast rendering + click dispatch (Wire toast rendering + click dispatch in GTK backend #454)". Implements exactly the render + click wiring described above, plus a few incidental quadraui API-compat fixes it needed at the time (dispatch_click gained a &[TextRegion] arg, Dialog::layout gained a measure_toolbar_item closure, DialogInput became an enum, ListView gained h_scroll/max_content_width).
  • git merge-tree against current develop (branch is 65 commits behind) → zero conflicts.
  • The quadraui APIs the commit touches (draw_toast_stack, dispatch_click, Dialog::layout) still match current quadraui signatures as of quadraui HEAD 85a922c (2026-07-10), despite quadraui having moved substantially since May 30.
  • Toast engine infra (Engine.toasts, toast_layout, handle_toast_hit) is unchanged in current develop.

Next session should: check out issue-454-wire-toast-rendering-click-dispatch-in-g, rebase/merge onto current develop, run the full quality-check suite (cargo build, cargo test --no-default-features, cargo clippy -- -D warnings, cargo fmt) to confirm it still builds clean against the current quadraui checkout, run the test plan above, then open the PR that never got opened. This should be materially faster than reimplementing — the design and code are already correct, this is a verify-and-land pass.

Still on the critical path for milestone #7 (Platform-Neutral) per GOALS.md — confirmed still needed, not stale scope.

Update (chat session #676, 2026-07-11) — correction: a straight rebase is NOT conflict-free; two of five compat hunks in the old commit are now obsolete/superseded

Re-verified with a fresh git merge-tree (read-only) against current origin/develop (branch is now
73 commits behind, not 65 — develop moved on since the note above was written). This is not
conflict-free
: src/render.rs and src/tui_main/render_impl.rs both genuinely conflict, because
quadraui::ListView/Dialog gained more fields since May 30 (show_v_scrollbar, table) on top
of what the old commit already knew about, and render_impl.rs's manual dialog-layout computation
was superseded entirely by a new shared render::dialog_generic_layout() helper. Neither of those
two files has anything toast-specific in it, though — the old commit's changes there were purely
"quadraui API compat shims" needed to build back in May, and both files' relevant shims are either
already applied verbatim elsewhere on develop, or moot because the call site changed shape.

Only two hunks are genuinely new and still missing from develop (confirmed via direct diff of
commit 9793a48 against its parent):

  1. src/gtk/draw.rs — the toast-overlay draw block in draw_editor (~19 lines), inserted right
    before the // Cache the ScreenLayout for click handlers (#344) comment.
  2. src/gtk/mod.rs — the toast hit-dispatch block in handle_mouse_click_msg (~19 lines), inserted
    right after self.reconcile_editor_hover_modal(); and before the // ── Scroll-surface click dispatch comment. Both anchor points confirmed structurally unchanged on current develop.

Revised recommendation: don't rebase the branch as-is (it'll conflict on the two compat-shim
files above, which don't need to be touched at all for this issue). Instead reset the branch to
current develop and insert only the two toast hunks. Full step-by-step instructions (exact
anchors + verbatim code) are in /tmp/rework-briefing-454.md on the elitebook machine, authored
during this chat session. Next step: coord assign elitebook vimcode 454 --rework-of issue-454-wire-toast-rendering-click-dispatch-in-g --interactive --briefing-file /tmp/rework-briefing-454.md.

Sibling issue #459 (context-menu ModalStack migration) was found in the identical orphaned-branch
situation from the same May 30 session, with the same "some compat shims already superseded"
pattern — see that issue for its own rework plan.

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

    coordTracked by coord-tui pipelineenhancementNew feature or requestplatformPlatform-specific (macOS, Windows, Linux)status:readyRefined and ready to enter the work pipelineuiUI/rendering

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions