8006941: [macosx] Deadlock in drag and drop
7199783: Setting cursor on DragSourceContext does not work on OSX Reviewed-by: anthony, serb
This commit is contained in:
parent
918a376474
commit
9ff5db6260
@ -336,7 +336,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
|
||||
return peerTreeLock;
|
||||
}
|
||||
|
||||
final T getTarget() {
|
||||
public final T getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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<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);
|
||||
@ -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);
|
||||
|
@ -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.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
*************************************************************/
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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]
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user