Skip to content

Consider multi-representation pasteboard writes for broader app compatibility #11

Description

@chigichan24

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:

  1. Default behavior remains raw passthrough (security-first)
  2. --compat would load data via NSImage(data:), obtain tiffRepresentation, and write both original format + TIFF
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions