alacritty/copypasta

`set_contents` works unexpectedly?

xliiv opened this issue · 8 comments

xliiv commented

I'm wondering why these two examples behave diffrently

extern crate copypasta;

use copypasta::ClipboardContext;
use copypasta::ClipboardProvider;

fn fails() {
    let mut ctx = ClipboardContext::new().unwrap();
    let mut previous = String::new();
    loop {
        let current = ctx.get_contents().unwrap();
        dbg!(&current);

        if current != previous {
            ctx.set_contents(current.clone()).unwrap();
            previous = current;
            dbg!(&previous);
        }

        std::thread::sleep(std::time::Duration::from_millis(100));
    }
}

fn works() {
    let mut ctx = ClipboardContext::new().unwrap();
    let mut previous = String::new();
    loop {
        let current = ctx.get_contents().unwrap();
        dbg!(&current);

        if true {
            ctx.set_contents(current.clone()).unwrap();
            previous = current;
            dbg!(&previous);
        }

        std::thread::sleep(std::time::Duration::from_millis(100));
    }
}

fn main() {
    fails();
    //works();
}

Actions to reproduce

  1. run the code
cd /tmp
git clone https://github.com/xliiv/copypasta.git --branch loop-error --single-branch
cd copypasta/
cargo run --example echo
  1. select some text in some window e.g. Firefox
  2. press ctrl+c
  3. focus some edit widget, e.g. Firefox's address bar
  4. press ctrl+v

I expect the copied text will show up in the widget (see step 4) but it doesn't.

Am i missing something?

OS: Linux, Wayland

I expect the copied text will show up in the widget (see step 4) but it doesn't.

What do you mean by this? Are you expecting it to show up in stdout?

Also please note that ClipboardContext::new() uses the X11 backend by default. If you want to create a native Wayland clipboard, you have to pass it a window handle. This is necessary because Wayland does not allow reading/writing of the clipboard for unfocused windows.

Thank you for a quick response.

I'm writing a clipboard manager. The program contains 2 modes

  • recorder, records clipboard history
  • selector, selects from recorded history

The recorder should run (more or less) this code

fn record_clipboard() {
    let mut ctx = ClipboardContext::new().unwrap();
    let mut previous = String::new();
    loop {
        let current = ctx.get_contents().unwrap();
        dbg!(&current);

        if current != previous {
            ctx.set_contents(current.clone()).unwrap();
            // let's say it saves clipboard entries to a file
            save_clipboard_content(&current);
            previous = current;
            dbg!(&previous);
        }

        std::thread::sleep(std::time::Duration::from_millis(100));
    }
}

However, if record_clipboard is running it makes ctrl-v not working.
Somehow it clears the clipboard content, because when i inspect right-click menu paste is greyed.

What do you mean by this? Are you expecting it to show up in stdout?

I expect it won't break ctrl-v like it happens now.

It's even weirder because when i remove the if condition (https://github.com/xliiv/copypasta/blob/744bf24cdf47f31b55d6d447f38ca13e1b56e651/examples/echo.rs#L40) it works like expected.

First of all, on Wayland you shouldn't implement a clipboard manager in userspace but it should be done in the compositor instead. Everything else doesn't make sense. Right now you're using XWayland to run your clipboard manager which will not work properly with native Wayland applications.

I'd assume this might be why things are behaving strangely too. So I'm unsure how much sense it makes to look into this while you're running this strange XWayland setup that runs into all kinds of problems with applications being unable to copy/paste between another by design.

copypasta isn't a crate you want to create a clipboard manager, at least on Wayland. it's designed to work in pair with other gui toolkits, winit, etc, not to run in CLI. Also, please, test your code natively on X11, since XWayland is strange sometimes.

First of all, on Wayland you shouldn't implement a clipboard manager in userspace but it should be done in the compositor instead.

While this is true originally, this isn't true on some compositors. On sway you can use https://github.com/swaywm/wlr-protocols/blob/master/unstable/wlr-data-control-unstable-v1.xml to implement clipboard manager in userspace IIRC.

So the way to go to write your clipboard manager on Wayland is to use this protocol.

For my own understanding, why isn't this crate applicable for a clipboard manager? I would think that set/get_contents is all you really need.

For my own understanding, why isn't this crate applicable for a clipboard manager?

API makes sense, however underlying platform clipboards isn't suitable for such cases. For example Wayland backend requires window, but it's specific to Wayland, you need a window to make clipboard work in general. However some compositors provides a protocol to work with clipboard without a window being around, but it's out of scope for our backend, since the protocol for such thing could only work under wlroots. X11 also creates window under the hood, not sure about other backends.

Thanks all you guys for bringing a lot of useful knowledge, it's very helpful.

Given all the input, the next step would be to close this issue.

First of all, on Wayland you shouldn't implement a clipboard manager in userspace but it should be done in the compositor instead. Everything else doesn't make sense.

Very heplful, thanks!

Right now you're using XWayland to run your clipboard manager

You answered a question which has bothered for some time.
I was sure

  1. I run Wayland
  2. but reviewing Copypasta code I was sure I'm using X11Clipboard which was a conflict for me

Now I know the answer - Very heplful, thanks!

So I'm unsure how much sense it makes to look into this while you're running this strange XWayland setup

Good point, let's close it.

copypasta isn't a crate you want to create a clipboard manager, at least on Wayland. it's designed to work in pair with other gui toolkits, winit, etc, not to run in CLI. Also, please, test your code natively on X11, since XWayland is strange sometimes.

Very heplful, thanks!

While this is true originally, this isn't true on some compositors. On sway you can use https://github.com/swaywm/wlr-protocols/blob/master/unstable/wlr-data-control-unstable-v1.xml to implement clipboard manager in userspace IIRC.

So the way to go to write your clipboard manager on Wayland is to use this protocol.

Also very heplful, thanks!

For my own understanding, why isn't this crate applicable for a clipboard manager? I would think that set/get_contents is all you really need.

That exactly was my reasoning, now I get it, because of..

API makes sense, however underlying platform clipboards isn't suitable for such cases. For example Wayland backend requires window, but it's specific to Wayland, you need a window to make clipboard work in general.

Again, very heplful, thanks!