Skip to content

Input Smooth & Search delay #3350

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 57 commits into from
Mar 31, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
b1a4681
Support search delay
Jack251970 Mar 15, 2025
3abcebd
Add settings ui
Jack251970 Mar 15, 2025
a41356c
Improve strings
Jack251970 Mar 15, 2025
dc3f663
Use property changed to change
Jack251970 Mar 16, 2025
e98b144
Improve code quality
Jack251970 Mar 16, 2025
35617e9
Merge branch 'dev' into search_delay
Jack251970 Mar 17, 2025
c114f2d
Fix build issue
Jack251970 Mar 17, 2025
8cdb872
Remove auto complete text clear because FL uses binding
Jack251970 Mar 18, 2025
e98964a
Change to one way binding mode
Jack251970 Mar 18, 2025
fc4b5c9
Fix
Jack251970 Mar 18, 2025
5dd9e8d
Add plugin search delay settings panel
Jack251970 Mar 18, 2025
2c949d6
Fix setting control
Jack251970 Mar 18, 2025
933582b
Change name to search delay & Support plugin search delay
Jack251970 Mar 18, 2025
2738636
Improve debug codes
Jack251970 Mar 18, 2025
1e01186
Merge branch 'dev' into search_delay
Jack251970 Mar 20, 2025
dc92f6a
Fix build issue
Jack251970 Mar 20, 2025
102636f
Improve code quality
Jack251970 Mar 20, 2025
8c387d0
Improve code quality & Add oneway bind mode
Jack251970 Mar 20, 2025
d785991
Improve search performance
Jack251970 Mar 21, 2025
2f4e140
Improve query async local function
Jack251970 Mar 21, 2025
2619851
Improve indention
Jack251970 Mar 21, 2025
bebe86d
Improve query async local function
Jack251970 Mar 21, 2025
529a219
Change serach delay method
Jack251970 Mar 21, 2025
5a88a1f
Merge branch 'dev' into search_delay
Jack251970 Mar 26, 2025
23470b6
Code quality
Jack251970 Mar 26, 2025
84bd5f5
Fix build issue
Jack251970 Mar 26, 2025
9cf34b2
Merge branch 'dev' into search_delay
Jack251970 Mar 26, 2025
7f5480d
Merge branch 'dev' into search_delay
Jack251970 Mar 30, 2025
1f6ab1c
Fix build issue
Jack251970 Mar 30, 2025
aec11ce
Code quality
Jack251970 Mar 30, 2025
cc7dc4a
Introduce unified settings panel design for search delay panel
Jack251970 Mar 30, 2025
72b0fbf
Add code comments
Jack251970 Mar 30, 2025
1ddfabc
Update code comments
Jack251970 Mar 30, 2025
63378e1
Code quality
Jack251970 Mar 30, 2025
1ede69c
Make Plugin dictionary private
Jack251970 Mar 30, 2025
d041fe8
Support default value
Jack251970 Mar 30, 2025
9ac6d58
Add default search delay for WebSearch plugins
Jack251970 Mar 30, 2025
2ea7ab2
Add todo
Jack251970 Mar 30, 2025
756ac0b
Remove debug codes
Jack251970 Mar 30, 2025
6604247
Fix typos & Improve code quality
Jack251970 Mar 30, 2025
2273d0c
Add debug codes
Jack251970 Mar 30, 2025
750cba2
Fix search delay runtime change issue
Jack251970 Mar 30, 2025
0dba9bc
Add search delay speed
Jack251970 Mar 30, 2025
659356a
Support plugin search delay
Jack251970 Mar 30, 2025
8a2ec4d
Update Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewM…
Jack251970 Mar 31, 2025
dd9514b
Support websearch plugin default search delay
Jack251970 Mar 31, 2025
12a3bbe
Code quality
Jack251970 Mar 31, 2025
a333041
Fix build issue
Jack251970 Mar 31, 2025
c925a79
Support changing plugin search delay
Jack251970 Mar 31, 2025
e9c1cff
Code quality
Jack251970 Mar 31, 2025
dec1e77
Improve code comments
Jack251970 Mar 31, 2025
c4cd51c
Change to search delay time
Jack251970 Mar 31, 2025
72a59ba
Change file names
Jack251970 Mar 31, 2025
5243d74
Improve code comments
Jack251970 Mar 31, 2025
b860bb2
Code quality
Jack251970 Mar 31, 2025
d42279b
Fix typo & Fix tip issue
Jack251970 Mar 31, 2025
39f41e4
Improve string resources
Jack251970 Mar 31, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Flow.Launcher.Core/Plugin/PluginManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,7 @@ internal static async Task UninstallPluginAsync(PluginMetadata plugin, bool remo
API.ShowMsg(API.GetTranslation("failedToRemovePluginCacheTitle"),
string.Format(API.GetTranslation("failedToRemovePluginCacheMessage"), plugin.Name));
}
Settings.Plugins.Remove(plugin.ID);
Settings.RemovePluginSettings(plugin.ID);
AllPlugins.RemoveAll(p => p.Metadata.ID == plugin.ID);
}

Expand Down
6 changes: 3 additions & 3 deletions Flow.Launcher.Core/Plugin/PluginsLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public static List<PluginPair> Plugins(List<PluginMetadata> metadatas, PluginsSe
return plugins;
}

public static IEnumerable<PluginPair> DotNetPlugins(List<PluginMetadata> source)
private static IEnumerable<PluginPair> DotNetPlugins(List<PluginMetadata> source)
{
var erroredPlugins = new List<string>();

Expand Down Expand Up @@ -132,7 +132,7 @@ public static IEnumerable<PluginPair> DotNetPlugins(List<PluginMetadata> source)
return plugins;
}

public static IEnumerable<PluginPair> ExecutablePlugins(IEnumerable<PluginMetadata> source)
private static IEnumerable<PluginPair> ExecutablePlugins(IEnumerable<PluginMetadata> source)
{
return source
.Where(o => o.Language.Equals(AllowedLanguage.Executable, StringComparison.OrdinalIgnoreCase))
Expand All @@ -146,7 +146,7 @@ public static IEnumerable<PluginPair> ExecutablePlugins(IEnumerable<PluginMetada
});
}

public static IEnumerable<PluginPair> ExecutableV2Plugins(IEnumerable<PluginMetadata> source)
private static IEnumerable<PluginPair> ExecutableV2Plugins(IEnumerable<PluginMetadata> source)
{
return source
.Where(o => o.Language.Equals(AllowedLanguage.ExecutableV2, StringComparison.OrdinalIgnoreCase))
Expand Down
66 changes: 59 additions & 7 deletions Flow.Launcher.Infrastructure/UserSettings/PluginSettings.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;
using Flow.Launcher.Plugin;

namespace Flow.Launcher.Infrastructure.UserSettings
{
public class PluginsSettings : BaseModel
{
private string pythonExecutablePath = string.Empty;
public string PythonExecutablePath {
get { return pythonExecutablePath; }
public string PythonExecutablePath
{
get => pythonExecutablePath;
set
{
pythonExecutablePath = value;
Expand All @@ -18,25 +20,40 @@ public string PythonExecutablePath {
private string nodeExecutablePath = string.Empty;
public string NodeExecutablePath
{
get { return nodeExecutablePath; }
get => nodeExecutablePath;
set
{
nodeExecutablePath = value;
Constant.NodePath = value;
}
}

public Dictionary<string, Plugin> Plugins { get; set; } = new Dictionary<string, Plugin>();
/// <summary>
/// Only used for serialization
/// </summary>
public Dictionary<string, Plugin> Plugins { get; set; } = new();

/// <summary>
/// Update plugin settings with metadata.
/// FL will get default values from metadata first and then load settings to metadata
/// </summary>
/// <param name="metadatas">Parsed plugin metadatas</param>
public void UpdatePluginSettings(List<PluginMetadata> metadatas)
{
foreach (var metadata in metadatas)
{
if (Plugins.TryGetValue(metadata.ID, out var settings))
{
// If settings exist, update settings & metadata value
// update settings values with metadata
if (string.IsNullOrEmpty(settings.Version))
{
settings.Version = metadata.Version;
}
settings.DefaultActionKeywords = metadata.ActionKeywords; // metadata provides default values
settings.DefaultSearchDelayTime = metadata.SearchDelayTime; // metadata provides default values

// update metadata values with settings
if (settings.ActionKeywords?.Count > 0)
{
metadata.ActionKeywords = settings.ActionKeywords;
Expand All @@ -49,30 +66,65 @@ public void UpdatePluginSettings(List<PluginMetadata> metadatas)
}
metadata.Disabled = settings.Disabled;
metadata.Priority = settings.Priority;
metadata.SearchDelayTime = settings.SearchDelayTime;
}
else
{
// If settings does not exist, create a new one
Plugins[metadata.ID] = new Plugin
{
ID = metadata.ID,
Name = metadata.Name,
Version = metadata.Version,
ActionKeywords = metadata.ActionKeywords,
DefaultActionKeywords = metadata.ActionKeywords, // metadata provides default values
ActionKeywords = metadata.ActionKeywords, // use default value
Disabled = metadata.Disabled,
Priority = metadata.Priority
Priority = metadata.Priority,
DefaultSearchDelayTime = metadata.SearchDelayTime, // metadata provides default values
SearchDelayTime = metadata.SearchDelayTime, // use default value
};
}
}
}

public Plugin GetPluginSettings(string id)
{
if (Plugins.TryGetValue(id, out var plugin))
{
return plugin;
}
return null;
}

public Plugin RemovePluginSettings(string id)
{
Plugins.Remove(id, out var plugin);
return plugin;
}
}

public class Plugin
{
public string ID { get; set; }

public string Name { get; set; }

public string Version { get; set; }
public List<string> ActionKeywords { get; set; } // a reference of the action keywords from plugin manager

[JsonIgnore]
public List<string> DefaultActionKeywords { get; set; }

// a reference of the action keywords from plugin manager
public List<string> ActionKeywords { get; set; }

public int Priority { get; set; }

[JsonIgnore]
public SearchDelayTime? DefaultSearchDelayTime { get; set; }

[JsonConverter(typeof(JsonStringEnumConverter))]
public SearchDelayTime? SearchDelayTime { get; set; }

/// <summary>
/// Used only to save the state of the plugin in settings
/// </summary>
Expand Down
10 changes: 7 additions & 3 deletions Flow.Launcher.Infrastructure/UserSettings/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ public string Theme
public double SettingWindowHeight { get; set; } = 700;
public double? SettingWindowTop { get; set; } = null;
public double? SettingWindowLeft { get; set; } = null;
public System.Windows.WindowState SettingWindowState { get; set; } = WindowState.Normal;
public WindowState SettingWindowState { get; set; } = WindowState.Normal;

bool _showPlaceholder { get; set; } = false;
public bool ShowPlaceholder
Expand Down Expand Up @@ -310,7 +310,7 @@ public bool KeepMaxResults
bool _hideNotifyIcon { get; set; }
public bool HideNotifyIcon
{
get { return _hideNotifyIcon; }
get => _hideNotifyIcon;
set
{
_hideNotifyIcon = value;
Expand All @@ -320,6 +320,11 @@ public bool HideNotifyIcon
public bool LeaveCmdOpen { get; set; }
public bool HideWhenDeactivated { get; set; } = true;

public bool SearchQueryResultsWithDelay { get; set; }

[JsonConverter(typeof(JsonStringEnumConverter))]
public SearchDelayTime SearchDelayTime { get; set; } = SearchDelayTime.Normal;

[JsonConverter(typeof(JsonStringEnumConverter))]
public SearchWindowScreens SearchWindowScreen { get; set; } = SearchWindowScreens.Cursor;

Expand All @@ -342,7 +347,6 @@ public bool HideNotifyIcon
[JsonIgnore]
public bool WMPInstalled { get; set; } = true;


// This needs to be loaded last by staying at the bottom
public PluginsSettings PluginSettings { get; set; } = new PluginsSettings();

Expand Down
8 changes: 7 additions & 1 deletion Flow.Launcher.Plugin/PluginMetadata.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,18 @@ internal set
/// All action keywords of plugin.
/// </summary>
public List<string> ActionKeywords { get; set; }

/// <summary>
/// Hide plugin keyword setting panel.
/// </summary>
public bool HideActionKeywordPanel { get; set; }

/// <summary>
/// Plugin search delay time. Null means use default search delay time.
/// </summary>
[JsonConverter(typeof(JsonStringEnumConverter))]
public SearchDelayTime? SearchDelayTime { get; set; } = null;

/// <summary>
/// Plugin icon path.
/// </summary>
Expand Down
32 changes: 32 additions & 0 deletions Flow.Launcher.Plugin/SearchDelayTime.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
namespace Flow.Launcher.Plugin;

/// <summary>
/// Enum for search delay time
/// </summary>
public enum SearchDelayTime
{
/// <summary>
/// Very long search delay time. 250ms.
/// </summary>
VeryLong,

/// <summary>
/// Long search delay time. 200ms.
/// </summary>
Long,

/// <summary>
/// Normal search delay time. 150ms. Default value.
/// </summary>
Normal,

/// <summary>
/// Short search delay time. 100ms.
/// </summary>
Short,

/// <summary>
/// Very short search delay time. 50ms.
/// </summary>
VeryShort
}
18 changes: 18 additions & 0 deletions Flow.Launcher/Languages/en.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,15 @@
<system:String x:Key="AlwaysPreview">Always Preview</system:String>
<system:String x:Key="AlwaysPreviewToolTip">Always open preview panel when Flow activates. Press {0} to toggle preview.</system:String>
<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">Default Search Delay Time</system:String>
<system:String x:Key="searchDelayTimeToolTip">Plugin default delay time after which search results appear when typing is stopped.</system:String>
<system:String x:Key="SearchDelayTimeVeryLong">Very long</system:String>
<system:String x:Key="SearchDelayTimeLong">Long</system:String>
<system:String x:Key="SearchDelayTimeNormal">Normal</system:String>
<system:String x:Key="SearchDelayTimeShort">Short</system:String>
<system:String x:Key="SearchDelayTimeVeryShort">Very short</system:String>

<!-- Setting Plugin -->
<system:String x:Key="searchplugin">Search Plugin</system:String>
Expand All @@ -118,6 +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="pluginSearchDelayTime">Plugin seach delay time</system:String>
<system:String x:Key="pluginSearchDelayTimeTooltip">Change Plugin Seach Delay Time</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>
Expand All @@ -133,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>
Expand Down Expand Up @@ -353,6 +365,12 @@
<system:String x:Key="completedSuccessfully">Completed successfully</system:String>
<system:String x:Key="actionkeyword_tips">Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.</system:String>

<!-- Search Delay Settings Dialog -->
<system:String x:Key="searchDelayTimeTitle">Search Delay Time Setting</system:String>
<system:String x:Key="searchDelayTime_tips">Select the search delay time you like to use for the plugin. Select "{0}" if you don't want to specify any, and the plugin will use default search delay time.</system:String>
<system:String x:Key="currentSearchDelayTime">Current search delay time</system:String>
<system:String x:Key="newSearchDelayTime">New search delay time</system:String>

<!-- Custom Query Hotkey Dialog -->
<system:String x:Key="customeQueryHotkeyTitle">Custom Query Hotkey</system:String>
<system:String x:Key="customeQueryHotkeyTips">Press a custom hotkey to open Flow Launcher and input the specified query automatically.</system:String>
Expand Down
3 changes: 2 additions & 1 deletion Flow.Launcher/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,8 @@
PreviewDragOver="QueryTextBox_OnPreviewDragOver"
PreviewKeyUp="QueryTextBox_KeyUp"
Style="{DynamicResource QueryBoxStyle}"
Text="{Binding QueryText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Text="{Binding QueryText, Mode=OneWay}"
TextChanged="QueryTextBox_TextChanged1"
Visibility="Visible"
WindowChrome.IsHitTestVisibleInChrome="True">
<TextBox.CommandBindings>
Expand Down
18 changes: 17 additions & 1 deletion Flow.Launcher/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
using Flow.Launcher.Plugin.SharedCommands;
using Flow.Launcher.ViewModel;
using ModernWpf.Controls;
using DataObject = System.Windows.DataObject;
using Key = System.Windows.Input.Key;
using MouseButtons = System.Windows.Forms.MouseButtons;
using NotifyIcon = System.Windows.Forms.NotifyIcon;
using Screen = System.Windows.Forms.Screen;
Expand Down Expand Up @@ -165,6 +167,8 @@ private async void OnLoaded(object sender, RoutedEventArgs _)
// Set the initial state of the QueryTextBoxCursorMovedToEnd property
// Without this part, when shown for the first time, switching the context menu does not move the cursor to the end.
_viewModel.QueryTextCursorMovedToEnd = false;

// View model property changed event
_viewModel.PropertyChanged += (o, e) =>
{
switch (e.PropertyName)
Expand Down Expand Up @@ -227,6 +231,7 @@ private async void OnLoaded(object sender, RoutedEventArgs _)
}
};

// Settings property changed event
_settings.PropertyChanged += (o, e) =>
{
switch (e.PropertyName)
Expand Down Expand Up @@ -1050,7 +1055,7 @@ private void QueryTextBox_OnPreviewDragOver(object sender, DragEventArgs e)
{
e.Handled = true;
}

#endregion

#region Placeholder
Expand Down Expand Up @@ -1101,6 +1106,17 @@ private void SetupResizeMode()
}
}

#endregion

#region Search Delay

private void QueryTextBox_TextChanged1(object sender, TextChangedEventArgs e)
{
var textBox = (TextBox)sender;
_viewModel.QueryText = textBox.Text;
_viewModel.Query(_settings.SearchQueryResultsWithDelay);
}

#endregion

#region IDisposable
Expand Down
Loading
Loading