[PTRun]Fix search being abandoned while cycling results (#27409)

* [Launcher] ignoring key preses while previous key press processing is ongoing

* extending TextChangedEventArgs with Initiator, storing and using initiator for the event lifetime to avoid overwriting of the initiator when parallel events occur.

* extending code with check on event object presence
This commit is contained in:
Laszlo Nemeth
2023-08-06 16:22:33 +02:00
committed by GitHub
parent 159bf7455d
commit 185ebad2f0
2 changed files with 57 additions and 12 deletions

View File

@@ -218,14 +218,15 @@ namespace PowerLauncher
if (showResultsWithDelay)
{
_reactiveSubscription = Observable.FromEventPattern<TextChangedEventHandler, TextChangedEventArgs>(
_reactiveSubscription = Observable.FromEventPattern<TextChangedEventHandler, TextChangedEventWithInitiatorArgs>(
conversion => (sender, eventArg) => conversion(sender, new TextChangedEventWithInitiatorArgs(eventArg.RoutedEvent, eventArg.UndoAction)),
add => SearchBox.QueryTextBox.TextChanged += add,
remove => SearchBox.QueryTextBox.TextChanged -= remove)
.Do(@event => ClearAutoCompleteText((TextBox)@event.Sender))
.Do(@event => ClearAutoCompleteText((TextBox)@event.Sender, @event))
.Throttle(TimeSpan.FromMilliseconds(_settings.SearchInputDelayFast))
.Do(@event => Dispatcher.InvokeAsync(() => PerformSearchQuery((TextBox)@event.Sender, false)))
.Do(@event => Dispatcher.InvokeAsync(() => PerformSearchQuery((TextBox)@event.Sender, false, @event)))
.Throttle(TimeSpan.FromMilliseconds(_settings.SearchInputDelay))
.Do(@event => Dispatcher.InvokeAsync(() => PerformSearchQuery((TextBox)@event.Sender, true)))
.Do(@event => Dispatcher.InvokeAsync(() => PerformSearchQuery((TextBox)@event.Sender, true, @event)))
.Subscribe();
/*
@@ -358,10 +359,18 @@ namespace PowerLauncher
_isTextSetProgrammatically = true;
if (_viewModel.Results != null)
{
SearchBox.QueryTextBox.Text = MainViewModel.GetSearchText(
string newText = MainViewModel.GetSearchText(
_viewModel.Results.SelectedIndex,
_viewModel.SystemQueryText,
_viewModel.QueryText);
if (SearchBox.QueryTextBox.Text != newText)
{
SearchBox.QueryTextBox.Text = newText;
}
else
{
_isTextSetProgrammatically = false;
}
}
}
}
@@ -563,12 +572,18 @@ namespace PowerLauncher
private void QueryTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
var textBox = (TextBox)sender;
ClearAutoCompleteText(textBox);
ClearAutoCompleteText(textBox, null);
PerformSearchQuery(textBox);
}
private void ClearAutoCompleteText(TextBox textBox)
private void ClearAutoCompleteText(TextBox textBox, System.Reactive.EventPattern<TextChangedEventWithInitiatorArgs> @event)
{
bool isTextSetProgrammaticallyAtStart = _isTextSetProgrammatically;
if (@event != null)
{
@event.EventArgs.IsTextSetProgrammatically = isTextSetProgrammaticallyAtStart;
}
var text = textBox.Text;
var autoCompleteText = SearchBox.AutoCompleteTextBlock.Text;
@@ -588,7 +603,7 @@ namespace PowerLauncher
if (pTRunStartNewSearchAction == "DeSelect")
{
// leave the results, be deselect anything to it will not be activated by <enter> key, can still be arrow-key or clicked though
if (!_isTextSetProgrammatically)
if (!isTextSetProgrammaticallyAtStart)
{
DeselectAllResults();
}
@@ -596,7 +611,7 @@ namespace PowerLauncher
else if (pTRunStartNewSearchAction == "Clear")
{
// remove all results to prepare for new results, this causes flashing usually and is not cool
if (!_isTextSetProgrammatically)
if (!isTextSetProgrammaticallyAtStart)
{
ClearResults();
}
@@ -630,14 +645,20 @@ namespace PowerLauncher
private void PerformSearchQuery(TextBox textBox)
{
PerformSearchQuery(textBox, null);
PerformSearchQuery(textBox, null, null);
}
private void PerformSearchQuery(TextBox textBox, bool? delayedExecution)
private void PerformSearchQuery(TextBox textBox, bool? delayedExecution, System.Reactive.EventPattern<TextChangedEventWithInitiatorArgs> @event)
{
var text = textBox.Text;
bool isTextSetProgrammaticallyForEvent = _isTextSetProgrammatically;
if (_isTextSetProgrammatically)
if (@event != null)
{
isTextSetProgrammaticallyForEvent = @event.EventArgs.IsTextSetProgrammatically;
}
if (isTextSetProgrammaticallyForEvent)
{
textBox.SelectionStart = textBox.Text.Length;

View File

@@ -0,0 +1,24 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
namespace PowerLauncher
{
internal sealed class TextChangedEventWithInitiatorArgs : TextChangedEventArgs
{
public TextChangedEventWithInitiatorArgs(RoutedEvent id, UndoAction action)
: base(id, action)
{
}
public bool IsTextSetProgrammatically { get; set; }
}
}