From 7a828a62c8991a1ecbc1e697f435c698426ef764 Mon Sep 17 00:00:00 2001 From: mcherkas Date: Fri, 11 Nov 2016 16:55:14 +0300 Subject: [PATCH] 8165626: Improved window framing Reviewed-by: serb --- .../com/apple/eawt/_AppDockIconHandler.java | 15 +- .../classes/sun/java2d/opengl/CGLLayer.java | 6 +- .../sun/lwawt/macosx/CFRetainedResource.java | 52 +++- .../classes/sun/lwawt/macosx/CImage.java | 32 ++- .../classes/sun/lwawt/macosx/CMenuItem.java | 8 +- .../sun/lwawt/macosx/CPlatformComponent.java | 7 +- .../sun/lwawt/macosx/CPlatformLWWindow.java | 5 - .../sun/lwawt/macosx/CPlatformView.java | 35 ++- .../sun/lwawt/macosx/CPlatformWindow.java | 228 +++++++++++------- .../classes/sun/lwawt/macosx/CTrayIcon.java | 23 +- .../macosx/CViewPlatformEmbeddedFrame.java | 4 +- .../sun/lwawt/macosx/CWarningWindow.java | 25 +- src/macosx/native/sun/awt/AWTSurfaceLayers.h | 2 + src/macosx/native/sun/awt/AWTSurfaceLayers.m | 6 +- 14 files changed, 280 insertions(+), 168 deletions(-) diff --git a/src/macosx/classes/com/apple/eawt/_AppDockIconHandler.java b/src/macosx/classes/com/apple/eawt/_AppDockIconHandler.java index e91efeaa0..4b858e93d 100644 --- a/src/macosx/classes/com/apple/eawt/_AppDockIconHandler.java +++ b/src/macosx/classes/com/apple/eawt/_AppDockIconHandler.java @@ -72,8 +72,7 @@ class _AppDockIconHandler { public void setDockIconImage(final Image image) { try { final CImage cImage = getCImageCreator().createFromImage(image); - final long nsImagePtr = getNSImagePtrFrom(cImage); - nativeSetDockIconImage(nsImagePtr); + cImage.execute(_AppDockIconHandler::nativeSetDockIconImage); } catch (final Throwable e) { throw new RuntimeException(e); } @@ -102,16 +101,4 @@ class _AppDockIconHandler { 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); - } - } } diff --git a/src/macosx/classes/sun/java2d/opengl/CGLLayer.java b/src/macosx/classes/sun/java2d/opengl/CGLLayer.java index 32a099cea..66d4e863f 100644 --- a/src/macosx/classes/sun/java2d/opengl/CGLLayer.java +++ b/src/macosx/classes/sun/java2d/opengl/CGLLayer.java @@ -108,7 +108,7 @@ public class CGLLayer extends CFRetainedResource { OGLRenderQueue rq = OGLRenderQueue.getInstance(); rq.lock(); try { - validate(getPointer(), cglsd); + execute(ptr -> validate(ptr, cglsd)); } finally { rq.unlock(); } @@ -124,7 +124,7 @@ public class CGLLayer extends CFRetainedResource { private void setScale(final int _scale) { if (scale != _scale) { scale = _scale; - nativeSetScale(getPointer(), scale); + execute(ptr -> nativeSetScale(ptr, scale)); } } @@ -138,7 +138,7 @@ public class CGLLayer extends CFRetainedResource { OGLRenderQueue rq = OGLRenderQueue.getInstance(); rq.lock(); try { - blitTexture(getPointer()); + execute(ptr -> blitTexture(ptr)); } finally { rq.unlock(); } diff --git a/src/macosx/classes/sun/lwawt/macosx/CFRetainedResource.java b/src/macosx/classes/sun/lwawt/macosx/CFRetainedResource.java index f69ad201e..adec34f9e 100644 --- a/src/macosx/classes/sun/lwawt/macosx/CFRetainedResource.java +++ b/src/macosx/classes/sun/lwawt/macosx/CFRetainedResource.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, 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 @@ public class CFRetainedResource { // 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 @@ public class CFRetainedResource { * @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 @@ public class CFRetainedResource { * * @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 @@ public class CFRetainedResource { * @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; } diff --git a/src/macosx/classes/sun/lwawt/macosx/CImage.java b/src/macosx/classes/sun/lwawt/macosx/CImage.java index 5f468df9a..fe300e909 100644 --- a/src/macosx/classes/sun/lwawt/macosx/CImage.java +++ b/src/macosx/classes/sun/lwawt/macosx/CImage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, 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.Arrays; import java.util.List; import sun.awt.image.MultiResolutionImage; import sun.awt.image.MultiResolutionCachedImage; +import java.util.concurrent.atomic.AtomicReference; import sun.awt.image.SunWritableRaster; @@ -235,15 +236,26 @@ public class CImage extends CFRetainedResource { /** @return A MultiResolution image created from nsImagePtr, or null. */ private Image toImage() { - if (ptr == 0) return null; + if (ptr == 0) { + return null; + } - final Dimension2D size = nativeGetNSImageSize(ptr); + AtomicReference sizeRef = new AtomicReference<>(); + execute(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()); + AtomicReference repRef = new AtomicReference<>(); + execute(ptr -> { + repRef.set(nativeGetNSImageRepresentationSizes(ptr, size.getWidth(), + size.getHeight())); + }); + Dimension2D[] sizes = repRef.get(); return sizes == null || sizes.length < 2 ? new MultiResolutionCachedImage(w, h, (width, height) @@ -256,18 +268,18 @@ public class CImage extends CFRetainedResource { 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(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(ptr -> nativeSetNSImageSize(ptr, w, h)); return this; } void resizeRepresentations(double w, double h) { - if (ptr != 0) nativeResizeNSImageRepresentations(ptr, w, h); + execute(ptr -> nativeResizeNSImageRepresentations(ptr, w, h)); } } diff --git a/src/macosx/classes/sun/lwawt/macosx/CMenuItem.java b/src/macosx/classes/sun/lwawt/macosx/CMenuItem.java index 01427dbb3..0970b3cd6 100644 --- a/src/macosx/classes/sun/lwawt/macosx/CMenuItem.java +++ b/src/macosx/classes/sun/lwawt/macosx/CMenuItem.java @@ -113,7 +113,13 @@ public class CMenuItem extends CMenuComponent implements MenuItemPeer { */ public final void setImage(final java.awt.Image img) { CImage cimg = CImage.getCreator().createFromImage(img); - execute(ptr -> nativeSetImage(ptr, cimg == null ? 0L : cimg.ptr)); + execute(ptr -> { + if (cimg == null) { + nativeSetImage(ptr, 0L); + } else { + cimg.execute(imgPtr -> nativeSetImage(ptr, imgPtr)); + } + }); } /** diff --git a/src/macosx/classes/sun/lwawt/macosx/CPlatformComponent.java b/src/macosx/classes/sun/lwawt/macosx/CPlatformComponent.java index 65a4392ca..a98b55298 100644 --- a/src/macosx/classes/sun/lwawt/macosx/CPlatformComponent.java +++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformComponent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, 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 @@ class CPlatformComponent extends CFRetainedResource super(0, true); } + /** + * Used by JAWT. + */ public long getPointer() { return ptr; } @@ -61,7 +64,7 @@ class CPlatformComponent extends CFRetainedResource // 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(ptr->nativeSetBounds(ptr, x - insets.left, y - insets.top, w, h)); } @Override diff --git a/src/macosx/classes/sun/lwawt/macosx/CPlatformLWWindow.java b/src/macosx/classes/sun/lwawt/macosx/CPlatformLWWindow.java index 9c2edf227..21a24ef7a 100644 --- a/src/macosx/classes/sun/lwawt/macosx/CPlatformLWWindow.java +++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformLWWindow.java @@ -107,11 +107,6 @@ public class CPlatformLWWindow extends CPlatformWindow { public void updateIconImages() { } - @Override - public long getNSWindowPtr() { - return 0; - } - @Override public SurfaceData getSurfaceData() { return null; diff --git a/src/macosx/classes/sun/lwawt/macosx/CPlatformView.java b/src/macosx/classes/sun/lwawt/macosx/CPlatformView.java index 9d1acafac..6630e6d97 100644 --- a/src/macosx/classes/sun/lwawt/macosx/CPlatformView.java +++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformView.java @@ -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 @@ -27,6 +27,9 @@ package sun.lwawt.macosx; import java.awt.*; 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; @@ -83,7 +86,7 @@ public class CPlatformView extends CFRetainedResource { * Cocoa coordinates). */ public void setBounds(int x, int y, int width, int height) { - CWrapper.NSView.setFrame(ptr, x, y, width, height); + execute(ptr->CWrapper.NSView.setFrame(ptr, x, y, width, height)); } // REMIND: CGLSurfaceData expects top-level's size @@ -96,7 +99,7 @@ public class CPlatformView extends CFRetainedResource { } public void setToolTip(String msg) { - CWrapper.NSView.setToolTip(ptr, msg); + execute(ptr -> CWrapper.NSView.setToolTip(ptr, msg)); } // ---------------------------------------------------------------------- @@ -147,18 +150,25 @@ public class CPlatformView extends CFRetainedResource { } public void setAutoResizable(boolean toResize) { - nativeSetAutoResizable(this.getAWTView(), toResize); + execute(ptr -> nativeSetAutoResizable(ptr, toResize)); } public boolean isUnderMouse() { - return nativeIsViewUnderMouse(getAWTView()); + AtomicBoolean ref = new AtomicBoolean(); + execute(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); + AtomicInteger ref = new AtomicInteger(); + execute(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 @@ -168,8 +178,15 @@ public class CPlatformView extends CFRetainedResource { } public Point getLocationOnScreen() { - Rectangle r = nativeGetLocationOnScreen(this.getAWTView()).getBounds(); - return new Point(r.x, r.y); + AtomicReference ref = new AtomicReference<>(); + execute(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); } // ---------------------------------------------------------------------- diff --git a/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java b/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java index 640a0deac..abcf70c6e 100644 --- a/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java +++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java @@ -31,6 +31,9 @@ import java.awt.event.*; 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,16 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo c.setStyleBits(FULLSCREENABLE, Boolean.parseBoolean(value.toString())); }}, new Property(WINDOW_SHADOW_REVALIDATE_NOW) { public void applyProperty(final CPlatformWindow c, final Object value) { - nativeRevalidateNSWindowShadow(c.getNSWindowPtr()); + c.execute(ptr -> nativeRevalidateNSWindowShadow(ptr)); }}, new Property(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(ptr->nativeSetNSWindowRepresentedFilename(ptr, null)); return; } final String filename = ((java.io.File)value).getAbsolutePath(); - nativeSetNSWindowRepresentedFilename(c.getNSWindowPtr(), filename); + c.execute(ptr->nativeSetNSWindowRepresentedFilename(ptr, filename)); }} }) { public CPlatformWindow convertJComponentToTarget(final JRootPane p) { @@ -232,7 +235,6 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo contentView = createContentView(); contentView.initialize(peer, responder); - final long ownerPtr = owner != null ? owner.getNSWindowPtr() : 0L; Rectangle bounds; if (!IS(DECORATED, styleBits)) { // For undecorated frames the move/resize event does not come if the frame is centered on the screen @@ -241,9 +243,21 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo } else { bounds = _peer.constrainBounds(_target.getBounds()); } - final long nativeWindowPtr = nativeCreateNSWindow(contentView.getAWTView(), - ownerPtr, styleBits, bounds.x, bounds.y, bounds.width, bounds.height); - setPtr(nativeWindowPtr); + AtomicLong ref = new AtomicLong(); + contentView.execute(viewPtr -> { + if (owner != null) { + owner.execute(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()); if (target instanceof javax.swing.RootPaneContainer) { final javax.swing.JRootPane rootpane = ((javax.swing.RootPaneContainer)target).getRootPane(); @@ -405,30 +419,31 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo // this is the counter-point to -[CWindow _nativeSetStyleBit:] private void setStyleBits(final int mask, final boolean value) { - nativeSetNSWindowStyleBits(getNSWindowPtr(), mask, value ? mask : 0); + execute(ptr -> nativeSetNSWindowStyleBits(ptr, mask, value ? mask : 0)); } private native void _toggleFullScreenMode(final long model); public void toggleFullScreen() { - _toggleFullScreenMode(getNSWindowPtr()); + execute(this::_toggleFullScreenMode); } @Override // PlatformWindow public void setMenuBar(MenuBar mb) { - final long nsWindowPtr = getNSWindowPtr(); CMenuBar mbPeer = (CMenuBar)LWToolkit.targetToPeer(mb); - if (mbPeer != null) { - mbPeer.execute(ptr -> nativeSetNSWindowMenuBar(nsWindowPtr, ptr)); - } else { - nativeSetNSWindowMenuBar(nsWindowPtr, 0); - } + execute(nsWindowPtr->{ + if (mbPeer != null) { + mbPeer.execute(ptr -> nativeSetNSWindowMenuBar(nsWindowPtr, ptr)); + } else { + nativeSetNSWindowMenuBar(nsWindowPtr, 0); + } + }); } @Override // PlatformWindow public void dispose() { contentView.dispose(); - nativeDispose(getNSWindowPtr()); + execute(CPlatformWindow::nativeDispose); CPlatformWindow.super.dispose(); } @@ -441,7 +456,11 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo @Override // PlatformWindow public Insets getInsets() { - return nativeGetNSWindowInsets(getNSWindowPtr()); + AtomicReference ref = new AtomicReference<>(); + execute(ptr -> { + ref.set(nativeGetNSWindowInsets(ptr)); + }); + return ref.get() != null ? ref.get() : new Insets(0, 0, 0, 0); } @Override // PlatformWindow @@ -468,12 +487,18 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo @Override // PlatformWindow public void setBounds(int x, int y, int w, int h) { // assert CThreading.assertEventQueue(); - nativeSetNSWindowBounds(getNSWindowPtr(), x, y, w, h); + execute(ptr -> nativeSetNSWindowBounds(ptr, x, y, w, h)); } private boolean isMaximized() { - return undecorated ? this.normalBounds != null - : CWrapper.NSWindow.isZoomed(getNSWindowPtr()); + if (undecorated) { + return this.normalBounds != null; + } + AtomicBoolean ref = new AtomicBoolean(); + execute(ptr -> { + ref.set(CWrapper.NSWindow.isZoomed(ptr)); + }); + return ref.get(); } private void maximize() { @@ -481,7 +506,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo return; } if (!undecorated) { - CWrapper.NSWindow.zoom(getNSWindowPtr()); + execute(CWrapper.NSWindow::zoom); } else { deliverZoom(true); @@ -505,7 +530,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo return; } if (!undecorated) { - CWrapper.NSWindow.zoom(getNSWindowPtr()); + execute(CWrapper.NSWindow::zoom); } else { deliverZoom(false); @@ -521,8 +546,6 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo @Override // PlatformWindow public void setVisible(boolean visible) { - final long nsWindowPtr = getNSWindowPtr(); - // Configure stuff updateIconImages(); updateFocusabilityForAutoRequestFocus(false); @@ -534,30 +557,44 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo 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(viewPtr -> { + execute(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); - } + execute(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(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(blockerPtr -> { + execute(ptr -> { + CWrapper.NSWindow.orderWindow(ptr, + CWrapper.NSWindow.NSWindowBelow, + blockerPtr); + }); + }); } this.visible = visible; @@ -576,7 +613,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo } switch (frameState) { case Frame.ICONIFIED: - CWrapper.NSWindow.miniaturize(nsWindowPtr); + execute(CWrapper.NSWindow::miniaturize); break; case Frame.MAXIMIZED_BOTH: maximize(); @@ -598,7 +635,11 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo if (visible) { // Order myself above my parent if (owner != null && owner.isVisible()) { - CWrapper.NSWindow.orderWindow(nsWindowPtr, CWrapper.NSWindow.NSWindowAbove, owner.getNSWindowPtr()); + owner.execute(ownerPtr -> { + execute(ptr -> { + CWrapper.NSWindow.orderWindow(ptr, CWrapper.NSWindow.NSWindowAbove, ownerPtr); + }); + }); applyWindowLevel(target); } @@ -608,7 +649,11 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo 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(childPtr -> { + execute(ptr -> { + CWrapper.NSWindow.orderWindow(childPtr, CWrapper.NSWindow.NSWindowAbove, ptr); + }); + }); pw.applyWindowLevel(w); } } @@ -624,25 +669,22 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo @Override // PlatformWindow public void setTitle(String title) { - nativeSetNSWindowTitle(getNSWindowPtr(), title); + execute(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(ptr -> { + if (cImage == null) { + nativeSetNSWindowMinimizedIcon(ptr, 0L); + } else { + cImage.execute(imagePtr -> { + nativeSetNSWindowMinimizedIcon(ptr, imagePtr); + }); } - } - return nsWindowPtr; + }); } public SurfaceData getSurfaceData() { @@ -651,13 +693,11 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo @Override // PlatformWindow public void toBack() { - final long nsWindowPtr = getNSWindowPtr(); - nativePushNSWindowToBack(nsWindowPtr); + execute(CPlatformWindow::nativePushNSWindowToBack); } @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 @@ -666,7 +706,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo lwcToolkit.activateApplicationIgnoringOtherApps(); } updateFocusabilityForAutoRequestFocus(false); - nativePushNSWindowToFront(nsWindowPtr); + execute(CPlatformWindow::nativePushNSWindowToFront); updateFocusabilityForAutoRequestFocus(true); } @@ -677,7 +717,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo @Override public void setSizeConstraints(int minW, int minH, int maxW, int maxH) { - nativeSetNSWindowMinMax(getNSWindowPtr(), minW, minH, maxW, maxH); + execute(ptr -> nativeSetNSWindowMinMax(ptr, minW, minH, maxW, maxH)); } @Override @@ -694,19 +734,22 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo @Override public boolean requestWindowFocus() { - - long ptr = getNSWindowPtr(); - if (CWrapper.NSWindow.canBecomeMainWindow(ptr)) { - CWrapper.NSWindow.makeMainWindow(ptr); - } - CWrapper.NSWindow.makeKeyAndOrderFront(ptr); + execute(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); + AtomicBoolean ref = new AtomicBoolean(); + execute(ptr -> { + ref.set(CWrapper.NSWindow.isKeyWindow(ptr)); + }); + return ref.get(); } @Override @@ -732,21 +775,21 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo @Override public void setOpacity(float opacity) { - CWrapper.NSWindow.setAlphaValue(getNSWindowPtr(), opacity); + execute(ptr -> CWrapper.NSWindow.setAlphaValue(ptr, opacity)); } @Override public void setOpaque(boolean isOpaque) { - CWrapper.NSWindow.setOpaque(getNSWindowPtr(), isOpaque); + execute(ptr -> CWrapper.NSWindow.setOpaque(ptr, isOpaque)); boolean isTextured = (peer == null) ? false : peer.isTextured(); if (!isTextured) { if (!isOpaque) { - CWrapper.NSWindow.setBackgroundColor(getNSWindowPtr(), 0); + execute(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); + execute(ptr->CWrapper.NSWindow.setBackgroundColor(ptr, rgb)); } } } @@ -759,12 +802,12 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo @Override public void enterFullScreenMode() { isFullScreenMode = true; - nativeEnterFullScreenMode(getNSWindowPtr()); + execute(CPlatformWindow::nativeEnterFullScreenMode); } @Override public void exitFullScreenMode() { - nativeExitFullScreenMode(getNSWindowPtr()); + execute(CPlatformWindow::nativeExitFullScreenMode); isFullScreenMode = false; } @@ -783,7 +826,6 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo 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; @@ -795,18 +837,18 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo // the zoom call toggles between the normal and the max states unmaximize(); } - CWrapper.NSWindow.miniaturize(nsWindowPtr); + execute(CWrapper.NSWindow::miniaturize); break; case Frame.MAXIMIZED_BOTH: if (prevWindowState == Frame.ICONIFIED) { // let's return into the normal states first - CWrapper.NSWindow.deminiaturize(nsWindowPtr); + execute(CWrapper.NSWindow::deminiaturize); } maximize(); break; case Frame.NORMAL: if (prevWindowState == Frame.ICONIFIED) { - CWrapper.NSWindow.deminiaturize(nsWindowPtr); + execute(CWrapper.NSWindow::deminiaturize); } else if (prevWindowState == Frame.MAXIMIZED_BOTH) { // the zoom call toggles between the normal and the max states unmaximize(); @@ -826,12 +868,12 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo return; } - nativeSetEnabled(getNSWindowPtr(), !blocked); + execute(ptr -> nativeSetEnabled(ptr, !blocked)); checkBlockingAndOrder(); } public final void invalidateShadow(){ - nativeRevalidateNSWindowShadow(getNSWindowPtr()); + execute(ptr -> nativeRevalidateNSWindowShadow(ptr)); } // ---------------------------------------------------------------------- @@ -1011,11 +1053,11 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo pWindow.orderAboveSiblings(); - final long nsWindowPtr = pWindow.getNSWindowPtr(); - CWrapper.NSWindow.orderFrontRegardless(nsWindowPtr); - CWrapper.NSWindow.makeKeyAndOrderFront(nsWindowPtr); - CWrapper.NSWindow.makeMainWindow(nsWindowPtr); - + pWindow.execute(ptr -> { + CWrapper.NSWindow.orderFrontRegardless(ptr); + CWrapper.NSWindow.makeKeyAndOrderFront(ptr); + CWrapper.NSWindow.makeMainWindow(ptr); + }); return true; } @@ -1035,10 +1077,12 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo 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(nsWindowOwnerPtr->{ + execute(nsWindowSelfPtr->{ + CWrapper.NSWindow.orderFront(nsWindowOwnerPtr); + CWrapper.NSWindow.orderWindow(nsWindowSelfPtr, CWrapper.NSWindow.NSWindowAbove, nsWindowOwnerPtr); + }); + }); } applyWindowLevel(target); @@ -1046,9 +1090,9 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo protected void applyWindowLevel(Window target) { if (target.isAlwaysOnTop() && target.getType() != Window.Type.POPUP) { - CWrapper.NSWindow.setLevel(getNSWindowPtr(), CWrapper.NSWindow.NSFloatingWindowLevel); + execute(ptr->CWrapper.NSWindow.setLevel(ptr, CWrapper.NSWindow.NSFloatingWindowLevel)); } else if (target.getType() == Window.Type.POPUP) { - CWrapper.NSWindow.setLevel(getNSWindowPtr(), CWrapper.NSWindow.NSPopUpMenuWindowLevel); + execute(ptr->CWrapper.NSWindow.setLevel(ptr, CWrapper.NSWindow.NSPopUpMenuWindowLevel)); } } diff --git a/src/macosx/classes/sun/lwawt/macosx/CTrayIcon.java b/src/macosx/classes/sun/lwawt/macosx/CTrayIcon.java index ff1648dba..bae7d8d25 100644 --- a/src/macosx/classes/sun/lwawt/macosx/CTrayIcon.java +++ b/src/macosx/classes/sun/lwawt/macosx/CTrayIcon.java @@ -36,6 +36,7 @@ import java.awt.image.BufferedImage; 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; @@ -88,10 +89,6 @@ public class CTrayIcon extends CFRetainedResource implements TrayIconPeer { return nativeCreate(); } - private long getModel() { - return ptr; - } - private native long nativeCreate(); //invocation from the AWTTrayIcon.m @@ -154,7 +151,7 @@ public class CTrayIcon extends CFRetainedResource implements TrayIconPeer { @Override public void setToolTip(String tooltip) { - nativeSetToolTip(getModel(), tooltip); + execute(ptr -> nativeSetToolTip(ptr, tooltip)); } //adds tooltip to the NSStatusBar's NSButton. @@ -183,7 +180,12 @@ public class CTrayIcon extends CFRetainedResource implements TrayIconPeer { } CImage cimage = CImage.getCreator().createFromImage(image); - setNativeImage(getModel(), cimage.ptr, target.isImageAutoSize()); + boolean imageAutoSize = target.isImageAutoSize(); + cimage.execute(imagePtr -> { + execute(ptr -> { + setNativeImage(ptr, imagePtr, imageAutoSize); + }); + }); } private native void setNativeImage(final long model, final long nsimage, final boolean autosize); @@ -363,7 +365,14 @@ public class CTrayIcon extends CFRetainedResource implements TrayIconPeer { private void showMessageDialog() { Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); - Point2D iconLoc = nativeGetIconLocation(getModel()); + AtomicReference ref = new AtomicReference<>(); + execute(ptr -> { + ref.set(nativeGetIconLocation(ptr)); + }); + Point2D iconLoc = ref.get(); + if (iconLoc == null) { + return; + } int dialogY = (int)iconLoc.getY(); int dialogX = (int)iconLoc.getX(); diff --git a/src/macosx/classes/sun/lwawt/macosx/CViewPlatformEmbeddedFrame.java b/src/macosx/classes/sun/lwawt/macosx/CViewPlatformEmbeddedFrame.java index 6c194c75b..b1a807a64 100644 --- a/src/macosx/classes/sun/lwawt/macosx/CViewPlatformEmbeddedFrame.java +++ b/src/macosx/classes/sun/lwawt/macosx/CViewPlatformEmbeddedFrame.java @@ -74,13 +74,13 @@ public class CViewPlatformEmbeddedFrame implements PlatformWindow { @Override public void dispose() { - CWrapper.NSView.removeFromSuperview(view.getAWTView()); + view.execute(CWrapper.NSView::removeFromSuperview); view.dispose(); } @Override public void setVisible(boolean visible) { - CWrapper.NSView.setHidden(view.getAWTView(), !visible); + view.execute(ptr -> CWrapper.NSView.setHidden(ptr, !visible)); } @Override diff --git a/src/macosx/classes/sun/lwawt/macosx/CWarningWindow.java b/src/macosx/classes/sun/lwawt/macosx/CWarningWindow.java index 5962b7f0c..64f9e4ee7 100644 --- a/src/macosx/classes/sun/lwawt/macosx/CWarningWindow.java +++ b/src/macosx/classes/sun/lwawt/macosx/CWarningWindow.java @@ -219,14 +219,14 @@ public final class CWarningWindow extends CPlatformWindow @Override public void setVisible(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(ptr -> { + // Actually show or hide the window + if (visible) { + CWrapper.NSWindow.orderFront(ptr); + } else { + CWrapper.NSWindow.orderOut(ptr); + } + }); this.visible = visible; @@ -234,8 +234,13 @@ public final class CWarningWindow extends CPlatformWindow if (visible) { // Order myself above my parent if (owner != null && owner.isVisible()) { - CWrapper.NSWindow.orderWindow(nsWindowPtr, - CWrapper.NSWindow.NSWindowAbove, owner.getNSWindowPtr()); + owner.execute(ownerPtr -> { + execute(ptr -> { + CWrapper.NSWindow.orderWindow(ptr, + CWrapper.NSWindow.NSWindowAbove, + ownerPtr); + }); + }); // do not allow security warning to be obscured by other windows applyWindowLevel(ownerWindow); diff --git a/src/macosx/native/sun/awt/AWTSurfaceLayers.h b/src/macosx/native/sun/awt/AWTSurfaceLayers.h index 5045be3a5..79eacd11f 100644 --- a/src/macosx/native/sun/awt/AWTSurfaceLayers.h +++ b/src/macosx/native/sun/awt/AWTSurfaceLayers.h @@ -41,6 +41,8 @@ CALayer *windowLayer; } +@property (retain) CALayer *windowLayer; + - (id) initWithWindowLayer: (CALayer *)windowLayer; - (void) setBounds: (CGRect)rect; diff --git a/src/macosx/native/sun/awt/AWTSurfaceLayers.m b/src/macosx/native/sun/awt/AWTSurfaceLayers.m index 8b0d576aa..c03ff90a3 100644 --- a/src/macosx/native/sun/awt/AWTSurfaceLayers.m +++ b/src/macosx/native/sun/awt/AWTSurfaceLayers.m @@ -38,11 +38,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; -- GitLab