If a QWidget is ignored for auto-quit, ignore its corresponding QWindow.

Unit test by Friedemann Kleint <Friedemann.Kleint@digia.com>

Task-number: QTBUG-31569
Change-Id: I526d33d4f88a41f6ac349098476bc45af6c841b0
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
This commit is contained in:
Stephen Kelly 2013-06-18 14:42:43 +02:00 committed by The Qt Project
parent 2a8efea1a9
commit 249c5f0689
4 changed files with 38 additions and 1 deletions

View File

@ -2478,11 +2478,19 @@ void QGuiApplicationPrivate::emitLastWindowClosed()
} }
bool QGuiApplicationPrivate::shouldQuit() bool QGuiApplicationPrivate::shouldQuit()
{
const QWindowList processedWindows;
return shouldQuitInternal(processedWindows);
}
bool QGuiApplicationPrivate::shouldQuitInternal(const QWindowList &processedWindows)
{ {
/* if there is no visible top-level window left, we allow the quit */ /* if there is no visible top-level window left, we allow the quit */
QWindowList list = QGuiApplication::topLevelWindows(); QWindowList list = QGuiApplication::topLevelWindows();
for (int i = 0; i < list.size(); ++i) { for (int i = 0; i < list.size(); ++i) {
QWindow *w = list.at(i); QWindow *w = list.at(i);
if (processedWindows.contains(w))
continue;
if (w->isVisible() && !w->transientParent()) if (w->isVisible() && !w->transientParent())
return false; return false;
} }

View File

@ -91,6 +91,8 @@ public:
virtual bool shouldQuit(); virtual bool shouldQuit();
bool shouldQuitInternal(const QWindowList &processedWindows);
static Qt::KeyboardModifiers modifier_buttons; static Qt::KeyboardModifiers modifier_buttons;
static Qt::MouseButtons mouse_buttons; static Qt::MouseButtons mouse_buttons;

View File

@ -2695,12 +2695,14 @@ bool QApplicationPrivate::shouldQuit()
the ones without QuitOnClose), we emit the lastWindowClosed the ones without QuitOnClose), we emit the lastWindowClosed
signal */ signal */
QWidgetList list = QApplication::topLevelWidgets(); QWidgetList list = QApplication::topLevelWidgets();
QWindowList processedWindows;
for (int i = 0; i < list.size(); ++i) { for (int i = 0; i < list.size(); ++i) {
QWidget *w = list.at(i); QWidget *w = list.at(i);
processedWindows.push_back(w->windowHandle());
if (w->isVisible() && !w->parentWidget() && w->testAttribute(Qt::WA_QuitOnClose)) if (w->isVisible() && !w->parentWidget() && w->testAttribute(Qt::WA_QuitOnClose))
return false; return false;
} }
return QGuiApplicationPrivate::shouldQuit(); return QGuiApplicationPrivate::shouldQuitInternal(processedWindows);
} }
static inline void closeAllPopups() static inline void closeAllPopups()

View File

@ -783,6 +783,31 @@ void tst_QApplication::quitOnLastWindowClosed()
QVERIFY(timerSpy.count() > 15); // Should be around 20 if closing did not caused the quit QVERIFY(timerSpy.count() > 15); // Should be around 20 if closing did not caused the quit
} }
{ // QTBUG-31569: If the last widget with Qt::WA_QuitOnClose set is closed, other
// widgets that don't have the attribute set should be closed automatically.
int argc = 0;
QApplication app(argc, 0);
QVERIFY(app.quitOnLastWindowClosed());
QWidget w1;
w1.show();
QWidget w2;
w2.setAttribute(Qt::WA_QuitOnClose, false);
w2.show();
QVERIFY(QTest::qWaitForWindowExposed(&w2));
QTimer timer;
timer.setInterval(100);
timer.start();
QSignalSpy timerSpy(&timer, SIGNAL(timeout()));
QTimer::singleShot(100, &w1, SLOT(close()));
app.exec();
QVERIFY(timerSpy.count() < 10);
}
} }
class PromptOnCloseWidget : public QWidget class PromptOnCloseWidget : public QWidget