Klip
Native clipboard access for Go on Linux (Wayland and X11), macOS and Windows. No cgo.
Built to solve the “copied a password, program exited, clipboard went blank” problem you get on Wayland with most clipboard libraries. On Linux, Klip shells out to wl-copy, xclip or xsel, which fork and keep serving the clipboard after your process exits. On macOS it uses pbcopy and osascript; on Windows it talks to the Win32 clipboard API directly. Kosh uses it to copy secrets.
Install
go get plutolab.org/klip
Usage
cb := klip.NewClipboard()
// plain copy
cb.Write(ctx, []byte("hello"), klip.WriteOptions{})
// copy a secret: hint clipboard managers to keep it out of history,
// and clear it after the first paste where supported
cb.Write(ctx, []byte(password), klip.WriteOptions{
Secret: true,
ClearOnPaste: true,
})
// clear now, but only if the clipboard still holds what we wrote
cb.Clear(klip.DirectCompare([]byte(password)))
// clear unconditionally
cb.Clear(klip.Always)
Platform support
Secrethides the copy from clipboard history:- Linux:
wl-copy --sensitive; no-op on xclip and xsel - macOS:
org.nspasteboard.ConcealedTypeandTransientType - Windows:
ExcludeClipboardContentFromMonitorProcessing
- Linux:
ClearOnPasteclears the clipboard after the first paste:- Linux:
wl-copy --paste-onceorxclip -loops 1; no-op on xsel - macOS and Windows: not supported
- Linux:
Clear-on-paste only exists where the OS lets a process serve its own clipboard selection on request (Wayland, X11). macOS and Windows hand clipboard content to the OS immediately, with no way to observe a paste, so there's nothing to hook there.
Clearing on a timeout
Klip has no background timer of its own. A library can't safely spawn one that outlives your process without doing something surprising to every program that imports it. Instead:
Clear(cmp ClearComparator) errorandClearAfter(cmp ClearComparator, d time.Duration) errorverify-then-clear, and sleep-then-verify-then-clear. Call these from your own worker process.klip.LaunchDetached(exePath, args, payload) errorspawns that worker as a real detached process that survives your program exiting, deliveringpayloadvia stdin.
Your app registers its own worker entry point (a hidden subcommand, same idea as gopass unclip), calls LaunchDetached right after Write, and has that worker call ClearAfter.
Known gaps
On Linux, KDE's Klipper re-asserts old content after a plain clear. A fix exists but isn't wired in yet: it works by wiping Klipper's entire history, not just the one entry, which isn't always the right tradeoff.
Releases
- : v0.1.1. Breaking change.
- : v0.1.0. First release.