Fix #135672: Ghost: Prefer CF_HDROP ahead of CF_TEXT during drag'n'drop

When a user starts a drag'n'drop operation, the originating application
dictates the formats carried along with it. In the context of what is
broadly supported by Blender, we actively look for "text" and "files" in
the data. In that order. This order sometimes leads to a suboptimal
choice where, for example, a drag'n'drop of a "file" is interpreted as
"text" containing just the path to the file.

This PR changes the ordering to prefer the "files" first. Two notable
applications where this matters are:
 - The Firefox download library window
 - The Perforce P4V client application

Dragging and dropping files, like say FBX or OBJ, from these two apps
now properly triggers file handler behavior. Existing behavior is best
seen in the Blender Text editor. Dragging and dropping a file from the
above apps into a Text data block will yield the raw "file:///test.ext"
text. This will no longer occur after this PR.

Other platforms might have similar concepts but I don't have the
capability of checking how they handle this type of situation. They
would have to be checked against several applications to see if they
have the same issue.

Pull Request: https://projects.blender.org/blender/blender/pulls/135939
This commit is contained in:
Jesse Yurkovich
2025-03-20 19:23:52 +01:00
committed by Jesse Yurkovich
parent 7e70e93345
commit b030acbe9d

View File

@@ -161,21 +161,22 @@ DWORD GHOST_DropTargetWin32::allowedDropEffect(DWORD dw_allowed)
GHOST_TDragnDropTypes GHOST_DropTargetWin32::getGhostType(IDataObject *p_data_object)
{
/* File-names. Prefer looking for the CF_HDROP data format first as certain file-manager
* applications send CF_TEXT as well. See issue #135672. */
FORMATETC fmtetc = {CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
if (p_data_object->QueryGetData(&fmtetc) == S_OK) {
return GHOST_kDragnDropTypeFilenames;
}
/* Text
* NOTE: Unicode text is available as CF_TEXT too, the system can do the
* conversion, but we do the conversion our self with #WC_NO_BEST_FIT_CHARS.
*/
FORMATETC fmtetc = {CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
fmtetc.cfFormat = CF_TEXT;
if (p_data_object->QueryGetData(&fmtetc) == S_OK) {
return GHOST_kDragnDropTypeString;
}
/* Files-names. */
fmtetc.cfFormat = CF_HDROP;
if (p_data_object->QueryGetData(&fmtetc) == S_OK) {
return GHOST_kDragnDropTypeFilenames;
}
return GHOST_kDragnDropTypeUnknown;
}