--- old/src/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java 2013-02-28 18:59:32.000000000 +0400 +++ new/src/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java 2013-02-28 18:59:32.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; + 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);