Support plugin search delay

This commit is contained in:
Jack251970 2025-03-30 22:40:46 +08:00
parent 0dba9bcc08
commit 659356a650
12 changed files with 89 additions and 115 deletions

View file

@ -51,7 +51,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
settings.Version = metadata.Version;
}
settings.DefaultActionKeywords = metadata.ActionKeywords; // metadata provides default values
settings.DefaultSearchDelay = metadata.SearchDelay; // metadata provides default values
settings.DefaultSearchDelaySpeed = metadata.SearchDelaySpeed; // metadata provides default values
// update metadata values with settings
if (settings.ActionKeywords?.Count > 0)
@ -66,7 +66,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
}
metadata.Disabled = settings.Disabled;
metadata.Priority = settings.Priority;
metadata.SearchDelay = settings.SearchDelay;
metadata.SearchDelaySpeed = settings.SearchDelaySpeed;
}
else
{
@ -80,8 +80,8 @@ namespace Flow.Launcher.Infrastructure.UserSettings
ActionKeywords = metadata.ActionKeywords, // use default value
Disabled = metadata.Disabled,
Priority = metadata.Priority,
DefaultSearchDelay = metadata.SearchDelay, // metadata provides default values
SearchDelay = metadata.SearchDelay, // use default value
DefaultSearchDelaySpeed = metadata.SearchDelaySpeed, // metadata provides default values
SearchDelaySpeed = metadata.SearchDelaySpeed, // use default value
};
}
}
@ -120,9 +120,10 @@ namespace Flow.Launcher.Infrastructure.UserSettings
public int Priority { get; set; }
[JsonIgnore]
public int DefaultSearchDelay { get; set; }
public SearchDelaySpeeds? DefaultSearchDelaySpeed { get; set; }
public int SearchDelay { get; set; }
[JsonConverter(typeof(JsonStringEnumConverter))]
public SearchDelaySpeeds? SearchDelaySpeed { get; set; }
/// <summary>
/// Used only to save the state of the plugin in settings

View file

@ -330,8 +330,9 @@ namespace Flow.Launcher.Infrastructure.UserSettings
OnPropertyChanged();
}
}
SearchDelaySpeeds searchDelaySpeed { get; set; } = SearchDelaySpeeds.Medium;
[JsonConverter(typeof(JsonStringEnumConverter))]
public SearchDelaySpeeds SearchDelaySpeed
{
get => searchDelaySpeed;
@ -342,23 +343,6 @@ namespace Flow.Launcher.Infrastructure.UserSettings
}
}
[JsonIgnore]
public int SearchDelay => SearchDelaySpeed switch
{
SearchDelaySpeeds.Slow => 250,
SearchDelaySpeeds.ModeratelySlow => 200,
SearchDelaySpeeds.Medium => 150,
SearchDelaySpeeds.ModeratelyFast => 100,
SearchDelaySpeeds.Fast => 50,
_ => 150
};
[JsonIgnore]
public List<int> PluginSearchDelayRange { get; } = new()
{
0, 30, 60, 90, 120, 150
};
[JsonConverter(typeof(JsonStringEnumConverter))]
public SearchWindowScreens SearchWindowScreen { get; set; } = SearchWindowScreens.Cursor;
@ -521,13 +505,4 @@ namespace Flow.Launcher.Infrastructure.UserSettings
Mica,
MicaAlt
}
public enum SearchDelaySpeeds
{
Slow,
ModeratelySlow,
Medium,
ModeratelyFast,
Fast
}
}

View file

@ -99,9 +99,10 @@ namespace Flow.Launcher.Plugin
public bool HideActionKeywordPanel { get; set; }
/// <summary>
/// Plugin search delay in ms.
/// Plugin search delay speed. Null means use default search delay.
/// </summary>
public int SearchDelay { get; set; }
[JsonConverter(typeof(JsonStringEnumConverter))]
public SearchDelaySpeeds? SearchDelaySpeed { get; set; } = null;
/// <summary>
/// Plugin icon path.

View file

@ -0,0 +1,32 @@
namespace Flow.Launcher.Plugin;
/// <summary>
/// Enum for search delay speeds
/// </summary>
public enum SearchDelaySpeeds
{
/// <summary>
/// Slow search delay speed. 50ms.
/// </summary>
Slow,
/// <summary>
/// Moderately slow search delay speed. 100ms.
/// </summary>
ModeratelySlow,
/// <summary>
/// Medium search delay speed. 150ms. Default value.
/// </summary>
Medium,
/// <summary>
/// Moderately fast search delay speed. 200ms.
/// </summary>
ModeratelyFast,
/// <summary>
/// Fast search delay speed. 250ms.
/// </summary>
Fast
}

View file

@ -100,7 +100,6 @@
<PackageReference Include="NHotkey.Wpf" Version="3.0.0" />
<PackageReference Include="PropertyChanged.Fody" Version="3.4.0" />
<PackageReference Include="SemanticVersioning" Version="3.0.0" />
<PackageReference Include="System.Reactive.Linq" Version="6.0.1" />
<PackageReference Include="TaskScheduler" Version="2.12.1" />
<PackageReference Include="VirtualizingWrapPanel" Version="2.1.1" />
</ItemGroup>

View file

@ -104,8 +104,8 @@
<system:String x:Key="shadowEffectNotAllowed">Shadow effect is not allowed while current theme has blur effect enabled</system:String>
<system:String x:Key="searchDelay">Search Delay</system:String>
<system:String x:Key="searchDelayToolTip">Delay for a while to search when typing. This reduces interface jumpiness and result load.</system:String>
<system:String x:Key="searchDelayTime">Search Delay Speed</system:String>
<system:String x:Key="searchDelayTimeToolTip">Delay time speed after which search results appear when typing is stopped. Default is medium.</system:String>
<system:String x:Key="searchDelaySpeed">Default Search Delay Speed</system:String>
<system:String x:Key="searchDelaySpeedToolTip">Plugins default delay time after which search results appear when typing is stopped. Default is medium.</system:String>
<system:String x:Key="SearchDelaySpeedSlow">Slow</system:String>
<system:String x:Key="SearchDelaySpeedModeratelySlow">Moderately slow</system:String>
<system:String x:Key="SearchDelaySpeedMedium">Medium</system:String>
@ -127,7 +127,8 @@
<system:String x:Key="currentActionKeywords">Current action keyword</system:String>
<system:String x:Key="newActionKeyword">New action keyword</system:String>
<system:String x:Key="actionKeywordsTooltip">Change Action Keywords</system:String>
<system:String x:Key="pluginSearchDelayTooltip">Change Seach Delay Time</system:String>
<system:String x:Key="pluginSearchDelaySpeed">Plugin seach delay speed</system:String>
<system:String x:Key="pluginSearchDelaySpeedTooltip">Change Plugin Seach Delay Speed</system:String>
<system:String x:Key="currentPriority">Current Priority</system:String>
<system:String x:Key="newPriority">New Priority</system:String>
<system:String x:Key="priority">Priority</system:String>
@ -143,6 +144,7 @@
<system:String x:Key="failedToRemovePluginSettingsMessage">Plugins: {0} - Fail to remove plugin settings files, please remove them manually</system:String>
<system:String x:Key="failedToRemovePluginCacheTitle">Fail to remove plugin cache</system:String>
<system:String x:Key="failedToRemovePluginCacheMessage">Plugins: {0} - Fail to remove plugin cache files, please remove them manually</system:String>
<system:String x:Key="default">Default</system:String>
<!-- Setting Plugin Store -->
<system:String x:Key="pluginStore">Plugin Store</system:String>

View file

@ -252,6 +252,7 @@
PreviewKeyUp="QueryTextBox_KeyUp"
Style="{DynamicResource QueryBoxStyle}"
Text="{Binding QueryText, Mode=OneWay}"
TextChanged="QueryTextBox_TextChanged1"
Visibility="Visible"
WindowChrome.IsHitTestVisibleInChrome="True">
<TextBox.CommandBindings>

View file

@ -2,7 +2,6 @@
using System.ComponentModel;
using System.Linq;
using System.Media;
using System.Reactive.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
@ -64,9 +63,6 @@ namespace Flow.Launcher
private const double DefaultRightMargin = 66; //* this value from base.xaml
private bool _isClockPanelAnimating = false;
// Search Delay
private IDisposable _reactiveSubscription;
// IDisposable
private bool _disposed = false;
@ -122,9 +118,6 @@ namespace Flow.Launcher
welcomeWindow.Show();
}
// Initialize search delay
SetupSearchTextBoxReactiveness(_settings.SearchQueryResultsWithDelay, _settings.SearchDelay);
// Initialize place holder
SetupPlaceholderText();
_viewModel.PlaceholderText = _settings.PlaceholderText;
@ -267,15 +260,6 @@ namespace Flow.Launcher
case nameof(Settings.KeepMaxResults):
SetupResizeMode();
break;
case nameof(Settings.SearchQueryResultsWithDelay):
SetupSearchTextBoxReactiveness(_settings.SearchQueryResultsWithDelay, _settings.SearchDelay);
break;
case nameof(Settings.SearchDelaySpeed):
if (_settings.SearchQueryResultsWithDelay)
{
SetupSearchTextBoxReactiveness(_settings.SearchQueryResultsWithDelay, _settings.SearchDelay);
}
break;
}
};
@ -1126,46 +1110,11 @@ namespace Flow.Launcher
#region Search Delay
// Edited from: https://github.com/microsoft/PowerToys
private void SetupSearchTextBoxReactiveness(bool showResultsWithDelay, int searchDelay)
{
if (_reactiveSubscription != null)
{
_reactiveSubscription.Dispose();
_reactiveSubscription = null;
}
QueryTextBox.TextChanged -= QueryTextBox_TextChanged1;
if (showResultsWithDelay)
{
_reactiveSubscription = Observable.FromEventPattern<TextChangedEventHandler, TextChangedEventArgs>(
conversion => (sender, eventArg) => conversion(sender, eventArg),
add => QueryTextBox.TextChanged += add,
remove => QueryTextBox.TextChanged -= remove)
// TODO: Remove debug codes.
.Throttle(TimeSpan.FromMilliseconds(_settings.SearchDelay * 10))
.Do(@event => Dispatcher.Invoke(() => PerformSearchQuery(true, (TextBox)@event.Sender)))
.Subscribe();
}
else
{
QueryTextBox.TextChanged += QueryTextBox_TextChanged1;
}
}
private void QueryTextBox_TextChanged1(object sender, TextChangedEventArgs e)
{
var textBox = (TextBox)sender;
PerformSearchQuery(false, textBox);
}
private void PerformSearchQuery(bool searchDelay, TextBox textBox)
{
var text = textBox.Text;
_viewModel.QueryText = text;
_viewModel.Query(searchDelay);
_viewModel.QueryText = textBox.Text;
_viewModel.Query(_settings.SearchQueryResultsWithDelay);
}
#endregion
@ -1180,7 +1129,6 @@ namespace Flow.Launcher
{
_hwndSource?.Dispose();
_notifyIcon?.Dispose();
_reactiveSubscription?.Dispose();
}
_disposed = true;

View file

@ -32,18 +32,18 @@
VerticalAlignment="Center"
DockPanel.Dock="Left"
Style="{DynamicResource SettingTitleLabel}"
Text="{DynamicResource searchDelayTime}" />
Text="{DynamicResource pluginSearchDelaySpeed}" />
<!-- Here Margin="0 -4.5 0 -4.5" is to remove redundant top bottom margin from Margin="{StaticResource SettingPanelMargin}" -->
<ComboBox
<Button
Width="100"
Margin="0 -4.5 0 -4.5"
HorizontalAlignment="Right"
Command="{Binding SetSearchDelaySpeedCommand}"
Content="{Binding SearchDelaySpeedText}"
Cursor="Hand"
DockPanel.Dock="Right"
FontWeight="Bold"
ItemsSource="{Binding PluginSearchDelayRange}"
SelectedItem="{Binding PluginSearchDelay}"
ToolTip="{DynamicResource pluginSearchDelayTooltip}" />
ToolTip="{DynamicResource pluginSearchDelaySpeedTooltip}" />
</DockPanel>
</Border>
</UserControl>

View file

@ -184,9 +184,9 @@
</cc:Card>
<cc:Card
Title="{DynamicResource searchDelayTime}"
Title="{DynamicResource searchDelaySpeed}"
Icon="&#xE916;"
Sub="{DynamicResource searchDelayTimeToolTip}">
Sub="{DynamicResource searchDelaySpeedToolTip}">
<ComboBox
MaxWidth="200"
DisplayMemberPath="Display"

View file

@ -1271,13 +1271,24 @@ namespace Flow.Launcher.ViewModel
{
if (searchDelay)
{
// TODO: Remove debug codes.
System.Diagnostics.Debug.WriteLine($"!!!{plugin.Metadata.Name} Waiting {plugin.Metadata.SearchDelay} ms");
await Task.Delay(plugin.Metadata.SearchDelay, token);
var searchDelaySpeed = plugin.Metadata.SearchDelaySpeed ?? Settings.SearchDelaySpeed;
var searchDelayTime = searchDelaySpeed switch
{
SearchDelaySpeeds.Slow => 250,
SearchDelaySpeeds.ModeratelySlow => 200,
SearchDelaySpeeds.Medium => 150,
SearchDelaySpeeds.ModeratelyFast => 100,
SearchDelaySpeeds.Fast => 50,
_ => 150
};
// TODO: Remove debug codes.
System.Diagnostics.Debug.WriteLine($"!!!{plugin.Metadata.Name} Waited {plugin.Metadata.SearchDelay} ms");
System.Diagnostics.Debug.WriteLine($"!!!{plugin.Metadata.Name} Waiting {searchDelayTime} ms");
await Task.Delay(searchDelayTime, token);
// TODO: Remove debug codes.
System.Diagnostics.Debug.WriteLine($"!!!{plugin.Metadata.Name} Waited {searchDelayTime} ms");
if (token.IsCancellationRequested)
return;

View file

@ -1,14 +1,11 @@
using System.Linq;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Infrastructure.Image;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.Resources.Controls;
@ -63,6 +60,7 @@ namespace Flow.Launcher.ViewModel
}
set => _image = value;
}
public bool PluginState
{
get => !PluginPair.Metadata.Disabled;
@ -72,6 +70,7 @@ namespace Flow.Launcher.ViewModel
PluginSettingsObject.Disabled = !value;
}
}
public bool IsExpanded
{
get => _isExpanded;
@ -84,16 +83,13 @@ namespace Flow.Launcher.ViewModel
}
}
public IEnumerable<int> PluginSearchDelayRange { get; } =
Ioc.Default.GetRequiredService<Settings>().PluginSearchDelayRange;
public int PluginSearchDelay
public SearchDelaySpeeds? PluginSearchDelay
{
get => PluginPair.Metadata.SearchDelay;
get => PluginPair.Metadata.SearchDelaySpeed;
set
{
PluginPair.Metadata.SearchDelay = value;
PluginSettingsObject.SearchDelay = value;
PluginPair.Metadata.SearchDelaySpeed = value;
PluginSettingsObject.SearchDelaySpeed = value;
}
}
@ -131,6 +127,7 @@ namespace Flow.Launcher.ViewModel
PluginPair.Metadata.AvgQueryTime + "ms";
public string ActionKeywordsText => string.Join(Query.ActionKeywordSeparator, PluginPair.Metadata.ActionKeywords);
public int Priority => PluginPair.Metadata.Priority;
public string SearchDelaySpeedText => PluginPair.Metadata.SearchDelaySpeed == null ? App.API.GetTranslation("default") : App.API.GetTranslation($"SearchDelaySpeed{PluginPair.Metadata.SearchDelaySpeed}");
public Infrastructure.UserSettings.Plugin PluginSettingsObject{ get; init; }
public void OnActionKeywordsChanged()
@ -179,5 +176,12 @@ namespace Flow.Launcher.ViewModel
ActionKeywords changeKeywordsWindow = new ActionKeywords(this);
changeKeywordsWindow.ShowDialog();
}
[RelayCommand]
private void SetSearchDelaySpeed()
{
/*SearchDelaySpeedWindow searchDelaySpeedWindow = new SearchDelaySpeedWindow(this);
searchDelaySpeedWindow.ShowDialog();*/
}
}
}