diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs index 7200b23eb..1e79242a4 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs @@ -288,9 +288,6 @@ namespace Flow.Launcher.Infrastructure.UserSettings } public int SearchDelay { get; set; } = 120; - // TODO: Remove debug codes. - public const int SearchDelayInterval = 30 * 60; - [JsonIgnore] public List SearchDelayRange { get; } = new() { diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs index 43274e496..181ee731d 100644 --- a/Flow.Launcher/MainWindow.xaml.cs +++ b/Flow.Launcher/MainWindow.xaml.cs @@ -59,7 +59,10 @@ namespace Flow.Launcher // Window Animation private const double DefaultRightMargin = 66; //* this value from base.xaml private bool _animating; - private bool _isClockPanelAnimating = false; // 애니메이션 실행 중인지 여부 + private bool _isClockPanelAnimating = false; + + // Search Delay + private IDisposable _reactiveSubscription; #endregion @@ -96,6 +99,9 @@ namespace Flow.Launcher private async void OnLoaded(object sender, RoutedEventArgs _) { + // Setup search text box reactiveness + SetupSearchTextBoxReactiveness(_settings.SearchQueryResultsWithDelay); + // Check first launch if (_settings.FirstLaunch) { @@ -144,6 +150,7 @@ namespace Flow.Launcher // Since the default main window visibility is visible, so we need set focus during startup QueryTextBox.Focus(); + // View model property changed event _viewModel.PropertyChanged += (o, e) => { switch (e.PropertyName) @@ -194,6 +201,7 @@ namespace Flow.Launcher } }; + // Settings property changed event _settings.PropertyChanged += (o, e) => { switch (e.PropertyName) @@ -917,7 +925,6 @@ namespace Flow.Launcher } } - private static double GetOpacityFromStyle(Style style, double defaultOpacity = 1.0) { if (style == null) @@ -1001,8 +1008,6 @@ namespace Flow.Launcher // Edited from: https://github.com/microsoft/PowerToys - private IDisposable _reactiveSubscription; - private void SetupSearchTextBoxReactiveness(bool showResultsWithDelay) { if (_reactiveSubscription != null) @@ -1020,17 +1025,7 @@ namespace Flow.Launcher add => QueryTextBox.TextChanged += add, remove => QueryTextBox.TextChanged -= remove) .Throttle(TimeSpan.FromMilliseconds(_settings.SearchDelay * 10)) - .Do(@event => Dispatcher.Invoke(() => PerformSearchQuery(0, (TextBox)@event.Sender))) - .Throttle(TimeSpan.FromMilliseconds(Settings.SearchDelayInterval)) - .Do(@event => Dispatcher.Invoke(() => PerformSearchQuery(30, (TextBox)@event.Sender))) - .Throttle(TimeSpan.FromMilliseconds(Settings.SearchDelayInterval)) - .Do(@event => Dispatcher.Invoke(() => PerformSearchQuery(60, (TextBox)@event.Sender))) - .Throttle(TimeSpan.FromMilliseconds(Settings.SearchDelayInterval)) - .Do(@event => Dispatcher.Invoke(() => PerformSearchQuery(90, (TextBox)@event.Sender))) - .Throttle(TimeSpan.FromMilliseconds(Settings.SearchDelayInterval)) - .Do(@event => Dispatcher.Invoke(() => PerformSearchQuery(120, (TextBox)@event.Sender))) - .Throttle(TimeSpan.FromMilliseconds(Settings.SearchDelayInterval)) - .Do(@event => Dispatcher.Invoke(() => PerformSearchQuery(150, (TextBox)@event.Sender))) + .Do(@event => Dispatcher.Invoke(() => PerformSearchQuery(true, (TextBox)@event.Sender))) .Subscribe(); } else @@ -1042,18 +1037,13 @@ namespace Flow.Launcher private void QueryTextBox_TextChanged(object sender, TextChangedEventArgs e) { var textBox = (TextBox)sender; - PerformSearchQuery(null, textBox); + PerformSearchQuery(false, textBox); } - // If delayInputTime is null, we will query plugins with all plugin search delay times - private void PerformSearchQuery(int? searchDelay, TextBox textBox) + private void PerformSearchQuery(bool searchDelay, TextBox textBox) { - // Only update query text when search delay is null or 0 - if (searchDelay.GetValueOrDefault(0) == 0) - { - var text = textBox.Text; - _viewModel.QueryText = text; - } + var text = textBox.Text; + _viewModel.QueryText = text; _viewModel.Query(searchDelay); } diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs index 3ed0d29d9..1b56f3ee6 100644 --- a/Flow.Launcher/ViewModel/MainViewModel.cs +++ b/Flow.Launcher/ViewModel/MainViewModel.cs @@ -282,14 +282,14 @@ namespace Flow.Launcher.ViewModel { if (SelectedIsFromQueryResults()) { - _ = QueryResultsAsync(null, isReQuery: true); + _ = QueryResultsAsync(false, isReQuery: true); } } public void ReQuery(bool reselect) { BackToQueryResults(); - _ = QueryResultsAsync(null, isReQuery: true, reSelect: reselect); + _ = QueryResultsAsync(false, isReQuery: true, reSelect: reselect); } [RelayCommand] @@ -622,14 +622,14 @@ namespace Flow.Launcher.ViewModel { // re-query is done in QueryText's setter method QueryText = queryText; - Query(null); + Query(false); // set to false so the subsequent set true triggers // PropertyChanged and MoveQueryTextToEnd is called QueryTextCursorMovedToEnd = false; } else if (isReQuery) { - Query(null, isReQuery: true); + Query(false, isReQuery: true); } QueryTextCursorMovedToEnd = true; @@ -679,15 +679,8 @@ namespace Flow.Launcher.ViewModel // setter won't be called when property value is not changed. // so we need manually call Query() // http://stackoverflow.com/posts/25895769/revisions - if (string.IsNullOrEmpty(QueryText)) - { - Query(null); - } - else - { - QueryText = string.Empty; - Query(null); - } + QueryText = string.Empty; + Query(false); } _selectedResults.Visibility = Visibility.Visible; @@ -955,7 +948,7 @@ namespace Flow.Launcher.ViewModel #region Query - public void Query(int? searchDelay, bool isReQuery = false) + public void Query(bool searchDelay, bool isReQuery = false) { if (SelectedIsFromQueryResults()) { @@ -963,19 +956,11 @@ namespace Flow.Launcher.ViewModel } else if (ContextMenuSelected()) { - // Only query history when search delay is null or 0 - if (searchDelay.GetValueOrDefault(0) == 0) - { - QueryContextMenu(); - } + QueryContextMenu(); } else if (HistorySelected()) { - // Only query history when search delay is null or 0 - if (searchDelay.GetValueOrDefault(0) == 0) - { - QueryHistory(); - } + QueryHistory(); } } @@ -1065,8 +1050,9 @@ namespace Flow.Launcher.ViewModel private readonly IReadOnlyList _emptyResult = new List(); - private async Task QueryResultsAsync(int? searchDelay, bool isReQuery = false, bool reSelect = true) + private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, bool reSelect = true) { + // TODO: Remove debug codes. System.Diagnostics.Debug.WriteLine("!!!QueryResults"); _updateSource?.Cancel(); @@ -1130,12 +1116,12 @@ namespace Flow.Launcher.ViewModel } _ = Task.Delay(200, _updateSource.Token).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 (!_updateSource.Token.IsCancellationRequested && _isQueryRunning) { - ProgressBarVisibility = Visibility.Visible; - } + // 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 (!_updateSource.Token.IsCancellationRequested && _isQueryRunning) + { + ProgressBarVisibility = Visibility.Visible; + } }, _updateSource.Token, TaskContinuationOptions.NotOnCanceled, @@ -1143,47 +1129,23 @@ namespace Flow.Launcher.ViewModel // plugins is ICollection, meaning LINQ will get the Count and preallocate Array - Task[] tasks; - if (searchDelay.HasValue) + var tasks = plugins.Select(plugin => plugin.Metadata.Disabled switch { - var searchDelayValue = searchDelay.Value; - tasks = plugins.Select(plugin => (plugin.Metadata.Disabled || plugin.Metadata.SearchDelay != searchDelayValue) switch - { - false => QueryTaskAsync(plugin, reSelect), - true => Task.CompletedTask - }).ToArray(); + false => QueryTaskAsync(plugin, searchDelay, reSelect, _updateSource.Token), + true => Task.CompletedTask + }).ToArray(); - // TODO: Remove debug codes. - System.Diagnostics.Debug.Write($"!!!{query.RawQuery} Querying {searchDelayValue}ms"); - foreach (var plugin in plugins) - { - if (!(plugin.Metadata.Disabled || plugin.Metadata.SearchDelay != searchDelayValue)) - { - System.Diagnostics.Debug.Write($"{plugin.Metadata.Name}"); - } - } - System.Diagnostics.Debug.Write("\n"); - } - else + // TODO: Remove debug codes. + System.Diagnostics.Debug.Write($"!!!Querying {query.RawQuery}: search dalay {searchDelay}"); + foreach (var plugin in plugins) { - tasks = plugins.Select(plugin => plugin.Metadata.Disabled switch + if (!plugin.Metadata.Disabled) { - false => QueryTaskAsync(plugin, reSelect), - true => Task.CompletedTask - }).ToArray(); - - // TODO: Remove debug codes. - System.Diagnostics.Debug.Write($"!!!{query.RawQuery} Querying null ms"); - foreach (var plugin in plugins) - { - if (!plugin.Metadata.Disabled) - { - System.Diagnostics.Debug.Write($"{plugin.Metadata.Name}"); - } + System.Diagnostics.Debug.Write($"{plugin.Metadata.Name}, "); } - System.Diagnostics.Debug.Write("\n"); } - + System.Diagnostics.Debug.Write("\n"); + try { // Check the code, WhenAll will translate all type of IEnumerable or Collection to Array, so make an array at first @@ -1207,15 +1169,29 @@ namespace Flow.Launcher.ViewModel } // Local function - async Task QueryTaskAsync(bool searchDelay, PluginPair plugin, bool reSelect, CancellationToken token) - { - if (!searchDelay) + async Task QueryTaskAsync(PluginPair plugin, bool searchDelay, bool reSelect, CancellationToken token) { + if (searchDelay) + { + // TODO: Remove debug codes. + System.Diagnostics.Debug.WriteLine($"!!!{plugin.Metadata.Name} Waiting {plugin.Metadata.SearchDelay} ms"); + + // TODO: Remove debug codes. + await Task.Delay(plugin.Metadata.SearchDelay * 60, token); + + // TODO: Remove debug codes. + System.Diagnostics.Debug.WriteLine($"!!!{plugin.Metadata.Name} Waited {plugin.Metadata.SearchDelay} ms"); + + if (token.IsCancellationRequested) + return; + } + // Since it is wrapped within a ThreadPool Thread, the synchronous context is null // Task.Yield will force it to run in ThreadPool await Task.Yield(); - } + // TODO: Remove debug codes. + System.Diagnostics.Debug.WriteLine($"!!!{query.RawQuery} Querying {plugin.Metadata.Name}"); IReadOnlyList results = await PluginManager.QueryForPluginAsync(plugin, query, token);