Repository navigation
Fix: check the system clipboard off the UI thread - #510
Closed
omellado-gh wants to merge 2 commits into
Closed
omellado-gh wants to merge 2 commits into
omellado-gh wants to merge 2 commits into
Conversation
An X11 clipboard owner that never answers `get_text()` blocks the thread that reads it for up to seconds. The app checks the clipboard every 0.25 s to enable Paste, so a stuck owner froze the whole frame loop (the window stopped drawing and could not be closed). These tests pin the regression before the fix: a fake clipboard whose `has()` blocks on a gate, a probe factory sharing a recorder, and a headless frame whose elapsed time is measured. They assert the frame does not wait on the clipboard and that the check runs on the probe thread, that the probe's verdict reaches `system_paste` and the Paste menu, that dropping the app stops the probe, and that the in-line check (no factory: the web, older hosts) still works. Two fail today: the frame waits on the clipboard (1 s) and the probe's verdict never arrives, because the probe is not wired yet.
`has()` on an X11 clipboard owner that never answers can block for seconds; the app called it every 0.25 s on the UI thread to decide whether Paste is enabled, so a stuck owner froze the frame loop. `clipboard_probe` owns a second clipboard handle on a worker thread, publishes its verdict over a channel and wakes the UI only when it changes; the frame reads the latest verdict without ever blocking. Without a factory the check stays in line, throttled, exactly as before (the web shows SVG text only; hosts that don't install one keep the old path). The factory is installed on Linux only for now (the environment the bug reproduces in); other platforms keep the in-line check, so this cannot change their behaviour. The five tests added previously now pass.
bflatastic
added a commit
that referenced
this pull request
Oct 8, 2026
Linux: check the system clipboard for Paste off the UI thread (#510)
Member
|
Thanks a lot for this, @omellado-gh, and welcome! A great first PR: you tracked the freeze down to arboard's X11 read on the UI thread, reproduced it with a stopped
If you'd like to chat about Linux and the rest of VectorCraft, come join us on Discord: https://discord.gg/artcraft |
Member
|
Landed via #534 (your commit, authored by you, plus our review commit). Thanks again! |
Haven-King
pushed a commit
to Haven-King/vectorcraft
that referenced
this pull request
Oct 8, 2026
For users, since 0.6.0: - Linux: no more startup crash on desktops whose compositor runs on another GPU (storytold#502, storytold#551); the window renders on the desktop's GPU and retries the next one instead of crashing. - Windows: rendering through DirectX 12 first, fixing the black flicker on Intel GPUs (storytold#545). - Italian interface (storytold#514). - macOS: the menus live in the system menu bar. - Panels, panel groups and the Tools panel undock into floating panels (storytold#495). - Live Corners on any path's corners: stars, polygons, pen paths (storytold#511). - Drawing tools snap to Smart Guides as the Selection tool does (storytold#506). - Pen: Cmd/Ctrl edits the path being drawn, Alt reshapes segments, drags out of the first anchor always close (storytold#494, storytold#501); Convert buttons for whole paths (storytold#504). - Right-click a ruler to change the document's units; the Control bar's Transform link opens the Transform panel. - Object > Image Trace > Make traces with the Default preset (storytold#543). - Edit menu Select All, Cut, Copy and Paste act on a focused field (storytold#516). - Japanese UI: new type starts top-to-top with em box centre alignment (storytold#432). - PDF/.ai import keeps type strokes, wrapped lines and layer order (storytold#508); EPS import fixes (storytold#498, storytold#505). - macOS 27: only file URLs are opened (storytold#433); Linux: the Paste menu no longer freezes on an unresponsive clipboard owner (storytold#510). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
What and why
The app checks the system clipboard every 0.25 s to decide whether the Paste menu
items are enabled. On X11,
arboard's clipboard read waits up to 4 s for aSelectionNotify; when the clipboard owner never answers (a hung or foreign app,a clipboard manager, XWayland), that call ran on the UI thread and froze the whole
frame loop — the window stopped drawing and could not be closed.
Reproduced with the real failure: seed the clipboard and stop its owner
(
printf x | xclip -selection clipboard; kill -STOP $(pgrep -x xclip)), then opena document. The app became unresponsive and a control-channel
ui.inspecttimed outwhile the main thread sat in arboard's wait loop.
This change moves the check off the UI thread: a
clipboard_probeworker owns asecond clipboard handle, publishes whether Paste has something to take
(
has(PASTE_ORDER)) over a channel, and wakes the UI only when the verdict changes.logic_framereads the latest verdict withtry_recvand never blocks. Without afactory (the web, and hosts that don't install one) the check stays in line,
throttled, exactly as before. The factory is installed on Linux only for now;
macOS and Windows keep the in-line check, so their behaviour is unchanged.
How it was tested
crates/ui-egui/src/tests_sysclip_probe.rs(5): a fake clipboardwhose
has()blocks proves the headless UI frame does not wait on it (measuredelapsed time) and that the check runs on the
vectorcraft-clipprobe thread; theprobe's verdict enables the Paste menu; a probe that reports nothing leaves it
disabled; dropping the app stops the probe; and the in-line path (no factory) still
works.
cargo test -p vectorcraft-ui-egui --lib→ 717 passed.SIGSTOPand a document open, the app stays responsive (
ui.inspectanswers in ~0 ms, mainthread in its normal
epollwait), where before it froze.cargo check -p vectorcraft,cargo fmt --all --check, and clippy on the touchedcrates.
Note: locally, workspace clippy /
cargo xtask cifails on a pre-existing lint incrates/eps/src/import/data.rs:746(chunks_exact_to_as_chunks, new in clippy 1.99)that this PR does not touch; the touched crates are clippy-clean with that lint
allowed.
Checklist
cargo xtask cipasses (fmt, clippy, tests, assets, brands, layers, wasm).unwrap(),expect(),panic!,unreachable!,todo!orunimplemented!outside tests, and no unchecked indexing on data from files, parameters ormessages. Errors are returned as
Resultand shown to the user(why and how).
ASSETS.md.