1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29#include "../../../shared/highdpi.h"
30
31#include <QtTest/QtTest>
32
33#include <qdialog.h>
34#include <qapplication.h>
35#include <qlineedit.h>
36#include <qpushbutton.h>
37#include <qstyle.h>
38#include <QVBoxLayout>
39#include <QSizeGrip>
40#include <QDesktopWidget>
41#include <QGraphicsProxyWidget>
42#include <QGraphicsView>
43#include <QWindow>
44#include <private/qguiapplication_p.h>
45#include <qpa/qplatformtheme.h>
46#include <qpa/qplatformtheme_p.h>
47
48QT_FORWARD_DECLARE_CLASS(QDialog)
49
50// work around function being protected
51class DummyDialog : public QDialog
52{
53public:
54 DummyDialog(): QDialog() {}
55#if QT_DEPRECATED_SINCE(5, 13)
56 using QDialog::showExtension;
57#endif
58};
59
60class tst_QDialog : public QObject
61{
62 Q_OBJECT
63public:
64 tst_QDialog();
65
66private slots:
67 void cleanup();
68 void getSetCheck();
69#if QT_DEPRECATED_SINCE(5, 13)
70 void showExtension_data();
71 void showExtension();
72#endif
73 void defaultButtons();
74 void showMaximized();
75 void showMinimized();
76 void showFullScreen();
77 void showAsTool();
78 void toolDialogPosition();
79 void deleteMainDefault();
80 void deleteInExec();
81#if QT_CONFIG(sizegrip)
82 void showSizeGrip();
83#if QT_DEPRECATED_SINCE(5, 13)
84 void showSizeGrip_deprecated();
85#endif
86#endif
87 void setVisible();
88 void reject();
89 void snapToDefaultButton();
90 void transientParent_data();
91 void transientParent();
92 void dialogInGraphicsView();
93 void keepPositionOnClose();
94};
95
96// Testing get/set functions
97void tst_QDialog::getSetCheck()
98{
99 QDialog obj1;
100#if QT_DEPRECATED_SINCE(5, 13)
101 // QWidget* QDialog::extension()
102 // void QDialog::setExtension(QWidget*)
103 QWidget *var1 = new QWidget;
104 obj1.setExtension(var1);
105 QCOMPARE(var1, obj1.extension());
106 obj1.setExtension((QWidget *)0);
107 QCOMPARE((QWidget *)0, obj1.extension());
108 // No delete var1, since setExtension takes ownership
109#endif
110
111 // int QDialog::result()
112 // void QDialog::setResult(int)
113 obj1.setResult(0);
114 QCOMPARE(0, obj1.result());
115 obj1.setResult(INT_MIN);
116 QCOMPARE(INT_MIN, obj1.result());
117 obj1.setResult(INT_MAX);
118 QCOMPARE(INT_MAX, obj1.result());
119}
120
121class ToolDialog : public QDialog
122{
123public:
124 ToolDialog(QWidget *parent = 0)
125 : QDialog(parent, Qt::Tool), mWasActive(false), mWasModalWindow(false), tId(-1) {}
126
127 bool wasActive() const { return mWasActive; }
128 bool wasModalWindow() const { return mWasModalWindow; }
129
130 int exec() {
131 tId = startTimer(interval: 300);
132 return QDialog::exec();
133 }
134protected:
135 void timerEvent(QTimerEvent *event) {
136 if (tId == event->timerId()) {
137 killTimer(id: tId);
138 mWasActive = isActiveWindow();
139 mWasModalWindow = QGuiApplication::modalWindow() == windowHandle();
140 reject();
141 }
142 }
143
144private:
145 int mWasActive;
146 bool mWasModalWindow;
147 int tId;
148};
149
150tst_QDialog::tst_QDialog()
151{
152}
153
154void tst_QDialog::cleanup()
155{
156 QVERIFY(QApplication::topLevelWidgets().isEmpty());
157}
158
159#if QT_DEPRECATED_SINCE(5, 13)
160void tst_QDialog::showExtension_data()
161{
162 QTest::addColumn<QSize>(name: "dlgSize");
163 QTest::addColumn<QSize>(name: "extSize");
164 QTest::addColumn<bool>(name: "horizontal");
165 QTest::addColumn<QSize>(name: "result");
166
167 //next we fill it with data
168 QTest::newRow( dataTag: "data0" ) << QSize(200,100) << QSize(50,50) << false << QSize(200,150);
169 QTest::newRow( dataTag: "data1" ) << QSize(200,100) << QSize(220,50) << false << QSize(220,150);
170 QTest::newRow( dataTag: "data2" ) << QSize(200,100) << QSize(50,50) << true << QSize(250,100);
171 QTest::newRow( dataTag: "data3" ) << QSize(200,100) << QSize(50,120) << true << QSize(250,120);
172}
173
174void tst_QDialog::showExtension()
175{
176 QFETCH( QSize, dlgSize );
177 QFETCH( QSize, extSize );
178 QFETCH( bool, horizontal );
179
180 DummyDialog testWidget;
181 testWidget.resize(w: 200, h: 200);
182 testWidget.setWindowTitle(QLatin1String(QTest::currentTestFunction()) + QLatin1Char(':')
183 + QLatin1String(QTest::currentDataTag()));
184 testWidget.show();
185 QVERIFY(QTest::qWaitForWindowExposed(&testWidget));
186
187 testWidget.setFixedSize( dlgSize );
188 QWidget *ext = new QWidget( &testWidget );
189 ext->setFixedSize( extSize );
190 testWidget.setExtension( ext );
191 testWidget.setOrientation( horizontal ? Qt::Horizontal : Qt::Vertical );
192
193 QCOMPARE( testWidget.size(), dlgSize );
194 QPoint oldPosition = testWidget.pos();
195
196 // show
197 testWidget.showExtension( true );
198// while ( testWidget->size() == dlgSize )
199// qApp->processEvents();
200
201 QTEST( testWidget.size(), "result" );
202
203 QCOMPARE(testWidget.pos(), oldPosition);
204
205 // hide extension. back to old size ?
206 testWidget.showExtension( false );
207 QCOMPARE( testWidget.size(), dlgSize );
208
209 testWidget.setExtension( 0 );
210}
211#endif
212
213void tst_QDialog::defaultButtons()
214{
215 DummyDialog testWidget;
216 testWidget.resize(w: 200, h: 200);
217 testWidget.setWindowTitle(QTest::currentTestFunction());
218 QLineEdit *lineEdit = new QLineEdit(&testWidget);
219 QPushButton *push = new QPushButton("Button 1", &testWidget);
220 QPushButton *pushTwo = new QPushButton("Button 2", &testWidget);
221 QPushButton *pushThree = new QPushButton("Button 3", &testWidget);
222 pushThree->setAutoDefault(false);
223
224 testWidget.show();
225 QApplication::setActiveWindow(&testWidget);
226 QVERIFY(QTest::qWaitForWindowExposed(&testWidget));
227
228 push->setDefault(true);
229 QVERIFY(push->isDefault());
230
231 pushTwo->setFocus();
232 QVERIFY(pushTwo->isDefault());
233 pushThree->setFocus();
234 QVERIFY(push->isDefault());
235 lineEdit->setFocus();
236 QVERIFY(push->isDefault());
237
238 pushTwo->setDefault(true);
239 QVERIFY(pushTwo->isDefault());
240
241 pushTwo->setFocus();
242 QVERIFY(pushTwo->isDefault());
243 lineEdit->setFocus();
244 QVERIFY(pushTwo->isDefault());
245}
246
247void tst_QDialog::showMaximized()
248{
249 QDialog dialog(0);
250 dialog.setSizeGripEnabled(true);
251#if QT_CONFIG(sizegrip)
252 QSizeGrip *sizeGrip = dialog.findChild<QSizeGrip *>();
253 QVERIFY(sizeGrip);
254#endif
255
256 dialog.showMaximized();
257 QVERIFY(dialog.isMaximized());
258 QVERIFY(dialog.isVisible());
259#if QT_CONFIG(sizegrip) && !defined(Q_OS_DARWIN) && !defined(Q_OS_HPUX)
260 QVERIFY(!sizeGrip->isVisible());
261#endif
262
263 dialog.showNormal();
264 QVERIFY(!dialog.isMaximized());
265 QVERIFY(dialog.isVisible());
266#if QT_CONFIG(sizegrip)
267 QVERIFY(sizeGrip->isVisible());
268#endif
269
270 dialog.showMaximized();
271 QVERIFY(dialog.isMaximized());
272 QVERIFY(dialog.isVisible());
273
274 dialog.hide();
275 QVERIFY(dialog.isMaximized());
276 QVERIFY(!dialog.isVisible());
277
278 dialog.setVisible(true);
279 QVERIFY(dialog.isMaximized());
280 QVERIFY(dialog.isVisible());
281
282 dialog.hide();
283 QVERIFY(dialog.isMaximized());
284 QVERIFY(!dialog.isVisible());
285
286 dialog.showMaximized();
287 QVERIFY(dialog.isMaximized());
288 QVERIFY(dialog.isVisible());
289}
290
291void tst_QDialog::showMinimized()
292{
293 QDialog dialog(0);
294
295 dialog.showMinimized();
296 QVERIFY(dialog.isMinimized());
297 QVERIFY(dialog.isVisible());
298
299 dialog.showNormal();
300 QVERIFY(!dialog.isMinimized());
301 QVERIFY(dialog.isVisible());
302
303 dialog.showMinimized();
304 QVERIFY(dialog.isMinimized());
305 QVERIFY(dialog.isVisible());
306
307 dialog.hide();
308 QVERIFY(dialog.isMinimized());
309 QVERIFY(!dialog.isVisible());
310
311 dialog.setVisible(true);
312 QVERIFY(dialog.isMinimized());
313 QVERIFY(dialog.isVisible());
314
315 dialog.hide();
316 QVERIFY(dialog.isMinimized());
317 QVERIFY(!dialog.isVisible());
318
319 dialog.showMinimized();
320 QVERIFY(dialog.isMinimized());
321 QVERIFY(dialog.isVisible());
322}
323
324void tst_QDialog::showFullScreen()
325{
326 QDialog dialog(0, Qt::X11BypassWindowManagerHint);
327 dialog.setSizeGripEnabled(true);
328#if QT_CONFIG(sizegrip)
329 QSizeGrip *sizeGrip = dialog.findChild<QSizeGrip *>();
330 QVERIFY(sizeGrip);
331#endif
332
333 dialog.showFullScreen();
334 QVERIFY(dialog.isFullScreen());
335 QVERIFY(dialog.isVisible());
336#if QT_CONFIG(sizegrip)
337 QVERIFY(!sizeGrip->isVisible());
338#endif
339
340 dialog.showNormal();
341 QVERIFY(!dialog.isFullScreen());
342 QVERIFY(dialog.isVisible());
343#if QT_CONFIG(sizegrip)
344 QVERIFY(sizeGrip->isVisible());
345#endif
346
347 dialog.showFullScreen();
348 QVERIFY(dialog.isFullScreen());
349 QVERIFY(dialog.isVisible());
350
351 dialog.hide();
352 QVERIFY(dialog.isFullScreen());
353 QVERIFY(!dialog.isVisible());
354
355 dialog.setVisible(true);
356 QVERIFY(dialog.isFullScreen());
357 QVERIFY(dialog.isVisible());
358
359 dialog.hide();
360 QVERIFY(dialog.isFullScreen());
361 QVERIFY(!dialog.isVisible());
362
363 dialog.showFullScreen();
364 QVERIFY(dialog.isFullScreen());
365 QVERIFY(dialog.isVisible());
366
367 dialog.hide();
368 QVERIFY(dialog.isFullScreen());
369 QVERIFY(!dialog.isVisible());
370}
371
372void tst_QDialog::showAsTool()
373{
374#if defined(Q_OS_UNIX)
375 QSKIP("Qt/X11: Skipped since activeWindow() is not respected by all window managers");
376#endif
377 DummyDialog testWidget;
378 testWidget.resize(w: 200, h: 200);
379 testWidget.setWindowTitle(QTest::currentTestFunction());
380 ToolDialog dialog(&testWidget);
381 testWidget.show();
382 testWidget.activateWindow();
383 QVERIFY(QTest::qWaitForWindowActive(&testWidget));
384 dialog.exec();
385#ifdef Q_OS_WINRT
386 QEXPECT_FAIL("", "As winrt does not support child widgets, the dialog is being activated"
387 "together with the main widget.", Continue);
388#endif
389 if (testWidget.style()->styleHint(stylehint: QStyle::SH_Widget_ShareActivation, opt: 0, widget: &testWidget)) {
390 QCOMPARE(dialog.wasActive(), true);
391 } else {
392 QCOMPARE(dialog.wasActive(), false);
393 }
394}
395
396// Verify that pos() returns the same before and after show()
397// for a dialog with the Tool window type.
398void tst_QDialog::toolDialogPosition()
399{
400 QDialog dialog(0, Qt::Tool);
401 dialog.move(QPoint(100,100));
402 const QPoint beforeShowPosition = dialog.pos();
403 dialog.show();
404 const int fuzz = int(dialog.devicePixelRatioF());
405 const QPoint afterShowPosition = dialog.pos();
406 QVERIFY2(HighDpi::fuzzyCompare(afterShowPosition, beforeShowPosition, fuzz),
407 HighDpi::msgPointMismatch(afterShowPosition, beforeShowPosition).constData());
408}
409
410class Dialog : public QDialog
411{
412public:
413 Dialog(QPushButton *&button)
414 {
415 button = new QPushButton(this);
416 }
417};
418
419void tst_QDialog::deleteMainDefault()
420{
421 QPushButton *button;
422 Dialog dialog(button);
423 button->setDefault(true);
424 delete button;
425 dialog.show();
426 QTestEventLoop::instance().enterLoop(secs: 2);
427}
428
429void tst_QDialog::deleteInExec()
430{
431 QDialog *dialog = new QDialog(0);
432 QMetaObject::invokeMethod(obj: dialog, member: "deleteLater", type: Qt::QueuedConnection);
433 QCOMPARE(dialog->exec(), int(QDialog::Rejected));
434}
435
436#if QT_CONFIG(sizegrip)
437
438// From Task 124269
439void tst_QDialog::showSizeGrip()
440{
441 QDialog dialog(nullptr);
442 dialog.show();
443 QWidget *ext = new QWidget(&dialog);
444 QVERIFY(!dialog.isSizeGripEnabled());
445
446 dialog.setSizeGripEnabled(true);
447 QPointer<QSizeGrip> sizeGrip = dialog.findChild<QSizeGrip *>();
448 QVERIFY(sizeGrip);
449 QVERIFY(sizeGrip->isVisible());
450 QVERIFY(dialog.isSizeGripEnabled());
451
452 dialog.setSizeGripEnabled(false);
453 QVERIFY(!dialog.isSizeGripEnabled());
454
455 dialog.setSizeGripEnabled(true);
456 sizeGrip = dialog.findChild<QSizeGrip *>();
457 QVERIFY(sizeGrip);
458 QVERIFY(sizeGrip->isVisible());
459 sizeGrip->hide();
460 dialog.hide();
461 dialog.show();
462 QVERIFY(!sizeGrip->isVisible());
463}
464
465#if QT_DEPRECATED_SINCE(5, 13)
466void tst_QDialog::showSizeGrip_deprecated()
467{
468 QDialog dialog(0);
469 dialog.show();
470 QWidget *ext = new QWidget(&dialog);
471 QVERIFY(!dialog.extension());
472 QVERIFY(!dialog.isSizeGripEnabled());
473
474 dialog.setSizeGripEnabled(true);
475 QPointer<QSizeGrip> sizeGrip = dialog.findChild<QSizeGrip *>();
476 QVERIFY(sizeGrip);
477 QVERIFY(sizeGrip->isVisible());
478 QVERIFY(dialog.isSizeGripEnabled());
479
480 dialog.setExtension(ext);
481 QVERIFY(dialog.extension() && !dialog.extension()->isVisible());
482 QVERIFY(dialog.isSizeGripEnabled());
483
484 // normal show/hide sequence
485 dialog.showExtension(true);
486 QVERIFY(dialog.extension() && dialog.extension()->isVisible());
487 QVERIFY(!dialog.isSizeGripEnabled());
488 QVERIFY(!sizeGrip);
489
490 dialog.showExtension(false);
491 QVERIFY(dialog.extension() && !dialog.extension()->isVisible());
492 QVERIFY(dialog.isSizeGripEnabled());
493 sizeGrip = dialog.findChild<QSizeGrip *>();
494 QVERIFY(sizeGrip);
495 QVERIFY(sizeGrip->isVisible());
496
497 // show/hide sequence with interleaved size grip update
498 dialog.showExtension(true);
499 QVERIFY(dialog.extension() && dialog.extension()->isVisible());
500 QVERIFY(!dialog.isSizeGripEnabled());
501 QVERIFY(!sizeGrip);
502
503 dialog.setSizeGripEnabled(false);
504 QVERIFY(!dialog.isSizeGripEnabled());
505
506 dialog.showExtension(false);
507 QVERIFY(dialog.extension() && !dialog.extension()->isVisible());
508 QVERIFY(!dialog.isSizeGripEnabled());
509
510 dialog.setSizeGripEnabled(true);
511 sizeGrip = dialog.findChild<QSizeGrip *>();
512 QVERIFY(sizeGrip);
513 QVERIFY(sizeGrip->isVisible());
514 sizeGrip->hide();
515 dialog.hide();
516 dialog.show();
517 QVERIFY(!sizeGrip->isVisible());
518}
519#endif // QT_DEPRECATED_SINCE(5, 13)
520
521#endif // QT_CONFIG(sizegrip)
522
523void tst_QDialog::setVisible()
524{
525 QWidget topLevel;
526 topLevel.show();
527
528 QDialog *dialog = new QDialog;
529 dialog->setLayout(new QVBoxLayout);
530 dialog->layout()->addWidget(w: new QPushButton("dialog button"));
531
532 QWidget *widget = new QWidget(&topLevel);
533 widget->setLayout(new QVBoxLayout);
534 widget->layout()->addWidget(w: dialog);
535
536 QVERIFY(!dialog->isVisible());
537 QVERIFY(!dialog->isHidden());
538
539 widget->show();
540 QVERIFY(dialog->isVisible());
541 QVERIFY(!dialog->isHidden());
542
543 widget->hide();
544 dialog->hide();
545 widget->show();
546 QVERIFY(!dialog->isVisible());
547 QVERIFY(dialog->isHidden());
548}
549
550class TestRejectDialog : public QDialog
551{
552 public:
553 TestRejectDialog() : cancelReject(false), called(0) {}
554 void reject()
555 {
556 called++;
557 if (!cancelReject)
558 QDialog::reject();
559 }
560 bool cancelReject;
561 int called;
562};
563
564void tst_QDialog::reject()
565{
566 TestRejectDialog dialog;
567 dialog.show();
568 QVERIFY(QTest::qWaitForWindowExposed(&dialog));
569 QVERIFY(dialog.isVisible());
570 dialog.reject();
571 QTRY_VERIFY(!dialog.isVisible());
572 QCOMPARE(dialog.called, 1);
573
574 dialog.show();
575 QVERIFY(QTest::qWaitForWindowExposed(&dialog));
576 QVERIFY(dialog.isVisible());
577 QVERIFY(dialog.close());
578 QTRY_VERIFY(!dialog.isVisible());
579 QCOMPARE(dialog.called, 2);
580
581 dialog.cancelReject = true;
582 dialog.show();
583 QVERIFY(QTest::qWaitForWindowExposed(&dialog));
584 QVERIFY(dialog.isVisible());
585 dialog.reject();
586 QTRY_VERIFY(dialog.isVisible());
587 QCOMPARE(dialog.called, 3);
588 QVERIFY(!dialog.close());
589 QTRY_VERIFY(dialog.isVisible());
590 QCOMPARE(dialog.called, 4);
591}
592
593static QByteArray formatPoint(QPoint p)
594{
595 return QByteArray::number(p.x()) + ", " + QByteArray::number(p.y());
596}
597
598void tst_QDialog::snapToDefaultButton()
599{
600#ifdef QT_NO_CURSOR
601 QSKIP("Test relies on there being a cursor");
602#else
603 if (!QGuiApplication::platformName().compare(other: QLatin1String("wayland"), cs: Qt::CaseInsensitive)
604 || !QGuiApplication::platformName().compare(other: QLatin1String("winrt"), cs: Qt::CaseInsensitive))
605 QSKIP("This platform does not support setting the cursor position.");
606
607 const QRect dialogGeometry(QGuiApplication::primaryScreen()->availableGeometry().topLeft()
608 + QPoint(100, 100), QSize(200, 200));
609 const QPoint startingPos = dialogGeometry.bottomRight() + QPoint(100, 100);
610 QCursor::setPos(startingPos);
611#ifdef Q_OS_MACOS
612 // On OS X we use CGEventPost to move the cursor, it needs at least
613 // some time before the event handled and the position really set.
614 QTest::qWait(100);
615#endif
616 QCOMPARE(QCursor::pos(), startingPos);
617 QDialog dialog;
618 QPushButton *button = new QPushButton(&dialog);
619 button->setDefault(true);
620 dialog.setGeometry(dialogGeometry);
621 dialog.show();
622 QVERIFY(QTest::qWaitForWindowExposed(&dialog));
623 const QPoint localPos = button->mapFromGlobal(QCursor::pos());
624 if (QGuiApplicationPrivate::platformTheme()->themeHint(hint: QPlatformTheme::DialogSnapToDefaultButton).toBool())
625 QVERIFY2(button->rect().contains(localPos), formatPoint(localPos).constData());
626 else
627 QVERIFY2(!button->rect().contains(localPos), formatPoint(localPos).constData());
628#endif // !QT_NO_CURSOR
629}
630
631void tst_QDialog::transientParent_data()
632{
633 QTest::addColumn<bool>(name: "nativewidgets");
634 QTest::newRow(dataTag: "Non-native") << false;
635 QTest::newRow(dataTag: "Native") << true;
636}
637
638void tst_QDialog::transientParent()
639{
640 QFETCH(bool, nativewidgets);
641 QWidget topLevel;
642 topLevel.resize(w: 200, h: 200);
643 topLevel.move(QGuiApplication::primaryScreen()->availableGeometry().center() - QPoint(100, 100));
644 QVBoxLayout *layout = new QVBoxLayout(&topLevel);
645 QWidget *innerWidget = new QWidget(&topLevel);
646 layout->addWidget(innerWidget);
647 if (nativewidgets)
648 innerWidget->winId();
649 topLevel.show();
650 QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
651 QDialog dialog(innerWidget);
652 dialog.show();
653 QVERIFY(QTest::qWaitForWindowExposed(&dialog));
654 // Transient parent should always be the top level, also when using
655 // native child widgets.
656 QCOMPARE(dialog.windowHandle()->transientParent(), topLevel.windowHandle());
657}
658
659void tst_QDialog::dialogInGraphicsView()
660{
661 // QTBUG-49124: A dialog embedded into QGraphicsView has Qt::WA_DontShowOnScreen
662 // set (as has a native dialog). It must not trigger the modal handling though
663 // as not to lock up.
664 QGraphicsScene scene;
665 QGraphicsView view(&scene);
666 view.setWindowTitle(QTest::currentTestFunction());
667 const QRect availableGeometry = QGuiApplication::primaryScreen()->availableGeometry();
668 view.resize(availableGeometry.size() / 2);
669 view.move(ax: availableGeometry.left() + availableGeometry.width() / 4,
670 ay: availableGeometry.top() + availableGeometry.height() / 4);
671 ToolDialog *dialog = new ToolDialog;
672 scene.addWidget(widget: dialog);
673 view.show();
674 QVERIFY(QTest::qWaitForWindowExposed(&view));
675 for (int i = 0; i < 3; ++i) {
676 dialog->exec();
677 QVERIFY(!dialog->wasModalWindow());
678 }
679}
680
681// QTBUG-79147 (Windows): Closing a dialog by clicking the 'X' in the title
682// bar would offset the dialog position when shown next time.
683void tst_QDialog::keepPositionOnClose()
684{
685#ifdef Q_OS_WINRT
686 QSKIP("Does not work on winrt", Continue);
687#endif
688 QDialog dialog;
689 dialog.setWindowTitle(QTest::currentTestFunction());
690 const QRect availableGeometry = QGuiApplication::primaryScreen()->availableGeometry();
691 dialog.resize(availableGeometry.size() / 4);
692 const QPoint pos = availableGeometry.topLeft() + QPoint(100, 100);
693 dialog.move(pos);
694 dialog.show();
695 QVERIFY(QTest::qWaitForWindowExposed(&dialog));
696 dialog.close();
697 dialog.windowHandle()->destroy(); // Emulate a click on close by destroying the window.
698 QTest::qWait(ms: 50);
699 dialog.show();
700 QVERIFY(QTest::qWaitForWindowExposed(&dialog));
701 QTest::qWait(ms: 50);
702 QCOMPARE(dialog.pos(), pos);
703}
704
705QTEST_MAIN(tst_QDialog)
706#include "tst_qdialog.moc"
707

source code of qtbase/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp