(From update of attachment 390806) Thank you for this. The general approach looks good, but some of the finer details should be touched up. It makes it much easier for reviewers to understand the changes and work out which code is being modified when patches show function names and have additional lines of context. This can be done automatically by adding a [diff] section to ~/.hgrc or .hg/hgrc: https://developer.mozilla.org/en/Mercurial_FAQ#Configuration >+ // We can not delete the temporary files immediately after the >+ // drag has finished, because the target application might have not >+ // copied the temporary file yet. Instead we collect all temporary >+ // files in mTemporaryFiles array and remove them here in the destructor. The destination app should not indicate that it is finished until it has copied the file. This seems to be implied by both the XDND and Motif protocols: http://newplanetsoftware.com/xdnd/dragging_files.html http://www.lesstif.org/InsideLessTif/node89.html So it should be safe to delete the temporary files in response to the drag-end (or drag-failed) signals (in SourceEndDragSession()). We don't really want to keep accumulating these files when the application runs for months and the files would not be cleaned up if the app doesn't get a chance to shut down nicely. Did you see any apps that were indicating that they had finished before they had copied the file? In GetSourceList(): >+ // check if application/x-moz-file-promise url is supported. >+ // If so, advertise text/uri-list. >+ if (strcmp(flavorStr, kFilePromiseURLMime) == 0) { >+ GdkAtom urlAtom = gdk_atom_intern(gTextUriListType, FALSE); >+ GtkTargetEntry *urlTarget = >+ (GtkTargetEntry *)g_malloc(sizeof(GtkTargetEntry)); >+ urlTarget->target = g_strdup(gTextUriListType); >+ urlTarget->flags = 0; >+ /* Bug 331198 */ >+ urlTarget->info = NS_PTR_TO_UINT32(urlAtom); >+ targetArray.AppendElement(urlTarget); >+ } It looks like this can be done even when numDragItems > 1. Though I don't think we want two gTextUriListType targets when both kURLMime and kFilePromiseURLMime are supported flavours (unless there's a reason why that won't happen). If both kFilePromiseURLMime and kURLMime flavours are available, then which should be used in the text/uri-list data? (We won't know whether the destination wants to copy or link.) Perhaps they are unlikely to both occur together and just picking one will be fine. I don't think handling multiple files would be too difficult, but even if you prefer to only implement this for one file right now, make sure that SourceDataGet() is consistent with GetSourceList(). In SourceDataGet(): >+ void *tmpData = NULL; >+ nsresult rv; >+ nsCOMPtr data; >+ rv = item->GetTransferData(kFilePromiseURLMime, >+ getter_AddRefs(data), >+ &tmpDataLen); >+ if (NS_SUCCEEDED(rv)) { >+ foundFilePromiseFlavor = PR_TRUE; >+ if (tmpData) { tmpData is not used. >+ if (foundFilePromiseFlavor == PR_FALSE) { >+ PR_LOG(sDragLm, PR_LOG_DEBUG, ("Transferable is missing kFilePromiseURLMime flavor\n")); >+ return; >+ } >+ I expect the transferable may often not have kFilePromiseURLMime even though someone asks for target type mimeFlavor == gTextUriListType. (If kURLMime is a supported flavour, then gTextUriListType will be in the GtkTargetList.) This function should continue to return gTextUriListType data even if there is no kFilePromiseURLMime flavour. >+ rv = NS_NewFileURI(getter_AddRefs(uri), tmpDir); The uri will need to contain the hostname. Will NS_NewFileURI do this? http://newplanetsoftware.com/xdnd/dragging_files.html Feel free to use glib functions (g_filename_to_uri() perhaps) when dealing with GTK as in this function (and others in this file), if that makes things easier. >+ // remove and re-add the text/uri-list flavor to discard any previous >+ // data of that flavor >+ item->RemoveDataFlavor(gTextUriListType); >+ item->AddDataFlavor(gTextUriListType); >+ >+ // set the file:///tmp/dnd_file/ URL for text/uri-list flavor >+ item->SetTransferData(gTextUriListType, genericDataWrapper, ucs2Str.Length() * 2); The side-effect of modifying the transferable here doesn't feel right to me. The transferable is an app-internal reference to the data, while the external uri list, generated here for the GtkSelectionData for other apps, is likely to be different. (Internally the data can be referenced from the original URI, rather than from the file intended for external use.) There is lot of code specific to kFilePromiseURLMime added to SourceDataGet() here. This dominates the function (which is actually much more general) and makes it harder to follow the flow. Most of the new code should be split out into one or more static functions or private methods.