Improve GetBestSize() for TLWs containing a single child

Previously the best size of such TLW was determined by the current size
of its only child, which is the behaviour inherited from wxWindow, where
it makes sense, as it works for the manually positioned children.

However at TLW level, the only child is not positioned manually but is
resized to the available client size by default, which means that this
logic didn't make much sense, as the best size grew whenever the TLW was
made larger but never shrunk.

Fix this by returning the best size of the unique child, if we have one,
as this seems much more logical: now the TLW best size is just big
enough for its contents, just as it should be.

In particular, this avoids making such TLWs bigger on each change from
higher to lower DPI in wxMSW, where the code ensures that the window is
still big enough to fit its contents at the new DPI.

Closes #22983.
This commit is contained in:
Vadim Zeitlin 2022-12-14 14:58:12 +01:00
parent 32caf7cbab
commit bcb9c19358
2 changed files with 14 additions and 0 deletions

View file

@ -325,6 +325,8 @@ protected:
DoGetPosition(x, y);
}
virtual wxSize DoGetBestClientSize() const override;
// test whether this window makes part of the frame
// (menubar, toolbar and statusbar are excluded from automatic layout)
virtual bool IsOneOfBars(const wxWindow *WXUNUSED(win)) const

View file

@ -486,6 +486,18 @@ bool wxTopLevelWindowBase::Layout()
return false;
}
wxSize wxTopLevelWindowBase::DoGetBestClientSize() const
{
// The logic here parallels that of Layout() above.
if ( !UsesAutoLayout() )
{
if ( wxWindow* const child = GetUniqueChild() )
return child->GetBestSize();
}
return wxNonOwnedWindow::DoGetBestClientSize();
}
// The default implementation for the close window event.
void wxTopLevelWindowBase::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
{