diff options
author | Robin Gareus <robin@gareus.org> | 2014-11-29 01:35:49 +0100 |
---|---|---|
committer | Robin Gareus <robin@gareus.org> | 2014-11-29 10:06:25 +0100 |
commit | 58663db3743dbb5feddd9fc4221e7a328ef3b4ed (patch) | |
tree | 540cc34efde1549482e91f68390e1e7d727468d9 | |
parent | 784b96e255e67f5166e1c610dea950eaf0a1f025 (diff) |
change ownership of processor window-proxy
fixes crashes:
* If the Editor-Mixer shows a channel with a plugin that
has been edited in the Mixer, double-clicking the plugin
will try to bring up a 2nd instance of the plugin-UI.
* When closing Ardour both the Mixer and the Editor-Mixer try to delete the underlying plugin, resulting in a double free.
-rw-r--r-- | gtk2_ardour/processor_box.cc | 128 | ||||
-rw-r--r-- | gtk2_ardour/processor_box.h | 7 | ||||
-rw-r--r-- | libs/ardour/ardour/processor.h | 5 | ||||
-rw-r--r-- | libs/ardour/processor.cc | 9 |
4 files changed, 30 insertions, 119 deletions
diff --git a/gtk2_ardour/processor_box.cc b/gtk2_ardour/processor_box.cc index 1a9cc87214..6c6f62ed58 100644 --- a/gtk2_ardour/processor_box.cc +++ b/gtk2_ardour/processor_box.cc @@ -1272,19 +1272,10 @@ ProcessorBox::processor_operation (ProcessorOperation op) ProcessorWindowProxy* ProcessorBox::find_window_proxy (boost::shared_ptr<Processor> processor) const { - for (list<ProcessorWindowProxy*>::const_iterator i = _processor_window_info.begin(); i != _processor_window_info.end(); ++i) { - boost::shared_ptr<Processor> p = (*i)->processor().lock(); - - if (p && p == processor) { - return (*i); - } - } - - return 0; + return processor->window_proxy(); } - bool ProcessorBox::processor_button_press_event (GdkEventButton *ev, ProcessorEntry* child) { @@ -1611,56 +1602,7 @@ ProcessorBox::redisplay_processors () &_visible_prefader_processors, &fader_seen)); _route->foreach_processor (sigc::mem_fun (*this, &ProcessorBox::add_processor_to_display)); - - for (ProcessorWindowProxies::iterator i = _processor_window_info.begin(); i != _processor_window_info.end(); ++i) { - (*i)->marked = false; - } - _route->foreach_processor (sigc::mem_fun (*this, &ProcessorBox::maybe_add_processor_to_ui_list)); - - /* trim dead wood from the processor window proxy list */ - - ProcessorWindowProxies::iterator i = _processor_window_info.begin(); - while (i != _processor_window_info.end()) { - ProcessorWindowProxies::iterator j = i; - ++j; - - if (!(*i)->valid()) { - - WM::Manager::instance().remove (*i); - delete *i; - _processor_window_info.erase (i); - - } else if (!(*i)->marked) { - - /* this processor is no longer part of this processor - * box. - * - * that could be because it was deleted or it could be - * because the route being displayed in the parent - * strip changed. - * - * The latter only happens with the editor mixer strip. - */ - - if (is_editor_mixer_strip()) { - - /* editor mixer strip .. DO NOTHING - * - * note: the processor window stays visible if - * it is already visible - */ - } else { - (*i)->hide (); - WM::Manager::instance().remove (*i); - delete *i; - _processor_window_info.erase (i); - } - } - - i = j; - } - setup_entry_positions (); } @@ -1674,24 +1616,14 @@ ProcessorBox::maybe_add_processor_to_ui_list (boost::weak_ptr<Processor> w) if (!p) { return; } - - ProcessorWindowProxies::iterator i = _processor_window_info.begin (); - while (i != _processor_window_info.end()) { - - boost::shared_ptr<Processor> t = (*i)->processor().lock (); - - if (p == t) { - /* this processor is already on the list; done */ - (*i)->marked = true; - return; - } - - ++i; + if (p->window_proxy()) { + return; } /* not on the list; add it */ string loc; +#if 0 // is this still needed? Why? if (_parent_strip) { if (_parent_strip->mixer_owned()) { loc = X_("M"); @@ -1701,6 +1633,9 @@ ProcessorBox::maybe_add_processor_to_ui_list (boost::weak_ptr<Processor> w) } else { loc = X_("P"); } +#else + loc = X_("P"); +#endif ProcessorWindowProxy* wp = new ProcessorWindowProxy ( string_compose ("%1-%2-%3", loc, _route->id(), p->id()), @@ -1713,19 +1648,13 @@ ProcessorBox::maybe_add_processor_to_ui_list (boost::weak_ptr<Processor> w) wp->set_state (*ui_xml); } - wp->marked = true; - - /* if the processor already has an existing UI, - note that so that we don't recreate it - */ - void* existing_ui = p->get_ui (); if (existing_ui) { wp->use_window (*(reinterpret_cast<Gtk::Window*>(existing_ui))); } - _processor_window_info.push_back (wp); + p->set_window_proxy (wp); WM::Manager::instance().register_window (wp); } @@ -2841,16 +2770,10 @@ ProcessorBox::generate_processor_title (boost::shared_ptr<PluginInsert> pi) Window * ProcessorBox::get_processor_ui (boost::shared_ptr<Processor> p) const { - list<ProcessorWindowProxy*>::const_iterator i = _processor_window_info.begin (); - while (i != _processor_window_info.end()) { - boost::shared_ptr<Processor> t = (*i)->processor().lock (); - if (t && t == p) { - return (*i)->get (); - } - - ++i; + ProcessorWindowProxy* wp = p->window_proxy(); + if (wp) { + return wp->get (); } - return 0; } @@ -2861,24 +2784,9 @@ ProcessorBox::get_processor_ui (boost::shared_ptr<Processor> p) const void ProcessorBox::set_processor_ui (boost::shared_ptr<Processor> p, Gtk::Window* w) { - list<ProcessorWindowProxy*>::iterator i = _processor_window_info.begin (); - + assert (p->window_proxy()); p->set_ui (w); - - while (i != _processor_window_info.end()) { - boost::shared_ptr<Processor> t = (*i)->processor().lock (); - if (t && t == p) { - (*i)->use_window (*w); - return; - } - - ++i; - } - - /* we shouldn't get here, because the ProcessorUIList should always contain - an entry for each processor. - */ - assert (false); + p->window_proxy()->use_window (*w); } void @@ -2953,12 +2861,10 @@ ProcessorBox::is_editor_mixer_strip() const ProcessorWindowProxy::ProcessorWindowProxy (string const & name, ProcessorBox* box, boost::weak_ptr<Processor> processor) : WM::ProxyBase (name, string()) - , marked (false) , _processor_box (box) , _processor (processor) , is_custom (false) , want_custom (false) - , _valid (true) { boost::shared_ptr<Processor> p = _processor.lock (); if (!p) { @@ -2981,7 +2887,7 @@ ProcessorWindowProxy::processor_going_away () { delete _window; _window = 0; - _valid = false; + WM::Manager::instance().remove (this); /* should be no real reason to do this, since the object that would send DropReferences is about to be deleted, but lets do it anyway. */ @@ -2995,12 +2901,6 @@ ProcessorWindowProxy::session_handle() return 0; } -bool -ProcessorWindowProxy::valid() const -{ - return _valid; -} - XMLNode& ProcessorWindowProxy::get_state () const { diff --git a/gtk2_ardour/processor_box.h b/gtk2_ardour/processor_box.h index a40b8e7bb5..9622011654 100644 --- a/gtk2_ardour/processor_box.h +++ b/gtk2_ardour/processor_box.h @@ -91,9 +91,6 @@ class ProcessorWindowProxy : public WM::ProxyBase void toggle(); void set_custom_ui_mode(bool use_custom) { want_custom = use_custom; } - bool marked; - bool valid () const; - void set_state (const XMLNode&); XMLNode& get_state () const; @@ -442,8 +439,8 @@ class ProcessorBox : public Gtk::HBox, public PluginInterestedObject, public ARD void route_property_changed (const PBD::PropertyChange&); std::string generate_processor_title (boost::shared_ptr<ARDOUR::PluginInsert> pi); - typedef std::list<ProcessorWindowProxy*> ProcessorWindowProxies; - ProcessorWindowProxies _processor_window_info; + //typedef std::list<ProcessorWindowProxy*> ProcessorWindowProxies; + //ProcessorWindowProxies _processor_window_info; ProcessorWindowProxy* find_window_proxy (boost::shared_ptr<ARDOUR::Processor>) const; diff --git a/libs/ardour/ardour/processor.h b/libs/ardour/ardour/processor.h index 85d466a169..4f8434f179 100644 --- a/libs/ardour/ardour/processor.h +++ b/libs/ardour/ardour/processor.h @@ -35,6 +35,7 @@ #include "ardour/automatable.h" class XMLNode; +class ProcessorWindowProxy; namespace ARDOUR { @@ -114,6 +115,9 @@ class LIBARDOUR_API Processor : public SessionObject, public Automatable, public void set_ui (void*); void* get_ui () const { return _ui_pointer; } + ProcessorWindowProxy * window_proxy () const { return _window_proxy; } + void set_window_proxy (ProcessorWindowProxy* wp); + void set_owner (SessionObject*); SessionObject* owner() const; @@ -129,6 +133,7 @@ protected: bool _display_to_user; bool _pre_fader; ///< true if this processor is currently placed before the Amp, otherwise false void* _ui_pointer; + ProcessorWindowProxy *_window_proxy; SessionObject* _owner; }; diff --git a/libs/ardour/processor.cc b/libs/ardour/processor.cc index d571f55688..ca1f71db5a 100644 --- a/libs/ardour/processor.cc +++ b/libs/ardour/processor.cc @@ -63,6 +63,7 @@ Processor::Processor(Session& session, const string& name) , _display_to_user (true) , _pre_fader (false) , _ui_pointer (0) + , _window_proxy (0) , _owner (0) { } @@ -79,6 +80,8 @@ Processor::Processor (const Processor& other) , _display_to_user (true) , _pre_fader (false) , _ui_pointer (0) + , _window_proxy (0) + , _owner (0) { } @@ -272,6 +275,12 @@ Processor::set_ui (void* p) } void +Processor::set_window_proxy (ProcessorWindowProxy* wp) +{ + _window_proxy = wp; +} + +void Processor::set_owner (SessionObject* o) { _owner = o; |