clientui: respect multiple displays when saving/loading client position

This commit is contained in:
Spedwards
2020-06-16 09:28:23 +10:00
committed by GitHub
parent 51f0b7752d
commit b2aa2537bf

View File

@@ -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)
{