diff --git a/src/java.desktop/macosx/classes/com/apple/eawt/_AppEventHandler.java b/src/java.desktop/macosx/classes/com/apple/eawt/_AppEventHandler.java index d75138bb9f81..494c6abfbdfd 100644 --- a/src/java.desktop/macosx/classes/com/apple/eawt/_AppEventHandler.java +++ b/src/java.desktop/macosx/classes/com/apple/eawt/_AppEventHandler.java @@ -27,6 +27,7 @@ package com.apple.eawt; import java.awt.EventQueue; import java.awt.Frame; +import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.desktop.AboutEvent; import java.awt.desktop.AboutHandler; @@ -65,8 +66,8 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import sun.awt.AppContext; +import sun.awt.CGraphicsDevice; import sun.awt.SunToolkit; -import sun.java2d.SunGraphicsEnvironment; import sun.util.logging.PlatformLogger; final class _AppEventHandler { @@ -275,9 +276,14 @@ final class _AppEventHandler { logger.fine("NOTIFY_SCREEN_CHANGE_PARAMETERS"); } if (AppContext.getAppContext() != null) { - EventQueue.invokeLater( - () -> ((SunGraphicsEnvironment) GraphicsEnvironment. - getLocalGraphicsEnvironment()).displayParametersChanged()); + CGraphicsDevice.DisplayConfiguration displayConfiguration = CGraphicsDevice.DisplayConfiguration.get(); + EventQueue.invokeLater(() -> { + for (GraphicsDevice gd : GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()) { + if (gd instanceof CGraphicsDevice) { + ((CGraphicsDevice) gd).updateDisplayParameters(displayConfiguration); + } + } + }); } break; default: diff --git a/src/java.desktop/macosx/classes/sun/awt/CGraphicsDevice.java b/src/java.desktop/macosx/classes/sun/awt/CGraphicsDevice.java index 3a68566e452d..ea510f698fdf 100644 --- a/src/java.desktop/macosx/classes/sun/awt/CGraphicsDevice.java +++ b/src/java.desktop/macosx/classes/sun/awt/CGraphicsDevice.java @@ -34,18 +34,21 @@ import java.awt.Window; import java.awt.geom.Rectangle2D; import java.awt.peer.WindowPeer; import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; import java.util.Objects; import sun.java2d.SunGraphicsEnvironment; import sun.java2d.MacOSFlags; import sun.java2d.metal.MTLGraphicsConfig; import sun.java2d.opengl.CGLGraphicsConfig; +import sun.lwawt.macosx.CThreading; import sun.util.logging.PlatformLogger; import static java.awt.peer.ComponentPeer.SET_BOUNDS; public final class CGraphicsDevice extends GraphicsDevice - implements DisplayChangedListener, DisplayParametersChangedListener { + implements DisplayChangedListener { private static final PlatformLogger logger = PlatformLogger.getLogger(CGraphicsDevice.class.getName()); /** @@ -192,20 +195,33 @@ public final class CGraphicsDevice extends GraphicsDevice return s == scale && xr == xResolution && yr == yResolution && m == isMirroring && b.equals(bounds); } - public void displayParametersChanged() { - Insets newScreenInsets = nativeGetScreenInsets(displayID); - if (!newScreenInsets.equals(screenInsets)) { + public void updateDisplayParameters(DisplayConfiguration config) { + Descriptor desc = config.getDescriptor(displayID); + if (desc == null) return; + if (!desc.screenInsets.equals(screenInsets)) { if (logger.isLoggable(PlatformLogger.Level.FINE)) { logger.fine("Screen insets for display(" + displayID + ") changed " + "[top=" + screenInsets.top + ",left=" + screenInsets.left + ",bottom=" + screenInsets.bottom + ",right=" + screenInsets.right + - "]->[top=" + newScreenInsets.top + ",left=" + newScreenInsets.left + - ",bottom=" + newScreenInsets.bottom + ",right=" + newScreenInsets.right + + "]->[top=" + desc.screenInsets.top + ",left=" + desc.screenInsets.left + + ",bottom=" + desc.screenInsets.bottom + ",right=" + desc.screenInsets.right + "]"); } - screenInsets = newScreenInsets; + screenInsets = desc.screenInsets; + } + int newScale = 1; + if (SunGraphicsEnvironment.isUIScaleEnabled()) { + double debugScale = SunGraphicsEnvironment.getDebugScale(); + newScale = (int) (debugScale >= 1 ? Math.round(debugScale) : (int) desc.scale); + } + if (newScale != scale) { + if (logger.isLoggable(PlatformLogger.Level.FINE)) { + logger.fine("Scale for display(" + displayID + ") changed " + scale + "->" + newScale); + } + scale = newScale; } } + @Override public void paletteChanged() { // devices do not need to react to this event. @@ -386,4 +402,36 @@ public final class CGraphicsDevice extends GraphicsDevice private static native Insets nativeGetScreenInsets(int displayID); private static native Rectangle2D nativeGetBounds(int displayID); + + private static native void nativeGetDisplayConfiguration(DisplayConfiguration config); + + public static final class DisplayConfiguration { + private final Map map = new HashMap<>(); + private void addDescriptor(int displayID, int top, int left, int bottom, int right, double scale) { + map.put(displayID, new Descriptor(new Insets(top, left, bottom, right), scale)); + } + public Descriptor getDescriptor(int displayID) { + return map.get(displayID); + } + public static DisplayConfiguration get() { + try { + return CThreading.executeOnAppKit(() -> { + DisplayConfiguration config = new DisplayConfiguration(); + nativeGetDisplayConfiguration(config); + return config; + }); + } catch (Throwable e) { + throw new RuntimeException(e); + } + } + } + + private static final class Descriptor { + private final Insets screenInsets; + private final double scale; + private Descriptor(Insets screenInsets, double scale) { + this.screenInsets = screenInsets; + this.scale = scale; + } + } } diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/CGraphicsDevice.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/CGraphicsDevice.m index 0f82c6c442e5..18151bda800a 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/CGraphicsDevice.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/CGraphicsDevice.m @@ -585,3 +585,43 @@ JNI_COCOA_ENTER(env); JNI_COCOA_EXIT(env); return ret; } + +/* + * Class: sun_awt_CGraphicsDevice + * Method: nativeGetDisplayConfiguration + * Signature: (Lsun/awt/CGraphicsDevice$DisplayConfiguration;)V + */ +JNIEXPORT void JNICALL +Java_sun_awt_CGraphicsDevice_nativeGetDisplayConfiguration +(JNIEnv *env, jclass class, jobject config) { +AWT_ASSERT_APPKIT_THREAD; +JNI_COCOA_ENTER(env); + + DECLARE_CLASS(jc_DisplayConfiguration, "sun/awt/CGraphicsDevice$DisplayConfiguration"); + DECLARE_METHOD(jc_DisplayConfiguration_addDescriptor, jc_DisplayConfiguration, "addDescriptor", "(IIIIID)V"); + + NSArray *screens = [NSScreen screens]; + for (NSScreen *screen in screens) { + NSDictionary *screenInfo = [screen deviceDescription]; + NSNumber *screenID = [screenInfo objectForKey:@"NSScreenNumber"]; + + jint displayID = [screenID unsignedIntValue]; + jdouble scale = 1.0; + if ([screen respondsToSelector:@selector(backingScaleFactor)]) { + scale = [screen backingScaleFactor]; + } + NSRect frame = [screen frame]; + NSRect visibleFrame = [screen visibleFrame]; + // Convert between Cocoa's coordinate system and Java. + jint bottom = visibleFrame.origin.y - frame.origin.y; + jint top = frame.size.height - visibleFrame.size.height - bottom; + jint left = visibleFrame.origin.x - frame.origin.x; + jint right = frame.size.width - visibleFrame.size.width - left; + + (*env)->CallVoidMethod(env, config, jc_DisplayConfiguration_addDescriptor, + displayID, top, left, bottom, right, scale); + CHECK_EXCEPTION(); + } + +JNI_COCOA_EXIT(env); +} diff --git a/src/java.desktop/share/classes/sun/awt/DisplayParametersChangedListener.java b/src/java.desktop/share/classes/sun/awt/DisplayParametersChangedListener.java deleted file mode 100644 index 69c34ffd76ef..000000000000 --- a/src/java.desktop/share/classes/sun/awt/DisplayParametersChangedListener.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2022, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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. - */ - -package sun.awt; - -import java.util.EventListener; - -public interface DisplayParametersChangedListener extends EventListener { - /** - * Invoked when the display parameters changed. - */ - public void displayParametersChanged(); -} diff --git a/src/java.desktop/share/classes/sun/java2d/SunGraphicsEnvironment.java b/src/java.desktop/share/classes/sun/java2d/SunGraphicsEnvironment.java index ca0467cf1d99..6c5863d96a49 100644 --- a/src/java.desktop/share/classes/sun/java2d/SunGraphicsEnvironment.java +++ b/src/java.desktop/share/classes/sun/java2d/SunGraphicsEnvironment.java @@ -44,7 +44,6 @@ import java.util.Locale; import java.util.TreeMap; import sun.awt.DisplayChangedListener; -import sun.awt.DisplayParametersChangedListener; import sun.awt.SunDisplayChanger; import sun.font.FontManager; import sun.font.FontManagerFactory; @@ -60,7 +59,7 @@ import sun.java2d.pipe.Region; * @see GraphicsConfiguration */ public abstract class SunGraphicsEnvironment extends GraphicsEnvironment - implements DisplayChangedListener, DisplayParametersChangedListener { + implements DisplayChangedListener { /** Establish the default font to be used by SG2D. */ private final Font defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12); @@ -276,15 +275,6 @@ public abstract class SunGraphicsEnvironment extends GraphicsEnvironment displayChanger.notifyListeners(); } - @Override - public void displayParametersChanged() { - for (GraphicsDevice gd : getScreenDevices()) { - if (gd instanceof DisplayParametersChangedListener) { - ((DisplayParametersChangedListener) gd).displayParametersChanged(); - } - } - } - /** * Part of the DisplayChangedListener interface: * propagate this event to listeners