private void HandleQueryTextUpdated() { if (_ignoreTextChange) { _ignoreTextChange = false; return; } IsProgressBarTooltipVisible = false; if (ContextMenuVisibility.IsVisible()) { QueryContextMenu(); } else { string query = QueryText.Trim(); if (!string.IsNullOrEmpty(query)) { Query(query); //reset query history index after user start new query ResetQueryHistoryIndex(); } else { Results.Clear(); } } }
private void HandleQueryTextUpdated() { ProgressBarVisibility = Visibility.Hidden; _updateSource?.Cancel(); _updateSource = new CancellationTokenSource(); _updateToken = _updateSource.Token; if (ContextMenuVisibility.IsVisible()) { QueryContextMenu(); } else { string query = QueryText.Trim(); if (!string.IsNullOrEmpty(query)) { Query(query); //reset query history index after user start new query ResetQueryHistoryIndex(); } else { Results.Clear(); ResultListBoxVisibility = Visibility.Collapsed; } } }
private void QueryResults() { if (!string.IsNullOrEmpty(QueryText)) { _updateSource?.Cancel(); _updateSource = new CancellationTokenSource(); _updateToken = _updateSource.Token; ProgressBarVisibility = Visibility.Hidden; _queryHasReturn = false; var query = PluginManager.QueryInit(QueryText.Trim()); if (query != null) { // handle the exclusiveness of plugin using action keyword string lastKeyword = _lastQuery.ActionKeyword; string keyword = query.ActionKeyword; if (string.IsNullOrEmpty(lastKeyword)) { if (!string.IsNullOrEmpty(keyword)) { Results.RemoveResultsExcept(PluginManager.NonGlobalPlugins[keyword].Metadata); } } else { if (string.IsNullOrEmpty(keyword)) { Results.RemoveResultsFor(PluginManager.NonGlobalPlugins[lastKeyword].Metadata); } else if (lastKeyword != keyword) { Results.RemoveResultsExcept(PluginManager.NonGlobalPlugins[keyword].Metadata); } } _lastQuery = query; Task.Delay(200, _updateToken).ContinueWith(_ => { if (query.RawQuery == _lastQuery.RawQuery && !_queryHasReturn) { ProgressBarVisibility = Visibility.Visible; } }, _updateToken); var plugins = PluginManager.ValidPluginsForQuery(query); Task.Run(() => { Parallel.ForEach(plugins, plugin => { var config = _settings.PluginSettings.Plugins[plugin.Metadata.ID]; if (!config.Disabled) { var results = PluginManager.QueryForPlugin(plugin, query); UpdateResultView(results, plugin.Metadata, query); } }); }, _updateToken); } } else { Results.Clear(); Results.Visbility = Visibility.Collapsed; } }
private void QueryResults() { if (!string.IsNullOrEmpty(QueryText)) { var queryTimer = new System.Diagnostics.Stopwatch(); queryTimer.Start(); _updateSource?.Cancel(); var currentUpdateSource = new CancellationTokenSource(); _updateSource = currentUpdateSource; var currentCancellationToken = _updateSource.Token; _updateToken = currentCancellationToken; var query = QueryBuilder.Build(QueryText.Trim(), PluginManager.NonGlobalPlugins); if (query != null) { _lastQuery = query; Task.Run(() => { Thread.Sleep(20); RemoveOldQueryResults(query); var plugins = PluginManager.ValidPluginsForQuery(query); try { currentCancellationToken.ThrowIfCancellationRequested(); foreach (PluginPair plugin in plugins) { if (!plugin.Metadata.Disabled && !currentCancellationToken.IsCancellationRequested) { var results = PluginManager.QueryForPlugin(plugin, query); currentCancellationToken.ThrowIfCancellationRequested(); lock (_addResultsLock) { UpdateResultView(results, plugin.Metadata, query); } } } currentCancellationToken.ThrowIfCancellationRequested(); Application.Current.Dispatcher.BeginInvoke(new Action(() => { if (query.RawQuery == _lastQuery.RawQuery) { Results.Results.NotifyChanges(); } if (Results.Results.Count > 0) { Results.Visibility = Visibility.Visible; Results.SelectedIndex = 0; } else { Results.Visibility = Visibility.Hidden; } })); } catch (OperationCanceledException) { // nothing to do here } queryTimer.Stop(); var queryEvent = new LauncherQueryEvent() { QueryTimeMs = queryTimer.ElapsedMilliseconds, NumResults = Results.Results.Count, QueryLength = query.RawQuery.Length }; PowerToysTelemetry.Log.WriteEvent(queryEvent); }, currentCancellationToken); } } else { _updateSource?.Cancel(); _lastQuery = _emptyQuery; Results.SelectedItem = null; Results.Visibility = Visibility.Hidden; Results.Clear(); } }
private void QueryResults() { if (!string.IsNullOrEmpty(QueryText)) { var queryTimer = new System.Diagnostics.Stopwatch(); queryTimer.Start(); _updateSource?.Cancel(); var currentUpdateSource = new CancellationTokenSource(); _updateSource = currentUpdateSource; var currentCancellationToken = _updateSource.Token; _updateToken = currentCancellationToken; ProgressBarVisibility = Visibility.Hidden; _isQueryRunning = true; var query = QueryBuilder.Build(QueryText.Trim(), PluginManager.NonGlobalPlugins); if (query != null) { // handle the exclusiveness of plugin using action keyword RemoveOldQueryResults(query); _lastQuery = query; var plugins = PluginManager.ValidPluginsForQuery(query); Task.Run(() => { // so looping will stop once it was cancelled var parallelOptions = new ParallelOptions { CancellationToken = currentCancellationToken }; try { Parallel.ForEach(plugins, parallelOptions, plugin => { if (!plugin.Metadata.Disabled) { var results = PluginManager.QueryForPlugin(plugin, query); if (Application.Current.Dispatcher.CheckAccess()) { UpdateResultView(results, plugin.Metadata, query); } else { Application.Current.Dispatcher.BeginInvoke(new Action(() => { UpdateResultView(results, plugin.Metadata, query); })); } } }); } catch (OperationCanceledException) { // nothing to do here } // this should happen once after all queries are done so progress bar should continue // until the end of all querying _isQueryRunning = false; if (currentUpdateSource == _updateSource) { // update to hidden if this is still the current query ProgressBarVisibility = Visibility.Hidden; } queryTimer.Stop(); var queryEvent = new LauncherQueryEvent() { QueryTimeMs = queryTimer.ElapsedMilliseconds, NumResults = Results.Results.Count, QueryLength = query.RawQuery.Length }; PowerToysTelemetry.Log.WriteEvent(queryEvent); }, currentCancellationToken); } } else { Results.SelectedItem = null; Results.Clear(); Results.Visibility = Visibility.Collapsed; } }
private void QueryResults() { if (_updateSource != null && !_updateSource.IsCancellationRequested) { // first condition used for init run // second condition used when task has already been canceled in last turn _updateSource.Cancel(); Logger.WoxDebug($"cancel init {_updateSource.Token.GetHashCode()} {Thread.CurrentThread.ManagedThreadId} {QueryText}"); _updateSource.Dispose(); } var source = new CancellationTokenSource(); _updateSource = source; var token = source.Token; ProgressBarVisibility = Visibility.Hidden; var queryText = QueryText.Trim(); Task.Run(() => { if (!string.IsNullOrEmpty(queryText)) { if (token.IsCancellationRequested) { return; } var query = QueryBuilder.Build(queryText, PluginManager.NonGlobalPlugins); _lastQuery = query; if (query != null) { // handle the exclusiveness of plugin using action keyword if (token.IsCancellationRequested) { return; } Task.Delay(200, token).ContinueWith(_ => { Logger.WoxTrace($"progressbar visible 1 {token.GetHashCode()} {token.IsCancellationRequested} {Thread.CurrentThread.ManagedThreadId} {query} {ProgressBarVisibility}"); // start the progress bar if query takes more than 200 ms if (!token.IsCancellationRequested) { ProgressBarVisibility = Visibility.Visible; } }, token); if (token.IsCancellationRequested) { return; } var plugins = PluginManager.ValidPluginsForQuery(query).Where(p => !p.Metadata.Disabled).ToList(); var option = new ParallelOptions() { CancellationToken = token, }; CountdownEvent countdown = new CountdownEvent(plugins.Count); Parallel.ForEach(plugins, plugin => { if (token.IsCancellationRequested) { Logger.WoxTrace($"canceled {token.GetHashCode()} {Thread.CurrentThread.ManagedThreadId} {queryText} {plugin.Metadata.Name}"); countdown.Signal(); return; } var results = PluginManager.QueryForPlugin(plugin, query); if (token.IsCancellationRequested) { Logger.WoxTrace($"canceled {token.GetHashCode()} {Thread.CurrentThread.ManagedThreadId} {queryText} {plugin.Metadata.Name}"); countdown.Signal(); return; } _resultsQueue.Add(new ResultsForUpdate(results, plugin.Metadata, query, token, countdown)); }); Task.Run(() => { Logger.WoxTrace($"progressbar visible 2 {token.GetHashCode()} {token.IsCancellationRequested} {Thread.CurrentThread.ManagedThreadId} {query} {ProgressBarVisibility}"); // wait all plugins has been processed try { countdown.Wait(token); } catch (OperationCanceledException) { // todo: why we need hidden here and why progress bar is not working ProgressBarVisibility = Visibility.Hidden; return; } if (!token.IsCancellationRequested) { // used to cancel previous progress bar visible task source.Cancel(); source.Dispose(); // update to hidden if this is still the current query ProgressBarVisibility = Visibility.Hidden; } }); } } else { Results.Clear(); Results.Visbility = Visibility.Collapsed; } }, token); }
private void QueryResults() { if (!string.IsNullOrEmpty(QueryText)) { var queryTimer = new System.Diagnostics.Stopwatch(); queryTimer.Start(); _updateSource?.Cancel(); var currentUpdateSource = new CancellationTokenSource(); _updateSource = currentUpdateSource; var currentCancellationToken = _updateSource.Token; _updateToken = currentCancellationToken; var query = QueryBuilder.Build(QueryText.Trim(), PluginManager.NonGlobalPlugins); if (query != null) { _currentQuery = query; Task.Run(() => { Thread.Sleep(20); var plugins = PluginManager.ValidPluginsForQuery(query); try { currentCancellationToken.ThrowIfCancellationRequested(); var resultPluginPair = new List <(List <Result>, PluginMetadata)>(); foreach (PluginPair plugin in plugins) { if (!plugin.Metadata.Disabled) { var results = PluginManager.QueryForPlugin(plugin, query); resultPluginPair.Add((results, plugin.Metadata)); currentCancellationToken.ThrowIfCancellationRequested(); } } lock (_addResultsLock) { if (query.RawQuery == _currentQuery.RawQuery) { Results.Clear(); foreach (var p in resultPluginPair) { UpdateResultView(p.Item1, query, currentCancellationToken); currentCancellationToken.ThrowIfCancellationRequested(); } currentCancellationToken.ThrowIfCancellationRequested(); Results.Sort(); } } currentCancellationToken.ThrowIfCancellationRequested(); UpdateResultsListViewAfterQuery(query); // Run the slower query of the DelayedExecution plugins currentCancellationToken.ThrowIfCancellationRequested(); Parallel.ForEach(plugins, (plugin) => { if (!plugin.Metadata.Disabled) { var results = PluginManager.QueryForPlugin(plugin, query, true); currentCancellationToken.ThrowIfCancellationRequested(); if ((results?.Count ?? 0) != 0) { lock (_addResultsLock) { if (query.RawQuery == _currentQuery.RawQuery) { currentCancellationToken.ThrowIfCancellationRequested(); // Remove the original results from the plugin Results.Results.RemoveAll(r => r.Result.PluginID == plugin.Metadata.ID); currentCancellationToken.ThrowIfCancellationRequested(); // Add the new results from the plugin UpdateResultView(results, query, currentCancellationToken); currentCancellationToken.ThrowIfCancellationRequested(); Results.Sort(); } } currentCancellationToken.ThrowIfCancellationRequested(); UpdateResultsListViewAfterQuery(query, true); } } }); } catch (OperationCanceledException) { // nothing to do here } queryTimer.Stop(); var queryEvent = new LauncherQueryEvent() { QueryTimeMs = queryTimer.ElapsedMilliseconds, NumResults = Results.Results.Count, QueryLength = query.RawQuery.Length }; PowerToysTelemetry.Log.WriteEvent(queryEvent); }, currentCancellationToken); } } else { _updateSource?.Cancel(); _currentQuery = _emptyQuery; Results.SelectedItem = null; Results.Visibility = Visibility.Hidden; Results.Clear(); } }
private void QueryResults() { if (!string.IsNullOrEmpty(QueryText)) { _updateSource?.Cancel(); var currentUpdateSource = new CancellationTokenSource(); _updateSource = currentUpdateSource; var currentCancellationToken = _updateSource.Token; _updateToken = currentCancellationToken; ProgressBarVisibility = Visibility.Hidden; _isQueryRunning = true; var query = QueryBuilder.Build(QueryText.Trim(), PluginManager.NonGlobalPlugins); if (query != null) { // handle the exclusiveness of plugin using action keyword RemoveOldQueryResults(query); _lastQuery = query; 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 if (currentUpdateSource == _updateSource && _isQueryRunning) { ProgressBarVisibility = Visibility.Visible; } }, currentCancellationToken); var plugins = PluginManager.ValidPluginsForQuery(query); Task.Run(() => { // so looping will stop once it was cancelled var parallelOptions = new ParallelOptions { CancellationToken = currentCancellationToken }; try { Parallel.ForEach(plugins, parallelOptions, plugin => { if (!plugin.Metadata.Disabled) { var results = PluginManager.QueryForPlugin(plugin, query); UpdateResultView(results, plugin.Metadata, query); } }); } catch (OperationCanceledException) { // nothing to do here } // this should happen once after all queries are done so progress bar should continue // until the end of all querying _isQueryRunning = false; if (currentUpdateSource == _updateSource) { // update to hidden if this is still the current query ProgressBarVisibility = Visibility.Hidden; } }, currentCancellationToken); } } else { Results.Clear(); Results.Visbility = Visibility.Collapsed; } }
private void QueryResults() { if (_updateSource != null && !_updateSource.IsCancellationRequested) { _updateSource.Cancel(); _updateSource.Dispose(); } var updateSource = new CancellationTokenSource(); _updateSource = updateSource; var token = updateSource.Token; _updateToken = token; ProgressBarVisibility = Visibility.Hidden; var queryText = QueryText.Trim(); if (!string.IsNullOrEmpty(queryText)) { if (token.IsCancellationRequested) { return; } var query = QueryBuilder.Build(queryText, PluginManager.NonGlobalPlugins); if (query != null) { // handle the exclusiveness of plugin using action keyword RemoveOldQueryResults(query); _lastQuery = query; Task.Delay(200, token).ContinueWith(_ => { // start the progress bar if query takes more than 200 ms if (!token.IsCancellationRequested) { ProgressBarVisibility = Visibility.Visible; Logger.WoxDebug($"progressbar visible {query} {token.IsCancellationRequested} {ProgressBarVisibility}"); } }, token); Task.Run(() => { if (token.IsCancellationRequested) { return; } var plugins = PluginManager.ValidPluginsForQuery(query); // so looping will stop once it was cancelled var parallelOptions = new ParallelOptions { CancellationToken = token }; try { Parallel.ForEach(plugins, parallelOptions, plugin => { if (!plugin.Metadata.Disabled) { if (token.IsCancellationRequested) { return; } var results = PluginManager.QueryForPlugin(plugin, query); if (token.IsCancellationRequested) { return; } UpdateResultView(results, plugin.Metadata, query); } }); } catch (OperationCanceledException) { // nothing to do here } if (!token.IsCancellationRequested) { // update to hidden if this is still the current query ProgressBarVisibility = Visibility.Hidden; updateSource.Cancel(); updateSource.Dispose(); } }, token); } } else { Results.Clear(); Results.Visbility = Visibility.Collapsed; } }
private void QueryResults() { if (!string.IsNullOrEmpty(QueryText)) { var queryTimer = new System.Diagnostics.Stopwatch(); queryTimer.Start(); _updateSource?.Cancel(); var currentUpdateSource = new CancellationTokenSource(); _updateSource = currentUpdateSource; var currentCancellationToken = _updateSource.Token; _updateToken = currentCancellationToken; var queryText = QueryText.Trim(); var pluginQueryPairs = QueryBuilder.Build(ref queryText, PluginManager.NonGlobalPlugins); if (pluginQueryPairs != null && pluginQueryPairs.Count > 0) { _currentQuery = queryText; Task.Run( () => { Thread.Sleep(20); // Keep track of total number of results for telemetry var numResults = 0; // Contains all the plugins for which this raw query is valid var plugins = pluginQueryPairs.Keys.ToList(); try { currentCancellationToken.ThrowIfCancellationRequested(); var resultPluginPair = new List <(List <Result>, PluginMetadata)>(); // To execute a query corresponding to each plugin foreach (KeyValuePair <PluginPair, Query> pluginQueryItem in pluginQueryPairs) { var plugin = pluginQueryItem.Key; var query = pluginQueryItem.Value; if (!plugin.Metadata.Disabled) { var results = PluginManager.QueryForPlugin(plugin, query); resultPluginPair.Add((results, plugin.Metadata)); currentCancellationToken.ThrowIfCancellationRequested(); } } lock (_addResultsLock) { // Using CurrentCultureIgnoreCase since this is user facing if (queryText.Equals(_currentQuery, StringComparison.CurrentCultureIgnoreCase)) { Results.Clear(); foreach (var p in resultPluginPair) { UpdateResultView(p.Item1, queryText, currentCancellationToken); currentCancellationToken.ThrowIfCancellationRequested(); } currentCancellationToken.ThrowIfCancellationRequested(); numResults = Results.Results.Count; Results.Sort(); Results.SelectedItem = Results.Results.FirstOrDefault(); } } currentCancellationToken.ThrowIfCancellationRequested(); UpdateResultsListViewAfterQuery(queryText); // Run the slower query of the DelayedExecution plugins currentCancellationToken.ThrowIfCancellationRequested(); Parallel.ForEach(plugins, (plugin) => { try { if (!plugin.Metadata.Disabled) { Query query; pluginQueryPairs.TryGetValue(plugin, out query); var results = PluginManager.QueryForPlugin(plugin, query, true); currentCancellationToken.ThrowIfCancellationRequested(); if ((results?.Count ?? 0) != 0) { lock (_addResultsLock) { // Using CurrentCultureIgnoreCase since this is user facing if (queryText.Equals(_currentQuery, StringComparison.CurrentCultureIgnoreCase)) { currentCancellationToken.ThrowIfCancellationRequested(); // Remove the original results from the plugin Results.Results.RemoveAll(r => r.Result.PluginID == plugin.Metadata.ID); currentCancellationToken.ThrowIfCancellationRequested(); // Add the new results from the plugin UpdateResultView(results, queryText, currentCancellationToken); currentCancellationToken.ThrowIfCancellationRequested(); numResults = Results.Results.Count; Results.Sort(); Results.SelectedItem = Results.Results.FirstOrDefault(); } } currentCancellationToken.ThrowIfCancellationRequested(); UpdateResultsListViewAfterQuery(queryText, true); } } } catch (OperationCanceledException) { // nothing to do here } }); } catch (OperationCanceledException) { // nothing to do here } queryTimer.Stop(); var queryEvent = new LauncherQueryEvent() { QueryTimeMs = queryTimer.ElapsedMilliseconds, NumResults = numResults, QueryLength = queryText.Length, }; PowerToysTelemetry.Log.WriteEvent(queryEvent); }, currentCancellationToken); } } else { _updateSource?.Cancel(); _currentQuery = _emptyQuery; Results.SelectedItem = null; Results.Visibility = Visibility.Hidden; Task.Run(() => { lock (_addResultsLock) { Results.Clear(); } }); } }
private void QueryResults() { if (_updateSource != null && !_updateSource.IsCancellationRequested) { // first condition used for init run // second condition used when task has already been canceled in last turn _updateSource.Cancel(); _updateSource.Dispose(); Logger.WoxDebug($"cancel init {_updateSource.Token.GetHashCode()} {Thread.CurrentThread.ManagedThreadId} {QueryText}"); } var source = new CancellationTokenSource(); _updateSource = source; var token = source.Token; ProgressBarVisibility = Visibility.Hidden; var queryText = QueryText.Trim(); Task.Run(() => { if (!string.IsNullOrEmpty(queryText)) { if (token.IsCancellationRequested) { return; } var query = QueryBuilder.Build(queryText, PluginManager.NonGlobalPlugins); _lastQuery = query; if (query != null) { // handle the exclusiveness of plugin using action keyword if (token.IsCancellationRequested) { return; } RemoveOldQueryResults(query); Task.Delay(200, token).ContinueWith(_ => { Logger.WoxTrace($"progressbar visible 1 {token.GetHashCode()} {token.IsCancellationRequested} {Thread.CurrentThread.ManagedThreadId} {query} {ProgressBarVisibility}"); // start the progress bar if query takes more than 200 ms if (!token.IsCancellationRequested) { ProgressBarVisibility = Visibility.Visible; } }, token); if (token.IsCancellationRequested) { return; } var plugins = PluginManager.ValidPluginsForQuery(query); var option = new ParallelOptions() { CancellationToken = token, }; Parallel.ForEach(plugins, plugin => { if (!plugin.Metadata.Disabled) { if (token.IsCancellationRequested) { Logger.WoxDebug($"canceled {token.GetHashCode()} {Thread.CurrentThread.ManagedThreadId} {queryText} {plugin.Metadata.Name}"); return; } var results = PluginManager.QueryForPlugin(plugin, query); if (token.IsCancellationRequested) { Logger.WoxDebug($"canceled {token.GetHashCode()} {Thread.CurrentThread.ManagedThreadId} {queryText} {plugin.Metadata.Name}"); return; } UpdateResultView(results, plugin.Metadata, query, token); } }); Logger.WoxTrace($"progressbar visible 2 {token.GetHashCode()} {token.IsCancellationRequested} {Thread.CurrentThread.ManagedThreadId} {query} {ProgressBarVisibility}"); if (!token.IsCancellationRequested) { // used to cancel previous progress bar visible task source.Cancel(); source.Dispose(); // update to hidden if this is still the current query ProgressBarVisibility = Visibility.Hidden; } } } else { Results.Clear(); Results.Visbility = Visibility.Collapsed; } }, token); }