Repository navigation
desktop_drop: add typed async drops and iOS support over shared FFI - #523
Merged
Merged
Conversation
Select destinations through Flutter hit testing and check acceptance again before delivery. Use a shared FFI bridge for synchronous macOS and Windows decisions, asynchronous GTK queries, and synchronous browser feedback. Preserve platform file handling and add independent example destinations with an inspector. Require onWillAccept and Flutter 3.47.7 / Dart 3.13.5; release metadata remains unchanged.
This was referenced Oct 15, 2026
Closed
Remove cross_file and keep metadata plus read/save methods on DropItem. Preserve original browser Blobs and stream bounded slices instead of re-fetching object URLs. Materialize accepted image data/src URLs with browser CORS handling, capture drag events before descendant bubbling handlers, and document secondary-engine registration and remaining host-specific regression cases. Refs #315, #339, #506, #196, #421, #219, #368, #260. Local validation was limited to formatting and static analysis; runtime regression remains pending.
Avoid fetching an already available data URL and align the browser regression with the widget test event loop. Clamp file read ranges at EOF consistently with native streams.
Delegate filesystem and retained browser Blob reads to XFile while preserving synchronous drag metadata, byte-backed constructors, empty ranges, and saveTo. Replace fixed browser chunk assertions with content checks and document the updated dependency.
Forward accepted and rejected OLE drag events to IDropTargetHelper using screen coordinates and the existing target decision. Clear the helper on leave, drop, and shutdown while keeping drag acceptance independent of optional Shell image support.
Expose typed file, directory, and string items with per-target operation decisions. Scope provider resources to asynchronous onDrop callbacks, preserve view-level bridges, and cache hover metadata. Use one shared native FFI transport in src and shared Darwin code for macOS and iOS. Preserve lazy promise reception, capture synchronous Windows virtual content, and delegate filesystem reads to XFile and XDirectory. Update the example to consume content during drop, normalize missing file MIME types, remove unused protocols and bindings, and centralize Linux cleanup.
UIKit supplies readable item providers at release even when drag item identities are unchanged. Refresh the cached offer before accepting the drop so files from Photos and Files can be loaded. Add an iOS regression test that replaces the provider between hover and drop. Verified the test fails before the fix and passes afterward; manually verified Photos and Files drops on the iPad simulator.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Let each DropTarget choose reject/copy/move/link through Flutter hit testing, then consume typed file, directory, and string items in an asynchronous onDrop callback. Provider resources remain available until that callback completes, including when its widget unmounts.
Closes #2, closes #68, closes #174, closes #243, closes #305, closes #389, closes #502, closes #196, closes #219, closes #260, closes #339, closes #368, closes #506.
Related reports that remain open: #315 (URL-only browser image drags are delivered as strings rather than downloaded files), #421 (the reported production TypeError still needs reproduction), #386, #299, #346, #373, #394, and #382. These are not claimed fixed by this PR.
Evidence
After: The shared selection path chooses a target and operation, delivers typed items, awaits onDrop, and releases provider resources. Compact hover updates reuse the cached offer.
Merge Danger
Door: two-way
Source changes can be reverted. No release, version bump, or data migration is included.
Blast Radius: desktop_drop
Breaking API: required onDropDecision replaces onWillAccept, async onDrop replaces onDragDone, and typed DropItem representations expose XFile/XDirectory instead of the former file wrappers. Provider-backed content must be consumed during onDrop; event disposal and byte-backed constructors are removed. URL-only image representations are no longer automatically downloaded. The minimum SDKs are Flutter 3.47.7 / Dart 3.13.5. Native acknowledgement can precede application completion on platforms whose source protocol cannot defer it; iOS and Android offer copy only.