diff options
3 files changed, 75 insertions, 68 deletions
diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XDecoratedPeer.java b/src/java.desktop/unix/classes/sun/awt/X11/XDecoratedPeer.java index dcecda96c1e..b5c013c768a 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XDecoratedPeer.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XDecoratedPeer.java @@ -874,33 +874,28 @@ abstract class XDecoratedPeer extends XWindowPeer { updateChildrenSizes(); - WindowLocation newLocation = getNewLocation(xe); - Dimension newDimension = new Dimension(xe.get_width(), xe.get_height()); + WindowLocation eventLocation = getNewLocation(xe); + Dimension eventDimension = new Dimension(xe.get_width(), xe.get_height()); boolean xinerama = XToolkit.localEnv.runningXinerama(); SunToolkit.executeOnEventHandlerThread(target, () -> { - Point newUserLocation = newLocation.getUserLocation(); - WindowDimensions newDimensions = new WindowDimensions(newUserLocation, - new Dimension(scaleDown(newDimension.width), scaleDown(newDimension.height)), getRealInsets(), true); - + Point oldLocation = getLocation(); + Dimension newSize = xinerama + ? checkIfOnNewScreen(new Rectangle(eventLocation.getDeviceLocation(), eventDimension)) + : new Dimension(scaleDown(eventDimension.width), scaleDown(eventDimension.height)); + Point newUserLocation = eventLocation.getUserLocation(); + WindowDimensions newDimensions = new WindowDimensions(newUserLocation, newSize, getRealInsets(), true); if (insLog.isLoggable(PlatformLogger.Level.FINER)) { insLog.finer("Insets are {0}, new dimensions {1}", getRealInsets(), newDimensions); } - - Point oldLocation = getLocation(); dimensions = newDimensions; if (!newUserLocation.equals(oldLocation)) { handleMoved(newDimensions); } reconfigureContentWindow(newDimensions); updateChildrenSizes(); - repositionSecurityWarning(); - - if (xinerama) { - checkIfOnNewScreen(new Rectangle(newLocation.getDeviceLocation(), newDimension)); - } }); } @@ -1444,20 +1439,23 @@ abstract class XDecoratedPeer extends XWindowPeer { if (r.width <= ins.left + ins.right || r.height <= ins.top + ins.bottom) { return; } - if (syncSizeOnly && dimensions != null) { - dimensions.setSize(r.width, r.height); - dimensions.setInsets(ins); - boolean isMaximized = target instanceof Frame f && (f.getExtendedState() & Frame.MAXIMIZED_BOTH) != 0; - // When a window is maximized, affirming its size through an explicit request to the X server - // may make the window fullscreen, which has undesirable consequences. Also, when a window - // already has the maximized attributes, it is already properly sized, so no need to - // resize explicitly. - if (!isMaximized) { - xSetSize(r.width, r.height); + + if (XWindowPeer.RESIZE_WITH_SCALE) { + if (syncSizeOnly && dimensions != null) { + dimensions.setSize(r.width, r.height); + dimensions.setInsets(ins); + boolean isMaximized = target instanceof Frame f && (f.getExtendedState() & Frame.MAXIMIZED_BOTH) != 0; + // When a window is maximized, affirming its size through an explicit request to the X server + // may make the window fullscreen, which has undesirable consequences. Also, when a window + // already has the maximized attributes, it is already properly sized, so no need to + // resize explicitly. + if (!isMaximized) { + xSetSize(r.width, r.height); + } + } else { + dimensions = new WindowDimensions(r, ins, false); + xSetBounds(r.x, r.y, r.width, r.height); } - } else { - dimensions = new WindowDimensions(r, ins, false); - xSetBounds(r.x, r.y, r.width, r.height); } reconfigureContentWindow(dimensions); doValidateSurface(); diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XEmbeddedFramePeer.java b/src/java.desktop/unix/classes/sun/awt/X11/XEmbeddedFramePeer.java index c43c3b759e6..72a7f05b121 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XEmbeddedFramePeer.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XEmbeddedFramePeer.java @@ -142,21 +142,24 @@ public class XEmbeddedFramePeer extends XFramePeer { xembedLog.fine(xe.toString()); } - WindowLocation newLocation = getNewLocation(xe); - Dimension newDimension = new Dimension(xe.get_width(), xe.get_height()); + WindowLocation eventLocation = getNewLocation(xe); + Dimension eventDimension = new Dimension(xe.get_width(), xe.get_height()); boolean xinerama = XToolkit.localEnv.runningXinerama(); // fix for 5063031 // if we use super.handleConfigureNotifyEvent() we would get wrong // size and position because embedded frame really is NOT a decorated one SunToolkit.executeOnEventHandlerThread(target, () -> { - Point newUserLocation = newLocation.getUserLocation(); + Point newUserLocation = eventLocation.getUserLocation(); Rectangle oldBounds = getBounds(); + Dimension newSize = xinerama + ? checkIfOnNewScreen(new Rectangle(eventLocation.getDeviceLocation(), eventDimension)) + : new Dimension(scaleDown(eventDimension.width), scaleDown(eventDimension.height)); synchronized (getStateLock()) { x = newUserLocation.x; y = newUserLocation.y; - width = scaleDown(newDimension.width); - height = scaleDown(newDimension.height); + width = newSize.width; + height = newSize.height; dimensions.setClientSize(width, height); dimensions.setLocation(x, y); @@ -166,10 +169,6 @@ public class XEmbeddedFramePeer extends XFramePeer { handleMoved(dimensions); } reconfigureContentWindow(dimensions); - - if (xinerama) { - checkIfOnNewScreen(new Rectangle(newLocation.getDeviceLocation(), newDimension)); - } }); } diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java b/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java index d8f18cb7392..a4e84b2c5c7 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java @@ -67,6 +67,8 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, = "true".equals(GetPropertyAction.privilegedGetProperty("transients.desktop.check", "true")); static final boolean FULL_MODAL_TRANSIENTS_CHAIN = "true".equals(GetPropertyAction.privilegedGetProperty("full.modal.transients.chain")); + static final boolean RESIZE_WITH_SCALE + = "true".equals(GetPropertyAction.privilegedGetProperty("resize.with.scale", "false")); // should be synchronized on awtLock private static Set<XWindowPeer> windows = new HashSet<XWindowPeer>(); @@ -659,8 +661,9 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, * called to check if we've been moved onto a different screen * Based on checkNewXineramaScreen() in awt_GraphicsEnv.c * newBounds are specified in device space. + * Returns the corrected dimension of this window. */ - public boolean checkIfOnNewScreen(Rectangle newBounds) { + public Dimension checkIfOnNewScreen(Rectangle newBounds) { if (log.isLoggable(PlatformLogger.Level.FINEST)) { log.finest("XWindowPeer: Check if we've been moved to a new screen since we're running in Xinerama mode"); } @@ -669,7 +672,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, int curScreenNum = ((X11GraphicsDevice)getGraphicsConfiguration().getDevice()).getScreen(); int newScreenNum = curScreenNum; GraphicsDevice[] gds = XToolkit.localEnv.getScreenDevices(); - GraphicsConfiguration newGC = null; + GraphicsConfiguration newGC = getGraphicsConfiguration(); for (int i = 0; i < gds.length; i++) { X11GraphicsDevice device = (X11GraphicsDevice) gds[i]; @@ -689,38 +692,47 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, } } } - // Ensure that after window will be moved to another monitor and (probably) - // resized as a result, majority of its area will stay on the new monitor - if (newScreenNum != curScreenNum) { - X11GraphicsDevice device = (X11GraphicsDevice) gds[newScreenNum]; - Rectangle screenBounds = newGC.getBounds(); - // Rescale screen size to native unscaled coordinates - screenBounds.width = device.scaleUp(screenBounds.width); - screenBounds.height = device.scaleUp(screenBounds.height); - // Rescale window to new screen's scale - newBounds.width = newBounds.width * device.getScaleFactor() / graphicsConfig.getScale(); - newBounds.height = newBounds.height * device.getScaleFactor() / graphicsConfig.getScale(); - Rectangle intersection = screenBounds.intersection(newBounds); - if (intersection.isEmpty() || - intersection.width * intersection.height <= newBounds.width * newBounds.height / 2) { - newScreenNum = curScreenNum; // Don't move to new screen + Rectangle newScaledBounds = newBounds.getBounds(); + if (XWindowPeer.RESIZE_WITH_SCALE) { + // Try to guess that after the window has been moved to another monitor and (probably) + // resized as a result, the majority of its area will still be on that new monitor. + // This is a guess since we cannot predict the result of the resize operation where + // the window manager has the final say. + boolean isMaximized = target instanceof Frame f && (f.getExtendedState() & Frame.MAXIMIZED_BOTH) != 0; + if (newScreenNum != curScreenNum && !isMaximized) { + X11GraphicsDevice device = (X11GraphicsDevice) gds[newScreenNum]; + Rectangle screenBounds = newGC.getBounds(); + // Rescale screen size to native unscaled coordinates + screenBounds.width = device.scaleUp(screenBounds.width); + screenBounds.height = device.scaleUp(screenBounds.height); + // Rescale window to new screen's scale + newScaledBounds.width = newBounds.width * device.getScaleFactor() / graphicsConfig.getScale(); + newScaledBounds.height = newBounds.height * device.getScaleFactor() / graphicsConfig.getScale(); + Rectangle intersection = screenBounds.intersection(newScaledBounds); + if (intersection.isEmpty() || + intersection.width * intersection.height <= newScaledBounds.width * newScaledBounds.height / 2) { + newScreenNum = curScreenNum; // Don't move to the new screen + } } } + + var device = (X11GraphicsDevice) newGC.getDevice(); + Dimension newSize = newScaledBounds.getSize(); + newSize.width = device.scaleDown(newSize.width); + newSize.height = device.scaleDown(newSize.height); if (newScreenNum != curScreenNum) { if (log.isLoggable(PlatformLogger.Level.FINEST)) { log.finest("XWindowPeer: Moved to a new screen"); } - var gc = newGC; - var device = (X11GraphicsDevice) gc.getDevice(); var acc = AWTAccessor.getComponentAccessor(); syncSizeOnly = true; - acc.setSize(target, device.scaleDown(newBounds.width), device.scaleDown(newBounds.height)); - acc.setGraphicsConfiguration(target, gc); + acc.setSize(target, newSize.width, newSize.height); + acc.setGraphicsConfiguration(target, newGC); syncSizeOnly = false; - return true; } - return false; + + return newSize; } /** @@ -854,18 +866,20 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, insLog.fine(xe.toString()); } - WindowLocation newLocation = getNewLocation(xe); - Dimension newDimension = new Dimension(xe.get_width(), xe.get_height()); + WindowLocation eventLocation = getNewLocation(xe); + Dimension eventDimension = new Dimension(xe.get_width(), xe.get_height()); boolean xinerama = XToolkit.localEnv.runningXinerama(); SunToolkit.executeOnEventHandlerThread(target, () -> { - Point newUserLocation = newLocation.getUserLocation(); Rectangle oldBounds = getBounds(); - + Dimension newSize = xinerama + ? checkIfOnNewScreen(new Rectangle(eventLocation.getDeviceLocation(), eventDimension)) + : new Dimension(scaleDown(eventDimension.width), scaleDown(eventDimension.height));; + Point newUserLocation = eventLocation.getUserLocation(); x = newUserLocation.x; y = newUserLocation.y; - width = scaleDown(newDimension.width); - height = scaleDown(newDimension.height); + width = newSize.width; + height = newSize.height; if (!getBounds().getSize().equals(oldBounds.getSize())) { AWTAccessor.getComponentAccessor().setSize(target, width, height); @@ -876,10 +890,6 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, postEvent(new ComponentEvent(target, ComponentEvent.COMPONENT_MOVED)); } repositionSecurityWarning(); - - if (xinerama) { - checkIfOnNewScreen(new Rectangle(newLocation.getDeviceLocation(), newDimension)); - } }); } |