161550 - Expanding a TreeItem on Mac OS X fires MouseUp-MouseDown in the wrong order
share code that sends fake mouse up events when the widget consumes it while tracking
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/Button.java b/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/Button.java
index 300a4c1..4e6fb67 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/Button.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/Button.java
@@ -15,7 +15,6 @@
import org.eclipse.swt.internal.carbon.ControlFontStyleRec;
import org.eclipse.swt.internal.carbon.ControlButtonContentInfo;
import org.eclipse.swt.internal.carbon.Rect;
-import org.eclipse.swt.internal.carbon.CGPoint;
import org.eclipse.swt.internal.carbon.ThemeButtonDrawInfo;
import org.eclipse.swt.*;
@@ -49,7 +48,7 @@
String text = "";
Image image;
int cIcon;
- boolean isImage, tracking;
+ boolean isImage;
/**
* Constructs a new instance of this class given its parent
@@ -440,61 +439,6 @@
return OS.eventNotHandledErr;
}
-int kEventMouseDown (int nextHandler, int theEvent, int userData) {
- int result = super.kEventMouseDown (nextHandler, theEvent, userData);
- if (result == OS.noErr) return result;
- /*
- * Feature in the Macintosh. Some controls call TrackControl() or
- * HandleControlClick() to track the mouse. Unfortunately, mouse move
- * events and the mouse up events are consumed. The fix is to call the
- * default handler and send a fake mouse up when tracking is finished.
- *
- * NOTE: No mouse move events are sent while tracking. There is no
- * fix for this at this time.
- */
- display.grabControl = null;
- display.runDeferredEvents ();
- tracking = false;
- result = OS.CallNextEventHandler (nextHandler, theEvent);
- if (tracking) {
- org.eclipse.swt.internal.carbon.Point outPt = new org.eclipse.swt.internal.carbon.Point ();
- OS.GetGlobalMouse (outPt);
- Rect rect = new Rect ();
- int window = OS.GetControlOwner (handle);
- int x, y;
- if (OS.HIVIEW) {
- CGPoint pt = new CGPoint ();
- pt.x = outPt.h;
- pt.y = outPt.v;
- OS.HIViewConvertPoint (pt, 0, handle);
- x = (int) pt.x;
- y = (int) pt.y;
- OS.GetWindowBounds (window, (short) OS.kWindowStructureRgn, rect);
- } else {
- OS.GetControlBounds (handle, rect);
- x = outPt.h - rect.left;
- y = outPt.v - rect.top;
- OS.GetWindowBounds (window, (short) OS.kWindowContentRgn, rect);
- }
- x -= rect.left;
- y -= rect.top;
- short [] button = new short [1];
- OS.GetEventParameter (theEvent, OS.kEventParamMouseButton, OS.typeMouseButton, null, 2, null, button);
- int chord = OS.GetCurrentEventButtonState ();
- int modifiers = OS.GetCurrentEventKeyModifiers ();
- sendMouseEvent (SWT.MouseUp, button [0], display.clickCount, true, chord, (short)x, (short)y, modifiers);
- }
- tracking = false;
- return result;
-}
-
-int kEventControlTrack (int nextHandler, int theEvent, int userData) {
- int result = super.kEventControlTrack (nextHandler, theEvent, userData);
- if (result == OS.noErr) return result;
- tracking = true;
- return OS.eventNotHandledErr;
-}
-
void releaseWidget () {
super.releaseWidget ();
if (cIcon != 0) {
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/Control.java b/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/Control.java
index 79fed54..cffa38f 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/Control.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/Control.java
@@ -1722,8 +1722,56 @@
}
int kEventControlTrack (int nextHandler, int theEvent, int userData) {
-// if (isEnabledModal ()) sendMouseEvent (SWT.MouseMove, theEvent);
- return OS.eventNotHandledErr;
+ int result = super.kEventControlTrack (nextHandler, theEvent, userData);
+ if (result == OS.noErr) return result;
+ /*
+ * Feature in the Macintosh. Some controls call TrackControl() to track
+ * the mouse. Unfortunately, mouse move events and the mouse up events are
+ * consumed. The fix is to call the default handler and send a fake mouse up
+ * when tracking is finished if the mouse event was consumed.
+ *
+ * NOTE: No mouse move events are sent while tracking. There is no
+ * fix for this at this time.
+ */
+ display.grabControl = null;
+ display.runDeferredEvents ();
+ int oldChord = OS.GetCurrentEventButtonState ();
+ result = OS.CallNextEventHandler (nextHandler, theEvent);
+ int newChord = OS.GetCurrentEventButtonState ();
+ if (newChord != oldChord) {
+ int [] masks = {OS.kEventClassMouse, OS.kEventMouseUp};
+ int mouseUpEvent = OS.AcquireFirstMatchingEventInQueue (OS.GetCurrentEventQueue (), masks.length, masks, OS.kEventQueueOptionsNone);
+ if (mouseUpEvent != 0) {
+ OS.ReleaseEvent (mouseUpEvent);
+ } else {
+ org.eclipse.swt.internal.carbon.Point outPt = new org.eclipse.swt.internal.carbon.Point ();
+ OS.GetGlobalMouse (outPt);
+ Rect rect = new Rect ();
+ int window = OS.GetControlOwner (handle);
+ int x, y;
+ if (OS.HIVIEW) {
+ CGPoint pt = new CGPoint ();
+ pt.x = outPt.h;
+ pt.y = outPt.v;
+ OS.HIViewConvertPoint (pt, 0, handle);
+ x = (int) pt.x;
+ y = (int) pt.y;
+ OS.GetWindowBounds (window, (short) OS.kWindowStructureRgn, rect);
+ } else {
+ OS.GetControlBounds (handle, rect);
+ x = outPt.h - rect.left;
+ y = outPt.v - rect.top;
+ OS.GetWindowBounds (window, (short) OS.kWindowContentRgn, rect);
+ }
+ x -= rect.left;
+ y -= rect.top;
+ short [] button = new short [1];
+ OS.GetEventParameter (theEvent, OS.kEventParamMouseButton, OS.typeMouseButton, null, 2, null, button);
+ int modifiers = OS.GetCurrentEventKeyModifiers ();
+ sendMouseEvent (SWT.MouseUp, button [0], display.clickCount, false, newChord, (short)x, (short)y, modifiers);
+ }
+ }
+ return result;
}
int kEventMouseDown (int nextHandler, int theEvent, int userData) {
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/Slider.java b/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/Slider.java
index 2308e69..e6bb0b4 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/Slider.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/Slider.java
@@ -12,8 +12,6 @@
import org.eclipse.swt.internal.carbon.OS;
-import org.eclipse.swt.internal.carbon.Rect;
-import org.eclipse.swt.internal.carbon.CGPoint;
import org.eclipse.swt.*;
import org.eclipse.swt.events.*;
@@ -68,7 +66,7 @@
* @see ScrollBar
*/
public class Slider extends Control {
- boolean dragging, tracking;
+ boolean dragging;
int increment = 1;
int pageIncrement = 10;
@@ -312,63 +310,16 @@
return OS.GetControlViewSize (handle);
}
-int kEventControlTrack (int nextHandler, int theEvent, int userData) {
- int result = super.kEventControlTrack (nextHandler, theEvent, userData);
- if (result == OS.noErr) return result;
- tracking = true;
- return OS.eventNotHandledErr;
-}
-
int kEventMouseDown (int nextHandler, int theEvent, int userData) {
int status = super.kEventMouseDown (nextHandler, theEvent, userData);
if (status == OS.noErr) return status;
- /*
- * Feature in the Macintosh. Some controls call TrackControl() or
- * HandleControlClick() to track the mouse. Unfortunately, mouse move
- * events and the mouse up events are consumed. The fix is to call the
- * default handler and send a fake mouse up when tracking is finished.
- *
- * NOTE: No mouse move events are sent while tracking. There is no
- * fix for this at this time.
- */
- display.grabControl = null;
- display.runDeferredEvents ();
- dragging = tracking = false;
+ dragging = false;
status = OS.CallNextEventHandler (nextHandler, theEvent);
if (dragging) {
Event event = new Event ();
sendEvent (SWT.Selection, event);
}
dragging = false;
- if (tracking) {
- org.eclipse.swt.internal.carbon.Point outPt = new org.eclipse.swt.internal.carbon.Point ();
- OS.GetGlobalMouse (outPt);
- Rect rect = new Rect ();
- int window = OS.GetControlOwner (handle);
- int x, y;
- if (OS.HIVIEW) {
- CGPoint pt = new CGPoint ();
- pt.x = outPt.h;
- pt.y = outPt.v;
- OS.HIViewConvertPoint (pt, 0, handle);
- x = (int) pt.x;
- y = (int) pt.y;
- OS.GetWindowBounds (window, (short) OS.kWindowStructureRgn, rect);
- } else {
- OS.GetControlBounds (handle, rect);
- x = outPt.h - rect.left;
- y = outPt.v - rect.top;
- OS.GetWindowBounds (window, (short) OS.kWindowContentRgn, rect);
- }
- x -= rect.left;
- y -= rect.top;
- short [] button = new short [1];
- OS.GetEventParameter (theEvent, OS.kEventParamMouseButton, OS.typeMouseButton, null, 2, null, button);
- int chord = OS.GetCurrentEventButtonState ();
- int modifiers = OS.GetCurrentEventKeyModifiers ();
- sendMouseEvent (SWT.MouseUp, button [0], display.clickCount, true, chord, (short)x, (short)y, modifiers);
- }
- tracking = false;
return status;
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/Spinner.java b/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/Spinner.java
index 3a84573..64876a3 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/Spinner.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/Spinner.java
@@ -550,6 +550,7 @@
int [] mask = new int [] {
OS.kEventClassControl, OS.kEventControlDraw,
OS.kEventClassControl, OS.kEventControlSetFocusPart,
+ OS.kEventClassControl, OS.kEventControlTrack,
};
int controlTarget = OS.GetControlEventTarget (textHandle);
OS.InstallEventHandler (controlTarget, controlProc, mask.length / 2, mask, handle, null);
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/ToolItem.java b/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/ToolItem.java
index 79c54b7..53661b0 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/ToolItem.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/ToolItem.java
@@ -51,7 +51,7 @@
Image hotImage, disabledImage;
String toolTipText;
Control control;
- boolean tracking, selection;
+ boolean selection;
static final int DEFAULT_WIDTH = 24;
static final int DEFAULT_HEIGHT = 22;
@@ -765,8 +765,18 @@
}
int kEventControlTrack (int nextHandler, int theEvent, int userData) {
- tracking = true;
- return OS.eventNotHandledErr;
+ int result = parent.kEventControlTrack (nextHandler, theEvent, userData);
+ if (OS.HIVIEW) {
+ partCode = 0;
+ if (text.length () > 0 && labelHandle != 0) {
+ redrawWidget (labelHandle, false);
+ }
+ if (image != null && iconHandle != 0) {
+ OS.SetControlData (iconHandle, OS.kControlEntireControl, OS.kControlIconTransformTag, 2, new short [] {(short) 0});
+ redrawWidget (iconHandle, false);
+ }
+ }
+ return result;
}
int kEventMouseDown (int nextHandler, int theEvent, int userData) {
@@ -816,59 +826,7 @@
postEvent (SWT.Selection, event);
}
}
- }
- /*
- * Feature in the Macintosh. Some controls call TrackControl() or
- * HandleControlClick() to track the mouse. Unfortunately, mouse move
- * events and the mouse up events are consumed. The fix is to call the
- * default handler and send a fake mouse up when tracking is finished.
- *
- * NOTE: No mouse move events are sent while tracking. There is no
- * fix for this at this time.
- */
- display.grabControl = null;
- display.runDeferredEvents ();
- tracking = false;
- result = OS.CallNextEventHandler (nextHandler, theEvent);
- if (tracking) {
- if (OS.HIVIEW) {
- partCode = 0;
- if (text.length () > 0 && labelHandle != 0) {
- redrawWidget (labelHandle, false);
- }
- if (image != null && iconHandle != 0) {
- OS.SetControlData (iconHandle, OS.kControlEntireControl, OS.kControlIconTransformTag, 2, new short [] {(short) 0});
- redrawWidget (iconHandle, false);
- }
- }
- org.eclipse.swt.internal.carbon.Point outPt = new org.eclipse.swt.internal.carbon.Point ();
- OS.GetGlobalMouse (outPt);
- Rect rect = new Rect ();
- int window = OS.GetControlOwner (handle);
- int x, y;
- if (OS.HIVIEW) {
- CGPoint pt = new CGPoint ();
- pt.x = outPt.h;
- pt.y = outPt.v;
- OS.HIViewConvertPoint (pt, 0, parent.handle);
- x = (int) pt.x;
- y = (int) pt.y;
- OS.GetWindowBounds (window, (short) OS.kWindowStructureRgn, rect);
- } else {
- OS.GetControlBounds (parent.handle, rect);
- x = outPt.h - rect.left;
- y = outPt.v - rect.top;
- OS.GetWindowBounds (window, (short) OS.kWindowContentRgn, rect);
- }
- x -= rect.left;
- y -= rect.top;
- short [] button = new short [1];
- OS.GetEventParameter (theEvent, OS.kEventParamMouseButton, OS.typeMouseButton, null, 2, null, button);
- int chord = OS.GetCurrentEventButtonState ();
- int modifiers = OS.GetCurrentEventKeyModifiers ();
- parent.sendMouseEvent (SWT.MouseUp, button [0], display.clickCount, true, chord, (short)x, (short)y, modifiers);
- }
- tracking = false;
+ }
return result;
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/Tree.java b/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/Tree.java
index 759c19f..0a260d3 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/Tree.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/Tree.java
@@ -2394,43 +2394,6 @@
}
}
}
- /*
- * Feature in the Macintosh. Some controls call TrackControl() or
- * HandleControlClick() to track the mouse. Unfortunately, mouse move
- * events and the mouse up events are consumed. The fix is to call the
- * default handler and send a fake mouse up when tracking is finished.
- *
- * NOTE: No mouse move events are sent while tracking. There is no
- * fix for this at this time.
- */
- if (wasExpanded) {
- org.eclipse.swt.internal.carbon.Point outPt = new org.eclipse.swt.internal.carbon.Point ();
- OS.GetGlobalMouse (outPt);
- Rect rect = new Rect ();
- int window = OS.GetControlOwner (handle);
- int x, y;
- if (OS.HIVIEW) {
- CGPoint pt = new CGPoint ();
- pt.x = outPt.h;
- pt.y = outPt.v;
- OS.HIViewConvertPoint (pt, 0, handle);
- x = (int) pt.x;
- y = (int) pt.y;
- OS.GetWindowBounds (window, (short) OS.kWindowStructureRgn, rect);
- } else {
- OS.GetControlBounds (handle, rect);
- x = outPt.h - rect.left;
- y = outPt.v - rect.top;
- OS.GetWindowBounds (window, (short) OS.kWindowContentRgn, rect);
- }
- x -= rect.left;
- y -= rect.top;
- short [] button = new short [1];
- OS.GetEventParameter (theEvent, OS.kEventParamMouseButton, OS.typeMouseButton, null, 2, null, button);
- int chord = OS.GetCurrentEventButtonState ();
- int modifiers = OS.GetCurrentEventKeyModifiers ();
- sendMouseEvent (SWT.MouseUp, button [0], display.clickCount, true, chord, (short)x, (short)y, modifiers);
- }
wasSelected = wasExpanded = false;
return result;
}