summaryrefslogtreecommitdiffstats
path: root/tests/auto/widgets
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2021-06-10 17:42:54 +0200
committerLaszlo Agocs <laszlo.agocs@qt.io>2021-06-18 15:14:02 +0200
commite6a969954a9e6865e5f662acd1d949561f8ef3be (patch)
treeeb0e77db06be3ce75fc90f11fabeeaf389c8dc5e /tests/auto/widgets
parent29789ff0eabc2ea91a21526c475e5a8c0126a7af (diff)
Do not alter a widget's backing window's format once created
Changing anything on a QWindow's QSurfaceFormat has zero and null effects once the underlying native window has been created. Letting QWidget update the format is wrong in this case, because we always expect that the value returned from QWindow::format() reflects reality. (reality being the settings with which the underlying native resource was created, which is typically frozen after QWindow::create(), not the state of some QWidget attribute. There are certain exceptions to this, such as when preparing to recreate the underlying native window, in which case one will want to update all relevant fields of the format based on the current values of the widget attributes, which is exactly what QWidgetPrivate::create() implements, and that's good.) Such a mismatch can have fatal consequences when OpenGL and friends are involved, but this always depends heavily on the platform and windowing system. For example, claiming that the alpha buffer size is 0 when the native window was created with 8, or vice versa, can break OpenGL-related code (both in Qt itself and in applications), that tries to create a QOpengGLContext configured based on what QWindow::format() returns. If that format describes settings that are incompatible with the actual underlying native window, we end up with the classic Invalid pixel format, EGL_BAD_MATCH, and alike errors. This is exactly what is happening when a QOpenGLWidget (or QQuickWidget) is placed in a QDockWidget where one of the ancestors is forced to native (winId() was called or WA_NativeWindow was set). When undocking, various code paths in QWidget will try to update the opaque flag of the widget, which in turn calls updateIsTranslucent. Now, if this function unconditionally changes the alphaBufferSize in the QWindow's QSurfaceFormat (even though this is completely futile to do, it has no visible effect in practice), we get the problem described above: rendering breaking down due to OpenGL contexts created with a pixel format incompatible with the native window. Prevent all this by not touching the format once the QWindow has a QPlatformWindow. This is the right thing to do, regardless of the bug in question: a window's (or context's or any other native resource wrapping class's) format must describe the underlying native resource and must never deviate, unless we are preparing to create a new native resource underneath. When it comes to the autotest, this changes the test added in 555661b625c40f21a6a3e4c73e928a6e8a46db20: the autotest logic is inverted because what we should test for is that the QSurfaceFormat stays untouched once the application makes a - futile - attribute change on the widget. Fixes: QTBUG-85714 Pick-to: 6.2 6.1 Change-Id: I7bf90711867e8a0fd474895625bf9530a7821fd5 Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io> Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'tests/auto/widgets')
-rw-r--r--tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp11
1 files changed, 8 insertions, 3 deletions
diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
index 8992a0b051..7ca08993ab 100644
--- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
+++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
@@ -9316,10 +9316,15 @@ void tst_QWidget::translucentWidget()
QCOMPARE(actual,expected);
const QWindow *window = label.windowHandle();
- const QSurfaceFormat translucentFormat = window->requestedFormat();
+ const QSurfaceFormat translucentFormat = window->format();
label.setAttribute(Qt::WA_TranslucentBackground, false);
- const QSurfaceFormat opaqueFormat = window->requestedFormat();
- QVERIFY(translucentFormat != opaqueFormat);
+ // Changing WA_TranslucentBackground with an already created native window
+ // has no effect since Qt 5.0 due to the introduction of QWindow et al.
+ // This means that the change must *not* be reflected in the
+ // QSurfaceFormat, because there is no change when it comes to the
+ // underlying native window. Otherwise the state would no longer
+ // describe reality (the native window) See QTBUG-85714.
+ QVERIFY(translucentFormat == window->format());
}
class MaskResizeTestWidget : public QWidget