From 460f2429671044e8a4cf89131b4f3b660580407a Mon Sep 17 00:00:00 2001 From: Henrik Lau Eriksson Date: Tue, 25 Oct 2022 23:27:18 +0200 Subject: [PATCH] [PTRun] Fix always show after executing context menu result (#21291) * fix always show * add tests * remove workaround --- .../Components/ContextMenuHelper.cs | 10 +-- .../Components/Window.cs | 7 +- .../PowerLauncher/ViewModel/IMainViewModel.cs | 11 +++ .../PowerLauncher/ViewModel/MainViewModel.cs | 8 +-- .../ViewModel/ResultViewModel.cs | 8 ++- .../ViewModel/ResultsViewModel.cs | 6 +- .../launcher/Wox.Plugin/ContextMenuResult.cs | 3 +- .../launcher/Wox.Test/ResultViewModelTest.cs | 71 +++++++++++++++++++ .../launcher/Wox.Test/ResultsViewModelTest.cs | 14 ++-- src/modules/launcher/Wox.Test/Wox.Test.csproj | 5 ++ 10 files changed, 111 insertions(+), 32 deletions(-) create mode 100644 src/modules/launcher/PowerLauncher/ViewModel/IMainViewModel.cs create mode 100644 src/modules/launcher/Wox.Test/ResultViewModelTest.cs diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/ContextMenuHelper.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/ContextMenuHelper.cs index 68caeca976..07c9afce46 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/ContextMenuHelper.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/ContextMenuHelper.cs @@ -42,9 +42,7 @@ namespace Microsoft.Plugin.WindowWalker.Components return false; } - // As a workaround to close PT Run after executing the context menu command, we switch to the window before closing it (Issue #16601). - // We use the setting OpenAfterKillAndClose to detect if we have to switch. - windowData.CloseThisWindow(!WindowWalkerSettings.Instance.OpenAfterKillAndClose); + windowData.CloseThisWindow(); return !WindowWalkerSettings.Instance.OpenAfterKillAndClose; }, @@ -102,12 +100,6 @@ namespace Microsoft.Plugin.WindowWalker.Components } } - // As a workaround to close PT Run before executing the command, we switch to the window before killing it's process - if (!WindowWalkerSettings.Instance.OpenAfterKillAndClose) - { - window.SwitchToWindow(); - } - // Kill process window.Process.KillThisProcess(WindowWalkerSettings.Instance.KillProcessTree); return !WindowWalkerSettings.Instance.OpenAfterKillAndClose; diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/Window.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/Window.cs index 473509a323..8fd3c129b9 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/Window.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/Window.cs @@ -237,13 +237,8 @@ namespace Microsoft.Plugin.WindowWalker.Components /// /// Closes the window /// - internal void CloseThisWindow(bool switchBeforeClose) + internal void CloseThisWindow() { - if (switchBeforeClose) - { - SwitchToWindow(); - } - _ = NativeMethods.SendMessage(Hwnd, Win32Constants.WM_SYSCOMMAND, Win32Constants.SC_CLOSE); } diff --git a/src/modules/launcher/PowerLauncher/ViewModel/IMainViewModel.cs b/src/modules/launcher/PowerLauncher/ViewModel/IMainViewModel.cs new file mode 100644 index 0000000000..40d4e53b40 --- /dev/null +++ b/src/modules/launcher/PowerLauncher/ViewModel/IMainViewModel.cs @@ -0,0 +1,11 @@ +// 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. + +namespace PowerLauncher.ViewModel +{ + public interface IMainViewModel + { + void Hide(); + } +} diff --git a/src/modules/launcher/PowerLauncher/ViewModel/MainViewModel.cs b/src/modules/launcher/PowerLauncher/ViewModel/MainViewModel.cs index 96bafc697f..3b5a59d71e 100644 --- a/src/modules/launcher/PowerLauncher/ViewModel/MainViewModel.cs +++ b/src/modules/launcher/PowerLauncher/ViewModel/MainViewModel.cs @@ -29,7 +29,7 @@ using Wox.Plugin.Logger; namespace PowerLauncher.ViewModel { [System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1309:Use ordinal string comparison", Justification = "Using CurrentCultureIgnoreCase for user facing strings. Each usage is attributed with a comment.")] - public class MainViewModel : BaseModel, ISavable, IDisposable + public class MainViewModel : BaseModel, IMainViewModel, ISavable, IDisposable { private string _currentQuery; private static string _emptyQuery = string.Empty; @@ -75,9 +75,9 @@ namespace PowerLauncher.ViewModel _history = _historyItemsStorage.Load(); _userSelectedRecord = _userSelectedRecordStorage.Load(); - ContextMenu = new ResultsViewModel(_settings); - Results = new ResultsViewModel(_settings); - History = new ResultsViewModel(_settings); + ContextMenu = new ResultsViewModel(_settings, this); + Results = new ResultsViewModel(_settings, this); + History = new ResultsViewModel(_settings, this); _selectedResults = Results; InitializeKeyCommands(); diff --git a/src/modules/launcher/PowerLauncher/ViewModel/ResultViewModel.cs b/src/modules/launcher/PowerLauncher/ViewModel/ResultViewModel.cs index fb524e77c9..6d58d62921 100644 --- a/src/modules/launcher/PowerLauncher/ViewModel/ResultViewModel.cs +++ b/src/modules/launcher/PowerLauncher/ViewModel/ResultViewModel.cs @@ -65,7 +65,7 @@ namespace PowerLauncher.ViewModel public const int NoSelectionIndex = -1; - public ResultViewModel(Result result) + public ResultViewModel(Result result, IMainViewModel mainViewModel) { if (result != null) { @@ -77,6 +77,7 @@ namespace PowerLauncher.ViewModel ActivateContextButtonsHoverCommand = new RelayCommand(ActivateContextButtonsHoverAction); DeactivateContextButtonsHoverCommand = new RelayCommand(DeactivateContextButtonsHoverAction); + MainViewModel = mainViewModel; } private void ActivateContextButtonsHoverAction(object sender) @@ -159,8 +160,7 @@ namespace PowerLauncher.ViewModel if (hideWindow) { - // TODO - Do we hide the window - // MainWindowVisibility = Visibility.Collapsed; + MainViewModel.Hide(); } }))); } @@ -258,6 +258,8 @@ namespace PowerLauncher.ViewModel public Result Result { get; } + public IMainViewModel MainViewModel { get; } + public override bool Equals(object obj) { var r = obj as ResultViewModel; diff --git a/src/modules/launcher/PowerLauncher/ViewModel/ResultsViewModel.cs b/src/modules/launcher/PowerLauncher/ViewModel/ResultsViewModel.cs index 70eb067d5c..6173d242df 100644 --- a/src/modules/launcher/PowerLauncher/ViewModel/ResultsViewModel.cs +++ b/src/modules/launcher/PowerLauncher/ViewModel/ResultsViewModel.cs @@ -21,6 +21,7 @@ namespace PowerLauncher.ViewModel private readonly object _collectionLock = new object(); private readonly PowerToysRunSettings _settings; + private readonly IMainViewModel _mainViewModel; public ResultsViewModel() { @@ -28,10 +29,11 @@ namespace PowerLauncher.ViewModel BindingOperations.EnableCollectionSynchronization(Results, _collectionLock); } - public ResultsViewModel(PowerToysRunSettings settings) + public ResultsViewModel(PowerToysRunSettings settings, IMainViewModel mainViewModel) : this() { _settings = settings ?? throw new ArgumentNullException(nameof(settings)); + _mainViewModel = mainViewModel; _settings.PropertyChanged += (s, e) => { if (e.PropertyName == nameof(_settings.MaxResultsToShow)) @@ -246,7 +248,7 @@ namespace PowerLauncher.ViewModel List newResults = new List(newRawResults.Count); foreach (Result r in newRawResults) { - newResults.Add(new ResultViewModel(r)); + newResults.Add(new ResultViewModel(r, _mainViewModel)); ct.ThrowIfCancellationRequested(); } diff --git a/src/modules/launcher/Wox.Plugin/ContextMenuResult.cs b/src/modules/launcher/Wox.Plugin/ContextMenuResult.cs index 07528692c7..ddff651f50 100644 --- a/src/modules/launcher/Wox.Plugin/ContextMenuResult.cs +++ b/src/modules/launcher/Wox.Plugin/ContextMenuResult.cs @@ -22,7 +22,8 @@ namespace Wox.Plugin public ModifierKeys AcceleratorModifiers { get; set; } /// - /// Gets or sets return true to hide wox after select result + /// Gets or sets the context menu result action. + /// Return true to hide PowerToys Run after the context menu result has been selected. /// public Func Action { get; set; } diff --git a/src/modules/launcher/Wox.Test/ResultViewModelTest.cs b/src/modules/launcher/Wox.Test/ResultViewModelTest.cs new file mode 100644 index 0000000000..5ce400fcc6 --- /dev/null +++ b/src/modules/launcher/Wox.Test/ResultViewModelTest.cs @@ -0,0 +1,71 @@ +// 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.Collections.Generic; +using System.Linq; +using Microsoft.PowerToys.STATestExtension; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; +using PowerLauncher.Plugin; +using PowerLauncher.ViewModel; +using Wox.Plugin; + +namespace Wox.Test +{ + [STATestClass] + public class ResultViewModelTest + { + private ContextMenuResult contextMenuResult; + private Mock mainViewModelMock; + private ResultViewModel resultViewModel; + + [TestInitialize] + public void Setup() + { + var result = new Result(); + contextMenuResult = new ContextMenuResult(); + mainViewModelMock = new Mock(); + resultViewModel = new ResultViewModel(result, mainViewModelMock.Object); + + var pluginMock = new Mock(); + pluginMock.As().Setup(x => x.LoadContextMenus(result)).Returns(new List { contextMenuResult }); + + var pair = new PluginPair(new PluginMetadata()); + pair.Plugin = pluginMock.Object; + PluginManager.SetAllPlugins(new List() + { + pair, + }); + PluginManager.InitializePlugins(new Mock().Object); + } + + [TestMethod] + public void ExecuteContextMenuResultActionThatReturnsTrueShouldHideTheMainView() + { + // Arrange + contextMenuResult.Action = _ => true; + + // Act + resultViewModel.LoadContextMenu(); + resultViewModel.ContextMenuItems.Single().Command.Execute(null); + + // Assert + mainViewModelMock.Verify(x => x.Hide(), Times.Once()); + } + + [TestMethod] + public void ExecuteContextMenuResultActionThatReturnsFalseShouldNotHideTheMainView() + { + // Arrange + contextMenuResult.Action = _ => false; + + // Act + resultViewModel.LoadContextMenu(); + resultViewModel.ContextMenuItems.Single().Command.Execute(null); + + // Assert + mainViewModelMock.Verify(x => x.Hide(), Times.Never()); + } + } +} diff --git a/src/modules/launcher/Wox.Test/ResultsViewModelTest.cs b/src/modules/launcher/Wox.Test/ResultsViewModelTest.cs index d15d5e125c..c458b56b18 100644 --- a/src/modules/launcher/Wox.Test/ResultsViewModelTest.cs +++ b/src/modules/launcher/Wox.Test/ResultsViewModelTest.cs @@ -18,7 +18,7 @@ namespace Wox.Test // Arrange ResultsViewModel rvm = new ResultsViewModel(); Result result = new Result(); - ResultViewModel selectedItem = new ResultViewModel(result); + ResultViewModel selectedItem = new ResultViewModel(result, null); selectedItem.ContextMenuItems.Add(new ContextMenuItemViewModel(null, null, null, null, Key.None, ModifierKeys.None, null)); rvm.SelectedItem = selectedItem; @@ -32,7 +32,7 @@ namespace Wox.Test // Arrange ResultsViewModel rvm = new ResultsViewModel(); Result result = new Result(); - ResultViewModel selectedItem = new ResultViewModel(result); + ResultViewModel selectedItem = new ResultViewModel(result, null); selectedItem.ContextMenuItems.Add(new ContextMenuItemViewModel(null, null, null, null, Key.None, ModifierKeys.None, null)); rvm.SelectedItem = selectedItem; @@ -49,7 +49,7 @@ namespace Wox.Test // Arrange ResultsViewModel rvm = new ResultsViewModel(); Result result = new Result(); - ResultViewModel selectedItem = new ResultViewModel(result); + ResultViewModel selectedItem = new ResultViewModel(result, null); selectedItem.ContextMenuItems.Add(new ContextMenuItemViewModel(null, null, null, null, Key.None, ModifierKeys.None, null)); rvm.SelectedItem = selectedItem; @@ -66,7 +66,7 @@ namespace Wox.Test // Arrange ResultsViewModel rvm = new ResultsViewModel(); Result result = new Result(); - ResultViewModel selectedItem = new ResultViewModel(result); + ResultViewModel selectedItem = new ResultViewModel(result, 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 @@ namespace Wox.Test // Arrange ResultsViewModel rvm = new ResultsViewModel(); Result result = new Result(); - ResultViewModel selectedItem = new ResultViewModel(result); + ResultViewModel selectedItem = new ResultViewModel(result, null); selectedItem.ContextMenuItems.Add(new ContextMenuItemViewModel(null, null, null, null, Key.None, ModifierKeys.None, null)); rvm.SelectedItem = selectedItem; @@ -106,7 +106,7 @@ namespace Wox.Test // Arrange ResultsViewModel rvm = new ResultsViewModel(); Result result = new Result(); - ResultViewModel selectedItem = new ResultViewModel(result); + ResultViewModel selectedItem = new ResultViewModel(result, null); selectedItem.ContextMenuItems.Add(new ContextMenuItemViewModel(null, null, null, null, Key.None, ModifierKeys.None, null)); rvm.SelectedItem = selectedItem; @@ -124,7 +124,7 @@ namespace Wox.Test // Arrange ResultsViewModel rvm = new ResultsViewModel(); Result result = new Result(); - ResultViewModel selectedItem = new ResultViewModel(result); + ResultViewModel selectedItem = new ResultViewModel(result, null); selectedItem.ContextMenuItems.Add(new ContextMenuItemViewModel(null, null, null, null, Key.None, ModifierKeys.None, null)); rvm.SelectedItem = selectedItem; diff --git a/src/modules/launcher/Wox.Test/Wox.Test.csproj b/src/modules/launcher/Wox.Test/Wox.Test.csproj index 88b76bf895..53b4652e6d 100644 --- a/src/modules/launcher/Wox.Test/Wox.Test.csproj +++ b/src/modules/launcher/Wox.Test/Wox.Test.csproj @@ -32,6 +32,11 @@ 4 + + + + +