aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMitch Curtis <mitch.curtis@qt.io>2021-01-11 17:03:21 +0100
committerMitch Curtis <mitch.curtis@qt.io>2021-01-13 13:27:57 +0100
commit51d416cdfd909aacd5047632a7cc1661a158731a (patch)
tree9880e8ee8b2ce0cbe65645f6dddc3e4f2f067357 /src
parent4b66c0bd7de6063982459fe45f69278fd0519b1b (diff)
Fix popups with exit transitions blocking mouse events when destroyed
If a popup had an exit transition set and was destroyed upon e.g. being rejected, it would not destroy its modal dimmer, and so events would not go through to popups that were beneath it even after it was destroyed. QQuickPopup's destructor does indirectly attempt to call finalizeExitTransition() through a setParentItem(nullptr) call, but prepareExitTransition() returns false if it sees that the exit transition is already running, and so transitionExit() never calls finished(). This patch fixes the problem by explicitly calling finalizeExitTransition() in QQuickPopup's destructor if the exit transition is running. Fixes: QTBUG-89673 Pick-to: 5.15 6.0 Change-Id: I468fae52f6a83ac314877c67d062028634bb7e17 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/quicktemplates2/qquickpopup.cpp23
1 files changed, 19 insertions, 4 deletions
diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp
index 455b0425..f54b610c 100644
--- a/src/quicktemplates2/qquickpopup.cpp
+++ b/src/quicktemplates2/qquickpopup.cpp
@@ -51,6 +51,8 @@
QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(lcDimmer, "qt.quick.controls.popup.dimmer")
+
/*!
\qmltype Popup
\inherits QtObject
@@ -499,8 +501,10 @@ void QQuickPopupPrivate::finalizeExitTransition()
{
Q_Q(QQuickPopup);
getPositioner()->setParentItem(nullptr);
- popupItem->setParentItem(nullptr);
- popupItem->setVisible(false);
+ if (popupItem) {
+ popupItem->setParentItem(nullptr);
+ popupItem->setVisible(false);
+ }
destroyOverlay();
if (hadActiveFocusBeforeExitTransition && window) {
@@ -531,8 +535,10 @@ void QQuickPopupPrivate::finalizeExitTransition()
hadActiveFocusBeforeExitTransition = false;
emit q->visibleChanged();
emit q->closed();
- popupItem->setScale(prevScale);
- popupItem->setOpacity(prevOpacity);
+ if (popupItem) {
+ popupItem->setScale(prevScale);
+ popupItem->setOpacity(prevOpacity);
+ }
}
void QQuickPopupPrivate::opened()
@@ -733,6 +739,8 @@ static QQuickItem *createDimmer(QQmlComponent *component, QQuickPopup *popup, QQ
if (component)
component->completeCreate();
}
+ qCDebug(lcDimmer) << "finished creating dimmer from component" << component
+ << "for popup" << popup << "with parent" << parent << "- item is:" << item;
return item;
}
@@ -759,6 +767,7 @@ void QQuickPopupPrivate::createOverlay()
void QQuickPopupPrivate::destroyOverlay()
{
if (dimmer) {
+ qCDebug(lcDimmer) << "destroying dimmer" << dimmer;
dimmer->setParentItem(nullptr);
dimmer->deleteLater();
dimmer = nullptr;
@@ -857,6 +866,12 @@ QQuickPopup::~QQuickPopup()
d->popupItem = nullptr;
delete d->positioner;
d->positioner = nullptr;
+
+ // If the popup is destroyed before the exit transition finishes,
+ // the necessary cleanup (removing modal dimmers that block mouse events,
+ // emitting closed signal, etc.) won't happen. That's why we do it manually here.
+ if (d->transitionState == QQuickPopupPrivate::ExitTransition && d->transitionManager.isRunning())
+ d->finalizeExitTransition();
}
/*!