From 651ac3cc0f2a8b3edf5cddb42df1d38d4aa0e1a6 Mon Sep 17 00:00:00 2001 From: anass baya Date: Fri, 31 Jan 2025 18:30:01 +0000 Subject: [PATCH] 6899304: java.awt.Toolkit.getScreenInsets(GraphicsConfiguration) returns incorrect values Reviewed-by: aivanov, honkar, prr, serb --- .../native/libawt/windows/awt_Toolkit.cpp | 29 +++------ .../MultiScreenInsetsTest.java | 60 +++++++++++++------ 2 files changed, 50 insertions(+), 39 deletions(-) diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp index 8dc908d0f90..b447ad6889a 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp @@ -1929,28 +1929,13 @@ JNIEnv* AwtToolkit::GetEnv() { BOOL AwtToolkit::GetScreenInsets(int screenNum, RECT * rect) { - /* if primary display */ - if (screenNum == 0) { - RECT rRW; - if (::SystemParametersInfo(SPI_GETWORKAREA,0,(void *) &rRW,0) == TRUE) { - rect->top = rRW.top; - rect->left = rRW.left; - rect->bottom = ::GetSystemMetrics(SM_CYSCREEN) - rRW.bottom; - rect->right = ::GetSystemMetrics(SM_CXSCREEN) - rRW.right; - return TRUE; - } - } - /* if additional display */ - else { - MONITORINFO *miInfo; - miInfo = AwtWin32GraphicsDevice::GetMonitorInfo(screenNum); - if (miInfo) { - rect->top = miInfo->rcWork.top - miInfo->rcMonitor.top; - rect->left = miInfo->rcWork.left - miInfo->rcMonitor.left; - rect->bottom = miInfo->rcMonitor.bottom - miInfo->rcWork.bottom; - rect->right = miInfo->rcMonitor.right - miInfo->rcWork.right; - return TRUE; - } + MONITORINFO *miInfo = AwtWin32GraphicsDevice::GetMonitorInfo(screenNum); + if (miInfo) { + rect->top = miInfo->rcWork.top - miInfo->rcMonitor.top; + rect->left = miInfo->rcWork.left - miInfo->rcMonitor.left; + rect->bottom = miInfo->rcMonitor.bottom - miInfo->rcWork.bottom; + rect->right = miInfo->rcMonitor.right - miInfo->rcWork.right; + return TRUE; } return FALSE; } diff --git a/test/jdk/java/awt/Multiscreen/MultiScreenInsetsTest/MultiScreenInsetsTest.java b/test/jdk/java/awt/Multiscreen/MultiScreenInsetsTest/MultiScreenInsetsTest.java index 610c21a1f6a..301d4f2caa3 100644 --- a/test/jdk/java/awt/Multiscreen/MultiScreenInsetsTest/MultiScreenInsetsTest.java +++ b/test/jdk/java/awt/Multiscreen/MultiScreenInsetsTest/MultiScreenInsetsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, 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 @@ -24,12 +24,11 @@ /* @test @key headful - @bug 8020443 - @summary Frame is not created on the specified GraphicsDevice with two -monitors - @author Oleg Pekhovskiy + @bug 8020443 6899304 + @summary Test to check if the frame is created on the specified GraphicsDevice + and if getScreenInsets()returns the correct values across multiple monitors. @library /test/lib - @build jdk.test.lib.Platform + @build jdk.test.lib.Platform jtreg.SkippedException @run main MultiScreenInsetsTest */ @@ -42,22 +41,18 @@ import java.awt.Rectangle; import java.awt.Toolkit; import jdk.test.lib.Platform; +import jtreg.SkippedException; public class MultiScreenInsetsTest { private static final int SIZE = 100; + // Allow a margin tolerance of 1 pixel due to scaling + private static final int MARGIN_TOLERANCE = 1; public static void main(String[] args) throws InterruptedException { - if (!Platform.isLinux()) { - System.out.println("This test is for Linux only..." + - "skipping!"); - return; - } - GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice[] gds = ge.getScreenDevices(); if (gds.length < 2) { - System.out.println("It's a multi-screen test... skipping!"); - return; + throw new SkippedException("It's a multi-screen test... skipping!"); } for (int screen = 0; screen < gds.length; ++screen) { @@ -65,12 +60,25 @@ public class MultiScreenInsetsTest { GraphicsConfiguration gc = gd.getDefaultConfiguration(); Rectangle bounds = gc.getBounds(); Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(gc); + System.out.println("Screen #" + screen); + System.out.println("Screen Bounds: " + bounds); + System.out.println("Insets: " + insets); Frame frame = new Frame(gc); frame.setLocation(bounds.x + (bounds.width - SIZE) / 2, bounds.y + (bounds.height - SIZE) / 2); frame.setSize(SIZE, SIZE); - frame.setUndecorated(true); + + /* + * On Windows, undecorated maximized frames are placed over the taskbar. + * Use a decorated frame instead. + */ + if (Platform.isWindows()) { + frame.setUndecorated(false); + } else { + frame.setUndecorated(true); + } + frame.setVisible(true); // Maximize Frame to reach the struts @@ -78,11 +86,29 @@ public class MultiScreenInsetsTest { Thread.sleep(2000); Rectangle frameBounds = frame.getBounds(); + System.out.println("Frame bounds: " + frameBounds); + frame.dispose(); + + /* + * On Windows, the top-left corner of an undecorated maximized frame + * may have negative coordinates (x, y). + * Adjust the frame bounds accordingly. + */ + if (frameBounds.x < bounds.x) { + frameBounds.width -= (bounds.x - frameBounds.x) * 2; + frameBounds.x = bounds.x; + } + if (frameBounds.y < bounds.y) { + frameBounds.height -= (bounds.y - frameBounds.y) * 2; + frameBounds.y = bounds.y; + } + System.out.println("Adjusted Frame bounds: " + frameBounds); + if (bounds.x + insets.left != frameBounds.x || bounds.y + insets.top != frameBounds.y - || bounds.width - insets.right - insets.left != frameBounds.width - || bounds.height - insets.bottom - insets.top != frameBounds.height) { + || Math.abs((bounds.width - insets.right - insets.left) - frameBounds.width) > MARGIN_TOLERANCE + || Math.abs((bounds.height - insets.bottom - insets.top) - frameBounds.height) > MARGIN_TOLERANCE) { throw new RuntimeException("Test FAILED! Wrong screen #" + screen + " insets: " + insets); }