GLUI: add Widget::delete_later(), fixes ParamLabel related crash
authorStefan Westerfeld <stefan@space.twc.de>
Mon, 11 Mar 2019 21:12:51 +0000 (22:12 +0100)
committerStefan Westerfeld <stefan@space.twc.de>
Mon, 11 Mar 2019 21:12:51 +0000 (22:12 +0100)
Signed-off-by: Stefan Westerfeld <stefan@space.twc.de>
glui/smparamlabel.hh
glui/smwidget.cc
glui/smwidget.hh
glui/smwindow.cc
glui/smwindow.hh

index e34a2b7..02ce4ae 100644 (file)
@@ -78,7 +78,7 @@ public:
     model->set_value_text (line_edit->text());
     signal_value_changed (model->db);
     set_text (model->display_text());
-    delete line_edit;
+    line_edit->delete_later();
     line_edit = nullptr;
   }
   Signal<double> signal_value_changed;
index d49e597..00bebc7 100644 (file)
@@ -150,6 +150,14 @@ Widget::update (double x, double y, double width, double height)
     }
 }
 
+void
+Widget::delete_later()
+{
+  Window *win = window();
+  if (win)
+    win->add_delete_later (this);
+}
+
 /* Color conversion from Rapicorn */
 // This Source Code Form is licensed MPL-2.0: http://mozilla.org/MPL/2.0
 void
index 7e0b204..b34d767 100644 (file)
@@ -367,6 +367,7 @@ public:
   void   update();
   void   update_with_children();
   void   update_full();
+  void   delete_later();
 };
 
 }
index 4f99b1a..a5c108f 100644 (file)
@@ -219,6 +219,9 @@ Window::~Window()
       if (child_windows[i])
         delete child_windows[i];
     }
+  /* do not use auto here */
+  for (size_t i = 0; i < delete_later_widgets.size(); i++)
+    delete delete_later_widgets[i];
 }
 
 void
@@ -233,6 +236,11 @@ Window::on_widget_deleted (Widget *child)
     menu_widget = nullptr;
   if (keyboard_focus_widget == child)
     keyboard_focus_widget = nullptr;
+  for (auto& w : delete_later_widgets)
+    {
+      if (w == child)
+        w = nullptr;
+    }
   if (dialog_widget == child)
     {
       update_full();
@@ -529,6 +537,15 @@ Window::process_events()
     }
   cleanup_null (child_windows);
 
+  /* do not use auto here */
+  for (size_t i = 0; i < delete_later_widgets.size(); i++)
+    {
+      delete delete_later_widgets[i];
+
+      assert (!delete_later_widgets[i]);
+    }
+  cleanup_null (delete_later_widgets);
+
   if (0)
     {
       timeval tv;
@@ -1012,3 +1029,9 @@ Window::remove_shortcut (Shortcut *shortcut)
         s = nullptr;
     }
 }
+
+void
+Window::add_delete_later (Widget *widget)
+{
+  delete_later_widgets.push_back (widget);
+}
index f62c0ef..04c820d 100644 (file)
@@ -42,6 +42,7 @@ protected:
   std::vector<Timer *>      timers;
   std::vector<Shortcut *>   shortcuts;
   std::vector<Window *>     child_windows;
+  std::vector<Widget *>     delete_later_widgets;
 
   std::function<void()>     m_close_callback;
 
@@ -75,6 +76,7 @@ public:
   void remove_shortcut (Shortcut *shortcut);
   void add_child_window (Window *window);
   void remove_child_window (Window *window);
+  void add_delete_later (Widget *widget);
   Window *window() override;
   PuglNativeWindow native_window();