8006941: [macosx] Deadlock in drag and drop
7199783: Setting cursor on DragSourceContext does not work on OSX
Reviewed-by: anthony, serb
--- a/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java Wed Apr 03 20:54:26 2013 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java Fri Apr 05 18:29:53 2013 +0100
@@ -336,7 +336,7 @@
return peerTreeLock;
}
- final T getTarget() {
+ public final T getTarget() {
return target;
}
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CCursorManager.java Wed Apr 03 20:54:26 2013 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CCursorManager.java Fri Apr 05 18:29:53 2013 +0100
@@ -51,15 +51,6 @@
@Override
protected Point getCursorPosition() {
- synchronized(this) {
- if (isDragging) {
- // during the drag operation, the appkit thread is blocked,
- // so nativeGetCursorPosition invocation may cause a deadlock.
- // In order to avoid this, we returns last know cursor position.
- return new Point(dragPos);
- }
- }
-
final Point2D nativePosition = nativeGetCursorPosition();
return new Point((int)nativePosition.getX(), (int)nativePosition.getY());
}
@@ -101,31 +92,4 @@
// do something special
throw new RuntimeException("Unimplemented");
}
-
- // package private methods to handle cursor change during drag-and-drop
- private boolean isDragging = false;
- private Point dragPos = null;
-
- synchronized void startDrag(int x, int y) {
- if (isDragging) {
- throw new RuntimeException("Invalid Drag state in CCursorManager!");
- }
- isDragging = true;
- dragPos = new Point(x, y);
- }
-
- synchronized void updateDragPosition(int x, int y) {
- if (!isDragging) {
- throw new RuntimeException("Invalid Drag state in CCursorManager!");
- }
- dragPos.move(x, y);
- }
-
- synchronized void stopDrag() {
- if (!isDragging) {
- throw new RuntimeException("Invalid Drag state in CCursorManager!");
- }
- isDragging = false;
- dragPos = null;
- }
}
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java Wed Apr 03 20:54:26 2013 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java Fri Apr 05 18:29:53 2013 +0100
@@ -38,8 +38,12 @@
import javax.accessibility.*;
import java.util.Map;
+import java.util.concurrent.Callable;
+
import sun.awt.dnd.*;
import sun.lwawt.LWComponentPeer;
+import sun.lwawt.LWWindowPeer;
+import sun.lwawt.PlatformWindow;
public final class CDragSourceContextPeer extends SunDragSourceContextPeer {
@@ -104,13 +108,8 @@
}
//It sure will be LWComponentPeer instance as rootComponent is a Window
- LWComponentPeer peer = (LWComponentPeer)rootComponent.getPeer();
- //Get a pointer to a native window
- CPlatformWindow platformWindow = (CPlatformWindow) peer.getPlatformWindow();
- long nativeWindowPtr = platformWindow.getNSWindowPtr();
-
- // Get drag cursor:
- Cursor cursor = this.getCursor();
+ PlatformWindow platformWindow = ((LWComponentPeer)rootComponent.getPeer()).getPlatformWindow();
+ long nativeViewPtr = CPlatformWindow.getNativeViewPtr(platformWindow);
// If there isn't any drag image make one of default appearance:
if (fDragImage == null)
@@ -139,19 +138,15 @@
try {
// Create native dragging source:
- final long nativeDragSource = createNativeDragSource(component, peer, nativeWindowPtr, transferable, triggerEvent,
+ final long nativeDragSource = createNativeDragSource(component, nativeViewPtr, transferable, triggerEvent,
(int) (dragOrigin.getX()), (int) (dragOrigin.getY()), extModifiers,
- clickCount, timestamp, cursor, fDragCImage, dragImageOffset.x, dragImageOffset.y,
+ clickCount, timestamp, fDragCImage, dragImageOffset.x, dragImageOffset.y,
getDragSourceContext().getSourceActions(), formats, formatMap);
if (nativeDragSource == 0)
throw new InvalidDnDOperationException("");
setNativeContext(nativeDragSource);
-
- CCursorManager.getInstance().startDrag(
- (int) (dragOrigin.getX()),
- (int) (dragOrigin.getY()));
}
catch (Exception e) {
@@ -160,6 +155,8 @@
SunDropTargetContextPeer.setCurrentJVMLocalSourceTransferable(transferable);
+ CCursorManager.getInstance().setCursor(getCursor());
+
// Create a new thread to run the dragging operation since it's synchronous, only coming back
// after dragging is finished. This leaves the AWT event thread free to handle AWT events which
// are posted during dragging by native event handlers.
@@ -173,8 +170,6 @@
} catch (Exception e) {
e.printStackTrace();
} finally {
- CCursorManager.getInstance().stopDrag();
-
releaseNativeDragSource(nativeDragSource);
fDragImage = null;
if (fDragCImage != null) {
@@ -189,8 +184,6 @@
}
catch (Exception e) {
- CCursorManager.getInstance().stopDrag();
-
final long nativeDragSource = getNativeContext();
setNativeContext(0);
releaseNativeDragSource(nativeDragSource);
@@ -416,13 +409,24 @@
final int modifiers,
final int x, final int y) {
- CCursorManager.getInstance().updateDragPosition(x, y);
+ try {
+ Component componentAt = LWCToolkit.invokeAndWait(
+ new Callable<Component>() {
+ @Override
+ public Component call() {
+ LWWindowPeer mouseEventComponent = LWWindowPeer.getWindowUnderCursor();
+ if (mouseEventComponent == null) {
+ return null;
+ }
+ Component root = SwingUtilities.getRoot(mouseEventComponent.getTarget());
+ if (root == null) {
+ return null;
+ }
+ Point rootLocation = root.getLocationOnScreen();
+ return getDropTargetAt(root, x - rootLocation.x, y - rootLocation.y);
+ }
+ }, getComponent());
- Component rootComponent = SwingUtilities.getRoot(getComponent());
- if(rootComponent != null) {
- Point componentPoint = new Point(x, y);
- SwingUtilities.convertPointFromScreen(componentPoint, rootComponent);
- Component componentAt = SwingUtilities.getDeepestComponentAt(rootComponent, componentPoint.x, componentPoint.y);
if(componentAt != hoveringComponent) {
if(hoveringComponent != null) {
dragExit(x, y);
@@ -432,20 +436,36 @@
}
hoveringComponent = componentAt;
}
+
+ postDragSourceDragEvent(targetActions, modifiers, x, y,
+ DISPATCH_MOUSE_MOVED);
+ } catch (Exception e) {
+ throw new InvalidDnDOperationException("Failed to handle DragMouseMoved event");
}
- postDragSourceDragEvent(targetActions, modifiers, x, y,
- DISPATCH_MOUSE_MOVED);
}
- /**
- * upcall from native code
- */
- private void dragEnter(final int targetActions,
- final int modifiers,
- final int x, final int y) {
- CCursorManager.getInstance().updateDragPosition(x, y);
+ //Returns the first lightweight or heavyweight Component which has a dropTarget ready to accept the drag
+ //Should be called from the EventDispatchThread
+ private static Component getDropTargetAt(Component root, int x, int y) {
+ if (!root.contains(x, y) || !root.isEnabled() || !root.isVisible()) {
+ return null;
+ }
+
+ if (root.getDropTarget() != null && root.getDropTarget().isActive()) {
+ return root;
+ }
- postDragSourceDragEvent(targetActions, modifiers, x, y, DISPATCH_ENTER);
+ if (root instanceof Container) {
+ for (Component comp : ((Container) root).getComponents()) {
+ Point loc = comp.getLocation();
+ Component dropTarget = getDropTargetAt(comp, x - loc.x, y - loc.y);
+ if (dropTarget != null) {
+ return dropTarget;
+ }
+ }
+ }
+
+ return null;
}
/**
@@ -455,19 +475,15 @@
hoveringComponent = null;
}
- public void setCursor(Cursor c) throws InvalidDnDOperationException {
- // TODO : BG
- //AWTLockAccess.awtLock();
- super.setCursor(c);
- //AWTLockAccess.awtUnlock();
+ @Override
+ protected void setNativeCursor(long nativeCtxt, Cursor c, int cType) {
+ CCursorManager.getInstance().setCursor(c);
}
- protected native void setNativeCursor(long nativeCtxt, Cursor c, int cType);
-
// Native support:
- private native long createNativeDragSource(Component component, ComponentPeer peer, long nativePeer, Transferable transferable,
+ private native long createNativeDragSource(Component component, long nativePeer, Transferable transferable,
InputEvent triggerEvent, int dragPosX, int dragPosY, int extModifiers, int clickCount, long timestamp,
- Cursor cursor, CImage nsDragImage, int dragImageOffsetX, int dragImageOffsetY,
+ CImage nsDragImage, int dragImageOffsetX, int dragImageOffsetY,
int sourceActions, long[] formats, Map formatMap);
private native void doDragging(long nativeDragSource);
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CDropTarget.java Wed Apr 03 20:54:26 2013 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CDropTarget.java Fri Apr 05 18:29:53 2013 +0100
@@ -30,6 +30,7 @@
import java.awt.dnd.DropTarget;
import sun.lwawt.LWComponentPeer;
+import sun.lwawt.PlatformWindow;
public final class CDropTarget {
@@ -50,21 +51,11 @@
fComponent = component;
fPeer = peer;
- // Make sure the drop target is a ComponentModel:
- if (!(peer instanceof LWComponentPeer))
- throw new IllegalArgumentException("CDropTarget's peer must be a LWComponentPeer.");
-
- // Get model pointer (CButton.m and such) and its native peer:
- LWComponentPeer model = (LWComponentPeer) peer;
- if (model.getPlatformWindow() instanceof CPlatformWindow) {
- CPlatformWindow platformWindow = (CPlatformWindow) model.getPlatformWindow();
- long nativePeer = platformWindow.getNSWindowPtr();
-
- // Create native dragging destination:
- fNativeDropTarget = this.createNativeDropTarget(dropTarget, component, peer, nativePeer);
- if (fNativeDropTarget == 0) {
- throw new IllegalStateException("CDropTarget.createNativeDropTarget() failed.");
- }
+ long nativePeer = CPlatformWindow.getNativeViewPtr(((LWComponentPeer) peer).getPlatformWindow());
+ // Create native dragging destination:
+ fNativeDropTarget = this.createNativeDropTarget(dropTarget, component, peer, nativePeer);
+ if (fNativeDropTarget == 0) {
+ throw new IllegalStateException("CDropTarget.createNativeDropTarget() failed.");
}
}
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Wed Apr 03 20:54:26 2013 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Fri Apr 05 18:29:53 2013 +0100
@@ -875,6 +875,21 @@
}
}
+ /**
+ * Helper method to get a pointer to the native view from the PlatformWindow.
+ */
+ static long getNativeViewPtr(PlatformWindow platformWindow) {
+ long nativePeer = 0L;
+ if (platformWindow instanceof CPlatformWindow) {
+ nativePeer = ((CPlatformWindow) platformWindow).getContentView().getAWTView();
+ } else if (platformWindow instanceof CViewPlatformEmbeddedFrame){
+ nativePeer = ((CViewPlatformEmbeddedFrame) platformWindow).getNSViewPtr();
+ } else {
+ throw new IllegalArgumentException("Unsupported platformWindow implementation");
+ }
+ return nativePeer;
+ }
+
/*************************************************************
* Callbacks from the AWTWindow and AWTView objc classes.
*************************************************************/
--- a/jdk/src/macosx/native/sun/awt/CDragSource.h Wed Apr 03 20:54:26 2013 +0400
+++ b/jdk/src/macosx/native/sun/awt/CDragSource.h Fri Apr 05 18:29:53 2013 +0100
@@ -33,7 +33,6 @@
@private
NSView* fView;
jobject fComponent;
- jobject fComponentPeer;
jobject fDragSourceContextPeer;
jobject fTransferable;
@@ -43,8 +42,6 @@
jint fClickCount;
jint fModifiers;
- jobject fCursor;
-
NSImage* fDragImage;
NSPoint fDragImageOffset;
@@ -59,12 +56,22 @@
+ (CDragSource *) currentDragSource;
// Common methods:
-- (id)init:(jobject)jdragsourcecontextpeer component:(jobject)jcomponent peer:(jobject)jpeer control:(id)control
- transferable:(jobject)jtransferable triggerEvent:(jobject)jtrigger
- dragPosX:(jint)dragPosX dragPosY:(jint)dragPosY modifiers:(jint)extModifiers clickCount:(jint)clickCount timeStamp:(jlong)timeStamp
- cursor:(jobject)jcursor
- dragImage:(jobject)jnsdragimage dragImageOffsetX:(jint)jdragimageoffsetx dragImageOffsetY:(jint)jdragimageoffsety
- sourceActions:(jint)jsourceactions formats:(jlongArray)jformats formatMap:(jobject)jformatmap;
+- (id) init:(jobject)jDragSourceContextPeer
+ component:(jobject)jComponent
+ control:(id)control
+ transferable:(jobject)jTransferable
+ triggerEvent:(jobject)jTrigger
+ dragPosX:(jint)dragPosX
+ dragPosY:(jint)dragPosY
+ modifiers:(jint)extModifiers
+ clickCount:(jint)clickCount
+ timeStamp:(jlong)timeStamp
+ dragImage:(jobject)jDragImage
+ dragImageOffsetX:(jint)jDragImageOffsetX
+ dragImageOffsetY:(jint)jDragImageOffsetY
+ sourceActions:(jint)jSourceActions
+ formats:(jlongArray)jFormats
+ formatMap:(jobject)jFormatMap;
- (void)removeFromView:(JNIEnv *)env;
--- a/jdk/src/macosx/native/sun/awt/CDragSource.m Wed Apr 03 20:54:26 2013 +0400
+++ b/jdk/src/macosx/native/sun/awt/CDragSource.m Fri Apr 05 18:29:53 2013 +0100
@@ -84,12 +84,22 @@
return sCurrentDragSource;
}
-- (id)init:(jobject)jdragsourcecontextpeer component:(jobject)jcomponent peer:(jobject)jpeer control:(id)control
- transferable:(jobject)jtransferable triggerEvent:(jobject)jtrigger
- dragPosX:(jint)dragPosX dragPosY:(jint)dragPosY modifiers:(jint)extModifiers clickCount:(jint)clickCount
- timeStamp:(jlong)timeStamp cursor:(jobject)jcursor
- dragImage:(jobject)jnsdragimage dragImageOffsetX:(jint)jdragimageoffsetx dragImageOffsetY:(jint)jdragimageoffsety
- sourceActions:(jint)jsourceactions formats:(jlongArray)jformats formatMap:(jobject)jformatmap
+- (id) init:(jobject)jDragSourceContextPeer
+ component:(jobject)jComponent
+ control:(id)control
+ transferable:(jobject)jTransferable
+ triggerEvent:(jobject)jTrigger
+ dragPosX:(jint)dragPosX
+ dragPosY:(jint)dragPosY
+ modifiers:(jint)extModifiers
+ clickCount:(jint)clickCount
+ timeStamp:(jlong)timeStamp
+ dragImage:(jobject)jDragImage
+ dragImageOffsetX:(jint)jDragImageOffsetX
+ dragImageOffsetY:(jint)jDragImageOffsetY
+ sourceActions:(jint)jSourceActions
+ formats:(jlongArray)jFormats
+ formatMap:(jobject)jFormatMap
{
self = [super init];
DLog2(@"[CDragSource init]: %@\n", self);
@@ -100,27 +110,25 @@
// Construct the object if we have a valid model for it:
if (control != nil) {
JNIEnv *env = [ThreadUtilities getJNIEnv];
- fComponent = JNFNewGlobalRef(env, jcomponent);
- fComponentPeer = JNFNewGlobalRef(env, jpeer);
- fDragSourceContextPeer = JNFNewGlobalRef(env, jdragsourcecontextpeer);
+ fComponent = JNFNewGlobalRef(env, jComponent);
+ fDragSourceContextPeer = JNFNewGlobalRef(env, jDragSourceContextPeer);
- fTransferable = JNFNewGlobalRef(env, jtransferable);
- fTriggerEvent = JNFNewGlobalRef(env, jtrigger);
- fCursor = JNFNewGlobalRef(env, jcursor);
+ fTransferable = JNFNewGlobalRef(env, jTransferable);
+ fTriggerEvent = JNFNewGlobalRef(env, jTrigger);
- if (jnsdragimage) {
+ if (jDragImage) {
JNF_MEMBER_CACHE(nsImagePtr, CImageClass, "ptr", "J");
- jlong imgPtr = JNFGetLongField(env, jnsdragimage, nsImagePtr);
+ jlong imgPtr = JNFGetLongField(env, jDragImage, nsImagePtr);
fDragImage = (NSImage*) jlong_to_ptr(imgPtr); // Double-casting prevents compiler 'd$|//
[fDragImage retain];
}
- fDragImageOffset = NSMakePoint(jdragimageoffsetx, jdragimageoffsety);
+ fDragImageOffset = NSMakePoint(jDragImageOffsetX, jDragImageOffsetY);
- fSourceActions = jsourceactions;
- fFormats = JNFNewGlobalRef(env, jformats);
- fFormatMap = JNFNewGlobalRef(env, jformatmap);
+ fSourceActions = jSourceActions;
+ fFormats = JNFNewGlobalRef(env, jFormats);
+ fFormatMap = JNFNewGlobalRef(env, jFormatMap);
fTriggerEventTimeStamp = timeStamp;
fDragPos = NSMakePoint(dragPosX, dragPosY);
@@ -129,9 +137,8 @@
// Set this object as a dragging source:
- AWTView *awtView = [((NSWindow *) control) contentView];
- fView = [awtView retain];
- [awtView setDragSource:self];
+ fView = [(AWTView *) control retain];
+ [fView setDragSource:self];
// Let AWTEvent know Java drag is getting underway:
[NSEvent javaDraggingBegin];
@@ -158,11 +165,6 @@
fComponent = NULL;
}
- if (fComponentPeer != NULL) {
- JNFDeleteGlobalRef(env, fComponentPeer);
- fComponentPeer = NULL;
- }
-
if (fDragSourceContextPeer != NULL) {
JNFDeleteGlobalRef(env, fDragSourceContextPeer);
fDragSourceContextPeer = NULL;
@@ -178,11 +180,6 @@
fTriggerEvent = NULL;
}
- if (fCursor != NULL) {
- JNFDeleteGlobalRef(env, fCursor);
- fCursor = NULL;
- }
-
if (fFormats != NULL) {
JNFDeleteGlobalRef(env, fFormats);
fFormats = NULL;
@@ -586,11 +583,6 @@
{
AWT_ASSERT_NOT_APPKIT_THREAD;
- // Set the drag cursor (or not 3839999)
- //JNIEnv *env = [ThreadUtilities getJNIEnv];
- //jobject gCursor = JNFNewGlobalRef(env, fCursor);
- //[EventFactory setJavaCursor:gCursor withEnv:env];
-
[self performSelectorOnMainThread:@selector(doDrag) withObject:nil waitUntilDone:YES]; // AWT_THREADING Safe (called from unique asynchronous thread)
}
--- a/jdk/src/macosx/native/sun/awt/CDragSourceContextPeer.m Wed Apr 03 20:54:26 2013 +0400
+++ b/jdk/src/macosx/native/sun/awt/CDragSourceContextPeer.m Fri Apr 05 18:29:53 2013 +0100
@@ -34,12 +34,13 @@
/*
* Class: sun_lwawt_macosx_CDragSourceContextPeer
* Method: createNativeDragSource
- * Signature: (Ljava/awt/Component;Ljava/awt/peer/ComponentPeer;JLjava/awt/datatransfer/Transferable;Ljava/awt/event/InputEvent;IIIIJLjava/awt/Cursor;IJIII[JLjava/util/Map;)J
+ * Signature: (Ljava/awt/Component;JLjava/awt/datatransfer/Transferable;
+ Ljava/awt/event/InputEvent;IIIIJIJIII[JLjava/util/Map;)J
*/
JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CDragSourceContextPeer_createNativeDragSource
- (JNIEnv *env, jobject jthis, jobject jcomponent, jobject jpeer, jlong jnativepeer, jobject jtransferable,
+ (JNIEnv *env, jobject jthis, jobject jcomponent, jlong jnativepeer, jobject jtransferable,
jobject jtrigger, jint jdragposx, jint jdragposy, jint jextmodifiers, jint jclickcount, jlong jtimestamp,
- jobject jcursor, jobject jnsdragimage, jint jdragimageoffsetx, jint jdragimageoffsety,
+ jobject jnsdragimage, jint jdragimageoffsetx, jint jdragimageoffsety,
jint jsourceactions, jlongArray jformats, jobject jformatmap)
{
id controlObj = (id) jlong_to_ptr(jnativepeer);
@@ -47,12 +48,22 @@
JNF_COCOA_ENTER(env);
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
- dragSource = [[CDragSource alloc] init:jthis component:jcomponent peer:jpeer control:controlObj
- transferable:jtransferable triggerEvent:jtrigger dragPosX:jdragposx
- dragPosY:jdragposy modifiers:jextmodifiers clickCount:jclickcount timeStamp:jtimestamp
- cursor:jcursor dragImage:jnsdragimage dragImageOffsetX:jdragimageoffsetx
- dragImageOffsetY:jdragimageoffsety sourceActions:jsourceactions
- formats:jformats formatMap:jformatmap];
+ dragSource = [[CDragSource alloc] init:jthis
+ component:jcomponent
+ control:controlObj
+ transferable:jtransferable
+ triggerEvent:jtrigger
+ dragPosX:jdragposx
+ dragPosY:jdragposy
+ modifiers:jextmodifiers
+ clickCount:jclickcount
+ timeStamp:jtimestamp
+ dragImage:jnsdragimage
+ dragImageOffsetX:jdragimageoffsetx
+ dragImageOffsetY:jdragimageoffsety
+ sourceActions:jsourceactions
+ formats:jformats
+ formatMap:jformatmap];
}];
JNF_COCOA_EXIT(env);
@@ -94,19 +105,3 @@
[dragSource removeFromView:env];
JNF_COCOA_EXIT(env);
}
-
-/*
- * Class: sun_lwawt_macosx_CDragSourceContextPeer
- * Method: setNativeCursor
- * Signature: (JLjava/awt/Cursor;I)V
- */
-JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CDragSourceContextPeer_setNativeCursor
- (JNIEnv *env, jobject jthis, jlong nativeDragSourceVal, jobject jcursor, jint jcursortype)
-{
- //AWT_ASSERT_NOT_APPKIT_THREAD;
-
-//JNF_COCOA_ENTER(env);
-// jobject gCursor = JNFNewGlobalRef(env, jcursor);
-// [EventFactory setJavaCursor:gCursor withEnv:env];
-//JNF_COCOA_EXIT(env);
-}
--- a/jdk/src/macosx/native/sun/awt/CDropTarget.m Wed Apr 03 20:54:26 2013 +0400
+++ b/jdk/src/macosx/native/sun/awt/CDropTarget.m Fri Apr 05 18:29:53 2013 +0100
@@ -81,9 +81,8 @@
fComponent = JNFNewGlobalRef(env, jcomponent);
fDropTarget = JNFNewGlobalRef(env, jdropTarget);
- AWTView *awtView = [((NSWindow *) control) contentView];
- fView = [awtView retain];
- [awtView setDropTarget:self];
+ fView = [((AWTView *) control) retain];
+ [fView setDropTarget:self];
} else {
@@ -177,6 +176,10 @@
{
DLog2(@"[CDropTarget dealloc]: %@\n", self);
+ if(sCurrentDropTarget == self) {
+ sCurrentDropTarget = nil;
+ }
+
[fView release];
fView = nil;
@@ -490,7 +493,10 @@
JNF_MEMBER_CACHE(handleEnterMessageMethod, jc_CDropTargetContextPeer, "handleEnterMessage", "(Ljava/awt/Component;IIII[JJ)I");
if (sDraggingError == FALSE) {
// Double-casting self gets rid of 'different size' compiler warning:
- actions = JNFCallIntMethod(env, fDropTargetContextPeer, handleEnterMessageMethod, fComponent, (jint) javaLocation.x, (jint) javaLocation.y, dropAction, actions, formats, ptr_to_jlong(self)); // AWT_THREADING Safe (CToolkitThreadBlockedHandler)
+ // AWT_THREADING Safe (CToolkitThreadBlockedHandler)
+ actions = JNFCallIntMethod(env, fDropTargetContextPeer, handleEnterMessageMethod,
+ fComponent, (jint) javaLocation.x, (jint) javaLocation.y,
+ dropAction, actions, formats, ptr_to_jlong(self));
}
if (sDraggingError == FALSE) {
@@ -510,11 +516,6 @@
// Remember the dragOp for no-op'd update messages:
sUpdateOperation = dragOp;
}
-
- // If we are in the same process as the sender, make the sender post the appropriate message
- if (sender) {
- [[CDragSource currentDragSource] postDragEnter];
- }
}
// 9-11-02 Note: the native event thread would not handle an exception gracefully:
@@ -608,11 +609,9 @@
JNF_MEMBER_CACHE(handleExitMessageMethod, jc_CDropTargetContextPeer, "handleExitMessage", "(Ljava/awt/Component;J)V");
if (sDraggingError == FALSE) {
DLog3(@" - dragExit: loc native %f, %f\n", sDraggingLocation.x, sDraggingLocation.y);
- JNFCallVoidMethod(env, fDropTargetContextPeer, handleExitMessageMethod, fComponent, ptr_to_jlong(self)); // AWT_THREADING Safe (CToolkitThreadBlockedHandler)
- // If we are in the same process as the sender, make the sender post the appropriate message
- if (sender) {
- [[CDragSource currentDragSource] postDragExit];
- }
+ // AWT_THREADING Safe (CToolkitThreadBlockedHandler)
+ JNFCallVoidMethod(env, fDropTargetContextPeer,
+ handleExitMessageMethod, fComponent, ptr_to_jlong(self));
}
// 5-27-03 Note: [Radar 3270455]
--- a/jdk/src/share/classes/sun/awt/dnd/SunDragSourceContextPeer.java Wed Apr 03 20:54:26 2013 +0400
+++ b/jdk/src/share/classes/sun/awt/dnd/SunDragSourceContextPeer.java Fri Apr 05 18:29:53 2013 +0100
@@ -278,7 +278,7 @@
* upcall from native code
*/
- private void dragEnter(final int targetActions,
+ protected void dragEnter(final int targetActions,
final int modifiers,
final int x, final int y) {
postDragSourceDragEvent(targetActions, modifiers, x, y, DISPATCH_ENTER);
@@ -356,10 +356,6 @@
public static void setDragDropInProgress(boolean b)
throws InvalidDnDOperationException {
- if (dragDropInProgress == b) {
- throw new InvalidDnDOperationException(getExceptionMessage(b));
- }
-
synchronized (SunDragSourceContextPeer.class) {
if (dragDropInProgress == b) {
throw new InvalidDnDOperationException(getExceptionMessage(b));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/dnd/DisposeFrameOnDragCrash/DisposeFrameOnDragTest.java Fri Apr 05 18:29:53 2013 +0100
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test @summary JVM crash if the frame is disposed in DropTargetListener
+ * @author Petr Pchelko
+ * @library ../../regtesthelpers
+ * @build Util
+ * @compile DisposeFrameOnDragTest.java
+ * @run main/othervm DisposeFrameOnDragTest
+ */
+import java.awt.AWTException;
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.dnd.DropTargetAdapter;
+import java.awt.dnd.DropTargetDragEvent;
+import java.awt.dnd.DropTargetDropEvent;
+import java.awt.event.InputEvent;
+import java.lang.reflect.InvocationTargetException;
+import java.util.TooManyListenersException;
+import javax.swing.JFrame;
+import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
+import test.java.awt.regtesthelpers.Util;
+
+public class DisposeFrameOnDragTest {
+
+ private static JTextArea textArea;
+
+ public static void main(String[] args) throws Throwable {
+
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ constructTestUI();
+ }
+ });
+
+ Util.waitForIdle(null);
+ try {
+ Point loc = textArea.getLocationOnScreen();
+ Util.drag(new Robot(),
+ new Point((int) loc.x + 3, (int) loc.y + 3),
+ new Point((int) loc.x + 40, (int) loc.y + 40),
+ InputEvent.BUTTON1_MASK);
+ } catch (AWTException ex) {
+ throw new RuntimeException("Could not initiate a drag operation");
+ }
+ Util.waitForIdle(null);
+ }
+
+ private static void constructTestUI() {
+ final JFrame frame = new JFrame("Test frame");
+ textArea = new JTextArea("Drag Me!");
+ try {
+ textArea.getDropTarget().addDropTargetListener(new DropTargetAdapter() {
+ @Override
+ public void drop(DropTargetDropEvent dtde) {
+ //IGNORE
+ }
+
+ @Override
+ public void dragOver(DropTargetDragEvent dtde) {
+ frame.dispose();
+ }
+ });
+ } catch (TooManyListenersException ex) {
+ throw new RuntimeException(ex);
+ }
+ textArea.setSize(100, 100);
+ textArea.setDragEnabled(true);
+ textArea.select(0, textArea.getText().length());
+ frame.add(textArea);
+ frame.setBounds(100, 100, 100, 100);
+ frame.setVisible(true);
+ }
+}