CmdPal: Fix window restore when the window is not WS_EX_TOOLWINDOW (#45877)

## 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
This commit is contained in:
Jiří Polášek
2026-03-03 17:28:17 +01:00
committed by GitHub
parent 9089ca2ede
commit c066cc3deb
2 changed files with 25 additions and 4 deletions

View File

@@ -59,6 +59,16 @@ internal static class WindowExtensions
return wasSet; return wasSet;
} }
/// <summary>
/// Returns true if the specified extended window style flag(s) are currently set on the window.
/// </summary>
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;
}
/// <summary> /// <summary>
/// Sets the window corner preference /// Sets the window corner preference
/// </summary> /// </summary>

View File

@@ -311,15 +311,26 @@ public sealed partial class MainWindow : WindowEx,
var rect = placement.rcNormalPosition; var rect = placement.rcNormalPosition;
var displayArea = DisplayArea.GetFromWindowId(AppWindow.Id, DisplayAreaFallback.Nearest) ?? DisplayArea.Primary; 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 _currentWindowPosition = new WindowPosition
{ {
X = rect.X, X = rect.X + (isToolWindow ? 0 : workArea.X),
Y = rect.Y, Y = rect.Y + (isToolWindow ? 0 : workArea.Y),
Width = rect.Width, Width = rect.Width,
Height = rect.Height, Height = rect.Height,
Dpi = (int)this.GetDpiForWindow(), Dpi = (int)this.GetDpiForWindow(),
ScreenWidth = displayArea.WorkArea.Width, ScreenWidth = workArea.Width,
ScreenHeight = displayArea.WorkArea.Height, ScreenHeight = workArea.Height,
}; };
} }