mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-07-05 09:59:28 +02:00
Compare commits
26 Commits
copilot/fi
...
dev/migrie
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
953258a6d1 | ||
|
|
175ed9e9b0 | ||
|
|
ab4a495aca | ||
|
|
587f73e8ae | ||
|
|
8575ca3557 | ||
|
|
e63773ce30 | ||
|
|
b4820c01cb | ||
|
|
87b6ca0ab6 | ||
|
|
1744bdecd8 | ||
|
|
05cd66c9bc | ||
|
|
cd15686416 | ||
|
|
655cd49cad | ||
|
|
f9b4b70294 | ||
|
|
e4165e5a73 | ||
|
|
f3ea6e6a08 | ||
|
|
9bb1e6c531 | ||
|
|
08ae18a896 | ||
|
|
5a28299f01 | ||
|
|
9b70e61b61 | ||
|
|
1e5d64391c | ||
|
|
65a623f66d | ||
|
|
7a96d8bb80 | ||
|
|
55d8baa8fc | ||
|
|
491492f7cb | ||
|
|
5981ad3a41 | ||
|
|
3435e492ad |
1
.github/actions/spell-check/expect.txt
vendored
1
.github/actions/spell-check/expect.txt
vendored
@@ -1965,6 +1965,7 @@ vabdq
|
||||
validmodulename
|
||||
valuegenerator
|
||||
VARTYPE
|
||||
vbcscompiler
|
||||
vcamp
|
||||
VCENTER
|
||||
vcgtq
|
||||
|
||||
@@ -16,6 +16,7 @@ pr:
|
||||
include:
|
||||
- main
|
||||
- stable
|
||||
drafts: false
|
||||
# paths:
|
||||
# exclude:
|
||||
# - '**.md'
|
||||
|
||||
@@ -200,7 +200,7 @@ jobs:
|
||||
- template: steps-ensure-dotnet-version.yml
|
||||
parameters:
|
||||
sdk: true
|
||||
version: '9.0'
|
||||
version: '10.0'
|
||||
|
||||
- ${{ if eq(parameters.runTests, true) }}:
|
||||
- task: VisualStudioTestPlatformInstaller@1
|
||||
@@ -418,7 +418,7 @@ jobs:
|
||||
/p:VCRTForwarders-IncludeDebugCRT=false
|
||||
/p:PowerToysRoot=$(Build.SourcesDirectory)
|
||||
/p:PublishProfile=InstallationPublishProfile.pubxml
|
||||
/p:TargetFramework=net9.0-windows10.0.26100.0
|
||||
/p:TargetFramework=net10.0-windows10.0.26100.0
|
||||
/bl:$(LogOutputDirectory)\publish-${{ join('_',split(project, '/')) }}.binlog
|
||||
$(RestoreAdditionalProjectSourcesArg)
|
||||
platform: $(BuildPlatform)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
parameters:
|
||||
- name: version
|
||||
type: string
|
||||
default: "9.0"
|
||||
default: "10.0"
|
||||
- name: sdk
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
@@ -22,7 +22,7 @@ $totalList = $projFiles | ForEach-Object -Parallel {
|
||||
#Workaround for preventing exit code from dotnet process from reflecting exit code in PowerShell
|
||||
$procInfo = New-Object System.Diagnostics.ProcessStartInfo -Property @{
|
||||
FileName = "dotnet.exe";
|
||||
Arguments = "list $csproj package";
|
||||
Arguments = "list $csproj package --no-restore";
|
||||
RedirectStandardOutput = $true;
|
||||
RedirectStandardError = $true;
|
||||
}
|
||||
|
||||
@@ -171,6 +171,12 @@
|
||||
$(USERPROFILE)\AppData\LocalLow\Microsoft\PowerToys\**;
|
||||
</MSBuildCacheAllowFileAccessAfterProjectFinishFilePatterns>
|
||||
|
||||
<!-- dotnet.exe seems to access files after builds. Temporarily putting in this entry for testing if we get further. This looks to be related to a .NET Roslyn Analyzer in .NET 10-->
|
||||
<MSBuildCacheAllowFileAccessAfterProjectFinishProcessPatterns>
|
||||
$(MSBuildCacheAllowFileAccessAfterProjectFinishProcessPatterns);
|
||||
\**\dotnet\dotnet.exe;
|
||||
\**\vbcscompiler.exe;
|
||||
</MSBuildCacheAllowFileAccessAfterProjectFinishProcessPatterns>
|
||||
<!--
|
||||
This repo uses a common output directory with many projects writing duplicate outputs. Allow everything, but note this costs some performance in the form of requiring
|
||||
the cache to use copies instead of hardlinks when pulling from cache.
|
||||
|
||||
@@ -39,22 +39,23 @@
|
||||
<PackageVersion Include="Markdig.Signed" Version="0.34.0" />
|
||||
<!-- Including MessagePack to force version, since it's used by StreamJsonRpc but contains vulnerabilities. After StreamJsonRpc updates the version of MessagePack, we can upgrade StreamJsonRpc instead. -->
|
||||
<PackageVersion Include="MessagePack" Version="3.1.3" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="9.0.0" />
|
||||
<PackageVersion Include="Microsoft.Data.Sqlite" Version="9.0.10" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="10.0.102" />
|
||||
<PackageVersion Include="Microsoft.CommandPalette.Extensions" Version="0.9.260303001" />
|
||||
<PackageVersion Include="Microsoft.Data.Sqlite" Version="10.0.7" />
|
||||
<!-- Including Microsoft.Bcl.AsyncInterfaces to force version, since it's used by Microsoft.SemanticKernel. -->
|
||||
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="9.0.10" />
|
||||
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="10.0.7" />
|
||||
<PackageVersion Include="Microsoft.Graphics.Win2D" Version="1.3.2" />
|
||||
<PackageVersion Include="Microsoft.Windows.CppWinRT" Version="2.0.250303.1" />
|
||||
<PackageVersion Include="Microsoft.Diagnostics.Tracing.TraceEvent" Version="3.1.16" />
|
||||
<PackageVersion Include="Microsoft.Extensions.AI" Version="9.9.1" />
|
||||
<PackageVersion Include="Microsoft.Extensions.AI.OpenAI" Version="9.9.1-preview.1.25474.6" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Caching.Abstractions" Version="9.0.10" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="9.0.10" />
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="9.0.10" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging" Version="9.0.10" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.10" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="9.0.10" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Hosting.WindowsServices" Version="9.0.10" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Caching.Abstractions" Version="10.0.7" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="10.0.7" />
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="10.0.7" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging" Version="10.0.7" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.7" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="10.0.7" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Hosting.WindowsServices" Version="10.0.7" />
|
||||
<PackageVersion Include="Microsoft.AI.Foundry.Local" Version="0.3.0" />
|
||||
<PackageVersion Include="Microsoft.SemanticKernel" Version="1.66.0" />
|
||||
<PackageVersion Include="Microsoft.SemanticKernel.Connectors.OpenAI" Version="1.66.0" />
|
||||
@@ -65,9 +66,9 @@
|
||||
<PackageVersion Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.2" />
|
||||
<PackageVersion Include="Microsoft.Web.WebView2" Version="1.0.3179.45" />
|
||||
<!-- Package Microsoft.Win32.SystemEvents added as a hack for being able to exclude the runtime assets so they don't conflict with 8.0.1. This is a dependency of System.Drawing.Common but the 8.0.1 version wasn't published to nuget. -->
|
||||
<PackageVersion Include="Microsoft.Win32.SystemEvents" Version="9.0.10" />
|
||||
<PackageVersion Include="Microsoft.Win32.SystemEvents" Version="10.0.7" />
|
||||
<PackageVersion Include="Microsoft.WindowsPackageManager.ComInterop" Version="1.10.340" />
|
||||
<PackageVersion Include="Microsoft.Windows.Compatibility" Version="9.0.10" />
|
||||
<PackageVersion Include="Microsoft.Windows.Compatibility" Version="10.0.7" />
|
||||
<PackageVersion Include="Microsoft.Windows.CsWin32" Version="0.3.183" />
|
||||
<!-- CsWinRT version needs to be set to have a WinRT.Runtime.dll at the same version contained inside the NET SDK we're currently building on CI. -->
|
||||
<!--
|
||||
@@ -105,31 +106,30 @@
|
||||
<PackageVersion Include="StreamJsonRpc" Version="2.21.69" />
|
||||
<PackageVersion Include="StyleCop.Analyzers" Version="1.2.0-beta.556" />
|
||||
<!-- Package System.CodeDom added as a hack for being able to exclude the runtime assets so they don't conflict with 8.0.1. This is a dependency of System.Management but the 8.0.1 version wasn't published to nuget. -->
|
||||
<PackageVersion Include="System.CodeDom" Version="9.0.10" />
|
||||
<PackageVersion Include="System.Collections.Immutable" Version="9.0.0" />
|
||||
<PackageVersion Include="System.CodeDom" Version="10.0.7" />
|
||||
<PackageVersion Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
|
||||
<PackageVersion Include="System.ComponentModel.Composition" Version="9.0.10" />
|
||||
<PackageVersion Include="System.Configuration.ConfigurationManager" Version="9.0.10" />
|
||||
<PackageVersion Include="System.Data.OleDb" Version="9.0.10" />
|
||||
<PackageVersion Include="System.ComponentModel.Composition" Version="10.0.7" />
|
||||
<PackageVersion Include="System.Configuration.ConfigurationManager" Version="10.0.7" />
|
||||
<PackageVersion Include="System.Data.OleDb" Version="10.0.7" />
|
||||
<!-- Package System.Data.SqlClient added to force it as a dependency of Microsoft.Windows.Compatibility to the latest version available at this time. -->
|
||||
<PackageVersion Include="System.Data.SqlClient" Version="4.9.0" />
|
||||
<PackageVersion Include="System.Data.SqlClient" Version="4.9.1" />
|
||||
<!-- Package System.Diagnostics.EventLog added as a hack for being able to exclude the runtime assets so they don't conflict with 8.0.1. This is a dependency of System.Data.OleDb but the 8.0.1 version wasn't published to nuget. -->
|
||||
<PackageVersion Include="System.Diagnostics.EventLog" Version="9.0.10" />
|
||||
<PackageVersion Include="System.Diagnostics.EventLog" Version="10.0.7" />
|
||||
<!-- Package System.Diagnostics.PerformanceCounter added as a hack for being able to exclude the runtime assets so they don't conflict with 8.0.11. -->
|
||||
<PackageVersion Include="System.Diagnostics.PerformanceCounter" Version="9.0.10" />
|
||||
<PackageVersion Include="System.Diagnostics.PerformanceCounter" Version="10.0.7" />
|
||||
<PackageVersion Include="System.ClientModel" Version="1.7.0" />
|
||||
<PackageVersion Include="System.Drawing.Common" Version="9.0.10" />
|
||||
<PackageVersion Include="System.Drawing.Common" Version="10.0.7" />
|
||||
<PackageVersion Include="System.IO.Abstractions" Version="22.0.13" />
|
||||
<PackageVersion Include="System.IO.Abstractions.TestingHelpers" Version="22.0.13" />
|
||||
<PackageVersion Include="System.Management" Version="9.0.10" />
|
||||
<PackageVersion Include="System.Management" Version="10.0.7" />
|
||||
<PackageVersion Include="System.Net.Http" Version="4.3.4" />
|
||||
<PackageVersion Include="System.Numerics.Tensors" Version="9.0.11" />
|
||||
<PackageVersion Include="System.Private.Uri" Version="4.3.2" />
|
||||
<PackageVersion Include="System.Reactive" Version="6.0.1" />
|
||||
<PackageVersion Include="System.Runtime.Caching" Version="9.0.10" />
|
||||
<PackageVersion Include="System.ServiceProcess.ServiceController" Version="9.0.10" />
|
||||
<PackageVersion Include="System.Text.Encoding.CodePages" Version="9.0.10" />
|
||||
<PackageVersion Include="System.Text.Json" Version="9.0.10" />
|
||||
<PackageVersion Include="System.Runtime.Caching" Version="10.0.7" />
|
||||
<PackageVersion Include="System.ServiceProcess.ServiceController" Version="10.0.7" />
|
||||
<PackageVersion Include="System.Text.Encoding.CodePages" Version="10.0.7" />
|
||||
<PackageVersion Include="System.Text.Json" Version="10.0.7" />
|
||||
<PackageVersion Include="System.Text.RegularExpressions" Version="4.3.1" />
|
||||
<PackageVersion Include="ToolGood.Words.Pinyin" Version="3.1.0.3" />
|
||||
<PackageVersion Include="UnicodeInformation" Version="2.6.0" />
|
||||
|
||||
18
README.md
18
README.md
@@ -47,21 +47,7 @@ But to get started quickly, choose one of the installation methods below:
|
||||
<summary><strong>Download the .exe file from GitHub</strong></summary>
|
||||
<br/>
|
||||
|
||||
Go to the [PowerToys GitHub releases](https://aka.ms/installPowerToys), select **Assets** to reveal the installation files, and choose the one that matches your architecture and install scope. For most devices, that would be _x64 per-user_.
|
||||
|
||||
<!-- items that need to be updated release to release -->
|
||||
[github-next-release-work]: https://github.com/microsoft/PowerToys/issues?q=is%3Aissue+milestone%3A%22PowerToys+0.100%22
|
||||
[ptUserX64]: https://github.com/microsoft/PowerToys/releases/download/v0.99.0/PowerToysUserSetup-0.99.0-x64.exe
|
||||
[ptUserArm64]: https://github.com/microsoft/PowerToys/releases/download/v0.99.0/PowerToysUserSetup-0.99.0-arm64.exe
|
||||
[ptMachineX64]: https://github.com/microsoft/PowerToys/releases/download/v0.99.0/PowerToysSetup-0.99.0-x64.exe
|
||||
[ptMachineArm64]: https://github.com/microsoft/PowerToys/releases/download/v0.99.0/PowerToysSetup-0.99.0-arm64.exe
|
||||
|
||||
| Description | Filename |
|
||||
| --- | --- |
|
||||
| Per user - x64 | [PowerToysUserSetup-0.99.0-x64.exe][ptUserX64] |
|
||||
| Per user - ARM64 | [PowerToysUserSetup-0.99.0-arm64.exe][ptUserArm64] |
|
||||
| Machine wide - x64 | [PowerToysSetup-0.99.0-x64.exe][ptMachineX64] |
|
||||
| Machine wide - ARM64 | [PowerToysSetup-0.99.0-arm64.exe][ptMachineArm64] |
|
||||
Go to the [PowerToys GitHub releases](https://aka.ms/installPowerToys), scroll down and select **Assets** to reveal the installation files, and choose the one that matches your architecture and install scope. For most devices, that would be _x64 per-user_.
|
||||
|
||||
</details>
|
||||
|
||||
@@ -106,7 +92,7 @@ There are [community driven install methods](https://learn.microsoft.com/windows
|
||||
|
||||
[](https://github.com/microsoft/PowerToys/releases)
|
||||
|
||||
To see what's new, check out the [release notes](https://github.com/microsoft/PowerToys/releases/tag/v0.99.0).
|
||||
To see what's new, check out the [release notes](https://github.com/microsoft/PowerToys/releases/).
|
||||
|
||||
## 🛣️ Roadmap
|
||||
|
||||
|
||||
54
auto-cherry-pick.ps1
Normal file
54
auto-cherry-pick.ps1
Normal file
@@ -0,0 +1,54 @@
|
||||
# Auto-resolve cherry-pick conflicts
|
||||
param([int]$MaxAttempts = 100)
|
||||
|
||||
$attempts = 0
|
||||
while ($attempts -lt $MaxAttempts) {
|
||||
$attempts++
|
||||
|
||||
# Check if cherry-pick is in progress
|
||||
$status = git status --porcelain
|
||||
if (-not $status) {
|
||||
Write-Host "Cherry-pick complete!" -ForegroundColor Green
|
||||
break
|
||||
}
|
||||
|
||||
# Get conflicted files
|
||||
$conflicts = git diff --name-only --diff-filter=U
|
||||
|
||||
if ($conflicts) {
|
||||
Write-Host "Attempt $attempts`: Resolving conflicts..." -ForegroundColor Yellow
|
||||
|
||||
foreach ($file in $conflicts) {
|
||||
Write-Host " Resolving: $file"
|
||||
git checkout --ours $file 2>$null
|
||||
}
|
||||
|
||||
# Handle deleted files
|
||||
git status --short | Where-Object { $_ -match '^DU' } | ForEach-Object {
|
||||
$file = ($_ -split '\s+', 2)[1]
|
||||
Write-Host " Removing deleted: $file"
|
||||
git rm $file 2>$null
|
||||
}
|
||||
|
||||
git add . 2>$null
|
||||
}
|
||||
|
||||
# Try to continue
|
||||
$result = git cherry-pick --continue 2>&1
|
||||
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Host " Continued successfully" -ForegroundColor Green
|
||||
}
|
||||
elseif ($result -match 'empty') {
|
||||
Write-Host " Skipping empty commit" -ForegroundColor Cyan
|
||||
git cherry-pick --skip 2>&1 | Out-Null
|
||||
}
|
||||
else {
|
||||
Write-Host " Error: $result" -ForegroundColor Red
|
||||
Start-Sleep -Seconds 1
|
||||
}
|
||||
}
|
||||
|
||||
if ($attempts -ge $MaxAttempts) {
|
||||
Write-Host "Max attempts reached. Check status manually." -ForegroundColor Red
|
||||
}
|
||||
@@ -3,9 +3,9 @@
|
||||
- [ ] The plugin is a project under `modules\launcher\Plugins`
|
||||
- [ ] Microsoft plugin project name pattern: `Microsoft.PowerToys.Run.Plugin.{PluginName}`
|
||||
- [ ] Community plugin project name pattern: `Community.PowerToys.Run.Plugin.{PluginName}`
|
||||
- [ ] The plugin target framework should be `net9.0-windows10.0.22621.0`
|
||||
- [ ] The plugin target framework should be `net10.0-windows10.0.22621.0`
|
||||
- [ ] If the plugin uses any 3rd party dependencies the project file should import `DynamicPlugin.props`
|
||||
- [ ] 3rd party dependencies must be compatible with .NET 9
|
||||
- [ ] 3rd party dependencies must be compatible with .NET 10
|
||||
- [ ] The plugin has to contain a `plugin.json` file of the following format in its root folder:
|
||||
|
||||
```json
|
||||
|
||||
@@ -8,10 +8,10 @@ SET VCToolsVersion=!VCToolsVersion!
|
||||
SET ClearDevCommandPromptEnvVars=false
|
||||
|
||||
rem In case of Release we should not use Debug CRT in VCRT forwarders
|
||||
msbuild !PTRoot!\src\modules\previewpane\MonacoPreviewHandler\MonacoPreviewHandler.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml -p:TargetFramework=net9.0-windows10.0.26100.0
|
||||
msbuild !PTRoot!\src\modules\previewpane\MonacoPreviewHandler\MonacoPreviewHandler.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml -p:TargetFramework=net10.0-windows10.0.26100.0
|
||||
|
||||
msbuild !PTRoot!\src\modules\previewpane\MarkdownPreviewHandler\MarkdownPreviewHandler.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml -p:TargetFramework=net9.0-windows10.0.26100.0
|
||||
msbuild !PTRoot!\src\modules\previewpane\MarkdownPreviewHandler\MarkdownPreviewHandler.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml -p:TargetFramework=net10.0-windows10.0.26100.0
|
||||
|
||||
msbuild !PTRoot!\src\modules\previewpane\SvgPreviewHandler\SvgPreviewHandler.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml -p:TargetFramework=net9.0-windows10.0.26100.0
|
||||
msbuild !PTRoot!\src\modules\previewpane\SvgPreviewHandler\SvgPreviewHandler.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml -p:TargetFramework=net10.0-windows10.0.26100.0
|
||||
|
||||
msbuild !PTRoot!\src\modules\previewpane\SvgThumbnailProvider\SvgThumbnailProvider.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml -p:TargetFramework=net9.0-windows10.0.26100.0
|
||||
msbuild !PTRoot!\src\modules\previewpane\SvgThumbnailProvider\SvgThumbnailProvider.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml -p:TargetFramework=net10.0-windows10.0.26100.0
|
||||
@@ -62,7 +62,7 @@
|
||||
<Import Project="$(RepoRoot)deps\spdlog.props" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
@@ -70,6 +70,6 @@
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.250303.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.231216.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.260126.7" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -4,7 +4,7 @@
|
||||
<Import Project=".\Common.Dotnet.PrepareGeneratedFolder.targets" />
|
||||
|
||||
<PropertyGroup>
|
||||
<CoreTargetFramework>net9.0</CoreTargetFramework>
|
||||
<CoreTargetFramework>net10.0</CoreTargetFramework>
|
||||
<WindowsSdkPackageVersion>10.0.26100.68-preview</WindowsSdkPackageVersion>
|
||||
<TargetFramework>$(CoreTargetFramework)-windows10.0.26100.0</TargetFramework>
|
||||
<TargetPlatformMinVersion>10.0.19041.0</TargetPlatformMinVersion>
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
<Import Project="$(RepoRoot)deps\spdlog.props" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
@@ -76,6 +76,6 @@
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.250303.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.231216.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.260126.7" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -36,12 +36,12 @@
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Library</OutputType>
|
||||
<TargetFramework>net9.0-windows10.0.26100.0</TargetFramework>
|
||||
<TargetFramework>net10.0-windows10.0.26100.0</TargetFramework>
|
||||
<RootNamespace>Microsoft.PowerToys.Common.UI.Controls</RootNamespace>
|
||||
<AssemblyName>PowerToys.Common.UI.Controls</AssemblyName>
|
||||
<UseWinUI>true</UseWinUI>
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Markdig.Signed" />
|
||||
<PackageReference Include="System.Text.Encoding.CodePages" />
|
||||
<PackageReference Include="UTF.Unknown" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
<Import Project="$(RepoRoot)deps\spdlog.props" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
@@ -63,6 +63,6 @@
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -38,7 +38,7 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
@@ -46,6 +46,6 @@
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.250303.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.231216.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.260126.7" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -8,7 +8,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<PublishAot>true</PublishAot>
|
||||
<InvariantGlobalization>true</InvariantGlobalization>
|
||||
<TargetFramework>net9.0-windows10.0.26100.0</TargetFramework>
|
||||
<TargetFramework>net10.0-windows10.0.26100.0</TargetFramework>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<PublishTrimmed>false</PublishTrimmed>
|
||||
</PropertyGroup>
|
||||
@@ -18,7 +18,6 @@
|
||||
<!-- Test libraries/utilities should not use the metapackage. -->
|
||||
<PackageReference Include="MSTest.TestFramework" />
|
||||
<PackageReference Include="System.IO.Abstractions" />
|
||||
<PackageReference Include="System.Text.RegularExpressions" />
|
||||
<PackageReference Include="CoenM.ImageSharp.ImageHash" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..\;..\utils;..\Telemetry;..\..\;..\..\..\deps\;..\..\..\deps\spdlog\include;..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\include;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\;..\utils;..\Telemetry;..\..\;..\..\..\deps\;..\..\..\deps\spdlog\include;..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\include;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<LanguageStandard>stdcpp23</LanguageStandard>
|
||||
<PreprocessorDefinitions>SPDLOG_WCHAR_TO_UTF8_SUPPORT;SPDLOG_HEADER_ONLY;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
|
||||
@@ -172,14 +172,14 @@
|
||||
<ImportGroup Label="ExtensionTargets" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
</Target>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.250303.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.231216.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.260126.7" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -46,7 +46,7 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
@@ -54,6 +54,6 @@
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.250303.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.231216.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.260126.7" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.250303.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.231216.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.260126.7" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -58,7 +58,7 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
@@ -66,6 +66,6 @@
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -74,8 +74,6 @@
|
||||
<PackageReference Include="ReverseMarkdown" />
|
||||
<PackageReference Include="StreamJsonRpc" />
|
||||
<PackageReference Include="WinUIEx" />
|
||||
<!-- HACK: To make sure the version pulled in by Microsoft.Extensions.Hosting is current. -->
|
||||
<PackageReference Include="System.Text.Json" />
|
||||
<!-- This line forces the WebView2 version used by Windows App SDK to be the one we expect from Directory.Packages.props . -->
|
||||
<PackageReference Include="Microsoft.Web.WebView2" />
|
||||
<!-- HACK: CmdPal uses CommunityToolkit.Common directly. Align the version. -->
|
||||
|
||||
@@ -20,9 +20,6 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Appium.WebDriver" />
|
||||
<PackageReference Include="MSTest" />
|
||||
<PackageReference Include="System.Net.Http" />
|
||||
<PackageReference Include="System.Private.Uri" />
|
||||
<PackageReference Include="System.Text.RegularExpressions" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -161,7 +161,7 @@
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\robmikh.common.0.0.23-beta\build\native\robmikh.common.targets" Condition="Exists('$(RepoRoot)packages\robmikh.common.0.0.23-beta\build\native\robmikh.common.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
@@ -170,6 +170,6 @@
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\robmikh.common.0.0.23-beta\build\native\robmikh.common.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\robmikh.common.0.0.23-beta\build\native\robmikh.common.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.250303.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.231216.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.260126.7" targetFramework="native" />
|
||||
<package id="robmikh.common" version="0.0.23-beta" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -103,7 +103,7 @@
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.211019.2\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.211019.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\robmikh.common.0.0.23-beta\build\native\robmikh.common.targets" Condition="Exists('$(RepoRoot)packages\robmikh.common.0.0.23-beta\build\native\robmikh.common.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
</ImportGroup>
|
||||
<Import Project="$(RepoRoot)deps\spdlog.props" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
@@ -113,6 +113,6 @@
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\robmikh.common.0.0.23-beta\build\native\robmikh.common.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\robmikh.common.0.0.23-beta\build\native\robmikh.common.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.250303.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.231216.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.260126.7" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -65,8 +65,6 @@
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" />
|
||||
<PackageReference Include="WinUIEx" />
|
||||
<!-- HACK: To make sure the version pulled in by Microsoft.Extensions.Hosting is current. -->
|
||||
<PackageReference Include="System.Text.Json" />
|
||||
<!-- This line forces the WebView2 version used by Windows App SDK to be the one we expect from Directory.Packages.props . -->
|
||||
<PackageReference Include="Microsoft.Web.WebView2" />
|
||||
<!-- HACK: CmdPal uses CommunityToolkit.Common directly. Align the version. -->
|
||||
|
||||
@@ -49,8 +49,6 @@
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Converters" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Controls.Sizers" />
|
||||
<PackageReference Include="System.IO.Abstractions" />
|
||||
<!-- HACK: To make sure the version pulled in by Microsoft.Extensions.Hosting is current. -->
|
||||
<PackageReference Include="System.Text.Json" />
|
||||
<Manifest Include="$(ApplicationManifest)" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -144,14 +144,14 @@ MakeAppx.exe pack /d . /p $(OutDir)FileLocksmithContextMenuPackage.msix /nv</Com
|
||||
<Import Project="$(RepoRoot)deps\spdlog.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
</Target>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.250303.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.231216.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.260126.7" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -61,7 +61,6 @@
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" />
|
||||
<PackageReference Include="Microsoft.Xaml.Behaviors.WinUI.Managed" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" />
|
||||
<PackageReference Include="System.Drawing.Common" />
|
||||
<PackageReference Include="WinUIEx" />
|
||||
<!-- This line forces the WebView2 version used by Windows App SDK to be the one we expect from Directory.Packages.props . -->
|
||||
<PackageReference Include="Microsoft.Web.WebView2" />
|
||||
|
||||
@@ -5,7 +5,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<TargetFramework>net9.0-windows10.0.26100.0</TargetFramework>
|
||||
<TargetFramework>net10.0-windows10.0.26100.0</TargetFramework>
|
||||
<TargetPlatformMinVersion>10.0.19041.0</TargetPlatformMinVersion>
|
||||
<SupportedOSPlatformVersion>10.0.19041.0</SupportedOSPlatformVersion>
|
||||
<PublishDir>$(PowerToysRoot)\$(Platform)\$(Configuration)\WinUI3Apps</PublishDir>
|
||||
|
||||
@@ -31,9 +31,6 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MSTest" />
|
||||
<PackageReference Include="System.Net.Http" />
|
||||
<PackageReference Include="System.Private.Uri" />
|
||||
<PackageReference Include="System.Text.RegularExpressions" />
|
||||
<ProjectReference Include="..\..\..\common\UITestAutomation\UITestAutomation.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -64,8 +64,6 @@
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" />
|
||||
<PackageReference Include="WinUIEx" />
|
||||
<!-- HACK: To make sure the version pulled in by Microsoft.Extensions.Hosting is current. -->
|
||||
<PackageReference Include="System.Text.Json" />
|
||||
<!-- This line forces the WebView2 version used by Windows App SDK to be the one we expect from Directory.Packages.props . -->
|
||||
<PackageReference Include="Microsoft.Web.WebView2" />
|
||||
<!-- HACK: CmdPal uses CommunityToolkit.Common directly. Align the version. -->
|
||||
|
||||
@@ -118,7 +118,7 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<Import Project="$(RepoRoot)deps\spdlog.props" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.250303.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.231216.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.260126.7" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -121,12 +121,12 @@ internal static class Encryption
|
||||
|
||||
if (!LegalKeyDictionary.TryGetValue(myKey, out byte[] value))
|
||||
{
|
||||
Rfc2898DeriveBytes key = new(
|
||||
rv = Rfc2898DeriveBytes.Pbkdf2(
|
||||
myKey,
|
||||
Common.GetBytesU(InitialIV),
|
||||
50000,
|
||||
HashAlgorithmName.SHA512);
|
||||
rv = key.GetBytes(32);
|
||||
HashAlgorithmName.SHA512,
|
||||
32);
|
||||
_ = LegalKeyDictionary.AddOrUpdate(myKey, rv, (k, v) => rv);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace MouseWithoutBorders
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
|
||||
protected override void OnFormClosing(System.Windows.Forms.FormClosingEventArgs e)
|
||||
{
|
||||
MachineStuff.Settings = null;
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace MouseWithoutBorders
|
||||
_currentPage.OnPageClosing();
|
||||
}
|
||||
|
||||
base.OnClosing(e);
|
||||
base.OnFormClosing(e);
|
||||
}
|
||||
|
||||
internal SettingsFormPage GetCurrentPage()
|
||||
|
||||
@@ -72,8 +72,6 @@
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" />
|
||||
<PackageReference Include="StreamJsonRpc" />
|
||||
<PackageReference Include="System.Data.SqlClient" /> <!-- It's a dependency of Microsoft.Windows.Compatibility. We're adding it here to force it to the version specified in Directory.Packages.props -->
|
||||
<!-- HACK: To make sure the version pulled in by Microsoft.Extensions.Hosting is current. -->
|
||||
<PackageReference Include="System.Text.Json" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\common\GPOWrapper\GPOWrapper.vcxproj" />
|
||||
|
||||
@@ -66,14 +66,14 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<Import Project="$(RepoRoot)deps\spdlog.props" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
</Target>
|
||||
|
||||
@@ -143,7 +143,7 @@
|
||||
<Import Project="$(RepoRoot)deps\spdlog.props" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
@@ -151,6 +151,6 @@
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.250303.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.231216.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.260126.7" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.250303.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.231216.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.260126.7" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -30,7 +30,6 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.ComponentModel.Composition" />
|
||||
<PackageReference Include="System.Drawing.Common" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -174,7 +174,7 @@
|
||||
<Import Project="..\..\..\..\deps\spdlog.props" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
@@ -182,6 +182,6 @@
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.250303.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.231216.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.260126.7" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -82,7 +82,7 @@
|
||||
<Import Project="$(RepoRoot)deps\spdlog.props" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
@@ -90,6 +90,6 @@
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.250303.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.231216.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.260126.7" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.250303.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.231216.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.260126.7" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -166,7 +166,7 @@
|
||||
<Import Project="..\..\..\..\deps\spdlog.props" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
@@ -174,6 +174,6 @@
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.250303.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.231216.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.260126.7" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -165,7 +165,7 @@
|
||||
<Import Project="..\..\..\..\deps\spdlog.props" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
@@ -173,6 +173,6 @@
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.250303.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.231216.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.260126.7" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -391,9 +391,9 @@
|
||||
<Error Condition="!Exists('..\..\..\..\packages\robmikh.common.0.0.23-beta\build\native\robmikh.common.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\robmikh.common.0.0.23-beta\build\native\robmikh.common.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
</Target>
|
||||
<Import Project="..\..\..\..\packages\robmikh.common.0.0.23-beta\build\native\robmikh.common.targets" Condition="Exists('..\..\..\..\packages\robmikh.common.0.0.23-beta\build\native\robmikh.common.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
</Project>
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
</Project>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.250303.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.231216.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.260126.7" targetFramework="native" />
|
||||
<package id="robmikh.common" version="0.0.23-beta" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -100,7 +100,7 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
</ImportGroup>
|
||||
<Import Project="$(RepoRoot)deps\spdlog.props" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
@@ -108,6 +108,6 @@
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -119,7 +119,7 @@
|
||||
<Import Project="$(RepoRoot)deps\spdlog.props" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
@@ -127,6 +127,6 @@
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.250303.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.231216.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.260126.7" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -187,7 +187,7 @@
|
||||
<Import Project="$(RepoRoot)deps\spdlog.props" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
@@ -195,6 +195,6 @@
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.250303.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.231216.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.260126.7" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -68,7 +68,7 @@
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.211019.2\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.211019.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
</ImportGroup>
|
||||
<Import Project="$(RepoRoot)deps\spdlog.props" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
@@ -77,6 +77,6 @@
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.250303.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.231216.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.260126.7" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -66,7 +66,7 @@
|
||||
<Import Project="$(RepoRoot)deps\spdlog.props" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
@@ -74,6 +74,6 @@
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(RepoRoot)packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.250303.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.231216.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.260126.7" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -5,7 +5,7 @@
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
|
||||
<WindowsSdkPackageVersion>10.0.26100.68-preview</WindowsSdkPackageVersion>
|
||||
<TargetFramework>net9.0-windows10.0.26100.0</TargetFramework>
|
||||
<TargetFramework>net10.0-windows10.0.26100.0</TargetFramework>
|
||||
<TargetPlatformMinVersion>10.0.19041.0</TargetPlatformMinVersion>
|
||||
<SupportedOSPlatformVersion>10.0.19041.0</SupportedOSPlatformVersion>
|
||||
<RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers>
|
||||
|
||||
@@ -496,16 +496,46 @@ public sealed class CommandProviderWrapper : ICommandProviderContext
|
||||
this.CommandsChanged?.Invoke(this, new ItemsChangedEventArgs(-1));
|
||||
}
|
||||
|
||||
public void PinDockBand(string commandId, IServiceProvider serviceProvider, Dock.DockPinSide side = Dock.DockPinSide.Start, bool? showTitles = null, bool? showSubtitles = null)
|
||||
public void PinDockBand(string commandId, IServiceProvider serviceProvider, Dock.DockPinSide side = Dock.DockPinSide.Start, bool? showTitles = null, bool? showSubtitles = null, string? monitorDeviceId = null)
|
||||
{
|
||||
var settingsService = serviceProvider.GetRequiredService<ISettingsService>();
|
||||
var settings = settingsService.Settings;
|
||||
var dockSettings = settings.DockSettings;
|
||||
|
||||
// Prevent duplicate pins — check all sections
|
||||
if (dockSettings.StartBands.Any(b => b.CommandId == commandId && b.ProviderId == this.ProviderId) ||
|
||||
dockSettings.CenterBands.Any(b => b.CommandId == commandId && b.ProviderId == this.ProviderId) ||
|
||||
dockSettings.EndBands.Any(b => b.CommandId == commandId && b.ProviderId == this.ProviderId))
|
||||
// Prevent duplicate pins — check the target destination's bands.
|
||||
// When pinning to a specific monitor, check that monitor's resolved bands
|
||||
// (which include forked-from-global bands). Otherwise, check global bands.
|
||||
bool alreadyPinned;
|
||||
if (monitorDeviceId is not null)
|
||||
{
|
||||
var configs = dockSettings.MonitorConfigs ?? System.Collections.Immutable.ImmutableList<DockMonitorConfig>.Empty;
|
||||
DockMonitorConfig? targetConfig = null;
|
||||
foreach (var cfg in configs)
|
||||
{
|
||||
if (string.Equals(cfg.MonitorDeviceId, monitorDeviceId, System.StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
targetConfig = cfg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve the bands for the target monitor (per-monitor if customized, else global)
|
||||
var resolvedStart = targetConfig?.ResolveStartBands(dockSettings.StartBands) ?? dockSettings.StartBands;
|
||||
var resolvedCenter = targetConfig?.ResolveCenterBands(dockSettings.CenterBands) ?? dockSettings.CenterBands;
|
||||
var resolvedEnd = targetConfig?.ResolveEndBands(dockSettings.EndBands) ?? dockSettings.EndBands;
|
||||
|
||||
alreadyPinned = resolvedStart.Any(b => b.CommandId == commandId && b.ProviderId == this.ProviderId) ||
|
||||
resolvedCenter.Any(b => b.CommandId == commandId && b.ProviderId == this.ProviderId) ||
|
||||
resolvedEnd.Any(b => b.CommandId == commandId && b.ProviderId == this.ProviderId);
|
||||
}
|
||||
else
|
||||
{
|
||||
alreadyPinned = dockSettings.StartBands.Any(b => b.CommandId == commandId && b.ProviderId == this.ProviderId) ||
|
||||
dockSettings.CenterBands.Any(b => b.CommandId == commandId && b.ProviderId == this.ProviderId) ||
|
||||
dockSettings.EndBands.Any(b => b.CommandId == commandId && b.ProviderId == this.ProviderId);
|
||||
}
|
||||
|
||||
if (alreadyPinned)
|
||||
{
|
||||
Logger.LogDebug($"Dock band '{commandId}' from provider '{this.ProviderId}' is already pinned; skipping.");
|
||||
return;
|
||||
@@ -519,6 +549,21 @@ public sealed class CommandProviderWrapper : ICommandProviderContext
|
||||
ShowSubtitles = showSubtitles,
|
||||
};
|
||||
|
||||
if (monitorDeviceId is not null)
|
||||
{
|
||||
PinDockBandToMonitor(settingsService, bandSettings, side, monitorDeviceId);
|
||||
}
|
||||
else
|
||||
{
|
||||
PinDockBandGlobal(settingsService, bandSettings, side);
|
||||
}
|
||||
|
||||
// Raise CommandsChanged so the TopLevelCommandManager reloads our commands
|
||||
this.CommandsChanged?.Invoke(this, new ItemsChangedEventArgs(-1));
|
||||
}
|
||||
|
||||
private static void PinDockBandGlobal(ISettingsService settingsService, DockBandSettings bandSettings, Dock.DockPinSide side)
|
||||
{
|
||||
settingsService.UpdateSettings(
|
||||
s =>
|
||||
{
|
||||
@@ -534,9 +579,59 @@ public sealed class CommandProviderWrapper : ICommandProviderContext
|
||||
};
|
||||
},
|
||||
hotReload: false);
|
||||
}
|
||||
|
||||
// Raise CommandsChanged so the TopLevelCommandManager reloads our commands
|
||||
this.CommandsChanged?.Invoke(this, new ItemsChangedEventArgs(-1));
|
||||
private static void PinDockBandToMonitor(ISettingsService settingsService, DockBandSettings bandSettings, Dock.DockPinSide side, string monitorDeviceId)
|
||||
{
|
||||
settingsService.UpdateSettings(
|
||||
s =>
|
||||
{
|
||||
var dockSettings = s.DockSettings;
|
||||
var configs = dockSettings.MonitorConfigs ?? System.Collections.Immutable.ImmutableList<DockMonitorConfig>.Empty;
|
||||
|
||||
// Find or create the monitor config
|
||||
DockMonitorConfig? target = null;
|
||||
var targetIndex = -1;
|
||||
for (var i = 0; i < configs.Count; i++)
|
||||
{
|
||||
if (string.Equals(configs[i].MonitorDeviceId, monitorDeviceId, System.StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
target = configs[i];
|
||||
targetIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (target is null)
|
||||
{
|
||||
// Monitor not yet in config; create and fork from global
|
||||
target = new DockMonitorConfig { MonitorDeviceId = monitorDeviceId, Enabled = true };
|
||||
target = target.ForkFromGlobal(dockSettings);
|
||||
configs = configs.Add(target);
|
||||
targetIndex = configs.Count - 1;
|
||||
}
|
||||
else if (!target.IsCustomized)
|
||||
{
|
||||
// Fork from global on first per-monitor customization
|
||||
target = target.ForkFromGlobal(dockSettings);
|
||||
}
|
||||
|
||||
// Add band to the appropriate section
|
||||
target = side switch
|
||||
{
|
||||
Dock.DockPinSide.Center => target with { CenterBands = (target.CenterBands ?? System.Collections.Immutable.ImmutableList<DockBandSettings>.Empty).Add(bandSettings) },
|
||||
Dock.DockPinSide.End => target with { EndBands = (target.EndBands ?? System.Collections.Immutable.ImmutableList<DockBandSettings>.Empty).Add(bandSettings) },
|
||||
_ => target with { StartBands = (target.StartBands ?? System.Collections.Immutable.ImmutableList<DockBandSettings>.Empty).Add(bandSettings) },
|
||||
};
|
||||
|
||||
configs = configs.SetItem(targetIndex, target);
|
||||
|
||||
return s with
|
||||
{
|
||||
DockSettings = dockSettings with { MonitorConfigs = configs },
|
||||
};
|
||||
},
|
||||
hotReload: false);
|
||||
}
|
||||
|
||||
public void UnpinDockBand(string commandId, IServiceProvider serviceProvider)
|
||||
|
||||
@@ -105,7 +105,18 @@ public sealed partial class DockBandViewModel : ExtensionObjectViewModel
|
||||
/// </summary>
|
||||
internal void SaveShowLabels()
|
||||
{
|
||||
ReplaceBandInSettings(_bandSettings with { ShowTitles = _showTitles, ShowSubtitles = _showSubtitles });
|
||||
// Only write to settings if the label values actually changed from
|
||||
// the snapshot. When multiple non-customized monitors share global
|
||||
// bands, an unconditional save would overwrite changes made by
|
||||
// another monitor's ViewModel (last-save-wins clobber).
|
||||
var changed = _showTitlesSnapshot is null
|
||||
|| _showTitles != _showTitlesSnapshot
|
||||
|| _showSubtitles != _showSubtitlesSnapshot;
|
||||
if (changed)
|
||||
{
|
||||
ReplaceBandInSettings(_bandSettings with { ShowTitles = _showTitles, ShowSubtitles = _showSubtitles });
|
||||
}
|
||||
|
||||
_showTitlesSnapshot = null;
|
||||
_showSubtitlesSnapshot = null;
|
||||
}
|
||||
@@ -135,15 +146,52 @@ public sealed partial class DockBandViewModel : ExtensionObjectViewModel
|
||||
s =>
|
||||
{
|
||||
var dockSettings = s.DockSettings;
|
||||
return s with
|
||||
|
||||
// Update in global bands
|
||||
var updatedDock = dockSettings with
|
||||
{
|
||||
DockSettings = dockSettings with
|
||||
{
|
||||
StartBands = ReplaceBandInList(dockSettings.StartBands, commandId, newSettings),
|
||||
CenterBands = ReplaceBandInList(dockSettings.CenterBands, commandId, newSettings),
|
||||
EndBands = ReplaceBandInList(dockSettings.EndBands, commandId, newSettings),
|
||||
},
|
||||
StartBands = ReplaceBandInList(dockSettings.StartBands, commandId, newSettings),
|
||||
CenterBands = ReplaceBandInList(dockSettings.CenterBands, commandId, newSettings),
|
||||
EndBands = ReplaceBandInList(dockSettings.EndBands, commandId, newSettings),
|
||||
};
|
||||
|
||||
// Also update in per-monitor bands for customized monitors
|
||||
var configs = updatedDock.MonitorConfigs ?? ImmutableList<DockMonitorConfig>.Empty;
|
||||
var configsChanged = false;
|
||||
for (var i = 0; i < configs.Count; i++)
|
||||
{
|
||||
var config = configs[i];
|
||||
if (!config.IsCustomized)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var start = config.StartBands ?? ImmutableList<DockBandSettings>.Empty;
|
||||
var center = config.CenterBands ?? ImmutableList<DockBandSettings>.Empty;
|
||||
var end = config.EndBands ?? ImmutableList<DockBandSettings>.Empty;
|
||||
|
||||
var newStart = ReplaceBandInList(start, commandId, newSettings);
|
||||
var newCenter = ReplaceBandInList(center, commandId, newSettings);
|
||||
var newEnd = ReplaceBandInList(end, commandId, newSettings);
|
||||
|
||||
if (newStart != start || newCenter != center || newEnd != end)
|
||||
{
|
||||
configs = configs.SetItem(i, config with
|
||||
{
|
||||
StartBands = newStart,
|
||||
CenterBands = newCenter,
|
||||
EndBands = newEnd,
|
||||
});
|
||||
configsChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (configsChanged)
|
||||
{
|
||||
updatedDock = updatedDock with { MonitorConfigs = configs };
|
||||
}
|
||||
|
||||
return s with { DockSettings = updatedDock };
|
||||
},
|
||||
false);
|
||||
_bandSettings = newSettings;
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Immutable;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Services;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Settings;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Dock;
|
||||
|
||||
/// <summary>
|
||||
/// ViewModel wrapping a <see cref="DockMonitorConfig"/> paired with its
|
||||
/// <see cref="MonitorInfo"/>. Exposes bindable properties for the monitor
|
||||
/// config UI and persists changes through <see cref="ISettingsService"/>.
|
||||
/// </summary>
|
||||
public partial class DockMonitorConfigViewModel : ObservableObject
|
||||
{
|
||||
private static readonly CompositeFormat ResolutionFormat = CompositeFormat.Parse("{0} \u00D7 {1}");
|
||||
|
||||
private readonly MonitorInfo _monitorInfo;
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly string _monitorDeviceId;
|
||||
|
||||
public DockMonitorConfigViewModel(
|
||||
DockMonitorConfig config,
|
||||
MonitorInfo monitorInfo,
|
||||
ISettingsService settingsService)
|
||||
{
|
||||
_monitorInfo = monitorInfo;
|
||||
_settingsService = settingsService;
|
||||
_monitorDeviceId = config.MonitorDeviceId;
|
||||
}
|
||||
|
||||
/// <summary>Gets the human-readable display name from the monitor hardware.</summary>
|
||||
public string DisplayName => _monitorInfo.DisplayName;
|
||||
|
||||
/// <summary>Gets the stable device identifier for this monitor.</summary>
|
||||
public string DeviceId => _monitorInfo.DeviceId;
|
||||
|
||||
/// <summary>Gets a value indicating whether this is the primary monitor.</summary>
|
||||
public bool IsPrimary => _monitorInfo.IsPrimary;
|
||||
|
||||
/// <summary>Gets the monitor resolution formatted as "W × H".</summary>
|
||||
public string Resolution => string.Format(
|
||||
CultureInfo.CurrentCulture,
|
||||
ResolutionFormat,
|
||||
_monitorInfo.Bounds.Width,
|
||||
_monitorInfo.Bounds.Height);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the dock is enabled on this monitor.
|
||||
/// </summary>
|
||||
public bool IsEnabled
|
||||
{
|
||||
get => GetConfig()?.Enabled ?? true;
|
||||
set
|
||||
{
|
||||
UpdateConfig(c => c with { Enabled = value });
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the side-override index for ComboBox binding.
|
||||
/// 0 = "Use default" (inherit), 1 = Left, 2 = Top, 3 = Right, 4 = Bottom.
|
||||
/// </summary>
|
||||
public int SideOverrideIndex
|
||||
{
|
||||
get => GetConfig()?.Side switch
|
||||
{
|
||||
null => 0,
|
||||
DockSide.Left => 1,
|
||||
DockSide.Top => 2,
|
||||
DockSide.Right => 3,
|
||||
DockSide.Bottom => 4,
|
||||
_ => 0,
|
||||
};
|
||||
set
|
||||
{
|
||||
var newSide = value switch
|
||||
{
|
||||
1 => (DockSide?)DockSide.Left,
|
||||
2 => (DockSide?)DockSide.Top,
|
||||
3 => (DockSide?)DockSide.Right,
|
||||
4 => (DockSide?)DockSide.Bottom,
|
||||
_ => null,
|
||||
};
|
||||
|
||||
UpdateConfig(c => c with { Side = newSide });
|
||||
OnPropertyChanged();
|
||||
OnPropertyChanged(nameof(HasSideOverride));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Gets a value indicating whether this monitor has a per-monitor side override.</summary>
|
||||
public bool HasSideOverride => GetConfig()?.Side is not null;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this monitor uses custom band pinning.
|
||||
/// When toggled ON, forks band lists from global settings.
|
||||
/// When toggled OFF, clears per-monitor bands.
|
||||
/// </summary>
|
||||
public bool IsCustomized
|
||||
{
|
||||
get => GetConfig()?.IsCustomized ?? false;
|
||||
set
|
||||
{
|
||||
_settingsService.UpdateSettings(s =>
|
||||
{
|
||||
var dockSettings = s.DockSettings;
|
||||
var configs = dockSettings.MonitorConfigs;
|
||||
var index = FindConfigIndex(configs);
|
||||
if (index < 0)
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
var config = configs[index];
|
||||
DockMonitorConfig updated;
|
||||
|
||||
if (value)
|
||||
{
|
||||
updated = config.ForkFromGlobal(dockSettings);
|
||||
}
|
||||
else
|
||||
{
|
||||
updated = config with
|
||||
{
|
||||
IsCustomized = false,
|
||||
StartBands = ImmutableList<DockBandSettings>.Empty,
|
||||
CenterBands = ImmutableList<DockBandSettings>.Empty,
|
||||
EndBands = ImmutableList<DockBandSettings>.Empty,
|
||||
};
|
||||
}
|
||||
|
||||
return s with
|
||||
{
|
||||
DockSettings = dockSettings with { MonitorConfigs = configs.SetItem(index, updated) },
|
||||
};
|
||||
});
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private DockMonitorConfig? GetConfig()
|
||||
{
|
||||
var configs = _settingsService.Settings.DockSettings.MonitorConfigs;
|
||||
for (var i = 0; i < configs.Count; i++)
|
||||
{
|
||||
if (string.Equals(configs[i].MonitorDeviceId, _monitorDeviceId, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return configs[i];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void UpdateConfig(Func<DockMonitorConfig, DockMonitorConfig> transform)
|
||||
{
|
||||
_settingsService.UpdateSettings(s =>
|
||||
{
|
||||
var dockSettings = s.DockSettings;
|
||||
var configs = dockSettings.MonitorConfigs;
|
||||
var index = FindConfigIndex(configs);
|
||||
if (index < 0)
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
var updated = transform(configs[index]);
|
||||
return s with
|
||||
{
|
||||
DockSettings = dockSettings with { MonitorConfigs = configs.SetItem(index, updated) },
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
private int FindConfigIndex(ImmutableList<DockMonitorConfig> configs)
|
||||
{
|
||||
for (var i = 0; i < configs.Count; i++)
|
||||
{
|
||||
if (string.Equals(configs[i].MonitorDeviceId, _monitorDeviceId, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -14,15 +14,23 @@ using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Dock;
|
||||
|
||||
public sealed partial class DockViewModel
|
||||
public sealed partial class DockViewModel : IDisposable
|
||||
{
|
||||
private readonly TopLevelCommandManager _topLevelCommandManager;
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly DockPageContext _pageContext; // only to be used for our own context menu - not for dock bands themselves
|
||||
private readonly IContextMenuFactory _contextMenuFactory;
|
||||
private readonly string? _monitorDeviceId;
|
||||
|
||||
private DockSettings _settings;
|
||||
private bool _isEditing;
|
||||
private bool _disposed;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the monitor device identifier this dock is associated with, or <c>null</c>
|
||||
/// for the default (single-monitor) dock.
|
||||
/// </summary>
|
||||
public string? MonitorDeviceId => _monitorDeviceId;
|
||||
|
||||
public TaskScheduler Scheduler { get; }
|
||||
|
||||
@@ -38,12 +46,14 @@ public sealed partial class DockViewModel
|
||||
TopLevelCommandManager tlcManager,
|
||||
IContextMenuFactory contextMenuFactory,
|
||||
TaskScheduler scheduler,
|
||||
ISettingsService settingsService)
|
||||
ISettingsService settingsService,
|
||||
string? monitorDeviceId = null)
|
||||
{
|
||||
_topLevelCommandManager = tlcManager;
|
||||
_contextMenuFactory = contextMenuFactory;
|
||||
_settingsService = settingsService;
|
||||
_settings = _settingsService.Settings.DockSettings;
|
||||
_monitorDeviceId = monitorDeviceId;
|
||||
Scheduler = scheduler;
|
||||
_pageContext = new(this);
|
||||
|
||||
@@ -72,17 +82,168 @@ public sealed partial class DockViewModel
|
||||
|
||||
public void UpdateSettings(DockSettings settings)
|
||||
{
|
||||
if (_isEditing)
|
||||
{
|
||||
Logger.LogDebug("DockViewModel.UpdateSettings skipped (edit in progress)");
|
||||
return;
|
||||
}
|
||||
|
||||
Logger.LogDebug($"DockViewModel.UpdateSettings");
|
||||
_settings = settings;
|
||||
SetupBands();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes bands from current settings. Call after the UI scheduler is ready
|
||||
/// (i.e., after the DockWindow is shown) to ensure proper dispatcher access.
|
||||
/// </summary>
|
||||
public void InitializeBands() => SetupBands();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the active band lists for this dock instance. Returns per-monitor bands
|
||||
/// when the associated monitor is customized; otherwise falls back to global bands.
|
||||
/// </summary>
|
||||
private (ImmutableList<DockBandSettings> Start, ImmutableList<DockBandSettings> Center, ImmutableList<DockBandSettings> End) GetActiveBands()
|
||||
{
|
||||
if (_monitorDeviceId is not null)
|
||||
{
|
||||
var config = FindMonitorConfig(_settings, _monitorDeviceId);
|
||||
if (config is not null)
|
||||
{
|
||||
return (
|
||||
config.ResolveStartBands(_settings.StartBands),
|
||||
config.ResolveCenterBands(_settings.CenterBands),
|
||||
config.ResolveEndBands(_settings.EndBands));
|
||||
}
|
||||
}
|
||||
|
||||
return (_settings.StartBands, _settings.CenterBands, _settings.EndBands);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an updated <see cref="DockSettings"/> with the given bands placed in the
|
||||
/// correct location — per-monitor config when customized, or global otherwise.
|
||||
/// </summary>
|
||||
private DockSettings WithActiveBands(
|
||||
ImmutableList<DockBandSettings> start,
|
||||
ImmutableList<DockBandSettings> center,
|
||||
ImmutableList<DockBandSettings> end)
|
||||
{
|
||||
if (_monitorDeviceId is not null)
|
||||
{
|
||||
var config = FindMonitorConfig(_settings, _monitorDeviceId);
|
||||
if (config is not null && config.IsCustomized)
|
||||
{
|
||||
var updatedConfig = config with
|
||||
{
|
||||
StartBands = start,
|
||||
CenterBands = center,
|
||||
EndBands = end,
|
||||
};
|
||||
return _settings with
|
||||
{
|
||||
MonitorConfigs = ReplaceMonitorConfig(_settings.MonitorConfigs, updatedConfig),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return _settings with
|
||||
{
|
||||
StartBands = start,
|
||||
CenterBands = center,
|
||||
EndBands = end,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures the monitor associated with this dock has its own independent band lists.
|
||||
/// If the monitor is not yet customized, forks bands from global settings.
|
||||
/// Returns <c>true</c> if the fork was performed, <c>false</c> if already customized or no monitor.
|
||||
/// </summary>
|
||||
public bool EnsureMonitorForked()
|
||||
{
|
||||
if (_monitorDeviceId is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var config = FindMonitorConfig(_settings, _monitorDeviceId);
|
||||
if (config is null || config.IsCustomized)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var forked = config.ForkFromGlobal(_settings);
|
||||
_settings = _settings with
|
||||
{
|
||||
MonitorConfigs = ReplaceMonitorConfig(_settings.MonitorConfigs, forked),
|
||||
};
|
||||
SaveSettings();
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the effective dock side for this instance, considering per-monitor overrides.
|
||||
/// </summary>
|
||||
public DockSide GetEffectiveSide()
|
||||
{
|
||||
if (_monitorDeviceId is not null)
|
||||
{
|
||||
var config = FindMonitorConfig(_settings, _monitorDeviceId);
|
||||
if (config is not null)
|
||||
{
|
||||
return config.ResolveSide(_settings.Side);
|
||||
}
|
||||
}
|
||||
|
||||
return _settings.Side;
|
||||
}
|
||||
|
||||
private static DockMonitorConfig? FindMonitorConfig(DockSettings settings, string deviceId)
|
||||
{
|
||||
var configs = settings.MonitorConfigs ?? System.Collections.Immutable.ImmutableList<DockMonitorConfig>.Empty;
|
||||
foreach (var config in configs)
|
||||
{
|
||||
if (string.Equals(config.MonitorDeviceId, deviceId, System.StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return config;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static ImmutableList<DockMonitorConfig> ReplaceMonitorConfig(
|
||||
ImmutableList<DockMonitorConfig> configs,
|
||||
DockMonitorConfig updated)
|
||||
{
|
||||
for (var i = 0; i < configs.Count; i++)
|
||||
{
|
||||
if (string.Equals(configs[i].MonitorDeviceId, updated.MonitorDeviceId, System.StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return configs.SetItem(i, updated);
|
||||
}
|
||||
}
|
||||
|
||||
return configs.Add(updated);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (!_disposed)
|
||||
{
|
||||
_topLevelCommandManager.DockBands.CollectionChanged -= DockBands_CollectionChanged;
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetupBands()
|
||||
{
|
||||
Logger.LogDebug($"Setting up dock bands");
|
||||
SetupBands(_settings.StartBands, StartItems);
|
||||
SetupBands(_settings.CenterBands, CenterItems);
|
||||
SetupBands(_settings.EndBands, EndItems);
|
||||
var (start, center, end) = GetActiveBands();
|
||||
SetupBands(start, StartItems);
|
||||
SetupBands(center, CenterItems);
|
||||
SetupBands(end, EndItems);
|
||||
}
|
||||
|
||||
private void SetupBands(
|
||||
@@ -207,42 +368,46 @@ public sealed partial class DockViewModel
|
||||
public void SyncBandPosition(DockBandViewModel band, DockPinSide targetSide, int targetIndex)
|
||||
{
|
||||
var bandId = band.Id;
|
||||
var dockSettings = _settings;
|
||||
var (activeSt, activeCt, activeEnd) = GetActiveBands();
|
||||
|
||||
var bandSettings = dockSettings.StartBands.FirstOrDefault(b => b.CommandId == bandId)
|
||||
?? dockSettings.CenterBands.FirstOrDefault(b => b.CommandId == bandId)
|
||||
?? dockSettings.EndBands.FirstOrDefault(b => b.CommandId == bandId);
|
||||
var bandSettings = activeSt.FirstOrDefault(b => b.CommandId == bandId)
|
||||
?? activeCt.FirstOrDefault(b => b.CommandId == bandId)
|
||||
?? activeEnd.FirstOrDefault(b => b.CommandId == bandId);
|
||||
|
||||
if (bandSettings == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove from all settings lists
|
||||
var newDock = dockSettings with
|
||||
{
|
||||
StartBands = dockSettings.StartBands.RemoveAll(b => b.CommandId == bandId),
|
||||
CenterBands = dockSettings.CenterBands.RemoveAll(b => b.CommandId == bandId),
|
||||
EndBands = dockSettings.EndBands.RemoveAll(b => b.CommandId == bandId),
|
||||
};
|
||||
// Remove from all active band lists
|
||||
var newStart = activeSt.RemoveAll(b => b.CommandId == bandId);
|
||||
var newCenter = activeCt.RemoveAll(b => b.CommandId == bandId);
|
||||
var newEnd = activeEnd.RemoveAll(b => b.CommandId == bandId);
|
||||
|
||||
// Add to target settings list at the correct index
|
||||
// Add to target list at the correct index
|
||||
var targetList = targetSide switch
|
||||
{
|
||||
DockPinSide.Start => newDock.StartBands,
|
||||
DockPinSide.Center => newDock.CenterBands,
|
||||
DockPinSide.End => newDock.EndBands,
|
||||
_ => newDock.StartBands,
|
||||
DockPinSide.Start => newStart,
|
||||
DockPinSide.Center => newCenter,
|
||||
DockPinSide.End => newEnd,
|
||||
_ => newStart,
|
||||
};
|
||||
var insertIndex = Math.Min(targetIndex, targetList.Count);
|
||||
newDock = targetSide switch
|
||||
switch (targetSide)
|
||||
{
|
||||
DockPinSide.Start => newDock with { StartBands = targetList.Insert(insertIndex, bandSettings) },
|
||||
DockPinSide.Center => newDock with { CenterBands = targetList.Insert(insertIndex, bandSettings) },
|
||||
DockPinSide.End => newDock with { EndBands = targetList.Insert(insertIndex, bandSettings) },
|
||||
_ => newDock with { StartBands = targetList.Insert(insertIndex, bandSettings) },
|
||||
};
|
||||
_settings = newDock;
|
||||
case DockPinSide.Start:
|
||||
newStart = newStart.Insert(insertIndex, bandSettings);
|
||||
break;
|
||||
case DockPinSide.Center:
|
||||
newCenter = newCenter.Insert(insertIndex, bandSettings);
|
||||
break;
|
||||
case DockPinSide.End:
|
||||
default:
|
||||
newEnd = newEnd.Insert(insertIndex, bandSettings);
|
||||
break;
|
||||
}
|
||||
|
||||
_settings = WithActiveBands(newStart, newCenter, newEnd);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -252,11 +417,11 @@ public sealed partial class DockViewModel
|
||||
public void MoveBandWithoutSaving(DockBandViewModel band, DockPinSide targetSide, int targetIndex)
|
||||
{
|
||||
var bandId = band.Id;
|
||||
var dockSettings = _settings;
|
||||
var (activeSt, activeCt, activeEnd) = GetActiveBands();
|
||||
|
||||
var bandSettings = dockSettings.StartBands.FirstOrDefault(b => b.CommandId == bandId)
|
||||
?? dockSettings.CenterBands.FirstOrDefault(b => b.CommandId == bandId)
|
||||
?? dockSettings.EndBands.FirstOrDefault(b => b.CommandId == bandId);
|
||||
var bandSettings = activeSt.FirstOrDefault(b => b.CommandId == bandId)
|
||||
?? activeCt.FirstOrDefault(b => b.CommandId == bandId)
|
||||
?? activeEnd.FirstOrDefault(b => b.CommandId == bandId);
|
||||
|
||||
if (bandSettings == null)
|
||||
{
|
||||
@@ -265,12 +430,9 @@ public sealed partial class DockViewModel
|
||||
}
|
||||
|
||||
// Remove from all sides (settings)
|
||||
var newDock = dockSettings with
|
||||
{
|
||||
StartBands = dockSettings.StartBands.RemoveAll(b => b.CommandId == bandId),
|
||||
CenterBands = dockSettings.CenterBands.RemoveAll(b => b.CommandId == bandId),
|
||||
EndBands = dockSettings.EndBands.RemoveAll(b => b.CommandId == bandId),
|
||||
};
|
||||
var newStart = activeSt.RemoveAll(b => b.CommandId == bandId);
|
||||
var newCenter = activeCt.RemoveAll(b => b.CommandId == bandId);
|
||||
var newEnd = activeEnd.RemoveAll(b => b.CommandId == bandId);
|
||||
|
||||
// Remove from UI collections
|
||||
StartItems.Remove(band);
|
||||
@@ -282,8 +444,8 @@ public sealed partial class DockViewModel
|
||||
{
|
||||
case DockPinSide.Start:
|
||||
{
|
||||
var settingsIndex = Math.Min(targetIndex, newDock.StartBands.Count);
|
||||
newDock = newDock with { StartBands = newDock.StartBands.Insert(settingsIndex, bandSettings) };
|
||||
var settingsIndex = Math.Min(targetIndex, newStart.Count);
|
||||
newStart = newStart.Insert(settingsIndex, bandSettings);
|
||||
|
||||
var uiIndex = Math.Min(targetIndex, StartItems.Count);
|
||||
StartItems.Insert(uiIndex, band);
|
||||
@@ -292,8 +454,8 @@ public sealed partial class DockViewModel
|
||||
|
||||
case DockPinSide.Center:
|
||||
{
|
||||
var settingsIndex = Math.Min(targetIndex, newDock.CenterBands.Count);
|
||||
newDock = newDock with { CenterBands = newDock.CenterBands.Insert(settingsIndex, bandSettings) };
|
||||
var settingsIndex = Math.Min(targetIndex, newCenter.Count);
|
||||
newCenter = newCenter.Insert(settingsIndex, bandSettings);
|
||||
|
||||
var uiIndex = Math.Min(targetIndex, CenterItems.Count);
|
||||
CenterItems.Insert(uiIndex, band);
|
||||
@@ -302,8 +464,8 @@ public sealed partial class DockViewModel
|
||||
|
||||
case DockPinSide.End:
|
||||
{
|
||||
var settingsIndex = Math.Min(targetIndex, newDock.EndBands.Count);
|
||||
newDock = newDock with { EndBands = newDock.EndBands.Insert(settingsIndex, bandSettings) };
|
||||
var settingsIndex = Math.Min(targetIndex, newEnd.Count);
|
||||
newEnd = newEnd.Insert(settingsIndex, bandSettings);
|
||||
|
||||
var uiIndex = Math.Min(targetIndex, EndItems.Count);
|
||||
EndItems.Insert(uiIndex, band);
|
||||
@@ -311,7 +473,7 @@ public sealed partial class DockViewModel
|
||||
}
|
||||
}
|
||||
|
||||
_settings = newDock;
|
||||
_settings = WithActiveBands(newStart, newCenter, newEnd);
|
||||
|
||||
Logger.LogDebug($"Moved band {bandId} to {targetSide} at index {targetIndex} (not saved yet)");
|
||||
}
|
||||
@@ -331,29 +493,95 @@ public sealed partial class DockViewModel
|
||||
// Preserve any per-band label edits made while in edit mode. Those edits are
|
||||
// saved independently of reorder, so merge the latest band settings back into
|
||||
// the local reordered snapshot before we persist dock settings.
|
||||
var latestBandSettings = BuildBandSettingsLookup(_settingsService.Settings.DockSettings);
|
||||
_settings = _settings with
|
||||
{
|
||||
StartBands = MergeBandSettings(_settings.StartBands, latestBandSettings),
|
||||
CenterBands = MergeBandSettings(_settings.CenterBands, latestBandSettings),
|
||||
EndBands = MergeBandSettings(_settings.EndBands, latestBandSettings),
|
||||
};
|
||||
var (latestStart, latestCenter, latestEnd) = GetActiveBandsFromSettings(_settingsService.Settings.DockSettings);
|
||||
var latestBandSettings = BuildBandSettingsLookup(latestStart, latestCenter, latestEnd);
|
||||
var (activeStart, activeCenter, activeEnd) = GetActiveBands();
|
||||
_settings = WithActiveBands(
|
||||
MergeBandSettings(activeStart, latestBandSettings),
|
||||
MergeBandSettings(activeCenter, latestBandSettings),
|
||||
MergeBandSettings(activeEnd, latestBandSettings));
|
||||
|
||||
_snapshotDockSettings = null;
|
||||
_snapshotBandViewModels = null;
|
||||
|
||||
// Save without hotReload to avoid triggering SettingsChanged → SetupBands,
|
||||
// which could race with stale DockBands_CollectionChanged work items and
|
||||
// re-add bands that were just unpinned.
|
||||
_settingsService.UpdateSettings(s => s with { DockSettings = _settings }, false);
|
||||
// Extract the final merged bands for this monitor
|
||||
var (myStart, myCenter, myEnd) = GetActiveBands();
|
||||
|
||||
// Save only this monitor's bands into the CURRENT persisted settings,
|
||||
// preserving other monitors' changes. Without this, each DockViewModel's
|
||||
// save would overwrite the entire DockSettings, causing the last save to
|
||||
// clobber changes from monitors that saved earlier.
|
||||
_settingsService.UpdateSettings(
|
||||
s =>
|
||||
{
|
||||
var currentDock = s.DockSettings;
|
||||
if (_monitorDeviceId is not null)
|
||||
{
|
||||
var config = FindMonitorConfig(currentDock, _monitorDeviceId);
|
||||
if (config is not null && config.IsCustomized)
|
||||
{
|
||||
var updatedConfig = config with
|
||||
{
|
||||
StartBands = myStart,
|
||||
CenterBands = myCenter,
|
||||
EndBands = myEnd,
|
||||
};
|
||||
var configs = currentDock.MonitorConfigs ?? ImmutableList<DockMonitorConfig>.Empty;
|
||||
return s with
|
||||
{
|
||||
DockSettings = currentDock with
|
||||
{
|
||||
MonitorConfigs = ReplaceMonitorConfig(configs, updatedConfig),
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return s with
|
||||
{
|
||||
DockSettings = currentDock with
|
||||
{
|
||||
StartBands = myStart,
|
||||
CenterBands = myCenter,
|
||||
EndBands = myEnd,
|
||||
},
|
||||
};
|
||||
},
|
||||
false);
|
||||
|
||||
// Refresh local settings from persisted state so all monitors' changes are visible
|
||||
_settings = _settingsService.Settings.DockSettings;
|
||||
_isEditing = false;
|
||||
Logger.LogDebug("Saved band order to settings");
|
||||
}
|
||||
|
||||
private static Dictionary<string, DockBandSettings> BuildBandSettingsLookup(DockSettings dockSettings)
|
||||
/// <summary>
|
||||
/// Gets active bands from a given DockSettings, considering this dock's monitor.
|
||||
/// </summary>
|
||||
private (ImmutableList<DockBandSettings> Start, ImmutableList<DockBandSettings> Center, ImmutableList<DockBandSettings> End) GetActiveBandsFromSettings(DockSettings dockSettings)
|
||||
{
|
||||
if (_monitorDeviceId is not null)
|
||||
{
|
||||
var config = FindMonitorConfig(dockSettings, _monitorDeviceId);
|
||||
if (config is not null)
|
||||
{
|
||||
return (
|
||||
config.ResolveStartBands(dockSettings.StartBands),
|
||||
config.ResolveCenterBands(dockSettings.CenterBands),
|
||||
config.ResolveEndBands(dockSettings.EndBands));
|
||||
}
|
||||
}
|
||||
|
||||
return (dockSettings.StartBands, dockSettings.CenterBands, dockSettings.EndBands);
|
||||
}
|
||||
|
||||
private static Dictionary<string, DockBandSettings> BuildBandSettingsLookup(
|
||||
ImmutableList<DockBandSettings> start,
|
||||
ImmutableList<DockBandSettings> center,
|
||||
ImmutableList<DockBandSettings> end)
|
||||
{
|
||||
var lookup = new Dictionary<string, DockBandSettings>(StringComparer.Ordinal);
|
||||
foreach (var band in dockSettings.StartBands.Concat(dockSettings.CenterBands).Concat(dockSettings.EndBands))
|
||||
foreach (var band in start.Concat(center).Concat(end))
|
||||
{
|
||||
lookup[band.CommandId] = band;
|
||||
}
|
||||
@@ -450,13 +678,13 @@ public sealed partial class DockViewModel
|
||||
return;
|
||||
}
|
||||
|
||||
var dockSettings = _settings;
|
||||
var (activeSt, activeCt, activeEnd) = GetActiveBands();
|
||||
|
||||
StartItems.Clear();
|
||||
CenterItems.Clear();
|
||||
EndItems.Clear();
|
||||
|
||||
foreach (var bandSettings in dockSettings.StartBands)
|
||||
foreach (var bandSettings in activeSt)
|
||||
{
|
||||
if (_snapshotBandViewModels.TryGetValue(bandSettings.CommandId, out var bandVM))
|
||||
{
|
||||
@@ -464,7 +692,7 @@ public sealed partial class DockViewModel
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var bandSettings in dockSettings.CenterBands)
|
||||
foreach (var bandSettings in activeCt)
|
||||
{
|
||||
if (_snapshotBandViewModels.TryGetValue(bandSettings.CommandId, out var bandVM))
|
||||
{
|
||||
@@ -472,7 +700,7 @@ public sealed partial class DockViewModel
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var bandSettings in dockSettings.EndBands)
|
||||
foreach (var bandSettings in activeEnd)
|
||||
{
|
||||
if (_snapshotBandViewModels.TryGetValue(bandSettings.CommandId, out var bandVM))
|
||||
{
|
||||
@@ -483,7 +711,7 @@ public sealed partial class DockViewModel
|
||||
|
||||
private void RebuildUICollections()
|
||||
{
|
||||
var dockSettings = _settings;
|
||||
var (activeSt, activeCt, activeEnd) = GetActiveBands();
|
||||
|
||||
// Create a lookup of all current band ViewModels
|
||||
var allBands = StartItems.Concat(CenterItems).Concat(EndItems).ToDictionary(b => b.Id);
|
||||
@@ -492,7 +720,7 @@ public sealed partial class DockViewModel
|
||||
CenterItems.Clear();
|
||||
EndItems.Clear();
|
||||
|
||||
foreach (var bandSettings in dockSettings.StartBands)
|
||||
foreach (var bandSettings in activeSt)
|
||||
{
|
||||
if (allBands.TryGetValue(bandSettings.CommandId, out var bandVM))
|
||||
{
|
||||
@@ -500,7 +728,7 @@ public sealed partial class DockViewModel
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var bandSettings in dockSettings.CenterBands)
|
||||
foreach (var bandSettings in activeCt)
|
||||
{
|
||||
if (allBands.TryGetValue(bandSettings.CommandId, out var bandVM))
|
||||
{
|
||||
@@ -508,7 +736,7 @@ public sealed partial class DockViewModel
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var bandSettings in dockSettings.EndBands)
|
||||
foreach (var bandSettings in activeEnd)
|
||||
{
|
||||
if (allBands.TryGetValue(bandSettings.CommandId, out var bandVM))
|
||||
{
|
||||
@@ -561,6 +789,7 @@ public sealed partial class DockViewModel
|
||||
// Create settings for the new band
|
||||
var bandSettings = new DockBandSettings { ProviderId = topLevel.CommandProviderId, CommandId = bandId };
|
||||
var dockSettings = _settings;
|
||||
var (activeSt, activeCt, activeEnd) = GetActiveBands();
|
||||
|
||||
// Create the band view model
|
||||
var bandVm = CreateBandItem(bandSettings, topLevel.ItemViewModel);
|
||||
@@ -569,15 +798,15 @@ public sealed partial class DockViewModel
|
||||
switch (targetSide)
|
||||
{
|
||||
case DockPinSide.Start:
|
||||
_settings = dockSettings with { StartBands = dockSettings.StartBands.Add(bandSettings) };
|
||||
_settings = WithActiveBands(activeSt.Add(bandSettings), activeCt, activeEnd);
|
||||
StartItems.Add(bandVm);
|
||||
break;
|
||||
case DockPinSide.Center:
|
||||
_settings = dockSettings with { CenterBands = dockSettings.CenterBands.Add(bandSettings) };
|
||||
_settings = WithActiveBands(activeSt, activeCt.Add(bandSettings), activeEnd);
|
||||
CenterItems.Add(bandVm);
|
||||
break;
|
||||
case DockPinSide.End:
|
||||
_settings = dockSettings with { EndBands = dockSettings.EndBands.Add(bandSettings) };
|
||||
_settings = WithActiveBands(activeSt, activeCt, activeEnd.Add(bandSettings));
|
||||
EndItems.Add(bandVm);
|
||||
break;
|
||||
}
|
||||
@@ -600,15 +829,13 @@ public sealed partial class DockViewModel
|
||||
public void UnpinBand(DockBandViewModel band)
|
||||
{
|
||||
var bandId = band.Id;
|
||||
var dockSettings = _settings;
|
||||
var (activeSt, activeCt, activeEnd) = GetActiveBands();
|
||||
|
||||
// Remove from settings
|
||||
_settings = dockSettings with
|
||||
{
|
||||
StartBands = dockSettings.StartBands.RemoveAll(b => b.CommandId == bandId),
|
||||
CenterBands = dockSettings.CenterBands.RemoveAll(b => b.CommandId == bandId),
|
||||
EndBands = dockSettings.EndBands.RemoveAll(b => b.CommandId == bandId),
|
||||
};
|
||||
_settings = WithActiveBands(
|
||||
activeSt.RemoveAll(b => b.CommandId == bandId),
|
||||
activeCt.RemoveAll(b => b.CommandId == bandId),
|
||||
activeEnd.RemoveAll(b => b.CommandId == bandId));
|
||||
|
||||
// Remove from UI collections
|
||||
StartItems.Remove(band);
|
||||
@@ -670,14 +897,16 @@ public sealed partial class DockViewModel
|
||||
private void EmitDockConfiguration()
|
||||
{
|
||||
var isDockEnabled = _settingsService.Settings.EnableDock;
|
||||
var dockSide = isDockEnabled ? _settings.Side.ToString().ToLowerInvariant() : "none";
|
||||
var dockSide = isDockEnabled ? GetEffectiveSide().ToString().ToLowerInvariant() : "none";
|
||||
|
||||
var (activeSt, activeCt, activeEnd) = GetActiveBands();
|
||||
|
||||
static string FormatBands(ImmutableList<DockBandSettings> bands) =>
|
||||
string.Join("\n", bands.Select(b => $"{b.ProviderId}/{b.CommandId}"));
|
||||
|
||||
var startBands = isDockEnabled ? FormatBands(_settings.StartBands) : string.Empty;
|
||||
var centerBands = isDockEnabled ? FormatBands(_settings.CenterBands) : string.Empty;
|
||||
var endBands = isDockEnabled ? FormatBands(_settings.EndBands) : string.Empty;
|
||||
var startBands = isDockEnabled ? FormatBands(activeSt) : string.Empty;
|
||||
var centerBands = isDockEnabled ? FormatBands(activeCt) : string.Empty;
|
||||
var endBands = isDockEnabled ? FormatBands(activeEnd) : string.Empty;
|
||||
|
||||
WeakReferenceMessenger.Default.Send(new TelemetryDockConfigurationMessage(
|
||||
isDockEnabled, dockSide, startBands, centerBands, endBands));
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
// 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;
|
||||
|
||||
/// <summary>
|
||||
/// Broadcast when the user exits dock edit mode on any monitor.
|
||||
/// All DockControls should respond by saving or discarding their changes.
|
||||
/// </summary>
|
||||
/// <param name="Discard">True to discard changes; false to save them.</param>
|
||||
public record ExitDockEditModeMessage(bool Discard);
|
||||
@@ -12,4 +12,5 @@ public record PinToDockMessage(
|
||||
bool Pin,
|
||||
DockPinSide Side = DockPinSide.Start,
|
||||
bool? ShowTitles = null,
|
||||
bool? ShowSubtitles = null);
|
||||
bool? ShowSubtitles = null,
|
||||
string? MonitorDeviceId = null);
|
||||
|
||||
@@ -2,6 +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.Collections.Generic;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Settings;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
@@ -12,4 +13,5 @@ public record ShowPinToDockDialogMessage(
|
||||
string Title,
|
||||
string Subtitle,
|
||||
IconInfoViewModel? Icon,
|
||||
DockSide DockSide);
|
||||
DockSide DockSide,
|
||||
IReadOnlyList<Microsoft.CmdPal.UI.ViewModels.Models.MonitorInfo>? AvailableMonitors = null);
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Service for enumerating and tracking connected display monitors.
|
||||
/// </summary>
|
||||
public interface IMonitorService
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets all currently connected monitors.
|
||||
/// </summary>
|
||||
IReadOnlyList<MonitorInfo> GetMonitors();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a specific monitor by its device identifier.
|
||||
/// </summary>
|
||||
MonitorInfo? GetMonitorByDeviceId(string deviceId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the primary monitor.
|
||||
/// </summary>
|
||||
MonitorInfo? GetPrimaryMonitor();
|
||||
|
||||
/// <summary>
|
||||
/// Invalidates the cached monitor list and raises <see cref="MonitorsChanged"/>.
|
||||
/// Call this when a display settings change is detected (e.g. WM_DISPLAYCHANGE).
|
||||
/// </summary>
|
||||
void NotifyMonitorsChanged();
|
||||
|
||||
/// <summary>
|
||||
/// Raised when the set of connected monitors changes (connect, disconnect, or resolution change).
|
||||
/// </summary>
|
||||
event System.EventHandler? MonitorsChanged;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
// 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.Text.Json.Serialization;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a physical display monitor connected to the system.
|
||||
/// </summary>
|
||||
public sealed record MonitorInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the device identifier (e.g. <c>\\.\DISPLAY1</c>).
|
||||
/// </summary>
|
||||
public required string DeviceId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the human-readable display name (e.g. <c>DELL U2723QE</c>).
|
||||
/// </summary>
|
||||
public required string DisplayName { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the full monitor rectangle in virtual-screen coordinates.
|
||||
/// </summary>
|
||||
public required ScreenRect Bounds { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the work area (excludes the taskbar) in virtual-screen coordinates.
|
||||
/// </summary>
|
||||
public required ScreenRect WorkArea { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the DPI value for this monitor (e.g. 96, 120, 144, 192).
|
||||
/// </summary>
|
||||
public required uint Dpi { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this is the primary monitor.
|
||||
/// </summary>
|
||||
public required bool IsPrimary { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the scale factor for this monitor (e.g. 1.0 = 100%, 1.5 = 150%).
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public double ScaleFactor => Dpi / 96.0;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// 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;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the bounds of a monitor in virtual-screen coordinates.
|
||||
/// </summary>
|
||||
public readonly record struct ScreenRect(int Left, int Top, int Right, int Bottom)
|
||||
{
|
||||
public int Width => Right - Left;
|
||||
|
||||
public int Height => Bottom - Top;
|
||||
}
|
||||
@@ -2,12 +2,14 @@
|
||||
// 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.Immutable;
|
||||
using System.Diagnostics;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
using System.Text.Json.Serialization.Metadata;
|
||||
using ManagedCommon;
|
||||
using Microsoft.CmdPal.Common.Services;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Settings;
|
||||
using Windows.Foundation;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Services;
|
||||
@@ -87,6 +89,8 @@ public sealed class SettingsService : ISettingsService
|
||||
DeprecatedHotkeyGoesHomeKey,
|
||||
(ref SettingsModel model, bool goesHome) => model = model with { AutoGoHomeInterval = goesHome ? TimeSpan.Zero : Timeout.InfiniteTimeSpan },
|
||||
JsonSerializationContext.Default.Boolean);
|
||||
|
||||
migratedAny |= TryMigrateBandShowLabels(root, ref _settings);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -132,4 +136,106 @@ public sealed class SettingsService : ISettingsService
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Migrates per-band <c>ShowLabels</c> to <c>ShowTitles</c> and <c>ShowSubtitles</c>.
|
||||
/// The old <c>ShowLabels</c> property on <see cref="DockBandSettings"/> was renamed to
|
||||
/// <c>ShowTitles</c> (with <c>ShowSubtitles</c> added). Because the legacy property is
|
||||
/// <c>[JsonIgnore]</c>, old JSON values are lost during deserialization. This migration
|
||||
/// reads the raw JSON to recover them.
|
||||
/// </summary>
|
||||
private static bool TryMigrateBandShowLabels(JsonObject root, ref SettingsModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (root[nameof(SettingsModel.DockSettings)] is not JsonObject dockSettingsNode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var migrated = false;
|
||||
var ds = model.DockSettings;
|
||||
|
||||
var newStart = MigrateBandList(dockSettingsNode, nameof(DockSettings.StartBands), ds.StartBands, ref migrated);
|
||||
var newCenter = MigrateBandList(dockSettingsNode, nameof(DockSettings.CenterBands), ds.CenterBands, ref migrated);
|
||||
var newEnd = MigrateBandList(dockSettingsNode, nameof(DockSettings.EndBands), ds.EndBands, ref migrated);
|
||||
|
||||
if (migrated)
|
||||
{
|
||||
model = model with
|
||||
{
|
||||
DockSettings = ds with
|
||||
{
|
||||
StartBands = newStart,
|
||||
CenterBands = newCenter,
|
||||
EndBands = newEnd,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return migrated;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError("Error during band ShowLabels migration.", ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scans a single band array in the raw JSON for <c>ShowLabels</c> entries that
|
||||
/// need migrating to <c>ShowTitles</c> / <c>ShowSubtitles</c>.
|
||||
/// </summary>
|
||||
private static ImmutableList<DockBandSettings> MigrateBandList(
|
||||
JsonObject dockSettingsNode,
|
||||
string bandKey,
|
||||
ImmutableList<DockBandSettings> bands,
|
||||
ref bool anyMigrated)
|
||||
{
|
||||
if (dockSettingsNode[bandKey] is not JsonArray jsonBands)
|
||||
{
|
||||
return bands;
|
||||
}
|
||||
|
||||
var builder = bands.ToBuilder();
|
||||
var listChanged = false;
|
||||
|
||||
for (var i = 0; i < builder.Count && i < jsonBands.Count; i++)
|
||||
{
|
||||
if (jsonBands[i] is not JsonObject jsonBand)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Only migrate if old key exists and new key does not
|
||||
if (!jsonBand.ContainsKey("ShowLabels") || jsonBand.ContainsKey("ShowTitles"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var showLabelsNode = jsonBand["ShowLabels"];
|
||||
if (showLabelsNode is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var showLabels = showLabelsNode.GetValue<bool>();
|
||||
var band = builder[i];
|
||||
band = band with
|
||||
{
|
||||
ShowTitles = band.ShowTitles ?? showLabels,
|
||||
ShowSubtitles = band.ShowSubtitles ?? showLabels,
|
||||
};
|
||||
builder[i] = band;
|
||||
listChanged = true;
|
||||
}
|
||||
|
||||
if (listChanged)
|
||||
{
|
||||
anyMigrated = true;
|
||||
return builder.ToImmutable();
|
||||
}
|
||||
|
||||
return bands;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,8 @@ namespace Microsoft.CmdPal.UI.ViewModels.Settings;
|
||||
|
||||
/// <summary>
|
||||
/// Settings for the Dock. These are settings for _the whole dock_. Band-specific
|
||||
/// settings are in <see cref="DockBandSettings"/>.
|
||||
/// settings are in <see cref="DockBandSettings"/>. Per-monitor overrides are
|
||||
/// stored in <see cref="MonitorConfigs"/>.
|
||||
/// </summary>
|
||||
public record DockSettings
|
||||
{
|
||||
@@ -92,11 +93,147 @@ public record DockSettings
|
||||
|
||||
public bool ShowLabels { get; init; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the per-monitor dock configurations. Each entry overrides global
|
||||
/// settings for a specific display. Empty by default (all monitors use global).
|
||||
/// </summary>
|
||||
private ImmutableList<DockMonitorConfig>? _monitorConfigs = ImmutableList<DockMonitorConfig>.Empty;
|
||||
|
||||
public ImmutableList<DockMonitorConfig> MonitorConfigs
|
||||
{
|
||||
get => _monitorConfigs ?? ImmutableList<DockMonitorConfig>.Empty;
|
||||
init => _monitorConfigs = value ?? ImmutableList<DockMonitorConfig>.Empty;
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public IEnumerable<(string ProviderId, string CommandId)> AllPinnedCommands =>
|
||||
StartBands.Select(b => (b.ProviderId, b.CommandId))
|
||||
.Concat(CenterBands.Select(b => (b.ProviderId, b.CommandId)))
|
||||
.Concat(EndBands.Select(b => (b.ProviderId, b.CommandId)));
|
||||
public IEnumerable<(string ProviderId, string CommandId)> AllPinnedCommands
|
||||
{
|
||||
get
|
||||
{
|
||||
// Start with global bands
|
||||
var result = StartBands.Select(b => (b.ProviderId, b.CommandId))
|
||||
.Concat(CenterBands.Select(b => (b.ProviderId, b.CommandId)))
|
||||
.Concat(EndBands.Select(b => (b.ProviderId, b.CommandId)));
|
||||
|
||||
// Include per-monitor bands so that commands pinned to specific
|
||||
// monitors are loaded as TopLevelViewModels and appear in the dock.
|
||||
var configs = MonitorConfigs ?? ImmutableList<DockMonitorConfig>.Empty;
|
||||
foreach (var config in configs)
|
||||
{
|
||||
if (config.IsCustomized)
|
||||
{
|
||||
var start = config.StartBands ?? ImmutableList<DockBandSettings>.Empty;
|
||||
var center = config.CenterBands ?? ImmutableList<DockBandSettings>.Empty;
|
||||
var end = config.EndBands ?? ImmutableList<DockBandSettings>.Empty;
|
||||
result = result
|
||||
.Concat(start.Select(b => (b.ProviderId, b.CommandId)))
|
||||
.Concat(center.Select(b => (b.ProviderId, b.CommandId)))
|
||||
.Concat(end.Select(b => (b.ProviderId, b.CommandId)));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Per-monitor configuration for the dock. Each monitor can override the global
|
||||
/// dock side, enable/disable its dock, and optionally maintain independent band lists.
|
||||
/// Uses a nullable-override pattern: <c>null</c> values inherit from global <see cref="DockSettings"/>.
|
||||
/// </summary>
|
||||
public sealed record DockMonitorConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the monitor device identifier (e.g. <c>\\.\DISPLAY1</c>).
|
||||
/// </summary>
|
||||
public required string MonitorDeviceId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the dock is enabled on this monitor. Defaults to <c>true</c>.
|
||||
/// </summary>
|
||||
public bool Enabled { get; init; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the dock side override for this monitor. When <c>null</c>, inherits the global
|
||||
/// <see cref="DockSettings.Side"/> value.
|
||||
/// </summary>
|
||||
public DockSide? Side { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this monitor is the primary display.
|
||||
/// Used as a stable key for reconciliation when device IDs change across reboots.
|
||||
/// </summary>
|
||||
public bool IsPrimary { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this monitor has its own independent band lists.
|
||||
/// When <c>false</c>, the monitor inherits bands from the global <see cref="DockSettings"/>.
|
||||
/// </summary>
|
||||
public bool IsCustomized { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the per-monitor start bands. Only used when <see cref="IsCustomized"/> is <c>true</c>.
|
||||
/// </summary>
|
||||
public ImmutableList<DockBandSettings>? StartBands { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the per-monitor center bands. Only used when <see cref="IsCustomized"/> is <c>true</c>.
|
||||
/// </summary>
|
||||
public ImmutableList<DockBandSettings>? CenterBands { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the per-monitor end bands. Only used when <see cref="IsCustomized"/> is <c>true</c>.
|
||||
/// </summary>
|
||||
public ImmutableList<DockBandSettings>? EndBands { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the UTC timestamp when this monitor was last seen connected. Used for
|
||||
/// staleness pruning: configs not seen for 6+ months are automatically removed
|
||||
/// during reconciliation.
|
||||
/// </summary>
|
||||
public DateTime? LastSeen { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the effective dock side for this monitor.
|
||||
/// </summary>
|
||||
public DockSide ResolveSide(DockSide defaultSide) => Side ?? defaultSide;
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the effective start bands for this monitor.
|
||||
/// Returns per-monitor bands when customized; otherwise falls back to the global bands.
|
||||
/// </summary>
|
||||
public ImmutableList<DockBandSettings> ResolveStartBands(ImmutableList<DockBandSettings> globalBands) =>
|
||||
IsCustomized && StartBands is not null ? StartBands : globalBands;
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the effective center bands for this monitor.
|
||||
/// Returns per-monitor bands when customized; otherwise falls back to the global bands.
|
||||
/// </summary>
|
||||
public ImmutableList<DockBandSettings> ResolveCenterBands(ImmutableList<DockBandSettings> globalBands) =>
|
||||
IsCustomized && CenterBands is not null ? CenterBands : globalBands;
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the effective end bands for this monitor.
|
||||
/// Returns per-monitor bands when customized; otherwise falls back to the global bands.
|
||||
/// </summary>
|
||||
public ImmutableList<DockBandSettings> ResolveEndBands(ImmutableList<DockBandSettings> globalBands) =>
|
||||
IsCustomized && EndBands is not null ? EndBands : globalBands;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="DockMonitorConfig"/> that is a customized fork of the
|
||||
/// given global dock settings. Copies global bands into per-monitor band lists so
|
||||
/// they can be independently modified.
|
||||
/// </summary>
|
||||
public DockMonitorConfig ForkFromGlobal(DockSettings globalSettings) => this with
|
||||
{
|
||||
IsCustomized = true,
|
||||
|
||||
// Create independent copies by rebuilding the immutable lists
|
||||
StartBands = ImmutableList.CreateRange(globalSettings.StartBands ?? ImmutableList<DockBandSettings>.Empty),
|
||||
CenterBands = ImmutableList.CreateRange(globalSettings.CenterBands ?? ImmutableList<DockBandSettings>.Empty),
|
||||
EndBands = ImmutableList.CreateRange(globalSettings.EndBands ?? ImmutableList<DockBandSettings>.Empty),
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -0,0 +1,206 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Settings;
|
||||
|
||||
/// <summary>
|
||||
/// Reconciles persisted <see cref="DockMonitorConfig"/> entries against the
|
||||
/// set of currently connected monitors. Handles stale device IDs that may change
|
||||
/// across reboots by using the <see cref="DockMonitorConfig.IsPrimary"/> flag as
|
||||
/// a secondary matching key.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// All operations are pure — they return new immutable lists rather than
|
||||
/// mutating input collections.
|
||||
/// </remarks>
|
||||
public static class MonitorConfigReconciler
|
||||
{
|
||||
/// <summary>
|
||||
/// Configs whose <see cref="DockMonitorConfig.LastSeen"/> is older than this
|
||||
/// duration are pruned during reconciliation.
|
||||
/// </summary>
|
||||
internal static readonly TimeSpan StaleThreshold = TimeSpan.FromDays(180);
|
||||
|
||||
/// <summary>
|
||||
/// Reconciles persisted monitor configs against the current set of connected monitors.
|
||||
/// <para>
|
||||
/// <b>Phase 1</b>: Exact DeviceId matching — keep IsPrimary up-to-date.<br/>
|
||||
/// <b>Phase 2</b>: Fuzzy matching — reassociate unmatched configs by IsPrimary flag.<br/>
|
||||
/// <b>Phase 3</b>: Create default configs for monitors that have no matching config.<br/>
|
||||
/// <b>Phase 4</b>: Retain disconnected monitor configs for future reconnection; prune entries not seen for 6+ months.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public static ImmutableList<DockMonitorConfig> Reconcile(
|
||||
ImmutableList<DockMonitorConfig>? existingConfigs,
|
||||
IReadOnlyList<MonitorInfo> currentMonitors)
|
||||
{
|
||||
// Use Date (day granularity) so the value stabilizes across multiple reconciliations
|
||||
// within the same day. This prevents infinite loops: SettingsChanged → SyncDocks →
|
||||
// Reconcile → SettingsChanged when LastSeen changes by milliseconds each call.
|
||||
return Reconcile(existingConfigs, currentMonitors, DateTime.UtcNow.Date);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overload accepting an explicit <paramref name="utcNow"/> for testability.
|
||||
/// </summary>
|
||||
internal static ImmutableList<DockMonitorConfig> Reconcile(
|
||||
ImmutableList<DockMonitorConfig>? existingConfigs,
|
||||
IReadOnlyList<MonitorInfo> currentMonitors,
|
||||
DateTime utcNow)
|
||||
{
|
||||
existingConfigs ??= ImmutableList<DockMonitorConfig>.Empty;
|
||||
|
||||
if (currentMonitors.Count == 0)
|
||||
{
|
||||
return existingConfigs;
|
||||
}
|
||||
|
||||
// Build sets for tracking
|
||||
var matchedMonitorDeviceIds = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
var matchedConfigIndices = new HashSet<int>();
|
||||
var result = new List<DockMonitorConfig>(currentMonitors.Count);
|
||||
|
||||
// Convert to mutable working list for easier manipulation
|
||||
var configs = new List<DockMonitorConfig>(existingConfigs);
|
||||
|
||||
// Phase 1: Exact DeviceId match
|
||||
for (var mi = 0; mi < currentMonitors.Count; mi++)
|
||||
{
|
||||
var monitor = currentMonitors[mi];
|
||||
for (var ci = 0; ci < configs.Count; ci++)
|
||||
{
|
||||
if (matchedConfigIndices.Contains(ci))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (string.Equals(configs[ci].MonitorDeviceId, monitor.DeviceId, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// Update IsPrimary and LastSeen to current state
|
||||
result.Add(configs[ci] with { IsPrimary = monitor.IsPrimary, LastSeen = utcNow });
|
||||
matchedMonitorDeviceIds.Add(monitor.DeviceId);
|
||||
matchedConfigIndices.Add(ci);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Phase 2: Fuzzy match by IsPrimary for unmatched configs (primary only).
|
||||
// Non-primary monitors are not interchangeable, so we only fuzzy-match the primary.
|
||||
for (var mi = 0; mi < currentMonitors.Count; mi++)
|
||||
{
|
||||
var monitor = currentMonitors[mi];
|
||||
if (!monitor.IsPrimary || matchedMonitorDeviceIds.Contains(monitor.DeviceId))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (var ci = 0; ci < configs.Count; ci++)
|
||||
{
|
||||
if (matchedConfigIndices.Contains(ci))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (configs[ci].IsPrimary)
|
||||
{
|
||||
// Reassociate: update DeviceId, IsPrimary, and LastSeen
|
||||
result.Add(configs[ci] with
|
||||
{
|
||||
MonitorDeviceId = monitor.DeviceId,
|
||||
IsPrimary = monitor.IsPrimary,
|
||||
LastSeen = utcNow,
|
||||
});
|
||||
matchedMonitorDeviceIds.Add(monitor.DeviceId);
|
||||
matchedConfigIndices.Add(ci);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Phase 3: Create defaults for new monitors with no matching config.
|
||||
// Primary monitors inherit global bands (IsCustomized = false) for a seamless
|
||||
// upgrade path. Secondary monitors start with empty band lists so users don't
|
||||
// have to manually unpin bands from every new display.
|
||||
for (var mi = 0; mi < currentMonitors.Count; mi++)
|
||||
{
|
||||
var monitor = currentMonitors[mi];
|
||||
if (matchedMonitorDeviceIds.Contains(monitor.DeviceId))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (monitor.IsPrimary)
|
||||
{
|
||||
// Primary: inherit global bands (IsCustomized = false)
|
||||
result.Add(new DockMonitorConfig
|
||||
{
|
||||
MonitorDeviceId = monitor.DeviceId,
|
||||
Enabled = true,
|
||||
IsPrimary = true,
|
||||
LastSeen = utcNow,
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// Secondary: start with empty bands so users choose what to pin per-monitor
|
||||
result.Add(new DockMonitorConfig
|
||||
{
|
||||
MonitorDeviceId = monitor.DeviceId,
|
||||
Enabled = true,
|
||||
IsPrimary = false,
|
||||
IsCustomized = true,
|
||||
StartBands = ImmutableList<DockBandSettings>.Empty,
|
||||
CenterBands = ImmutableList<DockBandSettings>.Empty,
|
||||
EndBands = ImmutableList<DockBandSettings>.Empty,
|
||||
LastSeen = utcNow,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Phase 4: Retain disconnected monitor configs so settings survive reconnection.
|
||||
// Prune entries not seen for longer than StaleThreshold (6 months).
|
||||
for (var ci = 0; ci < configs.Count; ci++)
|
||||
{
|
||||
if (matchedConfigIndices.Contains(ci))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var config = configs[ci];
|
||||
var lastSeen = config.LastSeen ?? utcNow; // Treat legacy entries (no LastSeen) as fresh
|
||||
if ((utcNow - lastSeen) < StaleThreshold)
|
||||
{
|
||||
result.Add(config);
|
||||
}
|
||||
}
|
||||
|
||||
// Return the original reference when nothing actually changed so callers
|
||||
// can use reference equality to skip no-op settings writes.
|
||||
if (result.Count == existingConfigs.Count)
|
||||
{
|
||||
var changed = false;
|
||||
for (var i = 0; i < result.Count; i++)
|
||||
{
|
||||
if (!result[i].Equals(existingConfigs[i]))
|
||||
{
|
||||
changed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!changed)
|
||||
{
|
||||
return existingConfigs;
|
||||
}
|
||||
}
|
||||
|
||||
return ImmutableList.CreateRange(result);
|
||||
}
|
||||
}
|
||||
@@ -196,6 +196,8 @@ public record SettingsModel
|
||||
[JsonSerializable(typeof(ImmutableDictionary<string, FallbackSettings>), TypeInfoPropertyName = "ImmutableFallbackDictionary")]
|
||||
[JsonSerializable(typeof(ImmutableList<string>), TypeInfoPropertyName = "ImmutableStringList")]
|
||||
[JsonSerializable(typeof(ImmutableList<DockBandSettings>), TypeInfoPropertyName = "ImmutableDockBandSettingsList")]
|
||||
[JsonSerializable(typeof(DockMonitorConfig))]
|
||||
[JsonSerializable(typeof(ImmutableList<DockMonitorConfig>), TypeInfoPropertyName = "ImmutableDockMonitorConfigList")]
|
||||
[JsonSerializable(typeof(ImmutableDictionary<string, ProviderSettings>), TypeInfoPropertyName = "ImmutableProviderSettingsDictionary")]
|
||||
[JsonSerializable(typeof(ImmutableDictionary<string, CommandAlias>), TypeInfoPropertyName = "ImmutableAliasDictionary")]
|
||||
[JsonSerializable(typeof(ImmutableList<TopLevelHotkey>), TypeInfoPropertyName = "ImmutableTopLevelHotkeyList")]
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Dock;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Services;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Settings;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
@@ -29,6 +31,7 @@ public partial class SettingsViewModel : INotifyPropertyChanged
|
||||
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly TopLevelCommandManager _topLevelCommandManager;
|
||||
private readonly IMonitorService? _monitorService;
|
||||
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
@@ -250,20 +253,26 @@ public partial class SettingsViewModel : INotifyPropertyChanged
|
||||
|
||||
public ObservableCollection<FallbackSettingsViewModel> FallbackRankings { get; set; } = new();
|
||||
|
||||
public ObservableCollection<DockMonitorConfigViewModel> MonitorConfigs { get; } = new();
|
||||
|
||||
public SettingsExtensionsViewModel Extensions { get; }
|
||||
|
||||
public SettingsViewModel(
|
||||
TopLevelCommandManager topLevelCommandManager,
|
||||
TaskScheduler scheduler,
|
||||
IThemeService themeService,
|
||||
ISettingsService settingsService)
|
||||
ISettingsService settingsService,
|
||||
IMonitorService? monitorService = null)
|
||||
{
|
||||
_settingsService = settingsService;
|
||||
_topLevelCommandManager = topLevelCommandManager;
|
||||
_monitorService = monitorService;
|
||||
|
||||
Appearance = new AppearanceSettingsViewModel(themeService, settingsService);
|
||||
DockAppearance = new DockAppearanceSettingsViewModel(themeService, settingsService);
|
||||
|
||||
PopulateMonitorConfigs();
|
||||
|
||||
var activeProviders = GetCommandProviders();
|
||||
var allProviderSettings = _settingsService.Settings.ProviderSettings;
|
||||
|
||||
@@ -332,4 +341,43 @@ public partial class SettingsViewModel : INotifyPropertyChanged
|
||||
_settingsService.UpdateSettings(s => s with { FallbackRanks = FallbackRankings.Select(s2 => s2.Id).ToArray() });
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(FallbackRankings)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds or refreshes the <see cref="MonitorConfigs"/> collection by reconciling
|
||||
/// connected monitors with persisted per-monitor settings.
|
||||
/// </summary>
|
||||
public void PopulateMonitorConfigs()
|
||||
{
|
||||
if (_monitorService is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var monitors = _monitorService.GetMonitors();
|
||||
var currentSettings = _settingsService.Settings.DockSettings;
|
||||
|
||||
var reconciled = MonitorConfigReconciler.Reconcile(currentSettings.MonitorConfigs, monitors);
|
||||
|
||||
if (!reconciled.SequenceEqual(currentSettings.MonitorConfigs))
|
||||
{
|
||||
_settingsService.UpdateSettings(s => s with
|
||||
{
|
||||
DockSettings = s.DockSettings with { MonitorConfigs = reconciled },
|
||||
});
|
||||
}
|
||||
|
||||
MonitorConfigs.Clear();
|
||||
foreach (var monitor in monitors)
|
||||
{
|
||||
var config = reconciled.FirstOrDefault(c =>
|
||||
string.Equals(c.MonitorDeviceId, monitor.DeviceId, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (config is not null)
|
||||
{
|
||||
MonitorConfigs.Add(new DockMonitorConfigViewModel(config, monitor, _settingsService));
|
||||
}
|
||||
}
|
||||
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(MonitorConfigs)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -707,7 +707,7 @@ public sealed partial class TopLevelCommandManager : ObservableObject,
|
||||
{
|
||||
if (message.Pin)
|
||||
{
|
||||
wrapper?.PinDockBand(message.CommandId, _serviceProvider, message.Side, message.ShowTitles, message.ShowSubtitles);
|
||||
wrapper?.PinDockBand(message.CommandId, _serviceProvider, message.Side, message.ShowTitles, message.ShowSubtitles, message.MonitorDeviceId);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -257,6 +257,14 @@ public partial class App : Application, IDisposable
|
||||
services.AddSingleton<DockViewModel>();
|
||||
services.AddSingleton<IContextMenuFactory, CommandPaletteContextMenuFactory>();
|
||||
services.AddSingleton<IPageViewModelFactoryService, CommandPalettePageViewModelFactory>();
|
||||
|
||||
// Multi-monitor dock support
|
||||
services.AddSingleton<IMonitorService, MonitorService>();
|
||||
services.AddSingleton<Dock.DockWindowManager>(sp =>
|
||||
new Dock.DockWindowManager(
|
||||
sp.GetRequiredService<IMonitorService>(),
|
||||
sp.GetRequiredService<ISettingsService>(),
|
||||
Microsoft.UI.Dispatching.DispatcherQueue.GetForCurrentThread()));
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
||||
@@ -2,12 +2,15 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using ManagedCommon;
|
||||
using Microsoft.CmdPal.Ext.Apps;
|
||||
using Microsoft.CmdPal.Ext.Apps.Programs;
|
||||
using Microsoft.CmdPal.UI.ViewModels;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Services;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Settings;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
@@ -20,11 +23,13 @@ internal sealed partial class CommandPaletteContextMenuFactory : IContextMenuFac
|
||||
{
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly TopLevelCommandManager _topLevelCommandManager;
|
||||
private readonly IMonitorService? _monitorService;
|
||||
|
||||
public CommandPaletteContextMenuFactory(ISettingsService settingsService, TopLevelCommandManager topLevelCommandManager)
|
||||
public CommandPaletteContextMenuFactory(ISettingsService settingsService, TopLevelCommandManager topLevelCommandManager, IMonitorService? monitorService = null)
|
||||
{
|
||||
_settingsService = settingsService;
|
||||
_topLevelCommandManager = topLevelCommandManager;
|
||||
_monitorService = monitorService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -212,7 +217,8 @@ internal sealed partial class CommandPaletteContextMenuFactory : IContextMenuFac
|
||||
PinLocation.Dock,
|
||||
_settingsService,
|
||||
_topLevelCommandManager,
|
||||
commandItemViewModel: commandItem);
|
||||
commandItemViewModel: commandItem,
|
||||
monitorService: _monitorService);
|
||||
|
||||
var contextItem = new PinToContextItem(pinToTopLevelCommand, commandItem);
|
||||
moreCommands.Add(contextItem);
|
||||
@@ -261,6 +267,7 @@ internal sealed partial class CommandPaletteContextMenuFactory : IContextMenuFac
|
||||
private readonly string _providerId;
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly TopLevelCommandManager _topLevelCommandManager;
|
||||
private readonly IMonitorService? _monitorService;
|
||||
private readonly bool _pin;
|
||||
private readonly PinLocation _pinLocation;
|
||||
private readonly CommandItemViewModel? _commandItemViewModel;
|
||||
@@ -282,7 +289,8 @@ internal sealed partial class CommandPaletteContextMenuFactory : IContextMenuFac
|
||||
PinLocation pinLocation,
|
||||
ISettingsService settingsService,
|
||||
TopLevelCommandManager topLevelCommandManager,
|
||||
CommandItemViewModel? commandItemViewModel = null)
|
||||
CommandItemViewModel? commandItemViewModel = null,
|
||||
IMonitorService? monitorService = null)
|
||||
{
|
||||
_commandId = commandId;
|
||||
_providerId = providerId;
|
||||
@@ -291,6 +299,7 @@ internal sealed partial class CommandPaletteContextMenuFactory : IContextMenuFac
|
||||
_topLevelCommandManager = topLevelCommandManager;
|
||||
_pin = pin;
|
||||
_commandItemViewModel = commandItemViewModel;
|
||||
_monitorService = monitorService;
|
||||
}
|
||||
|
||||
public override CommandResult Invoke()
|
||||
@@ -346,7 +355,8 @@ internal sealed partial class CommandPaletteContextMenuFactory : IContextMenuFac
|
||||
var subtitle = _commandItemViewModel?.Subtitle ?? string.Empty;
|
||||
var icon = _commandItemViewModel?.Icon;
|
||||
var dockSide = _settingsService.Settings.DockSettings.Side;
|
||||
ShowPinToDockDialogMessage message = new(_providerId, _commandId, title, subtitle, icon, dockSide);
|
||||
IReadOnlyList<MonitorInfo>? monitors = _monitorService?.GetMonitors();
|
||||
ShowPinToDockDialogMessage message = new(_providerId, _commandId, title, subtitle, icon, dockSide, monitors);
|
||||
WeakReferenceMessenger.Default.Send(message);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,12 +23,18 @@ using Windows.Foundation;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.Dock;
|
||||
|
||||
public sealed partial class DockControl : UserControl, IRecipient<CloseContextMenuMessage>, IRecipient<EnterDockEditModeMessage>
|
||||
public sealed partial class DockControl : UserControl, IRecipient<CloseContextMenuMessage>, IRecipient<EnterDockEditModeMessage>, IRecipient<ExitDockEditModeMessage>
|
||||
{
|
||||
private DockViewModel _viewModel;
|
||||
|
||||
internal DockViewModel ViewModel => _viewModel;
|
||||
|
||||
/// <summary>
|
||||
/// The HWND of the parent DockWindow that owns this control.
|
||||
/// Used to target palette-show messages to the correct DockWindow in multi-monitor setups.
|
||||
/// </summary>
|
||||
internal IntPtr OwnerHwnd { get; set; }
|
||||
|
||||
public static readonly DependencyProperty ItemsOrientationProperty =
|
||||
DependencyProperty.Register(nameof(ItemsOrientation), typeof(Orientation), typeof(DockControl), new PropertyMetadata(Orientation.Horizontal));
|
||||
|
||||
@@ -89,6 +95,7 @@ public sealed partial class DockControl : UserControl, IRecipient<CloseContextMe
|
||||
WeakReferenceMessenger.Default.UnregisterAll(this);
|
||||
WeakReferenceMessenger.Default.Register<CloseContextMenuMessage>(this);
|
||||
WeakReferenceMessenger.Default.Register<EnterDockEditModeMessage>(this);
|
||||
WeakReferenceMessenger.Default.Register<ExitDockEditModeMessage>(this);
|
||||
|
||||
ViewModel.CenterItems.CollectionChanged -= CenterItems_CollectionChanged;
|
||||
ViewModel.CenterItems.CollectionChanged += CenterItems_CollectionChanged;
|
||||
@@ -142,6 +149,21 @@ public sealed partial class DockControl : UserControl, IRecipient<CloseContextMe
|
||||
});
|
||||
}
|
||||
|
||||
public void Receive(ExitDockEditModeMessage message)
|
||||
{
|
||||
DispatcherQueue.TryEnqueue(() =>
|
||||
{
|
||||
if (message.Discard)
|
||||
{
|
||||
DiscardEditMode();
|
||||
}
|
||||
else
|
||||
{
|
||||
ExitEditMode();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void UpdateEditMode(bool isEditMode)
|
||||
{
|
||||
// Update center visibility based on edit mode and center items
|
||||
@@ -231,20 +253,21 @@ public sealed partial class DockControl : UserControl, IRecipient<CloseContextMe
|
||||
|
||||
private void DoneEditingButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ExitEditMode();
|
||||
WeakReferenceMessenger.Default.Send(new ExitDockEditModeMessage(Discard: false));
|
||||
}
|
||||
|
||||
private void DiscardEditingButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
DiscardEditMode();
|
||||
WeakReferenceMessenger.Default.Send(new ExitDockEditModeMessage(Discard: true));
|
||||
}
|
||||
|
||||
internal void UpdateSettings(DockSettings settings)
|
||||
internal void UpdateSettings(DockSettings settings, DockSide? effectiveSide = null)
|
||||
{
|
||||
DockSide = settings.Side;
|
||||
var side = effectiveSide ?? settings.Side;
|
||||
DockSide = side;
|
||||
|
||||
// Compact mode is only supported for Top/Bottom positions
|
||||
var isHorizontal = settings.Side == DockSide.Top || settings.Side == DockSide.Bottom;
|
||||
var isHorizontal = side == DockSide.Top || side == DockSide.Bottom;
|
||||
var effectiveSize = isHorizontal ? settings.DockSize : DockSize.Default;
|
||||
DockSize = effectiveSize;
|
||||
|
||||
@@ -378,7 +401,7 @@ public sealed partial class DockControl : UserControl, IRecipient<CloseContextMe
|
||||
var isPage = command.Model.Unsafe is not IInvokableCommand invokable;
|
||||
if (isPage)
|
||||
{
|
||||
WeakReferenceMessenger.Default.Send<RequestShowPaletteAtMessage>(new(pos));
|
||||
WeakReferenceMessenger.Default.Send<RequestShowPaletteAtMessage>(new(pos, OwnerHwnd));
|
||||
}
|
||||
}
|
||||
catch (COMException e)
|
||||
|
||||
@@ -9,6 +9,7 @@ using Microsoft.CmdPal.UI.Helpers;
|
||||
using Microsoft.CmdPal.UI.ViewModels;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Dock;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Services;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Settings;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
@@ -33,8 +34,8 @@ namespace Microsoft.CmdPal.UI.Dock;
|
||||
#pragma warning disable SA1402 // File may only contain a single type
|
||||
|
||||
public sealed partial class DockWindow : WindowEx,
|
||||
IRecipient<BringToTopMessage>,
|
||||
IRecipient<RequestShowPaletteAtMessage>,
|
||||
IRecipient<BringToTopMessage>,
|
||||
IRecipient<RequestShowPaletteAtMessage>,
|
||||
IRecipient<QuitMessage>,
|
||||
IDisposable
|
||||
{
|
||||
@@ -46,6 +47,7 @@ public sealed partial class DockWindow : WindowEx,
|
||||
|
||||
private readonly IThemeService _themeService;
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly IMonitorService _monitorService;
|
||||
private readonly DockWindowViewModel _windowViewModel;
|
||||
private readonly HiddenOwnerWindowBehavior _hiddenOwnerWindowBehavior = new();
|
||||
|
||||
@@ -65,21 +67,50 @@ public sealed partial class DockWindow : WindowEx,
|
||||
private DockSize _lastSize;
|
||||
private bool _isDisposed;
|
||||
|
||||
/// <summary>
|
||||
/// The monitor this dock window is displayed on. Null means primary monitor (legacy behavior).
|
||||
/// </summary>
|
||||
private ViewModels.Models.MonitorInfo? _targetMonitor;
|
||||
|
||||
/// <summary>
|
||||
/// Per-monitor dock side override. Null means use the global setting.
|
||||
/// </summary>
|
||||
private DockSide? _sideOverride;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the effective dock side for this window, respecting per-monitor overrides.
|
||||
/// </summary>
|
||||
private DockSide EffectiveSide => _sideOverride ?? _settings.Side;
|
||||
|
||||
// Store the original WndProc
|
||||
private WNDPROC? _originalWndProc;
|
||||
private WNDPROC? _customWndProc;
|
||||
|
||||
// internal Settings CurrentSettings => _settings;
|
||||
public DockWindow()
|
||||
: this(App.Current.Services.GetService<DockViewModel>()!)
|
||||
{
|
||||
}
|
||||
|
||||
public DockWindow(DockViewModel dockViewModel)
|
||||
: this(dockViewModel, null, null)
|
||||
{
|
||||
}
|
||||
|
||||
public DockWindow(DockViewModel dockViewModel, ViewModels.Models.MonitorInfo? targetMonitor, DockSide? sideOverride)
|
||||
{
|
||||
_targetMonitor = targetMonitor;
|
||||
_sideOverride = sideOverride;
|
||||
|
||||
var serviceProvider = App.Current.Services;
|
||||
var mainSettings = serviceProvider.GetRequiredService<ISettingsService>().Settings;
|
||||
_settingsService = serviceProvider.GetRequiredService<ISettingsService>();
|
||||
_settingsService.SettingsChanged += SettingsChangedHandler;
|
||||
_monitorService = serviceProvider.GetRequiredService<IMonitorService>();
|
||||
_settings = mainSettings.DockSettings;
|
||||
_lastSize = EffectiveDockSize(_settings);
|
||||
|
||||
viewModel = serviceProvider.GetService<DockViewModel>()!;
|
||||
viewModel = dockViewModel;
|
||||
_themeService = serviceProvider.GetRequiredService<IThemeService>();
|
||||
_themeService.ThemeChanged += ThemeService_ThemeChanged;
|
||||
InitializeBackdropSupport();
|
||||
@@ -108,6 +139,7 @@ public sealed partial class DockWindow : WindowEx,
|
||||
WeakReferenceMessenger.Default.Register<QuitMessage>(this);
|
||||
|
||||
_hwnd = GetWindowHandle(this);
|
||||
_dock.OwnerHwnd = (nint)_hwnd;
|
||||
|
||||
// Subclass the window to intercept messages
|
||||
//
|
||||
@@ -143,7 +175,13 @@ public sealed partial class DockWindow : WindowEx,
|
||||
|
||||
private void SettingsChangedHandler(ISettingsService sender, SettingsModel args)
|
||||
{
|
||||
if (_isDisposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_settings = args.DockSettings;
|
||||
RefreshSideOverride();
|
||||
DispatcherQueue.TryEnqueue(UpdateSettingsOnUiThread);
|
||||
}
|
||||
|
||||
@@ -172,12 +210,17 @@ public sealed partial class DockWindow : WindowEx,
|
||||
|
||||
private void UpdateSettingsOnUiThread()
|
||||
{
|
||||
if (_isDisposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.viewModel.UpdateSettings(_settings);
|
||||
UpdateBackdrop();
|
||||
|
||||
_dock.UpdateSettings(_settings);
|
||||
_dock.UpdateSettings(_settings, EffectiveSide);
|
||||
|
||||
var side = DockSettingsToViews.GetAppBarEdge(_settings.Side);
|
||||
var side = DockSettingsToViews.GetAppBarEdge(EffectiveSide);
|
||||
|
||||
if (_appBarData.hWnd != IntPtr.Zero)
|
||||
{
|
||||
@@ -394,7 +437,7 @@ public sealed partial class DockWindow : WindowEx,
|
||||
|
||||
var scaleFactor = dpi / 96.0;
|
||||
var effectiveSize = EffectiveDockSize(_settings);
|
||||
UpdateAppBarDataForEdge(_settings.Side, effectiveSize, scaleFactor);
|
||||
UpdateAppBarDataForEdge(EffectiveSide, effectiveSize, scaleFactor);
|
||||
|
||||
// Query and set position
|
||||
PInvoke.SHAppBarMessage(PInvoke.ABM_QUERYPOS, ref _appBarData);
|
||||
@@ -405,7 +448,7 @@ public sealed partial class DockWindow : WindowEx,
|
||||
// bar keeps its correct size. Without this, a second bar docked to
|
||||
// the same side would get a zero-height/width rect and fail to
|
||||
// reserve work-area space.
|
||||
switch (_settings.Side)
|
||||
switch (EffectiveSide)
|
||||
{
|
||||
case DockSide.Top:
|
||||
_appBarData.rc.bottom = _appBarData.rc.top + (int)(DockSettingsToViews.HeightForSize(effectiveSize) * scaleFactor);
|
||||
@@ -442,6 +485,48 @@ public sealed partial class DockWindow : WindowEx,
|
||||
true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Re-resolves <see cref="_targetMonitor"/> against the current monitor list.
|
||||
/// <see cref="MonitorInfo"/> is an immutable record, so the instance captured
|
||||
/// at construction time becomes stale whenever the display topography changes.
|
||||
/// If the monitor is no longer connected we keep the stale reference; the
|
||||
/// <see cref="DockWindowManager"/> will close this window shortly.
|
||||
/// </summary>
|
||||
private void RefreshTargetMonitor()
|
||||
{
|
||||
if (_targetMonitor is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var refreshed = _monitorService.GetMonitorByDeviceId(_targetMonitor.DeviceId);
|
||||
if (refreshed is not null)
|
||||
{
|
||||
_targetMonitor = refreshed;
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshSideOverride()
|
||||
{
|
||||
if (_targetMonitor is null)
|
||||
{
|
||||
_sideOverride = null;
|
||||
return;
|
||||
}
|
||||
|
||||
_sideOverride = null;
|
||||
var monitorConfigs = _settings.MonitorConfigs ?? System.Collections.Immutable.ImmutableList<DockMonitorConfig>.Empty;
|
||||
for (var i = 0; i < monitorConfigs.Count; i++)
|
||||
{
|
||||
var cfg = monitorConfigs[i];
|
||||
if (string.Equals(cfg.MonitorDeviceId, _targetMonitor.DeviceId, System.StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
_sideOverride = cfg.Side;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compact mode is only supported for Top/Bottom dock positions.
|
||||
/// For Left/Right, always use Default size.
|
||||
@@ -457,46 +542,61 @@ public sealed partial class DockWindow : WindowEx,
|
||||
Logger.LogDebug("UpdateAppBarDataForEdge");
|
||||
var horizontalHeightDips = DockSettingsToViews.HeightForSize(size);
|
||||
var verticalWidthDips = DockSettingsToViews.WidthForSize(size);
|
||||
var screenHeight = PInvoke.GetSystemMetrics(SYSTEM_METRICS_INDEX.SM_CYSCREEN);
|
||||
var screenWidth = PInvoke.GetSystemMetrics(SYSTEM_METRICS_INDEX.SM_CXSCREEN);
|
||||
|
||||
// Use monitor-specific bounds when available; fall back to primary screen metrics
|
||||
int monLeft, monTop, monRight, monBottom;
|
||||
if (_targetMonitor is not null)
|
||||
{
|
||||
monLeft = _targetMonitor.Bounds.Left;
|
||||
monTop = _targetMonitor.Bounds.Top;
|
||||
monRight = _targetMonitor.Bounds.Right;
|
||||
monBottom = _targetMonitor.Bounds.Bottom;
|
||||
}
|
||||
else
|
||||
{
|
||||
monLeft = 0;
|
||||
monTop = 0;
|
||||
monRight = PInvoke.GetSystemMetrics(SYSTEM_METRICS_INDEX.SM_CXSCREEN);
|
||||
monBottom = PInvoke.GetSystemMetrics(SYSTEM_METRICS_INDEX.SM_CYSCREEN);
|
||||
}
|
||||
|
||||
if (side == DockSide.Top)
|
||||
{
|
||||
_appBarData.uEdge = PInvoke.ABE_TOP;
|
||||
_appBarData.rc.left = 0;
|
||||
_appBarData.rc.top = 0;
|
||||
_appBarData.rc.right = screenWidth;
|
||||
_appBarData.rc.bottom = (int)(horizontalHeightDips * scaleFactor);
|
||||
_appBarData.rc.left = monLeft;
|
||||
_appBarData.rc.top = monTop;
|
||||
_appBarData.rc.right = monRight;
|
||||
_appBarData.rc.bottom = monTop + (int)(horizontalHeightDips * scaleFactor);
|
||||
}
|
||||
else if (side == DockSide.Bottom)
|
||||
{
|
||||
var heightPixels = (int)(horizontalHeightDips * scaleFactor);
|
||||
|
||||
_appBarData.uEdge = PInvoke.ABE_BOTTOM;
|
||||
_appBarData.rc.left = 0;
|
||||
_appBarData.rc.top = screenHeight - heightPixels;
|
||||
_appBarData.rc.right = screenWidth;
|
||||
_appBarData.rc.bottom = screenHeight;
|
||||
_appBarData.rc.left = monLeft;
|
||||
_appBarData.rc.top = monBottom - heightPixels;
|
||||
_appBarData.rc.right = monRight;
|
||||
_appBarData.rc.bottom = monBottom;
|
||||
}
|
||||
else if (side == DockSide.Left)
|
||||
{
|
||||
var widthPixels = (int)(verticalWidthDips * scaleFactor);
|
||||
|
||||
_appBarData.uEdge = PInvoke.ABE_LEFT;
|
||||
_appBarData.rc.left = 0;
|
||||
_appBarData.rc.top = 0;
|
||||
_appBarData.rc.right = widthPixels;
|
||||
_appBarData.rc.bottom = screenHeight;
|
||||
_appBarData.rc.left = monLeft;
|
||||
_appBarData.rc.top = monTop;
|
||||
_appBarData.rc.right = monLeft + widthPixels;
|
||||
_appBarData.rc.bottom = monBottom;
|
||||
}
|
||||
else if (side == DockSide.Right)
|
||||
{
|
||||
var widthPixels = (int)(verticalWidthDips * scaleFactor);
|
||||
|
||||
_appBarData.uEdge = PInvoke.ABE_RIGHT;
|
||||
_appBarData.rc.left = screenWidth - widthPixels;
|
||||
_appBarData.rc.top = 0;
|
||||
_appBarData.rc.right = screenWidth;
|
||||
_appBarData.rc.bottom = screenHeight;
|
||||
_appBarData.rc.left = monRight - widthPixels;
|
||||
_appBarData.rc.top = monTop;
|
||||
_appBarData.rc.right = monRight;
|
||||
_appBarData.rc.bottom = monBottom;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -521,8 +621,27 @@ public sealed partial class DockWindow : WindowEx,
|
||||
{
|
||||
Logger.LogDebug("WM_DISPLAYCHANGE");
|
||||
|
||||
// Use dispatcher to ensure we're on the UI thread
|
||||
DispatcherQueue.TryEnqueue(() => UpdateWindowPosition());
|
||||
// Invalidate the monitor cache so DockWindowManager can reconcile
|
||||
_monitorService.NotifyMonitorsChanged();
|
||||
|
||||
// Use dispatcher to ensure we're on the UI thread.
|
||||
// Refresh _targetMonitor before re-positioning: the MonitorInfo
|
||||
// captured at construction is an immutable record, so its Bounds
|
||||
// are stale after a topology change (e.g. an external display was
|
||||
// disconnected, shifting our monitor's virtual-screen origin).
|
||||
// Without this, UpdateAppBarDataForEdge would compute the AppBar
|
||||
// rect against the old coordinates and produce a wildly incorrect
|
||||
// size/position.
|
||||
DispatcherQueue.TryEnqueue(() =>
|
||||
{
|
||||
if (_isDisposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RefreshTargetMonitor();
|
||||
UpdateWindowPosition();
|
||||
});
|
||||
}
|
||||
|
||||
// Intercept WM_SYSCOMMAND to prevent minimize and maximize
|
||||
@@ -659,6 +778,11 @@ public sealed partial class DockWindow : WindowEx,
|
||||
|
||||
void IRecipient<RequestShowPaletteAtMessage>.Receive(RequestShowPaletteAtMessage message)
|
||||
{
|
||||
if (_isDisposed || message.OwnerHwnd != (nint)_hwnd)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () => RequestShowPaletteOnUiThread(message.PosDips));
|
||||
}
|
||||
|
||||
@@ -672,8 +796,23 @@ public sealed partial class DockWindow : WindowEx,
|
||||
var scaleFactor = dpi / 96.0;
|
||||
var screenPosPixels = new Point(screenPosDips.X * scaleFactor, screenPosDips.Y * scaleFactor);
|
||||
|
||||
var screenWidth = PInvoke.GetSystemMetrics(SYSTEM_METRICS_INDEX.SM_CXSCREEN);
|
||||
var screenHeight = PInvoke.GetSystemMetrics(SYSTEM_METRICS_INDEX.SM_CYSCREEN);
|
||||
// Use monitor-specific bounds when available
|
||||
int screenWidth, screenHeight;
|
||||
if (_targetMonitor is not null)
|
||||
{
|
||||
screenWidth = _targetMonitor.Bounds.Width;
|
||||
screenHeight = _targetMonitor.Bounds.Height;
|
||||
|
||||
// Adjust to monitor-local coordinates for quadrant calculation
|
||||
screenPosPixels = new Point(
|
||||
screenPosPixels.X - _targetMonitor.Bounds.Left,
|
||||
screenPosPixels.Y - _targetMonitor.Bounds.Top);
|
||||
}
|
||||
else
|
||||
{
|
||||
screenWidth = PInvoke.GetSystemMetrics(SYSTEM_METRICS_INDEX.SM_CXSCREEN);
|
||||
screenHeight = PInvoke.GetSystemMetrics(SYSTEM_METRICS_INDEX.SM_CYSCREEN);
|
||||
}
|
||||
|
||||
// Now we're going to find the best position for the palette.
|
||||
|
||||
@@ -695,7 +834,7 @@ public sealed partial class DockWindow : WindowEx,
|
||||
var onRightHalf = !onLeftHalf;
|
||||
var onBottomHalf = !onTopHalf;
|
||||
|
||||
var anchorPoint = _settings.Side switch
|
||||
var anchorPoint = EffectiveSide switch
|
||||
{
|
||||
DockSide.Top => onLeftHalf ? AnchorPoint.TopLeft : AnchorPoint.TopRight,
|
||||
DockSide.Bottom => onLeftHalf ? AnchorPoint.BottomLeft : AnchorPoint.BottomRight,
|
||||
@@ -710,7 +849,7 @@ public sealed partial class DockWindow : WindowEx,
|
||||
PInvoke.GetWindowRect(_hwnd, out var ourRect);
|
||||
|
||||
// Depending on the side we're on, we need to offset differently
|
||||
switch (_settings.Side)
|
||||
switch (EffectiveSide)
|
||||
{
|
||||
case DockSide.Top:
|
||||
screenPosPixels.Y = ourRect.bottom + paddingPixels;
|
||||
@@ -733,6 +872,8 @@ public sealed partial class DockWindow : WindowEx,
|
||||
|
||||
public DockWindowViewModel WindowViewModel => _windowViewModel;
|
||||
|
||||
public string? MonitorDeviceId => viewModel.MonitorDeviceId;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Cleanup();
|
||||
@@ -850,7 +991,7 @@ internal static class ShowDesktop
|
||||
|
||||
internal sealed record BringToTopMessage(bool BringToFront);
|
||||
|
||||
internal sealed record RequestShowPaletteAtMessage(Point PosDips);
|
||||
internal sealed record RequestShowPaletteAtMessage(Point PosDips, IntPtr OwnerHwnd);
|
||||
|
||||
internal sealed record ShowPaletteAtMessage(Point PosPixels, AnchorPoint Anchor);
|
||||
|
||||
|
||||
283
src/modules/cmdpal/Microsoft.CmdPal.UI/Dock/DockWindowManager.cs
Normal file
283
src/modules/cmdpal/Microsoft.CmdPal.UI/Dock/DockWindowManager.cs
Normal file
@@ -0,0 +1,283 @@
|
||||
// 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;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Dock;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Services;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Settings;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.UI.Dispatching;
|
||||
using WinUIEx;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.Dock;
|
||||
|
||||
/// <summary>
|
||||
/// Manages multiple <see cref="DockWindow"/> instances, one per enabled monitor.
|
||||
/// Replaces the single <c>_dockWindow</c> field previously held by ShellPage.
|
||||
/// </summary>
|
||||
public sealed partial class DockWindowManager : IDisposable
|
||||
{
|
||||
private readonly IMonitorService _monitorService;
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly DispatcherQueue _dispatcherQueue;
|
||||
private readonly Dictionary<string, DockWindow> _dockWindows = new(StringComparer.OrdinalIgnoreCase);
|
||||
private readonly Dictionary<string, DockViewModel> _dockViewModels = new(StringComparer.OrdinalIgnoreCase);
|
||||
private bool _disposed;
|
||||
private bool _syncing;
|
||||
|
||||
public DockWindowManager(
|
||||
IMonitorService monitorService,
|
||||
ISettingsService settingsService,
|
||||
DispatcherQueue dispatcherQueue)
|
||||
{
|
||||
_monitorService = monitorService;
|
||||
_settingsService = settingsService;
|
||||
_dispatcherQueue = dispatcherQueue;
|
||||
|
||||
_monitorService.MonitorsChanged += OnMonitorsChanged;
|
||||
_settingsService.SettingsChanged += OnSettingsChanged;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates dock windows for all enabled monitors according to current settings.
|
||||
/// Runs reconciliation to ensure configs match currently connected monitors.
|
||||
/// </summary>
|
||||
public void ShowDocks()
|
||||
{
|
||||
var settings = _settingsService.Settings;
|
||||
if (!settings.EnableDock)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SyncDocksToSettings();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destroys all dock windows.
|
||||
/// </summary>
|
||||
public void HideDocks()
|
||||
{
|
||||
foreach (var kvp in _dockWindows)
|
||||
{
|
||||
kvp.Value.Close();
|
||||
}
|
||||
|
||||
_dockWindows.Clear();
|
||||
|
||||
foreach (var kvp in _dockViewModels)
|
||||
{
|
||||
kvp.Value.Dispose();
|
||||
}
|
||||
|
||||
_dockViewModels.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Synchronizes running dock windows to match the current settings and connected monitors.
|
||||
/// </summary>
|
||||
public void SyncDocksToSettings()
|
||||
{
|
||||
if (_syncing)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_syncing = true;
|
||||
try
|
||||
{
|
||||
SyncDocksToSettingsCore();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_syncing = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void SyncDocksToSettingsCore()
|
||||
{
|
||||
var settings = _settingsService.Settings;
|
||||
if (!settings.EnableDock)
|
||||
{
|
||||
HideDocks();
|
||||
return;
|
||||
}
|
||||
|
||||
var dockSettings = settings.DockSettings;
|
||||
|
||||
// Reconcile stale monitor device IDs with currently connected monitors
|
||||
var monitors = _monitorService.GetMonitors();
|
||||
var currentConfigs = dockSettings.MonitorConfigs ?? System.Collections.Immutable.ImmutableList<DockMonitorConfig>.Empty;
|
||||
var reconciled = MonitorConfigReconciler.Reconcile(currentConfigs, monitors);
|
||||
if (reconciled != currentConfigs)
|
||||
{
|
||||
_settingsService.UpdateSettings(s => s with
|
||||
{
|
||||
DockSettings = s.DockSettings with { MonitorConfigs = reconciled },
|
||||
});
|
||||
|
||||
// Re-read settings after update
|
||||
dockSettings = _settingsService.Settings.DockSettings;
|
||||
}
|
||||
|
||||
var configs = GetEffectiveConfigs(dockSettings);
|
||||
var desiredMonitorIds = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
// Refresh settings on existing ViewModels so they pick up new pins/changes
|
||||
foreach (var kvp in _dockViewModels)
|
||||
{
|
||||
kvp.Value.UpdateSettings(dockSettings);
|
||||
}
|
||||
|
||||
for (var i = 0; i < configs.Count; i++)
|
||||
{
|
||||
var config = configs[i];
|
||||
if (!config.Enabled)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var monitor = _monitorService.GetMonitorByDeviceId(config.MonitorDeviceId);
|
||||
if (monitor is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
desiredMonitorIds.Add(config.MonitorDeviceId);
|
||||
|
||||
if (!_dockWindows.ContainsKey(config.MonitorDeviceId))
|
||||
{
|
||||
CreateDockForMonitor(config.MonitorDeviceId, dockSettings);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove dock windows for monitors that are no longer desired
|
||||
var toRemove = new List<string>();
|
||||
foreach (var id in _dockWindows.Keys)
|
||||
{
|
||||
if (!desiredMonitorIds.Contains(id))
|
||||
{
|
||||
toRemove.Add(id);
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < toRemove.Count; i++)
|
||||
{
|
||||
var id = toRemove[i];
|
||||
if (_dockWindows.Remove(id, out var window))
|
||||
{
|
||||
window.Close();
|
||||
}
|
||||
|
||||
if (_dockViewModels.Remove(id, out var vm))
|
||||
{
|
||||
vm.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_disposed = true;
|
||||
_monitorService.MonitorsChanged -= OnMonitorsChanged;
|
||||
_settingsService.SettingsChanged -= OnSettingsChanged;
|
||||
|
||||
HideDocks();
|
||||
}
|
||||
|
||||
private void CreateDockForMonitor(string monitorDeviceId, DockSettings dockSettings)
|
||||
{
|
||||
var viewModel = CreateDockViewModel(monitorDeviceId);
|
||||
_dockViewModels[monitorDeviceId] = viewModel;
|
||||
|
||||
var monitor = _monitorService.GetMonitorByDeviceId(monitorDeviceId);
|
||||
DockSide? sideOverride = null;
|
||||
var monitorConfigs = dockSettings.MonitorConfigs ?? System.Collections.Immutable.ImmutableList<DockMonitorConfig>.Empty;
|
||||
for (var i = 0; i < monitorConfigs.Count; i++)
|
||||
{
|
||||
var cfg = monitorConfigs[i];
|
||||
if (string.Equals(cfg.MonitorDeviceId, monitorDeviceId, System.StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
sideOverride = cfg.Side;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var window = new DockWindow(viewModel, monitor, sideOverride);
|
||||
_dockWindows[monitorDeviceId] = window;
|
||||
window.Show();
|
||||
|
||||
viewModel.InitializeBands();
|
||||
}
|
||||
|
||||
private DockViewModel CreateDockViewModel(string monitorDeviceId)
|
||||
{
|
||||
var serviceProvider = App.Current.Services;
|
||||
var tlcManager = serviceProvider.GetRequiredService<TopLevelCommandManager>();
|
||||
var contextMenuFactory = serviceProvider.GetRequiredService<IContextMenuFactory>();
|
||||
var scheduler = serviceProvider.GetRequiredService<TaskScheduler>();
|
||||
|
||||
return new DockViewModel(tlcManager, contextMenuFactory, scheduler, _settingsService, monitorDeviceId);
|
||||
}
|
||||
|
||||
private void OnMonitorsChanged(object? sender, EventArgs e)
|
||||
{
|
||||
_dispatcherQueue.TryEnqueue(() =>
|
||||
{
|
||||
if (!_disposed)
|
||||
{
|
||||
SyncDocksToSettings();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void OnSettingsChanged(ISettingsService sender, SettingsModel args)
|
||||
{
|
||||
_dispatcherQueue.TryEnqueue(() =>
|
||||
{
|
||||
if (!_disposed)
|
||||
{
|
||||
SyncDocksToSettings();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the effective list of monitor configs. If settings have no explicit
|
||||
/// configs (legacy / first-run), synthesizes one for the primary monitor.
|
||||
/// </summary>
|
||||
private IReadOnlyList<DockMonitorConfig> GetEffectiveConfigs(DockSettings dockSettings)
|
||||
{
|
||||
var configs = dockSettings.MonitorConfigs ?? System.Collections.Immutable.ImmutableList<DockMonitorConfig>.Empty;
|
||||
if (configs.Count > 0)
|
||||
{
|
||||
return configs;
|
||||
}
|
||||
|
||||
// Legacy / migration: no per-monitor configs saved yet.
|
||||
// Synthesize a config for the primary monitor inheriting global Side.
|
||||
var primary = _monitorService.GetPrimaryMonitor();
|
||||
if (primary is null)
|
||||
{
|
||||
return Array.Empty<DockMonitorConfig>();
|
||||
}
|
||||
|
||||
return new[]
|
||||
{
|
||||
new DockMonitorConfig
|
||||
{
|
||||
MonitorDeviceId = primary.DeviceId,
|
||||
Enabled = true,
|
||||
Side = null,
|
||||
IsPrimary = true,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<UserControl
|
||||
x:Class="Microsoft.CmdPal.UI.Dock.PinToDockDialogContent"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
@@ -107,6 +107,18 @@
|
||||
</tkcontrols:Segmented>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Monitor Selector (hidden when only one monitor) -->
|
||||
<StackPanel
|
||||
x:Name="MonitorSelectorPanel"
|
||||
Spacing="8"
|
||||
Visibility="Collapsed">
|
||||
<TextBlock
|
||||
x:Uid="PinToDock_MonitorHeader"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}" />
|
||||
<ComboBox x:Name="MonitorComboBox" HorizontalAlignment="Stretch" />
|
||||
</StackPanel>
|
||||
|
||||
<!-- Label Options -->
|
||||
<StackPanel Spacing="4">
|
||||
<CheckBox
|
||||
|
||||
@@ -2,8 +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 System.Collections.Generic;
|
||||
using Microsoft.CmdPal.UI.ViewModels;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Dock;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Settings;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
@@ -17,6 +19,7 @@ public sealed partial class PinToDockDialogContent : UserControl
|
||||
{
|
||||
private string _title = string.Empty;
|
||||
private string _subtitle = string.Empty;
|
||||
private IReadOnlyList<MonitorInfo>? _monitors;
|
||||
|
||||
public DockPinSide SelectedSide => SectionSegmented.SelectedIndex switch
|
||||
{
|
||||
@@ -30,12 +33,28 @@ public sealed partial class PinToDockDialogContent : UserControl
|
||||
|
||||
public bool? ShowSubtitles => ShowSubtitleCheckBox.IsChecked;
|
||||
|
||||
public string? SelectedMonitorDeviceId
|
||||
{
|
||||
get
|
||||
{
|
||||
// When only one monitor exists, return null so the pin lands in the
|
||||
// global bands (visible on all monitors by default). The per-monitor
|
||||
// path is only used when the user explicitly chooses from 2+ monitors.
|
||||
if (_monitors is null or { Count: <= 1 } || MonitorComboBox.SelectedIndex < 0 || MonitorComboBox.SelectedIndex >= _monitors.Count)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return _monitors[MonitorComboBox.SelectedIndex].DeviceId;
|
||||
}
|
||||
}
|
||||
|
||||
public PinToDockDialogContent()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public void Configure(string title, string subtitle, IconInfoViewModel? icon, DockSide dockSide)
|
||||
public void Configure(string title, string subtitle, IconInfoViewModel? icon, DockSide dockSide, IReadOnlyList<MonitorInfo>? monitors = null)
|
||||
{
|
||||
_title = title;
|
||||
_subtitle = subtitle;
|
||||
@@ -63,6 +82,7 @@ public sealed partial class PinToDockDialogContent : UserControl
|
||||
}
|
||||
|
||||
ApplyDockOrientation(dockSide);
|
||||
ConfigureMonitorSelector(monitors);
|
||||
}
|
||||
|
||||
public static async System.Threading.Tasks.Task<(ContentDialogResult Result, PinToDockDialogContent Content)> ShowAsync(
|
||||
@@ -70,10 +90,11 @@ public sealed partial class PinToDockDialogContent : UserControl
|
||||
string title,
|
||||
string subtitle,
|
||||
IconInfoViewModel? icon,
|
||||
DockSide dockSide)
|
||||
DockSide dockSide,
|
||||
IReadOnlyList<MonitorInfo>? monitors = null)
|
||||
{
|
||||
var content = new PinToDockDialogContent();
|
||||
content.Configure(title, subtitle, icon, dockSide);
|
||||
content.Configure(title, subtitle, icon, dockSide, monitors);
|
||||
|
||||
var dialog = new ContentDialog
|
||||
{
|
||||
@@ -168,4 +189,31 @@ public sealed partial class PinToDockDialogContent : UserControl
|
||||
|
||||
PreviewTextPanel.Visibility = (showTitle || showSubtitle) ? Visibility.Visible : Visibility.Collapsed;
|
||||
}
|
||||
|
||||
private void ConfigureMonitorSelector(IReadOnlyList<MonitorInfo>? monitors)
|
||||
{
|
||||
_monitors = monitors;
|
||||
|
||||
if (monitors is null || monitors.Count <= 1)
|
||||
{
|
||||
MonitorSelectorPanel.Visibility = Visibility.Collapsed;
|
||||
return;
|
||||
}
|
||||
|
||||
MonitorSelectorPanel.Visibility = Visibility.Visible;
|
||||
|
||||
var displayNames = new List<string>(monitors.Count);
|
||||
var primaryIndex = 0;
|
||||
for (var i = 0; i < monitors.Count; i++)
|
||||
{
|
||||
displayNames.Add(monitors[i].DisplayName);
|
||||
if (monitors[i].IsPrimary)
|
||||
{
|
||||
primaryIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
MonitorComboBox.ItemsSource = displayNames;
|
||||
MonitorComboBox.SelectedIndex = primaryIndex;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,4 +117,15 @@ WM_DPICHANGED
|
||||
|
||||
QUERY_USER_NOTIFICATION_STATE
|
||||
EnumWindows
|
||||
EnumDisplayMonitors
|
||||
MONITORINFOEXW
|
||||
IsWindowVisible
|
||||
GetDisplayConfigBufferSizes
|
||||
QueryDisplayConfig
|
||||
DisplayConfigGetDeviceInfo
|
||||
DISPLAYCONFIG_TARGET_DEVICE_NAME
|
||||
DISPLAYCONFIG_SOURCE_DEVICE_NAME
|
||||
DISPLAYCONFIG_PATH_INFO
|
||||
DISPLAYCONFIG_MODE_INFO
|
||||
DISPLAYCONFIG_DEVICE_INFO_TYPE
|
||||
QUERY_DISPLAY_CONFIG_FLAGS
|
||||
|
||||
@@ -26,7 +26,6 @@ using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Input;
|
||||
using Microsoft.UI.Xaml.Media.Animation;
|
||||
using WinUIEx;
|
||||
using DispatcherQueue = Microsoft.UI.Dispatching.DispatcherQueue;
|
||||
using VirtualKey = Windows.System.VirtualKey;
|
||||
|
||||
@@ -68,7 +67,7 @@ public sealed partial class ShellPage : Microsoft.UI.Xaml.Controls.Page,
|
||||
private readonly CompositeFormat _pageNavigatedAnnouncement;
|
||||
|
||||
private SettingsWindow? _settingsWindow;
|
||||
private DockWindow? _dockWindow;
|
||||
private DockWindowManager? _dockWindowManager;
|
||||
|
||||
private CancellationTokenSource? _focusAfterLoadedCts;
|
||||
private WeakReference<Page>? _lastNavigatedPageRef;
|
||||
@@ -116,8 +115,8 @@ public sealed partial class ShellPage : Microsoft.UI.Xaml.Controls.Page,
|
||||
|
||||
if (App.Current.Services.GetRequiredService<ISettingsService>().Settings.EnableDock)
|
||||
{
|
||||
_dockWindow = new DockWindow();
|
||||
_dockWindow.Show();
|
||||
_dockWindowManager = App.Current.Services.GetService<Dock.DockWindowManager>();
|
||||
_dockWindowManager?.ShowDocks();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,7 +233,8 @@ public sealed partial class ShellPage : Microsoft.UI.Xaml.Controls.Page,
|
||||
message.Title,
|
||||
message.Subtitle,
|
||||
message.Icon,
|
||||
message.DockSide);
|
||||
message.DockSide,
|
||||
message.AvailableMonitors);
|
||||
|
||||
if (result == ContentDialogResult.Primary)
|
||||
{
|
||||
@@ -244,7 +244,8 @@ public sealed partial class ShellPage : Microsoft.UI.Xaml.Controls.Page,
|
||||
Pin: true,
|
||||
Side: content.SelectedSide,
|
||||
ShowTitles: content.ShowTitles,
|
||||
ShowSubtitles: content.ShowSubtitles);
|
||||
ShowSubtitles: content.ShowSubtitles,
|
||||
MonitorDeviceId: content.SelectedMonitorDeviceId);
|
||||
WeakReferenceMessenger.Default.Send(pinMessage);
|
||||
}
|
||||
}
|
||||
@@ -543,17 +544,16 @@ public sealed partial class ShellPage : Microsoft.UI.Xaml.Controls.Page,
|
||||
|
||||
if (message.ShowDock)
|
||||
{
|
||||
if (_dockWindow is null)
|
||||
if (_dockWindowManager is null)
|
||||
{
|
||||
_dockWindow = new DockWindow();
|
||||
_dockWindowManager = App.Current.Services.GetService<Dock.DockWindowManager>();
|
||||
}
|
||||
|
||||
_dockWindow.Show();
|
||||
_dockWindowManager?.ShowDocks();
|
||||
}
|
||||
else if (_dockWindow is not null)
|
||||
else
|
||||
{
|
||||
_dockWindow.Close();
|
||||
_dockWindow = null;
|
||||
_dockWindowManager?.HideDocks();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -854,20 +854,9 @@ public sealed partial class ShellPage : Microsoft.UI.Xaml.Controls.Page,
|
||||
_focusAfterLoadedCts?.Dispose();
|
||||
_focusAfterLoadedCts = null;
|
||||
|
||||
var dockWindow = _dockWindow;
|
||||
_dockWindow = null;
|
||||
|
||||
if (dockWindow is not null)
|
||||
{
|
||||
if (DispatcherQueue.HasThreadAccess)
|
||||
{
|
||||
dockWindow.Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
DispatcherQueue.TryEnqueue(dockWindow.Close);
|
||||
}
|
||||
}
|
||||
var dockWindowManager = _dockWindowManager;
|
||||
_dockWindowManager = null;
|
||||
dockWindowManager?.Dispose();
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user