Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 5 additions & 4 deletions Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Plugin;

Expand Down Expand Up @@ -99,22 +100,22 @@
{
case TextBox textBox:
var text = value as string ?? string.Empty;
textBox.Dispatcher.Invoke(() => textBox.Text = text);
DispatcherHelper.Invoke(() => textBox.Text = text);
break;
case PasswordBox passwordBox:
var password = value as string ?? string.Empty;
passwordBox.Dispatcher.Invoke(() => passwordBox.Password = password);
DispatcherHelper.Invoke(() => passwordBox.Password = password);
break;
case ComboBox comboBox:
comboBox.Dispatcher.Invoke(() => comboBox.SelectedItem = value);
DispatcherHelper.Invoke(() => comboBox.SelectedItem = value);
break;
case CheckBox checkBox:
var isChecked = value is bool boolValue
? boolValue
// If can parse the default value to bool, use it, otherwise use false
: value is string stringValue && bool.TryParse(stringValue, out var boolValueFromString)
&& boolValueFromString;
checkBox.Dispatcher.Invoke(() => checkBox.IsChecked = isChecked);
DispatcherHelper.Invoke(() => checkBox.IsChecked = isChecked);
break;
}
}
Expand Down Expand Up @@ -422,14 +423,14 @@
}
case "hyperlink":
{
var hyperlink = new Hyperlink

Check warning on line 426 in Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs

View workflow job for this annotation

GitHub Actions / Check Spelling

`hyperlink` is not a recognized word. (unrecognized-spelling)
{
ToolTip = attributes.Description,
NavigateUri = attributes.url
};

hyperlink.Inlines.Add(attributes.urlLabel);

Check warning on line 432 in Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs

View workflow job for this annotation

GitHub Actions / Check Spelling

`hyperlink` is not a recognized word. (unrecognized-spelling)
hyperlink.RequestNavigate += (sender, e) =>

Check warning on line 433 in Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs

View workflow job for this annotation

GitHub Actions / Check Spelling

`hyperlink` is not a recognized word. (unrecognized-spelling)
{
API.OpenUrl(e.Uri);
e.Handled = true;
Expand All @@ -443,7 +444,7 @@
TextAlignment = TextAlignment.Left,
TextWrapping = TextWrapping.Wrap
};
textBlock.Inlines.Add(hyperlink);

Check warning on line 447 in Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs

View workflow job for this annotation

GitHub Actions / Check Spelling

`hyperlink` is not a recognized word. (unrecognized-spelling)

contentControl = textBlock;

Expand Down
102 changes: 102 additions & 0 deletions Flow.Launcher.Core/Resource/DispatcherHelper.cs
Original file line number Diff line number Diff line change
@@ -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;
}
}
}
4 changes: 2 additions & 2 deletions Flow.Launcher.Core/Resource/Theme.cs
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ private void SetResizeBoarderThickness(Thickness? effectMargin)
/// </summary>
public async Task RefreshFrameAsync()
{
await Application.Current.Dispatcher.InvokeAsync(() =>
await DispatcherHelper.InvokeAsync(() =>
{
// Get the actual backdrop type and drop shadow effect settings
var (backdropType, useDropShadowEffect) = GetActualValue();
Expand All @@ -619,7 +619,7 @@ await Application.Current.Dispatcher.InvokeAsync(() =>
/// </summary>
public async Task SetBlurForWindowAsync()
{
await Application.Current.Dispatcher.InvokeAsync(() =>
await DispatcherHelper.InvokeAsync(() =>
{
// Get the actual backdrop type and drop shadow effect settings
var (backdropType, _) = GetActualValue();
Expand Down
6 changes: 3 additions & 3 deletions Flow.Launcher/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ private static void AutoPluginUpdates()
var timer = new PeriodicTimer(TimeSpan.FromHours(5));
await PluginInstaller.CheckForPluginUpdatesAsync((plugins) =>
{
Current.Dispatcher.Invoke(() =>
DispatcherHelper.Invoke(() =>
{
var pluginUpdateWindow = new PluginUpdateWindow(plugins);
pluginUpdateWindow.ShowDialog();
Expand All @@ -345,7 +345,7 @@ await PluginInstaller.CheckForPluginUpdatesAsync((plugins) =>
// check updates on startup
await PluginInstaller.CheckForPluginUpdatesAsync((plugins) =>
{
Current.Dispatcher.Invoke(() =>
DispatcherHelper.Invoke(() =>
{
var pluginUpdateWindow = new PluginUpdateWindow(plugins);
pluginUpdateWindow.ShowDialog();
Expand Down Expand Up @@ -444,7 +444,7 @@ protected virtual void Dispose(bool disposing)
{
// Dispose needs to be called on the main Windows thread,
// since some resources owned by the thread need to be disposed.
_mainWindow?.Dispatcher.Invoke(_mainWindow.Dispose);
DispatcherHelper.Invoke(_mainWindow?.Dispatcher, _mainWindow.Dispose);
_mainVM?.Dispose();
DialogJump.Dispose();
_internationalization.Dispose();
Expand Down
5 changes: 4 additions & 1 deletion Flow.Launcher/Helper/SingleInstance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using Flow.Launcher.Core.Resource;

// http://blogs.microsoft.co.il/arik/2010/05/28/wpf-single-instance-application/
// modified to allow single instace restart
Expand All @@ -24,7 +25,7 @@
/// running as Administrator, can activate it with command line arguments.
/// For most apps, this will not be much of an issue.
/// </remarks>
public static class SingleInstance<TApplication> where TApplication : Application, ISingleInstanceApp

Check warning on line 28 in Flow.Launcher/Helper/SingleInstance.cs

View workflow job for this annotation

GitHub Actions / Check Spelling

`TApplication` is not a recognized word. (unrecognized-spelling)
{
#region Private Fields

Expand Down Expand Up @@ -100,7 +101,9 @@
await pipeServer.WaitForConnectionAsync();

// 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
pipeServer.Disconnect();
Expand Down Expand Up @@ -135,7 +138,7 @@
return;
}

((TApplication)Application.Current).OnSecondAppStarted();

Check warning on line 141 in Flow.Launcher/Helper/SingleInstance.cs

View workflow job for this annotation

GitHub Actions / Check Spelling

`TApplication` is not a recognized word. (unrecognized-spelling)
}

#endregion
Expand Down
10 changes: 5 additions & 5 deletions Flow.Launcher/Helper/WallpaperPathRetrieval.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
using System.IO;
using System.Linq;
using System.Threading;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Infrastructure;
using Microsoft.Win32;

Expand All @@ -22,11 +22,11 @@ public static class WallpaperPathRetrieval
public static Brush GetWallpaperBrush()
{
// Invoke the method on the UI thread
if (!Application.Current.Dispatcher.CheckAccess())
{
return Application.Current.Dispatcher.Invoke(GetWallpaperBrush);
}
return DispatcherHelper.Invoke(GetWallpaperBrushCore);
}

private static Brush GetWallpaperBrushCore()
{
try
{
var wallpaperPath = Win32Helper.GetWallpaperPath();
Expand Down
23 changes: 6 additions & 17 deletions Flow.Launcher/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
using Flow.Launcher.Plugin.SharedCommands;
using Flow.Launcher.Plugin.SharedModels;
using Flow.Launcher.ViewModel;
using iNKORE.UI.WPF.Modern;

Check warning on line 28 in Flow.Launcher/MainWindow.xaml.cs

View workflow job for this annotation

GitHub Actions / Check Spelling

`NKORE` is not a recognized word. (unrecognized-spelling)
using iNKORE.UI.WPF.Modern.Controls;

Check warning on line 29 in Flow.Launcher/MainWindow.xaml.cs

View workflow job for this annotation

GitHub Actions / Check Spelling

`NKORE` is not a recognized word. (unrecognized-spelling)
using DataObject = System.Windows.DataObject;
using Key = System.Windows.Input.Key;
using MouseButtons = System.Windows.Forms.MouseButtons;
Expand Down Expand Up @@ -116,7 +116,7 @@
{
var handle = Win32Helper.GetWindowHandle(this, true);
_hwndSource = HwndSource.FromHwnd(handle);
_hwndSource.AddHook(WndProc);

Check warning on line 119 in Flow.Launcher/MainWindow.xaml.cs

View workflow job for this annotation

GitHub Actions / Check Spelling

`Wnd` is not a recognized word. (unrecognized-spelling)
Win32Helper.HideFromAltTab(this);
Win32Helper.DisableControlBox(this);
}
Expand Down Expand Up @@ -153,7 +153,7 @@
Localize.appUpdateButtonContent(),
() =>
{
Application.Current.Dispatcher.Invoke(() =>
DispatcherHelper.Invoke(() =>
{
var releaseNotesWindow = new ReleaseNotesWindow();
releaseNotesWindow.Show();
Expand Down Expand Up @@ -225,7 +225,7 @@
{
case nameof(MainViewModel.MainWindowVisibilityStatus):
{
Dispatcher.Invoke(() =>
DispatcherHelper.Invoke(() =>
{
if (_viewModel.MainWindowVisibilityStatus)
{
Expand Down Expand Up @@ -269,7 +269,7 @@
{
// 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
Dispatcher.Invoke(() => QueryTextBox.CaretIndex = QueryTextBox.Text.Length);
DispatcherHelper.Invoke(() => QueryTextBox.CaretIndex = QueryTextBox.Text.Length);
_viewModel.QueryTextCursorMovedToEnd = false;
}
break;
Expand Down Expand Up @@ -376,7 +376,7 @@
{
try
{
_hwndSource.RemoveHook(WndProc);

Check warning on line 379 in Flow.Launcher/MainWindow.xaml.cs

View workflow job for this annotation

GitHub Actions / Check Spelling

`Wnd` is not a recognized word. (unrecognized-spelling)
}
catch (Exception)
{
Expand Down Expand Up @@ -542,7 +542,7 @@
// Switch to Normal state
WindowState = WindowState.Normal;

Application.Current?.Dispatcher.Invoke(new Action(() =>
DispatcherHelper.Invoke(() =>
{
double normalWidth = Width;
double normalHeight = Height;
Expand All @@ -555,7 +555,7 @@
{
DragMove();
}
}), DispatcherPriority.ApplicationIdle);
}, DispatcherPriority.ApplicationIdle);
}
else
{
Expand Down Expand Up @@ -726,19 +726,8 @@
{
Win32Helper.RegisterSleepModeListener(() =>
{
if (Application.Current == null)
{
return;
}

// We must run InitSoundEffects on UI thread because MediaPlayer is a DispatcherObject
if (!Application.Current.Dispatcher.CheckAccess())
{
Application.Current.Dispatcher.Invoke(InitSoundEffects);
return;
}

InitSoundEffects();
DispatcherHelper.Invoke(InitSoundEffects);
});
}
catch (Exception e)
Expand Down
14 changes: 10 additions & 4 deletions Flow.Launcher/MessageBoxEx.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Infrastructure;

namespace Flow.Launcher
Expand All @@ -29,11 +30,16 @@ public static MessageBoxResult Show(
MessageBoxImage icon = MessageBoxImage.None,
MessageBoxResult defaultResult = MessageBoxResult.OK)
{
if (!Application.Current.Dispatcher.CheckAccess())
{
return Application.Current.Dispatcher.Invoke(() => Show(messageBoxText, caption, button, icon, defaultResult));
}
return DispatcherHelper.Invoke(() => ShowCore(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
{
msgBox = new MessageBoxEx(button);
Expand Down
5 changes: 3 additions & 2 deletions Flow.Launcher/Msg.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Windows;
using System.Windows.Input;
using System.Windows.Media.Animation;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Plugin.SharedModels;

Expand Down Expand Up @@ -80,12 +81,12 @@ public async void Show(string title, string subTitle, string iconPath)

Show();

await Dispatcher.InvokeAsync(async () =>
await DispatcherHelper.InvokeAsync(async () =>
{
if (!closing)
{
closing = true;
await Dispatcher.InvokeAsync(fadeOutStoryboard.Begin);
fadeOutStoryboard.Begin();
}
});
}
Expand Down
5 changes: 3 additions & 2 deletions Flow.Launcher/MsgWithButton.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Windows;
using System.Windows.Input;
using System.Windows.Media.Animation;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Plugin.SharedModels;

Expand Down Expand Up @@ -82,12 +83,12 @@ public async void Show(string title, string buttonText, Action buttonAction, str

Show();

await Dispatcher.InvokeAsync(async () =>
await DispatcherHelper.InvokeAsync(async () =>
{
if (!closing)
{
closing = true;
await Dispatcher.InvokeAsync(fadeOutStoryboard.Begin);
fadeOutStoryboard.Begin();
}
});
}
Expand Down
6 changes: 3 additions & 3 deletions Flow.Launcher/Notification.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System;
using System.Collections.Concurrent;
using System.IO;
using System.Windows;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Infrastructure;
using Microsoft.Toolkit.Uwp.Notifications;

Expand Down Expand Up @@ -41,7 +41,7 @@ internal static void Uninstall()

public static void Show(string title, string subTitle, string iconPath = null)
{
Application.Current.Dispatcher.Invoke(() =>
DispatcherHelper.Invoke(() =>
{
ShowInternal(title, subTitle, iconPath);
});
Expand Down Expand Up @@ -91,7 +91,7 @@ private static void LegacyShow(string title, string subTitle, string iconPath)

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);
});
Expand Down
Loading
Loading