Account for the window frame when calculating initial position (#10902)
## Summary of the Pull Request Turns out, we'd only ever use the non-client size to calculate the size of the window, but not the actual position. As we learned in #10676, the nonclient area extends a few pixels past the visible borders of the window. ## PR Checklist * [x] Closes #10583 * [x] I work here * [ ] Tests added/passed * [n/a] Requires documentation to be updated ## Validation Steps Performed * [x] Works with the `IslandWindow` * [x] Works with the `NonClientIslandWindow`
This commit is contained in:
parent
cd4aabda84
commit
7acec306a6
|
@ -410,6 +410,7 @@ void AppHost::_HandleCreateWindow(const HWND hwnd, RECT proposedRect, LaunchMode
|
|||
// Get the size of a window we'd need to host that client rect. This will
|
||||
// add the titlebar space.
|
||||
const til::size nonClientSize = _window->GetTotalNonClientExclusiveSize(dpix);
|
||||
const til::rectangle nonClientFrame = _window->GetNonClientFrame(dpix);
|
||||
adjustedWidth = islandWidth + nonClientSize.width<long>();
|
||||
adjustedHeight = islandHeight + nonClientSize.height<long>();
|
||||
|
||||
|
@ -425,14 +426,18 @@ void AppHost::_HandleCreateWindow(const HWND hwnd, RECT proposedRect, LaunchMode
|
|||
const til::size desktopDimensions{ gsl::narrow<short>(nearestMonitorInfo.rcWork.right - nearestMonitorInfo.rcWork.left),
|
||||
gsl::narrow<short>(nearestMonitorInfo.rcWork.bottom - nearestMonitorInfo.rcWork.top) };
|
||||
|
||||
til::point origin{ (proposedRect.left),
|
||||
// GH#10583 - Adjust the position of the rectangle to account for the size
|
||||
// of the invisible borders on the left/right. We DON'T want to adjust this
|
||||
// for the top here - the IslandWindow includes the titlebar in
|
||||
// nonClientFrame.top, so adjusting for that would actually place the
|
||||
// titlebar _off_ the monitor.
|
||||
til::point origin{ (proposedRect.left + nonClientFrame.left<LONG>()),
|
||||
(proposedRect.top) };
|
||||
|
||||
if (_logic.IsQuakeWindow())
|
||||
{
|
||||
// If we just use rcWork by itself, we'll fail to account for the invisible
|
||||
// space reserved for the resize handles. So retrieve that size here.
|
||||
const til::size ncSize{ _window->GetTotalNonClientExclusiveSize(dpix) };
|
||||
const til::size availableSpace = desktopDimensions + nonClientSize;
|
||||
|
||||
origin = til::point{
|
||||
|
|
|
@ -616,12 +616,20 @@ void IslandWindow::SetContent(winrt::Windows::UI::Xaml::UIElement content)
|
|||
}
|
||||
|
||||
// Method Description:
|
||||
// - Gets the difference between window and client area size.
|
||||
// - Get the dimensions of our non-client area, as a rect where each component
|
||||
// represents that side.
|
||||
// - The .left will be a negative number, to represent that the actual side of
|
||||
// the non-client area is outside the border of our window. It's roughly 8px (
|
||||
// * DPI scaling) to the left of the visible border.
|
||||
// - The .right component will be positive, indicating that the nonclient border
|
||||
// is in the positive-x direction from the edge of our client area.
|
||||
// - This will also include our titlebar! It's in the nonclient area for us.
|
||||
// Arguments:
|
||||
// - dpi: dpi of a monitor on which the window is placed
|
||||
// Return Value
|
||||
// - The size difference
|
||||
SIZE IslandWindow::GetTotalNonClientExclusiveSize(const UINT dpi) const noexcept
|
||||
// - dpi: the scaling that we should use to calculate the border sizes.
|
||||
// Return Value:
|
||||
// - a RECT whose components represent the margins of the nonclient area,
|
||||
// relative to the client area.
|
||||
RECT IslandWindow::GetNonClientFrame(const UINT dpi) const noexcept
|
||||
{
|
||||
const auto windowStyle = static_cast<DWORD>(GetWindowLong(_window.get(), GWL_STYLE));
|
||||
RECT islandFrame{};
|
||||
|
@ -630,7 +638,18 @@ SIZE IslandWindow::GetTotalNonClientExclusiveSize(const UINT dpi) const noexcept
|
|||
// the error and go on. We'll use whatever the control proposed as the
|
||||
// size of our window, which will be at least close.
|
||||
LOG_IF_WIN32_BOOL_FALSE(AdjustWindowRectExForDpi(&islandFrame, windowStyle, false, 0, dpi));
|
||||
return islandFrame;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Gets the difference between window and client area size.
|
||||
// Arguments:
|
||||
// - dpi: dpi of a monitor on which the window is placed
|
||||
// Return Value
|
||||
// - The size difference
|
||||
SIZE IslandWindow::GetTotalNonClientExclusiveSize(const UINT dpi) const noexcept
|
||||
{
|
||||
const auto islandFrame{ GetNonClientFrame(dpi) };
|
||||
return {
|
||||
islandFrame.right - islandFrame.left,
|
||||
islandFrame.bottom - islandFrame.top
|
||||
|
|
|
@ -24,6 +24,7 @@ public:
|
|||
virtual void OnAppInitialized();
|
||||
virtual void SetContent(winrt::Windows::UI::Xaml::UIElement content);
|
||||
virtual void OnApplicationThemeChanged(const winrt::Windows::UI::Xaml::ElementTheme& requestedTheme);
|
||||
virtual RECT GetNonClientFrame(const UINT dpi) const noexcept;
|
||||
virtual SIZE GetTotalNonClientExclusiveSize(const UINT dpi) const noexcept;
|
||||
|
||||
virtual void Initialize();
|
||||
|
|
|
@ -629,14 +629,21 @@ int NonClientIslandWindow::_GetResizeHandleHeight() const noexcept
|
|||
|
||||
return DefWindowProc(GetHandle(), WM_SETCURSOR, wParam, lParam);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Gets the difference between window and client area size.
|
||||
// - Get the dimensions of our non-client area, as a rect where each component
|
||||
// represents that side.
|
||||
// - The .left will be a negative number, to represent that the actual side of
|
||||
// the non-client area is outside the border of our window. It's roughly 8px (
|
||||
// * DPI scaling) to the left of the visible border.
|
||||
// - The .right component will be positive, indicating that the nonclient border
|
||||
// is in the positive-x direction from the edge of our client area.
|
||||
// - This DOES NOT include our titlebar! It's in the client area for us.
|
||||
// Arguments:
|
||||
// - dpi: dpi of a monitor on which the window is placed
|
||||
// Return Value
|
||||
// - The size difference
|
||||
SIZE NonClientIslandWindow::GetTotalNonClientExclusiveSize(UINT dpi) const noexcept
|
||||
// - dpi: the scaling that we should use to calculate the border sizes.
|
||||
// Return Value:
|
||||
// - a RECT whose components represent the margins of the nonclient area,
|
||||
// relative to the client area.
|
||||
RECT NonClientIslandWindow::GetNonClientFrame(UINT dpi) const noexcept
|
||||
{
|
||||
const auto windowStyle = static_cast<DWORD>(GetWindowLong(_window.get(), GWL_STYLE));
|
||||
RECT islandFrame{};
|
||||
|
@ -647,6 +654,18 @@ SIZE NonClientIslandWindow::GetTotalNonClientExclusiveSize(UINT dpi) const noexc
|
|||
LOG_IF_WIN32_BOOL_FALSE(AdjustWindowRectExForDpi(&islandFrame, windowStyle, false, 0, dpi));
|
||||
|
||||
islandFrame.top = -topBorderVisibleHeight;
|
||||
return islandFrame;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Gets the difference between window and client area size.
|
||||
// Arguments:
|
||||
// - dpi: dpi of a monitor on which the window is placed
|
||||
// Return Value
|
||||
// - The size difference
|
||||
SIZE NonClientIslandWindow::GetTotalNonClientExclusiveSize(UINT dpi) const noexcept
|
||||
{
|
||||
const auto islandFrame{ GetNonClientFrame(dpi) };
|
||||
|
||||
// If we have a titlebar, this is being called after we've initialized, and
|
||||
// we can just ask that titlebar how big it wants to be.
|
||||
|
|
|
@ -37,6 +37,7 @@ public:
|
|||
|
||||
[[nodiscard]] virtual LRESULT MessageHandler(UINT const message, WPARAM const wparam, LPARAM const lparam) noexcept override;
|
||||
|
||||
virtual RECT GetNonClientFrame(UINT dpi) const noexcept override;
|
||||
virtual SIZE GetTotalNonClientExclusiveSize(UINT dpi) const noexcept override;
|
||||
|
||||
void Initialize() override;
|
||||
|
|
Loading…
Reference in a new issue