QWidgetWindow: Ensure Qt::WA_Mapped is set on obscured parent widgets

Frameless obscured windows do not receive WM_PAINT/expose events on
Windows. Qt::WA_Mapped needs to be set on them to ensure updating works.

Task-number: QTBUG-39220
Task-number: QTBUG-52039
Task-number: QTBUG-58575
Task-number: QTBUG-63927
Change-Id: Ic6c11f2be96378b6a6b61296f1f3e13cd49b50a6
Reviewed-by: Andy Shaw <andy.shaw@qt.io>
bb10
Friedemann Kleint 2016-11-29 14:34:03 +01:00
parent 5be5b798b2
commit cf0ea18ac4
2 changed files with 33 additions and 0 deletions

View File

@ -977,7 +977,10 @@ void QWidgetWindow::handleExposeEvent(QExposeEvent *event)
}
if (exposed) {
// QTBUG-39220, QTBUG-58575: set all (potentially fully obscured parent widgets) mapped.
m_widget->setAttribute(Qt::WA_Mapped);
for (QWidget *p = m_widget->parentWidget(); p && !p->testAttribute(Qt::WA_Mapped); p = p->parentWidget())
p->setAttribute(Qt::WA_Mapped);
if (!event->region().isNull())
wPriv->syncBackingStore(event->region());
} else {

View File

@ -44,6 +44,8 @@
#include <qmainwindow.h>
#include <qtoolbar.h>
#include <private/qwindow_p.h>
#include <private/qguiapplication_p.h>
#include <qpa/qplatformintegration.h>
#include <QtTest/private/qtesthelpers_p.h>
@ -79,6 +81,7 @@ private slots:
void tst_showWithoutActivating();
void tst_paintEventOnSecondShow();
void tst_exposeObscuredMapped_QTBUG39220();
void tst_paintEventOnResize_QTBUG50796();
#if QT_CONFIG(draganddrop)
@ -377,6 +380,33 @@ void tst_QWidget_window::tst_paintEventOnSecondShow()
QTRY_VERIFY(w.paintEventCount > 0);
}
void tst_QWidget_window::tst_exposeObscuredMapped_QTBUG39220()
{
const auto integration = QGuiApplicationPrivate::platformIntegration();
if (!integration->hasCapability(QPlatformIntegration::MultipleWindows)
|| !integration->hasCapability(QPlatformIntegration::NonFullScreenWindows)
|| QGuiApplication::platformName() == QLatin1String("winrt")) {
QSKIP("The platform does not have the required capabilities");
}
// QTBUG-39220: Fully obscured parent widgets may not receive expose
// events (as is the case for frameless, obscured parents on Windows).
// Ensure Qt::WA_Mapped is set so updating works.
const QRect availableGeometry = QGuiApplication::primaryScreen()->availableGeometry();
const QSize size = availableGeometry.size() / 6;
QWidget topLevel;
setFrameless(&topLevel);
topLevel.resize(size);
const QPoint sizeP(size.width(), size.height());
topLevel.move(availableGeometry.center() - sizeP / 2);
QWidget *child = new QWidget(&topLevel);
child->resize(size);
child->move(0, 0);
QVERIFY(child->winId());
topLevel.show();
QTRY_VERIFY(child->testAttribute(Qt::WA_Mapped));
QVERIFY(topLevel.testAttribute(Qt::WA_Mapped));
}
void tst_QWidget_window::tst_paintEventOnResize_QTBUG50796()
{
const QRect availableGeo = QGuiApplication::primaryScreen()->availableGeometry();