From db475be55f3601df17cdbec766eee7eb6582628a Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Wed, 24 Nov 2004 16:33:39 +0000
Subject: [PATCH] Use the new Fl::delete_widget() call to delete widgets in
 callbacks in FLTK 1.1.6. FLTK 1.1.5 introduced a potential crash due the fact
 that it could access a widget's data after its callback was executed.
 Fl::delete_widget() in 1.1.6 delays the deletion until the next Fl::wait()
 call. In any case, this means that we cannot use group.clear() anymore.

---
 Common/GmshUI.h |  3 +++
 Fltk/GUI.cpp    | 35 ++++++++++++++++++++++++++++-------
 2 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/Common/GmshUI.h b/Common/GmshUI.h
index 44f7a45b48..fffe86509e 100644
--- a/Common/GmshUI.h
+++ b/Common/GmshUI.h
@@ -23,6 +23,9 @@
 #if defined(HAVE_FLTK)
 #  include <FL/Fl.H>
 #  if (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 1)
+#    if (FL_PATCH_VERSION >= 6)
+#      define HAVE_FLTK_1_1_6_OR_ABOVE
+#    endif
 #    if (FL_PATCH_VERSION >= 5)
 #      define HAVE_FLTK_1_1_5_OR_ABOVE
 #    endif
diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp
index dfe72994fa..aa59bc1fc5 100644
--- a/Fltk/GUI.cpp
+++ b/Fltk/GUI.cpp
@@ -1,4 +1,4 @@
-// $Id: GUI.cpp,v 1.383 2004-11-19 18:26:47 geuzaine Exp $
+// $Id: GUI.cpp,v 1.384 2004-11-24 16:33:39 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -996,32 +996,53 @@ void GUI::set_context(Context_Item * menu_asked, int flag)
 
   Msg(STATUS2N, menu[0].label + 1);
 
-  // free all the children (m_push*, m_toggle*, m_pop*)
-#if defined(HAVE_FLTK_1_1_5_OR_ABOVE)
-  m_scroll->clear();
-#else
-  // Fl_Scroll.clear() is broken in old versions of FLTK...
+  // Remove all the children (m_push*, m_toggle*, m_pop*). FLTK <=
+  // 1.1.4 should be OK wih this. FLTK 1.1.5 may crash as it may
+  // access a widget's data after its callback is executed (we call
+  // set_context in the button callbacks!). FLTK 1.1.6 introduced a
+  // fix (Fl::delete_widget) to delay the deletion until the next
+  // Fl::wait call. In any case, we cannot use m_scroll->clear()
+  // (broken in < 1.1.5, potential crasher in >= 1.1.5).
   for(unsigned int i = 0; i < m_push_butt.size(); i++){
     m_scroll->remove(m_push_butt[i]);
+#if defined(HAVE_FLTK_1_1_6_OR_ABOVE)
+    Fl::delete_widget(m_push_butt[i]);
+#else
     delete m_push_butt[i];
+#endif
   }
   for(unsigned int i = 0; i < m_toggle_butt.size(); i++){
     m_scroll->remove(m_toggle_butt[i]);
+#if defined(HAVE_FLTK_1_1_6_OR_ABOVE)
+    Fl::delete_widget(m_toggle_butt[i]);
+#else
     delete m_toggle_butt[i];
+#endif
   }
   for(unsigned int i = 0; i < m_toggle2_butt.size(); i++){
     m_scroll->remove(m_toggle2_butt[i]);
+#if defined(HAVE_FLTK_1_1_6_OR_ABOVE)
+    Fl::delete_widget(m_toggle2_butt[i]);
+#else
     delete m_toggle2_butt[i];
+#endif
   }
   for(unsigned int i = 0; i < m_popup_butt.size(); i++){
     m_scroll->remove(m_popup_butt[i]);
+#if defined(HAVE_FLTK_1_1_6_OR_ABOVE)
+    Fl::delete_widget(m_popup_butt[i]);
+#else
     delete m_popup_butt[i];
+#endif
   }
   for(unsigned int i = 0; i < m_popup2_butt.size(); i++){
     m_scroll->remove(m_popup2_butt[i]);
+#if defined(HAVE_FLTK_1_1_6_OR_ABOVE)
+    Fl::delete_widget(m_popup2_butt[i]);
+#else
     delete m_popup2_butt[i];
-  }
 #endif
+  }
 
   // reset the vectors
   m_push_butt.clear();
-- 
GitLab