Selection icon indicating copy to clipboard operation
Selection copied to clipboard

XCB - couldn't establish conection: SetupFailed

Open tigitz opened this issue 1 year ago • 7 comments

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 ?

tigitz avatar Jan 17 '24 16:01 tigitz

I don’t know much about x11. You can submit a PR directly after testing.

Pylogmon avatar Jan 18 '24 08:01 Pylogmon

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 image

tigitz avatar Jan 18 '24 10:01 tigitz

@MarcusGrass friendly ping as you've contributed the x11rb refactor on x11-clipboard side, maybe you have some insights, thanks

tigitz avatar Jan 18 '24 12:01 tigitz

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 avatar Jan 18 '24 13:01 MarcusGrass

@MarcusGrass that would be awesome, thanks 🙏

tigitz avatar Jan 18 '24 15:01 tigitz

0.9 is out which fixes the client leak

MarcusGrass avatar Jan 29 '24 20:01 MarcusGrass

Maybe this issue can be closed?

Pylogmon avatar May 05 '24 14:05 Pylogmon