diff --git a/GUI/Main.cs b/GUI/Main.cs index f0684d6eaa..f652abc719 100644 --- a/GUI/Main.cs +++ b/GUI/Main.cs @@ -307,9 +307,16 @@ protected override void OnFormClosed(FormClosedEventArgs e) base.OnFormClosed(e); } - protected override void OnLoad(EventArgs e) + private void SetStartPosition() { - if (configuration.WindowLoc.X == -1 && configuration.WindowLoc.Y == -1) + Screen screen = Util.FindScreen(configuration.WindowLoc, configuration.WindowSize); + if (screen == null) + { + // Start at center of screen if we have an invalid location saved in the config + // (such as -32000,-32000, which Windows uses when you're minimized) + StartPosition = FormStartPosition.CenterScreen; + } + else if (configuration.WindowLoc.X == -1 && configuration.WindowLoc.Y == -1) { // Center on screen for first launch StartPosition = FormStartPosition.CenterScreen; @@ -319,14 +326,20 @@ protected override void OnLoad(EventArgs e) // Make sure there's room at the top for the MacOSX menu bar Location = Util.ClampedLocationWithMargins( configuration.WindowLoc, configuration.WindowSize, - new Size(0, 30), new Size(0, 0) + new Size(0, 30), new Size(0, 0), + screen ); } else { // Just make sure it's fully on screen - Location = Util.ClampedLocation(configuration.WindowLoc, configuration.WindowSize); + Location = Util.ClampedLocation(configuration.WindowLoc, configuration.WindowSize, screen); } + } + + protected override void OnLoad(EventArgs e) + { + SetStartPosition(); Size = configuration.WindowSize; WindowState = configuration.IsWindowMaximised ? FormWindowState.Maximized : FormWindowState.Normal; @@ -470,7 +483,7 @@ protected override void OnFormClosing(FormClosingEventArgs e) } // Copy window location to app settings - configuration.WindowLoc = Location; + configuration.WindowLoc = WindowState == FormWindowState.Normal ? Location : RestoreBounds.Location; // Copy window size to app settings if not maximized configuration.WindowSize = WindowState == FormWindowState.Normal ? Size : RestoreBounds.Size; diff --git a/GUI/Util.cs b/GUI/Util.cs index 8832417723..a72168623b 100644 --- a/GUI/Util.cs +++ b/GUI/Util.cs @@ -116,6 +116,20 @@ public static bool TryOpenWebPage(string url, IEnumerable prefixes = nul } } + /// + /// Find a screen that the given box overlaps + /// + /// Upper left corner of box + /// Width and height of box + /// + /// The first screen that overlaps the box if any, otherwise null + /// + public static Screen FindScreen(Point location, Size size) + { + var rect = new Rectangle(location, size); + return Screen.AllScreens.FirstOrDefault(sc => sc.WorkingArea.IntersectsWith(rect)); + } + /// /// Adjust position of a box so it fits entirely on one screen /// @@ -125,26 +139,23 @@ public static bool TryOpenWebPage(string url, IEnumerable prefixes = nul /// Original location if already fully on-screen, otherwise /// a position representing sliding it onto the screen /// - public static Point ClampedLocation(Point location, Size size) + public static Point ClampedLocation(Point location, Size size, Screen screen = null) { - var rect = new Rectangle(location, size); - // Find a screen that the default position overlaps - foreach (Screen screen in Screen.AllScreens) + if (screen == null) { - if (screen.WorkingArea.IntersectsWith(rect)) - { - // Slide the whole rectangle fully onto the screen - if (location.X < screen.WorkingArea.Top) - location.X = screen.WorkingArea.Top; - if (location.Y < screen.WorkingArea.Left) - location.Y = screen.WorkingArea.Left; - if (location.X + size.Width > screen.WorkingArea.Right) - location.X = screen.WorkingArea.Right - size.Width; - if (location.Y + size.Height > screen.WorkingArea.Bottom) - location.Y = screen.WorkingArea.Bottom - size.Height; - // Stop checking screens - break; - } + screen = FindScreen(location, size); + } + if (screen != null) + { + // Slide the whole rectangle fully onto the screen + if (location.X < screen.WorkingArea.Top) + location.X = screen.WorkingArea.Top; + if (location.Y < screen.WorkingArea.Left) + location.Y = screen.WorkingArea.Left; + if (location.X + size.Width > screen.WorkingArea.Right) + location.X = screen.WorkingArea.Right - size.Width; + if (location.Y + size.Height > screen.WorkingArea.Bottom) + location.Y = screen.WorkingArea.Bottom - size.Height; } return location; } @@ -160,12 +171,12 @@ public static Point ClampedLocation(Point location, Size size) /// Original location if already fully on-screen plus margins, otherwise /// a position representing sliding it onto the screen /// - public static Point ClampedLocationWithMargins(Point location, Size size, Size topLeftMargin, Size bottomRightMargin) + public static Point ClampedLocationWithMargins(Point location, Size size, Size topLeftMargin, Size bottomRightMargin, Screen screen = null) { // Imagine drawing a larger box around the window, the size of the desired margin. // We pass that box to ClampedLocation to make sure it fits on screen, // then place our window at an offset within the box - return ClampedLocation(location - topLeftMargin, size + topLeftMargin + bottomRightMargin) + topLeftMargin; + return ClampedLocation(location - topLeftMargin, size + topLeftMargin + bottomRightMargin, screen) + topLeftMargin; } }