]> git.saurik.com Git - wxWidgets.git/commitdiff
checked in just John's patch, will keep working my fixes...
authorRobin Dunn <robin@alldunn.com>
Tue, 12 Apr 2005 05:18:20 +0000 (05:18 +0000)
committerRobin Dunn <robin@alldunn.com>
Tue, 12 Apr 2005 05:18:20 +0000 (05:18 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@33538 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/popupwin.h
src/common/popupcmn.cpp

index 9cd390d2fad91fe03c4f5647550c56dbb5392e3c..b02debc98f72be12f270c681a9ccbdad7650f052 100644 (file)
@@ -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;
 
index 47099f03ba83a6ad5c332fb783e65abccfbca095..50b97f508074bbcdeda1e5619bbce1e3fcce1470 100644 (file)
@@ -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)
 {