aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlberto Mardegan <mardy@users.sourceforge.net>2019-03-24 22:54:31 +0300
committerAlberto Mardegan <mardy@users.sourceforge.net>2019-04-10 13:15:58 +0000
commitbd126fdea95ed994fdd35d50e445b45af75657ab (patch)
tree07337b566a799c03a6d0a688aa471ba6014cf3c4
parentf5f36b0db64e77822ef3053245c993ed14949192 (diff)
QQuickComboBox: don't hide popup if focused
The ComboBox popup should be closed when the ComboBox loses focus, but not if the control gaining focus is the popup itself. While all the styles implemented in this module implement the ComboBox popup as an unfocusable window and handle all the keyboard events in QQuickComboBox itself, the developer can choose to replace the popup with a custom implementation, which might need the keyboard focus. Fixes: QTBUG-74661 Change-Id: I838ab9cb697df63ea2099e68f1ae99eadb06be08 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
-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)
+ }
}