From 65378200c6c18d6d633afae602d9536774c8af9c Mon Sep 17 00:00:00 2001 From: Jaime Bernardo Date: Mon, 6 Mar 2023 22:57:52 +0000 Subject: [PATCH] [PTRun]Add setting to disable thumbnails (#24600) --- .../launcher/PowerLauncher/SettingsReader.cs | 5 +++ .../ViewModel/ResultViewModel.cs | 9 ++++-- .../ViewModel/ResultsViewModel.cs | 2 +- .../Wox.Infrastructure/Image/ImageLoader.cs | 32 ++++++++++++------- .../UserSettings/PowerToysRunSettings.cs | 2 ++ .../launcher/Wox.Test/ResultViewModelTest.cs | 2 +- .../launcher/Wox.Test/ResultsViewModelTest.cs | 14 ++++---- .../PowerLauncherProperties.cs | 4 +++ .../PowerLauncherViewModelTest.cs | 1 + .../Settings.UI/Strings/en-us/Resources.resw | 6 ++++ .../ViewModels/PowerLauncherViewModel.cs | 17 ++++++++++ .../Settings.UI/Views/PowerLauncherPage.xaml | 8 +++++ 12 files changed, 80 insertions(+), 22 deletions(-) diff --git a/src/modules/launcher/PowerLauncher/SettingsReader.cs b/src/modules/launcher/PowerLauncher/SettingsReader.cs index c3d3f3bbb93..e470f85749a 100644 --- a/src/modules/launcher/PowerLauncher/SettingsReader.cs +++ b/src/modules/launcher/PowerLauncher/SettingsReader.cs @@ -166,6 +166,11 @@ public void ReadSettings() _settings.StartupPosition = overloadSettings.Properties.Position; } + if (_settings.GenerateThumbnailsFromFiles != overloadSettings.Properties.GenerateThumbnailsFromFiles) + { + _settings.GenerateThumbnailsFromFiles = overloadSettings.Properties.GenerateThumbnailsFromFiles; + } + retry = false; } diff --git a/src/modules/launcher/PowerLauncher/ViewModel/ResultViewModel.cs b/src/modules/launcher/PowerLauncher/ViewModel/ResultViewModel.cs index 6d58d629217..768dcdbe973 100644 --- a/src/modules/launcher/PowerLauncher/ViewModel/ResultViewModel.cs +++ b/src/modules/launcher/PowerLauncher/ViewModel/ResultViewModel.cs @@ -10,6 +10,7 @@ using PowerLauncher.Helper; using PowerLauncher.Plugin; using Wox.Infrastructure.Image; +using Wox.Infrastructure.UserSettings; using Wox.Plugin; using Wox.Plugin.Logger; @@ -23,6 +24,8 @@ public enum ActivationType Hover, } + private readonly PowerToysRunSettings _settings; + public ObservableCollection ContextMenuItems { get; } = new ObservableCollection(); public ICommand ActivateContextButtonsHoverCommand { get; } @@ -65,13 +68,15 @@ public int ContextMenuSelectedIndex public const int NoSelectionIndex = -1; - public ResultViewModel(Result result, IMainViewModel mainViewModel) + public ResultViewModel(Result result, IMainViewModel mainViewModel, PowerToysRunSettings settings) { if (result != null) { Result = result; } + _settings = settings; + ContextMenuSelectedIndex = NoSelectionIndex; LoadContextMenu(); @@ -201,7 +206,7 @@ public ImageSource Image } // will get here either when icoPath has value\icon delegate is null\when had exception in delegate - return ImageLoader.Load(imagePath); + return ImageLoader.Load(imagePath, _settings.GenerateThumbnailsFromFiles); } } diff --git a/src/modules/launcher/PowerLauncher/ViewModel/ResultsViewModel.cs b/src/modules/launcher/PowerLauncher/ViewModel/ResultsViewModel.cs index 825d8a54864..ef7c300976a 100644 --- a/src/modules/launcher/PowerLauncher/ViewModel/ResultsViewModel.cs +++ b/src/modules/launcher/PowerLauncher/ViewModel/ResultsViewModel.cs @@ -272,7 +272,7 @@ public void AddResults(List newRawResults, CancellationToken ct) List newResults = new List(newRawResults.Count); foreach (Result r in newRawResults) { - newResults.Add(new ResultViewModel(r, _mainViewModel)); + newResults.Add(new ResultViewModel(r, _mainViewModel, _settings)); ct.ThrowIfCancellationRequested(); } diff --git a/src/modules/launcher/Wox.Infrastructure/Image/ImageLoader.cs b/src/modules/launcher/Wox.Infrastructure/Image/ImageLoader.cs index ef30ab672de..a52baf3c2c6 100644 --- a/src/modules/launcher/Wox.Infrastructure/Image/ImageLoader.cs +++ b/src/modules/launcher/Wox.Infrastructure/Image/ImageLoader.cs @@ -12,6 +12,7 @@ using System.Windows.Media; using System.Windows.Media.Imaging; using ManagedCommon; +using Wox.Infrastructure.UserSettings; using Wox.Plugin; using Wox.Plugin.Logger; @@ -67,7 +68,7 @@ public static void Initialize(Theme theme) { ImageCache.Usage.AsParallel().ForAll(x => { - Load(x.Key); + Load(x.Key, true); }); }); @@ -119,7 +120,7 @@ private enum ImageType Cache, } - private static ImageResult LoadInternal(string path, bool loadFullImage = false) + private static ImageResult LoadInternal(string path, bool generateThumbnailsFromFiles, bool loadFullImage = false) { ImageSource image; ImageType type = ImageType.Error; @@ -172,18 +173,27 @@ private static ImageResult LoadInternal(string path, bool loadFullImage = false) } else { - /* Although the documentation for GetImage on MSDN indicates that - * if a thumbnail is available it will return one, this has proved to not - * be the case in many situations while testing. - * - Solution: explicitly pass the ThumbnailOnly flag - */ - image = WindowsThumbnailProvider.GetThumbnail(path, Constant.ThumbnailSize, Constant.ThumbnailSize, ThumbnailOptions.ThumbnailOnly); + // PowerToys Run internal images are png, so we make this exception + if (extension == ".png" || generateThumbnailsFromFiles) + { + /* Although the documentation for GetImage on MSDN indicates that + * if a thumbnail is available it will return one, this has proved to not + * be the case in many situations while testing. + * - Solution: explicitly pass the ThumbnailOnly flag + */ + image = WindowsThumbnailProvider.GetThumbnail(path, Constant.ThumbnailSize, Constant.ThumbnailSize, ThumbnailOptions.ThumbnailOnly); + } + else + { + image = WindowsThumbnailProvider.GetThumbnail(path, Constant.ThumbnailSize, Constant.ThumbnailSize, ThumbnailOptions.IconOnly); + } } } - else if (extension == ".pdf" && WindowsThumbnailProvider.DoesPdfUseAcrobatAsProvider()) + else if (!generateThumbnailsFromFiles || (extension == ".pdf" && WindowsThumbnailProvider.DoesPdfUseAcrobatAsProvider())) { // The PDF thumbnail provider from Adobe Reader and Acrobat Pro lets crash PT Run with an Dispatcher exception. (https://github.com/microsoft/PowerToys/issues/18166) // To not run into the crash, we only request the icon of PDF files if the PDF thumbnail handler is set to Adobe Reader/Acrobat Pro. + // Also don't get thumbnail if the GenerateThumbnailsFromFiles option is off. type = ImageType.File; image = WindowsThumbnailProvider.GetThumbnail(path, Constant.ThumbnailSize, Constant.ThumbnailSize, ThumbnailOptions.IconOnly); } @@ -217,9 +227,9 @@ private static ImageResult LoadInternal(string path, bool loadFullImage = false) private const bool _enableImageHash = true; - public static ImageSource Load(string path, bool loadFullImage = false) + public static ImageSource Load(string path, bool generateThumbnailsFromFiles, bool loadFullImage = false) { - var imageResult = LoadInternal(path, loadFullImage); + var imageResult = LoadInternal(path, generateThumbnailsFromFiles, loadFullImage); var img = imageResult.ImageSource; if (imageResult.ImageType != ImageType.Error && imageResult.ImageType != ImageType.Cache) diff --git a/src/modules/launcher/Wox.Infrastructure/UserSettings/PowerToysRunSettings.cs b/src/modules/launcher/Wox.Infrastructure/UserSettings/PowerToysRunSettings.cs index 46d44822c8f..173de229bbe 100644 --- a/src/modules/launcher/Wox.Infrastructure/UserSettings/PowerToysRunSettings.cs +++ b/src/modules/launcher/Wox.Infrastructure/UserSettings/PowerToysRunSettings.cs @@ -323,6 +323,8 @@ public bool HideNotifyIcon public bool StartedFromPowerToysRunner { get; set; } + public bool GenerateThumbnailsFromFiles { get; set; } = true; + public HttpProxy Proxy { get; set; } = new HttpProxy(); [JsonConverter(typeof(JsonStringEnumConverter))] diff --git a/src/modules/launcher/Wox.Test/ResultViewModelTest.cs b/src/modules/launcher/Wox.Test/ResultViewModelTest.cs index 5ce400fcc69..42b58c71515 100644 --- a/src/modules/launcher/Wox.Test/ResultViewModelTest.cs +++ b/src/modules/launcher/Wox.Test/ResultViewModelTest.cs @@ -26,7 +26,7 @@ public void Setup() var result = new Result(); contextMenuResult = new ContextMenuResult(); mainViewModelMock = new Mock(); - resultViewModel = new ResultViewModel(result, mainViewModelMock.Object); + resultViewModel = new ResultViewModel(result, mainViewModelMock.Object, null); var pluginMock = new Mock(); pluginMock.As().Setup(x => x.LoadContextMenus(result)).Returns(new List { contextMenuResult }); diff --git a/src/modules/launcher/Wox.Test/ResultsViewModelTest.cs b/src/modules/launcher/Wox.Test/ResultsViewModelTest.cs index c458b56b18c..5ac53ba3b17 100644 --- a/src/modules/launcher/Wox.Test/ResultsViewModelTest.cs +++ b/src/modules/launcher/Wox.Test/ResultsViewModelTest.cs @@ -18,7 +18,7 @@ public void ContextMenuSelectedIndexShouldEqualNoSelectionIndexWhenInitialized() // Arrange ResultsViewModel rvm = new ResultsViewModel(); Result result = new Result(); - ResultViewModel selectedItem = new ResultViewModel(result, null); + ResultViewModel selectedItem = new ResultViewModel(result, null, null); selectedItem.ContextMenuItems.Add(new ContextMenuItemViewModel(null, null, null, null, Key.None, ModifierKeys.None, null)); rvm.SelectedItem = selectedItem; @@ -32,7 +32,7 @@ public void SelectNextContextMenuItemIncrementsContextMenuSelectedIndexWhenCalle // Arrange ResultsViewModel rvm = new ResultsViewModel(); Result result = new Result(); - ResultViewModel selectedItem = new ResultViewModel(result, null); + ResultViewModel selectedItem = new ResultViewModel(result, null, null); selectedItem.ContextMenuItems.Add(new ContextMenuItemViewModel(null, null, null, null, Key.None, ModifierKeys.None, null)); rvm.SelectedItem = selectedItem; @@ -49,7 +49,7 @@ public void SelectNextContextMenuItemDoesnNotIncrementContextMenuSelectedIndexWh // Arrange ResultsViewModel rvm = new ResultsViewModel(); Result result = new Result(); - ResultViewModel selectedItem = new ResultViewModel(result, null); + ResultViewModel selectedItem = new ResultViewModel(result, null, null); selectedItem.ContextMenuItems.Add(new ContextMenuItemViewModel(null, null, null, null, Key.None, ModifierKeys.None, null)); rvm.SelectedItem = selectedItem; @@ -66,7 +66,7 @@ public void SelectPreviousContextMenuItemDecrementsContextMenuSelectedIndexWhenC // Arrange ResultsViewModel rvm = new ResultsViewModel(); Result result = new Result(); - ResultViewModel selectedItem = new ResultViewModel(result, null); + ResultViewModel selectedItem = new ResultViewModel(result, null, null); selectedItem.ContextMenuItems.Add(new ContextMenuItemViewModel(null, null, null, null, Key.None, ModifierKeys.None, null)); selectedItem.ContextMenuItems.Add(new ContextMenuItemViewModel(null, null, null, null, Key.None, ModifierKeys.None, null)); selectedItem.ContextMenuItems.Add(new ContextMenuItemViewModel(null, null, null, null, Key.None, ModifierKeys.None, null)); @@ -88,7 +88,7 @@ public void SelectPreviousContextMenuItemResetsContextMenuSelectedIndexWhenCalle // Arrange ResultsViewModel rvm = new ResultsViewModel(); Result result = new Result(); - ResultViewModel selectedItem = new ResultViewModel(result, null); + ResultViewModel selectedItem = new ResultViewModel(result, null, null); selectedItem.ContextMenuItems.Add(new ContextMenuItemViewModel(null, null, null, null, Key.None, ModifierKeys.None, null)); rvm.SelectedItem = selectedItem; @@ -106,7 +106,7 @@ public void IsContextMenuItemSelectedReturnsTrueWhenContextMenuItemIsSelected() // Arrange ResultsViewModel rvm = new ResultsViewModel(); Result result = new Result(); - ResultViewModel selectedItem = new ResultViewModel(result, null); + ResultViewModel selectedItem = new ResultViewModel(result, null, null); selectedItem.ContextMenuItems.Add(new ContextMenuItemViewModel(null, null, null, null, Key.None, ModifierKeys.None, null)); rvm.SelectedItem = selectedItem; @@ -124,7 +124,7 @@ public void IsContextMenuItemSelectedReturnsFalseWhenContextMenuItemIsNotSelecte // Arrange ResultsViewModel rvm = new ResultsViewModel(); Result result = new Result(); - ResultViewModel selectedItem = new ResultViewModel(result, null); + ResultViewModel selectedItem = new ResultViewModel(result, null, null); selectedItem.ContextMenuItems.Add(new ContextMenuItemViewModel(null, null, null, null, Key.None, ModifierKeys.None, null)); rvm.SelectedItem = selectedItem; diff --git a/src/settings-ui/Settings.UI.Library/PowerLauncherProperties.cs b/src/settings-ui/Settings.UI.Library/PowerLauncherProperties.cs index c0720c65a09..d495203e4e2 100644 --- a/src/settings-ui/Settings.UI.Library/PowerLauncherProperties.cs +++ b/src/settings-ui/Settings.UI.Library/PowerLauncherProperties.cs @@ -72,6 +72,9 @@ public class PowerLauncherProperties [JsonPropertyName("search_wait_for_slow_results")] public bool SearchWaitForSlowResults { get; set; } + [JsonPropertyName("generate_thumbnails_from_files")] + public bool GenerateThumbnailsFromFiles { get; set; } + public PowerLauncherProperties() { OpenPowerLauncher = new HotkeySettings(false, false, true, false, 32); @@ -92,6 +95,7 @@ public PowerLauncherProperties() SearchClickedItemWeight = 5; SearchQueryTuningEnabled = false; SearchWaitForSlowResults = false; + GenerateThumbnailsFromFiles = true; } } } diff --git a/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/PowerLauncherViewModelTest.cs b/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/PowerLauncherViewModelTest.cs index 20f809ac6bd..1c5c0537d82 100644 --- a/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/PowerLauncherViewModelTest.cs +++ b/src/settings-ui/Settings.UI.UnitTests/ViewModelTests/PowerLauncherViewModelTest.cs @@ -80,6 +80,7 @@ public void OriginalFilesModificationTest(string version, string fileName) Assert.AreEqual(originalSettings.Properties.OverrideWinkeyS, viewModel.OverrideWinSKey); Assert.AreEqual(originalSettings.Properties.SearchResultPreference, viewModel.SearchResultPreference); Assert.AreEqual(originalSettings.Properties.SearchTypePreference, viewModel.SearchTypePreference); + Assert.AreEqual(originalSettings.Properties.GenerateThumbnailsFromFiles, viewModel.GenerateThumbnailsFromFiles); // Verify that the stub file was used var expectedCallCount = 2; // once via the view model, and once by the test (GetSettings) diff --git a/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw b/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw index 59d42142643..8740403ac7a 100644 --- a/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw +++ b/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw @@ -499,6 +499,12 @@ Pressing tab will first select through the available context buttons of the current selection before moving onto the next result + + Generate thumbnails from files + + + Results will try to generate thumbnails for files. Disabling this setting may increase stability and speed + Input Smoothing This is about adding a delay to wait for more input before executing a search diff --git a/src/settings-ui/Settings.UI/ViewModels/PowerLauncherViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/PowerLauncherViewModel.cs index fcc08dc904a..997c26921a1 100644 --- a/src/settings-ui/Settings.UI/ViewModels/PowerLauncherViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/PowerLauncherViewModel.cs @@ -563,6 +563,23 @@ public bool TabSelectsContextButtons } } + public bool GenerateThumbnailsFromFiles + { + get + { + return settings.Properties.GenerateThumbnailsFromFiles; + } + + set + { + if (settings.Properties.GenerateThumbnailsFromFiles != value) + { + settings.Properties.GenerateThumbnailsFromFiles = value; + UpdateSettings(); + } + } + } + private ObservableCollection _plugins; public ObservableCollection Plugins diff --git a/src/settings-ui/Settings.UI/Views/PowerLauncherPage.xaml b/src/settings-ui/Settings.UI/Views/PowerLauncherPage.xaml index c2e06861872..cf7e9451e4f 100644 --- a/src/settings-ui/Settings.UI/Views/PowerLauncherPage.xaml +++ b/src/settings-ui/Settings.UI/Views/PowerLauncherPage.xaml @@ -185,6 +185,14 @@ IsOn="{x:Bind ViewModel.TabSelectsContextButtons, Mode=TwoWay}" /> + + + +