aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java9
-rw-r--r--src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m34
-rw-r--r--test/jdk/java/awt/Window/WindowAppearanceTest/WindowAppearanceTest.java151
3 files changed, 188 insertions, 6 deletions
diff --git a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java
index 820e1f846e3..182f78f5a49 100644
--- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java
+++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java
@@ -75,6 +75,7 @@ import sun.util.logging.PlatformLogger;
public class CPlatformWindow extends CFRetainedResource implements PlatformWindow {
private native long nativeCreateNSWindow(long nsViewPtr,long ownerPtr, long styleBits, double x, double y, double w, double h);
private static native void nativeSetNSWindowStyleBits(long nsWindowPtr, int mask, int data);
+ private static native void nativeSetNSWindowAppearance(long nsWindowPtr, String appearanceName);
private static native void nativeSetNSWindowMenuBar(long nsWindowPtr, long menuBarPtr);
private static native Insets nativeGetNSWindowInsets(long nsWindowPtr);
private static native void nativeSetNSWindowBounds(long nsWindowPtr, double x, double y, double w, double h);
@@ -126,6 +127,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
public static final String WINDOW_FULL_CONTENT = "apple.awt.fullWindowContent";
public static final String WINDOW_TRANSPARENT_TITLE_BAR = "apple.awt.transparentTitleBar";
public static final String WINDOW_TITLE_VISIBLE = "apple.awt.windowTitleVisible";
+ public static final String WINDOW_APPEARANCE = "apple.awt.windowAppearance";
// Yeah, I know. But it's easier to deal with ints from JNI
static final int MODELESS = 0;
@@ -258,6 +260,13 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
public void applyProperty(final CPlatformWindow c, final Object value) {
c.setStyleBits(TITLE_VISIBLE, value == null ? true : Boolean.parseBoolean(value.toString()));
}
+ },
+ new Property<CPlatformWindow>(WINDOW_APPEARANCE) {
+ public void applyProperty(final CPlatformWindow c, final Object value) {
+ if (value != null && (value instanceof String)) {
+ c.execute(ptr -> nativeSetNSWindowAppearance(ptr, (String) value));
+ }
+ }
}
}) {
@SuppressWarnings("deprecation")
diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m
index 5d462a86e4e..4ce22588c8d 100644
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m
@@ -1109,12 +1109,6 @@ JNI_COCOA_ENTER(env);
NSString *uiStyle = [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"];
- if ([@"Dark" isEqualToString: uiStyle]) {
- [nsWindow setAppearance:[NSAppearance appearanceNamed:NSAppearanceNameVibrantDark]];
- } else {
- [nsWindow setAppearance:[NSAppearance appearanceNamed:NSAppearanceNameVibrantLight]];
- }
-
if (resized) {
[window _deliverMoveResizeEvent];
}
@@ -1125,6 +1119,34 @@ JNI_COCOA_EXIT(env);
/*
* Class: sun_lwawt_macosx_CPlatformWindow
+ * Method: nativeSetNSWindowStyleBits
+ * Signature: (JII)V
+ */
+JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowAppearance
+ (JNIEnv *env, jclass clazz, jlong windowPtr, jstring appearanceName)
+{
+ JNI_COCOA_ENTER(env);
+
+ NSWindow *nsWindow = OBJC(windowPtr);
+ // create a global-ref around the appearanceName, so it can be safely passed to Main thread
+ jobject appearanceNameRef= (*env)->NewGlobalRef(env, appearanceName);
+
+ [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
+ // attach the dispatch thread to the JVM if necessary, and get an env
+ JNIEnv* blockEnv = [ThreadUtilities getJNIEnvUncached];
+ NSAppearance* appearance = [NSAppearance appearanceNamed:
+ JavaStringToNSString(env, appearanceNameRef)];
+ if (appearance != NULL) {
+ [nsWindow setAppearance:appearance];
+ }
+ (*blockEnv)->DeleteGlobalRef(blockEnv, appearanceNameRef);
+ }];
+
+ JNI_COCOA_EXIT(env);
+}
+
+/*
+ * Class: sun_lwawt_macosx_CPlatformWindow
* Method: nativeSetNSWindowMenuBar
* Signature: (JJ)V
*/
diff --git a/test/jdk/java/awt/Window/WindowAppearanceTest/WindowAppearanceTest.java b/test/jdk/java/awt/Window/WindowAppearanceTest/WindowAppearanceTest.java
new file mode 100644
index 00000000000..fcdf337754b
--- /dev/null
+++ b/test/jdk/java/awt/Window/WindowAppearanceTest/WindowAppearanceTest.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, JetBrains s.r.o.. 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @key headful
+ * @bug 8265445
+ * @summary [macosx] window appearance test
+ * @author Alexey Ushakov
+ * @run main WindowAppearanceTest
+ * @requires (os.family == "mac")
+ */
+
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.lang.reflect.InvocationTargetException;
+import javax.swing.*;
+
+public class WindowAppearanceTest
+{
+ private static final int TD = 10;
+ private static final Color darkSystemGray4 = new Color(58, 58, 60);
+ private static final Color lightSystemGray6 = new Color(242, 242, 247);
+ static WindowAppearanceTest theTest;
+ private Robot robot;
+ private JFrame frame;
+ private JRootPane rootPane;
+
+ private int DELAY = 1000;
+
+ public WindowAppearanceTest() {
+ try {
+ robot = new Robot();
+ } catch (AWTException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ public void performTest() {
+
+ runSwing(() -> {
+ frame = new JFrame("");
+ frame.setBounds(100, 100, 300, 150);
+ rootPane = frame.getRootPane();
+ JComponent contentPane = (JComponent) frame.getContentPane();
+ JPanel comp = new JPanel();
+ contentPane.add(comp);
+ comp.setBackground(Color.RED);
+ frame.setVisible(true);
+ });
+
+ robot.delay(DELAY);
+ runSwing(() -> rootPane.putClientProperty("apple.awt.windowTitleVisible", false));
+ runSwing(() -> rootPane.putClientProperty("apple.awt.windowAppearance", "NSAppearanceNameVibrantDark"));
+ robot.delay(DELAY);
+
+ validateColor(darkSystemGray4);
+
+ runSwing(() -> rootPane.putClientProperty("apple.awt.windowAppearance", "NSAppearanceNameVibrantLight"));
+ robot.delay(DELAY);
+
+ validateColor(lightSystemGray6);
+
+ runSwing(() -> frame.dispose());
+
+ frame = null;
+ rootPane = null;
+ }
+
+ private Color getTestPixel(int x, int y) {
+ Rectangle bounds = frame.getBounds();
+ BufferedImage screenImage = robot.createScreenCapture(bounds);
+ int rgb = screenImage.getRGB(x, y);
+ int red = (rgb >> 16) & 0xFF;
+ int green = (rgb >> 8) & 0xFF;
+ int blue = rgb & 0xFF;
+ Color c = new Color(red, green, blue);
+ return c;
+ }
+
+ private void validateColor(Color color) {
+ for (int px = 140; px < 160; px++) {
+ for (int py = 5; py < 20; py++) {
+ Color c = getTestPixel(px, py);
+ if (!validateColor(c, color)) {
+ throw new RuntimeException("Test failed. Incorrect color " + c +
+ "at (" + px + "," + py + ")");
+ }
+ }
+ }
+ }
+
+ private boolean validateColor(Color c, Color expected) {
+ return Math.abs(c.getRed() - expected.getRed()) <= TD &&
+ Math.abs(c.getGreen() - expected.getGreen()) <= TD &&
+ Math.abs(c.getBlue() - expected.getBlue()) <= TD;
+ }
+
+ public void dispose() {
+ if (frame != null) {
+ frame.dispose();
+ frame = null;
+ }
+ }
+
+ private static void runSwing(Runnable r) {
+ try {
+ SwingUtilities.invokeAndWait(r);
+ } catch (InterruptedException e) {
+ } catch (InvocationTargetException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static void main(String[] args) {
+ if (!System.getProperty("os.name").contains("OS X")) {
+ System.out.println("This test is for MacOS only. Automatically passed on other platforms.");
+ return;
+ }
+
+ try {
+ runSwing(() -> theTest = new WindowAppearanceTest());
+ theTest.performTest();
+ } finally {
+ if (theTest != null) {
+ runSwing(() -> theTest.dispose());
+ }
+ }
+ }
+}