mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-29 08:29:10 +01:00
Compare commits
63 Commits
leilzh/Bgc
...
leilzh/get
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f8934769c9 | ||
|
|
6d80dce74c | ||
|
|
393fb15019 | ||
|
|
1d0cee997b | ||
|
|
28d585fef6 | ||
|
|
65e67f4098 | ||
|
|
68f474ef64 | ||
|
|
f1db717b6d | ||
|
|
d90c1954b0 | ||
|
|
b0d7bfef7c | ||
|
|
c8cea4a017 | ||
|
|
ca473b488b | ||
|
|
a16813b73b | ||
|
|
1fbb784bea | ||
|
|
421a7a62d5 | ||
|
|
1e0b6d5e38 | ||
|
|
3bee31bfd7 | ||
|
|
d37105bf84 | ||
|
|
a89d8476f8 | ||
|
|
19ada53ce3 | ||
|
|
0654edb18a | ||
|
|
7d02867b60 | ||
|
|
b05cf8bf9f | ||
|
|
522f12a0b2 | ||
|
|
d12bbf0cbf | ||
|
|
f067a925f6 | ||
|
|
6642c805b7 | ||
|
|
37c690b216 | ||
|
|
f6ff5064a3 | ||
|
|
78884bb587 | ||
|
|
d2b81450e3 | ||
|
|
425883508f | ||
|
|
41ff1f8cf7 | ||
|
|
2ee40a99d5 | ||
|
|
d5b15026ae | ||
|
|
943d79bb83 | ||
|
|
e42a1b8753 | ||
|
|
ed424faea5 | ||
|
|
b552f2ac1e | ||
|
|
cc16b61eb7 | ||
|
|
85db62e946 | ||
|
|
96de5d7a87 | ||
|
|
53bb471449 | ||
|
|
0783763dd0 | ||
|
|
19390e3198 | ||
|
|
8a1aff68c1 | ||
|
|
f19c2e1a78 | ||
|
|
5800b81638 | ||
|
|
d96c29d22d | ||
|
|
1dab45c87c | ||
|
|
0040112855 | ||
|
|
6205e25eb5 | ||
|
|
dbe3ac6077 | ||
|
|
227c5d8147 | ||
|
|
d258dcd61b | ||
|
|
1d464cc307 | ||
|
|
3686d6ac19 | ||
|
|
a0495736f1 | ||
|
|
22f565ca49 | ||
|
|
e041556395 | ||
|
|
b55c4eeed3 | ||
|
|
9a65c36859 | ||
|
|
668f3f3ebd |
4
.github/actions/spell-check/expect.txt
vendored
4
.github/actions/spell-check/expect.txt
vendored
@@ -218,6 +218,7 @@ coclass
|
||||
CODENAME
|
||||
codereview
|
||||
Codespaces
|
||||
Coen
|
||||
COINIT
|
||||
colid
|
||||
colorconv
|
||||
@@ -1383,6 +1384,7 @@ RIGHTSCROLLBAR
|
||||
riid
|
||||
RKey
|
||||
RNumber
|
||||
Rns
|
||||
rop
|
||||
ROUNDSMALL
|
||||
ROWSETEXT
|
||||
@@ -1613,6 +1615,8 @@ svgz
|
||||
SVSI
|
||||
SWFO
|
||||
SWP
|
||||
SWPNOSIZE
|
||||
SWPNOZORDER
|
||||
SWRESTORE
|
||||
symbolrequestprod
|
||||
SYMCACHE
|
||||
|
||||
@@ -43,6 +43,7 @@ stages:
|
||||
enableMsBuildCaching: ${{ parameters.enableMsBuildCaching }}
|
||||
runTests: true
|
||||
useVSPreview: ${{ parameters.useVSPreview }}
|
||||
timeoutInMinutes: 90
|
||||
|
||||
- stage: OneFuzz
|
||||
displayName: Fuzz ${{ parameters.platform }}
|
||||
|
||||
@@ -38,6 +38,11 @@ parameters:
|
||||
displayName: "Build Using Visual Studio Preview"
|
||||
default: false
|
||||
|
||||
- name: enableAOT
|
||||
type: boolean
|
||||
displayName: "Enable AOT (Ahead-of-Time) Compilation for CmdPal"
|
||||
default: true
|
||||
|
||||
name: $(BuildDefinitionName)_$(date:yyMM).$(date:dd)$(rev:rrr)
|
||||
|
||||
variables:
|
||||
@@ -95,7 +100,7 @@ extends:
|
||||
useManagedIdentity: $(SigningUseManagedIdentity)
|
||||
clientId: $(SigningOriginalClientId)
|
||||
# Have msbuild use the release nuget config profile
|
||||
additionalBuildOptions: /p:RestoreConfigFile="$(Build.SourcesDirectory)\.pipelines\release-nuget.config"
|
||||
additionalBuildOptions: /p:RestoreConfigFile="$(Build.SourcesDirectory)\.pipelines\release-nuget.config" /p:EnableCmdPalAOT=${{ parameters.enableAOT }}
|
||||
beforeBuildSteps:
|
||||
# Sets versions for all PowerToy created DLLs
|
||||
- pwsh: |-
|
||||
|
||||
@@ -81,6 +81,12 @@ parameters:
|
||||
- 'src/modules/previewpane/SvgPreviewHandler/SvgPreviewHandler.csproj'
|
||||
- 'src/modules/previewpane/SvgThumbnailProvider/SvgThumbnailProvider.csproj'
|
||||
- 'src/modules/FileLocksmith/FileLocksmithUI/FileLocksmithUI.csproj'
|
||||
- name: timeoutInMinutes
|
||||
type: number
|
||||
default: 240
|
||||
- name: cancelTimeoutInMinutes
|
||||
type: number
|
||||
default: 1
|
||||
|
||||
jobs:
|
||||
- job: ${{ parameters.jobName }}
|
||||
@@ -123,8 +129,8 @@ jobs:
|
||||
${{ else }}:
|
||||
RestoreAdditionalProjectSourcesArg: ''
|
||||
displayName: Build
|
||||
timeoutInMinutes: 240
|
||||
cancelTimeoutInMinutes: 1
|
||||
timeoutInMinutes: ${{ parameters.timeoutInMinutes }}
|
||||
cancelTimeoutInMinutes: ${{ parameters.cancelTimeoutInMinutes }}
|
||||
templateContext: # Required when this template is hosted in 1ES PT
|
||||
outputs:
|
||||
- output: pipelineArtifact
|
||||
|
||||
@@ -160,6 +160,7 @@ jobs:
|
||||
vsTestVersion: 'toolsInstaller'
|
||||
uiTests: true
|
||||
rerunFailedTests: true
|
||||
testRunTitle: 'UITests_${{ parameters.platform }}_${{ parameters.installMode }}'
|
||||
# Since UITests-FancyZonesEditor.dll is generated in both UITests-FancyZonesEditor and UITests-FancyZones, removed one to avoid duplicate test runs
|
||||
testAssemblyVer2: |
|
||||
**\*UITest*.dll
|
||||
@@ -182,6 +183,7 @@ jobs:
|
||||
vsTestVersion: 'toolsInstaller'
|
||||
uiTests: true
|
||||
rerunFailedTests: true
|
||||
testRunTitle: 'UITests_${{ parameters.platform }}_${{ parameters.installMode }}'
|
||||
testAssemblyVer2: |
|
||||
**\*${{ module }}*.dll
|
||||
!**\obj\**
|
||||
|
||||
@@ -57,4 +57,5 @@ stages:
|
||||
useLatestWinAppSDK: ${{ parameters.useLatestWinAppSDK }}
|
||||
${{ if eq(parameters.useLatestWinAppSDK, true) }}:
|
||||
winAppSDKVersionNumber: ${{ parameters.winAppSDKVersionNumber }}
|
||||
useExperimentalVersion: ${{ parameters.useExperimentalVersion }}
|
||||
useExperimentalVersion: ${{ parameters.useExperimentalVersion }}
|
||||
timeoutInMinutes: 90
|
||||
|
||||
@@ -56,6 +56,7 @@ stages:
|
||||
runTests: false
|
||||
buildTests: true
|
||||
useVSPreview: ${{ parameters.useVSPreview }}
|
||||
timeoutInMinutes: 90
|
||||
|
||||
- ${{ if eq(parameters.useLatestOfficialBuild, true) }}:
|
||||
- stage: BuildUITests_${{ platform }}
|
||||
|
||||
@@ -19,7 +19,7 @@ Get-ChildItem $targetDir -Recurse -Filter *.deps.json -Exclude *UITest*,MouseJum
|
||||
# Temporarily exclude All UI-Test, Fuzzer-Test projects because of Appium.WebDriver dependencies
|
||||
$depsJsonFullFileName = $_.FullName
|
||||
|
||||
if ($depsJsonFullFileName -like "*CmdPal*") {
|
||||
if ($depsJsonFullFileName -like "*CmdPal*" -or $depsJsonFullFileName -like "*CommandPalette*") {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
<PackageVersion Include="Microsoft.Bot.AdaptiveExpressions.Core" Version="4.23.0" />
|
||||
<PackageVersion Include="Appium.WebDriver" Version="4.4.5" />
|
||||
<PackageVersion Include="Azure.AI.OpenAI" Version="1.0.0-beta.17" />
|
||||
<PackageVersion Include="CoenM.ImageSharp.ImageHash" Version="1.3.6" />
|
||||
<PackageVersion Include="CommunityToolkit.Common" Version="8.4.0" />
|
||||
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.4.0" />
|
||||
<PackageVersion Include="CommunityToolkit.WinUI.Animations" Version="8.2.250402" />
|
||||
@@ -21,6 +22,7 @@
|
||||
<PackageVersion Include="CommunityToolkit.WinUI.Extensions" Version="8.2.250402" />
|
||||
<PackageVersion Include="CommunityToolkit.WinUI.UI.Controls.DataGrid" Version="7.1.2" />
|
||||
<PackageVersion Include="CommunityToolkit.WinUI.UI.Controls.Markdown" Version="7.1.2" />
|
||||
<PackageVersion Include="CommunityToolkit.Labs.WinUI.Controls.MarkdownTextBlock" Version="0.1.250703-build.2173" />
|
||||
<PackageVersion Include="ControlzEx" Version="6.0.0" />
|
||||
<PackageVersion Include="HelixToolkit" Version="2.24.0" />
|
||||
<PackageVersion Include="HelixToolkit.Core.Wpf" Version="2.24.0" />
|
||||
|
||||
@@ -1496,7 +1496,9 @@ SOFTWARE.
|
||||
- AdaptiveCards.Templating 2.0.5
|
||||
- Appium.WebDriver 4.4.5
|
||||
- Azure.AI.OpenAI 1.0.0-beta.17
|
||||
- CoenM.ImageSharp.ImageHash 1.3.6
|
||||
- CommunityToolkit.Common 8.4.0
|
||||
- CommunityToolkit.Labs.WinUI.Controls.MarkdownTextBlock 0.1.250703-build.2173
|
||||
- CommunityToolkit.Mvvm 8.4.0
|
||||
- CommunityToolkit.WinUI.Animations 8.2.250402
|
||||
- CommunityToolkit.WinUI.Collections 8.2.250402
|
||||
@@ -1579,4 +1581,3 @@ SOFTWARE.
|
||||
- WinUIEx 2.2.0
|
||||
- WPF-UI 3.0.5
|
||||
- WyHash 1.0.5
|
||||
|
||||
|
||||
@@ -736,6 +736,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ManagedCsWin32", "src\commo
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PowerRenameUITest", "src\modules\powerrename\PowerRenameUITest\PowerRenameUITest.csproj", "{9D3F3793-EFE3-4525-8782-238015DABA62}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Peek.UITests", "src\modules\peek\Peek.UITests\Peek.UITests.csproj", "{BCDC7246-F4F8-4EED-8DE6-037AA2E7C6D1}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Core", "Core", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Core.ViewModels", "src\modules\cmdpal\Microsoft.CmdPal.Core.ViewModels\Microsoft.CmdPal.Core.ViewModels.csproj", "{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.UITests", "src\modules\cmdpal\Microsoft.CmdPal.UITests\Microsoft.CmdPal.UITests.csproj", "{840455DF-5634-51BB-D937-9D7D32F0B0C2}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|ARM64 = Debug|ARM64
|
||||
@@ -2718,6 +2726,14 @@ 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
|
||||
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}.Debug|x64.Build.0 = Debug|x64
|
||||
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}.Release|x64.ActiveCfg = Release|x64
|
||||
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}.Release|x64.Build.0 = Release|x64
|
||||
{9D3F3793-EFE3-4525-8782-238015DABA62}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{9D3F3793-EFE3-4525-8782-238015DABA62}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{9D3F3793-EFE3-4525-8782-238015DABA62}.Debug|x64.ActiveCfg = Debug|x64
|
||||
@@ -2726,6 +2742,22 @@ Global
|
||||
{9D3F3793-EFE3-4525-8782-238015DABA62}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{9D3F3793-EFE3-4525-8782-238015DABA62}.Release|x64.ActiveCfg = Release|x64
|
||||
{9D3F3793-EFE3-4525-8782-238015DABA62}.Release|x64.Build.0 = Release|x64
|
||||
{BCDC7246-F4F8-4EED-8DE6-037AA2E7C6D1}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{BCDC7246-F4F8-4EED-8DE6-037AA2E7C6D1}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{BCDC7246-F4F8-4EED-8DE6-037AA2E7C6D1}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{BCDC7246-F4F8-4EED-8DE6-037AA2E7C6D1}.Debug|x64.Build.0 = Debug|x64
|
||||
{BCDC7246-F4F8-4EED-8DE6-037AA2E7C6D1}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{BCDC7246-F4F8-4EED-8DE6-037AA2E7C6D1}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{BCDC7246-F4F8-4EED-8DE6-037AA2E7C6D1}.Release|x64.ActiveCfg = Release|x64
|
||||
{BCDC7246-F4F8-4EED-8DE6-037AA2E7C6D1}.Release|x64.Build.0 = Release|x64
|
||||
{840455DF-5634-51BB-D937-9D7D32F0B0C2}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{840455DF-5634-51BB-D937-9D7D32F0B0C2}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{840455DF-5634-51BB-D937-9D7D32F0B0C2}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{840455DF-5634-51BB-D937-9D7D32F0B0C2}.Debug|x64.Build.0 = Debug|x64
|
||||
{840455DF-5634-51BB-D937-9D7D32F0B0C2}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{840455DF-5634-51BB-D937-9D7D32F0B0C2}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{840455DF-5634-51BB-D937-9D7D32F0B0C2}.Release|x64.ActiveCfg = Release|x64
|
||||
{840455DF-5634-51BB-D937-9D7D32F0B0C2}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -3010,7 +3042,11 @@ Global
|
||||
{43E779F3-D83C-48B1-BA8D-1912DBD76FC9} = {A2221D7E-55E7-4BEA-90D1-4F162D670BBF}
|
||||
{2CF78CF7-8FEB-4BE1-9591-55FA25B48FC6} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
{14AFD976-B4D2-49D0-9E6C-AA93CC061B8A} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
{02EA681E-C7D8-13C7-8484-4AC65E1B71E8} = {3846508C-77EB-4034-A702-F8BB263C4F79}
|
||||
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
|
||||
{9D3F3793-EFE3-4525-8782-238015DABA62} = {89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3}
|
||||
{BCDC7246-F4F8-4EED-8DE6-037AA2E7C6D1} = {17B4FA70-001E-4D33-BBBB-0D142DBC2E20}
|
||||
{840455DF-5634-51BB-D937-9D7D32F0B0C2} = {7520A2FE-00A2-49B8-83ED-DB216E874C04}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0}
|
||||
|
||||
@@ -47,6 +47,8 @@ Contact the developers of a plugin directly for assistance with a specific plugi
|
||||
| [Weather](https://github.com/ruslanlap/PowerToysRun-Weather) | [ruslanlap](https://github.com/ruslanlap) | Get real-time weather information directly from PowerToys Run. |
|
||||
| [Pomodoro](https://github.com/ruslanlap/PowerToysRun-Pomodoro) | [ruslanlap](https://github.com/ruslanlap) | Manage Pomodoro productivity sessions directly from PowerToys Run. |
|
||||
| [Definition](https://github.com/ruslanlap/PowerToysRun-Definition) | [ruslanlap](https://github.com/ruslanlap) | Lookup word definitions, phonetics, and synonyms directly in PowerToys Run. |
|
||||
| [Hotkeys](https://github.com/ruslanlap/PowerToysRun-Hotkeys) | [ruslanlap](https://github.com/ruslanlap) | Create, manage, and trigger custom keyboard shortcuts directly from PowerToys Run. |
|
||||
| [RandomGen](https://github.com/ruslanlap/PowerToysRun-RandomGen) | [ruslanlap](https://github.com/ruslanlap) | 🎲 Generate random data instantly with a single keystroke. Perfect for developers, testers, designers, and anyone who needs quick access to random data. Features include secure passwords, PINs, names, business data, dates, numbers, GUIDs, color codes, and more. Especially useful for designers who need random color codes and placeholder content. |
|
||||
|
||||
## Extending software plugins
|
||||
|
||||
|
||||
@@ -233,15 +233,6 @@
|
||||
</RegistryKey>
|
||||
<File Id="GcodePreviewHandler_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)\$(var.Language)\PowerToys.GcodePreviewHandler.resources.dll" />
|
||||
</Component>
|
||||
<Component
|
||||
Id="BgcodePreviewHandler_$(var.IdSafeLanguage)_Component"
|
||||
Directory="Resource$(var.IdSafeLanguage)INSTALLFOLDER"
|
||||
Guid="$(var.CompGUIDPrefix)07">
|
||||
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
|
||||
<RegistryValue Type="string" Name="BgcodePreviewHandler_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes"/>
|
||||
</RegistryKey>
|
||||
<File Id="BgcodePreviewHandler_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)\$(var.Language)\PowerToys.BgcodePreviewHandler.resources.dll" />
|
||||
</Component>
|
||||
<!-- PowerToys Run aka Launcher plugin resources -->
|
||||
<Component
|
||||
Id="Launcher_Calculator_$(var.IdSafeLanguage)_Component"
|
||||
@@ -467,6 +458,15 @@
|
||||
</RegistryKey>
|
||||
<File Id="WorkspacesEditor_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)\$(var.Language)\PowerToys.WorkspacesEditor.resources.dll" />
|
||||
</Component>
|
||||
<Component
|
||||
Id="BgcodePreviewHandler_$(var.IdSafeLanguage)_Component"
|
||||
Directory="Resource$(var.IdSafeLanguage)INSTALLFOLDER"
|
||||
Guid="$(var.CompGUIDPrefix)22">
|
||||
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
|
||||
<RegistryValue Type="string" Name="BgcodePreviewHandler_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes"/>
|
||||
</RegistryKey>
|
||||
<File Id="BgcodePreviewHandler_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)\$(var.Language)\PowerToys.BgcodePreviewHandler.resources.dll" />
|
||||
</Component>
|
||||
<?undef IdSafeLanguage?>
|
||||
<?undef CompGUIDPrefix?>
|
||||
<?endforeach?>
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<clear />
|
||||
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
|
||||
<add key="PowerToysPublicDependencies" value="https://pkgs.dev.azure.com/shine-oss/PowerToys/_packaging/PowerToysPublicDependencies/nuget/v3/index.json" />
|
||||
</packageSources>
|
||||
<packageSourceMapping>
|
||||
<packageSource key="nuget.org">
|
||||
<packageSource key="PowerToysPublicDependencies">
|
||||
<package pattern="*" />
|
||||
</packageSource>
|
||||
</packageSourceMapping>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<CsWinRTAotWarningLevel>2</CsWinRTAotWarningLevel>
|
||||
|
||||
<!-- Suppress DynamicallyAccessedMemberTypes.PublicParameterlessConstructor in fallback code path of Windows SDK projection -->
|
||||
<WarningsNotAsErrors>IL2081;CsWinRT1028;$(WarningsNotAsErrors)</WarningsNotAsErrors>
|
||||
<!-- Suppress CA1416 for Windows-specific APIs that are used in PowerToys which only runs on Windows 10.0.19041.0+ -->
|
||||
<WarningsNotAsErrors>IL2081;CsWinRT1028;CA1416;$(WarningsNotAsErrors)</WarningsNotAsErrors>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
||||
@@ -364,7 +364,7 @@ namespace Microsoft.PowerToys.UITest
|
||||
/// Save UI Element to a PNG file.
|
||||
/// </summary>
|
||||
/// <param name="path">the full path</param>
|
||||
internal void SaveToPngFile(string path)
|
||||
public void SaveToPngFile(string path)
|
||||
{
|
||||
Assert.IsNotNull(this.windowsElement, $"WindowsElement is null in method SaveToPngFile with parameter: path = {path}");
|
||||
this.windowsElement.GetScreenshot().SaveAsFile(path);
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace Microsoft.PowerToys.UITest
|
||||
Runner,
|
||||
Workspaces,
|
||||
PowerRename,
|
||||
CommandPalette,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -104,6 +105,7 @@ namespace Microsoft.PowerToys.UITest
|
||||
[PowerToysModule.Runner] = new ModuleInfo("PowerToys.exe", "PowerToys"),
|
||||
[PowerToysModule.Workspaces] = new ModuleInfo("PowerToys.WorkspacesEditor.exe", "Workspaces Editor"),
|
||||
[PowerToysModule.PowerRename] = new ModuleInfo("PowerToys.PowerRename.exe", "PowerRename", "WinUI3Apps"),
|
||||
[PowerToysModule.CommandPalette] = new ModuleInfo("Microsoft.CmdPal.UI.exe", "PowerToys Command Palette", "WinUI3Apps\\CmdPal"),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -91,15 +91,12 @@ namespace Microsoft.PowerToys.UITest
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exit a exe.
|
||||
/// Exit a exe by Name.
|
||||
/// </summary>
|
||||
/// <param name="appPath">The path to the application executable.</param>
|
||||
public void ExitExe(string appPath)
|
||||
/// <param name="processName">The path to the application executable.</param>
|
||||
public void ExitExeByName(string processName)
|
||||
{
|
||||
// Exit Exe
|
||||
string exeName = Path.GetFileNameWithoutExtension(appPath);
|
||||
|
||||
Process[] processes = Process.GetProcessesByName(exeName);
|
||||
Process[] processes = Process.GetProcessesByName(processName);
|
||||
foreach (Process process in processes)
|
||||
{
|
||||
try
|
||||
@@ -114,6 +111,18 @@ namespace Microsoft.PowerToys.UITest
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exit a exe.
|
||||
/// </summary>
|
||||
/// <param name="appPath">The path to the application executable.</param>
|
||||
public void ExitExe(string appPath)
|
||||
{
|
||||
// Exit Exe
|
||||
string exeName = Path.GetFileNameWithoutExtension(appPath);
|
||||
|
||||
ExitExeByName(exeName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts a new exe and takes control of it.
|
||||
/// </summary>
|
||||
@@ -122,26 +131,34 @@ namespace Microsoft.PowerToys.UITest
|
||||
public void StartExe(string appPath, string[]? args = null)
|
||||
{
|
||||
var opts = new AppiumOptions();
|
||||
opts.AddAdditionalCapability("app", appPath);
|
||||
|
||||
if (args != null && args.Length > 0)
|
||||
if (scope == PowerToysModule.PowerToysSettings)
|
||||
{
|
||||
// Build command line arguments string
|
||||
string argsString = string.Join(" ", args.Select(arg =>
|
||||
TryLaunchPowerToysSettings(opts);
|
||||
}
|
||||
else
|
||||
{
|
||||
opts.AddAdditionalCapability("app", appPath);
|
||||
|
||||
if (args != null && args.Length > 0)
|
||||
{
|
||||
// Quote arguments that contain spaces
|
||||
if (arg.Contains(' '))
|
||||
// Build command line arguments string
|
||||
string argsString = string.Join(" ", args.Select(arg =>
|
||||
{
|
||||
return $"\"{arg}\"";
|
||||
}
|
||||
// Quote arguments that contain spaces
|
||||
if (arg.Contains(' '))
|
||||
{
|
||||
return $"\"{arg}\"";
|
||||
}
|
||||
|
||||
return arg;
|
||||
}));
|
||||
return arg;
|
||||
}));
|
||||
|
||||
opts.AddAdditionalCapability("appArguments", argsString);
|
||||
opts.AddAdditionalCapability("appArguments", argsString);
|
||||
}
|
||||
}
|
||||
|
||||
this.Driver = NewWindowsDriver(opts);
|
||||
Driver = NewWindowsDriver(opts);
|
||||
}
|
||||
|
||||
private void TryLaunchPowerToysSettings(AppiumOptions opts)
|
||||
@@ -150,15 +167,18 @@ namespace Microsoft.PowerToys.UITest
|
||||
|
||||
var runnerProcessInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = locationPath + this.runnerPath,
|
||||
FileName = locationPath + runnerPath,
|
||||
Verb = "runas",
|
||||
Arguments = "--open-settings",
|
||||
};
|
||||
|
||||
this.ExitExe(runnerProcessInfo.FileName);
|
||||
this.runner = Process.Start(runnerProcessInfo);
|
||||
ExitExe(runnerProcessInfo.FileName);
|
||||
runner = Process.Start(runnerProcessInfo);
|
||||
Thread.Sleep(5000);
|
||||
|
||||
// Exit CmdPal UI before launching new process if use installer for test
|
||||
ExitExeByName("Microsoft.CmdPal.UI");
|
||||
|
||||
if (root != null)
|
||||
{
|
||||
const int maxRetries = 5;
|
||||
@@ -168,7 +188,7 @@ namespace Microsoft.PowerToys.UITest
|
||||
for (int attempt = 1; attempt <= maxRetries; attempt++)
|
||||
{
|
||||
var settingsWindow = ApiHelper.FindDesktopWindowHandler(
|
||||
new[] { windowName, AdministratorPrefix + windowName });
|
||||
[windowName, AdministratorPrefix + windowName]);
|
||||
|
||||
if (settingsWindow.Count > 0)
|
||||
{
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
<PackageReference Include="System.Net.Http" />
|
||||
<PackageReference Include="System.Private.Uri" />
|
||||
<PackageReference Include="System.Text.RegularExpressions" />
|
||||
<PackageReference Include="CoenM.ImageSharp.ImageHash" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -22,6 +22,8 @@ namespace Microsoft.PowerToys.UITest
|
||||
|
||||
public bool IsInPipeline { get; }
|
||||
|
||||
public string? ScreenshotDirectory { get; set; }
|
||||
|
||||
public static MonitorInfoData.ParamsWrapper MonitorInfoData { get; set; } = new MonitorInfoData.ParamsWrapper() { Monitors = new List<MonitorInfoData.MonitorInfoDataWrapper>() };
|
||||
|
||||
private readonly PowerToysModule scope;
|
||||
@@ -29,7 +31,6 @@ namespace Microsoft.PowerToys.UITest
|
||||
private readonly string[]? commandLineArgs;
|
||||
private SessionHelper? sessionHelper;
|
||||
private System.Threading.Timer? screenshotTimer;
|
||||
private string? screenshotDirectory;
|
||||
|
||||
public UITestBase(PowerToysModule scope = PowerToysModule.PowerToysSettings, WindowSize size = WindowSize.UnSpecified, string[]? commandLineArgs = null)
|
||||
{
|
||||
@@ -58,11 +59,11 @@ namespace Microsoft.PowerToys.UITest
|
||||
CloseOtherApplications();
|
||||
if (IsInPipeline)
|
||||
{
|
||||
screenshotDirectory = Path.Combine(this.TestContext.TestResultsDirectory ?? string.Empty, "UITestScreenshots_" + Guid.NewGuid().ToString());
|
||||
Directory.CreateDirectory(screenshotDirectory);
|
||||
ScreenshotDirectory = Path.Combine(this.TestContext.TestResultsDirectory ?? string.Empty, "UITestScreenshots_" + Guid.NewGuid().ToString());
|
||||
Directory.CreateDirectory(ScreenshotDirectory);
|
||||
|
||||
// Take screenshot every 1 second
|
||||
screenshotTimer = new System.Threading.Timer(ScreenCapture.TimerCallback, screenshotDirectory, TimeSpan.Zero, TimeSpan.FromMilliseconds(1000));
|
||||
screenshotTimer = new System.Threading.Timer(ScreenCapture.TimerCallback, ScreenshotDirectory, TimeSpan.Zero, TimeSpan.FromMilliseconds(1000));
|
||||
|
||||
// Escape Popups before starting
|
||||
System.Windows.Forms.SendKeys.SendWait("{ESC}");
|
||||
@@ -415,9 +416,9 @@ namespace Microsoft.PowerToys.UITest
|
||||
|
||||
protected void AddScreenShotsToTestResultsDirectory()
|
||||
{
|
||||
if (screenshotDirectory != null)
|
||||
if (ScreenshotDirectory != null)
|
||||
{
|
||||
foreach (string file in Directory.GetFiles(screenshotDirectory))
|
||||
foreach (string file in Directory.GetFiles(ScreenshotDirectory))
|
||||
{
|
||||
this.TestContext.AddResultFile(file);
|
||||
}
|
||||
@@ -627,6 +628,23 @@ namespace Microsoft.PowerToys.UITest
|
||||
Console.WriteLine($"Failed to change display resolution. Error code: {result}");
|
||||
}
|
||||
}
|
||||
|
||||
// Windows API for moving windows
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags);
|
||||
|
||||
private const uint SWPNOSIZE = 0x0001;
|
||||
private const uint SWPNOZORDER = 0x0004;
|
||||
|
||||
public static void MoveWindow(Element window, int x, int y)
|
||||
{
|
||||
var windowHandle = IntPtr.Parse(window.GetAttribute("NativeWindowHandle") ?? "0", System.Globalization.CultureInfo.InvariantCulture);
|
||||
if (windowHandle != IntPtr.Zero)
|
||||
{
|
||||
SetWindowPos(windowHandle, IntPtr.Zero, x, y, 0, 0, SWPNOSIZE | SWPNOZORDER);
|
||||
Task.Delay(500).Wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,11 @@ using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using CoenM.ImageHash;
|
||||
using CoenM.ImageHash.HashAlgorithms;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
|
||||
namespace Microsoft.PowerToys.UITest
|
||||
{
|
||||
@@ -127,34 +131,75 @@ namespace Microsoft.PowerToys.UITest
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test if two images are equal bit-by-bit
|
||||
/// Test if two images are equal using ImageHash comparison
|
||||
/// </summary>
|
||||
/// <param name="baselineImage">baseline image</param>
|
||||
/// <param name="testImage">test image</param>
|
||||
/// <returns>true if are equal,otherwise false</returns>
|
||||
private static bool AreEqual(Bitmap baselineImage, Bitmap testImage)
|
||||
{
|
||||
if (baselineImage.Width != testImage.Width || baselineImage.Height != testImage.Height)
|
||||
try
|
||||
{
|
||||
return false;
|
||||
// Define a threshold for similarity percentage
|
||||
const int SimilarityThreshold = 95;
|
||||
|
||||
// Use CoenM.ImageHash for perceptual hash comparison
|
||||
var hashAlgorithm = new AverageHash();
|
||||
|
||||
// Convert System.Drawing.Bitmap to SixLabors.ImageSharp.Image
|
||||
using var baselineImageSharp = ConvertBitmapToImageSharp(baselineImage);
|
||||
using var testImageSharp = ConvertBitmapToImageSharp(testImage);
|
||||
|
||||
// Calculate hashes for both images
|
||||
var baselineHash = hashAlgorithm.Hash(baselineImageSharp);
|
||||
var testHash = hashAlgorithm.Hash(testImageSharp);
|
||||
|
||||
// Compare hashes using CompareHash method
|
||||
// Returns similarity percentage (0-100, where 100 is identical)
|
||||
var similarity = CompareHash.Similarity(baselineHash, testHash);
|
||||
|
||||
// Consider images equal if similarity is very high
|
||||
// Allow for minor rendering differences (threshold can be adjusted)
|
||||
return similarity >= SimilarityThreshold; // 95% similarity threshold
|
||||
}
|
||||
|
||||
// WinAppDriver sometimes adds a border to the screenshot (around 2 pix width), and it is not always consistent.
|
||||
// So we exclude the border when comparing the images, and usually it is the edge of the windows, won't affect the comparison.
|
||||
int excludeBorderWidth = 5, excludeBorderHeight = 5;
|
||||
|
||||
for (int x = excludeBorderWidth; x < baselineImage.Width - excludeBorderWidth; x++)
|
||||
catch
|
||||
{
|
||||
for (int y = excludeBorderHeight; y < baselineImage.Height - excludeBorderHeight; y++)
|
||||
// Fallback to pixel-by-pixel comparison if hash comparison fails
|
||||
if (baselineImage.Width != testImage.Width || baselineImage.Height != testImage.Height)
|
||||
{
|
||||
if (!VisualHelper.PixIsSame(baselineImage.GetPixel(x, y), testImage.GetPixel(x, y)))
|
||||
return false;
|
||||
}
|
||||
|
||||
// WinAppDriver sometimes adds a border to the screenshot (around 2 pix width), and it is not always consistent.
|
||||
// So we exclude the border when comparing the images, and usually it is the edge of the windows, won't affect the comparison.
|
||||
int excludeBorderWidth = 5, excludeBorderHeight = 5;
|
||||
|
||||
for (int x = excludeBorderWidth; x < baselineImage.Width - excludeBorderWidth; x++)
|
||||
{
|
||||
for (int y = excludeBorderHeight; y < baselineImage.Height - excludeBorderHeight; y++)
|
||||
{
|
||||
return false;
|
||||
if (!VisualHelper.PixIsSame(baselineImage.GetPixel(x, y), testImage.GetPixel(x, y)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert System.Drawing.Bitmap to SixLabors.ImageSharp.Image
|
||||
/// </summary>
|
||||
/// <param name="bitmap">The bitmap to convert</param>
|
||||
/// <returns>ImageSharp Image</returns>
|
||||
private static Image<Rgba32> ConvertBitmapToImageSharp(Bitmap bitmap)
|
||||
{
|
||||
using var memoryStream = new MemoryStream();
|
||||
bitmap.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Png);
|
||||
memoryStream.Position = 0;
|
||||
return SixLabors.ImageSharp.Image.Load<Rgba32>(memoryStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,13 +19,13 @@ public interface IExtensionService
|
||||
|
||||
Task SignalStopExtensionsAsync();
|
||||
|
||||
public event TypedEventHandler<IExtensionService, IEnumerable<IExtensionWrapper>>? OnExtensionAdded;
|
||||
event TypedEventHandler<IExtensionService, IEnumerable<IExtensionWrapper>>? OnExtensionAdded;
|
||||
|
||||
public event TypedEventHandler<IExtensionService, IEnumerable<IExtensionWrapper>>? OnExtensionRemoved;
|
||||
event TypedEventHandler<IExtensionService, IEnumerable<IExtensionWrapper>>? OnExtensionRemoved;
|
||||
|
||||
public void EnableExtension(string extensionUniqueId);
|
||||
void EnableExtension(string extensionUniqueId);
|
||||
|
||||
public void DisableExtension(string extensionUniqueId);
|
||||
void DisableExtension(string extensionUniqueId);
|
||||
|
||||
///// <summary>
|
||||
///// Gets a boolean indicating whether the extension was disabled due to the corresponding Windows optional feature
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
// 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.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using ManagedCommon;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using Windows.Foundation;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public abstract partial class AppExtensionHost : IExtensionHost
|
||||
{
|
||||
private static readonly GlobalLogPageContext _globalLogPageContext = new();
|
||||
|
||||
private static ulong _hostingHwnd;
|
||||
|
||||
public static ObservableCollection<LogMessageViewModel> LogMessages { get; } = [];
|
||||
|
||||
public ulong HostingHwnd => _hostingHwnd;
|
||||
|
||||
public string LanguageOverride => string.Empty;
|
||||
|
||||
public ObservableCollection<StatusMessageViewModel> StatusMessages { get; } = [];
|
||||
|
||||
public static void SetHostHwnd(ulong hostHwnd) => _hostingHwnd = hostHwnd;
|
||||
|
||||
public void DebugLog(string message)
|
||||
{
|
||||
#if DEBUG
|
||||
this.ProcessLogMessage(new LogMessage(message));
|
||||
#endif
|
||||
}
|
||||
|
||||
public IAsyncAction HideStatus(IStatusMessage? message)
|
||||
{
|
||||
if (message == null)
|
||||
{
|
||||
return Task.CompletedTask.AsAsyncAction();
|
||||
}
|
||||
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
ProcessHideStatusMessage(message);
|
||||
});
|
||||
return Task.CompletedTask.AsAsyncAction();
|
||||
}
|
||||
|
||||
public void Log(string message)
|
||||
{
|
||||
this.ProcessLogMessage(new LogMessage(message));
|
||||
}
|
||||
|
||||
public IAsyncAction LogMessage(ILogMessage? message)
|
||||
{
|
||||
if (message == null)
|
||||
{
|
||||
return Task.CompletedTask.AsAsyncAction();
|
||||
}
|
||||
|
||||
Logger.LogDebug(message.Message);
|
||||
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
ProcessLogMessage(message);
|
||||
});
|
||||
|
||||
// We can't just make a LogMessageViewModel : ExtensionObjectViewModel
|
||||
// because we don't necessarily know the page context. Butts.
|
||||
return Task.CompletedTask.AsAsyncAction();
|
||||
}
|
||||
|
||||
public void ProcessHideStatusMessage(IStatusMessage message)
|
||||
{
|
||||
Task.Factory.StartNew(
|
||||
() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var vm = StatusMessages.Where(messageVM => messageVM.Model.Unsafe == message).FirstOrDefault();
|
||||
if (vm != null)
|
||||
{
|
||||
StatusMessages.Remove(vm);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
},
|
||||
CancellationToken.None,
|
||||
TaskCreationOptions.None,
|
||||
_globalLogPageContext.Scheduler);
|
||||
}
|
||||
|
||||
public void ProcessLogMessage(ILogMessage message)
|
||||
{
|
||||
var vm = new LogMessageViewModel(message, _globalLogPageContext);
|
||||
vm.SafeInitializePropertiesSynchronous();
|
||||
|
||||
Task.Factory.StartNew(
|
||||
() =>
|
||||
{
|
||||
LogMessages.Add(vm);
|
||||
},
|
||||
CancellationToken.None,
|
||||
TaskCreationOptions.None,
|
||||
_globalLogPageContext.Scheduler);
|
||||
}
|
||||
|
||||
public void ProcessStatusMessage(IStatusMessage message, StatusContext context)
|
||||
{
|
||||
// If this message is already in the list of messages, just bring it to the top
|
||||
var oldVm = StatusMessages.Where(messageVM => messageVM.Model.Unsafe == message).FirstOrDefault();
|
||||
if (oldVm != null)
|
||||
{
|
||||
Task.Factory.StartNew(
|
||||
() =>
|
||||
{
|
||||
StatusMessages.Remove(oldVm);
|
||||
StatusMessages.Add(oldVm);
|
||||
},
|
||||
CancellationToken.None,
|
||||
TaskCreationOptions.None,
|
||||
_globalLogPageContext.Scheduler);
|
||||
return;
|
||||
}
|
||||
|
||||
var vm = new StatusMessageViewModel(message, new(_globalLogPageContext));
|
||||
vm.SafeInitializePropertiesSynchronous();
|
||||
|
||||
Task.Factory.StartNew(
|
||||
() =>
|
||||
{
|
||||
StatusMessages.Add(vm);
|
||||
},
|
||||
CancellationToken.None,
|
||||
TaskCreationOptions.None,
|
||||
_globalLogPageContext.Scheduler);
|
||||
}
|
||||
|
||||
public IAsyncAction ShowStatus(IStatusMessage? message, StatusContext context)
|
||||
{
|
||||
if (message == null)
|
||||
{
|
||||
return Task.CompletedTask.AsAsyncAction();
|
||||
}
|
||||
|
||||
Debug.WriteLine(message.Message);
|
||||
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
ProcessStatusMessage(message, context);
|
||||
});
|
||||
|
||||
return Task.CompletedTask.AsAsyncAction();
|
||||
}
|
||||
|
||||
public abstract string? GetExtensionDisplayName();
|
||||
}
|
||||
|
||||
public interface IAppHostService
|
||||
{
|
||||
AppExtensionHost GetDefaultHost();
|
||||
|
||||
AppExtensionHost GetHostForCommand(object? context, AppExtensionHost? currentHost);
|
||||
}
|
||||
@@ -1,15 +1,15 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.ObjectModel;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using Windows.System;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public partial class CommandBarViewModel : ObservableObject,
|
||||
IRecipient<UpdateCommandBarMessage>
|
||||
@@ -149,6 +149,7 @@ public partial class CommandBarViewModel : ObservableObject,
|
||||
|
||||
if (command.HasMoreCommands)
|
||||
{
|
||||
WeakReferenceMessenger.Default.Send<PerformCommandMessage>(new(command.Command.Model, command.Model));
|
||||
return ContextKeybindingResult.KeepOpen;
|
||||
}
|
||||
else
|
||||
@@ -1,13 +1,11 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public partial class CommandContextItemViewModel(ICommandContextItem contextItem, WeakReference<IPageContext> context) : CommandItemViewModel(new(contextItem), context), IContextItemViewModel
|
||||
{
|
||||
@@ -1,13 +1,13 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.CmdPal.UI.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public partial class CommandItemViewModel : ExtensionObjectViewModel, ICommandBarContext
|
||||
{
|
||||
@@ -1,11 +1,11 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public partial class CommandViewModel : ExtensionObjectViewModel
|
||||
{
|
||||
@@ -1,11 +1,11 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public partial class ConfirmResultViewModel(IConfirmationArgs _args, WeakReference<IPageContext> context) :
|
||||
ExtensionObjectViewModel(context)
|
||||
@@ -7,12 +7,12 @@ using System.Diagnostics.CodeAnalysis;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public partial class ContentPageViewModel : PageViewModel, ICommandBarContext
|
||||
{
|
||||
@@ -47,7 +47,7 @@ public partial class ContentPageViewModel : PageViewModel, ICommandBarContext
|
||||
|
||||
// Remember - "observable" properties from the model (via PropChanged)
|
||||
// cannot be marked [ObservableProperty]
|
||||
public ContentPageViewModel(IContentPage model, TaskScheduler scheduler, CommandPaletteHost host)
|
||||
public ContentPageViewModel(IContentPage model, TaskScheduler scheduler, AppExtensionHost host)
|
||||
: base(model, scheduler, host)
|
||||
{
|
||||
_model = new(model);
|
||||
@@ -91,16 +91,12 @@ public partial class ContentPageViewModel : PageViewModel, ICommandBarContext
|
||||
});
|
||||
}
|
||||
|
||||
public static ContentViewModel? ViewModelFromContent(IContent content, WeakReference<IPageContext> context)
|
||||
public virtual ContentViewModel? ViewModelFromContent(IContent content, WeakReference<IPageContext> context)
|
||||
{
|
||||
ContentViewModel? viewModel = content switch
|
||||
{
|
||||
IFormContent form => new ContentFormViewModel(form, context),
|
||||
IMarkdownContent markdown => new ContentMarkdownViewModel(markdown, context),
|
||||
ITreeContent tree => new ContentTreeViewModel(tree, context),
|
||||
_ => null,
|
||||
};
|
||||
return viewModel;
|
||||
// The core ContentPageViewModel doesn't actually handle any content,
|
||||
// so we just return null here.
|
||||
// The real content is handled by the derived class CommandPaletteContentPageViewModel
|
||||
return null;
|
||||
}
|
||||
|
||||
public override void InitializeProperties()
|
||||
@@ -115,15 +111,15 @@ public partial class ContentPageViewModel : PageViewModel, ICommandBarContext
|
||||
|
||||
Commands = model.Commands
|
||||
.ToList()
|
||||
.Select(item =>
|
||||
.Select<IContextItem, IContextItemViewModel>(item =>
|
||||
{
|
||||
if (item is CommandContextItem contextItem)
|
||||
{
|
||||
return new CommandContextItemViewModel(contextItem, PageContext) as IContextItemViewModel;
|
||||
return new CommandContextItemViewModel(contextItem, PageContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new SeparatorContextItemViewModel() as IContextItemViewModel;
|
||||
return new SeparatorContextItemViewModel();
|
||||
}
|
||||
})
|
||||
.ToList();
|
||||
@@ -182,7 +178,7 @@ public partial class ContentPageViewModel : PageViewModel, ICommandBarContext
|
||||
}
|
||||
else
|
||||
{
|
||||
return new SeparatorContextItemViewModel() as IContextItemViewModel;
|
||||
return new SeparatorContextItemViewModel();
|
||||
}
|
||||
})
|
||||
.ToList();
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 Microsoft.CmdPal.UI.ViewModels;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public abstract partial class ContentViewModel(WeakReference<IPageContext> context) :
|
||||
ExtensionObjectViewModel(context)
|
||||
@@ -5,13 +5,13 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using Microsoft.Diagnostics.Utilities;
|
||||
using Windows.System;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public partial class ContextMenuViewModel : ObservableObject,
|
||||
IRecipient<UpdateCommandBarMessage>,
|
||||
@@ -22,15 +22,8 @@ public partial class ContextMenuViewModel : ObservableObject,
|
||||
get => field;
|
||||
set
|
||||
{
|
||||
if (field != null)
|
||||
{
|
||||
field.PropertyChanged -= SelectedItemPropertyChanged;
|
||||
}
|
||||
|
||||
field = value;
|
||||
SetSelectedItem(value);
|
||||
|
||||
OnPropertyChanged(nameof(SelectedItem));
|
||||
UpdateContextItems();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,33 +61,6 @@ public partial class ContextMenuViewModel : ObservableObject,
|
||||
OnPropertyChanged(nameof(FilterOnTop));
|
||||
}
|
||||
|
||||
private void SetSelectedItem(ICommandBarContext? value)
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
value.PropertyChanged += SelectedItemPropertyChanged;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SelectedItem != null)
|
||||
{
|
||||
SelectedItem.PropertyChanged -= SelectedItemPropertyChanged;
|
||||
}
|
||||
}
|
||||
|
||||
UpdateContextItems();
|
||||
}
|
||||
|
||||
private void SelectedItemPropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
{
|
||||
switch (e.PropertyName)
|
||||
{
|
||||
case nameof(SelectedItem.HasMoreCommands):
|
||||
UpdateContextItems();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateContextItems()
|
||||
{
|
||||
if (SelectedItem != null)
|
||||
@@ -1,11 +1,11 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public partial class DetailsCommandsViewModel(
|
||||
IDetailsElement _detailsElement,
|
||||
@@ -1,11 +1,11 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public abstract partial class DetailsDataViewModel(IPageContext context) : ExtensionObjectViewModel(context)
|
||||
{
|
||||
@@ -1,11 +1,11 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public abstract partial class DetailsElementViewModel(IDetailsElement _detailsElement, WeakReference<IPageContext> context) : ExtensionObjectViewModel(context)
|
||||
{
|
||||
@@ -1,11 +1,11 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public partial class DetailsLinkViewModel(
|
||||
IDetailsElement _detailsElement,
|
||||
@@ -1,11 +1,11 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public partial class DetailsSeparatorViewModel(
|
||||
IDetailsElement _detailsElement,
|
||||
@@ -1,11 +1,11 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public partial class DetailsTagsViewModel(
|
||||
IDetailsElement _detailsElement,
|
||||
@@ -1,11 +1,11 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public partial class DetailsViewModel(IDetails _details, WeakReference<IPageContext> context) : ExtensionObjectViewModel(context)
|
||||
{
|
||||
@@ -1,11 +1,11 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 CommunityToolkit.Mvvm.ComponentModel;
|
||||
using ManagedCommon;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public abstract partial class ExtensionObjectViewModel : ObservableObject
|
||||
{
|
||||
@@ -2,7 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public class GlobalLogPageContext : IPageContext
|
||||
{
|
||||
@@ -8,7 +8,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public interface IContextItemViewModel
|
||||
{
|
||||
@@ -0,0 +1,37 @@
|
||||
// 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 Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public interface IRootPageService
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the root page of the command palette. Return any IPage implementation that
|
||||
/// represents the root view of this instance of the command palette.
|
||||
/// </summary>
|
||||
Microsoft.CommandPalette.Extensions.IPage GetRootPage();
|
||||
|
||||
/// <summary>
|
||||
/// Pre-loads any necessary data or state before the root page is loaded.
|
||||
/// This will be awaited before the root page and the user can do anything,
|
||||
/// so ideally it should be quick and not block the UI thread for long.
|
||||
/// </summary>
|
||||
Task PreLoadAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Do any loading work that can be done after the root page is loaded and
|
||||
/// displayed to the user.
|
||||
/// This is run asynchronously, on a background thread.
|
||||
/// </summary>
|
||||
Task PostLoadRootPageAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Called when a command is performed. The context is the
|
||||
/// sender context for the invoked command. This is typically the IListItem
|
||||
/// or ICommandContextItem that was used to invoke the command.
|
||||
/// </summary>
|
||||
void OnPerformCommand(object? context, bool topLevel, AppExtensionHost? currentHost);
|
||||
|
||||
void GoHome();
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Windows.Storage.Streams;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public partial class IconDataViewModel : ObservableObject, IIconData
|
||||
{
|
||||
@@ -1,12 +1,12 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public partial class IconInfoViewModel : ObservableObject, IIconInfo
|
||||
{
|
||||
@@ -1,13 +1,13 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.Diagnostics.CodeAnalysis;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public partial class ListItemViewModel(IListItem model, WeakReference<IPageContext> context)
|
||||
: CommandItemViewModel(new(model), context)
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.
|
||||
|
||||
@@ -6,13 +6,13 @@ using System.Collections.ObjectModel;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using Windows.Foundation;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public partial class ListViewModel : PageViewModel, IDisposable
|
||||
{
|
||||
@@ -72,7 +72,7 @@ public partial class ListViewModel : PageViewModel, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
public ListViewModel(IListPage model, TaskScheduler scheduler, CommandPaletteHost host)
|
||||
public ListViewModel(IListPage model, TaskScheduler scheduler, AppExtensionHost host)
|
||||
: base(model, scheduler, host)
|
||||
{
|
||||
_model = new(model);
|
||||
@@ -158,10 +158,7 @@ public partial class ListViewModel : PageViewModel, IDisposable
|
||||
}
|
||||
|
||||
// Cancel any ongoing search
|
||||
if (_cancellationTokenSource != null)
|
||||
{
|
||||
_cancellationTokenSource.Cancel();
|
||||
}
|
||||
_cancellationTokenSource?.Cancel();
|
||||
|
||||
lock (_listLock)
|
||||
{
|
||||
@@ -1,15 +1,15 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public partial class LoadingPageViewModel : PageViewModel
|
||||
{
|
||||
public LoadingPageViewModel(IPage? model, TaskScheduler scheduler)
|
||||
: base(model, scheduler, CommandPaletteHost.Instance)
|
||||
public LoadingPageViewModel(IPage? model, TaskScheduler scheduler, AppExtensionHost host)
|
||||
: base(model, scheduler, host)
|
||||
{
|
||||
ModelIsLoading = true;
|
||||
IsInitialized = false;
|
||||
@@ -2,10 +2,10 @@
|
||||
// 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.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public partial class LogMessageViewModel : ExtensionObjectViewModel
|
||||
{
|
||||
@@ -13,8 +13,6 @@ public partial class LogMessageViewModel : ExtensionObjectViewModel
|
||||
|
||||
public string Message { get; private set; } = string.Empty;
|
||||
|
||||
public string ExtensionPfn { get; set; } = string.Empty;
|
||||
|
||||
public LogMessageViewModel(ILogMessage message, IPageContext context)
|
||||
: base(context)
|
||||
{
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
/// <summary>
|
||||
/// Used to perform a list item's secondary command when the user presses ctrl+enter in the search box
|
||||
@@ -2,7 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
/// <summary>
|
||||
/// Used to perform a list item's command when the user presses enter in the search box
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
public record BeginInvokeMessage;
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
public record ClearSearchMessage()
|
||||
{
|
||||
@@ -2,7 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
/// <summary>
|
||||
/// Used to announce that a context menu should close
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
public record CmdPalInvokeResultMessage(Microsoft.CommandPalette.Extensions.CommandResultKind Kind);
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
public record DismissMessage()
|
||||
{
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
public record FocusSearchBoxMessage()
|
||||
{
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
public record GoBackMessage(bool WithAnimation = true, bool FocusSearch = true)
|
||||
{
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
// TODO! sticking these properties here feels like leaking the UI into the models
|
||||
public record GoHomeMessage(bool WithAnimation = true, bool FocusSearch = true)
|
||||
@@ -1,11 +1,11 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
public record HandleCommandResultMessage(ExtensionObject<ICommandResult> Result)
|
||||
{
|
||||
@@ -1,11 +1,11 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
public record HideDetailsMessage()
|
||||
{
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
public record HotkeySummonMessage(string CommandId, IntPtr Hwnd)
|
||||
{
|
||||
@@ -1,11 +1,11 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
public record LaunchUriMessage(Uri Uri)
|
||||
{
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
public record NavigateBackMessage(bool FromBackspace = false)
|
||||
{
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
/// <summary>
|
||||
/// Used to navigate to the next command in the page when pressing the Down key in the SearchBox.
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
/// <summary>
|
||||
/// Used to navigate to the previous command in the page when pressing the Down key in the SearchBox.
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
public record NavigateToPageMessage(PageViewModel Page, bool WithAnimation)
|
||||
{
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.
|
||||
|
||||
@@ -6,7 +6,7 @@ using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||
using Windows.Foundation;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
/// <summary>
|
||||
/// Used to announce the context menu should open
|
||||
@@ -1,10 +1,8 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.CmdPal.UI.ViewModels.BuiltinCommands;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
public record OpenSettingsMessage()
|
||||
{
|
||||
@@ -1,11 +1,11 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
/// <summary>
|
||||
/// Used to do a command - navigate to a page or invoke it
|
||||
@@ -18,21 +18,12 @@ public record PerformCommandMessage
|
||||
|
||||
public bool WithAnimation { get; set; } = true;
|
||||
|
||||
public CommandPaletteHost? ExtensionHost { get; private set; }
|
||||
|
||||
public PerformCommandMessage(ExtensionObject<ICommand> command)
|
||||
{
|
||||
Command = command;
|
||||
Context = null;
|
||||
}
|
||||
|
||||
public PerformCommandMessage(TopLevelViewModel topLevelCommand)
|
||||
{
|
||||
Command = topLevelCommand.CommandViewModel.Model;
|
||||
Context = null;
|
||||
ExtensionHost = topLevelCommand.ExtensionHost;
|
||||
}
|
||||
|
||||
public PerformCommandMessage(ExtensionObject<ICommand> command, ExtensionObject<IListItem> context)
|
||||
{
|
||||
Command = command;
|
||||
@@ -1,10 +1,8 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.CmdPal.UI.ViewModels.BuiltinCommands;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
/// <summary>
|
||||
/// Message which closes the application. Used by <see cref="QuitCommand"/> via <see cref="BuiltInsCommandProvider"/>.
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
public record ReloadCommandsMessage()
|
||||
{
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
public record SettingsWindowClosedMessage
|
||||
{
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
public record ShowConfirmationMessage(Microsoft.CommandPalette.Extensions.IConfirmationArgs? Args)
|
||||
{
|
||||
@@ -1,11 +1,11 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
public record ShowDetailsMessage(DetailsViewModel Details)
|
||||
{
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
public record ShowToastMessage(string Message)
|
||||
{
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
public record ShowWindowMessage(IntPtr Hwnd)
|
||||
{
|
||||
@@ -1,10 +1,10 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 Windows.System;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
public record TryCommandKeybindingMessage(bool Ctrl, bool Alt, bool Shift, bool Win, VirtualKey Key)
|
||||
{
|
||||
@@ -1,11 +1,11 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.ComponentModel;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
/// <summary>
|
||||
/// Used to update the command bar at the bottom to reflect the commands for a list item
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
public record UpdateFallbackItemsMessage()
|
||||
{
|
||||
@@ -0,0 +1,60 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="..\..\..\Common.Dotnet.CsWinRT.props" />
|
||||
<Import Project="..\..\..\Common.Dotnet.AotCompatibility.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<OutputPath>$(SolutionDir)$(Platform)\$(Configuration)\WinUI3Apps\CmdPal</OutputPath>
|
||||
<!-- For MVVM Toolkit Partial Properties/AOT support -->
|
||||
<LangVersion>preview</LangVersion>
|
||||
<!-- Disable SA1313 for Primary Constructor fields conflict https://learn.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/instance-constructors#primary-constructors -->
|
||||
<NoWarn>SA1313;</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<CsWinRTAotOptimizerEnabled>true</CsWinRTAotOptimizerEnabled>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommunityToolkit.Common" />
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" />
|
||||
|
||||
<PackageReference Include="Microsoft.Windows.CsWin32">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
<PackageReference Include="WyHash" />
|
||||
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Microsoft.CmdPal.Common\Microsoft.CmdPal.Common.csproj" />
|
||||
<ProjectReference Include="..\extensionsdk\Microsoft.CommandPalette.Extensions.Toolkit\Microsoft.CommandPalette.Extensions.Toolkit.csproj" />
|
||||
<ProjectReference Include="..\..\..\common\ManagedCommon\ManagedCommon.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Properties\Resources.Designer.cs">
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<!-- Just mark it as AOT compatible. Do not publish with AOT now. We need fully test before we really publish it as AOT enabled-->
|
||||
<!--<PropertyGroup>
|
||||
<SelfContained>true</SelfContained>
|
||||
<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>
|
||||
<PublishTrimmed>true</PublishTrimmed>
|
||||
<PublishSingleFile>true</PublishSingleFile>
|
||||
--><!-- <DisableRuntimeMarshalling>true</DisableRuntimeMarshalling> --><!--
|
||||
<PublishAot>true</PublishAot>
|
||||
<EnableMsixTooling>true</EnableMsixTooling>
|
||||
</PropertyGroup>-->
|
||||
|
||||
</Project>
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
|
||||
public class ExtensionObject<T>(T? value) // where T : IInspectable
|
||||
{
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"$schema": "https://aka.ms/CsWin32.schema.json",
|
||||
"allowMarshaling": false
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
GetPhysicallyInstalledSystemMemory
|
||||
GlobalMemoryStatusEx
|
||||
GetSystemInfo
|
||||
CoCreateInstance
|
||||
SetForegroundWindow
|
||||
IsIconic
|
||||
RegisterHotKey
|
||||
SetWindowLongPtr
|
||||
CallWindowProc
|
||||
ShowWindow
|
||||
SetForegroundWindow
|
||||
SetFocus
|
||||
SetActiveWindow
|
||||
MonitorFromWindow
|
||||
GetMonitorInfo
|
||||
SHCreateStreamOnFileEx
|
||||
CoAllowSetForegroundWindow
|
||||
SHCreateStreamOnFileEx
|
||||
SHLoadIndirectString
|
||||
@@ -1,14 +1,14 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.ObjectModel;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public partial class PageViewModel : ExtensionObjectViewModel, IPageContext
|
||||
{
|
||||
@@ -43,7 +43,7 @@ public partial class PageViewModel : ExtensionObjectViewModel, IPageContext
|
||||
public bool ShowSuggestion => !string.IsNullOrEmpty(TextToSuggest) && TextToSuggest != Filter;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial CommandPaletteHost ExtensionHost { get; private set; }
|
||||
public partial AppExtensionHost ExtensionHost { get; private set; }
|
||||
|
||||
public bool HasStatusMessage => MostRecentStatusMessage != null;
|
||||
|
||||
@@ -69,7 +69,7 @@ public partial class PageViewModel : ExtensionObjectViewModel, IPageContext
|
||||
|
||||
public IconInfoViewModel Icon { get; protected set; }
|
||||
|
||||
public PageViewModel(IPage? model, TaskScheduler scheduler, CommandPaletteHost extensionHost)
|
||||
public PageViewModel(IPage? model, TaskScheduler scheduler, AppExtensionHost extensionHost)
|
||||
: base((IPageContext?)null)
|
||||
{
|
||||
_pageModel = new(model);
|
||||
@@ -220,7 +220,7 @@ public partial class PageViewModel : ExtensionObjectViewModel, IPageContext
|
||||
{
|
||||
// Set the extensionHint to the Page Title (if we have one, and one not provided).
|
||||
// extensionHint ??= _pageModel?.Unsafe?.Title;
|
||||
extensionHint ??= ExtensionHost.Extension?.ExtensionDisplayName ?? Title;
|
||||
extensionHint ??= ExtensionHost.GetExtensionDisplayName() ?? Title;
|
||||
Task.Factory.StartNew(
|
||||
() =>
|
||||
{
|
||||
@@ -249,7 +249,19 @@ public partial class PageViewModel : ExtensionObjectViewModel, IPageContext
|
||||
|
||||
public interface IPageContext
|
||||
{
|
||||
public void ShowException(Exception ex, string? extensionHint = null);
|
||||
void ShowException(Exception ex, string? extensionHint = null);
|
||||
|
||||
public TaskScheduler Scheduler { get; }
|
||||
TaskScheduler Scheduler { get; }
|
||||
}
|
||||
|
||||
public interface IPageViewModelFactoryService
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new instance of the page view model for the given page type.
|
||||
/// </summary>
|
||||
/// <param name="page">The page for which to create the view model.</param>
|
||||
/// <param name="nested">Indicates whether the page is not the top-level page.</param>
|
||||
/// <param name="host">The command palette host that will host the page (for status messages)</param>
|
||||
/// <returns>A new instance of the page view model.</returns>
|
||||
PageViewModel? TryCreatePageViewModel(IPage page, bool nested, AppExtensionHost host);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// 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;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public class PageViewModelFactory : IPageViewModelFactoryService
|
||||
{
|
||||
private readonly TaskScheduler _scheduler;
|
||||
|
||||
public PageViewModelFactory(TaskScheduler scheduler)
|
||||
{
|
||||
_scheduler = scheduler;
|
||||
}
|
||||
|
||||
public PageViewModel? TryCreatePageViewModel(IPage page, bool nested, AppExtensionHost host)
|
||||
{
|
||||
return page switch
|
||||
{
|
||||
IListPage listPage => new ListViewModel(listPage, _scheduler, host) { IsNested = nested },
|
||||
IContentPage contentPage => new ContentPageViewModel(contentPage, _scheduler, host),
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public partial class ProgressViewModel : ExtensionObjectViewModel
|
||||
{
|
||||
@@ -2,10 +2,10 @@
|
||||
// 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.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.Core.ViewModels;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public partial class SeparatorContextItemViewModel() : IContextItemViewModel, ISeparatorContextItem
|
||||
{
|
||||
@@ -1,28 +1,24 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.Runtime.InteropServices;
|
||||
using System.Runtime.Versioning;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using ManagedCommon;
|
||||
using Microsoft.CmdPal.Common.Services;
|
||||
using Microsoft.CmdPal.UI.ViewModels.MainPage;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using WinRT;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public partial class ShellViewModel : ObservableObject,
|
||||
IRecipient<PerformCommandMessage>
|
||||
{
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly IRootPageService _rootPageService;
|
||||
private readonly IAppHostService _appHostService;
|
||||
private readonly TaskScheduler _scheduler;
|
||||
private readonly IPageViewModelFactoryService _pageViewModelFactory;
|
||||
private readonly Lock _invokeLock = new();
|
||||
private Task? _handleInvokeTask;
|
||||
|
||||
@@ -60,18 +56,24 @@ public partial class ShellViewModel : ObservableObject,
|
||||
}
|
||||
}
|
||||
|
||||
private MainListPage? _mainListPage;
|
||||
private IPage? _rootPage;
|
||||
|
||||
private IExtensionWrapper? _activeExtension;
|
||||
private bool _isNested;
|
||||
|
||||
public bool IsNested { get => _isNested; }
|
||||
|
||||
public ShellViewModel(IServiceProvider serviceProvider, TaskScheduler scheduler)
|
||||
public ShellViewModel(
|
||||
TaskScheduler scheduler,
|
||||
IRootPageService rootPageService,
|
||||
IPageViewModelFactoryService pageViewModelFactory,
|
||||
IAppHostService appHostService)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
_pageViewModelFactory = pageViewModelFactory;
|
||||
_scheduler = scheduler;
|
||||
_currentPage = new LoadingPageViewModel(null, _scheduler);
|
||||
_rootPageService = rootPageService;
|
||||
_appHostService = appHostService;
|
||||
|
||||
_currentPage = new LoadingPageViewModel(null, _scheduler, appHostService.GetDefaultHost());
|
||||
|
||||
// Register to receive messages
|
||||
WeakReferenceMessenger.Default.Register<PerformCommandMessage>(this);
|
||||
@@ -80,24 +82,27 @@ public partial class ShellViewModel : ObservableObject,
|
||||
[RelayCommand]
|
||||
public async Task<bool> LoadAsync()
|
||||
{
|
||||
var tlcManager = _serviceProvider.GetService<TopLevelCommandManager>();
|
||||
await tlcManager!.LoadBuiltinsAsync();
|
||||
// First, do any loading that the root page service needs to do before we can
|
||||
// display the root page. For example, this might include loading
|
||||
// the built-in commands, or loading the settings.
|
||||
await _rootPageService.PreLoadAsync();
|
||||
|
||||
IsLoaded = true;
|
||||
|
||||
// Built-ins have loaded. We can display our page at this point.
|
||||
_mainListPage = new MainListPage(_serviceProvider);
|
||||
WeakReferenceMessenger.Default.Send<PerformCommandMessage>(new(new ExtensionObject<ICommand>(_mainListPage)));
|
||||
// Now that the basics are set up, we can load the root page.
|
||||
_rootPage = _rootPageService.GetRootPage();
|
||||
|
||||
// This sends a message to us to load the root page view model.
|
||||
WeakReferenceMessenger.Default.Send<PerformCommandMessage>(new(new ExtensionObject<ICommand>(_rootPage)));
|
||||
|
||||
// Now that the root page is loaded, do any post-load work that the root page service needs to do.
|
||||
// This runs asynchronously, on a background thread.
|
||||
// This might include starting extensions, for example.
|
||||
// Note: We don't await this, so that we can return immediately.
|
||||
// This is important because we don't want to block the UI thread.
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
// After loading built-ins, and starting navigation, kick off a thread to load extensions.
|
||||
tlcManager.LoadExtensionsCommand.Execute(null);
|
||||
|
||||
await tlcManager.LoadExtensionsCommand.ExecutionTask!;
|
||||
if (tlcManager.LoadExtensionsCommand.ExecutionTask.Status != TaskStatus.RanToCompletion)
|
||||
{
|
||||
// TODO: Handle failure case
|
||||
}
|
||||
await _rootPageService.PostLoadRootPageAsync();
|
||||
});
|
||||
|
||||
return true;
|
||||
@@ -170,19 +175,6 @@ public partial class ShellViewModel : ObservableObject,
|
||||
}
|
||||
}
|
||||
|
||||
public void PerformTopLevelCommand(PerformCommandMessage message)
|
||||
{
|
||||
if (_mainListPage == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.Context is IListItem listItem)
|
||||
{
|
||||
_mainListPage.UpdateHistory(listItem);
|
||||
}
|
||||
}
|
||||
|
||||
public void Receive(PerformCommandMessage message)
|
||||
{
|
||||
PerformCommand(message);
|
||||
@@ -196,69 +188,21 @@ public partial class ShellViewModel : ObservableObject,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CurrentPage.IsNested)
|
||||
{
|
||||
// on the main page here
|
||||
PerformTopLevelCommand(message);
|
||||
}
|
||||
var host = _appHostService.GetHostForCommand(message.Context, CurrentPage.ExtensionHost);
|
||||
|
||||
IExtensionWrapper? extension = null;
|
||||
_rootPageService.OnPerformCommand(message.Context, !CurrentPage.IsNested, host);
|
||||
|
||||
try
|
||||
{
|
||||
// In the case that we're coming from a top-level command, the
|
||||
// current page's host is the global instance. We only really want
|
||||
// to use that as the host of last resort.
|
||||
var pageHost = CurrentPage?.ExtensionHost;
|
||||
if (pageHost == CommandPaletteHost.Instance)
|
||||
{
|
||||
pageHost = null;
|
||||
}
|
||||
|
||||
var messageHost = message.ExtensionHost;
|
||||
|
||||
// Use the host from the current page if it has one, else use the
|
||||
// one specified in the PerformMessage for a top-level command,
|
||||
// else just use the global one.
|
||||
CommandPaletteHost host;
|
||||
|
||||
// Top level items can come through without a Extension set on the
|
||||
// message. In that case, the `Context` is actually the
|
||||
// TopLevelViewModel itself, and we can use that to get at the
|
||||
// extension object.
|
||||
extension = pageHost?.Extension ?? messageHost?.Extension ?? null;
|
||||
if (extension == null && message.Context is TopLevelViewModel topLevelViewModel)
|
||||
{
|
||||
extension = topLevelViewModel.ExtensionHost?.Extension;
|
||||
host = pageHost ?? messageHost ?? topLevelViewModel?.ExtensionHost ?? CommandPaletteHost.Instance;
|
||||
}
|
||||
else
|
||||
{
|
||||
host = pageHost ?? messageHost ?? CommandPaletteHost.Instance;
|
||||
}
|
||||
|
||||
if (extension != null)
|
||||
{
|
||||
if (messageHost != null)
|
||||
{
|
||||
Logger.LogDebug($"Activated top-level command from {extension.ExtensionDisplayName}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogDebug($"Activated command from {extension.ExtensionDisplayName}");
|
||||
}
|
||||
}
|
||||
|
||||
SetActiveExtension(extension);
|
||||
|
||||
if (command is IPage page)
|
||||
{
|
||||
Logger.LogDebug($"Navigating to page");
|
||||
|
||||
var isMainPage = command is MainListPage;
|
||||
var isMainPage = command == _rootPage;
|
||||
_isNested = !isMainPage;
|
||||
|
||||
// Construct our ViewModel of the appropriate type and pass it the UI Thread context.
|
||||
var pageViewModel = GetViewModelForPage(page, !isMainPage, host);
|
||||
var pageViewModel = _pageViewModelFactory.TryCreatePageViewModel(page, _isNested, host);
|
||||
if (pageViewModel == null)
|
||||
{
|
||||
Logger.LogError($"Failed to create ViewModel for page {page.GetType().Name}");
|
||||
@@ -267,8 +211,6 @@ public partial class ShellViewModel : ObservableObject,
|
||||
|
||||
// Kick off async loading of our ViewModel
|
||||
LoadPageViewModel(pageViewModel);
|
||||
_isNested = !isMainPage;
|
||||
|
||||
OnUIThread(() => { WeakReferenceMessenger.Default.Send<UpdateCommandBarMessage>(new(null)); });
|
||||
WeakReferenceMessenger.Default.Send<NavigateToPageMessage>(new(pageViewModel, message.WithAnimation));
|
||||
|
||||
@@ -280,18 +222,18 @@ public partial class ShellViewModel : ObservableObject,
|
||||
Logger.LogDebug($"Invoking command");
|
||||
|
||||
WeakReferenceMessenger.Default.Send<BeginInvokeMessage>();
|
||||
StartInvoke(message, invokable);
|
||||
StartInvoke(message, invokable, host);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// TODO: It would be better to do this as a page exception, rather
|
||||
// than a silent log message.
|
||||
CommandPaletteHost.Instance.Log(ex.Message);
|
||||
host?.Log(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private void StartInvoke(PerformCommandMessage message, IInvokableCommand invokable)
|
||||
private void StartInvoke(PerformCommandMessage message, IInvokableCommand invokable, AppExtensionHost? host)
|
||||
{
|
||||
// TODO GH #525 This needs more better locking.
|
||||
lock (_invokeLock)
|
||||
@@ -304,13 +246,13 @@ public partial class ShellViewModel : ObservableObject,
|
||||
{
|
||||
_handleInvokeTask = Task.Run(() =>
|
||||
{
|
||||
SafeHandleInvokeCommandSynchronous(message, invokable);
|
||||
SafeHandleInvokeCommandSynchronous(message, invokable, host);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SafeHandleInvokeCommandSynchronous(PerformCommandMessage message, IInvokableCommand invokable)
|
||||
private void SafeHandleInvokeCommandSynchronous(PerformCommandMessage message, IInvokableCommand invokable, AppExtensionHost? host)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -330,7 +272,7 @@ public partial class ShellViewModel : ObservableObject,
|
||||
|
||||
// TODO: It would be better to do this as a page exception, rather
|
||||
// than a silent log message.
|
||||
CommandPaletteHost.Instance.Log(ex.Message);
|
||||
host?.Log(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -405,54 +347,9 @@ public partial class ShellViewModel : ObservableObject,
|
||||
}
|
||||
}
|
||||
|
||||
private PageViewModel? GetViewModelForPage(IPage page, bool nested, CommandPaletteHost host)
|
||||
{
|
||||
return page switch
|
||||
{
|
||||
IListPage listPage => new ListViewModel(listPage, _scheduler, host)
|
||||
{
|
||||
IsNested = nested,
|
||||
},
|
||||
IContentPage contentPage => new ContentPageViewModel(contentPage, _scheduler, host),
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
||||
public void SetActiveExtension(IExtensionWrapper? extension)
|
||||
{
|
||||
if (extension != _activeExtension)
|
||||
{
|
||||
// There's not really a CoDisallowSetForegroundWindow, so we don't
|
||||
// need to handle that
|
||||
_activeExtension = extension;
|
||||
|
||||
var extensionWinRtObject = _activeExtension?.GetExtensionObject();
|
||||
if (extensionWinRtObject != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
var winrtObj = (IWinRTObject)extensionWinRtObject;
|
||||
var intPtr = winrtObj.NativeObject.ThisPtr;
|
||||
var hr = Native.CoAllowSetForegroundWindow(intPtr);
|
||||
if (hr != 0)
|
||||
{
|
||||
Logger.LogWarning($"Error giving foreground rights: 0x{hr.Value:X8}");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError(ex.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void GoHome(bool withAnimation = true, bool focusSearch = true)
|
||||
{
|
||||
SetActiveExtension(null);
|
||||
_rootPageService.GoHome();
|
||||
WeakReferenceMessenger.Default.Send<GoHomeMessage>(new(withAnimation, focusSearch));
|
||||
}
|
||||
|
||||
@@ -461,20 +358,6 @@ public partial class ShellViewModel : ObservableObject,
|
||||
WeakReferenceMessenger.Default.Send<GoBackMessage>(new(withAnimation, focusSearch));
|
||||
}
|
||||
|
||||
// You may ask yourself, why aren't we using CsWin32 for this?
|
||||
// The CsWin32 projected version includes some object marshalling, like so:
|
||||
//
|
||||
// HRESULT CoAllowSetForegroundWindow([MarshalAs(UnmanagedType.IUnknown)] object pUnk,...)
|
||||
//
|
||||
// And if you do it like that, then the IForegroundTransfer interface isn't marshalled correctly
|
||||
internal sealed class Native
|
||||
{
|
||||
[DllImport("OLE32.dll", ExactSpelling = true)]
|
||||
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
|
||||
[SupportedOSPlatform("windows5.0")]
|
||||
internal static extern unsafe global::Windows.Win32.Foundation.HRESULT CoAllowSetForegroundWindow(nint pUnk, [Optional] void* lpvReserved);
|
||||
}
|
||||
|
||||
private void OnUIThread(Action action)
|
||||
{
|
||||
_ = Task.Factory.StartNew(
|
||||
@@ -1,11 +1,11 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public partial class StatusMessageViewModel : ExtensionObjectViewModel
|
||||
{
|
||||
@@ -15,14 +15,10 @@ public partial class StatusMessageViewModel : ExtensionObjectViewModel
|
||||
|
||||
public MessageState State { get; private set; } = MessageState.Info;
|
||||
|
||||
public string ExtensionPfn { get; set; } = string.Empty;
|
||||
|
||||
public ProgressViewModel? Progress { get; private set; }
|
||||
|
||||
public bool HasProgress => Progress != null;
|
||||
|
||||
// public bool IsIndeterminate => Progress != null && Progress.IsIndeterminate;
|
||||
// public double ProgressValue => (Progress?.ProgressPercent ?? 0) / 100.0;
|
||||
public StatusMessageViewModel(IStatusMessage message, WeakReference<IPageContext> context)
|
||||
: base(context)
|
||||
{
|
||||
@@ -1,11 +1,11 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public partial class TagViewModel(ITag _tag, WeakReference<IPageContext> context) : ExtensionObjectViewModel(context)
|
||||
{
|
||||
@@ -4,9 +4,9 @@
|
||||
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public partial class ToastViewModel : ObservableObject
|
||||
{
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
@@ -38,7 +38,8 @@ public partial class AliasManager : ObservableObject
|
||||
if (topLevelCommand != null)
|
||||
{
|
||||
WeakReferenceMessenger.Default.Send<ClearSearchMessage>();
|
||||
WeakReferenceMessenger.Default.Send<PerformCommandMessage>(new(topLevelCommand));
|
||||
|
||||
WeakReferenceMessenger.Default.Send<PerformCommandMessage>(topLevelCommand.GetPerformCommandMessage());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 Microsoft.CmdPal.Core.ViewModels;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public partial class CommandPaletteContentPageViewModel : ContentPageViewModel
|
||||
{
|
||||
public CommandPaletteContentPageViewModel(IContentPage model, TaskScheduler scheduler, AppExtensionHost host)
|
||||
: base(model, scheduler, host)
|
||||
{
|
||||
}
|
||||
|
||||
public override ContentViewModel? ViewModelFromContent(IContent content, WeakReference<IPageContext> context)
|
||||
{
|
||||
ContentViewModel? viewModel = content switch
|
||||
{
|
||||
IFormContent form => new ContentFormViewModel(form, context),
|
||||
IMarkdownContent markdown => new ContentMarkdownViewModel(markdown, context),
|
||||
ITreeContent tree => new ContentTreeViewModel(tree, context),
|
||||
_ => null,
|
||||
};
|
||||
return viewModel;
|
||||
}
|
||||
}
|
||||
@@ -1,35 +1,19 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using ManagedCommon;
|
||||
using Microsoft.CmdPal.Common.Services;
|
||||
using Microsoft.CmdPal.Core.ViewModels;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using Windows.Foundation;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public sealed partial class CommandPaletteHost : IExtensionHost
|
||||
public sealed partial class CommandPaletteHost : AppExtensionHost, IExtensionHost
|
||||
{
|
||||
// Static singleton, so that we can access this from anywhere
|
||||
// Post MVVM - this should probably be like, a dependency injection thing.
|
||||
public static CommandPaletteHost Instance { get; } = new();
|
||||
|
||||
private static readonly GlobalLogPageContext _globalLogPageContext = new();
|
||||
|
||||
private static ulong _hostingHwnd;
|
||||
|
||||
public ulong HostingHwnd => _hostingHwnd;
|
||||
|
||||
public string LanguageOverride => string.Empty;
|
||||
|
||||
public static ObservableCollection<LogMessageViewModel> LogMessages { get; } = [];
|
||||
|
||||
public ObservableCollection<StatusMessageViewModel> StatusMessages { get; } = [];
|
||||
|
||||
public IExtensionWrapper? Extension { get; }
|
||||
|
||||
private readonly ICommandProvider? _builtInProvider;
|
||||
@@ -48,145 +32,8 @@ public sealed partial class CommandPaletteHost : IExtensionHost
|
||||
_builtInProvider = builtInProvider;
|
||||
}
|
||||
|
||||
public IAsyncAction ShowStatus(IStatusMessage? message, StatusContext context)
|
||||
public override string? GetExtensionDisplayName()
|
||||
{
|
||||
if (message == null)
|
||||
{
|
||||
return Task.CompletedTask.AsAsyncAction();
|
||||
}
|
||||
|
||||
Debug.WriteLine(message.Message);
|
||||
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
ProcessStatusMessage(message, context);
|
||||
});
|
||||
|
||||
return Task.CompletedTask.AsAsyncAction();
|
||||
}
|
||||
|
||||
public IAsyncAction HideStatus(IStatusMessage? message)
|
||||
{
|
||||
if (message == null)
|
||||
{
|
||||
return Task.CompletedTask.AsAsyncAction();
|
||||
}
|
||||
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
ProcessHideStatusMessage(message);
|
||||
});
|
||||
return Task.CompletedTask.AsAsyncAction();
|
||||
}
|
||||
|
||||
public IAsyncAction LogMessage(ILogMessage? message)
|
||||
{
|
||||
if (message == null)
|
||||
{
|
||||
return Task.CompletedTask.AsAsyncAction();
|
||||
}
|
||||
|
||||
Logger.LogDebug(message.Message);
|
||||
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
ProcessLogMessage(message);
|
||||
});
|
||||
|
||||
// We can't just make a LogMessageViewModel : ExtensionObjectViewModel
|
||||
// because we don't necessarily know the page context. Butts.
|
||||
return Task.CompletedTask.AsAsyncAction();
|
||||
}
|
||||
|
||||
public void ProcessLogMessage(ILogMessage message)
|
||||
{
|
||||
var vm = new LogMessageViewModel(message, _globalLogPageContext);
|
||||
vm.SafeInitializePropertiesSynchronous();
|
||||
|
||||
if (Extension != null)
|
||||
{
|
||||
vm.ExtensionPfn = Extension.PackageFamilyName;
|
||||
}
|
||||
|
||||
Task.Factory.StartNew(
|
||||
() =>
|
||||
{
|
||||
LogMessages.Add(vm);
|
||||
},
|
||||
CancellationToken.None,
|
||||
TaskCreationOptions.None,
|
||||
_globalLogPageContext.Scheduler);
|
||||
}
|
||||
|
||||
public void ProcessStatusMessage(IStatusMessage message, StatusContext context)
|
||||
{
|
||||
// If this message is already in the list of messages, just bring it to the top
|
||||
var oldVm = StatusMessages.Where(messageVM => messageVM.Model.Unsafe == message).FirstOrDefault();
|
||||
if (oldVm != null)
|
||||
{
|
||||
Task.Factory.StartNew(
|
||||
() =>
|
||||
{
|
||||
StatusMessages.Remove(oldVm);
|
||||
StatusMessages.Add(oldVm);
|
||||
},
|
||||
CancellationToken.None,
|
||||
TaskCreationOptions.None,
|
||||
_globalLogPageContext.Scheduler);
|
||||
return;
|
||||
}
|
||||
|
||||
var vm = new StatusMessageViewModel(message, new(_globalLogPageContext));
|
||||
vm.SafeInitializePropertiesSynchronous();
|
||||
|
||||
if (Extension != null)
|
||||
{
|
||||
vm.ExtensionPfn = Extension.PackageFamilyName;
|
||||
}
|
||||
|
||||
Task.Factory.StartNew(
|
||||
() =>
|
||||
{
|
||||
StatusMessages.Add(vm);
|
||||
},
|
||||
CancellationToken.None,
|
||||
TaskCreationOptions.None,
|
||||
_globalLogPageContext.Scheduler);
|
||||
}
|
||||
|
||||
public void ProcessHideStatusMessage(IStatusMessage message)
|
||||
{
|
||||
Task.Factory.StartNew(
|
||||
() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var vm = StatusMessages.Where(messageVM => messageVM.Model.Unsafe == message).FirstOrDefault();
|
||||
if (vm != null)
|
||||
{
|
||||
StatusMessages.Remove(vm);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
},
|
||||
CancellationToken.None,
|
||||
TaskCreationOptions.None,
|
||||
_globalLogPageContext.Scheduler);
|
||||
}
|
||||
|
||||
public static void SetHostHwnd(ulong hostHwnd) => _hostingHwnd = hostHwnd;
|
||||
|
||||
public void DebugLog(string message)
|
||||
{
|
||||
#if DEBUG
|
||||
this.ProcessLogMessage(new LogMessage(message));
|
||||
#endif
|
||||
}
|
||||
|
||||
public void Log(string message)
|
||||
{
|
||||
this.ProcessLogMessage(new LogMessage(message));
|
||||
return Extension?.ExtensionDisplayName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.CmdPal.Core.ViewModels;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public class CommandPalettePageViewModelFactory
|
||||
: IPageViewModelFactoryService
|
||||
{
|
||||
private readonly TaskScheduler _scheduler;
|
||||
|
||||
public CommandPalettePageViewModelFactory(TaskScheduler scheduler)
|
||||
{
|
||||
_scheduler = scheduler;
|
||||
}
|
||||
|
||||
public PageViewModel? TryCreatePageViewModel(IPage page, bool nested, AppExtensionHost host)
|
||||
{
|
||||
return page switch
|
||||
{
|
||||
IListPage listPage => new ListViewModel(listPage, _scheduler, host) { IsNested = nested },
|
||||
IContentPage contentPage => new CommandPaletteContentPageViewModel(contentPage, _scheduler, host),
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,8 @@
|
||||
|
||||
using ManagedCommon;
|
||||
using Microsoft.CmdPal.Common.Services;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.Core.ViewModels;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using ManagedCommon;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public partial class CommandSettingsViewModel(ICommandSettings? _unsafeSettings, CommandProviderWrapper provider, TaskScheduler mainThread)
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// 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.CmdPal.UI.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
|
||||
|
||||
@@ -2,15 +2,7 @@
|
||||
// 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.Diagnostics.CodeAnalysis;
|
||||
using System.IO.Compression;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
using Microsoft.CmdPal.Common;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using Windows.Foundation;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.BuiltinCommands;
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Collections.Specialized;
|
||||
using Microsoft.CmdPal.Core.ViewModels;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
|
||||
@@ -10,7 +11,7 @@ namespace Microsoft.CmdPal.UI.ViewModels.Commands;
|
||||
|
||||
public partial class LogMessagesPage : ListPage
|
||||
{
|
||||
private readonly List<IListItem> _listItems = new();
|
||||
private readonly List<IListItem> _listItems = [];
|
||||
|
||||
public LogMessagesPage()
|
||||
{
|
||||
@@ -31,7 +32,6 @@ public partial class LogMessagesPage : ListPage
|
||||
var li = new ListItem(new NoOpCommand())
|
||||
{
|
||||
Title = logMessageViewModel.Message,
|
||||
Subtitle = logMessageViewModel.ExtensionPfn,
|
||||
};
|
||||
_listItems.Insert(0, li);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user