### Eclipse Workspace Patch 1.0
#P org.eclipse.swt
Index: Eclipse SWT/cocoa/org/eclipse/swt/widgets/Composite.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Composite.java,v
retrieving revision 1.93
diff -u -r1.93 Composite.java
--- Eclipse SWT/cocoa/org/eclipse/swt/widgets/Composite.java 22 Dec 2010 16:04:34 -0000 1.93
+++ Eclipse SWT/cocoa/org/eclipse/swt/widgets/Composite.java 13 Jan 2011 17:43:20 -0000
@@ -941,48 +941,54 @@
getShell().deferFlushing();
NSEvent nsEvent = new NSEvent(theEvent);
boolean handled = false;
- float /*double*/ delta = nsEvent.deltaY();
- if (display.gestureStarted) {
- if (!sendGestureEvent(nsEvent, SWT.GESTURE_PAN, true)) handled = true;
- }
- if (delta != 0) {
- boolean doit = true;
- if (hooks (SWT.MouseWheel) || filters (SWT.MouseWheel)) {
- doit = sendMouseEvent(nsEvent, SWT.MouseWheel, true);
- }
- ScrollBar bar = verticalBar;
- if (doit && bar != null && bar.getEnabled ()) {
- if (-1 < delta && delta < 0) delta = -1;
- if (0 < delta && delta < 1) delta = 1;
- int selection = Math.max (0, (int)(0.5f + bar.getSelection () - bar.getIncrement () * delta));
- bar.setSelection (selection);
- Event event = new Event ();
- event.detail = delta > 0 ? SWT.PAGE_UP : SWT.PAGE_DOWN;
- bar.sendSelectionEvent (SWT.Selection, event, true);
- handled = true;
+ float /*double*/ deltaY = nsEvent.deltaY();
+ float /*double*/ deltaX = nsEvent.deltaX ();
+ if ((hooks(SWT.Gesture) || filters (SWT.Gesture))) {
+ if (deltaX != 0 || deltaY != 0) {
+ if (!gestureEvent(id, theEvent, SWT.GESTURE_PAN)) {
+ handled = true;
+ }
}
- if (!doit) handled = true;
}
- delta = nsEvent.deltaX ();
- if (delta != 0) {
- boolean doit = true;
- if (hooks (SWT.MouseHorizontalWheel) || filters (SWT.MouseHorizontalWheel)) {
- doit = sendMouseEvent(nsEvent, SWT.MouseHorizontalWheel, true);
+ if (!handled) {
+ if (deltaY != 0) {
+ boolean doit = true;
+ if (hooks (SWT.MouseWheel) || filters (SWT.MouseWheel)) {
+ doit = sendMouseEvent(nsEvent, SWT.MouseWheel, true);
+ }
+ ScrollBar bar = verticalBar;
+ if (doit && bar != null && bar.getEnabled ()) {
+ if (-1 < deltaY && deltaY < 0) deltaY = -1;
+ if (0 < deltaY && deltaY < 1) deltaY = 1;
+ int selection = Math.max (0, (int)(0.5f + bar.getSelection () - bar.getIncrement () * deltaY));
+ bar.setSelection (selection);
+ Event event = new Event ();
+ event.detail = deltaY > 0 ? SWT.PAGE_UP : SWT.PAGE_DOWN;
+ bar.sendSelectionEvent (SWT.Selection, event, true);
+ handled = true;
+ }
+ if (!doit) handled = true;
}
- ScrollBar bar = horizontalBar;
- if (doit && bar != null && bar.getEnabled ()) {
- if (-1 < delta && delta < 0) delta = -1;
- if (0 < delta && delta < 1) delta = 1;
- int selection = Math.max (0, (int)(0.5f + bar.getSelection () - bar.getIncrement () * delta));
- bar.setSelection (selection);
- Event event = new Event ();
- event.detail = delta > 0 ? SWT.PAGE_UP : SWT.PAGE_DOWN;
- bar.sendSelectionEvent (SWT.Selection, event, true);
- handled = true;
+ if (deltaX != 0) {
+ boolean doit = true;
+ if (hooks (SWT.MouseHorizontalWheel) || filters (SWT.MouseHorizontalWheel)) {
+ doit = sendMouseEvent(nsEvent, SWT.MouseHorizontalWheel, true);
+ }
+ ScrollBar bar = horizontalBar;
+ if (doit && bar != null && bar.getEnabled ()) {
+ if (-1 < deltaX && deltaX < 0) deltaX = -1;
+ if (0 < deltaX && deltaX < 1) deltaX = 1;
+ int selection = Math.max (0, (int)(0.5f + bar.getSelection () - bar.getIncrement () * deltaX));
+ bar.setSelection (selection);
+ Event event = new Event ();
+ event.detail = deltaX > 0 ? SWT.PAGE_UP : SWT.PAGE_DOWN;
+ bar.sendSelectionEvent (SWT.Selection, event, true);
+ handled = true;
+ }
+ if (!doit) handled = true;
}
- if (!doit) handled = true;
+ if (!handled) view.superview().scrollWheel(nsEvent);
}
- if (!handled) view.superview().scrollWheel(nsEvent);
return;
}
callSuper(id, sel, theEvent);
Index: Eclipse SWT/cocoa/org/eclipse/swt/widgets/Control.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Control.java,v
retrieving revision 1.215
diff -u -r1.215 Control.java
--- Eclipse SWT/cocoa/org/eclipse/swt/widgets/Control.java 23 Dec 2010 19:24:18 -0000 1.215
+++ Eclipse SWT/cocoa/org/eclipse/swt/widgets/Control.java 13 Jan 2011 17:43:21 -0000
@@ -68,7 +68,8 @@
NSBezierPath regionPath;
int /*long*/ visibleRgn;
Accessible accessible;
-
+ boolean touchEnabled;
+
final static int CLIPPING = 1 << 10;
final static int VISIBLE_REGION = 1 << 12;
@@ -657,6 +658,35 @@
/**
* Adds the listener to the collection of listeners who will
+ * be notified when touch events occur, by sending it
+ * one of the messages defined in the TouchListener
+ * interface.
+ *
+ * NOTE: You must also call setTouchEventsEnabled
to notify the
+ * windowing toolkit that you want touch events to be generated.
+ *
TraverseListener
* interface.
@@ -687,12 +717,12 @@
}
void beginGestureWithEvent (int /*long*/ id, int /*long*/ sel, int /*long*/ event) {
- if (!gestureEvent(id, sel, event, SWT.GESTURE_BEGIN)) return;
+ if (!gestureEvent(id, event, SWT.GESTURE_BEGIN)) return;
super.beginGestureWithEvent(id, sel, event);
}
void endGestureWithEvent (int /*long*/ id, int /*long*/ sel, int /*long*/ event) {
- if (!gestureEvent(id, sel, event, SWT.GESTURE_END)) return;
+ if (!gestureEvent(id, event, SWT.GESTURE_END)) return;
super.endGestureWithEvent(id, sel, event);
}
@@ -1389,15 +1419,59 @@
return view.window ().makeFirstResponder (focusView);
}
-boolean gestureEvent(int /*long*/ id, int /*long*/ sel, int /*long*/ event, int detail) {
+boolean gestureEvent(int /*long*/ id, int /*long*/ eventPtr, int detail) {
// For cross-platform compatibility, touch events and gestures are mutually exclusive.
// Don't send a gesture if touch events are enabled for this control.
-// if (touchEnabled) return true;
- if (!display.sendEvent) return true;
- display.sendEvent = false;
+ if (touchEnabled) return true;
if (!isEventView (id)) return true;
- NSEvent nsEvent = new NSEvent(event);
- return sendGestureEvent (nsEvent, detail, true);
+ if (!hooks(SWT.Gesture) && !filters(SWT.Gesture)) return true;
+ NSEvent nsEvent = new NSEvent(eventPtr);
+ Event event = new Event();
+ NSPoint windowPoint;
+ NSView view = eventView ();
+ windowPoint = nsEvent.locationInWindow();
+ NSPoint point = view.convertPoint_fromView_(windowPoint, null);
+ if (!view.isFlipped ()) {
+ point.y = view.bounds().height - point.y;
+ }
+ event.x = (int) point.x;
+ event.y = (int) point.y;
+ setInputState (event, nsEvent, SWT.Gesture);
+ event.detail = detail;
+
+ if (detail == SWT.GESTURE_BEGIN) {
+ display.gestureStarted = true;
+ display.rotation = 0.0;
+ display.magnification = 1.0;
+ } else if (detail == SWT.GESTURE_END) {
+ display.gestureStarted = false;
+ }
+
+ switch (detail) {
+ case SWT.GESTURE_SWIPE:
+ event.xDirection = (int) -nsEvent.deltaX();
+ event.yDirection = (int) -nsEvent.deltaY();
+ break;
+ case SWT.GESTURE_ROTATE: {
+ display.rotation += nsEvent.rotation();
+ event.rotation = display.rotation;
+ break;
+ }
+ case SWT.GESTURE_MAGNIFY:
+ display.magnification += nsEvent.magnification();
+ event.magnification = display.magnification;
+ break;
+ case SWT.GESTURE_PAN:
+ // Panning increment is expressed in terms of the direction of movement,
+ // not in terms of scrolling increment.
+ event.xDirection = (int) -nsEvent.deltaX();
+ event.yDirection = (int) -nsEvent.deltaY();
+ if (event.xDirection == 0 && event.yDirection == 0) return false;
+ break;
+ }
+
+ sendEvent (SWT.Gesture, event);
+ return event.doit;
}
/**
@@ -2248,7 +2322,7 @@
}
void magnifyWithEvent(int /*long*/ id, int /*long*/ sel, int /*long*/ event) {
- if (!gestureEvent(id, sel, event, SWT.GESTURE_MAGNIFY)) return;
+ if (!gestureEvent(id, event, SWT.GESTURE_MAGNIFY)) return;
super.magnifyWithEvent(id, sel, event);
}
@@ -2289,22 +2363,26 @@
boolean handled = false;
if (id == view.id) {
NSEvent nsEvent = new NSEvent(theEvent);
- if (display.gestureStarted && hooks(SWT.Gesture)) {
- if (!sendGestureEvent(nsEvent, SWT.GESTURE_PAN, true)) {
- handled = true;
+ if ((hooks(SWT.Gesture) || filters(SWT.Gesture))) {
+ if (nsEvent.deltaY() != 0 || nsEvent.deltaX() != 0) {
+ if (!gestureEvent(id, theEvent, SWT.GESTURE_PAN)) {
+ handled = true;
+ }
}
}
- if (hooks (SWT.MouseWheel) || filters (SWT.MouseWheel)) {
- if (nsEvent.deltaY() != 0) {
- if (!sendMouseEvent(nsEvent, SWT.MouseWheel, true)) {
- handled = true;
+ if (!handled) {
+ if (hooks (SWT.MouseWheel) || filters (SWT.MouseWheel)) {
+ if (nsEvent.deltaY() != 0) {
+ if (!sendMouseEvent(nsEvent, SWT.MouseWheel, true)) {
+ handled = true;
+ }
}
}
- }
- if (hooks (SWT.MouseHorizontalWheel) || filters (SWT.MouseHorizontalWheel)) {
- if (nsEvent.deltaX() != 0) {
- if (!sendMouseEvent(nsEvent, SWT.MouseHorizontalWheel, true)) {
- handled = true;
+ if (hooks (SWT.MouseHorizontalWheel) || filters (SWT.MouseHorizontalWheel)) {
+ if (nsEvent.deltaX() != 0) {
+ if (!sendMouseEvent(nsEvent, SWT.MouseHorizontalWheel, true)) {
+ handled = true;
+ }
}
}
}
@@ -3034,6 +3112,31 @@
/**
* Removes the listener from the collection of listeners who will
+ * be notified when touch events occur.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException TouchListener
instances
+ * registered for the control.
+ *
+ * @param enabled the new touch-enabled state.
+ *
+ * @exception SWTException true
,
* and marks it invisible otherwise.
*
@@ -4092,7 +4209,7 @@
}
void swipeWithEvent(int /*long*/ id, int /*long*/ sel, int /*long*/ event) {
- if (!gestureEvent(id, sel, event, SWT.GESTURE_SWIPE)) return;
+ if (!gestureEvent(id, event, SWT.GESTURE_SWIPE)) return;
super.swipeWithEvent(id, sel, event);
}
@@ -4197,6 +4314,94 @@
return view;
}
+void touchEvent(int /*long*/ id, int /*long*/ sel, int /*long*/ eventPtr) {
+ if (!(hooks(SWT.Touch) || filters(SWT.Touch))) return;
+ if (!isEventView (id)) return;
+ NSEvent nsEvent = new NSEvent(eventPtr);
+ NSMutableArray currentTouches = display.currentTouches();
+ Event event = new Event ();
+ NSPoint location = view.convertPoint_fromView_(nsEvent.locationInWindow(), null);
+ if (!view.isFlipped ()) {
+ location.y = view.bounds().height - location.y;
+ }
+ event.x = (int) location.x;
+ event.y = (int) location.y;
+ setInputState (event, nsEvent, SWT.Touch);
+ NSSet allTouchesSet = nsEvent.touchesMatchingPhase(OS.NSTouchPhaseAny, null);
+ int /*long*/ touchCount = allTouchesSet.count();
+ Touch touches[] = new Touch[(int)/*64*/touchCount];
+ int currTouchIndex = 0;
+
+ // Process removed/cancelled touches first.
+ NSArray endedTouches = nsEvent.touchesMatchingPhase(OS.NSTouchPhaseEnded | OS.NSTouchPhaseCancelled, null).allObjects();
+
+ for (int i = 0; i < endedTouches.count(); i++) {
+ NSTouch touch = new NSTouch(endedTouches.objectAtIndex(i).id);
+ NSObject identity = new NSObject(OS.objc_msgSend(touch.id, OS.sel_identity));
+ NSTouch endedTouch = findTouchWithId(currentTouches, identity);
+ if (endedTouch != null) currentTouches.removeObject(endedTouch);
+ touches[currTouchIndex++] = touchStateFromNSTouch(touch);
+ }
+
+ if (currentTouches.count() == 0) display.touchCounter = 0;
+
+ // Process touches in progress or starting.
+ NSArray activeTouches = nsEvent.touchesMatchingPhase(OS.NSTouchPhaseBegan | OS.NSTouchPhaseMoved | OS.NSTouchPhaseStationary, null).allObjects();
+
+ for (int i = 0; i < activeTouches.count(); i++) {
+ NSTouch touch = new NSTouch(activeTouches.objectAtIndex(i).id);
+ NSObject identity = new NSObject(OS.objc_msgSend(touch.id, OS.sel_identity));
+ NSTouch activeTouch = findTouchWithId(currentTouches, identity);
+ if (activeTouch == null) currentTouches.addObject(touch);
+ touches[currTouchIndex++] = touchStateFromNSTouch(touch);
+ }
+
+// if (activeTouches.count() != currentTouches.count()) {
+// /**
+// * Bug in Cocoa. Under some situations we don't get the NSTouchPhaseEnded/Cancelled notification. Most commonly this happens
+// * if a 4-finger gesture occurs and the application switcher appears. Workaround is to generate a TOUCHSTATE_UP for the
+// * orphaned touch.
+// */
+// for (int /*long*/ j = currentTouches.count() - 1; j >= 0 ; j--) {
+// NSTouch touch = new NSTouch(currentTouches.objectAtIndex(j).id);
+// NSObject identity = new NSObject(OS.objc_msgSend(touch.id, OS.sel_identity));
+// NSTouch activeTouch = findTouchWithId(activeTouches, identity);
+// if (activeTouch == null) {
+// Touch fakeTouchUp = touchStateFromNSTouch(touch);
+// fakeTouchUp.phase = Touch.TOUCHSTATE_UP;
+//
+// if (currTouchIndex == touches.length) {
+// Touch newTouchStates[] = new Touch[touches.length + 1];
+// System.arraycopy(touches, 0, newTouchStates, 0, touches.length);
+// touches = newTouchStates;
+// }
+//
+// touches[currTouchIndex++] = fakeTouchUp;
+// currentTouches.removeObject(activeTouch);
+// }
+// }
+// }
+
+ event.touches = touches;
+ postEvent (SWT.Touch, event);
+}
+
+void touchesBeganWithEvent (int /*long*/ id, int /*long*/ sel, int /*long*/ event) {
+ touchEvent(id, sel, event);
+}
+
+void touchesCancelledWithEvent (int /*long*/ id, int /*long*/ sel, int /*long*/ event) {
+ touchEvent(id, sel, event);
+}
+
+void touchesEndedWithEvent (int /*long*/ id, int /*long*/ sel, int /*long*/ event) {
+ touchEvent(id, sel, event);
+}
+
+void touchesMovedWithEvent (int /*long*/ id, int /*long*/ sel, int /*long*/ event) {
+ touchEvent(id, sel, event);
+}
+
boolean translateTraversal (int key, NSEvent theEvent, boolean [] consume) {
int detail = SWT.TRAVERSE_NONE;
int code = traversalCode (key, theEvent);
Index: Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java,v
retrieving revision 1.366
diff -u -r1.366 Display.java
--- Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java 11 Jan 2011 19:19:17 -0000 1.366
+++ Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java 13 Jan 2011 17:43:23 -0000
@@ -111,6 +111,17 @@
double magnification;
boolean gestureStarted;
+ /* touch event state */
+ int touchCounter;
+ long primaryIdentifier;
+ private NSMutableArray currentTouches;
+ private Map touchSourceMap;
+
+ NSPoint referenceMouseLoc;
+ double refTrackpadX;
+ double refTrackpadY;
+
+
/* Key event management */
int [] deadKeyState = new int[1];
int currentKeyboardUCHRdata;
@@ -985,6 +996,16 @@
mainMenu.release();
}
+NSMutableArray currentTouches() {
+ synchronized (Device.class) {
+ if (currentTouches == null) {
+ currentTouches = (NSMutableArray) new NSMutableArray().alloc();
+ currentTouches = currentTouches.initWithCapacity(5);
+ }
+ }
+ return currentTouches;
+}
+
int /*long*/ cursorSetProc (int /*long*/ id, int /*long*/ sel) {
if (lockCursor) {
if (currentControl != null) {
@@ -1164,6 +1185,23 @@
}
}
+TouchSource findTouchSource(NSTouch touch) {
+ if (touchSourceMap == null) {
+ touchSourceMap = new HashMap();
+ }
+ id touchDevice = touch.device();
+ Long touchDeviceObj = new Long(touchDevice.id);
+ TouchSource returnVal = (TouchSource) touchSourceMap.get(touchDeviceObj);
+
+ if (returnVal == null) {
+ Rectangle bounds = new Rectangle(0, 0, (int)Math.ceil(touch.deviceSize().width), (int)Math.ceil(touch.deviceSize().height));
+ returnVal = new TouchSource(false, bounds);;
+ touchSourceMap.put(touchDeviceObj, returnVal);
+ }
+
+ return returnVal;
+}
+
/**
* Returns the currently active Shell
, or null
* if no shell belonging to the currently running application
@@ -2918,6 +2956,17 @@
return false;
}
+/**
+ * Returns true if a touch-aware input device is attached to the system,
+ * enabled, and ready for use.
+ *
+ * @since 3.7
+ */
+public boolean isTouchEnabled() {
+ // Gestures are available on OS X 10.5.3 and later. Touch events are only available on 10.6 and later.
+ return (OS.VERSION > 0x1053);
+}
+
static boolean isValidClass (Class clazz) {
String name = clazz.getName ();
int index = name.lastIndexOf ('.');