diff --git a/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java b/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java index 052b91726b6..c907804c96a 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java @@ -336,7 +336,7 @@ public abstract class LWComponentPeer return peerTreeLock; } - final T getTarget() { + public final T getTarget() { return target; } diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CCursorManager.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CCursorManager.java index 6554dc9028f..1a1f6d5e700 100644 --- a/jdk/src/macosx/classes/sun/lwawt/macosx/CCursorManager.java +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CCursorManager.java @@ -51,15 +51,6 @@ final class CCursorManager extends LWCursorManager { @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 @@ final class CCursorManager extends LWCursorManager { // 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; - } } diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java index b4f9fd7abb5..0c0f3e7f1df 100644 --- a/jdk/src/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java @@ -38,8 +38,12 @@ import javax.swing.text.*; 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 @@ public final class CDragSourceContextPeer extends SunDragSourceContextPeer { } //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 @@ public final class CDragSourceContextPeer extends SunDragSourceContextPeer { 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 @@ public final class CDragSourceContextPeer extends SunDragSourceContextPeer { 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 @@ public final class CDragSourceContextPeer extends SunDragSourceContextPeer { } catch (Exception e) { e.printStackTrace(); } finally { - CCursorManager.getInstance().stopDrag(); - releaseNativeDragSource(nativeDragSource); fDragImage = null; if (fDragCImage != null) { @@ -189,8 +184,6 @@ public final class CDragSourceContextPeer extends SunDragSourceContextPeer { } catch (Exception e) { - CCursorManager.getInstance().stopDrag(); - final long nativeDragSource = getNativeContext(); setNativeContext(0); releaseNativeDragSource(nativeDragSource); @@ -416,13 +409,24 @@ public final class CDragSourceContextPeer extends SunDragSourceContextPeer { final int modifiers, final int x, final int y) { - CCursorManager.getInstance().updateDragPosition(x, y); + try { + Component componentAt = LWCToolkit.invokeAndWait( + new Callable() { + @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 @@ public final class CDragSourceContextPeer extends SunDragSourceContextPeer { } 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; + } - postDragSourceDragEvent(targetActions, modifiers, x, y, DISPATCH_ENTER); + if (root.getDropTarget() != null && root.getDropTarget().isActive()) { + return root; + } + + 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 @@ public final class CDragSourceContextPeer extends SunDragSourceContextPeer { 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); diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CDropTarget.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CDropTarget.java index 98088fbb636..1448424e0ee 100644 --- a/jdk/src/macosx/classes/sun/lwawt/macosx/CDropTarget.java +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CDropTarget.java @@ -30,6 +30,7 @@ import java.awt.peer.ComponentPeer; import java.awt.dnd.DropTarget; import sun.lwawt.LWComponentPeer; +import sun.lwawt.PlatformWindow; public final class CDropTarget { @@ -50,21 +51,11 @@ public final class CDropTarget { 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."); } } diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java index 3fb585bdb53..8854efde770 100644 --- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java @@ -875,6 +875,21 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo } } + /** + * 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. *************************************************************/ diff --git a/jdk/src/macosx/native/sun/awt/CDragSource.h b/jdk/src/macosx/native/sun/awt/CDragSource.h index 7e880cb529e..483924e81ef 100644 --- a/jdk/src/macosx/native/sun/awt/CDragSource.h +++ b/jdk/src/macosx/native/sun/awt/CDragSource.h @@ -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; diff --git a/jdk/src/macosx/native/sun/awt/CDragSource.m b/jdk/src/macosx/native/sun/awt/CDragSource.m index 635026483d3..47b6a6b602c 100644 --- a/jdk/src/macosx/native/sun/awt/CDragSource.m +++ b/jdk/src/macosx/native/sun/awt/CDragSource.m @@ -84,12 +84,22 @@ static BOOL sNeedsEnter; 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 @@ static BOOL sNeedsEnter; // 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 @@ static BOOL sNeedsEnter; // 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 @@ static BOOL sNeedsEnter; fComponent = NULL; } - if (fComponentPeer != NULL) { - JNFDeleteGlobalRef(env, fComponentPeer); - fComponentPeer = NULL; - } - if (fDragSourceContextPeer != NULL) { JNFDeleteGlobalRef(env, fDragSourceContextPeer); fDragSourceContextPeer = NULL; @@ -178,11 +180,6 @@ static BOOL sNeedsEnter; fTriggerEvent = NULL; } - if (fCursor != NULL) { - JNFDeleteGlobalRef(env, fCursor); - fCursor = NULL; - } - if (fFormats != NULL) { JNFDeleteGlobalRef(env, fFormats); fFormats = NULL; @@ -586,11 +583,6 @@ static BOOL sNeedsEnter; { 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) } diff --git a/jdk/src/macosx/native/sun/awt/CDragSourceContextPeer.m b/jdk/src/macosx/native/sun/awt/CDragSourceContextPeer.m index 46788795f45..97720fb38ec 100644 --- a/jdk/src/macosx/native/sun/awt/CDragSourceContextPeer.m +++ b/jdk/src/macosx/native/sun/awt/CDragSourceContextPeer.m @@ -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 @@ JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CDragSourceContextPeer_createNativ 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 @@ JNF_COCOA_ENTER(env); [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); -} diff --git a/jdk/src/macosx/native/sun/awt/CDropTarget.m b/jdk/src/macosx/native/sun/awt/CDropTarget.m index 9dda8ae3551..260bbdec82e 100644 --- a/jdk/src/macosx/native/sun/awt/CDropTarget.m +++ b/jdk/src/macosx/native/sun/awt/CDropTarget.m @@ -81,9 +81,8 @@ extern JNFClassInfo jc_CDropTargetContextPeer; 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 @@ extern JNFClassInfo jc_CDropTargetContextPeer; { DLog2(@"[CDropTarget dealloc]: %@\n", self); + if(sCurrentDropTarget == self) { + sCurrentDropTarget = nil; + } + [fView release]; fView = nil; @@ -490,7 +493,10 @@ extern JNFClassInfo jc_CDropTargetContextPeer; 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 @@ extern JNFClassInfo jc_CDropTargetContextPeer; // 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 @@ extern JNFClassInfo jc_CDropTargetContextPeer; 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] diff --git a/jdk/src/share/classes/sun/awt/dnd/SunDragSourceContextPeer.java b/jdk/src/share/classes/sun/awt/dnd/SunDragSourceContextPeer.java index c5e80b2a695..c2bd2250dd9 100644 --- a/jdk/src/share/classes/sun/awt/dnd/SunDragSourceContextPeer.java +++ b/jdk/src/share/classes/sun/awt/dnd/SunDragSourceContextPeer.java @@ -278,7 +278,7 @@ public abstract class SunDragSourceContextPeer implements DragSourceContextPeer * 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 abstract class SunDragSourceContextPeer implements DragSourceContextPeer 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)); diff --git a/jdk/test/java/awt/dnd/DisposeFrameOnDragCrash/DisposeFrameOnDragTest.java b/jdk/test/java/awt/dnd/DisposeFrameOnDragCrash/DisposeFrameOnDragTest.java new file mode 100644 index 00000000000..05cd0d51840 --- /dev/null +++ b/jdk/test/java/awt/dnd/DisposeFrameOnDragCrash/DisposeFrameOnDragTest.java @@ -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); + } +}