Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 34983

Summary: Native drag and drop doesn't work under linux
Product: [Eclipse Project] Platform Reporter: Eric Bordeau <ebordeau>
Component: SWTAssignee: Veronika Irvine <veronika_irvine>
Status: RESOLVED FIXED QA Contact:
Severity: critical    
Priority: P3 CC: david_williams, dirk_baeumer, hudsonr, thatnitind
Version: 2.1   
Target Milestone: 2.1 RC3   
Hardware: PC   
OS: Linux   
Whiteboard:

Description Eric Bordeau CLA 2003-03-13 17:42:03 EST
Here's a simple test case that works under Windows and not Linux (GTK or Motif)...


import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.*;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class DNDTest {

public static void main(String[] args) {
	Shell shell = new Shell();
	shell.setLayout(new FillLayout());
	Canvas canvas = new Canvas(shell, SWT.NONE);
	DragSource ds = new DragSource(canvas, DND.DROP_MOVE | DND.DROP_COPY |
DND.DROP_LINK);
	ds.addDragListener(new DragSourceListener() {
		public void dragStart(DragSourceEvent event) {
			System.out.println("Drag Start");
		}
		public void dragSetData(DragSourceEvent event) {
			System.out.println("Drag Set Data");
		}
		public void dragFinished(DragSourceEvent event) {
			System.out.println("Drag Finished");
		}
	});
	shell.open();
	Display display = Display.getDefault();
	while (!shell.isDisposed())
		if (!display.readAndDispatch())
			display.sleep();
}

}
Comment 1 Eric Bordeau CLA 2003-03-13 17:42:51 EST
I'm using RC2 on Red Hat 8.0
Comment 2 Eric Bordeau CLA 2003-03-13 18:25:19 EST
I also tested this with RC1 Motif and I do get the drag start.  I don't get the
drag finished, which I do get under Windows, but this may be a Motif "feature".
Comment 3 Randy Hudson CLA 2003-03-13 23:10:23 EST
We rely on the drag finished notification. If this doesn't occur on Motif, our 
palette buttons will stay depressed at the end of a drag. Should we open a 
separate bug on this issue?
Comment 4 Veronika Irvine CLA 2003-03-14 09:21:17 EST
Your example points out an error on Windows and Motif.  The drag source should 
not allow you to initate a drag unless a transfer type has been specified.  I 
will change Windows and Motif to stop initiating a drag in this case.

You must call DragSource.setTransfer.

Comment 5 Randy Hudson CLA 2003-03-14 11:14:25 EST
Opened bug 35022 on dragFinished not being sent on Motif.

The workaround for us on this bug is to set the Transfer[] before dragstart 
callback. So i'm reducing severity, this is just a portability issue.
Comment 6 Veronika Irvine CLA 2003-03-15 12:23:14 EST
I have modified the behaviour across platforms to send the dragStart event and 
then check after the event is returned to make sure that the transfer type has 
been set.

This will allow you to not specify the drag transfer type until the drag has 
started.  However, after you return from dragStart, a transfer type must be 
set or the DND operation will not continue.

Note, after the dragStart, if the dragStart handler threw an exception or if 
no transfer type is set, the drag will not start and there will be no 
dragFinished event.  Whether there should be a drag finished event in this 
case, can be debated. I think it would be undesirable but am open to 
suggestion.

The following code will now initiate a drag and get a dragStart and a dragEnd 
in all cases and across all platforms (win32, motif, gtk - no others are 
implemented yet):

public static void main2(String[] args) {
	Shell shell = new Shell();
	Canvas canvas = new Canvas(shell, SWT.BORDER);
	canvas.setBounds(10, 10, 100, 100);
	final DragSource ds = new DragSource(canvas, DND.DROP_MOVE | 
DND.DROP_COPY | DND.DROP_LINK);
	ds.addDragListener(new DragSourceListener() {
		public void dragStart(DragSourceEvent event) {
			System.out.println("Drag Start");
			ds.setTransfer(new Transfer[] {TextTransfer.getInstance
()});
		}
		public void dragSetData(DragSourceEvent event) {
			System.out.println("Drag Set Data");
		}
		public void dragFinished(DragSourceEvent event) {
			System.out.println("Drag Finished");
		}
	});
	shell.open();
	Display display = Display.getDefault();
	while (!shell.isDisposed())
		if (!display.readAndDispatch())
			display.sleep();
}