From b0ca91c82568d570b868f9722390e3634c3abcf0 Mon Sep 17 00:00:00 2001 From: jolavillette Date: Wed, 29 Jul 2026 12:44:54 +0200 Subject: [PATCH] gui(forums): drop the expanded-items save/restore around read-status changes setMsgReadStatus() only emits dataChanged(); it never resets the model nor changes its layout, so the expanded items and the current index survive it untouched. Saving and restoring them on every toggle was pure overhead, and an expensive one: the restore walks every expanded item and pays, for each, a linear scan of the post array plus a linear scan of the view items -- quadratic work on the GUI thread for a single post marked read or unread on a large forum. Co-Authored-By: Claude Opus 5 (1M context) --- .../src/gui/gxsforums/GxsForumThreadWidget.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp index 2e75199cf..e37f783cb 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp @@ -1485,7 +1485,6 @@ void GxsForumThreadWidget::markMsgAsReadUnread (bool read, bool children, bool f if (groupId().isNull() || !IS_GROUP_SUBSCRIBED(mForumGroup.mMeta.mSubscribeFlags)) { return; } - saveExpandedItems(mSavedExpandedMessages); QModelIndex src_index; if(forum) @@ -1497,11 +1496,15 @@ void GxsForumThreadWidget::markMsgAsReadUnread (bool read, bool children, bool f else src_index = mThreadModel->getIndexOfMessage(mThreadId); } - mThreadModel->setMsgReadStatus(src_index,read,children); - //Restore Selection - whileBlocking(ui->threadTreeWidget)->setCurrentIndex(mThreadProxyModel->mapFromSource(mThreadModel->getIndexOfMessage(mThreadId))); - recursRestoreExpandedItems(QModelIndex(),mSavedExpandedMessages); + // setMsgReadStatus() only emits dataChanged(): it never resets the model nor + // changes its layout, so neither the expanded items nor the current index are + // lost here. Saving and restoring them was pure overhead -- and not a cheap + // one: restoring walks every expanded item, and each of them costs a linear + // scan of the post array (getIndexOfMessage) plus a linear scan of the view + // items (QTreeView::setExpanded). On a forum with thousands of posts that is + // quadratic work on the GUI thread for every single post marked read. + mThreadModel->setMsgReadStatus(src_index,read,children); } void GxsForumThreadWidget::markMsgAsRead()