Ensure transient parents are top level widgets.

When a dialog was parented on a native child widget,
its window handle was used as a transient parent.
This confused QPlatformWindow::initialGeometry() among
other things. Use top level window as is in Qt 4.

Task-number: QTBUG-40195
Change-Id: Ic82adc276175f92adde825fb2551274351e41f30
Reviewed-by: Jørgen Lind <jorgen.lind@digia.com>
This commit is contained in:
Friedemann Kleint 2014-07-14 13:53:23 +02:00
parent e2203163d9
commit a71e285133
3 changed files with 38 additions and 1 deletions

View File

@ -1083,6 +1083,11 @@ Qt::WindowState QWindow::windowState() const
void QWindow::setTransientParent(QWindow *parent)
{
Q_D(QWindow);
if (parent && !parent->isTopLevel()) {
qWarning() << Q_FUNC_INFO << parent << "must be a top level window.";
return;
}
d->transientParent = parent;
QGuiApplicationPrivate::updateBlockedStatus(this);

View File

@ -138,7 +138,7 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO
if (QWidget *nativeParent = q->nativeParentWidget()) {
if (nativeParent->windowHandle()) {
if (flags & Qt::Window) {
win->setTransientParent(nativeParent->windowHandle());
win->setTransientParent(nativeParent->window()->windowHandle());
win->setParent(0);
} else {
win->setTransientParent(0);

View File

@ -50,6 +50,7 @@
#include <QVBoxLayout>
#include <QSizeGrip>
#include <QDesktopWidget>
#include <QWindow>
#include <private/qguiapplication_p.h>
#include <qpa/qplatformtheme.h>
#include <qpa/qplatformtheme_p.h>
@ -85,6 +86,8 @@ private slots:
void setVisible();
void reject();
void snapToDefaultButton();
void transientParent_data();
void transientParent();
private:
QDialog *testWidget;
@ -584,5 +587,34 @@ void tst_QDialog::snapToDefaultButton()
#endif // !QT_NO_CURSOR
}
void tst_QDialog::transientParent_data()
{
QTest::addColumn<bool>("nativewidgets");
QTest::newRow("Non-native") << false;
QTest::newRow("Native") << true;
}
void tst_QDialog::transientParent()
{
QFETCH(bool, nativewidgets);
testWidget->hide();
QWidget topLevel;
topLevel.resize(200, 200);
topLevel.move(QGuiApplication::primaryScreen()->availableGeometry().center() - QPoint(100, 100));
QVBoxLayout *layout = new QVBoxLayout(&topLevel);
QWidget *innerWidget = new QWidget(&topLevel);
layout->addWidget(innerWidget);
if (nativewidgets)
innerWidget->winId();
topLevel.show();
QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
QDialog dialog(innerWidget);
dialog.show();
QVERIFY(QTest::qWaitForWindowExposed(&dialog));
// Transient parent should always be the top level, also when using
// native child widgets.
QCOMPARE(dialog.windowHandle()->transientParent(), topLevel.windowHandle());
}
QTEST_MAIN(tst_QDialog)
#include "tst_qdialog.moc"