From 16c93b423d3f2bb3b753aeb36f83edc4c23810de Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Thu, 12 Jul 2018 08:59:59 +0200 Subject: [PATCH] Fix focus handling when leaving locator Pressing escape or triggering an item should get your focus back to where you were, also in external editor and help windows. Fixes triggering editor related menu items like "Close" from locator. Task-number: QTCREATORBUG-20071 Change-Id: I0111b846e9476697a7bba7856bb2cc4b5bef7979 Reviewed-by: David Schulz --- .../coreplugin/locator/locatorwidget.cpp | 38 +++++++++++++++---- .../coreplugin/locator/locatorwidget.h | 4 +- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/plugins/coreplugin/locator/locatorwidget.cpp b/src/plugins/coreplugin/locator/locatorwidget.cpp index 2318f072034..33a66f77eca 100644 --- a/src/plugins/coreplugin/locator/locatorwidget.cpp +++ b/src/plugins/coreplugin/locator/locatorwidget.cpp @@ -592,6 +592,8 @@ LocatorWidget::LocatorWidget(Locator *locator) : updatePlaceholderText(locateCmd); } + connect(qApp, &QApplication::focusChanged, this, &LocatorWidget::updatePreviousFocusWidget); + connect(locator, &Locator::filtersChanged, this, &LocatorWidget::updateFilterList); updateFilterList(); } @@ -620,6 +622,28 @@ void LocatorWidget::updateFilterList() m_filterMenu->addAction(m_configureAction); } +bool LocatorWidget::isInMainWindow() const +{ + return window() == ICore::mainWindow(); +} + +void LocatorWidget::updatePreviousFocusWidget(QWidget *previous, QWidget *current) +{ + const auto isInLocator = [this](QWidget *w) { return w == this || isAncestorOf(w); }; + if (isInLocator(current) && !isInLocator(previous)) + m_previousFocusWidget = previous; +} + +static void resetFocus(QPointer previousFocus, bool isInMainWindow) +{ + if (previousFocus) { + previousFocus->setFocus(); + ICore::raiseWindow(previousFocus); + } else if (isInMainWindow) { + ModeManager::setFocusToCurrentMode(); + } +} + bool LocatorWidget::eventFilter(QObject *obj, QEvent *event) { if (obj == m_fileLineEdit && event->type() == QEvent::ShortcutOverride) { @@ -706,7 +730,12 @@ bool LocatorWidget::eventFilter(QObject *obj, QEvent *event) case Qt::Key_Escape: if (!ke->modifiers()) { event->accept(); - QTimer::singleShot(0, this, &LocatorWidget::setFocusToCurrentMode); + QTimer::singleShot(0, + this, + [focus = m_previousFocusWidget, + isInMainWindow = isInMainWindow()] { + resetFocus(focus, isInMainWindow); + }); return true; } break; @@ -723,11 +752,6 @@ bool LocatorWidget::eventFilter(QObject *obj, QEvent *event) return QWidget::eventFilter(obj, event); } -void LocatorWidget::setFocusToCurrentMode() -{ - ModeManager::setFocusToCurrentMode(); -} - void LocatorWidget::showPopupDelayed() { m_updateRequested = true; @@ -858,7 +882,7 @@ void LocatorWidget::acceptEntry(int row) entry.filter->accept(entry, &newText, &selectionStart, &selectionLength); if (newText.isEmpty()) { emit hidePopup(); - m_fileLineEdit->clearFocus(); + resetFocus(m_previousFocusWidget, isInMainWindow()); } else { showText(newText, selectionStart, selectionLength); } diff --git a/src/plugins/coreplugin/locator/locatorwidget.h b/src/plugins/coreplugin/locator/locatorwidget.h index 22ab9bbc015..6d5a3a2a745 100644 --- a/src/plugins/coreplugin/locator/locatorwidget.h +++ b/src/plugins/coreplugin/locator/locatorwidget.h @@ -79,9 +79,10 @@ private: void showConfigureDialog(); void addSearchResults(int firstIndex, int endIndex); void handleSearchFinished(); - void setFocusToCurrentMode(); void updateFilterList(); + bool isInMainWindow() const; + void updatePreviousFocusWidget(QWidget *previous, QWidget *current); bool eventFilter(QObject *obj, QEvent *event) override; void updateCompletionList(const QString &text); @@ -103,6 +104,7 @@ private: QWidget *m_progressIndicator = nullptr; QTimer m_showProgressTimer; Utils::optional m_rowRequestedForAccept; + QPointer m_previousFocusWidget; }; class LocatorPopup : public QWidget