Keep window on the same display in SetClientSize()
It was unexpected that changing the window client size could change the display the window was on and, even worse, result in further size changes because changing the display could change the DPI scaling used. And, worst of all, if the window wxEVT_DPI_CHANGED handler called SetClientSize(), possibly indirectly such as via wxSizer::Fit(), this could result in an infinite recursion when moving the window to a high definition display located to the left of the standard definition one (the problem didn't happen for the reciprocal display arrangement because increasing the window size couldn't change the window display in that case). So ensure that the window remains on the same display it is on now, by keeping its center position unchanged, instead of keeping the position of its top left corner as we did before.
This commit is contained in:
parent
438da9c99a
commit
072d581e87
1 changed files with 36 additions and 5 deletions
|
|
@ -2277,6 +2277,10 @@ void wxWindowMSW::DoSetClientSize(int width, int height)
|
|||
const int widthWin = rectWin.right - rectWin.left,
|
||||
heightWin = rectWin.bottom - rectWin.top;
|
||||
|
||||
wxRect proposedRect(rectWin.left, rectWin.top,
|
||||
width + widthWin - rectClient.right,
|
||||
height + heightWin - rectClient.bottom);
|
||||
|
||||
if ( IsTopLevel() )
|
||||
{
|
||||
// toplevel window's coordinates are mirrored if the TLW is a child of another
|
||||
|
|
@ -2288,8 +2292,33 @@ void wxWindowMSW::DoSetClientSize(int width, int height)
|
|||
if ( tlwParent && (::GetWindowLong(tlwParent, GWL_EXSTYLE) & WS_EX_LAYOUTRTL) != 0 )
|
||||
{
|
||||
const int diffWidth = width - (rectClient.right - rectClient.left);
|
||||
rectWin.left -= diffWidth;
|
||||
rectWin.right -= diffWidth;
|
||||
proposedRect.x -= diffWidth;
|
||||
}
|
||||
|
||||
// Another complication with TLWs is that changing their size may
|
||||
// change the monitor they are on, even without changing their
|
||||
// position. This is unexpected and especially so if the new
|
||||
// monitor uses a different DPI scaling and so moving the window to
|
||||
// it changes its size -- which may result in an infinite recursion
|
||||
// if the window calls SetClientSize() when DPI changes.
|
||||
//
|
||||
// So ensure that the window stays on the same monitor, adjusting
|
||||
// its position if necessary.
|
||||
const int currentDisplay =
|
||||
wxDisplay::GetFromWindow(static_cast<const wxWindow*>(this));
|
||||
if ( currentDisplay != wxNOT_FOUND &&
|
||||
wxDisplay::GetFromRect(proposedRect) != currentDisplay )
|
||||
{
|
||||
// It's not obvious how to determine the smallest modification
|
||||
// of the window position sufficient for keeping it on the
|
||||
// current display, so keep things simple and preserve the
|
||||
// position of its center horizontally.
|
||||
proposedRect.x += widthWin/2 - proposedRect.width/2;
|
||||
if ( wxDisplay::GetFromRect(proposedRect) != currentDisplay )
|
||||
{
|
||||
// And if this isn't sufficient, then vertically too.
|
||||
proposedRect.y += heightWin/2 - proposedRect.height/2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -2300,6 +2329,8 @@ void wxWindowMSW::DoSetClientSize(int width, int height)
|
|||
if ( parent )
|
||||
{
|
||||
::ScreenToClient(GetHwndOf(parent), (POINT *)&rectWin);
|
||||
proposedRect.x = rectWin.left;
|
||||
proposedRect.y = rectWin.top;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2307,9 +2338,9 @@ void wxWindowMSW::DoSetClientSize(int width, int height)
|
|||
// and not defer it here as otherwise the value returned by
|
||||
// GetClient/WindowRect() wouldn't change as the window wouldn't be
|
||||
// really resized
|
||||
MSWMoveWindowToAnyPosition(GetHwnd(), rectWin.left, rectWin.top,
|
||||
width + widthWin - rectClient.right,
|
||||
height + heightWin - rectClient.bottom, true);
|
||||
MSWMoveWindowToAnyPosition(GetHwnd(), proposedRect.x, proposedRect.y,
|
||||
proposedRect.width, proposedRect.height,
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue