diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/MainWindow.xaml.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI/MainWindow.xaml.cs index f6d95e401d9f..3dc5bab99b79 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/MainWindow.xaml.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/MainWindow.xaml.cs @@ -94,6 +94,7 @@ public sealed partial class MainWindow : WindowEx, private WindowPosition _currentWindowPosition = new(); private bool _preventHideWhenDeactivated; + private bool _isLoadedFromDock; private DevRibbon? _devRibbon; @@ -142,7 +143,7 @@ public MainWindow() this.SetIcon(); AppWindow.Title = RS_.GetString("AppName"); - RestoreWindowPosition(); + RestoreWindowPositionFromSavedSettings(); UpdateWindowPositionInMemory(); WeakReferenceMessenger.Default.Register(this); @@ -245,10 +246,26 @@ private void PositionCentered() private void PositionCentered(DisplayArea displayArea) { + // Use the saved window size when available so that a dock-resized HWND + // (hidden but not destroyed) doesn't dictate the size on normal reopen. + SizeInt32 windowSize; + int windowDpi; + + if (_currentWindowPosition.IsSizeValid) + { + windowSize = new SizeInt32(_currentWindowPosition.Width, _currentWindowPosition.Height); + windowDpi = _currentWindowPosition.Dpi; + } + else + { + windowSize = AppWindow.Size; + windowDpi = (int)this.GetDpiForWindow(); + } + var rect = WindowPositionHelper.CenterOnDisplay( - displayArea, - AppWindow.Size, - (int)this.GetDpiForWindow()); + displayArea, + windowSize, + windowDpi); if (rect is not null) { @@ -256,10 +273,9 @@ private void PositionCentered(DisplayArea displayArea) } } - private void RestoreWindowPosition() + private void RestoreWindowPosition(WindowPosition? savedPosition) { - var settings = App.Current.Services.GetService(); - if (settings?.LastWindowPosition is not { Width: > 0, Height: > 0 } savedPosition) + if (savedPosition?.IsSizeValid != true) { // don't try to restore if the saved position is invalid, just recenter PositionCentered(); @@ -274,6 +290,17 @@ private void RestoreWindowPosition() MoveAndResizeDpiAware(newRect); } + private void RestoreWindowPositionFromSavedSettings() + { + var settings = App.Current.Services.GetService(); + RestoreWindowPosition(settings?.LastWindowPosition); + } + + private void RestoreWindowPositionFromMemory() + { + RestoreWindowPosition(_currentWindowPosition); + } + /// /// Moves and resizes the window while suppressing WM_DPICHANGED. /// The caller is expected to provide a rect already scaled for the target display's DPI. @@ -678,6 +705,8 @@ private static DisplayArea GetScreen(HWND currentHwnd, MonitorBehavior target) public void Receive(ShowWindowMessage message) { + _isLoadedFromDock = false; + var settings = App.Current.Services.GetService()!; // Start session tracking @@ -690,6 +719,13 @@ public void Receive(ShowWindowMessage message) internal void Receive(ShowPaletteAtMessage message) { + _isLoadedFromDock = true; + + // Reset the size in case users have resized a dock window. + // Ideally in the future, we'll have defined sizes that opening + // a dock window will adhere to, but alas, that's the future. + RestoreWindowPositionFromMemory(); + ShowHwnd(HWND.Null, message.PosPixels, message.Anchor); } @@ -860,12 +896,17 @@ private void Uncloak() internal void MainWindow_Closed(object sender, WindowEventArgs args) { var serviceProvider = App.Current.Services; - UpdateWindowPositionInMemory(); + + if (!_isLoadedFromDock) + { + UpdateWindowPositionInMemory(); + } var settings = serviceProvider.GetService(); if (settings is not null) { - // a quick sanity check, so we don't overwrite correct values + // If we were last shown from the dock, _currentWindowPosition still holds + // the last non-dock placement because dock sessions intentionally skip updates. if (_currentWindowPosition.IsSizeValid) { settings.LastWindowPosition = _currentWindowPosition; @@ -960,7 +1001,11 @@ internal void MainWindow_Activated(object sender, WindowActivatedEventArgs args) if (args.WindowActivationState == WindowActivationState.Deactivated) { // Save the current window position before hiding the window - UpdateWindowPositionInMemory(); + // but not when opened from dock — preserve the pre-dock size. + if (!_isLoadedFromDock) + { + UpdateWindowPositionInMemory(); + } // If there's a debugger attached... if (System.Diagnostics.Debugger.IsAttached)