Skip to content

Desktop: Switch to winit clipboard API - #4519

Merged
timon-schelling merged 2 commits into
masterfrom
desktop-winit-clipboard
Sep 15, 2026
Merged

timon-schelling merged 2 commits into
masterfrom
desktop-winit-clipboard

Conversation

@timon-schelling

Copy link
Copy Markdown
Member

Upstream work in rust-windowing/winit#4658 (thanks to @0HyperCube for implementing the x11 backend).
For now pulling this from my winit fork.

@timon-schelling

timon-schelling commented Sep 12, 2026 •

Copy link
Copy Markdown
Member Author

!build desktop (Run ID 34660824992)

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 issues found across 7 files

Confidence score: 2/5

  • desktop/src/app.rs can overwrite the serial for an in-flight paste, causing the first DataTransferReceived event to be ignored and silently dropping user data; track each concurrent paste request independently.
  • desktop/src/app.rs leaves pending_clipboard_fetch or pending_dnd_fetch set when no matching DataTransferReceived arrives, leaving the UI waiting indefinitely; add an error, timeout, or cleanup path for missing serials.
  • Cargo.toml routes the workspace’s core winit dependency through an unpinned personal fork branch, creating supply-chain and reproducibility risk; use a trusted upstream release or pin a reviewed commit.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="Cargo.toml">

<violation number="1" location="Cargo.toml:263">
P2: This patch routes the entire workspace's `winit` dependency (version 0.31.0-beta.2) through an unpinned personal git fork branch, which is a supply-chain and reproducibility concern for a core dependency. Unlike the adjacent `rfd` patch, this line has no comment or removal plan referencing the upstream winit clipboard work (winit PR #4658) that will let it be dropped once a release ships. Because only `branch = "graphite"` is specified without a `rev`, any force-push/rewrite of that branch breaks every downstream Cargo.lock and silently changes the winit code each time a contributor re-resolves. Pin the commit and add a TODO.</violation>
</file>

<file name="desktop/src/app.rs">

<violation number="1" location="desktop/src/app.rs:479">
P2: When a second paste starts before the first asynchronous fetch completes, this assignment overwrites the first serial, so the first `DataTransferReceived` event is ignored and that paste is silently dropped. Track all outstanding serials or explicitly serialize clipboard reads.</violation>

<violation number="2" location="desktop/src/app.rs:646">
P2: A clipboard read (or dropped-file fetch) whose serial never produces a DataTransferReceived leaves pending_clipboard_fetch/pending_dnd_fetch set forever, so no ClipboardReadResult is ever dispatched and the UI awaits indefinitely; the Err(WouldBlock) arm provides no terminal fallback and there is no timeout or DragLeave cleanup. Add a guaranteed terminal path (e.g. clear the pending state and dispatch content:None if the transfer cannot resolve) rather than relying solely on winit re-delivering the event.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread desktop/src/input.rs Resolved
Comment thread Cargo.toml
debug = true

[patch.crates-io]
winit = { git = "https://github.com/timon-schelling/winit", branch = "graphite" }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This patch routes the entire workspace's winit dependency (version 0.31.0-beta.2) through an unpinned personal git fork branch, which is a supply-chain and reproducibility concern for a core dependency. Unlike the adjacent rfd patch, this line has no comment or removal plan referencing the upstream winit clipboard work (winit PR #4658) that will let it be dropped once a release ships. Because only branch = "graphite" is specified without a rev, any force-push/rewrite of that branch breaks every downstream Cargo.lock and silently changes the winit code each time a contributor re-resolves. Pin the commit and add a TODO.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At Cargo.toml, line 263:

<comment>This patch routes the entire workspace's `winit` dependency (version 0.31.0-beta.2) through an unpinned personal git fork branch, which is a supply-chain and reproducibility concern for a core dependency. Unlike the adjacent `rfd` patch, this line has no comment or removal plan referencing the upstream winit clipboard work (winit PR #4658) that will let it be dropped once a release ships. Because only `branch = "graphite"` is specified without a `rev`, any force-push/rewrite of that branch breaks every downstream Cargo.lock and silently changes the winit code each time a contributor re-resolves. Pin the commit and add a TODO.</comment>

<file context>
@@ -260,6 +260,7 @@ lto = "thin"
 debug = true
 
 [patch.crates-io]
+winit = { git = "https://github.com/timon-schelling/winit", branch = "graphite" }
 rfd = { git = "https://github.com/timon-schelling/rfd.git", branch = "graphite" } # TODO: Remove this once https://github.com/PolyMeilex/rfd/pull/317 is merged and released
 cef = { git = "https://github.com/timon-schelling/cef-rs.git", branch = "graphite-151" }
</file context>
Suggested change
winit = { git = "https://github.com/timon-schelling/winit", branch = "graphite" }
winit = { git = "https://github.com/timon-schelling/winit", rev = "1226add1bb6473ebaae83c3e1a43b81f170aca54" } # TODO: Remove this and restore the crates.io release once the winit clipboard API (https://github.com/rust-windowing/winit/pull/4658) is in a released version

Comment thread desktop/src/app.rs
event_loop.fetch_data_transfer(id, &TypeHint::Plaintext).map(Some)
});
match result {
Ok(Some(serial)) => self.pending_clipboard_fetch = Some(serial),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: When a second paste starts before the first asynchronous fetch completes, this assignment overwrites the first serial, so the first DataTransferReceived event is ignored and that paste is silently dropped. Track all outstanding serials or explicitly serialize clipboard reads.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At desktop/src/app.rs, line 479:

<comment>When a second paste starts before the first asynchronous fetch completes, this assignment overwrites the first serial, so the first `DataTransferReceived` event is ignored and that paste is silently dropped. Track all outstanding serials or explicitly serialize clipboard reads.</comment>

<file context>
@@ -467,6 +466,32 @@ impl App {
+					event_loop.fetch_data_transfer(id, &TypeHint::Plaintext).map(Some)
+				});
+				match result {
+					Ok(Some(serial)) => self.pending_clipboard_fetch = Some(serial),
+					Ok(None) => self.dispatch_desktop_wrapper_message(DesktopWrapperMessage::ClipboardReadResult { content: None }),
+					Err(e) => {
</file context>

Comment thread desktop/src/app.rs
let message = DesktopWrapperMessage::ClipboardReadResult { content: Some(content) };
self.app_event_scheduler.schedule(AppEvent::DesktopWrapperMessage(message));
}
Err(e) if e.kind() == std::io::ErrorKind::WouldBlock => {}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: A clipboard read (or dropped-file fetch) whose serial never produces a DataTransferReceived leaves pending_clipboard_fetch/pending_dnd_fetch set forever, so no ClipboardReadResult is ever dispatched and the UI awaits indefinitely; the Err(WouldBlock) arm provides no terminal fallback and there is no timeout or DragLeave cleanup. Add a guaranteed terminal path (e.g. clear the pending state and dispatch content:None if the transfer cannot resolve) rather than relying solely on winit re-delivering the event.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At desktop/src/app.rs, line 646:

<comment>A clipboard read (or dropped-file fetch) whose serial never produces a DataTransferReceived leaves pending_clipboard_fetch/pending_dnd_fetch set forever, so no ClipboardReadResult is ever dispatched and the UI awaits indefinitely; the Err(WouldBlock) arm provides no terminal fallback and there is no timeout or DragLeave cleanup. Add a guaranteed terminal path (e.g. clear the pending state and dispatch content:None if the transfer cannot resolve) rather than relying solely on winit re-delivering the event.</comment>

<file context>
@@ -601,20 +626,53 @@ impl ApplicationHandler for App {
+					let message = DesktopWrapperMessage::ClipboardReadResult { content: Some(content) };
+					self.app_event_scheduler.schedule(AppEvent::DesktopWrapperMessage(message));
+				}
+				Err(e) if e.kind() == std::io::ErrorKind::WouldBlock => {}
+				Err(e) => {
+					self.pending_clipboard_fetch = None;
</file context>

@github-actions

Copy link
Copy Markdown
📦 Mac Build Complete for 7404406
Download binary

@github-actions

github-actions Bot commented Sep 12, 2026 •

Copy link
Copy Markdown
📦 Linux Build Complete for 7404406
Download binary
Download Flatpak

@github-actions

Copy link
Copy Markdown
📦 Windows Build Complete for 7404406
Download binary

@timon-schelling
timon-schelling force-pushed the desktop-winit-clipboard branch 2 times, most recently from 1824c4e to edf2633 Compare September 15, 2026 01:18
@timon-schelling

timon-schelling commented Sep 15, 2026 •

Copy link
Copy Markdown
Member Author

!build desktop (Run ID 34916753637)

@github-actions

Copy link
Copy Markdown
📦 Mac Build Complete for edf2633
Download binary

@github-actions

github-actions Bot commented Sep 15, 2026 •

Copy link
Copy Markdown
📦 Linux Build Complete for edf2633
Download binary
Download Flatpak

@github-actions

Copy link
Copy Markdown
📦 Windows Build Complete for edf2633
Download binary

@timon-schelling
timon-schelling merged commit fdf6cfe into master Sep 15, 2026
11 checks passed
@timon-schelling
timon-schelling deleted the desktop-winit-clipboard branch September 15, 2026 14:17
VimYoung pushed a commit to VimYoung/Graphite that referenced this pull request Sep 17, 2026
* Desktop: Upgrade winit and port DnD to the new data transfer API

* Desktop: Read and write the clipboard via the winit data transfer API

This branch was successfully deployed

1 active deployment
graphite-dev (Preview) — d5eac621 Deployed Sep 15, 2026 by github-actions[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant