Skip to content

Invalid access in singleShot timer #718

@anoymouserver

Description

@anoymouserver

If the DockWidget is removed before the eventloop is executed, the lambda in the singleShot still is enqueued in the eventloop but captured a pointer to the widget which is no longer valid.
This could happen for example if the initial layout is changed while loading a config file during application startup befor app.exec()

QTimer::singleShot(0, _this, [&, TabWidget]
{
_this->ensureWidgetVisible(TabWidget);
});

To reproduce I've modified the demo application:

diff --git a/demo/MainWindow.cpp b/demo/MainWindow.cpp
index 77c3af2..4bfa50a 100644
--- a/demo/MainWindow.cpp
+++ b/demo/MainWindow.cpp
@@ -579,6 +579,10 @@ void MainWindowPrivate::createContent()
        DockWidget = createQQuickWidget();
        DockWidget->setFeature(ads::CDockWidget::DockWidgetClosable, true);
        DockManager->addDockWidget(ads::LeftDockWidgetArea, DockWidget);
+
+    // Remove the last dock widget and delete it
+    DockManager->removeDockWidget(DockWidget);
+    delete DockWidget; // since it has no parent and has been removed from the DockManager, we have to delete it manually
 }

The following does mitigate the invalid pointer but it's just another workaround for the workaround of #520:

diff --git a/src/DockAreaTabBar.cpp b/src/DockAreaTabBar.cpp
index 724aedc..324073f 100644
--- a/src/DockAreaTabBar.cpp
+++ b/src/DockAreaTabBar.cpp
@@ -98,7 +98,7 @@ void DockAreaTabBarPrivate::updateTabs()
        // Set active TAB and update all other tabs to be inactive
        for (int i = 0; i < _this->count(); ++i)
        {
-               auto TabWidget = _this->tab(i);
+               QPointer<CDockWidgetTab> TabWidget(_this->tab(i));
                if (!TabWidget)
                {
                        continue;

Environment:
ADS: 7d9f9b4
Qt: 5.15.11 and 6.8.2
OS: Windows

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions