Community
Participate
Working Groups
Build ID: I20090520-2000 Steps To Reproduce: 1.In the package explorer view, create a project, create a file inside a project. 2.Let the file be open in the editor 3.Drag a file from a project to the desktop. Even after the drop, the file is still visible in the package explorer & is open in the editor. The user had to refresh the file or project. Refresh happens automatically on windows. More information: Happens on both Carbon and Cocoa
Weird. Works on Windows but not on Carbon or Cocoa.
The apparent cause is that the 'dragFinished' event is getting DND.DROP_MOVE on macs and DND.DROP_TARGET_MOVE on windows... I'm not sure what to do with this one, the FileTransferDropAdapter has code that reacts to the DROP_TARGET_MOVE but the code to handle DROP_MOVE is commented out...
Dani, is there any way that you could make the DROP_MOVE fall through the same code as the DROP_TARGET_MOVE or are there bad side-effects?
This seems to be caused by org.eclipse.jdt.internal.ui.packageview.FileTransferDragAdapter.dragFinished(DragSourceEvent): public void dragFinished(DragSourceEvent event) { if (!event.doit) return; if (event.detail == DND.DROP_MOVE) { // http://bugs.eclipse.org/bugs/show_bug.cgi?id=30543 // handleDropMove(event); } else if (event.detail == DND.DROP_TARGET_MOVE) { handleRefresh(); } } On the Mac, SWT is sending a DROP_MOVE instead of DROP_TARGET_MOVE.
This looks like a bug in UI rather than SWT. Kevin to confirm.
It may just be the platform behavior. We're dropping a file onto the desktop; who defines the event.detail for the 'dragFinished' event?
Only windows should be sending DND.DROP_TARGET_MOVE. At the moment it appears that Cocoa may be sending it as well. We can fix that post 3.5.
As noted, this happens on Carbon and Cocoa. In Cocoa, NSDragOperationDelete gets mapped to DROP_TARGET_MOVE. I probably copied that over from Carbon, where kDragActionDelete maps to DROP_TARGET_MOVE. I see the extra checking in win32's DragSource.drag() right before the DragEnd event is sent. Does carbon/cocoa need something similar?
Did no one try this even once? On Windows, the operating system will delete the file for you after it has copied it and sends drag finished with DROP_TARGET_MOVE to indicate "Hey, don't do anything, the target moved it (ie. copied and deleted the old, possibly in one operation). Unless, on the Mac, the target has deleted the file (after copying it), cocoa should not be setting the detail to DROP_TARGET_MOVE.
Not for 3.5 Ok, both carbon and cocoa are bogus?
I'm not sure about the conclusion here: is it now considered a SWT or an upstream bug? If it's an upstream bug we also have to check the other views like e.g. Project Explorer. Suggest to look at this for 3.5.1.
I believe that only windows should be sending DROP_TARGET_MOVE, the other platforms should be sending DROP_MOVE so SWT should be removing the DROP_TARGER_MOVE references from Cocoa. JDT should be handling the DROP_MOVE as well as DROP_TARGET_MOVE, so I'm not sure if there's a jdt bug here as well.
(In reply to comment #9) > Did no one try this even once? > > On Windows, the operating system will delete the file for you after it has > copied it and sends drag finished with DROP_TARGET_MOVE to indicate "Hey, don't > do anything, the target moved it (ie. copied and deleted the old, possibly in > one operation). I have tried this and on the Mac, the Finder does delete the file after copying it, which is why the file disappears from the Package Explorer when you do a refresh operation (see comment 0 for steps). > Unless, on the Mac, the target has deleted the file (after copying it), cocoa > should not be setting the detail to DROP_TARGET_MOVE. Wouldn't the conclusion then be that Cocoa needs to send a DROP_TARGET_MOVE?
Good, the Mac behaves like Windows then. I thought it was sending one (at least we saw it in the code but did not verify).
if we change the operation in DragSource to be DROP_TARGET_MOVE, then this starts working. We need to find a way to determine that the DropTarget has moved the data. When the target moves the data, we should send DROP_TARGET_MOVE, otherwise we should send DROP_MOVE.
Created attachment 139419 [details] potential patch Possible solution. Checks if the files that were put on to the pasteboard still exist, sends DROP_MOVE if they do, and DROP_TARGET_MOVE if they don't. I'm open to suggestions on this one.
(In reply to comment #15) > We need to find a way to determine that the DropTarget has moved the data. (In reply to comment #16) > Checks if the files that were put on to the pasteboard still exist I don't see code like this in the win32 version of DragSource. Does that mean that the Windows APIs tell you whether the the data has been moved, but the Cocoa APIs don't specify who moves the data or at least report it after the drop? Why is it not always a DROP_TARGET_MOVE?
win32 tells us when the files have been moved so we don't need this code there. It should be DROP_TARGET_MOVE when the original data is moved by the drop target, and DROP_MOVE when a copy of the moved by target and the original data is removed by the drag source.
I don't think this is a 3.5.1 candidate. The current behavior isn't a regression (at least from an SWT perpective) and the fix isn't trivial.
Created attachment 141243 [details] new patch
The patch in comment 20, save a list of file paths, and a list of booleans indicating that those files actually exist every time a FileTransfer starts. When the drag ends, it checks again and if any file that existed at the beginning of the drag does not exist anymore it sends DROP_TARGET_MOVE instead of DROP_MOVE. This needs some more consideration before it can be released to HEAD.
Created attachment 141747 [details] Patch 3 Can you explain why you can't simply set the event.detail to DROP_TARGET_MOVE (like on Windows)? I just can't believe that the Cocoa APIs don't specify whether it's the DragSource or the DropTarget's job to make sure the move is completely performed and the file is removed from the original location. Can you show me where this is specified or do you know of relevant examples in the field that behave in both ways? I quickly looked at http://developer.apple.com/DOCUMENTATION/Cocoa/Conceptual/DragandDrop/DragandDrop.html , and from what I understood, it's always the destination's duty to perform the operation in performDragOperation, and thus there's no need for guessing and checking whether files are still available. The only caveat is in http://developer.apple.com/DOCUMENTATION/Cocoa/Conceptual/DragandDrop/Concepts/dragsource.html#//apple_ref/doc/uid/20000976-105524 : When SWT's draggedImage:endedAt:operation: is called with NSDragOperationDelete then this means the *DragSource* has to delete the file, so SWT's draggedImage_endedAt_operation(..) needs to fire a DND.DROP_MOVE, and the change becomes as simple as the attached patch. Note that at least JDT currently does not correctly implement DND.DROP_MOVE due to bug 30543 in Mozilla (we don't delete the file although we should in that case). I'll check whether that's still an issue.
Windows does not always send DROP_TARGET_MOVE. There is code in DragSource#drag that checks the data effect and the drop operation and decides whether DROP_MOVE or DROP_TARGET_MOVE should be sent. Veronika explains the different moves like this (from http://www.eclipse.org/articles/Article-SWT-DND/DND-in-SWT.html): DND.DROP_MOVE: The drop target made a copy of the data and the drag source should now delete the original and update its display. DND.DROP_TARGET_MOVE: The drop target moved the data from its original location to a new location. This is usually only used with files. In this case, the drag source does not need to delete the original; it just needs to update its display information. NSDragOperationDelete usually indicates that the file has been dragged to the trash. In this case we correctly send DND.DROP_TARGET_MOVE. However when dragging to finder, we get NSDragOperationMove, but the file was moved, not copied, so we should be sending DND.DROP_TARGET_MOVE instead of DND.MOVE to let the client know they just need to refresh. The last patch I attached does accomplish this, and will probably be released for 3.5, but I'd like to spend more time testing and reviewing it. It's possible that there is a better solution.
Released patch to HEAD (attachment 141243 [details]) to HEAD for this weeks build. If a better solution is found, the patch can be removed. Releasing now gives us the most testing time. fixed > 20090720