diff options
-rw-r--r-- | src/quicktemplates2/qquickpopup.cpp | 73 | ||||
-rw-r--r-- | src/quicktemplates2/qquickpopup_p_p.h | 4 | ||||
-rw-r--r-- | src/quicktemplates2/qquickshortcutcontext.cpp | 10 | ||||
-rw-r--r-- | tests/auto/controls/data/tst_combobox.qml | 1 |
4 files changed, 76 insertions, 12 deletions
diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp index 6273e4ef..518117fa 100644 --- a/src/quicktemplates2/qquickpopup.cpp +++ b/src/quicktemplates2/qquickpopup.cpp @@ -37,9 +37,12 @@ #include "qquickpopup_p.h" #include "qquickpopup_p_p.h" #include "qquickapplicationwindow_p.h" +#include "qquickshortcutcontext_p_p.h" #include "qquickoverlay_p_p.h" #include "qquickcontrol_p_p.h" +#include <QtGui/private/qshortcutmap_p.h> +#include <QtGui/private/qguiapplication_p.h> #include <QtQml/qqmlinfo.h> #include <QtQuick/qquickitem.h> #include <QtQuick/private/qquicktransition_p.h> @@ -433,10 +436,15 @@ public: void resolveFont() override; + int backId; + int escapeId; QQuickPopup *popup; }; -QQuickPopupItemPrivate::QQuickPopupItemPrivate(QQuickPopup *popup) : popup(popup) +QQuickPopupItemPrivate::QQuickPopupItemPrivate(QQuickPopup *popup) + : backId(0), + escapeId(0), + popup(popup) { isTabFence = true; } @@ -479,6 +487,47 @@ void QQuickPopupItem::updatePolish() return QQuickPopupPrivate::get(d->popup)->reposition(); } +void QQuickPopupItem::grabShortcut() +{ +#ifndef QT_NO_SHORTCUT + Q_D(QQuickPopupItem); + QGuiApplicationPrivate *pApp = QGuiApplicationPrivate::instance(); + if (!d->backId) + d->backId = pApp->shortcutMap.addShortcut(this, Qt::Key_Back, Qt::WindowShortcut, QQuickShortcutContext::matcher); + if (!d->escapeId) + d->escapeId = pApp->shortcutMap.addShortcut(this, Qt::Key_Escape, Qt::WindowShortcut, QQuickShortcutContext::matcher); +#endif // QT_NO_SHORTCUT +} + +void QQuickPopupItem::ungrabShortcut() +{ +#ifndef QT_NO_SHORTCUT + Q_D(QQuickPopupItem); + QGuiApplicationPrivate *pApp = QGuiApplicationPrivate::instance(); + if (d->backId) { + pApp->shortcutMap.removeShortcut(d->backId, this); + d->backId = 0; + } + if (d->escapeId) { + pApp->shortcutMap.removeShortcut(d->escapeId, this); + d->escapeId = 0; + } +#endif // QT_NO_SHORTCUT +} + +bool QQuickPopupItem::event(QEvent *event) +{ + Q_D(QQuickPopupItem); + if (event->type() == QEvent::Shortcut) { + QShortcutEvent *se = static_cast<QShortcutEvent *>(event); + if (se->shortcutId() == d->escapeId || se->shortcutId() == d->backId) { + d->popup->close(); + return true; + } + } + return QQuickItem::event(event); +} + bool QQuickPopupItem::childMouseEventFilter(QQuickItem *child, QEvent *event) { Q_D(QQuickPopupItem); @@ -912,6 +961,7 @@ QQuickPopup::~QQuickPopup() { Q_D(QQuickPopup); setParentItem(nullptr); + d->popupItem->ungrabShortcut(); delete d->popupItem; } @@ -1963,6 +2013,12 @@ void QQuickPopup::setClosePolicy(ClosePolicy policy) if (d->closePolicy == policy) return; d->closePolicy = policy; + if (isVisible()) { + if (policy & QQuickPopup::CloseOnEscape) + d->popupItem->grabShortcut(); + else + d->popupItem->ungrabShortcut(); + } emit closePolicyChanged(); } @@ -2131,12 +2187,6 @@ void QQuickPopup::keyPressEvent(QKeyEvent *event) if (hasActiveFocus() && (event->key() == Qt::Key_Tab || event->key() == Qt::Key_Backtab)) QQuickItemPrivate::focusNextPrev(d->popupItem, event->key() == Qt::Key_Tab); - - if (event->key() != Qt::Key_Escape && event->key() != Qt::Key_Back) - return; - - if (d->closePolicy.testFlag(CloseOnEscape)) - close(); } void QQuickPopup::keyReleaseEvent(QKeyEvent *event) @@ -2233,7 +2283,7 @@ void QQuickPopup::geometryChanged(const QRectF &newGeometry, const QRectF &oldGe void QQuickPopup::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data) { - Q_UNUSED(data); + Q_D(QQuickPopup); switch (change) { case QQuickItem::ItemActiveFocusHasChanged: @@ -2242,6 +2292,13 @@ void QQuickPopup::itemChange(QQuickItem::ItemChange change, const QQuickItem::It case QQuickItem::ItemOpacityHasChanged: emit opacityChanged(); break; + case QQuickItem::ItemVisibleHasChanged: + if (isComponentComplete() && d->closePolicy & CloseOnEscape) { + if (data.boolValue) + d->popupItem->grabShortcut(); + else + d->popupItem->ungrabShortcut(); + } default: break; } diff --git a/src/quicktemplates2/qquickpopup_p_p.h b/src/quicktemplates2/qquickpopup_p_p.h index d2f16e11..96ce2ca0 100644 --- a/src/quicktemplates2/qquickpopup_p_p.h +++ b/src/quicktemplates2/qquickpopup_p_p.h @@ -86,9 +86,13 @@ class QQuickPopupItem : public QQuickControl public: explicit QQuickPopupItem(QQuickPopup *popup); + void grabShortcut(); + void ungrabShortcut(); + protected: void updatePolish() override; + bool event(QEvent *event) override; bool childMouseEventFilter(QQuickItem *child, QEvent *event) override; void focusInEvent(QFocusEvent *event) override; void focusOutEvent(QFocusEvent *event) override; diff --git a/src/quicktemplates2/qquickshortcutcontext.cpp b/src/quicktemplates2/qquickshortcutcontext.cpp index 2a3cb68a..04aa4f4d 100644 --- a/src/quicktemplates2/qquickshortcutcontext.cpp +++ b/src/quicktemplates2/qquickshortcutcontext.cpp @@ -50,8 +50,8 @@ static bool isBlockedByPopup(QQuickItem *item) QQuickOverlay *overlay = QQuickOverlay::overlay(item->window()); const auto popups = QQuickOverlayPrivate::get(overlay)->stackingOrderPopups(); for (QQuickPopup *popup : popups) { - if (popup->isModal()) - return !popup->popupItem()->isAncestorOf(item); + if (popup->isModal() || popup->closePolicy() & QQuickPopup::CloseOnEscape) + return item != popup->popupItem() && !popup->popupItem()->isAncestorOf(item); } return false; @@ -67,8 +67,12 @@ bool QQuickShortcutContext::matcher(QObject *obj, Qt::ShortcutContext context) while (obj && !obj->isWindowType()) { obj = obj->parent(); item = qobject_cast<QQuickItem *>(obj); - if (item) + if (item) { obj = item->window(); + } else if (QQuickPopup *popup = qobject_cast<QQuickPopup *>(obj)) { + obj = popup->window(); + item = popup->popupItem(); + } } return obj && obj == QGuiApplication::focusWindow() && !isBlockedByPopup(item); default: diff --git a/tests/auto/controls/data/tst_combobox.qml b/tests/auto/controls/data/tst_combobox.qml index 97ba7ea4..7d7e519f 100644 --- a/tests/auto/controls/data/tst_combobox.qml +++ b/tests/auto/controls/data/tst_combobox.qml @@ -467,7 +467,6 @@ TestCase { // hide popup keyPress(data.key2) compare(control.pressed, data.hidePress) - compare(control.popup.visible, data.showPopup) keyRelease(data.key2) compare(control.pressed, false) tryCompare(control.popup, "visible", !data.hidePopup) |