src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java

Print this page

        

@@ -62,21 +62,10 @@
     // like Windows.
     private static final int BUTTONS = 5;
 
     private static native void initIDs();
 
-    // On Mac OS we don't need to actually start the new event loop since there is
-    // a mechanic that allows us to just reschedule the next event in a native event loop
-    // for immediate execution and because this method is being called repeatedly we just
-    // executing one such event every time we call this method
-    static native void startNativeNestedEventLoop();
-
-    // Since we don't start an additional event loop this method is a no-op
-    // and shouldn't be called, left only for the better understanding of the concept on
-    // other OS'es
-    static native void stopNativeNestedEventLoop();
-
     private static CInputMethodDescriptor sInputMethodDescriptor;
 
     static {
         System.err.flush();
         java.security.AccessController.doPrivileged(new java.security.PrivilegedAction<Object>() {

@@ -503,34 +492,10 @@
         }}}, c); } catch (Exception e) { e.printStackTrace(); }
 
         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.
-     */
-    public static void flushPendingEventsOnAppkit(final Component component) {
-        try {
-            invokeAndWait(new Runnable() {
-                @Override
-                public void run() {
-                }
-            }, component);
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    // 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> T invokeAndWait(final Callable<T> callable, Component component) throws Exception {
         final CallableWrapper<T> wrapper = new CallableWrapper<T>(callable);
         invokeAndWait(wrapper, component);
         return wrapper.getResult();
     }

@@ -556,14 +521,31 @@
             if (e != null) throw e;
             return object;
         }
     }
 
-    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(component != null ? component : Toolkit.getDefaultToolkit(), event) {
+                    @Override
+                    public void dispatch() {
+                        try {
+                            super.dispatch();
+                        } finally {
+                            if (mediator != 0) {
+                                stopAWTRunLoop(mediator);
+                            }
+                        }
+                    }
+                };
 
         if (component != null) {
             AppContext appContext = SunToolkit.targetToAppContext(component);
             SunToolkit.postEvent(appContext, invocationEvent);
 

@@ -572,11 +554,11 @@
         } else {
             // This should be the equivalent to EventQueue.invokeAndWait
             ((LWCToolkit)Toolkit.getDefaultToolkit()).getSystemEventQueueForInvokeAndWait().postEvent(invocationEvent);
         }
 
-        doAWTRunLoop(mediator, true, detectDeadlocks);
+        doAWTRunLoop(mediator, false);
 
         Throwable eventException = invocationEvent.getException();
         if (eventException != null) {
             if (eventException instanceof UndeclaredThrowableException) {
                 eventException = ((UndeclaredThrowableException)eventException).getUndeclaredThrowable();

@@ -584,11 +566,12 @@
             throw new InvocationTargetException(eventException);
         }
     }
 
     public static void invokeLater(Runnable event, Component component) throws InvocationTargetException {
-        final InvocationEvent invocationEvent = new CPeerEvent(event, 0);
+        final InvocationEvent invocationEvent =
+                new InvocationEvent(component != null ? component : Toolkit.getDefaultToolkit(), event);
 
         if (component != null) {
             final AppContext appContext = SunToolkit.targetToAppContext(component);
             SunToolkit.postEvent(appContext, invocationEvent);
 

@@ -689,35 +672,10 @@
     @Override
     public boolean canPopupOverlapTaskBar() {
         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;
 
     /**
      * Returns the value of "sun.awt.disableCALayers" property. Default
      * value is {@code false}.

@@ -738,16 +696,24 @@
 
     /************************
      * 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);
 
     @Override
     public Clipboard createPlatformClipboard() {