From 5d10fd84eb9d95f4176ba1165632d0a60ab7a49f Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Wed, 15 Jun 2022 02:24:03 +0200 Subject: [PATCH] Reduce mixer redraws, and fix scrolling to newly added tracks PresentationInfo::Change (Properties::selected) is emitted and handled before Mixer_UI::add_routes() is called. At that point in time the MixerStrip(s) to be selected may not exist. Visual selection state was lost. Furthermore move_stripable_into_view() calling translate_coordinates() only works after GTK has completed the resize operation. This lead to the mixer scrolling back to the left edge when creating new tracks. Also each selection change caused all tracks to be re-packed. Now redisplay_track_list() is only called if visibility or order changes. This signficanly improves performance with large sessions. --- gtk2_ardour/mixer_ui.cc | 68 +++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 29 deletions(-) diff --git a/gtk2_ardour/mixer_ui.cc b/gtk2_ardour/mixer_ui.cc index a64be59b2d..44e462bba2 100644 --- a/gtk2_ardour/mixer_ui.cc +++ b/gtk2_ardour/mixer_ui.cc @@ -677,6 +677,7 @@ Mixer_UI::add_stripables (StripableList& slist) } strip = new MixerStrip (*this, _session, route); + strip->set_selected (route->is_selected ()); strips.push_back (strip); UIConfiguration::instance().get_default_narrow_ms() ? _strip_width = Narrow : _strip_width = Wide; @@ -716,14 +717,20 @@ Mixer_UI::add_stripables (StripableList& slist) track_display.set_model (track_model); - /* catch up on selection state, which we left to the editor to set */ - sync_treeview_from_presentation_info (PropertyChange (Properties::selected)); - if (!from_scratch) { sync_presentation_info_from_treeview (); } redisplay_track_list (); + + if (!from_scratch) { + /* Mixer_UI::move_stripable_into_view() can only correctly calculate + * the scroll offset after the layout was updated. + * We update update after the resize operation (+10), but before drawing (+20) + * https://docs.gtk.org/glib/const.PRIORITY_HIGH_IDLE.html + */ + Glib::signal_idle().connect (sigc::bind_return (sigc::bind (sigc::mem_fun (*this, &Mixer_UI::sync_treeview_from_presentation_info), PropertyChange (Properties::selected)), false), G_PRIORITY_HIGH_IDLE + 15); + } } void @@ -891,44 +898,49 @@ Mixer_UI::sync_treeview_from_presentation_info (PropertyChange const & what_chan * order for the GUI, so reorder the treeview model to match it. */ - vector neworder; - TreeModel::Children rows = track_model->children(); - uint32_t old_order = 0; - bool changed = false; + if (what_changed.contains (Properties::order)) { + vector neworder; + TreeModel::Children rows = track_model->children(); + uint32_t old_order = 0; + bool changed = false; - if (rows.empty()) { - return; - } + if (rows.empty()) { + return; + } - TreeOrderKeys sorted; - for (TreeModel::Children::iterator ri = rows.begin(); ri != rows.end(); ++ri, ++old_order) { - boost::shared_ptr stripable = (*ri)[stripable_columns.stripable]; - sorted.push_back (TreeOrderKey (old_order, stripable)); - } + TreeOrderKeys sorted; + for (TreeModel::Children::iterator ri = rows.begin(); ri != rows.end(); ++ri, ++old_order) { + boost::shared_ptr stripable = (*ri)[stripable_columns.stripable]; + sorted.push_back (TreeOrderKey (old_order, stripable)); + } - TreeOrderKeySorter cmp; + TreeOrderKeySorter cmp; - sort (sorted.begin(), sorted.end(), cmp); - neworder.assign (sorted.size(), 0); + sort (sorted.begin(), sorted.end(), cmp); + neworder.assign (sorted.size(), 0); - uint32_t n = 0; + uint32_t n = 0; - for (TreeOrderKeys::iterator sr = sorted.begin(); sr != sorted.end(); ++sr, ++n) { + for (TreeOrderKeys::iterator sr = sorted.begin(); sr != sorted.end(); ++sr, ++n) { - neworder[n] = sr->old_display_order; + neworder[n] = sr->old_display_order; - if (sr->old_display_order != n) { - changed = true; + if (sr->old_display_order != n) { + changed = true; + } + } + + if (changed) { + Unwinder uw (ignore_track_reorder, true); + track_model->reorder (neworder); } } - if (changed) { - Unwinder uw (ignore_track_reorder, true); - track_model->reorder (neworder); + if (what_changed.contains (Properties::order) || what_changed.contains (Properties::hidden)) { + redisplay_track_list (); } if (what_changed.contains (Properties::selected)) { - PresentationInfo::ChangeSuspender cs; for (list::const_iterator i = strips.begin(); i != strips.end(); ++i) { @@ -958,8 +970,6 @@ Mixer_UI::sync_treeview_from_presentation_info (PropertyChange const & what_chan } } } - - redisplay_track_list (); } void