Repository navigation
Conversation
Local Windows 11 x86_64:
WSL (Linux x86_64) at 602a976:
602a976 fixes the six Not run at 602a976: WSL clippy with no default features, and macOS. Before the merge, at f81762f, macOS The The merge needed two fits to |
[Medium impact] Changes how keyboard, paste, and file drop input queue during frame synchronization gaps. Fix the background paste failure path before merging so a held Enter cannot run without the paste. Findings
SummaryKeys, pastes, and file drops now share a queue while the window waits for its frame.
Diagram%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Key, paste, or file drop] --> B{Frame ready?}
B -->|No| C[Hold input in order]
B -->|Yes| D[Flush held input]
C --> D
D --> E{Delivery result}
E -->|Queued| F[Deliver next held input]
E -->|Copying or refused| G[Discard remaining held input]
F --> H[Background paste can still fail]
Reviews (2) · Last reviewed commit: "fix: hold a paste or file drop until the..." · Reviewed by Greptile |
df12b69 to
f8e299c
Compare
Brings leftos/patches up to PR penso#637 at f8e299c: the review round on "hold a paste or file drop until the window's frame returns". A held paste or drop that is refused, starts a remote file copy, or is refused at the cap ends the batch, and the input held after it is discarded with its count. A held paste delivered while a menu is open is refused with a reason, and a live paste or drop sends held input before itself.
f8e299c to
338e4f1
Compare
| preparing: true, | ||
| _task: task, | ||
| }); | ||
| Delivery::Queued |
There was a problem hiding this comment.
When a user holds an image paste followed by Enter, start_image_preparation returns Delivery::Queued before the background work finishes. flush_pending_input then releases Enter. If preparation fails—for example, a clipboard GIF exceeds the upload limit—the connection skips the empty paste slot and sends Enter without the image.
Keep the remaining held input pending until preparation succeeds, and discard it if preparation fails.
Knowledge Base Used: Input, clipboard, and port forwarding
There was a problem hiding this comment.
🤖 Posted by Claude Code on behalf of @leftos.
Fixed in f81762f. A held delivery that prepares in the background now returns Delivery::Preparing, which stops the flush and keeps the input behind it held. When the paste is queued, that input is flushed in order under the usual frame, focus and menu rules. When preparation fails, times out, is cancelled, or becomes a remote file copy, it is discarded with its count. Input made while waiting joins the back of the queue. window/pending_input/tests/background.rs covers each case, including an SVG image the bridge refuses, and each test failed before the change.
The previous commit let a paste or a file drop take a tab back from another window, but what was pasted or dropped was still thrown away: a window whose frame does not match its size refuses input, and only typed keys were held for later. The first paste or drop in an idle window was lost, and the user had to repeat it. Keys, pastes, and drops now share one hold queue, so they are delivered in the order the user made them once the frame matches. A held paste keeps only the action and reads the clipboard when it is delivered, so no image is kept in memory and nothing is read on the UI thread. A file drop is held for the pane under the pointer, or for the drop point when no frame is shown, which is hit-tested once one arrives. Ctrl-V on a remote pane is held the same way. Held pastes and drops follow the rules of held keys: they are dropped with an error if focus moves first, cleared on reconnect, and capped at four per gap, past which they are refused with an error. A held send that fails now says how many held inputs it discarded. A held paste or drop that is refused, or one that starts a remote file copy whose paths arrive only once it completes, ends the batch: the input held after it is discarded with the count, so a held Enter never runs a command without what was pasted before it. A fifth paste or drop refused at the cap ends the batch the same way. A held paste delivered while a menu is open or a focus click is pending is refused with a reason, and on macOS a held paste always reads the clipboard in the background. A live paste or drop sends held input before itself.
338e4f1 to
f81762f
Compare
…eturns) # Conflicts: # crates/herdr-gpui/src/window/file_drop.rs # crates/herdr-gpui/src/window/pending_input.rs
…l-frame # Conflicts: # crates/herdr-gpui/src/window/file_drop.rs # crates/herdr-gpui/src/window/pending_input.rs
The merge of upstream main brought tests that still read paste_files as a bool; it now returns Delivery, so they compare against Refused.
Since the metadata-update change on main, a newer snapshot that keeps the same focus and changes only metadata keeps input flowing, so the held-paste tests that opened their gap that way never saw input pause and timed out on every Unix CI job. The gap's snapshot now also republishes the host's key bindings, which still holds input until the matching surface arrives.
Summary
Follow-up to #582. That PR's description covers this change, but the commit reached its branch after the merge, so it never landed on
main.A window whose frame does not match its size (another client sized the tab) refuses input until its own frame returns. #582 made a paste or a file drop take the tab back. But only typed keys were held while the window waited, so the first paste or drop in an idle window was thrown away and the user had to repeat it.
Keys, pastes, and drops now share one hold queue (
window/pending_input.rs) and are delivered in the order the user made them once the frame matches.Delivery:Queued,Copying,Refused). Anything butQueuedends the batch, and the input held after it is discarded with its count, so a held Enter never runs a command without what was pasted or dropped before it. That covers:Known limitation: on macOS, Cmd-V of files copied in Finder onto a remote pane resolves in the background after its slot is reserved, so a copy it starts cannot stop keys already delivered behind it.
Validation
At f81762f, on
mainat 7c64479:check-commits(upstream/main..HEAD): passedjust cion Windows 11 x86_64:format-check,check-file-size,check-sorted,lint(all features and no default features),test(default and all features; herdr-gpui 3709 and 3752 passed, 0 failed) passed.test-mockup-waitfailed: that is the Windows-only failure intest_wait.py, and this PR touches nothing it covers.cfg(unix)lifecycle tests,held_pasteamong them, which Windows does not build.cargo clippy --workspace --all-targets -D warnings, all features and no default features: passed (all features re-run after the last change).cargo test --workspace, default and all features, before the last change: the only failure wasorchestrator::tests::service::the_worker_shows_runs_another_application_writes, a snapshot wait that timed out under load in code this PR does not touch; it passes run alone. After the last change,window::pending_inputandlifecycle_tests::held_paste: 26 passed, 0 failed.cargo test -p herdr-gpuioverwindow::pending_input,lifecycle_tests::held_paste,window::imagesandwindow::file_drop: 36 passed, 0 failed. This found the cap-mark case above before the last change.window/pending_input/tests/background.rstests for a held input behind a preparing paste, and the one for input after a refused cap mark, failed before their changes.endpoint::lifecycle_tests::held_pastetests failed before the change (nothing was held).window/pending_input/tests.rsbuilds and runs on Windows too. Its tests failed before their fixes: a key held after a refused drop, a key held after a remote copy, a paste refused while a menu is open, a fifth paste refused at the cap, a live drop and a live paste after held keys, and live-drop focus. The red runs were shown by mutation for the fixes written before their tests.Manual QA
cat, drop two files, press Enter, then let the tab come back. The paths are not followed by a stray Enter, and the status says the held input was discarded while the files copy.