mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-04 02:06:36 +02:00
[PTRun]Settings for result order tuning (#18978)
* Change to allow new settings for results tuning. * Change to allow new settings for results tuning. * Added WeightBoost * Fixed null-ref crash in QueryResults * Change based on stefansjfw review. Remove PowerLauncher_PluginWeightBoost.Content * Fixed another of my dumb null-refs... * Updated some text * Moved global sort order and set enable/disabled as needed. * Fixed enabled-state of "Global sort order score modifier" setting.
This commit is contained in:
@@ -212,7 +212,7 @@ namespace PowerLauncher
|
||||
private void OnThemeChanged(Theme oldTheme, Theme newTheme)
|
||||
{
|
||||
ImageLoader.UpdateIconPath(newTheme);
|
||||
_mainVM.Query();
|
||||
_mainVM.Query(new MainViewModel.QueryTuningOptions());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -159,7 +159,6 @@ namespace PowerLauncher
|
||||
|
||||
SearchBox.QueryTextBox.DataContext = _viewModel;
|
||||
SearchBox.QueryTextBox.PreviewKeyDown += Launcher_KeyDown;
|
||||
|
||||
SetupSearchTextBoxReactiveness(_viewModel.GetSearchQueryResultsWithDelaySetting(), _viewModel.GetSearchInputDelaySetting());
|
||||
_viewModel.RegisterSettingsChangeListener(
|
||||
(s, prop_e) =>
|
||||
@@ -489,8 +488,15 @@ namespace PowerLauncher
|
||||
}
|
||||
else
|
||||
{
|
||||
var options = new MainViewModel.QueryTuningOptions
|
||||
{
|
||||
SearchClickedItemWeight = _viewModel.GetSearchClickedItemWeight(),
|
||||
SearchQueryTuningEnabled = _viewModel.GetSearchQueryTuningEnabled(),
|
||||
SearchWaitForSlowResults = _viewModel.GetSearchWaitForSlowResults(),
|
||||
};
|
||||
|
||||
_viewModel.QueryText = text;
|
||||
_viewModel.Query();
|
||||
_viewModel.Query(options);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -205,6 +205,14 @@ namespace PowerLauncher.Plugin
|
||||
metadata.QueryCount += 1;
|
||||
metadata.AvgQueryTime = metadata.QueryCount == 1 ? milliseconds : (metadata.AvgQueryTime + milliseconds) / 2;
|
||||
|
||||
if (results != null)
|
||||
{
|
||||
foreach (var result in results)
|
||||
{
|
||||
result.Metadata = pair.Metadata;
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
catch (Exception e)
|
||||
|
||||
@@ -115,6 +115,21 @@ namespace PowerLauncher
|
||||
_settings.SearchInputDelay = overloadSettings.Properties.SearchInputDelay;
|
||||
}
|
||||
|
||||
if (_settings.SearchClickedItemWeight != overloadSettings.Properties.SearchClickedItemWeight)
|
||||
{
|
||||
_settings.SearchClickedItemWeight = overloadSettings.Properties.SearchClickedItemWeight;
|
||||
}
|
||||
|
||||
if (_settings.SearchQueryTuningEnabled != overloadSettings.Properties.SearchQueryTuningEnabled)
|
||||
{
|
||||
_settings.SearchQueryTuningEnabled = overloadSettings.Properties.SearchQueryTuningEnabled;
|
||||
}
|
||||
|
||||
if (_settings.SearchWaitForSlowResults != overloadSettings.Properties.SearchWaitForSlowResults)
|
||||
{
|
||||
_settings.SearchWaitForSlowResults = overloadSettings.Properties.SearchWaitForSlowResults;
|
||||
}
|
||||
|
||||
if (_settings.MaxResultsToShow != overloadSettings.Properties.MaximumNumberOfResults)
|
||||
{
|
||||
_settings.MaxResultsToShow = overloadSettings.Properties.MaximumNumberOfResults;
|
||||
|
||||
@@ -11,8 +11,15 @@ namespace PowerLauncher.Storage
|
||||
{
|
||||
public class UserSelectedRecord
|
||||
{
|
||||
public class UserSelectedRecordItem
|
||||
{
|
||||
public int SelectedCount { get; set; }
|
||||
|
||||
public DateTime LastSelected { get; set; }
|
||||
}
|
||||
|
||||
[JsonInclude]
|
||||
public Dictionary<string, int> Records { get; private set; } = new Dictionary<string, int>();
|
||||
public Dictionary<string, UserSelectedRecordItem> Records { get; private set; } = new Dictionary<string, UserSelectedRecordItem>();
|
||||
|
||||
public void Add(Result result)
|
||||
{
|
||||
@@ -22,29 +29,30 @@ namespace PowerLauncher.Storage
|
||||
}
|
||||
|
||||
var key = result.ToString();
|
||||
if (Records.TryGetValue(key, out int value))
|
||||
if (Records.TryGetValue(key, out var value))
|
||||
{
|
||||
Records[key] = value + 1;
|
||||
Records[key].SelectedCount = Records[key].SelectedCount + 1;
|
||||
Records[key].LastSelected = DateTime.UtcNow;
|
||||
}
|
||||
else
|
||||
{
|
||||
Records.Add(key, 1);
|
||||
Records.Add(key, new UserSelectedRecordItem { SelectedCount = 1, LastSelected = DateTime.UtcNow });
|
||||
}
|
||||
}
|
||||
|
||||
public int GetSelectedCount(Result result)
|
||||
public UserSelectedRecordItem GetSelectedData(Result result)
|
||||
{
|
||||
if (result == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(result));
|
||||
}
|
||||
|
||||
if (result != null && Records.TryGetValue(result.ToString(), out int value))
|
||||
if (result != null && Records.TryGetValue(result.ToString(), out var value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return new UserSelectedRecordItem { SelectedCount = 0, LastSelected = DateTime.MinValue };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -362,14 +362,14 @@ namespace PowerLauncher.ViewModel
|
||||
/// </summary>
|
||||
/// <param name="queryText">Text that is being queried from user</param>
|
||||
/// <param name="requery">Optional Parameter that if true, will automatically execute a query against the updated text</param>
|
||||
public void ChangeQueryText(string queryText, bool requery = false)
|
||||
public void ChangeQueryText(string queryText, bool requery = false, QueryTuningOptions tuningOptions = null)
|
||||
{
|
||||
SystemQueryText = queryText;
|
||||
|
||||
if (requery)
|
||||
{
|
||||
QueryText = queryText;
|
||||
Query();
|
||||
Query(tuningOptions);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -463,11 +463,20 @@ namespace PowerLauncher.ViewModel
|
||||
|
||||
public ICommand ClearQueryCommand { get; private set; }
|
||||
|
||||
public void Query()
|
||||
public class QueryTuningOptions
|
||||
{
|
||||
public int SearchClickedItemWeight { get; set; }
|
||||
|
||||
public bool SearchQueryTuningEnabled { get; set; }
|
||||
|
||||
public bool SearchWaitForSlowResults { get; set; }
|
||||
}
|
||||
|
||||
public void Query(QueryTuningOptions options)
|
||||
{
|
||||
if (SelectedIsFromQueryResults())
|
||||
{
|
||||
QueryResults();
|
||||
QueryResults(options);
|
||||
}
|
||||
else if (HistorySelected())
|
||||
{
|
||||
@@ -518,8 +527,10 @@ namespace PowerLauncher.ViewModel
|
||||
}
|
||||
}
|
||||
|
||||
private void QueryResults()
|
||||
private void QueryResults(QueryTuningOptions queryTuning)
|
||||
{
|
||||
var doFinalSort = queryTuning.SearchQueryTuningEnabled && queryTuning.SearchWaitForSlowResults;
|
||||
|
||||
if (!string.IsNullOrEmpty(QueryText))
|
||||
{
|
||||
var queryTimer = new System.Diagnostics.Stopwatch();
|
||||
@@ -536,7 +547,8 @@ namespace PowerLauncher.ViewModel
|
||||
{
|
||||
queryText = pluginQueryPairs.Values.First().RawQuery;
|
||||
_currentQuery = queryText;
|
||||
Task.Run(
|
||||
|
||||
var queryResultsTask = Task.Factory.StartNew(
|
||||
() =>
|
||||
{
|
||||
Thread.Sleep(20);
|
||||
@@ -577,12 +589,18 @@ namespace PowerLauncher.ViewModel
|
||||
|
||||
currentCancellationToken.ThrowIfCancellationRequested();
|
||||
numResults = Results.Results.Count;
|
||||
Results.Sort();
|
||||
Results.SelectedItem = Results.Results.FirstOrDefault();
|
||||
if (!doFinalSort)
|
||||
{
|
||||
Results.Sort(queryTuning);
|
||||
Results.SelectedItem = Results.Results.FirstOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
currentCancellationToken.ThrowIfCancellationRequested();
|
||||
UpdateResultsListViewAfterQuery(queryText);
|
||||
if (!doFinalSort)
|
||||
{
|
||||
UpdateResultsListViewAfterQuery(queryText);
|
||||
}
|
||||
}
|
||||
|
||||
bool noInitialResults = numResults == 0;
|
||||
@@ -616,11 +634,17 @@ namespace PowerLauncher.ViewModel
|
||||
|
||||
currentCancellationToken.ThrowIfCancellationRequested();
|
||||
numResults = Results.Results.Count;
|
||||
Results.Sort();
|
||||
if (!doFinalSort)
|
||||
{
|
||||
Results.Sort(queryTuning);
|
||||
}
|
||||
}
|
||||
|
||||
currentCancellationToken.ThrowIfCancellationRequested();
|
||||
UpdateResultsListViewAfterQuery(queryText, noInitialResults, true);
|
||||
if (!doFinalSort)
|
||||
{
|
||||
UpdateResultsListViewAfterQuery(queryText, noInitialResults, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -644,6 +668,19 @@ namespace PowerLauncher.ViewModel
|
||||
};
|
||||
PowerToysTelemetry.Log.WriteEvent(queryEvent);
|
||||
}, currentCancellationToken);
|
||||
|
||||
if (doFinalSort)
|
||||
{
|
||||
Task.Factory.ContinueWhenAll(
|
||||
new Task[] { queryResultsTask },
|
||||
completedTasks =>
|
||||
{
|
||||
Results.Sort(queryTuning);
|
||||
Results.SelectedItem = Results.Results.FirstOrDefault();
|
||||
UpdateResultsListViewAfterQuery(queryText, false, false);
|
||||
},
|
||||
currentCancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -944,7 +981,9 @@ namespace PowerLauncher.ViewModel
|
||||
|
||||
foreach (var result in list)
|
||||
{
|
||||
result.Score += _userSelectedRecord.GetSelectedCount(result) * 5;
|
||||
var selectedData = _userSelectedRecord.GetSelectedData(result);
|
||||
result.SelectedCount = selectedData.SelectedCount;
|
||||
result.LastSelected = selectedData.LastSelected;
|
||||
}
|
||||
|
||||
// Using CurrentCultureIgnoreCase since this is user facing
|
||||
@@ -1117,5 +1156,20 @@ namespace PowerLauncher.ViewModel
|
||||
{
|
||||
return _settings.SearchInputDelay;
|
||||
}
|
||||
|
||||
public int GetSearchClickedItemWeight()
|
||||
{
|
||||
return _settings.SearchClickedItemWeight;
|
||||
}
|
||||
|
||||
public bool GetSearchQueryTuningEnabled()
|
||||
{
|
||||
return _settings.SearchQueryTuningEnabled;
|
||||
}
|
||||
|
||||
public bool GetSearchWaitForSlowResults()
|
||||
{
|
||||
return _settings.SearchWaitForSlowResults;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -253,9 +253,19 @@ namespace PowerLauncher.ViewModel
|
||||
Results.AddRange(newResults);
|
||||
}
|
||||
|
||||
public void Sort()
|
||||
public void Sort(MainViewModel.QueryTuningOptions options)
|
||||
{
|
||||
var sorted = Results.OrderByDescending(x => x.Result.Score).ToList();
|
||||
List<ResultViewModel> sorted = null;
|
||||
|
||||
if (options.SearchQueryTuningEnabled)
|
||||
{
|
||||
sorted = Results.OrderByDescending(x => (x.Result.Metadata.WeightBoost + x.Result.Score + (x.Result.SelectedCount * options.SearchClickedItemWeight))).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
sorted = Results.OrderByDescending(x => (x.Result.Metadata.WeightBoost + x.Result.Score + (x.Result.SelectedCount * 5))).ToList();
|
||||
}
|
||||
|
||||
Clear();
|
||||
Results.AddRange(sorted);
|
||||
}
|
||||
|
||||
@@ -82,6 +82,12 @@ namespace Wox.Infrastructure.UserSettings
|
||||
|
||||
private int _searchInputDelay = 150;
|
||||
|
||||
private int _searchClickedItemWeight = 5;
|
||||
|
||||
private bool _searchQueryTuningEnabled;
|
||||
|
||||
private bool _searchWaitForSlowResults;
|
||||
|
||||
public int SearchInputDelay
|
||||
{
|
||||
get
|
||||
@@ -99,6 +105,57 @@ namespace Wox.Infrastructure.UserSettings
|
||||
}
|
||||
}
|
||||
|
||||
public bool SearchQueryTuningEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return _searchQueryTuningEnabled;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (_searchQueryTuningEnabled != value)
|
||||
{
|
||||
_searchQueryTuningEnabled = value;
|
||||
OnPropertyChanged(nameof(SearchQueryTuningEnabled));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool SearchWaitForSlowResults
|
||||
{
|
||||
get
|
||||
{
|
||||
return _searchWaitForSlowResults;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (_searchWaitForSlowResults != value)
|
||||
{
|
||||
_searchWaitForSlowResults = value;
|
||||
OnPropertyChanged(nameof(_searchWaitForSlowResults));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int SearchClickedItemWeight
|
||||
{
|
||||
get
|
||||
{
|
||||
return _searchClickedItemWeight;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (_searchClickedItemWeight != value)
|
||||
{
|
||||
_searchClickedItemWeight = value;
|
||||
OnPropertyChanged(nameof(SearchClickedItemWeight));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string Language { get; set; } = "en";
|
||||
|
||||
public Theme Theme { get; set; } = Theme.System;
|
||||
|
||||
@@ -56,6 +56,8 @@ namespace Wox.Plugin
|
||||
|
||||
public string ActionKeyword { get; set; }
|
||||
|
||||
public int WeightBoost { get; set; }
|
||||
|
||||
public bool IsGlobal { get; set; }
|
||||
|
||||
public string IcoPathDark { get; set; }
|
||||
|
||||
@@ -79,6 +79,8 @@ namespace Wox.Plugin
|
||||
}
|
||||
|
||||
Metadata.ActionKeyword = setting.ActionKeyword;
|
||||
Metadata.WeightBoost = setting.WeightBoost;
|
||||
|
||||
Metadata.IsGlobal = setting.IsGlobal;
|
||||
|
||||
(Plugin as ISettingProvider)?.UpdateSettings(setting);
|
||||
|
||||
@@ -103,6 +103,8 @@ namespace Wox.Plugin
|
||||
/// </summary>
|
||||
public const string GlobalPluginWildcardSign = "*";
|
||||
|
||||
public int WeightBoost { get; set; }
|
||||
|
||||
public string ActionKeyword { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -21,6 +21,8 @@ namespace Wox.Plugin
|
||||
private string _pluginDirectory;
|
||||
private string _icoPath;
|
||||
|
||||
public PluginMetadata Metadata { get; set; }
|
||||
|
||||
public string Title
|
||||
{
|
||||
get
|
||||
@@ -100,6 +102,10 @@ namespace Wox.Plugin
|
||||
|
||||
public int Score { get; set; }
|
||||
|
||||
public int SelectedCount { get; set; }
|
||||
|
||||
public DateTime LastSelected { get; set; } = DateTime.MinValue;
|
||||
|
||||
public Result(IList<int> titleHighlightData = null, IList<int> subTitleHighlightData = null)
|
||||
{
|
||||
TitleHighlightData = titleHighlightData;
|
||||
|
||||
Reference in New Issue
Block a user