src/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java
Print this page
@@ -36,12 +36,16 @@
import javax.swing.*;
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 {
private static final CDragSourceContextPeer fInstance = new CDragSourceContextPeer(null);
@@ -102,17 +106,19 @@
rootComponent = rootComponent.getParent();
loc = rootComponent.getLocation();
}
//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)
this.setDefaultDragImage(component);
@@ -137,31 +143,29 @@
dragImageOffset = new Point(0, 0);
}
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) {
throw new InvalidDnDOperationException("failed to create native peer: " + e);
}
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.
try {
@@ -171,12 +175,10 @@
try {
doDragging(nativeDragSource);
} catch (Exception e) {
e.printStackTrace();
} finally {
- CCursorManager.getInstance().stopDrag();
-
releaseNativeDragSource(nativeDragSource);
fDragImage = null;
if (fDragCImage != null) {
fDragCImage.dispose();
fDragCImage = null;
@@ -187,12 +189,10 @@
dragThread.start();
}
catch (Exception e) {
- CCursorManager.getInstance().stopDrag();
-
final long nativeDragSource = getNativeContext();
setNativeContext(0);
releaseNativeDragSource(nativeDragSource);
SunDropTargetContextPeer.setCurrentJVMLocalSourceTransferable(null);
throw new InvalidDnDOperationException("failed to start dragging thread: " + e);
@@ -414,62 +414,85 @@
*/
private void dragMouseMoved(final int targetActions,
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);
}
if(componentAt != null) {
dragEnter(targetActions, modifiers, x, y);
}
hoveringComponent = componentAt;
}
- }
+
postDragSourceDragEvent(targetActions, modifiers, x, y,
DISPATCH_MOUSE_MOVED);
+ } catch (Exception e) {
+ throw new InvalidDnDOperationException("Failed to handle DragMouseMoved event");
+ }
}
- /**
- * 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;
}
/**
* upcall from native code - reset hovering component
*/
private void resetHovering() {
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);
private native void releaseNativeDragSource(long nativeDragSource);