From 4422a9bd88602c8dfde8648ad39692d968295cfc Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Tue, 11 Jun 2019 08:54:34 +0200 Subject: QWidget: don't set WA_PendingMoveEvent when geometry does not change When the geometry of a hidden widget was set with setGeometry(), WA_PendingMoveEvent and WA_PendingResizeEvent were set unconditionally even if the crect already had the correct value. This lead to unneeded Move/Resize events within sendPendingMoveAndResizeEvents(). Fixes: QTBUG-75475 Fixes: QTBUG-79906 Change-Id: Ibbe03882f039948b6b7c04887420741ed2e9c0f7 Reviewed-by: Friedemann Kleint Reviewed-by: Shawn Rutledge Reviewed-by: Richard Moe Gustavsen --- src/widgets/kernel/qwidget.cpp | 11 ++++++-- tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp | 34 +++++++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index e9968e41b4..5a0ea58cf8 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -7005,8 +7005,10 @@ void QWidget::resize(const QSize &s) d->setGeometry_sys(geometry().x(), geometry().y(), s.width(), s.height(), false); d->setDirtyOpaqueRegion(); } else { + const auto oldRect = data->crect; data->crect.setSize(s.boundedTo(maximumSize()).expandedTo(minimumSize())); - setAttribute(Qt::WA_PendingResizeEvent); + if (oldRect != data->crect) + setAttribute(Qt::WA_PendingResizeEvent); } } @@ -7021,10 +7023,13 @@ void QWidget::setGeometry(const QRect &r) d->setGeometry_sys(r.x(), r.y(), r.width(), r.height(), true); d->setDirtyOpaqueRegion(); } else { + const auto oldRect = data->crect; data->crect.setTopLeft(r.topLeft()); data->crect.setSize(r.size().boundedTo(maximumSize()).expandedTo(minimumSize())); - setAttribute(Qt::WA_PendingMoveEvent); - setAttribute(Qt::WA_PendingResizeEvent); + if (oldRect != data->crect) { + setAttribute(Qt::WA_PendingMoveEvent); + setAttribute(Qt::WA_PendingResizeEvent); + } } if (d->extra && d->extra->hasWindowContainer) diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 882323ba4f..67fdd13652 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -198,6 +199,7 @@ private slots: void hideWhenFocusWidgetIsChild(); void normalGeometry(); void setGeometry(); + void setGeometryHidden(); void windowOpacity(); void raise(); void lower(); @@ -2922,6 +2924,38 @@ void tst_QWidget::setGeometry() QCOMPARE(tlw.geometry(), tr); } +void tst_QWidget::setGeometryHidden() +{ + if (QGuiApplication::styleHints()->showIsMaximized()) + QSKIP("Platform does not support QWidget::setGeometry() - skipping"); + + QWidget tlw; + tlw.setWindowTitle(QLatin1String(QTest::currentTestFunction())); + QWidget child(&tlw); + + const QRect tr(m_availableTopLeft + QPoint(100, 100), 2 * m_testWidgetSize); + const QRect cr(QPoint(50, 50), m_testWidgetSize); + tlw.setGeometry(tr); + child.setGeometry(cr); + tlw.showNormal(); + + tlw.hide(); + QTRY_VERIFY(tlw.isHidden()); + tlw.setGeometry(cr); + QVERIFY(tlw.testAttribute(Qt::WA_PendingMoveEvent)); + QVERIFY(tlw.testAttribute(Qt::WA_PendingResizeEvent)); + QImage img(tlw.size(), QImage::Format_ARGB32); // just needed to call QWidget::render() + tlw.render(&img); + QVERIFY(!tlw.testAttribute(Qt::WA_PendingMoveEvent)); + QVERIFY(!tlw.testAttribute(Qt::WA_PendingResizeEvent)); + tlw.setGeometry(cr); + QVERIFY(!tlw.testAttribute(Qt::WA_PendingMoveEvent)); + QVERIFY(!tlw.testAttribute(Qt::WA_PendingResizeEvent)); + tlw.resize(cr.size()); + QVERIFY(!tlw.testAttribute(Qt::WA_PendingMoveEvent)); + QVERIFY(!tlw.testAttribute(Qt::WA_PendingResizeEvent)); +} + void tst_QWidget::windowOpacity() { QWidget widget; -- cgit v1.2.3