Merge pull request #3513 from Flow-Launcher/fix_result_missing

Fix result missing issue
This commit is contained in:
Jack Ye 2025-05-07 19:20:25 +08:00 committed by GitHub
commit 2d2f7de687
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -35,7 +35,7 @@ namespace Flow.Launcher.ViewModel
private Query _lastQuery; private Query _lastQuery;
private bool _lastIsHomeQuery; private bool _lastIsHomeQuery;
private string _queryTextBeforeLeaveResults; private string _queryTextBeforeLeaveResults;
private string _ignoredQueryText = null; private string _ignoredQueryText; // Used to ignore query text change when switching between context menu and query results
private readonly FlowLauncherJsonStorage<History> _historyItemsStorage; private readonly FlowLauncherJsonStorage<History> _historyItemsStorage;
private readonly FlowLauncherJsonStorage<UserSelectedRecord> _userSelectedRecordStorage; private readonly FlowLauncherJsonStorage<UserSelectedRecord> _userSelectedRecordStorage;
@ -46,6 +46,7 @@ namespace Flow.Launcher.ViewModel
private readonly TopMostRecord _topMostRecord; private readonly TopMostRecord _topMostRecord;
private CancellationTokenSource _updateSource; // Used to cancel old query flows private CancellationTokenSource _updateSource; // Used to cancel old query flows
private CancellationToken _updateToken; // Used to avoid ObjectDisposedException of _updateSource.Token
private ChannelWriter<ResultsForUpdate> _resultsUpdateChannelWriter; private ChannelWriter<ResultsForUpdate> _resultsUpdateChannelWriter;
private Task _resultsViewUpdateTask; private Task _resultsViewUpdateTask;
@ -67,6 +68,7 @@ namespace Flow.Launcher.ViewModel
_queryTextBeforeLeaveResults = ""; _queryTextBeforeLeaveResults = "";
_queryText = ""; _queryText = "";
_lastQuery = new Query(); _lastQuery = new Query();
_ignoredQueryText = null; // null as invalid value
Settings = Ioc.Default.GetRequiredService<Settings>(); Settings = Ioc.Default.GetRequiredService<Settings>();
Settings.PropertyChanged += (_, args) => Settings.PropertyChanged += (_, args) =>
@ -248,7 +250,7 @@ namespace Flow.Launcher.ViewModel
return; return;
} }
var token = e.Token == default ? _updateSource.Token : e.Token; var token = e.Token == default ? _updateToken : e.Token;
// make a clone to avoid possible issue that plugin will also change the list and items when updating view model // make a clone to avoid possible issue that plugin will also change the list and items when updating view model
var resultsCopy = DeepCloneResults(e.Results, token); var resultsCopy = DeepCloneResults(e.Results, token);
@ -1264,7 +1266,12 @@ namespace Flow.Launcher.ViewModel
var isHomeQuery = query.RawQuery == string.Empty; var isHomeQuery = query.RawQuery == string.Empty;
_updateSource = new CancellationTokenSource(); _updateSource?.Dispose();
var currentUpdateSource = new CancellationTokenSource();
_updateSource = currentUpdateSource;
var currentCancellationToken = _updateSource.Token;
_updateToken = currentCancellationToken;
ProgressBarVisibility = Visibility.Hidden; ProgressBarVisibility = Visibility.Hidden;
_isQueryRunning = true; _isQueryRunning = true;
@ -1272,7 +1279,7 @@ namespace Flow.Launcher.ViewModel
// Switch to ThreadPool thread // Switch to ThreadPool thread
await TaskScheduler.Default; await TaskScheduler.Default;
if (_updateSource.Token.IsCancellationRequested) return; if (currentCancellationToken.IsCancellationRequested) return;
// Update the query's IsReQuery property to true if this is a re-query // Update the query's IsReQuery property to true if this is a re-query
query.IsReQuery = isReQuery; query.IsReQuery = isReQuery;
@ -1321,12 +1328,11 @@ namespace Flow.Launcher.ViewModel
{ {
// Wait 15 millisecond for query change in global query // Wait 15 millisecond for query change in global query
// if query changes, return so that it won't be calculated // if query changes, return so that it won't be calculated
await Task.Delay(15, _updateSource.Token); await Task.Delay(15, currentCancellationToken);
if (_updateSource.Token.IsCancellationRequested) if (currentCancellationToken.IsCancellationRequested) return;
return;
}*/ }*/
_ = Task.Delay(200, _updateSource.Token).ContinueWith(_ => _ = Task.Delay(200, currentCancellationToken).ContinueWith(_ =>
{ {
// start the progress bar if query takes more than 200 ms and this is the current running query and it didn't finish yet // start the progress bar if query takes more than 200 ms and this is the current running query and it didn't finish yet
if (_isQueryRunning) if (_isQueryRunning)
@ -1334,7 +1340,7 @@ namespace Flow.Launcher.ViewModel
ProgressBarVisibility = Visibility.Visible; ProgressBarVisibility = Visibility.Visible;
} }
}, },
_updateSource.Token, currentCancellationToken,
TaskContinuationOptions.NotOnCanceled, TaskContinuationOptions.NotOnCanceled,
TaskScheduler.Default); TaskScheduler.Default);
@ -1345,21 +1351,21 @@ namespace Flow.Launcher.ViewModel
{ {
tasks = plugins.Select(plugin => plugin.Metadata.HomeDisabled switch tasks = plugins.Select(plugin => plugin.Metadata.HomeDisabled switch
{ {
false => QueryTaskAsync(plugin, _updateSource.Token), false => QueryTaskAsync(plugin, currentCancellationToken),
true => Task.CompletedTask true => Task.CompletedTask
}).ToArray(); }).ToArray();
// Query history results for home page firstly so it will be put on top of the results // Query history results for home page firstly so it will be put on top of the results
if (Settings.ShowHistoryResultsForHomePage) if (Settings.ShowHistoryResultsForHomePage)
{ {
QueryHistoryTask(); QueryHistoryTask(currentCancellationToken);
} }
} }
else else
{ {
tasks = plugins.Select(plugin => plugin.Metadata.Disabled switch tasks = plugins.Select(plugin => plugin.Metadata.Disabled switch
{ {
false => QueryTaskAsync(plugin, _updateSource.Token), false => QueryTaskAsync(plugin, currentCancellationToken),
true => Task.CompletedTask true => Task.CompletedTask
}).ToArray(); }).ToArray();
} }
@ -1374,13 +1380,13 @@ namespace Flow.Launcher.ViewModel
// nothing to do here // nothing to do here
} }
if (_updateSource.Token.IsCancellationRequested) return; if (currentCancellationToken.IsCancellationRequested) return;
// this should happen once after all queries are done so progress bar should continue // this should happen once after all queries are done so progress bar should continue
// until the end of all querying // until the end of all querying
_isQueryRunning = false; _isQueryRunning = false;
if (!_updateSource.Token.IsCancellationRequested) if (!currentCancellationToken.IsCancellationRequested)
{ {
// update to hidden if this is still the current query // update to hidden if this is still the current query
ProgressBarVisibility = Visibility.Hidden; ProgressBarVisibility = Visibility.Hidden;
@ -1440,19 +1446,19 @@ namespace Flow.Launcher.ViewModel
} }
} }
void QueryHistoryTask() void QueryHistoryTask(CancellationToken token)
{ {
// Select last history results and revert its order to make sure last history results are on top // Select last history results and revert its order to make sure last history results are on top
var historyItems = _history.Items.TakeLast(Settings.MaxHistoryResultsToShowForHomePage).Reverse(); var historyItems = _history.Items.TakeLast(Settings.MaxHistoryResultsToShowForHomePage).Reverse();
var results = GetHistoryItems(historyItems); var results = GetHistoryItems(historyItems);
if (_updateSource.Token.IsCancellationRequested) return; if (token.IsCancellationRequested) return;
App.API.LogDebug(ClassName, $"Update results for history"); App.API.LogDebug(ClassName, $"Update results for history");
if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(results, _historyMetadata, query, if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(results, _historyMetadata, query,
_updateSource.Token))) token)))
{ {
App.API.LogError(ClassName, "Unable to add item to Result Update Queue"); App.API.LogError(ClassName, "Unable to add item to Result Update Queue");
} }