--- old/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java 2013-02-14 17:19:05.000000000 +0400 +++ new/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java 2013-02-14 17:19:04.000000000 +0400 @@ -63,8 +63,6 @@ private static native void initIDs(); - static native void executeNextAppKitEvent(); - private static CInputMethodDescriptor sInputMethodDescriptor; static { @@ -495,9 +493,11 @@ synchronized(ret) { return ret[0]; } } + /** * Just a wrapper for LWCToolkit.invokeAndWait. Posts an empty event to the * appropriate event queue and waits for it to finish. + * Native events are not processed during waiting. */ public static void flushPendingEventsOnAppkit(final Component component) { try { @@ -511,14 +511,6 @@ } } - // Kicks an event over to the appropriate eventqueue and waits for it to finish - // To avoid deadlocking, we manually run the NSRunLoop while waiting - // Any selector invoked using ThreadUtilities performOnMainThread will be processed in doAWTRunLoop - // The CInvocationEvent will call LWCToolkit.stopAWTRunLoop() when finished, which will stop our manual runloop - public static void invokeAndWait(Runnable event, Component component) throws InterruptedException, InvocationTargetException { - invokeAndWait(event, component, true); - } - public static T invokeAndWait(final Callable callable, Component component) throws Exception { final CallableWrapper wrapper = new CallableWrapper(callable); invokeAndWait(wrapper, component); @@ -548,10 +540,26 @@ } } - public static void invokeAndWait(Runnable event, Component component, boolean detectDeadlocks) throws InterruptedException, InvocationTargetException { - long mediator = createAWTRunLoopMediator(); + // Kicks an event over to the appropriate eventqueue and waits for it to finish + // To avoid deadlocking, we manually run the NSRunLoop while waiting + // Any selector invoked using ThreadUtilities performOnMainThread will be processed in doAWTRunLoop + // The InvocationEvent will call LWCToolkit.stopAWTRunLoop() when finished, which will stop our manual runloop + // Does not dispatch native events while in the loop + public static void invokeAndWait(Runnable event, Component component) throws InterruptedException, InvocationTargetException { + final long mediator = createAWTRunLoopMediator(); - InvocationEvent invocationEvent = new CPeerEvent(event, mediator); + InvocationEvent invocationEvent = new InvocationEvent(Toolkit.getDefaultToolkit(), event) { + @Override + public void dispatch() { + try { + super.dispatch(); + } finally { + if (mediator != 0) { + stopAWTRunLoop(mediator); + } + } + } + }; if (component != null) { AppContext appContext = SunToolkit.targetToAppContext(component); @@ -564,7 +572,7 @@ ((LWCToolkit)Toolkit.getDefaultToolkit()).getSystemEventQueueForInvokeAndWait().postEvent(invocationEvent); } - doAWTRunLoop(mediator, true, detectDeadlocks); + doAWTRunLoop(mediator, false); Throwable eventException = invocationEvent.getException(); if (eventException != null) { @@ -576,7 +584,7 @@ } public static void invokeLater(Runnable event, Component component) throws InvocationTargetException { - final InvocationEvent invocationEvent = new CPeerEvent(event, 0); + final InvocationEvent invocationEvent = new InvocationEvent(Toolkit.getDefaultToolkit(), event); if (component != null) { final AppContext appContext = SunToolkit.targetToAppContext(component); @@ -681,31 +689,6 @@ return false; } - // Extends PeerEvent because we want to pass long an ObjC mediator object and because we want these events to be posted early - // Typically, rather than relying on the notifier to call notifyAll(), we use the mediator to stop the runloop - public static class CPeerEvent extends PeerEvent { - private long _mediator = 0; - - public CPeerEvent(Runnable runnable, long mediator) { - super(Toolkit.getDefaultToolkit(), runnable, null, true, 0); - _mediator = mediator; - } - - public void dispatch() { - try { - super.dispatch(); - } finally { - if (_mediator != 0) { - LWCToolkit.stopAWTRunLoop(_mediator); - } - } - } - } - - // Call through to native methods - public static void doAWTRunLoop(long mediator, boolean awtMode) { doAWTRunLoop(mediator, awtMode, true); } - public static void doAWTRunLoop(long mediator) { doAWTRunLoop(mediator, true); } - private static Boolean sunAwtDisableCALayers = null; /** @@ -730,12 +713,20 @@ * Native methods section ************************/ - // These are public because they are accessed from WebKitPluginObject in JavaDeploy - // Basic usage: - // createAWTRunLoopMediator. Start client code on another thread. doAWTRunLoop. When client code is finished, stopAWTRunLoop. - public static native long createAWTRunLoopMediator(); - public static native void doAWTRunLoop(long mediator, boolean awtMode, boolean detectDeadlocks); - public static native void stopAWTRunLoop(long mediator); + static native long createAWTRunLoopMediator(); + /** + * Method to run a nested run-loop. The nested loop is spinned in the javaRunLoop mode, so selectors sent + * by [JNFRunLoop performOnMainThreadWaiting] are processed. + * @param mediator a native pointer to the mediator object created by createAWTRunLoopMediator + * @param processEvents if true - dispatches event while in the nested loop. Used in DnD. + * Additional attention is needed when using this feature as we short-circuit normal event + * processing which could break Appkit. + * (One known example is when the window is resized with the mouse) + * + * if false - all events come after exit form the nested loop + */ + static native void doAWTRunLoop(long mediator, boolean processEvents); + static native void stopAWTRunLoop(long mediator); private native boolean nativeSyncQueue(long timeout);