Bug 1958096 - Prefer files over images for CF_HDROP drag and drop on Windows a=RyanVM

When dropping an image over Total Commander, we first offer a .png file
regardless of the source image type, which requires converting to .png
and losing the original file name. Instead, if an application requests
CF_HDROP (which represents an existing file), prefer a file or file promise
if the nsDataObj has one, and only fall back to a native image if it does
not.

Original Revision: https://phabricator.services.mozilla.com/D253035

Differential Revision: https://phabricator.services.mozilla.com/D258413
This commit is contained in:
Greg Stoll
2025-07-23 14:40:08 +00:00
committed by rvandermeulen@mozilla.com
parent 99b2c5786c
commit 8fca93d6ba

View File

@@ -1588,20 +1588,46 @@ HRESULT nsDataObj::GetText(const nsACString& aDataFlavor, FORMATETC& aFE,
//----------------------------------------------------- //-----------------------------------------------------
HRESULT nsDataObj::GetFile(FORMATETC& aFE, STGMEDIUM& aSTG) { HRESULT nsDataObj::GetFile(FORMATETC& aFE, STGMEDIUM& aSTG) {
uint32_t dfInx = 0;
ULONG count; ULONG count;
FORMATETC fe; FORMATETC fe;
// We want to prefer kFileMime over kFilePromiseMime, and only
// fall back to kNativeImageMime if neither of those are present, since
// kNativeImageMime isn't really a file and we'll have to convert it to
// either PNG or BMP regardless of the original format.
enum class FlavorType : uint8_t {
eNone = 0,
eNativeImageMime = 1,
eFilePromiseMime = 2,
eFileMime = 3,
};
FlavorType flavorType = FlavorType::eNone;
m_enumFE->Reset(); m_enumFE->Reset();
while (NOERROR == m_enumFE->Next(1, &fe, &count) && for (const auto& dataFlavor : mDataFlavors) {
dfInx < mDataFlavors.Length()) { if (m_enumFE->Next(1, &fe, &count) != NOERROR) {
if (mDataFlavors[dfInx].EqualsLiteral(kNativeImageMime)) break;
return DropImage(aFE, aSTG); }
if (mDataFlavors[dfInx].EqualsLiteral(kFileMime))
return DropFile(aFE, aSTG); if (dataFlavor.EqualsLiteral(kFileMime)) {
if (mDataFlavors[dfInx].EqualsLiteral(kFilePromiseMime)) flavorType = std::max(FlavorType::eFileMime, flavorType);
return DropTempFile(aFE, aSTG); } else if (dataFlavor.EqualsLiteral(kFilePromiseMime)) {
dfInx++; flavorType = std::max(FlavorType::eFilePromiseMime, flavorType);
} else if (dataFlavor.EqualsLiteral(kNativeImageMime)) {
flavorType = std::max(FlavorType::eNativeImageMime, flavorType);
}
} }
switch (flavorType) {
case FlavorType::eFileMime:
return DropFile(aFE, aSTG);
case FlavorType::eFilePromiseMime:
return DropTempFile(aFE, aSTG);
case FlavorType::eNativeImageMime:
return DropImage(aFE, aSTG);
case FlavorType::eNone:
return E_FAIL;
}
MOZ_ASSERT_UNREACHABLE("Unexpected flavor type");
return E_FAIL; return E_FAIL;
} }