From c887bbf123755307affd2020f722a8325794c9e4 Mon Sep 17 00:00:00 2001 From: Christian Rohlfs Date: Fri, 17 Mar 2023 03:57:00 +0500 Subject: [PATCH 1/3] Improve Layers an Objects dialog performance By deferring update on selection change to Glib idle event. --- src/ui/dialog/objects.cpp | 24 ++++++++++++++++++------ src/ui/dialog/objects.h | 3 +++ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index 01363c5f92..2b6206ca84 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -905,8 +905,8 @@ ObjectsPanel::ObjectsPanel() // Before expanding a row, replace the dummy child with the actual children _tree.signal_test_expand_row().connect([this](const Gtk::TreeModel::iterator &iter, const Gtk::TreeModel::Path &) { if (cleanDummyChildren(*iter)) { - if (auto selection = getSelection()) { - selectionChanged(selection); + if (getSelection()) { + _selectionChanged(); } } return false; @@ -1015,7 +1015,7 @@ void ObjectsPanel::setRootWatcher() root_watcher = new ObjectWatcher(this, document->getRoot(), nullptr, filtered); root_watcher->rememberExtendedItems(); layerChanged(getDesktop()->layerManager().currentLayer()); - selectionChanged(getSelection()); + _selectionChanged(); } } @@ -1085,13 +1085,22 @@ ObjectWatcher *ObjectsPanel::unpackToObject(SPObject *item) return watcher; } -void ObjectsPanel::selectionChanged(Selection *selected) +void ObjectsPanel::selectionChanged(Selection *selected /* not used */) +{ + if (!_selection_changed_connected) { + Glib::signal_idle().connect_once(sigc::mem_fun(*this, &ObjectsPanel::_selectionChanged), + G_PRIORITY_HIGH_IDLE); + _selection_changed_connected = true; + } +} + +void ObjectsPanel::_selectionChanged() { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); root_watcher->setSelectedBitRecursive(SELECTED_OBJECT, false); bool keep_current_item = false; - for (auto item : selected->items()) { + for (auto item : getSelection()->items()) { keep_current_item |= (item == current_item); // Failing to find the watchers here means the object is filtered out // of the current object view and can be safely skipped. @@ -1114,6 +1123,8 @@ void ObjectsPanel::selectionChanged(Selection *selected) if (!keep_current_item) { current_item = nullptr; } + _scroll_lock = false; + _selection_changed_connected = false; } /** @@ -1724,6 +1735,8 @@ bool ObjectsPanel::on_drag_drop(const Glib::RefPtr &context, i void ObjectsPanel::on_drag_start(const Glib::RefPtr &context) { + _scroll_lock = true; + auto selection = _tree.get_selection(); selection->set_mode(Gtk::SELECTION_MULTIPLE); selection->unselect_all(); @@ -1803,7 +1816,6 @@ bool ObjectsPanel::selectCursorItem(unsigned int state) } selection->set(item); } - _scroll_lock = false; return true; } return false; diff --git a/src/ui/dialog/objects.h b/src/ui/dialog/objects.h index e59d7f9bb9..44ec2aed5c 100644 --- a/src/ui/dialog/objects.h +++ b/src/ui/dialog/objects.h @@ -178,6 +178,9 @@ private: PrefCheckButton& _setting_layers; PrefCheckButton& _setting_track; bool _drag_flip; + + void _selectionChanged(); + bool _selection_changed_connected = false; }; -- GitLab From e4b0d786fc5e5fd29386d74197b4dc9f7ed9a4c2 Mon Sep 17 00:00:00 2001 From: Christian Rohlfs Date: Fri, 17 Mar 2023 03:57:00 +0500 Subject: [PATCH 2/3] Improve Layers and Objects dialog performance By deferring update on selection change to Glib idle event. --- src/ui/dialog/objects.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index 2b6206ca84..30125f5f6a 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -1085,11 +1085,14 @@ ObjectWatcher *ObjectsPanel::unpackToObject(SPObject *item) return watcher; } +// Same definition as in 'document.cpp' +#define SP_DOCUMENT_UPDATE_PRIORITY (G_PRIORITY_HIGH_IDLE - 2) + void ObjectsPanel::selectionChanged(Selection *selected /* not used */) { if (!_selection_changed_connected) { Glib::signal_idle().connect_once(sigc::mem_fun(*this, &ObjectsPanel::_selectionChanged), - G_PRIORITY_HIGH_IDLE); + SP_DOCUMENT_UPDATE_PRIORITY + 1); _selection_changed_connected = true; } } -- GitLab From 696238ee2d284e65aa7c56b0b4ca538ec21f99b7 Mon Sep 17 00:00:00 2001 From: Christian Rohlfs Date: Fri, 17 Mar 2023 03:57:00 +0500 Subject: [PATCH 3/3] Improve Layers and Objects dialog performance By deferring update on selection change to Glib idle event. --- src/ui/dialog/objects.cpp | 14 ++++++++------ src/ui/dialog/objects.h | 5 ++--- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index 30125f5f6a..991a98b9a6 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -1090,14 +1090,14 @@ ObjectWatcher *ObjectsPanel::unpackToObject(SPObject *item) void ObjectsPanel::selectionChanged(Selection *selected /* not used */) { - if (!_selection_changed_connected) { - Glib::signal_idle().connect_once(sigc::mem_fun(*this, &ObjectsPanel::_selectionChanged), - SP_DOCUMENT_UPDATE_PRIORITY + 1); - _selection_changed_connected = true; + if (!_idle_connection.connected()) { + auto handler = sigc::mem_fun(*this, &ObjectsPanel::_selectionChanged); + int priority = SP_DOCUMENT_UPDATE_PRIORITY + 1; + _idle_connection = Glib::signal_idle().connect(handler, priority); } } -void ObjectsPanel::_selectionChanged() +bool ObjectsPanel::_selectionChanged() { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); root_watcher->setSelectedBitRecursive(SELECTED_OBJECT, false); @@ -1127,7 +1127,9 @@ void ObjectsPanel::_selectionChanged() current_item = nullptr; } _scroll_lock = false; - _selection_changed_connected = false; + + // Returning 'false' disconnects idle signal handler + return false; } /** diff --git a/src/ui/dialog/objects.h b/src/ui/dialog/objects.h index 44ec2aed5c..5a19a53737 100644 --- a/src/ui/dialog/objects.h +++ b/src/ui/dialog/objects.h @@ -32,7 +32,6 @@ #include "selection.h" #include "style-enums.h" #include "color-rgba.h" -#include "helper/auto-connection.h" using Inkscape::XML::Node; using namespace Inkscape::UI::Widget; @@ -179,8 +178,8 @@ private: PrefCheckButton& _setting_track; bool _drag_flip; - void _selectionChanged(); - bool _selection_changed_connected = false; + bool _selectionChanged(); + auto_connection _idle_connection; }; -- GitLab