Qt-Advanced-Docking-System icon indicating copy to clipboard operation
Qt-Advanced-Docking-System copied to clipboard

Crash when using QOpenGLWidget/QOpenGLWindow inside a dock together with QWebEngineView

Open martbelko opened this issue 8 months ago • 4 comments

Issue Description

When using OpenGL (QOpenGLWidget or QOpenGLWindow) within the Qt Advanced Docking System alongside QWebEngineView, the application crashes under specific reordering conditions.

This happens when there is a stack of five widgets with an OpenGL-based widget in the middle and QWebEngineView at the bottom. If a widget below the OpenGL widget is dragged across the OpenGL widget and docked to the top, and then the OpenGL widget is docked above, the application crashes.

Steps to Reproduce

  1. Create a dock layout with a stack of five dock widgets.
  2. Insert a QOpenGLWidget or QOpenGLWindow in the middle of the stack.
  3. Add a QWebEngineView as the bottom-most widget.
  4. Drag the widget immediately below the OpenGL widget upward across it and dock it to the top.
  5. Then drag the OpenGL widget and dock it above the previous one.

Environment

  • Operating System: [Windows 11]
  • Qt Version: [6.5.3]
  • OpenGL Version: [4.6]
  • Qt-Advanced-Docking-System Version: [latest]

Demo

Image

Minimal Reproducible Example:

#include <QApplication>
#include <QOpenGLWidget>
#include <QMainWindow>
#include <QtWebEngineWidgets>

#include <DockManager.h>

class MainWindow : public QMainWindow
{
public:
	MainWindow()
	{
		m_DockManager = new ads::CDockManager(this);

		QWebEngineView* w1 = new QWebEngineView();
		QWebEngineView* w2 = new QWebEngineView();
		QOpenGLWidget* glWidget = new QOpenGLWidget();
		QWidget* w3 = new QWidget();
		QWidget* w4 = new QWidget();

		ads::CDockWidget* dw1 = new ads::CDockWidget("WebView 1");
		dw1->setWidget(w1);
		ads::CDockWidget* dw2 = new ads::CDockWidget("Widget 1");
		dw2->setWidget(w2);
		ads::CDockWidget* glDw = new ads::CDockWidget("OpenGL");
		glDw->setWidget(glWidget);
		ads::CDockWidget* dw3 = new ads::CDockWidget("Widget 2");
		dw3->setWidget(w3);
		ads::CDockWidget* dw4 = new ads::CDockWidget("Widget 3");
		dw4->setWidget(w4);

		m_DockManager->addDockWidget(ads::TopDockWidgetArea, dw1);
		m_DockManager->addDockWidget(ads::TopDockWidgetArea, dw2);
		m_DockManager->addDockWidget(ads::TopDockWidgetArea, glDw);
		m_DockManager->addDockWidget(ads::TopDockWidgetArea, dw3);
		m_DockManager->addDockWidget(ads::TopDockWidgetArea, dw4);
	}
private:
	ads::CDockManager* m_DockManager;
};

int main(int argc, char* argv[])
{
	QApplication app(argc, argv);
	MainWindow window;

	window.show();

	return app.exec();
}

martbelko avatar Apr 04 '25 10:04 martbelko

Could you please check if the pull request #727 improves something for you?

githubuser0xFFFF avatar Apr 04 '25 12:04 githubuser0xFFFF

No, it is still the same.

martbelko avatar Apr 04 '25 15:04 martbelko

You should inherit from QOpenGLWidget in order to manage with the OpenGL context. See my GLWidget class in the mentionned PR.

First create a cleanup with at least these lines:


void GLWidget::cleanup()
{
    makeCurrent();
    doneCurrent();
    QObject::disconnect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &GLWidget::cleanup);
}

Then you must override initializeGL in order to connect the cleanup to the QOpenGLContext::aboutToBeDestroyed signal: connect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &GLWidget::cleanup, Qt::UniqueConnection);

Please try these modifications with the ADS version of my PR. Could you also try my OpenGL example to see if you can reproduce this issue with my example?

zyrkiel avatar Apr 15 '25 07:04 zyrkiel

Unfortunately, the issue still persists. I was able to reproduce the crash using the GLWidget class exactly as you described. Additionally, in the OpenGL example, if you start docking the OpenGL widgets randomly, then close some of them and exit the application, an error appears indicating that the OpenGLChartWidget destructor was already called.

Furthermore, I tried adding two QWebEngineView instances into the OpenGL example, and by docking them around each other in various configurations, I encountered the same type of crash as before. It seems that the problem is triggered by dynamic docking behavior involving OpenGL or WebEngine components.

martbelko avatar Apr 16 '25 07:04 martbelko

I met this issue before, and finally seem solved by using QApplication::setAttribute(Qt::AA_ShareOpenGLContexts);

Image

yiman919 avatar May 22 '25 02:05 yiman919

@yiman919 Thank you very much for your finding. I will add a section to the documentation regarding using OpenGL widgets in ADS.

githubuser0xFFFF avatar May 27 '25 07:05 githubuser0xFFFF

I addes a section to the user guide

githubuser0xFFFF avatar Jun 12 '25 21:06 githubuser0xFFFF

@githubuser0xFFFF @yiman919 Have you also tried the solution with QWebEngineView and QOpenGLWidget at the same it? Because it still crashes for me. QApplication::setAttribute(Qt::AA_ShareOpenGLContexts) did not solve the issue (maybe for QOpenGLWidget only, but using it with QWebEngineView still results in crash).

martbelko avatar Jun 17 '25 08:06 martbelko

on the application i develop this solution fixed the crashes caused by detaching and re-attaching twice an opengl window (https://github.com/aargirakis/BZRPlayer/issues/596), however introduced a regression that leads the opengl windows itself to become blank after the reattach or when switching tabs (https://github.com/aargirakis/BZRPlayer/issues/615). at this point i'm not sure if this regression is strictly related to the AA_ShareOpenGLContexts set or caused by something else

ciros88 avatar Aug 14 '25 12:08 ciros88