Background
Currently, PasteboardWriter writes image data to the pasteboard with a single UTI type. For example, when copying a PNG, only public.png is set via pasteboard.setData(data, forType: .png).
macOS has a long-standing convention where clipboard image data is provided in multiple representations simultaneously. When you copy an image from Preview, Finder, or Safari, the pasteboard typically contains:
public.tiff (TIFF) — the historical "lingua franca" of macOS image clipboard
public.png (PNG)
com.adobe.pdf (PDF) — sometimes
- File URL — if applicable
This convention dates back to the NeXTSTEP/Cocoa origins of macOS, where TIFF was the native image interchange format. Many older or Carbon-based applications historically checked only for public.tiff on the pasteboard.
Current Behavior
xpbc writes exactly one UTI type per copy operation. This is a direct consequence of the "no image decoding" security principle — raw bytes are passed through without conversion.
Practical Impact
Low in most real-world scenarios. Modern macOS apps (macOS 13+) handle single-format pasteboard data correctly:
NSImage(pasteboard:) recognizes public.png, public.jpeg, com.compuserve.gif, etc. directly — TIFF is not required
- Electron-based apps (Slack, VS Code, Notion) check for
public.png among other types
- Apple's own apps (TextEdit, Pages, Notes, Mail) use
NSImage(pasteboard:) or readObjects(forClasses:) which support all standard image UTIs
The only apps that might fail are very old Carbon-based applications that exclusively look for public.tiff, which are increasingly rare on modern macOS.
Technical Constraint
True multi-representation writes without image decoding are impossible for cross-format types. You cannot write PNG raw bytes under the public.tiff UTI — the receiving app would attempt to decode the bytes as TIFF and fail. Multi-representation requires converting the image data via NSImage(data:) → tiffRepresentation, which means invoking ImageIO's decoder — exactly what xpbc's security model avoids.
Possible Approach
If real-world compatibility issues are reported, a --compat flag could opt into NSImage-based conversion:
- Default behavior remains raw passthrough (security-first)
--compat would load data via NSImage(data:), obtain tiffRepresentation, and write both original format + TIFF
- The security trade-off would be clearly documented
Status
No action needed at this time. This issue is filed to document the design decision and trade-off. If users report paste failures in specific applications, this issue can be revisited.
Background
Currently,
PasteboardWriterwrites image data to the pasteboard with a single UTI type. For example, when copying a PNG, onlypublic.pngis set viapasteboard.setData(data, forType: .png).macOS has a long-standing convention where clipboard image data is provided in multiple representations simultaneously. When you copy an image from Preview, Finder, or Safari, the pasteboard typically contains:
public.tiff(TIFF) — the historical "lingua franca" of macOS image clipboardpublic.png(PNG)com.adobe.pdf(PDF) — sometimesThis convention dates back to the NeXTSTEP/Cocoa origins of macOS, where TIFF was the native image interchange format. Many older or Carbon-based applications historically checked only for
public.tiffon the pasteboard.Current Behavior
xpbc writes exactly one UTI type per copy operation. This is a direct consequence of the "no image decoding" security principle — raw bytes are passed through without conversion.
Practical Impact
Low in most real-world scenarios. Modern macOS apps (macOS 13+) handle single-format pasteboard data correctly:
NSImage(pasteboard:)recognizespublic.png,public.jpeg,com.compuserve.gif, etc. directly — TIFF is not requiredpublic.pngamong other typesNSImage(pasteboard:)orreadObjects(forClasses:)which support all standard image UTIsThe only apps that might fail are very old Carbon-based applications that exclusively look for
public.tiff, which are increasingly rare on modern macOS.Technical Constraint
True multi-representation writes without image decoding are impossible for cross-format types. You cannot write PNG raw bytes under the
public.tiffUTI — the receiving app would attempt to decode the bytes as TIFF and fail. Multi-representation requires converting the image data viaNSImage(data:)→tiffRepresentation, which means invoking ImageIO's decoder — exactly what xpbc's security model avoids.Possible Approach
If real-world compatibility issues are reported, a
--compatflag could opt intoNSImage-based conversion:--compatwould load data viaNSImage(data:), obtaintiffRepresentation, and write both original format + TIFFStatus
No action needed at this time. This issue is filed to document the design decision and trade-off. If users report paste failures in specific applications, this issue can be revisited.