1Password / arboard

A clipboard for Rust
Apache License 2.0
594 stars 63 forks source link

Using `set_text` is not working when calling&creating Clipboard from other function #154

Open ktwrd opened 1 month ago

ktwrd commented 1 month ago

When using a different function for handling the creation of Clipboard and usage of set_text, the clipboard content is not set.

use arboard::Clipboard;
use std::thread::sleep;
use core::time::Duration;
fn main() {
    let data = String::from("hello world");

    println!("before copy_text");
    copy_text(data);
    println!("after copy_text");

    let d = Duration::from_millis(2500);
    sleep(d);

    println!("exiting (after 2.5s)");
    std::process::exit(0);
    // clipboard content will NOT be "hello world"
}
fn copy_text(content: String) {
    let mut instance = Clipboard::new().unwrap();
    instance.set_text(&content).unwrap();
}

I do not want to put a sleep inside of copy_text since I want stuff to run instantly after that and only wait 2s before actually exiting the application.

complexspaces commented 3 weeks ago

Hi there @ktwrd, thanks for opening an issue.

AFAICT the code you are showing is behaving as expected. On Linux, the process which puts values on the clipboard is responsible for serving them to other processes/apps forever. In your code, copy_text makes a temporary instance of Clipboard which gets Droped after the function returns. To avoid the immediate issue, you could pass a &mut Clipboard into copy_text instead. However when your main function returns, the clipboard contents would vanish as well. I don't know if it would work in your use case, but the wait method exists to help with cases like this.

When the last Clipboard instance in a process is dropped, arboard attempts to quickly handoff any clipboard contents its been instructed to serve (via .set_text(), etc) to the desktop environment's clipboard manager to preserve them to be copied later. If this times out or if there is no clipboard manager, the clipboard is "reset" as the background thread which used to serve incoming requests has now exited.

FWIW I'm trying to explain this more clearly in #149 so it is less confusing to users in the future.