summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/kernel/qguiapplication.cpp59
-rw-r--r--src/gui/kernel/qguiapplication_p.h5
-rw-r--r--src/widgets/kernel/qapplication.cpp70
-rw-r--r--src/widgets/kernel/qapplication_p.h3
4 files changed, 42 insertions, 95 deletions
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 7887db8534..0814339150 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -852,6 +852,17 @@ void QGuiApplicationPrivate::hideModalWindow(QWindow *window)
}
}
+Qt::WindowModality QGuiApplicationPrivate::defaultModality() const
+{
+ return Qt::NonModal;
+}
+
+bool QGuiApplicationPrivate::windowNeverBlocked(QWindow *window) const
+{
+ Q_UNUSED(window);
+ return false;
+}
+
/*
Returns \c true if \a window is blocked by a modal window. If \a
blockingWindow is non-zero, *blockingWindow will be set to the blocking
@@ -859,49 +870,40 @@ void QGuiApplicationPrivate::hideModalWindow(QWindow *window)
*/
bool QGuiApplicationPrivate::isWindowBlocked(QWindow *window, QWindow **blockingWindow) const
{
+ Q_ASSERT_X(window, Q_FUNC_INFO, "The window must not be null");
+
QWindow *unused = nullptr;
if (!blockingWindow)
blockingWindow = &unused;
+ *blockingWindow = nullptr;
- if (modalWindowList.isEmpty()) {
- *blockingWindow = nullptr;
+ if (modalWindowList.isEmpty() || windowNeverBlocked(window))
return false;
- }
for (int i = 0; i < modalWindowList.count(); ++i) {
QWindow *modalWindow = modalWindowList.at(i);
// A window is not blocked by another modal window if the two are
// the same, or if the window is a child of the modal window.
- if (window == modalWindow || modalWindow->isAncestorOf(window, QWindow::IncludeTransients)) {
- *blockingWindow = nullptr;
+ if (window == modalWindow || modalWindow->isAncestorOf(window, QWindow::IncludeTransients))
return false;
- }
- Qt::WindowModality windowModality = modalWindow->modality();
- switch (windowModality) {
+ switch (modalWindow->modality() == Qt::NonModal ? defaultModality()
+ : modalWindow->modality()) {
case Qt::ApplicationModal:
- {
- if (modalWindow != window) {
- *blockingWindow = modalWindow;
- return true;
- }
- break;
- }
- case Qt::WindowModal:
- {
- QWindow *w = window;
+ *blockingWindow = modalWindow;
+ return true;
+ case Qt::WindowModal: {
+ // Find the nearest ancestor of window which is also an ancestor of modal window to
+ // determine if the modal window blocks the window.
+ auto *current = window;
do {
- QWindow *m = modalWindow;
- do {
- if (m == w) {
- *blockingWindow = m;
- return true;
- }
- m = m->parent(QWindow::IncludeTransients);
- } while (m);
- w = w->parent(QWindow::IncludeTransients);
- } while (w);
+ if (current->isAncestorOf(modalWindow, QWindow::IncludeTransients)) {
+ *blockingWindow = current;
+ return true;
+ }
+ current = current->parent(QWindow::IncludeTransients);
+ } while (current);
break;
}
default:
@@ -909,7 +911,6 @@ bool QGuiApplicationPrivate::isWindowBlocked(QWindow *window, QWindow **blocking
break;
}
}
- *blockingWindow = nullptr;
return false;
}
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index 3b30c14dbe..8309e2bfa7 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -188,7 +188,10 @@ public:
static void showModalWindow(QWindow *window);
static void hideModalWindow(QWindow *window);
static void updateBlockedStatus(QWindow *window);
- virtual bool isWindowBlocked(QWindow *window, QWindow **blockingWindow = nullptr) const;
+
+ virtual Qt::WindowModality defaultModality() const;
+ virtual bool windowNeverBlocked(QWindow *window) const;
+ bool isWindowBlocked(QWindow *window, QWindow **blockingWindow = nullptr) const;
virtual bool popupActive() { return false; }
virtual bool closeAllPopups() { return false; }
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index a075182969..ea2e53867f 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -2170,74 +2170,16 @@ bool QApplicationPrivate::isBlockedByModal(QWidget *widget)
return window && self->isWindowBlocked(window);
}
-bool QApplicationPrivate::isWindowBlocked(QWindow *window, QWindow **blockingWindow) const
+Qt::WindowModality QApplicationPrivate::defaultModality() const
{
- QWindow *unused = nullptr;
- if (Q_UNLIKELY(!window)) {
- qWarning().nospace() << "window == 0 passed.";
- return false;
- }
- if (!blockingWindow)
- blockingWindow = &unused;
+ return Qt::ApplicationModal;
+}
- if (modalWindowList.isEmpty()) {
- *blockingWindow = nullptr;
- return false;
- }
+bool QApplicationPrivate::windowNeverBlocked(QWindow *window) const
+{
QWidget *popupWidget = QApplication::activePopupWidget();
QWindow *popupWindow = popupWidget ? popupWidget->windowHandle() : nullptr;
- if (popupWindow == window || (!popupWindow && QWindowPrivate::get(window)->isPopup())) {
- *blockingWindow = nullptr;
- return false;
- }
-
- for (int i = 0; i < modalWindowList.count(); ++i) {
- QWindow *modalWindow = modalWindowList.at(i);
-
- // A window is not blocked by another modal window if the two are
- // the same, or if the window is a child of the modal window.
- if (window == modalWindow || modalWindow->isAncestorOf(window, QWindow::IncludeTransients)) {
- *blockingWindow = nullptr;
- return false;
- }
-
- Qt::WindowModality windowModality = modalWindow->modality();
- if (windowModality == Qt::NonModal) {
- // If modality type hasn't been set on the modalWindow's widget, as
- // when waiting for a native dialog, use ApplicationModal.
- windowModality = Qt::ApplicationModal;
- }
-
- switch (windowModality) {
- case Qt::ApplicationModal:
- if (modalWindow != window) {
- *blockingWindow = modalWindow;
- return true;
- }
- break;
- case Qt::WindowModal:
- {
- QWindow *w = window;
- do {
- QWindow *m = modalWindow;
- do {
- if (m == w) {
- *blockingWindow = m;
- return true;
- }
- m = m->parent(QWindow::IncludeTransients);
- } while (m);
- w = w->parent(QWindow::IncludeTransients);
- } while (w);
- break;
- }
- default:
- Q_ASSERT_X(false, "QApplication", "internal error, a modal window cannot be modeless");
- break;
- }
- }
- *blockingWindow = nullptr;
- return false;
+ return popupWindow == window || (!popupWindow && QWindowPrivate::get(window)->isPopup());
}
/*!\internal
diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h
index 6d80201d62..4be35320d9 100644
--- a/src/widgets/kernel/qapplication_p.h
+++ b/src/widgets/kernel/qapplication_p.h
@@ -84,7 +84,8 @@ public:
#endif
//modality
- bool isWindowBlocked(QWindow *window, QWindow **blockingWindow = nullptr) const override;
+ Qt::WindowModality defaultModality() const override;
+ bool windowNeverBlocked(QWindow *window) const override;
static bool isBlockedByModal(QWidget *widget);
static bool modalState();
static bool tryModalHelper(QWidget *widget, QWidget **rettop = nullptr);