Skip to content

[Catalyst,Windows] Allow drag item from outside the app#21684

Merged
rmarinho merged 5 commits into
mainfrom
fix-6080
Apr 11, 2024
Merged

[Catalyst,Windows] Allow drag item from outside the app#21684
rmarinho merged 5 commits into
mainfrom
fix-6080

Conversation

@rmarinho
Copy link
Copy Markdown
Member

@rmarinho rmarinho commented Apr 6, 2024

Description of Change

Seems we can allow the DropGestureRecognizer to work with an item being dragged from outside of our application, like drop a file into the .NET MAUI app and process it.
This does make the experience perfect but unblocks ours users to use the Drop gesture.

Not sure how we test this, I added a sample page that allows to show the path of the file dragged. we can add more logic to this .

I used some sample code from @drasticactions for the native parte..

Issues Fixed

Fixes #6080

@rmarinho rmarinho changed the title [Catalyst] Allow drag item from outside the app [Catalyst,Windows] Allow drag item from outside the app Apr 7, 2024
@rmarinho rmarinho marked this pull request as ready for review April 7, 2024 00:09
@rmarinho rmarinho requested a review from a team as a code owner April 7, 2024 00:09
@samhouts samhouts added this to the Under Consideration milestone Apr 9, 2024
@jsuarezruiz jsuarezruiz added platform/macos macOS / Mac Catalyst platform/windows area-gestures Gesture types labels Apr 9, 2024
@mattleibow
Copy link
Copy Markdown
Member

Do you know if this will work in iOS? I think they had some way you can drag things from outside the app.

Comment thread src/Controls/samples/Controls.Sample.Sandbox/MauiProgram.cs
#if WINDOWS
if (e.PlatformArgs is not null && e.PlatformArgs.DragEventArgs.DataView.Contains(StandardDataFormats.StorageItems))
{
var items = await e.PlatformArgs.DragEventArgs.DataView.GetStorageItemsAsync();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doe this work in unpackaged? Not sure how all the storage APIs work.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me test and see..

@rmarinho
Copy link
Copy Markdown
Member Author

rmarinho commented Apr 9, 2024

Do you know if this will work in iOS? I think they had some way you can drag things from outside the app.

Yeah I didn't test on iOS , I saw and hit myself this issue when writing a desktop app.

@drasticactions
Copy link
Copy Markdown
Contributor

Do you know if this will work in iOS? I think they had some way you can drag things from outside the app.

(I have not tested this PR yet nor reviewed it)

You can drag and drop from outside apps to another app on iOS, on both iPad and iPhone. On iPad, you can do it via split view. On iPhone, it's more complicated: You need to drag the item, go into multitasking mode (while holding the item with your finger), go to the other app, and drop it in the supported view. I doubt many apps actually support that since it's such a pain to do, but it is doable.

The API is the same as Catalyst so it "should" work as is. Again, I have not tested this PR yet., but it should work, and if not... then we should make it work ;).


}
}
#elif MACCATALYST
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works with iOS, so you can enable it here.

Copy link
Copy Markdown
Contributor

@drasticactions drasticactions left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tried it on Mac Catalyst and iOS and worked as expected in both. (To try this with iOS, you need to have an app that can drag items out of it, like Files or Photos, and drag them to the drop target in your app.

@rmarinho rmarinho merged commit 478f174 into main Apr 11, 2024
@rmarinho rmarinho deleted the fix-6080 branch April 11, 2024 11:48
@showtroylove
Copy link
Copy Markdown

Description of Change

Seems we can allow the DropGestureRecognizer to work with an item being dragged from outside of our application, like drop a file into the .NET MAUI app and process it. This does make the experience perfect but unblocks ours users to use the Drop gesture.

Not sure how we test this, I added a sample page that allows to show the path of the file dragged. we can add more logic to this .

I used some sample code from @drasticactions for the native parte..

Issues Fixed

Fixes #6080

I don't understand the remarks made regarding this fix. Can you please kindly explain?

@rmarinho
Copy link
Copy Markdown
Member Author

Hey @showtroylove the fix unblocks the crash and users reporting DropGesture not working when dragging something from outside, but the experience for example of providing coordinates a custom drag template etc might not work so that's why I say the experience is not perfect.

@BrandonStudio
Copy link
Copy Markdown

Which version will these changes be available?

@rmarinho
Copy link
Copy Markdown
Member Author

This should be right now in our nightly feed. Do you mind testing it? Thanks

@showtroylove
Copy link
Copy Markdown

@rmarinho, I cannot get this to function using the nightly feed as suggested (i.e., 8.0.21). The drag and drag leave triggers, but the drop is nonresponsive. It doesn't appear to even have a handler when registering one in the XAML

This should be right now in our nightly feed. Do you mind testing it? Thanks

@showtroylove
Copy link
Copy Markdown

using Operation = Microsoft.Maui.Controls.DataPackageOperation;
using WinOperation = Windows.ApplicationModel.DataTransfer.DataPackageOperation;

public partial class MainPage : ContentPage
{
:

private void OnDragOver(object? sender, DragEventArgs e) => Debug.WriteLine($"Dragging {e.Data?.Text}, {e.Data?.Image}");
private void OnDragLeave(object? sender, DragEventArgs e) => DropZonColor = Colors.Transparent;

protected async Task OnDropImpl(DropEventArgs e)
{
    var args = e.PlatformArgs!.DragEventArgs;
    var dv = e.PlatformArgs!.DragEventArgs.DataView;
    if (!dv.Contains(StandardDataFormats.StorageItems))
    {
        args.AcceptedOperation = WinOperation.None;
        return;
    }

    args.AcceptedOperation = WinOperation.Copy;

    var items = await dv.GetStorageItemsAsync();
    List<FileResult> filePaths = [];
    items.OfType<StorageFile>().ToList().ForEach(f => filePaths.Add(new(f.Path)));

    if (filePaths.Count > 0)
    {
        DragImage = filePaths.First().FullPath;
        e.Handled = true;
    }
    else
        args.AcceptedOperation = WinOperation.None;

    DropZonColor = Colors.Transparent;
}

private async void OnDropTarget(object? sender, DropEventArgs e) => await OnDropImpl(e);

}
`

@rmarinho
Copy link
Copy Markdown
Member Author

can you post a repo link and I can take a look please? thanks

@showtroylove
Copy link
Copy Markdown

showtroylove commented Apr 20, 2024 via email

@showtroylove
Copy link
Copy Markdown

I've had success with @drasticactions' drag and drop sample code found on GitHub. However, it seems his code isn't compatible with the in-app drag and drop features (e.g., DragGestureRecognizer, DropGestureRecognizers, etc.). What's more, his code appears to be affected by the https://github.com/dotnet/maui/issues/16919 known issue and other issues I've corrected related to iOS. Additionally, there appears to be no implementation for Android.

@github-actions github-actions Bot locked and limited conversation to collaborators May 25, 2024
@samhouts samhouts removed this from the Under Consideration milestone Jul 1, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MAUI can't get file data from Windows Explorer by Drag&Drop and app will crash

7 participants