feat(clipboard): pass original JPEG/GIF through verbatim beside the PNG floor
android / android (push) Has been cancelled
audit / bun-audit (push) Successful in 14s
audit / cargo-audit (push) Successful in 2m29s
ci / web (push) Successful in 50s
ci / docs-site (push) Successful in 54s
decky / build-publish (push) Successful in 30s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 18s
apple / swift (push) Successful in 1m23s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 12s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 13s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 12s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 11s
ci / bench (push) Successful in 5m58s
ci / rust (push) Failing after 6m54s
release / apple (push) Successful in 5m52s
arch / build-publish (push) Failing after 11m7s
flatpak / build-publish (push) Failing after 8m7s
deb / build-publish (push) Successful in 13m52s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 14m31s
docker / deploy-docs (push) Successful in 24s
apple / screenshots (push) Successful in 6m28s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 18m5s
windows-host / package (push) Has been cancelled
windows-msix / package (arm64, C:\Users\Public\ffmpeg-arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (push) Has been cancelled
windows-msix / package (x64, C:\Users\Public\ffmpeg, , x86_64-pc-windows-msvc, C:\t) (push) Has been cancelled
windows / build (aarch64-pc-windows-msvc) (push) Has been cancelled
windows / build (x86_64-pc-windows-msvc) (push) Has been cancelled
android / android (push) Has been cancelled
audit / bun-audit (push) Successful in 14s
audit / cargo-audit (push) Successful in 2m29s
ci / web (push) Successful in 50s
ci / docs-site (push) Successful in 54s
decky / build-publish (push) Successful in 30s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 18s
apple / swift (push) Successful in 1m23s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 12s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 13s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 12s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 11s
ci / bench (push) Successful in 5m58s
ci / rust (push) Failing after 6m54s
release / apple (push) Successful in 5m52s
arch / build-publish (push) Failing after 11m7s
flatpak / build-publish (push) Failing after 8m7s
deb / build-publish (push) Successful in 13m52s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 14m31s
docker / deploy-docs (push) Successful in 24s
apple / screenshots (push) Successful in 6m28s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 18m5s
windows-host / package (push) Has been cancelled
windows-msix / package (arm64, C:\Users\Public\ffmpeg-arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (push) Has been cancelled
windows-msix / package (x64, C:\Users\Public\ffmpeg, , x86_64-pc-windows-msvc, C:\t) (push) Has been cancelled
windows / build (aarch64-pc-windows-msvc) (push) Has been cancelled
windows / build (x86_64-pc-windows-msvc) (push) Has been cancelled
Transcoding every image to PNG was the Phase-1 floor, but it bloats lossy originals (a copied JPEG re-encoded lossless is 5-10x the bytes for zero quality gain — feeding the render-timeout on constrained links) and flattens GIFs to one frame. The wire already carries kind LISTS, so offer the original format beside the portable fallback and let the destination pick: - New wire kinds image/jpeg + image/gif (§3.5 extension; strings only, no protocol change). image/png stays the universal floor every peer accepts. - macOS: public.jpeg / com.compuserve.gif rows pass through verbatim both directions; the PNG floor is announced whenever any image is present. - Windows: registered JFIF/GIF formats read + promised verbatim; every image offer still promises CF_DIB, whose delayed render now fetches the richest offered kind (png > jpeg > gif) through the generalized image_to_dib. - Linux maps gain the matching rows (native MIME pass-through). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -29,6 +29,11 @@ public final class ClipboardSync: NSObject {
|
||||
("text/rtf", .rtf),
|
||||
("text/html", .html),
|
||||
("image/png", .png),
|
||||
// Original image formats pass through VERBATIM beside the PNG floor — a copied JPEG
|
||||
// never balloons into PNG, a GIF keeps its animation; the destination picks the richest
|
||||
// kind it can place.
|
||||
("image/jpeg", NSPasteboard.PasteboardType("public.jpeg")),
|
||||
("image/gif", NSPasteboard.PasteboardType("com.compuserve.gif")),
|
||||
]
|
||||
/// Pasteboard marker types that must never cross the wire (password managers mark secrets
|
||||
/// with these — see nspasteboard.org).
|
||||
@@ -205,11 +210,14 @@ public final class ClipboardSync: NSObject {
|
||||
var kinds = Self.wireToPasteboard
|
||||
.filter { types.contains($0.type) }
|
||||
.map { PunktfunkConnection.ClipKind(mime: $0.wire) }
|
||||
// Images: macOS image copies usually carry TIFF (browsers add WebP/AVIF/GIF, screenshots
|
||||
// TIFF) and only sometimes PNG — announce the portable `image/png` whenever ANY
|
||||
// convertible image type is present; `serveFetch` converts at fetch time (lazy, §3.5).
|
||||
// PNG floor: announce the portable `image/png` whenever ANY convertible image is present
|
||||
// — native PNG, TIFF/HEIC (screenshots, Preview), or a JPEG/GIF original already being
|
||||
// offered verbatim above. `readWireData` converts at fetch time (lazy, §3.5), so the
|
||||
// fallback costs nothing unless a peer actually pastes it.
|
||||
if !kinds.contains(where: { $0.mime == "image/png" }),
|
||||
types.contains(.tiff) || types.contains(NSPasteboard.PasteboardType("public.heic"))
|
||||
types.contains(.tiff)
|
||||
|| types.contains(NSPasteboard.PasteboardType("public.heic"))
|
||||
|| kinds.contains(where: { $0.mime.hasPrefix("image/") })
|
||||
{
|
||||
kinds.append(PunktfunkConnection.ClipKind(mime: "image/png"))
|
||||
}
|
||||
@@ -385,6 +393,8 @@ private final class RemoteOfferProvider: NSObject, NSPasteboardItemDataProvider
|
||||
case .rtf: return "text/rtf"
|
||||
case .html: return "text/html"
|
||||
case .png: return "image/png"
|
||||
case NSPasteboard.PasteboardType("public.jpeg"): return "image/jpeg"
|
||||
case NSPasteboard.PasteboardType("com.compuserve.gif"): return "image/gif"
|
||||
default: return nil
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user