Merge pull request #3467 from Flow-Launcher/warning_fix_tweak

Fix Dialog Owner & Improve Window Exiting & Improve WindowsThumbnailProvider & Fix Warnings
This commit is contained in:
Jack Ye 2025-04-15 15:09:35 +08:00 committed by GitHub
commit 7d6fceb21b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 68 additions and 124 deletions

View file

@ -171,8 +171,8 @@ namespace Flow.Launcher.Infrastructure.Image
}
catch (System.Exception e2)
{
Log.Exception(ClassName, $"|ImageLoader.Load|Failed to get thumbnail for {path} on first try", e);
Log.Exception(ClassName, $"|ImageLoader.Load|Failed to get thumbnail for {path} on second try", e2);
Log.Exception(ClassName, $"Failed to get thumbnail for {path} on first try", e);
Log.Exception(ClassName, $"Failed to get thumbnail for {path} on second try", e2);
ImageSource image = ImageCache[Constant.MissingImgIcon, false];
ImageCache[path, false] = image;

View file

@ -12,7 +12,7 @@ using Windows.Win32.Graphics.Gdi;
namespace Flow.Launcher.Infrastructure.Image
{
/// <summary>
/// Subclass of <see cref="Windows.Win32.UI.Shell.SIIGBF"/>
/// Subclass of <see cref="SIIGBF"/>
/// </summary>
[Flags]
public enum ThumbnailOptions
@ -31,7 +31,9 @@ namespace Flow.Launcher.Infrastructure.Image
private static readonly Guid GUID_IShellItem = typeof(IShellItem).GUID;
private static readonly HRESULT S_ExtractionFailed = (HRESULT)0x8004B200;
private static readonly HRESULT S_EXTRACTIONFAILED = (HRESULT)0x8004B200;
private static readonly HRESULT S_PATHNOTFOUND = (HRESULT)0x8004B205;
public static BitmapSource GetThumbnail(string fileName, int width, int height, ThumbnailOptions options)
{
@ -79,9 +81,10 @@ namespace Flow.Launcher.Infrastructure.Image
{
imageFactory.GetImage(size, (SIIGBF)options, &hBitmap);
}
catch (COMException ex) when (ex.HResult == S_ExtractionFailed && options == ThumbnailOptions.ThumbnailOnly)
catch (COMException ex) when (options == ThumbnailOptions.ThumbnailOnly &&
(ex.HResult == S_PATHNOTFOUND || ex.HResult == S_EXTRACTIONFAILED))
{
// Fallback to IconOnly if ThumbnailOnly fails
// Fallback to IconOnly if extraction fails or files cannot be found
imageFactory.GetImage(size, (SIIGBF)ThumbnailOptions.IconOnly, &hBitmap);
}
catch (FileNotFoundException) when (options == ThumbnailOptions.ThumbnailOnly)
@ -89,6 +92,11 @@ namespace Flow.Launcher.Infrastructure.Image
// Fallback to IconOnly if files cannot be found
imageFactory.GetImage(size, (SIIGBF)ThumbnailOptions.IconOnly, &hBitmap);
}
catch (System.Exception ex)
{
// Handle other exceptions
throw new InvalidOperationException("Failed to get thumbnail", ex);
}
}
finally
{

View file

@ -59,6 +59,7 @@ namespace Flow.Launcher
Close();
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "<Pending>")]
public async void Show(string title, string subTitle, string iconPath)
{
tbTitle.Text = title;

View file

@ -15,8 +15,6 @@ namespace Flow.Launcher
{
internal partial class ReportWindow
{
private static readonly string ClassName = nameof(ReportWindow);
public ReportWindow(Exception exception)
{
InitializeComponent();

View file

@ -111,11 +111,11 @@ public partial class SettingsPanePluginsViewModel : BaseModel
.ToList();
[RelayCommand]
private async Task OpenHelperAsync()
private async Task OpenHelperAsync(Button button)
{
var helpDialog = new ContentDialog()
{
Owner = Application.Current.MainWindow,
Owner = Window.GetWindow(button),
Content = new StackPanel
{
Children =

View file

@ -57,6 +57,7 @@
Height="34"
Margin="0 0 20 0"
Command="{Binding OpenHelperCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource Self}}"
Content="&#xe9ce;"
FontFamily="{DynamicResource SymbolThemeFontFamily}"
FontSize="14" />

View file

@ -1,8 +1,8 @@
using System.Windows.Navigation;
using System.Windows.Navigation;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.SettingPages.ViewModels;
using Page = ModernWpf.Controls.Page;
using Flow.Launcher.Infrastructure.UserSettings;
using Page = ModernWpf.Controls.Page;
namespace Flow.Launcher.SettingPages.Views;

View file

@ -1,29 +0,0 @@
using System;
using System.Windows.Input;
namespace Flow.Launcher.ViewModel
{
public class RelayCommand : ICommand
{
private readonly Action<object> _action;
public RelayCommand(Action<object> action)
{
_action = action;
}
public virtual bool CanExecute(object parameter)
{
return true;
}
#pragma warning disable CS0067 // the event is never used
public event EventHandler CanExecuteChanged;
#pragma warning restore CS0067
public virtual void Execute(object parameter)
{
_action?.Invoke(parameter);
}
}
}

View file

@ -45,6 +45,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<!-- Do not upgrade System.Data.OleDb since we are .Net7.0 -->
<PackageReference Include="System.Data.OleDb" Version="8.0.1" />
<PackageReference Include="System.Linq.Async" Version="6.0.1" />

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Drawing;
@ -341,7 +341,7 @@ namespace Peter
return null;
}
IShellFolder oParentFolder = GetParentFolder(arrFI[0].Parent.FullName);
IShellFolder oParentFolder = GetParentFolder(arrFI[0].Parent!.FullName);
if (null == oParentFolder)
{
return null;
@ -1535,7 +1535,7 @@ namespace Peter
m_hookType,
m_filterFunc,
IntPtr.Zero,
(int)AppDomain.GetCurrentThreadId());
Environment.CurrentManagedThreadId);
}
// ************************************************************************

View file

@ -16,7 +16,7 @@ public static class SortOptionTranslationHelper
ArgumentNullException.ThrowIfNull(API);
var enumName = Enum.GetName(sortOption);
var splited = enumName.Split('_');
var splited = enumName!.Split('_');
var name = string.Join('_', splited[..^1]);
var direction = splited[^1];

View file

@ -47,7 +47,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
foreach (DictionaryEntry special in Environment.GetEnvironmentVariables())
{
var path = special.Value.ToString();
var path = special.Value!.ToString();
// we add a trailing slash to the path to make sure drive paths become valid absolute paths.
// for example, if %systemdrive% is C: we turn it to C:\
path = path.EnsureTrailingSlash();
@ -61,7 +61,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
{
// Variables are returned with a mixture of all upper/lower case.
// Call ToUpper() to make the results look consistent
_envStringPaths.Add(special.Key.ToString().ToUpper(), path);
_envStringPaths.Add(special.Key.ToString()!.ToUpper(), path);
}
}
}

View file

@ -1,13 +1,15 @@
using System.ComponentModel;
using System.Runtime.CompilerServices;
#nullable enable
namespace Flow.Launcher.Plugin.Explorer.Views
{
public class ActionKeywordModel : INotifyPropertyChanged
{
private static Settings _settings;
private static Settings _settings = null!;
public event PropertyChangedEventHandler PropertyChanged;
public event PropertyChangedEventHandler? PropertyChanged;
public static void Init(Settings settings)
{
@ -54,4 +56,4 @@ namespace Flow.Launcher.Plugin.Explorer.Views
}
}
}
}
}

View file

@ -1,27 +0,0 @@
using System;
using System.Windows.Input;
namespace Flow.Launcher.Plugin.Explorer.ViewModels
{
internal class RelayCommand : ICommand
{
private Action<object> _action;
public RelayCommand(Action<object> action)
{
_action = action;
}
public virtual bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public virtual void Execute(object parameter)
{
_action?.Invoke(parameter);
}
}
}

View file

@ -1,9 +1,4 @@
#nullable enable
using Flow.Launcher.Plugin.Explorer.Search;
using Flow.Launcher.Plugin.Explorer.Search.Everything;
using Flow.Launcher.Plugin.Explorer.Search.Everything.Exceptions;
using Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks;
using Flow.Launcher.Plugin.Explorer.Views;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@ -13,11 +8,16 @@ using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Input;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Plugin.Explorer.Search;
using Flow.Launcher.Plugin.Explorer.Search.Everything;
using Flow.Launcher.Plugin.Explorer.Search.Everything.Exceptions;
using Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks;
using Flow.Launcher.Plugin.Explorer.Views;
namespace Flow.Launcher.Plugin.Explorer.ViewModels
{
public class SettingsViewModel : BaseModel
public partial class SettingsViewModel : BaseModel
{
public Settings Settings { get; set; }
@ -36,7 +36,6 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
InitializeActionKeywordModels();
}
public void Save()
{
Context.API.SaveSettingJsonStorage<Settings>();
@ -48,7 +47,6 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
private EnumBindingModel<Settings.ContentIndexSearchEngineOption> _selectedContentSearchEngine;
private EnumBindingModel<Settings.PathEnumerationEngineOption> _selectedPathEnumerationEngine;
public EnumBindingModel<Settings.IndexSearchEngineOption> SelectedIndexSearchEngine
{
get => _selectedIndexSearchEngine;
@ -261,8 +259,7 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
public ActionKeywordModel? SelectedActionKeyword { get; set; }
public ICommand EditActionKeywordCommand => new RelayCommand(EditActionKeyword);
[RelayCommand]
private void EditActionKeyword(object obj)
{
if (SelectedActionKeyword is not { } actionKeyword)
@ -307,12 +304,6 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
public AccessLink? SelectedQuickAccessLink { get; set; }
public AccessLink? SelectedIndexSearchExcludedPath { get; set; }
public ICommand RemoveLinkCommand => new RelayCommand(RemoveLink);
public ICommand EditLinkCommand => new RelayCommand(EditLink);
public ICommand AddLinkCommand => new RelayCommand(AddLink);
public void AppendLink(string containerName, AccessLink link)
{
var container = containerName switch
@ -324,6 +315,7 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
container.Add(link);
}
[RelayCommand]
private void EditLink(object commandParameter)
{
var (selectedLink, collection) = commandParameter switch
@ -360,7 +352,7 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
Context.API.ShowMsgBox(warning);
}
[RelayCommand]
private void AddLink(object commandParameter)
{
var container = commandParameter switch
@ -385,6 +377,7 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
container.Add(newAccessLink);
}
[RelayCommand]
private void RemoveLink(object obj)
{
if (obj is not string container) return;
@ -435,7 +428,6 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
return path;
}
internal static void OpenWindowsIndexingOptions()
{
var psi = new ProcessStartInfo
@ -448,39 +440,35 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
Process.Start(psi);
}
private ICommand? _openFileEditorPathCommand;
public ICommand OpenFileEditorPath => _openFileEditorPathCommand ??= new RelayCommand(_ =>
[RelayCommand]
private void OpenFileEditorPath()
{
var path = PromptUserSelectPath(ResultType.File, Settings.EditorPath != null ? Path.GetDirectoryName(Settings.EditorPath) : null);
if (path is null)
return;
FileEditorPath = path;
});
}
private ICommand? _openFolderEditorPathCommand;
public ICommand OpenFolderEditorPath => _openFolderEditorPathCommand ??= new RelayCommand(_ =>
[RelayCommand]
private void OpenFolderEditorPath()
{
var path = PromptUserSelectPath(ResultType.File, Settings.FolderEditorPath != null ? Path.GetDirectoryName(Settings.FolderEditorPath) : null);
if (path is null)
return;
FolderEditorPath = path;
});
}
private ICommand? _openShellPathCommand;
public ICommand OpenShellPath => _openShellPathCommand ??= new RelayCommand(_ =>
[RelayCommand]
private void OpenShellPath()
{
var path = PromptUserSelectPath(ResultType.File, Settings.EditorPath != null ? Path.GetDirectoryName(Settings.EditorPath) : null);
if (path is null)
return;
ShellPath = path;
});
}
public string FileEditorPath
{
@ -537,7 +525,6 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
}
}
#region Everything FastSortWarning
public Visibility FastSortWarningVisibility
@ -593,7 +580,5 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
}
#endregion
}
}

View file

@ -85,6 +85,7 @@ namespace Flow.Launcher.Plugin.Explorer.Views
DialogResult = false;
Close();
}
private void TxtCurrentActionKeyword_OnKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
@ -94,11 +95,13 @@ namespace Flow.Launcher.Plugin.Explorer.Views
e.Handled = true;
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(field, value))

View file

@ -245,7 +245,7 @@
Margin="{StaticResource SettingPanelItemLeftMargin}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Command="{Binding OpenFileEditorPath}"
Command="{Binding OpenFileEditorPathCommand}"
Content="{DynamicResource select}" />
</StackPanel>
@ -272,7 +272,7 @@
Margin="{StaticResource SettingPanelItemLeftMargin}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Command="{Binding OpenFolderEditorPath}"
Command="{Binding OpenFolderEditorPathCommand}"
Content="{DynamicResource select}" />
</StackPanel>
@ -299,7 +299,7 @@
Margin="{StaticResource SettingPanelItemLeftMargin}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Command="{Binding OpenShellPath}"
Command="{Binding OpenShellPathCommand}"
Content="{DynamicResource select}" />
</StackPanel>

View file

@ -1,11 +1,10 @@
using Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks;
using Flow.Launcher.Plugin.Explorer.ViewModels;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks;
using Flow.Launcher.Plugin.Explorer.ViewModels;
using DataFormats = System.Windows.DataFormats;
using DragDropEffects = System.Windows.DragDropEffects;
using DragEventArgs = System.Windows.DragEventArgs;
@ -19,9 +18,6 @@ namespace Flow.Launcher.Plugin.Explorer.Views
{
private readonly SettingsViewModel viewModel;
private List<ActionKeywordModel> actionKeywordsListView;
public ExplorerSettings(SettingsViewModel viewModel)
{
DataContext = viewModel;
@ -39,8 +35,6 @@ namespace Flow.Launcher.Plugin.Explorer.Views
lbxExcludedPaths.Items.SortDescriptions.Add(new SortDescription("Path", ListSortDirection.Ascending));
}
private void AccessLinkDragDrop(string containerName, DragEventArgs e)
{
var files = (string[])e.Data.GetData(DataFormats.FileDrop);

View file

@ -146,6 +146,7 @@ namespace Flow.Launcher.Plugin.Program.Views
programSourceView.Items.Refresh();
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "<Pending>")]
private async void ReIndexing()
{
ViewRefresh();
@ -183,6 +184,7 @@ namespace Flow.Launcher.Plugin.Program.Views
EditProgramSource(selectedProgramSource);
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "<Pending>")]
private async void EditProgramSource(ProgramSource selectedProgramSource)
{
if (selectedProgramSource == null)
@ -277,6 +279,7 @@ namespace Flow.Launcher.Plugin.Program.Views
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "<Pending>")]
private async void btnLoadAllProgramSource_OnClick(object sender, RoutedEventArgs e)
{
await ProgramSettingDisplay.DisplayAllProgramsAsync();
@ -284,6 +287,7 @@ namespace Flow.Launcher.Plugin.Program.Views
ViewRefresh();
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "<Pending>")]
private async void btnProgramSourceStatus_OnClick(object sender, RoutedEventArgs e)
{
var selectedItems = programSourceView

View file

@ -362,6 +362,7 @@ namespace Flow.Launcher.Plugin.Sys
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe89f"),
Action = c =>
{
_context.API.HideMainWindow();
Application.Current.MainWindow.Close();
return true;
}

View file

@ -28,6 +28,7 @@ namespace Flow.Launcher.Plugin.WebSearch
Initialize(sources, context, Action.Add);
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "<Pending>")]
private async void Initialize(IList<SearchSource> sources, PluginInitContext context, Action action)
{
InitializeComponent();
@ -124,6 +125,7 @@ namespace Flow.Launcher.Plugin.WebSearch
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "<Pending>")]
private async void OnSelectIconClick(object sender, RoutedEventArgs e)
{
const string filter = "Image files (*.jpg, *.jpeg, *.gif, *.png, *.bmp) |*.jpg; *.jpeg; *.gif; *.png; *.bmp";