Repository navigation
perf(desktop-gpui): read and decode the screenshot clipboard image off the UI thread - #2756
Open
celeroncoder wants to merge 1 commit into
Open
celeroncoder wants to merge 1 commit into
celeroncoder wants to merge 1 commit into
Conversation
Contributor
|
@celeroncoder is attempting to deploy a commit to the Cap Software Inc Team on Vercel. A member of the Team first needs to authorize it. |
Contributor
Author
|
cc @richiemcilroy for review (GitHub doesn't let a fork request reviewers, so tagging instead). |
celeroncoder
marked this pull request as ready for review
October 20, 2026 12:27
Comment on lines
+565
to
+574
| cx.spawn(async move |cx| { | ||
| let image = cx | ||
| .background_executor() | ||
| .spawn(async move { | ||
| let bytes = std::fs::read(&path) | ||
| .map_err(|error| format!("Could not read the clipboard image: {error}"))?; | ||
| prepare_clipboard_image(bytes) | ||
| }) | ||
| .await?; | ||
| cx.update(|cx| write_clipboard_image(image, cx)) |
Contributor
There was a problem hiding this comment.
Older copies replace newer ones
copy_image_to_clipboard now writes in the order background work finishes, not the order users click Copy. The library leaves its Copy buttons active and detaches every request. If a user copies a large screenshot and then a smaller one while the first is still preparing, the older request can finish last and replace the newer image. Track request order and skip stale writes, or queue the copies so an older request cannot overwrite a newer one.
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop-gpui/src/platform.rs
Line: 565-574
Comment:
**Older copies replace newer ones**
`copy_image_to_clipboard` now writes in the order background work finishes, not the order users click Copy. The library leaves its Copy buttons active and detaches every request. If a user copies a large screenshot and then a smaller one while the first is still preparing, the older request can finish last and replace the newer image. Track request order and skip stale writes, or queue the copies so an older request cannot overwrite a newer one.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
After a screenshot,
screenshot_finishedcopied the image to the clipboard on the UI thread:std::fs::readof the full-resolution PNG (tens of MB on a Retina display), then per platform the clipboard conversion, right when the tray, library and editor are also refreshing. On Linux that was a format sniff,bytes.to_vec(), a content hash and another clone insideClipboardItem::new_image; on Windows a fullRustImageData::from_bytesdecode; on macOSNSData+NSImage+ the pasteboard write.Change
copy_image_to_clipboard(path, cx)now returns aTask: the file read andprepare_clipboard_imagerun on the background executor, and onlywrite_clipboard_imageruns on the UI thread. Each platform module exports the same three items (ClipboardImage,prepare_clipboard_image,write_clipboard_image):ClipboardItemfrom the owned bytes (noto_vec(), nonew_imageclone; the hash runs in the background). Write istry_write_to_clipboard.RustImageData::from_bytesdecode in the background (RustImageDatais{u32, u32, Option<DynamicImage>}, so it isSend).ClipboardContext::newandset_imagestay on the UI thread.NSData,NSImageand the pasteboard write stay on the main thread, same body as before.Error strings are unchanged. The same treatment is applied to the library "Copy" action, the settings "Copy" action and the editor's export-to-clipboard; the editor's success toast still fires only after the write succeeds. Nothing after
screenshot_finishedreads the clipboard, so the only observable change is that the clipboard is populated a few milliseconds after the editor opens instead of before.Results
Linux, debug build (dependencies at opt-level 2), synthetic 5120×2880 PNG of 27.8 MB, medians of 5 runs, 2 vCPU aarch64 Linux box.
main@ 2a61427The
try_write_to_clipboardcall itself is unchanged and not included. On Windows,set_imagestill re-encodes to PNG and BMP on the UI thread; that is the largest remaining cost there and is out of scope here. macOS keeps its AppKit main-thread work by design.Overlap
screenshot_editor.rs/app_windows.rs; both apply cleanly on top of this branch. perf(desktop-gpui): encode screenshot save and copy with the parallel PNG writer #2717 (open, parallel PNG writer) speeds up the encode half of copy inkernels/and doesn't overlap.src-tauri/automation.rs); same domain, no shared code.main.main.How this was made
This PR is agent-generated.
mainby OpenCode scouts and Gemini 3.8 Flash, re-checked against the source by the orchestrating Claude session.main, checkedclipboard_rsforSend, and took the Linux measurement above.Sendbounds from theclipboard_rsand gpui sources, the identical signatures across the three platform modules, that every task is detached and every toast fires after the write, re-rancargo check, clippy and theplatform::tests on Linux, and approved. Neither agent had a macOS or Windows machine to build on.🤖 Generated with Claude Code
Fix clipboard request ordering before merging so users reliably paste the screenshot they copied last.
Findings
Fix with agent prompt
Summary
Moves screenshot file reads and image preparation off the UI thread.
Reviews (1) · Last reviewed commit: "perf(desktop-gpui): read and decode the ..." · Reviewed by Greptile