Crash when using QOpenGLWidget/QOpenGLWindow inside a dock together with QWebEngineView
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
- Create a dock layout with a stack of five dock widgets.
- Insert a QOpenGLWidget or QOpenGLWindow in the middle of the stack.
- Add a QWebEngineView as the bottom-most widget.
- Drag the widget immediately below the OpenGL widget upward across it and dock it to the top.
- 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
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();
}
Could you please check if the pull request #727 improves something for you?
No, it is still the same.
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?
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.
I met this issue before, and finally seem solved by using QApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
@yiman919 Thank you very much for your finding. I will add a section to the documentation regarding using OpenGL widgets in ADS.
I addes a section to the user guide
@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).
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