diff --git a/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java b/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java index 78fffa2128..9fdd9d60ae 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java @@ -35,6 +35,8 @@ import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; import java.awt.LayoutManager; import java.awt.Rectangle; import java.awt.Toolkit; @@ -510,7 +512,32 @@ public class ClientUI if (clientBounds != null) { frame.setBounds(clientBounds); - frame.revalidateMinimumSize(); + + // frame.getGraphicsConfiguration().getBounds() returns the bounds for the primary display. + // We have to find the correct graphics configuration by using the intersection of the client boundaries. + GraphicsConfiguration gc = getIntersectingDisplay(clientBounds); + if (gc != null) + { + double scale = gc.getDefaultTransform().getScaleX(); + + // When Windows screen scaling is on, the position/bounds will be wrong when they are set. + // The bounds saved in shutdown are the full, non-scaled co-ordinates. + if (scale != 1) + { + clientBounds.setRect( + clientBounds.getX() / scale, + clientBounds.getY() / scale, + clientBounds.getWidth() / scale, + clientBounds.getHeight() / scale); + + frame.setMinimumSize(clientBounds.getSize()); + frame.setBounds(clientBounds); + } + } + else + { + frame.setLocationRelativeTo(frame.getOwner()); + } } else { @@ -533,25 +560,13 @@ public class ClientUI frame.setLocationRelativeTo(frame.getOwner()); } - // If the frame is well hidden (e.g. unplugged 2nd screen), - // we want to move it back to default position as it can be - // hard for the user to reposition it themselves otherwise. - Rectangle clientBounds = frame.getBounds(); - Rectangle screenBounds = frame.getGraphicsConfiguration().getBounds(); - if (clientBounds.x + clientBounds.width - CLIENT_WELL_HIDDEN_MARGIN < screenBounds.getX() || - clientBounds.x + CLIENT_WELL_HIDDEN_MARGIN > screenBounds.getX() + screenBounds.getWidth() || - clientBounds.y + CLIENT_WELL_HIDDEN_MARGIN_TOP < screenBounds.getY() || - clientBounds.y + CLIENT_WELL_HIDDEN_MARGIN > screenBounds.getY() + screenBounds.getHeight()) - { - frame.setLocationRelativeTo(frame.getOwner()); - } - // Show frame frame.setVisible(true); frame.toFront(); requestFocus(); giveClientFocus(); log.info("Showing frame {}", frame); + frame.revalidateMinimumSize(); }); // Show out of date dialog if needed @@ -564,6 +579,24 @@ public class ClientUI } } + private GraphicsConfiguration getIntersectingDisplay(final Rectangle bounds) + { + GraphicsDevice[] gds = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices(); + + for (GraphicsDevice gd : gds) + { + GraphicsConfiguration gc = gd.getDefaultConfiguration(); + + final Rectangle displayBounds = gc.getBounds(); + if (displayBounds.intersects(bounds)) + { + return gc; + } + } + + return null; + } + private boolean showWarningOnExit() { if (config.warningOnExit() == WarningOnExit.ALWAYS) @@ -1056,14 +1089,14 @@ public class ClientUI private void saveClientBoundsConfig() { + final Rectangle bounds = frame.getBounds(); if ((frame.getExtendedState() & JFrame.MAXIMIZED_BOTH) != 0) { + configManager.setConfiguration(CONFIG_GROUP, CONFIG_CLIENT_BOUNDS, bounds); configManager.setConfiguration(CONFIG_GROUP, CONFIG_CLIENT_MAXIMIZED, true); } else { - final Rectangle bounds = frame.getBounds(); - // Try to expand sidebar if (!sidebarOpen) {