Solution
If we want for user to drag entries without using meta keys we should always allow system-default drag operation both on drag and drop ends. On Windows this happen to be a DND.DRAG_MOVE
operation (and I believe the same it true for other platforms).
source.addDragSupport(DND.DROP_MOVE, new Transfer[] { DragSelectionListener.getTransfer() }, new DragSelectionListener(viewer));
target.addDropSupport(DND.DROP_MOVE, new Transfer[]{ DropListListener.getTransfer() }, new DropListListener(viewer));
Explanation
Three sets of operations should intersect:
- operations that drag source allow (are set with StructuredViewer.addDragSupport())
- operations that drag target support (are set with StructuredViewer.addDropSupport())
- operation selected by user (depends on which meta keys were pressed at the moment of drop)
only then drop target will validate the drop received and drag source would be requested for data.
Investigation
The handling of meta-keys is done in org.eclipse.swt.dnd.DropTarget.setEventData()
the line
operations[0] = osToOp(operations[0]) & style;
if (operations[0] == DND.DROP_NONE) return false;
intersects style from droptarget with value which came from system drop operation is based on dragsource but stripped of DND.DRAG_DEFAULT
. If those two do not intersect, operation is aborted.
Further down this set is compared with the one calculated from meta keys pressed. Operation could be aborted again.
if ((operation & operations[0]) == 0) operation = DND.DROP_NONE;
This behaviour can be controlled passing DND.DROP_DEFAULT
to addDropSupport()
, but that is even worse as the user selected operation would be then compared to DND.DROP_MOVE
, which would be filtered out earlier if not used as an argument of addDropSupport()
.
I think the DND.DROP_DEFAULT
handling is broken and should not be relied upon. It's use if effectively prevented by first condition.