|
| 1 | +From b60cfd52ddc3892a3af860425ee9858598e668d7 Mon Sep 17 00:00:00 2001 |
| 2 | +From: Santhosh Kumar < [email protected]> |
| 3 | +Date: Wed, 21 Aug 2024 18:42:55 +0200 |
| 4 | +Subject: [PATCH] Propagate modality to the non-native quick dialogs |
| 5 | + |
| 6 | +[slipher: rebased it to 6.8.3 and removed tests/ changes] |
| 7 | + |
| 8 | +The non-native quick dialogs don't block input to the windows even after |
| 9 | +setting the modality as ApplicationModal/WindowModal. This is because |
| 10 | +non-native platform dialogs (QuickPlaform*Dialogs) didn't set modal to |
| 11 | +its respective window (QQuickPopupWindow). |
| 12 | + |
| 13 | +This patch fixes that issue by setting the modality to the non-native |
| 14 | +platform dialogs. |
| 15 | + |
| 16 | +Task-number: QTBUG-127605 |
| 17 | +Pick-to: 6.10 6.9 6.8 |
| 18 | +Change-Id: Idb3374e881766ae92adc0360c9b9af5c498dd6df |
| 19 | +Reviewed-by: Oliver Eftevaag < [email protected]> |
| 20 | +--- |
| 21 | + .../qquickplatformcolordialog.cpp | 3 ++- |
| 22 | + .../qquickplatformfiledialog.cpp | 3 ++- |
| 23 | + .../qquickplatformfolderdialog.cpp | 3 ++- |
| 24 | + .../qquickplatformfontdialog.cpp | 3 ++- |
| 25 | + .../qquickplatformmessagedialog.cpp | 3 ++- |
| 26 | + src/quicktemplates/qquickdialog.cpp | 2 ++ |
| 27 | + src/quicktemplates/qquickpopup.cpp | 19 ++++++++++++++++--- |
| 28 | + src/quicktemplates/qquickpopup_p.h | 2 ++ |
| 29 | + src/quicktemplates/qquickpopup_p_p.h | 1 + |
| 30 | + src/quicktemplates/qquickpopupwindow.cpp | 7 +++++-- |
| 31 | + 10 files changed, 36 insertions(+), 10 deletions(-) |
| 32 | + |
| 33 | +diff --git a/src/quickdialogs/quickdialogsquickimpl/qquickplatformcolordialog.cpp b/src/quickdialogs/quickdialogsquickimpl/qquickplatformcolordialog.cpp |
| 34 | +index 205b4e0b1b..a7f2fdab73 100644 |
| 35 | +--- a/src/quickdialogs/quickdialogsquickimpl/qquickplatformcolordialog.cpp |
| 36 | ++++ b/src/quickdialogs/quickdialogsquickimpl/qquickplatformcolordialog.cpp |
| 37 | +@@ -9,6 +9,7 @@ |
| 38 | + #include <QtQml/qqmlinfo.h> |
| 39 | + #include <QtQuick/qquickwindow.h> |
| 40 | + #include <QtQuickTemplates2/private/qquickdialog_p.h> |
| 41 | ++#include <QtQuickTemplates2/private/qquickdialog_p_p.h> |
| 42 | + #include <QtQuickTemplates2/private/qquickpopup_p_p.h> |
| 43 | + #include <QtQuickTemplates2/private/qquickpopupanchors_p.h> |
| 44 | + |
| 45 | +@@ -108,7 +109,7 @@ bool QQuickPlatformColorDialog::show(Qt::WindowFlags flags, Qt::WindowModality m |
| 46 | + |
| 47 | + m_dialog->setTitle(options->windowTitle()); |
| 48 | + m_dialog->setOptions(options); |
| 49 | +- |
| 50 | ++ m_dialog->setWindowModality(modality); |
| 51 | + m_dialog->open(); |
| 52 | + return true; |
| 53 | + } |
| 54 | +diff --git a/src/quickdialogs/quickdialogsquickimpl/qquickplatformfiledialog.cpp b/src/quickdialogs/quickdialogsquickimpl/qquickplatformfiledialog.cpp |
| 55 | +index 1c9174a8e4..367f229414 100644 |
| 56 | +--- a/src/quickdialogs/quickdialogsquickimpl/qquickplatformfiledialog.cpp |
| 57 | ++++ b/src/quickdialogs/quickdialogsquickimpl/qquickplatformfiledialog.cpp |
| 58 | +@@ -10,6 +10,7 @@ |
| 59 | + #include <QtQuick/qquickwindow.h> |
| 60 | + #include <QtQuickDialogs2Utils/private/qquickfilenamefilter_p.h> |
| 61 | + #include <QtQuickTemplates2/private/qquickdialog_p.h> |
| 62 | ++#include <QtQuickTemplates2/private/qquickdialog_p_p.h> |
| 63 | + #include <QtQuickTemplates2/private/qquickpopup_p_p.h> |
| 64 | + #include <QtQuickTemplates2/private/qquickpopupanchors_p.h> |
| 65 | + |
| 66 | +@@ -194,7 +195,7 @@ bool QQuickPlatformFileDialog::show(Qt::WindowFlags flags, Qt::WindowModality mo |
| 67 | + m_dialog->setCurrentFolder(QUrl::fromLocalFile(QDir().absolutePath())); |
| 68 | + } |
| 69 | + } |
| 70 | +- |
| 71 | ++ m_dialog->setWindowModality(modality); |
| 72 | + m_dialog->open(); |
| 73 | + return true; |
| 74 | + } |
| 75 | +diff --git a/src/quickdialogs/quickdialogsquickimpl/qquickplatformfolderdialog.cpp b/src/quickdialogs/quickdialogsquickimpl/qquickplatformfolderdialog.cpp |
| 76 | +index d0ccea353e..dd41ed1ce3 100644 |
| 77 | +--- a/src/quickdialogs/quickdialogsquickimpl/qquickplatformfolderdialog.cpp |
| 78 | ++++ b/src/quickdialogs/quickdialogsquickimpl/qquickplatformfolderdialog.cpp |
| 79 | +@@ -9,6 +9,7 @@ |
| 80 | + #include <QtQml/qqmlinfo.h> |
| 81 | + #include <QtQuick/qquickwindow.h> |
| 82 | + #include <QtQuickTemplates2/private/qquickdialog_p.h> |
| 83 | ++#include <QtQuickTemplates2/private/qquickdialog_p_p.h> |
| 84 | + #include <QtQuickTemplates2/private/qquickpopup_p_p.h> |
| 85 | + #include <QtQuickTemplates2/private/qquickpopupanchors_p.h> |
| 86 | + |
| 87 | +@@ -153,7 +154,7 @@ bool QQuickPlatformFolderDialog::show(Qt::WindowFlags flags, Qt::WindowModality |
| 88 | + ? options->labelText(QFileDialogOptions::Accept) : QString()); |
| 89 | + m_dialog->setRejectLabel(options->isLabelExplicitlySet(QFileDialogOptions::Reject) |
| 90 | + ? options->labelText(QFileDialogOptions::Reject) : QString()); |
| 91 | +- |
| 92 | ++ m_dialog->setWindowModality(modality); |
| 93 | + m_dialog->open(); |
| 94 | + return true; |
| 95 | + } |
| 96 | +diff --git a/src/quickdialogs/quickdialogsquickimpl/qquickplatformfontdialog.cpp b/src/quickdialogs/quickdialogsquickimpl/qquickplatformfontdialog.cpp |
| 97 | +index 4ef0b1bec6..e5a8c2ed78 100644 |
| 98 | +--- a/src/quickdialogs/quickdialogsquickimpl/qquickplatformfontdialog.cpp |
| 99 | ++++ b/src/quickdialogs/quickdialogsquickimpl/qquickplatformfontdialog.cpp |
| 100 | +@@ -9,6 +9,7 @@ |
| 101 | + #include <QtQml/qqmlinfo.h> |
| 102 | + #include <QtQuick/qquickwindow.h> |
| 103 | + #include <QtQuickTemplates2/private/qquickdialog_p.h> |
| 104 | ++#include <QtQuickTemplates2/private/qquickdialog_p_p.h> |
| 105 | + #include <QtQuickTemplates2/private/qquickpopup_p_p.h> |
| 106 | + #include <QtQuickTemplates2/private/qquickpopupanchors_p.h> |
| 107 | + |
| 108 | +@@ -124,7 +125,7 @@ bool QQuickPlatformFontDialog::show(Qt::WindowFlags flags, Qt::WindowModality mo |
| 109 | + m_dialog->setOptions(options); |
| 110 | + |
| 111 | + m_dialog->init(); |
| 112 | +- |
| 113 | ++ m_dialog->setWindowModality(modality); |
| 114 | + m_dialog->open(); |
| 115 | + return true; |
| 116 | + } |
| 117 | +diff --git a/src/quickdialogs/quickdialogsquickimpl/qquickplatformmessagedialog.cpp b/src/quickdialogs/quickdialogsquickimpl/qquickplatformmessagedialog.cpp |
| 118 | +index a9f1e858ed..4f2d4df7d4 100644 |
| 119 | +--- a/src/quickdialogs/quickdialogsquickimpl/qquickplatformmessagedialog.cpp |
| 120 | ++++ b/src/quickdialogs/quickdialogsquickimpl/qquickplatformmessagedialog.cpp |
| 121 | +@@ -3,6 +3,7 @@ |
| 122 | + |
| 123 | + #include "qquickplatformmessagedialog_p.h" |
| 124 | + |
| 125 | ++#include <QtQuickTemplates2/private/qquickdialog_p_p.h> |
| 126 | + #include <QtQuickTemplates2/private/qquickpopup_p_p.h> |
| 127 | + #include <QtQuickTemplates2/private/qquickpopupanchors_p.h> |
| 128 | + |
| 129 | +@@ -86,7 +87,7 @@ bool QQuickPlatformMessageDialog::show(Qt::WindowFlags flags, Qt::WindowModality |
| 130 | + QSharedPointer<QMessageDialogOptions> options = QPlatformMessageDialogHelper::options(); |
| 131 | + m_dialog->setTitle(options->windowTitle()); |
| 132 | + m_dialog->setOptions(options); |
| 133 | +- |
| 134 | ++ m_dialog->setWindowModality(modality); |
| 135 | + m_dialog->open(); |
| 136 | + return true; |
| 137 | + } |
| 138 | +diff --git a/src/quicktemplates/qquickdialog.cpp b/src/quicktemplates/qquickdialog.cpp |
| 139 | +index 458c3e6ba3..4bb1c3f0d6 100644 |
| 140 | +--- a/src/quicktemplates/qquickdialog.cpp |
| 141 | ++++ b/src/quicktemplates/qquickdialog.cpp |
| 142 | +@@ -7,6 +7,8 @@ |
| 143 | + #include "qquickabstractbutton_p.h" |
| 144 | + #include "qquickpopupitem_p_p.h" |
| 145 | + #include "qquickpopupwindow_p_p.h" |
| 146 | ++#include <qpa/qplatformintegration.h> |
| 147 | ++#include <private/qguiapplication_p.h> |
| 148 | + |
| 149 | + QT_BEGIN_NAMESPACE |
| 150 | + |
| 151 | +diff --git a/src/quicktemplates/qquickpopup.cpp b/src/quicktemplates/qquickpopup.cpp |
| 152 | +index 60806701d4..4c1faf5a45 100644 |
| 153 | +--- a/src/quicktemplates/qquickpopup.cpp |
| 154 | ++++ b/src/quicktemplates/qquickpopup.cpp |
| 155 | +@@ -1098,15 +1098,21 @@ void QQuickPopupPrivate::adjustPopupItemParentAndWindow() |
| 156 | + popupWindow = new QQuickPopupWindow(q, window); |
| 157 | + popupWindow->setWidth(popupItem->width() + windowInsets().left() + windowInsets().right()); |
| 158 | + popupWindow->setHeight(popupItem->height() + windowInsets().top() + windowInsets().bottom()); |
| 159 | +- popupWindow->setModality(modal ? Qt::ApplicationModal : Qt::NonModal); |
| 160 | ++ if (popupWndModality != Qt::NonModal) |
| 161 | ++ popupWindow->setModality(popupWndModality); |
| 162 | ++ else |
| 163 | ++ popupWindow->setModality(modal ? Qt::ApplicationModal : Qt::NonModal); |
| 164 | + popupItem->resetTitle(); |
| 165 | + popupWindow->setTitle(m_title); |
| 166 | + } |
| 167 | + popupItem->setParentItem(popupWindow->contentItem()); |
| 168 | + popupItem->forceActiveFocus(Qt::PopupFocusReason); |
| 169 | + } |
| 170 | +- if (popupWindow) |
| 171 | +- popupWindow->setVisible(visible); |
| 172 | ++ if (popupWindow && popupWindow->transientParent()) { |
| 173 | ++ auto *transientParentPriv = QQuickWindowPrivate::get(qobject_cast<QQuickWindow *>(popupWindow->transientParent())); |
| 174 | ++ if (!transientParentPriv->inDestructor) |
| 175 | ++ popupWindow->setVisible(visible); |
| 176 | ++ } |
| 177 | + } else { |
| 178 | + if (visible) { |
| 179 | + popupItem->setParentItem(overlay); |
| 180 | +@@ -1129,6 +1135,7 @@ void QQuickPopupPrivate::adjustPopupItemParentAndWindow() |
| 181 | + if (!hasZ) |
| 182 | + popupItem->setZ(qMax(topPopupItem->z(), popupItem->z())); |
| 183 | + } |
| 184 | ++ q->setModal((popupWndModality != Qt::NonModal) || modal); |
| 185 | + } |
| 186 | + |
| 187 | + popupItem->setTitle(m_title); |
| 188 | +@@ -3378,6 +3385,12 @@ bool QQuickPopup::setAccessibleProperty(const char *propertyName, const QVariant |
| 189 | + return d->popupItem->setAccessibleProperty(propertyName, value); |
| 190 | + } |
| 191 | + |
| 192 | ++void QQuickPopup::setWindowModality(const Qt::WindowModality modality) |
| 193 | ++{ |
| 194 | ++ Q_D(QQuickPopup); |
| 195 | ++ d->popupWndModality = modality; |
| 196 | ++} |
| 197 | ++ |
| 198 | + QT_END_NAMESPACE |
| 199 | + |
| 200 | + #include "moc_qquickpopup_p.cpp" |
| 201 | +diff --git a/src/quicktemplates/qquickpopup_p.h b/src/quicktemplates/qquickpopup_p.h |
| 202 | +index 089d86ba29..5909ef36e4 100644 |
| 203 | +--- a/src/quicktemplates/qquickpopup_p.h |
| 204 | ++++ b/src/quicktemplates/qquickpopup_p.h |
| 205 | +@@ -312,6 +312,8 @@ public: |
| 206 | + void setBottomInset(qreal inset); |
| 207 | + void resetBottomInset(); |
| 208 | + |
| 209 | ++ void setWindowModality(const Qt::WindowModality modality); |
| 210 | ++ |
| 211 | + enum PopupType { |
| 212 | + Item, |
| 213 | + Window, |
| 214 | +diff --git a/src/quicktemplates/qquickpopup_p_p.h b/src/quicktemplates/qquickpopup_p_p.h |
| 215 | +index a8cc14ee33..88ebb7d9f4 100644 |
| 216 | +--- a/src/quicktemplates/qquickpopup_p_p.h |
| 217 | ++++ b/src/quicktemplates/qquickpopup_p_p.h |
| 218 | +@@ -202,6 +202,7 @@ public: |
| 219 | + qreal prevScale = 0; |
| 220 | + QString m_title; |
| 221 | + QQuickPopup::PopupType m_popupType = QQuickPopup::Item; |
| 222 | ++ Qt::WindowModality popupWndModality = Qt::NonModal; |
| 223 | + |
| 224 | + friend class QQuickPopupTransitionManager; |
| 225 | + }; |
| 226 | +diff --git a/src/quicktemplates/qquickpopupwindow.cpp b/src/quicktemplates/qquickpopupwindow.cpp |
| 227 | +index 890c609684..e1e763908d 100644 |
| 228 | +--- a/src/quicktemplates/qquickpopupwindow.cpp |
| 229 | ++++ b/src/quicktemplates/qquickpopupwindow.cpp |
| 230 | +@@ -23,7 +23,7 @@ QT_BEGIN_NAMESPACE |
| 231 | + Q_LOGGING_CATEGORY(lcPopupWindow, "qt.quick.controls.popup.window") |
| 232 | + |
| 233 | + static bool s_popupGrabOk = false; |
| 234 | +-static QWindow *s_grabbedWindow = nullptr; |
| 235 | ++static QPointer<QWindow> s_grabbedWindow; |
| 236 | + |
| 237 | + class QQuickPopupWindowPrivate : public QQuickWindowQmlImplPrivate |
| 238 | + { |
| 239 | +@@ -132,7 +132,10 @@ void QQuickPopupWindow::resizeEvent(QResizeEvent *e) |
| 240 | + |
| 241 | + void QQuickPopupWindowPrivate::setVisible(bool visible) |
| 242 | + { |
| 243 | +- if (m_inHideEvent) |
| 244 | ++ Q_Q(QQuickPopupWindow); |
| 245 | ++ const bool isTransientParentDestroyed = !q->transientParent() ? true : |
| 246 | ++ QQuickWindowPrivate::get(qobject_cast<QQuickWindow *>(q->transientParent()))->inDestructor; |
| 247 | ++ if (m_inHideEvent || isTransientParentDestroyed) |
| 248 | + return; |
| 249 | + |
| 250 | + const bool visibleChanged = QWindowPrivate::visible != visible; |
| 251 | +-- |
| 252 | +2.47.3 |
| 253 | + |
0 commit comments