提交 f0310e85 编写于 作者: P pchelko

8006941: [macosx] Deadlock in drag and drop

7199783: Setting cursor on DragSourceContext does not work on OSX
Reviewed-by: anthony, serb
上级 0d0b24f7
...@@ -336,7 +336,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent> ...@@ -336,7 +336,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
return peerTreeLock; return peerTreeLock;
} }
final T getTarget() { public final T getTarget() {
return target; return target;
} }
......
...@@ -51,15 +51,6 @@ final class CCursorManager extends LWCursorManager { ...@@ -51,15 +51,6 @@ final class CCursorManager extends LWCursorManager {
@Override @Override
protected Point getCursorPosition() { 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(); final Point2D nativePosition = nativeGetCursorPosition();
return new Point((int)nativePosition.getX(), (int)nativePosition.getY()); return new Point((int)nativePosition.getX(), (int)nativePosition.getY());
} }
...@@ -101,31 +92,4 @@ final class CCursorManager extends LWCursorManager { ...@@ -101,31 +92,4 @@ final class CCursorManager extends LWCursorManager {
// do something special // do something special
throw new RuntimeException("Unimplemented"); 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;
}
} }
...@@ -38,8 +38,12 @@ import javax.swing.text.*; ...@@ -38,8 +38,12 @@ import javax.swing.text.*;
import javax.accessibility.*; import javax.accessibility.*;
import java.util.Map; import java.util.Map;
import java.util.concurrent.Callable;
import sun.awt.dnd.*; import sun.awt.dnd.*;
import sun.lwawt.LWComponentPeer; import sun.lwawt.LWComponentPeer;
import sun.lwawt.LWWindowPeer;
import sun.lwawt.PlatformWindow;
public final class CDragSourceContextPeer extends SunDragSourceContextPeer { public final class CDragSourceContextPeer extends SunDragSourceContextPeer {
...@@ -104,13 +108,8 @@ 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 //It sure will be LWComponentPeer instance as rootComponent is a Window
LWComponentPeer peer = (LWComponentPeer)rootComponent.getPeer(); PlatformWindow platformWindow = ((LWComponentPeer)rootComponent.getPeer()).getPlatformWindow();
//Get a pointer to a native window long nativeViewPtr = CPlatformWindow.getNativeViewPtr(platformWindow);
CPlatformWindow platformWindow = (CPlatformWindow) peer.getPlatformWindow();
long nativeWindowPtr = platformWindow.getNSWindowPtr();
// Get drag cursor:
Cursor cursor = this.getCursor();
// If there isn't any drag image make one of default appearance: // If there isn't any drag image make one of default appearance:
if (fDragImage == null) if (fDragImage == null)
...@@ -139,19 +138,15 @@ public final class CDragSourceContextPeer extends SunDragSourceContextPeer { ...@@ -139,19 +138,15 @@ public final class CDragSourceContextPeer extends SunDragSourceContextPeer {
try { try {
// Create native dragging source: // 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, (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); getDragSourceContext().getSourceActions(), formats, formatMap);
if (nativeDragSource == 0) if (nativeDragSource == 0)
throw new InvalidDnDOperationException(""); throw new InvalidDnDOperationException("");
setNativeContext(nativeDragSource); setNativeContext(nativeDragSource);
CCursorManager.getInstance().startDrag(
(int) (dragOrigin.getX()),
(int) (dragOrigin.getY()));
} }
catch (Exception e) { catch (Exception e) {
...@@ -160,6 +155,8 @@ public final class CDragSourceContextPeer extends SunDragSourceContextPeer { ...@@ -160,6 +155,8 @@ public final class CDragSourceContextPeer extends SunDragSourceContextPeer {
SunDropTargetContextPeer.setCurrentJVMLocalSourceTransferable(transferable); SunDropTargetContextPeer.setCurrentJVMLocalSourceTransferable(transferable);
CCursorManager.getInstance().setCursor(getCursor());
// Create a new thread to run the dragging operation since it's synchronous, only coming back // 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 // after dragging is finished. This leaves the AWT event thread free to handle AWT events which
// are posted during dragging by native event handlers. // are posted during dragging by native event handlers.
...@@ -173,8 +170,6 @@ public final class CDragSourceContextPeer extends SunDragSourceContextPeer { ...@@ -173,8 +170,6 @@ public final class CDragSourceContextPeer extends SunDragSourceContextPeer {
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} finally { } finally {
CCursorManager.getInstance().stopDrag();
releaseNativeDragSource(nativeDragSource); releaseNativeDragSource(nativeDragSource);
fDragImage = null; fDragImage = null;
if (fDragCImage != null) { if (fDragCImage != null) {
...@@ -189,8 +184,6 @@ public final class CDragSourceContextPeer extends SunDragSourceContextPeer { ...@@ -189,8 +184,6 @@ public final class CDragSourceContextPeer extends SunDragSourceContextPeer {
} }
catch (Exception e) { catch (Exception e) {
CCursorManager.getInstance().stopDrag();
final long nativeDragSource = getNativeContext(); final long nativeDragSource = getNativeContext();
setNativeContext(0); setNativeContext(0);
releaseNativeDragSource(nativeDragSource); releaseNativeDragSource(nativeDragSource);
...@@ -416,13 +409,24 @@ public final class CDragSourceContextPeer extends SunDragSourceContextPeer { ...@@ -416,13 +409,24 @@ public final class CDragSourceContextPeer extends SunDragSourceContextPeer {
final int modifiers, final int modifiers,
final int x, final int y) { 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(componentAt != hoveringComponent) {
if(hoveringComponent != null) { if(hoveringComponent != null) {
dragExit(x, y); dragExit(x, y);
...@@ -432,20 +436,36 @@ public final class CDragSourceContextPeer extends SunDragSourceContextPeer { ...@@ -432,20 +436,36 @@ public final class CDragSourceContextPeer extends SunDragSourceContextPeer {
} }
hoveringComponent = componentAt; hoveringComponent = componentAt;
} }
}
postDragSourceDragEvent(targetActions, modifiers, x, y, postDragSourceDragEvent(targetActions, modifiers, x, y,
DISPATCH_MOUSE_MOVED); DISPATCH_MOUSE_MOVED);
} catch (Exception e) {
throw new InvalidDnDOperationException("Failed to handle DragMouseMoved event");
}
} }
/** //Returns the first lightweight or heavyweight Component which has a dropTarget ready to accept the drag
* upcall from native code //Should be called from the EventDispatchThread
*/ private static Component getDropTargetAt(Component root, int x, int y) {
private void dragEnter(final int targetActions, if (!root.contains(x, y) || !root.isEnabled() || !root.isVisible()) {
final int modifiers, return null;
final int x, final int y) { }
CCursorManager.getInstance().updateDragPosition(x, y);
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 { ...@@ -455,19 +475,15 @@ public final class CDragSourceContextPeer extends SunDragSourceContextPeer {
hoveringComponent = null; hoveringComponent = null;
} }
public void setCursor(Cursor c) throws InvalidDnDOperationException { @Override
// TODO : BG protected void setNativeCursor(long nativeCtxt, Cursor c, int cType) {
//AWTLockAccess.awtLock(); CCursorManager.getInstance().setCursor(c);
super.setCursor(c);
//AWTLockAccess.awtUnlock();
} }
protected native void setNativeCursor(long nativeCtxt, Cursor c, int cType);
// Native support: // 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, 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); int sourceActions, long[] formats, Map formatMap);
private native void doDragging(long nativeDragSource); private native void doDragging(long nativeDragSource);
......
...@@ -30,6 +30,7 @@ import java.awt.peer.ComponentPeer; ...@@ -30,6 +30,7 @@ import java.awt.peer.ComponentPeer;
import java.awt.dnd.DropTarget; import java.awt.dnd.DropTarget;
import sun.lwawt.LWComponentPeer; import sun.lwawt.LWComponentPeer;
import sun.lwawt.PlatformWindow;
public final class CDropTarget { public final class CDropTarget {
...@@ -50,23 +51,13 @@ public final class CDropTarget { ...@@ -50,23 +51,13 @@ public final class CDropTarget {
fComponent = component; fComponent = component;
fPeer = peer; fPeer = peer;
// Make sure the drop target is a ComponentModel: long nativePeer = CPlatformWindow.getNativeViewPtr(((LWComponentPeer) peer).getPlatformWindow());
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: // Create native dragging destination:
fNativeDropTarget = this.createNativeDropTarget(dropTarget, component, peer, nativePeer); fNativeDropTarget = this.createNativeDropTarget(dropTarget, component, peer, nativePeer);
if (fNativeDropTarget == 0) { if (fNativeDropTarget == 0) {
throw new IllegalStateException("CDropTarget.createNativeDropTarget() failed."); throw new IllegalStateException("CDropTarget.createNativeDropTarget() failed.");
} }
} }
}
public DropTarget getDropTarget() { public DropTarget getDropTarget() {
return fDropTarget; return fDropTarget;
......
...@@ -875,6 +875,21 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo ...@@ -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. * Callbacks from the AWTWindow and AWTView objc classes.
*************************************************************/ *************************************************************/
......
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
@private @private
NSView* fView; NSView* fView;
jobject fComponent; jobject fComponent;
jobject fComponentPeer;
jobject fDragSourceContextPeer; jobject fDragSourceContextPeer;
jobject fTransferable; jobject fTransferable;
...@@ -43,8 +42,6 @@ ...@@ -43,8 +42,6 @@
jint fClickCount; jint fClickCount;
jint fModifiers; jint fModifiers;
jobject fCursor;
NSImage* fDragImage; NSImage* fDragImage;
NSPoint fDragImageOffset; NSPoint fDragImageOffset;
...@@ -59,12 +56,22 @@ ...@@ -59,12 +56,22 @@
+ (CDragSource *) currentDragSource; + (CDragSource *) currentDragSource;
// Common methods: // Common methods:
- (id)init:(jobject)jdragsourcecontextpeer component:(jobject)jcomponent peer:(jobject)jpeer control:(id)control - (id) init:(jobject)jDragSourceContextPeer
transferable:(jobject)jtransferable triggerEvent:(jobject)jtrigger component:(jobject)jComponent
dragPosX:(jint)dragPosX dragPosY:(jint)dragPosY modifiers:(jint)extModifiers clickCount:(jint)clickCount timeStamp:(jlong)timeStamp control:(id)control
cursor:(jobject)jcursor transferable:(jobject)jTransferable
dragImage:(jobject)jnsdragimage dragImageOffsetX:(jint)jdragimageoffsetx dragImageOffsetY:(jint)jdragimageoffsety triggerEvent:(jobject)jTrigger
sourceActions:(jint)jsourceactions formats:(jlongArray)jformats formatMap:(jobject)jformatmap; 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; - (void)removeFromView:(JNIEnv *)env;
......
...@@ -84,12 +84,22 @@ static BOOL sNeedsEnter; ...@@ -84,12 +84,22 @@ static BOOL sNeedsEnter;
return sCurrentDragSource; return sCurrentDragSource;
} }
- (id)init:(jobject)jdragsourcecontextpeer component:(jobject)jcomponent peer:(jobject)jpeer control:(id)control - (id) init:(jobject)jDragSourceContextPeer
transferable:(jobject)jtransferable triggerEvent:(jobject)jtrigger component:(jobject)jComponent
dragPosX:(jint)dragPosX dragPosY:(jint)dragPosY modifiers:(jint)extModifiers clickCount:(jint)clickCount control:(id)control
timeStamp:(jlong)timeStamp cursor:(jobject)jcursor transferable:(jobject)jTransferable
dragImage:(jobject)jnsdragimage dragImageOffsetX:(jint)jdragimageoffsetx dragImageOffsetY:(jint)jdragimageoffsety triggerEvent:(jobject)jTrigger
sourceActions:(jint)jsourceactions formats:(jlongArray)jformats formatMap:(jobject)jformatmap 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]; self = [super init];
DLog2(@"[CDragSource init]: %@\n", self); DLog2(@"[CDragSource init]: %@\n", self);
...@@ -100,27 +110,25 @@ static BOOL sNeedsEnter; ...@@ -100,27 +110,25 @@ static BOOL sNeedsEnter;
// Construct the object if we have a valid model for it: // Construct the object if we have a valid model for it:
if (control != nil) { if (control != nil) {
JNIEnv *env = [ThreadUtilities getJNIEnv]; JNIEnv *env = [ThreadUtilities getJNIEnv];
fComponent = JNFNewGlobalRef(env, jcomponent); fComponent = JNFNewGlobalRef(env, jComponent);
fComponentPeer = JNFNewGlobalRef(env, jpeer); fDragSourceContextPeer = JNFNewGlobalRef(env, jDragSourceContextPeer);
fDragSourceContextPeer = JNFNewGlobalRef(env, jdragsourcecontextpeer);
fTransferable = JNFNewGlobalRef(env, jtransferable); fTransferable = JNFNewGlobalRef(env, jTransferable);
fTriggerEvent = JNFNewGlobalRef(env, jtrigger); fTriggerEvent = JNFNewGlobalRef(env, jTrigger);
fCursor = JNFNewGlobalRef(env, jcursor);
if (jnsdragimage) { if (jDragImage) {
JNF_MEMBER_CACHE(nsImagePtr, CImageClass, "ptr", "J"); 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 = (NSImage*) jlong_to_ptr(imgPtr); // Double-casting prevents compiler 'd$|//
[fDragImage retain]; [fDragImage retain];
} }
fDragImageOffset = NSMakePoint(jdragimageoffsetx, jdragimageoffsety); fDragImageOffset = NSMakePoint(jDragImageOffsetX, jDragImageOffsetY);
fSourceActions = jsourceactions; fSourceActions = jSourceActions;
fFormats = JNFNewGlobalRef(env, jformats); fFormats = JNFNewGlobalRef(env, jFormats);
fFormatMap = JNFNewGlobalRef(env, jformatmap); fFormatMap = JNFNewGlobalRef(env, jFormatMap);
fTriggerEventTimeStamp = timeStamp; fTriggerEventTimeStamp = timeStamp;
fDragPos = NSMakePoint(dragPosX, dragPosY); fDragPos = NSMakePoint(dragPosX, dragPosY);
...@@ -129,9 +137,8 @@ static BOOL sNeedsEnter; ...@@ -129,9 +137,8 @@ static BOOL sNeedsEnter;
// Set this object as a dragging source: // Set this object as a dragging source:
AWTView *awtView = [((NSWindow *) control) contentView]; fView = [(AWTView *) control retain];
fView = [awtView retain]; [fView setDragSource:self];
[awtView setDragSource:self];
// Let AWTEvent know Java drag is getting underway: // Let AWTEvent know Java drag is getting underway:
[NSEvent javaDraggingBegin]; [NSEvent javaDraggingBegin];
...@@ -158,11 +165,6 @@ static BOOL sNeedsEnter; ...@@ -158,11 +165,6 @@ static BOOL sNeedsEnter;
fComponent = NULL; fComponent = NULL;
} }
if (fComponentPeer != NULL) {
JNFDeleteGlobalRef(env, fComponentPeer);
fComponentPeer = NULL;
}
if (fDragSourceContextPeer != NULL) { if (fDragSourceContextPeer != NULL) {
JNFDeleteGlobalRef(env, fDragSourceContextPeer); JNFDeleteGlobalRef(env, fDragSourceContextPeer);
fDragSourceContextPeer = NULL; fDragSourceContextPeer = NULL;
...@@ -178,11 +180,6 @@ static BOOL sNeedsEnter; ...@@ -178,11 +180,6 @@ static BOOL sNeedsEnter;
fTriggerEvent = NULL; fTriggerEvent = NULL;
} }
if (fCursor != NULL) {
JNFDeleteGlobalRef(env, fCursor);
fCursor = NULL;
}
if (fFormats != NULL) { if (fFormats != NULL) {
JNFDeleteGlobalRef(env, fFormats); JNFDeleteGlobalRef(env, fFormats);
fFormats = NULL; fFormats = NULL;
...@@ -586,11 +583,6 @@ static BOOL sNeedsEnter; ...@@ -586,11 +583,6 @@ static BOOL sNeedsEnter;
{ {
AWT_ASSERT_NOT_APPKIT_THREAD; 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) [self performSelectorOnMainThread:@selector(doDrag) withObject:nil waitUntilDone:YES]; // AWT_THREADING Safe (called from unique asynchronous thread)
} }
......
...@@ -34,12 +34,13 @@ ...@@ -34,12 +34,13 @@
/* /*
* Class: sun_lwawt_macosx_CDragSourceContextPeer * Class: sun_lwawt_macosx_CDragSourceContextPeer
* Method: createNativeDragSource * 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 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 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) jint jsourceactions, jlongArray jformats, jobject jformatmap)
{ {
id controlObj = (id) jlong_to_ptr(jnativepeer); id controlObj = (id) jlong_to_ptr(jnativepeer);
...@@ -47,12 +48,22 @@ JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CDragSourceContextPeer_createNativ ...@@ -47,12 +48,22 @@ JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CDragSourceContextPeer_createNativ
JNF_COCOA_ENTER(env); JNF_COCOA_ENTER(env);
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){ [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
dragSource = [[CDragSource alloc] init:jthis component:jcomponent peer:jpeer control:controlObj dragSource = [[CDragSource alloc] init:jthis
transferable:jtransferable triggerEvent:jtrigger dragPosX:jdragposx component:jcomponent
dragPosY:jdragposy modifiers:jextmodifiers clickCount:jclickcount timeStamp:jtimestamp control:controlObj
cursor:jcursor dragImage:jnsdragimage dragImageOffsetX:jdragimageoffsetx transferable:jtransferable
dragImageOffsetY:jdragimageoffsety sourceActions:jsourceactions triggerEvent:jtrigger
formats:jformats formatMap:jformatmap]; 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); JNF_COCOA_EXIT(env);
...@@ -94,19 +105,3 @@ JNF_COCOA_ENTER(env); ...@@ -94,19 +105,3 @@ JNF_COCOA_ENTER(env);
[dragSource removeFromView:env]; [dragSource removeFromView:env];
JNF_COCOA_EXIT(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);
}
...@@ -81,9 +81,8 @@ extern JNFClassInfo jc_CDropTargetContextPeer; ...@@ -81,9 +81,8 @@ extern JNFClassInfo jc_CDropTargetContextPeer;
fComponent = JNFNewGlobalRef(env, jcomponent); fComponent = JNFNewGlobalRef(env, jcomponent);
fDropTarget = JNFNewGlobalRef(env, jdropTarget); fDropTarget = JNFNewGlobalRef(env, jdropTarget);
AWTView *awtView = [((NSWindow *) control) contentView]; fView = [((AWTView *) control) retain];
fView = [awtView retain]; [fView setDropTarget:self];
[awtView setDropTarget:self];
} else { } else {
...@@ -177,6 +176,10 @@ extern JNFClassInfo jc_CDropTargetContextPeer; ...@@ -177,6 +176,10 @@ extern JNFClassInfo jc_CDropTargetContextPeer;
{ {
DLog2(@"[CDropTarget dealloc]: %@\n", self); DLog2(@"[CDropTarget dealloc]: %@\n", self);
if(sCurrentDropTarget == self) {
sCurrentDropTarget = nil;
}
[fView release]; [fView release];
fView = nil; fView = nil;
...@@ -490,7 +493,10 @@ extern JNFClassInfo jc_CDropTargetContextPeer; ...@@ -490,7 +493,10 @@ extern JNFClassInfo jc_CDropTargetContextPeer;
JNF_MEMBER_CACHE(handleEnterMessageMethod, jc_CDropTargetContextPeer, "handleEnterMessage", "(Ljava/awt/Component;IIII[JJ)I"); JNF_MEMBER_CACHE(handleEnterMessageMethod, jc_CDropTargetContextPeer, "handleEnterMessage", "(Ljava/awt/Component;IIII[JJ)I");
if (sDraggingError == FALSE) { if (sDraggingError == FALSE) {
// Double-casting self gets rid of 'different size' compiler warning: // 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) { if (sDraggingError == FALSE) {
...@@ -510,11 +516,6 @@ extern JNFClassInfo jc_CDropTargetContextPeer; ...@@ -510,11 +516,6 @@ extern JNFClassInfo jc_CDropTargetContextPeer;
// Remember the dragOp for no-op'd update messages: // Remember the dragOp for no-op'd update messages:
sUpdateOperation = dragOp; 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: // 9-11-02 Note: the native event thread would not handle an exception gracefully:
...@@ -608,11 +609,9 @@ extern JNFClassInfo jc_CDropTargetContextPeer; ...@@ -608,11 +609,9 @@ extern JNFClassInfo jc_CDropTargetContextPeer;
JNF_MEMBER_CACHE(handleExitMessageMethod, jc_CDropTargetContextPeer, "handleExitMessage", "(Ljava/awt/Component;J)V"); JNF_MEMBER_CACHE(handleExitMessageMethod, jc_CDropTargetContextPeer, "handleExitMessage", "(Ljava/awt/Component;J)V");
if (sDraggingError == FALSE) { if (sDraggingError == FALSE) {
DLog3(@" - dragExit: loc native %f, %f\n", sDraggingLocation.x, sDraggingLocation.y); DLog3(@" - dragExit: loc native %f, %f\n", sDraggingLocation.x, sDraggingLocation.y);
JNFCallVoidMethod(env, fDropTargetContextPeer, handleExitMessageMethod, fComponent, ptr_to_jlong(self)); // AWT_THREADING Safe (CToolkitThreadBlockedHandler) // AWT_THREADING Safe (CToolkitThreadBlockedHandler)
// If we are in the same process as the sender, make the sender post the appropriate message JNFCallVoidMethod(env, fDropTargetContextPeer,
if (sender) { handleExitMessageMethod, fComponent, ptr_to_jlong(self));
[[CDragSource currentDragSource] postDragExit];
}
} }
// 5-27-03 Note: [Radar 3270455] // 5-27-03 Note: [Radar 3270455]
......
...@@ -278,7 +278,7 @@ public abstract class SunDragSourceContextPeer implements DragSourceContextPeer ...@@ -278,7 +278,7 @@ public abstract class SunDragSourceContextPeer implements DragSourceContextPeer
* upcall from native code * upcall from native code
*/ */
private void dragEnter(final int targetActions, protected void dragEnter(final int targetActions,
final int modifiers, final int modifiers,
final int x, final int y) { final int x, final int y) {
postDragSourceDragEvent(targetActions, modifiers, x, y, DISPATCH_ENTER); postDragSourceDragEvent(targetActions, modifiers, x, y, DISPATCH_ENTER);
...@@ -356,10 +356,6 @@ public abstract class SunDragSourceContextPeer implements DragSourceContextPeer ...@@ -356,10 +356,6 @@ public abstract class SunDragSourceContextPeer implements DragSourceContextPeer
public static void setDragDropInProgress(boolean b) public static void setDragDropInProgress(boolean b)
throws InvalidDnDOperationException { throws InvalidDnDOperationException {
if (dragDropInProgress == b) {
throw new InvalidDnDOperationException(getExceptionMessage(b));
}
synchronized (SunDragSourceContextPeer.class) { synchronized (SunDragSourceContextPeer.class) {
if (dragDropInProgress == b) { if (dragDropInProgress == b) {
throw new InvalidDnDOperationException(getExceptionMessage(b)); throw new InvalidDnDOperationException(getExceptionMessage(b));
......
/*
* 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);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册