X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Ffloating_text_entry.cc;h=e22e77982c493916495eea39c658ba7100d75906;hb=f90a70e774726a5d67fa462cab06637d4baeabc8;hp=29be2ef774756bb01902777d51c280f2b58932d5;hpb=9b6aebe842c0ceb0200de241c95c036b13f72f42;p=ardour.git diff --git a/gtk2_ardour/floating_text_entry.cc b/gtk2_ardour/floating_text_entry.cc index 29be2ef774..e22e77982c 100644 --- a/gtk2_ardour/floating_text_entry.cc +++ b/gtk2_ardour/floating_text_entry.cc @@ -28,13 +28,14 @@ #include "pbd/i18n.h" FloatingTextEntry::FloatingTextEntry (Gtk::Window* parent, const std::string& initial_contents) - : Gtk::Window (Gtk::WINDOW_POPUP) - , entry_changed (false) - , by_popup_menu (false) + : Gtk::Window () + , entry_changed (false) { //set_name (X_("FloatingTextEntry")); set_position (Gtk::WIN_POS_MOUSE); set_border_width (0); + set_type_hint(Gdk::WINDOW_TYPE_HINT_POPUP_MENU); + set_resizable (false); if (!initial_contents.empty()) { entry.set_text (initial_contents); @@ -46,23 +47,16 @@ FloatingTextEntry::FloatingTextEntry (Gtk::Window* parent, const std::string& in _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) { - _connections.push_back (parent->signal_focus_out_event().connect (sigc::mem_fun (*this, &FloatingTextEntry::entry_focus_out))); + set_transient_for (*parent); } add (entry); } -void -FloatingTextEntry::populate_popup (Gtk::Menu *) -{ - by_popup_menu = true; -} - void FloatingTextEntry::changed () { @@ -74,20 +68,17 @@ FloatingTextEntry::on_realize () { Gtk::Window::on_realize (); get_window()->set_decorations (Gdk::WMDecoration (0)); + set_keep_above (true); entry.add_modal_grab (); } bool FloatingTextEntry::entry_focus_out (GdkEventFocus* ev) { - if (by_popup_menu) { - by_popup_menu = false; - return false; - } - 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 +99,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 +111,7 @@ FloatingTextEntry::button_press (GdkEventButton* ev) void FloatingTextEntry::activated () { + disconect_signals (); use_text (entry.get_text(), 0); // EMIT SIGNAL idle_delete_self (); } @@ -151,11 +144,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 +168,41 @@ 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 (); } + _connections.clear (); + /* 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); }