{"record":{"id":"6435c15f87480e52","repo":"linebender/druid","slug":"timeout-while-waiting-for-selection-owner-to-reply","errorCode":null,"errorMessage":"Timeout while waiting for selection owner to reply","messagePattern":"Timeout while waiting for selection owner to reply","errorType":"exception","errorClass":"std::io::Error (TimedOut)","httpStatus":null,"severity":"error","filePath":"druid-shell/src/backend/x11/clipboard.rs","lineNumber":664,"sourceCode":"/// Wait for an X11 event or return a timeout error if the given deadline is in the past.\nfn wait_for_event_with_deadline(\n    conn: &XCBConnection,\n    deadline: Instant,\n) -> Result<Event, ConnectionError> {\n    use nix::poll::{poll, PollFd, PollFlags};\n    use std::os::raw::c_int;\n    use std::os::unix::io::AsRawFd;\n\n    loop {\n        // Is there already an event?\n        if let Some(event) = conn.poll_for_event()? {\n            return Ok(event);\n        }\n\n        // Are we past the deadline?\n        let now = Instant::now();\n        if deadline <= now {\n            return Err(std::io::Error::new(\n                std::io::ErrorKind::TimedOut,\n                \"Timeout while waiting for selection owner to reply\",\n            )\n            .into());\n        }\n\n        // Use poll() to wait for the socket to become readable.\n        let mut poll_fds = [PollFd::new(conn.as_raw_fd(), PollFlags::POLLIN)];\n        let poll_timeout = c_int::try_from(deadline.duration_since(now).as_millis())\n            .unwrap_or(c_int::MAX - 1)\n            // The above rounds down, but we don't want to wake up to early, so add one\n            .saturating_add(1);\n\n        // Wait for the socket to be readable via poll() and try again\n        match poll(&mut poll_fds, poll_timeout) {\n            Ok(_) => {}\n            Err(nix::errno::Errno::EINTR) => {}\n            Err(e) => return Err(std::io::Error::from(e).into()),","sourceCodeStart":646,"sourceCodeEnd":682,"githubUrl":"https://github.com/linebender/druid/blob/0f8b1195e4e073f9597f2865299c3d18f8e4005f/druid-shell/src/backend/x11/clipboard.rs#L646-L682","documentation":"The X11 clipboard transfer implementation asks the current selection owner for clipboard data and then waits for the reply event on the X connection. If the owner does not respond before the deadline, wait_for_event_with_deadline returns an io::Error with ErrorKind::TimedOut and this message, surfaced (via do_transfer_impl) as a ClipboardError::Io.","triggerScenarios":"Calling clipboard get/set_string (or paste) while the selection owner (another X client holding the clipboard) is hung, dead, or slow to respond; race where the owning window closed between claiming the selection and the data request; extremely large transfers exceeding the deadline.","commonSituations":"Copy/paste from a frozen or misbehaving application under X11; clipboard managers or window-manager shutdown mid-transfer; running druid apps in remote/VNC X sessions with high latency; pasting immediately after closing the source app.","solutions":["Retry the clipboard read after a short delay; transient owner hangs often clear.","Check that the source application holding the clipboard is still responsive; re-copy from it.","If it recurs with one specific app, work around by using an intermediate clipboard (e.g. `xclip -selection clipboard -o` from shell) or a clipboard manager.","Upgrade druid/druid-shell; X11 clipboard handling has had timeout and error-handling fixes.","Handle the TimedOut io error in app code around clipboard get_string calls so a failed paste does not panic or hang."],"exampleFix":"// before\nlet text = window.get_clipboard_string().unwrap();\n\n// after\nlet text = match window.get_clipboard_string() {\n    Ok(t) => t,\n    Err(e) if matches!(e, druid_shell::Error::ShellError(_)) || e.to_string().contains(\"Timeout\") => {\n        tracing::warn!(\"clipboard transfer timed out\");\n        String::new()\n    }\n    Err(e) => return Err(e.into()),\n};","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"match window.get_clipboard_string() {\n    Ok(text) => text,\n    Err(err) if err.to_string().contains(\"Timeout while waiting for selection owner\") => {\n        // retry once, then fall back\n        window.get_clipboard_string().unwrap_or_default()\n    }\n    Err(err) => return Err(err.into()),\n}","preventionTips":["Keep clipboard source applications responsive; re-copy before pasting if the source was closed.","Wrap clipboard reads in retry-with-backoff helpers.","On flaky X11 setups prefer clipboard managers (e.g. clipman, parcellite) as intermediaries.","Avoid pasting from apps in the middle of teardown."],"tags":["x11","clipboard","timeout","linux","ipc"],"backgroundTag":"request-timeout","analyzedSha":"0f8b1195e4e073f9597f2865299c3d18f8e4005f","analyzedAt":"2026-09-10T14:27:34.582Z","contentChangedAt":"2026-09-10T14:27:34.582Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}