Fixed multiple modal windows from all blocking each other.
authorSamuel Rødal <samuel.rodal@digia.com>
Fri, 21 Sep 2012 10:12:01 +0000 (12:12 +0200)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Fri, 21 Sep 2012 20:04:00 +0000 (22:04 +0200)
A modal window in front in the modal window list should never be blocked
by a modal window further back in the list. This was taken care of in
QGuiApplicationPrivate::isWindowBlocked(), we just need to make sure it
gets called when a new modal window gets shown so that its blocked
status is up to date.

Task-number: QTBUG-27206
Change-Id: I590f1715e66067edb178081352636f34fe54a885
Reviewed-by: Tim Jenssen <tim.jenssen@digia.com>
src/gui/kernel/qguiapplication.cpp
tests/auto/gui/kernel/qwindow/tst_qwindow.cpp

index f59c7dc..59be4fa 100644 (file)
@@ -458,6 +458,8 @@ void QGuiApplicationPrivate::showModalWindow(QWindow *modal)
         if (!window->d_func()->blockedByModalWindow)
             updateBlockedStatus(window);
     }
+
+    updateBlockedStatus(modal);
 }
 
 void QGuiApplicationPrivate::hideModalWindow(QWindow *window)
index 0f9cf2b..d50d154 100644 (file)
@@ -73,6 +73,7 @@ private slots:
     void windowModality();
     void inputReentrancy();
     void tabletEvents();
+    void windowModality_QTBUG27039();
 
     void initTestCase()
     {
@@ -987,5 +988,44 @@ void tst_QWindow::tabletEvents()
 #endif
 }
 
+void tst_QWindow::windowModality_QTBUG27039()
+{
+    QWindow parent;
+    parent.setGeometry(10, 10, 100, 100);
+    parent.show();
+
+    InputTestWindow modalA;
+    modalA.setTransientParent(&parent);
+    modalA.setGeometry(10, 10, 20, 20);
+    modalA.setWindowModality(Qt::ApplicationModal);
+    modalA.show();
+
+    InputTestWindow modalB;
+    modalB.setTransientParent(&parent);
+    modalB.setGeometry(30, 10, 20, 20);
+    modalB.setWindowModality(Qt::ApplicationModal);
+    modalB.show();
+
+    QPointF local(5, 5);
+    QWindowSystemInterface::handleMouseEvent(&modalA, local, local, Qt::LeftButton);
+    QWindowSystemInterface::handleMouseEvent(&modalA, local, local, Qt::NoButton);
+    QWindowSystemInterface::handleMouseEvent(&modalB, local, local, Qt::LeftButton);
+    QWindowSystemInterface::handleMouseEvent(&modalB, local, local, Qt::NoButton);
+    QCoreApplication::processEvents();
+
+    // modal A should be blocked since it was shown first, but modal B should not be blocked
+    QCOMPARE(modalB.mousePressedCount, 1);
+    QCOMPARE(modalA.mousePressedCount, 0);
+
+    modalB.hide();
+    QWindowSystemInterface::handleMouseEvent(&modalA, local, local, Qt::LeftButton);
+    QWindowSystemInterface::handleMouseEvent(&modalA, local, local, Qt::NoButton);
+    QCoreApplication::processEvents();
+
+    // modal B has been hidden, modal A should be unblocked again
+    QCOMPARE(modalA.mousePressedCount, 1);
+}
+
 #include <tst_qwindow.moc>
 QTEST_MAIN(tst_QWindow)
+