This commit is contained in:
Jack Ye 2026-03-10 12:20:47 +08:00 committed by GitHub
commit b1b03fd3ea
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 178 additions and 91 deletions

View file

@ -5,6 +5,7 @@ using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Documents; using System.Windows.Documents;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Infrastructure.Storage; using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Plugin; using Flow.Launcher.Plugin;
@ -99,14 +100,14 @@ namespace Flow.Launcher.Core.Plugin
{ {
case TextBox textBox: case TextBox textBox:
var text = value as string ?? string.Empty; var text = value as string ?? string.Empty;
textBox.Dispatcher.Invoke(() => textBox.Text = text); DispatcherHelper.Invoke(() => textBox.Text = text);
break; break;
case PasswordBox passwordBox: case PasswordBox passwordBox:
var password = value as string ?? string.Empty; var password = value as string ?? string.Empty;
passwordBox.Dispatcher.Invoke(() => passwordBox.Password = password); DispatcherHelper.Invoke(() => passwordBox.Password = password);
break; break;
case ComboBox comboBox: case ComboBox comboBox:
comboBox.Dispatcher.Invoke(() => comboBox.SelectedItem = value); DispatcherHelper.Invoke(() => comboBox.SelectedItem = value);
break; break;
case CheckBox checkBox: case CheckBox checkBox:
var isChecked = value is bool boolValue var isChecked = value is bool boolValue
@ -114,7 +115,7 @@ namespace Flow.Launcher.Core.Plugin
// If can parse the default value to bool, use it, otherwise use false // If can parse the default value to bool, use it, otherwise use false
: value is string stringValue && bool.TryParse(stringValue, out var boolValueFromString) : value is string stringValue && bool.TryParse(stringValue, out var boolValueFromString)
&& boolValueFromString; && boolValueFromString;
checkBox.Dispatcher.Invoke(() => checkBox.IsChecked = isChecked); DispatcherHelper.Invoke(() => checkBox.IsChecked = isChecked);
break; break;
} }
} }

View file

@ -0,0 +1,102 @@
using System;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
namespace Flow.Launcher.Core.Resource;
#pragma warning disable VSTHRD001 // Avoid legacy thread switching APIs
public static class DispatcherHelper
{
public static void Invoke(Action action, DispatcherPriority priority = DispatcherPriority.Normal)
{
Invoke(Application.Current?.Dispatcher, action, priority);
}
public static T Invoke<T>(Func<T> func, DispatcherPriority priority = DispatcherPriority.Normal)
{
return Invoke(Application.Current?.Dispatcher, func, priority);
}
public static void Invoke(Dispatcher dispatcher, Action action, DispatcherPriority priority = DispatcherPriority.Normal)
{
if (dispatcher == null) return;
if (dispatcher.CheckAccess())
{
action();
}
else
{
dispatcher.Invoke(action, priority);
}
}
public static T Invoke<T>(Dispatcher dispatcher, Func<T> func, DispatcherPriority priority = DispatcherPriority.Normal)
{
if (dispatcher == null) return default;
if (dispatcher.CheckAccess())
{
return func();
}
else
{
return dispatcher.Invoke(func, priority);
}
}
public static async Task InvokeAsync(Action action, DispatcherPriority priority = DispatcherPriority.Normal)
{
await InvokeAsync(Application.Current?.Dispatcher, action, priority);
}
public static async Task<T> InvokeAsync<T>(Func<T> func, DispatcherPriority priority = DispatcherPriority.Normal)
{
return await InvokeAsync(Application.Current?.Dispatcher, func, priority);
}
public static async Task InvokeAsync(Func<Task> func, DispatcherPriority priority = DispatcherPriority.Normal)
{
await InvokeAsync(Application.Current?.Dispatcher, func, priority);
}
public static async Task InvokeAsync(Dispatcher dispatcher, Action action, DispatcherPriority priority = DispatcherPriority.Normal)
{
if (dispatcher == null) return;
if (dispatcher.CheckAccess())
{
action();
}
else
{
await dispatcher.InvokeAsync(action, priority);
}
}
public static async Task<T> InvokeAsync<T>(Dispatcher dispatcher, Func<T> func, DispatcherPriority priority = DispatcherPriority.Normal)
{
if (dispatcher == null) return default;
if (dispatcher.CheckAccess())
{
return func();
}
else
{
return await dispatcher.InvokeAsync(func, priority);
}
}
public static async Task InvokeAsync(Dispatcher dispatcher, Func<Task> func, DispatcherPriority priority = DispatcherPriority.Normal)
{
if (dispatcher == null) return;
if (dispatcher.CheckAccess())
{
await func();
}
else
{
var task = await dispatcher.InvokeAsync(func, priority);
await task;
}
}
}

View file

@ -596,7 +596,7 @@ namespace Flow.Launcher.Core.Resource
/// </summary> /// </summary>
public async Task RefreshFrameAsync() public async Task RefreshFrameAsync()
{ {
await Application.Current.Dispatcher.InvokeAsync(() => await DispatcherHelper.InvokeAsync(() =>
{ {
// Get the actual backdrop type and drop shadow effect settings // Get the actual backdrop type and drop shadow effect settings
var (backdropType, useDropShadowEffect) = GetActualValue(); var (backdropType, useDropShadowEffect) = GetActualValue();
@ -623,7 +623,7 @@ namespace Flow.Launcher.Core.Resource
/// </summary> /// </summary>
public async Task SetBlurForWindowAsync() public async Task SetBlurForWindowAsync()
{ {
await Application.Current.Dispatcher.InvokeAsync(() => await DispatcherHelper.InvokeAsync(() =>
{ {
// Get the actual backdrop type and drop shadow effect settings // Get the actual backdrop type and drop shadow effect settings
var (backdropType, _) = GetActualValue(); var (backdropType, _) = GetActualValue();

View file

@ -334,7 +334,7 @@ namespace Flow.Launcher
var timer = new PeriodicTimer(TimeSpan.FromHours(5)); var timer = new PeriodicTimer(TimeSpan.FromHours(5));
await PluginInstaller.CheckForPluginUpdatesAsync((plugins) => await PluginInstaller.CheckForPluginUpdatesAsync((plugins) =>
{ {
Current.Dispatcher.Invoke(() => DispatcherHelper.Invoke(() =>
{ {
var pluginUpdateWindow = new PluginUpdateWindow(plugins); var pluginUpdateWindow = new PluginUpdateWindow(plugins);
pluginUpdateWindow.ShowDialog(); pluginUpdateWindow.ShowDialog();
@ -345,7 +345,7 @@ namespace Flow.Launcher
// check updates on startup // check updates on startup
await PluginInstaller.CheckForPluginUpdatesAsync((plugins) => await PluginInstaller.CheckForPluginUpdatesAsync((plugins) =>
{ {
Current.Dispatcher.Invoke(() => DispatcherHelper.Invoke(() =>
{ {
var pluginUpdateWindow = new PluginUpdateWindow(plugins); var pluginUpdateWindow = new PluginUpdateWindow(plugins);
pluginUpdateWindow.ShowDialog(); pluginUpdateWindow.ShowDialog();
@ -444,7 +444,7 @@ namespace Flow.Launcher
{ {
// Dispose needs to be called on the main Windows thread, // Dispose needs to be called on the main Windows thread,
// since some resources owned by the thread need to be disposed. // since some resources owned by the thread need to be disposed.
_mainWindow?.Dispatcher.Invoke(_mainWindow.Dispose); DispatcherHelper.Invoke(_mainWindow?.Dispatcher, _mainWindow.Dispose);
_mainVM?.Dispose(); _mainVM?.Dispose();
DialogJump.Dispose(); DialogJump.Dispose();
_internationalization.Dispose(); _internationalization.Dispose();

View file

@ -3,6 +3,7 @@ using System.IO.Pipes;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows; using System.Windows;
using Flow.Launcher.Core.Resource;
// http://blogs.microsoft.co.il/arik/2010/05/28/wpf-single-instance-application/ // http://blogs.microsoft.co.il/arik/2010/05/28/wpf-single-instance-application/
// modified to allow single instace restart // modified to allow single instace restart
@ -100,7 +101,9 @@ namespace Flow.Launcher.Helper
await pipeServer.WaitForConnectionAsync(); await pipeServer.WaitForConnectionAsync();
// Do an asynchronous call to ActivateFirstInstance function // Do an asynchronous call to ActivateFirstInstance function
Application.Current?.Dispatcher.Invoke(ActivateFirstInstance); #pragma warning disable VSTHRD103 // Call async methods when in an async method
DispatcherHelper.Invoke(ActivateFirstInstance);
#pragma warning restore VSTHRD103 // Call async methods when in an async method
// Disconect client // Disconect client
pipeServer.Disconnect(); pipeServer.Disconnect();

View file

@ -3,9 +3,9 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Windows;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Infrastructure; using Flow.Launcher.Infrastructure;
using Microsoft.Win32; using Microsoft.Win32;
@ -22,11 +22,11 @@ public static class WallpaperPathRetrieval
public static Brush GetWallpaperBrush() public static Brush GetWallpaperBrush()
{ {
// Invoke the method on the UI thread // Invoke the method on the UI thread
if (!Application.Current.Dispatcher.CheckAccess()) return DispatcherHelper.Invoke(GetWallpaperBrushCore);
{ }
return Application.Current.Dispatcher.Invoke(GetWallpaperBrush);
}
private static Brush GetWallpaperBrushCore()
{
try try
{ {
var wallpaperPath = Win32Helper.GetWallpaperPath(); var wallpaperPath = Win32Helper.GetWallpaperPath();

View file

@ -153,7 +153,7 @@ namespace Flow.Launcher
Localize.appUpdateButtonContent(), Localize.appUpdateButtonContent(),
() => () =>
{ {
Application.Current.Dispatcher.Invoke(() => DispatcherHelper.Invoke(() =>
{ {
var releaseNotesWindow = new ReleaseNotesWindow(); var releaseNotesWindow = new ReleaseNotesWindow();
releaseNotesWindow.Show(); releaseNotesWindow.Show();
@ -225,7 +225,7 @@ namespace Flow.Launcher
{ {
case nameof(MainViewModel.MainWindowVisibilityStatus): case nameof(MainViewModel.MainWindowVisibilityStatus):
{ {
Dispatcher.Invoke(() => DispatcherHelper.Invoke(() =>
{ {
if (_viewModel.MainWindowVisibilityStatus) if (_viewModel.MainWindowVisibilityStatus)
{ {
@ -269,7 +269,7 @@ namespace Flow.Launcher
{ {
// QueryTextBox seems to be update with a DispatcherPriority as low as ContextIdle. // QueryTextBox seems to be update with a DispatcherPriority as low as ContextIdle.
// To ensure QueryTextBox is up to date with QueryText from the View, we need to Dispatch with such a priority // To ensure QueryTextBox is up to date with QueryText from the View, we need to Dispatch with such a priority
Dispatcher.Invoke(() => QueryTextBox.CaretIndex = QueryTextBox.Text.Length); DispatcherHelper.Invoke(() => QueryTextBox.CaretIndex = QueryTextBox.Text.Length);
_viewModel.QueryTextCursorMovedToEnd = false; _viewModel.QueryTextCursorMovedToEnd = false;
} }
break; break;
@ -542,7 +542,7 @@ namespace Flow.Launcher
// Switch to Normal state // Switch to Normal state
WindowState = WindowState.Normal; WindowState = WindowState.Normal;
Application.Current?.Dispatcher.Invoke(new Action(() => DispatcherHelper.Invoke(() =>
{ {
double normalWidth = Width; double normalWidth = Width;
double normalHeight = Height; double normalHeight = Height;
@ -555,7 +555,7 @@ namespace Flow.Launcher
{ {
DragMove(); DragMove();
} }
}), DispatcherPriority.ApplicationIdle); }, DispatcherPriority.ApplicationIdle);
} }
else else
{ {
@ -726,19 +726,8 @@ namespace Flow.Launcher
{ {
Win32Helper.RegisterSleepModeListener(() => Win32Helper.RegisterSleepModeListener(() =>
{ {
if (Application.Current == null)
{
return;
}
// We must run InitSoundEffects on UI thread because MediaPlayer is a DispatcherObject // We must run InitSoundEffects on UI thread because MediaPlayer is a DispatcherObject
if (!Application.Current.Dispatcher.CheckAccess()) DispatcherHelper.Invoke(InitSoundEffects);
{
Application.Current.Dispatcher.Invoke(InitSoundEffects);
return;
}
InitSoundEffects();
}); });
} }
catch (Exception e) catch (Exception e)

View file

@ -3,6 +3,7 @@ using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Input; using System.Windows.Input;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Infrastructure; using Flow.Launcher.Infrastructure;
namespace Flow.Launcher namespace Flow.Launcher
@ -29,11 +30,16 @@ namespace Flow.Launcher
MessageBoxImage icon = MessageBoxImage.None, MessageBoxImage icon = MessageBoxImage.None,
MessageBoxResult defaultResult = MessageBoxResult.OK) MessageBoxResult defaultResult = MessageBoxResult.OK)
{ {
if (!Application.Current.Dispatcher.CheckAccess()) return DispatcherHelper.Invoke(() => ShowCore(messageBoxText, caption, button, icon, defaultResult));
{ }
return Application.Current.Dispatcher.Invoke(() => Show(messageBoxText, caption, button, icon, defaultResult));
}
private static MessageBoxResult ShowCore(
string messageBoxText,
string caption = "",
MessageBoxButton button = MessageBoxButton.OK,
MessageBoxImage icon = MessageBoxImage.None,
MessageBoxResult defaultResult = MessageBoxResult.OK)
{
try try
{ {
msgBox = new MessageBoxEx(button); msgBox = new MessageBoxEx(button);

View file

@ -3,6 +3,7 @@ using System.IO;
using System.Windows; using System.Windows;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Media.Animation; using System.Windows.Media.Animation;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Infrastructure; using Flow.Launcher.Infrastructure;
using Flow.Launcher.Plugin.SharedModels; using Flow.Launcher.Plugin.SharedModels;
@ -80,12 +81,12 @@ namespace Flow.Launcher
Show(); Show();
await Dispatcher.InvokeAsync(async () => await DispatcherHelper.InvokeAsync(async () =>
{ {
if (!closing) if (!closing)
{ {
closing = true; closing = true;
await Dispatcher.InvokeAsync(fadeOutStoryboard.Begin); fadeOutStoryboard.Begin();
} }
}); });
} }

View file

@ -3,6 +3,7 @@ using System.IO;
using System.Windows; using System.Windows;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Media.Animation; using System.Windows.Media.Animation;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Infrastructure; using Flow.Launcher.Infrastructure;
using Flow.Launcher.Plugin.SharedModels; using Flow.Launcher.Plugin.SharedModels;
@ -82,12 +83,12 @@ namespace Flow.Launcher
Show(); Show();
await Dispatcher.InvokeAsync(async () => await DispatcherHelper.InvokeAsync(async () =>
{ {
if (!closing) if (!closing)
{ {
closing = true; closing = true;
await Dispatcher.InvokeAsync(fadeOutStoryboard.Begin); fadeOutStoryboard.Begin();
} }
}); });
} }

View file

@ -1,7 +1,7 @@
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.IO; using System.IO;
using System.Windows; using Flow.Launcher.Core.Resource;
using Flow.Launcher.Infrastructure; using Flow.Launcher.Infrastructure;
using Microsoft.Toolkit.Uwp.Notifications; using Microsoft.Toolkit.Uwp.Notifications;
@ -41,7 +41,7 @@ namespace Flow.Launcher
public static void Show(string title, string subTitle, string iconPath = null) public static void Show(string title, string subTitle, string iconPath = null)
{ {
Application.Current.Dispatcher.Invoke(() => DispatcherHelper.Invoke(() =>
{ {
ShowInternal(title, subTitle, iconPath); ShowInternal(title, subTitle, iconPath);
}); });
@ -91,7 +91,7 @@ namespace Flow.Launcher
public static void ShowWithButton(string title, string buttonText, Action buttonAction, string subTitle, string iconPath = null) public static void ShowWithButton(string title, string buttonText, Action buttonAction, string subTitle, string iconPath = null)
{ {
Application.Current.Dispatcher.Invoke(() => DispatcherHelper.Invoke(() =>
{ {
ShowInternalWithButton(title, buttonText, buttonAction, subTitle, iconPath); ShowInternalWithButton(title, buttonText, buttonAction, subTitle, iconPath);
}); });

View file

@ -2,6 +2,7 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Input; using System.Windows.Input;
using Flow.Launcher.Core.Resource;
namespace Flow.Launcher namespace Flow.Launcher
{ {
@ -22,19 +23,7 @@ namespace Flow.Launcher
ProgressBoxEx progressBox = null; ProgressBoxEx progressBox = null;
try try
{ {
if (!Application.Current.Dispatcher.CheckAccess()) await DispatcherHelper.InvokeAsync(() =>
{
await Application.Current.Dispatcher.InvokeAsync(() =>
{
progressBox = new ProgressBoxEx(cancelProgress)
{
Title = caption
};
progressBox.TitleTextBlock.Text = caption;
progressBox.Show();
});
}
else
{ {
progressBox = new ProgressBoxEx(cancelProgress) progressBox = new ProgressBoxEx(cancelProgress)
{ {
@ -42,7 +31,7 @@ namespace Flow.Launcher
}; };
progressBox.TitleTextBlock.Text = caption; progressBox.TitleTextBlock.Text = caption;
progressBox.Show(); progressBox.Show();
} });
await reportProgressAsync(progressBox.ReportProgress).ConfigureAwait(false); await reportProgressAsync(progressBox.ReportProgress).ConfigureAwait(false);
} }
@ -54,28 +43,20 @@ namespace Flow.Launcher
} }
finally finally
{ {
if (!Application.Current.Dispatcher.CheckAccess()) await DispatcherHelper.InvokeAsync(() =>
{
await Application.Current.Dispatcher.InvokeAsync(() =>
{
progressBox?.Close();
});
}
else
{ {
progressBox?.Close(); progressBox?.Close();
} });
} }
} }
private void ReportProgress(double progress) private void ReportProgress(double progress)
{ {
if (!Application.Current.Dispatcher.CheckAccess()) DispatcherHelper.Invoke(() => ReportProgressCore(progress));
{ }
Application.Current.Dispatcher.Invoke(() => ReportProgress(progress));
return;
}
private void ReportProgressCore(double progress)
{
if (progress < 0) if (progress < 0)
{ {
ProgressBar.Value = 0; ProgressBar.Value = 0;

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
@ -141,7 +141,7 @@ namespace Flow.Launcher
public void OpenSettingDialog() public void OpenSettingDialog()
{ {
Application.Current.Dispatcher.Invoke(() => DispatcherHelper.Invoke(() =>
{ {
SettingWindow sw = SingletonWindowOpener.Open<SettingWindow>(); SettingWindow sw = SingletonWindowOpener.Open<SettingWindow>();
}); });

View file

@ -9,6 +9,7 @@ using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Infrastructure.Http; using Flow.Launcher.Infrastructure.Http;
using iNKORE.UI.WPF.Modern; using iNKORE.UI.WPF.Modern;
@ -28,7 +29,7 @@ namespace Flow.Launcher
private void ThemeManager_ActualApplicationThemeChanged(ThemeManager sender, object args) private void ThemeManager_ActualApplicationThemeChanged(ThemeManager sender, object args)
{ {
Application.Current.Dispatcher.Invoke(() => DispatcherHelper.Invoke(() =>
{ {
if (ThemeManager.Current.ActualApplicationTheme == ApplicationTheme.Light) if (ThemeManager.Current.ActualApplicationTheme == ApplicationTheme.Light)
{ {
@ -124,7 +125,7 @@ namespace Flow.Launcher
{ {
var output = await GetReleaseNotesMarkdownAsync().ConfigureAwait(false); var output = await GetReleaseNotesMarkdownAsync().ConfigureAwait(false);
Application.Current.Dispatcher.Invoke(() => DispatcherHelper.Invoke(() =>
{ {
RefreshProgressRing.Visibility = Visibility.Collapsed; RefreshProgressRing.Visibility = Visibility.Collapsed;
if (string.IsNullOrEmpty(output)) if (string.IsNullOrEmpty(output))

View file

@ -5,6 +5,7 @@ using System.Threading.Tasks;
using System.Windows; using System.Windows;
using CommunityToolkit.Mvvm.Input; using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Core.Plugin; using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Plugin; using Flow.Launcher.Plugin;
using Flow.Launcher.ViewModel; using Flow.Launcher.ViewModel;
@ -115,7 +116,7 @@ public partial class SettingsPanePluginStoreViewModel : BaseModel
{ {
await PluginInstaller.CheckForPluginUpdatesAsync((plugins) => await PluginInstaller.CheckForPluginUpdatesAsync((plugins) =>
{ {
Application.Current.Dispatcher.Invoke(() => DispatcherHelper.Invoke(() =>
{ {
var pluginUpdateWindow = new PluginUpdateWindow(plugins); var pluginUpdateWindow = new PluginUpdateWindow(plugins);
pluginUpdateWindow.ShowDialog(); pluginUpdateWindow.ShowDialog();

View file

@ -16,6 +16,7 @@ using System.Windows.Threading;
using CommunityToolkit.Mvvm.DependencyInjection; using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.Input; using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Core.Plugin; using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Helper; using Flow.Launcher.Helper;
using Flow.Launcher.Infrastructure; using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.DialogJump; using Flow.Launcher.Infrastructure.DialogJump;
@ -763,12 +764,11 @@ namespace Flow.Launcher.ViewModel
public void ChangeQueryText(string queryText, bool isReQuery = false) public void ChangeQueryText(string queryText, bool isReQuery = false)
{ {
// Must check access so that we will not block the UI thread which causes window visibility issue // Must check access so that we will not block the UI thread which causes window visibility issue
if (!Application.Current.Dispatcher.CheckAccess()) DispatcherHelper.Invoke(() => ChangeQueryTextCore(queryText, isReQuery));
{ }
Application.Current.Dispatcher.Invoke(() => ChangeQueryText(queryText, isReQuery));
return;
}
private void ChangeQueryTextCore(string queryText, bool isReQuery = false)
{
if (QueryText != queryText) if (QueryText != queryText)
{ {
// Change query text first // Change query text first
@ -795,12 +795,11 @@ namespace Flow.Launcher.ViewModel
private async Task ChangeQueryTextAsync(string queryText, bool isReQuery = false) private async Task ChangeQueryTextAsync(string queryText, bool isReQuery = false)
{ {
// Must check access so that we will not block the UI thread which causes window visibility issue // Must check access so that we will not block the UI thread which causes window visibility issue
if (!Application.Current.Dispatcher.CheckAccess()) await DispatcherHelper.InvokeAsync(() => ChangeQueryTextCoreAsync(queryText, isReQuery));
{ }
await Application.Current.Dispatcher.InvokeAsync(() => ChangeQueryTextAsync(queryText, isReQuery));
return;
}
private async Task ChangeQueryTextCoreAsync(string queryText, bool isReQuery = false)
{
if (QueryText != queryText) if (QueryText != queryText)
{ {
// Change query text first // Change query text first
@ -1951,10 +1950,12 @@ namespace Flow.Launcher.ViewModel
if (dialogWindowHandleChanged) if (dialogWindowHandleChanged)
{ {
// Only update the position // Only update the position
Application.Current?.Dispatcher.Invoke(() => #pragma warning disable VSTHRD103 // Call async methods when in an async method
DispatcherHelper.Invoke(() =>
{ {
(Application.Current?.MainWindow as MainWindow)?.UpdatePosition(); (Application.Current?.MainWindow as MainWindow)?.UpdatePosition();
}); });
#pragma warning restore VSTHRD103 // Call async methods when in an async method
_ = ResetWindowAsync(); _ = ResetWindowAsync();
} }
@ -2049,7 +2050,7 @@ namespace Flow.Launcher.ViewModel
if (_previousMainWindowVisibilityStatus) if (_previousMainWindowVisibilityStatus)
{ {
// Only update the position // Only update the position
Application.Current?.Dispatcher.Invoke(() => DispatcherHelper.Invoke(() =>
{ {
(Application.Current?.MainWindow as MainWindow)?.UpdatePosition(); (Application.Current?.MainWindow as MainWindow)?.UpdatePosition();
}); });
@ -2112,7 +2113,7 @@ namespace Flow.Launcher.ViewModel
if (App.LoadingOrExiting) return; if (App.LoadingOrExiting) return;
// When application is exiting, the Application.Current will be null // When application is exiting, the Application.Current will be null
Application.Current?.Dispatcher.Invoke(() => DispatcherHelper.Invoke(() =>
{ {
// When application is exiting, the Application.Current will be null // When application is exiting, the Application.Current will be null
if (Application.Current?.MainWindow is MainWindow mainWindow) if (Application.Current?.MainWindow is MainWindow mainWindow)
@ -2194,7 +2195,7 @@ namespace Flow.Launcher.ViewModel
} }
// When application is exiting, the Application.Current will be null // When application is exiting, the Application.Current will be null
Application.Current?.Dispatcher.Invoke(() => DispatcherHelper.Invoke(() =>
{ {
// When application is exiting, the Application.Current will be null // When application is exiting, the Application.Current will be null
if (Application.Current?.MainWindow is MainWindow mainWindow) if (Application.Current?.MainWindow is MainWindow mainWindow)
@ -2328,7 +2329,7 @@ namespace Flow.Launcher.ViewModel
public void FocusQueryTextBox() public void FocusQueryTextBox()
{ {
// When application is exiting, the Application.Current will be null // When application is exiting, the Application.Current will be null
Application.Current?.Dispatcher.Invoke(() => DispatcherHelper.Invoke(() =>
{ {
// When application is exiting, the Application.Current will be null // When application is exiting, the Application.Current will be null
if (Application.Current?.MainWindow is MainWindow window) if (Application.Current?.MainWindow is MainWindow window)