From 1c25a4c2aef8c001e48a99df271d72d1372ce398 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 13 Jun 2013 13:57:28 +0000 Subject: [PATCH 1/1] Use two step creation of wxListHeaderWindow to avoid reentrancy under OSX. This improves the solution of the problem already solved in r74197 by separating setting of m_headerWin variable from the window creation instead of using an explicit recursion check. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74231 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/generic/private/listctrl.h | 17 ++++++----- src/generic/listctrl.cpp | 42 +++++++++++++-------------- 2 files changed, 30 insertions(+), 29 deletions(-) diff --git a/include/wx/generic/private/listctrl.h b/include/wx/generic/private/listctrl.h index 2267ca3dd7..d7aa7883e5 100644 --- a/include/wx/generic/private/listctrl.h +++ b/include/wx/generic/private/listctrl.h @@ -336,13 +336,16 @@ protected: public: wxListHeaderWindow(); - wxListHeaderWindow( wxWindow *win, - wxWindowID id, - wxListMainWindow *owner, - const wxPoint &pos = wxDefaultPosition, - const wxSize &size = wxDefaultSize, - long style = 0, - const wxString &name = wxT("wxlistctrlcolumntitles") ); + // We provide only Create(), not the ctor, because we need to create the + // C++ object before creating the window, see the explanations in + // CreateOrDestroyHeaderWindowAsNeeded() + bool Create( wxWindow *win, + wxWindowID id, + wxListMainWindow *owner, + const wxPoint &pos = wxDefaultPosition, + const wxSize &size = wxDefaultSize, + long style = 0, + const wxString &name = wxT("wxlistctrlcolumntitles") ); virtual ~wxListHeaderWindow(); diff --git a/src/generic/listctrl.cpp b/src/generic/listctrl.cpp index bf9448a331..1ababf3a26 100644 --- a/src/generic/listctrl.cpp +++ b/src/generic/listctrl.cpp @@ -952,15 +952,17 @@ wxListHeaderWindow::wxListHeaderWindow() m_resizeCursor = NULL; } -wxListHeaderWindow::wxListHeaderWindow( wxWindow *win, - wxWindowID id, - wxListMainWindow *owner, - const wxPoint& pos, - const wxSize& size, - long style, - const wxString &name ) - : wxWindow( win, id, pos, size, style, name ) -{ +bool wxListHeaderWindow::Create( wxWindow *win, + wxWindowID id, + wxListMainWindow *owner, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString &name ) +{ + if ( !wxWindow::Create(win, id, pos, size, style, name) ) + return false; + Init(); m_owner = owner; @@ -978,6 +980,8 @@ wxListHeaderWindow::wxListHeaderWindow( wxWindow *win, if (!m_hasFont) SetOwnFont( wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT )); #endif + + return true; } wxListHeaderWindow::~wxListHeaderWindow() @@ -4509,18 +4513,13 @@ void wxGenericListCtrl::CreateOrDestroyHeaderWindowAsNeeded() if (needs_header) { - // since there is no separate Create method for the wxListHeaderWindow - // we have to guard against reentrancy which happens via new wxListHeaderWindow -> - // wxNavigationEnabled::AddChild -> ToggleWindowStyle -> SetWindowStyleFlag - // since has_header is still false then - static bool blockreentrancy = false; - - if ( blockreentrancy ) - return; - - blockreentrancy = true; - - m_headerWin = new wxListHeaderWindow + // Notice that we must initialize m_headerWin first, and create the + // real window only later, so that the test in the beginning of the + // function blocks repeated creation of the header as it could happen + // before via wxNavigationEnabled::AddChild() -> ToggleWindowStyle() -> + // SetWindowStyleFlag(). + m_headerWin = new wxListHeaderWindow(); + m_headerWin->Create ( this, wxID_ANY, m_mainWin, wxPoint(0,0), @@ -4531,7 +4530,6 @@ void wxGenericListCtrl::CreateOrDestroyHeaderWindowAsNeeded() ), wxTAB_TRAVERSAL ); - blockreentrancy = false; #if defined( __WXMAC__ ) static wxFont font( wxOSX_SYSTEM_FONT_SMALL ); -- 2.45.2