From c066cc3deb854b146105e13a9e4bea2c62f9d9d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Pol=C3=A1=C5=A1ek?= Date: Tue, 3 Mar 2026 17:28:17 +0100 Subject: [PATCH] CmdPal: Fix window restore when the window is not WS_EX_TOOLWINDOW (#45877) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary of the Pull Request This PR checks the window’s actual extended style before saving the current window size so the offset is calculated correctly. The API used can return coordinates in different coordinate spaces depending on whether the window has the `WS_EX_TOOLWINDOW` extended style. This makes sense in case that settings `WS_EX_TOOLWINDOW` fails, or is not applied (when debugger is attached). > https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-windowplacement > If the window is a top-level window that does not have the WS_EX_TOOLWINDOW window style, then the coordinates represented by the following members are in workspace coordinates: ptMinPos --- .../Helpers/WindowExtensions.cs | 10 ++++++++++ .../Microsoft.CmdPal.UI/MainWindow.xaml.cs | 19 +++++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/Helpers/WindowExtensions.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI/Helpers/WindowExtensions.cs index ee782766bc..aa6dde458b 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/Helpers/WindowExtensions.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/Helpers/WindowExtensions.cs @@ -59,6 +59,16 @@ internal static class WindowExtensions return wasSet; } + /// + /// Returns true if the specified extended window style flag(s) are currently set on the window. + /// + internal static bool HasExtendedStyle(this Window window, WINDOW_EX_STYLE style) + { + var hWnd = GetWindowHwnd(window); + var currentStyle = (WINDOW_EX_STYLE)PInvoke.GetWindowLong(hWnd, WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE); + return (currentStyle & style) != 0; + } + /// /// Sets the window corner preference /// diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/MainWindow.xaml.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI/MainWindow.xaml.cs index a168176c85..f6d95e401d 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/MainWindow.xaml.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/MainWindow.xaml.cs @@ -311,15 +311,26 @@ public sealed partial class MainWindow : WindowEx, var rect = placement.rcNormalPosition; var displayArea = DisplayArea.GetFromWindowId(AppWindow.Id, DisplayAreaFallback.Nearest) ?? DisplayArea.Primary; + + // GetWindowPlacement returns rcNormalPosition in workspace coordinates for + // normal windows, but in screen coordinates for tool windows (WS_EX_TOOLWINDOW). + // HiddenOwnerWindowBehavior applies WS_EX_TOOLWINDOW to hide from taskbar/Alt+Tab, + // so we must check the current style before converting coordinates. + // + // To be on the safe side, we should consider the possibility that setting + // WS_EX_TOOLWINDOW failed or isn't applied while debugging. + var workArea = displayArea.WorkArea; + var isToolWindow = this.HasExtendedStyle(WINDOW_EX_STYLE.WS_EX_TOOLWINDOW); + _currentWindowPosition = new WindowPosition { - X = rect.X, - Y = rect.Y, + X = rect.X + (isToolWindow ? 0 : workArea.X), + Y = rect.Y + (isToolWindow ? 0 : workArea.Y), Width = rect.Width, Height = rect.Height, Dpi = (int)this.GetDpiForWindow(), - ScreenWidth = displayArea.WorkArea.Width, - ScreenHeight = displayArea.WorkArea.Height, + ScreenWidth = workArea.Width, + ScreenHeight = workArea.Height, }; }