From ceb21d5e8659e3bf77393613382ac4f775df27e7 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 18 Jul 2020 17:51:41 +0200 Subject: [PATCH] Also call wxAuiManager::UnInit() when manager itself is destroyed This completes the changes of the previous commit and should ensure that UnInit() is always called, whoever is destroyed first -- the managed window or the manager itself. Also update the documentation to mention that calling UnInit() explicitly is not necessary any longer. --- interface/wx/aui/framemanager.h | 11 ++++++----- samples/aui/auidemo.cpp | 7 ------- src/aui/framemanager.cpp | 9 ++++++--- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/interface/wx/aui/framemanager.h b/interface/wx/aui/framemanager.h index 14c05fe6d5..7f25e9e12f 100644 --- a/interface/wx/aui/framemanager.h +++ b/interface/wx/aui/framemanager.h @@ -484,11 +484,12 @@ public: void StartPaneDrag(wxWindow* paneWindow, const wxPoint& offset); /** - Uninitializes the framework and should be called before a managed frame or - window is destroyed. UnInit() is usually called in the managed wxFrame's - destructor. It is necessary to call this function before the managed frame - or window is destroyed, otherwise the manager cannot remove its custom event - handlers from a window. + Dissociate the managed window from the manager. + + This function may be called before the managed frame or window is + destroyed, but, since wxWidgets 3.1.4, it's unnecessary to call it + explicitly, as it will be called automatically when this window is + destroyed, as well as when the manager itself is. */ void UnInit(); diff --git a/samples/aui/auidemo.cpp b/samples/aui/auidemo.cpp index 492f0ba61b..008a26427a 100644 --- a/samples/aui/auidemo.cpp +++ b/samples/aui/auidemo.cpp @@ -116,8 +116,6 @@ public: const wxSize& size = wxDefaultSize, long style = wxDEFAULT_FRAME_STYLE | wxSUNKEN_BORDER); - ~MyFrame(); - wxAuiDockArt* GetDockArt(); void DoUpdate(); @@ -1016,11 +1014,6 @@ MyFrame::MyFrame(wxWindow* parent, m_mgr.Update(); } -MyFrame::~MyFrame() -{ - m_mgr.UnInit(); -} - wxAuiDockArt* MyFrame::GetDockArt() { return m_mgr.GetArtProvider(); diff --git a/src/aui/framemanager.cpp b/src/aui/framemanager.cpp index 247ab756e2..e9aed4e5f0 100644 --- a/src/aui/framemanager.cpp +++ b/src/aui/framemanager.cpp @@ -633,6 +633,8 @@ wxAuiManager::wxAuiManager(wxWindow* managed_wnd, unsigned int flags) wxAuiManager::~wxAuiManager() { + UnInit(); + // NOTE: It's possible that the windows have already been destroyed by the // time this dtor is called, so this loop can result in memory access via // invalid pointers, resulting in a crash. So it will be disabled while @@ -953,9 +955,10 @@ void wxAuiManager::SetManagedWindow(wxWindow* wnd) } -// UnInit() must be called, usually in the destructor -// of the frame class. If it is not called, usually this -// will result in a crash upon program exit +// UnInit() is called automatically by wxAuiManager itself when either the +// manager itself or its associated frame is destroyed, but can also be called +// explicitly, so make it safe to call it multiple times and just do nothing +// during any calls but the first one. void wxAuiManager::UnInit() { if (m_frame)