wire things up

This commit is contained in:
Kai Tao
2025-11-27 13:14:56 +08:00
parent 4f4dff8c2d
commit 1205da5a23
11 changed files with 338 additions and 46 deletions

View File

@@ -731,8 +731,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CalculatorEngineCommon", "s
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ManagedCsWin32", "src\common\ManagedCsWin32\ManagedCsWin32.csproj", "{14AFD976-B4D2-49D0-9E6C-AA93CC061B8A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.PowerToys.Host", "src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.PowerToys.Host\Microsoft.CmdPal.Ext.PowerToys.Host.csproj", "{DDF8565C-B67A-9B79-6156-A2544408BCF7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PowerRename.UITests", "src\modules\powerrename\PowerRenameUITest\PowerRename.UITests.csproj", "{9D3F3793-EFE3-4525-8782-238015DABA62}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Core", "Core", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
@@ -3770,18 +3768,6 @@ Global
{14AFD976-B4D2-49D0-9E6C-AA93CC061B8A}.Release|ARM64.Build.0 = Release|ARM64
{14AFD976-B4D2-49D0-9E6C-AA93CC061B8A}.Release|x64.ActiveCfg = Release|x64
{14AFD976-B4D2-49D0-9E6C-AA93CC061B8A}.Release|x64.Build.0 = Release|x64
{DDF8565C-B67A-9B79-6156-A2544408BCF7}.Debug|Any CPU.ActiveCfg = Debug|x64
{DDF8565C-B67A-9B79-6156-A2544408BCF7}.Debug|Any CPU.Build.0 = Debug|x64
{DDF8565C-B67A-9B79-6156-A2544408BCF7}.Debug|ARM64.ActiveCfg = Debug|ARM64
{DDF8565C-B67A-9B79-6156-A2544408BCF7}.Debug|ARM64.Build.0 = Debug|ARM64
{DDF8565C-B67A-9B79-6156-A2544408BCF7}.Debug|x64.ActiveCfg = Debug|x64
{DDF8565C-B67A-9B79-6156-A2544408BCF7}.Debug|x64.Build.0 = Debug|x64
{DDF8565C-B67A-9B79-6156-A2544408BCF7}.Release|Any CPU.ActiveCfg = Release|x64
{DDF8565C-B67A-9B79-6156-A2544408BCF7}.Release|Any CPU.Build.0 = Release|x64
{DDF8565C-B67A-9B79-6156-A2544408BCF7}.Release|ARM64.ActiveCfg = Release|ARM64
{DDF8565C-B67A-9B79-6156-A2544408BCF7}.Release|ARM64.Build.0 = Release|ARM64
{DDF8565C-B67A-9B79-6156-A2544408BCF7}.Release|x64.ActiveCfg = Release|x64
{DDF8565C-B67A-9B79-6156-A2544408BCF7}.Release|x64.Build.0 = Release|x64
{9D3F3793-EFE3-4525-8782-238015DABA62}.Debug|Any CPU.ActiveCfg = Debug|x64
{9D3F3793-EFE3-4525-8782-238015DABA62}.Debug|Any CPU.Build.0 = Debug|x64
{9D3F3793-EFE3-4525-8782-238015DABA62}.Debug|ARM64.ActiveCfg = Debug|ARM64
@@ -4439,7 +4425,6 @@ Global
{43E779F3-D83C-48B1-BA8D-1912DBD76FC9} = {68328142-5B31-4715-BCBB-7B6345EE0971}
{2CF78CF7-8FEB-4BE1-9591-55FA25B48FC6} = {1AFB6476-670D-4E80-A464-657E01DFF482}
{14AFD976-B4D2-49D0-9E6C-AA93CC061B8A} = {1AFB6476-670D-4E80-A464-657E01DFF482}
{DDF8565C-B67A-9B79-6156-A2544408BCF7} = {ECB8E0D1-7603-4E5C-AB10-D1E545E6F8E2}
{9D3F3793-EFE3-4525-8782-238015DABA62} = {66E1534A-1587-42B2-912F-45C994D32904}
{02EA681E-C7D8-13C7-8484-4AC65E1B71E8} = {3846508C-77EB-4034-A702-F8BB263C4F79}
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}

View File

@@ -0,0 +1,28 @@
// 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 Common.UI;
using Microsoft.CommandPalette.Extensions.Toolkit;
namespace PowerToysExtension.Commands;
/// <summary>
/// Opens the PowerToys settings page for the given module via SettingsDeepLink.
/// </summary>
internal sealed partial class OpenInSettingsCommand : InvokableCommand
{
private readonly SettingsDeepLink.SettingsWindow _module;
internal OpenInSettingsCommand(SettingsDeepLink.SettingsWindow module, string? title = null)
{
_module = module;
Name = string.IsNullOrWhiteSpace(title) ? $"Open {_module} settings" : title;
}
public override CommandResult Invoke()
{
SettingsDeepLink.OpenSettings(_module);
return CommandResult.Hide();
}
}

View File

@@ -0,0 +1,113 @@
// 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;
using System.Collections.Generic;
using System.Linq;
using Common.Search.FuzzSearch;
using Common.UI;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
using PowerToysExtension.Commands;
using PowerToysExtension.Helper;
namespace PowerToysExtension.Helper;
/// <summary>
/// Builds the list of PowerToys module entries and supports basic fuzzy filtering.
/// </summary>
internal static class ModuleItemsHelper
{
private static List<ListItem>? _cache;
public static IListItem[] FilteredItems(string query)
{
var all = AllItems();
if (string.IsNullOrWhiteSpace(query))
{
return [.. all];
}
var matched = new List<Tuple<int, ListItem>>();
foreach (var item in all)
{
var result = StringMatcher.FuzzyMatch(query, item.Title);
if (result.Success)
{
matched.Add(new Tuple<int, ListItem>(result.Score, item));
}
}
matched.Sort((x, y) => y.Item1.CompareTo(x.Item1));
return [.. matched.Select(x => x.Item2)];
}
private static List<ListItem> AllItems()
{
if (_cache is not null)
{
return _cache;
}
var items = new List<ListItem>();
foreach (var module in Enum.GetValues<SettingsDeepLink.SettingsWindow>())
{
var item = CreateItem(module);
if (item is not null)
{
items.Add(item);
}
}
_cache = items;
return items;
}
private static ListItem? CreateItem(SettingsDeepLink.SettingsWindow module)
{
// Skip purely internal pages.
if (module is SettingsDeepLink.SettingsWindow.Dashboard)
{
return null;
}
var icon = module.ModuleIcon();
var title = module.ModuleDisplayName();
var settingsCommand = new OpenInSettingsCommand(module, $"Open {title} settings");
// Module-specific extras
var more = new List<CommandContextItem>();
switch (module)
{
case SettingsDeepLink.SettingsWindow.Awake:
more.Add(new CommandContextItem(new StartAwakeCommand("Awake: Keep awake indefinitely", () => "-m indefinite", "Awake set to indefinite")));
more.Add(new CommandContextItem(new StartAwakeCommand("Awake: Keep awake for 30 minutes", () => "-m timed -t 30", "Awake set for 30 minutes")));
more.Add(new CommandContextItem(new StartAwakeCommand("Awake: Keep awake for 2 hours", () => "-m timed -t 120", "Awake set for 2 hours")));
more.Add(new CommandContextItem(new StopAwakeCommand()));
break;
case SettingsDeepLink.SettingsWindow.Workspaces:
more.Add(new CommandContextItem(new OpenWorkspaceEditorCommand()));
more.Add(new CommandContextItem(new OpenPowerToysSettingsCommand("Workspaces", "Workspaces")));
break;
case SettingsDeepLink.SettingsWindow.Overview:
// Overview just opens main settings
break;
default:
break;
}
var command = new CommandItem(settingsCommand)
{
Title = title,
Icon = icon,
MoreCommands = more.Count > 0 ? [.. more] : [],
};
return new ListItem(command);
}
}

View File

@@ -0,0 +1,93 @@
// 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 static Common.UI.SettingsDeepLink;
namespace PowerToysExtension.Helper;
internal static class PowerToysResourcesHelper
{
public static IconInfo ProviderIcon() => IconHelpers.FromRelativePath("Assets\\PowerToys.png");
public static IconInfo ModuleIcon(this SettingsWindow module)
{
var iconPath = module switch
{
SettingsWindow.ColorPicker => "Assets\\ColorPicker.png",
SettingsWindow.FancyZones => "Assets\\FancyZones.png",
SettingsWindow.Hosts => "Assets\\Hosts.png",
SettingsWindow.PowerOCR => "Assets\\PowerOcr.png",
SettingsWindow.RegistryPreview => "Assets\\RegistryPreview.png",
SettingsWindow.MeasureTool => "Assets\\ScreenRuler.png",
SettingsWindow.ShortcutGuide => "Assets\\ShortcutGuide.png",
SettingsWindow.CropAndLock => "Assets\\CropAndLock.png",
SettingsWindow.EnvironmentVariables => "Assets\\EnvironmentVariables.png",
SettingsWindow.Awake => "Assets\\Awake.png",
SettingsWindow.PowerRename => "Assets\\PowerRename.png",
SettingsWindow.Run => "Assets\\PowerToysRun.png",
SettingsWindow.ImageResizer => "Assets\\ImageResizer.png",
SettingsWindow.KBM => "Assets\\KeyboardManager.png",
SettingsWindow.MouseUtils => "Assets\\MouseUtils.png",
SettingsWindow.Workspaces => "Assets\\Workspaces.png",
SettingsWindow.AdvancedPaste => "Assets\\AdvancedPaste.png",
SettingsWindow.CmdPal => "Assets\\CmdPal.png",
SettingsWindow.ZoomIt => "Assets\\ZoomIt.png",
SettingsWindow.FileExplorer => "Assets\\FileExplorerPreview.png",
SettingsWindow.FileLocksmith => "Assets\\FileLocksmith.png",
SettingsWindow.NewPlus => "Assets\\NewPlus.png",
SettingsWindow.Peek => "Assets\\Peek.png",
SettingsWindow.AlwaysOnTop => "Assets\\AlwaysOnTop.png",
SettingsWindow.CmdNotFound => "Assets\\CommandNotFound.png",
SettingsWindow.MouseWithoutBorders => "Assets\\MouseWithoutBorders.png",
SettingsWindow.PowerAccent => "Assets\\QuickAccent.png",
SettingsWindow.PowerLauncher => "Assets\\PowerToysRun.png",
SettingsWindow.PowerPreview => "Assets\\FileExplorerPreview.png",
SettingsWindow.Overview => "Assets\\PowerToys.png",
SettingsWindow.Dashboard => "Assets\\PowerToys.png",
_ => "Assets\\PowerToys.png",
};
return IconHelpers.FromRelativePath(iconPath);
}
public static string ModuleDisplayName(this SettingsWindow module)
{
return module switch
{
SettingsWindow.ColorPicker => "Color Picker",
SettingsWindow.FancyZones => "FancyZones",
SettingsWindow.Hosts => "Hosts File Editor",
SettingsWindow.PowerOCR => "Text Extractor",
SettingsWindow.RegistryPreview => "Registry Preview",
SettingsWindow.MeasureTool => "Screen Ruler",
SettingsWindow.ShortcutGuide => "Shortcut Guide",
SettingsWindow.CropAndLock => "Crop And Lock",
SettingsWindow.EnvironmentVariables => "Environment Variables",
SettingsWindow.Awake => "Awake",
SettingsWindow.PowerRename => "PowerRename",
SettingsWindow.Run => "PowerToys Run",
SettingsWindow.ImageResizer => "Image Resizer",
SettingsWindow.KBM => "Keyboard Manager",
SettingsWindow.MouseUtils => "Mouse Utilities",
SettingsWindow.Workspaces => "Workspaces",
SettingsWindow.AdvancedPaste => "Advanced Paste",
SettingsWindow.CmdPal => "Command Palette",
SettingsWindow.ZoomIt => "ZoomIt",
SettingsWindow.FileExplorer => "File Explorer Add-ons",
SettingsWindow.FileLocksmith => "File Locksmith",
SettingsWindow.NewPlus => "New+",
SettingsWindow.Peek => "Peek",
SettingsWindow.AlwaysOnTop => "Always On Top",
SettingsWindow.CmdNotFound => "Command Not Found",
SettingsWindow.MouseWithoutBorders => "Mouse Without Borders",
SettingsWindow.PowerAccent => "Quick Accent",
SettingsWindow.Overview => "General",
SettingsWindow.Dashboard => "Dashboard",
SettingsWindow.PowerLauncher => "PowerToys Run",
SettingsWindow.PowerPreview => "File Explorer Add-ons",
_ => module.ToString(),
};
}
}

View File

@@ -32,7 +32,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\extensionsdk\Microsoft.CommandPalette.Extensions.Toolkit\Microsoft.CommandPalette.Extensions.Toolkit.csproj" />
<PackageReference Include="Microsoft.WindowsAppSDK" />
<PackageReference Include="Microsoft.Windows.CsWin32">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
@@ -50,7 +50,10 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\extensionsdk\Microsoft.CommandPalette.Extensions.Toolkit\Microsoft.CommandPalette.Extensions.Toolkit.csproj" />
<ProjectReference Include="..\..\..\..\common\ManagedCommon\ManagedCommon.csproj" />
<ProjectReference Include="..\..\..\..\common\Common.Search\Common.Search.csproj" />
<ProjectReference Include="..\..\..\..\common\Common.UI\Common.UI.csproj" />
</ItemGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Release'">

View File

@@ -44,8 +44,8 @@
<Extensions>
<com:Extension Category="windows.comServer">
<com:ComServer>
<com:ExeServer Executable="$targetnametoken$.exe" Arguments="-RegisterProcessAsComServer" DisplayName="PowerToys Command Palette Extension">
<com:Class Id="3D0F0E1F-6F0C-4D5C-91C0-5C4A4B1A5D55" DisplayName="PowerToys Command Palette Extension" />
<com:ExeServer Executable="Microsoft.CmdPal.Ext.PowerToys.exe" Arguments="-RegisterProcessAsComServer" DisplayName="PowerToys Command Palette Extension">
<com:Class Id="7EC02C7D-8F98-4A2E-9F23-B58C2C2F2B17" DisplayName="PowerToys Command Palette Extension" />
</com:ExeServer>
</com:ComServer>
</com:Extension>
@@ -58,7 +58,7 @@
<uap3:Properties>
<CmdPalProvider>
<Activation>
<CreateInstance ClassId="3D0F0E1F-6F0C-4D5C-91C0-5C4A4B1A5D55" />
<CreateInstance ClassId="7EC02C7D-8F98-4A2E-9F23-B58C2C2F2B17" />
</Activation>
<SupportedInterfaces>
<Commands/>

View File

@@ -4,6 +4,7 @@
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
using PowerToysExtension.Commands;
namespace PowerToysExtension;
@@ -11,15 +12,54 @@ internal sealed partial class PowerToysExtensionPage : ListPage
{
public PowerToysExtensionPage()
{
Icon = IconHelpers.FromRelativePath("Assets\\StoreLogo.png");
Title = "PowerToysExtension";
Name = "Open";
Icon = IconHelpers.FromRelativePath("Assets\\PowerToys.png");
Title = "PowerToys";
Name = "PowerToys commands";
}
public override IListItem[] GetItems()
{
return [
new ListItem(new NoOpCommand()) { Title = "TODO: Implement your extension here" }
new ListItem(new LaunchModuleCommand("PowerToys", executableName: "PowerToys.exe", displayName: "Open PowerToys"))
{
Title = "Open PowerToys",
Subtitle = "Launch the PowerToys shell",
},
new ListItem(new OpenPowerToysSettingsCommand("PowerToys", "General"))
{
Title = "Open PowerToys settings",
Subtitle = "Open the main PowerToys settings window",
},
new ListItem(new OpenPowerToysSettingsCommand("Workspaces", "Workspaces"))
{
Title = "Open Workspaces settings",
Subtitle = "Jump directly to Workspaces settings",
},
new ListItem(new OpenWorkspaceEditorCommand())
{
Title = "Open Workspaces editor",
Subtitle = "Launch the Workspaces editor",
},
new ListItem(new StartAwakeCommand("Awake: Keep awake indefinitely", () => "-m indefinite", "Awake set to indefinite"))
{
Title = "Awake: Keep awake indefinitely",
Subtitle = "Run Awake in indefinite mode",
},
new ListItem(new StartAwakeCommand("Awake: Keep awake for 30 minutes", () => "-m timed -t 30", "Awake set for 30 minutes"))
{
Title = "Awake: Keep awake for 30 minutes",
Subtitle = "Run Awake timed for 30 minutes",
},
new ListItem(new StartAwakeCommand("Awake: Keep awake for 2 hours", () => "-m timed -t 120", "Awake set for 2 hours"))
{
Title = "Awake: Keep awake for 2 hours",
Subtitle = "Run Awake timed for 2 hours",
},
new ListItem(new StopAwakeCommand())
{
Title = "Awake: Turn off",
Subtitle = "Switch Awake back to Off",
},
];
}
}

View File

@@ -0,0 +1,36 @@
// 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;
using Microsoft.CommandPalette.Extensions.Toolkit;
using PowerToysExtension.Helper;
namespace PowerToysExtension.Pages;
internal sealed partial class PowerToysListPage : DynamicListPage
{
private readonly CommandItem _empty;
public PowerToysListPage()
{
Icon = IconHelpers.FromRelativePath("Assets\\PowerToys.png");
Name = Title = "PowerToys";
Id = "com.microsoft.cmdpal.powertoys";
_empty = new CommandItem()
{
Icon = IconHelpers.FromRelativePath("Assets\\PowerToys.png"),
Title = "No matching module found",
Subtitle = SearchText,
};
EmptyContent = _empty;
}
public override void UpdateSearchText(string oldSearch, string newSearch)
{
_empty.Subtitle = newSearch;
RaiseItemsChanged(0);
}
public override IListItem[] GetItems() => ModuleItemsHelper.FilteredItems(SearchText);
}

View File

@@ -13,25 +13,15 @@ public sealed partial class PowerToysCommandsProvider : CommandProvider
public PowerToysCommandsProvider()
{
DisplayName = "PowerToys";
Icon = new IconInfo("\uE82D"); // TODO: Use proper icon
Logger.LogInfo("PowerToysCommandsProvider constructed.");
Icon = IconHelpers.FromRelativePath("Assets\\PowerToys.png");
}
public override ICommandItem[] TopLevelCommands()
{
Logger.LogInfo("PowerToysCommandsProvider.TopLevelCommands invoked.");
return
public override ICommandItem[] TopLevelCommands() =>
[
new CommandItem(new ListPage()
{
Name = "PowerToys",
Title = "PowerToys",
Icon = new IconInfo("\uE82D"),
})
new CommandItem(new Pages.PowerToysListPage())
{
Title = "PowerToys",
Subtitle = "PowerToys commands",
Subtitle = "PowerToys commands and settings",
}
];
}
}

View File

@@ -10,7 +10,7 @@ using Microsoft.CommandPalette.Extensions;
namespace PowerToysExtension;
[Guid("3D0F0E1F-6F0C-4D5C-91C0-5C4A4B1A5D55")]
[Guid("7EC02C7D-8F98-4A2E-9F23-B58C2C2F2B17")]
public sealed partial class PowerToysExtension : IExtension, IDisposable
{
private readonly ManualResetEvent _extensionDisposedEvent;

View File

@@ -13,10 +13,14 @@ public partial class PowerToysExtensionCommandsProvider : CommandProvider
public PowerToysExtensionCommandsProvider()
{
DisplayName = "PowerToysExtension";
Icon = IconHelpers.FromRelativePath("Assets\\StoreLogo.png");
DisplayName = "PowerToys";
Icon = IconHelpers.FromRelativePath("Assets\\PowerToys.png");
_commands = [
new CommandItem(new PowerToysExtensionPage()) { Title = DisplayName },
new CommandItem(new Pages.PowerToysListPage())
{
Title = "PowerToys",
Subtitle = "PowerToys commands and settings",
},
];
}