From fd897629bf698c9efb4628188db79f2937ef3d89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Tue, 13 Jun 2017 12:09:59 +0100 Subject: [PATCH] Fix moving a hidden QOpenGLWidget to another window A visibile QOpenGLWidget receives a QEvent::WindowChangeInternal which triggers a QOpenGLWidget::reset(). A hidden QOpenGLWidget never received this event so it was never reset, resulting in a black rendering. Includes unit-test that fails without this patch. Change-Id: I9d2c57d66fa629f631a9829a5ebf4de09998ad75 Task-Id: QTBUG-60896 Reviewed-by: Laszlo Agocs --- src/widgets/kernel/qopenglwidget.cpp | 2 ++ src/widgets/kernel/qwidget.cpp | 2 +- .../qopenglwidget/tst_qopenglwidget.cpp | 31 +++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp index 9aab0bd76a..218d3c4a46 100644 --- a/src/widgets/kernel/qopenglwidget.cpp +++ b/src/widgets/kernel/qopenglwidget.cpp @@ -1342,6 +1342,8 @@ bool QOpenGLWidget::event(QEvent *e) break; if (d->initialized) d->reset(); + if (isHidden()) + break; // FALLTHROUGH case QEvent::Show: // reparenting may not lead to a resize so reinitalize on Show too if (!d->initialized && !size().isEmpty() && window() && window()->windowHandle()) { diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 1265052281..d4cbe81c2d 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -10511,7 +10511,7 @@ static void sendWindowChangeToTextureChildrenRecursively(QWidget *widget) for (int i = 0; i < d->children.size(); ++i) { QWidget *w = qobject_cast(d->children.at(i)); - if (w && !w->isWindow() && !w->isHidden() && QWidgetPrivate::get(w)->textureChildSeen) + if (w && !w->isWindow() && QWidgetPrivate::get(w)->textureChildSeen) sendWindowChangeToTextureChildrenRecursively(w); } } diff --git a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp index f51c566f20..2a05900adc 100644 --- a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp +++ b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp @@ -55,6 +55,7 @@ private slots: void painter(); void reparentToAlreadyCreated(); void reparentToNotYetCreated(); + void reparentHidden(); void asViewport(); void requestUpdate(); void fboRedirect(); @@ -279,6 +280,36 @@ void tst_QOpenGLWidget::reparentToNotYetCreated() QVERIFY(image.pixel(20, 10) == qRgb(0, 0, 255)); } +void tst_QOpenGLWidget::reparentHidden() +{ + // Tests QTBUG-60896 + QWidget topLevel1; + + QWidget *container = new QWidget(&topLevel1); + PainterWidget *glw = new PainterWidget(container); + topLevel1.resize(640, 480); + glw->resize(320, 200); + topLevel1.show(); + + glw->hide(); // Explicitly hidden + + QTest::qWaitForWindowExposed(&topLevel1); + + QWidget topLevel2; + topLevel2.resize(640, 480); + topLevel2.show(); + QTest::qWaitForWindowExposed(&topLevel2); + + QOpenGLContext *originalContext = glw->context(); + QVERIFY(originalContext); + + container->setParent(&topLevel2); + glw->show(); // Should get a new context now + + QOpenGLContext *newContext = glw->context(); + QVERIFY(originalContext != newContext); +} + class CountingGraphicsView : public QGraphicsView { public: