From f8b151891e276d8f9f1e4c4f3f3bc7ae20af49d5 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Thu, 1 Dec 2022 22:15:02 +0100 Subject: [PATCH] QComboBox: hide the popup on keypress rather than ShortcutOverride MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Qt sends a ShortcutOverride to the focus widget to evaluate whether the widget's key event handling has higher priority than shortcut handling. A KeyPress is then sent if the ShortcutOverride comes back accepted, or if the Shortcut event returns ignored. QComboBox needs to accept the ShortcutOverride for Cancel, so that hiding the popup has priority over application shortcuts. But it should only hide the popup when the KeyPress event actually arrives, as otherwise the the focus widget changes (from popup to combobox), which breaks event delivery on macOS. Fixes: QTBUG-108908 Change-Id: Ie9cce1c2041cbe0e41be301686d7c3b5683e9f10 Reviewed-by: Richard Moe Gustavsen Reviewed-by: Tor Arne Vestbø (cherry picked from commit a874087504cf5af8bb4171d4137f23f100b7063b) Reviewed-by: Qt Cherry-pick Bot --- src/widgets/widgets/qcombobox.cpp | 10 +++++++++- src/widgets/widgets/qcombobox_p.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 330bcb6a397..2f9e49426f5 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -737,7 +737,8 @@ bool QComboBoxPrivateContainer::eventFilter(QObject *o, QEvent *e) default: #if QT_CONFIG(shortcut) if (keyEvent->matches(QKeySequence::Cancel)) { - combo->hidePopup(); + closeOnCancel = true; + keyEvent->accept(); return true; } #endif @@ -784,6 +785,7 @@ bool QComboBoxPrivateContainer::eventFilter(QObject *o, QEvent *e) void QComboBoxPrivateContainer::showEvent(QShowEvent *) { + closeOnCancel = true; combo->update(); } @@ -3234,6 +3236,12 @@ void QComboBox::keyPressEvent(QKeyEvent *e) break; #endif default: + if (e->matches(QKeySequence::Cancel) && (!d->container || d->container->closeOnCancel)) { + hidePopup(); + e->accept(); + d->container->closeOnCancel = false; + } + if (!d->lineEdit) { if (!e->text().isEmpty()) d->keyboardSearchString(e->text()); diff --git a/src/widgets/widgets/qcombobox_p.h b/src/widgets/widgets/qcombobox_p.h index a26f3a34d4c..d7b90bd2a72 100644 --- a/src/widgets/widgets/qcombobox_p.h +++ b/src/widgets/widgets/qcombobox_p.h @@ -221,6 +221,7 @@ private: QComboBoxPrivateScroller *bottom = nullptr; QElapsedTimer popupTimer; bool maybeIgnoreMouseButtonRelease = false; + bool closeOnCancel = false; friend class QComboBox; friend class QComboBoxPrivate;