--- old/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java 2013-05-30 12:46:51.000000000 +0400 +++ new/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java 2013-05-30 12:46:51.000000000 +0400 @@ -77,8 +77,20 @@ if (!GraphicsEnvironment.isHeadless()) { initIDs(); } + inAWT = AccessController.doPrivileged(new PrivilegedAction() { + @Override + public Boolean run() { + return !Boolean.parseBoolean(System.getProperty("javafx.embed.singleThread", "false")); + } + }); } + /* + * If true we operate in normal mode and nested runloop is executed in JavaRunLoopMode + * If false we operate in singleThreaded FX/AWT interop mode and nested loop uses NSDefaultRunLoopMode + */ + private static final boolean inAWT; + public LWCToolkit() { SunToolkit.setDataTransfererClassName("sun.lwawt.macosx.CDataTransferer"); @@ -701,7 +713,10 @@ * * if false - all events come after exit form the nested loop */ - static native void doAWTRunLoop(long mediator, boolean processEvents); + static void doAWTRunLoop(long mediator, boolean processEvents) { + doAWTRunLoopImpl(mediator, processEvents, inAWT); + } + static private native void doAWTRunLoopImpl(long mediator, boolean processEvents, boolean inAWT); static native void stopAWTRunLoop(long mediator); private native boolean nativeSyncQueue(long timeout); --- old/src/macosx/native/sun/awt/CDropTargetContextPeer.m 2013-05-30 12:46:52.000000000 +0400 +++ new/src/macosx/native/sun/awt/CDropTargetContextPeer.m 2013-05-30 12:46:52.000000000 +0400 @@ -61,7 +61,6 @@ JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CDropTargetContextPeer_startTransfer (JNIEnv *env, jobject jthis, jlong jdroptarget, jlong jformat) { - AWT_ASSERT_NOT_APPKIT_THREAD; jlong result = (jlong) 0L; --- old/src/macosx/native/sun/awt/LWCToolkit.m 2013-05-30 12:46:53.000000000 +0400 +++ new/src/macosx/native/sun/awt/LWCToolkit.m 2013-05-30 12:46:53.000000000 +0400 @@ -295,11 +295,11 @@ /* * Class: sun_lwawt_macosx_LWCToolkit - * Method: doAWTRunLoop + * Method: doAWTRunLoopImpl * Signature: (JZZ)V */ -JNIEXPORT void JNICALL Java_sun_lwawt_macosx_LWCToolkit_doAWTRunLoop -(JNIEnv *env, jclass clz, jlong mediator, jboolean processEvents) +JNIEXPORT void JNICALL Java_sun_lwawt_macosx_LWCToolkit_doAWTRunLoopImpl +(JNIEnv *env, jclass clz, jlong mediator, jboolean processEvents, jboolean inAWT) { AWT_ASSERT_APPKIT_THREAD; JNF_COCOA_ENTER(env); @@ -311,7 +311,7 @@ // Don't use acceptInputForMode because that doesn't setup autorelease pools properly BOOL isRunning = true; while (![mediatorObject shouldEndRunLoop] && isRunning) { - isRunning = [[NSRunLoop currentRunLoop] runMode:[JNFRunLoop javaRunLoopMode] + isRunning = [[NSRunLoop currentRunLoop] runMode:inAWT ? [JNFRunLoop javaRunLoopMode] : NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.010]]; if (processEvents) { //We do not spin a runloop here as date is nil, so does not matter which mode to use @@ -340,7 +340,6 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_LWCToolkit_stopAWTRunLoop (JNIEnv *env, jclass clz, jlong mediator) { -AWT_ASSERT_NOT_APPKIT_THREAD; JNF_COCOA_ENTER(env); AWTRunLoopObject* mediatorObject = (AWTRunLoopObject*)jlong_to_ptr(mediator); --- old/src/share/classes/java/awt/EventQueue.java 2013-05-30 12:46:54.000000000 +0400 +++ new/src/share/classes/java/awt/EventQueue.java 2013-05-30 12:46:54.000000000 +0400 @@ -37,16 +37,10 @@ import java.util.EmptyStackException; +import sun.awt.*; import sun.awt.dnd.SunDropTargetEvent; import sun.util.logging.PlatformLogger; -import sun.awt.AppContext; -import sun.awt.AWTAutoShutdown; -import sun.awt.PeerEvent; -import sun.awt.SunToolkit; -import sun.awt.EventQueueItem; -import sun.awt.AWTAccessor; - import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.atomic.AtomicInteger; @@ -181,6 +175,8 @@ private final String name = "AWT-EventQueue-" + threadInitNumber.getAndIncrement(); + private FwDispatcher fwDispatcher; + private static final PlatformLogger eventLog = PlatformLogger.getLogger("java.awt.event.EventQueue"); static { @@ -209,6 +205,10 @@ { EventQueue.invokeAndWait(source, r); } + public void setFwDispatcher(EventQueue eventQueue, + FwDispatcher dispatcher) { + eventQueue.setFwDispatcher(dispatcher); + } }); } @@ -684,7 +684,16 @@ final Object src = event.getSource(); final PrivilegedAction action = new PrivilegedAction() { public Void run() { - dispatchEventImpl(event, src); + if (fwDispatcher == null) { + dispatchEventImpl(event, src); + } else { + fwDispatcher.scheduleDispatch(new Runnable() { + @Override + public void run() { + dispatchEventImpl(event, src); + } + }); + } return null; } }; @@ -844,7 +853,9 @@ while (topQueue.nextQueue != null) { topQueue = topQueue.nextQueue; } - + if (topQueue.fwDispatcher != null) { + throw new RuntimeException("push() to queue with fwDispatcher"); + } if ((topQueue.dispatchThread != null) && (topQueue.dispatchThread.getEventQueue() == this)) { @@ -975,6 +986,9 @@ // Forward the request to the top of EventQueue stack return nextQueue.createSecondaryLoop(cond, filter, interval); } + if (fwDispatcher != null) { + return fwDispatcher.createSecondaryLoop(); + } if (dispatchThread == null) { initDispatchThread(); } @@ -1018,6 +1032,9 @@ eq = next; next = eq.nextQueue; } + if (eq.fwDispatcher != null) { + return eq.fwDispatcher.isDispatchThread(); + } return (Thread.currentThread() == eq.dispatchThread); } finally { pushPopLock.unlock(); @@ -1303,6 +1320,15 @@ pushPopLock.unlock(); } } + + // The method is used by AWTAccessor for javafx/AWT single threaded mode. + private void setFwDispatcher(FwDispatcher dispatcher) { + if (nextQueue != null) { + nextQueue.setFwDispatcher(dispatcher); + } else { + fwDispatcher = dispatcher; + } + } } /** --- old/src/share/classes/sun/awt/AWTAccessor.java 2013-05-30 12:46:55.000000000 +0400 +++ new/src/share/classes/sun/awt/AWTAccessor.java 2013-05-30 12:46:55.000000000 +0400 @@ -484,6 +484,11 @@ */ void invokeAndWait(Object source, Runnable r) throws InterruptedException, InvocationTargetException; + + /** + * Sets the delegate for the EventQueue used by FX/AWT single threaded mode + */ + public void setFwDispatcher(EventQueue eventQueue, FwDispatcher dispatcher); } /*