--- title: Keeping the clipboard alive date: 2024-09-04 tags: [design, wayland] description: Copied data is lost when you close the application that you wanted to copy from. I find this deeply confusing. I believe we can do better. --- It frequently happens to me that I want to paste something, but nothing happens. This is because on wayland (and many other systems, but I will focus on wayland) the copied data is lost when you close the application that you wanted to copy from. I find this deeply confusing. The official solution seems to be to setup a clipboard manager. However, I found out that clipboard managers are not a solution, they just make different trade offs. I believe we can do better. ## The Problem I first thought that the clipboard contains the actual bits that are being copied. But that is not the case. When you hit Ctrl-C, no data is actually copied. Instead the data can be offered in multiple mime types at the same time, so that the receiving end can pick which mime type it prefers. For example, text copied from the web browser could be offered as both `text/html` and `text/plain`. Of course, this mechanism only works as long as the application that is offering the data does not quit. After that, there is no one left to answer the request. ## Clipboard managers A common workaround for that problem is to use a clipboard manager like this: wl-paste --watch cliphist store In this case, `wl-paste` will call `cliphist store` whenever something is copied. It passes the copied data in one of the available mime types. `cliphist` will then replace the original offer with its own (`text/plain`). This means that the clipboard contents will not be lost when the original source goes away. But it also has some drawbacks: - Most mime type information is lost - The data needs to be transferred even if it is never actually pasted [`clipmon`](https://git.sr.ht/~whynothugo/clipmon) is another clipboard manager that makes slightly different trade offs: It also replaces the original offer with its own, but it preserves all mime types. This solves the first drawback, but amplifies the second one: the same image might have to be stored in multiple different formats. The author of `clipmon` wrote a [great blog post about these trade offs](https://whynothugo.nl/journal/2022/10/21/how-the-clipboard-works/). So in summary, the following goals are in conflict: - offer content in different mime types - keep the clipboard alive when an application quits - avoid unnecessary data transfer and storage ## Finding balance Many clipboard managers have features beyond just keeping the clipboard alive. But I only care about find a better default behavior. It would be nice if we could keep the original offer intact, and only replace it with a fallback if the application actually quits. The fallback could be restricted (e.g. only offer `text/plain`) to avoid wasting resources. Still, I think this would be a more balanced solution than what is currently available. I came up with the following script which can be used with `wl-paste --watch`: ``` sh #!/bin/sh -e path="/tmp/clipboard-$USER-$XDG_SEAT.txt" input=$(cat) if [ -n "$input" ]; then umask 077 printf '%s' "$input" > "$path" elif [ -f "$path" ] && ! wl-paste -l >/dev/null 2>&1; then wl-copy < "$path" fi ``` ## Moving it into the compositor I think the behavior I described above should be implemented in compositors for three reasons: - It should be the default behavior - The above script has a race condition if an application creates a new offer right before the call to `wl-copy`. Compositors have more information and might be able to avoid that (not sure about it, this might be an issue on the protocol level). - By default, the wayland protocol only allows the currently active window to access the clipboard for security reasons. Clipboard managers only work if the compositor supports the [wlr data control](https://wayland.app/protocols/wlr-data-control-unstable-v1) extension protocol. Not relying on that protocol is the more secure option. *Much of this post is based on discussions in .*