summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/querycompleter.cpp14
-rw-r--r--src/querycompleter.h5
2 files changed, 18 insertions, 1 deletions
diff --git a/src/querycompleter.cpp b/src/querycompleter.cpp
index a6a1aeb..7e9dfd9 100644
--- a/src/querycompleter.cpp
+++ b/src/querycompleter.cpp
@@ -422,6 +422,12 @@ bool QueryCompleter::eventFilter(QObject *watched, QEvent *event)
if (event->type() != QEvent::KeyPress || !popupVisible())
return QObject::eventFilter(watched, event);
+ // A key this filter is itself redelivering. sendEvent re-runs application
+ // event filters, so without this the forwarded key comes straight back and
+ // recurses until the stack is gone.
+ if (m_forwarding)
+ return QObject::eventFilter(watched, event);
+
auto *keyEvent = static_cast<QKeyEvent *>(event);
switch (keyEvent->key()) {
case Qt::Key_Tab:
@@ -452,11 +458,17 @@ bool QueryCompleter::eventFilter(QObject *watched, QEvent *event)
case Qt::Key_Up:
case Qt::Key_Down:
case Qt::Key_PageUp:
- case Qt::Key_PageDown:
+ case Qt::Key_PageDown: {
// Navigation belongs to the popup, which is not the focus widget while
// the user is typing in the bar.
+ //
+ // m_forwarding is what keeps this from recursing; see the guard at the
+ // top of the filter.
+ m_forwarding = true;
QCoreApplication::sendEvent(m_popup, event);
+ m_forwarding = false;
return true;
+ }
default:
break;
}
diff --git a/src/querycompleter.h b/src/querycompleter.h
index 6f658f2..27161bc 100644
--- a/src/querycompleter.h
+++ b/src/querycompleter.h
@@ -135,6 +135,11 @@ private:
const Config &m_config;
QStringList m_tags;
+ /// Set while the filter is redelivering a key to the popup. The filter is
+ /// installed on the application and sendEvent re-runs application filters,
+ /// so without this the forwarded key returns to the filter that sent it.
+ bool m_forwarding = false;
+
QCompleter *m_completer = nullptr;
QStandardItemModel *m_model = nullptr;
CompletionPopup *m_popup = nullptr;