diff options
author | Xi Yan | 2018-12-13 15:37:51 +0000 |
---|---|---|
committer | Eric Williams | 2018-12-13 18:18:18 +0000 |
commit | 7df1bc9d8482b903533bbd251a9ba84f01941980 (patch) | |
tree | a033d4b266bd7742d5b18b5a9269964c23436d0d | |
parent | 218b69a1632dcada8464e8f4114e52547033b943 (diff) | |
download | eclipse.platform.swt-7df1bc9d8482b903533bbd251a9ba84f01941980.tar.gz eclipse.platform.swt-7df1bc9d8482b903533bbd251a9ba84f01941980.tar.xz eclipse.platform.swt-7df1bc9d8482b903533bbd251a9ba84f01941980.zip |
Bug 541635 - [Wayland] Random behaviour when moving editor tabs
1) Block in dragDetect until mouse is released or drag is detected while
using gtk_motion_event for drag detection. See Bug 515396. This was done
using extra mouseDown and dragBegun flags to keep track of the mouse or
drag state.
2) When editor tabs are being dragged, CTabFolder receives
button_pressed event a *single* motion_notify event when drag begins.
Then the Tracker rectangle is initialize and all motion_notify event and
button_released event is received by the Tracker which is not part of
Control. This causes the issue that even when mouse is released,
dragDetect still assumes the drag has not ended. So the cursor can still
move a tab even after releasing the mouse. The fix is to extend the DND
blocking logic and update that mouse was released in Tracker.
Change-Id: I71ac7edf3f2c51349426004af514037ff537c0aa
Signed-off-by: Xi Yan <xixiyan@redhat.com>
3 files changed, 26 insertions, 2 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/DragSource.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/DragSource.java index 7f6eefe262..8743479d51 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/DragSource.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/DragSource.java @@ -229,6 +229,7 @@ static long /*int*/ DragDataDelete(long /*int*/ widget, long /*int*/ context){ } static long /*int*/ DragEnd(long /*int*/ widget, long /*int*/ context){ + Control.mouseDown = false; DragSource source = FindDragSource(widget); if (source == null) return 0; source.dragEnd(widget, context); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java index 1d279a4e61..b8d0633273 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java @@ -114,6 +114,12 @@ public abstract class Control extends Widget implements Drawable { long.class, long.class, long.class}); //$NON-NLS-1$ if (gestureEnd.getAddress() == 0) SWT.error(SWT.ERROR_NO_MORE_CALLBACKS); } + /** + * Bug 541635, 515396: GTK Wayland only flag to keep track whether mouse + * is currently pressed or released for DND. + */ + public static boolean mouseDown; + boolean dragBegun; Control () { } @@ -2587,9 +2593,18 @@ boolean dragDetect (int x, int y, boolean filter, boolean dragOnTimeout, boolean } else { return false; } + // Block until mouse was released or drag was detected, see Bug 515396. + while (true) { + if (!mouseDown) { + return false; + } + if (dragBegun) { + return true; + } + } } else { boolean quit = false; - //428852 DND workaround for GTk3. + //428852 DND workaround for GTK3. //Gtk3 no longer sends motion events on the same control during thread sleep //before a drag started. This is due to underlying gdk changes. //Thus for gtk3 we check mouse coords manually @@ -3282,6 +3297,9 @@ long /*int*/ gtk_button_press_event (long /*int*/ widget, long /*int*/ event) { } long /*int*/ gtk_button_press_event (long /*int*/ widget, long /*int*/ event, boolean sendMouseDown) { + mouseDown = true; + dragBegun = false; + GdkEventButton gdkEvent = new GdkEventButton (); OS.memmove (gdkEvent, event, GdkEventButton.sizeof); lastInput.x = (int) gdkEvent.x; @@ -3364,6 +3382,7 @@ long /*int*/ gtk_button_press_event (long /*int*/ widget, long /*int*/ event, bo @Override long /*int*/ gtk_button_release_event (long /*int*/ widget, long /*int*/ event) { + mouseDown = false; GdkEventButton gdkEvent = new GdkEventButton (); OS.memmove (gdkEvent, event, GdkEventButton.sizeof); lastInput.x = (int) gdkEvent.x; @@ -3709,6 +3728,9 @@ long /*int*/ gtk_mnemonic_activate (long /*int*/ widget, long /*int*/ arg1) { @Override long /*int*/ gtk_motion_notify_event (long /*int*/ widget, long /*int*/ event) { + if (mouseDown) { + dragBegun = true; + } int result; GdkEventMotion gdkEvent = new GdkEventMotion (); OS.memmove (gdkEvent, event, GdkEventMotion.sizeof); @@ -4558,7 +4580,7 @@ boolean sendMouseEvent (int type, int button, int count, int detail, boolean sen break; case SWT.MouseUp: // Case where mouse up was released before DnD threshold was hit. - + mouseDown = false; // Decide if we should send or post the queued up MouseDown and MouseMovement events. // If mouseUp is send, then send all. If mouseUp is post, then decide based on previous // send flag. diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tracker.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tracker.java index b8ae6c7bac..aa5bad2424 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tracker.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tracker.java @@ -472,6 +472,7 @@ boolean grab () { @Override long /*int*/ gtk_button_release_event (long /*int*/ widget, long /*int*/ event) { + Control.mouseDown = false; return gtk_mouse (GDK.GDK_BUTTON_RELEASE, widget, event); } |