Community
Participate
Working Groups
From <http://stackoverflow.com/questions/3908290/> : Run this code with 3.7: ================================== package swttest; import org.eclipse.swt.dnd.DND; import org.eclipse.swt.dnd.DragSource; import org.eclipse.swt.dnd.DragSourceEvent; import org.eclipse.swt.dnd.DragSourceListener; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseListener; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; public class SwtTest { public static void main(String[] args) { final Display display = new Display(); final Shell shell = new Shell(display); shell.addMouseListener(new MouseListener() { public void mouseUp(MouseEvent e) { System.out.println("mouseUp"); } public void mouseDown(MouseEvent e) { System.out.println("mouseDown"); } public void mouseDoubleClick(MouseEvent e) { System.out.println("mouseDoubleClick"); } }); DragSourceListener dragListener = new DragSourceListener() { public void dragFinished(DragSourceEvent event) { System.out.println("dragFinished"); } public void dragSetData(DragSourceEvent event) { System.out.println("dragSetData"); } public void dragStart(DragSourceEvent event) { System.out.println("dragStart"); } }; DragSource dragSource = new DragSource(shell, DND.DROP_COPY | DND.DROP_MOVE); dragSource.addDragListener(dragListener); shell.pack(); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); } } ======================== The mouseDown doesn't arrive until the drag is underway or until you release the mouse. At that point you get a mouseDown and an immediate mouseUp afterwards. Now, comment out these lines and run again: DragSource dragSource = new DragSource(shell, DND.DROP_COPY | DND.DROP_MOVE); dragSource.addDragListener(dragListener); The mouseDown is delivered immediately, on click. This seems to be an issue across all platforms, but I only tested it with Cocoa.
I can confirm at on GTK+ you do get the mouseDown, but it is delayed a few seconds (or if you release the button, then you get the mouseDown/mouseUp together like on Cocoa).
Created attachment 181455 [details] Patch Fix for Cocoa. Other platforms will have a similar fix; deliver the mousedown right away if the component is watching for DragDetect.
Created attachment 181456 [details] Patch for linux
One difference I've noticed is that the drag detection on GTK and Windows times out. In GTK, click and hold cancels the drag and on Win32 click and hold initiates a drag. On Cocoa it does neither -- we continue until either a mouseup happens or the mouse is dragged out of the 5x5 box to indicate a real drag has started. These patches harmonize the behavior by sending the SWT.MouseDown immediately before checking for the drag start if the control is listening for SWT.DragDetect but also keeps the current behavior of posting the event and not dispatching it until the current native event has been handled. Bug #26605 implies that should be the current behavior, but it doesn't look like it to me.
Created attachment 181457 [details] Patch for win32
The code in HEAD is right. If the control is a drag source it has to determine if a drag start should happen before proceeding with the mouse down. It seems the win32 patch is not the correct file for this bug. I suspect fixing this problem (based on the comments above) will break the workbench.
Is the problem then that we're not consistent about drag detection timeout? Maybe on Cocoa I need to add a timeout similar to GTK where we stop looking for a drag after a half second or so. Tor added himself to the CC list; Tor, what were you trying to do that's causing a problem here?
(In reply to comment #7) > Is the problem then that we're not consistent about drag detection timeout? > Maybe on Cocoa I need to add a timeout similar to GTK where we stop looking for > a drag after a half second or so. If you don't have a timeout on cocoa that certainly looks like a bug to me. (note that the duration of the time out is platform specific.) On Windows we have a OS call that does all the work us (see OS.DragDetect()) On GTK we simulate the process ourself (during the event loop and all), see Control#dragDetect(). I would expect Cocoa to have code similar to the one in GTK.
(In reply to comment #8) > If you don't have a timeout on cocoa that certainly looks like a bug to me. > (note that the duration of the time out is platform specific.) > > On Windows we have a OS call that does all the work us (see OS.DragDetect()) > On GTK we simulate the process ourself (during the event loop and all), see > Control#dragDetect(). > > I would expect Cocoa to have code similar to the one in GTK. Interesting... that's the first I've heard that this is intentional behavior. Should be easy to fix, though.
Created attachment 181526 [details] Drag detect timeout for cocoa Add half-second timeout for a drag detect. Works, but it feels odd to do that.
(In reply to comment #7) > Tor added himself to the CC list; Tor, what were you trying to do that's > causing a problem here? We have a visual editor which uses drag & drop, instead of just a mouse listener, such that it can support dragging a visual element from one canvas to another canvas (even another canvas in another instance of Eclipse). Therefore, we have a drag gesture listener on the canvas such that we can find out when you start dragging something. However, I noticed that (as a Mac user) the UI felt a bit "laggy" to me, and I realized it was because it's only acting on mouse -up-, instead of on mouse -down-. For example, context menus aren't shown until the mouse is released, which is the opposite of how menus -should- behave on Macs. I know SWT has support for handling context menus in a platform-specific way (the equivalent of Swing's isPopupTrigger), so a simple SWT program with a menu will correctly pop up the context menu on mouse down on the Mac, on on mouse up on Windows. However, it looks like the drag gesture listener suppresses all of this and forces nothing, including popup menus, to post until mouse release. I don't really understand why the drag gesture blocking mouse events and timeouts is necessary. If I simply hold the mouse button (but don't move the mouse) for 5 seconds I don't consider that a drag; certainly at least on the Mac in the native applications I don't get a drag cursor until I drag the mouse for a few pixels. From a naive perspective, it seems to me that the control should be notified immediately when a mouse is pushed, even if it will later result in a drag - definitely the context menus should work that way on the Mac. If this cannot be fixed in this way (e.g. without the 1 second delay), it sounds like I might be better off getting rid of the drag gesture listener, and just use a plain mouse listener for visual editor interactions within the canvas, and then somehow programmatically triggering a full drag & drop interaction the minute you drag the mouse out of the canvas (a mouseLeave event with the primary button pressed). If anyone can point me to some existing code for how to trigger that, I would appreciate it; I know this bug thread isn't the right place for it, but it would help me work around this issue... And I know it should be possible to make this work since the Eclipse package explorer does what I want - it supports native drag & drop, yet it also responds immediately to context menu clicks. I'm just not sure how to do it since the naive implementation, shown in the testcase attached to this issue, does not behave that way.
(In reply to comment #11) > (In reply to comment #7) > However, I noticed that (as a Mac user) the UI felt a bit "laggy" to me, and I > realized it was because it's only acting on mouse -up-, instead of on mouse > -down-. For example, context menus aren't shown until the mouse is released, > which is the opposite of how menus -should- behave on Macs. I know SWT has > support for handling context menus in a platform-specific way (the equivalent > of Swing's isPopupTrigger), so a simple SWT program with a menu will correctly > pop up the context menu on mouse down on the Mac, on on mouse up on Windows. > > However, it looks like the drag gesture listener suppresses all of this and > forces nothing, including popup menus, to post until mouse release. Aha, now this is making more sense. I assume you're using control-click to get the context menu, right? The test to see if we should detect a drag looks for DragDetect listeners and a single click on the left mouse, but if the control key is down we should skip the check because that combination can never start a drag. > From a naive perspective, it seems to me that the control should be notified > immediately when a mouse is pushed, even if it will later result in a drag - > definitely the context menus should work that way on the Mac. I agree with you, but based on Felipe's comment above, it looks like the workbench relies on the current behavior. I didn't see any problems in my testing but I'm hesitant to make any changes. I think we can make both of these scenarios work on Cocoa, but you'll have to wait for 3.7 for a fix from us. > If anyone can point me to some existing code for how to > trigger that, I would appreciate it; I know this bug thread isn't the right > place for it, but it would help me work around this issue... See Snippet259.java at www.eclipse.org/swt/snippets, which shows how you can call dragDetect(Event) yourself during a mouseDown. > And I know it > should be possible to make this work since the Eclipse package explorer does > what I want - it supports native drag & drop, yet it also responds immediately > to context menu clicks. I'm just not sure how to do it since the naive > implementation, shown in the testcase attached to this issue, does not behave > that way. Table and Tree don't have this problem because we let Cocoa perform the drag detection and then start the drag when we get the first callback from NSTableView. I would guess that Cocoa doesn't check for a drag on control-click either.
Checked in a fix that's slightly different. I pass in an NSDate that is .3 seconds in the future as a timeout. With that there's no need for special checking for the control key. Fixed > 20101022.