From 272808600ae297e67fd97f191ea20ff87d28de2d Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Mon, 29 Apr 2024 15:24:52 +0200 Subject: [PATCH] QCompleter: Hide popup when widget is hidden When the widget the completer is attached to was hidden, the popup stayed open. It would "hang around" with no corresponding UI being around anymore, which is weird. Fixes: QTBUG-124861 Change-Id: If9cb04e693c2663ef9da14164611f26becafc4b4 Reviewed-by: Volker Hilsheimer (cherry picked from commit 24859d7deaf995e992f0d9439a1c476126d5f654) Reviewed-by: Qt Cherry-pick Bot --- src/widgets/util/qcompleter.cpp | 19 ++++++++++--- .../util/qcompleter/tst_qcompleter.cpp | 28 +++++++++++++++++++ 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/widgets/util/qcompleter.cpp b/src/widgets/util/qcompleter.cpp index 394a968aad6..f52321a3e11 100644 --- a/src/widgets/util/qcompleter.cpp +++ b/src/widgets/util/qcompleter.cpp @@ -1296,10 +1296,21 @@ bool QCompleter::eventFilter(QObject *o, QEvent *e) { Q_D(QCompleter); - if (d->eatFocusOut && o == d->widget && e->type() == QEvent::FocusOut) { - d->hiddenBecauseNoMatch = false; - if (d->popup && d->popup->isVisible()) - return true; + if (o == d->widget) { + switch (e->type()) { + case QEvent::FocusOut: + if (d->eatFocusOut) { + d->hiddenBecauseNoMatch = false; + if (d->popup && d->popup->isVisible()) + return true; + } + break; + case QEvent::Hide: + if (d->popup) + d->popup->hide(); + default: + break; + } } if (o != d->popup) diff --git a/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp b/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp index 8b151ec2423..869bf699b1e 100644 --- a/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp +++ b/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp @@ -109,6 +109,8 @@ private slots: void dynamicSortOrder(); void disabledItems(); + void hideWidget(); + // task-specific tests below me void task178797_activatedOnReturn(); void task189564_omitNonSelectableItems(); @@ -1185,6 +1187,32 @@ void tst_QCompleter::disabledItems() QVERIFY(!view->isVisible()); } +void tst_QCompleter::hideWidget() +{ + // hiding the widget should hide/close the popup + QWidget w; + w.setWindowTitle(QLatin1String(QTest::currentTestFunction())); + w.setLayout(new QVBoxLayout); + + QLineEdit edit; + edit.setCompleter(new QCompleter({ "foo", "bar" })); + + w.layout()->addWidget(&edit); + + const auto pos = w.screen()->availableGeometry().topLeft() + QPoint(200, 200); + w.move(pos); + w.show(); + QApplicationPrivate::setActiveWindow(&w); + QVERIFY(QTest::qWaitForWindowActive(&w)); + + // activate the completer + QTest::keyClick(&edit, Qt::Key_F); + QVERIFY(edit.completer()->popup()); + QTRY_VERIFY(edit.completer()->popup()->isVisible()); + edit.hide(); + QVERIFY(!edit.completer()->popup()->isVisible()); +} + void tst_QCompleter::task178797_activatedOnReturn() { if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive))