Clipferry solves the problem of X11 ↔ Wayland clipboard sync. Let me explain why I built this.
I often use niri or Hyprland with Steam. Steam, Proton and Wine are all X11 clients: they reach Wayland via xwayland-satellite on niri, and via Hyprland's builtin Xwayland on Hyprland.
Copying inside a Wayland app and pasting into a Wine window works. Copying out of an X11 app doesn't: the X11 selection never crosses back. A WoW SimC dump you want in raidbots, a talent or WeakAuras import string bound for Discord, a Path of Building code, a Factorio blueprint, an FFXIV gear set string: all stuck on the X11 side.
Recent xwayland-satellite releases have closed some of these gaps, but apps that don't play the usual focus games, and less-common MIME types, still fall through on both stacks.
dnut/clipboard-sync hasn't been touched since 2023 and has a much broader scope than I wanted. Everything else was bash around wl-copy and xclip, polling in a loop with content hashes for loop suppression and a pipe cost paid on every copy whether anyone pastes or not. Fine for text; grim for a 30 MB screenshot.
clipferry is a small Rust daemon that speaks both clipboard protocols directly and shuttles selections across on demand.
The design is deliberately narrow.
- Lazy by default. When you copy, clipferry exchanges the list of MIME types with the other side. The bytes themselves only move when someone actually pastes. A 50 MB image copy is a handful of strings until a paste happens, not two full transfers up-front.
- All the MIME types, not just text. Images, HTML,
text/uri-list, and a small translation table for the X11-isms (x-special/gnome-copied-files, a couple of WeChat and Wine quirks), plus INCR in both directions for the awkwardly large ones. - Loop prevention by ownership identity, not hashing. clipferry knows which selection claims are its own, so it never chases its own tail. No content hashes, no sleeps, no races.
- Sandboxed. It applies Landlock to itself: no filesystem, no TCP. Plus the usual systemd hardening. Clipboard content is never logged, and payload buffers are zeroed when they die.
- Small. One process, a ~1 MiB binary, under 5 MiB resident.
By default it runs in backstop mode: it watches both clipboards passively, and only claims a selection when nothing else has bridged the other side within ~200 ms of a copy. If satellite's builtin sync handles a case, clipferry stays out of the way. Clipboard history managers (cliphist, clipse) coexist as designed.
Install is short:
# Arch
paru -S clipferry
# any distro
cargo install --git https://github.com/jmylchreest/clipferry
sudo cp contrib/clipferry.service /usr/lib/systemd/user/
systemctl --user enable --now clipferry.service
clipferry --oneshot-check # sanity: both displays reachable?
There isn't much to configure, but there are a handful of flags to deal with edge cases. For most people the defaults will work. The README documents them.
If copy-out-of-X11 has been annoying you, give it a go. Issues and patches welcome on the repo.
