Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clipboard is cleared when the process exits on Linux #61

Open
yaa110 opened this issue Dec 22, 2018 · 8 comments
Open

Clipboard is cleared when the process exits on Linux #61

yaa110 opened this issue Dec 22, 2018 · 8 comments

Comments

@yaa110
Copy link

yaa110 commented Dec 22, 2018

Please consider the following code:

fn main() {
    let mut ctx: ClipboardContext = ClipboardProvider::new().unwrap();
    ctx.set_contents("some string".to_owned()).unwrap();
    // Clipboard is "some string"
} // Clipboard is empty after exit
@aweinstock314
Copy link
Owner

This is a known tradeoff/design decision around a limitation of x11. This was documented in a comment back when x11-clipboard lived in-tree (

// Under x11, "copying data into the clipboard" is actually
// accomplished by starting a "server" process that owns the
// copied data, and streams copied chunks of it through an
// event loop when another process requests it.
// xclip uses fork(2) to ensure that the clipboard "server"
// outlives the process that generated the data.
// Since there are potential complications of using fork(2)
// from rust (e.g. multiple calls of destructors), threads are
// used for now (until the complications are reviewed in more
// detail). As such, the clipboard "server" provided by
// X11ClipboardContext::set_contents will not outlive the calling
// process.
// X11ClipboardContextSetter is intended to be created {on the thread,
// in the process} that will be serving the clipboard data.
). I'll probably address this by copying that comment back in tree (and possibly adding the feature to create a clipboard context that forks, with a warning about the issues around locks/destructors).

@brownjohnf
Copy link

I realize this might be out of scope, but is there a way of detecting when the contents of the clipboard have been accessed, from rust-clipboard? I want to write a tool to receive input from stdin and copy that to the clipboard. I'd be fine with the process hanging until the contents had been pasted out (in fact, that could be ideal), but I'm not sure how i'd know when that had occurred.

I guess this might require something like a variation on set_contents that would block until the contents had been read back out?

@ghost
Copy link

ghost commented Aug 4, 2019

Thank you for addressing this in detail. As someone who is learning Rust, would you be able to give brief details on the problems involved with using fork?

@LordFoom
Copy link

This is a real pity as it renders the library essentially useless for my purposes.

@timvisee
Copy link

Assuming this is a wontfix, I've created the clipboard-ext crate to extend upon this. It provides some additional clipboard providers for X11 that do implement the noted workarounds such as forking or invoking xclip/xsel.

For example, these will keep clipboard contents after exit:

use clipboard_ext::prelude::*;

// Fork and keep contents
clipboard_ext::x11_fork::ClipboardContext::new().unwrap()
    .set_contents("some string".into()).unwrap();

// Invoke xclip/xsel and keep contents
clipboard_ext::x11_bin::ClipboardContext::new().unwrap()
    .set_contents("some string".into()).unwrap();

See the README for more information.

@brownjohnf
Copy link

I did a bit of digging to see how much work it would be to enable the paste detection functionality that I mention in #61 (comment), and it appears pretty nontrivial, since this package uses various lower-level libraries for the actual clipboard bits.

@timvisee
Copy link

@brownjohnf I've done exactly this in clipboard-ext which I mentioned in #61 (comment).

You'd have to use the x11-clipboard crate for this which provides access to the lower level X11 library. This is alright though, because this is the only provider you'd need to implement this for anyway. It provides the load_wait function which blocks until clipboard content is changed.
See my implementation and usage here: https://github.com/timvisee/rust-clipboard-ext/blob/a47cc13807ca19bc2c815b07688a27235ad9b4f7/src/x11_fork.rs#L90-L107

@woodruffw
Copy link

woodruffw commented May 14, 2020

Following up here with my own hack solution, which is to use the nix crate's fork functionality to spawn a temporary child:

match fork() {
    Ok(ForkResult::Child) => {
        let mut ctx: ClipboardContext = ClipboardProvider::new().unwrap();
        ctx.set_contents(password.value.to_owned()).unwrap();

        std::thread::sleep(std::time::Duration::from_secs(10));

        // optionally clear the clipboard here
    }
    Err(_) => return Err("clipboard fork failed".into()),
    _ => {}
}

This only works on platforms that have a fork, of course.

Edit: This also shouldn't be done in library code. It's safe-ish in the context I intend to use it in, but not necessarily others.

stchris added a commit to stchris/passage that referenced this issue Jun 27, 2020
This is related to an issue with the clipboard handling in xorg,
see aweinstock314/rust-clipboard#61

This now forks a child process and sleeps for 10 seconds, after
which it clears the clipboard before exiting.

Closes #5
stchris added a commit to stchris/passage that referenced this issue Jun 27, 2020
This is related to an issue with the clipboard handling in xorg,
see aweinstock314/rust-clipboard#61

This now forks a child process and sleeps for 10 seconds, after
which it clears the clipboard before exiting.

Closes #5
stchris added a commit to stchris/passage that referenced this issue Jun 27, 2020
This is related to an issue with the clipboard handling in xorg,
see aweinstock314/rust-clipboard#61

This now forks a child process and sleeps for 10 seconds, after
which it clears the clipboard before exiting.

Closes #5
stchris added a commit to stchris/passage that referenced this issue Jun 27, 2020
This is related to an issue with the clipboard handling in xorg,
see aweinstock314/rust-clipboard#61

This now forks a child process and sleeps for 10 seconds, after
which it clears the clipboard before exiting.

Closes #5
stchris added a commit to stchris/passage that referenced this issue Jun 27, 2020
This is related to an issue with the clipboard handling in xorg,
see aweinstock314/rust-clipboard#61

This now forks a child process and sleeps for 10 seconds, after
which it clears the clipboard before exiting.

Closes #5
stchris added a commit to stchris/passage that referenced this issue Jun 27, 2020
This is related to an issue with the clipboard handling in xorg,
see aweinstock314/rust-clipboard#61

This now forks a child process and sleeps for 10 seconds, after
which it clears the clipboard before exiting.

Closes #5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants