From 9b6aebe842c0ceb0200de241c95c036b13f72f42 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Sun, 5 Mar 2017 16:42:40 +0100 Subject: Prevent duplicate self-delete. debug-prints indicat it was at least possible for the same Window to receive FloatingTextEntry::entry_focus_out twice (without idle) --- gtk2_ardour/floating_text_entry.cc | 37 +++++++++++++++++++++++-------------- gtk2_ardour/floating_text_entry.h | 3 +++ 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/gtk2_ardour/floating_text_entry.cc b/gtk2_ardour/floating_text_entry.cc index 571969d2dc..29be2ef774 100644 --- a/gtk2_ardour/floating_text_entry.cc +++ b/gtk2_ardour/floating_text_entry.cc @@ -41,17 +41,17 @@ FloatingTextEntry::FloatingTextEntry (Gtk::Window* parent, const std::string& in } entry.show (); - entry.signal_changed().connect (sigc::mem_fun (*this, &FloatingTextEntry::changed)); - entry.signal_activate().connect (sigc::mem_fun (*this, &FloatingTextEntry::activated)); - entry.signal_key_press_event().connect (sigc::mem_fun (*this, &FloatingTextEntry::key_press), false); - entry.signal_key_release_event().connect (sigc::mem_fun (*this, &FloatingTextEntry::key_release), false); - entry.signal_button_press_event().connect (sigc::mem_fun (*this, &FloatingTextEntry::button_press)); - entry.signal_populate_popup().connect (sigc::mem_fun (*this, &FloatingTextEntry::populate_popup)); + _connections.push_back (entry.signal_changed().connect (sigc::mem_fun (*this, &FloatingTextEntry::changed))); + _connections.push_back (entry.signal_activate().connect (sigc::mem_fun (*this, &FloatingTextEntry::activated))); + _connections.push_back (entry.signal_key_press_event().connect (sigc::mem_fun (*this, &FloatingTextEntry::key_press), false)); + _connections.push_back (entry.signal_key_release_event().connect (sigc::mem_fun (*this, &FloatingTextEntry::key_release), false)); + _connections.push_back (entry.signal_button_press_event().connect (sigc::mem_fun (*this, &FloatingTextEntry::button_press))); + _connections.push_back (entry.signal_populate_popup().connect (sigc::mem_fun (*this, &FloatingTextEntry::populate_popup))); entry.select_region (0, -1); if (parent) { - parent->signal_focus_out_event().connect (sigc::mem_fun (*this, &FloatingTextEntry::entry_focus_out)); + _connections.push_back (parent->signal_focus_out_event().connect (sigc::mem_fun (*this, &FloatingTextEntry::entry_focus_out))); } add (entry); @@ -90,7 +90,7 @@ FloatingTextEntry::entry_focus_out (GdkEventFocus* ev) use_text (entry.get_text (), 0); } - delete_when_idle ( this); + idle_delete_self (); return false; } @@ -111,7 +111,7 @@ FloatingTextEntry::button_press (GdkEventButton* ev) use_text (entry.get_text (), 0); } - delete_when_idle ( this); + idle_delete_self (); return false; } @@ -120,7 +120,7 @@ void FloatingTextEntry::activated () { use_text (entry.get_text(), 0); // EMIT SIGNAL - delete_when_idle (this); + idle_delete_self (); } bool @@ -143,7 +143,7 @@ FloatingTextEntry::key_release (GdkEventKey* ev) switch (ev->keyval) { case GDK_Escape: /* cancel edit */ - delete_when_idle (this); + idle_delete_self (); return true; case GDK_ISO_Left_Tab: @@ -152,12 +152,12 @@ FloatingTextEntry::key_release (GdkEventKey* ev) * ev->state. */ use_text (entry.get_text(), -1); // EMIT SIGNAL, move to prev - delete_when_idle (this); + idle_delete_self (); return true; case GDK_Tab: use_text (entry.get_text(), 1); // EMIT SIGNAL, move to next - delete_when_idle (this); + idle_delete_self (); return true; default: break; @@ -177,6 +177,15 @@ FloatingTextEntry::on_hide () method of cancelling the edit. */ - delete_when_idle (this); + idle_delete_self (); Gtk::Window::on_hide (); } + +void +FloatingTextEntry::idle_delete_self () +{ + for (std::list::iterator i = _connections.begin(); i != _connections.end(); ++i) { + i->disconnect (); + } + delete_when_idle (this); +} diff --git a/gtk2_ardour/floating_text_entry.h b/gtk2_ardour/floating_text_entry.h index 764d1fce37..d70185a8a6 100644 --- a/gtk2_ardour/floating_text_entry.h +++ b/gtk2_ardour/floating_text_entry.h @@ -49,6 +49,9 @@ private: bool button_press (GdkEventButton*); void changed (); void populate_popup (Gtk::Menu*); + void idle_delete_self (); + + std::list _connections; /* handlers for window events */ -- cgit v1.2.3