From: Robin Dunn Date: Tue, 12 Apr 2005 05:18:20 +0000 (+0000) Subject: checked in just John's patch, will keep working my fixes... X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/276612f7e4f0d7dd103000d065adef58537aa708 checked in just John's patch, will keep working my fixes... git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@33538 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/popupwin.h b/include/wx/popupwin.h index 9cd390d2fa..b02debc98f 100644 --- a/include/wx/popupwin.h +++ b/include/wx/popupwin.h @@ -124,6 +124,9 @@ protected: // remove our event handlers void PopHandlers(); + // get alerted when child gets deleted from under us + void OnDestroy(wxWindowDestroyEvent& event); + // the child of this popup if any wxWindow *m_child; diff --git a/src/common/popupcmn.cpp b/src/common/popupcmn.cpp index 47099f03ba..50b97f5080 100644 --- a/src/common/popupcmn.cpp +++ b/src/common/popupcmn.cpp @@ -66,7 +66,8 @@ IMPLEMENT_DYNAMIC_CLASS(wxPopupTransientWindow, wxPopupWindow) class wxPopupWindowHandler : public wxEvtHandler { public: - wxPopupWindowHandler(wxPopupTransientWindow *popup) { m_popup = popup; } + wxPopupWindowHandler(wxPopupTransientWindow *popup) : m_popup(popup) {} + ~wxPopupWindowHandler(); protected: // event handlers @@ -82,10 +83,8 @@ private: class wxPopupFocusHandler : public wxEvtHandler { public: - wxPopupFocusHandler(wxPopupTransientWindow *popup) - { - m_popup = popup; - } + wxPopupFocusHandler(wxPopupTransientWindow *popup) : m_popup(popup) {} + ~wxPopupFocusHandler(); protected: void OnKillFocus(wxFocusEvent& event); @@ -244,6 +243,10 @@ void wxPopupTransientWindow::Popup(wxWindow *winFocus) Show(); + // There is is a problem if these are still valid + wxASSERT_MSG(!m_handlerPopup, wxT("Popup handler not deleted")); + wxASSERT_MSG(!m_handlerFocus, wxT("Focus handler not deleted")); + delete m_handlerPopup; m_handlerPopup = new wxPopupWindowHandler(this); @@ -272,6 +275,14 @@ void wxPopupTransientWindow::Popup(wxWindow *winFocus) PushEventHandler(m_handlerFocus); #endif // __WXMSW__ + // catch destroy events, if you close a program with a popup shown in MSW + // you get a segfault if m_child or m_focus are deleted before this is + m_child->Connect(wxEVT_DESTROY, + wxWindowDestroyEventHandler(wxPopupTransientWindow::OnDestroy), + NULL, this); + m_focus->Connect(wxEVT_DESTROY, + wxWindowDestroyEventHandler(wxPopupTransientWindow::OnDestroy), + NULL, this); } bool wxPopupTransientWindow::Show( bool show ) @@ -354,6 +365,14 @@ bool wxPopupTransientWindow::ProcessLeftDown(wxMouseEvent& WXUNUSED(event)) return false; } +void wxPopupTransientWindow::OnDestroy(wxWindowDestroyEvent& event) +{ + if (event.GetEventObject() == m_child) + m_child = NULL; + if (event.GetEventObject() == m_focus) + m_focus = NULL; +} + #if wxUSE_COMBOBOX && defined(__WXUNIVERSAL__) // ---------------------------------------------------------------------------- @@ -411,6 +430,11 @@ void wxPopupComboWindow::OnKeyDown(wxKeyEvent& event) // ---------------------------------------------------------------------------- // wxPopupWindowHandler // ---------------------------------------------------------------------------- +wxPopupWindowHandler::~wxPopupWindowHandler() +{ + if (m_popup && (m_popup->m_handlerPopup == this)) + m_popup->m_handlerPopup = NULL; +} void wxPopupWindowHandler::OnLeftDown(wxMouseEvent& event) { @@ -499,6 +523,11 @@ void wxPopupWindowHandler::OnLeftDown(wxMouseEvent& event) // ---------------------------------------------------------------------------- // wxPopupFocusHandler // ---------------------------------------------------------------------------- +wxPopupFocusHandler::~wxPopupFocusHandler() +{ + if (m_popup && (m_popup->m_handlerFocus == this)) + m_popup->m_handlerFocus = NULL; +} void wxPopupFocusHandler::OnKillFocus(wxFocusEvent& event) {