Linux clipboard: the read worker holds the window as long as its clipboard

The worker's closure named loader.cb, and a closure moves only the fields it names, so
the worker's window clone was dropped when TextClipboard::new returned. A worker held
by an owner that never answers could then outlive the window. The closure now calls
Loader::load, which moves the whole Loader.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
wjrichards
2026-10-30 17:12:17 +07:00
committed by bflatastic
co-authored by Claude Opus 5.5
parent 7a86f94282
commit 9b3b662f5d
+9 -1
View File
@@ -785,6 +785,12 @@ mod wayland {
_window: Arc<winit::window::Window>,
}
impl Loader {
fn load(&self) -> Result<String, String> {
self.cb.load().map_err(|e| e.to_string())
}
}
impl TextClipboard {
/// None when `window` isn't a Wayland window or the read worker can't start.
#[allow(unsafe_code)]
@@ -797,7 +803,9 @@ mod wayland {
// makes its own event queue on the display and doesn't close it.
let (cb, reader) = unsafe { (smithay_clipboard::Clipboard::new(display), smithay_clipboard::Clipboard::new(display)) };
let loader = Loader { cb: reader, _window: window.clone() };
let loads = Loads::spawn(move || loader.cb.load().map_err(|e| e.to_string()))?;
// `loader.load()`, not `loader.cb.load()`: a closure moves only the fields it names,
// and the worker must hold the window as long as its clipboard.
let loads = Loads::spawn(move || loader.load())?;
Some(Self { cb, loads, _window: window })
}