forked from qt-creator/qt-creator
Prevent locator widgets from running in parallel
We make a promise to locator filters that their prepareSearch() and matchesFor() methods are never run in parallel, and never more than a single matchesFor() call is running at the same time. This broke with the introduction of multiple locator widgets (in multiple windows). Extend the existing code that makes a locator widget "wait" for a running search to cancel and finish, to wait for any locator widget to cancel and finish. Save the currently running search in shared future for that purpose. Change-Id: Id81f31faad9321cbd42bd451c452e542c99bde3a Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
This commit is contained in:
@@ -72,6 +72,9 @@ const int LocatorEntryRole = int(HighlightingItemRole::User);
|
||||
namespace Core {
|
||||
namespace Internal {
|
||||
|
||||
QFuture<void> LocatorWidget::m_sharedFuture;
|
||||
LocatorWidget *LocatorWidget::m_sharedFutureOrigin = nullptr;
|
||||
|
||||
/* A model to represent the Locator results. */
|
||||
class LocatorModel : public QAbstractListModel
|
||||
{
|
||||
@@ -839,13 +842,23 @@ void LocatorWidget::updateCompletionList(const QString &text)
|
||||
return;
|
||||
|
||||
m_updateRequested = true;
|
||||
if (m_entriesWatcher->future().isRunning()) {
|
||||
if (m_sharedFuture.isRunning()) {
|
||||
// Cancel the old future. We may not just block the UI thread to wait for the search to
|
||||
// actually cancel, so try again when the finshed signal of the watcher ends up in
|
||||
// updateEntries() (which will call updateCompletionList again with the
|
||||
// requestedCompletionText)
|
||||
// actually cancel.
|
||||
m_requestedCompletionText = text;
|
||||
m_entriesWatcher->future().cancel();
|
||||
if (m_sharedFutureOrigin == this) {
|
||||
// This locator widget is currently running. Make handleSearchFinished trigger another
|
||||
// update.
|
||||
m_rerunAfterFinished = true;
|
||||
} else {
|
||||
// Another locator widget is running. Trigger another update when that is finished.
|
||||
Utils::onFinished(m_sharedFuture, this, [this](const QFuture<void> &) {
|
||||
const QString text = m_requestedCompletionText;
|
||||
m_requestedCompletionText.clear();
|
||||
updateCompletionList(text);
|
||||
});
|
||||
}
|
||||
m_sharedFuture.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -857,6 +870,8 @@ void LocatorWidget::updateCompletionList(const QString &text)
|
||||
for (ILocatorFilter *filter : filters)
|
||||
filter->prepareSearch(searchText);
|
||||
QFuture<LocatorFilterEntry> future = Utils::runAsync(&runSearch, filters, searchText);
|
||||
m_sharedFuture = QFuture<void>(future);
|
||||
m_sharedFutureOrigin = this;
|
||||
m_entriesWatcher->setFuture(future);
|
||||
}
|
||||
|
||||
@@ -870,7 +885,8 @@ void LocatorWidget::handleSearchFinished()
|
||||
m_rowRequestedForAccept.reset();
|
||||
return;
|
||||
}
|
||||
if (m_entriesWatcher->future().isCanceled()) {
|
||||
if (m_rerunAfterFinished) {
|
||||
m_rerunAfterFinished = false;
|
||||
const QString text = m_requestedCompletionText;
|
||||
m_requestedCompletionText.clear();
|
||||
updateCompletionList(text);
|
||||
|
||||
@@ -97,10 +97,13 @@ private:
|
||||
Utils::FancyLineEdit *m_fileLineEdit = nullptr;
|
||||
QTimer m_showPopupTimer;
|
||||
QFutureWatcher<LocatorFilterEntry> *m_entriesWatcher = nullptr;
|
||||
static QFuture<void> m_sharedFuture;
|
||||
static LocatorWidget *m_sharedFutureOrigin;
|
||||
QString m_requestedCompletionText;
|
||||
bool m_shuttingDown = false;
|
||||
bool m_needsClearResult = true;
|
||||
bool m_updateRequested = false;
|
||||
bool m_rerunAfterFinished = false;
|
||||
bool m_possibleToolTipRequest = false;
|
||||
QWidget *m_progressIndicator = nullptr;
|
||||
QTimer m_showProgressTimer;
|
||||
|
||||
Reference in New Issue
Block a user