changeset 8674:d2a734cc9752

8165626: Improved window framing Reviewed-by: serb
author mcherkas
date Fri, 21 Apr 2017 05:47:49 +0100
parents 4e12cba33eaa
children 30d17dc1d9fe
files src/macosx/classes/com/apple/eawt/_AppDockIconHandler.java src/macosx/classes/sun/java2d/opengl/CGLLayer.java src/macosx/classes/sun/lwawt/macosx/CFRetainedResource.java src/macosx/classes/sun/lwawt/macosx/CImage.java src/macosx/classes/sun/lwawt/macosx/CMenuItem.java src/macosx/classes/sun/lwawt/macosx/CPlatformComponent.java src/macosx/classes/sun/lwawt/macosx/CPlatformView.java src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java src/macosx/classes/sun/lwawt/macosx/CTrayIcon.java src/macosx/classes/sun/lwawt/macosx/CViewPlatformEmbeddedFrame.java src/macosx/classes/sun/lwawt/macosx/CWarningWindow.java src/macosx/native/sun/awt/AWTSurfaceLayers.h src/macosx/native/sun/awt/AWTSurfaceLayers.m
diffstat 13 files changed, 616 insertions(+), 190 deletions(-) [+]
line wrap: on
line diff
--- a/src/macosx/classes/com/apple/eawt/_AppDockIconHandler.java	Tue Apr 01 13:10:06 2014 +0400
+++ b/src/macosx/classes/com/apple/eawt/_AppDockIconHandler.java	Fri Apr 21 05:47:49 2017 +0100
@@ -72,8 +72,12 @@
     public void setDockIconImage(final Image image) {
         try {
             final CImage cImage = getCImageCreator().createFromImage(image);
-            final long nsImagePtr = getNSImagePtrFrom(cImage);
-            nativeSetDockIconImage(nsImagePtr);
+            cImage.execute(new CFRetainedResource.CFNativeAction() {
+                @Override
+                public void run(long ptr) {
+                    _AppDockIconHandler.nativeSetDockIconImage(ptr);
+                }
+            });
         } catch (final Throwable e) {
             throw new RuntimeException(e);
         }
@@ -102,16 +106,4 @@
             throw new RuntimeException(e);
         }
     }
-
-    static long getNSImagePtrFrom(final CImage cImage) {
-        if (cImage == null) return 0;
-
-        try {
-            final Field cImagePtrField = CFRetainedResource.class.getDeclaredField("ptr");
-            cImagePtrField.setAccessible(true);
-            return cImagePtrField.getLong(cImage);
-        } catch (final Throwable e) {
-            throw new RuntimeException(e);
-        }
-    }
 }
--- a/src/macosx/classes/sun/java2d/opengl/CGLLayer.java	Tue Apr 01 13:10:06 2014 +0400
+++ b/src/macosx/classes/sun/java2d/opengl/CGLLayer.java	Fri Apr 21 05:47:49 2017 +0100
@@ -108,7 +108,12 @@
         OGLRenderQueue rq = OGLRenderQueue.getInstance();
         rq.lock();
         try {
-            validate(getPointer(), cglsd);
+            execute(new CFNativeAction() {
+                @Override
+                public void run(long ptr) {
+                    validate(ptr, cglsd);
+                }
+            });
         } finally {
             rq.unlock();
         }
@@ -124,7 +129,12 @@
     private void setScale(final int _scale) {
         if (scale != _scale) {
             scale = _scale;
-            nativeSetScale(getPointer(), scale);
+            execute(new CFNativeAction() {
+                @Override
+                public void run(long ptr) {
+                    nativeSetScale(ptr, scale);
+                }
+            });
         }
     }
 
@@ -138,7 +148,12 @@
         OGLRenderQueue rq = OGLRenderQueue.getInstance();
         rq.lock();
         try {
-            blitTexture(getPointer());
+            execute(new CFNativeAction() {
+                @Override
+                public void run(long ptr) {
+                    blitTexture(ptr);
+                }
+            });
         } finally {
             rq.unlock();
         }
--- a/src/macosx/classes/sun/lwawt/macosx/CFRetainedResource.java	Tue Apr 01 13:10:06 2014 +0400
+++ b/src/macosx/classes/sun/lwawt/macosx/CFRetainedResource.java	Fri Apr 21 05:47:49 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -25,6 +25,10 @@
 
 package sun.lwawt.macosx;
 
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
 /**
  * Safely holds and disposes of native AppKit resources, using the
  * correct AppKit threading and Objective-C GC semantics.
@@ -36,6 +40,10 @@
     // TODO this pointer should be private and accessed via CFNativeAction class
     protected volatile long ptr;
 
+    private final ReadWriteLock lock = new ReentrantReadWriteLock();
+    private final Lock writeLock = lock.writeLock();
+    private final Lock readLock = lock.readLock();
+
     /**
      * @param ptr CFRetained native object pointer
      * @param disposeOnAppKitThread is the object needs to be CFReleased on the main thread
@@ -50,21 +58,31 @@
      * @param ptr CFRetained native object pointer
      */
     protected void setPtr(final long ptr) {
-        synchronized (this) {
-            if (this.ptr != 0) dispose();
+        writeLock.lock();
+        try {
+            if (this.ptr != 0) {
+                dispose();
+            }
             this.ptr = ptr;
+        } finally {
+            writeLock.unlock();
         }
     }
 
     /**
-     * Manually CFReleases the native resource
+     * Manually CFReleases the native resource.
      */
     protected void dispose() {
         long oldPtr = 0L;
-        synchronized (this) {
-            if (ptr == 0) return;
+        writeLock.lock();
+        try {
+            if (ptr == 0) {
+                return;
+            }
             oldPtr = ptr;
             ptr = 0;
+        } finally {
+            writeLock.unlock();
         }
 
         nativeCFRelease(oldPtr, disposeOnAppKitThread); // perform outside of the synchronized block
@@ -109,9 +127,14 @@
      *
      * @param  action The native operation
      */
-    public final synchronized void execute(final CFNativeAction action) {
-        if (ptr != 0) {
-            action.run(ptr);
+    public final void execute(final CFNativeAction action) {
+        readLock.lock();
+        try {
+            if (ptr != 0) {
+                action.run(ptr);
+            }
+        } finally {
+            readLock.unlock();
         }
     }
 
@@ -127,9 +150,14 @@
      * @return result of the native operation, usually the native pointer to
      *         some other data
      */
-    final synchronized long executeGet(final CFNativeActionGet action) {
-        if (ptr != 0) {
-            return action.run(ptr);
+    final long executeGet(final CFNativeActionGet action) {
+        readLock.lock();
+        try {
+            if (ptr != 0) {
+                return action.run(ptr);
+            }
+        } finally {
+            readLock.unlock();
         }
         return 0;
     }
--- a/src/macosx/classes/sun/lwawt/macosx/CImage.java	Tue Apr 01 13:10:06 2014 +0400
+++ b/src/macosx/classes/sun/lwawt/macosx/CImage.java	Fri Apr 21 05:47:49 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -33,6 +33,7 @@
 import java.util.List;
 import sun.awt.image.MultiResolutionImage;
 import sun.awt.image.MultiResolutionBufferedImage;
+import java.util.concurrent.atomic.AtomicReference;
 
 import sun.awt.image.SunWritableRaster;
 
@@ -214,15 +215,32 @@
 
     /** @return A MultiResolution image created from nsImagePtr, or null. */
     private BufferedImage toImage() {
-        if (ptr == 0) return null;
+        if (ptr == 0) {
+            return null;
+        }
 
-        final Dimension2D size = nativeGetNSImageSize(ptr);
+        final AtomicReference<Dimension2D> sizeRef = new AtomicReference<>();
+        execute(new CFNativeAction() {
+            @Override
+            public void run(long ptr) {
+                sizeRef.set(nativeGetNSImageSize(ptr));
+            }
+        });
+        final Dimension2D size = sizeRef.get();
+        if (size == null) {
+            return null;
+        }
         final int w = (int)size.getWidth();
         final int h = (int)size.getHeight();
-
-        Dimension2D[] sizes
-                = nativeGetNSImageRepresentationSizes(ptr,
-                        size.getWidth(), size.getHeight());
+        final AtomicReference<Dimension2D[]> repRef = new AtomicReference<>();
+        execute(new CFNativeAction() {
+            @Override
+            public void run(long ptr) {
+                repRef.set(nativeGetNSImageRepresentationSizes(ptr, size.getWidth(),
+                                                               size.getHeight()));
+            }
+        });
+        Dimension2D[] sizes = repRef.get();
 
         if (sizes == null || sizes.length < 2) {
             return toImage(w, h, w, h);
@@ -244,22 +262,37 @@
                 currentImageIndex, images);
     }
 
-    private BufferedImage toImage(int srcWidth, int srcHeight, int dstWidth, int dstHeight) {
+    private BufferedImage toImage(final int srcWidth, final int srcHeight, final int dstWidth, final int dstHeight) {
         final BufferedImage bimg = new BufferedImage(dstWidth, dstHeight, BufferedImage.TYPE_INT_ARGB_PRE);
         final DataBufferInt dbi = (DataBufferInt)bimg.getRaster().getDataBuffer();
         final int[] buffer = SunWritableRaster.stealData(dbi, 0);
-        nativeCopyNSImageIntoArray(ptr, buffer, srcWidth, srcHeight, dstWidth, dstHeight);
+        execute(new CFNativeAction() {
+            @Override
+            public void run(long ptr) {
+                nativeCopyNSImageIntoArray(ptr, buffer, srcWidth, srcHeight, dstWidth, dstHeight);
+            }
+        });
         SunWritableRaster.markDirty(dbi);
         return bimg;
     }
 
     /** If nsImagePtr != 0 then scale this NSImage. @return *this* */
     CImage resize(final double w, final double h) {
-        if (ptr != 0) nativeSetNSImageSize(ptr, w, h);
+        execute(new CFNativeAction() {
+            @Override
+            public void run(long ptr) {
+                nativeSetNSImageSize(ptr, w, h);
+            }
+        });
         return this;
     }
 
-    void resizeRepresentations(double w, double h) {
-        if (ptr != 0) nativeResizeNSImageRepresentations(ptr, w, h);
+    void resizeRepresentations(final double w, final double h) {
+        execute(new CFNativeAction() {
+            @Override
+            public void run(long ptr) {
+                nativeResizeNSImageRepresentations(ptr, w, h);
+            }
+        });
     }
 }
--- a/src/macosx/classes/sun/lwawt/macosx/CMenuItem.java	Tue Apr 01 13:10:06 2014 +0400
+++ b/src/macosx/classes/sun/lwawt/macosx/CMenuItem.java	Fri Apr 21 05:47:49 2017 +0100
@@ -124,11 +124,20 @@
     public final void setImage(final java.awt.Image img) {
         final CImage cimg = CImage.getCreator().createFromImage(img);
         execute(new CFNativeAction() {
-                @Override
-                public void run(long ptr) {
-                    nativeSetImage(ptr, cimg == null ? 0L : cimg.ptr);
+            @Override
+            public void run(final long ptr) {
+                if (cimg == null) {
+                    nativeSetImage(ptr, 0L);
+                } else {
+                    cimg.execute(new CFNativeAction() {
+                        @Override
+                        public void run(long imgPtr) {
+                            nativeSetImage(ptr, imgPtr);
+                        }
+                    });
                 }
-            });
+            }
+        });
     }
 
     /**
--- a/src/macosx/classes/sun/lwawt/macosx/CPlatformComponent.java	Tue Apr 01 13:10:06 2014 +0400
+++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformComponent.java	Fri Apr 21 05:47:49 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -44,6 +44,9 @@
         super(0, true);
     }
 
+    /**
+     * Used by JAWT.
+     */
     public long getPointer() {
         return ptr;
     }
@@ -61,7 +64,12 @@
         // translates values from the coordinate system of the top-level window
         // to the coordinate system of the content view
         final Insets insets = platformWindow.getPeer().getInsets();
-        nativeSetBounds(getPointer(), x - insets.left, y - insets.top, w, h);
+        execute(new CFNativeAction() {
+            @Override
+            public void run(long ptr) {
+                nativeSetBounds(ptr, x - insets.left, y - insets.top, w, h);
+            }
+        });
     }
 
     @Override
--- a/src/macosx/classes/sun/lwawt/macosx/CPlatformView.java	Tue Apr 01 13:10:06 2014 +0400
+++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformView.java	Fri Apr 21 05:47:49 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -28,6 +28,9 @@
 import java.awt.*;
 import java.awt.event.*;
 import java.awt.geom.Rectangle2D;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
 
 import sun.awt.CGraphicsConfig;
 import sun.awt.CGraphicsEnvironment;
@@ -79,8 +82,13 @@
      * All coordinates passed to the method should be based on the origin being in the bottom-left corner (standard
      * Cocoa coordinates).
      */
-    public void setBounds(int x, int y, int width, int height) {
-        CWrapper.NSView.setFrame(ptr, x, y, width, height);
+    public void setBounds(final int x, final int y, final int width, final int height) {
+        execute(new CFNativeAction() {
+            @Override
+            public void run(long ptr) {
+                CWrapper.NSView.setFrame(ptr, x, y, width, height);
+            }
+        });
     }
 
     // REMIND: CGLSurfaceData expects top-level's size
@@ -92,8 +100,13 @@
         return peer;
     }
 
-    public void setToolTip(String msg) {
-        CWrapper.NSView.setToolTip(ptr, msg);
+    public void setToolTip(final String msg) {
+        execute(new CFNativeAction() {
+            @Override
+            public void run(long ptr) {
+                CWrapper.NSView.setToolTip(ptr, msg);
+            }
+        });
     }
 
     // ----------------------------------------------------------------------
@@ -143,19 +156,37 @@
         }
     }
 
-    public void setAutoResizable(boolean toResize) {
-        nativeSetAutoResizable(this.getAWTView(), toResize);
+    public void setAutoResizable(final boolean toResize) {
+        execute(new CFNativeAction() {
+            @Override
+            public void run(long ptr) {
+                nativeSetAutoResizable(ptr, toResize);
+            }
+        });
     }
 
     public boolean isUnderMouse() {
-        return nativeIsViewUnderMouse(getAWTView());
+        final AtomicBoolean ref = new AtomicBoolean();
+        execute(new CFNativeAction() {
+            @Override
+            public void run(long ptr) {
+                ref.set(nativeIsViewUnderMouse(ptr));
+            }
+        });
+        return ref.get();
     }
 
     public GraphicsDevice getGraphicsDevice() {
         GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
         CGraphicsEnvironment cge = (CGraphicsEnvironment)ge;
-        int displayID = nativeGetNSViewDisplayID(getAWTView());
-        GraphicsDevice gd = cge.getScreenDevice(displayID);
+        final AtomicInteger ref = new AtomicInteger();
+        execute(new CFNativeAction() {
+            @Override
+            public void run(long ptr) {
+                ref.set(nativeGetNSViewDisplayID(ptr));
+            }
+        });
+        GraphicsDevice gd = cge.getScreenDevice(ref.get());
         if (gd == null) {
             // this could possibly happen during device removal
             // use the default screen device in this case
@@ -165,8 +196,18 @@
     }
 
     public Point getLocationOnScreen() {
-        Rectangle r = nativeGetLocationOnScreen(this.getAWTView()).getBounds();
-        return new Point(r.x, r.y);
+        final AtomicReference<Rectangle> ref = new AtomicReference<>();
+        execute(new CFNativeAction() {
+            @Override
+            public void run(long ptr) {
+                ref.set(nativeGetLocationOnScreen(ptr).getBounds());
+            }
+        });
+        Rectangle r = ref.get();
+        if (r != null) {
+            return new Point(r.x, r.y);
+        }
+        return new Point(0, 0);
     }
 
     // ----------------------------------------------------------------------
--- a/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Tue Apr 01 13:10:06 2014 +0400
+++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Fri Apr 21 05:47:49 2017 +0100
@@ -31,6 +31,9 @@
 import java.awt.peer.WindowPeer;
 import java.beans.*;
 import java.lang.reflect.InvocationTargetException;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicReference;
 import java.util.List;
 import java.util.Objects;
 
@@ -178,16 +181,31 @@
             c.setStyleBits(FULLSCREENABLE, Boolean.parseBoolean(value.toString()));
         }},
         new Property<CPlatformWindow>(WINDOW_SHADOW_REVALIDATE_NOW) { public void applyProperty(final CPlatformWindow c, final Object value) {
-            nativeRevalidateNSWindowShadow(c.getNSWindowPtr());
+                c.execute(new CFNativeAction() {
+                    @Override
+                    public void run(long ptr) {
+                        nativeRevalidateNSWindowShadow(ptr);
+                    }
+                });
         }},
         new Property<CPlatformWindow>(WINDOW_DOCUMENT_FILE) { public void applyProperty(final CPlatformWindow c, final Object value) {
             if (value == null || !(value instanceof java.io.File)) {
-                nativeSetNSWindowRepresentedFilename(c.getNSWindowPtr(), null);
+                c.execute(new CFNativeAction() {
+                    @Override
+                    public void run(long ptr) {
+                        nativeSetNSWindowRepresentedFilename(ptr, null);
+                    }
+                });
                 return;
             }
 
             final String filename = ((java.io.File)value).getAbsolutePath();
-            nativeSetNSWindowRepresentedFilename(c.getNSWindowPtr(), filename);
+            c.execute(new CFNativeAction() {
+                @Override
+                public void run(long ptr) {
+                    nativeSetNSWindowRepresentedFilename(ptr, filename);
+                }
+            });
         }}
     }) {
         public CPlatformWindow convertJComponentToTarget(final JRootPane p) {
@@ -236,8 +254,7 @@
         contentView = createContentView();
         contentView.initialize(peer, responder);
 
-        final long ownerPtr = owner != null ? owner.getNSWindowPtr() : 0L;
-        Rectangle bounds;
+        final Rectangle bounds;
         if (!IS(DECORATED, styleBits)) {
             // For undecorated frames the move/resize event does not come if the frame is centered on the screen
             // so we need to set a stub location to force an initial move/resize. Real bounds would be set later.
@@ -245,9 +262,27 @@
         } else {
             bounds = _peer.constrainBounds(_target.getBounds());
         }
-        final long nativeWindowPtr = nativeCreateNSWindow(contentView.getAWTView(),
-                ownerPtr, styleBits, bounds.x, bounds.y, bounds.width, bounds.height);
-        setPtr(nativeWindowPtr);
+        final AtomicLong ref = new AtomicLong();
+        contentView.execute(new CFNativeAction() {
+            @Override
+            public void run(final long viewPtr) {
+                if (owner != null) {
+                    owner.execute(new CFNativeAction() {
+                        @Override
+                        public void run(long ownerPtr) {
+                            ref.set(nativeCreateNSWindow(viewPtr, ownerPtr, styleBits,
+                                                         bounds.x, bounds.y,
+                                                         bounds.width, bounds.height));
+                        }
+                    });
+                } else {
+                    ref.set(nativeCreateNSWindow(viewPtr, 0,
+                                                 styleBits, bounds.x, bounds.y,
+                                                 bounds.width, bounds.height));
+                }
+            }
+        });
+        setPtr(ref.get());
 
         // TODO: implement on top of JObjC bridged class
     //    NSWindow window = JObjC.getInstance().AppKit().NSWindow().getInstance(nativeWindowPtr, JObjCRuntime.getInstance());
@@ -404,35 +439,54 @@
 
     // this is the counter-point to -[CWindow _nativeSetStyleBit:]
     protected void setStyleBits(final int mask, final boolean value) {
-        nativeSetNSWindowStyleBits(getNSWindowPtr(), mask, value ? mask : 0);
+        execute(new CFNativeAction() {
+            @Override
+            public void run(long ptr) {
+                nativeSetNSWindowStyleBits(ptr, mask, value ? mask : 0);
+            }
+        });
     }
 
     private native void _toggleFullScreenMode(final long model);
 
     public void toggleFullScreen() {
-        _toggleFullScreenMode(getNSWindowPtr());
+        execute(new CFNativeAction() {
+            @Override
+            public void run(long ptr) {
+                _toggleFullScreenMode(ptr);
+            }
+        });
     }
 
     @Override // PlatformWindow
     public void setMenuBar(MenuBar mb) {
-        final long nsWindowPtr = getNSWindowPtr();
-        CMenuBar mbPeer = (CMenuBar)LWToolkit.targetToPeer(mb);
-        if (mbPeer != null) {
-            mbPeer.execute(new CFNativeAction() {
-                    @Override
-                    public void run(long ptr) {
-                        nativeSetNSWindowMenuBar(nsWindowPtr, ptr);
-                    }
-                });
-        } else {
-            nativeSetNSWindowMenuBar(nsWindowPtr, 0);
-        }
+        final CMenuBar mbPeer = (CMenuBar)LWToolkit.targetToPeer(mb);
+        execute(new CFNativeAction() {
+            @Override
+            public void run(final long nsWindowPtr) {
+                if (mbPeer != null) {
+                    mbPeer.execute(new CFNativeAction() {
+                        @Override
+                        public void run(long ptr) {
+                            nativeSetNSWindowMenuBar(nsWindowPtr, ptr);
+                        }
+                    });
+                } else {
+                    nativeSetNSWindowMenuBar(nsWindowPtr, 0);
+                }
+            }
+        });
     }
 
     @Override // PlatformWindow
     public void dispose() {
         contentView.dispose();
-        nativeDispose(getNSWindowPtr());
+        execute(new CFNativeAction() {
+            @Override
+            public void run(long ptr) {
+                CPlatformWindow.nativeDispose(ptr);
+            }
+        });
         CPlatformWindow.super.dispose();
     }
 
@@ -445,7 +499,14 @@
 
     @Override // PlatformWindow
     public Insets getInsets() {
-        return nativeGetNSWindowInsets(getNSWindowPtr());
+        final AtomicReference<Insets> ref = new AtomicReference<>();
+        execute(new CFNativeAction() {
+            @Override
+            public void run(long ptr) {
+                ref.set(nativeGetNSWindowInsets(ptr));
+            }
+        });
+        return ref.get() != null ? ref.get() : new Insets(0, 0, 0, 0);
     }
 
     @Override // PlatformWindow
@@ -470,9 +531,14 @@
     }
 
     @Override // PlatformWindow
-    public void setBounds(int x, int y, int w, int h) {
+    public void setBounds(final int x, final int y, final int w, final int h) {
 //        assert CThreading.assertEventQueue();
-        nativeSetNSWindowBounds(getNSWindowPtr(), x, y, w, h);
+        execute(new CFNativeAction() {
+            @Override
+            public void run(long ptr) {
+                nativeSetNSWindowBounds(ptr, x, y, w, h);
+            }
+        });
     }
 
     public boolean isVisible() {
@@ -480,8 +546,17 @@
     }
 
     private boolean isMaximized() {
-        return undecorated ? this.normalBounds != null
-                : CWrapper.NSWindow.isZoomed(getNSWindowPtr());
+        if (undecorated) {
+            return this.normalBounds != null;
+        }
+        final AtomicBoolean ref = new AtomicBoolean();
+        execute(new CFNativeAction() {
+            @Override
+            public void run(long ptr) {
+                ref.set(CWrapper.NSWindow.isZoomed(ptr));
+            }
+        });
+        return ref.get();
     }
 
     private void maximize() {
@@ -489,7 +564,12 @@
             return;
         }
         if (!undecorated) {
-            CWrapper.NSWindow.zoom(getNSWindowPtr());
+            execute(new CFNativeAction() {
+                @Override
+                public void run(long ptr) {
+                    CWrapper.NSWindow.zoom(ptr);
+                }
+            });
         } else {
             deliverZoom(true);
 
@@ -510,7 +590,12 @@
             return;
         }
         if (!undecorated) {
-            CWrapper.NSWindow.zoom(getNSWindowPtr());
+            execute(new CFNativeAction() {
+                @Override
+                public void run(long ptr) {
+                    CWrapper.NSWindow.zoom(ptr);
+                }
+            });
         } else {
             deliverZoom(false);
 
@@ -522,8 +607,6 @@
 
     @Override // PlatformWindow
     public void setVisible(boolean visible) {
-        final long nsWindowPtr = getNSWindowPtr();
-
         // Configure stuff
         updateIconImages();
         updateFocusabilityForAutoRequestFocus(false);
@@ -533,30 +616,64 @@
         if (blocker == null || !visible) {
             // If it ain't blocked, or is being hidden, go regular way
             if (visible) {
-                CWrapper.NSWindow.makeFirstResponder(nsWindowPtr, contentView.getAWTView());
+                contentView.execute(new CFNativeAction() {
+                    @Override
+                    public void run(final long viewPtr) {
+                        execute(new CFNativeAction() {
+                            @Override
+                            public void run(long ptr) {
+                                CWrapper.NSWindow.makeFirstResponder(ptr,
+                                                                     viewPtr);
+                            }
+                        });
+                    }
+                });
 
-                boolean isPopup = (target.getType() == Window.Type.POPUP);
-                if (isPopup) {
-                    // Popups in applets don't activate applet's process
-                    CWrapper.NSWindow.orderFrontRegardless(nsWindowPtr);
-                } else {
-                    CWrapper.NSWindow.orderFront(nsWindowPtr);
-                }
+                final boolean isPopup = (target.getType() == Window.Type.POPUP);
+                execute(new CFNativeAction() {
+                    @Override
+                    public void run(long ptr) {
+                        if (isPopup) {
+                            // Popups in applets don't activate applet's process
+                            CWrapper.NSWindow.orderFrontRegardless(ptr);
+                        } else {
+                            CWrapper.NSWindow.orderFront(ptr);
+                        }
 
-                boolean isKeyWindow = CWrapper.NSWindow.isKeyWindow(nsWindowPtr);
-                if (!isKeyWindow) {
-                    CWrapper.NSWindow.makeKeyWindow(nsWindowPtr);
-                }
+                        boolean isKeyWindow = CWrapper.NSWindow.isKeyWindow(ptr);
+                        if (!isKeyWindow) {
+                            CWrapper.NSWindow.makeKeyWindow(ptr);
+                        }
+                    }
+                });
             } else {
-                // immediately hide the window
-                CWrapper.NSWindow.orderOut(nsWindowPtr);
-                // process the close
-                CWrapper.NSWindow.close(nsWindowPtr);
+                execute(new CFNativeAction() {
+                    @Override
+                    public void run(long ptr) {
+                        // immediately hide the window
+                        CWrapper.NSWindow.orderOut(ptr);
+                        // process the close
+                        CWrapper.NSWindow.close(ptr);
+                    }
+                });
             }
         } else {
             // otherwise, put it in a proper z-order
-            CWrapper.NSWindow.orderWindow(nsWindowPtr, CWrapper.NSWindow.NSWindowBelow,
-                    ((CPlatformWindow)blocker.getPlatformWindow()).getNSWindowPtr());
+            CPlatformWindow bw
+                    = (CPlatformWindow) blocker.getPlatformWindow();
+            bw.execute(new CFNativeAction() {
+                @Override
+                public void run(final long blockerPtr) {
+                    execute(new CFNativeAction() {
+                        @Override
+                        public void run(long ptr) {
+                            CWrapper.NSWindow.orderWindow(ptr,
+                                                          CWrapper.NSWindow.NSWindowBelow,
+                                                          blockerPtr);
+                        }
+                    });
+                }
+            });
         }
         this.visible = visible;
 
@@ -571,7 +688,12 @@
                 }
                 switch (frameState) {
                     case Frame.ICONIFIED:
-                        CWrapper.NSWindow.miniaturize(nsWindowPtr);
+                        execute(new CFNativeAction() {
+                            @Override
+                            public void run(long ptr) {
+                                CWrapper.NSWindow.miniaturize(ptr);
+                            }
+                        });
                         break;
                     case Frame.MAXIMIZED_BOTH:
                         maximize();
@@ -592,7 +714,17 @@
         if (visible) {
             // Order myself above my parent
             if (owner != null && owner.isVisible()) {
-                CWrapper.NSWindow.orderWindow(nsWindowPtr, CWrapper.NSWindow.NSWindowAbove, owner.getNSWindowPtr());
+                owner.execute(new CFNativeAction() {
+                    @Override
+                    public void run(final long ownerPtr) {
+                        execute(new CFNativeAction() {
+                            @Override
+                            public void run(long ptr) {
+                                CWrapper.NSWindow.orderWindow(ptr, CWrapper.NSWindow.NSWindowAbove, ownerPtr);
+                            }
+                        });
+                    }
+                });
                 applyWindowLevel(target);
             }
 
@@ -602,7 +734,17 @@
                 if (p instanceof LWWindowPeer) {
                     CPlatformWindow pw = (CPlatformWindow)((LWWindowPeer)p).getPlatformWindow();
                     if (pw != null && pw.isVisible()) {
-                        CWrapper.NSWindow.orderWindow(pw.getNSWindowPtr(), CWrapper.NSWindow.NSWindowAbove, nsWindowPtr);
+                        pw.execute(new CFNativeAction() {
+                            @Override
+                            public void run(final long childPtr) {
+                                execute(new CFNativeAction() {
+                                    @Override
+                                    public void run(long ptr) {
+                                        CWrapper.NSWindow.orderWindow(childPtr, CWrapper.NSWindow.NSWindowAbove, ptr);
+                                    }
+                                });
+                            }
+                        });
                         pw.applyWindowLevel(w);
                     }
                 }
@@ -617,26 +759,34 @@
     }
 
     @Override // PlatformWindow
-    public void setTitle(String title) {
-        nativeSetNSWindowTitle(getNSWindowPtr(), title);
+    public void setTitle(final String title) {
+        execute(new CFNativeAction() {
+            @Override
+            public void run(long ptr) {
+                nativeSetNSWindowTitle(ptr, title);
+            }
+        });
     }
 
     // Should be called on every window key property change.
     @Override // PlatformWindow
     public void updateIconImages() {
-        final long nsWindowPtr = getNSWindowPtr();
         final CImage cImage = getImageForTarget();
-        nativeSetNSWindowMinimizedIcon(nsWindowPtr, cImage == null ? 0L : cImage.ptr);
-    }
-
-    public long getNSWindowPtr() {
-        final long nsWindowPtr = ptr;
-        if (nsWindowPtr == 0L) {
-            if(logger.isLoggable(PlatformLogger.Level.FINE)) {
-                logger.fine("NSWindow already disposed?", new Exception("Pointer to native NSWindow is invalid."));
+        execute(new CFNativeAction() {
+            @Override
+            public void run(final long ptr) {
+                if (cImage == null) {
+                    nativeSetNSWindowMinimizedIcon(ptr, 0L);
+                } else {
+                    cImage.execute(new CFNativeAction() {
+                        @Override
+                        public void run(long imagePtr) {
+                            nativeSetNSWindowMinimizedIcon(ptr, imagePtr);
+                        }
+                    });
+                }
             }
-        }
-        return nsWindowPtr;
+        });
     }
 
     public SurfaceData getSurfaceData() {
@@ -645,13 +795,16 @@
 
     @Override  // PlatformWindow
     public void toBack() {
-        final long nsWindowPtr = getNSWindowPtr();
-        nativePushNSWindowToBack(nsWindowPtr);
+        execute(new CFNativeAction() {
+            @Override
+            public void run(long ptr) {
+                CPlatformWindow.nativePushNSWindowToBack(ptr);
+            }
+        });
     }
 
     @Override  // PlatformWindow
     public void toFront() {
-        final long nsWindowPtr = getNSWindowPtr();
         LWCToolkit lwcToolkit = (LWCToolkit) Toolkit.getDefaultToolkit();
         Window w = DefaultKeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
         if( w != null && w.getPeer() != null
@@ -660,7 +813,12 @@
             lwcToolkit.activateApplicationIgnoringOtherApps();
         }
         updateFocusabilityForAutoRequestFocus(false);
-        nativePushNSWindowToFront(nsWindowPtr);
+        execute(new CFNativeAction() {
+            @Override
+            public void run(long ptr) {
+                CPlatformWindow.nativePushNSWindowToFront(ptr);
+            }
+        });
         updateFocusabilityForAutoRequestFocus(true);
     }
 
@@ -681,8 +839,13 @@
     }
 
     @Override
-    public void setSizeConstraints(int minW, int minH, int maxW, int maxH) {
-        nativeSetNSWindowMinMax(getNSWindowPtr(), minW, minH, maxW, maxH);
+    public void setSizeConstraints(final int minW, final int minH, final int maxW, final int maxH) {
+        execute(new CFNativeAction() {
+            @Override
+            public void run(long ptr) {
+                nativeSetNSWindowMinMax(ptr, minW, minH, maxW, maxH);
+            }
+        });
     }
 
     @Override
@@ -699,19 +862,28 @@
 
     @Override
     public boolean requestWindowFocus() {
-
-        long ptr = getNSWindowPtr();
-        if (CWrapper.NSWindow.canBecomeMainWindow(ptr)) {
-            CWrapper.NSWindow.makeMainWindow(ptr);
-        }
-        CWrapper.NSWindow.makeKeyAndOrderFront(ptr);
+        execute(new CFNativeAction() {
+            @Override
+            public void run(long ptr) {
+                if (CWrapper.NSWindow.canBecomeMainWindow(ptr)) {
+                    CWrapper.NSWindow.makeMainWindow(ptr);
+                }
+                CWrapper.NSWindow.makeKeyAndOrderFront(ptr);
+            }
+        });
         return true;
     }
 
     @Override
     public boolean isActive() {
-        long ptr = getNSWindowPtr();
-        return CWrapper.NSWindow.isKeyWindow(ptr);
+        final AtomicBoolean ref = new AtomicBoolean();
+        execute(new CFNativeAction() {
+            @Override
+            public void run(long ptr) {
+                ref.set(CWrapper.NSWindow.isKeyWindow(ptr));
+            }
+        });
+        return ref.get();
     }
 
     @Override
@@ -732,22 +904,42 @@
     }
 
     @Override
-    public void setOpacity(float opacity) {
-        CWrapper.NSWindow.setAlphaValue(getNSWindowPtr(), opacity);
+    public void setOpacity(final float opacity) {
+        execute(new CFNativeAction() {
+            @Override
+            public void run(long ptr) {
+                CWrapper.NSWindow.setAlphaValue(ptr, opacity);
+            }
+        });
     }
 
     @Override
-    public void setOpaque(boolean isOpaque) {
-        CWrapper.NSWindow.setOpaque(getNSWindowPtr(), isOpaque);
+    public void setOpaque(final boolean isOpaque) {
+        execute(new CFNativeAction() {
+            @Override
+            public void run(long ptr) {
+                CWrapper.NSWindow.setOpaque(ptr, isOpaque);
+            }
+        });
         boolean isTextured = (peer == null) ? false : peer.isTextured();
         if (!isTextured) {
             if (!isOpaque) {
-                CWrapper.NSWindow.setBackgroundColor(getNSWindowPtr(), 0);
+                execute(new CFNativeAction() {
+                    @Override
+                    public void run(long ptr) {
+                        CWrapper.NSWindow.setBackgroundColor(ptr, 0);
+                    }
+                });
             } else if (peer != null) {
                 Color color = peer.getBackground();
                 if (color != null) {
-                    int rgb = color.getRGB();
-                    CWrapper.NSWindow.setBackgroundColor(getNSWindowPtr(), rgb);
+                    final int rgb = color.getRGB();
+                    execute(new CFNativeAction() {
+                        @Override
+                        public void run(long ptr) {
+                            CWrapper.NSWindow.setBackgroundColor(ptr, rgb);
+                        }
+                    });
                 }
             }
         }
@@ -765,12 +957,22 @@
     @Override
     public void enterFullScreenMode() {
         isFullScreenMode = true;
-        nativeEnterFullScreenMode(getNSWindowPtr());
+        execute(new CFNativeAction() {
+            @Override
+            public void run(long ptr) {
+                CPlatformWindow.nativeEnterFullScreenMode(ptr);
+            }
+        });
     }
 
     @Override
     public void exitFullScreenMode() {
-        nativeExitFullScreenMode(getNSWindowPtr());
+        execute(new CFNativeAction() {
+            @Override
+            public void run(long ptr) {
+                CPlatformWindow.nativeExitFullScreenMode(ptr);
+            }
+        });
         isFullScreenMode = false;
     }
 
@@ -789,7 +991,6 @@
         int prevWindowState = peer.getState();
         if (prevWindowState == windowState) return;
 
-        final long nsWindowPtr = getNSWindowPtr();
         if ((windowState & Frame.ICONIFIED) != 0) {
             // Treat all state bit masks with ICONIFIED bit as ICONIFIED state.
             windowState = Frame.ICONIFIED;
@@ -801,18 +1002,33 @@
                     // the zoom call toggles between the normal and the max states
                     unmaximize();
                 }
-                CWrapper.NSWindow.miniaturize(nsWindowPtr);
+                execute(new CFNativeAction() {
+                    @Override
+                    public void run(long ptr) {
+                        CWrapper.NSWindow.miniaturize(ptr);
+                    }
+                });
                 break;
             case Frame.MAXIMIZED_BOTH:
                 if (prevWindowState == Frame.ICONIFIED) {
                     // let's return into the normal states first
-                    CWrapper.NSWindow.deminiaturize(nsWindowPtr);
+                    execute(new CFNativeAction() {
+                        @Override
+                        public void run(long ptr) {
+                            CWrapper.NSWindow.deminiaturize(ptr);
+                        }
+                    });
                 }
                 maximize();
                 break;
             case Frame.NORMAL:
                 if (prevWindowState == Frame.ICONIFIED) {
-                    CWrapper.NSWindow.deminiaturize(nsWindowPtr);
+                    execute(new CFNativeAction() {
+                        @Override
+                        public void run(long ptr) {
+                            CWrapper.NSWindow.deminiaturize(ptr);
+                        }
+                    });
                 } else if (prevWindowState == Frame.MAXIMIZED_BOTH) {
                     // the zoom call toggles between the normal and the max states
                     unmaximize();
@@ -829,17 +1045,27 @@
     }
 
     @Override
-    public void setModalBlocked(boolean blocked) {
+    public void setModalBlocked(final boolean blocked) {
         if (target.getModalExclusionType() == Dialog.ModalExclusionType.APPLICATION_EXCLUDE) {
             return;
         }
 
-        nativeSetEnabled(getNSWindowPtr(), !blocked);
+        execute(new CFNativeAction() {
+            @Override
+            public void run(long ptr) {
+                nativeSetEnabled(ptr, !blocked);
+            }
+        });
     }
 
 
     public final void invalidateShadow(){
-        nativeRevalidateNSWindowShadow(getNSWindowPtr());
+        execute(new CFNativeAction() {
+            @Override
+            public void run(long ptr) {
+                nativeRevalidateNSWindowShadow(ptr);
+            }
+        });
     }
 
     // ----------------------------------------------------------------------
@@ -1005,11 +1231,14 @@
 
         pWindow.orderAboveSiblings();
 
-        final long nsWindowPtr = pWindow.getNSWindowPtr();
-        CWrapper.NSWindow.orderFrontRegardless(nsWindowPtr);
-        CWrapper.NSWindow.makeKeyAndOrderFront(nsWindowPtr);
-        CWrapper.NSWindow.makeMainWindow(nsWindowPtr);
-
+        pWindow.execute(new CFNativeAction() {
+            @Override
+            public void run(long ptr) {
+                CWrapper.NSWindow.orderFrontRegardless(ptr);
+                CWrapper.NSWindow.makeKeyAndOrderFront(ptr);
+                CWrapper.NSWindow.makeMainWindow(ptr);
+            }
+        });
         return true;
     }
 
@@ -1029,10 +1258,18 @@
             owner.orderAboveSiblings();
 
             // Order the window to front of the stack of child windows
-            final long nsWindowSelfPtr = getNSWindowPtr();
-            final long nsWindowOwnerPtr = owner.getNSWindowPtr();
-            CWrapper.NSWindow.orderFront(nsWindowOwnerPtr);
-            CWrapper.NSWindow.orderWindow(nsWindowSelfPtr, CWrapper.NSWindow.NSWindowAbove, nsWindowOwnerPtr);
+            owner.execute(new CFNativeAction() {
+                @Override
+                public void run(final long nsWindowOwnerPtr) {
+                    execute(new CFNativeAction() {
+                        @Override
+                        public void run(long nsWindowSelfPtr) {
+                            CWrapper.NSWindow.orderFront(nsWindowOwnerPtr);
+                            CWrapper.NSWindow.orderWindow(nsWindowSelfPtr, CWrapper.NSWindow.NSWindowAbove, nsWindowOwnerPtr);
+                        }
+                    });
+                }
+            });
         }
 
         applyWindowLevel(target);
@@ -1040,9 +1277,19 @@
 
     protected void applyWindowLevel(Window target) {
         if (target.isAlwaysOnTop() && target.getType() != Window.Type.POPUP) {
-            CWrapper.NSWindow.setLevel(getNSWindowPtr(), CWrapper.NSWindow.NSFloatingWindowLevel);
+            execute(new CFNativeAction() {
+                @Override
+                public void run(long ptr) {
+                    CWrapper.NSWindow.setLevel(ptr, CWrapper.NSWindow.NSFloatingWindowLevel);
+                }
+            });
         } else if (target.getType() == Window.Type.POPUP) {
-            CWrapper.NSWindow.setLevel(getNSWindowPtr(), CWrapper.NSWindow.NSPopUpMenuWindowLevel);
+            execute(new CFNativeAction() {
+                @Override
+                public void run(long ptr) {
+                    CWrapper.NSWindow.setLevel(ptr, CWrapper.NSWindow.NSPopUpMenuWindowLevel);
+                }
+            });
         }
     }
 
--- a/src/macosx/classes/sun/lwawt/macosx/CTrayIcon.java	Tue Apr 01 13:10:06 2014 +0400
+++ b/src/macosx/classes/sun/lwawt/macosx/CTrayIcon.java	Fri Apr 21 05:47:49 2017 +0100
@@ -35,6 +35,7 @@
 import java.awt.peer.TrayIconPeer;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
+import java.util.concurrent.atomic.AtomicReference;
 
 public class CTrayIcon extends CFRetainedResource implements TrayIconPeer {
     private TrayIcon target;
@@ -86,10 +87,6 @@
         return nativeCreate();
     }
 
-    private long getModel() {
-        return ptr;
-    }
-
     private native long nativeCreate();
 
     //invocation from the AWTTrayIcon.m
@@ -142,8 +139,13 @@
     }
 
     @Override
-    public void setToolTip(String tooltip) {
-        nativeSetToolTip(getModel(), tooltip);
+    public void setToolTip(final String tooltip) {
+        execute(new CFNativeAction() {
+            @Override
+            public void run(long ptr) {
+                nativeSetToolTip(ptr, tooltip);
+            }
+        });
     }
 
     //adds tooltip to the NSStatusBar's NSButton.
@@ -172,7 +174,18 @@
         }
 
         CImage cimage = CImage.getCreator().createFromImage(image);
-        setNativeImage(getModel(), cimage.ptr, target.isImageAutoSize());
+        final boolean imageAutoSize = target.isImageAutoSize();
+        cimage.execute(new CFNativeAction() {
+            @Override
+            public void run(final long imagePtr) {
+                execute(new CFNativeAction() {
+                    @Override
+                    public void run(long ptr) {
+                        setNativeImage(ptr, imagePtr, imageAutoSize);
+                    }
+                });
+            }
+        });
     }
 
     private native void setNativeImage(final long model, final long nsimage, final boolean autosize);
@@ -349,7 +362,17 @@
     private void showMessageDialog() {
 
         Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
-        Point2D iconLoc = nativeGetIconLocation(getModel());
+        final AtomicReference<Point2D> ref = new AtomicReference<>();
+        execute(new CFNativeAction() {
+            @Override
+            public void run(long ptr) {
+                ref.set(nativeGetIconLocation(ptr));
+            }
+        });
+        Point2D iconLoc = ref.get();
+        if (iconLoc == null) {
+            return;
+        }
 
         int dialogY = (int)iconLoc.getY();
         int dialogX = (int)iconLoc.getX();
--- a/src/macosx/classes/sun/lwawt/macosx/CViewPlatformEmbeddedFrame.java	Tue Apr 01 13:10:06 2014 +0400
+++ b/src/macosx/classes/sun/lwawt/macosx/CViewPlatformEmbeddedFrame.java	Fri Apr 21 05:47:49 2017 +0100
@@ -78,13 +78,23 @@
 
     @Override
     public void dispose() {
-        CWrapper.NSView.removeFromSuperview(view.getAWTView());
+        view.execute(new CFRetainedResource.CFNativeAction() {
+            @Override
+            public void run(long ptr) {
+                CWrapper.NSView.removeFromSuperview(ptr);
+            }
+        });
         view.dispose();
     }
 
     @Override
-    public void setVisible(boolean visible) {
-        CWrapper.NSView.setHidden(view.getAWTView(), !visible);
+    public void setVisible(final boolean visible) {
+        view.execute(new CFRetainedResource.CFNativeAction() {
+            @Override
+            public void run(long ptr) {
+                CWrapper.NSView.setHidden(ptr, !visible);
+            }
+        });
     }
 
     @Override
--- a/src/macosx/classes/sun/lwawt/macosx/CWarningWindow.java	Tue Apr 01 13:10:06 2014 +0400
+++ b/src/macosx/classes/sun/lwawt/macosx/CWarningWindow.java	Fri Apr 21 05:47:49 2017 +0100
@@ -119,7 +119,7 @@
         setBounds((int)point.getX(), (int)point.getY(), getWidth(), getHeight());
     }
 
-    public void setVisible(boolean visible, boolean doSchedule) {
+    public void setVisible(final boolean visible, boolean doSchedule) {
         synchronized (scheduler) {
             if (showingTaskHandle != null) {
                 showingTaskHandle.cancel(false);
@@ -217,16 +217,19 @@
     }
 
     @Override
-    public void setVisible(boolean visible) {
+    public void setVisible(final boolean visible) {
         synchronized (lock) {
-            final long nsWindowPtr = getNSWindowPtr();
-
-            // Actually show or hide the window
-            if (visible) {
-                CWrapper.NSWindow.orderFront(nsWindowPtr);
-            } else {
-                CWrapper.NSWindow.orderOut(nsWindowPtr);
-            }
+            execute(new CFNativeAction() {
+                @Override
+                public void run(long ptr) {
+                    // Actually show or hide the window
+                    if (visible) {
+                        CWrapper.NSWindow.orderFront(ptr);
+                    } else {
+                        CWrapper.NSWindow.orderOut(ptr);
+                    }
+                }
+            });
 
             this.visible = visible;
 
@@ -234,8 +237,19 @@
             if (visible) {
                 // Order myself above my parent
                 if (owner != null && owner.isVisible()) {
-                    CWrapper.NSWindow.orderWindow(nsWindowPtr,
-                            CWrapper.NSWindow.NSWindowAbove, owner.getNSWindowPtr());
+                    owner.execute(new CFNativeAction() {
+                        @Override
+                        public void run(final long ownerPtr) {
+                            execute(new CFNativeAction() {
+                                @Override
+                                public void run(long ptr) {
+                                    CWrapper.NSWindow.orderWindow(ptr,
+                                                                  CWrapper.NSWindow.NSWindowAbove,
+                                                                  ownerPtr);
+                                }
+                            });
+                        }
+                    });
 
                     // do not allow security warning to be obscured by other windows
                     applyWindowLevel(ownerWindow);
--- a/src/macosx/native/sun/awt/AWTSurfaceLayers.h	Tue Apr 01 13:10:06 2014 +0400
+++ b/src/macosx/native/sun/awt/AWTSurfaceLayers.h	Fri Apr 21 05:47:49 2017 +0100
@@ -41,6 +41,8 @@
     CALayer *windowLayer;
 }
 
+@property (retain) CALayer *windowLayer;
+
 - (id) initWithWindowLayer: (CALayer *)windowLayer;
 - (void) setBounds: (CGRect)rect;
 
--- a/src/macosx/native/sun/awt/AWTSurfaceLayers.m	Tue Apr 01 13:10:06 2014 +0400
+++ b/src/macosx/native/sun/awt/AWTSurfaceLayers.m	Fri Apr 21 05:47:49 2017 +0100
@@ -37,11 +37,15 @@
     self = [super init];
     if (self == nil) return self;
 
-    windowLayer = aWindowLayer;
+    self.windowLayer = aWindowLayer;
 
     return self;
 }
 
+- (void) dealloc {
+    self.windowLayer = nil;
+    [super dealloc];
+}
 
 - (CALayer *) layer {
     return layer;