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

current status of ClipboardContext::set_contents on linux #28

Open
kindlychung opened this issue Apr 17, 2016 · 8 comments
Open

current status of ClipboardContext::set_contents on linux #28

kindlychung opened this issue Apr 17, 2016 · 8 comments

Comments

@kindlychung
Copy link
Contributor

Is it possible to make the set_content effect outlive the process now? Thanks!

@aweinstock314
Copy link
Owner

That the clipboard provided by this crate doesn't outlast the process is due to several considerations:

  • the method that xclip uses to provide a clipboard daemon (the fork syscall) would be unsafe to use in a library, since the client code could have instantiated objects with nontrivial destructors (which would be at risk of being called twice, although this might be mitigateable with with exit) or could have acquired a global lock (there's a known issue with this in malloc, this is harder/impossible to mitigate).
  • an alternate method of achieving clipboard persistance (fork and exec) would require that the library drop an executable (in order to pass the filename to exec), this might be difficult logistically (nontrivial build script) as well as inelegant and heuristically malware-like (and may not work well with sandboxing).
  • there's precedent for clipboards not outlasting processes: firefox doesn't preserve the clipboard after terminating on linux distros that don't have an external clipboard manager (e.g. Debian with XFCE).

I havn't personally tested this crate with a clipboard manager, but have received reports via IRC that it does work with them (possibly together with a call to sleep for a few hundred milliseconds if the client would otherwise exit immediately after setting the contents).

I'll try to document this better.

@kindlychung
Copy link
Contributor Author

Cool. Thanks!

@samuela
Copy link

samuela commented Sep 23, 2019

I'll add that this behavior recently really tripped me up. I'm writing a CLI app so it immediately exits after "setting" the clipboard. It's highly unintuitive to have it all work this way on linux. Some documentation here would be good.

@timvisee
Copy link

timvisee commented Sep 23, 2019

... this behavior recently really tripped me up. I'm writing a CLI app so it immediately exits after "setting" the clipboard. It's highly unintuitive to have it all work this way on linux.

I agree. I invoke xclip/xsel directly on Linux systems to mitigate this, but this is ugly. I'd argue it's worse than implementing the methods noted in the second comment.

@samuela
Copy link

samuela commented Sep 23, 2019

I invoke xclip/xsel directly on Linux systems

Ditto. This is exactly the same as my current solution.

use std::io::Write;
use std::process::{Command, Stdio};

pub fn write(s: &str) -> Option<()> {
  #[cfg(target_os = "macos")]
  let mut command = Command::new("pbcopy");

  #[cfg(target_os = "linux")]
  let mut command = {
    // See https://linux.die.net/man/1/xclip.
    let mut c = Command::new("xclip");
    c.arg("-in");
    c.arg("-selection");
    c.arg("clipboard");
    c
  };

  let mut child = command.stdin(Stdio::piped()).spawn().ok()?;

  // When stdin is dropped the fd is automatically closed. See
  // https://doc.rust-lang.org/std/process/struct.ChildStdin.html.
  {
    let stdin = child.stdin.as_mut()?;
    stdin.write_all(s.as_bytes()).ok()?;
  }

  // Wait on pbcopy/xclip to finish.
  child.wait().ok()?;
  Some(())
}

@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.

@IPI-Paul
Copy link

IPI-Paul commented Sep 27, 2023

I got around this issue by delaying the function end which allows me time enough to paste the resulting cliboard using:

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

@eirnym
Copy link

eirnym commented May 15, 2024

What do you think about solution made clip c++ library?

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