From 3860f76dc10943fbf729b586be7dcce594620a87 Mon Sep 17 00:00:00 2001 From: jolavillette Date: Sat, 25 Jul 2026 08:40:05 +0200 Subject: [PATCH] gui(forums): create reload timer before setGroupId (fix ctor SIGSEGV) The coalescing timer was allocated near the end of the constructor, but setGroupId(forumId) is called earlier and synchronously reaches groupIdChanged() -> updateDisplay(true) -> mDeferredReloadTimer->stop(), dereferencing the still-uninitialised pointer and crashing the moment a forum was opened. Allocate the timer right after setupUi(), before setGroupId(). Co-Authored-By: Claude Opus 4.8 (1M context) --- .../src/gui/gxsforums/GxsForumThreadWidget.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp index a7de911c9..2e75199cf 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp @@ -254,6 +254,13 @@ GxsForumThreadWidget::GxsForumThreadWidget(const RsGxsGroupId &forumId, QWidget { ui->setupUi(this); + // Single-shot timer used to coalesce the full-forum reloads requested by + // incoming GXS events (see scheduleForumReload()). Created first thing: + // setGroupId(forumId) below reaches updateDisplay(), which touches this timer. + mDeferredReloadTimer = new QTimer(this); + mDeferredReloadTimer->setSingleShot(true); + connect(mDeferredReloadTimer, &QTimer::timeout, this, [this]() { updateDisplay(true); }); + //setUpdateWhenInvisible(true); //mUpdating = false; @@ -375,12 +382,6 @@ GxsForumThreadWidget::GxsForumThreadWidget(const RsGxsGroupId &forumId, QWidget ui->threadTreeWidget->enableColumnCustomize(true); #endif - // Single-shot timer used to coalesce the full-forum reloads requested by - // incoming GXS events (see scheduleForumReload()). - mDeferredReloadTimer = new QTimer(this); - mDeferredReloadTimer->setSingleShot(true); - connect(mDeferredReloadTimer, &QTimer::timeout, this, [this]() { updateDisplay(true); }); - mEventHandlerId = 0; // Needs to be asynced because this function is called by another thread! rsEvents->registerEventsHandler(