aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/quicktemplates2/qquickcombobox.cpp10
-rw-r--r--tests/auto/controls/data/tst_combobox.qml51
2 files changed, 56 insertions, 5 deletions
diff --git a/src/quicktemplates2/qquickcombobox.cpp b/src/quicktemplates2/qquickcombobox.cpp
index 03dd6086..328797b8 100644
--- a/src/quicktemplates2/qquickcombobox.cpp
+++ b/src/quicktemplates2/qquickcombobox.cpp
@@ -1556,10 +1556,10 @@ bool QQuickComboBox::eventFilter(QObject *object, QEvent *event)
break;
}
case QEvent::FocusOut:
- if (qGuiApp->focusObject() != this) {
+ if (qGuiApp->focusObject() != this && (!d->popup || !d->popup->hasActiveFocus())) {
// Only close the popup if focus was transferred somewhere else
- // than to the popup button (which normally means that the user
- // clicked on the popup button to open it, not close it.
+ // than to the popup or the popup button (which normally means that
+ // the user clicked on the popup button to open it, not close it).
d->hidePopup(false);
setPressed(false);
}
@@ -1589,9 +1589,9 @@ void QQuickComboBox::focusOutEvent(QFocusEvent *event)
Q_D(QQuickComboBox);
QQuickControl::focusOutEvent(event);
- if (qGuiApp->focusObject() != d->contentItem) {
+ if (qGuiApp->focusObject() != d->contentItem && (!d->popup || !d->popup->hasActiveFocus())) {
// Only close the popup if focus was transferred
- // somewhere else than to the inner line edit (which is
+ // somewhere else than to the popup or the inner line edit (which is
// normally done from QQuickComboBox::focusInEvent).
d->hidePopup(false);
setPressed(false);
diff --git a/tests/auto/controls/data/tst_combobox.qml b/tests/auto/controls/data/tst_combobox.qml
index 70c4f090..0d266e1a 100644
--- a/tests/auto/controls/data/tst_combobox.qml
+++ b/tests/auto/controls/data/tst_combobox.qml
@@ -85,6 +85,17 @@ TestCase {
MouseArea { }
}
+ Component {
+ id: customPopup
+ Popup {
+ width: 100
+ implicitHeight: contentItem.implicitHeight
+ contentItem: TextInput {
+ anchors.fill: parent
+ }
+ }
+ }
+
function init() {
// QTBUG-61225: Move the mouse away to avoid QQuickWindowPrivate::flushFrameSynchronousEvents()
// delivering interfering hover events based on the last mouse position from earlier tests. For
@@ -1680,4 +1691,44 @@ TestCase {
compare(container.releasedKeys, ++releasedKeys)
compare(container.lastReleasedKey, data.key)
}
+
+ function test_popupFocus_QTBUG_74661() {
+ var control = createTemporaryObject(comboBox, testCase)
+ verify(control)
+
+ var popup = createTemporaryObject(customPopup, testCase)
+ verify(popup)
+
+ control.popup = popup
+
+ var openedSpy = signalSpy.createObject(control, {target: popup, signalName: "opened"})
+ verify(openedSpy.valid)
+
+ var closedSpy = signalSpy.createObject(control, {target: popup, signalName: "closed"})
+ verify(closedSpy.valid)
+
+ control.forceActiveFocus()
+ verify(control.activeFocus)
+
+ // show popup
+ keyClick(Qt.Key_Space)
+ openedSpy.wait()
+ compare(openedSpy.count, 1)
+
+ popup.contentItem.forceActiveFocus()
+ verify(popup.contentItem.activeFocus)
+
+ // type something in the text field
+ keyClick(Qt.Key_Space)
+ keyClick(Qt.Key_H)
+ keyClick(Qt.Key_I)
+ compare(popup.contentItem.text, " hi")
+
+ compare(closedSpy.count, 0)
+
+ // hide popup
+ keyClick(Qt.Key_Escape)
+ closedSpy.wait()
+ compare(closedSpy.count, 1)
+ }
}