diff options
Diffstat (limited to 'src')
-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 |
3 files changed, 76 insertions, 11 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: |