--- old/src/macosx/classes/sun/lwawt/LWComponentPeer.java 2013-02-28 16:06:16.000000000 +0400 +++ new/src/macosx/classes/sun/lwawt/LWComponentPeer.java 2013-02-28 16:06:16.000000000 +0400 @@ -336,7 +336,7 @@ return peerTreeLock; } - final T getTarget() { + public final T getTarget() { return target; } --- old/src/macosx/classes/sun/lwawt/macosx/CCursorManager.java 2013-02-28 16:06:17.000000000 +0400 +++ new/src/macosx/classes/sun/lwawt/macosx/CCursorManager.java 2013-02-28 16:06:17.000000000 +0400 @@ -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; - } } --- old/src/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java 2013-02-28 16:06:18.000000000 +0400 +++ new/src/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java 2013-02-28 16:06:18.000000000 +0400 @@ -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,15 @@ } //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 = 0; + if (platformWindow instanceof CPlatformWindow) { + nativeViewPtr = ((CPlatformWindow) platformWindow).getContentView().getAWTView(); + } else if (platformWindow instanceof CViewPlatformEmbeddedFrame) { + nativeViewPtr = ((CViewPlatformEmbeddedFrame) platformWindow).getNSViewPtr(); + } else { + throw new InvalidDnDOperationException("Unsupported PlatformWindow implementation"); + } // If there isn't any drag image make one of default appearance: if (fDragImage == null) @@ -139,19 +145,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 +162,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 +177,6 @@ } catch (Exception e) { e.printStackTrace(); } finally { - CCursorManager.getInstance().stopDrag(); - releaseNativeDragSource(nativeDragSource); fDragImage = null; if (fDragCImage != null) { @@ -189,8 +191,6 @@ } catch (Exception e) { - CCursorManager.getInstance().stopDrag(); - final long nativeDragSource = getNativeContext(); setNativeContext(0); releaseNativeDragSource(nativeDragSource); @@ -416,13 +416,24 @@ 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 +443,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 +482,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); --- old/src/macosx/native/sun/awt/CDragSource.h 2013-02-28 16:06:19.000000000 +0400 +++ new/src/macosx/native/sun/awt/CDragSource.h 2013-02-28 16:06:18.000000000 +0400 @@ -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; --- old/src/macosx/native/sun/awt/CDragSource.m 2013-02-28 16:06:19.000000000 +0400 +++ new/src/macosx/native/sun/awt/CDragSource.m 2013-02-28 16:06:19.000000000 +0400 @@ -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); - - fTransferable = JNFNewGlobalRef(env, jtransferable); - fTriggerEvent = JNFNewGlobalRef(env, jtrigger); - fCursor = JNFNewGlobalRef(env, jcursor); + fComponent = JNFNewGlobalRef(env, jComponent); + fDragSourceContextPeer = JNFNewGlobalRef(env, jDragSourceContextPeer); - if (jnsdragimage) { + fTransferable = JNFNewGlobalRef(env, jTransferable); + fTriggerEvent = JNFNewGlobalRef(env, jTrigger); + + 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) } --- old/src/macosx/native/sun/awt/CDragSourceContextPeer.m 2013-02-28 16:06:20.000000000 +0400 +++ new/src/macosx/native/sun/awt/CDragSourceContextPeer.m 2013-02-28 16:06:20.000000000 +0400 @@ -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); -} --- old/src/macosx/native/sun/awt/CDropTarget.m 2013-02-28 16:06:21.000000000 +0400 +++ new/src/macosx/native/sun/awt/CDropTarget.m 2013-02-28 16:06:21.000000000 +0400 @@ -490,7 +490,9 @@ 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) + actions = JNFCallIntMethod(env, fDropTargetContextPeer, handleEnterMessageMethod, + fComponent, (jint) javaLocation.x, (jint) javaLocation.y, + dropAction, actions, formats, ptr_to_jlong(self)); // AWT_THREADING Safe (CToolkitThreadBlockedHandler) } if (sDraggingError == FALSE) { @@ -510,11 +512,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 +605,8 @@ 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] --- old/src/share/classes/sun/awt/dnd/SunDragSourceContextPeer.java 2013-02-28 16:06:22.000000000 +0400 +++ new/src/share/classes/sun/awt/dnd/SunDragSourceContextPeer.java 2013-02-28 16:06:22.000000000 +0400 @@ -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));