Skip to content

Ctrl+V paste silently does nothing on GTK — quadraui swallows the key, vimcode has no ClipboardPaste handler #593

Description

@JDonaghy

Summary

Ctrl+V does nothing on GTK. It doesn't freeze (that was fixed on the #587 branch by d50d624) — it silently no-ops, in every context tested.

Two independent faults compound:

  1. quadraui's runner swallows the key. quadraui/src/gtk/run.rs intercepts Ctrl+V, reads the system clipboard, emits UiEvent::ClipboardPaste(text), and unconditionally returns glib::Propagation::Stop — so the keypress never reaches anything else.
  2. vimcode never handles UiEvent::ClipboardPaste. There is no match arm for it anywhere in src/. The only paste plumbing is vimcode's own Msg::ClipboardPasteToInput (src/gtk/mod.rs:1137, :2137, :7484), fed by an async GDK clipboard read (:2655-2667, :2865) that belongs to the pre-ShellApp Relm4 widget world.

So quadraui hands over an event vimcode ignores, having already consumed the key that vimcode's own path would have needed.

Reproduction (verified interactively, X11 + XTEST)

printf 'PASTED_CLIPBOARD_TEXT' | xclip -selection clipboard
./target/debug/vimcode

Command line: press :, then Ctrl+V, then type LIVE.
Result: command line shows :LIVE. The pasted text is absent. LIVE renders, proving the app is alive and processing input — this is a no-op, not a hang.

Editor, insert mode: press i, then Ctrl+V, then type LIVE.
Result: buffer shows LIVE. Pasted text absent.

Liveness confirmed both times — process in Sl on poll_schedule_timeout (normal GTK idle), window queryable, exits cleanly on SIGTERM.

Relationship to #587

Not a regression from #587's branch. Before d50d624, pasting froze the whole app (fork()-based x11_fork::ClipboardContext deadlocking a multithreaded GTK4 process), so paste never worked either. d50d624 correctly removes the deadlock hazard by using the non-forking X11ClipboardContext directly — it just reveals that the paste path underneath was never wired.

Worth stating plainly so the #587 branch isn't over-credited: "paste no longer freezes" is true; "paste works" is not.

Relationship to #592

Same family. Msg::ClipboardPasteToInput's live producers are GDK-widget callbacks from the Relm4 era, i.e. another orphan of the #540 Relm4→ShellApp migration, the same root cause as #592's 13 dropped overlay fields and #587's unpainted palette. Filed separately because the fix is different: #592 is about paint call sites, this is about an event handler that was never ported.

Suggested fix

Add a UiEvent::ClipboardPaste(text) arm to vimcode's GTK handle that routes to the focused input — command line, find/replace field, tree inline-edit, or the editor buffer — mirroring how TUI treats bracketed paste (TUI gets ClipboardPaste from crossterm for free, which is why paste works there). Routing to the focused input is explicitly the app's job per quadraui's own comment in run.rs.

Then either delete the dead Msg::ClipboardPasteToInput GDK path or reduce it to a thin producer of the same event, so there is one paste route rather than two.

Verification note (superseded — see re-scope below)

No GTK acceptance harness exists yet (quadraui#301 GtkDriver unbuilt), so this needs
live smoke on a display-capable machine (not dellserver). Working loop: set the clipboard
with xclip, drive with xdotool key --clearmodifiers ctrl+v (XTEST — --window is
ignored by GTK4), then type a sentinel string to prove liveness, and screenshot with
import -window.


Found while verifying #587's smoke checklist in a human-attended session on 2026-07-19.


Re-scope 2026-09-01 — unblocked, and the verification plan has changed

The hold is lifted. GOALS.md said to hold this until #592-D landed. #672 closed
2026-08-28 (2505786) and src/gtk/draw.rs is deleted. Nothing gates this issue now.

The "needs live smoke" note above is stale. #646 shipped GtkDriver
(src/gtk/testing.rs), which paints into in-memory Cairo ImageSurfaces and runs
headlessly with no DISPLAY. Per CLAUDE.md, black-box driver coverage is the
acceptance bar and there is no "no harness here" excuse on either backend. Write the
test; do not plan a manual smoke session around a harness that now exists.

The xclip/xdotool loop stays useful for a final on-screen confirmation, but it is no
longer the verification plan and must not be the only evidence.

One correction to the fix section. It proposes deleting or thinning the dead
Msg::ClipboardPasteToInput GDK path. That path's producers are the async GDK clipboard
reads at mod.rs:2655-2667 / :2865, which sit behind self.drawing_area — one of 22
Relm4-era widget handles that are initialised None and assigned nowhere in the
crate
(audited 2026-09-01; see #592's audit comment). So that path is not merely
"orphaned in spirit", it is provably unreachable: there is nothing to thin, only to
delete. Do not attempt to revive it as a producer.

Acceptance criteria

  • Ctrl+V pastes into the command line, the find/replace field, tree inline-edit, and
    the editor buffer on GTK.
  • A UiEvent::ClipboardPaste arm exists in GTK's ShellApp::handle; Msg::ClipboardPasteToInput
    and its dead GDK producers are gone.
  • A GtkDriver black-box test asserts the rendered result of a paste — not that a
    state field was populated (CLAUDE.md rule 1).
  • The PR states the test was verified RED against unfixed develop (rule 2).
  • cargo build && cargo test && cargo clippy -- -D warnings && cargo fmt --check EXIT=0.

Files

  • src/gtk/mod.rs (the UiEvent::ClipboardPaste arm; deletion of Msg::ClipboardPasteToInput
    and its dead GDK producers at :2655-2667 / :2865)
  • src/gtk/testing.rs (GtkDriver coverage)

Overlaps #731 (which deletes the drawing_area handle those dead producers sit behind) and
#734 slice 5 (the clipboard-paste rung of the shared key router). Sequenced ahead of both:
this is the smallest of the three and the only one a user can see.

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

    bugSomething isn't workingcoordTracked by coord-tui pipelinestatus:readyRefined and ready to enter the work pipelineuiUI/rendering

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions