XCB - couldn't establish conection: SetupFailed
Hello, first of all, big thanks for your lib, it's quite magical to use it along with a tauri app and be crossplatform right away.
However my use case is to poll frequently if something is highlighted to display a window next to it and at some point calling get_text() result in this error:
[selection::linux][ERROR] XCB - couldn't establish conection: SetupFailed(SetupFailed { status: 0, protocol_major_version: 11, protocol_minor_version: 0, length: 9, reason: [77, 97, 120, 105, 109, 117, 109, 32, 110, 117, 109, 98, 101, 114, 32, 111, 102, 32, 99, 108, 105, 101, 110, 116, 115, 32, 114, 101, 97, 99, 104, 101, 100] })
I'm complete beginner in rust and x11 server but as far as I understand, Clipboard::new() shouldn't be created every time get_text() is called as it open a new connection to x11 everytime.
To reuse the same connection, maybe something like that could help:
use std::sync::Mutex;
use lazy_static::lazy_static;
use x11_clipboard::Clipboard;
use std::error::Error;
use std::time::Duration;
use log::error;
lazy_static! {
static ref X11_CLIPBOARD: Mutex<Option<Clipboard>> = Mutex::new(None);
}
fn get_text_on_x11() -> Result<String, Box<dyn Error>> {
let mut clipboard_lock = X11_CLIPBOARD.lock().unwrap();
if clipboard_lock.is_none() {
*clipboard_lock = match Clipboard::new() {
Ok(clipboard) => Some(clipboard),
Err(err) => {
error!("Failed to create X11 clipboard: {}", err);
return Ok(String::new()); // Return an empty string or handle as needed
}
};
}
if let Some(ref clipboard) = *clipboard_lock {
let primary = match clipboard.load(
clipboard.getter.atoms.primary,
clipboard.getter.atoms.utf8_string,
clipboard.getter.atoms.property,
Duration::from_millis(100),
) {
Ok(data) => data,
Err(err) => {
error!("Failed to load X11 clipboard data: {}", err);
return Ok(String::new());
}
};
let result = String::from_utf8_lossy(&primary)
.trim_matches('\u{0}')
.trim()
.to_string();
Ok(result)
} else {
error!("Failed to initialize X11 clipboard");
Ok(String::new())
}
}
WDYT ?
I don’t know much about x11. You can submit a PR directly after testing.
After conducting a few tests, I found that it functions correctly. However, there's an unintended consequence: it continues to return the text that was previously selected, even after everything has been deselected.
Before, it would return an empty string because the Clipboard was recreated each time get_text was called. But now, by reusing the same Clipboard instance, it ends up returning the text that was selected earlier.
I'm hoping we can find a way to close the x11 client connection from within the Clipboard crate. Perhaps @quininer might have some insights on this.
Notes: I'm using xrestop to monitor the growing number of client if it helps
@MarcusGrass friendly ping as you've contributed the x11rb refactor on x11-clipboard side, maybe you have some insights, thanks
Nice find, I don't know whether this will fix your problem, but there's a bug where a reference to the connection is cloned into a thread which spawns a wait-loop which will keep that reference alive for the duration of the program, that's why clients are growing forever. I'm gonna try a fix and hope that it doesn't get too dirty.
@MarcusGrass that would be awesome, thanks 🙏
0.9 is out which fixes the client leak
Maybe this issue can be closed?