From f62c8c664d9e7419e4af2ca39b1767ddbb8fc709 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Thu, 20 Jul 2017 23:41:18 +0200 Subject: Fix crash when renaming track to an invalid name If the "Sorry I cannot do that" dialog is displayed from FloatingTextEntry::use_text(), the entry is still visible and accepts [focus] events. Also the dialog returns focus and multiple idle_delete_self() will be called for an Entry that's already being deleted. --- gtk2_ardour/floating_text_entry.cc | 42 ++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) (limited to 'gtk2_ardour/floating_text_entry.cc') diff --git a/gtk2_ardour/floating_text_entry.cc b/gtk2_ardour/floating_text_entry.cc index 29be2ef774..3dc74fe796 100644 --- a/gtk2_ardour/floating_text_entry.cc +++ b/gtk2_ardour/floating_text_entry.cc @@ -87,7 +87,8 @@ FloatingTextEntry::entry_focus_out (GdkEventFocus* ev) entry.remove_modal_grab (); if (entry_changed) { - use_text (entry.get_text (), 0); + disconect_signals (); + use_text (entry.get_text (), 0); /* EMIT SIGNAL */ } idle_delete_self (); @@ -108,7 +109,8 @@ FloatingTextEntry::button_press (GdkEventButton* ev) Glib::signal_idle().connect (sigc::bind_return (sigc::bind (sigc::ptr_fun (gtk_main_do_event), gdk_event_copy ((GdkEvent*) ev)), false)); if (entry_changed) { - use_text (entry.get_text (), 0); + disconect_signals (); + use_text (entry.get_text (), 0); /* EMIT SIGNAL */ } idle_delete_self (); @@ -119,6 +121,7 @@ FloatingTextEntry::button_press (GdkEventButton* ev) void FloatingTextEntry::activated () { + disconect_signals (); use_text (entry.get_text(), 0); // EMIT SIGNAL idle_delete_self (); } @@ -151,11 +154,13 @@ FloatingTextEntry::key_release (GdkEventKey* ev) * generates a different ev->keyval, rather than setting * ev->state. */ + disconect_signals (); use_text (entry.get_text(), -1); // EMIT SIGNAL, move to prev idle_delete_self (); return true; case GDK_Tab: + disconect_signals (); use_text (entry.get_text(), 1); // EMIT SIGNAL, move to next idle_delete_self (); return true; @@ -173,19 +178,40 @@ FloatingTextEntry::on_hide () entry.remove_modal_grab (); /* No hide button is shown (no decoration on the window), - so being hidden is equivalent to the Escape key or any other - method of cancelling the edit. - */ - - idle_delete_self (); + * so being hidden is equivalent to the Escape key or any other + * method of cancelling the edit. + * + * This is also used during disconect_signals() before calling + * use_text (). see note below. + * + * If signals are already disconnected, idle-delete must be + * in progress already. + */ + if (!_connections.empty ()) { + idle_delete_self (); + } Gtk::Window::on_hide (); } void -FloatingTextEntry::idle_delete_self () +FloatingTextEntry::disconect_signals () { for (std::list::iterator i = _connections.begin(); i != _connections.end(); ++i) { i->disconnect (); } + /* the entry is floating on-top, emitting use_text() + * may result in another dialog being shown (cannot rename track) + * which would + * - be stacked below the floating text entry + * - return focus to the entry when closedA + * so we hide the entry here. + */ + hide (); +} + +void +FloatingTextEntry::idle_delete_self () +{ + disconect_signals (); delete_when_idle (this); } -- cgit v1.2.3