Get rid of copypasted code between isWindowBlocked's overrides
The code in QGuiApplication::isWindowBlocked and QApplication::isWindowBlocked is very similar, a result of copying and pasting. Due to the copying it is difficult to modify the code and the implementation is hard to comprehend, too. There are ultimately only two parts that are different. First is that QApplication's override may also specify a certain window as non-blockable if it is a popup window. Second, default modality is computed in QApplication if a modal window does not have one assigned. The differing parts have been extracted following the template method design pattern. Pick-to: 6.4 Change-Id: I3b9aa206a3c7211fe022730943bf6f76aa5ae6d2 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>bb10
parent
de56047620
commit
b4780f1990
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue