Move workaround for initial TLW size to wxGTK itself
Add wxWindow::WXSetInitialFittingClientSize() instead of handling wxGTK TLWs specially in the common wxSizer code and override it in wxGTK to remember that we need to reset the client size once the window is shown. This commit shouldn't result in any changes in the observed behaviour.
This commit is contained in:
@@ -138,6 +138,16 @@ public:
|
||||
|
||||
void GTKDoAfterShow();
|
||||
|
||||
#ifdef __WXGTK3__
|
||||
void GTKUpdateClientSizeIfNecessary();
|
||||
|
||||
virtual void WXSetInitialFittingClientSize(int flags) wxOVERRIDE;
|
||||
|
||||
private:
|
||||
// Flags to call WXSetInitialFittingClientSize() with if != 0.
|
||||
int m_pendingFittingClientSizeFlags;
|
||||
#endif // __WXGTK3__
|
||||
|
||||
protected:
|
||||
// give hints to the Window Manager for how the size
|
||||
// of the TLW can be changed by dragging
|
||||
|
@@ -139,6 +139,13 @@ enum
|
||||
wxSEND_EVENT_POST = 1
|
||||
};
|
||||
|
||||
// Flags for WXSetInitialFittingClientSize().
|
||||
enum
|
||||
{
|
||||
wxSIZE_SET_CURRENT = 0x0001, // Set the current size.
|
||||
wxSIZE_SET_MIN = 0x0002 // Set the size as the minimum allowed size.
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// (pseudo)template list classes
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -1541,6 +1548,13 @@ public:
|
||||
// window is part of a composite control.
|
||||
bool WXSendContextMenuEvent(const wxPoint& posInScreenCoords);
|
||||
|
||||
// This internal function needs to be called to set the fitting client size
|
||||
// (i.e. the minimum size determined by the window sizer) when the size
|
||||
// that we really need to use is not known until the window is actually
|
||||
// shown, as is the case for TLWs with recent GTK versions, as it will
|
||||
// update the size again when it does become known, if necessary.
|
||||
virtual void WXSetInitialFittingClientSize(int flags);
|
||||
|
||||
// get the handle of the window for the underlying window system: this
|
||||
// is only used for wxWin itself or for user code which wants to call
|
||||
// platform-specific APIs
|
||||
|
@@ -999,31 +999,12 @@ wxSize wxSizer::ComputeFittingWindowSize(wxWindow *window)
|
||||
return window->ClientToWindowSize(ComputeFittingClientSize(window));
|
||||
}
|
||||
|
||||
#ifdef __WXGTK3__
|
||||
static void FitOnShow(wxShowEvent& event)
|
||||
{
|
||||
wxWindow* win = static_cast<wxWindow*>(event.GetEventObject());
|
||||
wxSizer* sizer = win->GetSizer();
|
||||
if (sizer)
|
||||
sizer->Fit(win);
|
||||
win->Unbind(wxEVT_SHOW, FitOnShow);
|
||||
}
|
||||
#endif
|
||||
|
||||
wxSize wxSizer::Fit( wxWindow *window )
|
||||
{
|
||||
wxCHECK_MSG( window, wxDefaultSize, "window can't be NULL" );
|
||||
|
||||
#ifdef __WXGTK3__
|
||||
// GTK3 updates cached style information before showing a TLW,
|
||||
// which may affect best size calculations, so add a handler to
|
||||
// redo the calculations at that time
|
||||
if (!window->IsShown() && window->IsTopLevel())
|
||||
window->Bind(wxEVT_SHOW, FitOnShow);
|
||||
#endif
|
||||
|
||||
// set client size
|
||||
window->SetClientSize(ComputeFittingClientSize(window));
|
||||
window->WXSetInitialFittingClientSize(wxSIZE_SET_CURRENT);
|
||||
|
||||
// return entire size
|
||||
return window->GetSize();
|
||||
@@ -1059,38 +1040,11 @@ void wxSizer::Layout()
|
||||
RepositionChildren(minSize);
|
||||
}
|
||||
|
||||
#ifdef __WXGTK3__
|
||||
static void SetSizeHintsOnShow(wxShowEvent& event)
|
||||
{
|
||||
wxWindow* win = static_cast<wxWindow*>(event.GetEventObject());
|
||||
wxSizer* sizer = win->GetSizer();
|
||||
if (sizer)
|
||||
sizer->SetSizeHints(win);
|
||||
win->Unbind(wxEVT_SHOW, SetSizeHintsOnShow);
|
||||
}
|
||||
#endif
|
||||
|
||||
void wxSizer::SetSizeHints( wxWindow *window )
|
||||
{
|
||||
// Preserve the window's max size hints, but set the
|
||||
// lower bound according to the sizer calculations.
|
||||
|
||||
// This is equivalent to calling Fit(), except that we need to set
|
||||
// the size hints _in between_ the two steps performed by Fit
|
||||
// (1. ComputeFittingClientSize, 2. SetClientSize). That's because
|
||||
// otherwise SetClientSize() could have no effect if there already are
|
||||
// size hints in effect that forbid requested client size.
|
||||
|
||||
#ifdef __WXGTK3__
|
||||
// see comment in Fit()
|
||||
if (!window->IsShown() && window->IsTopLevel())
|
||||
window->Bind(wxEVT_SHOW, SetSizeHintsOnShow);
|
||||
#endif
|
||||
|
||||
const wxSize clientSize = ComputeFittingClientSize(window);
|
||||
|
||||
window->SetMinClientSize(clientSize);
|
||||
window->SetClientSize(clientSize);
|
||||
window->WXSetInitialFittingClientSize(wxSIZE_SET_CURRENT | wxSIZE_SET_MIN);
|
||||
}
|
||||
|
||||
#if WXWIN_COMPATIBILITY_2_8
|
||||
|
@@ -1002,6 +1002,25 @@ wxSize wxWindowBase::WindowToClientSize(const wxSize& size) const
|
||||
size.y == -1 ? -1 : size.y - diff.y);
|
||||
}
|
||||
|
||||
void wxWindowBase::WXSetInitialFittingClientSize(int flags)
|
||||
{
|
||||
wxSizer* const sizer = GetSizer();
|
||||
if ( !sizer )
|
||||
return;
|
||||
|
||||
const wxSize
|
||||
size = sizer->ComputeFittingClientSize(static_cast<wxWindow *>(this));
|
||||
|
||||
// It is important to set the min client size before changing the size
|
||||
// itself as the existing size hints could prevent SetClientSize() from
|
||||
// working otherwise.
|
||||
if ( flags & wxSIZE_SET_MIN )
|
||||
SetMinClientSize(size);
|
||||
|
||||
if ( flags & wxSIZE_SET_CURRENT )
|
||||
SetClientSize(size);
|
||||
}
|
||||
|
||||
void wxWindowBase::SetWindowVariant( wxWindowVariant variant )
|
||||
{
|
||||
if ( m_windowVariant != variant )
|
||||
|
@@ -612,6 +612,10 @@ void wxTopLevelWindowGTK::Init()
|
||||
m_incWidth = m_incHeight = 0;
|
||||
|
||||
m_urgency_hint = -2;
|
||||
|
||||
#ifdef __WXGTK3__
|
||||
m_pendingFittingClientSizeFlags = 0;
|
||||
#endif // __WXGTK3__
|
||||
}
|
||||
|
||||
bool wxTopLevelWindowGTK::Create( wxWindow *parent,
|
||||
@@ -1161,6 +1165,12 @@ bool wxTopLevelWindowGTK::Show( bool show )
|
||||
bool change = base_type::Show(show);
|
||||
|
||||
#ifdef __WXGTK3__
|
||||
if (change && show)
|
||||
{
|
||||
// We may need to redo it after showing the window.
|
||||
GTKUpdateClientSizeIfNecessary();
|
||||
}
|
||||
|
||||
if (m_needSizeEvent)
|
||||
{
|
||||
m_needSizeEvent = false;
|
||||
@@ -1525,8 +1535,41 @@ void wxTopLevelWindowGTK::GTKDoAfterShow()
|
||||
wxShowEvent showEvent(GetId(), true);
|
||||
showEvent.SetEventObject(this);
|
||||
HandleWindowEvent(showEvent);
|
||||
|
||||
#ifdef __WXGTK3__
|
||||
// Set the client size again if necessary, we should be able to do it
|
||||
// correctly by now as the style cache should be up to date.
|
||||
GTKUpdateClientSizeIfNecessary();
|
||||
#endif // __WXGTK3__
|
||||
}
|
||||
|
||||
#ifdef __WXGTK3__
|
||||
|
||||
void wxTopLevelWindowGTK::GTKUpdateClientSizeIfNecessary()
|
||||
{
|
||||
if ( m_pendingFittingClientSizeFlags )
|
||||
{
|
||||
WXSetInitialFittingClientSize(m_pendingFittingClientSizeFlags);
|
||||
|
||||
m_pendingFittingClientSizeFlags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void wxTopLevelWindowGTK::WXSetInitialFittingClientSize(int flags)
|
||||
{
|
||||
// In any case, update the size immediately.
|
||||
wxTopLevelWindowBase::WXSetInitialFittingClientSize(flags);
|
||||
|
||||
// But if we're not shown yet, the fitting size may be wrong because GTK
|
||||
// style cache hasn't been updated yet and we need to do it again when the
|
||||
// window becomes visible as we can be sure that by then we'll be able to
|
||||
// compute the best size correctly.
|
||||
if ( !IsShown() )
|
||||
m_pendingFittingClientSizeFlags = flags;
|
||||
}
|
||||
|
||||
#endif // __WXGTK3__
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// frame title/icon
|
||||
// ----------------------------------------------------------------------------
|
||||
|
Reference in New Issue
Block a user