Smithay / smithay-clipboard

Provides access to the wayland clipboard for client applications
MIT License
29 stars 12 forks source link

Make copy work on arbitrarily long strings #41

Closed rhelmot closed 1 year ago

rhelmot commented 2 years ago

I noticed that there was a limit on the amount of data that could be pushed into the clipboard - for me it was 65536 bytes. I determined that this limit was a linux internal buffer size - what's happening is that the socket that gets provided to transfer the data over is nonblocking, but the code in this crate which handles the transfer assumes it's blocking, so the write only fills up the operating system's buffer before returning.

It's not enough to just loop until all the data goes over the socket, since if you're trying to copy-paste from an application to itself, this will result in a deadlock. I observed some other applications tossing the data socket into a pool which is polled along with the main wayland socket to determine which when data can be written or when additional wayland events become available, but I think this would require integration with an event loop. In lieu of that, this patch starts a new thread for each piece of data being copied and sends it sockets to copy the data onto. I verified empirically that when the copied data is released (i.e. something else is copied) the thread exits.

kchibisov commented 2 years ago

Using thread for that seems redundant, also this issue applies to read, and there's no guarantee that fd from the pipe is non-blocking, so you should explicitly set it that way.

rhelmot commented 2 years ago

This code will work on both blocking and non-blocking sockets. It's adapted from the stdlib code for writing a string to a pipe.

What should I use instead of a thread?

kchibisov commented 2 years ago

This code will work on both blocking and non-blocking sockets. It's adapted from the stdlib code for writing a string to a pipe.

But you don't have a socket here, you have a pipe, and you can mark it non blocking yourself with fcntl, you always want non-blocking here.

What should I use instead of a thread?

epoll/kqueue via calloop and its GenericFd interface. Basically how you do that with any other fd reading.

rhelmot commented 2 years ago

I attempted to address your concerns. I chose to not bring in the calloop dependency and instead launched one additional thread for the process which manages live clipboard contents. Let me know if there are any issues with this approach.

rhelmot commented 2 years ago

Is there anything I can do to help this PR get merged?

kchibisov commented 1 year ago

See #47.