8033786: White flashing when opening Dialogs and Menus using Nimbus with dark background
authorserb
Thu, 12 Jun 2014 00:43:14 +0400
changeset 25196 48d9cfe3f138
parent 25195 9de77f5b0df2
child 25197 533f45be322f
8033786: White flashing when opening Dialogs and Menus using Nimbus with dark background Reviewed-by: alexsch, anthony
jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java
jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java
jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java
jdk/src/macosx/classes/sun/lwawt/macosx/CWrapper.java
jdk/src/macosx/native/sun/awt/CWrapper.m
jdk/src/share/classes/javax/swing/JDialog.java
jdk/test/javax/swing/JDialog/WrongBackgroundColor/WrongBackgroundColor.java
--- a/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java	Thu Jun 12 00:32:33 2014 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java	Thu Jun 12 00:43:14 2014 +0400
@@ -317,6 +317,8 @@
      * subclasses to initialize specific peers properties.
      */
     void initializeImpl() {
+        // note that these methods can be overridden by the user and
+        // can return some strange values like null.
         setBackground(target.getBackground());
         setForeground(target.getForeground());
         setFont(target.getFont());
--- a/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java	Thu Jun 12 00:32:33 2014 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java	Thu Jun 12 00:43:14 2014 +0400
@@ -444,6 +444,12 @@
     }
 
     @Override
+    public void setBackground(final Color c) {
+        super.setBackground(c);
+        updateOpaque();
+    }
+
+    @Override
     public void setOpacity(float opacity) {
         getPlatformWindow().setOpacity(opacity);
         repaintPeer();
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Thu Jun 12 00:32:33 2014 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Thu Jun 12 00:43:14 2014 +0400
@@ -746,20 +746,22 @@
     @Override
     public void setOpaque(boolean isOpaque) {
         CWrapper.NSWindow.setOpaque(getNSWindowPtr(), isOpaque);
-        boolean isTextured = (peer == null)? false : peer.isTextured();
-        if (!isOpaque && !isTextured) {
-            long clearColor = CWrapper.NSColor.clearColor();
-            CWrapper.NSWindow.setBackgroundColor(getNSWindowPtr(), clearColor);
+        boolean isTextured = (peer == null) ? false : peer.isTextured();
+        if (!isTextured) {
+            if (!isOpaque) {
+                CWrapper.NSWindow.setBackgroundColor(getNSWindowPtr(), 0);
+            } else if (peer != null) {
+                Color color = peer.getBackground();
+                if (color != null) {
+                    int rgb = color.getRGB();
+                    CWrapper.NSWindow.setBackgroundColor(getNSWindowPtr(), rgb);
+                }
+            }
         }
 
         //This is a temporary workaround. Looks like after 7124236 will be fixed
         //the correct place for invalidateShadow() is CGLayer.drawInCGLContext.
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                invalidateShadow();
-            }
-        });
+        SwingUtilities.invokeLater(this::invalidateShadow);
     }
 
     @Override
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CWrapper.java	Thu Jun 12 00:32:33 2014 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CWrapper.java	Thu Jun 12 00:43:14 2014 +0400
@@ -61,7 +61,14 @@
 
         static native void setAlphaValue(long window, float alpha);
         static native void setOpaque(long window, boolean opaque);
-        static native void setBackgroundColor(long window, long color);
+
+        /**
+         * Sets background color of the NSWindow.
+         *
+         * @param window the pointer of the NSWindow
+         * @param color the color in argb format
+         */
+        static native void setBackgroundColor(long window, int color);
 
         static native void miniaturize(long window);
         static native void deminiaturize(long window);
@@ -82,8 +89,4 @@
 
         static native void setToolTip(long view, String msg);
     }
-
-    static final class NSColor {
-        static native long clearColor();
-    }
 }
--- a/jdk/src/macosx/native/sun/awt/CWrapper.m	Thu Jun 12 00:32:33 2014 +0400
+++ b/jdk/src/macosx/native/sun/awt/CWrapper.m	Thu Jun 12 00:43:14 2014 +0400
@@ -337,12 +337,17 @@
  */
 JNIEXPORT void JNICALL
 Java_sun_lwawt_macosx_CWrapper_00024NSWindow_setBackgroundColor
-(JNIEnv *env, jclass cls, jlong windowPtr, jlong colorPtr)
+(JNIEnv *env, jclass cls, jlong windowPtr, jint rgb)
 {
 JNF_COCOA_ENTER(env);
 
     NSWindow *window = (NSWindow *)jlong_to_ptr(windowPtr);
-    NSColor *color = (NSColor *)jlong_to_ptr(colorPtr);
+    CGFloat alpha = (((rgb >> 24) & 0xff) / 255.0);
+    CGFloat red   = (((rgb >> 16) & 0xff) / 255.0);
+    CGFloat green = (((rgb >>  8) & 0xff) / 255.0);
+    CGFloat blue  = (((rgb >>  0) & 0xff) / 255.0);
+    NSColor *color = [NSColor colorWithCalibratedRed:red green:green blue:blue
+                                               alpha:alpha];
     [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
         [window setBackgroundColor:color];
     }];
@@ -575,26 +580,3 @@
 
 JNF_COCOA_EXIT(env);
 }
-
-/*
- * Class:     sun_lwawt_macosx_CWrapper$NSColor
- * Method:    clearColor
- * Signature: ()J
- */
-JNIEXPORT jlong JNICALL
-Java_sun_lwawt_macosx_CWrapper_00024NSColor_clearColor
-(JNIEnv *env, jclass cls)
-{
-    __block jlong clearColorPtr = 0L;
-
-JNF_COCOA_ENTER(env);
-
-    [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
-        clearColorPtr = ptr_to_jlong([NSColor clearColor]);
-    }];
-
-JNF_COCOA_EXIT(env);
-
-    return clearColorPtr;
-}
-
--- a/jdk/src/share/classes/javax/swing/JDialog.java	Thu Jun 12 00:32:33 2014 +0400
+++ b/jdk/src/share/classes/javax/swing/JDialog.java	Thu Jun 12 00:43:14 2014 +0400
@@ -647,6 +647,7 @@
         enableEvents(AWTEvent.KEY_EVENT_MASK | AWTEvent.WINDOW_EVENT_MASK);
         setLocale( JComponent.getDefaultLocale() );
         setRootPane(createRootPane());
+        setBackground(UIManager.getColor("control"));
         setRootPaneCheckingEnabled(true);
         if (JDialog.isDefaultLookAndFeelDecorated()) {
             boolean supportsWindowDecorations =
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JDialog/WrongBackgroundColor/WrongBackgroundColor.java	Thu Jun 12 00:43:14 2014 +0400
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2014, 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
+ * 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.
+ */
+
+import java.awt.Color;
+import java.lang.reflect.InvocationTargetException;
+
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.SwingUtilities;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import javax.swing.plaf.ColorUIResource;
+
+/**
+ * @test
+ * @bug 8033786
+ * @summary JDialog should update background color of the native peer.
+ * @author Sergey Bylokhov
+ */
+public final class WrongBackgroundColor {
+
+    public static void main(final String[] args)
+            throws InvocationTargetException, InterruptedException {
+        SwingUtilities.invokeAndWait(() -> {
+            UIDefaults ui = UIManager.getDefaults();
+            ui.put("control", new ColorUIResource(54, 54, 54));
+            final JDialog dialog = new JDialog();
+            final JFrame frame = new JFrame();
+            frame.pack();
+            dialog.pack();
+            final Color dialogBackground = dialog.getBackground();
+            final Color frameBackground = frame.getBackground();
+            frame.dispose();
+            dialog.dispose();
+            if (!dialogBackground.equals(frameBackground)) {
+                System.err.println("Expected:" + frameBackground);
+                System.err.println("Actual:" + dialogBackground);
+                throw new RuntimeException("Wrong background color");
+            }
+        });
+    }
+}