godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.12k stars 69 forks source link

Improve Window file drag-and-drop functionality and user feedback with filter for accepted file types #10178

Open lostminds opened 2 months ago

lostminds commented 2 months ago

Describe the project you are working on

An editor application where I want user to be able to easily import files from the OS file manager

Describe the problem or limitation you are having in your project

There is currently rudimentary file drop support that allows all native windows to support drag and drop of files from the file system. There's no configuration as far as I can tell, all windows just accept dragging files into them, and if you do they emit a files_dropped signal with an array of the paths of the dropped files. So far so good.

The problem is basically that to get a good user experience with this modern drag and drop implementations have multiple feedback-systems to help the user understand what's going on. Typically something like this:

But in the current Godot implementation there is no way of setting what files will be supported for drag, so all files will show the "you can drag them here" cursor, even if they're not supported. And after dropping a file there's no way of reporting if the drop was successful, so all drops (at least on macOS) show as failed, bouncing back to their origin. (EDIT: this incorrect failure drag feedback is now fixed in https://github.com/godotengine/godot/pull/94232)

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Some sort of system to validate what files will be accepted and after dropping what dropped files were successfully dropped.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

A pattern used in other systems to overcome this sort of case is to have delegate methods, basically callables you can set ahead of time that will for example be used to validate if a set of files can be accepted, and return if a drop was successful. The return values of these calls can then be used by the window code to show the appropriate cursor and feedback to the OS systems to show if the drag operation was successful. However, this is not I think a pattern that is used in Godot, so it might not be a good solution.

A much simpler system that might well handle the issues in 90% of the cases could be to introduce a new supported_file_drop_filters property on Window. Similar to the FileDialog filters property, to define what files should be allowed to be dropped in the window.

This filter can then be used first to evaluate if a set of files can be dropped to show the appropriate icon on drag entry of the window. And then the same filter can just be used and report back that the drop was successful if it's a matching file and unsuccessful if not.

The default value of the filter could just be * to match all files to retail backwards compatibility. As a bonus feature this filter could also be used to set a filter disabling all file drops into the window by setting it to "", something that is also not possible right now.

If this enhancement will not be used often, can it be worked around with a few lines of script?

No, as the OS drag operation validation happens in the core somewhere

Is there a reason why this should be core and not an add-on in the asset library?

Windows and OS interactions are part of the core

lostminds commented 2 months ago

If we can now detect if a signal has any connections to it, an alternative/complementary improvement could be to validate if a window should accept any file drops by checking if anything is connected to the files_dropped signal on the window. As if there isn't this means the files will at least not be used.