Fix tiny window on high-DPI displays and tray restore un-maximizing
AppWindow.Resize/Move take physical pixels and the app is PerMonitorV2-aware, but RestoreWindowBounds passed the logical default/minimum sizes unscaled, so on a high-DPI display (e.g. a 200% laptop panel) the window came out at half size. That showed up when restoring from the tray, since RestoreMainWindow's SW_RESTORE un-maximizes to that size. Scale the default/minimum sizes by the window DPI via GetDpiForWindow. Also stop RestoreMainWindow from un-maximizing: it called SW_RESTORE unconditionally, collapsing a window that was hidden to the tray while maximized. Only SW_RESTORE when the window is minimized; otherwise SW_SHOW preserves state. Verified on a 200% display: the restored window is 1520x1360 (= 760x680 logical) and stays maximized across tray hide/show. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -788,7 +788,10 @@ public sealed class MainWindow : Window
|
||||
IntPtr hwnd = WindowNative.GetWindowHandle(this);
|
||||
_isMainWindowHidden = false;
|
||||
ShowWindow(hwnd, ShowWindowShow);
|
||||
ShowWindow(hwnd, ShowWindowRestore);
|
||||
// Only un-minimize. The window is hidden to the tray with SW_HIDE while keeping its maximized state, so
|
||||
// SW_SHOW alone brings it back as it was; an unconditional SW_RESTORE would also un-maximize it.
|
||||
if (IsIconic(hwnd))
|
||||
ShowWindow(hwnd, ShowWindowRestore);
|
||||
Activate();
|
||||
}
|
||||
|
||||
@@ -1542,8 +1545,14 @@ public sealed class MainWindow : Window
|
||||
|
||||
private void RestoreWindowBounds()
|
||||
{
|
||||
int width = Math.Max(470, ViewModel.Settings.GetValue("mainForm.Width", 760));
|
||||
int height = Math.Max(640, ViewModel.Settings.GetValue("mainForm.Height", 680));
|
||||
// AppWindow.Resize takes physical pixels and the app is PerMonitorV2 DPI-aware, so the logical default/minimum
|
||||
// sizes must be scaled by the window's DPI. Without this, on a high-DPI display (e.g. a 200% laptop panel) the
|
||||
// window — and any SW_RESTORE from the tray, which un-maximizes to this size — came out at half size.
|
||||
double scale = GetWindowScale();
|
||||
int minWidth = (int)Math.Round(470 * scale);
|
||||
int minHeight = (int)Math.Round(640 * scale);
|
||||
int width = Math.Max(minWidth, ViewModel.Settings.GetValue("mainForm.Width", (int)Math.Round(760 * scale)));
|
||||
int height = Math.Max(minHeight, ViewModel.Settings.GetValue("mainForm.Height", (int)Math.Round(680 * scale)));
|
||||
_appWindow.Resize(new SizeInt32(width, height));
|
||||
|
||||
int x = ViewModel.Settings.GetValue("mainForm.Location.X", int.MinValue);
|
||||
@@ -1552,6 +1561,12 @@ public sealed class MainWindow : Window
|
||||
_appWindow.Move(new PointInt32(x, y));
|
||||
}
|
||||
|
||||
private double GetWindowScale()
|
||||
{
|
||||
uint dpi = GetDpiForWindow(WindowNative.GetWindowHandle(this));
|
||||
return dpi == 0 ? 1.0 : dpi / 96.0;
|
||||
}
|
||||
|
||||
private void MaximizeWindow()
|
||||
{
|
||||
if (_appWindow.Presenter is OverlappedPresenter presenter)
|
||||
@@ -1787,6 +1802,9 @@ public sealed class MainWindow : Window
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool IsIconic(IntPtr windowHandle);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern uint GetDpiForWindow(IntPtr windowHandle);
|
||||
|
||||
private sealed record ParameterEditorRow(IParameter Parameter, Grid Container, CheckBox UseDefault, TextBox Value);
|
||||
|
||||
private static void Bind(DependencyObject target, DependencyProperty property, object source, string path, BindingMode mode = BindingMode.OneWay)
|
||||
|
||||
Reference in New Issue
Block a user