mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-08-29 10:09:43 +02:00
CmdPal: use unique IDs for PowerToys fallback commands (#50047)
## Summary of the Pull Request PowerToys fallback commands currently all use the same fallback ID (`com.microsoft.powertoys.fallback`). Because Command Palette persists fallback settings by ID, disabling one command writes a setting that is then read by every fallback command in the provider. This change derives each fallback item's ID from the command's existing stable ID by appending `.fallback`, so fallback settings are stored independently without colliding with the underlying command IDs. It also adds a focused regression test covering the generated fallback IDs. ## PR Checklist * [x] Closes: #48607 * [x] **Communication:** The issue is labeled `Help Wanted`; implementation intent and approach were posted in #28769. * [ ] **Tests:** Added; official CI pending. The local PowerToys build is blocked because the available Visual Studio/MSBuild 17.10 cannot load the repository's .NET 10 SDK, which requires MSBuild 18. * [x] **Localization:** No end-user-facing strings were added or changed. * [x] **Dev docs:** Not applicable; no public behavior or API contract was added. * [x] **New binaries:** No shipping binaries were added. The new unit-test assembly is included in `PowerToys.slnx` and the applicable Command Palette solution filters, and matches the existing `*UnitTest*.dll` CI test discovery pattern. * [x] **Documentation updated:** Not applicable. ## Detailed Description of the Pull Request / Additional comments `ProviderSettingsViewModel` stores fallback state in a dictionary keyed by `IFallbackCommandItem.Id`. The PowerToys extension generated many fallback items with one shared ID, causing the last persisted state for that key to apply to the entire provider after reopening settings. All commands produced by the PowerToys module catalog already have stable, unique IDs used for command identity and pinning. Appending `.fallback` to those IDs gives each fallback item a stable, unique identity while keeping it distinct from the underlying command. Existing legacy settings under `com.microsoft.powertoys.fallback` are left harmlessly unused because there is no meaningful way to map that shared value back to one specific command. The new unit-test project is also included in the applicable Command Palette solution filters so it is available in the relevant development and test configurations. ## Validation Steps Performed * Added `FallbackItemsAppendFallbackSuffixToCommandIds`, covering two commands and verifying that fallback IDs append `.fallback`, remain distinct from the underlying command IDs, and remain unique across commands. * Added the new unit-test project to `PowerToys.slnx`, `CommandPalette.slnf`, `CommandPalette - no UI tests.slnf`, and `Microsoft.CmdPal.Ext.PowerToys.slnf`. * Included `Microsoft.CmdPal.Ext.UnitTestsBase` in the PowerToys-specific solution filter because it is a direct dependency of the new unit-test project. * Validated the modified solution and project files. * Confirmed all 64 literal command IDs in the PowerToys module providers are unique. * Ran `git diff --check` successfully. * Attempted the repository-prescribed targeted Release/x64 build. It reached MSBuild but was blocked by the local toolchain version noted above; authoritative build and test results are therefore left to CI.
This commit is contained in:
@@ -349,6 +349,10 @@
|
||||
<Platform Solution="*|ARM64" Project="ARM64" />
|
||||
<Platform Solution="*|x64" Project="x64" />
|
||||
</Project>
|
||||
<Project Path="src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.PowerToys.UnitTests/Microsoft.CmdPal.Ext.PowerToys.UnitTests.csproj">
|
||||
<Platform Solution="*|ARM64" Project="ARM64" />
|
||||
<Platform Solution="*|x64" Project="x64" />
|
||||
</Project>
|
||||
<Project Path="src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.Registry.UnitTests/Microsoft.CmdPal.Ext.Registry.UnitTests.csproj">
|
||||
<Platform Solution="*|ARM64" Project="ARM64" />
|
||||
<Platform Solution="*|x64" Project="x64" />
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
"src\\modules\\cmdpal\\Tests\\Microsoft.CmdPal.Ext.ClipboardHistory.UnitTests\\Microsoft.CmdPal.Ext.ClipboardHistory.UnitTests.csproj",
|
||||
"src\\modules\\cmdpal\\Tests\\Microsoft.CmdPal.Ext.Indexer.UnitTests\\Microsoft.CmdPal.Ext.Indexer.UnitTests.csproj",
|
||||
"src\\modules\\cmdpal\\Tests\\Microsoft.CmdPal.Ext.PerformanceMonitor.UnitTests\\Microsoft.CmdPal.Ext.PerformanceMonitor.UnitTests.csproj",
|
||||
"src\\modules\\cmdpal\\Tests\\Microsoft.CmdPal.Ext.PowerToys.UnitTests\\Microsoft.CmdPal.Ext.PowerToys.UnitTests.csproj",
|
||||
"src\\modules\\cmdpal\\Tests\\Microsoft.CmdPal.Ext.Registry.UnitTests\\Microsoft.CmdPal.Ext.Registry.UnitTests.csproj",
|
||||
"src\\modules\\cmdpal\\Tests\\Microsoft.CmdPal.Ext.RemoteDesktop.UnitTests\\Microsoft.CmdPal.Ext.RemoteDesktop.UnitTests.csproj",
|
||||
"src\\modules\\cmdpal\\Tests\\Microsoft.CmdPal.Ext.Shell.UnitTests\\Microsoft.CmdPal.Ext.Shell.UnitTests.csproj",
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
"src\\modules\\cmdpal\\Tests\\Microsoft.CmdPal.Ext.ClipboardHistory.UnitTests\\Microsoft.CmdPal.Ext.ClipboardHistory.UnitTests.csproj",
|
||||
"src\\modules\\cmdpal\\Tests\\Microsoft.CmdPal.Ext.Indexer.UnitTests\\Microsoft.CmdPal.Ext.Indexer.UnitTests.csproj",
|
||||
"src\\modules\\cmdpal\\Tests\\Microsoft.CmdPal.Ext.PerformanceMonitor.UnitTests\\Microsoft.CmdPal.Ext.PerformanceMonitor.UnitTests.csproj",
|
||||
"src\\modules\\cmdpal\\Tests\\Microsoft.CmdPal.Ext.PowerToys.UnitTests\\Microsoft.CmdPal.Ext.PowerToys.UnitTests.csproj",
|
||||
"src\\modules\\cmdpal\\Tests\\Microsoft.CmdPal.Ext.Registry.UnitTests\\Microsoft.CmdPal.Ext.Registry.UnitTests.csproj",
|
||||
"src\\modules\\cmdpal\\Tests\\Microsoft.CmdPal.Ext.RemoteDesktop.UnitTests\\Microsoft.CmdPal.Ext.RemoteDesktop.UnitTests.csproj",
|
||||
"src\\modules\\cmdpal\\Tests\\Microsoft.CmdPal.Ext.Shell.UnitTests\\Microsoft.CmdPal.Ext.Shell.UnitTests.csproj",
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
"src\\modules\\Workspaces\\WorkspacesCsharpLibrary\\WorkspacesCsharpLibrary.csproj",
|
||||
"src\\modules\\ZoomIt\\ZoomItSettingsInterop\\ZoomItSettingsInterop.vcxproj",
|
||||
"src\\modules\\awake\\Awake.ModuleServices\\Awake.ModuleServices.csproj",
|
||||
"src\\modules\\cmdpal\\Tests\\Microsoft.CmdPal.Ext.PowerToys.UnitTests\\Microsoft.CmdPal.Ext.PowerToys.UnitTests.csproj",
|
||||
"src\\modules\\cmdpal\\Tests\\Microsoft.CmdPal.Ext.UnitTestsBase\\Microsoft.CmdPal.Ext.UnitTestBase.csproj",
|
||||
"src\\modules\\cmdpal\\ext\\Microsoft.CmdPal.Ext.PowerToys\\Microsoft.CmdPal.Ext.PowerToys.csproj",
|
||||
"src\\modules\\cmdpal\\extensionsdk\\Microsoft.CommandPalette.Extensions.Toolkit\\Microsoft.CommandPalette.Extensions.Toolkit.csproj",
|
||||
"src\\modules\\cmdpal\\extensionsdk\\Microsoft.CommandPalette.Extensions\\Microsoft.CommandPalette.Extensions.vcxproj",
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<!-- Look at Directory.Build.props in root for common stuff as well -->
|
||||
<Import Project="$(RepoRoot)src\Common.Dotnet.CsWinRT.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<IsPackable>false</IsPackable>
|
||||
<IsTestProject>true</IsTestProject>
|
||||
<RootNamespace>Microsoft.CmdPal.Ext.PowerToys.UnitTests</RootNamespace>
|
||||
<OutputPath>$(RepoRoot)$(Platform)\$(Configuration)\WinUI3Apps\CmdPal\tests\</OutputPath>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MSTest" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\..\ext\Microsoft.CmdPal.Ext.PowerToys\Helpers\PowerToysFallbackCommandItem.cs" Link="PowerToysFallbackCommandItem.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\common\Common.Search\Common.Search.csproj" />
|
||||
<ProjectReference Include="..\..\extensionsdk\Microsoft.CommandPalette.Extensions.Toolkit\Microsoft.CommandPalette.Extensions.Toolkit.csproj" />
|
||||
<ProjectReference Include="..\Microsoft.CmdPal.Ext.UnitTestsBase\Microsoft.CmdPal.Ext.UnitTestBase.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,29 @@
|
||||
// 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 Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using PowerToysExtension.Helpers;
|
||||
|
||||
namespace Microsoft.CmdPal.Ext.PowerToys.UnitTests;
|
||||
|
||||
[TestClass]
|
||||
public class PowerToysFallbackCommandItemTests
|
||||
{
|
||||
[TestMethod]
|
||||
public void FallbackItemsAppendFallbackSuffixToCommandIds()
|
||||
{
|
||||
var firstCommand = new NoOpCommand { Id = "com.microsoft.powertoys.first" };
|
||||
var secondCommand = new NoOpCommand { Id = "com.microsoft.powertoys.second" };
|
||||
|
||||
var firstFallback = new PowerToysFallbackCommandItem(firstCommand, "First", string.Empty, null, null);
|
||||
var secondFallback = new PowerToysFallbackCommandItem(secondCommand, "Second", string.Empty, null, null);
|
||||
|
||||
Assert.AreEqual($"{firstCommand.Id}.fallback", firstFallback.Id);
|
||||
Assert.AreEqual($"{secondCommand.Id}.fallback", secondFallback.Id);
|
||||
Assert.AreNotEqual(firstCommand.Id, firstFallback.Id);
|
||||
Assert.AreNotEqual(secondCommand.Id, secondFallback.Id);
|
||||
Assert.AreNotEqual(firstFallback.Id, secondFallback.Id);
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ internal sealed partial class PowerToysFallbackCommandItem : FallbackCommandItem
|
||||
private readonly Command? _mutableCommand;
|
||||
|
||||
public PowerToysFallbackCommandItem(ICommand command, string title, string subtitle, IIconInfo? icon, IContextItem[]? moreCommands)
|
||||
: base(command, title, "com.microsoft.powertoys.fallback")
|
||||
: base(command, title, $"{command.Id}.fallback")
|
||||
{
|
||||
_baseTitle = title ?? string.Empty;
|
||||
_baseSubtitle = subtitle ?? string.Empty;
|
||||
|
||||
Reference in New Issue
Block a user