summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGabriel de Dietrich <gabriel.dedietrich@qt.io>2017-06-12 16:55:03 -0700
committerGabriel de Dietrich <gabriel.dedietrich@qt.io>2017-08-23 08:42:44 +0000
commitb65e30c861af308d142c36b5f96f1a4cfedde1f3 (patch)
treea5534e7885d30c218aec056f38fffb5718fbfc9c
parent1bbad92e83d9fe4f5f75e5b232e1c06cf8bf049d (diff)
QWidget: Call appropriate QWindow method from setGeometry_sys()
When calling resize() from showEvent(), we'd set the full geometry on the widget's QWindow. This resulted in the top-level window being moved to the top-left corner, even though no other call to move() or setGeometry() had happened before. The solution consists on calling the proper QWindow methods depending on whether setGeometry_sys() is called for a move, a resize or both. Furthermore, this needs QWindow::resize() to set its position policy to frame-exclusive. The documentation states that is already the case and we're setting the full geometry on the platform window, so we need to convey that bit of information. This also solves the age-old conundrum: "### why do we have isMove as a parameter?" Change-Id: I2e00fd632929ade14b35ae5e6495ed1ab176d32f Task-number: QTBUG-56277 Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@qt.io> Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
-rw-r--r--src/gui/kernel/qwindow.cpp1
-rw-r--r--src/widgets/kernel/qwidget.cpp14
-rw-r--r--tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp31
3 files changed, 42 insertions, 4 deletions
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index eb9d7a8868..43b201e9b0 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -1759,6 +1759,7 @@ void QWindow::resize(int w, int h)
void QWindow::resize(const QSize &newSize)
{
Q_D(QWindow);
+ d->positionPolicy = QWindowPrivate::WindowFrameExclusive;
if (d->platformWindow) {
d->platformWindow->setGeometry(QHighDpi::toNativePixels(QRect(position(), newSize), this));
} else {
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index d372d69d02..11915a4a21 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -7255,7 +7255,8 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
QRect r(x, y, w, h);
bool isResize = olds != r.size();
- isMove = oldp != r.topLeft(); //### why do we have isMove as a parameter?
+ if (!isMove)
+ isMove = oldp != r.topLeft();
// We only care about stuff that changes the geometry, or may
@@ -7289,12 +7290,17 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
if (q->isVisible()) {
if (!q->testAttribute(Qt::WA_DontShowOnScreen) && !q->testAttribute(Qt::WA_OutsideWSRange)) {
- if (q->windowHandle()) {
+ if (QWindow *win = q->windowHandle()) {
if (q->isWindow()) {
- q->windowHandle()->setGeometry(q->geometry());
+ if (isResize && !isMove)
+ win->resize(w, h);
+ else if (isMove && !isResize)
+ win->setPosition(x, y);
+ else
+ win->setGeometry(q->geometry());
} else {
QPoint posInNativeParent = q->mapTo(q->nativeParentWidget(),QPoint());
- q->windowHandle()->setGeometry(QRect(posInNativeParent,r.size()));
+ win->setGeometry(QRect(posInNativeParent,r.size()));
}
if (needsShow)
diff --git a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp
index 6aaac6d135..f20978c295 100644
--- a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp
+++ b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp
@@ -99,6 +99,8 @@ private slots:
void tst_eventfilter_on_toplevel();
void QTBUG_50561_QCocoaBackingStore_paintDevice_crash();
+
+ void QTBUG_56277_resize_on_showEvent();
};
void tst_QWidget_window::initTestCase()
@@ -861,5 +863,34 @@ void tst_QWidget_window::QTBUG_50561_QCocoaBackingStore_paintDevice_crash()
w.close();
}
+class ResizedOnShowEventWidget : public QWidget
+{
+public:
+ void showEvent(QShowEvent *) override
+ {
+ const auto *primaryScreen = QApplication::primaryScreen();
+ auto newSize = primaryScreen->availableGeometry().size() / 4;
+ if (newSize == geometry().size())
+ newSize -= QSize(10, 10);
+ resize(newSize);
+ }
+};
+
+void tst_QWidget_window::QTBUG_56277_resize_on_showEvent()
+{
+ const auto platformName = QGuiApplication::platformName().toLower();
+ if (platformName != "cocoa" && platformName != "windows")
+ QSKIP("This can only be consistently tested on desktop platforms with well-known behavior.");
+
+ ResizedOnShowEventWidget w;
+ w.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&w));
+ const auto *screen = w.windowHandle()->screen();
+ const auto geometry = w.geometry();
+ const int frameHeight = geometry.top() - w.frameGeometry().top();
+ const int topmostY = screen->availableGeometry().top() + frameHeight;
+ QVERIFY(geometry.top() > topmostY || geometry.left() > screen->availableGeometry().left());
+}
+
QTEST_MAIN(tst_QWidget_window)
#include "tst_qwidget_window.moc"