Skip to content

fix(macos): use modern pasteboard API for drag-drop file collection#1723

Open
vdavid wants to merge 1 commit into
tauri-apps:devfrom
vdavid:fix/macos-drag-drop-modern-pasteboard
Open

fix(macos): use modern pasteboard API for drag-drop file collection#1723
vdavid wants to merge 1 commit into
tauri-apps:devfrom
vdavid:fix/macos-drag-drop-modern-pasteboard

Conversation

@vdavid
Copy link
Copy Markdown

@vdavid vdavid commented May 5, 2026

On macOS, collect_paths reads dragged file paths from the deprecated NSFilenamesPboardType only. When the drag source publishes only the modern per-item public.file-url type (the standard for NSDraggingItem.initWithPasteboardWriter: with NSPasteboardItem), availableTypeFromArray: reports the legacy type as derivable but propertyListForType: returns nil, hitting an unwrap and panicking the whole webview process.

This switches collect_paths to the modern NSPasteboard.readObjectsForClasses:options: API with NSURL, which covers both legacy and modern sources in one call. The legacy NSFilenamesPboardType branch is kept as a defensive fallback in case readObjectsForClasses:options: returns nothing on some configuration. No unwrap calls anywhere in the new code — every fallible conversion skips the entry instead of panicking.

Test plan

I did these:

  • Ran cargo build and cargo test on aarch64-apple-darwin and x86_64-apple-darwin, with default features, --all-features, and --no-default-features --features os-webview. All combinations: 8 unit tests + 6–7 doc tests passed, 0 failed.
  • Ran cargo clippy --all-targets --all-features, it's clean (existing unrelated examples/gtk_opengl.rs unused-import warnings only, present on dev since docs: add gtk opengl triangle example #1682).
  • Ran cargo fmt --all -- --check clean.
  • End-to-end validated against Cmdr (my file manager), which is the real-world drag source that triggered this bug. With Cmdr publishing only modern per-item public.file-url types (no NSFilenamesPboardType), self-drag re-entry into the wry webview no longer panics — the readObjectsForClasses: path returns the URLs and collect_paths yields the expected Vec<PathBuf>.

Switch `collect_paths` to `NSPasteboard.readObjectsForClasses:options:` with
`NSURL`, which covers both legacy `NSFilenamesPboardType` and the modern
per-item `public.file-url` type (the standard for sources using
`NSDraggingItem.initWithPasteboardWriter:` with `NSPasteboardItem`).

This also removes the panic when the source publishes only the modern type:
`availableTypeFromArray:` reported the legacy type was derivable but
`propertyListForType:` returned nil, hitting an `unwrap` and crashing the
webview process. The new code has no `unwrap` calls — failures skip the
entry.

The legacy `NSFilenamesPboardType` branch is kept as a defensive fallback.
@vdavid vdavid requested a review from a team as a code owner May 5, 2026 13:03
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 5, 2026

Package Changes Through 545b7ab

There are 1 changes which include wry with minor

Planned Package Versions

The following package releases are the planned based on the context of changes in this pull request.

package current next
wry 0.55.1 0.56.0

Add another change file through the GitHub UI by following this link.


Read about change files or the docs at github.com/jbolda/covector

vdavid added a commit to vdavid/cmdr that referenced this pull request May 6, 2026
- New `native_drag.rs` builds `NSPasteboardItem`s vending `public.file-url`,
  `public.utf8-plain-text` (joined paths on item 0), and `NSFilenamesPboardType`
  (legacy, for stock wry until tauri-apps/wry#1723 ships)
- Permissive op mask (Copy|Link|Generic|Move) so terminals like Warp accept
  the drop instead of rejecting it; macOS arbitrates the actual op via
  modifier keys natively
- Drops `drag` + `tauri-plugin-drag` Rust deps and `@crabnebula/tauri-plugin-drag`
  JS dep; both drag-out paths (single-file and multi-file selection) now route
  through `native_drag.rs` via `start_drag_paths` / `start_selection_drag`
- Removes the `mode` parameter from drag IPC end-to-end — modifier handling
  belongs in the OS, not at drag-start
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants