github golang-design/clipboard v0.8.0
v0.8.0 — a community milestone

5 hours ago

v0.8.0 — a community milestone 🎉

This is by far the largest release in the project's history — and it exists because of you. Every feature below started as a community issue, a prototype, a design discussion, or a bug report. Thank you to everyone who reported, proposed, prototyped, reviewed, and pushed for these — your input directly shaped this release. 🙏

Heads up — one breaking change: Watch now returns <-chan Data instead of <-chan []byte. Migration is one line: read data.Bytes (and you can now inspect data.Format).

✨ Highlights

  • Cgo-free on every desktop platform. macOS (purego/Obj-C), Linux/X11, and the BSDs now talk to the OS clipboard with no C toolchain at build time and no libX11/libwayland at runtime (Windows was already Cgo-free). Cross-compiling to desktop "just works." (#69, #25, #55)
  • Native Wayland support. A pure-Go data-control backend (ext-data-control-v1 / zwlr_data_control_manager_v1), event-driven Watch, auto-selected over X11 when available, with XWayland fallback. (#6)
  • Custom, MIME-typed formats. Register(mime) Format + ReadAs[T] give raw, passthrough read/write/watch for any MIME type — no conversion, no new mandatory dependency, no platform detail leaking into your code. (#17, subsumes #40)
  • Clipboard enumeration. Formats() []Format reports what's on the clipboard right now (auto-registering MIME types it discovers), and Format.MIME() tells you what a token is. (#89)
  • Variadic, format-tagged Watch. Watch(ctx, ...Format) <-chan Data watches several formats at once and tags each change with its format (no args watches the built-ins). (#89)
  • Flexible image input. Write(FmtImage, …) now accepts JPEG/GIF/WebP/… (when you blank-import the decoder) and normalizes to canonical PNG; Read(FmtImage) always returns PNG. (#155)

🐛 Fixes

  • Windows: transparent images no longer paste too dark — images are stored/read with straight (non-premultiplied) alpha to match CF_DIBV5. Verified end-to-end via a real Windows consumer in CI. (#105)
  • Windows: 24-bit (and other non-32-bit) DIB images now decode instead of returning nil. (#65)
  • Windows: OpenClipboard no longer busy-waits forever — bounded backoff + timeout when another app holds the clipboard. (#144)
  • Watch no longer leaks — tickers are stopped and the send honors context cancellation. (#153)

📦 Dependencies

  • Adds the first-party, pure-Go X11 codec golang.design/x/x11 v0.2.0 (extracted from this repo; reusable elsewhere).
  • iOS/Android continue to use gomobile (Cgo); mobile keeps text-only support.

🙏 Thanks

This release is the work of many hands. With gratitude to:

…and everyone who joined the discussions, tested pre-release behavior, and filed clear, actionable issues. Thank you all. ❤️

Migration

// Before (v0.7.x):
for data := range clipboard.Watch(ctx, clipboard.FmtText) {
    use(data)            // data was []byte
}

// After (v0.8.0):
for data := range clipboard.Watch(ctx, clipboard.FmtText) {
    use(data.Bytes)      // data is clipboard.Data{Format, Bytes}
}

Full changelog: v0.7.1...v0.8.0

Don't miss a new clipboard release

NewReleases is sending notifications on new releases.