changeset 60275:19adbbca4307

8221823: Requested JDialog width is ignored Reviewed-by: aivanov
author serb
date Thu, 13 Feb 2020 13:19:55 -0800
parents 314f940aaf82
children bdcad73943d5
files src/java.desktop/windows/classes/sun/awt/windows/WDialogPeer.java src/java.desktop/windows/classes/sun/awt/windows/WFramePeer.java src/java.desktop/windows/classes/sun/awt/windows/WWindowPeer.java src/java.desktop/windows/native/libawt/windows/awt_Window.cpp test/jdk/ProblemList.txt test/jdk/java/awt/Mixing/AWT_Mixing/HierarchyBoundsListenerMixingTest.java test/jdk/java/awt/Mixing/AWT_Mixing/MixingFrameResizing.java test/jdk/java/awt/Mixing/AWT_Mixing/MixingPanelsResizing.java test/jdk/java/awt/Window/MinimumSizeDPIVariation/MinimumSizeDPIVariation.java
diffstat 9 files changed, 165 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.desktop/windows/classes/sun/awt/windows/WDialogPeer.java	Thu Feb 13 13:17:16 2020 -0800
+++ b/src/java.desktop/windows/classes/sun/awt/windows/WDialogPeer.java	Thu Feb 13 13:19:55 2020 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2020, 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
@@ -22,13 +22,19 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+
 package sun.awt.windows;
 
-import java.awt.*;
-import java.awt.peer.*;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dialog;
+import java.awt.Dimension;
+import java.awt.SystemColor;
+import java.awt.Window;
+import java.awt.peer.DialogPeer;
 
-import sun.awt.*;
-import sun.awt.im.*;
+import sun.awt.AWTAccessor;
+import sun.awt.im.InputMethodManager;
 
 final class WDialogPeer extends WWindowPeer implements DialogPeer {
     // Toolkit & peer internals
@@ -110,9 +116,9 @@
     public Dimension getMinimumSize() {
         if (((Dialog)target).isUndecorated()) {
             return super.getMinimumSize();
-        } else {
-            return new Dimension(getSysMinWidth(), getSysMinHeight());
         }
+        return new Dimension(scaleDownX(getSysMinWidth()),
+                             scaleDownY(getSysMinHeight()));
     }
 
     @Override
--- a/src/java.desktop/windows/classes/sun/awt/windows/WFramePeer.java	Thu Feb 13 13:17:16 2020 -0800
+++ b/src/java.desktop/windows/classes/sun/awt/windows/WFramePeer.java	Thu Feb 13 13:19:55 2020 -0800
@@ -147,13 +147,14 @@
     }
 
     @Override
-    public Dimension getMinimumSize() {
+    public final Dimension getMinimumSize() {
         Dimension d = new Dimension();
         if (!((Frame)target).isUndecorated()) {
-            d.setSize(getSysMinWidth(), getSysMinHeight());
+            d.setSize(scaleDownX(getSysMinWidth()),
+                      scaleDownY(getSysMinHeight()));
         }
         if (((Frame)target).getMenuBar() != null) {
-            d.height += getSysMenuHeight();
+            d.height += scaleDownY(getSysMenuHeight());
         }
         return d;
     }
--- a/src/java.desktop/windows/classes/sun/awt/windows/WWindowPeer.java	Thu Feb 13 13:17:16 2020 -0800
+++ b/src/java.desktop/windows/classes/sun/awt/windows/WWindowPeer.java	Thu Feb 13 13:19:55 2020 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2020, 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
@@ -402,10 +402,8 @@
             minimumSize = ((Component)target).getMinimumSize();
         }
         if (minimumSize != null) {
-            int msw = getSysMinWidth();
-            int msh = getSysMinHeight();
-            int w = (minimumSize.width >= msw) ? minimumSize.width : msw;
-            int h = (minimumSize.height >= msh) ? minimumSize.height : msh;
+            int w = Math.max(minimumSize.width, scaleDownX(getSysMinWidth()));
+            int h = Math.max(minimumSize.height, scaleDownY(getSysMinHeight()));
             setMinSize(w, h);
         } else {
             setMinSize(0, 0);
@@ -687,6 +685,22 @@
         }
     }
 
+    final int scaleUpX(int x) {
+        return Region.clipRound(x * scaleX);
+    }
+
+    final int scaleUpY(int y) {
+        return Region.clipRound(y * scaleY);
+    }
+
+    final int scaleDownX(int x) {
+        return Region.clipRound(x / scaleX);
+    }
+
+    final int scaleDownY(int y) {
+        return Region.clipRound(y / scaleY);
+    }
+
     @Override
     public void print(Graphics g) {
         // We assume we print the whole frame,
--- a/src/java.desktop/windows/native/libawt/windows/awt_Window.cpp	Thu Feb 13 13:17:16 2020 -0800
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Window.cpp	Thu Feb 13 13:19:55 2020 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2020, 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
@@ -2534,8 +2534,8 @@
             if (!p->IsEmbeddedFrame())
             {
                 jobject peer = p->GetPeer(env);
-                int minWidth = ::GetSystemMetrics(SM_CXMIN);
-                int minHeight = ::GetSystemMetrics(SM_CYMIN);
+                int minWidth = p->ScaleDownX(::GetSystemMetrics(SM_CXMIN));
+                int minHeight = p->ScaleDownY(::GetSystemMetrics(SM_CYMIN));
                 if (w < minWidth)
                 {
                     env->SetIntField(target, AwtComponent::widthID,
@@ -3826,7 +3826,7 @@
     os->iOpacity = iOpacity;
 
     AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetOpacity, os);
-    // global refs and mds are deleted in _SetMinSize
+    // global refs and mds are deleted in _SetOpacity
 
     CATCH_BAD_ALLOC;
 }
@@ -3847,7 +3847,7 @@
     os->isOpaque = isOpaque;
 
     AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetOpaque, os);
-    // global refs and mds are deleted in _SetMinSize
+    // global refs and mds are deleted in _SetOpaque
 
     CATCH_BAD_ALLOC;
 }
--- a/test/jdk/ProblemList.txt	Thu Feb 13 13:17:16 2020 -0800
+++ b/test/jdk/ProblemList.txt	Thu Feb 13 13:19:55 2020 -0800
@@ -551,8 +551,6 @@
 java/awt/Choice/ChoiceKeyEventReaction/ChoiceKeyEventReaction.java 7185258 macosx-all
 java/awt/TrayIcon/RightClickWhenBalloonDisplayed/RightClickWhenBalloonDisplayed.java 8238720 windows-all
 java/awt/PopupMenu/PopupMenuLocation.java 8238720 windows-all
-java/awt/Mixing/AWT_Mixing/MixingFrameResizing.java 8238720 windows-all
-java/awt/Mixing/AWT_Mixing/HierarchyBoundsListenerMixingTest.java 8238720 windows-all
 java/awt/GridLayout/ComponentPreferredSize/ComponentPreferredSize.java 8238720 windows-all
 java/awt/GridLayout/ChangeGridSize/ChangeGridSize.java   8238720 windows-all
 java/awt/event/MouseEvent/FrameMouseEventAbsoluteCoordsTest/FrameMouseEventAbsoluteCoordsTest.java
--- a/test/jdk/java/awt/Mixing/AWT_Mixing/HierarchyBoundsListenerMixingTest.java	Thu Feb 13 13:17:16 2020 -0800
+++ b/test/jdk/java/awt/Mixing/AWT_Mixing/HierarchyBoundsListenerMixingTest.java	Thu Feb 13 13:19:55 2020 -0800
@@ -35,7 +35,7 @@
 /*
  * @test
  * @key headful
- * @bug 6768230
+ * @bug 6768230 8221823
  * @summary Mixing test for HierarchyBoundsListener ancestors
  * @build FrameBorderCounter
  * @run main HierarchyBoundsListenerMixingTest
--- a/test/jdk/java/awt/Mixing/AWT_Mixing/MixingFrameResizing.java	Thu Feb 13 13:17:16 2020 -0800
+++ b/test/jdk/java/awt/Mixing/AWT_Mixing/MixingFrameResizing.java	Thu Feb 13 13:19:55 2020 -0800
@@ -39,7 +39,7 @@
 /*
  * @test
  * @key headful
- * @bug 6777370
+ * @bug 6777370 8221823
  * @summary Issues when resizing the JFrame with HW components
  * @author sergey.grinev@oracle.com: area=awt.mixing
  * @library /java/awt/patchlib  ../../regtesthelpers
--- a/test/jdk/java/awt/Mixing/AWT_Mixing/MixingPanelsResizing.java	Thu Feb 13 13:17:16 2020 -0800
+++ b/test/jdk/java/awt/Mixing/AWT_Mixing/MixingPanelsResizing.java	Thu Feb 13 13:19:55 2020 -0800
@@ -35,7 +35,7 @@
 /*
  * @test
  * @key headful
- * @bug 6786219
+ * @bug 6786219 8221823
  * @summary Issues when resizing the frame after mixing of heavy weight & light weight components
  * @author sergey.grinev@oracle.com: area=awt.mixing
  * @library ../../regtesthelpers
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/Window/MinimumSizeDPIVariation/MinimumSizeDPIVariation.java	Thu Feb 13 13:19:55 2020 -0800
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2020, 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.Dialog;
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.awt.Window;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import jdk.test.lib.Platform;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+/**
+ * @test
+ * @bug 8221823
+ * @key headful
+ * @summary Verifies TOP level component's minimumSize using different DPI
+ * @library /test/lib
+ * @run main/othervm -Dsun.java2d.uiScale=1 MinimumSizeDPIVariation
+ */
+public final class MinimumSizeDPIVariation {
+
+    public static void main(String[] args) throws Exception {
+        if (args.length == 0) {
+            Dimension minimumSize = test(new Frame());
+            checkAllDPI("frame", minimumSize.width, minimumSize.height);
+            minimumSize = test(new Window(null));
+            checkAllDPI("window", minimumSize.width, minimumSize.height);
+            minimumSize = test(new Dialog((Frame) null));
+            checkAllDPI("dialog", minimumSize.width, minimumSize.height);
+        } else {
+            String comp = args[0];
+            int w = Integer.parseInt(args[1]);
+            int h = Integer.parseInt(args[2]);
+            double scale = Double.parseDouble(args[3]);
+
+            System.err.println("comp = " + comp);
+            System.err.println("scale = " + scale);
+
+            Dimension minimumSize = switch (comp) {
+                case "frame" -> test(new Frame());
+                case "window" -> test(new Window(null));
+                case "dialog" -> test(new Dialog((Frame) null));
+                default -> throw new java.lang.IllegalStateException(
+                        "Unexpected value: " + comp);
+            };
+            check(minimumSize.width, Math.max(w / scale, 1));
+            check(minimumSize.height, Math.max(h / scale, 1));
+        }
+    }
+
+    private static Dimension test(Window window) {
+        try {
+            window.setLayout(null); // trigger use the minimum size of the peer
+            window.setSize(new Dimension(1, 1));
+            window.pack();
+            Dimension minimumSize = window.getMinimumSize();
+            Dimension size = window.getSize();
+            if (!minimumSize.equals(size)) {
+                System.err.println(window);
+                System.err.println("Expected: " + minimumSize);
+                System.err.println("Actual: " + size);
+                throw new RuntimeException("Wrong size");
+            }
+            return minimumSize;
+        } finally {
+            window.dispose();
+        }
+    }
+
+    private static void check(int actual, double expected) {
+        double i = 100 * (actual - expected) / expected;
+        if (Math.abs(i) > 10) { // no more than 10% variation
+            System.err.println("Expected: " + expected);
+            System.err.println("Actual: " + actual);
+            throw new RuntimeException("Difference is too big: " + i);
+        }
+    }
+
+    private static void checkAllDPI(String comp, int w, int h)
+            throws Exception {
+        if (!Platform.isOSX()) {
+            for (String dpi : List.of("1.5", "1.75", "2", "2.5")) {
+                runPocess(dpi, comp, w, h);
+            }
+        }
+    }
+
+    private static void runPocess(String dpi, String comp, int w, int h)
+            throws Exception {
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+                "-Dsun.java2d.uiScale=" + dpi,
+                MinimumSizeDPIVariation.class.getSimpleName(), comp,
+                String.valueOf(w), String.valueOf(h), dpi);
+        Process worker = ProcessTools.startProcess("Worker", pb, null, 20,
+                TimeUnit.SECONDS);
+        new OutputAnalyzer(worker).shouldHaveExitValue(0);
+    }
+}