diff options
author | Scott Kovatch <skovatch> | 2009-02-02 18:38:44 +0000 |
---|---|---|
committer | Scott Kovatch <skovatch> | 2009-02-02 18:38:44 +0000 |
commit | 0828fa148f6ab10bffd0dad7cb0381fa25623a9b (patch) | |
tree | c5ecd2cd06cb52cdb93bfcee1e5474e68bd10e0c | |
parent | 3518dcf86c71885a55fc8e7584e113022fefcef3 (diff) | |
download | eclipse.platform.swt-0828fa148f6ab10bffd0dad7cb0381fa25623a9b.tar.gz eclipse.platform.swt-0828fa148f6ab10bffd0dad7cb0381fa25623a9b.tar.xz eclipse.platform.swt-0828fa148f6ab10bffd0dad7cb0381fa25623a9b.zip |
262970 - implement drag hysteresis in dragDetect.
9 files changed, 90 insertions, 13 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/library/os.c b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/library/os.c index 5ca280c811..2a3c451878 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/library/os.c +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/library/os.c @@ -2039,6 +2039,18 @@ JNIEXPORT jintLong JNICALL OS_NATIVE(NSErrorFailingURLStringKey) } #endif +#ifndef NO_NSEventTrackingRunLoopMode +JNIEXPORT jintLong JNICALL OS_NATIVE(NSEventTrackingRunLoopMode) + (JNIEnv *env, jclass that) +{ + jintLong rc = 0; + OS_NATIVE_ENTER(env, that, NSEventTrackingRunLoopMode_FUNC); + rc = (jintLong)NSEventTrackingRunLoopMode; + OS_NATIVE_EXIT(env, that, NSEventTrackingRunLoopMode_FUNC); + return rc; +} +#endif + #ifndef NO_NSFileTypeForHFSTypeCode JNIEXPORT jintLong JNICALL OS_NATIVE(NSFileTypeForHFSTypeCode) (JNIEnv *env, jclass that, jint arg0) diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/library/os_stats.c b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/library/os_stats.c index 59c491df6a..c02cf368d1 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/library/os_stats.c +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/library/os_stats.c @@ -14,8 +14,8 @@ #ifdef NATIVE_STATS -int OS_nativeFunctionCount = 381; -int OS_nativeFunctionCallCount[381]; +int OS_nativeFunctionCount = 382; +int OS_nativeFunctionCallCount[382]; char * OS_nativeFunctionNames[] = { "CFRelease", "CFRunLoopAddObserver", @@ -182,6 +182,7 @@ char * OS_nativeFunctionNames[] = { "NSDragPboard", "NSEqualRects", "NSErrorFailingURLStringKey", + "NSEventTrackingRunLoopMode", "NSFileTypeForHFSTypeCode", "NSFilenamesPboardType", "NSFontAttributeName", diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/library/os_stats.h b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/library/os_stats.h index df78b9b7c5..9d783f9e01 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/library/os_stats.h +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/library/os_stats.h @@ -190,6 +190,7 @@ typedef enum { NSDragPboard_FUNC, NSEqualRects_FUNC, NSErrorFailingURLStringKey_FUNC, + NSEventTrackingRunLoopMode_FUNC, NSFileTypeForHFSTypeCode_FUNC, NSFilenamesPboardType_FUNC, NSFontAttributeName_FUNC, diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras index 0fd052674f..c6358e60f6 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras @@ -414,7 +414,7 @@ <constant name="NSEditableBinding"></constant> <constant name="NSEditorDocumentAttribute"></constant> <constant name="NSEnabledBinding"></constant> -<constant name="NSEventTrackingRunLoopMode"></constant> +<constant name="NSEventTrackingRunLoopMode" swt_gen="true"></constant> <constant name="NSExcludedElementsDocumentAttribute"></constant> <constant name="NSExcludedKeysBinding"></constant> <constant name="NSExpansionAttributeName"></constant> @@ -2852,10 +2852,10 @@ <method selector="orderedWindows" swt_gen="true"> <retval swt_gen="true"></retval> </method> -<method selector="postEvent:atStart:"> -<arg name="event"></arg> -<arg name="flag"></arg> -<retval></retval> +<method selector="postEvent:atStart:" swt_gen="true"> +<arg name="event" swt_gen="true"></arg> +<arg name="flag" swt_gen="true"></arg> +<retval swt_gen="true"></retval> </method> <method selector="preventWindowOrdering"> <retval></retval> diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/FoundationFull.bridgesupport.extras b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/FoundationFull.bridgesupport.extras index dceeb0197c..56b4053033 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/FoundationFull.bridgesupport.extras +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/FoundationFull.bridgesupport.extras @@ -6302,8 +6302,8 @@ <method selector="removeAllObjects"> <retval></retval> </method> -<method selector="removeLastObject"> -<retval></retval> +<method selector="removeLastObject" swt_gen="true"> +<retval swt_gen="true"></retval> </method> <method selector="removeObject:" swt_gen="true"> <arg name="anObject" swt_gen="true"></arg> diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSApplication.java b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSApplication.java index 4d7cfd1f83..64fedf049e 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSApplication.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSApplication.java @@ -73,6 +73,10 @@ public NSArray orderedWindows() { return result != 0 ? new NSArray(result) : null; } +public void postEvent(NSEvent event, boolean flag) { + OS.objc_msgSend(this.id, OS.sel_postEvent_atStart_, event != null ? event.id : 0, flag); +} + public void run() { OS.objc_msgSend(this.id, OS.sel_run); } diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSMutableArray.java b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSMutableArray.java index dadd58babf..6f64b026fa 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSMutableArray.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSMutableArray.java @@ -37,6 +37,10 @@ public static NSMutableArray arrayWithCapacity(int /*long*/ numItems) { return result != 0 ? new NSMutableArray(result) : null; } +public void removeLastObject() { + OS.objc_msgSend(this.id, OS.sel_removeLastObject); +} + public void removeObject(id anObject) { OS.objc_msgSend(this.id, OS.sel_removeObject_, anObject != null ? anObject.id : 0); } diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java index 3a518c9945..7e96408e6e 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java @@ -1031,6 +1031,7 @@ public static final int /*long*/ sel_pointSize = sel_registerName("pointSize"); public static final int /*long*/ sel_pointValue = sel_registerName("pointValue"); public static final int /*long*/ sel_pointingHandCursor = sel_registerName("pointingHandCursor"); public static final int /*long*/ sel_popUpContextMenu_withEvent_forView_ = sel_registerName("popUpContextMenu:withEvent:forView:"); +public static final int /*long*/ sel_postEvent_atStart_ = sel_registerName("postEvent:atStart:"); public static final int /*long*/ sel_prependTransform_ = sel_registerName("prependTransform:"); public static final int /*long*/ sel_preventDefault = sel_registerName("preventDefault"); public static final int /*long*/ sel_printDocumentView = sel_registerName("printDocumentView"); @@ -1060,6 +1061,7 @@ public static final int /*long*/ sel_removeFromSuperview = sel_registerName("rem public static final int /*long*/ sel_removeItem_ = sel_registerName("removeItem:"); public static final int /*long*/ sel_removeItemAtIndex_ = sel_registerName("removeItemAtIndex:"); public static final int /*long*/ sel_removeItemAtPath_error_ = sel_registerName("removeItemAtPath:error:"); +public static final int /*long*/ sel_removeLastObject = sel_registerName("removeLastObject"); public static final int /*long*/ sel_removeObject_ = sel_registerName("removeObject:"); public static final int /*long*/ sel_removeObjectAtIndex_ = sel_registerName("removeObjectAtIndex:"); public static final int /*long*/ sel_removeObserver_ = sel_registerName("removeObserver:"); @@ -3555,6 +3557,9 @@ public static final NSString NSDeviceResolution = new NSString(NSDeviceResolutio public static final native int /*long*/ NSDragPboard(); public static final NSString NSDragPboard = new NSString(NSDragPboard()); /** @method flags=const */ +public static final native int /*long*/ NSEventTrackingRunLoopMode(); +public static final NSString NSEventTrackingRunLoopMode = new NSString(NSEventTrackingRunLoopMode()); +/** @method flags=const */ public static final native int /*long*/ NSFilenamesPboardType(); public static final NSString NSFilenamesPboardType = new NSString(NSFilenamesPboardType()); /** @method flags=const */ diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Control.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Control.java index 2c9dab7be5..86c08428b4 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Control.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Control.java @@ -55,7 +55,6 @@ public abstract class Control extends Widget implements Drawable { String toolTipText; Object layoutData; int drawCount; -// int visibleRgn; Menu menu; Color foreground, background; Image backgroundImage; @@ -63,11 +62,15 @@ public abstract class Control extends Widget implements Drawable { Cursor cursor; Region region; NSBezierPath regionPath; -// GCData gcs[]; Accessible accessible; // static final String RESET_VISIBLE_REGION = "org.eclipse.swt.internal.resetVisibleRegion"; + /** + * Magic number comes from experience. There's no API for this value in Cocoa or Carbon. + */ + static final int DEFAULT_DRAG_HYSTERESIS = 5; + Control () { /* Do nothing */ } @@ -896,9 +899,56 @@ boolean dragDetect (int button, int count, int stateMask, int x, int y) { } boolean dragDetect (int x, int y, boolean filter, boolean [] consume) { + /** + * Feature in Cocoa. Mouse drag events do not account for hysteresis. + * As soon as the mouse drags a mouse dragged event is fired. Fix is to + * check for another mouse drag event that is at least 5 pixels away + * from the start of the drag. + */ NSApplication application = NSApplication.sharedApplication(); - NSEvent event = application.nextEventMatchingMask(OS.NSLeftMouseDraggedMask, NSDate.dateWithTimeIntervalSinceNow(0.2), OS.NSDefaultRunLoopMode, false); - return (event != null); + boolean dragging = false; + int /*long*/ eventType = OS.NSLeftMouseDown; + float /*double*/ dragX = x; + float /*double*/ dragY = y; + + /** + * To check for an actual drag we need to pull off mouse moved and mouse up events + * to detect if the user dragged outside of a 10 x 10 box centered on the mouse down location. + * We still want the view to see the events, so save them and re-post when done checking. + */ + NSEvent mouseUpEvent = null; + NSMutableArray dragEvents = NSMutableArray.arrayWithCapacity(10); + + while (eventType != OS.NSLeftMouseUp) { + NSEvent event = application.nextEventMatchingMask((OS.NSLeftMouseUpMask | OS.NSLeftMouseDraggedMask), + NSDate.distantFuture(), OS.NSEventTrackingRunLoopMode, true); + eventType = event.type(); + + if (eventType == OS.NSLeftMouseDragged) { + dragEvents.addObject(event); + NSPoint windowLoc = event.locationInWindow(); + NSPoint viewLoc = view.convertPoint_fromView_(windowLoc, null); + if ((Math.abs(viewLoc.x - dragX) > DEFAULT_DRAG_HYSTERESIS) || (Math.abs(viewLoc.y - dragY) > DEFAULT_DRAG_HYSTERESIS)) { + dragging = true; + break; + } + } else if (eventType == OS.NSLeftMouseUp) { + mouseUpEvent = event; + } + } + + // Push back any events we took out of the queue so the control can receive them. + if (mouseUpEvent != null) application.postEvent(mouseUpEvent, true); + + if (dragEvents.count() > 0) { + while (dragEvents.count() > 0) { + NSEvent currEvent = new NSEvent(dragEvents.objectAtIndex(dragEvents.count() - 1).id); + dragEvents.removeLastObject(); + application.postEvent(currEvent, true); + } + } + + return dragging; } boolean drawGripper (int x, int y, int width, int height, boolean vertical) { |