commit db07192845a839032697001b9cafeeab86c27db8
parent b7429b0fcf1014d7d930342d3348f64f11172726
Author: Stephen A Pohl <spohl@mozilla.com>
Date: Thu, 11 Dec 2025 17:16:44 +0000
Bug 1986071: Only provide the data for the data type requested by macOS during a drag operation. r=mstange
Differential Revision: https://phabricator.services.mozilla.com/D262882
Diffstat:
2 files changed, 92 insertions(+), 114 deletions(-)
diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm
@@ -154,8 +154,6 @@ static void RollUpPopups(nsIRollupListener::AllowAnimations aAllowAnimations =
}
extern nsIArray* gDraggedTransferables;
-extern bool gCreatedFileForFileURL;
-extern bool gCreatedFileForFilePromise;
ChildView* ChildViewMouseTracker::sLastMouseEventView = nil;
NSEvent* ChildViewMouseTracker::sLastMouseMoveEvent = nil;
NSWindow* ChildViewMouseTracker::sWindowUnderMouse = nil;
@@ -3896,129 +3894,115 @@ static NSURL* GetPasteLocation(NSPasteboard* aPasteboard, bool aUseFallback) {
// Transform the transferable to an NSDictionary.
NSDictionary* pasteboardOutputDict =
nsClipboard::PasteboardDictFromTransferable(currentTransferable);
- if (!pasteboardOutputDict) {
+ if (!pasteboardOutputDict || ![pasteboardOutputDict objectForKey:aType]) {
return;
}
- // Write everything out to the pasteboard.
- unsigned int typeCount = [pasteboardOutputDict count];
- NSMutableArray* types = [NSMutableArray arrayWithCapacity:typeCount + 1];
- [types addObjectsFromArray:[pasteboardOutputDict allKeys]];
- [types addObject:[UTIHelper stringFromPboardType:kMozWildcardPboardType]];
- for (unsigned int k = 0; k < typeCount; k++) {
- NSString* curType = [types objectAtIndex:k];
- if ([curType isEqualToString:[UTIHelper stringFromPboardType:
- NSPasteboardTypeString]] ||
- [curType
- isEqualToString:[UTIHelper
- stringFromPboardType:kPublicUrlPboardType]] ||
- [curType isEqualToString:[UTIHelper stringFromPboardType:
- kPublicUrlNamePboardType]] ||
- ([curType
- isEqualToString:[UTIHelper
- stringFromPboardType:(NSString*)
- kUTTypeFileURL]] &&
- ![[pasteboardOutputDict valueForKey:curType] isEqualToString:@""])) {
- [aPasteboard setString:[pasteboardOutputDict valueForKey:curType]
- forType:curType];
- } else if (([curType
- isEqualToString:[UTIHelper
- stringFromPboardType:
- (NSString*)kUTTypeFileURL]] &&
- !gCreatedFileForFileURL) ||
- ([curType
- isEqualToString:
+ if ([aType
+ isEqualToString:[UTIHelper
+ stringFromPboardType:NSPasteboardTypeString]] ||
+ [aType
+ isEqualToString:[UTIHelper
+ stringFromPboardType:kPublicUrlPboardType]] ||
+ [aType isEqualToString:
+ [UTIHelper stringFromPboardType:kPublicUrlNamePboardType]] ||
+ ([aType isEqualToString:[UTIHelper
+ stringFromPboardType:(NSString*)
+ kUTTypeFileURL]] &&
+ ![[pasteboardOutputDict valueForKey:aType] isEqualToString:@""])) {
+ [aPasteboard setString:[pasteboardOutputDict valueForKey:aType]
+ forType:aType];
+ } else if ([aType
+ isEqualToString:[UTIHelper stringFromPboardType:
+ (NSString*)kUTTypeFileURL]] ||
+ [aType isEqualToString:
[UTIHelper
stringFromPboardType:
- (NSString*)kPasteboardTypeFileURLPromise]] &&
- !gCreatedFileForFilePromise)) {
- NSURL* url = GetPasteLocation(
- aPasteboard,
- [curType
- isEqualToString:[UTIHelper
- stringFromPboardType:(NSString*)
- kUTTypeFileURL]]);
- nsCOMPtr<nsILocalFileMac> macLocalFile;
- if (NS_FAILED(NS_NewLocalFileWithCFURL((__bridge CFURLRef)url,
- getter_AddRefs(macLocalFile)))) {
- NS_ERROR("failed NS_NewLocalFileWithCFURL");
- continue;
- }
+ (NSString*)kPasteboardTypeFileURLPromise]]) {
+ NSURL* url = GetPasteLocation(
+ aPasteboard,
+ [aType isEqualToString:[UTIHelper
+ stringFromPboardType:(NSString*)
+ kUTTypeFileURL]]);
+ nsCOMPtr<nsILocalFileMac> macLocalFile;
+ if (NS_FAILED(NS_NewLocalFileWithCFURL((__bridge CFURLRef)url,
+ getter_AddRefs(macLocalFile)))) {
+ NS_ERROR("failed NS_NewLocalFileWithCFURL");
+ continue;
+ }
- if (!gDraggedTransferables) {
- continue;
- }
+ if (!gDraggedTransferables) {
+ continue;
+ }
- uint32_t transferableCount;
- nsresult rv = gDraggedTransferables->GetLength(&transferableCount);
- if (NS_FAILED(rv)) {
+ uint32_t transferableCount;
+ nsresult rv = gDraggedTransferables->GetLength(&transferableCount);
+ if (NS_FAILED(rv)) {
+ continue;
+ }
+
+ for (uint32_t i = 0; i < transferableCount; i++) {
+ nsCOMPtr<nsITransferable> item =
+ do_QueryElementAt(gDraggedTransferables, i);
+ if (!item) {
+ NS_ERROR("no transferable");
continue;
}
- for (uint32_t i = 0; i < transferableCount; i++) {
- nsCOMPtr<nsITransferable> item =
- do_QueryElementAt(gDraggedTransferables, i);
- if (!item) {
- NS_ERROR("no transferable");
- continue;
- }
+ item->SetTransferData(kFilePromiseDirectoryMime, macLocalFile);
- item->SetTransferData(kFilePromiseDirectoryMime, macLocalFile);
+ // Now request the kFilePromiseMime data, which will invoke the data
+ // provider. If successful, the file will have been created.
+ nsCOMPtr<nsISupports> fileDataPrimitive;
+ if (NS_FAILED(item->GetTransferData(
+ kFilePromiseMime, getter_AddRefs(fileDataPrimitive)))) {
+ continue;
+ }
- // Now request the kFilePromiseMime data, which will invoke the data
- // provider. If successful, the file will have been created.
- nsCOMPtr<nsISupports> fileDataPrimitive;
- if (NS_FAILED(item->GetTransferData(
- kFilePromiseMime, getter_AddRefs(fileDataPrimitive)))) {
+ if ([aType
+ isEqualToString:[UTIHelper
+ stringFromPboardType:(NSString*)
+ kUTTypeFileURL]]) {
+ // In case of a file URL we need to populate the pasteboard with the
+ // path to the file.
+ nsCOMPtr<nsIFile> file = do_QueryInterface(fileDataPrimitive);
+ if (!file) {
continue;
}
-
- if ([curType
- isEqualToString:[UTIHelper stringFromPboardType:
- (NSString*)kUTTypeFileURL]]) {
- // In case of a file URL we need to populate the pasteboard with the
- // path to the file.
- nsCOMPtr<nsIFile> file = do_QueryInterface(fileDataPrimitive);
- if (!file) {
- continue;
- }
- nsAutoCString finalPath;
- file->GetNativePath(finalPath);
- NSString* filePath =
- [NSString stringWithUTF8String:(const char*)finalPath.get()];
- [aPasteboard
- setString:[[NSURL fileURLWithPath:filePath] absoluteString]
- forType:curType];
- gCreatedFileForFileURL = true;
- } else {
- gCreatedFileForFilePromise = true;
- }
+ nsAutoCString finalPath;
+ file->GetNativePath(finalPath);
+ NSString* filePath =
+ [NSString stringWithUTF8String:(const char*)finalPath.get()];
+ [aPasteboard
+ setString:[[NSURL fileURLWithPath:filePath] absoluteString]
+ forType:aType];
}
- } else if ([curType isEqualToString:[UTIHelper
- stringFromPboardType:
- kUrlsWithTitlesPboardType]]) {
- [aPasteboard setPropertyList:[pasteboardOutputDict valueForKey:curType]
- forType:curType];
- } else if ([curType
- isEqualToString:[UTIHelper stringFromPboardType:
- NSPasteboardTypeHTML]]) {
- [aPasteboard setString:(nsClipboard::WrapHtmlForSystemPasteboard(
- [pasteboardOutputDict valueForKey:curType]))
- forType:curType];
- } else if ([curType
- isEqualToString:[UTIHelper stringFromPboardType:
- NSPasteboardTypeTIFF]] ||
- [curType isEqualToString:[UTIHelper
- stringFromPboardType:
- kMozCustomTypesPboardType]]) {
- [aPasteboard setData:[pasteboardOutputDict valueForKey:curType]
- forType:curType];
- } else if ([curType
- isEqualToString:[UTIHelper stringFromPboardType:
- kMozFileUrlsPboardType]]) {
- [aPasteboard writeObjects:[pasteboardOutputDict valueForKey:curType]];
}
+ } else if ([aType
+ isEqualToString:[UTIHelper stringFromPboardType:
+ kUrlsWithTitlesPboardType]]) {
+ [aPasteboard setPropertyList:[pasteboardOutputDict valueForKey:aType]
+ forType:aType];
+ } else if ([aType isEqualToString:[UTIHelper stringFromPboardType:
+ NSPasteboardTypeHTML]]) {
+ [aPasteboard setString:(nsClipboard::WrapHtmlForSystemPasteboard(
+ [pasteboardOutputDict valueForKey:aType]))
+ forType:aType];
+ } else if ([aType isEqualToString:[UTIHelper stringFromPboardType:
+ NSPasteboardTypeTIFF]]) {
+ [aPasteboard setData:[pasteboardOutputDict valueForKey:aType]
+ forType:aType];
}
+
+ [aPasteboard
+ setData:[pasteboardOutputDict
+ valueForKey:[UTIHelper stringFromPboardType:
+ kMozCustomTypesPboardType]]
+ forType:[UTIHelper stringFromPboardType:kMozCustomTypesPboardType]];
+ [aPasteboard
+ writeObjects:[pasteboardOutputDict
+ valueForKey:[UTIHelper stringFromPboardType:
+ kMozFileUrlsPboardType]]];
}
NS_OBJC_END_TRY_IGNORE_BLOCK;
diff --git a/widget/cocoa/nsDragService.mm b/widget/cocoa/nsDragService.mm
@@ -42,10 +42,6 @@ extern bool gUserCancelledDrag;
// This global makes the transferable array available to Cocoa's promised
// file destination callback.
mozilla::StaticRefPtr<nsIArray> gDraggedTransferables;
-// These globals ensure that files pertaining to file URLs and file promises,
-// respectively, are only created once on disk per drag session.
-bool gCreatedFileForFileURL;
-bool gCreatedFileForFilePromise;
already_AddRefed<nsIDragSession> nsDragService::CreateDragSession() {
RefPtr<nsIDragSession> sess = new nsDragSession();
@@ -203,8 +199,6 @@ nsresult nsDragSession::InvokeDragSessionImpl(
// Save the transferables away in case a promised file callback is invoked.
gDraggedTransferables = aTransferableArray;
- gCreatedFileForFileURL = false;
- gCreatedFileForFilePromise = false;
// We need to retain the view and the event during the drag in case either
// gets destroyed.