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
|
// Get the size of a window we'd need to host that client rect. This will
|
||||||
// add the titlebar space.
|
// add the titlebar space.
|
||||||
const til::size nonClientSize = _window->GetTotalNonClientExclusiveSize(dpix);
|
const til::size nonClientSize = _window->GetTotalNonClientExclusiveSize(dpix);
|
||||||
|
const til::rectangle nonClientFrame = _window->GetNonClientFrame(dpix);
|
||||||
adjustedWidth = islandWidth + nonClientSize.width<long>();
|
adjustedWidth = islandWidth + nonClientSize.width<long>();
|
||||||
adjustedHeight = islandHeight + nonClientSize.height<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),
|
const til::size desktopDimensions{ gsl::narrow<short>(nearestMonitorInfo.rcWork.right - nearestMonitorInfo.rcWork.left),
|
||||||
gsl::narrow<short>(nearestMonitorInfo.rcWork.bottom - nearestMonitorInfo.rcWork.top) };
|
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) };
|
(proposedRect.top) };
|
||||||
|
|
||||||
if (_logic.IsQuakeWindow())
|
if (_logic.IsQuakeWindow())
|
||||||
{
|
{
|
||||||
// If we just use rcWork by itself, we'll fail to account for the invisible
|
// 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.
|
// space reserved for the resize handles. So retrieve that size here.
|
||||||
const til::size ncSize{ _window->GetTotalNonClientExclusiveSize(dpix) };
|
|
||||||
const til::size availableSpace = desktopDimensions + nonClientSize;
|
const til::size availableSpace = desktopDimensions + nonClientSize;
|
||||||
|
|
||||||
origin = til::point{
|
origin = til::point{
|
||||||
|
|
|
@ -616,12 +616,20 @@ void IslandWindow::SetContent(winrt::Windows::UI::Xaml::UIElement content)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// 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:
|
// Arguments:
|
||||||
// - dpi: dpi of a monitor on which the window is placed
|
// - dpi: the scaling that we should use to calculate the border sizes.
|
||||||
// Return Value
|
// Return Value:
|
||||||
// - The size difference
|
// - a RECT whose components represent the margins of the nonclient area,
|
||||||
SIZE IslandWindow::GetTotalNonClientExclusiveSize(const UINT dpi) const noexcept
|
// relative to the client area.
|
||||||
|
RECT IslandWindow::GetNonClientFrame(const UINT dpi) const noexcept
|
||||||
{
|
{
|
||||||
const auto windowStyle = static_cast<DWORD>(GetWindowLong(_window.get(), GWL_STYLE));
|
const auto windowStyle = static_cast<DWORD>(GetWindowLong(_window.get(), GWL_STYLE));
|
||||||
RECT islandFrame{};
|
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
|
// the error and go on. We'll use whatever the control proposed as the
|
||||||
// size of our window, which will be at least close.
|
// size of our window, which will be at least close.
|
||||||
LOG_IF_WIN32_BOOL_FALSE(AdjustWindowRectExForDpi(&islandFrame, windowStyle, false, 0, dpi));
|
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 {
|
return {
|
||||||
islandFrame.right - islandFrame.left,
|
islandFrame.right - islandFrame.left,
|
||||||
islandFrame.bottom - islandFrame.top
|
islandFrame.bottom - islandFrame.top
|
||||||
|
|
|
@ -24,6 +24,7 @@ public:
|
||||||
virtual void OnAppInitialized();
|
virtual void OnAppInitialized();
|
||||||
virtual void SetContent(winrt::Windows::UI::Xaml::UIElement content);
|
virtual void SetContent(winrt::Windows::UI::Xaml::UIElement content);
|
||||||
virtual void OnApplicationThemeChanged(const winrt::Windows::UI::Xaml::ElementTheme& requestedTheme);
|
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 SIZE GetTotalNonClientExclusiveSize(const UINT dpi) const noexcept;
|
||||||
|
|
||||||
virtual void Initialize();
|
virtual void Initialize();
|
||||||
|
|
|
@ -629,14 +629,21 @@ int NonClientIslandWindow::_GetResizeHandleHeight() const noexcept
|
||||||
|
|
||||||
return DefWindowProc(GetHandle(), WM_SETCURSOR, wParam, lParam);
|
return DefWindowProc(GetHandle(), WM_SETCURSOR, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// 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:
|
// Arguments:
|
||||||
// - dpi: dpi of a monitor on which the window is placed
|
// - dpi: the scaling that we should use to calculate the border sizes.
|
||||||
// Return Value
|
// Return Value:
|
||||||
// - The size difference
|
// - a RECT whose components represent the margins of the nonclient area,
|
||||||
SIZE NonClientIslandWindow::GetTotalNonClientExclusiveSize(UINT dpi) const noexcept
|
// relative to the client area.
|
||||||
|
RECT NonClientIslandWindow::GetNonClientFrame(UINT dpi) const noexcept
|
||||||
{
|
{
|
||||||
const auto windowStyle = static_cast<DWORD>(GetWindowLong(_window.get(), GWL_STYLE));
|
const auto windowStyle = static_cast<DWORD>(GetWindowLong(_window.get(), GWL_STYLE));
|
||||||
RECT islandFrame{};
|
RECT islandFrame{};
|
||||||
|
@ -647,6 +654,18 @@ SIZE NonClientIslandWindow::GetTotalNonClientExclusiveSize(UINT dpi) const noexc
|
||||||
LOG_IF_WIN32_BOOL_FALSE(AdjustWindowRectExForDpi(&islandFrame, windowStyle, false, 0, dpi));
|
LOG_IF_WIN32_BOOL_FALSE(AdjustWindowRectExForDpi(&islandFrame, windowStyle, false, 0, dpi));
|
||||||
|
|
||||||
islandFrame.top = -topBorderVisibleHeight;
|
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
|
// 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.
|
// 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;
|
[[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;
|
virtual SIZE GetTotalNonClientExclusiveSize(UINT dpi) const noexcept override;
|
||||||
|
|
||||||
void Initialize() override;
|
void Initialize() override;
|
||||||
|
|
Loading…
Reference in a new issue