From 70d84fcb886da3fe022158f504dc990e5775dd75 Mon Sep 17 00:00:00 2001 From: Gordon Lam <73506701+yeelam-gordon@users.noreply.github.com> Date: Wed, 4 Feb 2026 08:31:40 -0800 Subject: [PATCH 01/41] chore(claude): add symlinks for Claude Code support to GitHub configs (#45204) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary of the Pull Request Adds Claude Code support by creating symbolic links under `.claude/` that point to existing GitHub Copilot configuration files in `.github/`. This enables Claude Code to use the same AI contributor guidance, agents, prompts, instructions, and skills without duplicating content. ## Detailed Description of the Pull Request / Additional comments This PR creates a `.claude/` directory with symbolic links mapping Claude Code's expected paths to existing GitHub Copilot configurations: | Claude Code Path | → | GitHub Copilot Source | |------------------|---|----------------------| | `.claude/CLAUDE.md` | → | `.github/copilot-instructions.md` | | `.claude/agents/` | → | `.github/agents/` | | `.claude/commands/` | → | `.github/prompts/` | | `.claude/rules/` | → | `.github/instructions/` | | `.claude/skills/` | → | `.github/skills/` | **Key benefits:** - Single source of truth — edits to `.github/` files automatically apply to Claude Code - Directory symlinks ensure new files (agents, prompts, skills) are picked up without updating the mapping - `.gitattributes` updated with `symlink` hint for `.claude/**` **Windows users cloning this repo need:** - Developer Mode enabled, OR admin privileges - `git config --global core.symlinks true` before cloning ## Validation Steps Performed - [x] Verified symlinks resolve correctly on Windows (`Get-ChildItem .claude` shows targets) - [x] Confirmed content is readable through symlinks (`Get-Content .claude\CLAUDE.md`) - [x] Verified Git indexes files as symlinks (mode `120000` in `git ls-files -s`) - [x] Confirmed symlink targets stored with forward slashes for cross-platform compatibility - [x] No automated tests required — changes are config/symlinks only with no runtime impact --- .claude/CLAUDE.md | 1 + .claude/agents | 1 + .claude/commands | 1 + .claude/rules | 1 + .claude/skills | 1 + 5 files changed, 5 insertions(+) create mode 120000 .claude/CLAUDE.md create mode 120000 .claude/agents create mode 120000 .claude/commands create mode 120000 .claude/rules create mode 120000 .claude/skills diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md new file mode 120000 index 0000000000..ff80726687 --- /dev/null +++ b/.claude/CLAUDE.md @@ -0,0 +1 @@ +../.github/copilot-instructions.md \ No newline at end of file diff --git a/.claude/agents b/.claude/agents new file mode 120000 index 0000000000..fa084a095e --- /dev/null +++ b/.claude/agents @@ -0,0 +1 @@ +../.github/agents \ No newline at end of file diff --git a/.claude/commands b/.claude/commands new file mode 120000 index 0000000000..95a795b09e --- /dev/null +++ b/.claude/commands @@ -0,0 +1 @@ +../.github/prompts \ No newline at end of file diff --git a/.claude/rules b/.claude/rules new file mode 120000 index 0000000000..89b1ff5da7 --- /dev/null +++ b/.claude/rules @@ -0,0 +1 @@ +../.github/instructions \ No newline at end of file diff --git a/.claude/skills b/.claude/skills new file mode 120000 index 0000000000..3e73f3a383 --- /dev/null +++ b/.claude/skills @@ -0,0 +1 @@ +../.github/skills \ No newline at end of file From 6f87e947ff4cd6e84d8d9004d46a6c36c632c3bf Mon Sep 17 00:00:00 2001 From: Alex Mihaiuc <69110671+foxmsft@users.noreply.github.com> Date: Thu, 5 Feb 2026 02:01:10 +0100 Subject: [PATCH 02/41] ZoomIt: close the virtual microphone on stop (#45386) This is not a leak per se, but closing the virtual microphone when recording stops is a good thing to do. Also bump ZoomIt's version to 10.1. ## Summary of the Pull Request This is a code quality addition, not a real bug per se - ZoomIt holds one reference to a virtual microphone stream, thus causing the notification area (system tray) microphone symbol always show ZoomIt as "recording" even after stopping a screen recording in ZoomIt. ## PR Checklist - [ ] Closes: #xxx - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx ## Detailed Description of the Pull Request / Additional comments It's sufficient to just notice that: - Audio recording still works. - The notification area / system tray microphone notification is active while screen recording. - That notification disappears after stopping the ZoomIt screen capture session. - ## Validation Steps Performed --- src/modules/ZoomIt/ZoomIt/AudioSampleGenerator.cpp | 8 ++++++++ src/modules/ZoomIt/ZoomIt/ZoomIt.rc | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/modules/ZoomIt/ZoomIt/AudioSampleGenerator.cpp b/src/modules/ZoomIt/ZoomIt/AudioSampleGenerator.cpp index fecdca4356..b3b0ed373f 100644 --- a/src/modules/ZoomIt/ZoomIt/AudioSampleGenerator.cpp +++ b/src/modules/ZoomIt/ZoomIt/AudioSampleGenerator.cpp @@ -311,6 +311,14 @@ void AudioSampleGenerator::Stop() // Stop the audio graph - no more quantum callbacks will run m_audioGraph.Stop(); + // Close the microphone input node to release the device so Windows no longer + // reports the microphone as in use by ZoomIt. + if (m_audioInputNode) + { + m_audioInputNode.Close(); + m_audioInputNode = nullptr; + } + // Mark as stopped m_started.store(false); diff --git a/src/modules/ZoomIt/ZoomIt/ZoomIt.rc b/src/modules/ZoomIt/ZoomIt/ZoomIt.rc index 6fe01af2bb..d3c5210744 100644 --- a/src/modules/ZoomIt/ZoomIt/ZoomIt.rc +++ b/src/modules/ZoomIt/ZoomIt/ZoomIt.rc @@ -121,7 +121,7 @@ FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN DEFPUSHBUTTON "OK",IDOK,186,306,50,14 PUSHBUTTON "Cancel",IDCANCEL,243,306,50,14 - LTEXT "ZoomIt v10.0",IDC_VERSION,42,7,73,10 + LTEXT "ZoomIt v10.1",IDC_VERSION,42,7,73,10 LTEXT "Copyright \251 2006-2026 Mark Russinovich",IDC_COPYRIGHT,42,17,251,8 CONTROL "Sysinternals - www.sysinternals.com",IDC_LINK, "SysLink",WS_TABSTOP,42,26,150,9 From 266908c62ac8806cff12bacd0c942b5fc4a9d820 Mon Sep 17 00:00:00 2001 From: leileizhang Date: Thu, 5 Feb 2026 09:03:48 +0800 Subject: [PATCH 03/41] [ImageResizer] Fix Image Resizer not working after upgrade on Windows 10 (#45184) ## Summary of the Pull Request - Fixes an issue where Image Resizer stops working after upgrading PowerToys on Windows 10 - Root cause: the PackageIdentityMSIX (sparse app) was not being properly cleaned up during upgrade ## Problem Previous versions of PowerToys installed the sparse app on Windows 10. The current version only installs it on Windows 11+ (build >= 22000). During upgrade on Windows 10: 1. The `NOT UPGRADINGPRODUCTCODE` condition prevented the uninstall action from running 2. The Windows 11 version check prevented the new sparse app from being installed 3. Result: the old sparse app remained on the system, causing Image Resizer to malfunction ## Fix Changed the `UninstallPackageIdentityMSIX` condition from: Installed AND (NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL") to: Installed AND (REMOVE="ALL") This ensures the old sparse app is properly cleaned up during upgrades, which is also consistent with other similar cleanup ## PR Checklist - [x] Closes: #45178 #45280 - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx ## Detailed Description of the Pull Request / Additional comments ## Validation Steps Performed 1. Install PowerToys version 0.96.1 on Windows 10. 2. Upgrade to version 0.97.1. 3. Run Get-AppxPackage -Name "*Sparse*" in PowerShell to check whether a Sparse App package is present. --- installer/PowerToysSetupVNext/Product.wxs | 2 +- src/modules/imageresizer/ui/ImageResizerUI.csproj | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/installer/PowerToysSetupVNext/Product.wxs b/installer/PowerToysSetupVNext/Product.wxs index 5256af42fd..1a5f8010f7 100644 --- a/installer/PowerToysSetupVNext/Product.wxs +++ b/installer/PowerToysSetupVNext/Product.wxs @@ -147,7 +147,7 @@ - + From 0259e31d206d9e92c011fae6fcdd9a05e1a72562 Mon Sep 17 00:00:00 2001 From: Niels Laute Date: Thu, 5 Feb 2026 02:17:13 +0100 Subject: [PATCH 04/41] Fix contrast issue (#45367) ## Summary of the Pull Request ## PR Checklist - [X] Closes: #42261 - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx ## Detailed Description of the Pull Request / Additional comments ## Validation Steps Performed --- .../colorPicker/ColorPickerUI/Controls/ColorFormatControl.xaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/colorPicker/ColorPickerUI/Controls/ColorFormatControl.xaml b/src/modules/colorPicker/ColorPickerUI/Controls/ColorFormatControl.xaml index 723b2cfa7f..5c2e22fbee 100644 --- a/src/modules/colorPicker/ColorPickerUI/Controls/ColorFormatControl.xaml +++ b/src/modules/colorPicker/ColorPickerUI/Controls/ColorFormatControl.xaml @@ -140,7 +140,7 @@ From d9a1c35132d13d3b2f566a95be67947b7f242746 Mon Sep 17 00:00:00 2001 From: Shawn Yuan <128874481+shuaiyuanxx@users.noreply.github.com> Date: Thu, 5 Feb 2026 10:35:59 +0800 Subject: [PATCH 05/41] Fix Advanced Paste settings page crash issue (#45207) ## Summary of the Pull Request This pull request refactors the `AdvancedPasteAdditionalActions` class to use private backing fields and custom property accessors for its action properties. This change allows for better control over property initialization and ensures that the properties always have valid, non-null default values. **Refactoring for property initialization and null safety:** * Introduced private backing fields (`_imageToText`, `_pasteAsFile`, `_transcode`) for the `ImageToText`, `PasteAsFile`, and `Transcode` properties in `AdvancedPasteAdditionalActions`, replacing auto-properties. * Updated the property accessors for `ImageToText`, `PasteAsFile`, and `Transcode` to use the new backing fields and ensure that a new default instance is assigned if a null value is provided during initialization. ## PR Checklist - [x] Closes: #45189 - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx ## Detailed Description of the Pull Request / Additional comments ## Validation Steps Performed --- .../AdvancedPasteAdditionalActions.cs | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/settings-ui/Settings.UI.Library/AdvancedPasteAdditionalActions.cs b/src/settings-ui/Settings.UI.Library/AdvancedPasteAdditionalActions.cs index 6d908c617a..b193c01c74 100644 --- a/src/settings-ui/Settings.UI.Library/AdvancedPasteAdditionalActions.cs +++ b/src/settings-ui/Settings.UI.Library/AdvancedPasteAdditionalActions.cs @@ -10,6 +10,10 @@ namespace Microsoft.PowerToys.Settings.UI.Library; public sealed class AdvancedPasteAdditionalActions { + private AdvancedPasteAdditionalAction _imageToText = new(); + private AdvancedPastePasteAsFileAction _pasteAsFile = new(); + private AdvancedPasteTranscodeAction _transcode = new(); + public static class PropertyNames { public const string ImageToText = "image-to-text"; @@ -18,13 +22,25 @@ public sealed class AdvancedPasteAdditionalActions } [JsonPropertyName(PropertyNames.ImageToText)] - public AdvancedPasteAdditionalAction ImageToText { get; init; } = new(); + public AdvancedPasteAdditionalAction ImageToText + { + get => _imageToText; + init => _imageToText = value ?? new(); + } [JsonPropertyName(PropertyNames.PasteAsFile)] - public AdvancedPastePasteAsFileAction PasteAsFile { get; init; } = new(); + public AdvancedPastePasteAsFileAction PasteAsFile + { + get => _pasteAsFile; + init => _pasteAsFile = value ?? new(); + } [JsonPropertyName(PropertyNames.Transcode)] - public AdvancedPasteTranscodeAction Transcode { get; init; } = new(); + public AdvancedPasteTranscodeAction Transcode + { + get => _transcode; + init => _transcode = value ?? new(); + } public IEnumerable GetAllActions() { From 4c0926d7b7f113587cc240b2c01063179edef120 Mon Sep 17 00:00:00 2001 From: Kai Tao <69313318+vanzue@users.noreply.github.com> Date: Thu, 5 Feb 2026 16:12:58 +0800 Subject: [PATCH 06/41] Doc: Add a dev guideline to make sure codes builds and verified before open a pr (#45419) ## Summary of the Pull Request Making sure the codes builds and verified before submitting a pr. ## PR Checklist - [ ] Closes: #xxx - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx ## Detailed Description of the Pull Request / Additional comments ## Validation Steps Performed --- doc/devdocs/readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/devdocs/readme.md b/doc/devdocs/readme.md index 35814fe03c..f07b53f14e 100644 --- a/doc/devdocs/readme.md +++ b/doc/devdocs/readme.md @@ -68,6 +68,7 @@ Once you've discussed your proposed feature/fix/etc. with a team member, and an - Add the `In progress` label to the issue, if not already present. Also add a `Cost-Small/Medium/Large` estimate and make sure all appropriate labels are set. - If you are a community contributor, you will not be able to add labels to the issue; in that case just add a comment saying that you have started work on the issue and try to give an estimate for the delivery date. - If the work item has a medium/large cost, using the markdown task list, list each sub item and update the list with a check mark after completing each sub item. +- **Before opening a PR, ensure your changes build successfully locally and functionality tests pass.** This is especially important for AI-assisted (vibe coding) contributions—always verify AI-generated code works as intended. Exploratory PRs or draft PRs for discussion are exceptions. - When opening a PR, follow the PR template. - When you'd like the team to take a look (even if the work is not yet fully complete) mark the PR as 'Ready For Review' so that the team can review your work and provide comments, suggestions, and request changes. It may take several cycles, but the end result will be solid, testable, conformant code that is safe for us to merge. - When the PR is approved, let the owner of the PR merge it. For community contributions, the reviewer who approved the PR can also merge it. From 3336c134dd96fccb84eddce3ba91c1b2f14e8308 Mon Sep 17 00:00:00 2001 From: moooyo <42196638+moooyo@users.noreply.github.com> Date: Thu, 5 Feb 2026 17:02:55 +0800 Subject: [PATCH 07/41] [PowerDisplay] Add custom vcp code name map and fix some bugs (#45355) ## Summary of the Pull Request 1. Fix quick access not working bug 2. Add custom value mapping 3. Fix some vcp slider visibility bug demo for custom vcp value name mapping: image image image image ## PR Checklist - [ ] Closes: #xxx - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx ## Detailed Description of the Pull Request / Additional comments ## Validation Steps Performed --------- Co-authored-by: Yu Leng --- .../Models/CustomVcpValueMapping.cs | 88 ++++ .../PowerDisplay.Lib/Utils/VcpNames.cs | 86 +++- .../powerdisplay/PowerDisplay/Program.cs | 23 +- .../ViewModels/MainViewModel.Settings.cs | 25 +- .../PowerDisplay/ViewModels/MainViewModel.cs | 21 + .../ViewModels/MonitorViewModel.cs | 40 +- .../PowerDisplayProcessManager.cpp | 5 +- .../PowerDisplayModuleInterface/dllmain.cpp | 127 +++++- .../QuickAccess/QuickAccessLauncher.cs | 7 + .../PowerDisplayProperties.cs | 8 + .../Views/CustomVcpMappingEditorDialog.xaml | 75 ++++ .../CustomVcpMappingEditorDialog.xaml.cs | 421 ++++++++++++++++++ .../SettingsXAML/Views/PowerDisplayPage.xaml | 42 +- .../Views/PowerDisplayPage.xaml.cs | 59 +++ .../Settings.UI/Strings/en-us/Resources.resw | 63 +++ .../ViewModels/PowerDisplayViewModel.cs | 145 +++++- 16 files changed, 1195 insertions(+), 40 deletions(-) create mode 100644 src/modules/powerdisplay/PowerDisplay.Lib/Models/CustomVcpValueMapping.cs create mode 100644 src/settings-ui/Settings.UI/SettingsXAML/Views/CustomVcpMappingEditorDialog.xaml create mode 100644 src/settings-ui/Settings.UI/SettingsXAML/Views/CustomVcpMappingEditorDialog.xaml.cs diff --git a/src/modules/powerdisplay/PowerDisplay.Lib/Models/CustomVcpValueMapping.cs b/src/modules/powerdisplay/PowerDisplay.Lib/Models/CustomVcpValueMapping.cs new file mode 100644 index 0000000000..65131af103 --- /dev/null +++ b/src/modules/powerdisplay/PowerDisplay.Lib/Models/CustomVcpValueMapping.cs @@ -0,0 +1,88 @@ +// 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; +using PowerDisplay.Common.Utils; + +namespace PowerDisplay.Common.Models +{ + /// + /// Represents a custom name mapping for a VCP code value. + /// Used to override the default VCP value names with user-defined names. + /// This class is shared between PowerDisplay app and Settings UI. + /// + public class CustomVcpValueMapping + { + /// + /// Gets or sets the VCP code (e.g., 0x14 for color temperature, 0x60 for input source). + /// + [JsonPropertyName("vcpCode")] + public byte VcpCode { get; set; } + + /// + /// Gets or sets the VCP value to map (e.g., 0x11 for HDMI-1). + /// + [JsonPropertyName("value")] + public int Value { get; set; } + + /// + /// Gets or sets the custom name to display instead of the default name. + /// + [JsonPropertyName("customName")] + public string CustomName { get; set; } = string.Empty; + + /// + /// Gets or sets a value indicating whether this mapping applies to all monitors. + /// When true, the mapping is applied globally. When false, only applies to TargetMonitorId. + /// + [JsonPropertyName("applyToAll")] + public bool ApplyToAll { get; set; } = true; + + /// + /// Gets or sets the target monitor ID when ApplyToAll is false. + /// This is the monitor's unique identifier. + /// + [JsonPropertyName("targetMonitorId")] + public string TargetMonitorId { get; set; } = string.Empty; + + /// + /// Gets or sets the target monitor display name (for UI display only, not serialized). + /// + [JsonIgnore] + public string TargetMonitorName { get; set; } = string.Empty; + + /// + /// Gets the display name for the VCP code (for UI display). + /// Uses VcpNames.GetCodeName() to get the standard MCCS VCP code name. + /// Note: For localized display in Settings UI, use VcpCodeToDisplayNameConverter instead. + /// + [JsonIgnore] + public string VcpCodeDisplayName => VcpNames.GetCodeName(VcpCode); + + /// + /// Gets the display name for the VCP value (using built-in mapping). + /// + [JsonIgnore] + public string ValueDisplayName => VcpNames.GetFormattedValueName(VcpCode, Value); + + /// + /// Gets a summary string for display in the UI list. + /// Format: "OriginalValue → CustomName" or "OriginalValue → CustomName (MonitorName)" + /// + [JsonIgnore] + public string DisplaySummary + { + get + { + var baseSummary = $"{VcpNames.GetValueName(VcpCode, Value) ?? $"0x{Value:X2}"} → {CustomName}"; + if (!ApplyToAll && !string.IsNullOrEmpty(TargetMonitorName)) + { + return $"{baseSummary} ({TargetMonitorName})"; + } + + return baseSummary; + } + } + } +} diff --git a/src/modules/powerdisplay/PowerDisplay.Lib/Utils/VcpNames.cs b/src/modules/powerdisplay/PowerDisplay.Lib/Utils/VcpNames.cs index 2d4fed19c6..1ecd5f150e 100644 --- a/src/modules/powerdisplay/PowerDisplay.Lib/Utils/VcpNames.cs +++ b/src/modules/powerdisplay/PowerDisplay.Lib/Utils/VcpNames.cs @@ -2,16 +2,27 @@ // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; using System.Collections.Generic; +using System.Linq; +using PowerDisplay.Common.Models; namespace PowerDisplay.Common.Utils { /// /// Provides human-readable names for VCP codes and their values based on MCCS v2.2a specification. /// Combines VCP code names (e.g., 0x10 = "Brightness") and VCP value names (e.g., 0x14:0x05 = "6500K"). + /// Supports localization through the LocalizedCodeNameProvider delegate. /// public static class VcpNames { + /// + /// Optional delegate to provide localized VCP code names. + /// Set this at application startup to enable localization. + /// The delegate receives a VCP code and should return the localized name, or null to use the default. + /// + public static Func? LocalizedCodeNameProvider { get; set; } + /// /// VCP code to name mapping /// @@ -237,12 +248,21 @@ namespace PowerDisplay.Common.Utils }; /// - /// Get the friendly name for a VCP code + /// Get the friendly name for a VCP code. + /// Uses LocalizedCodeNameProvider if set; falls back to built-in MCCS names if not. /// /// VCP code (e.g., 0x10) /// Friendly name, or hex representation if unknown public static string GetCodeName(byte code) { + // Try localized name first + var localizedName = LocalizedCodeNameProvider?.Invoke(code); + if (!string.IsNullOrEmpty(localizedName)) + { + return localizedName; + } + + // Fallback to built-in MCCS names return CodeNames.TryGetValue(code, out var name) ? name : $"Unknown (0x{code:X2})"; } @@ -389,6 +409,16 @@ namespace PowerDisplay.Common.Utils }, }; + /// + /// Get all known values for a VCP code + /// + /// VCP code (e.g., 0x14) + /// Dictionary of value to name mappings, or null if no mappings exist + public static IReadOnlyDictionary? GetValueMappings(byte vcpCode) + { + return ValueNames.TryGetValue(vcpCode, out var values) ? values : null; + } + /// /// Get human-readable name for a VCP value /// @@ -424,5 +454,59 @@ namespace PowerDisplay.Common.Utils return $"0x{value:X2}"; } + + /// + /// Get human-readable name for a VCP value with custom mapping support. + /// Custom mappings take priority over built-in mappings. + /// Monitor ID is required to properly filter monitor-specific mappings. + /// + /// VCP code (e.g., 0x14) + /// Value to translate + /// Optional custom mappings that take priority + /// Monitor ID to filter mappings + /// Name string like "sRGB" or null if unknown + public static string? GetValueName(byte vcpCode, int value, IEnumerable? customMappings, string monitorId) + { + // 1. Priority: Check custom mappings first + if (customMappings != null) + { + // Find a matching custom mapping: + // - ApplyToAll = true (global), OR + // - ApplyToAll = false AND TargetMonitorId matches the given monitorId + var custom = customMappings.FirstOrDefault(m => + m.VcpCode == vcpCode && + m.Value == value && + (m.ApplyToAll || (!m.ApplyToAll && m.TargetMonitorId == monitorId))); + + if (custom != null && !string.IsNullOrEmpty(custom.CustomName)) + { + return custom.CustomName; + } + } + + // 2. Fallback to built-in mappings + return GetValueName(vcpCode, value); + } + + /// + /// Get formatted display name for a VCP value with custom mapping support. + /// Custom mappings take priority over built-in mappings. + /// Monitor ID is required to properly filter monitor-specific mappings. + /// + /// VCP code (e.g., 0x14) + /// Value to translate + /// Optional custom mappings that take priority + /// Monitor ID to filter mappings + /// Formatted string like "sRGB (0x01)" or "0x01" if unknown + public static string GetFormattedValueName(byte vcpCode, int value, IEnumerable? customMappings, string monitorId) + { + var name = GetValueName(vcpCode, value, customMappings, monitorId); + if (name != null) + { + return $"{name} (0x{value:X2})"; + } + + return $"0x{value:X2}"; + } } } diff --git a/src/modules/powerdisplay/PowerDisplay/Program.cs b/src/modules/powerdisplay/PowerDisplay/Program.cs index f893741e77..2553637b6f 100644 --- a/src/modules/powerdisplay/PowerDisplay/Program.cs +++ b/src/modules/powerdisplay/PowerDisplay/Program.cs @@ -125,14 +125,27 @@ namespace PowerDisplay /// /// Called when an existing instance is activated by another process. - /// This happens when EnsureProcessRunning() launches a new process while one is already running. - /// We intentionally don't show the window here - window visibility should only be controlled via: - /// - Toggle event (hotkey, tray icon click, Settings UI Launch button) - /// - Standalone mode startup (handled in OnLaunched) + /// This happens when Quick Access or other launchers start the process while one is already running. + /// We toggle the window to show it - this allows Quick Access launch to work properly. /// private static void OnActivated(object? sender, AppActivationArguments args) { - Logger.LogInfo("OnActivated: Redirect activation received - window visibility unchanged"); + Logger.LogInfo("OnActivated: Redirect activation received - toggling window"); + + // Toggle the main window on redirect activation + if (_app?.MainWindow is MainWindow mainWindow) + { + // Dispatch to UI thread since OnActivated may be called from a different thread + mainWindow.DispatcherQueue.TryEnqueue(() => + { + Logger.LogTrace("OnActivated: Toggling window from redirect activation"); + mainWindow.ToggleWindow(); + }); + } + else + { + Logger.LogWarning("OnActivated: MainWindow not available for toggle"); + } } } } diff --git a/src/modules/powerdisplay/PowerDisplay/ViewModels/MainViewModel.Settings.cs b/src/modules/powerdisplay/PowerDisplay/ViewModels/MainViewModel.Settings.cs index dc9e7ccbbd..d01af35c6c 100644 --- a/src/modules/powerdisplay/PowerDisplay/ViewModels/MainViewModel.Settings.cs +++ b/src/modules/powerdisplay/PowerDisplay/ViewModels/MainViewModel.Settings.cs @@ -43,6 +43,10 @@ public partial class MainViewModel // UpdateMonitorList already handles filtering hidden monitors UpdateMonitorList(_monitorManager.Monitors, isInitialLoad: false); + // Reload UI display settings first (includes custom VCP mappings) + // Must be loaded before ApplyUIConfiguration so names are available for UI refresh + LoadUIDisplaySettings(); + // Apply UI configuration changes only (feature visibility toggles, etc.) // Hardware parameters (brightness, color temperature) are applied via custom actions var settings = _settingsUtils.GetSettingsOrDefault("PowerDisplay"); @@ -51,8 +55,11 @@ public partial class MainViewModel // Reload profiles in case they were added/updated/deleted in Settings UI LoadProfiles(); - // Reload UI display settings (profile switcher, identify button, color temp switcher) - LoadUIDisplaySettings(); + // Notify MonitorViewModels to refresh their custom VCP name displays + foreach (var monitor in Monitors) + { + monitor.RefreshCustomVcpNames(); + } } catch (Exception ex) { @@ -304,7 +311,8 @@ public partial class MainViewModel } /// - /// Apply feature visibility settings to a monitor ViewModel + /// Apply feature visibility settings to a monitor ViewModel. + /// Only shows features that are both enabled by user AND supported by hardware. /// private void ApplyFeatureVisibility(MonitorViewModel monitorVm, PowerDisplaySettings settings) { @@ -313,12 +321,13 @@ public partial class MainViewModel if (monitorSettings != null) { - monitorVm.ShowContrast = monitorSettings.EnableContrast; - monitorVm.ShowVolume = monitorSettings.EnableVolume; - monitorVm.ShowInputSource = monitorSettings.EnableInputSource; + // Only show features that are both enabled by user AND supported by hardware + monitorVm.ShowContrast = monitorSettings.EnableContrast && monitorVm.SupportsContrast; + monitorVm.ShowVolume = monitorSettings.EnableVolume && monitorVm.SupportsVolume; + monitorVm.ShowInputSource = monitorSettings.EnableInputSource && monitorVm.SupportsInputSource; monitorVm.ShowRotation = monitorSettings.EnableRotation; - monitorVm.ShowColorTemperature = monitorSettings.EnableColorTemperature; - monitorVm.ShowPowerState = monitorSettings.EnablePowerState; + monitorVm.ShowColorTemperature = monitorSettings.EnableColorTemperature && monitorVm.SupportsColorTemperature; + monitorVm.ShowPowerState = monitorSettings.EnablePowerState && monitorVm.SupportsPowerState; } } diff --git a/src/modules/powerdisplay/PowerDisplay/ViewModels/MainViewModel.cs b/src/modules/powerdisplay/PowerDisplay/ViewModels/MainViewModel.cs index d3a831a07d..e16b34cadb 100644 --- a/src/modules/powerdisplay/PowerDisplay/ViewModels/MainViewModel.cs +++ b/src/modules/powerdisplay/PowerDisplay/ViewModels/MainViewModel.cs @@ -163,6 +163,23 @@ public partial class MainViewModel : INotifyPropertyChanged, IDisposable } } + // Custom VCP mappings - loaded from settings + private List _customVcpMappings = new(); + + /// + /// Gets or sets the custom VCP value name mappings. + /// These mappings override the default VCP value names for color temperature and input source. + /// + public List CustomVcpMappings + { + get => _customVcpMappings; + set + { + _customVcpMappings = value ?? new List(); + OnPropertyChanged(); + } + } + public bool IsScanning { get => _isScanning; @@ -389,6 +406,10 @@ public partial class MainViewModel : INotifyPropertyChanged, IDisposable var settings = _settingsUtils.GetSettingsOrDefault(PowerDisplaySettings.ModuleName); ShowProfileSwitcher = settings.Properties.ShowProfileSwitcher; ShowIdentifyMonitorsButton = settings.Properties.ShowIdentifyMonitorsButton; + + // Load custom VCP mappings (now using shared type from PowerDisplay.Common.Models) + CustomVcpMappings = settings.Properties.CustomVcpMappings?.ToList() ?? new List(); + Logger.LogInfo($"[Settings] Loaded {CustomVcpMappings.Count} custom VCP mappings"); } catch (Exception ex) { diff --git a/src/modules/powerdisplay/PowerDisplay/ViewModels/MonitorViewModel.cs b/src/modules/powerdisplay/PowerDisplay/ViewModels/MonitorViewModel.cs index 5629ebdacf..b50fcc03e4 100644 --- a/src/modules/powerdisplay/PowerDisplay/ViewModels/MonitorViewModel.cs +++ b/src/modules/powerdisplay/PowerDisplay/ViewModels/MonitorViewModel.cs @@ -279,6 +279,16 @@ public partial class MonitorViewModel : INotifyPropertyChanged, IDisposable // Advanced control display logic public bool HasAdvancedControls => ShowContrast || ShowVolume; + /// + /// Gets a value indicating whether this monitor supports contrast control via VCP 0x12 + /// + public bool SupportsContrast => _monitor.SupportsContrast; + + /// + /// Gets a value indicating whether this monitor supports volume control via VCP 0x62 + /// + public bool SupportsVolume => _monitor.SupportsVolume; + public bool ShowContrast { get => _showContrast; @@ -456,8 +466,10 @@ public partial class MonitorViewModel : INotifyPropertyChanged, IDisposable /// /// Gets human-readable color temperature preset name (e.g., "6500K", "sRGB") + /// Uses custom mappings if available; falls back to built-in names if not. /// - public string ColorTemperaturePresetName => _monitor.ColorTemperaturePresetName; + public string ColorTemperaturePresetName => + Common.Utils.VcpNames.GetFormattedValueName(0x14, _monitor.CurrentColorTemperature, _mainViewModel?.CustomVcpMappings, _monitor.Id); /// /// Gets a value indicating whether this monitor supports color temperature via VCP 0x14 @@ -537,7 +549,7 @@ public partial class MonitorViewModel : INotifyPropertyChanged, IDisposable _availableColorPresets = presetValues.Select(value => new ColorTemperatureItem { VcpValue = value, - DisplayName = Common.Utils.VcpNames.GetFormattedValueName(0x14, value), + DisplayName = Common.Utils.VcpNames.GetFormattedValueName(0x14, value, _mainViewModel?.CustomVcpMappings, _monitor.Id), IsSelected = value == _monitor.CurrentColorTemperature, MonitorId = _monitor.Id, }).ToList(); @@ -557,8 +569,11 @@ public partial class MonitorViewModel : INotifyPropertyChanged, IDisposable /// /// Gets human-readable current input source name (e.g., "HDMI-1", "DisplayPort-1") + /// Uses custom mappings if available; falls back to built-in names if not. /// - public string CurrentInputSourceName => _monitor.InputSourceName; + public string CurrentInputSourceName => + Common.Utils.VcpNames.GetValueName(0x60, _monitor.CurrentInputSource, _mainViewModel?.CustomVcpMappings, _monitor.Id) + ?? $"Source 0x{_monitor.CurrentInputSource:X2}"; private List? _availableInputSources; @@ -593,7 +608,7 @@ public partial class MonitorViewModel : INotifyPropertyChanged, IDisposable _availableInputSources = supportedSources.Select(value => new InputSourceItem { Value = value, - Name = Common.Utils.VcpNames.GetValueName(0x60, value) ?? $"Source 0x{value:X2}", + Name = Common.Utils.VcpNames.GetValueName(0x60, value, _mainViewModel?.CustomVcpMappings, _monitor.Id) ?? $"Source 0x{value:X2}", SelectionVisibility = value == _monitor.CurrentInputSource ? Visibility.Visible : Visibility.Collapsed, MonitorId = _monitor.Id, }).ToList(); @@ -601,6 +616,23 @@ public partial class MonitorViewModel : INotifyPropertyChanged, IDisposable OnPropertyChanged(nameof(AvailableInputSources)); } + /// + /// Refresh custom VCP name displays after settings change. + /// Called when CustomVcpMappings is updated from Settings UI. + /// + public void RefreshCustomVcpNames() + { + // Refresh color temperature names + OnPropertyChanged(nameof(ColorTemperaturePresetName)); + _availableColorPresets = null; // Force rebuild with new custom names + OnPropertyChanged(nameof(AvailableColorPresets)); + + // Refresh input source names + OnPropertyChanged(nameof(CurrentInputSourceName)); + _availableInputSources = null; // Force rebuild with new custom names + OnPropertyChanged(nameof(AvailableInputSources)); + } + /// /// Set input source for this monitor /// diff --git a/src/modules/powerdisplay/PowerDisplayModuleInterface/PowerDisplayProcessManager.cpp b/src/modules/powerdisplay/PowerDisplayModuleInterface/PowerDisplayProcessManager.cpp index 6f35629d3b..cf9ab171c2 100644 --- a/src/modules/powerdisplay/PowerDisplayModuleInterface/PowerDisplayProcessManager.cpp +++ b/src/modules/powerdisplay/PowerDisplayModuleInterface/PowerDisplayProcessManager.cpp @@ -52,8 +52,11 @@ void PowerDisplayProcessManager::send_message(const std::wstring& message_type, { submit_task([this, message_type, message_arg] { // Ensure process is running before sending message - if (!is_process_running() && m_enabled) + // If process is not running, enable and start it - this allows Quick Access launch + // to work even when the module was not previously enabled + if (!is_process_running()) { + m_enabled = true; refresh(); } send_named_pipe_message(message_type, message_arg); diff --git a/src/modules/powerdisplay/PowerDisplayModuleInterface/dllmain.cpp b/src/modules/powerdisplay/PowerDisplayModuleInterface/dllmain.cpp index 871a8797ef..7360a34772 100644 --- a/src/modules/powerdisplay/PowerDisplayModuleInterface/dllmain.cpp +++ b/src/modules/powerdisplay/PowerDisplayModuleInterface/dllmain.cpp @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include "resource.h" @@ -48,6 +50,11 @@ private: HANDLE m_hRefreshEvent = nullptr; HANDLE m_hSendSettingsTelemetryEvent = nullptr; + // Toggle event handle and listener thread for Quick Access support + HANDLE m_hToggleEvent = nullptr; + HANDLE m_hStopEvent = nullptr; // Manual-reset event to signal thread termination + std::thread m_toggleEventThread; + public: PowerDisplayModule() { @@ -62,16 +69,29 @@ public: m_hSendSettingsTelemetryEvent = CreateDefaultEvent(CommonSharedConstants::POWER_DISPLAY_SEND_SETTINGS_TELEMETRY_EVENT); Logger::trace(L"Created SEND_SETTINGS_TELEMETRY_EVENT: handle={}", reinterpret_cast(m_hSendSettingsTelemetryEvent)); - if (!m_hRefreshEvent || !m_hSendSettingsTelemetryEvent) + // Create Toggle event for Quick Access support + // This allows Quick Access to launch PowerDisplay even when module is not enabled + m_hToggleEvent = CreateDefaultEvent(CommonSharedConstants::TOGGLE_POWER_DISPLAY_EVENT); + Logger::trace(L"Created TOGGLE_EVENT: handle={}", reinterpret_cast(m_hToggleEvent)); + + // Create manual-reset stop event for clean thread termination + m_hStopEvent = CreateEventW(nullptr, TRUE, FALSE, nullptr); + Logger::trace(L"Created STOP_EVENT: handle={}", reinterpret_cast(m_hStopEvent)); + + if (!m_hRefreshEvent || !m_hSendSettingsTelemetryEvent || !m_hToggleEvent || !m_hStopEvent) { - Logger::error(L"Failed to create one or more event handles: Refresh={}, SettingsTelemetry={}", + Logger::error(L"Failed to create one or more event handles: Refresh={}, SettingsTelemetry={}, Toggle={}", reinterpret_cast(m_hRefreshEvent), - reinterpret_cast(m_hSendSettingsTelemetryEvent)); + reinterpret_cast(m_hSendSettingsTelemetryEvent), + reinterpret_cast(m_hToggleEvent)); } else { Logger::info(L"All Windows Events created successfully"); } + + // Start toggle event listener thread for Quick Access support + StartToggleEventListener(); } ~PowerDisplayModule() @@ -81,6 +101,9 @@ public: disable(); } + // Stop toggle event listener thread + StopToggleEventListener(); + // Clean up event handles if (m_hRefreshEvent) { @@ -92,6 +115,99 @@ public: CloseHandle(m_hSendSettingsTelemetryEvent); m_hSendSettingsTelemetryEvent = nullptr; } + if (m_hToggleEvent) + { + CloseHandle(m_hToggleEvent); + m_hToggleEvent = nullptr; + } + if (m_hStopEvent) + { + CloseHandle(m_hStopEvent); + m_hStopEvent = nullptr; + } + } + + void StartToggleEventListener() + { + if (!m_hToggleEvent || !m_hStopEvent) + { + return; + } + + // Reset stop event before starting thread + ResetEvent(m_hStopEvent); + + m_toggleEventThread = std::thread([this]() { + Logger::info(L"Toggle event listener thread started"); + + HANDLE handles[] = { m_hToggleEvent, m_hStopEvent }; + constexpr DWORD TOGGLE_EVENT_INDEX = 0; + constexpr DWORD STOP_EVENT_INDEX = 1; + + while (true) + { + // Wait indefinitely for either toggle event or stop event + DWORD result = WaitForMultipleObjects(2, handles, FALSE, INFINITE); + + if (result == WAIT_OBJECT_0 + TOGGLE_EVENT_INDEX) + { + Logger::trace(L"Toggle event received"); + TogglePowerDisplay(); + } + else if (result == WAIT_OBJECT_0 + STOP_EVENT_INDEX) + { + // Stop event signaled - exit the loop + Logger::trace(L"Stop event received, exiting toggle listener"); + break; + } + else + { + // WAIT_FAILED or unexpected result + Logger::warn(L"WaitForMultipleObjects returned unexpected result: {}", result); + break; + } + } + + Logger::info(L"Toggle event listener thread stopped"); + }); + } + + void StopToggleEventListener() + { + if (m_hStopEvent) + { + // Signal the stop event to wake up the waiting thread + SetEvent(m_hStopEvent); + } + + if (m_toggleEventThread.joinable()) + { + m_toggleEventThread.join(); + } + } + + /// + /// Toggle PowerDisplay window visibility. + /// If process is running, launches again to trigger redirect activation (OnActivated handles toggle). + /// If process is not running, starts it via Named Pipe and sends toggle message. + /// + void TogglePowerDisplay() + { + if (m_processManager.is_running()) + { + // Process running - launch to trigger single instance redirect, OnActivated will toggle + SHELLEXECUTEINFOW sei{ sizeof(sei) }; + sei.fMask = SEE_MASK_FLAG_NO_UI; + sei.lpFile = L"WinUI3Apps\\PowerToys.PowerDisplay.exe"; + sei.nShow = SW_SHOWNORMAL; + ShellExecuteExW(&sei); + } + else + { + // Process not running - start and send toggle via Named Pipe + m_processManager.send_message(CommonSharedConstants::POWER_DISPLAY_TOGGLE_MESSAGE); + } + Trace::ActivatePowerDisplay(); } virtual void destroy() override @@ -135,10 +251,7 @@ public: if (action_object.get_name() == L"Launch") { Logger::trace(L"Launch action received"); - - // Send Toggle message via Named Pipe (will start process if needed) - m_processManager.send_message(CommonSharedConstants::POWER_DISPLAY_TOGGLE_MESSAGE); - Trace::ActivatePowerDisplay(); + TogglePowerDisplay(); } else if (action_object.get_name() == L"RefreshMonitors") { diff --git a/src/settings-ui/Settings.UI.Controls/QuickAccess/QuickAccessLauncher.cs b/src/settings-ui/Settings.UI.Controls/QuickAccess/QuickAccessLauncher.cs index b81c9638f3..1347ce86c1 100644 --- a/src/settings-ui/Settings.UI.Controls/QuickAccess/QuickAccessLauncher.cs +++ b/src/settings-ui/Settings.UI.Controls/QuickAccess/QuickAccessLauncher.cs @@ -119,6 +119,13 @@ namespace Microsoft.PowerToys.Settings.UI.Controls eventHandle.Set(); } + return true; + case ModuleType.PowerDisplay: + using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.TogglePowerDisplayEvent())) + { + eventHandle.Set(); + } + return true; default: return false; diff --git a/src/settings-ui/Settings.UI.Library/PowerDisplayProperties.cs b/src/settings-ui/Settings.UI.Library/PowerDisplayProperties.cs index 25a4354474..5539daf0fd 100644 --- a/src/settings-ui/Settings.UI.Library/PowerDisplayProperties.cs +++ b/src/settings-ui/Settings.UI.Library/PowerDisplayProperties.cs @@ -23,6 +23,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library ShowSystemTrayIcon = true; ShowProfileSwitcher = true; ShowIdentifyMonitorsButton = true; + CustomVcpMappings = new List(); // Note: saved_monitor_settings has been moved to monitor_state.json // which is managed separately by PowerDisplay app @@ -61,5 +62,12 @@ namespace Microsoft.PowerToys.Settings.UI.Library /// [JsonPropertyName("show_identify_monitors_button")] public bool ShowIdentifyMonitorsButton { get; set; } + + /// + /// Gets or sets custom VCP value name mappings shared across all monitors. + /// Allows users to define custom names for color temperature presets and input sources. + /// + [JsonPropertyName("custom_vcp_mappings")] + public List CustomVcpMappings { get; set; } } } diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Views/CustomVcpMappingEditorDialog.xaml b/src/settings-ui/Settings.UI/SettingsXAML/Views/CustomVcpMappingEditorDialog.xaml new file mode 100644 index 0000000000..9f0bc51079 --- /dev/null +++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/CustomVcpMappingEditorDialog.xaml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Views/CustomVcpMappingEditorDialog.xaml.cs b/src/settings-ui/Settings.UI/SettingsXAML/Views/CustomVcpMappingEditorDialog.xaml.cs new file mode 100644 index 0000000000..915c891ada --- /dev/null +++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/CustomVcpMappingEditorDialog.xaml.cs @@ -0,0 +1,421 @@ +// 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. + +#nullable enable + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Globalization; +using System.Linq; +using System.Runtime.CompilerServices; +using Microsoft.PowerToys.Settings.UI.Helpers; +using Microsoft.PowerToys.Settings.UI.Library; +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Controls; +using PowerDisplay.Common.Models; +using PowerDisplay.Common.Utils; + +namespace Microsoft.PowerToys.Settings.UI.Views +{ + /// + /// Dialog for creating/editing custom VCP value name mappings + /// + public sealed partial class CustomVcpMappingEditorDialog : ContentDialog, INotifyPropertyChanged + { + /// + /// Special value to indicate "Custom value" option in the ComboBox + /// + private const int CustomValueMarker = -1; + + /// + /// Represents a selectable VCP value item in the Value ComboBox + /// + public class VcpValueItem + { + public int Value { get; set; } + + public string DisplayName { get; set; } = string.Empty; + + public bool IsCustomOption => Value == CustomValueMarker; + } + + /// + /// Represents a selectable monitor item in the Monitor ComboBox + /// + public class MonitorItem + { + public string Id { get; set; } = string.Empty; + + public string DisplayName { get; set; } = string.Empty; + } + + private readonly IEnumerable? _monitors; + private ObservableCollection _availableValues = new(); + private ObservableCollection _availableMonitors = new(); + private byte _selectedVcpCode; + private int _selectedValue; + private string _customName = string.Empty; + private bool _canSave; + private bool _showCustomValueInput; + private bool _showMonitorSelector; + private int _customValueParsed; + private bool _applyToAll = true; + private string _selectedMonitorId = string.Empty; + private string _selectedMonitorName = string.Empty; + + public CustomVcpMappingEditorDialog(IEnumerable? monitors) + { + _monitors = monitors; + this.InitializeComponent(); + + // Set localized strings for ContentDialog + var resourceLoader = ResourceLoaderInstance.ResourceLoader; + Title = resourceLoader.GetString("PowerDisplay_CustomMappingEditor_Title"); + PrimaryButtonText = resourceLoader.GetString("PowerDisplay_Dialog_Save"); + CloseButtonText = resourceLoader.GetString("PowerDisplay_Dialog_Cancel"); + + // Set VCP code ComboBox items content dynamically using localized names + VcpCodeItem_0x14.Content = GetFormattedVcpCodeName(resourceLoader, 0x14); + VcpCodeItem_0x60.Content = GetFormattedVcpCodeName(resourceLoader, 0x60); + + // Populate monitor list + PopulateMonitorList(); + + // Default to Color Temperature (0x14) + VcpCodeComboBox.SelectedIndex = 0; + } + + /// + /// Gets the result mapping after dialog closes with Primary button + /// + public CustomVcpValueMapping? ResultMapping { get; private set; } + + /// + /// Gets the available values for the selected VCP code + /// + public ObservableCollection AvailableValues + { + get => _availableValues; + private set + { + _availableValues = value; + OnPropertyChanged(); + } + } + + /// + /// Gets the available monitors for selection + /// + public ObservableCollection AvailableMonitors + { + get => _availableMonitors; + private set + { + _availableMonitors = value; + OnPropertyChanged(); + } + } + + /// + /// Gets a value indicating whether the dialog can be saved + /// + public bool CanSave + { + get => _canSave; + private set + { + if (_canSave != value) + { + _canSave = value; + OnPropertyChanged(); + } + } + } + + /// + /// Gets a value indicating whether to show the custom value input TextBox + /// + public Visibility ShowCustomValueInput => _showCustomValueInput ? Visibility.Visible : Visibility.Collapsed; + + /// + /// Gets a value indicating whether to show the monitor selector ComboBox + /// + public Visibility ShowMonitorSelector => _showMonitorSelector ? Visibility.Visible : Visibility.Collapsed; + + private void SetShowCustomValueInput(bool value) + { + if (_showCustomValueInput != value) + { + _showCustomValueInput = value; + OnPropertyChanged(nameof(ShowCustomValueInput)); + } + } + + private void SetShowMonitorSelector(bool value) + { + if (_showMonitorSelector != value) + { + _showMonitorSelector = value; + OnPropertyChanged(nameof(ShowMonitorSelector)); + } + } + + private void PopulateMonitorList() + { + AvailableMonitors = new ObservableCollection( + _monitors?.Select(m => new MonitorItem { Id = m.Id, DisplayName = m.DisplayName }) + ?? Enumerable.Empty()); + + if (AvailableMonitors.Count > 0) + { + MonitorComboBox.SelectedIndex = 0; + } + } + + /// + /// Pre-fill the dialog with existing mapping data for editing + /// + public void PreFillMapping(CustomVcpValueMapping mapping) + { + if (mapping is null) + { + return; + } + + // Select the VCP code + VcpCodeComboBox.SelectedIndex = mapping.VcpCode == 0x14 ? 0 : 1; + + // Populate values for the selected VCP code + PopulateValuesForVcpCode(mapping.VcpCode); + + // Try to select the value in the ComboBox + var matchingItem = AvailableValues.FirstOrDefault(v => !v.IsCustomOption && v.Value == mapping.Value); + if (matchingItem is not null) + { + ValueComboBox.SelectedItem = matchingItem; + } + else + { + // Value not found in list, select "Custom value" option and fill the TextBox + ValueComboBox.SelectedItem = AvailableValues.FirstOrDefault(v => v.IsCustomOption); + CustomValueTextBox.Text = $"0x{mapping.Value:X2}"; + _customValueParsed = mapping.Value; + } + + // Set the custom name + CustomNameTextBox.Text = mapping.CustomName; + _customName = mapping.CustomName; + + // Set apply scope + _applyToAll = mapping.ApplyToAll; + ApplyToAllToggle.IsOn = mapping.ApplyToAll; + SetShowMonitorSelector(!mapping.ApplyToAll); + + // Select the target monitor if not applying to all + if (!mapping.ApplyToAll && !string.IsNullOrEmpty(mapping.TargetMonitorId)) + { + var targetMonitor = AvailableMonitors.FirstOrDefault(m => m.Id == mapping.TargetMonitorId); + if (targetMonitor is not null) + { + MonitorComboBox.SelectedItem = targetMonitor; + _selectedMonitorId = targetMonitor.Id; + _selectedMonitorName = targetMonitor.DisplayName; + } + } + + UpdateCanSave(); + } + + private void VcpCodeComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + if (VcpCodeComboBox.SelectedItem is ComboBoxItem selectedItem && + selectedItem.Tag is string tagValue && + byte.TryParse(tagValue, out byte vcpCode)) + { + _selectedVcpCode = vcpCode; + PopulateValuesForVcpCode(vcpCode); + UpdateCanSave(); + } + } + + private void PopulateValuesForVcpCode(byte vcpCode) + { + var values = new ObservableCollection(); + var seenValues = new HashSet(); + + // Collect values from all monitors + if (_monitors is not null) + { + foreach (var monitor in _monitors) + { + if (monitor.VcpCodesFormatted is null) + { + continue; + } + + // Find the VCP code entry + var vcpEntry = monitor.VcpCodesFormatted.FirstOrDefault(v => + !string.IsNullOrEmpty(v.Code) && + TryParseHexCode(v.Code, out int code) && + code == vcpCode); + + if (vcpEntry?.ValueList is null) + { + continue; + } + + // Add each value from this monitor + foreach (var valueInfo in vcpEntry.ValueList) + { + if (TryParseHexCode(valueInfo.Value, out int vcpValue) && !seenValues.Contains(vcpValue)) + { + seenValues.Add(vcpValue); + var displayName = !string.IsNullOrEmpty(valueInfo.Name) + ? $"{valueInfo.Name} (0x{vcpValue:X2})" + : VcpNames.GetFormattedValueName(vcpCode, vcpValue); + values.Add(new VcpValueItem + { + Value = vcpValue, + DisplayName = displayName, + }); + } + } + } + } + + // If no values found from monitors, fall back to built-in values from VcpNames + if (values.Count == 0) + { + var builtInValues = VcpNames.GetValueMappings(vcpCode); + if (builtInValues is not null) + { + foreach (var kvp in builtInValues) + { + values.Add(new VcpValueItem + { + Value = kvp.Key, + DisplayName = $"{kvp.Value} (0x{kvp.Key:X2})", + }); + } + } + } + + // Sort by value + var sortedValues = new ObservableCollection(values.OrderBy(v => v.Value)); + + // Add "Custom value" option at the end + var resourceLoader = ResourceLoaderInstance.ResourceLoader; + sortedValues.Add(new VcpValueItem + { + Value = CustomValueMarker, + DisplayName = resourceLoader.GetString("PowerDisplay_CustomMappingEditor_CustomValueOption"), + }); + + AvailableValues = sortedValues; + + // Select first item if available + if (sortedValues.Count > 0) + { + ValueComboBox.SelectedIndex = 0; + } + } + + private static bool TryParseHexCode(string? hex, out int result) + { + result = 0; + if (string.IsNullOrEmpty(hex)) + { + return false; + } + + var cleanHex = hex.StartsWith("0x", StringComparison.OrdinalIgnoreCase) ? hex[2..] : hex; + return int.TryParse(cleanHex, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out result); + } + + private static string GetFormattedVcpCodeName(Windows.ApplicationModel.Resources.ResourceLoader resourceLoader, byte vcpCode) + { + var resourceKey = $"PowerDisplay_VcpCode_Name_0x{vcpCode:X2}"; + var localizedName = resourceLoader.GetString(resourceKey); + var name = string.IsNullOrEmpty(localizedName) ? VcpNames.GetCodeName(vcpCode) : localizedName; + return $"{name} (0x{vcpCode:X2})"; + } + + private void ValueComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + if (ValueComboBox.SelectedItem is VcpValueItem selectedItem) + { + SetShowCustomValueInput(selectedItem.IsCustomOption); + _selectedValue = selectedItem.IsCustomOption ? 0 : selectedItem.Value; + UpdateCanSave(); + } + } + + private void CustomValueTextBox_TextChanged(object sender, TextChangedEventArgs e) + { + _customValueParsed = TryParseHexCode(CustomValueTextBox.Text?.Trim(), out int parsed) ? parsed : 0; + UpdateCanSave(); + } + + private void CustomNameTextBox_TextChanged(object sender, TextChangedEventArgs e) + { + _customName = CustomNameTextBox.Text?.Trim() ?? string.Empty; + UpdateCanSave(); + } + + private void ApplyToAllToggle_Toggled(object sender, RoutedEventArgs e) + { + _applyToAll = ApplyToAllToggle.IsOn; + SetShowMonitorSelector(!_applyToAll); + UpdateCanSave(); + } + + private void MonitorComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + if (MonitorComboBox.SelectedItem is MonitorItem selectedMonitor) + { + _selectedMonitorId = selectedMonitor.Id; + _selectedMonitorName = selectedMonitor.DisplayName; + UpdateCanSave(); + } + } + + private void UpdateCanSave() + { + var hasValidValue = _showCustomValueInput + ? _customValueParsed > 0 + : ValueComboBox.SelectedItem is VcpValueItem item && !item.IsCustomOption; + + CanSave = _selectedVcpCode > 0 && + hasValidValue && + !string.IsNullOrWhiteSpace(_customName) && + (_applyToAll || !string.IsNullOrEmpty(_selectedMonitorId)); + } + + private void ContentDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args) + { + if (CanSave) + { + int finalValue = _showCustomValueInput ? _customValueParsed : _selectedValue; + ResultMapping = new CustomVcpValueMapping + { + VcpCode = _selectedVcpCode, + Value = finalValue, + CustomName = _customName, + ApplyToAll = _applyToAll, + TargetMonitorId = _applyToAll ? string.Empty : _selectedMonitorId, + TargetMonitorName = _applyToAll ? string.Empty : _selectedMonitorName, + }; + } + } + + public event PropertyChangedEventHandler? PropertyChanged; + + private void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + } +} diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Views/PowerDisplayPage.xaml b/src/settings-ui/Settings.UI/SettingsXAML/Views/PowerDisplayPage.xaml index 08d736a0fc..899295ec66 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/Views/PowerDisplayPage.xaml +++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/PowerDisplayPage.xaml @@ -63,11 +63,51 @@ + + + + + + + + + + + diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Views/PowerDisplayPage.xaml.cs b/src/settings-ui/Settings.UI/SettingsXAML/Views/PowerDisplayPage.xaml.cs index 641311daad..d82746faf6 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/Views/PowerDisplayPage.xaml.cs +++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/PowerDisplayPage.xaml.cs @@ -133,6 +133,65 @@ namespace Microsoft.PowerToys.Settings.UI.Views return ProfileHelper.GenerateUniqueProfileName(existingNames, baseName); } + // Custom VCP Mapping event handlers + private async void AddCustomMapping_Click(object sender, RoutedEventArgs e) + { + var dialog = new CustomVcpMappingEditorDialog(ViewModel.Monitors); + dialog.XamlRoot = this.XamlRoot; + + var result = await dialog.ShowAsync(); + + if (result == ContentDialogResult.Primary && dialog.ResultMapping != null) + { + ViewModel.AddCustomVcpMapping(dialog.ResultMapping); + } + } + + private async void EditCustomMapping_Click(object sender, RoutedEventArgs e) + { + if (sender is not Button button || button.Tag is not CustomVcpValueMapping mapping) + { + return; + } + + var dialog = new CustomVcpMappingEditorDialog(ViewModel.Monitors); + dialog.XamlRoot = this.XamlRoot; + dialog.PreFillMapping(mapping); + + var result = await dialog.ShowAsync(); + + if (result == ContentDialogResult.Primary && dialog.ResultMapping != null) + { + ViewModel.UpdateCustomVcpMapping(mapping, dialog.ResultMapping); + } + } + + private async void DeleteCustomMapping_Click(object sender, RoutedEventArgs e) + { + if (sender is not Button button || button.Tag is not CustomVcpValueMapping mapping) + { + return; + } + + var resourceLoader = ResourceLoaderInstance.ResourceLoader; + var dialog = new ContentDialog + { + XamlRoot = this.XamlRoot, + Title = resourceLoader.GetString("PowerDisplay_CustomMapping_Delete_Title"), + Content = resourceLoader.GetString("PowerDisplay_CustomMapping_Delete_Message"), + PrimaryButtonText = resourceLoader.GetString("Yes"), + CloseButtonText = resourceLoader.GetString("No"), + DefaultButton = ContentDialogButton.Close, + }; + + var result = await dialog.ShowAsync(); + + if (result == ContentDialogResult.Primary) + { + ViewModel.DeleteCustomVcpMapping(mapping); + } + } + // Flag to prevent reentrant handling during programmatic checkbox changes private bool _isRestoringColorTempCheckbox; diff --git a/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw b/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw index ff7e61cccd..a11cbd72bc 100644 --- a/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw +++ b/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw @@ -5995,6 +5995,69 @@ The break timer font matches the text font. Show or hide the identify monitors button in the Power Display flyout + + Custom VCP Name Mappings + + + Custom name mappings + + + Define custom display names for color temperature presets and input sources + + + Add custom mapping + + + Add mapping + + + Custom VCP Name Mapping + + + VCP Code + + + Color Temperature + + + Input Source + + + Custom Name + + + Enter custom name + + + Value + + + Custom value... + + + Enter custom value (hex) + + + e.g., 0x11 or 17 + + + Apply to all monitors + + + On + + + Off + + + Select monitor + + + Delete custom mapping? + + + This custom name mapping will be permanently removed. + Backup diff --git a/src/settings-ui/Settings.UI/ViewModels/PowerDisplayViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/PowerDisplayViewModel.cs index ce19e37467..6c96214d5b 100644 --- a/src/settings-ui/Settings.UI/ViewModels/PowerDisplayViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/PowerDisplayViewModel.cs @@ -36,6 +36,9 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels public PowerDisplayViewModel(SettingsUtils settingsUtils, ISettingsRepository settingsRepository, ISettingsRepository powerDisplaySettingsRepository, Func ipcMSGCallBackFunc) { + // Set up localized VCP code names for UI display + VcpNames.LocalizedCodeNameProvider = GetLocalizedVcpCodeName; + // To obtain the general settings configurations of PowerToys Settings. ArgumentNullException.ThrowIfNull(settingsRepository); @@ -56,9 +59,15 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels // set the callback functions value to handle outgoing IPC message. SendConfigMSG = ipcMSGCallBackFunc; + // Subscribe to collection changes for HasProfiles binding + _profiles.CollectionChanged += (s, e) => OnPropertyChanged(nameof(HasProfiles)); + // Load profiles LoadProfiles(); + // Load custom VCP mappings + LoadCustomVcpMappings(); + // Listen for monitor refresh events from PowerDisplay.exe NativeEventWaiter.WaitForEventLoop( Constants.RefreshPowerDisplayMonitorsEvent(), @@ -446,21 +455,28 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels // Profile-related fields private ObservableCollection _profiles = new ObservableCollection(); + // Custom VCP mapping fields + private ObservableCollection _customVcpMappings; + /// - /// Gets or sets collection of available profiles (for button display) + /// Gets collection of custom VCP value name mappings /// - public ObservableCollection Profiles - { - get => _profiles; - set - { - if (_profiles != value) - { - _profiles = value; - OnPropertyChanged(); - } - } - } + public ObservableCollection CustomVcpMappings => _customVcpMappings; + + /// + /// Gets whether there are any custom VCP mappings (for UI binding) + /// + public bool HasCustomVcpMappings => _customVcpMappings?.Count > 0; + + /// + /// Gets collection of available profiles (for button display) + /// + public ObservableCollection Profiles => _profiles; + + /// + /// Gets whether there are any profiles (for UI binding) + /// + public bool HasProfiles => _profiles?.Count > 0; public void RefreshEnabledState() { @@ -646,6 +662,109 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels } } + /// + /// Load custom VCP mappings from settings + /// + private void LoadCustomVcpMappings() + { + List mappings; + try + { + mappings = _settings.Properties.CustomVcpMappings ?? new List(); + Logger.LogInfo($"Loaded {mappings.Count} custom VCP mappings"); + } + catch (Exception ex) + { + Logger.LogError($"Failed to load custom VCP mappings: {ex.Message}"); + mappings = new List(); + } + + _customVcpMappings = new ObservableCollection(mappings); + _customVcpMappings.CollectionChanged += (s, e) => OnPropertyChanged(nameof(HasCustomVcpMappings)); + OnPropertyChanged(nameof(CustomVcpMappings)); + OnPropertyChanged(nameof(HasCustomVcpMappings)); + } + + /// + /// Add a new custom VCP mapping. + /// No duplicate checking - mappings are resolved by order (first match wins in VcpNames). + /// + public void AddCustomVcpMapping(CustomVcpValueMapping mapping) + { + if (mapping == null) + { + return; + } + + CustomVcpMappings.Add(mapping); + Logger.LogInfo($"Added custom VCP mapping: VCP=0x{mapping.VcpCode:X2}, Value=0x{mapping.Value:X2} -> {mapping.CustomName}"); + SaveCustomVcpMappings(); + } + + /// + /// Update an existing custom VCP mapping + /// + public void UpdateCustomVcpMapping(CustomVcpValueMapping oldMapping, CustomVcpValueMapping newMapping) + { + if (oldMapping == null || newMapping == null) + { + return; + } + + var index = CustomVcpMappings.IndexOf(oldMapping); + if (index >= 0) + { + CustomVcpMappings[index] = newMapping; + Logger.LogInfo($"Updated custom VCP mapping at index {index}"); + SaveCustomVcpMappings(); + } + } + + /// + /// Delete a custom VCP mapping + /// + public void DeleteCustomVcpMapping(CustomVcpValueMapping mapping) + { + if (mapping == null) + { + return; + } + + if (CustomVcpMappings.Remove(mapping)) + { + Logger.LogInfo($"Deleted custom VCP mapping: VCP=0x{mapping.VcpCode:X2}, Value=0x{mapping.Value:X2}"); + SaveCustomVcpMappings(); + } + } + + /// + /// Save custom VCP mappings to settings + /// + private void SaveCustomVcpMappings() + { + _settings.Properties.CustomVcpMappings = CustomVcpMappings.ToList(); + NotifySettingsChanged(); + + // Signal PowerDisplay to reload settings + SignalSettingsUpdated(); + } + + /// + /// Provides localized VCP code names for UI display. + /// Looks for resource string with pattern "PowerDisplay_VcpCode_Name_0xXX". + /// Returns null for unknown codes to use the default MCCS name. + /// +#nullable enable + private static string? GetLocalizedVcpCodeName(byte vcpCode) + { + var resourceKey = $"PowerDisplay_VcpCode_Name_0x{vcpCode:X2}"; + var localizedName = ResourceLoaderInstance.ResourceLoader.GetString(resourceKey); + + // ResourceLoader returns empty string if key not found + return string.IsNullOrEmpty(localizedName) ? null : localizedName; + } +#nullable restore + private void NotifySettingsChanged() { // Skip during initialization when SendConfigMSG is not yet set From bde2055f267d2143e2f6839fb16194d7e3b51c1d Mon Sep 17 00:00:00 2001 From: Shawn Yuan <128874481+shuaiyuanxx@users.noreply.github.com> Date: Thu, 5 Feb 2026 17:04:24 +0800 Subject: [PATCH 08/41] Fix pipeline build issue when using wasdk 2.0 exp (#45390) ## Summary of the Pull Request This pull request updates project configuration for two modules by changing how the Windows App SDK is included. Specifically, it switches both modules from using a self-contained Windows App SDK deployment to a framework-dependent deployment. This means the applications will now rely on the system-installed Windows App SDK rather than bundling it with the app. ## PR Checklist - [ ] Closes: #xxx - [x] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [x] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx ## Detailed Description of the Pull Request / Additional comments ## Validation Steps Performed --- .../MeasureToolCore/PowerToys.MeasureToolCore.vcxproj | 2 +- src/modules/MouseUtils/FindMyMouse/FindMyMouse.vcxproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/MeasureTool/MeasureToolCore/PowerToys.MeasureToolCore.vcxproj b/src/modules/MeasureTool/MeasureToolCore/PowerToys.MeasureToolCore.vcxproj index c71c81acec..5a589c673d 100644 --- a/src/modules/MeasureTool/MeasureToolCore/PowerToys.MeasureToolCore.vcxproj +++ b/src/modules/MeasureTool/MeasureToolCore/PowerToys.MeasureToolCore.vcxproj @@ -30,7 +30,7 @@ Windows Store 10.0 true - true + false true diff --git a/src/modules/MouseUtils/FindMyMouse/FindMyMouse.vcxproj b/src/modules/MouseUtils/FindMyMouse/FindMyMouse.vcxproj index 0d61ca8567..47867ebb2d 100644 --- a/src/modules/MouseUtils/FindMyMouse/FindMyMouse.vcxproj +++ b/src/modules/MouseUtils/FindMyMouse/FindMyMouse.vcxproj @@ -21,7 +21,7 @@ false false false - true + false false From 731532fdd87cafffc6159f4d226f23cf6d6af4c9 Mon Sep 17 00:00:00 2001 From: Mike Hall Date: Thu, 5 Feb 2026 10:37:10 +0000 Subject: [PATCH 09/41] Add option to disable CursorWrap when on a single monitor. (#45303) ## Summary of the Pull Request CursorWrap wraps on the outer edge of monitors, if a user is swapping between a laptop and docked laptop with external monitors the user might want to only enable wrapping when connected to external monitors, and disable when only on the laptop. ## PR Checklist - [ ] Closes: #45198 - [ ] Closes: #45154 - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx ## Detailed Description of the Pull Request / Additional comments Currently CursorWrap will wrap around the horizontal/vertical edges of monitors, if the user has more than one monitor the outer edges are used as wrap targets, if the user only has one monitor (perhaps a laptop) wrapping might be temporarily disabled until additional external monitors are added (such as being plugged into a dock or using a USB-C monitor). The new option will disable wrapping if only a single monitor is detected, monitor detection is dynamic. ## Validation Steps Performed Validated on a Surface Laptop 7 Pro (Intel) with a USB-C External Monitor. --------- Co-authored-by: Niels Laute --- .../MouseUtils/CursorWrap/CursorWrapCore.cpp | 16 +++++++++- .../MouseUtils/CursorWrap/CursorWrapCore.h | 4 ++- src/modules/MouseUtils/CursorWrap/dllmain.cpp | 20 +++++++++++- .../CursorWrapProperties.cs | 4 +++ .../Settings.UI.Library/CursorWrapSettings.cs | 7 ++++ .../SettingsXAML/Views/MouseUtilsPage.xaml | 3 ++ .../Settings.UI/Strings/en-us/Resources.resw | 3 ++ .../ViewModels/MouseUtilsViewModel.cs | 32 +++++++++++++++++++ 8 files changed, 86 insertions(+), 3 deletions(-) diff --git a/src/modules/MouseUtils/CursorWrap/CursorWrapCore.cpp b/src/modules/MouseUtils/CursorWrap/CursorWrapCore.cpp index bea59e6186..c1d4a9b36b 100644 --- a/src/modules/MouseUtils/CursorWrap/CursorWrapCore.cpp +++ b/src/modules/MouseUtils/CursorWrap/CursorWrapCore.cpp @@ -163,8 +163,22 @@ void CursorWrapCore::UpdateMonitorInfo() Logger::info(L"======= UPDATE MONITOR INFO END ======="); } -POINT CursorWrapCore::HandleMouseMove(const POINT& currentPos, bool disableWrapDuringDrag, int wrapMode) +POINT CursorWrapCore::HandleMouseMove(const POINT& currentPos, bool disableWrapDuringDrag, int wrapMode, bool disableOnSingleMonitor) { + // Check if wrapping should be disabled on single monitor + if (disableOnSingleMonitor && m_monitors.size() <= 1) + { +#ifdef _DEBUG + static bool loggedOnce = false; + if (!loggedOnce) + { + OutputDebugStringW(L"[CursorWrap] Single monitor detected - cursor wrapping disabled\n"); + loggedOnce = true; + } +#endif + return currentPos; + } + // Check if wrapping should be disabled during drag if (disableWrapDuringDrag && (GetAsyncKeyState(VK_LBUTTON) & 0x8000)) { diff --git a/src/modules/MouseUtils/CursorWrap/CursorWrapCore.h b/src/modules/MouseUtils/CursorWrap/CursorWrapCore.h index 6c19a26e39..d8472efd08 100644 --- a/src/modules/MouseUtils/CursorWrap/CursorWrapCore.h +++ b/src/modules/MouseUtils/CursorWrap/CursorWrapCore.h @@ -18,9 +18,11 @@ public: // Handle mouse move with wrap mode filtering // wrapMode: 0=Both, 1=VerticalOnly, 2=HorizontalOnly - POINT HandleMouseMove(const POINT& currentPos, bool disableWrapDuringDrag, int wrapMode); + // disableOnSingleMonitor: if true, cursor wrapping is disabled when only one monitor is connected + POINT HandleMouseMove(const POINT& currentPos, bool disableWrapDuringDrag, int wrapMode, bool disableOnSingleMonitor); const std::vector& GetMonitors() const { return m_monitors; } + size_t GetMonitorCount() const { return m_monitors.size(); } const MonitorTopology& GetTopology() const { return m_topology; } private: diff --git a/src/modules/MouseUtils/CursorWrap/dllmain.cpp b/src/modules/MouseUtils/CursorWrap/dllmain.cpp index 08c39bab60..add9fb7f92 100644 --- a/src/modules/MouseUtils/CursorWrap/dllmain.cpp +++ b/src/modules/MouseUtils/CursorWrap/dllmain.cpp @@ -54,6 +54,7 @@ namespace const wchar_t JSON_KEY_AUTO_ACTIVATE[] = L"auto_activate"; const wchar_t JSON_KEY_DISABLE_WRAP_DURING_DRAG[] = L"disable_wrap_during_drag"; const wchar_t JSON_KEY_WRAP_MODE[] = L"wrap_mode"; + const wchar_t JSON_KEY_DISABLE_ON_SINGLE_MONITOR[] = L"disable_cursor_wrap_on_single_monitor"; } // The PowerToy name that will be shown in the settings. @@ -80,6 +81,7 @@ private: bool m_enabled = false; bool m_autoActivate = false; bool m_disableWrapDuringDrag = true; // Default to true to prevent wrap during drag + bool m_disableOnSingleMonitor = false; // Default to false int m_wrapMode = 0; // 0=Both (default), 1=VerticalOnly, 2=HorizontalOnly // Mouse hook @@ -415,6 +417,21 @@ private: { Logger::warn("Failed to initialize CursorWrap wrap mode from settings. Will use default value (0=Both)"); } + + try + { + // Parse disable on single monitor + auto propertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES); + if (propertiesObject.HasKey(JSON_KEY_DISABLE_ON_SINGLE_MONITOR)) + { + auto disableOnSingleMonitorObject = propertiesObject.GetNamedObject(JSON_KEY_DISABLE_ON_SINGLE_MONITOR); + m_disableOnSingleMonitor = disableOnSingleMonitorObject.GetNamedBoolean(JSON_KEY_VALUE); + } + } + catch (...) + { + Logger::warn("Failed to initialize CursorWrap disable on single monitor from settings. Will use default value (false)"); + } } else { @@ -646,7 +663,8 @@ private: POINT newPos = g_cursorWrapInstance->m_core.HandleMouseMove( currentPos, g_cursorWrapInstance->m_disableWrapDuringDrag, - g_cursorWrapInstance->m_wrapMode); + g_cursorWrapInstance->m_wrapMode, + g_cursorWrapInstance->m_disableOnSingleMonitor); if (newPos.x != currentPos.x || newPos.y != currentPos.y) { diff --git a/src/settings-ui/Settings.UI.Library/CursorWrapProperties.cs b/src/settings-ui/Settings.UI.Library/CursorWrapProperties.cs index bffa75a3f3..228cf74998 100644 --- a/src/settings-ui/Settings.UI.Library/CursorWrapProperties.cs +++ b/src/settings-ui/Settings.UI.Library/CursorWrapProperties.cs @@ -25,12 +25,16 @@ namespace Microsoft.PowerToys.Settings.UI.Library [JsonPropertyName("wrap_mode")] public IntProperty WrapMode { get; set; } + [JsonPropertyName("disable_cursor_wrap_on_single_monitor")] + public BoolProperty DisableCursorWrapOnSingleMonitor { get; set; } + public CursorWrapProperties() { ActivationShortcut = DefaultActivationShortcut; AutoActivate = new BoolProperty(false); DisableWrapDuringDrag = new BoolProperty(true); WrapMode = new IntProperty(0); // 0=Both (default), 1=VerticalOnly, 2=HorizontalOnly + DisableCursorWrapOnSingleMonitor = new BoolProperty(false); } } } diff --git a/src/settings-ui/Settings.UI.Library/CursorWrapSettings.cs b/src/settings-ui/Settings.UI.Library/CursorWrapSettings.cs index 0ee6c4a523..fc918c37db 100644 --- a/src/settings-ui/Settings.UI.Library/CursorWrapSettings.cs +++ b/src/settings-ui/Settings.UI.Library/CursorWrapSettings.cs @@ -56,6 +56,13 @@ namespace Microsoft.PowerToys.Settings.UI.Library settingsUpgraded = true; } + // Add DisableCursorWrapOnSingleMonitor property if it doesn't exist (for users upgrading from older versions) + if (Properties.DisableCursorWrapOnSingleMonitor == null) + { + Properties.DisableCursorWrapOnSingleMonitor = new BoolProperty(false); // Default to false + settingsUpgraded = true; + } + return settingsUpgraded; } } diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Views/MouseUtilsPage.xaml b/src/settings-ui/Settings.UI/SettingsXAML/Views/MouseUtilsPage.xaml index 39c3800f93..1ded2db636 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/Views/MouseUtilsPage.xaml +++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/MouseUtilsPage.xaml @@ -54,6 +54,9 @@ + + + diff --git a/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw b/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw index a11cbd72bc..cd53ee4dec 100644 --- a/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw +++ b/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw @@ -2726,6 +2726,9 @@ From there, simply click on one of the supported files in the File Explorer and Disable wrapping while dragging + + Disable wrapping when using a single monitor + Auto-activate on startup diff --git a/src/settings-ui/Settings.UI/ViewModels/MouseUtilsViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/MouseUtilsViewModel.cs index 11045e0108..bd6a431a20 100644 --- a/src/settings-ui/Settings.UI/ViewModels/MouseUtilsViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/MouseUtilsViewModel.cs @@ -116,6 +116,9 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels // Null-safe access in case property wasn't upgraded yet - default to 0 (Both) _cursorWrapWrapMode = CursorWrapSettingsConfig.Properties.WrapMode?.Value ?? 0; + // Null-safe access in case property wasn't upgraded yet - default to false + _cursorWrapDisableOnSingleMonitor = CursorWrapSettingsConfig.Properties.DisableCursorWrapOnSingleMonitor?.Value ?? false; + int isEnabled = 0; Utilities.NativeMethods.SystemParametersInfo(Utilities.NativeMethods.SPI_GETCLIENTAREAANIMATION, 0, ref isEnabled, 0); @@ -1114,6 +1117,34 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels } } + public bool CursorWrapDisableOnSingleMonitor + { + get + { + return _cursorWrapDisableOnSingleMonitor; + } + + set + { + if (value != _cursorWrapDisableOnSingleMonitor) + { + _cursorWrapDisableOnSingleMonitor = value; + + // Ensure the property exists before setting value + if (CursorWrapSettingsConfig.Properties.DisableCursorWrapOnSingleMonitor == null) + { + CursorWrapSettingsConfig.Properties.DisableCursorWrapOnSingleMonitor = new BoolProperty(value); + } + else + { + CursorWrapSettingsConfig.Properties.DisableCursorWrapOnSingleMonitor.Value = value; + } + + NotifyCursorWrapPropertyChanged(); + } + } + } + public void NotifyCursorWrapPropertyChanged([CallerMemberName] string propertyName = null) { OnPropertyChanged(propertyName); @@ -1186,5 +1217,6 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels private bool _cursorWrapAutoActivate; private bool _cursorWrapDisableWrapDuringDrag; // Will be initialized in constructor from settings private int _cursorWrapWrapMode; // 0=Both, 1=VerticalOnly, 2=HorizontalOnly + private bool _cursorWrapDisableOnSingleMonitor; // Disable cursor wrap when only one monitor is connected } } From 2be4c4eb465490160516cb65dd1a0334c82c8ecd Mon Sep 17 00:00:00 2001 From: Thanh Nguyen <74597207+ThanhNguyxn@users.noreply.github.com> Date: Thu, 5 Feb 2026 06:58:49 -0500 Subject: [PATCH 10/41] Fix CursorWrap "Automatically activate on utility startup" setting not persisting (#45210) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary of the Pull Request Fixes #45185 - CursorWrap "Automatically activate on utility startup" setting cannot be disabled, and prevents spurious activation on startup. ## PR Checklist - [x] Closes: #45185 - [x] **Communication:** Issue was reported by community; fix follows established patterns from MousePointerCrosshairs - [x] **Tests:** Manual validation performed by contributor (video available) - [x] **Localization:** No new user-facing strings added - [ ] **Dev docs:** N/A - bug fix only - [ ] **New binaries:** N/A - no new binaries - [ ] **Documentation updated:** N/A - bug fix only ## Detailed Description of the Pull Request / Additional comments ### Problem Users reported that disabling the "Automatically activate on utility startup" setting for CursorWrap does not work - the mouse hook always starts automatically regardless of the setting value. ### Root Causes 1. **`dllmain.cpp` `enable()` method**: `StartMouseHook()` was always called unconditionally, ignoring `m_autoActivate`. 2. **`MouseUtilsViewModel.cs` `IsCursorWrapEnabled` setter**: enabling CursorWrap forced `AutoActivate = true`, overriding the user's preference. 3. **Startup edge case**: the trigger event could remain signaled from a previous session, immediately toggling CursorWrap on startup even when AutoActivate is off. ### Solution 1. **`src/modules/MouseUtils/CursorWrap/dllmain.cpp`**: only start the mouse hook if `m_autoActivate` is true. 2. **`src/settings-ui/Settings.UI/ViewModels/MouseUtilsViewModel.cs`**: remove the line that forced `AutoActivate = true` when enabling CursorWrap. 3. **`src/modules/MouseUtils/CursorWrap/dllmain.cpp`**: reset the trigger event on enable to avoid immediate activation on startup. ### Pattern Reference This fix follows the same pattern used by **MousePointerCrosshairs** module which has a similar `AutoActivate` setting that works correctly. ## Validation Steps Performed ### Build - `tools\build\build.ps1 -Platform x64 -Configuration Debug` ### Manual validation (contributor) #### Test Case 1: AutoActivate = false (should NOT auto-start mouse hook) 1. Open PowerToys Settings → Mouse Utilities → Cursor Wrap 2. Enable Cursor Wrap 3. **Disable** "Automatically activate on utility startup" 4. Close PowerToys completely (right-click tray icon → Exit) 5. Restart PowerToys 6. **Expected Result**: CursorWrap module is loaded but mouse hook is NOT active - cursor does NOT wrap at screen edges 7. Press activation hotkey (default: `Win+Alt+U`) 8. **Expected Result**: Mouse hook activates, cursor now wraps at screen edges 9. **Actual Result**: ✅ Works as expected #### Test Case 2: AutoActivate = true (should auto-start mouse hook) 1. Open PowerToys Settings → Mouse Utilities → Cursor Wrap 2. Enable Cursor Wrap 3. **Enable** "Automatically activate on utility startup" 4. Close PowerToys completely 5. Restart PowerToys 6. **Expected Result**: Mouse hook is immediately active, cursor wraps at screen edges without pressing hotkey 7. **Actual Result**: ✅ Works as expected #### Test Case 3: Setting persistence after restart 1. Set AutoActivate = false, restart PowerToys 2. Open Settings and verify AutoActivate is still false 3. Set AutoActivate = true, restart PowerToys 4. Open Settings and verify AutoActivate is still true 5. **Actual Result**: ✅ Setting persists correctly #### Test Case 4: Hotkey toggle works correctly 1. With AutoActivate = false, restart PowerToys 2. Press hotkey → cursor should start wrapping 3. Press hotkey again → cursor should stop wrapping 4. **Actual Result**: ✅ Hotkey toggle works correctly --- **Note**: Video demonstration available from contributor. --- src/modules/MouseUtils/CursorWrap/dllmain.cpp | 16 ++++++++++++++-- .../ViewModels/MouseUtilsViewModel.cs | 7 ------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/modules/MouseUtils/CursorWrap/dllmain.cpp b/src/modules/MouseUtils/CursorWrap/dllmain.cpp index add9fb7f92..b172f1c8b6 100644 --- a/src/modules/MouseUtils/CursorWrap/dllmain.cpp +++ b/src/modules/MouseUtils/CursorWrap/dllmain.cpp @@ -198,6 +198,10 @@ public: // Start listening for external trigger event so we can invoke the same logic as the activation hotkey. m_triggerEventHandle = CreateEventW(nullptr, false, false, CommonSharedConstants::CURSOR_WRAP_TRIGGER_EVENT); m_terminateEventHandle = CreateEventW(nullptr, false, false, nullptr); + if (m_triggerEventHandle) + { + ResetEvent(m_triggerEventHandle); + } if (m_triggerEventHandle && m_terminateEventHandle) { m_listening = true; @@ -212,8 +216,16 @@ public: // Create message window for display change notifications RegisterForDisplayChanges(); - StartMouseHook(); - Logger::info("CursorWrap enabled - mouse hook started"); + // Only start the mouse hook automatically if auto-activate is enabled + if (m_autoActivate) + { + StartMouseHook(); + Logger::info("CursorWrap enabled - mouse hook started (auto-activate on)"); + } + else + { + Logger::info("CursorWrap enabled - waiting for activation hotkey (auto-activate off)"); + } while (m_listening) { diff --git a/src/settings-ui/Settings.UI/ViewModels/MouseUtilsViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/MouseUtilsViewModel.cs index bd6a431a20..678c090397 100644 --- a/src/settings-ui/Settings.UI/ViewModels/MouseUtilsViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/MouseUtilsViewModel.cs @@ -1006,13 +1006,6 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels GeneralSettingsConfig.Enabled.CursorWrap = value; OnPropertyChanged(nameof(IsCursorWrapEnabled)); - // Auto-enable the AutoActivate setting when CursorWrap is enabled - // This ensures cursor wrapping is active immediately after enabling - if (value && !_cursorWrapAutoActivate) - { - CursorWrapAutoActivate = true; - } - OutGoingGeneralSettings outgoing = new OutGoingGeneralSettings(GeneralSettingsConfig); SendConfigMSG(outgoing.ToString()); From 753689309e93b828d3f12a7cf8afd444fce604e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Pol=C3=A1=C5=A1ek?= Date: Thu, 5 Feb 2026 23:47:45 +0100 Subject: [PATCH 11/41] CmdPal: Fix alias UI clearing when toggling Direct/Indirect combobox (#45381) ## Summary of the Pull Request This PR fixes the settings UI for the top-level command alias. ## PR Checklist https://github.com/user-attachments/assets/0d1e1392-0293-4482-97cb-e8e8c0ed0dd5 - [x] Closes: #41301 - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx ## Detailed Description of the Pull Request / Additional comments ## Validation Steps Performed --- .../cmdpal/Microsoft.CmdPal.UI.ViewModels/AliasManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/AliasManager.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/AliasManager.cs index 72a295c83f..4c997266c6 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/AliasManager.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/AliasManager.cs @@ -107,7 +107,7 @@ public partial class AliasManager : ObservableObject } // Look for the alias belonging to another command, and remove it - if (newAlias is not null && kv.Value.Alias == newAlias.Alias) + if (newAlias is not null && kv.Value.Alias == newAlias.Alias && kv.Value.CommandId != commandId) { toRemove.Add(kv.Value); From ab47d5446357bf1c3d84d4bed9238c572b0dabc0 Mon Sep 17 00:00:00 2001 From: Shawn Yuan <128874481+shuaiyuanxx@users.noreply.github.com> Date: Fri, 6 Feb 2026 16:58:29 +0800 Subject: [PATCH 12/41] Fix WinuiEx crash issue (#45443) ## Summary of the Pull Request Fixes a crash related to `IsShownInSwitchers` when explorer.exe is not running. The property has been removed from XAML and is now set in the C# backend with added exception handling to improve stability. No changes were made for projects where the property is set to true, as they are not affected. ## PR Checklist - [ ] Closes: #xxx - [x] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [x] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx ## Detailed Description of the Pull Request / Additional comments ## Validation Steps Performed --------- Co-authored-by: vanzue --- .../MeasureToolUI/MeasureToolXAML/MainWindow.xaml | 1 - .../MeasureToolXAML/MainWindow.xaml.cs | 13 ++++++++++++- .../QuickAccess.UI/QuickAccessXAML/MainWindow.xaml | 1 - .../QuickAccessXAML/MainWindow.xaml.cs | 12 +++++++++++- 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/modules/MeasureTool/MeasureToolUI/MeasureToolXAML/MainWindow.xaml b/src/modules/MeasureTool/MeasureToolUI/MeasureToolXAML/MainWindow.xaml index 4a4f3dd8b0..5ae5e6e4c1 100644 --- a/src/modules/MeasureTool/MeasureToolUI/MeasureToolXAML/MainWindow.xaml +++ b/src/modules/MeasureTool/MeasureToolUI/MeasureToolXAML/MainWindow.xaml @@ -10,7 +10,6 @@ IsMaximizable="False" IsMinimizable="False" IsResizable="False" - IsShownInSwitchers="False" IsTitleBarVisible="False" mc:Ignorable="d"> diff --git a/src/modules/MeasureTool/MeasureToolUI/MeasureToolXAML/MainWindow.xaml.cs b/src/modules/MeasureTool/MeasureToolUI/MeasureToolXAML/MainWindow.xaml.cs index 4f807655da..afc59eb8d3 100644 --- a/src/modules/MeasureTool/MeasureToolUI/MeasureToolXAML/MainWindow.xaml.cs +++ b/src/modules/MeasureTool/MeasureToolUI/MeasureToolXAML/MainWindow.xaml.cs @@ -52,12 +52,23 @@ namespace MeasureToolUI var presenter = _appWindow.Presenter as OverlappedPresenter; presenter.IsAlwaysOnTop = true; this.SetIsAlwaysOnTop(true); - this.SetIsShownInSwitchers(false); this.SetIsResizable(false); this.SetIsMinimizable(false); this.SetIsMaximizable(false); IsTitleBarVisible = false; + try + { + this.SetIsShownInSwitchers(false); + } + catch (NotImplementedException) + { + // WinUI will throw if explorer is not running, safely ignore + } + catch (Exception) + { + } + // Remove the caption style from the window style. Windows App SDK 1.6 added it, which made the title bar and borders appear for Measure Tool. This code removes it. var windowStyle = GetWindowLong(hwnd, GWL_STYLE); windowStyle = windowStyle & (~WS_CAPTION); diff --git a/src/settings-ui/QuickAccess.UI/QuickAccessXAML/MainWindow.xaml b/src/settings-ui/QuickAccess.UI/QuickAccessXAML/MainWindow.xaml index 92e0a65f8b..90db2afca7 100644 --- a/src/settings-ui/QuickAccess.UI/QuickAccessXAML/MainWindow.xaml +++ b/src/settings-ui/QuickAccess.UI/QuickAccessXAML/MainWindow.xaml @@ -15,7 +15,6 @@ IsMaximizable="False" IsMinimizable="False" IsResizable="False" - IsShownInSwitchers="False" IsTitleBarVisible="False" mc:Ignorable="d"> diff --git a/src/settings-ui/QuickAccess.UI/QuickAccessXAML/MainWindow.xaml.cs b/src/settings-ui/QuickAccess.UI/QuickAccessXAML/MainWindow.xaml.cs index dab53d9432..00db257bae 100644 --- a/src/settings-ui/QuickAccess.UI/QuickAccessXAML/MainWindow.xaml.cs +++ b/src/settings-ui/QuickAccess.UI/QuickAccessXAML/MainWindow.xaml.cs @@ -305,7 +305,17 @@ public sealed partial class MainWindow : WindowEx, IDisposable return; } - _appWindow.IsShownInSwitchers = false; + try + { + _appWindow.IsShownInSwitchers = false; + } + catch (NotImplementedException) + { + // WinUI Will throw if explorer is not running, safely ignore + } + catch (Exception) + { + } } private bool CloakWindow() From 1fc0dfc28de6d59759f9428215280aacc2728d55 Mon Sep 17 00:00:00 2001 From: Shawn Yuan <128874481+shuaiyuanxx@users.noreply.github.com> Date: Fri, 6 Feb 2026 22:50:23 +0800 Subject: [PATCH 13/41] [PowerDisplay] Prevent from WinuiEx crash (#45449) ## Summary of the Pull Request This pull request updates how the `IsShownInSwitchers` property is set for the PowerDisplay windows, moving from XAML-based configuration to explicit runtime setting in the code-behind. This improves compatibility and error handling, especially in scenarios where the property may not be supported or could throw exceptions. ## PR Checklist - [ ] Closes: #xxx - [x] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [x] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx ## Detailed Description of the Pull Request / Additional comments ## Validation Steps Performed --- .../PowerDisplayXAML/IdentifyWindow.xaml | 1 - .../PowerDisplayXAML/IdentifyWindow.xaml.cs | 12 ++++++++++++ .../PowerDisplay/PowerDisplayXAML/MainWindow.xaml | 1 - .../PowerDisplay/PowerDisplayXAML/MainWindow.xaml.cs | 4 ++++ 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/modules/powerdisplay/PowerDisplay/PowerDisplayXAML/IdentifyWindow.xaml b/src/modules/powerdisplay/PowerDisplay/PowerDisplayXAML/IdentifyWindow.xaml index 7d41fdc12d..fccc9ce0f6 100644 --- a/src/modules/powerdisplay/PowerDisplay/PowerDisplayXAML/IdentifyWindow.xaml +++ b/src/modules/powerdisplay/PowerDisplay/PowerDisplayXAML/IdentifyWindow.xaml @@ -8,7 +8,6 @@ IsMaximizable="False" IsMinimizable="False" IsResizable="False" - IsShownInSwitchers="False" IsTitleBarVisible="False" mc:Ignorable="d"> diff --git a/src/modules/powerdisplay/PowerDisplay/PowerDisplayXAML/IdentifyWindow.xaml.cs b/src/modules/powerdisplay/PowerDisplay/PowerDisplayXAML/IdentifyWindow.xaml.cs index 1668aef820..63ec38f150 100644 --- a/src/modules/powerdisplay/PowerDisplay/PowerDisplayXAML/IdentifyWindow.xaml.cs +++ b/src/modules/powerdisplay/PowerDisplay/PowerDisplayXAML/IdentifyWindow.xaml.cs @@ -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; using System.Threading.Tasks; using Microsoft.UI.Windowing; using Windows.Graphics; @@ -24,6 +25,17 @@ namespace PowerDisplay.PowerDisplayXAML { InitializeComponent(); NumberText.Text = displayText; + try + { + this.SetIsShownInSwitchers(false); + } + catch (NotImplementedException) + { + // WinUI will throw if explorer is not running, safely ignore + } + catch (Exception) + { + } // Configure window style ConfigureWindow(); diff --git a/src/modules/powerdisplay/PowerDisplay/PowerDisplayXAML/MainWindow.xaml b/src/modules/powerdisplay/PowerDisplay/PowerDisplayXAML/MainWindow.xaml index 7c43bc105f..137894fd3f 100644 --- a/src/modules/powerdisplay/PowerDisplay/PowerDisplayXAML/MainWindow.xaml +++ b/src/modules/powerdisplay/PowerDisplay/PowerDisplayXAML/MainWindow.xaml @@ -15,7 +15,6 @@ IsMaximizable="False" IsMinimizable="False" IsResizable="False" - IsShownInSwitchers="False" IsTitleBarVisible="False"> diff --git a/src/modules/powerdisplay/PowerDisplay/PowerDisplayXAML/MainWindow.xaml.cs b/src/modules/powerdisplay/PowerDisplay/PowerDisplayXAML/MainWindow.xaml.cs index 62fa666d6e..67b8605442 100644 --- a/src/modules/powerdisplay/PowerDisplay/PowerDisplayXAML/MainWindow.xaml.cs +++ b/src/modules/powerdisplay/PowerDisplay/PowerDisplayXAML/MainWindow.xaml.cs @@ -71,6 +71,10 @@ namespace PowerDisplay _hotkeyService.Initialize(this); Logger.LogTrace("MainWindow constructor: HotkeyService initialized"); + Logger.LogTrace("MainWindow constructor: Setting IsShownInSwitchers property"); + this.SetIsShownInSwitchers(false); + Logger.LogTrace("MainWindow constructor: Set IsShownInSwitchers property successfully"); + // Note: ViewModel handles all async initialization internally. // We listen to InitializationCompleted event to know when data is ready. // No duplicate initialization here - single responsibility in ViewModel. From 914f2281c34bf9be84a16623724229f086347e13 Mon Sep 17 00:00:00 2001 From: Gordon Lam <73506701+yeelam-gordon@users.noreply.github.com> Date: Fri, 6 Feb 2026 08:25:10 -0800 Subject: [PATCH 14/41] feat(advancedpaste): add auto-copy selection for custom action hotkeys (#44767) ## Summary of the Pull Request Boosting productivity #2x. Customer mentioned with Custom Action (Shortcut trigger) "We should not need to do two keyboard actions to finish this awesome AI data transformation, instead, just single shortcut should do copy + advanced paste." This pull request introduces a new feature to the Advanced Paste module that allows users to automatically copy the current selection when triggering a custom action hotkey. The changes include backend logic for sending the copy command, updates to configuration and settings management, and UI additions to expose this option to users. ### Feature Addition: Auto-Copy Selection for Custom Action Hotkeys * Added a new boolean setting, `AutoCopySelectionForCustomActionHotkey`, to both the backend (`dllmain.cpp`, `AdvancedPasteProperties.cs`) and the settings UI, allowing users to enable or disable automatic copying of the current selection when a custom action hotkey is pressed. [[1]](diffhunk://#diff-3866eb99ffe4453e0d03248e11d3560f7f15f4b982e323519d45e282f0fe898dR63) [[2]](diffhunk://#diff-3866eb99ffe4453e0d03248e11d3560f7f15f4b982e323519d45e282f0fe898dR106) [[3]](diffhunk://#diff-7f5d34989db7593fa4969a79cf97f709d210c157343d474650d5df4b9bf18114R31) [[4]](diffhunk://#diff-7f5d34989db7593fa4969a79cf97f709d210c157343d474650d5df4b9bf18114R83-R85) [[5]](diffhunk://#diff-09c575763019d9108b85a2e7b87a3bb6ed23a835970bf511b1a6bbe9a9f53835R174-R178) [[6]](diffhunk://#diff-0f8bf95882c074d687f6c4f2673cf9c8b1a904b117c11f75d0c892d809f3cd42R558-R570) ### Backend Logic and Integration * Implemented the `send_copy_selection()` and `try_send_copy_message()` methods in `dllmain.cpp` to send a WM_COPY message or simulate a Ctrl+C keystroke, ensuring the selected content is copied before executing the custom action. * Integrated the new setting into the hotkey handler logic so that when a custom action hotkey is pressed and the setting is enabled, the copy operation is triggered before running the custom action. ### Configuration and State Management * Updated serialization/deserialization and property synchronization logic to support the new setting, ensuring its value is correctly loaded, saved, and reflected in the UI and runtime behavior. [[1]](diffhunk://#diff-3866eb99ffe4453e0d03248e11d3560f7f15f4b982e323519d45e282f0fe898dR353-R357) [[2]](diffhunk://#diff-0f8bf95882c074d687f6c4f2673cf9c8b1a904b117c11f75d0c892d809f3cd42R1235-R1240) ### UI and Localization * Added a new checkbox to the Advanced Paste settings page in XAML to allow users to toggle the auto-copy feature. * Provided localized strings for the new setting, including header and description, in the resource file for user clarity. ### Refactoring for Hotkey Logic * Refactored hotkey handling code to correctly calculate indices for additional and custom actions, supporting the new auto-copy logic and improving code clarity. [[1]](diffhunk://#diff-3866eb99ffe4453e0d03248e11d3560f7f15f4b982e323519d45e282f0fe898dR918-R936) [[2]](diffhunk://#diff-3866eb99ffe4453e0d03248e11d3560f7f15f4b982e323519d45e282f0fe898dL871) [[3]](diffhunk://#diff-3866eb99ffe4453e0d03248e11d3560f7f15f4b982e323519d45e282f0fe898dL884) --- .../AdvancedPasteModuleInterface/dllmain.cpp | 157 +++++++++++++++++- .../AdvancedPasteProperties.cs | 4 + .../SettingsXAML/Views/AdvancedPastePage.xaml | 3 + .../Settings.UI/Strings/en-us/Resources.resw | 8 + .../ViewModels/AdvancedPasteViewModel.cs | 19 +++ 5 files changed, 189 insertions(+), 2 deletions(-) diff --git a/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/dllmain.cpp b/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/dllmain.cpp index 6cf2e8d9a9..17205687a5 100644 --- a/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/dllmain.cpp +++ b/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/dllmain.cpp @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -60,6 +61,7 @@ namespace const wchar_t JSON_KEY_IS_AI_ENABLED[] = L"IsAIEnabled"; const wchar_t JSON_KEY_IS_OPEN_AI_ENABLED[] = L"IsOpenAIEnabled"; const wchar_t JSON_KEY_SHOW_CUSTOM_PREVIEW[] = L"ShowCustomPreview"; + const wchar_t JSON_KEY_AUTO_COPY_SELECTION_CUSTOM_ACTION[] = L"AutoCopySelectionForCustomActionHotkey"; const wchar_t JSON_KEY_PASTE_AI_CONFIGURATION[] = L"paste-ai-configuration"; const wchar_t JSON_KEY_PROVIDERS[] = L"providers"; const wchar_t JSON_KEY_SERVICE_TYPE[] = L"service-type"; @@ -102,6 +104,7 @@ private: bool m_is_ai_enabled = false; bool m_is_advanced_ai_enabled = false; bool m_preview_custom_format_output = true; + bool m_auto_copy_selection_custom_action = false; // Event listening for external triggers (e.g., from CmdPal extension) EventWaiter m_triggerEventWaiter; @@ -348,6 +351,11 @@ private: { m_preview_custom_format_output = propertiesObject.GetNamedObject(JSON_KEY_SHOW_CUSTOM_PREVIEW).GetNamedBoolean(JSON_KEY_VALUE); } + + if (propertiesObject.HasKey(JSON_KEY_AUTO_COPY_SELECTION_CUSTOM_ACTION)) + { + m_auto_copy_selection_custom_action = propertiesObject.GetNamedObject(JSON_KEY_AUTO_COPY_SELECTION_CUSTOM_ACTION).GetNamedBoolean(JSON_KEY_VALUE, false); + } } if (old_data_migrated) @@ -481,6 +489,131 @@ private: } } + bool try_send_copy_message() + { + GUITHREADINFO gui_info = {}; + gui_info.cbSize = sizeof(GUITHREADINFO); + + if (!GetGUIThreadInfo(0, &gui_info)) + { + return false; + } + + HWND target = gui_info.hwndFocus ? gui_info.hwndFocus : gui_info.hwndActive; + if (!target) + { + return false; + } + + DWORD_PTR result = 0; + return SendMessageTimeout(target, + WM_COPY, + 0, + 0, + SMTO_ABORTIFHUNG | SMTO_BLOCK, + 50, + &result) != 0; + } + + bool send_copy_selection() + { + constexpr int copy_attempts = 2; + constexpr auto copy_retry_delay = std::chrono::milliseconds(100); + constexpr int clipboard_poll_attempts = 5; + constexpr auto clipboard_poll_delay = std::chrono::milliseconds(30); + + bool copy_succeeded = false; + for (int attempt = 0; attempt < copy_attempts; ++attempt) + { + const auto initial_sequence = GetClipboardSequenceNumber(); + copy_succeeded = try_send_copy_message(); + + if (!copy_succeeded) + { + std::vector inputs; + + // send Ctrl+C (key downs and key ups) + { + INPUT input_event = {}; + input_event.type = INPUT_KEYBOARD; + input_event.ki.wVk = VK_CONTROL; + input_event.ki.dwExtraInfo = CENTRALIZED_KEYBOARD_HOOK_DONT_TRIGGER_FLAG; + inputs.push_back(input_event); + } + + { + INPUT input_event = {}; + input_event.type = INPUT_KEYBOARD; + input_event.ki.wVk = 0x43; // C + // Avoid triggering detection by the centralized keyboard hook. + input_event.ki.dwExtraInfo = CENTRALIZED_KEYBOARD_HOOK_DONT_TRIGGER_FLAG; + inputs.push_back(input_event); + } + + { + INPUT input_event = {}; + input_event.type = INPUT_KEYBOARD; + input_event.ki.wVk = 0x43; // C + input_event.ki.dwFlags = KEYEVENTF_KEYUP; + // Avoid triggering detection by the centralized keyboard hook. + input_event.ki.dwExtraInfo = CENTRALIZED_KEYBOARD_HOOK_DONT_TRIGGER_FLAG; + inputs.push_back(input_event); + } + + { + INPUT input_event = {}; + input_event.type = INPUT_KEYBOARD; + input_event.ki.wVk = VK_CONTROL; + input_event.ki.dwFlags = KEYEVENTF_KEYUP; + input_event.ki.dwExtraInfo = CENTRALIZED_KEYBOARD_HOOK_DONT_TRIGGER_FLAG; + inputs.push_back(input_event); + } + + auto uSent = SendInput(static_cast(inputs.size()), inputs.data(), sizeof(INPUT)); + if (uSent != inputs.size()) + { + DWORD errorCode = GetLastError(); + auto errorMessage = get_last_error_message(errorCode); + Logger::error(L"SendInput failed for Ctrl+C. Expected to send {} inputs and sent only {}. {}", inputs.size(), uSent, errorMessage.has_value() ? errorMessage.value() : L""); + Trace::AdvancedPaste_Error(errorCode, errorMessage.has_value() ? errorMessage.value() : L"", L"input.SendInput"); + } + else + { + copy_succeeded = true; + } + } + + if (copy_succeeded) + { + bool sequence_changed = false; + for (int poll_attempt = 0; poll_attempt < clipboard_poll_attempts; ++poll_attempt) + { + if (GetClipboardSequenceNumber() != initial_sequence) + { + sequence_changed = true; + break; + } + + std::this_thread::sleep_for(clipboard_poll_delay); + } + + copy_succeeded = sequence_changed; + } + + if (copy_succeeded) + { + break; + } + + if (attempt + 1 < copy_attempts) + { + std::this_thread::sleep_for(copy_retry_delay); + } + } + + return copy_succeeded; + } + void try_to_paste_as_plain_text() { std::wstring clipboard_text; @@ -826,6 +959,28 @@ public: Logger::trace(L"AdvancedPaste hotkey pressed"); if (m_enabled) { + size_t additional_action_index = 0; + size_t custom_action_index = 0; + bool is_custom_action_hotkey = false; + + if (hotkeyId >= NUM_DEFAULT_HOTKEYS) + { + additional_action_index = hotkeyId - NUM_DEFAULT_HOTKEYS; + if (additional_action_index >= m_additional_actions.size()) + { + custom_action_index = additional_action_index - m_additional_actions.size(); + is_custom_action_hotkey = custom_action_index < m_custom_actions.size(); + } + } + + if (is_custom_action_hotkey && m_auto_copy_selection_custom_action) + { + if (!send_copy_selection()) + { + return false; + } + } + m_process_manager.start(); // hotkeyId in same order as set by get_hotkeys @@ -868,7 +1023,6 @@ public: } - const auto additional_action_index = hotkeyId - NUM_DEFAULT_HOTKEYS; if (additional_action_index < m_additional_actions.size()) { const auto& id = m_additional_actions.at(additional_action_index).id; @@ -881,7 +1035,6 @@ public: return true; } - const auto custom_action_index = additional_action_index - m_additional_actions.size(); if (custom_action_index < m_custom_actions.size()) { const auto id = m_custom_actions.at(custom_action_index).id; diff --git a/src/settings-ui/Settings.UI.Library/AdvancedPasteProperties.cs b/src/settings-ui/Settings.UI.Library/AdvancedPasteProperties.cs index ecfa0ce636..683ef06bf9 100644 --- a/src/settings-ui/Settings.UI.Library/AdvancedPasteProperties.cs +++ b/src/settings-ui/Settings.UI.Library/AdvancedPasteProperties.cs @@ -28,6 +28,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library ShowCustomPreview = true; CloseAfterLosingFocus = false; EnableClipboardPreview = true; + AutoCopySelectionForCustomActionHotkey = false; PasteAIConfiguration = new(); } @@ -79,6 +80,9 @@ namespace Microsoft.PowerToys.Settings.UI.Library [JsonConverter(typeof(BoolPropertyJsonConverter))] public bool EnableClipboardPreview { get; set; } + [JsonConverter(typeof(BoolPropertyJsonConverter))] + public bool AutoCopySelectionForCustomActionHotkey { get; set; } + [JsonPropertyName("advanced-paste-ui-hotkey")] public HotkeySettings AdvancedPasteUIShortcut { get; set; } diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Views/AdvancedPastePage.xaml b/src/settings-ui/Settings.UI/SettingsXAML/Views/AdvancedPastePage.xaml index ae4bbeb438..bfcaf63db8 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/Views/AdvancedPastePage.xaml +++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/AdvancedPastePage.xaml @@ -171,6 +171,9 @@ + + + Show clipboard preview Enables display of clipboard contents preview in the Advanced Paste window + + Auto-copy selection for custom action hotkeys + Advanced Paste is a product name + + + Attempts to copy the current selection before running a custom action shortcut + Advanced Paste is a product name + The Command Not Found module is disabled by your organization. "Command Not Found" is a product name diff --git a/src/settings-ui/Settings.UI/ViewModels/AdvancedPasteViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/AdvancedPasteViewModel.cs index deb47719e1..ad75c72d10 100644 --- a/src/settings-ui/Settings.UI/ViewModels/AdvancedPasteViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/AdvancedPasteViewModel.cs @@ -569,6 +569,19 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels } } + public bool AutoCopySelectionForCustomActionHotkey + { + get => _advancedPasteSettings.Properties.AutoCopySelectionForCustomActionHotkey; + set + { + if (value != _advancedPasteSettings.Properties.AutoCopySelectionForCustomActionHotkey) + { + _advancedPasteSettings.Properties.AutoCopySelectionForCustomActionHotkey = value; + NotifySettingsChanged(); + } + } + } + public bool IsConflictingCopyShortcut => _customActions.Select(customAction => customAction.Shortcut) .Concat([PasteAsPlainTextShortcut, AdvancedPasteUIShortcut, PasteAsMarkdownShortcut, PasteAsJsonShortcut]) @@ -1233,6 +1246,12 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels OnPropertyChanged(nameof(EnableClipboardPreview)); } + if (target.AutoCopySelectionForCustomActionHotkey != source.AutoCopySelectionForCustomActionHotkey) + { + target.AutoCopySelectionForCustomActionHotkey = source.AutoCopySelectionForCustomActionHotkey; + OnPropertyChanged(nameof(AutoCopySelectionForCustomActionHotkey)); + } + var incomingConfig = source.PasteAIConfiguration ?? new PasteAIConfiguration(); if (ShouldReplacePasteAIConfiguration(target.PasteAIConfiguration, incomingConfig)) { From 740dbf5699e5654a3d5f433c595b4c076d08c1bc Mon Sep 17 00:00:00 2001 From: Gordon Lam <73506701+yeelam-gordon@users.noreply.github.com> Date: Fri, 6 Feb 2026 16:12:44 -0800 Subject: [PATCH 15/41] build(common): update project references to use $(RepoRoot) for paths (#44639) ## Summary of the Pull Request Update project references across multiple projects to utilize `$(RepoRoot)` for paths, ensuring consistency and improving maintainability. ## PR Checklist - [ ] Closes: N/A - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [x] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx ## Detailed Description of the Pull Request / Additional comments This change affects the following projects: - `src/common/ManagedCsWin32/ManagedCsWin32.csproj` - `src/common/Common.Search/Common.Search.csproj` - `src/common/AllExperiments/AllExperiments.csproj` - `src/modules/peek/Peek.Common/Peek.Common.csproj` - `src/common/UITestAutomation/UITestAutomation.csproj` - `src/common/GPOWrapperProjection/GPOWrapperProjection.csproj` - `src/modules/powerrename/PowerRenameUITest/PowerRename.UITests.csproj` - `src/common/LanguageModelProvider/LanguageModelProvider.csproj` - `src/modules/Hosts/Hosts.Tests/HostsEditor.UnitTests.csproj` - `tools/StylesReportTool/StylesReportTool.vcxproj` - `src/common/interop/interop-tests/Common.Interop.UnitTests.csproj` - `tools/MonitorReportTool/MonitorReportTool.vcxproj` - `src/common/ManagedTelemetry/Telemetry/ManagedTelemetry.csproj` - `src/modules/peek/Peek.FilePreviewer/Peek.FilePreviewer.csproj` - `src/settings-ui/Settings.UI.Controls/Settings.UI.Controls.csproj` - `src/common/Themes/Themes.vcxproj` - `src/common/COMUtils/COMUtils.vcxproj` - `src/modules/cmdpal/Tests/Microsoft.CmdPal.UITests/Microsoft.CmdPal.UITests.csproj` - `src/modules/imageresizer/tests/ImageResizer.UnitTests.csproj` The changes were validated by running existing unit tests, which all passed successfully. ## Validation Steps Performed Executed all unit tests related to the modified projects, confirming that all tests passed without issues. ``` --- Directory.Build.props | 11 +- src/ActionRunner/actionRunner.vcxproj | 20 +- src/Update/PowerToys.Update.vcxproj | 20 +- .../AllExperiments/AllExperiments.csproj | 4 +- src/common/COMUtils/COMUtils.vcxproj | 6 +- .../CalculatorEngineCommon.vcxproj | 14 +- src/common/Common.Search/Common.Search.csproj | 4 +- src/common/Common.UI/Common.UI.csproj | 6 +- src/common/Display/Display.vcxproj | 2 +- .../FilePreviewCommon.csproj | 8 +- src/common/GPOWrapper/GPOWrapper.vcxproj | 10 +- .../GPOWrapperProjection.csproj | 2 +- .../LanguageModelProvider.csproj | 2 +- src/common/ManagedCommon/ManagedCommon.csproj | 6 +- .../ManagedCsWin32/ManagedCsWin32.csproj | 2 +- .../Telemetry/ManagedTelemetry.csproj | 4 +- .../PowerToys.ModuleContracts.csproj | 4 +- src/common/SettingsAPI/SettingsAPI.vcxproj | 18 +- .../Telemetry/EtwTrace/EtwTrace.vcxproj | 14 +- src/common/Themes/Themes.vcxproj | 12 +- .../UITestAutomation/UITestAutomation.csproj | 4 +- .../UnitTests-CommonLib.vcxproj | 10 +- src/common/interop/HotkeyManager.cpp | 2 +- src/common/interop/PowerToys.Interop.vcxproj | 20 +- .../Common.Interop.UnitTests.csproj | 4 +- src/common/logger/logger.vcxproj | 15 +- .../BackgroundActivator.vcxproj | 16 +- .../BackgroundActivatorDLL.vcxproj | 12 +- .../notifications/notifications.vcxproj | 17 +- src/common/version/version.vcxproj | 2 +- ...rToys.Settings.DSC.Schema.Generator.csproj | 6 +- .../PowerToys.DSC.UnitTests.csproj | 6 +- src/dsc/v3/PowerToys.DSC/PowerToys.DSC.csproj | 8 +- src/logging/logging.vcxproj | 190 +++++++++--------- .../AdvancedPaste.FuzzTests.csproj | 6 +- .../AdvancedPaste.UnitTests.csproj | 4 +- .../AdvancedPaste/AdvancedPaste.csproj | 8 +- .../AdvancedPasteModuleInterface.vcxproj | 20 +- .../AdvancedPaste-UITests.csproj | 6 +- .../CropAndLock/CropAndLock.vcxproj | 32 +-- .../CropAndLockModuleInterface.vcxproj | 30 +-- .../EnvironmentVariables.csproj | 8 +- ...nvironmentVariablesModuleInterface.vcxproj | 24 +-- .../EnvironmentVariablesUILib.csproj | 4 +- .../tests/FileLocksmithCLIUnitTests.vcxproj | 22 +- .../FileLocksmithContextMenu.vcxproj | 26 +-- .../FileLocksmithExt/FileLocksmithExt.vcxproj | 24 +-- .../FileLocksmithLib/FileLocksmithLib.vcxproj | 10 +- .../FileLocksmithLibInterop.vcxproj | 14 +- .../FileLocksmithUI/FileLocksmithUI.csproj | 8 +- .../HostsEditor.FuzzTests.csproj | 8 +- .../Hosts.Tests/HostsEditor.UnitTests.csproj | 4 +- .../Hosts.UITests/HostsEditor.UITests.csproj | 4 +- src/modules/Hosts/Hosts/Hosts.csproj | 8 +- .../HostsModuleInterface.vcxproj | 20 +- .../Hosts/HostsUILib/HostsUILib.csproj | 6 +- .../LightSwitchModuleInterface.vcxproj | 22 +- .../LightSwitchService.vcxproj | 31 +-- .../LightSwitch.UITests.csproj | 4 +- .../PowerToys.MeasureToolCore.vcxproj | 18 +- .../MeasureToolModuleInterface.vcxproj | 20 +- .../MeasureToolUI/MeasureToolUI.csproj | 8 +- .../ScreenRuler.UITests.csproj | 4 +- .../MouseUtils/CursorWrap/CursorWrap.vcxproj | 20 +- .../FindMyMouse/FindMyMouse.vcxproj | 10 +- .../MouseHighlighter/MouseHighlighter.vcxproj | 20 +- .../MouseJump.Common.UnitTests.csproj | 6 +- .../MouseJump.Common/MouseJump.Common.csproj | 6 +- .../MouseUtils/MouseJump/MouseJump.vcxproj | 20 +- .../MouseUtils/MouseJumpUI/MouseJumpUI.csproj | 8 +- .../MousePointerCrosshairs.vcxproj | 20 +- .../MouseUtils.UITests.csproj | 4 +- .../Helper/MouseWithoutBordersHelper.csproj | 8 +- .../App/MouseWithoutBorders.csproj | 8 +- .../Service/MouseWithoutBordersService.csproj | 8 +- ...MouseWithoutBordersModuleInterface.vcxproj | 24 +-- .../MouseWithoutBorders.UnitTests.csproj | 6 +- .../NewPlus.ShellExtension.win10.vcxproj | 30 +-- .../NewShellExtensionContextMenu.vcxproj | 32 +-- .../PowerOCR-UITests/PowerOCR.UITests.csproj | 4 +- src/modules/PowerOCR/PowerOCR/PowerOCR.csproj | 8 +- .../PowerOCRModuleInterface.vcxproj | 22 +- .../ShortcutGuide/ShortcutGuide.vcxproj | 28 +-- .../ShortcutGuideModuleInterface.vcxproj | 22 +- .../Workspaces.ModuleServices.csproj | 6 +- .../WorkspacesCsharpLibrary.csproj | 8 +- .../WorkspacesEditor/WorkspacesEditor.csproj | 8 +- .../Workspaces.Editor.UITests.csproj | 4 +- .../WorkspacesLauncherUI.csproj | 8 +- .../WorkspacesLibUnitTests.vcxproj | 18 +- .../WorkspacesLib/WorkspacesLib.vcxproj | 24 +-- .../WorkspacesModuleInterface.vcxproj | 20 +- .../ZoomItModuleInterface.vcxproj | 22 +- .../ZoomItSettingsInterop.vcxproj | 22 +- .../AlwaysOnTop/AlwaysOnTop.vcxproj | 35 ++-- .../AlwaysOnTopModuleInterface.vcxproj | 26 +-- .../Awake.ModuleServices.csproj | 4 +- src/modules/awake/Awake/Awake.csproj | 8 +- .../AwakeModuleInterface.vcxproj | 24 +-- .../CmdNotFoundModuleInterface.vcxproj | 20 +- .../CmdPalKeyboardService.vcxproj | 14 +- .../CmdPalModuleInterface.vcxproj | 20 +- .../Microsoft.CmdPal.UI.ViewModels.csproj | 6 +- .../Microsoft.CmdPal.UI.csproj | 8 +- ...Microsoft.CmdPal.Ext.Apps.UnitTests.csproj | 2 +- ...soft.CmdPal.Ext.Bookmarks.UnitTests.csproj | 2 +- ...Microsoft.CmdPal.Ext.Calc.UnitTests.csproj | 2 +- ...dPal.Ext.ClipboardHistory.UnitTests.csproj | 2 +- ...osoft.CmdPal.Ext.Registry.UnitTests.csproj | 2 +- ....CmdPal.Ext.RemoteDesktop.UnitTests.csproj | 2 +- ...icrosoft.CmdPal.Ext.Shell.UnitTests.csproj | 2 +- ...crosoft.CmdPal.Ext.System.UnitTests.csproj | 2 +- ...osoft.CmdPal.Ext.TimeDate.UnitTests.csproj | 2 +- .../Microsoft.CmdPal.Ext.UnitTestBase.csproj | 4 +- ...soft.CmdPal.Ext.WebSearch.UnitTests.csproj | 2 +- ...t.CmdPal.Ext.WindowWalker.UnitTests.csproj | 2 +- ...soft.CmdPal.UI.ViewModels.UnitTests.csproj | 2 +- .../Microsoft.CmdPal.UITests.csproj | 4 +- .../Microsoft.CmdPal.Ext.Apps.csproj | 6 +- .../Microsoft.CmdPal.Ext.Bookmarks.csproj | 6 +- .../Microsoft.CmdPal.Ext.Calc.csproj | 6 +- ...crosoft.CmdPal.Ext.ClipboardHistory.csproj | 6 +- .../Microsoft.CmdPal.Ext.Indexer.csproj | 6 +- .../Microsoft.CmdPal.Ext.PowerToys.csproj | 8 +- .../Microsoft.CmdPal.Ext.Registry.csproj | 6 +- .../Microsoft.CmdPal.Ext.RemoteDesktop.csproj | 6 +- .../Microsoft.CmdPal.Ext.System.csproj | 6 +- .../Microsoft.CmdPal.Ext.TimeDate.csproj | 6 +- .../Microsoft.CmdPal.Ext.WebSearch.csproj | 6 +- .../Microsoft.CmdPal.Ext.WinGet.csproj | 2 +- .../Microsoft.CmdPal.Ext.WindowWalker.csproj | 6 +- ...icrosoft.CmdPal.Ext.WindowsServices.csproj | 6 +- ...icrosoft.CmdPal.Ext.WindowsSettings.csproj | 6 +- ...icrosoft.CmdPal.Ext.WindowsTerminal.csproj | 6 +- .../ProcessMonitorExtension.csproj | 4 +- .../SamplePagesExtension.csproj | 6 +- ...t.CommandPalette.Extensions.Toolkit.csproj | 6 +- ...icrosoft.CommandPalette.Extensions.vcxproj | 1 - .../ColorPicker.ModuleServices.csproj | 4 +- .../ColorPicker/ColorPicker.vcxproj | 22 +- .../ColorPickerUI.UnitTests.csproj | 6 +- .../ColorPickerUI/ColorPickerUI.csproj | 8 +- .../UITest-ColorPicker.csproj | 6 +- .../FancyZones.FuzzTests.csproj | 6 +- .../FancyZones.UITests.csproj | 6 +- .../FancyZonesCLI/FancyZonesCLI.csproj | 6 +- .../FancyZonesEditor.UITests.csproj | 6 +- .../FancyZonesEditor.UnitTests.csproj | 4 +- .../FancyZonesEditorCommon.csproj | 6 +- .../FancyZonesLib/FancyZonesLib.vcxproj | 28 +-- .../FancyZonesModuleInterface.vcxproj | 26 +-- .../UnitTests/UnitTests.vcxproj | 24 +-- .../FancyZonesEditor/FancyZonesEditor.csproj | 8 +- .../ImageResizerCLI/ImageResizerCLI.csproj | 8 +- .../ImageResizerContextMenu.vcxproj | 30 +-- .../ImageResizerLib/ImageResizerLib.vcxproj | 16 +- .../imageresizer/dll/ImageResizerExt.vcxproj | 28 +-- .../tests/ImageResizer.UnitTests.csproj | 4 +- .../imageresizer/ui/ImageResizerUI.csproj | 8 +- .../keyboardmanager/Directory.Build.targets | 2 +- ...eyboardManagerEditorLibraryWrapper.vcxproj | 28 +-- .../KeyboardManagerEditorTest.vcxproj | 14 +- .../KeyboardManagerEditorUI.csproj | 8 +- .../KeyboardManagerEngine.vcxproj | 22 +- .../KeyboardManagerEngineLibrary.vcxproj | 20 +- .../KeyboardManagerEngineTest.vcxproj | 14 +- .../common/KeyboardManagerCommon.vcxproj | 24 +-- .../dll/KeyboardManager.vcxproj | 22 +- .../Microsoft.Launcher.vcxproj | 26 +-- ...s.Run.Plugin.UnitConverter.UnitTest.csproj | 2 +- ....PowerToys.Run.Plugin.UnitConverter.csproj | 6 +- ...werToys.Run.Plugin.VSCodeWorkspaces.csproj | 6 +- ...Run.Plugin.ValueGenerator.UnitTests.csproj | 4 +- ...PowerToys.Run.Plugin.ValueGenerator.csproj | 6 +- ...nity.PowerToys.Run.Plugin.WebSearch.csproj | 6 +- .../Microsoft.Plugin.Folder.UnitTests.csproj | 2 +- .../Microsoft.Plugin.Folder.csproj | 6 +- .../Microsoft.Plugin.Indexer.csproj | 6 +- .../Microsoft.Plugin.Program.UnitTests.csproj | 4 +- .../Microsoft.Plugin.Program.csproj | 6 +- .../Microsoft.Plugin.Shell.csproj | 6 +- .../Microsoft.Plugin.Uri.UnitTests.csproj | 4 +- .../Microsoft.Plugin.Uri.csproj | 6 +- ...osoft.Plugin.WindowWalker.UnitTests.csproj | 4 +- .../Microsoft.Plugin.WindowWalker.csproj | 6 +- ...Toys.Run.Plugin.Calculator.UnitTest.csproj | 2 +- ...oft.PowerToys.Run.Plugin.Calculator.csproj | 6 +- ...rosoft.PowerToys.Run.Plugin.History.csproj | 6 +- ...rosoft.PowerToys.Run.Plugin.OneNote.csproj | 6 +- ...soft.PowerToys.Run.Plugin.PowerToys.csproj | 6 +- ...rToys.Run.Plugin.Registry.UnitTests.csproj | 4 +- ...osoft.PowerToys.Run.Plugin.Registry.csproj | 6 +- ...rosoft.PowerToys.Run.Plugin.Service.csproj | 4 +- ...werToys.Run.Plugin.System.UnitTests.csproj | 4 +- ...crosoft.PowerToys.Run.Plugin.System.csproj | 6 +- ...rToys.Run.Plugin.TimeDate.UnitTests.csproj | 4 +- ...osoft.PowerToys.Run.Plugin.TimeDate.csproj | 6 +- ...owerToys.Run.Plugin.WindowsSettings.csproj | 6 +- ...ft.Plugin.WindowsTerminal.UnitTests.csproj | 4 +- ...owerToys.Run.Plugin.WindowsTerminal.csproj | 6 +- .../PowerLauncher.Telemetry.csproj | 4 +- .../PowerLauncher/PowerLauncher.csproj | 8 +- .../Wox.Infrastructure.csproj | 6 +- .../launcher/Wox.Plugin/Wox.Plugin.csproj | 6 +- src/modules/launcher/Wox.Test/Wox.Test.csproj | 6 +- .../peek/Peek.Common/Peek.Common.csproj | 4 +- .../Peek.FilePreviewer.csproj | 4 +- src/modules/peek/Peek.UI/Peek.UI.csproj | 10 +- .../peek/Peek.UITests/Peek.UITests.csproj | 6 +- src/modules/peek/peek/peek.vcxproj | 24 +-- .../PowerAccent.Core/PowerAccent.Core.csproj | 8 +- .../PowerAccent.UI/PowerAccent.UI.csproj | 8 +- .../PowerAccentKeyboardService.vcxproj | 18 +- .../PowerAccentModuleInterface.vcxproj | 24 +-- .../PowerRename.FuzzingTest.vcxproj | 26 +-- .../PowerRenameContextMenu.vcxproj | 28 +-- .../PowerRenameUILib/PowerRenameUI.vcxproj | 14 +- .../PowerRename.UITests.csproj | 4 +- .../powerrename/dll/PowerRenameExt.vcxproj | 36 ++-- .../powerrename/lib/PowerRenameLib.vcxproj | 30 +-- .../testapp/PowerRenameTest.vcxproj | 28 +-- .../unittests/PowerRenameLibUnitTests.vcxproj | 26 +-- .../BgcodePreviewHandler.csproj | 8 +- .../BgcodePreviewHandlerCpp.vcxproj | 20 +- .../BgcodeThumbnailProvider.csproj | 8 +- .../BgcodeThumbnailProviderCpp.vcxproj | 22 +- .../GcodePreviewHandler.csproj | 8 +- .../GcodePreviewHandlerCpp.vcxproj | 20 +- .../GcodeThumbnailProvider.csproj | 8 +- .../GcodeThumbnailProviderCpp.vcxproj | 22 +- .../MarkdownPreviewHandler.csproj | 10 +- .../MarkdownPreviewHandlerCpp.vcxproj | 22 +- .../MonacoPreviewHandler.csproj | 6 +- .../MonacoPreviewHandlerCpp.vcxproj | 20 +- .../PdfPreviewHandler.csproj | 8 +- .../PdfPreviewHandlerCpp.vcxproj | 18 +- .../PdfThumbnailProvider.csproj | 6 +- .../PdfThumbnailProviderCpp.vcxproj | 22 +- .../QoiPreviewHandler.csproj | 8 +- .../QoiPreviewHandlerCpp.vcxproj | 20 +- .../QoiThumbnailProvider.csproj | 8 +- .../QoiThumbnailProviderCpp.vcxproj | 22 +- .../StlThumbnailProvider.csproj | 8 +- .../StlThumbnailProviderCpp.vcxproj | 22 +- .../SvgPreviewHandler.csproj | 6 +- .../SvgPreviewHandlerCpp.vcxproj | 20 +- .../SvgThumbnailProvider.csproj | 6 +- .../SvgThumbnailProviderCpp.vcxproj | 22 +- ...view.BgcodePreviewHandler.UnitTests.csproj | 4 +- ...w.BgcodeThumbnailProvider.UnitTests.csproj | 4 +- ...eview.GcodePreviewHandler.UnitTests.csproj | 4 +- ...ew.GcodeThumbnailProvider.UnitTests.csproj | 4 +- ...ew.MarkdownPreviewHandler.UnitTests.csproj | 4 +- ...Preview.PdfPreviewHandler.UnitTests.csproj | 4 +- ...view.PdfThumbnailProvider.UnitTests.csproj | 4 +- ...view.PreviewHandlerCommon.UnitTests.csproj | 4 +- ...Preview.QoiPreviewHandler.UnitTests.csproj | 4 +- ...view.QoiThumbnailProvider.UnitTests.csproj | 4 +- ...view.StlThumbnailProvider.UnitTests.csproj | 4 +- ...Preview.SvgPreviewHandler.UnitTests.csproj | 4 +- ...view.SvgThumbnailProvider.UnitTests.csproj | 4 +- .../powerpreview/powerpreview.vcxproj | 32 +-- .../RegistryPreview.FuzzTests.csproj | 6 +- .../RegistryPreview/RegistryPreview.csproj | 8 +- .../RegistryPreviewExt.vcxproj | 26 +-- .../RegistryPreviewUILib.csproj | 6 +- src/runner/runner.vcxproj | 6 +- .../PowerToys.QuickAccess.csproj | 8 +- .../Settings.UI.Controls.csproj | 4 +- .../Settings.UI.Library.csproj | 6 +- .../Settings.UI.UnitTests.csproj | 6 +- .../Settings.UI.XamlIndexBuilder.csproj | 4 +- .../Settings.UI/PowerToys.Settings.csproj | 8 +- .../UITest-Settings/UITest-Settings.csproj | 6 +- .../BugReportTool/BugReportTool.vcxproj | 10 +- .../MonitorReportTool.vcxproj | 2 +- .../StylesReportTool/StylesReportTool.vcxproj | 2 +- tools/module_loader/ModuleLoader.vcxproj | 8 +- .../ModuleTemplate/ModuleTemplate.vcxproj | 2 +- .../ModuleTemplateCompileTest.vcxproj | 6 +- 280 files changed, 1576 insertions(+), 1572 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 99379ecefc..e9127613df 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,5 +1,8 @@ - + + $(MSBuildThisFileDirectory) + + Copyright (C) Microsoft Corporation. All rights reserved. Copyright (C) Microsoft Corporation. All rights reserved. @@ -61,7 +64,7 @@ <_PropertySheetDisplayName>PowerToys.Root.Props - $(MsbuildThisFileDirectory)\Cpp.Build.props + $(RepoRoot)Cpp.Build.props @@ -70,8 +73,8 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + all diff --git a/src/ActionRunner/actionRunner.vcxproj b/src/ActionRunner/actionRunner.vcxproj index dc98b28a06..737e5f2e2e 100644 --- a/src/ActionRunner/actionRunner.vcxproj +++ b/src/ActionRunner/actionRunner.vcxproj @@ -1,8 +1,9 @@ - + + - + 16.0 @@ -10,11 +11,10 @@ actionRunner PowerToys.ActionRunner - - + Application @@ -59,17 +59,17 @@ - + - - + + 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}. - - - + + + \ No newline at end of file diff --git a/src/Update/PowerToys.Update.vcxproj b/src/Update/PowerToys.Update.vcxproj index f60273324c..68418fa703 100644 --- a/src/Update/PowerToys.Update.vcxproj +++ b/src/Update/PowerToys.Update.vcxproj @@ -1,8 +1,9 @@ - + + - + 16.0 @@ -10,11 +11,10 @@ Update PowerToys.Update - - + Application @@ -65,17 +65,17 @@ - + - - + + 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}. - - - + + + \ No newline at end of file diff --git a/src/common/AllExperiments/AllExperiments.csproj b/src/common/AllExperiments/AllExperiments.csproj index 2da48432c1..2ecd131532 100644 --- a/src/common/AllExperiments/AllExperiments.csproj +++ b/src/common/AllExperiments/AllExperiments.csproj @@ -1,6 +1,6 @@ - + - + enable diff --git a/src/common/COMUtils/COMUtils.vcxproj b/src/common/COMUtils/COMUtils.vcxproj index 42c3e7802b..43a9e9f8d0 100644 --- a/src/common/COMUtils/COMUtils.vcxproj +++ b/src/common/COMUtils/COMUtils.vcxproj @@ -21,7 +21,7 @@ NotUsing - ..\..\..\;%(AdditionalIncludeDirectories) + $(RepoRoot)src\;%(AdditionalIncludeDirectories) _LIB;%(PreprocessorDefinitions) @@ -36,12 +36,12 @@ - + 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}. - + \ No newline at end of file diff --git a/src/common/CalculatorEngineCommon/CalculatorEngineCommon.vcxproj b/src/common/CalculatorEngineCommon/CalculatorEngineCommon.vcxproj index bce77c8ee1..91db92845f 100644 --- a/src/common/CalculatorEngineCommon/CalculatorEngineCommon.vcxproj +++ b/src/common/CalculatorEngineCommon/CalculatorEngineCommon.vcxproj @@ -1,6 +1,7 @@ - + + true true @@ -37,7 +38,6 @@ <_NoWinAPIFamilyApp>true - DynamicLibrary @@ -66,7 +66,7 @@ CalculatorEngineCommon - ..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ @@ -138,16 +138,16 @@ - + - + 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}. - - + + - + enable diff --git a/src/common/Common.UI/Common.UI.csproj b/src/common/Common.UI/Common.UI.csproj index 19fe2f1ee4..671e03f7ec 100644 --- a/src/common/Common.UI/Common.UI.csproj +++ b/src/common/Common.UI/Common.UI.csproj @@ -1,7 +1,7 @@ - + - - + + true diff --git a/src/common/Display/Display.vcxproj b/src/common/Display/Display.vcxproj index c5802f0ad8..cd1314f2df 100644 --- a/src/common/Display/Display.vcxproj +++ b/src/common/Display/Display.vcxproj @@ -25,7 +25,7 @@ NotUsing - ..\..\..\;..\..\common;.\;%(AdditionalIncludeDirectories) + $(RepoRoot)src\;..\..\common;.\;%(AdditionalIncludeDirectories) _LIB;%(PreprocessorDefinitions) diff --git a/src/common/FilePreviewCommon/FilePreviewCommon.csproj b/src/common/FilePreviewCommon/FilePreviewCommon.csproj index 560fbf3287..b968ba5ab4 100644 --- a/src/common/FilePreviewCommon/FilePreviewCommon.csproj +++ b/src/common/FilePreviewCommon/FilePreviewCommon.csproj @@ -1,8 +1,8 @@ - + - - - + + + PowerToys FilePreviewCommon diff --git a/src/common/GPOWrapper/GPOWrapper.vcxproj b/src/common/GPOWrapper/GPOWrapper.vcxproj index 4ebc0f0cc9..17e50e3fe2 100644 --- a/src/common/GPOWrapper/GPOWrapper.vcxproj +++ b/src/common/GPOWrapper/GPOWrapper.vcxproj @@ -1,6 +1,7 @@ - + + true true @@ -16,7 +17,6 @@ Windows Store 10.0 - DynamicLibrary @@ -116,13 +116,13 @@ - + 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}. - - + + \ No newline at end of file diff --git a/src/common/GPOWrapperProjection/GPOWrapperProjection.csproj b/src/common/GPOWrapperProjection/GPOWrapperProjection.csproj index 4afd5d9393..a3f43f48fb 100644 --- a/src/common/GPOWrapperProjection/GPOWrapperProjection.csproj +++ b/src/common/GPOWrapperProjection/GPOWrapperProjection.csproj @@ -1,6 +1,6 @@ - + enable diff --git a/src/common/LanguageModelProvider/LanguageModelProvider.csproj b/src/common/LanguageModelProvider/LanguageModelProvider.csproj index 4dba9247a3..8d9d6754aa 100644 --- a/src/common/LanguageModelProvider/LanguageModelProvider.csproj +++ b/src/common/LanguageModelProvider/LanguageModelProvider.csproj @@ -1,6 +1,6 @@ - + enable diff --git a/src/common/ManagedCommon/ManagedCommon.csproj b/src/common/ManagedCommon/ManagedCommon.csproj index bd74253073..83ff7e058d 100644 --- a/src/common/ManagedCommon/ManagedCommon.csproj +++ b/src/common/ManagedCommon/ManagedCommon.csproj @@ -1,7 +1,7 @@ - + - - + + PowerToys ManagedCommon diff --git a/src/common/ManagedCsWin32/ManagedCsWin32.csproj b/src/common/ManagedCsWin32/ManagedCsWin32.csproj index a80c111ad0..65b06d5f9c 100644 --- a/src/common/ManagedCsWin32/ManagedCsWin32.csproj +++ b/src/common/ManagedCsWin32/ManagedCsWin32.csproj @@ -1,6 +1,6 @@  - + PowerToys ManagedCsWin32 diff --git a/src/common/ManagedTelemetry/Telemetry/ManagedTelemetry.csproj b/src/common/ManagedTelemetry/Telemetry/ManagedTelemetry.csproj index 3929c60618..c73bd6ca6f 100644 --- a/src/common/ManagedTelemetry/Telemetry/ManagedTelemetry.csproj +++ b/src/common/ManagedTelemetry/Telemetry/ManagedTelemetry.csproj @@ -1,6 +1,6 @@ - + - + PowerToys Telemetry diff --git a/src/common/PowerToys.ModuleContracts/PowerToys.ModuleContracts.csproj b/src/common/PowerToys.ModuleContracts/PowerToys.ModuleContracts.csproj index aa80bb05fb..eec8c621b2 100644 --- a/src/common/PowerToys.ModuleContracts/PowerToys.ModuleContracts.csproj +++ b/src/common/PowerToys.ModuleContracts/PowerToys.ModuleContracts.csproj @@ -1,7 +1,7 @@ - - + + enable diff --git a/src/common/SettingsAPI/SettingsAPI.vcxproj b/src/common/SettingsAPI/SettingsAPI.vcxproj index 0355836a00..432129d3c0 100644 --- a/src/common/SettingsAPI/SettingsAPI.vcxproj +++ b/src/common/SettingsAPI/SettingsAPI.vcxproj @@ -1,6 +1,7 @@ - + + 16.0 @@ -9,7 +10,6 @@ SettingsAPI SettingsAPI - StaticLibrary @@ -22,7 +22,7 @@ - ..\;..\..\;..\..\..\;%(AdditionalIncludeDirectories) + ..\;..\..\;$(RepoRoot)src\;%(AdditionalIncludeDirectories) _LIB;%(PreprocessorDefinitions) @@ -52,17 +52,17 @@ - + - - + + 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}. - - - + + + \ No newline at end of file diff --git a/src/common/Telemetry/EtwTrace/EtwTrace.vcxproj b/src/common/Telemetry/EtwTrace/EtwTrace.vcxproj index b213541eda..11d114e986 100644 --- a/src/common/Telemetry/EtwTrace/EtwTrace.vcxproj +++ b/src/common/Telemetry/EtwTrace/EtwTrace.vcxproj @@ -1,14 +1,14 @@ - + + 17.0 Win32Proj {8f021b46-362b-485c-bfba-ccf83e820cbd} EtwTrace - StaticLibrary @@ -37,15 +37,15 @@ - - + + 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}. - - - + + + \ No newline at end of file diff --git a/src/common/Themes/Themes.vcxproj b/src/common/Themes/Themes.vcxproj index be37d7d15c..d939b4118c 100644 --- a/src/common/Themes/Themes.vcxproj +++ b/src/common/Themes/Themes.vcxproj @@ -1,6 +1,7 @@ - + + 16.0 {98537082-0FDB-40DE-ABD8-0DC5A4269BAB} @@ -8,7 +9,6 @@ Themes Themes - StaticLibrary @@ -24,7 +24,7 @@ - ..\..\..\;%(AdditionalIncludeDirectories) + $(RepoRoot)src\;%(AdditionalIncludeDirectories) _LIB;%(PreprocessorDefinitions) NotUsing @@ -46,13 +46,13 @@ - + 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}. - - + + \ No newline at end of file diff --git a/src/common/UITestAutomation/UITestAutomation.csproj b/src/common/UITestAutomation/UITestAutomation.csproj index 549b8a430b..0b40b9fcd3 100644 --- a/src/common/UITestAutomation/UITestAutomation.csproj +++ b/src/common/UITestAutomation/UITestAutomation.csproj @@ -1,6 +1,6 @@ - + - + Library diff --git a/src/common/UnitTests-CommonLib/UnitTests-CommonLib.vcxproj b/src/common/UnitTests-CommonLib/UnitTests-CommonLib.vcxproj index e0842faf83..9556bbf43d 100644 --- a/src/common/UnitTests-CommonLib/UnitTests-CommonLib.vcxproj +++ b/src/common/UnitTests-CommonLib/UnitTests-CommonLib.vcxproj @@ -1,6 +1,7 @@ - + + 16.0 {1A066C63-64B3-45F8-92FE-664E1CCE8077} @@ -9,7 +10,6 @@ NativeUnitTestProject Common.Lib.UnitTests - DynamicLibrary false @@ -58,13 +58,13 @@ - + 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}. - - + + \ No newline at end of file diff --git a/src/common/interop/HotkeyManager.cpp b/src/common/interop/HotkeyManager.cpp index adcbb9ada0..a9a6a19e6a 100644 --- a/src/common/interop/HotkeyManager.cpp +++ b/src/common/interop/HotkeyManager.cpp @@ -14,7 +14,7 @@ namespace winrt::PowerToys::Interop::implementation } // When all Shortcut keys are pressed, fire the HotkeyCallback event. - void HotkeyManager::KeyboardEventProc(KeyboardEvent ev) + void HotkeyManager::KeyboardEventProc(KeyboardEvent /*ev*/) { // pressedKeys always stores the latest keyboard state auto pressedKeysHandle = GetHotkeyHandle(pressedKeys); diff --git a/src/common/interop/PowerToys.Interop.vcxproj b/src/common/interop/PowerToys.Interop.vcxproj index a531a65d9f..d4b73762b0 100644 --- a/src/common/interop/PowerToys.Interop.vcxproj +++ b/src/common/interop/PowerToys.Interop.vcxproj @@ -1,6 +1,7 @@ - + - + + PowerToys.Interop @@ -38,7 +39,6 @@ Windows Store 10.0 - DynamicLibrary @@ -56,7 +56,7 @@ PowerToys.Interop - ..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ true @@ -80,7 +80,7 @@ $(IntDir)pch.pch _WINRT_DLL;WINRT_LEAN_AND_MEAN;PowerToysInterop;%(PreprocessorDefinitions) - $(SolutionDir)src\common\interop;../../;../;%(AdditionalIncludeDirectories) + $(RepoRoot)src\common\interop;../../;../;%(AdditionalIncludeDirectories) $(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories) false %(AdditionalOptions) /bigobj /Zc:twoPhase- @@ -172,15 +172,15 @@ - - + + 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}. - - - + + + \ No newline at end of file diff --git a/src/common/interop/interop-tests/Common.Interop.UnitTests.csproj b/src/common/interop/interop-tests/Common.Interop.UnitTests.csproj index 9370dae75a..f68411165b 100644 --- a/src/common/interop/interop-tests/Common.Interop.UnitTests.csproj +++ b/src/common/interop/interop-tests/Common.Interop.UnitTests.csproj @@ -1,6 +1,6 @@ - + - + false diff --git a/src/common/logger/logger.vcxproj b/src/common/logger/logger.vcxproj index 157b3d1abc..88296868b7 100644 --- a/src/common/logger/logger.vcxproj +++ b/src/common/logger/logger.vcxproj @@ -1,6 +1,7 @@ - + + Debug @@ -33,14 +34,12 @@ {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} logger - StaticLibrary - - ..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ - + @@ -83,13 +82,13 @@ - + 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}. - - + + \ No newline at end of file diff --git a/src/common/notifications/BackgroundActivator/BackgroundActivator.vcxproj b/src/common/notifications/BackgroundActivator/BackgroundActivator.vcxproj index a201dc0fa5..41fd325563 100644 --- a/src/common/notifications/BackgroundActivator/BackgroundActivator.vcxproj +++ b/src/common/notifications/BackgroundActivator/BackgroundActivator.vcxproj @@ -1,6 +1,7 @@ - + + true true @@ -15,7 +16,6 @@ Windows Store 10.0 - StaticLibrary @@ -44,7 +44,8 @@ - notifications + + BackgroundActivator @@ -60,7 +61,8 @@ $(IntDir)pch.pch Level4 - %(AdditionalOptions) /bigobj + + %(AdditionalOptions) /bigobj /FS _WINRT_DLL;WIN32_LEAN_AND_MEAN;WINRT_LEAN_AND_MEAN;%(PreprocessorDefinitions) $(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories) @@ -96,13 +98,13 @@ - + 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}. - - + + \ No newline at end of file diff --git a/src/common/notifications/BackgroundActivatorDLL/BackgroundActivatorDLL.vcxproj b/src/common/notifications/BackgroundActivatorDLL/BackgroundActivatorDLL.vcxproj index c0b0cae81b..96adff13d8 100644 --- a/src/common/notifications/BackgroundActivatorDLL/BackgroundActivatorDLL.vcxproj +++ b/src/common/notifications/BackgroundActivatorDLL/BackgroundActivatorDLL.vcxproj @@ -1,13 +1,13 @@ - + + 16.0 {031AC72E-FA28-4AB7-B690-6F7B9C28AA73} Win32Proj BackgroundActivatorDLL - DynamicLibrary @@ -64,10 +64,10 @@ - + - + {cc6e41ac-8174-4e8a-8d22-85dd7f4851df} @@ -81,7 +81,7 @@ 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}. - - + + \ No newline at end of file diff --git a/src/common/notifications/notifications.vcxproj b/src/common/notifications/notifications.vcxproj index 33ee65cdc3..111c949fc1 100644 --- a/src/common/notifications/notifications.vcxproj +++ b/src/common/notifications/notifications.vcxproj @@ -1,6 +1,7 @@ - + + 16.0 {1D5BE09D-78C0-4FD7-AF00-AE7C1AF7C525} @@ -8,7 +9,6 @@ notifications Notifications - StaticLibrary @@ -21,7 +21,8 @@ - ..\;..\..\;..\..\..\;%(AdditionalIncludeDirectories) + ..\;..\..\;$(RepoRoot)src\;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) _LIB;%(PreprocessorDefinitions) @@ -44,15 +45,15 @@ - - + + 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}. - - - + + + \ No newline at end of file diff --git a/src/common/version/version.vcxproj b/src/common/version/version.vcxproj index fff8efc983..ed5ff0d799 100644 --- a/src/common/version/version.vcxproj +++ b/src/common/version/version.vcxproj @@ -57,7 +57,7 @@ - ..\;..\..\;..\..\..\;%(AdditionalIncludeDirectories) + ..\;..\..\;$(RepoRoot)src\;%(AdditionalIncludeDirectories) _LIB;%(PreprocessorDefinitions) NotUsing diff --git a/src/dsc/PowerToys.Settings.DSC.Schema.Generator/PowerToys.Settings.DSC.Schema.Generator.csproj b/src/dsc/PowerToys.Settings.DSC.Schema.Generator/PowerToys.Settings.DSC.Schema.Generator.csproj index b36e602d25..ab943c5090 100644 --- a/src/dsc/PowerToys.Settings.DSC.Schema.Generator/PowerToys.Settings.DSC.Schema.Generator.csproj +++ b/src/dsc/PowerToys.Settings.DSC.Schema.Generator/PowerToys.Settings.DSC.Schema.Generator.csproj @@ -1,7 +1,7 @@ - + - - + + Exe diff --git a/src/dsc/v3/PowerToys.DSC.UnitTests/PowerToys.DSC.UnitTests.csproj b/src/dsc/v3/PowerToys.DSC.UnitTests/PowerToys.DSC.UnitTests.csproj index d7a8c8c2f8..3995b78254 100644 --- a/src/dsc/v3/PowerToys.DSC.UnitTests/PowerToys.DSC.UnitTests.csproj +++ b/src/dsc/v3/PowerToys.DSC.UnitTests/PowerToys.DSC.UnitTests.csproj @@ -1,10 +1,10 @@ - + - + false - ..\..\..\..\$(Configuration)\$(Platform)\tests\PowerToys.DSC.Tests\ + $(RepoRoot)$(Configuration)\$(Platform)\tests\PowerToys.DSC.Tests\ diff --git a/src/dsc/v3/PowerToys.DSC/PowerToys.DSC.csproj b/src/dsc/v3/PowerToys.DSC/PowerToys.DSC.csproj index a87508604f..003a1f1d58 100644 --- a/src/dsc/v3/PowerToys.DSC/PowerToys.DSC.csproj +++ b/src/dsc/v3/PowerToys.DSC/PowerToys.DSC.csproj @@ -1,11 +1,11 @@ - + - - + + Exe - ..\..\..\..\$(Platform)\$(Configuration) + $(RepoRoot)$(Platform)\$(Configuration) false false PowerToys.DSC diff --git a/src/logging/logging.vcxproj b/src/logging/logging.vcxproj index b1a584ec94..fe6403be71 100644 --- a/src/logging/logging.vcxproj +++ b/src/logging/logging.vcxproj @@ -1,5 +1,6 @@  + Debug @@ -31,13 +32,12 @@ Win32Proj spdlog - - + StaticLibrary MultiByte - ..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ @@ -65,98 +65,98 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/modules/AdvancedPaste/AdvancedPaste.FuzzTests/AdvancedPaste.FuzzTests.csproj b/src/modules/AdvancedPaste/AdvancedPaste.FuzzTests/AdvancedPaste.FuzzTests.csproj index 2d0b5f1ad1..557803aa64 100644 --- a/src/modules/AdvancedPaste/AdvancedPaste.FuzzTests/AdvancedPaste.FuzzTests.csproj +++ b/src/modules/AdvancedPaste/AdvancedPaste.FuzzTests/AdvancedPaste.FuzzTests.csproj @@ -1,14 +1,14 @@ - - + + latest enable enable - ..\..\..\..\$(Platform)\$(Configuration)\tests\AdvancedPaste.FuzzTests\ + $(RepoRoot)$(Platform)\$(Configuration)\tests\AdvancedPaste.FuzzTests\ diff --git a/src/modules/AdvancedPaste/AdvancedPaste.UnitTests/AdvancedPaste.UnitTests.csproj b/src/modules/AdvancedPaste/AdvancedPaste.UnitTests/AdvancedPaste.UnitTests.csproj index 15b998a245..df90a2fa5d 100644 --- a/src/modules/AdvancedPaste/AdvancedPaste.UnitTests/AdvancedPaste.UnitTests.csproj +++ b/src/modules/AdvancedPaste/AdvancedPaste.UnitTests/AdvancedPaste.UnitTests.csproj @@ -1,6 +1,6 @@ - + - + false diff --git a/src/modules/AdvancedPaste/AdvancedPaste/AdvancedPaste.csproj b/src/modules/AdvancedPaste/AdvancedPaste/AdvancedPaste.csproj index 1c80479c2d..090f3c75a7 100644 --- a/src/modules/AdvancedPaste/AdvancedPaste/AdvancedPaste.csproj +++ b/src/modules/AdvancedPaste/AdvancedPaste/AdvancedPaste.csproj @@ -1,11 +1,11 @@ - + - - + + WinExe - ..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps + $(RepoRoot)$(Platform)\$(Configuration)\WinUI3Apps true Assets\AdvancedPaste\AdvancedPaste.ico app.manifest diff --git a/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/AdvancedPasteModuleInterface.vcxproj b/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/AdvancedPasteModuleInterface.vcxproj index 7ccd5e0cda..8d282cb008 100644 --- a/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/AdvancedPasteModuleInterface.vcxproj +++ b/src/modules/AdvancedPaste/AdvancedPasteModuleInterface/AdvancedPasteModuleInterface.vcxproj @@ -1,6 +1,7 @@ - + + @@ -12,7 +13,6 @@ AdvancedPasteModuleInterface PowerToys.AdvancedPasteModuleInterface - DynamicLibrary @@ -27,12 +27,12 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ EXAMPLEPOWERTOY_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - ..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories) + $(RepoRoot)src\common\inc;$(RepoRoot)src\common\Telemetry;..\..\;$(RepoRoot)src\;%(AdditionalIncludeDirectories) $(OutDir)$(TargetName)$(TargetExt) @@ -56,10 +56,10 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} @@ -73,15 +73,15 @@ - + - + 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}. - - + + \ No newline at end of file diff --git a/src/modules/AdvancedPaste/UITest-AdvancedPaste/AdvancedPaste-UITests.csproj b/src/modules/AdvancedPaste/UITest-AdvancedPaste/AdvancedPaste-UITests.csproj index 82a599d660..6848b5f1a6 100644 --- a/src/modules/AdvancedPaste/UITest-AdvancedPaste/AdvancedPaste-UITests.csproj +++ b/src/modules/AdvancedPaste/UITest-AdvancedPaste/AdvancedPaste-UITests.csproj @@ -1,6 +1,6 @@ - + - + {2B1505FA-132A-460B-B22B-7CC3FFAB0C5D} @@ -14,7 +14,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\tests\UITests-AdvancedPaste\ + $(RepoRoot)$(Platform)\$(Configuration)\tests\UITests-AdvancedPaste\ diff --git a/src/modules/CropAndLock/CropAndLock/CropAndLock.vcxproj b/src/modules/CropAndLock/CropAndLock/CropAndLock.vcxproj index 6d33ed8c4e..ce336d5585 100644 --- a/src/modules/CropAndLock/CropAndLock/CropAndLock.vcxproj +++ b/src/modules/CropAndLock/CropAndLock/CropAndLock.vcxproj @@ -1,6 +1,7 @@ - + + true true @@ -13,7 +14,6 @@ 10.0.26100.0 10.0.19041.0 - Debug @@ -60,14 +60,14 @@ PowerToys.$(MSBuildProjectName) - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ _CONSOLE;WINRT_LEAN_AND_MEAN;%(PreprocessorDefinitions) Level4 %(AdditionalOptions) /bigobj - $(SolutionDir)src\common\Telemetry;$(SolutionDir)src;%(AdditionalIncludeDirectories) + $(RepoRoot)src\common\Telemetry;$(RepoRoot)src;%(AdditionalIncludeDirectories) Windows @@ -143,33 +143,33 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} - + {8f021b46-362b-485c-bfba-ccf83e820cbd} - + {98537082-0fdb-40de-abd8-0dc5a4269bab} - + - - - + + + 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}. - - - - + + + + \ No newline at end of file diff --git a/src/modules/CropAndLock/CropAndLockModuleInterface/CropAndLockModuleInterface.vcxproj b/src/modules/CropAndLock/CropAndLockModuleInterface/CropAndLockModuleInterface.vcxproj index af72e21d21..09af280a4e 100644 --- a/src/modules/CropAndLock/CropAndLockModuleInterface/CropAndLockModuleInterface.vcxproj +++ b/src/modules/CropAndLock/CropAndLockModuleInterface/CropAndLockModuleInterface.vcxproj @@ -1,6 +1,7 @@ - + + 16.0 Win32Proj @@ -8,7 +9,6 @@ CropAndLockModuleInterface CropAndLockModuleInterface - DynamicLibrary true @@ -31,12 +31,12 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ PowerToys.CropAndLockModuleInterface - ..\;$(SolutionDir)src\common\Telemetry;$(SolutionDir)src;%(AdditionalIncludeDirectories) + ..\;$(RepoRoot)src\common\Telemetry;$(RepoRoot)src;%(AdditionalIncludeDirectories) $(OutDir)$(TargetName)$(TargetExt) @@ -91,28 +91,28 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} - - - - + + + + - + 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}. - - - - + + + + \ No newline at end of file diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariables.csproj b/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariables.csproj index 2dcbc1e237..01587e9186 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariables.csproj +++ b/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariables.csproj @@ -1,7 +1,7 @@ - + - - + + WinExe @@ -16,7 +16,7 @@ false true DISABLE_XAML_GENERATED_MAIN,TRACE - ..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps + $(RepoRoot)$(Platform)\$(Configuration)\WinUI3Apps PowerToys.EnvironmentVariables Assets\EnvironmentVariables\EnvironmentVariables.ico diff --git a/src/modules/EnvironmentVariables/EnvironmentVariablesModuleInterface/EnvironmentVariablesModuleInterface.vcxproj b/src/modules/EnvironmentVariables/EnvironmentVariablesModuleInterface/EnvironmentVariablesModuleInterface.vcxproj index ff4c557a64..9eabc28e12 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariablesModuleInterface/EnvironmentVariablesModuleInterface.vcxproj +++ b/src/modules/EnvironmentVariables/EnvironmentVariablesModuleInterface/EnvironmentVariablesModuleInterface.vcxproj @@ -1,8 +1,9 @@ - + + - + 17.0 @@ -11,7 +12,6 @@ EnvironmentVariablesModuleInterface EnvironmentVariablesModuleInterface - DynamicLibrary true @@ -35,7 +35,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps\ + $(RepoRoot)$(Platform)\$(Configuration)\WinUI3Apps\ PowerToys.EnvironmentVariablesModuleInterface @@ -70,7 +70,7 @@ - $(SolutionDir)src;$(SolutionDir)src\modules;$(SolutionDir)src\common\Telemetry;%(AdditionalIncludeDirectories) + $(RepoRoot)src;$(RepoRoot)src\modules;$(RepoRoot)src\common\Telemetry;%(AdditionalIncludeDirectories) @@ -94,26 +94,26 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} - + {cc6e41ac-8174-4e8a-8d22-85dd7f4851df} - + - + 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}. - - + + \ No newline at end of file diff --git a/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/EnvironmentVariablesUILib.csproj b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/EnvironmentVariablesUILib.csproj index 3973f8d2eb..858f43313f 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/EnvironmentVariablesUILib.csproj +++ b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/EnvironmentVariablesUILib.csproj @@ -1,6 +1,6 @@ - + - + Library diff --git a/src/modules/FileLocksmith/FileLocksmithCLI/tests/FileLocksmithCLIUnitTests.vcxproj b/src/modules/FileLocksmith/FileLocksmithCLI/tests/FileLocksmithCLIUnitTests.vcxproj index 12b0a89c7b..6d420907b8 100644 --- a/src/modules/FileLocksmith/FileLocksmithCLI/tests/FileLocksmithCLIUnitTests.vcxproj +++ b/src/modules/FileLocksmith/FileLocksmithCLI/tests/FileLocksmithCLIUnitTests.vcxproj @@ -1,6 +1,7 @@ - + + {A1B2C3D4-E5F6-7890-1234-567890ABCDEF} Win32Proj @@ -8,8 +9,7 @@ FileLocksmithCLI.UnitTests 10.0 - - + DynamicLibrary Unicode @@ -24,11 +24,11 @@ - ..\..\..\..\..\$(Platform)\$(Configuration)\tests\FileLocksmithCLI\ + $(RepoRoot)$(Platform)\$(Configuration)\tests\FileLocksmithCLI\ - ..\;..\..\;..\..\..\..\;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories) + ..\;..\..\;$(RepoRoot)src\;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories) WIN32;UNIT_TEST;%(PreprocessorDefinitions) true Use @@ -56,13 +56,13 @@ {9d52fd25-ef90-4f9a-a015-91efc5daf54f} - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} - + {1248566c-272a-43c0-88d6-e6675d569a09} @@ -71,13 +71,13 @@ - + 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}. - - + + diff --git a/src/modules/FileLocksmith/FileLocksmithContextMenu/FileLocksmithContextMenu.vcxproj b/src/modules/FileLocksmith/FileLocksmithContextMenu/FileLocksmithContextMenu.vcxproj index a1617bfc06..bdb9f5e001 100644 --- a/src/modules/FileLocksmith/FileLocksmithContextMenu/FileLocksmithContextMenu.vcxproj +++ b/src/modules/FileLocksmith/FileLocksmithContextMenu/FileLocksmithContextMenu.vcxproj @@ -1,8 +1,9 @@ - + + - + 17.0 @@ -10,12 +11,11 @@ {799a50d8-de89-4ed1-8ff8-ad5a9ed8c0ca} FileLocksmithContextMenu - PowerToys.FileLocksmithContextMenu $(SolutionDir)$(Platform)\$(Configuration)\TemporaryBuild\obj\$(ProjectName)\ - ..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps\ + $(RepoRoot)$(Platform)\$(Configuration)\WinUI3Apps\ DynamicLibrary @@ -125,13 +125,13 @@ MakeAppx.exe pack /d . /p $(OutDir)FileLocksmithContextMenuPackage.msix /nv - + {6955446d-23f7-4023-9bb3-8657f904af99} - + {8f021b46-362b-485c-bfba-ccf83e820cbd} - + {cc6e41ac-8174-4e8a-8d22-85dd7f4851df} @@ -141,18 +141,18 @@ MakeAppx.exe pack /d . /p $(OutDir)FileLocksmithContextMenuPackage.msix /nv - + - - + + 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}. - - - + + + \ No newline at end of file diff --git a/src/modules/FileLocksmith/FileLocksmithExt/FileLocksmithExt.vcxproj b/src/modules/FileLocksmith/FileLocksmithExt/FileLocksmithExt.vcxproj index 8bca058c43..3d38699c83 100644 --- a/src/modules/FileLocksmith/FileLocksmithExt/FileLocksmithExt.vcxproj +++ b/src/modules/FileLocksmith/FileLocksmithExt/FileLocksmithExt.vcxproj @@ -1,18 +1,18 @@ - + + - + 16.0 Win32Proj {57175ec7-92a5-4c1e-8244-e3fbca2a81de} FileLocksmithExt - ..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps\ + $(RepoRoot)$(Platform)\$(Configuration)\WinUI3Apps\ PowerToys.FileLocksmithExt - DynamicLibrary true @@ -98,16 +98,16 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} - + {8f021b46-362b-485c-bfba-ccf83e820cbd} - + {98537082-0fdb-40de-abd8-0dc5a4269bab} @@ -115,15 +115,15 @@ - + - + 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}. - - + + \ No newline at end of file diff --git a/src/modules/FileLocksmith/FileLocksmithLib/FileLocksmithLib.vcxproj b/src/modules/FileLocksmith/FileLocksmithLib/FileLocksmithLib.vcxproj index e64b569387..41c6d166a4 100644 --- a/src/modules/FileLocksmith/FileLocksmithLib/FileLocksmithLib.vcxproj +++ b/src/modules/FileLocksmith/FileLocksmithLib/FileLocksmithLib.vcxproj @@ -1,6 +1,7 @@ - + + 17.0 Win32Proj @@ -8,7 +9,6 @@ FileLocksmithLib 10.0 - StaticLibrary true @@ -86,13 +86,13 @@ - + 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}. - - + + \ No newline at end of file diff --git a/src/modules/FileLocksmith/FileLocksmithLibInterop/FileLocksmithLibInterop.vcxproj b/src/modules/FileLocksmith/FileLocksmithLibInterop/FileLocksmithLibInterop.vcxproj index fd995a2d97..f6cfa11262 100644 --- a/src/modules/FileLocksmith/FileLocksmithLibInterop/FileLocksmithLibInterop.vcxproj +++ b/src/modules/FileLocksmith/FileLocksmithLibInterop/FileLocksmithLibInterop.vcxproj @@ -1,6 +1,7 @@ - + + Debug @@ -26,10 +27,9 @@ PowerToys.FileLocksmithLib.Interop PowerToys.FileLocksmithLib.Interop net8.0-windows10.0.22621.0 - ..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps\ + $(RepoRoot)$(Platform)\$(Configuration)\WinUI3Apps\ PowerToys.FileLocksmithLib.Interop - DynamicLibrary @@ -116,7 +116,7 @@ - + {f055103b-f80b-4d0c-bf48-057c55620033} @@ -133,13 +133,13 @@ - + 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}. - - + + \ No newline at end of file diff --git a/src/modules/FileLocksmith/FileLocksmithUI/FileLocksmithUI.csproj b/src/modules/FileLocksmith/FileLocksmithUI/FileLocksmithUI.csproj index f4b28d3922..600216fdbf 100644 --- a/src/modules/FileLocksmith/FileLocksmithUI/FileLocksmithUI.csproj +++ b/src/modules/FileLocksmith/FileLocksmithUI/FileLocksmithUI.csproj @@ -1,13 +1,13 @@ - + - - + + PowerToys.FileLocksmith PowerToys File Locksmith WinExe - ..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps + $(RepoRoot)$(Platform)\$(Configuration)\WinUI3Apps PowerToys.FileLocksmithUI PowerToys.FileLocksmithUI app.manifest diff --git a/src/modules/Hosts/Hosts.FuzzTests/HostsEditor.FuzzTests.csproj b/src/modules/Hosts/Hosts.FuzzTests/HostsEditor.FuzzTests.csproj index 51dee7a40b..89edfbfc98 100644 --- a/src/modules/Hosts/Hosts.FuzzTests/HostsEditor.FuzzTests.csproj +++ b/src/modules/Hosts/Hosts.FuzzTests/HostsEditor.FuzzTests.csproj @@ -1,7 +1,7 @@ - + - - + + latest @@ -10,7 +10,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\tests\Hosts.FuzzTests\ + $(RepoRoot)$(Platform)\$(Configuration)\tests\Hosts.FuzzTests\ diff --git a/src/modules/Hosts/Hosts.Tests/HostsEditor.UnitTests.csproj b/src/modules/Hosts/Hosts.Tests/HostsEditor.UnitTests.csproj index 0f0a57ba6b..7b5aa8b532 100644 --- a/src/modules/Hosts/Hosts.Tests/HostsEditor.UnitTests.csproj +++ b/src/modules/Hosts/Hosts.Tests/HostsEditor.UnitTests.csproj @@ -1,6 +1,6 @@ - + - + false diff --git a/src/modules/Hosts/Hosts.UITests/HostsEditor.UITests.csproj b/src/modules/Hosts/Hosts.UITests/HostsEditor.UITests.csproj index c8a45ea3aa..e3fe2d8f65 100644 --- a/src/modules/Hosts/Hosts.UITests/HostsEditor.UITests.csproj +++ b/src/modules/Hosts/Hosts.UITests/HostsEditor.UITests.csproj @@ -1,6 +1,6 @@ - + {4E0AE3A4-2EE0-44D7-A2D0-8769977254A0} @@ -15,7 +15,7 @@ false - ..\..\..\..\$(Platform)\$(Configuration)\tests\Hosts.UITests\ + $(RepoRoot)$(Platform)\$(Configuration)\tests\Hosts.UITests\ diff --git a/src/modules/Hosts/Hosts/Hosts.csproj b/src/modules/Hosts/Hosts/Hosts.csproj index cf595dd44b..2d00648ca4 100644 --- a/src/modules/Hosts/Hosts/Hosts.csproj +++ b/src/modules/Hosts/Hosts/Hosts.csproj @@ -1,7 +1,7 @@ - + - - + + WinExe @@ -13,7 +13,7 @@ false false true - ..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps + $(RepoRoot)$(Platform)\$(Configuration)\WinUI3Apps PowerToys.Hosts DISABLE_XAML_GENERATED_MAIN,TRACE Assets/Hosts/Hosts.ico diff --git a/src/modules/Hosts/HostsModuleInterface/HostsModuleInterface.vcxproj b/src/modules/Hosts/HostsModuleInterface/HostsModuleInterface.vcxproj index 40601496d3..2f370134ba 100644 --- a/src/modules/Hosts/HostsModuleInterface/HostsModuleInterface.vcxproj +++ b/src/modules/Hosts/HostsModuleInterface/HostsModuleInterface.vcxproj @@ -1,6 +1,7 @@ - + + @@ -11,7 +12,6 @@ HostsModuleInterface HostsModuleInterface - DynamicLibrary true @@ -35,7 +35,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps\ + $(RepoRoot)$(Platform)\$(Configuration)\WinUI3Apps\ PowerToys.HostsModuleInterface @@ -46,7 +46,7 @@ - ..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories) + $(RepoRoot)src\common\inc;$(RepoRoot)src\common\Telemetry;..\..\;$(RepoRoot)src\;%(AdditionalIncludeDirectories) @@ -64,10 +64,10 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} @@ -79,15 +79,15 @@ - + - + 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}. - - + + \ No newline at end of file diff --git a/src/modules/Hosts/HostsUILib/HostsUILib.csproj b/src/modules/Hosts/HostsUILib/HostsUILib.csproj index 21e7822000..267e5e137d 100644 --- a/src/modules/Hosts/HostsUILib/HostsUILib.csproj +++ b/src/modules/Hosts/HostsUILib/HostsUILib.csproj @@ -1,7 +1,7 @@ - + - - + + Library diff --git a/src/modules/LightSwitch/LightSwitchModuleInterface/LightSwitchModuleInterface.vcxproj b/src/modules/LightSwitch/LightSwitchModuleInterface/LightSwitchModuleInterface.vcxproj index 7ec2238edf..b9107eb59d 100644 --- a/src/modules/LightSwitch/LightSwitchModuleInterface/LightSwitchModuleInterface.vcxproj +++ b/src/modules/LightSwitch/LightSwitchModuleInterface/LightSwitchModuleInterface.vcxproj @@ -1,6 +1,7 @@ - + + Debug @@ -28,7 +29,6 @@ LightSwitchModuleInterface PowerToys.LightSwitchModuleInterface - DynamicLibrary true @@ -74,7 +74,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ true @@ -166,7 +166,7 @@ - ..\LightSwitchLib;..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories) + ..\LightSwitchLib;$(RepoRoot)src\common\inc;$(RepoRoot)src\common\Telemetry;..\..\;$(RepoRoot)src\;%(AdditionalIncludeDirectories) @@ -193,13 +193,13 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {4aed67b6-55fd-486f-b917-e543dee2cb3c} - + {6955446d-23f7-4023-9bb3-8657f904af99} @@ -210,15 +210,15 @@ - + - + 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}. - - + + diff --git a/src/modules/LightSwitch/LightSwitchService/LightSwitchService.vcxproj b/src/modules/LightSwitch/LightSwitchService/LightSwitchService.vcxproj index f10364e4e3..fa2407b294 100644 --- a/src/modules/LightSwitch/LightSwitchService/LightSwitchService.vcxproj +++ b/src/modules/LightSwitch/LightSwitchService/LightSwitchService.vcxproj @@ -1,6 +1,7 @@ - + + Debug @@ -27,7 +28,7 @@ 10.0.26100.0 LightSwitchService - + Application true @@ -43,7 +44,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\$(MSBuildProjectName)\ + $(RepoRoot)$(Platform)\$(Configuration)\$(MSBuildProjectName)\ PowerToys.LightSwitchService @@ -57,11 +58,11 @@ ./../; ..\LightSwitchLib; ..\..\..\common; - ..\..\..\common\logger; - ..\..\..\common\utils; - ..\..\..\common\SettingsAPI; - ..\..\..\common\Telemetry; - ..\..\..\; + $(RepoRoot)src\common\logger; + $(RepoRoot)src\common\utils; + $(RepoRoot)src\common\SettingsAPI; + $(RepoRoot)src\common\Telemetry; + $(RepoRoot)src\; ..\..\..\..\deps\spdlog\include; ./; %(AdditionalIncludeDirectories) @@ -98,16 +99,16 @@ - + {4aed67b6-55fd-486f-b917-e543dee2cb3c} - + {6955446d-23f7-4023-9bb3-8657f904af99} - + {1d5be09d-78c0-4fd7-af00-ae7c1af7c525} - + {8f021b46-362b-485c-bfba-ccf83e820cbd} @@ -115,9 +116,9 @@ - + - - + + diff --git a/src/modules/LightSwitch/Tests/LightSwitch.UITests/LightSwitch.UITests.csproj b/src/modules/LightSwitch/Tests/LightSwitch.UITests/LightSwitch.UITests.csproj index a1ec81d30c..c230c1c958 100644 --- a/src/modules/LightSwitch/Tests/LightSwitch.UITests/LightSwitch.UITests.csproj +++ b/src/modules/LightSwitch/Tests/LightSwitch.UITests/LightSwitch.UITests.csproj @@ -1,5 +1,5 @@ - - + + PowerToys.LightSwitch.UITests LightSwitch.UITests diff --git a/src/modules/MeasureTool/MeasureToolCore/PowerToys.MeasureToolCore.vcxproj b/src/modules/MeasureTool/MeasureToolCore/PowerToys.MeasureToolCore.vcxproj index 5a589c673d..a61b2e58bb 100644 --- a/src/modules/MeasureTool/MeasureToolCore/PowerToys.MeasureToolCore.vcxproj +++ b/src/modules/MeasureTool/MeasureToolCore/PowerToys.MeasureToolCore.vcxproj @@ -1,4 +1,4 @@ - + @@ -52,13 +52,13 @@ - ..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps\ + $(RepoRoot)$(Platform)\$(Configuration)\WinUI3Apps\ Level4 %(AdditionalOptions) /bigobj - $(SolutionDir)src\;..\..\..\common\Telemetry;..\..\..\;%(AdditionalIncludeDirectories) + $(RepoRoot)src\;$(RepoRoot)src\common\Telemetry;$(RepoRoot)src\;%(AdditionalIncludeDirectories) Windows @@ -125,19 +125,19 @@ - + {caba8dfb-823b-4bf2-93ac-3f31984150d9} - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} - + {8f021b46-362b-485c-bfba-ccf83e820cbd} - + {98537082-0fdb-40de-abd8-0dc5a4269bab} @@ -145,5 +145,5 @@ - + \ No newline at end of file diff --git a/src/modules/MeasureTool/MeasureToolModuleInterface/MeasureToolModuleInterface.vcxproj b/src/modules/MeasureTool/MeasureToolModuleInterface/MeasureToolModuleInterface.vcxproj index 561bf95b15..242a994c37 100644 --- a/src/modules/MeasureTool/MeasureToolModuleInterface/MeasureToolModuleInterface.vcxproj +++ b/src/modules/MeasureTool/MeasureToolModuleInterface/MeasureToolModuleInterface.vcxproj @@ -1,6 +1,7 @@ - + + 16.0 {92C39820-9F84-4529-BC7D-22AAE514D63B} @@ -8,7 +9,6 @@ MeasureToolModuleInterface MeasureToolModuleInterface - DynamicLibrary true @@ -32,7 +32,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps\ + $(RepoRoot)$(Platform)\$(Configuration)\WinUI3Apps\ PowerToys.MeasureToolModuleInterface @@ -43,7 +43,7 @@ - $(SolutionDir)src\;$(SolutionDir)src\modules;$(SolutionDir)src\common\Telemetry;%(AdditionalIncludeDirectories) + $(RepoRoot)src\;$(RepoRoot)src\modules;$(RepoRoot)src\common\Telemetry;%(AdditionalIncludeDirectories) @@ -60,10 +60,10 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} @@ -74,15 +74,15 @@ - + - + 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}. - - + + \ No newline at end of file diff --git a/src/modules/MeasureTool/MeasureToolUI/MeasureToolUI.csproj b/src/modules/MeasureTool/MeasureToolUI/MeasureToolUI.csproj index 3e92bd42f3..f2424eda21 100644 --- a/src/modules/MeasureTool/MeasureToolUI/MeasureToolUI.csproj +++ b/src/modules/MeasureTool/MeasureToolUI/MeasureToolUI.csproj @@ -1,13 +1,13 @@ - + - - + + PowerToys.MeasureTool PowerToys MeasureTool WinExe - ..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps + $(RepoRoot)$(Platform)\$(Configuration)\WinUI3Apps PowerToys.MeasureToolUI PowerToys.MeasureToolUI app.manifest diff --git a/src/modules/MeasureTool/Tests/ScreenRuler.UITests/ScreenRuler.UITests.csproj b/src/modules/MeasureTool/Tests/ScreenRuler.UITests/ScreenRuler.UITests.csproj index be1da425a7..4e59a4c5b4 100644 --- a/src/modules/MeasureTool/Tests/ScreenRuler.UITests/ScreenRuler.UITests.csproj +++ b/src/modules/MeasureTool/Tests/ScreenRuler.UITests/ScreenRuler.UITests.csproj @@ -1,5 +1,5 @@ - - + + PowerToys.ScreenRuler.UITests ScreenRuler.UITests diff --git a/src/modules/MouseUtils/CursorWrap/CursorWrap.vcxproj b/src/modules/MouseUtils/CursorWrap/CursorWrap.vcxproj index d4eede3cb0..b361345cbd 100644 --- a/src/modules/MouseUtils/CursorWrap/CursorWrap.vcxproj +++ b/src/modules/MouseUtils/CursorWrap/CursorWrap.vcxproj @@ -1,6 +1,7 @@ - + + 15.0 {48a1db8c-5df8-4fb3-9e14-2b67f3f2d8b5} @@ -8,8 +9,7 @@ CursorWrap CursorWrap - - + DynamicLibrary true @@ -33,7 +33,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ PowerToys.CursorWrap @@ -80,7 +80,7 @@ - ..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories) + $(RepoRoot)src\common\inc;$(RepoRoot)src\common\Telemetry;..\..\;$(RepoRoot)src\;%(AdditionalIncludeDirectories) @@ -104,10 +104,10 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} @@ -121,13 +121,13 @@ - + 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}. - - + + diff --git a/src/modules/MouseUtils/FindMyMouse/FindMyMouse.vcxproj b/src/modules/MouseUtils/FindMyMouse/FindMyMouse.vcxproj index 47867ebb2d..7c4d855986 100644 --- a/src/modules/MouseUtils/FindMyMouse/FindMyMouse.vcxproj +++ b/src/modules/MouseUtils/FindMyMouse/FindMyMouse.vcxproj @@ -54,7 +54,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ PowerToys.FindMyMouse @@ -102,7 +102,7 @@ - $(GeneratedFilesDir);$(SolutionDir)src\;$(SolutionDir)src\modules;$(SolutionDir)src\common\Telemetry;$(MSBuildThisFileDirectory)..\..\..\..\src\;$(MSBuildThisFileDirectory)..\..\..\..\src\modules;$(MSBuildThisFileDirectory)..\..\..\..\src\common\Telemetry;%(AdditionalIncludeDirectories) + $(GeneratedFilesDir);$(RepoRoot)src\;$(RepoRoot)src\modules;$(RepoRoot)src\common\Telemetry;$(MSBuildThisFileDirectory)..\..\..\..\src\;$(MSBuildThisFileDirectory)..\..\..\..\src\modules;$(MSBuildThisFileDirectory)..\..\..\..\src\common\Telemetry;%(AdditionalIncludeDirectories) @@ -123,10 +123,10 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} @@ -153,5 +153,5 @@ - + diff --git a/src/modules/MouseUtils/MouseHighlighter/MouseHighlighter.vcxproj b/src/modules/MouseUtils/MouseHighlighter/MouseHighlighter.vcxproj index 4463846c20..422eef20cf 100644 --- a/src/modules/MouseUtils/MouseHighlighter/MouseHighlighter.vcxproj +++ b/src/modules/MouseUtils/MouseHighlighter/MouseHighlighter.vcxproj @@ -1,6 +1,7 @@ - + + 15.0 {782a61be-9d85-4081-b35c-1ccc9dcc1e88} @@ -8,7 +9,6 @@ MouseHighlighter MouseHighlighter - DynamicLibrary true @@ -32,7 +32,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ PowerToys.MouseHighlighter @@ -79,7 +79,7 @@ - $(SolutionDir)src\;$(SolutionDir)src\modules;$(SolutionDir)src\common\Telemetry;%(AdditionalIncludeDirectories) + $(RepoRoot)src\;$(RepoRoot)src\modules;$(RepoRoot)src\common\Telemetry;%(AdditionalIncludeDirectories) @@ -100,10 +100,10 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} @@ -111,15 +111,15 @@ - + - + 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}. - - + + \ No newline at end of file diff --git a/src/modules/MouseUtils/MouseJump.Common.UnitTests/MouseJump.Common.UnitTests.csproj b/src/modules/MouseUtils/MouseJump.Common.UnitTests/MouseJump.Common.UnitTests.csproj index c97b009bb6..c247b3e7fa 100644 --- a/src/modules/MouseUtils/MouseJump.Common.UnitTests/MouseJump.Common.UnitTests.csproj +++ b/src/modules/MouseUtils/MouseJump.Common.UnitTests/MouseJump.Common.UnitTests.csproj @@ -1,6 +1,6 @@ - + - + @@ -9,7 +9,7 @@ PowerToys.MouseJump.Common.UnitTests PowerToys MouseJump.Common.UnitTests Library - ..\..\..\..\$(Platform)\$(Configuration)\tests\MouseJump.Common.UnitTests\ + $(RepoRoot)$(Platform)\$(Configuration)\tests\MouseJump.Common.UnitTests\ false false diff --git a/src/modules/MouseUtils/MouseJump.Common/MouseJump.Common.csproj b/src/modules/MouseUtils/MouseJump.Common/MouseJump.Common.csproj index 4b56443fa7..79d6b7b47e 100644 --- a/src/modules/MouseUtils/MouseJump.Common/MouseJump.Common.csproj +++ b/src/modules/MouseUtils/MouseJump.Common/MouseJump.Common.csproj @@ -1,6 +1,6 @@ - + - + @@ -9,7 +9,7 @@ PowerToys.MouseJump.Common PowerToys MouseJump.Common Library - ..\..\..\..\$(Platform)\$(Configuration) + $(RepoRoot)$(Platform)\$(Configuration) false false diff --git a/src/modules/MouseUtils/MouseJump/MouseJump.vcxproj b/src/modules/MouseUtils/MouseJump/MouseJump.vcxproj index b6ddd885fb..322973db30 100644 --- a/src/modules/MouseUtils/MouseJump/MouseJump.vcxproj +++ b/src/modules/MouseUtils/MouseJump/MouseJump.vcxproj @@ -1,6 +1,7 @@ - + + 15.0 {8a08d663-4995-40e3-b42c-3f910625f284} @@ -8,7 +9,6 @@ MouseJumpModuleInterface MouseJump - DynamicLibrary true @@ -32,7 +32,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ PowerToys.MouseJump @@ -79,7 +79,7 @@ - $(SolutionDir)src\;$(SolutionDir)src\modules;$(SolutionDir)src\common\Telemetry;%(AdditionalIncludeDirectories) + $(RepoRoot)src\;$(RepoRoot)src\modules;$(RepoRoot)src\common\Telemetry;%(AdditionalIncludeDirectories) @@ -95,10 +95,10 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} @@ -109,15 +109,15 @@ - + - + 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}. - - + + \ No newline at end of file diff --git a/src/modules/MouseUtils/MouseJumpUI/MouseJumpUI.csproj b/src/modules/MouseUtils/MouseJumpUI/MouseJumpUI.csproj index 4ffd69bee6..53f949f4c3 100644 --- a/src/modules/MouseUtils/MouseJumpUI/MouseJumpUI.csproj +++ b/src/modules/MouseUtils/MouseJumpUI/MouseJumpUI.csproj @@ -1,7 +1,7 @@ - + - - + + @@ -9,7 +9,7 @@ PowerToys.MouseJumpUI PowerToys MouseJumpUI WinExe - ..\..\..\..\$(Platform)\$(Configuration) + $(RepoRoot)$(Platform)\$(Configuration) false false diff --git a/src/modules/MouseUtils/MousePointerCrosshairs/MousePointerCrosshairs.vcxproj b/src/modules/MouseUtils/MousePointerCrosshairs/MousePointerCrosshairs.vcxproj index 0823564a44..355bcee256 100644 --- a/src/modules/MouseUtils/MousePointerCrosshairs/MousePointerCrosshairs.vcxproj +++ b/src/modules/MouseUtils/MousePointerCrosshairs/MousePointerCrosshairs.vcxproj @@ -1,6 +1,7 @@ - + + 15.0 {eae14c0e-7a6b-45da-9080-a7d8c077ba6e} @@ -8,8 +9,7 @@ MousePointerCrosshairs MousePointerCrosshairs - - + DynamicLibrary true @@ -33,7 +33,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ PowerToys.MousePointerCrosshairs @@ -80,7 +80,7 @@ - ..\..\..\;..\..\..\modules;..\..\..\common\Telemetry;%(AdditionalIncludeDirectories) + $(RepoRoot)src\;..\..\..\modules;$(RepoRoot)src\common\Telemetry;%(AdditionalIncludeDirectories) @@ -101,10 +101,10 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} @@ -113,13 +113,13 @@ - + 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}. - - + + \ No newline at end of file diff --git a/src/modules/MouseUtils/MouseUtils.UITests/MouseUtils.UITests.csproj b/src/modules/MouseUtils/MouseUtils.UITests/MouseUtils.UITests.csproj index 911de3e8e1..33d722718f 100644 --- a/src/modules/MouseUtils/MouseUtils.UITests/MouseUtils.UITests.csproj +++ b/src/modules/MouseUtils/MouseUtils.UITests/MouseUtils.UITests.csproj @@ -1,6 +1,6 @@ - + - + {4E0AE3A4-2EE0-44D7-A2D0-8769977254A1} diff --git a/src/modules/MouseWithoutBorders/App/Helper/MouseWithoutBordersHelper.csproj b/src/modules/MouseWithoutBorders/App/Helper/MouseWithoutBordersHelper.csproj index 981266c0cb..4b3fc7fd50 100644 --- a/src/modules/MouseWithoutBorders/App/Helper/MouseWithoutBordersHelper.csproj +++ b/src/modules/MouseWithoutBorders/App/Helper/MouseWithoutBordersHelper.csproj @@ -1,7 +1,7 @@ - + - - + + WinExe @@ -11,7 +11,7 @@ PowerToys.MouseWithoutBordersHelper true true - ..\..\..\..\..\$(Platform)\$(Configuration) + $(RepoRoot)$(Platform)\$(Configuration) true ..\Logo.ico true diff --git a/src/modules/MouseWithoutBorders/App/MouseWithoutBorders.csproj b/src/modules/MouseWithoutBorders/App/MouseWithoutBorders.csproj index 4c2e35c6ad..acc66deea6 100644 --- a/src/modules/MouseWithoutBorders/App/MouseWithoutBorders.csproj +++ b/src/modules/MouseWithoutBorders/App/MouseWithoutBorders.csproj @@ -1,7 +1,7 @@ - + - - + + WinExe @@ -11,7 +11,7 @@ PowerToys.MouseWithoutBorders true true - ..\..\..\..\$(Platform)\$(Configuration) + $(RepoRoot)$(Platform)\$(Configuration) true Logo.ico true diff --git a/src/modules/MouseWithoutBorders/App/Service/MouseWithoutBordersService.csproj b/src/modules/MouseWithoutBorders/App/Service/MouseWithoutBordersService.csproj index 1431445733..53af161e16 100644 --- a/src/modules/MouseWithoutBorders/App/Service/MouseWithoutBordersService.csproj +++ b/src/modules/MouseWithoutBorders/App/Service/MouseWithoutBordersService.csproj @@ -1,7 +1,7 @@ - + - - + + true @@ -12,7 +12,7 @@ PowerToys.MouseWithoutBordersService true true - ..\..\..\..\..\$(Platform)\$(Configuration) + $(RepoRoot)$(Platform)\$(Configuration) true ..\Logo.ico true diff --git a/src/modules/MouseWithoutBorders/ModuleInterface/MouseWithoutBordersModuleInterface.vcxproj b/src/modules/MouseWithoutBorders/ModuleInterface/MouseWithoutBordersModuleInterface.vcxproj index f2af1e923e..1f79f19e56 100644 --- a/src/modules/MouseWithoutBorders/ModuleInterface/MouseWithoutBordersModuleInterface.vcxproj +++ b/src/modules/MouseWithoutBorders/ModuleInterface/MouseWithoutBordersModuleInterface.vcxproj @@ -1,13 +1,13 @@ - + + 15.0 {2833C9C6-AB32-4048-A5C7-A70898337B57} Win32Proj MouseWithoutBordersModuleInterface - DynamicLibrary @@ -22,13 +22,13 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ PowerToys.MouseWithoutBordersModuleInterface FANCYZONES_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - ..\;..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories) + ..\;$(RepoRoot)src\common\inc;$(RepoRoot)src\common\Telemetry;..\..\;$(RepoRoot)src\;%(AdditionalIncludeDirectories) $(OutDir)$(TargetName)$(TargetExt) @@ -50,10 +50,10 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} @@ -64,17 +64,17 @@ - + - - + + 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}. - - - + + + \ No newline at end of file diff --git a/src/modules/MouseWithoutBorders/MouseWithoutBorders.UnitTests/MouseWithoutBorders.UnitTests.csproj b/src/modules/MouseWithoutBorders/MouseWithoutBorders.UnitTests/MouseWithoutBorders.UnitTests.csproj index ad95d818a1..6020214279 100644 --- a/src/modules/MouseWithoutBorders/MouseWithoutBorders.UnitTests/MouseWithoutBorders.UnitTests.csproj +++ b/src/modules/MouseWithoutBorders/MouseWithoutBorders.UnitTests/MouseWithoutBorders.UnitTests.csproj @@ -1,7 +1,7 @@ - + - - + + enable diff --git a/src/modules/NewPlus/NewShellExtensionContextMenu.win10/NewPlus.ShellExtension.win10.vcxproj b/src/modules/NewPlus/NewShellExtensionContextMenu.win10/NewPlus.ShellExtension.win10.vcxproj index fb1bf3c06b..9436d412f3 100644 --- a/src/modules/NewPlus/NewShellExtensionContextMenu.win10/NewPlus.ShellExtension.win10.vcxproj +++ b/src/modules/NewPlus/NewShellExtensionContextMenu.win10/NewPlus.ShellExtension.win10.vcxproj @@ -1,8 +1,9 @@ - + + - + 17.0 @@ -11,7 +12,6 @@ NewPlusShellExtensionWin10 10.0.26100.0 - DynamicLibrary @@ -34,7 +34,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps\ + $(RepoRoot)$(Platform)\$(Configuration)\WinUI3Apps\ PowerToys.NewPlus.ShellExtension.win10 @@ -46,7 +46,7 @@ _DEBUG;NEWPLUSSHELLEXTENSIONWIN10_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true Use - ..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories);..\NewShellExtensionContextMenu;$(MSBuildThisFileDirectory) + $(RepoRoot)src\common\Telemetry;..\..\;$(RepoRoot)src\;%(AdditionalIncludeDirectories);..\NewShellExtensionContextMenu;$(MSBuildThisFileDirectory) false stdcpplatest @@ -67,7 +67,7 @@ NDEBUG;NEWPLUSSHELLEXTENSIONWIN10_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true Use - ..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories);..\NewShellExtensionContextMenu;$(MSBuildThisFileDirectory) + $(RepoRoot)src\common\Telemetry;..\..\;$(RepoRoot)src\;%(AdditionalIncludeDirectories);..\NewShellExtensionContextMenu;$(MSBuildThisFileDirectory) false stdcpplatest @@ -125,13 +125,13 @@ - + {6955446d-23f7-4023-9bb3-8657f904af99} - + {8f021b46-362b-485c-bfba-ccf83e820cbd} - + {98537082-0fdb-40de-abd8-0dc5a4269bab} @@ -140,17 +140,17 @@ - + - - + + 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}. - - - + + + \ No newline at end of file diff --git a/src/modules/NewPlus/NewShellExtensionContextMenu/NewShellExtensionContextMenu.vcxproj b/src/modules/NewPlus/NewShellExtensionContextMenu/NewShellExtensionContextMenu.vcxproj index e43fb73e80..58f01522ed 100644 --- a/src/modules/NewPlus/NewShellExtensionContextMenu/NewShellExtensionContextMenu.vcxproj +++ b/src/modules/NewPlus/NewShellExtensionContextMenu/NewShellExtensionContextMenu.vcxproj @@ -1,8 +1,9 @@ - + + - + 17.0 @@ -12,7 +13,6 @@ 10.0.20348.0 NewPlus.ShellExtension - DynamicLibrary true @@ -37,14 +37,14 @@ .dll - ..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps\ + $(RepoRoot)$(Platform)\$(Configuration)\WinUI3Apps\ PowerToys.NewPlus.ShellExtension $(SolutionDir)$(Platform)\$(Configuration)\TemporaryBuild\obj\$(ProjectName)\ - ..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps\ + $(RepoRoot)$(Platform)\$(Configuration)\WinUI3Apps\ PowerToys.NewPlus.ShellExtension $(SolutionDir)$(Platform)\$(Configuration)\TemporaryBuild\obj\$(ProjectName)\ @@ -59,7 +59,7 @@ Use pch.h stdcpplatest - ..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories) + $(RepoRoot)src\common\Telemetry;..\..\;$(RepoRoot)src\;%(AdditionalIncludeDirectories) Windows @@ -90,7 +90,7 @@ MakeAppx.exe pack /d . /p $(OutDir)NewPlusPackage.msix /nv Use pch.h stdcpplatest - ..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories) + $(RepoRoot)src\common\Telemetry;..\..\;$(RepoRoot)src\;%(AdditionalIncludeDirectories) Windows @@ -167,19 +167,19 @@ MakeAppx.exe pack /d . /p $(OutDir)NewPlusPackage.msix /nv - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} - + {8f021b46-362b-485c-bfba-ccf83e820cbd} - + {98537082-0fdb-40de-abd8-0dc5a4269bab} - + {cc6e41ac-8174-4e8a-8d22-85dd7f4851df} @@ -231,15 +231,15 @@ MakeAppx.exe pack /d . /p $(OutDir)NewPlusPackage.msix /nv - + - + 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}. - - + + \ No newline at end of file diff --git a/src/modules/PowerOCR/PowerOCR-UITests/PowerOCR.UITests.csproj b/src/modules/PowerOCR/PowerOCR-UITests/PowerOCR.UITests.csproj index c2a51bb332..572cf5ab69 100644 --- a/src/modules/PowerOCR/PowerOCR-UITests/PowerOCR.UITests.csproj +++ b/src/modules/PowerOCR/PowerOCR-UITests/PowerOCR.UITests.csproj @@ -1,5 +1,5 @@ - + PowerOCR.UITests enable @@ -9,7 +9,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\tests\PowerOCR.UITests\ + $(RepoRoot)$(Platform)\$(Configuration)\tests\PowerOCR.UITests\ diff --git a/src/modules/PowerOCR/PowerOCR/PowerOCR.csproj b/src/modules/PowerOCR/PowerOCR/PowerOCR.csproj index 1c95308d25..8586acaa2e 100644 --- a/src/modules/PowerOCR/PowerOCR/PowerOCR.csproj +++ b/src/modules/PowerOCR/PowerOCR/PowerOCR.csproj @@ -1,11 +1,11 @@ - + - - + + PowerToys.PowerOCR - ..\..\..\..\$(Platform)\$(Configuration) + $(RepoRoot)$(Platform)\$(Configuration) false false true diff --git a/src/modules/PowerOCR/PowerOCRModuleInterface/PowerOCRModuleInterface.vcxproj b/src/modules/PowerOCR/PowerOCRModuleInterface/PowerOCRModuleInterface.vcxproj index 252037b584..b7e07ef9fe 100644 --- a/src/modules/PowerOCR/PowerOCRModuleInterface/PowerOCRModuleInterface.vcxproj +++ b/src/modules/PowerOCR/PowerOCRModuleInterface/PowerOCRModuleInterface.vcxproj @@ -1,8 +1,9 @@ - + + - + 15.0 @@ -12,7 +13,6 @@ PowerOCRModuleInterface PowerToys.PowerOCRModuleInterface - DynamicLibrary @@ -27,12 +27,12 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ EXAMPLEPOWERTOY_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - ..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories) + $(RepoRoot)src\common\inc;$(RepoRoot)src\common\Telemetry;..\..\;$(RepoRoot)src\;%(AdditionalIncludeDirectories) $(OutDir)$(TargetName)$(TargetExt) @@ -54,10 +54,10 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} @@ -71,15 +71,15 @@ - + - + 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}. - - + + \ No newline at end of file diff --git a/src/modules/ShortcutGuide/ShortcutGuide/ShortcutGuide.vcxproj b/src/modules/ShortcutGuide/ShortcutGuide/ShortcutGuide.vcxproj index 95dcaebc1c..2a525092c9 100644 --- a/src/modules/ShortcutGuide/ShortcutGuide/ShortcutGuide.vcxproj +++ b/src/modules/ShortcutGuide/ShortcutGuide/ShortcutGuide.vcxproj @@ -1,8 +1,9 @@ - + + - + true @@ -14,7 +15,6 @@ Win32Proj ShortcutGuide - Application @@ -47,11 +47,11 @@ PowerToys.$(MSBuildProjectName) - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ - ;..\..\..\common\inc;..\..\..\common\Telemetry;..\..\..\;..\;%(AdditionalIncludeDirectories) + ;$(RepoRoot)src\common\inc;$(RepoRoot)src\common\Telemetry;$(RepoRoot)src\;..\;%(AdditionalIncludeDirectories) ole32.lib;Shell32.lib;OleAut32.lib;Dbghelp.lib;Dwmapi.lib;Dcomp.lib;Shlwapi.lib;%(AdditionalDependencies) @@ -149,19 +149,19 @@ - + {caba8dfb-823b-4bf2-93ac-3f31984150d9} - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} - + {8f021b46-362b-485c-bfba-ccf83e820cbd} - + {98537082-0fdb-40de-abd8-0dc5a4269bab} @@ -179,15 +179,15 @@ - + - + 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}. - - + + \ No newline at end of file diff --git a/src/modules/ShortcutGuide/ShortcutGuideModuleInterface/ShortcutGuideModuleInterface.vcxproj b/src/modules/ShortcutGuide/ShortcutGuideModuleInterface/ShortcutGuideModuleInterface.vcxproj index c5590605ae..6a245b23df 100644 --- a/src/modules/ShortcutGuide/ShortcutGuideModuleInterface/ShortcutGuideModuleInterface.vcxproj +++ b/src/modules/ShortcutGuide/ShortcutGuideModuleInterface/ShortcutGuideModuleInterface.vcxproj @@ -1,8 +1,9 @@ - + + - + 15.0 @@ -11,7 +12,6 @@ ShortcutGuideModuleInterface ShortcutGuideModuleInterface - DynamicLibrary true @@ -37,12 +37,12 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ PowerToys.ShortcutGuideModuleInterface - ;..\..\..\common\inc;..\..\..\common\Telemetry;..\..\..\;..\;%(AdditionalIncludeDirectories) + ;$(RepoRoot)src\common\inc;$(RepoRoot)src\common\Telemetry;$(RepoRoot)src\;..\;%(AdditionalIncludeDirectories) Dwmapi.lib;Dcomp.lib;Shlwapi.lib;%(AdditionalDependencies) @@ -60,10 +60,10 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} @@ -76,15 +76,15 @@ - + - + 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}. - - + + \ No newline at end of file diff --git a/src/modules/Workspaces/Workspaces.ModuleServices/Workspaces.ModuleServices.csproj b/src/modules/Workspaces/Workspaces.ModuleServices/Workspaces.ModuleServices.csproj index f835138a27..74bc59de0c 100644 --- a/src/modules/Workspaces/Workspaces.ModuleServices/Workspaces.ModuleServices.csproj +++ b/src/modules/Workspaces/Workspaces.ModuleServices/Workspaces.ModuleServices.csproj @@ -1,7 +1,7 @@ - + - - + + enable diff --git a/src/modules/Workspaces/WorkspacesCsharpLibrary/WorkspacesCsharpLibrary.csproj b/src/modules/Workspaces/WorkspacesCsharpLibrary/WorkspacesCsharpLibrary.csproj index 501f6b4f0c..b88e6a9f9c 100644 --- a/src/modules/Workspaces/WorkspacesCsharpLibrary/WorkspacesCsharpLibrary.csproj +++ b/src/modules/Workspaces/WorkspacesCsharpLibrary/WorkspacesCsharpLibrary.csproj @@ -1,7 +1,7 @@ - + - - + + PowerToys.WorkspacesCsharpLibrary @@ -13,7 +13,7 @@ false false true - ..\..\..\..\$(Platform)\$(Configuration) + $(RepoRoot)$(Platform)\$(Configuration) PowerToys.WorkspacesCsharpLibrary diff --git a/src/modules/Workspaces/WorkspacesEditor/WorkspacesEditor.csproj b/src/modules/Workspaces/WorkspacesEditor/WorkspacesEditor.csproj index 71e91979bd..9fa94a892b 100644 --- a/src/modules/Workspaces/WorkspacesEditor/WorkspacesEditor.csproj +++ b/src/modules/Workspaces/WorkspacesEditor/WorkspacesEditor.csproj @@ -1,7 +1,7 @@ - + - - + + PowerToys.WorkspacesEditor @@ -13,7 +13,7 @@ false false true - ..\..\..\..\$(Platform)\$(Configuration) + $(RepoRoot)$(Platform)\$(Configuration) diff --git a/src/modules/Workspaces/WorkspacesEditorUITest/Workspaces.Editor.UITests.csproj b/src/modules/Workspaces/WorkspacesEditorUITest/Workspaces.Editor.UITests.csproj index f0d2181522..f80bc502d5 100644 --- a/src/modules/Workspaces/WorkspacesEditorUITest/Workspaces.Editor.UITests.csproj +++ b/src/modules/Workspaces/WorkspacesEditorUITest/Workspaces.Editor.UITests.csproj @@ -1,5 +1,5 @@ - + latest @@ -13,7 +13,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\tests\Workspaces.UITests\ + $(RepoRoot)$(Platform)\$(Configuration)\tests\Workspaces.UITests\ diff --git a/src/modules/Workspaces/WorkspacesLauncherUI/WorkspacesLauncherUI.csproj b/src/modules/Workspaces/WorkspacesLauncherUI/WorkspacesLauncherUI.csproj index f55d30205f..0f9cc3c1c0 100644 --- a/src/modules/Workspaces/WorkspacesLauncherUI/WorkspacesLauncherUI.csproj +++ b/src/modules/Workspaces/WorkspacesLauncherUI/WorkspacesLauncherUI.csproj @@ -1,7 +1,7 @@ - + - - + + PowerToys.WorkspacesLauncherUI @@ -13,7 +13,7 @@ false false true - ..\..\..\..\$(Platform)\$(Configuration) + $(RepoRoot)$(Platform)\$(Configuration) diff --git a/src/modules/Workspaces/WorkspacesLib.UnitTests/WorkspacesLibUnitTests.vcxproj b/src/modules/Workspaces/WorkspacesLib.UnitTests/WorkspacesLibUnitTests.vcxproj index 1c7098f3b3..4e1ad16171 100644 --- a/src/modules/Workspaces/WorkspacesLib.UnitTests/WorkspacesLibUnitTests.vcxproj +++ b/src/modules/Workspaces/WorkspacesLib.UnitTests/WorkspacesLibUnitTests.vcxproj @@ -1,13 +1,13 @@ - + + {A85D4D9F-9A39-4B5D-8B5A-9F2D5C9A8B4C} Win32Proj WorkspacesLibUnitTests Workspaces.Lib.UnitTests - @@ -24,16 +24,16 @@ - ..\..\..\..\$(Platform)\$(Configuration)\tests\Workspaces\ + $(RepoRoot)$(Platform)\$(Configuration)\tests\Workspaces\ - ..\;..\WorkspacesLib\;$(SolutionDir)src\;$(SolutionDir)src\common;$(SolutionDir)src\common\Telemetry;..\..\;..\..\..\;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories) + ..\;..\WorkspacesLib\;$(RepoRoot)src\;$(RepoRoot)src\common;$(RepoRoot)src\common\Telemetry;..\..\;$(RepoRoot)src\;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories) WIN32;%(PreprocessorDefinitions) true - $(VCInstallDir)UnitTest\\lib;$(SolutionDir)$(Platform)\\$(Configuration)\\;%(AdditionalLibraryDirectories) + $(VCInstallDir)UnitTest\\lib;$(RepoRoot)$(Platform)\\$(Configuration)\\;%(AdditionalLibraryDirectories) propsys.lib;comctl32.lib;pathcch.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;Pathcch.lib;%(AdditionalDependencies) @@ -55,7 +55,7 @@ - + {6955446d-23f7-4023-9bb3-8657f904af99} @@ -64,13 +64,13 @@ - + 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}. - - + + \ No newline at end of file diff --git a/src/modules/Workspaces/WorkspacesLib/WorkspacesLib.vcxproj b/src/modules/Workspaces/WorkspacesLib/WorkspacesLib.vcxproj index e968036d59..b004fa9050 100644 --- a/src/modules/Workspaces/WorkspacesLib/WorkspacesLib.vcxproj +++ b/src/modules/Workspaces/WorkspacesLib/WorkspacesLib.vcxproj @@ -1,6 +1,7 @@ - + + 16.0 {b31fcc55-b5a4-4ea7-b414-2dceae6af332} @@ -8,7 +9,6 @@ WorkspacesLib WorkspacesLib - StaticLibrary @@ -23,12 +23,12 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ _LIB;%(PreprocessorDefinitions) - ..\;$(SolutionDir)src\;$(SolutionDir)src\common;$(SolutionDir)src\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories) + ..\;$(RepoRoot)src\;$(RepoRoot)src\common;$(RepoRoot)src\common\Telemetry;..\..\;$(RepoRoot)src\;%(AdditionalIncludeDirectories) @@ -68,10 +68,10 @@ - + {f055103b-f80b-4d0c-bf48-057c55620033} - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} @@ -79,17 +79,17 @@ - + - - + + 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}. - - - + + + \ No newline at end of file diff --git a/src/modules/Workspaces/WorkspacesModuleInterface/WorkspacesModuleInterface.vcxproj b/src/modules/Workspaces/WorkspacesModuleInterface/WorkspacesModuleInterface.vcxproj index 40d400daf4..54756310cd 100644 --- a/src/modules/Workspaces/WorkspacesModuleInterface/WorkspacesModuleInterface.vcxproj +++ b/src/modules/Workspaces/WorkspacesModuleInterface/WorkspacesModuleInterface.vcxproj @@ -1,6 +1,7 @@ - + + 15.0 {45285DF2-9742-4ECA-9AC9-58951FC26489} @@ -8,7 +9,6 @@ workspaces WorkspacesModuleInterface - DynamicLibrary @@ -23,13 +23,13 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ PowerToys.WorkspacesModuleInterface PROJECTS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - ..\;..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories) + ..\;$(RepoRoot)src\common\inc;$(RepoRoot)src\common\Telemetry;..\..\;$(RepoRoot)src\;%(AdditionalIncludeDirectories) $(OutDir)$(TargetName)$(TargetExt) @@ -48,10 +48,10 @@ - + {caba8dfb-823b-4bf2-93ac-3f31984150d9} - + {6955446d-23f7-4023-9bb3-8657f904af99} @@ -66,14 +66,14 @@ - + - + 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}. - - + + \ No newline at end of file diff --git a/src/modules/ZoomIt/ZoomItModuleInterface/ZoomItModuleInterface.vcxproj b/src/modules/ZoomIt/ZoomItModuleInterface/ZoomItModuleInterface.vcxproj index 955de8de91..d7848146cb 100644 --- a/src/modules/ZoomIt/ZoomItModuleInterface/ZoomItModuleInterface.vcxproj +++ b/src/modules/ZoomIt/ZoomItModuleInterface/ZoomItModuleInterface.vcxproj @@ -1,6 +1,7 @@ - + + 17.0 Win32Proj @@ -8,7 +9,6 @@ ZoomItModuleInterface ZoomItModuleInterface - DynamicLibrary true @@ -31,12 +31,12 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ PowerToys.ZoomItModuleInterface - ..\;$(SolutionDir)src\common\Telemetry;$(SolutionDir)src;%(AdditionalIncludeDirectories) + ..\.;$(RepoRoot)src\common\Telemetry;$(RepoRoot)src;%(AdditionalIncludeDirectories) $(OutDir)$(TargetName)$(TargetExt) @@ -90,24 +90,24 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} - - + + - + 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}. - - + + \ No newline at end of file diff --git a/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettingsInterop.vcxproj b/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettingsInterop.vcxproj index aa53283607..6fd8fbf3b3 100644 --- a/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettingsInterop.vcxproj +++ b/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettingsInterop.vcxproj @@ -1,6 +1,7 @@ - + + true true @@ -16,7 +17,6 @@ Windows Store 10.0 - DynamicLibrary @@ -46,7 +46,7 @@ PowerToys.ZoomItSettingsInterop - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ @@ -105,10 +105,10 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} @@ -116,17 +116,17 @@ - + - - + + 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}. - - - + + + \ No newline at end of file diff --git a/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.vcxproj b/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.vcxproj index f3d4b6f75d..34e3848743 100644 --- a/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.vcxproj +++ b/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.vcxproj @@ -1,10 +1,11 @@ + - + - + @@ -13,7 +14,6 @@ false true stdcpplatest - /await %(AdditionalOptions) _UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -64,7 +64,6 @@ Unicode Spectre - true true @@ -85,7 +84,7 @@ PowerToys.$(MSBuildProjectName) - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ @@ -93,7 +92,7 @@ true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true - ./../;$(SolutionDir)src\common\Telemetry;$(SolutionDir)src\common;$(SolutionDir)src\;./;%(AdditionalIncludeDirectories) + ./../;$(RepoRoot)src\common\Telemetry;$(RepoRoot)src\common;$(RepoRoot)src\;./;%(AdditionalIncludeDirectories) Windows @@ -109,7 +108,7 @@ true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true - ./../;$(SolutionDir)src\common\Telemetry;$(SolutionDir)src\common;$(SolutionDir)src\;./;%(AdditionalIncludeDirectories) + ./../;$(RepoRoot)src\common\Telemetry;$(RepoRoot)src\common;$(RepoRoot)src\;./;%(AdditionalIncludeDirectories) Windows @@ -158,19 +157,19 @@ - + {caba8dfb-823b-4bf2-93ac-3f31984150d9} - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} - + {1d5be09d-78c0-4fd7-af00-ae7c1af7c525} - + {8f021b46-362b-485c-bfba-ccf83e820cbd} @@ -185,17 +184,17 @@ - + - - + + 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}. - - - + + + \ No newline at end of file diff --git a/src/modules/alwaysontop/AlwaysOnTopModuleInterface/AlwaysOnTopModuleInterface.vcxproj b/src/modules/alwaysontop/AlwaysOnTopModuleInterface/AlwaysOnTopModuleInterface.vcxproj index c9be3969e2..8b1d4f4723 100644 --- a/src/modules/alwaysontop/AlwaysOnTopModuleInterface/AlwaysOnTopModuleInterface.vcxproj +++ b/src/modules/alwaysontop/AlwaysOnTopModuleInterface/AlwaysOnTopModuleInterface.vcxproj @@ -1,6 +1,7 @@ - + + 15.0 {48A0A19E-A0BE-4256-ACF8-CC3B80291AF9} @@ -8,7 +9,6 @@ alwaysontop AlwaysOnTopModuleInterface - DynamicLibrary @@ -22,7 +22,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ PowerToys.AlwaysOnTopModuleInterface @@ -30,7 +30,7 @@ _WINDOWS;_USRDLL;%(PreprocessorDefinitions) - ..\;..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories) + ..\;$(RepoRoot)src\common\inc;$(RepoRoot)src\common\Telemetry;..\..\;$(RepoRoot)src\;%(AdditionalIncludeDirectories) $(OutDir)$(TargetName)$(TargetExt) @@ -51,10 +51,10 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} @@ -66,17 +66,17 @@ - - - + + + - + 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}. - - - + + + \ No newline at end of file diff --git a/src/modules/awake/Awake.ModuleServices/Awake.ModuleServices.csproj b/src/modules/awake/Awake.ModuleServices/Awake.ModuleServices.csproj index 52588938e4..75be8c685d 100644 --- a/src/modules/awake/Awake.ModuleServices/Awake.ModuleServices.csproj +++ b/src/modules/awake/Awake.ModuleServices/Awake.ModuleServices.csproj @@ -1,7 +1,7 @@ - - + + enable diff --git a/src/modules/awake/Awake/Awake.csproj b/src/modules/awake/Awake/Awake.csproj index 5199709a11..605e105964 100644 --- a/src/modules/awake/Awake/Awake.csproj +++ b/src/modules/awake/Awake/Awake.csproj @@ -1,11 +1,11 @@ - + - - + + WinExe - ..\..\..\..\$(Platform)\$(Configuration) + $(RepoRoot)$(Platform)\$(Configuration) enable false false diff --git a/src/modules/awake/AwakeModuleInterface/AwakeModuleInterface.vcxproj b/src/modules/awake/AwakeModuleInterface/AwakeModuleInterface.vcxproj index 718e13e462..13770529fe 100644 --- a/src/modules/awake/AwakeModuleInterface/AwakeModuleInterface.vcxproj +++ b/src/modules/awake/AwakeModuleInterface/AwakeModuleInterface.vcxproj @@ -1,6 +1,7 @@ - + + 15.0 {5e7360a8-d048-4ed3-8f09-0bfd64c5529a} @@ -10,7 +11,6 @@ PowerToys.AwakeModuleInterface - DynamicLibrary @@ -24,12 +24,12 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ EXAMPLEPOWERTOY_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - ..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories) + $(RepoRoot)src\common\inc;$(RepoRoot)src\common\Telemetry;..\..\;$(RepoRoot)src\;%(AdditionalIncludeDirectories) $(OutDir)$(TargetName)$(TargetExt) @@ -49,10 +49,10 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} @@ -63,17 +63,17 @@ - + - - + + 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}. - - - + + + \ No newline at end of file diff --git a/src/modules/cmdNotFound/CmdNotFoundModuleInterface/CmdNotFoundModuleInterface.vcxproj b/src/modules/cmdNotFound/CmdNotFoundModuleInterface/CmdNotFoundModuleInterface.vcxproj index 58be2b1c5f..4a51422152 100644 --- a/src/modules/cmdNotFound/CmdNotFoundModuleInterface/CmdNotFoundModuleInterface.vcxproj +++ b/src/modules/cmdNotFound/CmdNotFoundModuleInterface/CmdNotFoundModuleInterface.vcxproj @@ -1,6 +1,7 @@ - + + 17.0 Win32Proj @@ -10,7 +11,6 @@ CmdNotFoundModuleInterface - DynamicLibrary true @@ -32,7 +32,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ @@ -68,7 +68,7 @@ - ..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories) + $(RepoRoot)src\common\Telemetry;..\..\;$(RepoRoot)src\;%(AdditionalIncludeDirectories) @@ -88,10 +88,10 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} @@ -102,15 +102,15 @@ - + - + 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}. - - + + \ No newline at end of file diff --git a/src/modules/cmdpal/CmdPalKeyboardService/CmdPalKeyboardService.vcxproj b/src/modules/cmdpal/CmdPalKeyboardService/CmdPalKeyboardService.vcxproj index cc5bdfeb26..5828339f4f 100644 --- a/src/modules/cmdpal/CmdPalKeyboardService/CmdPalKeyboardService.vcxproj +++ b/src/modules/cmdpal/CmdPalKeyboardService/CmdPalKeyboardService.vcxproj @@ -1,7 +1,8 @@ - + + true true @@ -39,7 +40,6 @@ - DynamicLibrary @@ -71,7 +71,7 @@ CmdPalKeyboardService - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ @@ -130,16 +130,16 @@ - + - + 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}. - - + + diff --git a/src/modules/cmdpal/CmdPalModuleInterface/CmdPalModuleInterface.vcxproj b/src/modules/cmdpal/CmdPalModuleInterface/CmdPalModuleInterface.vcxproj index ba6da61ec2..80d540d8da 100644 --- a/src/modules/cmdpal/CmdPalModuleInterface/CmdPalModuleInterface.vcxproj +++ b/src/modules/cmdpal/CmdPalModuleInterface/CmdPalModuleInterface.vcxproj @@ -1,7 +1,8 @@ - + + 17.0 @@ -11,7 +12,6 @@ 10.0 PowerToys.CmdPalModuleInterface - DynamicLibrary true @@ -35,13 +35,13 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} @@ -54,7 +54,7 @@ IS_DEV_BRANDING;%(PreprocessorDefinitions) - ..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories) + $(RepoRoot)src\common\inc;$(RepoRoot)src\common\Telemetry;..\..\;$(RepoRoot)src\;%(AdditionalIncludeDirectories) $(OutDir)$(TargetName)$(TargetExt) @@ -74,15 +74,15 @@ - + - + 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}. - - + + diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Microsoft.CmdPal.UI.ViewModels.csproj b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Microsoft.CmdPal.UI.ViewModels.csproj index 1c85aa939b..187c835e37 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Microsoft.CmdPal.UI.ViewModels.csproj +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Microsoft.CmdPal.UI.ViewModels.csproj @@ -1,6 +1,6 @@ - - - + + + enable diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/Microsoft.CmdPal.UI.csproj b/src/modules/cmdpal/Microsoft.CmdPal.UI/Microsoft.CmdPal.UI.csproj index 5500326b87..0ec7518188 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/Microsoft.CmdPal.UI.csproj +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/Microsoft.CmdPal.UI.csproj @@ -1,7 +1,7 @@ - - - - + + + + diff --git a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.Apps.UnitTests/Microsoft.CmdPal.Ext.Apps.UnitTests.csproj b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.Apps.UnitTests/Microsoft.CmdPal.Ext.Apps.UnitTests.csproj index d6a9638378..ed86ab834b 100644 --- a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.Apps.UnitTests/Microsoft.CmdPal.Ext.Apps.UnitTests.csproj +++ b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.Apps.UnitTests/Microsoft.CmdPal.Ext.Apps.UnitTests.csproj @@ -1,6 +1,6 @@ - + false diff --git a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.Bookmarks.UnitTests/Microsoft.CmdPal.Ext.Bookmarks.UnitTests.csproj b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.Bookmarks.UnitTests/Microsoft.CmdPal.Ext.Bookmarks.UnitTests.csproj index 07b6a9bfe5..22577866f4 100644 --- a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.Bookmarks.UnitTests/Microsoft.CmdPal.Ext.Bookmarks.UnitTests.csproj +++ b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.Bookmarks.UnitTests/Microsoft.CmdPal.Ext.Bookmarks.UnitTests.csproj @@ -1,6 +1,6 @@ - + false diff --git a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.Calc.UnitTests/Microsoft.CmdPal.Ext.Calc.UnitTests.csproj b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.Calc.UnitTests/Microsoft.CmdPal.Ext.Calc.UnitTests.csproj index d3f9adeeab..2080cafec7 100644 --- a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.Calc.UnitTests/Microsoft.CmdPal.Ext.Calc.UnitTests.csproj +++ b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.Calc.UnitTests/Microsoft.CmdPal.Ext.Calc.UnitTests.csproj @@ -1,6 +1,6 @@ - + false diff --git a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.ClipboardHistory.UnitTests/Microsoft.CmdPal.Ext.ClipboardHistory.UnitTests.csproj b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.ClipboardHistory.UnitTests/Microsoft.CmdPal.Ext.ClipboardHistory.UnitTests.csproj index 73abdbe772..6c03a216c7 100644 --- a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.ClipboardHistory.UnitTests/Microsoft.CmdPal.Ext.ClipboardHistory.UnitTests.csproj +++ b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.ClipboardHistory.UnitTests/Microsoft.CmdPal.Ext.ClipboardHistory.UnitTests.csproj @@ -1,6 +1,6 @@ - + false diff --git a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.Registry.UnitTests/Microsoft.CmdPal.Ext.Registry.UnitTests.csproj b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.Registry.UnitTests/Microsoft.CmdPal.Ext.Registry.UnitTests.csproj index 6bcc7bd5da..070fc9b91e 100644 --- a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.Registry.UnitTests/Microsoft.CmdPal.Ext.Registry.UnitTests.csproj +++ b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.Registry.UnitTests/Microsoft.CmdPal.Ext.Registry.UnitTests.csproj @@ -1,6 +1,6 @@ - + false diff --git a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.RemoteDesktop.UnitTests/Microsoft.CmdPal.Ext.RemoteDesktop.UnitTests.csproj b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.RemoteDesktop.UnitTests/Microsoft.CmdPal.Ext.RemoteDesktop.UnitTests.csproj index 0b998ec4ad..2e083ceab7 100644 --- a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.RemoteDesktop.UnitTests/Microsoft.CmdPal.Ext.RemoteDesktop.UnitTests.csproj +++ b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.RemoteDesktop.UnitTests/Microsoft.CmdPal.Ext.RemoteDesktop.UnitTests.csproj @@ -1,6 +1,6 @@ - + false diff --git a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.Shell.UnitTests/Microsoft.CmdPal.Ext.Shell.UnitTests.csproj b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.Shell.UnitTests/Microsoft.CmdPal.Ext.Shell.UnitTests.csproj index 74aeb04b39..aaa86d2f07 100644 --- a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.Shell.UnitTests/Microsoft.CmdPal.Ext.Shell.UnitTests.csproj +++ b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.Shell.UnitTests/Microsoft.CmdPal.Ext.Shell.UnitTests.csproj @@ -1,6 +1,6 @@ - + false diff --git a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.System.UnitTests/Microsoft.CmdPal.Ext.System.UnitTests.csproj b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.System.UnitTests/Microsoft.CmdPal.Ext.System.UnitTests.csproj index 64c5884136..9fa2332949 100644 --- a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.System.UnitTests/Microsoft.CmdPal.Ext.System.UnitTests.csproj +++ b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.System.UnitTests/Microsoft.CmdPal.Ext.System.UnitTests.csproj @@ -1,6 +1,6 @@ - + false diff --git a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.TimeDate.UnitTests/Microsoft.CmdPal.Ext.TimeDate.UnitTests.csproj b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.TimeDate.UnitTests/Microsoft.CmdPal.Ext.TimeDate.UnitTests.csproj index b19c5348eb..bd785d94da 100644 --- a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.TimeDate.UnitTests/Microsoft.CmdPal.Ext.TimeDate.UnitTests.csproj +++ b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.TimeDate.UnitTests/Microsoft.CmdPal.Ext.TimeDate.UnitTests.csproj @@ -1,6 +1,6 @@ - + false diff --git a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.UnitTestsBase/Microsoft.CmdPal.Ext.UnitTestBase.csproj b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.UnitTestsBase/Microsoft.CmdPal.Ext.UnitTestBase.csproj index ad01a7c507..9e12557b9a 100644 --- a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.UnitTestsBase/Microsoft.CmdPal.Ext.UnitTestBase.csproj +++ b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.UnitTestsBase/Microsoft.CmdPal.Ext.UnitTestBase.csproj @@ -1,6 +1,6 @@ - + - + false diff --git a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.WebSearch.UnitTests/Microsoft.CmdPal.Ext.WebSearch.UnitTests.csproj b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.WebSearch.UnitTests/Microsoft.CmdPal.Ext.WebSearch.UnitTests.csproj index d819beb7c7..601d3d147f 100644 --- a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.WebSearch.UnitTests/Microsoft.CmdPal.Ext.WebSearch.UnitTests.csproj +++ b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.WebSearch.UnitTests/Microsoft.CmdPal.Ext.WebSearch.UnitTests.csproj @@ -1,6 +1,6 @@ - + false diff --git a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.WindowWalker.UnitTests/Microsoft.CmdPal.Ext.WindowWalker.UnitTests.csproj b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.WindowWalker.UnitTests/Microsoft.CmdPal.Ext.WindowWalker.UnitTests.csproj index 8fde8f6f39..ec165aa5fc 100644 --- a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.WindowWalker.UnitTests/Microsoft.CmdPal.Ext.WindowWalker.UnitTests.csproj +++ b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.WindowWalker.UnitTests/Microsoft.CmdPal.Ext.WindowWalker.UnitTests.csproj @@ -1,6 +1,6 @@ - + false diff --git a/src/modules/cmdpal/Tests/Microsoft.CmdPal.UI.ViewModels.UnitTests/Microsoft.CmdPal.UI.ViewModels.UnitTests.csproj b/src/modules/cmdpal/Tests/Microsoft.CmdPal.UI.ViewModels.UnitTests/Microsoft.CmdPal.UI.ViewModels.UnitTests.csproj index 9282141355..fa7a95b5fb 100644 --- a/src/modules/cmdpal/Tests/Microsoft.CmdPal.UI.ViewModels.UnitTests/Microsoft.CmdPal.UI.ViewModels.UnitTests.csproj +++ b/src/modules/cmdpal/Tests/Microsoft.CmdPal.UI.ViewModels.UnitTests/Microsoft.CmdPal.UI.ViewModels.UnitTests.csproj @@ -1,6 +1,6 @@ - + false diff --git a/src/modules/cmdpal/Tests/Microsoft.CmdPal.UITests/Microsoft.CmdPal.UITests.csproj b/src/modules/cmdpal/Tests/Microsoft.CmdPal.UITests/Microsoft.CmdPal.UITests.csproj index 1ba6722489..ef3206262b 100644 --- a/src/modules/cmdpal/Tests/Microsoft.CmdPal.UITests/Microsoft.CmdPal.UITests.csproj +++ b/src/modules/cmdpal/Tests/Microsoft.CmdPal.UITests/Microsoft.CmdPal.UITests.csproj @@ -1,5 +1,5 @@ - - + + Microsoft.CmdPal.UITests diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Apps/Microsoft.CmdPal.Ext.Apps.csproj b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Apps/Microsoft.CmdPal.Ext.Apps.csproj index e59cdfd7e9..39f0e46f76 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Apps/Microsoft.CmdPal.Ext.Apps.csproj +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Apps/Microsoft.CmdPal.Ext.Apps.csproj @@ -1,6 +1,6 @@ - - - + + + Microsoft.CmdPal.Ext.Apps diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Bookmark/Microsoft.CmdPal.Ext.Bookmarks.csproj b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Bookmark/Microsoft.CmdPal.Ext.Bookmarks.csproj index f47b5e216f..f3194986d6 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Bookmark/Microsoft.CmdPal.Ext.Bookmarks.csproj +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Bookmark/Microsoft.CmdPal.Ext.Bookmarks.csproj @@ -1,6 +1,6 @@ - - - + + + Microsoft.CmdPal.Ext.Bookmarks enable diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Calc/Microsoft.CmdPal.Ext.Calc.csproj b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Calc/Microsoft.CmdPal.Ext.Calc.csproj index 2ec602d96a..2f22891c61 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Calc/Microsoft.CmdPal.Ext.Calc.csproj +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Calc/Microsoft.CmdPal.Ext.Calc.csproj @@ -1,6 +1,6 @@ - - - + + + Microsoft.CmdPal.Ext.Calc diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.ClipboardHistory/Microsoft.CmdPal.Ext.ClipboardHistory.csproj b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.ClipboardHistory/Microsoft.CmdPal.Ext.ClipboardHistory.csproj index b0c0617c34..5e1abb1a2e 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.ClipboardHistory/Microsoft.CmdPal.Ext.ClipboardHistory.csproj +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.ClipboardHistory/Microsoft.CmdPal.Ext.ClipboardHistory.csproj @@ -1,6 +1,6 @@ - - - + + + Microsoft.CmdPal.Ext.ClipboardHistory diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Microsoft.CmdPal.Ext.Indexer.csproj b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Microsoft.CmdPal.Ext.Indexer.csproj index 2c40afd19c..193c4ea203 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Microsoft.CmdPal.Ext.Indexer.csproj +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Microsoft.CmdPal.Ext.Indexer.csproj @@ -1,6 +1,6 @@ - - - + + + Microsoft.CmdPal.Ext.Indexer diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.PowerToys/Microsoft.CmdPal.Ext.PowerToys.csproj b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.PowerToys/Microsoft.CmdPal.Ext.PowerToys.csproj index dffff59b9f..8479699538 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.PowerToys/Microsoft.CmdPal.Ext.PowerToys.csproj +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.PowerToys/Microsoft.CmdPal.Ext.PowerToys.csproj @@ -1,7 +1,7 @@ - - - - + + + + WinExe diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Registry/Microsoft.CmdPal.Ext.Registry.csproj b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Registry/Microsoft.CmdPal.Ext.Registry.csproj index 24e8958ba9..cfcf15f8cc 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Registry/Microsoft.CmdPal.Ext.Registry.csproj +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Registry/Microsoft.CmdPal.Ext.Registry.csproj @@ -1,6 +1,6 @@ - - - + + + diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.RemoteDesktop/Microsoft.CmdPal.Ext.RemoteDesktop.csproj b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.RemoteDesktop/Microsoft.CmdPal.Ext.RemoteDesktop.csproj index 2a561b9b9e..3a45115bbb 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.RemoteDesktop/Microsoft.CmdPal.Ext.RemoteDesktop.csproj +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.RemoteDesktop/Microsoft.CmdPal.Ext.RemoteDesktop.csproj @@ -1,6 +1,6 @@ - - - + + + Microsoft.CmdPal.Ext.RemoteDesktop diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.System/Microsoft.CmdPal.Ext.System.csproj b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.System/Microsoft.CmdPal.Ext.System.csproj index ca178bb0b6..699af993c3 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.System/Microsoft.CmdPal.Ext.System.csproj +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.System/Microsoft.CmdPal.Ext.System.csproj @@ -1,6 +1,6 @@ - - - + + + diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.TimeDate/Microsoft.CmdPal.Ext.TimeDate.csproj b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.TimeDate/Microsoft.CmdPal.Ext.TimeDate.csproj index 886104347b..c1291472f1 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.TimeDate/Microsoft.CmdPal.Ext.TimeDate.csproj +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.TimeDate/Microsoft.CmdPal.Ext.TimeDate.csproj @@ -1,6 +1,6 @@ - - - + + + diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Microsoft.CmdPal.Ext.WebSearch.csproj b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Microsoft.CmdPal.Ext.WebSearch.csproj index 2f6665d8d0..843f5cf49e 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Microsoft.CmdPal.Ext.WebSearch.csproj +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Microsoft.CmdPal.Ext.WebSearch.csproj @@ -1,6 +1,6 @@ - - - + + + Microsoft.CmdPal.Ext.WebSearch diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WinGet/Microsoft.CmdPal.Ext.WinGet.csproj b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WinGet/Microsoft.CmdPal.Ext.WinGet.csproj index 6fd229449e..5b109bf34b 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WinGet/Microsoft.CmdPal.Ext.WinGet.csproj +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WinGet/Microsoft.CmdPal.Ext.WinGet.csproj @@ -1,5 +1,5 @@ - + Microsoft.CmdPal.Ext.WinGet diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowWalker/Microsoft.CmdPal.Ext.WindowWalker.csproj b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowWalker/Microsoft.CmdPal.Ext.WindowWalker.csproj index 29996fd177..f5233a47e4 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowWalker/Microsoft.CmdPal.Ext.WindowWalker.csproj +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowWalker/Microsoft.CmdPal.Ext.WindowWalker.csproj @@ -1,6 +1,6 @@ - - - + + + diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsServices/Microsoft.CmdPal.Ext.WindowsServices.csproj b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsServices/Microsoft.CmdPal.Ext.WindowsServices.csproj index 49c6771cc0..681b788cac 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsServices/Microsoft.CmdPal.Ext.WindowsServices.csproj +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsServices/Microsoft.CmdPal.Ext.WindowsServices.csproj @@ -1,6 +1,6 @@ - - - + + + diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsSettings/Microsoft.CmdPal.Ext.WindowsSettings.csproj b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsSettings/Microsoft.CmdPal.Ext.WindowsSettings.csproj index 44d89bb9a0..85b5d386ad 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsSettings/Microsoft.CmdPal.Ext.WindowsSettings.csproj +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsSettings/Microsoft.CmdPal.Ext.WindowsSettings.csproj @@ -1,6 +1,6 @@ - - - + + + Microsoft.CmdPal.Ext.WindowsSettings diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsTerminal/Microsoft.CmdPal.Ext.WindowsTerminal.csproj b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsTerminal/Microsoft.CmdPal.Ext.WindowsTerminal.csproj index 776e97e3d1..df8f3e3487 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsTerminal/Microsoft.CmdPal.Ext.WindowsTerminal.csproj +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsTerminal/Microsoft.CmdPal.Ext.WindowsTerminal.csproj @@ -1,6 +1,6 @@ - - - + + + diff --git a/src/modules/cmdpal/ext/ProcessMonitorExtension/ProcessMonitorExtension.csproj b/src/modules/cmdpal/ext/ProcessMonitorExtension/ProcessMonitorExtension.csproj index 8ec263d9bb..4ff1435154 100644 --- a/src/modules/cmdpal/ext/ProcessMonitorExtension/ProcessMonitorExtension.csproj +++ b/src/modules/cmdpal/ext/ProcessMonitorExtension/ProcessMonitorExtension.csproj @@ -1,5 +1,5 @@ - - + + WinExe ProcessMonitorExtension diff --git a/src/modules/cmdpal/ext/SamplePagesExtension/SamplePagesExtension.csproj b/src/modules/cmdpal/ext/SamplePagesExtension/SamplePagesExtension.csproj index 964211ddff..b9a8acc29d 100644 --- a/src/modules/cmdpal/ext/SamplePagesExtension/SamplePagesExtension.csproj +++ b/src/modules/cmdpal/ext/SamplePagesExtension/SamplePagesExtension.csproj @@ -1,6 +1,6 @@ - - - + + + WinExe SamplePagesExtension diff --git a/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Microsoft.CommandPalette.Extensions.Toolkit.csproj b/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Microsoft.CommandPalette.Extensions.Toolkit.csproj index 0e72a8a51a..c1e995056f 100644 --- a/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Microsoft.CommandPalette.Extensions.Toolkit.csproj +++ b/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Microsoft.CommandPalette.Extensions.Toolkit.csproj @@ -1,6 +1,6 @@ - - - + + + $(MSBuildThisFileDirectory)..\..\..\..\..\ diff --git a/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions/Microsoft.CommandPalette.Extensions.vcxproj b/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions/Microsoft.CommandPalette.Extensions.vcxproj index d6391bb748..140f49c46b 100644 --- a/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions/Microsoft.CommandPalette.Extensions.vcxproj +++ b/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions/Microsoft.CommandPalette.Extensions.vcxproj @@ -10,7 +10,6 @@ $(WindowsTargetPlatformVersion) - $(MSBuildThisFileDirectory)..\..\..\..\..\ true true true diff --git a/src/modules/colorPicker/ColorPicker.ModuleServices/ColorPicker.ModuleServices.csproj b/src/modules/colorPicker/ColorPicker.ModuleServices/ColorPicker.ModuleServices.csproj index 1efe5cdc8d..e3ab24a9bb 100644 --- a/src/modules/colorPicker/ColorPicker.ModuleServices/ColorPicker.ModuleServices.csproj +++ b/src/modules/colorPicker/ColorPicker.ModuleServices/ColorPicker.ModuleServices.csproj @@ -1,7 +1,7 @@ - - + + enable diff --git a/src/modules/colorPicker/ColorPicker/ColorPicker.vcxproj b/src/modules/colorPicker/ColorPicker/ColorPicker.vcxproj index a1df086509..ced2765475 100644 --- a/src/modules/colorPicker/ColorPicker/ColorPicker.vcxproj +++ b/src/modules/colorPicker/ColorPicker/ColorPicker.vcxproj @@ -1,8 +1,9 @@ - + + - + 15.0 @@ -11,7 +12,6 @@ ColorPicker ColorPicker - DynamicLibrary @@ -26,13 +26,13 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ PowerToys.ColorPicker EXAMPLEPOWERTOY_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - ..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories) + $(RepoRoot)src\common\inc;$(RepoRoot)src\common\Telemetry;..\..\;$(RepoRoot)src\;%(AdditionalIncludeDirectories) $(OutDir)$(TargetName)$(TargetExt) @@ -54,10 +54,10 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} @@ -71,15 +71,15 @@ - + - + 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}. - - + + \ No newline at end of file diff --git a/src/modules/colorPicker/ColorPickerUI.UnitTests/ColorPickerUI.UnitTests.csproj b/src/modules/colorPicker/ColorPickerUI.UnitTests/ColorPickerUI.UnitTests.csproj index 051e47add2..5035cc40c4 100644 --- a/src/modules/colorPicker/ColorPickerUI.UnitTests/ColorPickerUI.UnitTests.csproj +++ b/src/modules/colorPicker/ColorPickerUI.UnitTests/ColorPickerUI.UnitTests.csproj @@ -1,6 +1,6 @@ - + - + {F93C2817-C846-4259-84D8-B39A6B57C8DE} @@ -11,7 +11,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\tests\ColorPickerUI.UnitTest\ + $(RepoRoot)$(Platform)\$(Configuration)\tests\ColorPickerUI.UnitTest\ diff --git a/src/modules/colorPicker/ColorPickerUI/ColorPickerUI.csproj b/src/modules/colorPicker/ColorPickerUI/ColorPickerUI.csproj index d1c55e3db7..2a09975846 100644 --- a/src/modules/colorPicker/ColorPickerUI/ColorPickerUI.csproj +++ b/src/modules/colorPicker/ColorPickerUI/ColorPickerUI.csproj @@ -1,12 +1,12 @@ - + - - + + PowerToys.ColorPickerUI PowerToys ColorPicker - ..\..\..\..\$(Platform)\$(Configuration) + $(RepoRoot)$(Platform)\$(Configuration) false false true diff --git a/src/modules/colorPicker/UITest-ColorPicker/UITest-ColorPicker.csproj b/src/modules/colorPicker/UITest-ColorPicker/UITest-ColorPicker.csproj index effe513069..bc360c2c91 100644 --- a/src/modules/colorPicker/UITest-ColorPicker/UITest-ColorPicker.csproj +++ b/src/modules/colorPicker/UITest-ColorPicker/UITest-ColorPicker.csproj @@ -1,6 +1,6 @@ - + - + {6880CE86-5B71-4440-9795-79A325F95747} @@ -14,7 +14,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\tests\UITests-ColorPicker\ + $(RepoRoot)$(Platform)\$(Configuration)\tests\UITests-ColorPicker\ diff --git a/src/modules/fancyzones/FancyZones.FuzzTests/FancyZones.FuzzTests.csproj b/src/modules/fancyzones/FancyZones.FuzzTests/FancyZones.FuzzTests.csproj index dd1665bc0d..bf4aa9f551 100644 --- a/src/modules/fancyzones/FancyZones.FuzzTests/FancyZones.FuzzTests.csproj +++ b/src/modules/fancyzones/FancyZones.FuzzTests/FancyZones.FuzzTests.csproj @@ -1,11 +1,11 @@ - - + + - ..\..\..\..\$(Platform)\$(Configuration)\tests\FancyZones.FuzzTests\ + $(RepoRoot)$(Platform)\$(Configuration)\tests\FancyZones.FuzzTests\ diff --git a/src/modules/fancyzones/FancyZones.UITests/FancyZones.UITests.csproj b/src/modules/fancyzones/FancyZones.UITests/FancyZones.UITests.csproj index 4bcf755e27..2149093bbf 100644 --- a/src/modules/fancyzones/FancyZones.UITests/FancyZones.UITests.csproj +++ b/src/modules/fancyzones/FancyZones.UITests/FancyZones.UITests.csproj @@ -1,6 +1,6 @@ - + - + {69D76A76-6EF6-4846-94CD-EAAF0CAC9F15} @@ -14,7 +14,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\tests\FancyZones.UITests\ + $(RepoRoot)$(Platform)\$(Configuration)\tests\FancyZones.UITests\ diff --git a/src/modules/fancyzones/FancyZonesCLI/FancyZonesCLI.csproj b/src/modules/fancyzones/FancyZonesCLI/FancyZonesCLI.csproj index f1198d5b40..419c12cfd0 100644 --- a/src/modules/fancyzones/FancyZonesCLI/FancyZonesCLI.csproj +++ b/src/modules/fancyzones/FancyZonesCLI/FancyZonesCLI.csproj @@ -1,7 +1,7 @@ - - + + PowerToys.FancyZonesCLI @@ -11,7 +11,7 @@ x64;ARM64 false false - ..\..\..\..\$(Platform)\$(Configuration) + $(RepoRoot)$(Platform)\$(Configuration) FancyZonesCLI $(NoWarn);SA1500;SA1402;CA1852;CA1863;CA1305 diff --git a/src/modules/fancyzones/FancyZonesEditor.UITests/FancyZonesEditor.UITests.csproj b/src/modules/fancyzones/FancyZonesEditor.UITests/FancyZonesEditor.UITests.csproj index 5164c50962..fa35f121ea 100644 --- a/src/modules/fancyzones/FancyZonesEditor.UITests/FancyZonesEditor.UITests.csproj +++ b/src/modules/fancyzones/FancyZonesEditor.UITests/FancyZonesEditor.UITests.csproj @@ -1,6 +1,6 @@ - + - + {9BAFFC28-E1EF-4C14-A101-EEBFC0A50D83} @@ -14,7 +14,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\tests\UITests-FancyZonesEditor\ + $(RepoRoot)$(Platform)\$(Configuration)\tests\UITests-FancyZonesEditor\ diff --git a/src/modules/fancyzones/FancyZonesEditor.UnitTests/FancyZonesEditor.UnitTests.csproj b/src/modules/fancyzones/FancyZonesEditor.UnitTests/FancyZonesEditor.UnitTests.csproj index a6056cd2aa..00b2f79256 100644 --- a/src/modules/fancyzones/FancyZonesEditor.UnitTests/FancyZonesEditor.UnitTests.csproj +++ b/src/modules/fancyzones/FancyZonesEditor.UnitTests/FancyZonesEditor.UnitTests.csproj @@ -1,6 +1,6 @@ - + enable @@ -9,7 +9,7 @@ false true - ..\..\..\..\$(Platform)\$(Configuration)\tests\UnitTest-FancyZonesEditor\ + $(RepoRoot)$(Platform)\$(Configuration)\tests\UnitTest-FancyZonesEditor\ diff --git a/src/modules/fancyzones/FancyZonesEditorCommon/FancyZonesEditorCommon.csproj b/src/modules/fancyzones/FancyZonesEditorCommon/FancyZonesEditorCommon.csproj index 3b5d9d0d4f..ebed411a81 100644 --- a/src/modules/fancyzones/FancyZonesEditorCommon/FancyZonesEditorCommon.csproj +++ b/src/modules/fancyzones/FancyZonesEditorCommon/FancyZonesEditorCommon.csproj @@ -1,6 +1,6 @@ - + - + PowerToys FancyZonesEditorCommon @@ -12,6 +12,6 @@ - ..\..\..\..\$(Platform)\$(Configuration)\FancyZonesEditorCommon\ + $(RepoRoot)$(Platform)\$(Configuration)\FancyZonesEditorCommon\ diff --git a/src/modules/fancyzones/FancyZonesLib/FancyZonesLib.vcxproj b/src/modules/fancyzones/FancyZonesLib/FancyZonesLib.vcxproj index 74574dd93f..272e9eb823 100644 --- a/src/modules/fancyzones/FancyZonesLib/FancyZonesLib.vcxproj +++ b/src/modules/fancyzones/FancyZonesLib/FancyZonesLib.vcxproj @@ -1,8 +1,9 @@ - + + - + 16.0 @@ -11,7 +12,6 @@ FancyZonesLib FancyZonesLib - StaticLibrary @@ -26,12 +26,12 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ _LIB;%(PreprocessorDefinitions) - ..\;..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories) + ..\;$(RepoRoot)src\common\inc;$(RepoRoot)src\common\Telemetry;..\..\;$(RepoRoot)src\;%(AdditionalIncludeDirectories) @@ -140,31 +140,31 @@ - + {caba8dfb-823b-4bf2-93ac-3f31984150d9} - + {1d5be09d-78c0-4fd7-af00-ae7c1af7c525} - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + - - + + 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}. - - - + + + \ No newline at end of file diff --git a/src/modules/fancyzones/FancyZonesModuleInterface/FancyZonesModuleInterface.vcxproj b/src/modules/fancyzones/FancyZonesModuleInterface/FancyZonesModuleInterface.vcxproj index c22808ddce..aff24548ba 100644 --- a/src/modules/fancyzones/FancyZonesModuleInterface/FancyZonesModuleInterface.vcxproj +++ b/src/modules/fancyzones/FancyZonesModuleInterface/FancyZonesModuleInterface.vcxproj @@ -1,6 +1,7 @@ - + + 15.0 {48804216-2A0E-4168-A6D8-9CD068D14227} @@ -8,7 +9,6 @@ fancyzones FancyZonesModuleInterface - DynamicLibrary @@ -23,13 +23,13 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ PowerToys.FancyZonesModuleInterface FANCYZONES_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - ..\;..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories) + ..\;$(RepoRoot)src\common\inc;$(RepoRoot)src\common\Telemetry;..\..\;$(RepoRoot)src\;%(AdditionalIncludeDirectories) $(OutDir)$(TargetName)$(TargetExt) @@ -48,13 +48,13 @@ - + {caba8dfb-823b-4bf2-93ac-3f31984150d9} - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} @@ -69,16 +69,16 @@ - - + + - + 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}. - - - + + + \ No newline at end of file diff --git a/src/modules/fancyzones/FancyZonesTests/UnitTests/UnitTests.vcxproj b/src/modules/fancyzones/FancyZonesTests/UnitTests/UnitTests.vcxproj index 0eb927d85d..1632cda340 100644 --- a/src/modules/fancyzones/FancyZonesTests/UnitTests/UnitTests.vcxproj +++ b/src/modules/fancyzones/FancyZonesTests/UnitTests/UnitTests.vcxproj @@ -1,6 +1,7 @@ - + + 16.0 {9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9} @@ -9,7 +10,6 @@ NativeUnitTestProject FancyZones.UnitTests - DynamicLibrary false @@ -31,7 +31,7 @@ - ..\..\..\..\common\Telemetry;..\..\..\..\;..\..\;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories) + $(RepoRoot)src\common\Telemetry;$(RepoRoot)src\;..\..\;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories) UNIT_TESTS;%(PreprocessorDefinitions) @@ -67,10 +67,10 @@ - + {caba8dfb-823b-4bf2-93ac-3f31984150d9} - + {6955446d-23f7-4023-9bb3-8657f904af99} @@ -83,18 +83,18 @@ - + - - + + 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}. - - - + + + - \ No newline at end of file + diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj b/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj index b7d7fcce1c..fe8a16b86f 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj +++ b/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj @@ -1,7 +1,7 @@ - + - - + + PowerToys.FancyZonesEditor @@ -14,7 +14,7 @@ false false true - ..\..\..\..\..\$(Platform)\$(Configuration) + $(RepoRoot)$(Platform)\$(Configuration) {5CCC8468-DEC8-4D36-99D4-5C891BEBD481} {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} true diff --git a/src/modules/imageresizer/ImageResizerCLI/ImageResizerCLI.csproj b/src/modules/imageresizer/ImageResizerCLI/ImageResizerCLI.csproj index 41de902d6e..05efacafd8 100644 --- a/src/modules/imageresizer/ImageResizerCLI/ImageResizerCLI.csproj +++ b/src/modules/imageresizer/ImageResizerCLI/ImageResizerCLI.csproj @@ -1,8 +1,8 @@ - - - + + + PowerToys.ImageResizerCLI @@ -12,7 +12,7 @@ x64;ARM64 false false - ..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps\ + $(RepoRoot)$(Platform)\$(Configuration)\WinUI3Apps\ PowerToys.ImageResizerCLI $(NoWarn);SA1500;SA1402;CA1852 diff --git a/src/modules/imageresizer/ImageResizerContextMenu/ImageResizerContextMenu.vcxproj b/src/modules/imageresizer/ImageResizerContextMenu/ImageResizerContextMenu.vcxproj index 66fb2ace0d..94cec2efb0 100644 --- a/src/modules/imageresizer/ImageResizerContextMenu/ImageResizerContextMenu.vcxproj +++ b/src/modules/imageresizer/ImageResizerContextMenu/ImageResizerContextMenu.vcxproj @@ -1,15 +1,15 @@ - + + - + Win32Proj {93b72a06-c8bd-484f-a6f7-c9f280b150bf} ImageResizerContextMenu - DynamicLibrary true @@ -34,7 +34,7 @@ PowerToys.ImageResizerContextMenu $(SolutionDir)$(Platform)\$(Configuration)\TemporaryBuild\obj\$(ProjectName)\ - ..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps\ + $(RepoRoot)$(Platform)\$(Configuration)\WinUI3Apps\ @@ -42,7 +42,7 @@ true _DEBUG;IMAGERESIZERCONTEXTMENU_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true - ..\ImageResizerLib;..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories) + ..\ImageResizerLib;$(RepoRoot)src\common\inc;$(RepoRoot)src\common\Telemetry;..\..\;$(RepoRoot)src\;%(AdditionalIncludeDirectories) Windows @@ -63,7 +63,7 @@ MakeAppx.exe pack /d . /p $(OutDir)ImageResizerContextMenuPackage.msix /nvtrue NDEBUG;IMAGERESIZERCONTEXTMENU_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true - ..\ImageResizerLib;..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories) + ..\ImageResizerLib;$(RepoRoot)src\common\inc;$(RepoRoot)src\common\Telemetry;..\..\;$(RepoRoot)src\;%(AdditionalIncludeDirectories) Windows @@ -125,13 +125,13 @@ MakeAppx.exe pack /d . /p $(OutDir)ImageResizerContextMenuPackage.msix /nv - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} - + {8f021b46-362b-485c-bfba-ccf83e820cbd} @@ -142,17 +142,17 @@ MakeAppx.exe pack /d . /p $(OutDir)ImageResizerContextMenuPackage.msix /nv - + - - + + 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}. - - - + + + \ No newline at end of file diff --git a/src/modules/imageresizer/ImageResizerLib/ImageResizerLib.vcxproj b/src/modules/imageresizer/ImageResizerLib/ImageResizerLib.vcxproj index fa5b8ff18e..e6c755f2e5 100644 --- a/src/modules/imageresizer/ImageResizerLib/ImageResizerLib.vcxproj +++ b/src/modules/imageresizer/ImageResizerLib/ImageResizerLib.vcxproj @@ -1,6 +1,7 @@ - + + Win32Proj {18b3db45-4ffe-4d01-97d6-5223feee1853} @@ -11,7 +12,6 @@ Unicode - true @@ -29,7 +29,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps\ + $(RepoRoot)$(Platform)\$(Configuration)\WinUI3Apps\ PowerToys.$(ProjectName) @@ -38,7 +38,7 @@ Level3 WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - ..\..\..\common\Telemetry;..\..\..\;%(AdditionalIncludeDirectories) + $(RepoRoot)src\common\Telemetry;$(RepoRoot)src\;%(AdditionalIncludeDirectories) @@ -52,7 +52,7 @@ true true WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - ..\..\..\common\Telemetry;..\..\..\;%(AdditionalIncludeDirectories) + $(RepoRoot)src\common\Telemetry;$(RepoRoot)src\;%(AdditionalIncludeDirectories) @@ -81,13 +81,13 @@ - + 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}. - - + + \ No newline at end of file diff --git a/src/modules/imageresizer/dll/ImageResizerExt.vcxproj b/src/modules/imageresizer/dll/ImageResizerExt.vcxproj index 53a1d88d14..24a60e1439 100644 --- a/src/modules/imageresizer/dll/ImageResizerExt.vcxproj +++ b/src/modules/imageresizer/dll/ImageResizerExt.vcxproj @@ -1,15 +1,15 @@ - + - + + - + {0B43679E-EDFA-4DA0-AD30-F4628B308B1B} AtlProj false - DynamicLibrary Static @@ -26,13 +26,13 @@ true - ..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps\ + $(RepoRoot)$(Platform)\$(Configuration)\WinUI3Apps\ PowerToys.ImageResizerExt _WINDOWS;_USRDLL;%(PreprocessorDefinitions) - ..\ImageResizerLib;..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories) + ..\ImageResizerLib;$(RepoRoot)src\common\inc;$(RepoRoot)src\common\Telemetry;..\..\;$(RepoRoot)src\;%(AdditionalIncludeDirectories) .\ImageResizerExt.def @@ -117,16 +117,16 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} - + {8f021b46-362b-485c-bfba-ccf83e820cbd} - + {98537082-0fdb-40de-abd8-0dc5a4269bab} @@ -140,15 +140,15 @@ - + - + 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}. - - + + \ No newline at end of file diff --git a/src/modules/imageresizer/tests/ImageResizer.UnitTests.csproj b/src/modules/imageresizer/tests/ImageResizer.UnitTests.csproj index d30ab80a2e..ceaa169692 100644 --- a/src/modules/imageresizer/tests/ImageResizer.UnitTests.csproj +++ b/src/modules/imageresizer/tests/ImageResizer.UnitTests.csproj @@ -1,6 +1,6 @@ - + - + {E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8} diff --git a/src/modules/imageresizer/ui/ImageResizerUI.csproj b/src/modules/imageresizer/ui/ImageResizerUI.csproj index e03725507f..f2bec0c3b6 100644 --- a/src/modules/imageresizer/ui/ImageResizerUI.csproj +++ b/src/modules/imageresizer/ui/ImageResizerUI.csproj @@ -1,11 +1,11 @@ - + - - + + PowerToys.ImageResizer - ..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps\ + $(RepoRoot)$(Platform)\$(Configuration)\WinUI3Apps\ false false true diff --git a/src/modules/keyboardmanager/Directory.Build.targets b/src/modules/keyboardmanager/Directory.Build.targets index dfcf63e016..d25c78388a 100644 --- a/src/modules/keyboardmanager/Directory.Build.targets +++ b/src/modules/keyboardmanager/Directory.Build.targets @@ -2,6 +2,6 @@ - + \ No newline at end of file diff --git a/src/modules/keyboardmanager/KeyboardManagerEditorLibraryWrapper/KeyboardManagerEditorLibraryWrapper.vcxproj b/src/modules/keyboardmanager/KeyboardManagerEditorLibraryWrapper/KeyboardManagerEditorLibraryWrapper.vcxproj index 59ed2bfe08..a6dbe57a7d 100644 --- a/src/modules/keyboardmanager/KeyboardManagerEditorLibraryWrapper/KeyboardManagerEditorLibraryWrapper.vcxproj +++ b/src/modules/keyboardmanager/KeyboardManagerEditorLibraryWrapper/KeyboardManagerEditorLibraryWrapper.vcxproj @@ -1,6 +1,7 @@ - + + Debug @@ -37,7 +38,6 @@ PowerToys.KeyboardManagerEditorLibraryWrapper - DynamicLibrary true @@ -149,14 +149,14 @@ _DEBUG;KEYBOARDMANAGEREDITORLIBRARYWRAPPER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) false Use - ./;$(SolutionDir)src\modules\;$(SolutionDir)src\modules\KeyboardManager\KeyboardManagerEditorLibrary\;$(SolutionDir)src\common\Display;$(SolutionDir)src\common\inc;$(SolutionDir)src\common\Telemetry;$(SolutionDir)src;%(AdditionalIncludeDirectories) + ./;$(RepoRoot)src\modules\;$(RepoRoot)src\modules\KeyboardManager\KeyboardManagerEditorLibrary\;$(RepoRoot)src\common\Display;$(RepoRoot)src\common\inc;$(RepoRoot)src\common\Telemetry;$(RepoRoot)src;%(AdditionalIncludeDirectories) false Windows true false - $(SolutionDir)$(Platform)\$(ConfigurationName);%(AdditionalLibraryDirectories) + $(RepoRoot)$(Platform)\$(ConfigurationName);%(AdditionalLibraryDirectories) @@ -166,14 +166,14 @@ _DEBUG;KEYBOARDMANAGEREDITORLIBRARYWRAPPER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) false Use - ./;$(SolutionDir)src\modules\;$(SolutionDir)src\modules\KeyboardManager\KeyboardManagerEditorLibrary\;$(SolutionDir)src\common\Display;$(SolutionDir)src\common\inc;$(SolutionDir)src\common\Telemetry;$(SolutionDir)src;%(AdditionalIncludeDirectories) + ./;$(RepoRoot)src\modules\;$(RepoRoot)src\modules\KeyboardManager\KeyboardManagerEditorLibrary\;$(RepoRoot)src\common\Display;$(RepoRoot)src\common\inc;$(RepoRoot)src\common\Telemetry;$(RepoRoot)src;%(AdditionalIncludeDirectories) false Windows true false - $(SolutionDir)$(Platform)\$(ConfigurationName);%(AdditionalLibraryDirectories) + $(RepoRoot)$(Platform)\$(ConfigurationName);%(AdditionalLibraryDirectories) @@ -185,7 +185,7 @@ NDEBUG;KEYBOARDMANAGEREDITORLIBRARYWRAPPER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) false Use - ./;$(SolutionDir)src\modules\;$(SolutionDir)src\modules\KeyboardManager\KeyboardManagerEditorLibrary\;$(SolutionDir)src\common\Display;$(SolutionDir)src\common\inc;$(SolutionDir)src\common\Telemetry;$(SolutionDir)src;%(AdditionalIncludeDirectories) + ./;$(RepoRoot)src\modules\;$(RepoRoot)src\modules\KeyboardManager\KeyboardManagerEditorLibrary\;$(RepoRoot)src\common\Display;$(RepoRoot)src\common\inc;$(RepoRoot)src\common\Telemetry;$(RepoRoot)src;%(AdditionalIncludeDirectories) true ProgramDatabase @@ -195,7 +195,7 @@ true true false - $(SolutionDir)$(Platform)\$(ConfigurationName);%(AdditionalLibraryDirectories) + $(RepoRoot)$(Platform)\$(ConfigurationName);%(AdditionalLibraryDirectories) @@ -207,7 +207,7 @@ NDEBUG;KEYBOARDMANAGEREDITORLIBRARYWRAPPER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) false Use - ./;$(SolutionDir)src\modules\;$(SolutionDir)src\modules\KeyboardManager\KeyboardManagerEditorLibrary\;$(SolutionDir)src\common\Display;$(SolutionDir)src\common\inc;$(SolutionDir)src\common\Telemetry;$(SolutionDir)src;%(AdditionalIncludeDirectories) + ./;$(RepoRoot)src\modules\;$(RepoRoot)src\modules\KeyboardManager\KeyboardManagerEditorLibrary\;$(RepoRoot)src\common\Display;$(RepoRoot)src\common\inc;$(RepoRoot)src\common\Telemetry;$(RepoRoot)src;%(AdditionalIncludeDirectories) Windows @@ -239,7 +239,7 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} @@ -253,15 +253,15 @@ - + - + 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}. - - + + \ No newline at end of file diff --git a/src/modules/keyboardmanager/KeyboardManagerEditorTest/KeyboardManagerEditorTest.vcxproj b/src/modules/keyboardmanager/KeyboardManagerEditorTest/KeyboardManagerEditorTest.vcxproj index e0f18a51d9..cc5b93d451 100644 --- a/src/modules/keyboardmanager/KeyboardManagerEditorTest/KeyboardManagerEditorTest.vcxproj +++ b/src/modules/keyboardmanager/KeyboardManagerEditorTest/KeyboardManagerEditorTest.vcxproj @@ -1,6 +1,7 @@ - + + 16.0 {62173D9A-6724-4C00-A1C8-FB646480A9EC} @@ -9,7 +10,6 @@ NativeUnitTestProject KeyboardManager.Editor.UnitTests - DynamicLibrary @@ -30,7 +30,7 @@ - $(VCInstallDir)UnitTest\include;$(SolutionDir)src\;$(SolutionDir)src\modules;$(SolutionDir)src\common\Telemetry;%(AdditionalIncludeDirectories) + $(VCInstallDir)UnitTest\include;$(RepoRoot)src\;$(RepoRoot)src\modules;$(RepoRoot)src\common\Telemetry;%(AdditionalIncludeDirectories) true @@ -50,7 +50,7 @@ - + {6955446d-23f7-4023-9bb3-8657f904af99} @@ -68,13 +68,13 @@ - + 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}. - - + + \ No newline at end of file diff --git a/src/modules/keyboardmanager/KeyboardManagerEditorUI/KeyboardManagerEditorUI.csproj b/src/modules/keyboardmanager/KeyboardManagerEditorUI/KeyboardManagerEditorUI.csproj index 4d278fa0c1..b71aa65515 100644 --- a/src/modules/keyboardmanager/KeyboardManagerEditorUI/KeyboardManagerEditorUI.csproj +++ b/src/modules/keyboardmanager/KeyboardManagerEditorUI/KeyboardManagerEditorUI.csproj @@ -1,7 +1,7 @@ - + - - + + WinExe @@ -15,7 +15,7 @@ false false PowerToys.KeyboardManagerEditorUI - ..\..\..\..\$(Platform)\$(Configuration)\$(MSBuildProjectName) + $(RepoRoot)$(Platform)\$(Configuration)\$(MSBuildProjectName) diff --git a/src/modules/keyboardmanager/KeyboardManagerEngine/KeyboardManagerEngine.vcxproj b/src/modules/keyboardmanager/KeyboardManagerEngine/KeyboardManagerEngine.vcxproj index 96190cb926..a768d37904 100644 --- a/src/modules/keyboardmanager/KeyboardManagerEngine/KeyboardManagerEngine.vcxproj +++ b/src/modules/keyboardmanager/KeyboardManagerEngine/KeyboardManagerEngine.vcxproj @@ -1,6 +1,7 @@ - + + true true @@ -11,7 +12,6 @@ Win32Proj KeyboardManagerEngine - Application @@ -34,11 +34,11 @@ PowerToys.$(MSBuildProjectName) - ..\..\..\..\$(Platform)\$(Configuration)\$(ProjectName)\ + $(RepoRoot)$(Platform)\$(Configuration)\$(ProjectName)\ - $(SolutionDir)src\;$(SolutionDir)src\modules;$(SolutionDir)src\common\Telemetry;%(AdditionalIncludeDirectories) + $(RepoRoot)src\;$(RepoRoot)src\modules;$(RepoRoot)src\common\Telemetry;%(AdditionalIncludeDirectories) EXAMPLEPOWERTOY_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) @@ -61,13 +61,13 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} - + {8f021b46-362b-485c-bfba-ccf83e820cbd} @@ -81,15 +81,15 @@ - + - + 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}. - - + + \ No newline at end of file diff --git a/src/modules/keyboardmanager/KeyboardManagerEngineLibrary/KeyboardManagerEngineLibrary.vcxproj b/src/modules/keyboardmanager/KeyboardManagerEngineLibrary/KeyboardManagerEngineLibrary.vcxproj index bc3f81219d..b34eef150a 100644 --- a/src/modules/keyboardmanager/KeyboardManagerEngineLibrary/KeyboardManagerEngineLibrary.vcxproj +++ b/src/modules/keyboardmanager/KeyboardManagerEngineLibrary/KeyboardManagerEngineLibrary.vcxproj @@ -1,16 +1,16 @@ - + + 16.0 Win32Proj {e496b7fc-1e99-4bab-849b-0e8367040b02} KeyboardManagerEngineLibrary - StaticLibrary - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ @@ -27,7 +27,7 @@ Level3 - $(SolutionDir)src\;$(SolutionDir)src\modules;$(SolutionDir)src\common\Telemetry;%(AdditionalIncludeDirectories) + $(RepoRoot)src\;$(RepoRoot)src\modules;$(RepoRoot)src\common\Telemetry;%(AdditionalIncludeDirectories) true _LIB;%(PreprocessorDefinitions) @@ -57,17 +57,17 @@ - + - - + + 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}. - - - + + + \ No newline at end of file diff --git a/src/modules/keyboardmanager/KeyboardManagerEngineTest/KeyboardManagerEngineTest.vcxproj b/src/modules/keyboardmanager/KeyboardManagerEngineTest/KeyboardManagerEngineTest.vcxproj index f8c53f61aa..86a41730f0 100644 --- a/src/modules/keyboardmanager/KeyboardManagerEngineTest/KeyboardManagerEngineTest.vcxproj +++ b/src/modules/keyboardmanager/KeyboardManagerEngineTest/KeyboardManagerEngineTest.vcxproj @@ -1,6 +1,7 @@ - + + 16.0 {7f4b3a60-bc27-45a7-8000-68b0b6ea7466} @@ -9,7 +10,6 @@ NativeUnitTestProject KeyboardManager.Engine.UnitTests - DynamicLibrary @@ -30,7 +30,7 @@ - $(VCInstallDir)UnitTest\include;$(SolutionDir)src\;$(SolutionDir)src\modules;$(SolutionDir)src\common\Telemetry;%(AdditionalIncludeDirectories) + $(VCInstallDir)UnitTest\include;$(RepoRoot)src\;$(RepoRoot)src\modules;$(RepoRoot)src\common\Telemetry;%(AdditionalIncludeDirectories) true @@ -57,7 +57,7 @@ - + {6955446d-23f7-4023-9bb3-8657f904af99} @@ -72,13 +72,13 @@ - + 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}. - - + + \ No newline at end of file diff --git a/src/modules/keyboardmanager/common/KeyboardManagerCommon.vcxproj b/src/modules/keyboardmanager/common/KeyboardManagerCommon.vcxproj index e4192fce4f..889776f9e1 100644 --- a/src/modules/keyboardmanager/common/KeyboardManagerCommon.vcxproj +++ b/src/modules/keyboardmanager/common/KeyboardManagerCommon.vcxproj @@ -1,12 +1,12 @@ - + + 16.0 {8AFFA899-0B73-49EC-8C50-0FADDA57B2FC} KeyboardManagerCommon - StaticLibrary @@ -21,12 +21,12 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ _CONSOLE;%(PreprocessorDefinitions) - ..\;..\..\..\;..\..\..\common\telemetry;..\..\;%(AdditionalIncludeDirectories) + ..\;$(RepoRoot)src\;$(RepoRoot)src\common\telemetry;..\..\;%(AdditionalIncludeDirectories) %(AdditionalOptions) @@ -37,7 +37,7 @@ - + @@ -60,13 +60,13 @@ - + {7319089e-46d6-4400-bc65-e39bdf1416ee} - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} @@ -74,15 +74,15 @@ - + - + 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}. - - + + \ No newline at end of file diff --git a/src/modules/keyboardmanager/dll/KeyboardManager.vcxproj b/src/modules/keyboardmanager/dll/KeyboardManager.vcxproj index 1b608bb63c..e19a11c1ce 100644 --- a/src/modules/keyboardmanager/dll/KeyboardManager.vcxproj +++ b/src/modules/keyboardmanager/dll/KeyboardManager.vcxproj @@ -1,6 +1,7 @@ - + + 15.0 {89f34af7-1c34-4a72-aa6e-534bcf972bd9} @@ -8,7 +9,6 @@ KeyboardManager KeyboardManager - DynamicLibrary @@ -25,12 +25,12 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ PowerToys.KeyboardManager - $(SolutionDir)src\;$(SolutionDir)src\modules;$(SolutionDir)src\common\Telemetry;%(AdditionalIncludeDirectories) + $(RepoRoot)src\;$(RepoRoot)src\modules;$(RepoRoot)src\common\Telemetry;%(AdditionalIncludeDirectories) EXAMPLEPOWERTOY_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) @@ -53,10 +53,10 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} @@ -71,18 +71,18 @@ - + - + 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}. - - + + - + \ No newline at end of file diff --git a/src/modules/launcher/Microsoft.Launcher/Microsoft.Launcher.vcxproj b/src/modules/launcher/Microsoft.Launcher/Microsoft.Launcher.vcxproj index 52c6d6d062..c96dd785c1 100644 --- a/src/modules/launcher/Microsoft.Launcher/Microsoft.Launcher.vcxproj +++ b/src/modules/launcher/Microsoft.Launcher/Microsoft.Launcher.vcxproj @@ -1,9 +1,10 @@ - + + - + 15.0 @@ -12,10 +13,9 @@ Wox_Launcher Microsoft.Launcher - DynamicLibrary - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ @@ -35,7 +35,7 @@ EXAMPLEPOWERTOY_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - ..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories) + $(RepoRoot)src\common\Telemetry;..\..\;$(RepoRoot)src\;%(AdditionalIncludeDirectories) Shlwapi.lib;%(AdditionalDependencies) @@ -55,10 +55,10 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} @@ -73,17 +73,17 @@ - + - - + + 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}. - - - + + + \ No newline at end of file diff --git a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.UnitConverter.UnitTest/Community.PowerToys.Run.Plugin.UnitConverter.UnitTest.csproj b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.UnitConverter.UnitTest/Community.PowerToys.Run.Plugin.UnitConverter.UnitTest.csproj index e98d30893b..f72848843c 100644 --- a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.UnitConverter.UnitTest/Community.PowerToys.Run.Plugin.UnitConverter.UnitTest.csproj +++ b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.UnitConverter.UnitTest/Community.PowerToys.Run.Plugin.UnitConverter.UnitTest.csproj @@ -1,6 +1,6 @@ - + false diff --git a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.UnitConverter/Community.PowerToys.Run.Plugin.UnitConverter.csproj b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.UnitConverter/Community.PowerToys.Run.Plugin.UnitConverter.csproj index 8bfd37e7a8..cf2328e442 100644 --- a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.UnitConverter/Community.PowerToys.Run.Plugin.UnitConverter.csproj +++ b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.UnitConverter/Community.PowerToys.Run.Plugin.UnitConverter.csproj @@ -1,6 +1,6 @@ - + - + {BB23A474-5058-4F75-8FA3-5FE3DE53CDF4} @@ -12,7 +12,7 @@ false false true - ..\..\..\..\..\$(Platform)\$(Configuration)\RunPlugins\UnitConverter\ + $(RepoRoot)$(Platform)\$(Configuration)\RunPlugins\UnitConverter\ diff --git a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/Community.PowerToys.Run.Plugin.VSCodeWorkspaces.csproj b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/Community.PowerToys.Run.Plugin.VSCodeWorkspaces.csproj index f482308c42..7a86ae52f9 100644 --- a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/Community.PowerToys.Run.Plugin.VSCodeWorkspaces.csproj +++ b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/Community.PowerToys.Run.Plugin.VSCodeWorkspaces.csproj @@ -1,6 +1,6 @@ - + - + {4D971245-7A70-41D5-BAA0-DDB5684CAF51} @@ -12,7 +12,7 @@ false false true - ..\..\..\..\..\$(Platform)\$(Configuration)\RunPlugins\VSCodeWorkspaces\ + $(RepoRoot)$(Platform)\$(Configuration)\RunPlugins\VSCodeWorkspaces\ diff --git a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator.UnitTests/Community.PowerToys.Run.Plugin.ValueGenerator.UnitTests.csproj b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator.UnitTests/Community.PowerToys.Run.Plugin.ValueGenerator.UnitTests.csproj index f302772736..3668a64b0f 100644 --- a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator.UnitTests/Community.PowerToys.Run.Plugin.ValueGenerator.UnitTests.csproj +++ b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator.UnitTests/Community.PowerToys.Run.Plugin.ValueGenerator.UnitTests.csproj @@ -1,6 +1,6 @@ - + - + enable diff --git a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Community.PowerToys.Run.Plugin.ValueGenerator.csproj b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Community.PowerToys.Run.Plugin.ValueGenerator.csproj index 31ba1ce1e8..e771f4e6ca 100644 --- a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Community.PowerToys.Run.Plugin.ValueGenerator.csproj +++ b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Community.PowerToys.Run.Plugin.ValueGenerator.csproj @@ -1,6 +1,6 @@ - + - + {D095BE44-1F2E-463E-A494-121892A75EA2} @@ -11,7 +11,7 @@ false false true - ..\..\..\..\..\$(Platform)\$(Configuration)\RunPlugins\ValueGenerator\ + $(RepoRoot)$(Platform)\$(Configuration)\RunPlugins\ValueGenerator\ diff --git a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.WebSearch/Community.PowerToys.Run.Plugin.WebSearch.csproj b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.WebSearch/Community.PowerToys.Run.Plugin.WebSearch.csproj index 623ea68075..b43f91f5e8 100644 --- a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.WebSearch/Community.PowerToys.Run.Plugin.WebSearch.csproj +++ b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.WebSearch/Community.PowerToys.Run.Plugin.WebSearch.csproj @@ -1,6 +1,6 @@ - + - + {9F94B303-5E21-4364-9362-64426F8DB932} @@ -12,7 +12,7 @@ false false true - ..\..\..\..\..\$(Platform)\$(Configuration)\RunPlugins\WebSearch\ + $(RepoRoot)$(Platform)\$(Configuration)\RunPlugins\WebSearch\ diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder.UnitTests/Microsoft.Plugin.Folder.UnitTests.csproj b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder.UnitTests/Microsoft.Plugin.Folder.UnitTests.csproj index 7740130700..22fce25549 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder.UnitTests/Microsoft.Plugin.Folder.UnitTests.csproj +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder.UnitTests/Microsoft.Plugin.Folder.UnitTests.csproj @@ -1,6 +1,6 @@ - + false diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Microsoft.Plugin.Folder.csproj b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Microsoft.Plugin.Folder.csproj index 9207e9dd56..4648722df9 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Microsoft.Plugin.Folder.csproj +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Microsoft.Plugin.Folder.csproj @@ -1,6 +1,6 @@ - + - + {787B8AA6-CA93-4C84-96FE-DF31110AD1C4} @@ -12,7 +12,7 @@ false false true - ..\..\..\..\..\$(Platform)\$(Configuration)\RunPlugins\Folder\ + $(RepoRoot)$(Platform)\$(Configuration)\RunPlugins\Folder\ diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/Microsoft.Plugin.Indexer.csproj b/src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/Microsoft.Plugin.Indexer.csproj index 89191ad854..dcfbb3dfb1 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/Microsoft.Plugin.Indexer.csproj +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/Microsoft.Plugin.Indexer.csproj @@ -1,6 +1,6 @@ - + - + {F8B870EB-D5F5-45BA-9CF7-A5C459818820} @@ -12,7 +12,7 @@ false false true - ..\..\..\..\..\$(Platform)\$(Configuration)\RunPlugins\Indexer\ + $(RepoRoot)$(Platform)\$(Configuration)\RunPlugins\Indexer\ diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/Microsoft.Plugin.Program.UnitTests.csproj b/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/Microsoft.Plugin.Program.UnitTests.csproj index 1f95c5ba9b..06a97d8c19 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/Microsoft.Plugin.Program.UnitTests.csproj +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/Microsoft.Plugin.Program.UnitTests.csproj @@ -1,6 +1,6 @@ - + - + false diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Microsoft.Plugin.Program.csproj b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Microsoft.Plugin.Program.csproj index bf0034286f..853a23d20b 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Microsoft.Plugin.Program.csproj +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Microsoft.Plugin.Program.csproj @@ -1,6 +1,6 @@ - + - + {FDB3555B-58EF-4AE6-B5F1-904719637AB4} @@ -13,7 +13,7 @@ false false true - ..\..\..\..\..\$(Platform)\$(Configuration)\RunPlugins\Program\ + $(RepoRoot)$(Platform)\$(Configuration)\RunPlugins\Program\ diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Shell/Microsoft.Plugin.Shell.csproj b/src/modules/launcher/Plugins/Microsoft.Plugin.Shell/Microsoft.Plugin.Shell.csproj index 8ac68f7c14..45ffa6d33a 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Shell/Microsoft.Plugin.Shell.csproj +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Shell/Microsoft.Plugin.Shell.csproj @@ -1,6 +1,6 @@ - + - + {C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0} @@ -12,7 +12,7 @@ false false true - ..\..\..\..\..\$(Platform)\$(Configuration)\RunPlugins\Shell\ + $(RepoRoot)$(Platform)\$(Configuration)\RunPlugins\Shell\ diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Uri.UnitTests/Microsoft.Plugin.Uri.UnitTests.csproj b/src/modules/launcher/Plugins/Microsoft.Plugin.Uri.UnitTests/Microsoft.Plugin.Uri.UnitTests.csproj index f9b7c01a9e..88bd01fbb9 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Uri.UnitTests/Microsoft.Plugin.Uri.UnitTests.csproj +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Uri.UnitTests/Microsoft.Plugin.Uri.UnitTests.csproj @@ -1,6 +1,6 @@ - + - + false diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Uri/Microsoft.Plugin.Uri.csproj b/src/modules/launcher/Plugins/Microsoft.Plugin.Uri/Microsoft.Plugin.Uri.csproj index 876096794e..e69dfc09cf 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Uri/Microsoft.Plugin.Uri.csproj +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Uri/Microsoft.Plugin.Uri.csproj @@ -1,6 +1,6 @@ - + - + {03276a39-d4e9-417c-8ffd-200b0ee5e871} @@ -12,7 +12,7 @@ false false true - ..\..\..\..\..\$(Platform)\$(Configuration)\RunPlugins\Uri\ + $(RepoRoot)$(Platform)\$(Configuration)\RunPlugins\Uri\ diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker.UnitTests/Microsoft.Plugin.WindowWalker.UnitTests.csproj b/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker.UnitTests/Microsoft.Plugin.WindowWalker.UnitTests.csproj index cd677328bf..2f4b9ca9a7 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker.UnitTests/Microsoft.Plugin.WindowWalker.UnitTests.csproj +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker.UnitTests/Microsoft.Plugin.WindowWalker.UnitTests.csproj @@ -1,6 +1,6 @@ - + - + false diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Microsoft.Plugin.WindowWalker.csproj b/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Microsoft.Plugin.WindowWalker.csproj index c814348273..908de41f15 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Microsoft.Plugin.WindowWalker.csproj +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Microsoft.Plugin.WindowWalker.csproj @@ -1,6 +1,6 @@ - + - + {74F1B9ED-F59C-4FE7-B473-7B453E30837E} @@ -12,7 +12,7 @@ false false true - ..\..\..\..\..\$(Platform)\$(Configuration)\RunPlugins\WindowWalker\ + $(RepoRoot)$(Platform)\$(Configuration)\RunPlugins\WindowWalker\ diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator.UnitTest/Microsoft.PowerToys.Run.Plugin.Calculator.UnitTest.csproj b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator.UnitTest/Microsoft.PowerToys.Run.Plugin.Calculator.UnitTest.csproj index 048a3df958..9ba8ad6f92 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator.UnitTest/Microsoft.PowerToys.Run.Plugin.Calculator.UnitTest.csproj +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator.UnitTest/Microsoft.PowerToys.Run.Plugin.Calculator.UnitTest.csproj @@ -1,6 +1,6 @@ - + false diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Microsoft.PowerToys.Run.Plugin.Calculator.csproj b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Microsoft.PowerToys.Run.Plugin.Calculator.csproj index 9f4123d32a..1565933913 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Microsoft.PowerToys.Run.Plugin.Calculator.csproj +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Microsoft.PowerToys.Run.Plugin.Calculator.csproj @@ -1,6 +1,6 @@ - + - + {59BD9891-3837-438A-958D-ADC7F91F6F7E} @@ -12,7 +12,7 @@ false false true - ..\..\..\..\..\$(Platform)\$(Configuration)\RunPlugins\Calculator\ + $(RepoRoot)$(Platform)\$(Configuration)\RunPlugins\Calculator\ diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.History/Microsoft.PowerToys.Run.Plugin.History.csproj b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.History/Microsoft.PowerToys.Run.Plugin.History.csproj index 1197139d30..c4fcf151b8 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.History/Microsoft.PowerToys.Run.Plugin.History.csproj +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.History/Microsoft.PowerToys.Run.Plugin.History.csproj @@ -1,6 +1,6 @@ - + - + {212AD910-8488-4036-BE20-326931B75FB2} @@ -12,7 +12,7 @@ false false true - ..\..\..\..\..\$(Platform)\$(Configuration)\RunPlugins\History\ + $(RepoRoot)$(Platform)\$(Configuration)\RunPlugins\History\ diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.OneNote/Microsoft.PowerToys.Run.Plugin.OneNote.csproj b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.OneNote/Microsoft.PowerToys.Run.Plugin.OneNote.csproj index 4cc88d06e6..97f5389395 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.OneNote/Microsoft.PowerToys.Run.Plugin.OneNote.csproj +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.OneNote/Microsoft.PowerToys.Run.Plugin.OneNote.csproj @@ -1,6 +1,6 @@ - + - + Microsoft.PowerToys.Run.Plugin.OneNote @@ -11,7 +11,7 @@ false true enable - ..\..\..\..\..\$(Platform)\$(Configuration)\RunPlugins\OneNote\ + $(RepoRoot)$(Platform)\$(Configuration)\RunPlugins\OneNote\ diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.PowerToys/Microsoft.PowerToys.Run.Plugin.PowerToys.csproj b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.PowerToys/Microsoft.PowerToys.Run.Plugin.PowerToys.csproj index d31dab3b80..2327bee14f 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.PowerToys/Microsoft.PowerToys.Run.Plugin.PowerToys.csproj +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.PowerToys/Microsoft.PowerToys.Run.Plugin.PowerToys.csproj @@ -1,6 +1,6 @@ - + - + Microsoft.PowerToys.Run.Plugin.PowerToys @@ -9,7 +9,7 @@ false false true - ..\..\..\..\..\$(Platform)\$(Configuration)\RunPlugins\PowerToys\ + $(RepoRoot)$(Platform)\$(Configuration)\RunPlugins\PowerToys\ diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry.UnitTest/Microsoft.PowerToys.Run.Plugin.Registry.UnitTests.csproj b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry.UnitTest/Microsoft.PowerToys.Run.Plugin.Registry.UnitTests.csproj index 36812a23db..49474e767e 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry.UnitTest/Microsoft.PowerToys.Run.Plugin.Registry.UnitTests.csproj +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry.UnitTest/Microsoft.PowerToys.Run.Plugin.Registry.UnitTests.csproj @@ -1,6 +1,6 @@ - + - + enable diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Microsoft.PowerToys.Run.Plugin.Registry.csproj b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Microsoft.PowerToys.Run.Plugin.Registry.csproj index fba2adb1c8..bd93210b90 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Microsoft.PowerToys.Run.Plugin.Registry.csproj +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Microsoft.PowerToys.Run.Plugin.Registry.csproj @@ -1,6 +1,6 @@ - + - + Microsoft.PowerToys.Run.Plugin.Registry @@ -10,7 +10,7 @@ false enable true - ..\..\..\..\..\$(Platform)\$(Configuration)\RunPlugins\Registry\ + $(RepoRoot)$(Platform)\$(Configuration)\RunPlugins\Registry\ diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/Microsoft.PowerToys.Run.Plugin.Service.csproj b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/Microsoft.PowerToys.Run.Plugin.Service.csproj index 1f9bb66178..f473775c84 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/Microsoft.PowerToys.Run.Plugin.Service.csproj +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/Microsoft.PowerToys.Run.Plugin.Service.csproj @@ -1,6 +1,6 @@ - + Microsoft.PowerToys.Run.Plugin.Service @@ -9,7 +9,7 @@ false false true - ..\..\..\..\..\$(Platform)\$(Configuration)\RunPlugins\Service\ + $(RepoRoot)$(Platform)\$(Configuration)\RunPlugins\Service\ diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System.UnitTests/Microsoft.PowerToys.Run.Plugin.System.UnitTests.csproj b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System.UnitTests/Microsoft.PowerToys.Run.Plugin.System.UnitTests.csproj index 8833804a16..a3b50d1700 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System.UnitTests/Microsoft.PowerToys.Run.Plugin.System.UnitTests.csproj +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System.UnitTests/Microsoft.PowerToys.Run.Plugin.System.UnitTests.csproj @@ -1,6 +1,6 @@ - + - + false diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Microsoft.PowerToys.Run.Plugin.System.csproj b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Microsoft.PowerToys.Run.Plugin.System.csproj index e868337841..cb8683c826 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Microsoft.PowerToys.Run.Plugin.System.csproj +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Microsoft.PowerToys.Run.Plugin.System.csproj @@ -1,6 +1,6 @@ - + - + Library @@ -12,7 +12,7 @@ false false true - ..\..\..\..\..\$(Platform)\$(Configuration)\RunPlugins\System\ + $(RepoRoot)$(Platform)\$(Configuration)\RunPlugins\System\ diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests.csproj b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests.csproj index 483955ba44..09eab9110d 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests.csproj +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests.csproj @@ -1,6 +1,6 @@ - + - + false diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Microsoft.PowerToys.Run.Plugin.TimeDate.csproj b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Microsoft.PowerToys.Run.Plugin.TimeDate.csproj index 4236156764..42fb8dc114 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Microsoft.PowerToys.Run.Plugin.TimeDate.csproj +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Microsoft.PowerToys.Run.Plugin.TimeDate.csproj @@ -1,6 +1,6 @@ - + - + Library @@ -12,7 +12,7 @@ false false true - ..\..\..\..\..\$(Platform)\$(Configuration)\RunPlugins\TimeDate\ + $(RepoRoot)$(Platform)\$(Configuration)\RunPlugins\TimeDate\ diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsSettings/Microsoft.PowerToys.Run.Plugin.WindowsSettings.csproj b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsSettings/Microsoft.PowerToys.Run.Plugin.WindowsSettings.csproj index 9e7d5d6d2a..bb540576cf 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsSettings/Microsoft.PowerToys.Run.Plugin.WindowsSettings.csproj +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsSettings/Microsoft.PowerToys.Run.Plugin.WindowsSettings.csproj @@ -1,6 +1,6 @@ - + - + {5043CECE-E6A7-4867-9CBE-02D27D83747A} @@ -13,7 +13,7 @@ true enable true - ..\..\..\..\..\$(Platform)\$(Configuration)\RunPlugins\WindowsSettings\ + $(RepoRoot)$(Platform)\$(Configuration)\RunPlugins\WindowsSettings\ diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsTerminal.UnitTests/Microsoft.Plugin.WindowsTerminal.UnitTests.csproj b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsTerminal.UnitTests/Microsoft.Plugin.WindowsTerminal.UnitTests.csproj index 0a4a791084..590c967217 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsTerminal.UnitTests/Microsoft.Plugin.WindowsTerminal.UnitTests.csproj +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsTerminal.UnitTests/Microsoft.Plugin.WindowsTerminal.UnitTests.csproj @@ -1,6 +1,6 @@ - + - + true diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsTerminal/Microsoft.PowerToys.Run.Plugin.WindowsTerminal.csproj b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsTerminal/Microsoft.PowerToys.Run.Plugin.WindowsTerminal.csproj index 25c35fceaa..395055db42 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsTerminal/Microsoft.PowerToys.Run.Plugin.WindowsTerminal.csproj +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsTerminal/Microsoft.PowerToys.Run.Plugin.WindowsTerminal.csproj @@ -1,6 +1,6 @@ - + - + Microsoft.PowerToys.Run.Plugin.WindowsTerminal @@ -9,7 +9,7 @@ false false true - ..\..\..\..\..\$(Platform)\$(Configuration)\RunPlugins\WindowsTerminal\ + $(RepoRoot)$(Platform)\$(Configuration)\RunPlugins\WindowsTerminal\ diff --git a/src/modules/launcher/PowerLauncher.Telemetry/PowerLauncher.Telemetry.csproj b/src/modules/launcher/PowerLauncher.Telemetry/PowerLauncher.Telemetry.csproj index 9b161cd95e..f7d094abc3 100644 --- a/src/modules/launcher/PowerLauncher.Telemetry/PowerLauncher.Telemetry.csproj +++ b/src/modules/launcher/PowerLauncher.Telemetry/PowerLauncher.Telemetry.csproj @@ -1,6 +1,6 @@ - + - + PowerToys PowerLauncher Telemetry diff --git a/src/modules/launcher/PowerLauncher/PowerLauncher.csproj b/src/modules/launcher/PowerLauncher/PowerLauncher.csproj index 0953b4d5a1..d22f82282f 100644 --- a/src/modules/launcher/PowerLauncher/PowerLauncher.csproj +++ b/src/modules/launcher/PowerLauncher/PowerLauncher.csproj @@ -1,7 +1,7 @@ - + - - + + PowerToys.Run @@ -18,7 +18,7 @@ uap10.0.19041 PowerToys PowerLauncher PowerToys.PowerLauncher - ..\..\..\..\$(Platform)\$(Configuration) + $(RepoRoot)$(Platform)\$(Configuration) true diff --git a/src/modules/launcher/Wox.Infrastructure/Wox.Infrastructure.csproj b/src/modules/launcher/Wox.Infrastructure/Wox.Infrastructure.csproj index 6490b7cee5..ffdc41aad9 100644 --- a/src/modules/launcher/Wox.Infrastructure/Wox.Infrastructure.csproj +++ b/src/modules/launcher/Wox.Infrastructure/Wox.Infrastructure.csproj @@ -1,6 +1,6 @@ - + - + {4FD29318-A8AB-4D8F-AA47-60BC241B8DA3} @@ -12,7 +12,7 @@ false false - ..\..\..\..\$(Platform)\$(Configuration)\WoxInfrastructure + $(RepoRoot)$(Platform)\$(Configuration)\WoxInfrastructure diff --git a/src/modules/launcher/Wox.Plugin/Wox.Plugin.csproj b/src/modules/launcher/Wox.Plugin/Wox.Plugin.csproj index 67f7ead02c..0c7d6889a0 100644 --- a/src/modules/launcher/Wox.Plugin/Wox.Plugin.csproj +++ b/src/modules/launcher/Wox.Plugin/Wox.Plugin.csproj @@ -1,6 +1,6 @@ - + - + {8451ECDD-2EA4-4966-BB0A-7BBC40138E80} @@ -13,7 +13,7 @@ false false true - ..\..\..\..\$(Platform)\$(Configuration)\WoxPlugin + $(RepoRoot)$(Platform)\$(Configuration)\WoxPlugin diff --git a/src/modules/launcher/Wox.Test/Wox.Test.csproj b/src/modules/launcher/Wox.Test/Wox.Test.csproj index bae3bcc813..ae3a2fe7ce 100644 --- a/src/modules/launcher/Wox.Test/Wox.Test.csproj +++ b/src/modules/launcher/Wox.Test/Wox.Test.csproj @@ -1,6 +1,6 @@ - + - + {FF742965-9A80-41A5-B042-D6C7D3A21708} @@ -11,7 +11,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\tests\WoxTest + $(RepoRoot)$(Platform)\$(Configuration)\tests\WoxTest diff --git a/src/modules/peek/Peek.Common/Peek.Common.csproj b/src/modules/peek/Peek.Common/Peek.Common.csproj index b5707ed23a..8f51923493 100644 --- a/src/modules/peek/Peek.Common/Peek.Common.csproj +++ b/src/modules/peek/Peek.Common/Peek.Common.csproj @@ -1,6 +1,6 @@ - + - + Peek.Common diff --git a/src/modules/peek/Peek.FilePreviewer/Peek.FilePreviewer.csproj b/src/modules/peek/Peek.FilePreviewer/Peek.FilePreviewer.csproj index 83b75f8ed9..6d58478be3 100644 --- a/src/modules/peek/Peek.FilePreviewer/Peek.FilePreviewer.csproj +++ b/src/modules/peek/Peek.FilePreviewer/Peek.FilePreviewer.csproj @@ -1,6 +1,6 @@ - + - + Peek.FilePreviewer diff --git a/src/modules/peek/Peek.UI/Peek.UI.csproj b/src/modules/peek/Peek.UI/Peek.UI.csproj index 070d9d2ef2..6448ec7322 100644 --- a/src/modules/peek/Peek.UI/Peek.UI.csproj +++ b/src/modules/peek/Peek.UI/Peek.UI.csproj @@ -1,8 +1,8 @@ - + - - - + + + PowerToys.Peek.UI @@ -10,7 +10,7 @@ PowerToys Peek UI Peek.UI WinExe - ..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps + $(RepoRoot)$(Platform)\$(Configuration)\WinUI3Apps app.manifest true x64;ARM64 diff --git a/src/modules/peek/Peek.UITests/Peek.UITests.csproj b/src/modules/peek/Peek.UITests/Peek.UITests.csproj index baed641b15..0b73d4913a 100644 --- a/src/modules/peek/Peek.UITests/Peek.UITests.csproj +++ b/src/modules/peek/Peek.UITests/Peek.UITests.csproj @@ -1,5 +1,5 @@ - - + + PowerToys.Peek.UITests enable @@ -9,7 +9,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\tests\Peek.UITests\ + $(RepoRoot)$(Platform)\$(Configuration)\tests\Peek.UITests\ diff --git a/src/modules/peek/peek/peek.vcxproj b/src/modules/peek/peek/peek.vcxproj index 1764bcb192..017e80b009 100644 --- a/src/modules/peek/peek/peek.vcxproj +++ b/src/modules/peek/peek/peek.vcxproj @@ -1,6 +1,7 @@ - + + 15.0 {a1425b53-3d61-4679-8623-e64a0d3d0a48} @@ -8,7 +9,6 @@ peek Peek - DynamicLibrary @@ -23,13 +23,13 @@ - ..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps\ + $(RepoRoot)$(Platform)\$(Configuration)\WinUI3Apps\ PowerToys.Peek EXAMPLEPOWERTOY_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - ..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories) + $(RepoRoot)src\common\inc;$(RepoRoot)src\common\Telemetry;..\..\;$(RepoRoot)src\;%(AdditionalIncludeDirectories) $(OutDir)$(TargetName)$(TargetExt) @@ -48,10 +48,10 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} @@ -60,18 +60,18 @@ - - + + - + 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}. - - - + + + \ No newline at end of file diff --git a/src/modules/poweraccent/PowerAccent.Core/PowerAccent.Core.csproj b/src/modules/poweraccent/PowerAccent.Core/PowerAccent.Core.csproj index 1f653884cf..49ae53eb23 100644 --- a/src/modules/poweraccent/PowerAccent.Core/PowerAccent.Core.csproj +++ b/src/modules/poweraccent/PowerAccent.Core/PowerAccent.Core.csproj @@ -1,8 +1,8 @@ - + - - - + + + enable diff --git a/src/modules/poweraccent/PowerAccent.UI/PowerAccent.UI.csproj b/src/modules/poweraccent/PowerAccent.UI/PowerAccent.UI.csproj index 217b437e95..30111fbdf7 100644 --- a/src/modules/poweraccent/PowerAccent.UI/PowerAccent.UI.csproj +++ b/src/modules/poweraccent/PowerAccent.UI/PowerAccent.UI.csproj @@ -1,7 +1,7 @@ - + - - + + WinExe @@ -13,7 +13,7 @@ PowerToys.PowerAccent True PowerAccent.UI.Program - ..\..\..\..\$(Platform)\$(Configuration) + $(RepoRoot)$(Platform)\$(Configuration) false false diff --git a/src/modules/poweraccent/PowerAccentKeyboardService/PowerAccentKeyboardService.vcxproj b/src/modules/poweraccent/PowerAccentKeyboardService/PowerAccentKeyboardService.vcxproj index 402c39e533..d6cead3cc8 100644 --- a/src/modules/poweraccent/PowerAccentKeyboardService/PowerAccentKeyboardService.vcxproj +++ b/src/modules/poweraccent/PowerAccentKeyboardService/PowerAccentKeyboardService.vcxproj @@ -1,6 +1,7 @@ - + + true true @@ -16,7 +17,6 @@ Windows Store 10.0 - DynamicLibrary @@ -46,7 +46,7 @@ PowerToys.PowerAccentKeyboardService - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ @@ -105,10 +105,10 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} @@ -116,15 +116,15 @@ - + - + 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}. - - + + \ No newline at end of file diff --git a/src/modules/poweraccent/PowerAccentModuleInterface/PowerAccentModuleInterface.vcxproj b/src/modules/poweraccent/PowerAccentModuleInterface/PowerAccentModuleInterface.vcxproj index 06f2722733..7987b90c2c 100644 --- a/src/modules/poweraccent/PowerAccentModuleInterface/PowerAccentModuleInterface.vcxproj +++ b/src/modules/poweraccent/PowerAccentModuleInterface/PowerAccentModuleInterface.vcxproj @@ -1,6 +1,7 @@ - + + 15.0 {34A354C5-23C7-4343-916C-C52DAF4FC39D} @@ -8,7 +9,6 @@ PowerAccent PowerAccentModuleInterface - DynamicLibrary @@ -22,7 +22,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ PowerToys.$(ProjectName) @@ -30,7 +30,7 @@ EXAMPLEPOWERTOY_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - ..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories) + $(RepoRoot)src\common\inc;$(RepoRoot)src\common\Telemetry;..\..\;$(RepoRoot)src\;%(AdditionalIncludeDirectories) $(OutDir)$(TargetName)$(TargetExt) @@ -50,10 +50,10 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} @@ -64,17 +64,17 @@ - + - - + + 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}. - - - + + + \ No newline at end of file diff --git a/src/modules/powerrename/PowerRename.FuzzingTest/PowerRename.FuzzingTest.vcxproj b/src/modules/powerrename/PowerRename.FuzzingTest/PowerRename.FuzzingTest.vcxproj index e05a9797c1..8c6d6c52a8 100644 --- a/src/modules/powerrename/PowerRename.FuzzingTest/PowerRename.FuzzingTest.vcxproj +++ b/src/modules/powerrename/PowerRename.FuzzingTest/PowerRename.FuzzingTest.vcxproj @@ -1,6 +1,7 @@ - + + 17.0 Win32Proj @@ -9,7 +10,6 @@ 10.0.26100.0 PowerRename.FuzzTests - Application false @@ -32,7 +32,7 @@ $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(VCToolsInstallDir)\lib\$(Platform) - ..\..\..\..\$(Platform)\$(Configuration)\tests\PowerRename.FuzzTests\ + $(RepoRoot)$(Platform)\$(Configuration)\tests\PowerRename.FuzzTests\ @@ -46,7 +46,7 @@ /fsanitize=address /fsanitize-coverage=inline-8bit-counters /fsanitize-coverage=edge /fsanitize-coverage=trace-cmp /fsanitize-coverage=trace-div %(AdditionalOptions) MultiThreaded stdcpplatest - ..\;..\lib\;..\..\..\;%(AdditionalIncludeDirectories) + ..\;..\lib\;$(RepoRoot)src\;%(AdditionalIncludeDirectories) Console @@ -68,7 +68,7 @@ true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) NotUsing - ..\;..\lib\;..\..\..\;%(AdditionalIncludeDirectories) + ..\;..\lib\;$(RepoRoot)src\;%(AdditionalIncludeDirectories) Console @@ -88,23 +88,23 @@ {51920f1f-c28c-4adf-8660-4238766796c2} - + {6955446d-23f7-4023-9bb3-8657f904af99} - - - + + + 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}. - - - - + + + + \ No newline at end of file diff --git a/src/modules/powerrename/PowerRenameContextMenu/PowerRenameContextMenu.vcxproj b/src/modules/powerrename/PowerRenameContextMenu/PowerRenameContextMenu.vcxproj index babf0b4fa7..c0a630c45a 100644 --- a/src/modules/powerrename/PowerRenameContextMenu/PowerRenameContextMenu.vcxproj +++ b/src/modules/powerrename/PowerRenameContextMenu/PowerRenameContextMenu.vcxproj @@ -1,8 +1,9 @@ - + + - + 16.0 @@ -10,7 +11,6 @@ {1dbbb112-4bb1-444b-8ebb-e66555c76ba6} PowerRenameContextMenu - DynamicLibrary true @@ -37,7 +37,7 @@ PowerToys.PowerRenameContextMenu $(SolutionDir)$(Platform)\$(Configuration)\TemporaryBuild\obj\$(ProjectName)\ - ..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps\ + $(RepoRoot)$(Platform)\$(Configuration)\WinUI3Apps\ @@ -45,7 +45,7 @@ true _DEBUG;POWERRENAMECONTEXTMENU_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true - ..\..\..\;..\lib\;..\..\;..\..\..\common\telemetry;%(AdditionalIncludeDirectories) + $(RepoRoot)src\;..\lib\;..\..\;$(RepoRoot)src\common\telemetry;%(AdditionalIncludeDirectories) Windows @@ -67,7 +67,7 @@ MakeAppx.exe pack /d . /p $(OutDir)PowerRenameContextMenuPackage.msix /nvtrue NDEBUG;POWERRENAMECONTEXTMENU_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true - ..\..\..\;..\lib\;..\..\;..\..\..\common\telemetry;%(AdditionalIncludeDirectories) + $(RepoRoot)src\;..\lib\;..\..\;$(RepoRoot)src\common\telemetry;%(AdditionalIncludeDirectories) Windows @@ -129,10 +129,10 @@ MakeAppx.exe pack /d . /p $(OutDir)PowerRenameContextMenuPackage.msix /nv - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {8f021b46-362b-485c-bfba-ccf83e820cbd} @@ -143,17 +143,17 @@ MakeAppx.exe pack /d . /p $(OutDir)PowerRenameContextMenuPackage.msix /nv - + - - + + 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}. - - - + + + \ No newline at end of file diff --git a/src/modules/powerrename/PowerRenameUILib/PowerRenameUI.vcxproj b/src/modules/powerrename/PowerRenameUILib/PowerRenameUI.vcxproj index de8fb6d4ca..bd3086e1ab 100644 --- a/src/modules/powerrename/PowerRenameUILib/PowerRenameUI.vcxproj +++ b/src/modules/powerrename/PowerRenameUILib/PowerRenameUI.vcxproj @@ -1,4 +1,4 @@ - + @@ -69,7 +69,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps\ + $(RepoRoot)$(Platform)\$(Configuration)\WinUI3Apps\ @@ -77,7 +77,7 @@ Level4 %(AdditionalOptions) /bigobj - $(ProjectDir)\Generated Files\PowerRenameXAML;$(ProjectDir)..\..\..\common\Telemetry;$(ProjectDir)..\..\..\;$(ProjectDir)..\lib;%(AdditionalIncludeDirectories) + $(ProjectDir)\Generated Files\PowerRenameXAML;$(RepoRoot)src\common\Telemetry;$(RepoRoot)src\;$(ProjectDir)..\lib;%(AdditionalIncludeDirectories) @@ -201,13 +201,13 @@ <_WildCardPRIResource Include="Strings\*\Resources.resw" /> - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {8f021b46-362b-485c-bfba-ccf83e820cbd} - + {98537082-0fdb-40de-abd8-0dc5a4269bab} @@ -218,7 +218,7 @@ - + diff --git a/src/modules/powerrename/PowerRenameUITest/PowerRename.UITests.csproj b/src/modules/powerrename/PowerRenameUITest/PowerRename.UITests.csproj index 388db1df9f..7cdde8ae3b 100644 --- a/src/modules/powerrename/PowerRenameUITest/PowerRename.UITests.csproj +++ b/src/modules/powerrename/PowerRenameUITest/PowerRename.UITests.csproj @@ -1,5 +1,5 @@ - - + + PowerRename.UITests diff --git a/src/modules/powerrename/dll/PowerRenameExt.vcxproj b/src/modules/powerrename/dll/PowerRenameExt.vcxproj index b74624569c..4576c3322c 100644 --- a/src/modules/powerrename/dll/PowerRenameExt.vcxproj +++ b/src/modules/powerrename/dll/PowerRenameExt.vcxproj @@ -1,19 +1,19 @@ - + - + + - + 15.0 {B25AC7A5-FB9F-4789-B392-D5C85E948670} PowerRenameExt - DynamicLibrary PowerToys.PowerRenameExt - ..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps\ + $(RepoRoot)$(Platform)\$(Configuration)\WinUI3Apps\ @@ -21,7 +21,7 @@ - ..\lib\;..\PowerRenameUILib\;..\;..\..\..\;..\..\..\common\telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories) + ..\lib\;..\PowerRenameUILib\;..\;$(RepoRoot)src\;$(RepoRoot)src\common\telemetry;..\..\;$(RepoRoot)src\;%(AdditionalIncludeDirectories) Pathcch.lib;comctl32.lib;shcore.lib;windowscodecs.lib;%(AdditionalDependencies) @@ -55,16 +55,16 @@ - + {caba8dfb-823b-4bf2-93ac-3f31984150d9} - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {8f021b46-362b-485c-bfba-ccf83e820cbd} - + {98537082-0fdb-40de-abd8-0dc5a4269bab} @@ -75,19 +75,19 @@ - + - - - + + + 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}. - - - - + + + + \ No newline at end of file diff --git a/src/modules/powerrename/lib/PowerRenameLib.vcxproj b/src/modules/powerrename/lib/PowerRenameLib.vcxproj index ef52de5085..a1b0757c3c 100644 --- a/src/modules/powerrename/lib/PowerRenameLib.vcxproj +++ b/src/modules/powerrename/lib/PowerRenameLib.vcxproj @@ -1,12 +1,12 @@ - + - + + {51920F1F-C28C-4ADF-8660-4238766796C2} Win32Proj PowerRenameLib - StaticLibrary @@ -18,8 +18,8 @@ - ..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps\ - $(ProjectDir)..\..\..\..\deps + $(RepoRoot)$(Platform)\$(Configuration)\WinUI3Apps\ + $(RepoRoot)deps @@ -28,7 +28,7 @@ Level3 WIN32;_LIB;%(PreprocessorDefinitions) - $(ProjectDir)..\;$(ProjectDir)..\ui;$(ProjectDir)..\dll;$(ProjectDir)..\lib;$(ProjectDir)..\..\..\;$(ProjectDir)..\..\..\common\Telemetry;%(AdditionalIncludeDirectories);$(GeneratedFilesDir) + $(ProjectDir)..\;$(ProjectDir)..\ui;$(ProjectDir)..\dll;$(ProjectDir)..\lib;$(RepoRoot)src\;$(RepoRoot)src\common\Telemetry;%(AdditionalIncludeDirectories);$(GeneratedFilesDir) /FS %(AdditionalOptions) @@ -84,26 +84,26 @@ - + {6955446d-23f7-4023-9bb3-8657f904af99} - + {98537082-0fdb-40de-abd8-0dc5a4269bab} - - - + + + 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}. - - - - + + + + \ No newline at end of file diff --git a/src/modules/powerrename/testapp/PowerRenameTest.vcxproj b/src/modules/powerrename/testapp/PowerRenameTest.vcxproj index 9e678439f4..4e0352a7ea 100644 --- a/src/modules/powerrename/testapp/PowerRenameTest.vcxproj +++ b/src/modules/powerrename/testapp/PowerRenameTest.vcxproj @@ -1,13 +1,13 @@ - + + 15.0 {A3935CF4-46C5-4A88-84D3-6B12E16E6BA2} Win32Proj PowerRenameTest - Application @@ -24,11 +24,11 @@ - ..\..\..\..\$(Platform)\$(Configuration)\tests\PowerRename\ + $(RepoRoot)$(Platform)\$(Configuration)\tests\PowerRename\ - $(ProjectDir)..\;$(ProjectDir)..\ui;$(ProjectDir)..\dll;$(ProjectDir)..\lib;$(ProjectDir)..\..\..\;$(ProjectDir)..\..\..\common\Telemetry;%(AdditionalIncludeDirectories);$(GeneratedFilesDir) + $(ProjectDir)..\;$(ProjectDir)..\ui;$(ProjectDir)..\dll;$(ProjectDir)..\lib;$(RepoRoot)src\;$(RepoRoot)src\common\Telemetry;%(AdditionalIncludeDirectories);$(GeneratedFilesDir) WIN32;_WINDOWS;%(PreprocessorDefinitions) @@ -51,13 +51,13 @@ - + {caba8dfb-823b-4bf2-93ac-3f31984150d9} - + {6955446d-23f7-4023-9bb3-8657f904af99} - + {98537082-0fdb-40de-abd8-0dc5a4269bab} @@ -69,17 +69,17 @@ - - - + + + 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}. - - - - + + + + \ No newline at end of file diff --git a/src/modules/powerrename/unittests/PowerRenameLibUnitTests.vcxproj b/src/modules/powerrename/unittests/PowerRenameLibUnitTests.vcxproj index 4b6924a370..843d2fbea8 100644 --- a/src/modules/powerrename/unittests/PowerRenameLibUnitTests.vcxproj +++ b/src/modules/powerrename/unittests/PowerRenameLibUnitTests.vcxproj @@ -1,13 +1,13 @@ - + + {2151F984-E006-4A9F-92EF-C6DDE3DC8413} Win32Proj PowerRenameLibUnitTests PowerRename.UnitTests - @@ -24,11 +24,11 @@ - ..\..\..\..\$(Platform)\$(Configuration)\tests\PowerRename\ + $(RepoRoot)$(Platform)\$(Configuration)\tests\PowerRename\ - ..\;..\lib\;..\..\..\;..\..\..\common\telemetry;..\..\;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories) + ..\;..\lib\;$(RepoRoot)src\;$(RepoRoot)src\common\telemetry;..\..\;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories) WIN32;%(PreprocessorDefinitions) true @@ -64,10 +64,10 @@ - + {6955446d-23f7-4023-9bb3-8657f904af99} - + {98537082-0fdb-40de-abd8-0dc5a4269bab} @@ -107,17 +107,17 @@ - - - + + + 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}. - - - - + + + + \ No newline at end of file diff --git a/src/modules/previewpane/BgcodePreviewHandler/BgcodePreviewHandler.csproj b/src/modules/previewpane/BgcodePreviewHandler/BgcodePreviewHandler.csproj index 2042920cdc..3c73225bb8 100644 --- a/src/modules/previewpane/BgcodePreviewHandler/BgcodePreviewHandler.csproj +++ b/src/modules/previewpane/BgcodePreviewHandler/BgcodePreviewHandler.csproj @@ -1,7 +1,7 @@ - + - - + + enable @@ -10,7 +10,7 @@ PowerToys BgcodePreviewHandler PowerToys BgcodePreviewHandler ..\..\..\..\$(Platform)\$(Configuration)\BgcodePreviewPaneDocumentation.xml - ..\..\..\..\$(Platform)\$(Configuration) + $(RepoRoot)$(Platform)\$(Configuration) false false true diff --git a/src/modules/previewpane/BgcodePreviewHandlerCpp/BgcodePreviewHandlerCpp.vcxproj b/src/modules/previewpane/BgcodePreviewHandlerCpp/BgcodePreviewHandlerCpp.vcxproj index 3089dc4f9a..e368b89218 100644 --- a/src/modules/previewpane/BgcodePreviewHandlerCpp/BgcodePreviewHandlerCpp.vcxproj +++ b/src/modules/previewpane/BgcodePreviewHandlerCpp/BgcodePreviewHandlerCpp.vcxproj @@ -1,13 +1,13 @@ - + + 16.0 Win32Proj {F6088A11-1C9E-4420-AA90-CF7E78DD7F1C} BgcodePreviewHandlerCpp - DynamicLibrary true @@ -31,7 +31,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ PowerToys.$(ProjectName) @@ -94,26 +94,26 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} - + {98537082-0fdb-40de-abd8-0dc5a4269bab} - + - + 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}. - - + + \ No newline at end of file diff --git a/src/modules/previewpane/BgcodeThumbnailProvider/BgcodeThumbnailProvider.csproj b/src/modules/previewpane/BgcodeThumbnailProvider/BgcodeThumbnailProvider.csproj index b17ac59a18..1899ba6981 100644 --- a/src/modules/previewpane/BgcodeThumbnailProvider/BgcodeThumbnailProvider.csproj +++ b/src/modules/previewpane/BgcodeThumbnailProvider/BgcodeThumbnailProvider.csproj @@ -1,7 +1,7 @@ - + - - + + enable @@ -13,7 +13,7 @@ PowerToys BgcodePreviewHandler true PowerToys BgcodePreviewHandler - ..\..\..\..\$(Platform)\$(Configuration) + $(RepoRoot)$(Platform)\$(Configuration) false false true diff --git a/src/modules/previewpane/BgcodeThumbnailProviderCpp/BgcodeThumbnailProviderCpp.vcxproj b/src/modules/previewpane/BgcodeThumbnailProviderCpp/BgcodeThumbnailProviderCpp.vcxproj index 1ce068b2df..019f5d6214 100644 --- a/src/modules/previewpane/BgcodeThumbnailProviderCpp/BgcodeThumbnailProviderCpp.vcxproj +++ b/src/modules/previewpane/BgcodeThumbnailProviderCpp/BgcodeThumbnailProviderCpp.vcxproj @@ -1,13 +1,13 @@ - + + 16.0 Win32Proj {47B0678C-806B-4FE1-9F50-46BA88989532} BgcodeThumbnailProviderCpp - DynamicLibrary true @@ -31,7 +31,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ PowerToys.$(ProjectName) @@ -91,28 +91,28 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} - + - - + + 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}. - - - + + + \ No newline at end of file diff --git a/src/modules/previewpane/GcodePreviewHandler/GcodePreviewHandler.csproj b/src/modules/previewpane/GcodePreviewHandler/GcodePreviewHandler.csproj index 51bf6f1f7e..2a0947dc81 100644 --- a/src/modules/previewpane/GcodePreviewHandler/GcodePreviewHandler.csproj +++ b/src/modules/previewpane/GcodePreviewHandler/GcodePreviewHandler.csproj @@ -1,7 +1,7 @@ - + - - + + enable @@ -10,7 +10,7 @@ PowerToys GcodePreviewHandler PowerToys GcodePreviewHandler ..\..\..\..\$(Platform)\$(Configuration)\GcodePreviewPaneDocumentation.xml - ..\..\..\..\$(Platform)\$(Configuration) + $(RepoRoot)$(Platform)\$(Configuration) false false true diff --git a/src/modules/previewpane/GcodePreviewHandlerCpp/GcodePreviewHandlerCpp.vcxproj b/src/modules/previewpane/GcodePreviewHandlerCpp/GcodePreviewHandlerCpp.vcxproj index 45401739c5..943d224a65 100644 --- a/src/modules/previewpane/GcodePreviewHandlerCpp/GcodePreviewHandlerCpp.vcxproj +++ b/src/modules/previewpane/GcodePreviewHandlerCpp/GcodePreviewHandlerCpp.vcxproj @@ -1,13 +1,13 @@ - + + 16.0 Win32Proj {5a5dd09d-723a-44d3-8f2b-293584c3d731} GcodePreviewHandlerCpp - DynamicLibrary true @@ -31,7 +31,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ PowerToys.$(ProjectName) @@ -94,26 +94,26 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} - + {98537082-0fdb-40de-abd8-0dc5a4269bab} - + - + 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}. - - + + \ No newline at end of file diff --git a/src/modules/previewpane/GcodeThumbnailProvider/GcodeThumbnailProvider.csproj b/src/modules/previewpane/GcodeThumbnailProvider/GcodeThumbnailProvider.csproj index 9073a94931..dad5b10b44 100644 --- a/src/modules/previewpane/GcodeThumbnailProvider/GcodeThumbnailProvider.csproj +++ b/src/modules/previewpane/GcodeThumbnailProvider/GcodeThumbnailProvider.csproj @@ -1,7 +1,7 @@ - + - - + + enable @@ -13,7 +13,7 @@ PowerToys GcodePreviewHandler true PowerToys GcodePreviewHandler - ..\..\..\..\$(Platform)\$(Configuration) + $(RepoRoot)$(Platform)\$(Configuration) false false true diff --git a/src/modules/previewpane/GcodeThumbnailProviderCpp/GcodeThumbnailProviderCpp.vcxproj b/src/modules/previewpane/GcodeThumbnailProviderCpp/GcodeThumbnailProviderCpp.vcxproj index c996788e68..2f9b4d99a3 100644 --- a/src/modules/previewpane/GcodeThumbnailProviderCpp/GcodeThumbnailProviderCpp.vcxproj +++ b/src/modules/previewpane/GcodeThumbnailProviderCpp/GcodeThumbnailProviderCpp.vcxproj @@ -1,13 +1,13 @@ - + + 16.0 Win32Proj {56cc2f10-6e41-453d-be16-c593a5e58482} GcodeThumbnailProviderCpp - DynamicLibrary true @@ -31,7 +31,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ PowerToys.$(ProjectName) @@ -91,28 +91,28 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} - + - - + + 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}. - - - + + + \ No newline at end of file diff --git a/src/modules/previewpane/MarkdownPreviewHandler/MarkdownPreviewHandler.csproj b/src/modules/previewpane/MarkdownPreviewHandler/MarkdownPreviewHandler.csproj index 6d0fe10677..6dc4006e53 100644 --- a/src/modules/previewpane/MarkdownPreviewHandler/MarkdownPreviewHandler.csproj +++ b/src/modules/previewpane/MarkdownPreviewHandler/MarkdownPreviewHandler.csproj @@ -1,8 +1,8 @@ - + - - - + + + enable @@ -11,7 +11,7 @@ PowerToys MarkdownPreviewHandler PowerToys MarkdownPreviewHandler ..\..\..\..\$(Platform)\$(Configuration)\MarkdownPreviewPaneDocumentation.xml - ..\..\..\..\$(Platform)\$(Configuration) + $(RepoRoot)$(Platform)\$(Configuration) false false true diff --git a/src/modules/previewpane/MarkdownPreviewHandlerCpp/MarkdownPreviewHandlerCpp.vcxproj b/src/modules/previewpane/MarkdownPreviewHandlerCpp/MarkdownPreviewHandlerCpp.vcxproj index 7ba8adda50..9d2039d807 100644 --- a/src/modules/previewpane/MarkdownPreviewHandlerCpp/MarkdownPreviewHandlerCpp.vcxproj +++ b/src/modules/previewpane/MarkdownPreviewHandlerCpp/MarkdownPreviewHandlerCpp.vcxproj @@ -1,8 +1,9 @@ - + + - + 16.0 @@ -10,7 +11,6 @@ {ed9a1ac6-aeb0-4569-a6e9-e1696182b545} MarkdownPreviewHandlerCpp - DynamicLibrary true @@ -34,7 +34,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ true @@ -100,29 +100,29 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} - + {98537082-0fdb-40de-abd8-0dc5a4269bab} - + - + 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}. - - + + \ No newline at end of file diff --git a/src/modules/previewpane/MonacoPreviewHandler/MonacoPreviewHandler.csproj b/src/modules/previewpane/MonacoPreviewHandler/MonacoPreviewHandler.csproj index 5753ad910d..adc89ae1f6 100644 --- a/src/modules/previewpane/MonacoPreviewHandler/MonacoPreviewHandler.csproj +++ b/src/modules/previewpane/MonacoPreviewHandler/MonacoPreviewHandler.csproj @@ -1,7 +1,7 @@ - - + + enable @@ -9,7 +9,7 @@ PowerToys.MonacoPreviewHandler PowerToys MonacoPreviewHandler PowerToys MonacoPreviewHandler - ..\..\..\..\$(Platform)\$(Configuration) + $(RepoRoot)$(Platform)\$(Configuration) false false true diff --git a/src/modules/previewpane/MonacoPreviewHandlerCpp/MonacoPreviewHandlerCpp.vcxproj b/src/modules/previewpane/MonacoPreviewHandlerCpp/MonacoPreviewHandlerCpp.vcxproj index 08d322bd64..4e17f9a42c 100644 --- a/src/modules/previewpane/MonacoPreviewHandlerCpp/MonacoPreviewHandlerCpp.vcxproj +++ b/src/modules/previewpane/MonacoPreviewHandlerCpp/MonacoPreviewHandlerCpp.vcxproj @@ -1,13 +1,13 @@ - + + 16.0 Win32Proj {b3e869c4-8210-4ebd-a621-ff4c4afcbfa9} MonacoPreviewHandlerCpp - DynamicLibrary true @@ -31,7 +31,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ PowerToys.$(ProjectName) @@ -94,26 +94,26 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} - + {98537082-0fdb-40de-abd8-0dc5a4269bab} - + - + 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}. - - + + \ No newline at end of file diff --git a/src/modules/previewpane/PdfPreviewHandler/PdfPreviewHandler.csproj b/src/modules/previewpane/PdfPreviewHandler/PdfPreviewHandler.csproj index 069ce76d8f..9997442f39 100644 --- a/src/modules/previewpane/PdfPreviewHandler/PdfPreviewHandler.csproj +++ b/src/modules/previewpane/PdfPreviewHandler/PdfPreviewHandler.csproj @@ -1,7 +1,7 @@ - + - - + + enable @@ -10,7 +10,7 @@ PowerToys PdfPreviewHandler PowerToys PdfPreviewHandler ..\..\..\..\$(Platform)\$(Configuration)\PdfPreviewPaneDocumentation.xml - ..\..\..\..\$(Platform)\$(Configuration) + $(RepoRoot)$(Platform)\$(Configuration) false false true diff --git a/src/modules/previewpane/PdfPreviewHandlerCpp/PdfPreviewHandlerCpp.vcxproj b/src/modules/previewpane/PdfPreviewHandlerCpp/PdfPreviewHandlerCpp.vcxproj index 084e339e5f..75e46ff86f 100644 --- a/src/modules/previewpane/PdfPreviewHandlerCpp/PdfPreviewHandlerCpp.vcxproj +++ b/src/modules/previewpane/PdfPreviewHandlerCpp/PdfPreviewHandlerCpp.vcxproj @@ -1,13 +1,13 @@ - + + 16.0 Win32Proj {54f7c616-fd41-4e62-bff9-015686914f4d} PdfPreviewHandlerCpp - DynamicLibrary true @@ -31,7 +31,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ PowerToys.$(ProjectName) @@ -94,23 +94,23 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} - + - + 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}. - - + + \ No newline at end of file diff --git a/src/modules/previewpane/PdfThumbnailProvider/PdfThumbnailProvider.csproj b/src/modules/previewpane/PdfThumbnailProvider/PdfThumbnailProvider.csproj index b3702300c3..a5837836e3 100644 --- a/src/modules/previewpane/PdfThumbnailProvider/PdfThumbnailProvider.csproj +++ b/src/modules/previewpane/PdfThumbnailProvider/PdfThumbnailProvider.csproj @@ -1,7 +1,7 @@ - - + + enable @@ -13,7 +13,7 @@ PowerToys PdfPreviewHandler true PowerToys PdfPreviewHandler - ..\..\..\..\$(Platform)\$(Configuration) + $(RepoRoot)$(Platform)\$(Configuration) false false true diff --git a/src/modules/previewpane/PdfThumbnailProviderCpp/PdfThumbnailProviderCpp.vcxproj b/src/modules/previewpane/PdfThumbnailProviderCpp/PdfThumbnailProviderCpp.vcxproj index 113783a4f7..383872c12c 100644 --- a/src/modules/previewpane/PdfThumbnailProviderCpp/PdfThumbnailProviderCpp.vcxproj +++ b/src/modules/previewpane/PdfThumbnailProviderCpp/PdfThumbnailProviderCpp.vcxproj @@ -1,13 +1,13 @@ - + + 16.0 Win32Proj {ca5518ed-0458-4b09-8f53-4122b9888655} PdfThumbnailProviderCpp - DynamicLibrary true @@ -31,7 +31,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ PowerToys.$(ProjectName) @@ -91,28 +91,28 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} - + - - + + 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}. - - - + + + \ No newline at end of file diff --git a/src/modules/previewpane/QoiPreviewHandler/QoiPreviewHandler.csproj b/src/modules/previewpane/QoiPreviewHandler/QoiPreviewHandler.csproj index eaa6744203..d757f2ab57 100644 --- a/src/modules/previewpane/QoiPreviewHandler/QoiPreviewHandler.csproj +++ b/src/modules/previewpane/QoiPreviewHandler/QoiPreviewHandler.csproj @@ -1,7 +1,7 @@ - + - - + + enable @@ -10,7 +10,7 @@ PowerToys QoiPreviewHandler PowerToys QoiPreviewHandler ..\..\..\..\$(Platform)\$(Configuration)\QoiPreviewPaneDocumentation.xml - ..\..\..\..\$(Platform)\$(Configuration) + $(RepoRoot)$(Platform)\$(Configuration) false false true diff --git a/src/modules/previewpane/QoiPreviewHandlerCpp/QoiPreviewHandlerCpp.vcxproj b/src/modules/previewpane/QoiPreviewHandlerCpp/QoiPreviewHandlerCpp.vcxproj index 2e156fce12..5dd6320fb4 100644 --- a/src/modules/previewpane/QoiPreviewHandlerCpp/QoiPreviewHandlerCpp.vcxproj +++ b/src/modules/previewpane/QoiPreviewHandlerCpp/QoiPreviewHandlerCpp.vcxproj @@ -1,13 +1,13 @@ - + + 16.0 Win32Proj {3BAF9C81-A194-4925-A035-5E24A5D1E542} QoiPreviewHandlerCpp - DynamicLibrary true @@ -31,7 +31,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ PowerToys.$(ProjectName) @@ -94,26 +94,26 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} - + {98537082-0fdb-40de-abd8-0dc5a4269bab} - + - + 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}. - - + + \ No newline at end of file diff --git a/src/modules/previewpane/QoiThumbnailProvider/QoiThumbnailProvider.csproj b/src/modules/previewpane/QoiThumbnailProvider/QoiThumbnailProvider.csproj index b12679fad7..19d8a0f12d 100644 --- a/src/modules/previewpane/QoiThumbnailProvider/QoiThumbnailProvider.csproj +++ b/src/modules/previewpane/QoiThumbnailProvider/QoiThumbnailProvider.csproj @@ -1,7 +1,7 @@ - + - - + + enable @@ -13,7 +13,7 @@ PowerToys QoiPreviewHandler true PowerToys QoiPreviewHandler - ..\..\..\..\$(Platform)\$(Configuration) + $(RepoRoot)$(Platform)\$(Configuration) false false true diff --git a/src/modules/previewpane/QoiThumbnailProviderCpp/QoiThumbnailProviderCpp.vcxproj b/src/modules/previewpane/QoiThumbnailProviderCpp/QoiThumbnailProviderCpp.vcxproj index 15f196ca6b..75393f0e3a 100644 --- a/src/modules/previewpane/QoiThumbnailProviderCpp/QoiThumbnailProviderCpp.vcxproj +++ b/src/modules/previewpane/QoiThumbnailProviderCpp/QoiThumbnailProviderCpp.vcxproj @@ -1,13 +1,13 @@ - + + 16.0 Win32Proj {CCB5E44F-84D9-4203-83C6-1C9EC9302BC7} QoiThumbnailProviderCpp - DynamicLibrary true @@ -31,7 +31,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ PowerToys.$(ProjectName) @@ -91,28 +91,28 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} - + - - + + 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}. - - - + + + \ No newline at end of file diff --git a/src/modules/previewpane/StlThumbnailProvider/StlThumbnailProvider.csproj b/src/modules/previewpane/StlThumbnailProvider/StlThumbnailProvider.csproj index 951d1ec1d3..31da5d4a83 100644 --- a/src/modules/previewpane/StlThumbnailProvider/StlThumbnailProvider.csproj +++ b/src/modules/previewpane/StlThumbnailProvider/StlThumbnailProvider.csproj @@ -1,7 +1,7 @@ - + - - + + enable @@ -13,7 +13,7 @@ PowerToys StlPreviewHandler true PowerToys StlPreviewHandler - ..\..\..\..\$(Platform)\$(Configuration) + $(RepoRoot)$(Platform)\$(Configuration) false false true diff --git a/src/modules/previewpane/StlThumbnailProviderCpp/StlThumbnailProviderCpp.vcxproj b/src/modules/previewpane/StlThumbnailProviderCpp/StlThumbnailProviderCpp.vcxproj index 0e58b5999f..0328003ad2 100644 --- a/src/modules/previewpane/StlThumbnailProviderCpp/StlThumbnailProviderCpp.vcxproj +++ b/src/modules/previewpane/StlThumbnailProviderCpp/StlThumbnailProviderCpp.vcxproj @@ -1,13 +1,13 @@ - + + 16.0 Win32Proj {d6dcc3ae-18c0-488a-b978-baa9e3cff09d} StlThumbnailProviderCpp - DynamicLibrary true @@ -31,7 +31,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ PowerToys.$(ProjectName) @@ -91,28 +91,28 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} - + - - + + 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}. - - - + + + \ No newline at end of file diff --git a/src/modules/previewpane/SvgPreviewHandler/SvgPreviewHandler.csproj b/src/modules/previewpane/SvgPreviewHandler/SvgPreviewHandler.csproj index 32f8bc0e30..40ff418d99 100644 --- a/src/modules/previewpane/SvgPreviewHandler/SvgPreviewHandler.csproj +++ b/src/modules/previewpane/SvgPreviewHandler/SvgPreviewHandler.csproj @@ -1,7 +1,7 @@ - - + + enable @@ -10,7 +10,7 @@ PowerToys.SvgPreviewHandler PowerToys SvgPreviewHandler PowerToys SvgPreviewHandler - ..\..\..\..\$(Platform)\$(Configuration) + $(RepoRoot)$(Platform)\$(Configuration) ..\..\..\..\$(Platform)\$(Configuration)\SvgPreviewHandler.xml false false diff --git a/src/modules/previewpane/SvgPreviewHandlerCpp/SvgPreviewHandlerCpp.vcxproj b/src/modules/previewpane/SvgPreviewHandlerCpp/SvgPreviewHandlerCpp.vcxproj index 53fe7bdd53..003f66dcfa 100644 --- a/src/modules/previewpane/SvgPreviewHandlerCpp/SvgPreviewHandlerCpp.vcxproj +++ b/src/modules/previewpane/SvgPreviewHandlerCpp/SvgPreviewHandlerCpp.vcxproj @@ -1,13 +1,13 @@ - + + 16.0 Win32Proj {143f13e3-d2e3-4d83-b035-356612d99956} SvgPreviewHandlerCpp - DynamicLibrary true @@ -31,7 +31,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ PowerToys.$(ProjectName) @@ -94,26 +94,26 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} - + {98537082-0fdb-40de-abd8-0dc5a4269bab} - + - + 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}. - - + + \ No newline at end of file diff --git a/src/modules/previewpane/SvgThumbnailProvider/SvgThumbnailProvider.csproj b/src/modules/previewpane/SvgThumbnailProvider/SvgThumbnailProvider.csproj index 847c22bd6b..1d6382b039 100644 --- a/src/modules/previewpane/SvgThumbnailProvider/SvgThumbnailProvider.csproj +++ b/src/modules/previewpane/SvgThumbnailProvider/SvgThumbnailProvider.csproj @@ -1,7 +1,7 @@ - - + + enable @@ -13,7 +13,7 @@ PowerToys SvgPreviewHandler true PowerToys SvgPreviewHandler - ..\..\..\..\$(Platform)\$(Configuration) + $(RepoRoot)$(Platform)\$(Configuration) true false false diff --git a/src/modules/previewpane/SvgThumbnailProviderCpp/SvgThumbnailProviderCpp.vcxproj b/src/modules/previewpane/SvgThumbnailProviderCpp/SvgThumbnailProviderCpp.vcxproj index ae0ea11672..1c5eedabdd 100644 --- a/src/modules/previewpane/SvgThumbnailProviderCpp/SvgThumbnailProviderCpp.vcxproj +++ b/src/modules/previewpane/SvgThumbnailProviderCpp/SvgThumbnailProviderCpp.vcxproj @@ -1,13 +1,13 @@ - + + 16.0 Win32Proj {2bbc9e33-21ec-401c-84da-bb6590a9b2aa} SvgThumbnailProviderCpp - DynamicLibrary true @@ -31,7 +31,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ PowerToys.$(ProjectName) @@ -91,28 +91,28 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} - + - - + + 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}. - - - + + + \ No newline at end of file diff --git a/src/modules/previewpane/UnitTests-BgcodePreviewHandler/Preview.BgcodePreviewHandler.UnitTests.csproj b/src/modules/previewpane/UnitTests-BgcodePreviewHandler/Preview.BgcodePreviewHandler.UnitTests.csproj index ca3cbbd4f6..3dc6bb8036 100644 --- a/src/modules/previewpane/UnitTests-BgcodePreviewHandler/Preview.BgcodePreviewHandler.UnitTests.csproj +++ b/src/modules/previewpane/UnitTests-BgcodePreviewHandler/Preview.BgcodePreviewHandler.UnitTests.csproj @@ -1,6 +1,6 @@ - + - + UnitTests-BgcodePreviewHandler diff --git a/src/modules/previewpane/UnitTests-BgcodeThumbnailProvider/Preview.BgcodeThumbnailProvider.UnitTests.csproj b/src/modules/previewpane/UnitTests-BgcodeThumbnailProvider/Preview.BgcodeThumbnailProvider.UnitTests.csproj index 5a44d479d5..c1d8a153cf 100644 --- a/src/modules/previewpane/UnitTests-BgcodeThumbnailProvider/Preview.BgcodeThumbnailProvider.UnitTests.csproj +++ b/src/modules/previewpane/UnitTests-BgcodeThumbnailProvider/Preview.BgcodeThumbnailProvider.UnitTests.csproj @@ -1,6 +1,6 @@ - + - + UnitTests-BgcodeThumbnailProvider diff --git a/src/modules/previewpane/UnitTests-GcodePreviewHandler/Preview.GcodePreviewHandler.UnitTests.csproj b/src/modules/previewpane/UnitTests-GcodePreviewHandler/Preview.GcodePreviewHandler.UnitTests.csproj index 9fe8e06939..0a94141857 100644 --- a/src/modules/previewpane/UnitTests-GcodePreviewHandler/Preview.GcodePreviewHandler.UnitTests.csproj +++ b/src/modules/previewpane/UnitTests-GcodePreviewHandler/Preview.GcodePreviewHandler.UnitTests.csproj @@ -1,6 +1,6 @@ - + - + UnitTests-GcodePreviewHandler diff --git a/src/modules/previewpane/UnitTests-GcodeThumbnailProvider/Preview.GcodeThumbnailProvider.UnitTests.csproj b/src/modules/previewpane/UnitTests-GcodeThumbnailProvider/Preview.GcodeThumbnailProvider.UnitTests.csproj index 669463555f..a1bf1773d1 100644 --- a/src/modules/previewpane/UnitTests-GcodeThumbnailProvider/Preview.GcodeThumbnailProvider.UnitTests.csproj +++ b/src/modules/previewpane/UnitTests-GcodeThumbnailProvider/Preview.GcodeThumbnailProvider.UnitTests.csproj @@ -1,6 +1,6 @@ - + - + UnitTests-GcodeThumbnailProvider diff --git a/src/modules/previewpane/UnitTests-MarkdownPreviewHandler/Preview.MarkdownPreviewHandler.UnitTests.csproj b/src/modules/previewpane/UnitTests-MarkdownPreviewHandler/Preview.MarkdownPreviewHandler.UnitTests.csproj index 8de2e96772..fbb7639dec 100644 --- a/src/modules/previewpane/UnitTests-MarkdownPreviewHandler/Preview.MarkdownPreviewHandler.UnitTests.csproj +++ b/src/modules/previewpane/UnitTests-MarkdownPreviewHandler/Preview.MarkdownPreviewHandler.UnitTests.csproj @@ -1,6 +1,6 @@ - + - + UnitTests-MarkdownPreviewHandler diff --git a/src/modules/previewpane/UnitTests-PdfPreviewHandler/Preview.PdfPreviewHandler.UnitTests.csproj b/src/modules/previewpane/UnitTests-PdfPreviewHandler/Preview.PdfPreviewHandler.UnitTests.csproj index 801766eca3..d2aea2043d 100644 --- a/src/modules/previewpane/UnitTests-PdfPreviewHandler/Preview.PdfPreviewHandler.UnitTests.csproj +++ b/src/modules/previewpane/UnitTests-PdfPreviewHandler/Preview.PdfPreviewHandler.UnitTests.csproj @@ -1,6 +1,6 @@ - + - + UnitTests-PdfPreviewHandler diff --git a/src/modules/previewpane/UnitTests-PdfThumbnailProvider/Preview.PdfThumbnailProvider.UnitTests.csproj b/src/modules/previewpane/UnitTests-PdfThumbnailProvider/Preview.PdfThumbnailProvider.UnitTests.csproj index 5e24595147..6f31041e75 100644 --- a/src/modules/previewpane/UnitTests-PdfThumbnailProvider/Preview.PdfThumbnailProvider.UnitTests.csproj +++ b/src/modules/previewpane/UnitTests-PdfThumbnailProvider/Preview.PdfThumbnailProvider.UnitTests.csproj @@ -1,6 +1,6 @@ - + - + UnitTests-PdfThumbnailProvider diff --git a/src/modules/previewpane/UnitTests-PreviewHandlerCommon/Preview.PreviewHandlerCommon.UnitTests.csproj b/src/modules/previewpane/UnitTests-PreviewHandlerCommon/Preview.PreviewHandlerCommon.UnitTests.csproj index 0d682d2ddd..934ff4a40c 100644 --- a/src/modules/previewpane/UnitTests-PreviewHandlerCommon/Preview.PreviewHandlerCommon.UnitTests.csproj +++ b/src/modules/previewpane/UnitTests-PreviewHandlerCommon/Preview.PreviewHandlerCommon.UnitTests.csproj @@ -1,6 +1,6 @@ - + - + UnitTests-PreviewHandlerCommon diff --git a/src/modules/previewpane/UnitTests-QoiPreviewHandler/Preview.QoiPreviewHandler.UnitTests.csproj b/src/modules/previewpane/UnitTests-QoiPreviewHandler/Preview.QoiPreviewHandler.UnitTests.csproj index 2c689dc7cd..e251c35d45 100644 --- a/src/modules/previewpane/UnitTests-QoiPreviewHandler/Preview.QoiPreviewHandler.UnitTests.csproj +++ b/src/modules/previewpane/UnitTests-QoiPreviewHandler/Preview.QoiPreviewHandler.UnitTests.csproj @@ -1,6 +1,6 @@ - + - + UnitTests-QoiPreviewHandler diff --git a/src/modules/previewpane/UnitTests-QoiThumbnailProvider/Preview.QoiThumbnailProvider.UnitTests.csproj b/src/modules/previewpane/UnitTests-QoiThumbnailProvider/Preview.QoiThumbnailProvider.UnitTests.csproj index 96b52b0978..86ccad0f3d 100644 --- a/src/modules/previewpane/UnitTests-QoiThumbnailProvider/Preview.QoiThumbnailProvider.UnitTests.csproj +++ b/src/modules/previewpane/UnitTests-QoiThumbnailProvider/Preview.QoiThumbnailProvider.UnitTests.csproj @@ -1,6 +1,6 @@ - + - + UnitTests-QoiThumbnailProvider diff --git a/src/modules/previewpane/UnitTests-StlThumbnailProvider/Preview.StlThumbnailProvider.UnitTests.csproj b/src/modules/previewpane/UnitTests-StlThumbnailProvider/Preview.StlThumbnailProvider.UnitTests.csproj index d27e90a2cf..36fe2bd908 100644 --- a/src/modules/previewpane/UnitTests-StlThumbnailProvider/Preview.StlThumbnailProvider.UnitTests.csproj +++ b/src/modules/previewpane/UnitTests-StlThumbnailProvider/Preview.StlThumbnailProvider.UnitTests.csproj @@ -1,6 +1,6 @@ - + - + UnitTests-StlThumbnailProvider diff --git a/src/modules/previewpane/UnitTests-SvgPreviewHandler/Preview.SvgPreviewHandler.UnitTests.csproj b/src/modules/previewpane/UnitTests-SvgPreviewHandler/Preview.SvgPreviewHandler.UnitTests.csproj index 9ae6a01618..ba5997925f 100644 --- a/src/modules/previewpane/UnitTests-SvgPreviewHandler/Preview.SvgPreviewHandler.UnitTests.csproj +++ b/src/modules/previewpane/UnitTests-SvgPreviewHandler/Preview.SvgPreviewHandler.UnitTests.csproj @@ -1,6 +1,6 @@ - + - + UnitTests-SvgPreviewHandler diff --git a/src/modules/previewpane/UnitTests-SvgThumbnailProvider/Preview.SvgThumbnailProvider.UnitTests.csproj b/src/modules/previewpane/UnitTests-SvgThumbnailProvider/Preview.SvgThumbnailProvider.UnitTests.csproj index c06b5c2298..0975fbc9e2 100644 --- a/src/modules/previewpane/UnitTests-SvgThumbnailProvider/Preview.SvgThumbnailProvider.UnitTests.csproj +++ b/src/modules/previewpane/UnitTests-SvgThumbnailProvider/Preview.SvgThumbnailProvider.UnitTests.csproj @@ -1,6 +1,6 @@ - + - + UnitTests-SvgThumbnailProvider diff --git a/src/modules/previewpane/powerpreview/powerpreview.vcxproj b/src/modules/previewpane/powerpreview/powerpreview.vcxproj index 4a29b66dc6..d9926e7b5b 100644 --- a/src/modules/previewpane/powerpreview/powerpreview.vcxproj +++ b/src/modules/previewpane/powerpreview/powerpreview.vcxproj @@ -1,8 +1,9 @@ - + + - + 15.0 @@ -11,7 +12,6 @@ examplepowertoy powerpreview - DynamicLibrary @@ -28,7 +28,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\ + $(RepoRoot)$(Platform)\$(Configuration)\ PowerToys.powerpreview @@ -36,7 +36,7 @@ _WINDOWS;_USRDLL;%(PreprocessorDefinitions) - ..\;..\..\..\common;..\..\..\common\telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories) + ..\;..\..\..\common;$(RepoRoot)src\common\telemetry;..\..\;$(RepoRoot)src\;%(AdditionalIncludeDirectories) $(OutDir)$(TargetName)$(TargetExt) @@ -65,19 +65,19 @@ - + {7319089e-46d6-4400-bc65-e39bdf1416ee} - + {caba8dfb-823b-4bf2-93ac-3f31984150d9} - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {1d5be09d-78c0-4fd7-af00-ae7c1af7c525} - + {6955446d-23f7-4023-9bb3-8657f904af99} @@ -90,18 +90,18 @@ Designer - + - - + + 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}. - - - + + + \ No newline at end of file diff --git a/src/modules/registrypreview/RegistryPreview.FuzzTests/RegistryPreview.FuzzTests.csproj b/src/modules/registrypreview/RegistryPreview.FuzzTests/RegistryPreview.FuzzTests.csproj index c4d6fa1cd2..9fff08025f 100644 --- a/src/modules/registrypreview/RegistryPreview.FuzzTests/RegistryPreview.FuzzTests.csproj +++ b/src/modules/registrypreview/RegistryPreview.FuzzTests/RegistryPreview.FuzzTests.csproj @@ -1,7 +1,7 @@ - - + + x64;ARM64 @@ -11,7 +11,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\tests\RegistryPreview.FuzzTests\ + $(RepoRoot)$(Platform)\$(Configuration)\tests\RegistryPreview.FuzzTests\ diff --git a/src/modules/registrypreview/RegistryPreview/RegistryPreview.csproj b/src/modules/registrypreview/RegistryPreview/RegistryPreview.csproj index 8ca723808f..a7376b7fe4 100644 --- a/src/modules/registrypreview/RegistryPreview/RegistryPreview.csproj +++ b/src/modules/registrypreview/RegistryPreview/RegistryPreview.csproj @@ -1,7 +1,7 @@ - + - - + + WinExe @@ -15,7 +15,7 @@ false false true - ..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps + $(RepoRoot)$(Platform)\$(Configuration)\WinUI3Apps PowerToys.RegistryPreview Assets\RegistryPreview\RegistryPreview.ico diff --git a/src/modules/registrypreview/RegistryPreviewExt/RegistryPreviewExt.vcxproj b/src/modules/registrypreview/RegistryPreviewExt/RegistryPreviewExt.vcxproj index 02818e8615..81c8864a5c 100644 --- a/src/modules/registrypreview/RegistryPreviewExt/RegistryPreviewExt.vcxproj +++ b/src/modules/registrypreview/RegistryPreviewExt/RegistryPreviewExt.vcxproj @@ -1,6 +1,7 @@ - + + Debug @@ -25,7 +26,6 @@ Win32Proj RegistryPreviewExt - DynamicLibrary true @@ -49,7 +49,7 @@ - ..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps\ + $(RepoRoot)$(Platform)\$(Configuration)\WinUI3Apps\ PowerToys.RegistryPreviewExt @@ -58,7 +58,7 @@ true _DEBUG;REGISTRYPREVIEWEXT_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true - ..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories) + $(RepoRoot)src\common\inc;$(RepoRoot)src\common\Telemetry;..\..\;$(RepoRoot)src\;%(AdditionalIncludeDirectories) Windows @@ -75,7 +75,7 @@ true NDEBUG;REGISTRYPREVIEWEXT_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true - ..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories) + $(RepoRoot)src\common\inc;$(RepoRoot)src\common\Telemetry;..\..\;$(RepoRoot)src\;%(AdditionalIncludeDirectories) Windows @@ -100,10 +100,10 @@ - + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} - + {6955446d-23f7-4023-9bb3-8657f904af99} @@ -114,17 +114,17 @@ - + - - + + 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}. - - - + + + \ No newline at end of file diff --git a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewUILib.csproj b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewUILib.csproj index 22fca0e273..7b91f8e0d6 100644 --- a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewUILib.csproj +++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewUILib.csproj @@ -1,7 +1,7 @@ - + - - + + Library diff --git a/src/runner/runner.vcxproj b/src/runner/runner.vcxproj index 88b74e3faa..16587c73ac 100644 --- a/src/runner/runner.vcxproj +++ b/src/runner/runner.vcxproj @@ -1,4 +1,4 @@ - + @@ -28,7 +28,7 @@ - + Application @@ -164,7 +164,7 @@ - + diff --git a/src/settings-ui/QuickAccess.UI/PowerToys.QuickAccess.csproj b/src/settings-ui/QuickAccess.UI/PowerToys.QuickAccess.csproj index ea4586f217..c3c48d37b3 100644 --- a/src/settings-ui/QuickAccess.UI/PowerToys.QuickAccess.csproj +++ b/src/settings-ui/QuickAccess.UI/PowerToys.QuickAccess.csproj @@ -1,6 +1,6 @@ - - - + + + WinExe @@ -15,7 +15,7 @@ false false app.manifest - ..\..\..\$(Platform)\$(Configuration)\WinUI3Apps + $(RepoRoot)$(Platform)\$(Configuration)\WinUI3Apps false false enable diff --git a/src/settings-ui/Settings.UI.Controls/Settings.UI.Controls.csproj b/src/settings-ui/Settings.UI.Controls/Settings.UI.Controls.csproj index fac43d56a4..6cdd3d0867 100644 --- a/src/settings-ui/Settings.UI.Controls/Settings.UI.Controls.csproj +++ b/src/settings-ui/Settings.UI.Controls/Settings.UI.Controls.csproj @@ -1,6 +1,6 @@ - - + + Library diff --git a/src/settings-ui/Settings.UI.Library/Settings.UI.Library.csproj b/src/settings-ui/Settings.UI.Library/Settings.UI.Library.csproj index 8ecd0da804..744e42e38c 100644 --- a/src/settings-ui/Settings.UI.Library/Settings.UI.Library.csproj +++ b/src/settings-ui/Settings.UI.Library/Settings.UI.Library.csproj @@ -1,7 +1,7 @@ - + - - + + PowerToys Settings UI Library PowerToys.Settings.UI.Lib diff --git a/src/settings-ui/Settings.UI.UnitTests/Settings.UI.UnitTests.csproj b/src/settings-ui/Settings.UI.UnitTests/Settings.UI.UnitTests.csproj index 3c2260363a..97bb22c486 100644 --- a/src/settings-ui/Settings.UI.UnitTests/Settings.UI.UnitTests.csproj +++ b/src/settings-ui/Settings.UI.UnitTests/Settings.UI.UnitTests.csproj @@ -1,10 +1,10 @@ - + - + false - ..\..\..\$(Configuration)\$(Platform)\tests\SettingsTests\ + $(RepoRoot)$(Configuration)\$(Platform)\tests\SettingsTests\ diff --git a/src/settings-ui/Settings.UI.XamlIndexBuilder/Settings.UI.XamlIndexBuilder.csproj b/src/settings-ui/Settings.UI.XamlIndexBuilder/Settings.UI.XamlIndexBuilder.csproj index dba7fdcd3b..91416fc676 100644 --- a/src/settings-ui/Settings.UI.XamlIndexBuilder/Settings.UI.XamlIndexBuilder.csproj +++ b/src/settings-ui/Settings.UI.XamlIndexBuilder/Settings.UI.XamlIndexBuilder.csproj @@ -1,6 +1,6 @@ - + - + net9.0 diff --git a/src/settings-ui/Settings.UI/PowerToys.Settings.csproj b/src/settings-ui/Settings.UI/PowerToys.Settings.csproj index 6274dc672a..c2b7d81ee4 100644 --- a/src/settings-ui/Settings.UI/PowerToys.Settings.csproj +++ b/src/settings-ui/Settings.UI/PowerToys.Settings.csproj @@ -1,7 +1,7 @@ - + - - + + WinExe @@ -15,7 +15,7 @@ Assets\Settings\icon.ico true - ..\..\..\$(Platform)\$(Configuration)\WinUI3Apps + $(RepoRoot)$(Platform)\$(Configuration)\WinUI3Apps PowerToys.Settings.pri diff --git a/src/settings-ui/UITest-Settings/UITest-Settings.csproj b/src/settings-ui/UITest-Settings/UITest-Settings.csproj index e93560ae17..917efdf1a3 100644 --- a/src/settings-ui/UITest-Settings/UITest-Settings.csproj +++ b/src/settings-ui/UITest-Settings/UITest-Settings.csproj @@ -1,6 +1,6 @@ - + - + {29B91A80-0590-4B1F-89B8-4F8812A7F116} @@ -14,7 +14,7 @@ - ..\..\..\$(Platform)\$(Configuration)\tests\UITests-Settings\ + $(RepoRoot)$(Platform)\$(Configuration)\tests\UITests-Settings\ diff --git a/tools/BugReportTool/BugReportTool/BugReportTool.vcxproj b/tools/BugReportTool/BugReportTool/BugReportTool.vcxproj index 3429200a37..cf12743f7b 100644 --- a/tools/BugReportTool/BugReportTool/BugReportTool.vcxproj +++ b/tools/BugReportTool/BugReportTool/BugReportTool.vcxproj @@ -1,5 +1,6 @@ - + + 16.0 @@ -8,7 +9,6 @@ BugReportTool BugReportTool - @@ -16,7 +16,7 @@ Application PowerToys.$(ProjectName) - $(SolutionDir)..\..\$(Platform)\$(Configuration)\Tools\ + $(RepoRoot)$(Platform)\$(Configuration)\Tools\ @@ -63,7 +63,7 @@ - + @@ -85,4 +85,4 @@ - \ No newline at end of file + diff --git a/tools/MonitorReportTool/MonitorReportTool.vcxproj b/tools/MonitorReportTool/MonitorReportTool.vcxproj index fed5602042..fddbe44212 100644 --- a/tools/MonitorReportTool/MonitorReportTool.vcxproj +++ b/tools/MonitorReportTool/MonitorReportTool.vcxproj @@ -36,7 +36,7 @@ false - $(SolutionDir)..\..\$(Platform)\$(Configuration)\$(ProjectName)\ + $(RepoRoot)$(Platform)\$(Configuration)\$(ProjectName)\ PowerToys.$(ProjectName) diff --git a/tools/StylesReportTool/StylesReportTool.vcxproj b/tools/StylesReportTool/StylesReportTool.vcxproj index 0e31780c10..d35295b201 100644 --- a/tools/StylesReportTool/StylesReportTool.vcxproj +++ b/tools/StylesReportTool/StylesReportTool.vcxproj @@ -36,7 +36,7 @@ false - $(SolutionDir)..\..\$(Platform)\$(Configuration)\$(ProjectName)\ + $(RepoRoot)$(Platform)\$(Configuration)\$(ProjectName)\ PowerToys.$(ProjectName) diff --git a/tools/module_loader/ModuleLoader.vcxproj b/tools/module_loader/ModuleLoader.vcxproj index 52a45f3be5..8917ecbc78 100644 --- a/tools/module_loader/ModuleLoader.vcxproj +++ b/tools/module_loader/ModuleLoader.vcxproj @@ -98,7 +98,7 @@ _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true stdcpp20 - $(ProjectDir)src;$(SolutionDir)src\modules\interface;$(SolutionDir)src;%(AdditionalIncludeDirectories) + $(ProjectDir)src;$(RepoRoot)src\modules\interface;$(RepoRoot)src;%(AdditionalIncludeDirectories) NotUsing false @@ -119,7 +119,7 @@ _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true stdcpp20 - $(ProjectDir)src;$(SolutionDir)src\modules\interface;$(SolutionDir)src;%(AdditionalIncludeDirectories) + $(ProjectDir)src;$(RepoRoot)src\modules\interface;$(RepoRoot)src;%(AdditionalIncludeDirectories) NotUsing false @@ -142,7 +142,7 @@ NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true stdcpp20 - $(ProjectDir)src;$(SolutionDir)src\modules\interface;$(SolutionDir)src;%(AdditionalIncludeDirectories) + $(ProjectDir)src;$(RepoRoot)src\modules\interface;$(RepoRoot)src;%(AdditionalIncludeDirectories) NotUsing false @@ -167,7 +167,7 @@ NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true stdcpp20 - $(ProjectDir)src;$(SolutionDir)src\modules\interface;$(SolutionDir)src;%(AdditionalIncludeDirectories) + $(ProjectDir)src;$(RepoRoot)src\modules\interface;$(RepoRoot)src;%(AdditionalIncludeDirectories) NotUsing false diff --git a/tools/project_template/ModuleTemplate/ModuleTemplate.vcxproj b/tools/project_template/ModuleTemplate/ModuleTemplate.vcxproj index af96353e8b..0bb45add9d 100644 --- a/tools/project_template/ModuleTemplate/ModuleTemplate.vcxproj +++ b/tools/project_template/ModuleTemplate/ModuleTemplate.vcxproj @@ -77,7 +77,7 @@ - $(SolutionDir)src\;$(SolutionDir)src\modules;$(SolutionDir)src\common\Telemetry;%(AdditionalIncludeDirectories) + $(RepoRoot)src\;$(RepoRoot)src\modules;$(RepoRoot)src\common\Telemetry;%(AdditionalIncludeDirectories) diff --git a/tools/project_template/ModuleTemplate/ModuleTemplateCompileTest.vcxproj b/tools/project_template/ModuleTemplate/ModuleTemplateCompileTest.vcxproj index 2d56b4d499..cdc76f9d45 100644 --- a/tools/project_template/ModuleTemplate/ModuleTemplateCompileTest.vcxproj +++ b/tools/project_template/ModuleTemplate/ModuleTemplateCompileTest.vcxproj @@ -1,5 +1,6 @@ + 15.0 @@ -8,7 +9,6 @@ templatenamespace ModuleTemplateCompileTest - DynamicLibrary true @@ -76,7 +76,7 @@ - $(SolutionDir)src\;$(SolutionDir)src\modules;$(SolutionDir)src\common\Telemetry;%(AdditionalIncludeDirectories) + $(RepoRoot)src\;$(RepoRoot)src\modules;$(RepoRoot)src\common\Telemetry;%(AdditionalIncludeDirectories) @@ -113,4 +113,4 @@ - \ No newline at end of file + From 7477b561a174975f04844bdb25b406dc732145ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Pol=C3=A1=C5=A1ek?= Date: Mon, 9 Feb 2026 20:37:59 +0100 Subject: [PATCH 16/41] CmdPal: Add precomputed fuzzy string matching to Command Palette (#44090) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary of the Pull Request This PR improves fuzzy matching in Command Palette by: - Precomputing normalized strings to enable faster comparisons - Reducing memory allocations during matching, effectively down to zero It also introduces several behavioral improvements: - Strips diacritics from the normalized search string to improve matching across languages - Suppresses the same-case bonus when the query consists entirely of lowercase characters -- reflecting typical user input patterns - Allows skipping word separators -- enabling queries like Power Point to match PowerPoint This implementation is currently kept internal and is used only on the home page. For other scenarios, the `FuzzyStringMatcher` from `Microsoft.CommandPalette.Extensions.Toolkit` is being improved instead. `PrecomputedFuzzyMatcher` offers up to a 100× performance improvement over the current `FuzzyStringMatcher`, and approximately 2–5× better performance compared to the improved version. The improvement might seem small, but it adds up and becomes quite noticeable when filtering the entire home page—whether the user starts a new search or changes the query non-incrementally (e.g., using backspace). ## PR Checklist - [x] Closes: #45226 - [x] Closes: #44066 - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx ## Detailed Description of the Pull Request / Additional comments ## Validation Steps Performed --- .github/actions/spell-check/excludes.txt | 1 + .../Helpers/IPrecomputedListItem.cs | 27 + .../Helpers/InternalListHelpers.cs | 142 +++++ .../Text/BloomFilter.cs | 40 ++ .../Text/FuzzyMatcherProvider.cs | 52 ++ .../Text/FuzzyQuery.cs | 65 ++ .../Text/FuzzyTarget.cs | 46 ++ .../Text/FuzzyTargetCache.cs | 34 ++ .../Text/IBloomFilter.cs | 12 + .../Text/IFuzzyMatcherProvider.cs | 12 + .../Text/IPrecomputedFuzzyMatcher.cs | 16 + .../Text/IStringFolder.cs | 10 + .../Text/PinyinFuzzyMatcherOptions.cs | 13 + .../Text/PinyinMode.cs | 12 + .../Text/PrecomputedFuzzyMatcher.cs | 575 ++++++++++++++++++ .../Text/PrecomputedFuzzyMatcherOptions.cs | 40 ++ .../Text/PrecomputedFuzzyMatcherWithPinyin.cs | 177 ++++++ .../Text/StringFolder.cs | 163 +++++ .../Text/SymbolClassifier.cs | 29 + .../Text/SymbolKind.cs | 12 + .../CommandItemViewModel.cs | 23 +- .../ContextMenuViewModel.cs | 31 +- .../Commands/MainListPage.cs | 179 +++--- .../Commands/MainListPageResultFactory.cs | 11 +- .../TopLevelViewModel.cs | 35 +- .../cmdpal/Microsoft.CmdPal.UI/App.xaml.cs | 4 + .../Controls/ContextMenu.xaml.cs | 12 +- .../PowerToysRootPageService.cs | 5 +- .../Text/PrecomputedFuzzyMatcherEmojiTests.cs | 78 +++ .../PrecomputedFuzzyMatcherOptionsTests.cs | 84 +++ ...computedFuzzyMatcherSecondaryInputTests.cs | 227 +++++++ .../Text/PrecomputedFuzzyMatcherTests.cs | 209 +++++++ .../PrecomputedFuzzyMatcherUnicodeTests.cs | 124 ++++ .../PrecomputedFuzzyMatcherWithPinyinTests.cs | 117 ++++ .../Text/StringFolderTests.cs | 55 ++ .../MainListPageResultFactoryTests.cs | 21 +- .../RecentCommandsTests.cs | 33 +- .../Microsoft.CmdPal.Ext.Apps/AppListItem.cs | 38 +- 38 files changed, 2626 insertions(+), 138 deletions(-) create mode 100644 src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Helpers/IPrecomputedListItem.cs create mode 100644 src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Helpers/InternalListHelpers.cs create mode 100644 src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/BloomFilter.cs create mode 100644 src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/FuzzyMatcherProvider.cs create mode 100644 src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/FuzzyQuery.cs create mode 100644 src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/FuzzyTarget.cs create mode 100644 src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/FuzzyTargetCache.cs create mode 100644 src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/IBloomFilter.cs create mode 100644 src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/IFuzzyMatcherProvider.cs create mode 100644 src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/IPrecomputedFuzzyMatcher.cs create mode 100644 src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/IStringFolder.cs create mode 100644 src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/PinyinFuzzyMatcherOptions.cs create mode 100644 src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/PinyinMode.cs create mode 100644 src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/PrecomputedFuzzyMatcher.cs create mode 100644 src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/PrecomputedFuzzyMatcherOptions.cs create mode 100644 src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/PrecomputedFuzzyMatcherWithPinyin.cs create mode 100644 src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/StringFolder.cs create mode 100644 src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/SymbolClassifier.cs create mode 100644 src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/SymbolKind.cs create mode 100644 src/modules/cmdpal/Tests/Microsoft.CmdPal.Core.Common.UnitTests/Text/PrecomputedFuzzyMatcherEmojiTests.cs create mode 100644 src/modules/cmdpal/Tests/Microsoft.CmdPal.Core.Common.UnitTests/Text/PrecomputedFuzzyMatcherOptionsTests.cs create mode 100644 src/modules/cmdpal/Tests/Microsoft.CmdPal.Core.Common.UnitTests/Text/PrecomputedFuzzyMatcherSecondaryInputTests.cs create mode 100644 src/modules/cmdpal/Tests/Microsoft.CmdPal.Core.Common.UnitTests/Text/PrecomputedFuzzyMatcherTests.cs create mode 100644 src/modules/cmdpal/Tests/Microsoft.CmdPal.Core.Common.UnitTests/Text/PrecomputedFuzzyMatcherUnicodeTests.cs create mode 100644 src/modules/cmdpal/Tests/Microsoft.CmdPal.Core.Common.UnitTests/Text/PrecomputedFuzzyMatcherWithPinyinTests.cs create mode 100644 src/modules/cmdpal/Tests/Microsoft.CmdPal.Core.Common.UnitTests/Text/StringFolderTests.cs diff --git a/.github/actions/spell-check/excludes.txt b/.github/actions/spell-check/excludes.txt index 9e587fa284..b029f1dbcb 100644 --- a/.github/actions/spell-check/excludes.txt +++ b/.github/actions/spell-check/excludes.txt @@ -111,6 +111,7 @@ ^src/modules/cmdpal/ext/SamplePagesExtension/Pages/SampleMarkdownImagesPage\.cs$ ^src/modules/cmdpal/Microsoft\.CmdPal\.UI/Settings/InternalPage\.SampleData\.cs$ ^src/modules/cmdpal/Tests/Microsoft\.CmdPal\.Core\.Common\.UnitTests/.*\.TestData\.cs$ +^src/modules/cmdpal/Tests/Microsoft\.CmdPal\.Core\.Common\.UnitTests/Text/.*\.cs$ ^src/modules/colorPicker/ColorPickerUI/Shaders/GridShader\.cso$ ^src/modules/launcher/Plugins/Microsoft\.PowerToys\.Run\.Plugin\.TimeDate/Properties/ ^src/modules/MouseUtils/MouseJumpUI/MainForm\.resx$ diff --git a/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Helpers/IPrecomputedListItem.cs b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Helpers/IPrecomputedListItem.cs new file mode 100644 index 0000000000..2847ee7b12 --- /dev/null +++ b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Helpers/IPrecomputedListItem.cs @@ -0,0 +1,27 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.CmdPal.Core.Common.Text; + +namespace Microsoft.CmdPal.Core.Common.Helpers; + +/// +/// Represents an item that can provide precomputed fuzzy matching targets for its title and subtitle. +/// +public interface IPrecomputedListItem +{ + /// + /// Gets the fuzzy matching target for the item's title. + /// + /// The precomputed fuzzy matcher used to build the target. + /// The fuzzy target for the title. + FuzzyTarget GetTitleTarget(IPrecomputedFuzzyMatcher matcher); + + /// + /// Gets the fuzzy matching target for the item's subtitle. + /// + /// The precomputed fuzzy matcher used to build the target. + /// The fuzzy target for the subtitle. + FuzzyTarget GetSubtitleTarget(IPrecomputedFuzzyMatcher matcher); +} diff --git a/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Helpers/InternalListHelpers.cs b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Helpers/InternalListHelpers.cs new file mode 100644 index 0000000000..60d841aaf8 --- /dev/null +++ b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Helpers/InternalListHelpers.cs @@ -0,0 +1,142 @@ +// 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.Buffers; +using System.Diagnostics; +using Microsoft.CmdPal.Core.Common.Text; + +namespace Microsoft.CmdPal.Core.Common.Helpers; + +public static partial class InternalListHelpers +{ + public static RoScored[] FilterListWithScores( + IEnumerable? items, + in FuzzyQuery query, + in ScoringFunction scoreFunction) + { + if (items == null) + { + return []; + } + + // Try to get initial capacity hint + var initialCapacity = items switch + { + ICollection col => col.Count, + IReadOnlyCollection rc => rc.Count, + _ => 64, + }; + + var buffer = ArrayPool>.Shared.Rent(initialCapacity); + var count = 0; + + try + { + foreach (var item in items) + { + var score = scoreFunction(in query, item); + if (score <= 0) + { + continue; + } + + if (count == buffer.Length) + { + GrowBuffer(ref buffer, count); + } + + buffer[count++] = new RoScored(item, score); + } + + Array.Sort(buffer, 0, count, default(RoScoredDescendingComparer)); + var result = GC.AllocateUninitializedArray>(count); + buffer.AsSpan(0, count).CopyTo(result); + return result; + } + finally + { + ArrayPool>.Shared.Return(buffer); + } + } + + private static void GrowBuffer(ref RoScored[] buffer, int count) + { + var newBuffer = ArrayPool>.Shared.Rent(buffer.Length * 2); + buffer.AsSpan(0, count).CopyTo(newBuffer); + ArrayPool>.Shared.Return(buffer); + buffer = newBuffer; + } + + public static T[] FilterList(IEnumerable items, in FuzzyQuery query, ScoringFunction scoreFunction) + { + // Try to get initial capacity hint + var initialCapacity = items switch + { + ICollection col => col.Count, + IReadOnlyCollection rc => rc.Count, + _ => 64, + }; + + var buffer = ArrayPool>.Shared.Rent(initialCapacity); + var count = 0; + + try + { + foreach (var item in items) + { + var score = scoreFunction(in query, item); + if (score <= 0) + { + continue; + } + + if (count == buffer.Length) + { + GrowBuffer(ref buffer, count); + } + + buffer[count++] = new RoScored(item, score); + } + + Array.Sort(buffer, 0, count, default(RoScoredDescendingComparer)); + + var result = GC.AllocateUninitializedArray(count); + for (var i = 0; i < count; i++) + { + result[i] = buffer[i].Item; + } + + return result; + } + finally + { + ArrayPool>.Shared.Return(buffer); + } + } + + private readonly struct RoScoredDescendingComparer : IComparer> + { + public int Compare(RoScored x, RoScored y) => y.Score.CompareTo(x.Score); + } +} + +public delegate int ScoringFunction(in FuzzyQuery query, T item); + +[DebuggerDisplay($"{{{nameof(GetDebuggerDisplay)}(),nq}}")] +public readonly struct RoScored +{ + public readonly int Score; + public readonly T Item; + + public RoScored(T item, int score) + { + Score = score; + Item = item; + } + + private string GetDebuggerDisplay() + { + return "Score = " + Score + ", Item = " + Item; + } +} diff --git a/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/BloomFilter.cs b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/BloomFilter.cs new file mode 100644 index 0000000000..59255a1bae --- /dev/null +++ b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/BloomFilter.cs @@ -0,0 +1,40 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Runtime.CompilerServices; + +namespace Microsoft.CmdPal.Core.Common.Text; + +public sealed class BloomFilter : IBloomFilter +{ + public ulong Compute(string input) + { + ulong bloom = 0; + + foreach (var ch in input) + { + if (SymbolClassifier.Classify(ch) == SymbolKind.WordSeparator) + { + continue; + } + + var h = (uint)ch * 0x45d9f3b; + bloom |= 1UL << (int)(h & 31); + bloom |= 1UL << (int)(((h >> 16) & 31) + 32); + + if (bloom == ulong.MaxValue) + { + break; + } + } + + return bloom; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool MightContain(ulong candidateBloom, ulong queryBloom) + { + return (candidateBloom & queryBloom) == queryBloom; + } +} diff --git a/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/FuzzyMatcherProvider.cs b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/FuzzyMatcherProvider.cs new file mode 100644 index 0000000000..80c5fa9ace --- /dev/null +++ b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/FuzzyMatcherProvider.cs @@ -0,0 +1,52 @@ +// 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.Globalization; + +namespace Microsoft.CmdPal.Core.Common.Text; + +public sealed class FuzzyMatcherProvider : IFuzzyMatcherProvider +{ + private readonly IBloomFilter _bloomCalculator = new BloomFilter(); + private readonly IStringFolder _normalizer = new StringFolder(); + + private IPrecomputedFuzzyMatcher _current; + + public FuzzyMatcherProvider(PrecomputedFuzzyMatcherOptions core, PinyinFuzzyMatcherOptions? pinyin = null) + { + _current = CreateMatcher(core, pinyin); + } + + public IPrecomputedFuzzyMatcher Current => Volatile.Read(ref _current); + + public void UpdateSettings(PrecomputedFuzzyMatcherOptions core, PinyinFuzzyMatcherOptions? pinyin = null) + { + Volatile.Write(ref _current, CreateMatcher(core, pinyin)); + } + + private IPrecomputedFuzzyMatcher CreateMatcher(PrecomputedFuzzyMatcherOptions core, PinyinFuzzyMatcherOptions? pinyin) + { + return pinyin is null || !IsPinyinEnabled(pinyin) + ? new PrecomputedFuzzyMatcher(core, _normalizer, _bloomCalculator) + : new PrecomputedFuzzyMatcherWithPinyin(core, pinyin, _normalizer, _bloomCalculator); + } + + private static bool IsPinyinEnabled(PinyinFuzzyMatcherOptions o) + { + return o.Mode switch + { + PinyinMode.Off => false, + PinyinMode.On => true, + PinyinMode.AutoSimplifiedChineseUi => IsSimplifiedChineseUi(), + _ => false, + }; + } + + private static bool IsSimplifiedChineseUi() + { + var culture = CultureInfo.CurrentUICulture; + return culture.Name.StartsWith("zh-CN", StringComparison.OrdinalIgnoreCase) + || culture.Name.StartsWith("zh-Hans", StringComparison.OrdinalIgnoreCase); + } +} diff --git a/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/FuzzyQuery.cs b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/FuzzyQuery.cs new file mode 100644 index 0000000000..80de31bd7a --- /dev/null +++ b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/FuzzyQuery.cs @@ -0,0 +1,65 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.CmdPal.Core.Common.Text; + +public readonly struct FuzzyQuery +{ + public readonly string Original; + + public readonly string Folded; + + public readonly ulong Bloom; + + public readonly int EffectiveLength; + + public readonly bool IsAllLowercaseAsciiOrNonLetter; + + public readonly string? SecondaryOriginal; + + public readonly string? SecondaryFolded; + + public readonly ulong SecondaryBloom; + + public readonly int SecondaryEffectiveLength; + + public readonly bool SecondaryIsAllLowercaseAsciiOrNonLetter; + + public int Length => Folded.Length; + + public bool HasSecondary => SecondaryFolded is not null; + + public ReadOnlySpan OriginalSpan => Original.AsSpan(); + + public ReadOnlySpan FoldedSpan => Folded.AsSpan(); + + public ReadOnlySpan SecondaryOriginalSpan => SecondaryOriginal.AsSpan(); + + public ReadOnlySpan SecondaryFoldedSpan => SecondaryFolded.AsSpan(); + + public FuzzyQuery( + string original, + string folded, + ulong bloom, + int effectiveLength, + bool isAllLowercaseAsciiOrNonLetter, + string? secondaryOriginal = null, + string? secondaryFolded = null, + ulong secondaryBloom = 0, + int secondaryEffectiveLength = 0, + bool secondaryIsAllLowercaseAsciiOrNonLetter = true) + { + Original = original; + Folded = folded; + Bloom = bloom; + EffectiveLength = effectiveLength; + IsAllLowercaseAsciiOrNonLetter = isAllLowercaseAsciiOrNonLetter; + + SecondaryOriginal = secondaryOriginal; + SecondaryFolded = secondaryFolded; + SecondaryBloom = secondaryBloom; + SecondaryEffectiveLength = secondaryEffectiveLength; + SecondaryIsAllLowercaseAsciiOrNonLetter = secondaryIsAllLowercaseAsciiOrNonLetter; + } +} diff --git a/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/FuzzyTarget.cs b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/FuzzyTarget.cs new file mode 100644 index 0000000000..b0c2927f20 --- /dev/null +++ b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/FuzzyTarget.cs @@ -0,0 +1,46 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.CmdPal.Core.Common.Text; + +public readonly struct FuzzyTarget +{ + public readonly string Original; + public readonly string Folded; + public readonly ulong Bloom; + + public readonly string? SecondaryOriginal; + public readonly string? SecondaryFolded; + public readonly ulong SecondaryBloom; + + public int Length => Folded.Length; + + public bool HasSecondary => SecondaryFolded is not null; + + public int SecondaryLength => SecondaryFolded?.Length ?? 0; + + public ReadOnlySpan OriginalSpan => Original.AsSpan(); + + public ReadOnlySpan FoldedSpan => Folded.AsSpan(); + + public ReadOnlySpan SecondaryOriginalSpan => SecondaryOriginal.AsSpan(); + + public ReadOnlySpan SecondaryFoldedSpan => SecondaryFolded.AsSpan(); + + public FuzzyTarget( + string original, + string folded, + ulong bloom, + string? secondaryOriginal = null, + string? secondaryFolded = null, + ulong secondaryBloom = 0) + { + Original = original; + Folded = folded; + Bloom = bloom; + SecondaryOriginal = secondaryOriginal; + SecondaryFolded = secondaryFolded; + SecondaryBloom = secondaryBloom; + } +} diff --git a/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/FuzzyTargetCache.cs b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/FuzzyTargetCache.cs new file mode 100644 index 0000000000..dc5ec6e011 --- /dev/null +++ b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/FuzzyTargetCache.cs @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.CmdPal.Core.Common.Text; + +public struct FuzzyTargetCache +{ + private string? _lastRaw; + private uint _schemaId; + private FuzzyTarget _target; + + public FuzzyTarget GetOrUpdate(IPrecomputedFuzzyMatcher matcher, string? raw) + { + raw ??= string.Empty; + + if (_schemaId == matcher.SchemaId && string.Equals(_lastRaw, raw, StringComparison.Ordinal)) + { + return _target; + } + + _target = matcher.PrecomputeTarget(raw); + _schemaId = matcher.SchemaId; + _lastRaw = raw; + return _target; + } + + public void Invalidate() + { + _lastRaw = null; + _target = default; + _schemaId = 0; + } +} diff --git a/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/IBloomFilter.cs b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/IBloomFilter.cs new file mode 100644 index 0000000000..e9234e7adf --- /dev/null +++ b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/IBloomFilter.cs @@ -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.Core.Common.Text; + +public interface IBloomFilter +{ + ulong Compute(string input); + + bool MightContain(ulong candidateBloom, ulong queryBloom); +} diff --git a/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/IFuzzyMatcherProvider.cs b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/IFuzzyMatcherProvider.cs new file mode 100644 index 0000000000..706dd0d8bf --- /dev/null +++ b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/IFuzzyMatcherProvider.cs @@ -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.Core.Common.Text; + +public interface IFuzzyMatcherProvider +{ + IPrecomputedFuzzyMatcher Current { get; } + + void UpdateSettings(PrecomputedFuzzyMatcherOptions core, PinyinFuzzyMatcherOptions? pinyin = null); +} diff --git a/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/IPrecomputedFuzzyMatcher.cs b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/IPrecomputedFuzzyMatcher.cs new file mode 100644 index 0000000000..dfb8af378e --- /dev/null +++ b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/IPrecomputedFuzzyMatcher.cs @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.CmdPal.Core.Common.Text; + +public interface IPrecomputedFuzzyMatcher +{ + uint SchemaId { get; } + + FuzzyQuery PrecomputeQuery(string? input); + + FuzzyTarget PrecomputeTarget(string? input); + + int Score(scoped in FuzzyQuery query, scoped in FuzzyTarget target); +} diff --git a/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/IStringFolder.cs b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/IStringFolder.cs new file mode 100644 index 0000000000..6fcfbfaf61 --- /dev/null +++ b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/IStringFolder.cs @@ -0,0 +1,10 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.CmdPal.Core.Common.Text; + +public interface IStringFolder +{ + string Fold(string input, bool removeDiacritics); +} diff --git a/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/PinyinFuzzyMatcherOptions.cs b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/PinyinFuzzyMatcherOptions.cs new file mode 100644 index 0000000000..c060c33c92 --- /dev/null +++ b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/PinyinFuzzyMatcherOptions.cs @@ -0,0 +1,13 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.CmdPal.Core.Common.Text; + +public sealed class PinyinFuzzyMatcherOptions +{ + public PinyinMode Mode { get; init; } = PinyinMode.AutoSimplifiedChineseUi; + + /// Remove IME syllable separators (') for query secondary variant. + public bool RemoveApostrophesForQuery { get; init; } = true; +} diff --git a/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/PinyinMode.cs b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/PinyinMode.cs new file mode 100644 index 0000000000..0da88e14c0 --- /dev/null +++ b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/PinyinMode.cs @@ -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.Core.Common.Text; + +public enum PinyinMode +{ + Off = 0, + AutoSimplifiedChineseUi = 1, + On = 2, +} diff --git a/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/PrecomputedFuzzyMatcher.cs b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/PrecomputedFuzzyMatcher.cs new file mode 100644 index 0000000000..0994f1d328 --- /dev/null +++ b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/PrecomputedFuzzyMatcher.cs @@ -0,0 +1,575 @@ +// 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.Buffers; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Microsoft.CmdPal.Core.Common.Text; + +public sealed class PrecomputedFuzzyMatcher : IPrecomputedFuzzyMatcher +{ + private const int NoMatchScore = 0; + private const int StackallocThresholdChars = 512; + private const int FolderSchemaVersion = 1; + private const int BloomSchemaVersion = 1; + + private readonly PrecomputedFuzzyMatcherOptions _options; + private readonly IStringFolder _stringFolder; + private readonly IBloomFilter _bloom; + + public PrecomputedFuzzyMatcher( + PrecomputedFuzzyMatcherOptions? options = null, + IStringFolder? normalization = null, + IBloomFilter? bloomCalculator = null) + { + _options = options ?? PrecomputedFuzzyMatcherOptions.Default; + _bloom = bloomCalculator ?? new BloomFilter(); + _stringFolder = normalization ?? new StringFolder(); + + SchemaId = ComputeSchemaId(_options); + } + + public uint SchemaId { get; } + + public FuzzyQuery PrecomputeQuery(string? input) => PrecomputeQuery(input, null); + + public FuzzyTarget PrecomputeTarget(string? input) => PrecomputeTarget(input, null); + + public int Score(in FuzzyQuery query, in FuzzyTarget target) + { + var qFold = query.FoldedSpan; + var tLen = target.Length; + + if (query.EffectiveLength == 0 || tLen == 0) + { + return NoMatchScore; + } + + var skipWordSeparators = _options.SkipWordSeparators; + var bestScore = 0; + + // 1. Primary → Primary + if (tLen >= query.EffectiveLength && _bloom.MightContain(target.Bloom, query.Bloom)) + { + if (CanMatchSubsequence(qFold, target.FoldedSpan, skipWordSeparators)) + { + bestScore = ScoreNonContiguous( + qRaw: query.OriginalSpan, + qFold: qFold, + qEffectiveLen: query.EffectiveLength, + tRaw: target.OriginalSpan, + tFold: target.FoldedSpan, + ignoreSameCaseBonusForThisQuery: _options.IgnoreSameCaseBonusIfQueryIsAllLowercase && query.IsAllLowercaseAsciiOrNonLetter); + } + } + + // 2. Secondary → Secondary + if (query.HasSecondary && target.HasSecondary) + { + var qSecFold = query.SecondaryFoldedSpan; + + if (target.SecondaryLength >= query.SecondaryEffectiveLength && + _bloom.MightContain(target.SecondaryBloom, query.SecondaryBloom) && + CanMatchSubsequence(qSecFold, target.SecondaryFoldedSpan, skipWordSeparators)) + { + var score = ScoreNonContiguous( + qRaw: query.SecondaryOriginalSpan, + qFold: qSecFold, + qEffectiveLen: query.SecondaryEffectiveLength, + tRaw: target.SecondaryOriginalSpan, + tFold: target.SecondaryFoldedSpan, + ignoreSameCaseBonusForThisQuery: _options.IgnoreSameCaseBonusIfQueryIsAllLowercase && query.SecondaryIsAllLowercaseAsciiOrNonLetter); + + if (score > bestScore) + { + bestScore = score; + } + } + } + + // 3. Primary query → Secondary target + if (target.HasSecondary && + target.SecondaryLength >= query.EffectiveLength && + _bloom.MightContain(target.SecondaryBloom, query.Bloom)) + { + if (CanMatchSubsequence(qFold, target.SecondaryFoldedSpan, skipWordSeparators)) + { + var score = ScoreNonContiguous( + qRaw: query.OriginalSpan, + qFold: qFold, + qEffectiveLen: query.EffectiveLength, + tRaw: target.SecondaryOriginalSpan, + tFold: target.SecondaryFoldedSpan, + ignoreSameCaseBonusForThisQuery: _options.IgnoreSameCaseBonusIfQueryIsAllLowercase && query.IsAllLowercaseAsciiOrNonLetter); + + if (score > bestScore) + { + bestScore = score; + } + } + } + + // 4. Secondary query → Primary target + if (query.HasSecondary && + tLen >= query.SecondaryEffectiveLength && + _bloom.MightContain(target.Bloom, query.SecondaryBloom)) + { + var qSecFold = query.SecondaryFoldedSpan; + + if (CanMatchSubsequence(qSecFold, target.FoldedSpan, skipWordSeparators)) + { + var score = ScoreNonContiguous( + qRaw: query.SecondaryOriginalSpan, + qFold: qSecFold, + qEffectiveLen: query.SecondaryEffectiveLength, + tRaw: target.OriginalSpan, + tFold: target.FoldedSpan, + ignoreSameCaseBonusForThisQuery: _options.IgnoreSameCaseBonusIfQueryIsAllLowercase && query.SecondaryIsAllLowercaseAsciiOrNonLetter); + + if (score > bestScore) + { + bestScore = score; + } + } + } + + return bestScore; + } + + private FuzzyQuery PrecomputeQuery(string? input, string? secondaryInput) + { + input ??= string.Empty; + + var folded = _stringFolder.Fold(input, _options.RemoveDiacritics); + var bloom = _bloom.Compute(folded); + var effectiveLength = _options.SkipWordSeparators + ? folded.Length - CountWordSeparators(folded) + : folded.Length; + + var isAllLowercase = IsAllLowercaseAsciiOrNonLetter(input); + + string? secondaryOriginal = null; + string? secondaryFolded = null; + ulong secondaryBloom = 0; + var secondaryEffectiveLength = 0; + var secondaryIsAllLowercase = true; + + if (!string.IsNullOrEmpty(secondaryInput)) + { + secondaryOriginal = secondaryInput; + secondaryFolded = _stringFolder.Fold(secondaryInput, _options.RemoveDiacritics); + secondaryBloom = _bloom.Compute(secondaryFolded); + secondaryEffectiveLength = _options.SkipWordSeparators + ? secondaryFolded.Length - CountWordSeparators(secondaryFolded) + : secondaryFolded.Length; + + secondaryIsAllLowercase = IsAllLowercaseAsciiOrNonLetter(secondaryInput); + } + + return new FuzzyQuery( + original: input, + folded: folded, + bloom: bloom, + effectiveLength: effectiveLength, + isAllLowercaseAsciiOrNonLetter: isAllLowercase, + secondaryOriginal: secondaryOriginal, + secondaryFolded: secondaryFolded, + secondaryBloom: secondaryBloom, + secondaryEffectiveLength: secondaryEffectiveLength, + secondaryIsAllLowercaseAsciiOrNonLetter: secondaryIsAllLowercase); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static int CountWordSeparators(string s) + { + var count = 0; + foreach (var c in s) + { + if (SymbolClassifier.Classify(c) == SymbolKind.WordSeparator) + { + count++; + } + } + + return count; + } + } + + internal FuzzyTarget PrecomputeTarget(string? input, string? secondaryInput) + { + input ??= string.Empty; + + var folded = _stringFolder.Fold(input, _options.RemoveDiacritics); + var bloom = _bloom.Compute(folded); + + string? secondaryFolded = null; + ulong secondaryBloom = 0; + + if (!string.IsNullOrEmpty(secondaryInput)) + { + secondaryFolded = _stringFolder.Fold(secondaryInput, _options.RemoveDiacritics); + secondaryBloom = _bloom.Compute(secondaryFolded); + } + + return new FuzzyTarget( + input, + folded, + bloom, + secondaryInput, + secondaryFolded, + secondaryBloom); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static bool IsAllLowercaseAsciiOrNonLetter(string s) + { + foreach (var c in s) + { + if ((uint)(c - 'A') <= ('Z' - 'A')) + { + return false; + } + } + + return true; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static bool CanMatchSubsequence( + ReadOnlySpan qFold, + ReadOnlySpan tFold, + bool skipWordSeparators) + { + var qi = 0; + var ti = 0; + + while (qi < qFold.Length && ti < tFold.Length) + { + var qChar = qFold[qi]; + + if (skipWordSeparators && SymbolClassifier.Classify(qChar) == SymbolKind.WordSeparator) + { + qi++; + continue; + } + + if (qChar == tFold[ti]) + { + qi++; + } + + ti++; + } + + // Skip trailing word separators in query + if (skipWordSeparators) + { + while (qi < qFold.Length && SymbolClassifier.Classify(qFold[qi]) == SymbolKind.WordSeparator) + { + qi++; + } + } + + return qi == qFold.Length; + } + + [MethodImpl(MethodImplOptions.AggressiveOptimization)] + [SkipLocalsInit] + private int ScoreNonContiguous( + scoped in ReadOnlySpan qRaw, + scoped in ReadOnlySpan qFold, + int qEffectiveLen, + scoped in ReadOnlySpan tRaw, + scoped in ReadOnlySpan tFold, + bool ignoreSameCaseBonusForThisQuery) + { + Debug.Assert(qRaw.Length == qFold.Length, "Original and folded spans are traversed in lockstep: requires qRaw.Length == qFold.Length"); + Debug.Assert(tRaw.Length == tFold.Length, "Original and folded spans are traversed in lockstep: requires tRaw.Length == tFold.Length"); + Debug.Assert(qEffectiveLen <= qFold.Length, "Effective length must be less than or equal to folded length"); + + var qLen = qFold.Length; + var tLen = tFold.Length; + + // Copy options to local variables to avoid repeated field accesses + var charMatchBonus = _options.CharMatchBonus; + var sameCaseBonus = ignoreSameCaseBonusForThisQuery ? 0 : _options.SameCaseBonus; + var consecutiveMultiplier = _options.ConsecutiveMultiplier; + var camelCaseBonus = _options.CamelCaseBonus; + var startOfWordBonus = _options.StartOfWordBonus; + var pathSeparatorBonus = _options.PathSeparatorBonus; + var wordSeparatorBonus = _options.WordSeparatorBonus; + var separatorAlignmentBonus = _options.SeparatorAlignmentBonus; + var exactSeparatorBonus = _options.ExactSeparatorBonus; + var skipWordSeparators = _options.SkipWordSeparators; + + // DP buffer: two rows of length tLen + var bufferSize = tLen * 2; + int[]? rented = null; + + try + { + scoped Span buffer; + if (bufferSize <= StackallocThresholdChars) + { + buffer = stackalloc int[bufferSize]; + } + else + { + rented = ArrayPool.Shared.Rent(bufferSize); + buffer = rented.AsSpan(0, bufferSize); + } + + var scores = buffer[..tLen]; + var seqLens = buffer.Slice(tLen, tLen); + + scores.Clear(); + seqLens.Clear(); + + ref var scores0 = ref MemoryMarshal.GetReference(scores); + ref var seqLens0 = ref MemoryMarshal.GetReference(seqLens); + ref var qRaw0 = ref MemoryMarshal.GetReference(qRaw); + ref var qFold0 = ref MemoryMarshal.GetReference(qFold); + ref var tRaw0 = ref MemoryMarshal.GetReference(tRaw); + ref var tFold0 = ref MemoryMarshal.GetReference(tFold); + + var qiEffective = 0; + + for (var qi = 0; qi < qLen; qi++) + { + var qCharFold = Unsafe.Add(ref qFold0, qi); + var qCharKind = SymbolClassifier.Classify(qCharFold); + + if (skipWordSeparators && qCharKind == SymbolKind.WordSeparator) + { + continue; + } + + // Hoisted values + var qRawIsUpper = char.IsUpper(Unsafe.Add(ref qRaw0, qi)); + + // row computation + var leftScore = 0; + var diagScore = 0; + var diagSeqLen = 0; + + // limit ti to ensure enough remaining characters to match the rest of the query + var tiMax = tLen - qEffectiveLen + qiEffective; + + for (var ti = 0; ti <= tiMax; ti++) + { + var upScore = Unsafe.Add(ref scores0, ti); + var upSeqLen = Unsafe.Add(ref seqLens0, ti); + + var charScore = 0; + if (diagScore != 0 || qiEffective == 0) + { + charScore = ComputeCharScore( + qi, + ti, + qCharFold, + qCharKind, + diagSeqLen, + qRawIsUpper, + ref tRaw0, + ref qFold0, + ref tFold0); + } + + var candidateScore = diagScore + charScore; + if (charScore != 0 && candidateScore >= leftScore) + { + Unsafe.Add(ref scores0, ti) = candidateScore; + Unsafe.Add(ref seqLens0, ti) = diagSeqLen + 1; + leftScore = candidateScore; + } + else + { + Unsafe.Add(ref scores0, ti) = leftScore; + Unsafe.Add(ref seqLens0, ti) = 0; + /* leftScore remains unchanged */ + } + + diagScore = upScore; + diagSeqLen = upSeqLen; + } + + // Early exit: no match possible + if (leftScore == 0) + { + return NoMatchScore; + } + + // Advance effective query index + // Only counts non-separator characters if skipWordSeparators is enabled + qiEffective++; + + if (qiEffective == qEffectiveLen) + { + return leftScore; + } + } + + return scores[tLen - 1]; + + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + int ComputeCharScore( + int qi, + int ti, + char qCharFold, + SymbolKind qCharKind, + int seqLen, + bool qCharRawCurrIsUpper, + ref char tRaw0, + ref char qFold0, + ref char tFold0) + { + // Match check: + // - exact folded char match always ok + // - otherwise, allow equivalence only for word separators (e.g. '_' matches '-') + var tCharFold = Unsafe.Add(ref tFold0, ti); + if (qCharFold != tCharFold) + { + if (!skipWordSeparators) + { + return 0; + } + + if (qCharKind != SymbolKind.WordSeparator || + SymbolClassifier.Classify(tCharFold) != SymbolKind.WordSeparator) + { + return 0; + } + } + + // 0. Base char match bonus + var score = charMatchBonus; + + // 1. Consecutive match bonus + if (seqLen > 0) + { + score += seqLen * consecutiveMultiplier; + } + + // 2. Same case bonus + // Early outs to appease the branch predictor + if (sameCaseBonus != 0) + { + var tCharRawCurr = Unsafe.Add(ref tRaw0, ti); + var tCharRawCurrIsUpper = char.IsUpper(tCharRawCurr); + if (qCharRawCurrIsUpper == tCharRawCurrIsUpper) + { + score += sameCaseBonus; + } + + if (ti == 0) + { + score += startOfWordBonus; + return score; + } + + var tPrevFold = Unsafe.Add(ref tFold0, ti - 1); + var tPrevKind = SymbolClassifier.Classify(tPrevFold); + if (tPrevKind != SymbolKind.Other) + { + score += tPrevKind == SymbolKind.PathSeparator + ? pathSeparatorBonus + : wordSeparatorBonus; + + if (skipWordSeparators && seqLen == 0 && qi > 0) + { + var qPrevFold = Unsafe.Add(ref qFold0, qi - 1); + var qPrevKind = SymbolClassifier.Classify(qPrevFold); + + if (qPrevKind == SymbolKind.WordSeparator) + { + score += separatorAlignmentBonus; + + if (tPrevKind == SymbolKind.WordSeparator && qPrevFold == tPrevFold) + { + score += exactSeparatorBonus; + } + } + } + + return score; + } + + if (tCharRawCurrIsUpper && seqLen == 0) + { + score += camelCaseBonus; + return score; + } + + return score; + } + else + { + if (ti == 0) + { + score += startOfWordBonus; + return score; + } + + var tPrevFold = Unsafe.Add(ref tFold0, ti - 1); + var tPrevKind = SymbolClassifier.Classify(tPrevFold); + if (tPrevKind != SymbolKind.Other) + { + score += tPrevKind == SymbolKind.PathSeparator + ? pathSeparatorBonus + : wordSeparatorBonus; + + if (skipWordSeparators && seqLen == 0 && qi > 0) + { + var qPrevFold = Unsafe.Add(ref qFold0, qi - 1); + var qPrevKind = SymbolClassifier.Classify(qPrevFold); + + if (qPrevKind == SymbolKind.WordSeparator) + { + score += separatorAlignmentBonus; + + if (tPrevKind == SymbolKind.WordSeparator && qPrevFold == tPrevFold) + { + score += exactSeparatorBonus; + } + } + } + + return score; + } + + if (camelCaseBonus != 0 && seqLen == 0 && char.IsUpper(Unsafe.Add(ref tRaw0, ti))) + { + score += camelCaseBonus; + return score; + } + + return score; + } + } + } + finally + { + if (rented is not null) + { + ArrayPool.Shared.Return(rented); + } + } + } + + // Schema ID is for cache invalidation of precomputed targets. + // Only includes options that affect folding/bloom, not scoring. + private static uint ComputeSchemaId(PrecomputedFuzzyMatcherOptions o) + { + const uint fnvOffset = 2166136261; + const uint fnvPrime = 16777619; + + var h = fnvOffset; + h = unchecked((h ^ FolderSchemaVersion) * fnvPrime); + h = unchecked((h ^ BloomSchemaVersion) * fnvPrime); + h = unchecked((h ^ (uint)(o.RemoveDiacritics ? 1 : 0)) * fnvPrime); + + return h; + } +} diff --git a/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/PrecomputedFuzzyMatcherOptions.cs b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/PrecomputedFuzzyMatcherOptions.cs new file mode 100644 index 0000000000..b1b01d60f1 --- /dev/null +++ b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/PrecomputedFuzzyMatcherOptions.cs @@ -0,0 +1,40 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.CmdPal.Core.Common.Text; + +public sealed class PrecomputedFuzzyMatcherOptions +{ + public static PrecomputedFuzzyMatcherOptions Default { get; } = new(); + + /* + * Bonuses + */ + public int CharMatchBonus { get; init; } = 1; + + public int SameCaseBonus { get; init; } = 1; + + public int ConsecutiveMultiplier { get; init; } = 5; + + public int CamelCaseBonus { get; init; } = 2; + + public int StartOfWordBonus { get; init; } = 8; + + public int PathSeparatorBonus { get; init; } = 5; + + public int WordSeparatorBonus { get; init; } = 4; + + public int SeparatorAlignmentBonus { get; init; } = 2; + + public int ExactSeparatorBonus { get; init; } = 1; + + /* + * Settings + */ + public bool RemoveDiacritics { get; init; } = true; + + public bool SkipWordSeparators { get; init; } = true; + + public bool IgnoreSameCaseBonusIfQueryIsAllLowercase { get; init; } = true; +} diff --git a/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/PrecomputedFuzzyMatcherWithPinyin.cs b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/PrecomputedFuzzyMatcherWithPinyin.cs new file mode 100644 index 0000000000..026328f2c5 --- /dev/null +++ b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/PrecomputedFuzzyMatcherWithPinyin.cs @@ -0,0 +1,177 @@ +// 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.Globalization; +using System.Runtime.CompilerServices; +using ToolGood.Words.Pinyin; + +namespace Microsoft.CmdPal.Core.Common.Text; + +public sealed class PrecomputedFuzzyMatcherWithPinyin : IPrecomputedFuzzyMatcher +{ + private readonly IBloomFilter _bloom; + private readonly PrecomputedFuzzyMatcher _core; + + private readonly IStringFolder _stringFolder; + private readonly PinyinFuzzyMatcherOptions _pinyin; + + public PrecomputedFuzzyMatcherWithPinyin( + PrecomputedFuzzyMatcherOptions coreOptions, + PinyinFuzzyMatcherOptions pinyinOptions, + IStringFolder stringFolder, + IBloomFilter bloom) + { + _pinyin = pinyinOptions; + _stringFolder = stringFolder; + _bloom = bloom; + + _core = new PrecomputedFuzzyMatcher(coreOptions, stringFolder, bloom); + + SchemaId = CombineSchema(_core.SchemaId, _pinyin); + } + + public uint SchemaId { get; } + + public FuzzyQuery PrecomputeQuery(string? input) + { + input ??= string.Empty; + + var primary = _core.PrecomputeQuery(input); + + // Fast exit if effectively off (provider should already filter, but keep robust) + if (!IsPinyinEnabled(_pinyin)) + { + return primary; + } + + // Match legacy: remove apostrophes for query secondary + var queryForPinyin = _pinyin.RemoveApostrophesForQuery ? RemoveApostrophesIfAny(input) : input; + + var pinyin = WordsHelper.GetPinyin(queryForPinyin); + if (string.IsNullOrEmpty(pinyin)) + { + return primary; + } + + var secondary = _core.PrecomputeQuery(pinyin); + return new FuzzyQuery( + primary.Original, + primary.Folded, + primary.Bloom, + primary.EffectiveLength, + primary.IsAllLowercaseAsciiOrNonLetter, + secondary.Original, + secondary.Folded, + secondary.Bloom, + secondary.EffectiveLength, + secondary.SecondaryIsAllLowercaseAsciiOrNonLetter); + } + + public FuzzyTarget PrecomputeTarget(string? input) + { + input ??= string.Empty; + + var primary = _core.PrecomputeTarget(input); + + if (!IsPinyinEnabled(_pinyin)) + { + return primary; + } + + // Match legacy: only compute target pinyin when target contains Chinese + if (!ContainsToolGoodChinese(input)) + { + return primary; + } + + var pinyin = WordsHelper.GetPinyin(input); + if (string.IsNullOrEmpty(pinyin)) + { + return primary; + } + + var secondary = _core.PrecomputeTarget(pinyin); + return new FuzzyTarget( + primary.Original, + primary.Folded, + primary.Bloom, + secondary.Original, + secondary.Folded, + secondary.Bloom); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int Score(scoped in FuzzyQuery query, scoped in FuzzyTarget target) + => _core.Score(in query, in target); + + private static bool IsPinyinEnabled(PinyinFuzzyMatcherOptions o) => o.Mode switch + { + PinyinMode.Off => false, + PinyinMode.On => true, + PinyinMode.AutoSimplifiedChineseUi => IsSimplifiedChineseUi(), + _ => false, + }; + + private static bool IsSimplifiedChineseUi() + { + var culture = CultureInfo.CurrentUICulture; + return culture.Name.StartsWith("zh-CN", StringComparison.OrdinalIgnoreCase) + || culture.Name.StartsWith("zh-Hans", StringComparison.OrdinalIgnoreCase); + } + + private static bool ContainsToolGoodChinese(string s) + { + return WordsHelper.HasChinese(s); + } + + private static string RemoveApostrophesIfAny(string input) + { + var first = input.IndexOf('\''); + if (first < 0) + { + return input; + } + + var removeCount = 1; + for (var i = first + 1; i < input.Length; i++) + { + if (input[i] == '\'') + { + removeCount++; + } + } + + return string.Create(input.Length - removeCount, input, static (dst, src) => + { + var di = 0; + for (var i = 0; i < src.Length; i++) + { + var c = src[i]; + if (c == '\'') + { + continue; + } + + dst[di++] = c; + } + }); + } + + private static uint CombineSchema(uint coreSchemaId, PinyinFuzzyMatcherOptions p) + { + const uint fnvOffset = 2166136261; + const uint fnvPrime = 16777619; + + var h = fnvOffset; + h = unchecked((h ^ coreSchemaId) * fnvPrime); + h = unchecked((h ^ (uint)p.Mode) * fnvPrime); + h = unchecked((h ^ (p.RemoveApostrophesForQuery ? 1u : 0u)) * fnvPrime); + + // bump if you change formatting/conversion behavior + const uint pinyinAlgoVersion = 1; + h = unchecked((h ^ pinyinAlgoVersion) * fnvPrime); + + return h; + } +} diff --git a/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/StringFolder.cs b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/StringFolder.cs new file mode 100644 index 0000000000..2d814be553 --- /dev/null +++ b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/StringFolder.cs @@ -0,0 +1,163 @@ +// 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.Globalization; +using System.Runtime.CompilerServices; +using System.Text; + +namespace Microsoft.CmdPal.Core.Common.Text; + +public sealed class StringFolder : IStringFolder +{ + // Cache for diacritic-stripped uppercase characters. + // Benign race: worst case is redundant computation writing the same value. + // 0 = uncached, else cachedChar + 1 + private static readonly ushort[] StripCacheUpper = new ushort[char.MaxValue + 1]; + + public string Fold(string input, bool removeDiacritics) + { + if (string.IsNullOrEmpty(input)) + { + return string.Empty; + } + + if (!removeDiacritics || Ascii.IsValid(input)) + { + if (IsAlreadyFoldedAndSlashNormalized(input)) + { + return input; + } + + return string.Create(input.Length, input, static (dst, src) => + { + for (var i = 0; i < src.Length; i++) + { + var c = src[i]; + dst[i] = c == '\\' ? '/' : char.ToUpperInvariant(c); + } + }); + } + + return string.Create(input.Length, input, static (dst, src) => + { + for (var i = 0; i < src.Length; i++) + { + var c = src[i]; + var upper = c == '\\' ? '/' : char.ToUpperInvariant(c); + dst[i] = StripDiacriticsFromUpper(upper); + } + }); + } + + private static bool IsAlreadyFoldedAndSlashNormalized(string input) + { + var sawNonAscii = false; + + for (var i = 0; i < input.Length; i++) + { + var c = input[i]; + + if (c == '\\') + { + return false; + } + + if ((uint)(c - 'a') <= 'z' - 'a') + { + return false; + } + + if (c > 0x7F) + { + sawNonAscii = true; + } + } + + if (sawNonAscii) + { + for (var i = 0; i < input.Length; i++) + { + var c = input[i]; + if (c <= 0x7F) + { + continue; + } + + var cat = CharUnicodeInfo.GetUnicodeCategory(c); + if (cat is UnicodeCategory.LowercaseLetter or UnicodeCategory.TitlecaseLetter) + { + return false; + } + } + } + + return true; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static char StripDiacriticsFromUpper(char upper) + { + if (upper <= 0x7F) + { + return upper; + } + + // Never attempt normalization on lone UTF-16 surrogates. + if (char.IsSurrogate(upper)) + { + return upper; + } + + var cachedPlus1 = StripCacheUpper[upper]; + if (cachedPlus1 != 0) + { + return (char)(cachedPlus1 - 1); + } + + var mapped = StripDiacriticsSlow(upper); + StripCacheUpper[upper] = (ushort)(mapped + 1); + return mapped; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static char StripDiacriticsSlow(char upper) + { + try + { + var baseChar = FirstNonMark(upper, NormalizationForm.FormD); + if (baseChar == '\0' || baseChar == upper) + { + var kd = FirstNonMark(upper, NormalizationForm.FormKD); + if (kd != '\0') + { + baseChar = kd; + } + } + + return char.ToUpperInvariant(baseChar == '\0' ? upper : baseChar); + } + catch + { + // Absolute safety: if globalization tables ever throw for some reason, + // degrade gracefully rather than failing hard. + return upper; + } + + static char FirstNonMark(char c, NormalizationForm form) + { + var normalized = c.ToString().Normalize(form); + + foreach (var ch in normalized) + { + var cat = CharUnicodeInfo.GetUnicodeCategory(ch); + if (cat is not (UnicodeCategory.NonSpacingMark or UnicodeCategory.SpacingCombiningMark or UnicodeCategory.EnclosingMark)) + { + return ch; + } + } + + return '\0'; + } + } +} diff --git a/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/SymbolClassifier.cs b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/SymbolClassifier.cs new file mode 100644 index 0000000000..e1be786646 --- /dev/null +++ b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/SymbolClassifier.cs @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Runtime.CompilerServices; + +namespace Microsoft.CmdPal.Core.Common.Text; + +internal static class SymbolClassifier +{ + // Embedded in .data section - no allocation, no static constructor + private static ReadOnlySpan Lookup => + [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0-15 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16-31 + 2, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 2, 1, // 32-47: space=2, "=2, '=2, -=2, .=2, /=1 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, // 48-63: :=2 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 64-79 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, // 80-95: _=2 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 96-111 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // 112-127 + ]; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static SymbolKind Classify(char c) + { + return c > 0x7F ? SymbolKind.Other : (SymbolKind)Lookup[c]; + } +} diff --git a/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/SymbolKind.cs b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/SymbolKind.cs new file mode 100644 index 0000000000..d2644be420 --- /dev/null +++ b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Text/SymbolKind.cs @@ -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.Core.Common.Text; + +internal enum SymbolKind : byte +{ + Other = 0, + PathSeparator = 1, + WordSeparator = 2, +} diff --git a/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.ViewModels/CommandItemViewModel.cs b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.ViewModels/CommandItemViewModel.cs index f8e9478023..af10995cf9 100644 --- a/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.ViewModels/CommandItemViewModel.cs +++ b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.ViewModels/CommandItemViewModel.cs @@ -4,6 +4,8 @@ using System.Diagnostics.CodeAnalysis; using Microsoft.CmdPal.Core.Common; +using Microsoft.CmdPal.Core.Common.Helpers; +using Microsoft.CmdPal.Core.Common.Text; using Microsoft.CmdPal.Core.ViewModels.Messages; using Microsoft.CmdPal.Core.ViewModels.Models; using Microsoft.CommandPalette.Extensions; @@ -13,7 +15,7 @@ using Windows.ApplicationModel.DataTransfer; namespace Microsoft.CmdPal.Core.ViewModels; [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] -public partial class CommandItemViewModel : ExtensionObjectViewModel, ICommandBarContext +public partial class CommandItemViewModel : ExtensionObjectViewModel, ICommandBarContext, IPrecomputedListItem { public ExtensionObject Model => _commandItemModel; @@ -22,6 +24,9 @@ public partial class CommandItemViewModel : ExtensionObjectViewModel, ICommandBa private readonly ExtensionObject _commandItemModel = new(null); private CommandContextItemViewModel? _defaultCommandContextItemViewModel; + private FuzzyTargetCache _titleCache; + private FuzzyTargetCache _subtitleCache; + internal InitializedState Initialized { get; private set; } = InitializedState.Uninitialized; protected bool IsFastInitialized => IsInErrorState || Initialized.HasFlag(InitializedState.FastInitialized); @@ -116,6 +121,8 @@ public partial class CommandItemViewModel : ExtensionObjectViewModel, ICommandBa _itemTitle = model.Title; Subtitle = model.Subtitle; + _titleCache.Invalidate(); + _subtitleCache.Invalidate(); Initialized |= InitializedState.FastInitialized; } @@ -249,6 +256,8 @@ public partial class CommandItemViewModel : ExtensionObjectViewModel, ICommandBa Subtitle = "Item failed to load"; MoreCommands = []; _icon = _errorIcon; + _titleCache.Invalidate(); + _subtitleCache.Invalidate(); Initialized |= InitializedState.Error; } @@ -286,6 +295,8 @@ public partial class CommandItemViewModel : ExtensionObjectViewModel, ICommandBa Subtitle = "Item failed to load"; MoreCommands = []; _icon = _errorIcon; + _titleCache.Invalidate(); + _subtitleCache.Invalidate(); Initialized |= InitializedState.Error; } @@ -335,12 +346,14 @@ public partial class CommandItemViewModel : ExtensionObjectViewModel, ICommandBa case nameof(Title): _itemTitle = model.Title; + _titleCache.Invalidate(); break; case nameof(Subtitle): var modelSubtitle = model.Subtitle; this.Subtitle = modelSubtitle; _defaultCommandContextItemViewModel?.Subtitle = modelSubtitle; + _subtitleCache.Invalidate(); break; case nameof(Icon): @@ -415,6 +428,7 @@ public partial class CommandItemViewModel : ExtensionObjectViewModel, ICommandBa // Extensions based on Command Palette SDK < 0.3 CommandItem class won't notify when Title changes because Command // or Command.Name change. This is a workaround to ensure that the Title is always up-to-date for extensions with old SDK. _itemTitle = model.Title; + _titleCache.Invalidate(); UpdateProperty(nameof(Title), nameof(Name)); _defaultCommandContextItemViewModel?.UpdateTitle(model.Command.Name); @@ -436,6 +450,7 @@ public partial class CommandItemViewModel : ExtensionObjectViewModel, ICommandBa private void UpdateTitle(string? title) { _itemTitle = title ?? string.Empty; + _titleCache.Invalidate(); UpdateProperty(nameof(Title)); } @@ -456,6 +471,12 @@ public partial class CommandItemViewModel : ExtensionObjectViewModel, ICommandBa UpdateProperty(nameof(DataPackage)); } + public FuzzyTarget GetTitleTarget(IPrecomputedFuzzyMatcher matcher) + => _titleCache.GetOrUpdate(matcher, Title); + + public FuzzyTarget GetSubtitleTarget(IPrecomputedFuzzyMatcher matcher) + => _subtitleCache.GetOrUpdate(matcher, Subtitle); + protected override void UnsafeCleanup() { base.UnsafeCleanup(); diff --git a/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.ViewModels/ContextMenuViewModel.cs b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.ViewModels/ContextMenuViewModel.cs index 07c238ab42..83f314a11f 100644 --- a/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.ViewModels/ContextMenuViewModel.cs +++ b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.ViewModels/ContextMenuViewModel.cs @@ -3,9 +3,12 @@ // See the LICENSE file in the project root for more information. using System.Collections.ObjectModel; +using System.Runtime.CompilerServices; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Messaging; using Microsoft.CmdPal.Core.Common; +using Microsoft.CmdPal.Core.Common.Helpers; +using Microsoft.CmdPal.Core.Common.Text; using Microsoft.CmdPal.Core.ViewModels.Messages; using Microsoft.CommandPalette.Extensions; using Microsoft.CommandPalette.Extensions.Toolkit; @@ -16,6 +19,8 @@ namespace Microsoft.CmdPal.Core.ViewModels; public partial class ContextMenuViewModel : ObservableObject, IRecipient { + private readonly IFuzzyMatcherProvider _fuzzyMatcherProvider; + public ICommandBarContext? SelectedItem { get => field; @@ -39,8 +44,9 @@ public partial class ContextMenuViewModel : ObservableObject, private string _lastSearchText = string.Empty; - public ContextMenuViewModel() + public ContextMenuViewModel(IFuzzyMatcherProvider fuzzyMatcherProvider) { + _fuzzyMatcherProvider = fuzzyMatcherProvider; WeakReferenceMessenger.Default.Register(this); } @@ -91,13 +97,14 @@ public partial class ContextMenuViewModel : ObservableObject, .OfType() .Where(c => c.ShouldBeVisible); - var newResults = ListHelpers.FilterList(commands, searchText, ScoreContextCommand); + var query = _fuzzyMatcherProvider.Current.PrecomputeQuery(searchText); + var newResults = InternalListHelpers.FilterList(commands, in query, ScoreFunction); ListHelpers.InPlaceUpdateList(FilteredItems, newResults); } - private static int ScoreContextCommand(string query, CommandContextItemViewModel item) + private int ScoreFunction(in FuzzyQuery query, CommandContextItemViewModel item) { - if (string.IsNullOrEmpty(query) || string.IsNullOrWhiteSpace(query)) + if (string.IsNullOrWhiteSpace(query.Original)) { return 1; } @@ -107,11 +114,21 @@ public partial class ContextMenuViewModel : ObservableObject, return 0; } - var nameMatch = FuzzyStringMatcher.ScoreFuzzy(query, item.Title); + var fuzzyMatcher = _fuzzyMatcherProvider.Current; + var title = item.GetTitleTarget(fuzzyMatcher); + var subtitle = item.GetSubtitleTarget(fuzzyMatcher); - var descriptionMatch = FuzzyStringMatcher.ScoreFuzzy(query, item.Subtitle); + var titleScore = fuzzyMatcher.Score(query, title); + var subtitleScore = (fuzzyMatcher.Score(query, subtitle) - 4) / 2; - return new[] { nameMatch, (descriptionMatch - 4) / 2, 0 }.Max(); + return Max3(titleScore, subtitleScore, 0); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static int Max3(int a, int b, int c) + { + var m = a > b ? a : b; + return m > c ? m : c; } /// diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Commands/MainListPage.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Commands/MainListPage.cs index 2ee8f1e357..325f9b5ff8 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Commands/MainListPage.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Commands/MainListPage.cs @@ -8,6 +8,7 @@ using System.Diagnostics; using CommunityToolkit.Mvvm.Messaging; using ManagedCommon; using Microsoft.CmdPal.Core.Common.Helpers; +using Microsoft.CmdPal.Core.Common.Text; using Microsoft.CmdPal.Core.ViewModels.Messages; using Microsoft.CmdPal.Ext.Apps; using Microsoft.CmdPal.Ext.Apps.Programs; @@ -24,7 +25,7 @@ namespace Microsoft.CmdPal.UI.ViewModels.MainPage; /// This class encapsulates the data we load from built-in providers and extensions to use within the same extension-UI system for a . /// TODO: Need to think about how we structure/interop for the page -> section -> item between the main setup, the extensions, and our viewmodels. /// -public partial class MainListPage : DynamicListPage, +public sealed partial class MainListPage : DynamicListPage, IRecipient, IRecipient, IDisposable { @@ -32,13 +33,18 @@ public partial class MainListPage : DynamicListPage, private readonly AliasManager _aliasManager; private readonly SettingsModel _settings; private readonly AppStateModel _appStateModel; - private List>? _filteredItems; - private List>? _filteredApps; + private readonly ScoringFunction _scoringFunction; + private readonly ScoringFunction _fallbackScoringFunction; + private readonly IFuzzyMatcherProvider _fuzzyMatcherProvider; + + private RoScored[]? _filteredItems; + private RoScored[]? _filteredApps; // Keep as IEnumerable for deferred execution. Fallback item titles are updated // asynchronously, so scoring must happen lazily when GetItems is called. - private IEnumerable>? _scoredFallbackItems; - private IEnumerable>? _fallbackItems; + private IEnumerable>? _scoredFallbackItems; + private IEnumerable>? _fallbackItems; + private bool _includeApps; private bool _filteredItemsIncludesApps; private int _appResultLimit = 10; @@ -48,7 +54,12 @@ public partial class MainListPage : DynamicListPage, private CancellationTokenSource? _cancellationTokenSource; - public MainListPage(TopLevelCommandManager topLevelCommandManager, SettingsModel settings, AliasManager aliasManager, AppStateModel appStateModel) + public MainListPage( + TopLevelCommandManager topLevelCommandManager, + SettingsModel settings, + AliasManager aliasManager, + AppStateModel appStateModel, + IFuzzyMatcherProvider fuzzyMatcherProvider) { Title = Resources.builtin_home_name; Icon = IconHelpers.FromRelativePath("Assets\\StoreLogo.scale-200.png"); @@ -58,6 +69,10 @@ public partial class MainListPage : DynamicListPage, _aliasManager = aliasManager; _appStateModel = appStateModel; _tlcManager = topLevelCommandManager; + _fuzzyMatcherProvider = fuzzyMatcherProvider; + _scoringFunction = (in query, item) => ScoreTopLevelItem(in query, item, _appStateModel.RecentCommands, _fuzzyMatcherProvider.Current); + _fallbackScoringFunction = (in _, item) => ScoreFallbackItem(item, _settings.FallbackRanks); + _tlcManager.PropertyChanged += TlcManager_PropertyChanged; _tlcManager.TopLevelCommands.CollectionChanged += Commands_CollectionChanged; @@ -190,8 +205,7 @@ public partial class MainListPage : DynamicListPage, public override void UpdateSearchText(string oldSearch, string newSearch) { - var timer = new Stopwatch(); - timer.Start(); + var stopwatch = Stopwatch.StartNew(); _cancellationTokenSource?.Cancel(); _cancellationTokenSource?.Dispose(); @@ -354,15 +368,14 @@ public partial class MainListPage : DynamicListPage, if (_includeApps) { - var allNewApps = AllAppsCommandProvider.Page.GetItems().ToList(); + var allNewApps = AllAppsCommandProvider.Page.GetItems().Cast().ToList(); // We need to remove pinned apps from allNewApps so they don't show twice. var pinnedApps = PinnedAppsManager.Instance.GetPinnedAppIdentifiers(); if (pinnedApps.Length > 0) { - newApps = allNewApps.Where(w => - pinnedApps.IndexOf(((AppListItem)w).AppIdentifier) < 0); + newApps = allNewApps.Where(w => pinnedApps.IndexOf(w.AppIdentifier) < 0); } else { @@ -376,11 +389,10 @@ public partial class MainListPage : DynamicListPage, } } - var history = _appStateModel.RecentCommands!; - Func scoreItem = (a, b) => { return ScoreTopLevelItem(a, b, history); }; + var searchQuery = _fuzzyMatcherProvider.Current.PrecomputeQuery(SearchText); // Produce a list of everything that matches the current filter. - _filteredItems = [.. ListHelpers.FilterListWithScores(newFilteredItems ?? [], SearchText, scoreItem)]; + _filteredItems = InternalListHelpers.FilterListWithScores(newFilteredItems, searchQuery, _scoringFunction); if (token.IsCancellationRequested) { @@ -388,21 +400,14 @@ public partial class MainListPage : DynamicListPage, } IEnumerable newFallbacksForScoring = commands.Where(s => s.IsFallback && globalFallbacks.Contains(s.Id)); + _scoredFallbackItems = InternalListHelpers.FilterListWithScores(newFallbacksForScoring, searchQuery, _scoringFunction); if (token.IsCancellationRequested) { return; } - _scoredFallbackItems = ListHelpers.FilterListWithScores(newFallbacksForScoring ?? [], SearchText, scoreItem); - - if (token.IsCancellationRequested) - { - return; - } - - Func scoreFallbackItem = (a, b) => { return ScoreFallbackItem(a, b, _settings.FallbackRanks); }; - _fallbackItems = [.. ListHelpers.FilterListWithScores(newFallbacks ?? [], SearchText, scoreFallbackItem)]; + _fallbackItems = InternalListHelpers.FilterListWithScores(newFallbacks ?? [], searchQuery, _fallbackScoringFunction); if (token.IsCancellationRequested) { @@ -412,18 +417,7 @@ public partial class MainListPage : DynamicListPage, // Produce a list of filtered apps with the appropriate limit if (newApps.Any()) { - var scoredApps = ListHelpers.FilterListWithScores(newApps, SearchText, scoreItem); - - if (token.IsCancellationRequested) - { - return; - } - - // We'll apply this limit in the GetItems method after merging with commands - // but we need to know the limit now to avoid re-scoring apps - var appLimit = AllAppsCommandProvider.TopLevelResultLimit; - - _filteredApps = [.. scoredApps]; + _filteredApps = InternalListHelpers.FilterListWithScores(newApps, searchQuery, _scoringFunction); if (token.IsCancellationRequested) { @@ -431,10 +425,15 @@ public partial class MainListPage : DynamicListPage, } } + var filterDoneTimestamp = stopwatch.ElapsedMilliseconds; + Logger.LogDebug($"Filter with '{newSearch}' in {filterDoneTimestamp}ms"); + RaiseItemsChanged(); - timer.Stop(); - Logger.LogDebug($"Filter with '{newSearch}' in {timer.ElapsedMilliseconds}ms"); + var listPageUpdatedTimestamp = stopwatch.ElapsedMilliseconds; + Logger.LogDebug($"Render items with '{newSearch}' in {listPageUpdatedTimestamp}ms /d {listPageUpdatedTimestamp - filterDoneTimestamp}ms"); + + stopwatch.Stop(); } } @@ -478,7 +477,11 @@ public partial class MainListPage : DynamicListPage, // Almost verbatim ListHelpers.ScoreListItem, but also accounting for the // fact that we want fallback handlers down-weighted, so that they don't // _always_ show up first. - internal static int ScoreTopLevelItem(string query, IListItem topLevelOrAppItem, IRecentCommandsManager history) + internal static int ScoreTopLevelItem( + in FuzzyQuery query, + IListItem topLevelOrAppItem, + IRecentCommandsManager history, + IPrecomputedFuzzyMatcher precomputedFuzzyMatcher) { var title = topLevelOrAppItem.Title; if (string.IsNullOrWhiteSpace(title)) @@ -486,94 +489,80 @@ public partial class MainListPage : DynamicListPage, return 0; } - var isWhiteSpace = string.IsNullOrWhiteSpace(query); - var isFallback = false; var isAliasSubstringMatch = false; var isAliasMatch = false; var id = IdForTopLevelOrAppItem(topLevelOrAppItem); - var extensionDisplayName = string.Empty; + FuzzyTarget? extensionDisplayNameTarget = null; if (topLevelOrAppItem is TopLevelViewModel topLevel) { isFallback = topLevel.IsFallback; + extensionDisplayNameTarget = topLevel.GetExtensionNameTarget(precomputedFuzzyMatcher); + if (topLevel.HasAlias) { var alias = topLevel.AliasText; - isAliasMatch = alias == query; - isAliasSubstringMatch = isAliasMatch || alias.StartsWith(query, StringComparison.CurrentCultureIgnoreCase); + isAliasMatch = alias == query.Original; + isAliasSubstringMatch = isAliasMatch || alias.StartsWith(query.Original, StringComparison.CurrentCultureIgnoreCase); } - - extensionDisplayName = topLevel.ExtensionHost?.Extension?.PackageDisplayName ?? string.Empty; } - // StringMatcher.FuzzySearch will absolutely BEEF IT if you give it a - // whitespace-only query. - // - // in that scenario, we'll just use a simple string contains for the - // query. Maybe someone is really looking for things with a space in - // them, I don't know. - - // Title: - // * whitespace query: 1 point - // * otherwise full weight match - var nameMatch = isWhiteSpace ? - (title.Contains(query) ? 1 : 0) : - FuzzyStringMatcher.ScoreFuzzy(query, title); - - // Subtitle: - // * whitespace query: 1/2 point - // * otherwise ~half weight match. Minus a bit, because subtitles tend to be longer - var descriptionMatch = isWhiteSpace ? - (topLevelOrAppItem.Subtitle.Contains(query) ? .5 : 0) : - (FuzzyStringMatcher.ScoreFuzzy(query, topLevelOrAppItem.Subtitle) - 4) / 2.0; - - // Extension title: despite not being visible, give the extension name itself some weight - // * whitespace query: 0 points - // * otherwise more weight than a subtitle, but not much - var extensionTitleMatch = isWhiteSpace ? 0 : FuzzyStringMatcher.ScoreFuzzy(query, extensionDisplayName) / 1.5; - - var scores = new[] + // Handle whitespace query separately - FuzzySearch doesn't handle it well + if (string.IsNullOrWhiteSpace(query.Original)) { - nameMatch, - descriptionMatch, - isFallback ? 1 : 0, // Always give fallbacks a chance - }; - var max = scores.Max(); + return ScoreWhitespaceQuery(query.Original, title, topLevelOrAppItem.Subtitle, isFallback); + } - // _Add_ the extension name. This will bubble items that match both - // title and extension name up above ones that just match title. - // e.g. "git" will up-weight "GitHub searches" from the GitHub extension - // above "git" from "whatever" - max = max + extensionTitleMatch; + // Get precomputed targets + var (titleTarget, subtitleTarget) = topLevelOrAppItem is IPrecomputedListItem precomputedItem + ? (precomputedItem.GetTitleTarget(precomputedFuzzyMatcher), precomputedItem.GetSubtitleTarget(precomputedFuzzyMatcher)) + : (precomputedFuzzyMatcher.PrecomputeTarget(title), precomputedFuzzyMatcher.PrecomputeTarget(topLevelOrAppItem.Subtitle)); + + // Score components + var nameScore = precomputedFuzzyMatcher.Score(query, titleTarget); + var descriptionScore = (precomputedFuzzyMatcher.Score(query, subtitleTarget) - 4) / 2.0; + var extensionScore = extensionDisplayNameTarget is { } extTarget ? precomputedFuzzyMatcher.Score(query, extTarget) / 1.5 : 0; + + // Take best match from title/description/fallback, then add extension score + // Extension adds to max so items matching both title AND extension bubble up + var baseScore = Math.Max(Math.Max(nameScore, descriptionScore), isFallback ? 1 : 0); + var matchScore = baseScore + extensionScore; // Apply a penalty to fallback items so they rank below direct matches. // Fallbacks that dynamically match queries (like RDP connections) should // appear after apps and direct command matches. - if (isFallback && max > 1) + if (isFallback && matchScore > 1) { // Reduce fallback scores by 50% to prioritize direct matches - max = max * 0.5; + matchScore = matchScore * 0.5; } - var matchSomething = max - + (isAliasMatch ? 9001 : (isAliasSubstringMatch ? 1 : 0)); + // Alias matching: exact match is overwhelming priority, substring match adds a small boost + var aliasBoost = isAliasMatch ? 9001 : (isAliasSubstringMatch ? 1 : 0); + var totalMatch = matchScore + aliasBoost; - // If we matched title, subtitle, or alias (something real), then - // here we add the recent command weight boost - // - // Otherwise something like `x` will still match everything you've run before - var finalScore = matchSomething * 10; - if (matchSomething > 0) + // Apply scaling and history boost only if we matched something real + var finalScore = totalMatch * 10; + if (totalMatch > 0) { - var recentWeightBoost = history.GetCommandHistoryWeight(id); - finalScore += recentWeightBoost; + finalScore += history.GetCommandHistoryWeight(id); } return (int)finalScore; } - internal static int ScoreFallbackItem(string query, IListItem topLevelOrAppItem, string[] fallbackRanks) + private static int ScoreWhitespaceQuery(string query, string title, string subtitle, bool isFallback) + { + // Simple contains check for whitespace queries + var nameMatch = title.Contains(query, StringComparison.Ordinal) ? 1.0 : 0; + var descriptionMatch = subtitle.Contains(query, StringComparison.Ordinal) ? 0.5 : 0; + var baseScore = Math.Max(Math.Max(nameMatch, descriptionMatch), isFallback ? 1 : 0); + + return (int)(baseScore * 10); + } + + private static int ScoreFallbackItem(IListItem topLevelOrAppItem, string[] fallbackRanks) { // Default to 1 so it always shows in list. var finalScore = 1; diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Commands/MainListPageResultFactory.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Commands/MainListPageResultFactory.cs index d63c0e4f90..0c0d876179 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Commands/MainListPageResultFactory.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Commands/MainListPageResultFactory.cs @@ -4,6 +4,7 @@ #pragma warning disable IDE0007 // Use implicit type +using Microsoft.CmdPal.Core.Common.Helpers; using Microsoft.CommandPalette.Extensions; using Microsoft.CommandPalette.Extensions.Toolkit; @@ -16,10 +17,10 @@ internal static class MainListPageResultFactory /// applying an application result limit and filtering fallback items as needed. /// public static IListItem[] Create( - IList>? filteredItems, - IList>? scoredFallbackItems, - IList>? filteredApps, - IList>? fallbackItems, + IList>? filteredItems, + IList>? scoredFallbackItems, + IList>? filteredApps, + IList>? fallbackItems, int appResultLimit) { if (appResultLimit < 0) @@ -147,7 +148,7 @@ internal static class MainListPageResultFactory return result; } - private static int GetNonEmptyFallbackItemsCount(IList>? fallbackItems) + private static int GetNonEmptyFallbackItemsCount(IList>? fallbackItems) { int fallbackItemsCount = 0; diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/TopLevelViewModel.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/TopLevelViewModel.cs index cc863fe362..13b9423119 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/TopLevelViewModel.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/TopLevelViewModel.cs @@ -3,8 +3,11 @@ // See the LICENSE file in the project root for more information. using System.Collections.ObjectModel; +using System.Diagnostics; using CommunityToolkit.Mvvm.ComponentModel; using ManagedCommon; +using Microsoft.CmdPal.Core.Common.Helpers; +using Microsoft.CmdPal.Core.Common.Text; using Microsoft.CmdPal.Core.ViewModels; using Microsoft.CmdPal.Core.ViewModels.Messages; using Microsoft.CmdPal.UI.ViewModels.Settings; @@ -16,7 +19,8 @@ using WyHash; namespace Microsoft.CmdPal.UI.ViewModels; -public sealed partial class TopLevelViewModel : ObservableObject, IListItem, IExtendedAttributesProvider +[DebuggerDisplay($"{{{nameof(GetDebuggerDisplay)}(),nq}}")] +public sealed partial class TopLevelViewModel : ObservableObject, IListItem, IExtendedAttributesProvider, IPrecomputedListItem { private readonly SettingsModel _settings; private readonly ProviderSettings _providerSettings; @@ -34,6 +38,10 @@ public sealed partial class TopLevelViewModel : ObservableObject, IListItem, IEx private HotkeySettings? _hotkey; private IIconInfo? _initialIcon; + private FuzzyTargetCache _titleCache; + private FuzzyTargetCache _subtitleCache; + private FuzzyTargetCache _extensionNameCache; + private CommandAlias? Alias { get; set; } public bool IsFallback { get; private set; } @@ -176,6 +184,8 @@ public sealed partial class TopLevelViewModel : ObservableObject, IListItem, IEx } } + public string ExtensionName => ExtensionHost.GetExtensionDisplayName() ?? string.Empty; + public TopLevelViewModel( CommandItemViewModel item, bool isFallback, @@ -230,6 +240,15 @@ public sealed partial class TopLevelViewModel : ObservableObject, IListItem, IEx { PropChanged?.Invoke(this, new PropChangedEventArgs(e.PropertyName)); + if (e.PropertyName is nameof(CommandItemViewModel.Title) or nameof(CommandItemViewModel.Name)) + { + _titleCache.Invalidate(); + } + else if (e.PropertyName is nameof(CommandItemViewModel.Subtitle)) + { + _subtitleCache.Invalidate(); + } + if (e.PropertyName is "IsInitialized" or nameof(CommandItemViewModel.Command)) { GenerateId(); @@ -420,4 +439,18 @@ public sealed partial class TopLevelViewModel : ObservableObject, IListItem, IEx [WellKnownExtensionAttributes.DataPackage] = _commandItemViewModel?.DataPackage, }; } + + public FuzzyTarget GetTitleTarget(IPrecomputedFuzzyMatcher matcher) + => _titleCache.GetOrUpdate(matcher, Title); + + public FuzzyTarget GetSubtitleTarget(IPrecomputedFuzzyMatcher matcher) + => _subtitleCache.GetOrUpdate(matcher, Subtitle); + + public FuzzyTarget GetExtensionNameTarget(IPrecomputedFuzzyMatcher matcher) + => _extensionNameCache.GetOrUpdate(matcher, ExtensionName); + + private string GetDebuggerDisplay() + { + return ToString(); + } } diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/App.xaml.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI/App.xaml.cs index eb103d3157..152bf95a62 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/App.xaml.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/App.xaml.cs @@ -6,6 +6,7 @@ using ManagedCommon; using Microsoft.CmdPal.Core.Common; using Microsoft.CmdPal.Core.Common.Helpers; using Microsoft.CmdPal.Core.Common.Services; +using Microsoft.CmdPal.Core.Common.Text; using Microsoft.CmdPal.Core.ViewModels; using Microsoft.CmdPal.Ext.Apps; using Microsoft.CmdPal.Ext.Bookmarks; @@ -206,6 +207,9 @@ public partial class App : Application, IDisposable services.AddSingleton(); services.AddSingleton(); + services.AddSingleton( + _ => new FuzzyMatcherProvider(new PrecomputedFuzzyMatcherOptions(), new PinyinFuzzyMatcherOptions())); + // ViewModels services.AddSingleton(); services.AddSingleton(); diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/ContextMenu.xaml.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/ContextMenu.xaml.cs index afc2d190ef..58f7c6318f 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/ContextMenu.xaml.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/ContextMenu.xaml.cs @@ -4,9 +4,11 @@ using CommunityToolkit.Mvvm.Messaging; using CommunityToolkit.WinUI; +using Microsoft.CmdPal.Core.Common.Text; using Microsoft.CmdPal.Core.ViewModels; using Microsoft.CmdPal.Core.ViewModels.Messages; using Microsoft.CmdPal.UI.Messages; +using Microsoft.Extensions.DependencyInjection; using Microsoft.UI.Input; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; @@ -21,21 +23,19 @@ public sealed partial class ContextMenu : UserControl, IRecipient, IRecipient { - public ContextMenuViewModel ViewModel { get; } = new(); + public ContextMenuViewModel ViewModel { get; } public ContextMenu() { this.InitializeComponent(); + ViewModel = new ContextMenuViewModel(App.Current.Services.GetRequiredService()); + ViewModel.PropertyChanged += ViewModel_PropertyChanged; + // RegisterAll isn't AOT compatible WeakReferenceMessenger.Default.Register(this); WeakReferenceMessenger.Default.Register(this); WeakReferenceMessenger.Default.Register(this); - - if (ViewModel is not null) - { - ViewModel.PropertyChanged += ViewModel_PropertyChanged; - } } public void Receive(OpenContextMenuMessage message) diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/PowerToysRootPageService.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI/PowerToysRootPageService.cs index 9a877358f0..23d8b413e0 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/PowerToysRootPageService.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/PowerToysRootPageService.cs @@ -6,6 +6,7 @@ using System.Runtime.InteropServices; using System.Runtime.Versioning; using ManagedCommon; using Microsoft.CmdPal.Core.Common.Services; +using Microsoft.CmdPal.Core.Common.Text; using Microsoft.CmdPal.Core.ViewModels; using Microsoft.CmdPal.UI.ViewModels; using Microsoft.CmdPal.UI.ViewModels.MainPage; @@ -23,13 +24,13 @@ internal sealed class PowerToysRootPageService : IRootPageService private IExtensionWrapper? _activeExtension; private Lazy _mainListPage; - public PowerToysRootPageService(TopLevelCommandManager topLevelCommandManager, SettingsModel settings, AliasManager aliasManager, AppStateModel appStateModel) + public PowerToysRootPageService(TopLevelCommandManager topLevelCommandManager, SettingsModel settings, AliasManager aliasManager, AppStateModel appStateModel, IFuzzyMatcherProvider fuzzyMatcherProvider) { _tlcManager = topLevelCommandManager; _mainListPage = new Lazy(() => { - return new MainListPage(_tlcManager, settings, aliasManager, appStateModel); + return new MainListPage(_tlcManager, settings, aliasManager, appStateModel, fuzzyMatcherProvider); }); } diff --git a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Core.Common.UnitTests/Text/PrecomputedFuzzyMatcherEmojiTests.cs b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Core.Common.UnitTests/Text/PrecomputedFuzzyMatcherEmojiTests.cs new file mode 100644 index 0000000000..fc85834b2e --- /dev/null +++ b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Core.Common.UnitTests/Text/PrecomputedFuzzyMatcherEmojiTests.cs @@ -0,0 +1,78 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.CmdPal.Core.Common.Text; + +namespace Microsoft.CmdPal.Common.UnitTests.Text; + +[TestClass] +public sealed class PrecomputedFuzzyMatcherEmojiTests +{ + private readonly PrecomputedFuzzyMatcher _matcher = new(); + + [TestMethod] + public void ExactMatch_SimpleEmoji_ReturnsScore() + { + const string needle = "🚀"; + const string haystack = "Launch 🚀 sequence"; + + var query = _matcher.PrecomputeQuery(needle); + var target = _matcher.PrecomputeTarget(haystack); + var score = _matcher.Score(query, target); + + Assert.IsTrue(score > 0, "Expected match for simple emoji"); + } + + [TestMethod] + public void ExactMatch_SkinTone_ReturnsScore() + { + const string needle = "👍🏽"; // Medium skin tone + const string haystack = "Thumbs up 👍🏽 here"; + + var query = _matcher.PrecomputeQuery(needle); + var target = _matcher.PrecomputeTarget(haystack); + var score = _matcher.Score(query, target); + + Assert.IsTrue(score > 0, "Expected match for emoji with skin tone"); + } + + [TestMethod] + public void ZWJSequence_Family_Match() + { + const string needle = "👨‍👩‍👧‍👦"; // Family: Man, Woman, Girl, Boy + const string haystack = "Emoji 👨‍👩‍👧‍👦 Test"; + + var query = _matcher.PrecomputeQuery(needle); + var target = _matcher.PrecomputeTarget(haystack); + var score = _matcher.Score(query, target); + + Assert.IsTrue(score > 0, "Expected match for ZWJ sequence"); + } + + [TestMethod] + public void Flags_Match() + { + const string needle = "🇺🇸"; // US Flag (Regional Indicator U + Regional Indicator S) + const string haystack = "USA 🇺🇸"; + + var query = _matcher.PrecomputeQuery(needle); + var target = _matcher.PrecomputeTarget(haystack); + var score = _matcher.Score(query, target); + + Assert.IsTrue(score > 0, "Expected match for flag emoji"); + } + + [TestMethod] + public void Emoji_MixedWithText_Search() + { + const string needle = "t🌮o"; // "t" + taco + "o" + const string haystack = "taco 🌮 on tuesday"; + + var query = _matcher.PrecomputeQuery(needle); + var target = _matcher.PrecomputeTarget(haystack); + var score = _matcher.Score(query, target); + + Assert.IsTrue(score > 0, "Expected match for emoji mixed with text"); + } +} diff --git a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Core.Common.UnitTests/Text/PrecomputedFuzzyMatcherOptionsTests.cs b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Core.Common.UnitTests/Text/PrecomputedFuzzyMatcherOptionsTests.cs new file mode 100644 index 0000000000..b5798986ff --- /dev/null +++ b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Core.Common.UnitTests/Text/PrecomputedFuzzyMatcherOptionsTests.cs @@ -0,0 +1,84 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.CmdPal.Core.Common.Text; + +namespace Microsoft.CmdPal.Common.UnitTests.Text; + +[TestClass] +public sealed class PrecomputedFuzzyMatcherOptionsTests +{ + [TestMethod] + public void Score_RemoveDiacriticsOption_AffectsMatching() + { + var withDiacriticsRemoved = new PrecomputedFuzzyMatcher( + new PrecomputedFuzzyMatcherOptions { RemoveDiacritics = true }); + var withoutDiacriticsRemoved = new PrecomputedFuzzyMatcher( + new PrecomputedFuzzyMatcherOptions { RemoveDiacritics = false }); + + const string needle = "cafe"; + const string haystack = "CAFÉ"; + + var scoreWithRemoval = withDiacriticsRemoved.Score( + withDiacriticsRemoved.PrecomputeQuery(needle), + withDiacriticsRemoved.PrecomputeTarget(haystack)); + var scoreWithoutRemoval = withoutDiacriticsRemoved.Score( + withoutDiacriticsRemoved.PrecomputeQuery(needle), + withoutDiacriticsRemoved.PrecomputeTarget(haystack)); + + Assert.IsTrue(scoreWithRemoval > 0, "Expected match when diacritics are removed."); + Assert.AreEqual(0, scoreWithoutRemoval, "Expected no match when diacritics are preserved."); + } + + [TestMethod] + public void Score_SkipWordSeparatorsOption_AffectsMatching() + { + var skipSeparators = new PrecomputedFuzzyMatcher( + new PrecomputedFuzzyMatcherOptions { SkipWordSeparators = true }); + var keepSeparators = new PrecomputedFuzzyMatcher( + new PrecomputedFuzzyMatcherOptions { SkipWordSeparators = false }); + + const string needle = "a b"; + const string haystack = "ab"; + + var scoreSkip = skipSeparators.Score( + skipSeparators.PrecomputeQuery(needle), + skipSeparators.PrecomputeTarget(haystack)); + var scoreKeep = keepSeparators.Score( + keepSeparators.PrecomputeQuery(needle), + keepSeparators.PrecomputeTarget(haystack)); + + Assert.IsTrue(scoreSkip > 0, "Expected match when word separators are skipped."); + Assert.AreEqual(0, scoreKeep, "Expected no match when word separators are preserved."); + } + + [TestMethod] + public void Score_IgnoreSameCaseBonusOption_AffectsLowercaseQuery() + { + var ignoreSameCase = new PrecomputedFuzzyMatcher( + new PrecomputedFuzzyMatcherOptions + { + IgnoreSameCaseBonusIfQueryIsAllLowercase = true, + SameCaseBonus = 10, + }); + var applySameCase = new PrecomputedFuzzyMatcher( + new PrecomputedFuzzyMatcherOptions + { + IgnoreSameCaseBonusIfQueryIsAllLowercase = false, + SameCaseBonus = 10, + }); + + const string needle = "test"; + const string haystack = "test"; + + var scoreIgnore = ignoreSameCase.Score( + ignoreSameCase.PrecomputeQuery(needle), + ignoreSameCase.PrecomputeTarget(haystack)); + var scoreApply = applySameCase.Score( + applySameCase.PrecomputeQuery(needle), + applySameCase.PrecomputeTarget(haystack)); + + Assert.IsTrue(scoreApply > scoreIgnore, "Expected same-case bonus to apply when not ignored."); + } +} diff --git a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Core.Common.UnitTests/Text/PrecomputedFuzzyMatcherSecondaryInputTests.cs b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Core.Common.UnitTests/Text/PrecomputedFuzzyMatcherSecondaryInputTests.cs new file mode 100644 index 0000000000..70c86a4598 --- /dev/null +++ b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Core.Common.UnitTests/Text/PrecomputedFuzzyMatcherSecondaryInputTests.cs @@ -0,0 +1,227 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.CmdPal.Core.Common.Text; + +namespace Microsoft.CmdPal.Common.UnitTests.Text; + +[TestClass] +public sealed class PrecomputedFuzzyMatcherSecondaryInputTests +{ + private readonly PrecomputedFuzzyMatcher _matcher = new(); + private readonly StringFolder _folder = new(); + private readonly BloomFilter _bloom = new(); + + [TestMethod] + public void Score_PrimaryQueryMatchesSecondaryTarget_ShouldMatch() + { + // Scenario: Searching for "calc" should match a file "calculator.exe" where primary is filename, secondary is path + var query = CreateQuery("calc"); + var target = CreateTarget(primary: "important.txt", secondary: "C:\\Programs\\Calculator\\"); + + var score = _matcher.Score(query, target); + + Assert.IsTrue(score > 0, "Expected primary query to match secondary target"); + } + + [TestMethod] + public void Score_SecondaryQueryMatchesPrimaryTarget_ShouldMatch() + { + // Scenario: User types "documents\\report" and we want to match against filename + var query = CreateQuery(primary: "documents", secondary: "report"); + var target = CreateTarget(primary: "report.docx"); + + var score = _matcher.Score(query, target); + + Assert.IsTrue(score > 0, "Expected secondary query to match primary target"); + } + + [TestMethod] + public void Score_SecondaryQueryMatchesSecondaryTarget_ShouldMatch() + { + // Scenario: Both query and target have secondary info that matches + var query = CreateQuery(primary: "test", secondary: "documents"); + var target = CreateTarget(primary: "something.txt", secondary: "C:\\Users\\Documents\\"); + + var score = _matcher.Score(query, target); + + Assert.IsTrue(score > 0, "Expected secondary query to match secondary target"); + } + + [TestMethod] + public void Score_PrimaryQueryMatchesBothTargets_ShouldReturnBestScore() + { + // The same query matches both primary and secondary of target + var query = CreateQuery("test"); + var target = CreateTarget(primary: "test.txt", secondary: "test_folder\\"); + + var score = _matcher.Score(query, target); + + Assert.IsTrue(score > 0, "Expected query to match when it appears in both primary and secondary"); + } + + [TestMethod] + public void Score_NoSecondaryInQuery_MatchesSecondaryTarget() + { + // Query without secondary can still match target's secondary + var query = CreateQuery("downloads"); + var target = CreateTarget(primary: "file.txt", secondary: "C:\\Downloads\\"); + + var score = _matcher.Score(query, target); + + Assert.IsTrue(score > 0, "Expected primary query to match secondary target"); + } + + [TestMethod] + public void Score_NoSecondaryInTarget_SecondaryQueryShouldNotMatch() + { + // Query with secondary but target without secondary - secondary query shouldn't interfere + var query = CreateQuery(primary: "test", secondary: "extra"); + var target = CreateTarget(primary: "test.txt"); + + var score = _matcher.Score(query, target); + + // Primary should still match, secondary query just doesn't contribute + Assert.IsTrue(score > 0, "Expected primary query to match primary target"); + } + + [TestMethod] + public void Score_SecondaryQueryNoMatch_PrimaryCanStillMatch() + { + // Secondary doesn't match anything, but primary does + var query = CreateQuery(primary: "file", secondary: "nomatch"); + var target = CreateTarget(primary: "myfile.txt", secondary: "C:\\Documents\\"); + + var score = _matcher.Score(query, target); + + Assert.IsTrue(score > 0, "Expected primary query to match even when secondary doesn't"); + } + + [TestMethod] + public void Score_OnlySecondaryMatches_ShouldReturnScore() + { + // Only the secondary parts match, primary doesn't + var query = CreateQuery(primary: "xyz", secondary: "documents"); + var target = CreateTarget(primary: "abc.txt", secondary: "C:\\Users\\Documents\\"); + + var score = _matcher.Score(query, target); + + Assert.IsTrue(score > 0, "Expected match when only secondary parts match"); + } + + [TestMethod] + public void Score_BothQueriesMatchDifferentTargets_ShouldReturnBestScore() + { + // Primary query matches secondary target, secondary query matches primary target + var query = CreateQuery(primary: "docs", secondary: "report"); + var target = CreateTarget(primary: "report.pdf", secondary: "C:\\Documents\\"); + + var score = _matcher.Score(query, target); + + Assert.IsTrue(score > 0, "Expected match when queries cross-match with targets"); + } + + [TestMethod] + public void Score_CompletelyDifferent_ShouldNotMatch() + { + var query = CreateQuery(primary: "xyz", secondary: "abc"); + var target = CreateTarget(primary: "hello", secondary: "world"); + + var score = _matcher.Score(query, target); + + Assert.AreEqual(0, score, "Expected no match when nothing matches"); + } + + [TestMethod] + public void Score_EmptySecondaryInputs_ShouldMatchOnPrimary() + { + var query = CreateQuery(primary: "test", secondary: string.Empty); + var target = CreateTarget(primary: "test.txt", secondary: string.Empty); + + var score = _matcher.Score(query, target); + + Assert.IsTrue(score > 0, "Expected match on primary when secondaries are empty"); + } + + [TestMethod] + public void Score_WordSeparatorMatching_AcrossSecondary() + { + // Test that "Power Point" matches "PowerPoint" using secondary + var query = CreateQuery(primary: "power", secondary: "point"); + var target = CreateTarget(primary: "PowerPoint.exe"); + + var score = _matcher.Score(query, target); + + Assert.IsTrue(score > 0, "Expected 'power' + 'point' to match 'PowerPoint'"); + } + + private FuzzyQuery CreateQuery(string primary, string? secondary = null) + { + var primaryFolded = _folder.Fold(primary, removeDiacritics: true); + var primaryBloom = _bloom.Compute(primaryFolded); + var primaryEffectiveLength = primaryFolded.Length; + var primaryIsAllLowercase = IsAllLowercaseAsciiOrNonLetter(primary); + + string? secondaryFolded = null; + ulong secondaryBloom = 0; + var secondaryEffectiveLength = 0; + var secondaryIsAllLowercase = true; + + if (!string.IsNullOrEmpty(secondary)) + { + secondaryFolded = _folder.Fold(secondary, removeDiacritics: true); + secondaryBloom = _bloom.Compute(secondaryFolded); + secondaryEffectiveLength = secondaryFolded.Length; + secondaryIsAllLowercase = IsAllLowercaseAsciiOrNonLetter(secondary); + } + + return new FuzzyQuery( + original: primary, + folded: primaryFolded, + bloom: primaryBloom, + effectiveLength: primaryEffectiveLength, + isAllLowercaseAsciiOrNonLetter: primaryIsAllLowercase, + secondaryOriginal: secondary, + secondaryFolded: secondaryFolded, + secondaryBloom: secondaryBloom, + secondaryEffectiveLength: secondaryEffectiveLength, + secondaryIsAllLowercaseAsciiOrNonLetter: secondaryIsAllLowercase); + } + + private FuzzyTarget CreateTarget(string primary, string? secondary = null) + { + var primaryFolded = _folder.Fold(primary, removeDiacritics: true); + var primaryBloom = _bloom.Compute(primaryFolded); + + string? secondaryFolded = null; + ulong secondaryBloom = 0; + + if (!string.IsNullOrEmpty(secondary)) + { + secondaryFolded = _folder.Fold(secondary, removeDiacritics: true); + secondaryBloom = _bloom.Compute(secondaryFolded); + } + + return new FuzzyTarget( + original: primary, + folded: primaryFolded, + bloom: primaryBloom, + secondaryOriginal: secondary, + secondaryFolded: secondaryFolded, + secondaryBloom: secondaryBloom); + } + + private static bool IsAllLowercaseAsciiOrNonLetter(string s) + { + foreach (var c in s) + { + if ((uint)(c - 'A') <= ('Z' - 'A')) + { + return false; + } + } + + return true; + } +} diff --git a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Core.Common.UnitTests/Text/PrecomputedFuzzyMatcherTests.cs b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Core.Common.UnitTests/Text/PrecomputedFuzzyMatcherTests.cs new file mode 100644 index 0000000000..bdd3898ac9 --- /dev/null +++ b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Core.Common.UnitTests/Text/PrecomputedFuzzyMatcherTests.cs @@ -0,0 +1,209 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.CmdPal.Core.Common.Text; + +namespace Microsoft.CmdPal.Common.UnitTests.Text; + +[TestClass] +public class PrecomputedFuzzyMatcherTests +{ + private readonly PrecomputedFuzzyMatcher _matcher = new(); + + public static IEnumerable MatchData => + [ + ["a", "a"], + ["abc", "abc"], + ["a", "ab"], + ["b", "ab"], + ["abc", "axbycz"], + ["pt", "PowerToys"], + ["calc", "Calculator"], + ["vs", "Visual Studio"], + ["code", "Visual Studio Code"], + + // Diacritics + ["abc", "ÁBC"], + + // Separators + ["p/t", "power\\toys"], + ]; + + public static IEnumerable NonMatchData => + [ + ["z", "abc"], + ["verylongstring", "short"], + ]; + + [TestMethod] + [DynamicData(nameof(MatchData))] + public void Score_Matches_ShouldHavePositiveScore(string needle, string haystack) + { + var query = _matcher.PrecomputeQuery(needle); + var target = _matcher.PrecomputeTarget(haystack); + var score = _matcher.Score(query, target); + + Assert.IsTrue(score > 0, $"Expected positive score for needle='{needle}', haystack='{haystack}'"); + } + + [TestMethod] + [DynamicData(nameof(NonMatchData))] + public void Score_NonMatches_ShouldHaveZeroScore(string needle, string haystack) + { + var query = _matcher.PrecomputeQuery(needle); + var target = _matcher.PrecomputeTarget(haystack); + var score = _matcher.Score(query, target); + + Assert.AreEqual(0, score, $"Expected 0 score for needle='{needle}', haystack='{haystack}'"); + } + + [TestMethod] + public void Score_EmptyQuery_ReturnsZero() + { + var query = _matcher.PrecomputeQuery(string.Empty); + var target = _matcher.PrecomputeTarget("something"); + Assert.AreEqual(0, _matcher.Score(query, target)); + } + + [TestMethod] + public void Score_EmptyTarget_ReturnsZero() + { + var query = _matcher.PrecomputeQuery("something"); + var target = _matcher.PrecomputeTarget(string.Empty); + Assert.AreEqual(0, _matcher.Score(query, target)); + } + + [TestMethod] + public void SchemaId_DefaultMatcher_IsConsistent() + { + var matcher1 = new PrecomputedFuzzyMatcher(); + var matcher2 = new PrecomputedFuzzyMatcher(); + + Assert.AreEqual(matcher1.SchemaId, matcher2.SchemaId, "Default matchers should have the same SchemaId"); + } + + [TestMethod] + public void SchemaId_SameOptions_ProducesSameId() + { + var options = new PrecomputedFuzzyMatcherOptions { RemoveDiacritics = true }; + var matcher1 = new PrecomputedFuzzyMatcher(options); + var matcher2 = new PrecomputedFuzzyMatcher(options); + + Assert.AreEqual(matcher1.SchemaId, matcher2.SchemaId, "Matchers with same options should have the same SchemaId"); + } + + [TestMethod] + public void SchemaId_DifferentRemoveDiacriticsOption_ProducesDifferentId() + { + var matcherWithDiacriticsRemoval = new PrecomputedFuzzyMatcher( + new PrecomputedFuzzyMatcherOptions { RemoveDiacritics = true }); + var matcherWithoutDiacriticsRemoval = new PrecomputedFuzzyMatcher( + new PrecomputedFuzzyMatcherOptions { RemoveDiacritics = false }); + + Assert.AreNotEqual( + matcherWithDiacriticsRemoval.SchemaId, + matcherWithoutDiacriticsRemoval.SchemaId, + "Different RemoveDiacritics option should produce different SchemaId"); + } + + [TestMethod] + public void SchemaId_ScoringOptionsDoNotAffectId() + { + // SchemaId should only be affected by options that affect folding/bloom, not scoring + var matcher1 = new PrecomputedFuzzyMatcher( + new PrecomputedFuzzyMatcherOptions { CharMatchBonus = 1, CamelCaseBonus = 2 }); + var matcher2 = new PrecomputedFuzzyMatcher( + new PrecomputedFuzzyMatcherOptions { CharMatchBonus = 100, CamelCaseBonus = 200 }); + + Assert.AreEqual(matcher1.SchemaId, matcher2.SchemaId, "Scoring options should not affect SchemaId"); + } + + [TestMethod] + public void Score_WordSeparatorMatching_PowerPoint() + { + // Test that "Power Point" can match "PowerPoint" when word separators are skipped + var query = _matcher.PrecomputeQuery("Power Point"); + var target = _matcher.PrecomputeTarget("PowerPoint"); + var score = _matcher.Score(query, target); + + Assert.IsTrue(score > 0, "Expected 'Power Point' to match 'PowerPoint'"); + } + + [TestMethod] + public void Score_WordSeparatorMatching_UnderscoreDash() + { + // Test that different word separators match each other + var query = _matcher.PrecomputeQuery("hello_world"); + var target = _matcher.PrecomputeTarget("hello-world"); + var score = _matcher.Score(query, target); + + Assert.IsTrue(score > 0, "Expected 'hello_world' to match 'hello-world'"); + } + + [TestMethod] + public void Score_WordSeparatorMatching_MixedSeparators() + { + // Test multiple different separators + var query = _matcher.PrecomputeQuery("my.file_name"); + var target = _matcher.PrecomputeTarget("my-file.name"); + var score = _matcher.Score(query, target); + + Assert.IsTrue(score > 0, "Expected mixed separators to match"); + } + + [TestMethod] + public void Score_PrecomputedQueryReuse_ShouldWorkConsistently() + { + // Test that precomputed query can be reused across multiple targets + var query = _matcher.PrecomputeQuery("test"); + var target1 = _matcher.PrecomputeTarget("test123"); + var target2 = _matcher.PrecomputeTarget("mytest"); + var target3 = _matcher.PrecomputeTarget("unrelated"); + + var score1 = _matcher.Score(query, target1); + var score2 = _matcher.Score(query, target2); + var score3 = _matcher.Score(query, target3); + + Assert.IsTrue(score1 > 0, "Expected query to match first target"); + Assert.IsTrue(score2 > 0, "Expected query to match second target"); + Assert.AreEqual(0, score3, "Expected query not to match third target"); + } + + [TestMethod] + public void Score_PrecomputedTargetReuse_ShouldWorkConsistently() + { + // Test that precomputed target can be reused across multiple queries + var target = _matcher.PrecomputeTarget("calculator"); + var query1 = _matcher.PrecomputeQuery("calc"); + var query2 = _matcher.PrecomputeQuery("lator"); + var query3 = _matcher.PrecomputeQuery("xyz"); + + var score1 = _matcher.Score(query1, target); + var score2 = _matcher.Score(query2, target); + var score3 = _matcher.Score(query3, target); + + Assert.IsTrue(score1 > 0, "Expected first query to match target"); + Assert.IsTrue(score2 > 0, "Expected second query to match target"); + Assert.AreEqual(0, score3, "Expected third query not to match target"); + } + + [TestMethod] + public void Score_CaseInsensitiveMatching_Works() + { + // Test various case combinations + var query1 = _matcher.PrecomputeQuery("test"); + var query2 = _matcher.PrecomputeQuery("TEST"); + var query3 = _matcher.PrecomputeQuery("TeSt"); + + var target = _matcher.PrecomputeTarget("TestFile"); + + var score1 = _matcher.Score(query1, target); + var score2 = _matcher.Score(query2, target); + var score3 = _matcher.Score(query3, target); + + Assert.IsTrue(score1 > 0, "Expected lowercase query to match"); + Assert.IsTrue(score2 > 0, "Expected uppercase query to match"); + Assert.IsTrue(score3 > 0, "Expected mixed case query to match"); + } +} diff --git a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Core.Common.UnitTests/Text/PrecomputedFuzzyMatcherUnicodeTests.cs b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Core.Common.UnitTests/Text/PrecomputedFuzzyMatcherUnicodeTests.cs new file mode 100644 index 0000000000..8cdf39bc82 --- /dev/null +++ b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Core.Common.UnitTests/Text/PrecomputedFuzzyMatcherUnicodeTests.cs @@ -0,0 +1,124 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.CmdPal.Core.Common.Text; + +namespace Microsoft.CmdPal.Common.UnitTests.Text; + +[TestClass] +public sealed class PrecomputedFuzzyMatcherUnicodeTests +{ + private readonly PrecomputedFuzzyMatcher _defaultMatcher = new(); + + [TestMethod] + public void UnpairedHighSurrogateInNeedle_ShouldNotThrow() + { + const string needle = "\uD83D"; // high surrogate (unpaired) + const string haystack = "abc"; + + var q = _defaultMatcher.PrecomputeQuery(needle); + var t = _defaultMatcher.PrecomputeTarget(haystack); + _ = _defaultMatcher.Score(q, t); + } + + [TestMethod] + public void UnpairedLowSurrogateInNeedle_ShouldNotThrow() + { + const string needle = "\uDC00"; // low surrogate (unpaired) + const string haystack = "abc"; + + var q = _defaultMatcher.PrecomputeQuery(needle); + var t = _defaultMatcher.PrecomputeTarget(haystack); + _ = _defaultMatcher.Score(q, t); + } + + [TestMethod] + public void UnpairedHighSurrogateInHaystack_ShouldNotThrow() + { + const string needle = "a"; + const string haystack = "a\uD83D" + "bc"; // inject unpaired high surrogate + + var q = _defaultMatcher.PrecomputeQuery(needle); + var t = _defaultMatcher.PrecomputeTarget(haystack); + _ = _defaultMatcher.Score(q, t); + } + + [TestMethod] + public void MixedSurrogatesAndMarks_ShouldNotThrow() + { + // "Garbage smoothie": unpaired surrogate + combining mark + emoji surrogate pair + const string needle = "a\uD83D\u0301"; // 'a' + unpaired high surrogate + combining acute + const string haystack = "a\u0301 \U0001F600"; // 'a' + combining acute + space + 😀 (valid pair) + + var q = _defaultMatcher.PrecomputeQuery(needle); + var t = _defaultMatcher.PrecomputeTarget(haystack); + _ = _defaultMatcher.Score(q, t); + } + + [TestMethod] + public void ValidEmojiSurrogatePair_ShouldNotThrow_AndCanMatch() + { + // 😀 U+1F600 encoded as surrogate pair in UTF-16 + const string needle = "\U0001F600"; + const string haystack = "x \U0001F600 y"; + + var q = _defaultMatcher.PrecomputeQuery(needle); + var t = _defaultMatcher.PrecomputeTarget(haystack); + var score = _defaultMatcher.Score(q, t); + + Assert.IsTrue(score > 0, "Expected emoji to produce a match score > 0."); + } + + [TestMethod] + public void RandomUtf16Garbage_ShouldNotThrow() + { + // Deterministic pseudo-random "UTF-16 garbage", including surrogates. + var s1 = MakeDeterministicGarbage(seed: 1234, length: 512); + var s2 = MakeDeterministicGarbage(seed: 5678, length: 1024); + + var q = _defaultMatcher.PrecomputeQuery(s1); + var t = _defaultMatcher.PrecomputeTarget(s2); + _ = _defaultMatcher.Score(q, t); + } + + [TestMethod] + public void HighSurrogateAtEndOfHaystack_ShouldNotThrow() + { + const string needle = "a"; + const string haystack = "abc\uD83D"; // Ends with high surrogate + + var q = _defaultMatcher.PrecomputeQuery(needle); + var t = _defaultMatcher.PrecomputeTarget(haystack); + _ = _defaultMatcher.Score(q, t); + } + + [TestMethod] + public void VeryLongStrings_ShouldNotThrow() + { + var needle = new string('a', 100); + var haystack = new string('b', 10000) + needle + new string('c', 10000); + + var q = _defaultMatcher.PrecomputeQuery(needle); + var t = _defaultMatcher.PrecomputeTarget(haystack); + _ = _defaultMatcher.Score(q, t); + } + + private static string MakeDeterministicGarbage(int seed, int length) + { + // LCG for deterministic generation without Random’s platform/version surprises. + var x = (uint)seed; + var chars = length <= 2048 ? stackalloc char[length] : new char[length]; + + for (var i = 0; i < chars.Length; i++) + { + // LCG: x = (a*x + c) mod 2^32 + x = unchecked((1664525u * x) + 1013904223u); + + // Take top 16 bits as UTF-16 code unit (includes surrogates). + chars[i] = (char)(x >> 16); + } + + return new string(chars); + } +} diff --git a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Core.Common.UnitTests/Text/PrecomputedFuzzyMatcherWithPinyinTests.cs b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Core.Common.UnitTests/Text/PrecomputedFuzzyMatcherWithPinyinTests.cs new file mode 100644 index 0000000000..3e811c050a --- /dev/null +++ b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Core.Common.UnitTests/Text/PrecomputedFuzzyMatcherWithPinyinTests.cs @@ -0,0 +1,117 @@ +// 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.Globalization; +using Microsoft.CmdPal.Core.Common.Text; + +namespace Microsoft.CmdPal.Common.UnitTests.Text; + +[TestClass] +public class PrecomputedFuzzyMatcherWithPinyinTests +{ + private PrecomputedFuzzyMatcherWithPinyin CreateMatcher(PinyinMode mode = PinyinMode.On, bool removeApostrophes = true) + { + return new PrecomputedFuzzyMatcherWithPinyin( + new PrecomputedFuzzyMatcherOptions(), + new PinyinFuzzyMatcherOptions { Mode = mode, RemoveApostrophesForQuery = removeApostrophes }, + new StringFolder(), + new BloomFilter()); + } + + [TestMethod] + [DataRow("bj", "北京")] + [DataRow("sh", "上海")] + [DataRow("nihao", "你好")] + [DataRow("beijing", "北京")] + [DataRow("ce", "测试")] + public void Score_PinyinMatches_ShouldHavePositiveScore(string needle, string haystack) + { + var matcher = CreateMatcher(PinyinMode.On); + var query = matcher.PrecomputeQuery(needle); + var target = matcher.PrecomputeTarget(haystack); + var score = matcher.Score(query, target); + + Assert.IsTrue(score > 0, $"Expected positive score for needle='{needle}', haystack='{haystack}'"); + } + + [TestMethod] + public void Score_PinyinOff_ShouldNotMatchPinyin() + { + var matcher = CreateMatcher(PinyinMode.Off); + var needle = "bj"; + var haystack = "北京"; + + var query = matcher.PrecomputeQuery(needle); + var target = matcher.PrecomputeTarget(haystack); + var score = matcher.Score(query, target); + + Assert.AreEqual(0, score, "Pinyin match should be disabled."); + } + + [TestMethod] + public void Score_StandardMatch_WorksWithPinyinMatcher() + { + var matcher = CreateMatcher(PinyinMode.On); + var needle = "abc"; + var haystack = "abc"; + + var query = matcher.PrecomputeQuery(needle); + var target = matcher.PrecomputeTarget(haystack); + var score = matcher.Score(query, target); + + Assert.IsTrue(score > 0, "Standard match should still work."); + } + + [TestMethod] + public void Score_ApostropheRemoval_Works() + { + var matcher = CreateMatcher(PinyinMode.On, removeApostrophes: true); + var needle = "xi'an"; + + // "xi'an" -> "xian" -> matches "西安" (Xi An) + var haystack = "西安"; + + var query = matcher.PrecomputeQuery(needle); + var target = matcher.PrecomputeTarget(haystack); + var score = matcher.Score(query, target); + + Assert.IsTrue(score > 0, "Expected match for 'xi'an' -> '西安' with apostrophe removal."); + } + + [TestMethod] + public void AutoMode_EnablesForChineseCulture() + { + var originalCulture = CultureInfo.CurrentUICulture; + try + { + CultureInfo.CurrentUICulture = new CultureInfo("zh-CN"); + var matcher = CreateMatcher(PinyinMode.AutoSimplifiedChineseUi); + + var score = matcher.Score(matcher.PrecomputeQuery("bj"), matcher.PrecomputeTarget("北京")); + Assert.IsTrue(score > 0, "Should match when UI culture is zh-CN"); + } + finally + { + CultureInfo.CurrentUICulture = originalCulture; + } + } + + [TestMethod] + public void AutoMode_DisablesForNonChineseCulture() + { + var originalCulture = CultureInfo.CurrentUICulture; + try + { + CultureInfo.CurrentUICulture = new CultureInfo("en-US"); + var matcher = CreateMatcher(PinyinMode.AutoSimplifiedChineseUi); + + var score = matcher.Score(matcher.PrecomputeQuery("bj"), matcher.PrecomputeTarget("北京")); + Assert.AreEqual(0, score, "Should NOT match when UI culture is en-US"); + } + finally + { + CultureInfo.CurrentUICulture = originalCulture; + } + } +} diff --git a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Core.Common.UnitTests/Text/StringFolderTests.cs b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Core.Common.UnitTests/Text/StringFolderTests.cs new file mode 100644 index 0000000000..076636f2fb --- /dev/null +++ b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Core.Common.UnitTests/Text/StringFolderTests.cs @@ -0,0 +1,55 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.CmdPal.Core.Common.Text; + +namespace Microsoft.CmdPal.Common.UnitTests.Text; + +[TestClass] +public class StringFolderTests +{ + private readonly StringFolder _folder = new(); + + [TestMethod] + [DataRow(null, "")] + [DataRow("", "")] + [DataRow("abc", "ABC")] + [DataRow("ABC", "ABC")] + [DataRow("a\\b", "A/B")] + [DataRow("a/b", "A/B")] + [DataRow("ÁBC", "ABC")] // Diacritic removal + [DataRow("ñ", "N")] + [DataRow("hello world", "HELLO WORLD")] + public void Fold_RemoveDiacritics_Works(string input, string expected) + { + Assert.AreEqual(expected, _folder.Fold(input, removeDiacritics: true)); + } + + [TestMethod] + [DataRow("abc", "ABC")] + [DataRow("ÁBC", "ÁBC")] // No diacritic removal + [DataRow("a\\b", "A/B")] + public void Fold_KeepDiacritics_Works(string input, string expected) + { + Assert.AreEqual(expected, _folder.Fold(input, removeDiacritics: false)); + } + + [TestMethod] + public void Fold_IsAlreadyFolded_ReturnsSameInstance() + { + var input = "ALREADY/FOLDED"; + var result = _folder.Fold(input, removeDiacritics: true); + Assert.AreSame(input, result); + } + + [TestMethod] + public void Fold_WithNonAsciiButNoDiacritics_ReturnsFolded() + { + // E.g. Cyrillic or other scripts that might not decompose in a simple way or just upper case + // "привет" -> "ПРИВЕТ" + var input = "привет"; + var expected = "ПРИВЕТ"; + Assert.AreEqual(expected, _folder.Fold(input, removeDiacritics: true)); + } +} diff --git a/src/modules/cmdpal/Tests/Microsoft.CmdPal.UI.ViewModels.UnitTests/MainListPageResultFactoryTests.cs b/src/modules/cmdpal/Tests/Microsoft.CmdPal.UI.ViewModels.UnitTests/MainListPageResultFactoryTests.cs index 5a1e4bff54..5cb60ca03b 100644 --- a/src/modules/cmdpal/Tests/Microsoft.CmdPal.UI.ViewModels.UnitTests/MainListPageResultFactoryTests.cs +++ b/src/modules/cmdpal/Tests/Microsoft.CmdPal.UI.ViewModels.UnitTests/MainListPageResultFactoryTests.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Microsoft.CmdPal.Core.Common.Helpers; using Microsoft.CmdPal.UI.ViewModels.Commands; using Microsoft.CommandPalette.Extensions; using Microsoft.CommandPalette.Extensions.Toolkit; @@ -43,38 +44,34 @@ public partial class MainListPageResultFactoryTests public override string ToString() => Title; } - private static Scored S(string title, int score) + private static RoScored S(string title, int score) { - return new Scored - { - Score = score, - Item = new MockListItem { Title = title }, - }; + return new RoScored(score: score, item: new MockListItem { Title = title }); } [TestMethod] public void Merge_PrioritizesListsCorrectly() { - var filtered = new List> + var filtered = new List> { S("F1", 100), S("F2", 50), }; - var scoredFallback = new List> + var scoredFallback = new List> { S("SF1", 100), S("SF2", 60), }; - var apps = new List> + var apps = new List> { S("A1", 100), S("A2", 55), }; // Fallbacks are not scored. - var fallbacks = new List> + var fallbacks = new List> { S("FB1", 0), S("FB2", 0), @@ -104,7 +101,7 @@ public partial class MainListPageResultFactoryTests [TestMethod] public void Merge_AppliesAppLimit() { - var apps = new List> + var apps = new List> { S("A1", 100), S("A2", 90), @@ -126,7 +123,7 @@ public partial class MainListPageResultFactoryTests [TestMethod] public void Merge_FiltersEmptyFallbacks() { - var fallbacks = new List> + var fallbacks = new List> { S("FB1", 0), S("FB3", 0), diff --git a/src/modules/cmdpal/Tests/Microsoft.CmdPal.UI.ViewModels.UnitTests/RecentCommandsTests.cs b/src/modules/cmdpal/Tests/Microsoft.CmdPal.UI.ViewModels.UnitTests/RecentCommandsTests.cs index 78ead1588e..ec93373f74 100644 --- a/src/modules/cmdpal/Tests/Microsoft.CmdPal.UI.ViewModels.UnitTests/RecentCommandsTests.cs +++ b/src/modules/cmdpal/Tests/Microsoft.CmdPal.UI.ViewModels.UnitTests/RecentCommandsTests.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Microsoft.CmdPal.Core.Common.Text; using Microsoft.CmdPal.Ext.UnitTestBase; using Microsoft.CmdPal.UI.ViewModels.MainPage; using Microsoft.CommandPalette.Extensions; @@ -263,10 +264,12 @@ public partial class RecentCommandsTests : CommandPaletteUnitTestBase }; var history = CreateHistory(items.Reverse().ToList()); + var fuzzyMatcher = CreateMatcher(); + var q = fuzzyMatcher.PrecomputeQuery("C"); - var scoreA = MainListPage.ScoreTopLevelItem("C", items[0], history); - var scoreB = MainListPage.ScoreTopLevelItem("C", items[1], history); - var scoreC = MainListPage.ScoreTopLevelItem("C", items[2], history); + var scoreA = MainListPage.ScoreTopLevelItem(q, items[0], history, fuzzyMatcher); + var scoreB = MainListPage.ScoreTopLevelItem(q, items[1], history, fuzzyMatcher); + var scoreC = MainListPage.ScoreTopLevelItem(q, items[2], history, fuzzyMatcher); // Assert // All of these equally match the query, and they're all in the same bucket, @@ -296,6 +299,11 @@ public partial class RecentCommandsTests : CommandPaletteUnitTestBase return history; } + private static IPrecomputedFuzzyMatcher CreateMatcher() + { + return new PrecomputedFuzzyMatcher(new PrecomputedFuzzyMatcherOptions()); + } + private sealed record ScoredItem(ListItemMock Item, int Score) { public string Title => Item.Title; @@ -337,9 +345,11 @@ public partial class RecentCommandsTests : CommandPaletteUnitTestBase var items = CreateMockHistoryItems(); var emptyHistory = CreateMockHistoryService(new()); var history = CreateMockHistoryService(items); + var fuzzyMatcher = CreateMatcher(); - var unweightedScores = items.Select(item => MainListPage.ScoreTopLevelItem("C", item, emptyHistory)).ToList(); - var weightedScores = items.Select(item => MainListPage.ScoreTopLevelItem("C", item, history)).ToList(); + var q = fuzzyMatcher.PrecomputeQuery("C"); + var unweightedScores = items.Select(item => MainListPage.ScoreTopLevelItem(q, item, emptyHistory, fuzzyMatcher)).ToList(); + var weightedScores = items.Select(item => MainListPage.ScoreTopLevelItem(q, item, history, fuzzyMatcher)).ToList(); Assert.AreEqual(unweightedScores.Count, weightedScores.Count, "Both score lists should have the same number of items"); for (var i = 0; i < unweightedScores.Count; i++) { @@ -380,7 +390,10 @@ public partial class RecentCommandsTests : CommandPaletteUnitTestBase var items = CreateMockHistoryItems(); var emptyHistory = CreateMockHistoryService(new()); var history = CreateMockHistoryService(items); - var weightedScores = items.Select(item => MainListPage.ScoreTopLevelItem("te", item, history)).ToList(); + var fuzzyMatcher = CreateMatcher(); + var q = fuzzyMatcher.PrecomputeQuery("te"); + + var weightedScores = items.Select(item => MainListPage.ScoreTopLevelItem(q, item, history, fuzzyMatcher)).ToList(); var weightedMatches = GetMatches(items, weightedScores).ToList(); Assert.AreEqual(3, weightedMatches.Count, "Find Terminal, VsCode and Run commands"); @@ -398,6 +411,8 @@ public partial class RecentCommandsTests : CommandPaletteUnitTestBase var items = CreateMockHistoryItems(); var emptyHistory = CreateMockHistoryService(new()); var history = CreateMockHistoryService(items); + var fuzzyMatcher = CreateMatcher(); + var q = fuzzyMatcher.PrecomputeQuery("te"); // Add extra uses of VS Code to try and push it above Terminal for (var i = 0; i < 10; i++) @@ -405,7 +420,7 @@ public partial class RecentCommandsTests : CommandPaletteUnitTestBase history.AddHistoryItem(items[1].Id); } - var weightedScores = items.Select(item => MainListPage.ScoreTopLevelItem("te", item, history)).ToList(); + var weightedScores = items.Select(item => MainListPage.ScoreTopLevelItem(q, item, history, fuzzyMatcher)).ToList(); var weightedMatches = GetMatches(items, weightedScores).ToList(); Assert.AreEqual(3, weightedMatches.Count, "Find Terminal, VsCode and Run commands"); @@ -423,6 +438,8 @@ public partial class RecentCommandsTests : CommandPaletteUnitTestBase var items = CreateMockHistoryItems(); var emptyHistory = CreateMockHistoryService(new()); var history = CreateMockHistoryService(items); + var fuzzyMatcher = CreateMatcher(); + var q = fuzzyMatcher.PrecomputeQuery("C"); // We're gonna run this test and keep adding more uses of VS Code till // it breaks past Command Prompt @@ -431,7 +448,7 @@ public partial class RecentCommandsTests : CommandPaletteUnitTestBase { history.AddHistoryItem(vsCodeId); - var weightedScores = items.Select(item => MainListPage.ScoreTopLevelItem("C", item, history)).ToList(); + var weightedScores = items.Select(item => MainListPage.ScoreTopLevelItem(q, item, history, fuzzyMatcher)).ToList(); var weightedMatches = GetMatches(items, weightedScores).ToList(); Assert.AreEqual(4, weightedMatches.Count); diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Apps/AppListItem.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Apps/AppListItem.cs index 8d1a05d641..5d1c413281 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Apps/AppListItem.cs +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Apps/AppListItem.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using ManagedCommon; using Microsoft.CmdPal.Core.Common.Helpers; +using Microsoft.CmdPal.Core.Common.Text; using Microsoft.CmdPal.Ext.Apps.Commands; using Microsoft.CmdPal.Ext.Apps.Helpers; using Microsoft.CommandPalette.Extensions; @@ -14,7 +15,7 @@ using Microsoft.CommandPalette.Extensions.Toolkit; namespace Microsoft.CmdPal.Ext.Apps.Programs; -public sealed partial class AppListItem : ListItem +public sealed partial class AppListItem : ListItem, IPrecomputedListItem { private readonly AppCommand _appCommand; private readonly AppItem _app; @@ -25,6 +26,35 @@ public sealed partial class AppListItem : ListItem private InterlockedBoolean _isLoadingIcon; private InterlockedBoolean _isLoadingDetails; + private FuzzyTargetCache _titleCache; + private FuzzyTargetCache _subtitleCache; + + public override string Title + { + get => base.Title; + set + { + if (!string.Equals(base.Title, value, StringComparison.Ordinal)) + { + base.Title = value; + _titleCache.Invalidate(); + } + } + } + + public override string Subtitle + { + get => base.Subtitle; + set + { + if (!string.Equals(value, base.Subtitle, StringComparison.Ordinal)) + { + base.Subtitle = value; + _subtitleCache.Invalidate(); + } + } + } + public override IDetails? Details { get @@ -259,4 +289,10 @@ public sealed partial class AppListItem : ListItem return null; }).ConfigureAwait(false); } + + public FuzzyTarget GetTitleTarget(IPrecomputedFuzzyMatcher matcher) + => _titleCache.GetOrUpdate(matcher, Title); + + public FuzzyTarget GetSubtitleTarget(IPrecomputedFuzzyMatcher matcher) + => _subtitleCache.GetOrUpdate(matcher, Subtitle); } From 095961402b9ab5aeee3f71204d67e84ecf63bee5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Pol=C3=A1=C5=A1ek?= Date: Mon, 9 Feb 2026 20:42:01 +0100 Subject: [PATCH 17/41] CmdPal: Transparent window (#45159) ## Summary This PR adds: - Backdrop material customization - Alongside acrylic, the following options are now available: - Transparent background - Mica background - Background material opacity - Lets you control how transparent the background is ## Pictures? Pictures! image https://github.com/user-attachments/assets/84e83279-afab-481e-b904-f054318c5d2f image ## PR Checklist - [x] Closes: #44197 - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx ## Detailed Description of the Pull Request / Additional comments ## Validation Steps Performed --- .../AppearanceSettingsViewModel.cs | 176 +++++++++++++++-- .../BackdropControllerKind.cs | 41 ++++ .../BackdropStyle.cs | 36 ++++ .../BackdropStyleConfig.cs | 77 ++++++++ .../BackdropStyles.cs | 65 ++++++ .../MainWindowViewModel.cs | 28 +++ .../PreviewBrushKind.cs | 21 ++ .../Services/AcrylicBackdropParameters.cs | 9 - .../Services/BackdropParameters.cs | 29 +++ .../Services/ThemeSnapshot.cs | 17 +- .../SettingsModel.cs | 6 + .../Controls/BlurImageControl.cs | 1 - .../Controls/CommandPalettePreview.xaml | 18 +- .../Controls/CommandPalettePreview.xaml.cs | 112 +++++++++-- .../Microsoft.CmdPal.UI/MainWindow.xaml | 2 +- .../Microsoft.CmdPal.UI/MainWindow.xaml.cs | 185 +++++++++++++++--- .../Services/ColorfulThemeProvider.cs | 24 ++- .../Services/IThemeProvider.cs | 16 +- .../Services/NormalThemeProvider.cs | 21 +- .../Services/ThemeContext.cs | 8 + .../Services/ThemeService.cs | 36 +++- .../Settings/AppearancePage.xaml | 136 ++++++++++--- .../Settings/AppearancePage.xaml.cs | 11 ++ .../Strings/en-us/Resources.resw | 105 +++++++--- 24 files changed, 1023 insertions(+), 157 deletions(-) create mode 100644 src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/BackdropControllerKind.cs create mode 100644 src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/BackdropStyle.cs create mode 100644 src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/BackdropStyleConfig.cs create mode 100644 src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/BackdropStyles.cs create mode 100644 src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/PreviewBrushKind.cs delete mode 100644 src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Services/AcrylicBackdropParameters.cs create mode 100644 src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Services/BackdropParameters.cs diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/AppearanceSettingsViewModel.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/AppearanceSettingsViewModel.cs index 71e150a7d2..4de0215311 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/AppearanceSettingsViewModel.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/AppearanceSettingsViewModel.cs @@ -18,6 +18,8 @@ namespace Microsoft.CmdPal.UI.ViewModels; public sealed partial class AppearanceSettingsViewModel : ObservableObject, IDisposable { + private static readonly Color DefaultTintColor = Color.FromArgb(255, 0, 120, 212); + private static readonly ObservableCollection WindowsColorSwatches = [ // row 0 @@ -128,10 +130,13 @@ public sealed partial class AppearanceSettingsViewModel : ObservableObject, IDis OnPropertyChanged(); OnPropertyChanged(nameof(ColorizationModeIndex)); OnPropertyChanged(nameof(IsCustomTintVisible)); - OnPropertyChanged(nameof(IsCustomTintIntensityVisible)); + OnPropertyChanged(nameof(IsColorIntensityVisible)); + OnPropertyChanged(nameof(IsImageTintIntensityVisible)); + OnPropertyChanged(nameof(EffectiveTintIntensity)); OnPropertyChanged(nameof(IsBackgroundControlsVisible)); OnPropertyChanged(nameof(IsNoBackgroundVisible)); OnPropertyChanged(nameof(IsAccentColorControlsVisible)); + OnPropertyChanged(nameof(IsResetButtonVisible)); if (value == ColorizationMode.WindowsAccentColor) { @@ -179,6 +184,19 @@ public sealed partial class AppearanceSettingsViewModel : ObservableObject, IDis { _settings.CustomThemeColorIntensity = value; OnPropertyChanged(); + OnPropertyChanged(nameof(EffectiveTintIntensity)); + Save(); + } + } + + public int BackgroundImageTintIntensity + { + get => _settings.BackgroundImageTintIntensity; + set + { + _settings.BackgroundImageTintIntensity = value; + OnPropertyChanged(); + OnPropertyChanged(nameof(EffectiveTintIntensity)); Save(); } } @@ -279,12 +297,108 @@ public sealed partial class AppearanceSettingsViewModel : ObservableObject, IDis }; } + public int BackdropOpacity + { + get => _settings.BackdropOpacity; + set + { + if (_settings.BackdropOpacity != value) + { + _settings.BackdropOpacity = value; + OnPropertyChanged(); + OnPropertyChanged(nameof(EffectiveBackdropStyle)); + OnPropertyChanged(nameof(EffectiveImageOpacity)); + Save(); + } + } + } + + public int BackdropStyleIndex + { + get => (int)_settings.BackdropStyle; + set + { + var newStyle = (BackdropStyle)value; + if (_settings.BackdropStyle != newStyle) + { + _settings.BackdropStyle = newStyle; + + OnPropertyChanged(); + OnPropertyChanged(nameof(IsBackdropOpacityVisible)); + OnPropertyChanged(nameof(IsMicaBackdropDescriptionVisible)); + OnPropertyChanged(nameof(IsBackgroundSettingsEnabled)); + OnPropertyChanged(nameof(IsBackgroundNotAvailableVisible)); + + if (!IsBackgroundSettingsEnabled) + { + IsColorizationDetailsExpanded = false; + } + + Save(); + } + } + } + + /// + /// Gets whether the backdrop opacity slider should be visible. + /// + public bool IsBackdropOpacityVisible => + BackdropStyles.Get(_settings.BackdropStyle).SupportsOpacity; + + /// + /// Gets whether the backdrop description (for styles without options) should be visible. + /// + public bool IsMicaBackdropDescriptionVisible => + !BackdropStyles.Get(_settings.BackdropStyle).SupportsOpacity; + + /// + /// Gets whether background/colorization settings are available. + /// + public bool IsBackgroundSettingsEnabled => + BackdropStyles.Get(_settings.BackdropStyle).SupportsColorization; + + /// + /// Gets whether the "not available" message should be shown (inverse of IsBackgroundSettingsEnabled). + /// + public bool IsBackgroundNotAvailableVisible => + !BackdropStyles.Get(_settings.BackdropStyle).SupportsColorization; + + public BackdropStyle? EffectiveBackdropStyle + { + get + { + // Return style when transparency/blur is visible (not fully opaque Acrylic) + // - Clear/Mica/MicaAlt/AcrylicThin always show their effect + // - Acrylic shows effect only when opacity < 100 + if (_settings.BackdropStyle != BackdropStyle.Acrylic || _settings.BackdropOpacity < 100) + { + return _settings.BackdropStyle; + } + + return null; + } + } + + public double EffectiveImageOpacity => + EffectiveBackdropStyle is not null + ? (BackgroundImageOpacity / 100f) * Math.Sqrt(_settings.BackdropOpacity / 100.0) + : (BackgroundImageOpacity / 100f); + [ObservableProperty] public partial bool IsColorizationDetailsExpanded { get; set; } public bool IsCustomTintVisible => _settings.ColorizationMode is ColorizationMode.CustomColor or ColorizationMode.Image; - public bool IsCustomTintIntensityVisible => _settings.ColorizationMode is ColorizationMode.CustomColor or ColorizationMode.WindowsAccentColor or ColorizationMode.Image; + public bool IsColorIntensityVisible => _settings.ColorizationMode is ColorizationMode.CustomColor or ColorizationMode.WindowsAccentColor; + + public bool IsImageTintIntensityVisible => _settings.ColorizationMode is ColorizationMode.Image; + + /// + /// Gets the effective tint intensity for the preview, based on the current colorization mode. + /// + public int EffectiveTintIntensity => _settings.ColorizationMode is ColorizationMode.Image + ? _settings.BackgroundImageTintIntensity + : _settings.CustomThemeColorIntensity; public bool IsBackgroundControlsVisible => _settings.ColorizationMode is ColorizationMode.Image; @@ -292,16 +406,21 @@ public sealed partial class AppearanceSettingsViewModel : ObservableObject, IDis public bool IsAccentColorControlsVisible => _settings.ColorizationMode is ColorizationMode.WindowsAccentColor; - public AcrylicBackdropParameters EffectiveBackdrop { get; private set; } = new(Colors.Black, Colors.Black, 0.5f, 0.5f); + public bool IsResetButtonVisible => _settings.ColorizationMode is ColorizationMode.Image; + + public BackdropParameters EffectiveBackdrop { get; private set; } = new(Colors.Black, Colors.Black, 0.5f, 0.5f); public ElementTheme EffectiveTheme => _elementThemeOverride ?? _themeService.Current.Theme; - public Color EffectiveThemeColor => ColorizationMode switch - { - ColorizationMode.WindowsAccentColor => _currentSystemAccentColor, - ColorizationMode.CustomColor or ColorizationMode.Image => ThemeColor, - _ => Colors.Transparent, - }; + public Color EffectiveThemeColor => + !BackdropStyles.Get(_settings.BackdropStyle).SupportsColorization + ? Colors.Transparent + : ColorizationMode switch + { + ColorizationMode.WindowsAccentColor => _currentSystemAccentColor, + ColorizationMode.CustomColor or ColorizationMode.Image => ThemeColor, + _ => Colors.Transparent, + }; // Since the blur amount is absolute, we need to scale it down for the preview (which is smaller than full screen). public int EffectiveBackgroundImageBlurAmount => (int)Math.Round(BackgroundImageBlurAmount / 4f); @@ -309,11 +428,13 @@ public sealed partial class AppearanceSettingsViewModel : ObservableObject, IDis public double EffectiveBackgroundImageBrightness => BackgroundImageBrightness / 100.0; public ImageSource? EffectiveBackgroundImageSource => - ColorizationMode is ColorizationMode.Image - && !string.IsNullOrWhiteSpace(BackgroundImagePath) - && Uri.TryCreate(BackgroundImagePath, UriKind.RelativeOrAbsolute, out var uri) - ? new Microsoft.UI.Xaml.Media.Imaging.BitmapImage(uri) - : null; + !BackdropStyles.Get(_settings.BackdropStyle).SupportsBackgroundImage + ? null + : ColorizationMode is ColorizationMode.Image + && !string.IsNullOrWhiteSpace(BackgroundImagePath) + && Uri.TryCreate(BackgroundImagePath, UriKind.RelativeOrAbsolute, out var uri) + ? new Microsoft.UI.Xaml.Media.Imaging.BitmapImage(uri) + : null; public AppearanceSettingsViewModel(IThemeService themeService, SettingsModel settings) { @@ -327,7 +448,7 @@ public sealed partial class AppearanceSettingsViewModel : ObservableObject, IDis Reapply(); - IsColorizationDetailsExpanded = _settings.ColorizationMode != ColorizationMode.None; + IsColorizationDetailsExpanded = _settings.ColorizationMode != ColorizationMode.None && IsBackgroundSettingsEnabled; } private void UiSettingsOnColorValuesChanged(UISettings sender, object args) => _uiDispatcher.TryEnqueue(() => UpdateAccentColor(sender)); @@ -357,6 +478,8 @@ public sealed partial class AppearanceSettingsViewModel : ObservableObject, IDis // Theme services recalculates effective color and opacity based on current settings. EffectiveBackdrop = _themeService.Current.BackdropParameters; OnPropertyChanged(nameof(EffectiveBackdrop)); + OnPropertyChanged(nameof(EffectiveBackdropStyle)); + OnPropertyChanged(nameof(EffectiveImageOpacity)); OnPropertyChanged(nameof(EffectiveBackgroundImageBrightness)); OnPropertyChanged(nameof(EffectiveBackgroundImageSource)); OnPropertyChanged(nameof(EffectiveThemeColor)); @@ -379,7 +502,28 @@ public sealed partial class AppearanceSettingsViewModel : ObservableObject, IDis BackgroundImageBlurAmount = 0; BackgroundImageFit = BackgroundImageFit.UniformToFill; BackgroundImageOpacity = 100; - ColorIntensity = 0; + BackgroundImageTintIntensity = 0; + } + + [RelayCommand] + private void ResetAppearanceSettings() + { + // Reset theme + Theme = UserTheme.Default; + + // Reset backdrop settings + BackdropStyleIndex = (int)BackdropStyle.Acrylic; + BackdropOpacity = 100; + + // Reset background image settings + BackgroundImagePath = string.Empty; + ResetBackgroundImageProperties(); + + // Reset colorization + ColorizationMode = ColorizationMode.None; + ThemeColor = DefaultTintColor; + ColorIntensity = 100; + BackgroundImageTintIntensity = 0; } public void Dispose() diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/BackdropControllerKind.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/BackdropControllerKind.cs new file mode 100644 index 0000000000..9d24d5d435 --- /dev/null +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/BackdropControllerKind.cs @@ -0,0 +1,41 @@ +// 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; + +/// +/// Specifies the type of system backdrop controller to use. +/// +public enum BackdropControllerKind +{ + /// + /// Solid color with alpha transparency (TransparentTintBackdrop). + /// + Solid, + + /// + /// Desktop Acrylic with default blur (DesktopAcrylicKind.Default). + /// + Acrylic, + + /// + /// Desktop Acrylic with thinner blur (DesktopAcrylicKind.Thin). + /// + AcrylicThin, + + /// + /// Mica effect (MicaKind.Base). + /// + Mica, + + /// + /// Mica alternate/darker variant (MicaKind.BaseAlt). + /// + MicaAlt, + + /// + /// Custom backdrop implementation. + /// + Custom, +} diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/BackdropStyle.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/BackdropStyle.cs new file mode 100644 index 0000000000..72d2835e48 --- /dev/null +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/BackdropStyle.cs @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.CmdPal.UI.ViewModels; + +/// +/// Specifies the visual backdrop style for the window. +/// +public enum BackdropStyle +{ + /// + /// Standard desktop acrylic with blur effect. + /// + Acrylic, + + /// + /// Solid color with alpha transparency (no blur). + /// + Clear, + + /// + /// Mica effect that samples the desktop wallpaper. + /// + Mica, + + /// + /// Thinner acrylic variant with more transparency. + /// + AcrylicThin, + + /// + /// Mica alternate variant (darker). + /// + MicaAlt, +} diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/BackdropStyleConfig.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/BackdropStyleConfig.cs new file mode 100644 index 0000000000..c9fa50a23d --- /dev/null +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/BackdropStyleConfig.cs @@ -0,0 +1,77 @@ +// 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; + +/// +/// Configuration parameters for a backdrop style. +/// +public sealed record BackdropStyleConfig +{ + /// + /// Gets the type of system backdrop controller to use. + /// + public required BackdropControllerKind ControllerKind { get; init; } + + /// + /// Gets the base tint opacity before user adjustments. + /// + public required float BaseTintOpacity { get; init; } + + /// + /// Gets the base luminosity opacity before user adjustments. + /// + public required float BaseLuminosityOpacity { get; init; } + + /// + /// Gets the brush type to use for preview approximation. + /// + public required PreviewBrushKind PreviewBrush { get; init; } + + /// + /// Gets the fixed opacity for styles that don't support user adjustment (e.g., Mica). + /// When is false, this value is used as the effective opacity. + /// + public float FixedOpacity { get; init; } + + /// + /// Gets whether this backdrop style supports custom colorization (tint colors). + /// + public bool SupportsColorization { get; init; } = true; + + /// + /// Gets whether this backdrop style supports custom background images. + /// + public bool SupportsBackgroundImage { get; init; } = true; + + /// + /// Gets whether this backdrop style supports opacity adjustment. + /// + public bool SupportsOpacity { get; init; } = true; + + /// + /// Computes the effective tint opacity based on this style's configuration. + /// + /// User's backdrop opacity setting (0-1 normalized). + /// Optional override for base tint opacity (used by colorful theme). + /// The effective opacity to apply. + public float ComputeEffectiveOpacity(float userOpacity, float? baseTintOpacityOverride = null) + { + // For styles that don't support opacity (Mica), use FixedOpacity + if (!SupportsOpacity && FixedOpacity > 0) + { + return FixedOpacity; + } + + // For Solid: only user opacity matters (controls alpha of solid color) + if (ControllerKind == BackdropControllerKind.Solid) + { + return userOpacity; + } + + // For blur effects: multiply base opacity with user opacity + var baseTint = baseTintOpacityOverride ?? BaseTintOpacity; + return baseTint * userOpacity; + } +} diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/BackdropStyles.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/BackdropStyles.cs new file mode 100644 index 0000000000..6ba46c156e --- /dev/null +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/BackdropStyles.cs @@ -0,0 +1,65 @@ +// 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; + +/// +/// Central registry of backdrop style configurations. +/// +public static class BackdropStyles +{ + private static readonly Dictionary Configs = new() + { + [BackdropStyle.Acrylic] = new() + { + ControllerKind = BackdropControllerKind.Acrylic, + BaseTintOpacity = 0.5f, + BaseLuminosityOpacity = 0.9f, + PreviewBrush = PreviewBrushKind.Acrylic, + }, + [BackdropStyle.AcrylicThin] = new() + { + ControllerKind = BackdropControllerKind.AcrylicThin, + BaseTintOpacity = 0.0f, + BaseLuminosityOpacity = 0.85f, + PreviewBrush = PreviewBrushKind.Acrylic, + }, + [BackdropStyle.Mica] = new() + { + ControllerKind = BackdropControllerKind.Mica, + BaseTintOpacity = 0.0f, + BaseLuminosityOpacity = 1.0f, + PreviewBrush = PreviewBrushKind.Solid, + FixedOpacity = 0.96f, + SupportsOpacity = false, + }, + [BackdropStyle.MicaAlt] = new() + { + ControllerKind = BackdropControllerKind.MicaAlt, + BaseTintOpacity = 0.0f, + BaseLuminosityOpacity = 1.0f, + PreviewBrush = PreviewBrushKind.Solid, + FixedOpacity = 0.98f, + SupportsOpacity = false, + }, + [BackdropStyle.Clear] = new() + { + ControllerKind = BackdropControllerKind.Solid, + BaseTintOpacity = 1.0f, + BaseLuminosityOpacity = 1.0f, + PreviewBrush = PreviewBrushKind.Solid, + }, + }; + + /// + /// Gets the configuration for the specified backdrop style. + /// + public static BackdropStyleConfig Get(BackdropStyle style) => + Configs.TryGetValue(style, out var config) ? config : Configs[BackdropStyle.Acrylic]; + + /// + /// Gets all registered backdrop styles. + /// + public static IEnumerable All => Configs.Keys; +} diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/MainWindowViewModel.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/MainWindowViewModel.cs index 140811c784..4d775083f0 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/MainWindowViewModel.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/MainWindowViewModel.cs @@ -22,6 +22,7 @@ public partial class MainWindowViewModel : ObservableObject, IDisposable public partial Stretch BackgroundImageStretch { get; private set; } = Stretch.Fill; [ObservableProperty] + [NotifyPropertyChangedFor(nameof(EffectiveImageOpacity))] public partial double BackgroundImageOpacity { get; private set; } [ObservableProperty] @@ -39,6 +40,30 @@ public partial class MainWindowViewModel : ObservableObject, IDisposable [ObservableProperty] public partial bool ShowBackgroundImage { get; private set; } + [ObservableProperty] + [NotifyPropertyChangedFor(nameof(EffectiveBackdropStyle))] + [NotifyPropertyChangedFor(nameof(EffectiveImageOpacity))] + public partial BackdropStyle BackdropStyle { get; private set; } + + [ObservableProperty] + [NotifyPropertyChangedFor(nameof(EffectiveBackdropStyle))] + [NotifyPropertyChangedFor(nameof(EffectiveImageOpacity))] + public partial float BackdropOpacity { get; private set; } = 1.0f; + + // Returns null when no transparency needed (BlurImageControl uses this to decide source type) + public BackdropStyle? EffectiveBackdropStyle => + BackdropStyle == BackdropStyle.Clear || + BackdropStyle == BackdropStyle.Mica || + BackdropOpacity < 1.0f + ? BackdropStyle + : null; + + // When transparency is enabled, use square root curve so image stays visible longer as backdrop fades + public double EffectiveImageOpacity => + EffectiveBackdropStyle is not null + ? BackgroundImageOpacity * Math.Sqrt(BackdropOpacity) + : BackgroundImageOpacity; + public MainWindowViewModel(IThemeService themeService) { _themeService = themeService; @@ -58,6 +83,9 @@ public partial class MainWindowViewModel : ObservableObject, IDisposable BackgroundImageTintIntensity = _themeService.Current.TintIntensity; BackgroundImageBlurAmount = _themeService.Current.BlurAmount; + BackdropStyle = _themeService.Current.BackdropParameters.Style; + BackdropOpacity = _themeService.Current.BackdropOpacity; + ShowBackgroundImage = BackgroundImageSource != null; }); } diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/PreviewBrushKind.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/PreviewBrushKind.cs new file mode 100644 index 0000000000..2e8a644a28 --- /dev/null +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/PreviewBrushKind.cs @@ -0,0 +1,21 @@ +// 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; + +/// +/// Specifies the brush type to use for backdrop preview approximation. +/// +public enum PreviewBrushKind +{ + /// + /// SolidColorBrush with computed alpha. + /// + Solid, + + /// + /// AcrylicBrush with blur effect. + /// + Acrylic, +} diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Services/AcrylicBackdropParameters.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Services/AcrylicBackdropParameters.cs deleted file mode 100644 index efb7ca1fa1..0000000000 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Services/AcrylicBackdropParameters.cs +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) Microsoft Corporation -// The Microsoft Corporation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Windows.UI; - -namespace Microsoft.CmdPal.UI.ViewModels.Services; - -public sealed record AcrylicBackdropParameters(Color TintColor, Color FallbackColor, float TintOpacity, float LuminosityOpacity); diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Services/BackdropParameters.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Services/BackdropParameters.cs new file mode 100644 index 0000000000..dde4df0e0e --- /dev/null +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Services/BackdropParameters.cs @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Windows.UI; + +namespace Microsoft.CmdPal.UI.ViewModels.Services; + +/// +/// Parameters for configuring the window backdrop appearance. +/// +/// The tint color applied to the backdrop. +/// The fallback color when backdrop effects are unavailable. +/// +/// The effective opacity for the backdrop, pre-computed by the theme provider. +/// For Acrylic style: TintOpacity * BackdropOpacity. +/// For Clear style: BackdropOpacity (controls the solid color alpha). +/// +/// +/// The effective luminosity opacity for Acrylic backdrop, pre-computed by the theme provider. +/// Computed as LuminosityOpacity * BackdropOpacity. +/// +/// The backdrop style (Acrylic or Clear). +public sealed record BackdropParameters( + Color TintColor, + Color FallbackColor, + float EffectiveOpacity, + float EffectiveLuminosityOpacity, + BackdropStyle Style = BackdropStyle.Acrylic); diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Services/ThemeSnapshot.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Services/ThemeSnapshot.cs index 244fd41fba..a82484d52f 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Services/ThemeSnapshot.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Services/ThemeSnapshot.cs @@ -51,12 +51,23 @@ public sealed class ThemeSnapshot public required double BackgroundImageOpacity { get; init; } /// - /// Gets the effective acrylic backdrop parameters based on current settings and theme. + /// Gets the effective backdrop parameters based on current settings and theme. /// - /// The resolved AcrylicBackdropParameters to apply. - public required AcrylicBackdropParameters BackdropParameters { get; init; } + /// The resolved BackdropParameters to apply. + public required BackdropParameters BackdropParameters { get; init; } + + /// + /// Gets the raw backdrop opacity setting (0-1 range). + /// Used for determining if transparency is enabled and for image opacity calculations. + /// + public required float BackdropOpacity { get; init; } public required int BlurAmount { get; init; } public required float BackgroundBrightness { get; init; } + + /// + /// Gets whether colorization is active (accent color, custom color, or image mode). + /// + public required bool HasColorization { get; init; } } diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/SettingsModel.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/SettingsModel.cs index 483fe3fdc3..c023c3daae 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/SettingsModel.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/SettingsModel.cs @@ -74,6 +74,8 @@ public partial class SettingsModel : ObservableObject public int CustomThemeColorIntensity { get; set; } = 100; + public int BackgroundImageTintIntensity { get; set; } + public int BackgroundImageOpacity { get; set; } = 20; public int BackgroundImageBlurAmount { get; set; } @@ -84,6 +86,10 @@ public partial class SettingsModel : ObservableObject public string? BackgroundImagePath { get; set; } + public BackdropStyle BackdropStyle { get; set; } + + public int BackdropOpacity { get; set; } = 100; + // END SETTINGS /////////////////////////////////////////////////////////////////////////// diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/BlurImageControl.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/BlurImageControl.cs index d77cab0645..3d52042751 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/BlurImageControl.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/BlurImageControl.cs @@ -288,7 +288,6 @@ internal sealed partial class BlurImageControl : Control _effectBrush?.Dispose(); _effectBrush = effectFactory.CreateBrush(); - // Set initial source if (ImageSource is not null) { _imageBrush ??= _compositor.CreateSurfaceBrush(); diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/CommandPalettePreview.xaml b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/CommandPalettePreview.xaml index a30d1fafdf..33fbacb839 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/CommandPalettePreview.xaml +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/CommandPalettePreview.xaml @@ -16,24 +16,38 @@ CornerRadius="8" Translation="0,0,8"> + + Visibility="{x:Bind ClearVisibility, Mode=OneWay}"> + + + + + + + TintOpacity="{x:Bind PreviewEffectiveOpacity, Mode=OneWay}" /> + (double)GetValue(PreviewBackgroundImageOpacityProperty); + set => SetValue(PreviewBackgroundImageOpacityProperty, value); } public double PreviewBackgroundImageBrightness @@ -92,12 +95,48 @@ public sealed partial class CommandPalettePreview : UserControl set => SetValue(ShowBackgroundImageProperty, value); } + public BackdropStyle? PreviewBackdropStyle + { + get => (BackdropStyle?)GetValue(PreviewBackdropStyleProperty); + set => SetValue(PreviewBackdropStyleProperty, value); + } + + /// + /// Gets or sets the effective opacity for the backdrop, pre-computed by the theme provider. + /// For Acrylic style: used directly as TintOpacity. + /// For Clear style: used to compute the alpha channel of the solid color. + /// + public double PreviewEffectiveOpacity + { + get => (double)GetValue(PreviewEffectiveOpacityProperty); + set => SetValue(PreviewEffectiveOpacityProperty, value); + } + + // Computed read-only properties + public Color EffectiveClearColor + { + get => (Color)GetValue(EffectiveClearColorProperty); + private set => SetValue(EffectiveClearColorProperty, value); + } + + public Visibility AcrylicVisibility + { + get => (Visibility)GetValue(AcrylicVisibilityProperty); + private set => SetValue(AcrylicVisibilityProperty, value); + } + + public Visibility ClearVisibility + { + get => (Visibility)GetValue(ClearVisibilityProperty); + private set => SetValue(ClearVisibilityProperty, value); + } + public CommandPalettePreview() { InitializeComponent(); } - private static void PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) + private static void OnBackgroundImageSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is not CommandPalettePreview preview) { @@ -107,7 +146,46 @@ public sealed partial class CommandPalettePreview : UserControl preview.ShowBackgroundImage = e.NewValue is ImageSource ? Visibility.Visible : Visibility.Collapsed; } - private double ToOpacity(int value) => value / 100.0; + private static void OnBackdropPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (d is not CommandPalettePreview preview) + { + return; + } + + preview.UpdateComputedClearColor(); + } + + private static void OnVisibilityPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (d is not CommandPalettePreview preview) + { + return; + } + + preview.UpdateComputedVisibilityProperties(); + preview.UpdateComputedClearColor(); + } + + private void UpdateComputedClearColor() + { + EffectiveClearColor = Color.FromArgb( + (byte)(PreviewEffectiveOpacity * 255), + PreviewBackgroundColor.R, + PreviewBackgroundColor.G, + PreviewBackgroundColor.B); + } + + private void UpdateComputedVisibilityProperties() + { + var config = BackdropStyles.Get(PreviewBackdropStyle ?? BackdropStyle.Acrylic); + + // Show backdrop effect based on style (on top of any background image) + AcrylicVisibility = config.PreviewBrush == PreviewBrushKind.Acrylic + ? Visibility.Visible : Visibility.Collapsed; + ClearVisibility = config.PreviewBrush == PreviewBrushKind.Solid + ? Visibility.Visible : Visibility.Collapsed; + } private double ToTintIntensity(int value) => value / 100.0; diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/MainWindow.xaml b/src/modules/cmdpal/Microsoft.CmdPal.UI/MainWindow.xaml index 32329e17a0..74c736b471 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/MainWindow.xaml +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/MainWindow.xaml @@ -22,7 +22,7 @@ VerticalAlignment="Stretch" BlurAmount="{x:Bind ViewModel.BackgroundImageBlurAmount, Mode=OneWay}" ImageBrightness="{x:Bind ViewModel.BackgroundImageBrightness, Mode=OneWay}" - ImageOpacity="{x:Bind ViewModel.BackgroundImageOpacity, Mode=OneWay}" + ImageOpacity="{x:Bind ViewModel.EffectiveImageOpacity, Mode=OneWay}" ImageSource="{x:Bind ViewModel.BackgroundImageSource, Mode=OneWay}" ImageStretch="{x:Bind ViewModel.BackgroundImageStretch, Mode=OneWay}" IsHitTestVisible="False" diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/MainWindow.xaml.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI/MainWindow.xaml.cs index d54fbe93d2..10139a94d1 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/MainWindow.xaml.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/MainWindow.xaml.cs @@ -31,6 +31,7 @@ using Windows.ApplicationModel.Activation; using Windows.Foundation; using Windows.Graphics; using Windows.System; +using Windows.UI; using Windows.Win32; using Windows.Win32.Foundation; using Windows.Win32.Graphics.Dwm; @@ -80,7 +81,9 @@ public sealed partial class MainWindow : WindowEx, private int _sessionErrorCount; private DesktopAcrylicController? _acrylicController; + private MicaController? _micaController; private SystemBackdropConfiguration? _configurationSource; + private bool _isUpdatingBackdrop; private TimeSpan _autoGoHomeInterval = Timeout.InfiniteTimeSpan; private WindowPosition _currentWindowPosition = new(); @@ -109,7 +112,7 @@ public sealed partial class MainWindow : WindowEx, CommandPaletteHost.SetHostHwnd((ulong)_hwnd.Value); } - SetAcrylic(); + InitializeBackdropSupport(); _hiddenOwnerBehavior.ShowInTaskbar(this, Debugger.IsAttached); @@ -158,7 +161,7 @@ public sealed partial class MainWindow : WindowEx, App.Current.Services.GetService()!.SettingsChanged += SettingsChangedHandler; // Make sure that we update the acrylic theme when the OS theme changes - RootElement.ActualThemeChanged += (s, e) => DispatcherQueue.TryEnqueue(UpdateAcrylic); + RootElement.ActualThemeChanged += (s, e) => DispatcherQueue.TryEnqueue(UpdateBackdrop); // Hardcoding event name to avoid bringing in the PowerToys.interop dependency. Event name must match CMDPAL_SHOW_EVENT from shared_constants.h NativeEventWaiter.WaitForEventLoop("Local\\PowerToysCmdPal-ShowEvent-62336fcd-8611-4023-9b30-091a6af4cc5a", () => @@ -185,7 +188,7 @@ public sealed partial class MainWindow : WindowEx, private void ThemeServiceOnThemeChanged(object? sender, ThemeChangedEventArgs e) { - UpdateAcrylic(); + UpdateBackdrop(); } private static void LocalKeyboardListener_OnKeyPressed(object? sender, LocalKeyboardListenerKeyPressedEventArgs e) @@ -280,48 +283,170 @@ public sealed partial class MainWindow : WindowEx, _autoGoHomeTimer.Interval = _autoGoHomeInterval; } - private void SetAcrylic() + private void InitializeBackdropSupport() { - if (DesktopAcrylicController.IsSupported()) + if (DesktopAcrylicController.IsSupported() || MicaController.IsSupported()) { - // Hooking up the policy object. _configurationSource = new SystemBackdropConfiguration { - // Initial configuration state. IsInputActive = true, }; - UpdateAcrylic(); } } - private void UpdateAcrylic() + private void UpdateBackdrop() { + // Prevent re-entrance when backdrop changes trigger ActualThemeChanged + if (_isUpdatingBackdrop) + { + return; + } + + _isUpdatingBackdrop = true; + + var backdrop = _themeService.Current.BackdropParameters; + var isImageMode = ViewModel.ShowBackgroundImage; + var config = BackdropStyles.Get(backdrop.Style); + try { - if (_acrylicController != null) + switch (config.ControllerKind) { - _acrylicController.RemoveAllSystemBackdropTargets(); - _acrylicController.Dispose(); + case BackdropControllerKind.Solid: + CleanupBackdropControllers(); + var tintColor = Color.FromArgb( + (byte)(backdrop.EffectiveOpacity * 255), + backdrop.TintColor.R, + backdrop.TintColor.G, + backdrop.TintColor.B); + SetupTransparentBackdrop(tintColor); + break; + + case BackdropControllerKind.Mica: + case BackdropControllerKind.MicaAlt: + SetupMica(backdrop, isImageMode, config.ControllerKind); + break; + + case BackdropControllerKind.Acrylic: + case BackdropControllerKind.AcrylicThin: + default: + SetupDesktopAcrylic(backdrop, isImageMode, config.ControllerKind); + break; } - - var backdrop = _themeService.Current.BackdropParameters; - _acrylicController = new DesktopAcrylicController - { - TintColor = backdrop.TintColor, - TintOpacity = backdrop.TintOpacity, - FallbackColor = backdrop.FallbackColor, - LuminosityOpacity = backdrop.LuminosityOpacity, - }; - - // Enable the system backdrop. - // Note: Be sure to have "using WinRT;" to support the Window.As<...>() call. - _acrylicController.AddSystemBackdropTarget(this.As()); - _acrylicController.SetSystemBackdropConfiguration(_configurationSource); } catch (Exception ex) { Logger.LogError("Failed to update backdrop", ex); } + finally + { + _isUpdatingBackdrop = false; + } + } + + private void SetupTransparentBackdrop(Color tintColor) + { + if (SystemBackdrop is TransparentTintBackdrop existingBackdrop) + { + existingBackdrop.TintColor = tintColor; + } + else + { + SystemBackdrop = new TransparentTintBackdrop { TintColor = tintColor }; + } + } + + private void CleanupBackdropControllers() + { + if (_acrylicController is not null) + { + _acrylicController.RemoveAllSystemBackdropTargets(); + _acrylicController.Dispose(); + _acrylicController = null; + } + + if (_micaController is not null) + { + _micaController.RemoveAllSystemBackdropTargets(); + _micaController.Dispose(); + _micaController = null; + } + } + + private void SetupDesktopAcrylic(BackdropParameters backdrop, bool isImageMode, BackdropControllerKind kind) + { + CleanupBackdropControllers(); + + // Fall back to solid color if acrylic not supported + if (_configurationSource is null || !DesktopAcrylicController.IsSupported()) + { + SetupTransparentBackdrop(backdrop.FallbackColor); + return; + } + + // DesktopAcrylicController and SystemBackdrop can't be active simultaneously + SystemBackdrop = null; + + // Image mode: no tint here, BlurImageControl handles it (avoids double-tinting) + var effectiveTintOpacity = isImageMode + ? 0.0f + : backdrop.EffectiveOpacity; + + _acrylicController = new DesktopAcrylicController + { + Kind = kind == BackdropControllerKind.AcrylicThin + ? DesktopAcrylicKind.Thin + : DesktopAcrylicKind.Default, + TintColor = backdrop.TintColor, + TintOpacity = effectiveTintOpacity, + FallbackColor = backdrop.FallbackColor, + LuminosityOpacity = backdrop.EffectiveLuminosityOpacity, + }; + + // Requires "using WinRT;" for Window.As<>() + _acrylicController.AddSystemBackdropTarget(this.As()); + _acrylicController.SetSystemBackdropConfiguration(_configurationSource); + } + + private void SetupMica(BackdropParameters backdrop, bool isImageMode, BackdropControllerKind kind) + { + CleanupBackdropControllers(); + + // Fall back to solid color if Mica not supported + if (_configurationSource is null || !MicaController.IsSupported()) + { + SetupTransparentBackdrop(backdrop.FallbackColor); + return; + } + + // MicaController and SystemBackdrop can't be active simultaneously + SystemBackdrop = null; + _configurationSource.Theme = _themeService.Current.Theme == ElementTheme.Dark + ? SystemBackdropTheme.Dark + : SystemBackdropTheme.Light; + + var hasColorization = _themeService.Current.HasColorization || isImageMode; + + _micaController = new MicaController + { + Kind = kind == BackdropControllerKind.MicaAlt + ? MicaKind.BaseAlt + : MicaKind.Base, + }; + + // Only set tint properties when colorization is active + // Otherwise let system handle light/dark theme defaults automatically + if (hasColorization) + { + // Image mode: no tint here, BlurImageControl handles it (avoids double-tinting) + _micaController.TintColor = backdrop.TintColor; + _micaController.TintOpacity = isImageMode ? 0.0f : backdrop.EffectiveOpacity; + _micaController.FallbackColor = backdrop.FallbackColor; + _micaController.LuminosityOpacity = backdrop.EffectiveLuminosityOpacity; + } + + _micaController.AddSystemBackdropTarget(this.As()); + _micaController.SetSystemBackdropConfiguration(_configurationSource); } private void ShowHwnd(IntPtr hwndValue, MonitorBehavior target) @@ -637,12 +762,8 @@ public sealed partial class MainWindow : WindowEx, private void DisposeAcrylic() { - if (_acrylicController is not null) - { - _acrylicController.Dispose(); - _acrylicController = null!; - _configurationSource = null!; - } + CleanupBackdropControllers(); + _configurationSource = null!; } // Updates our window s.t. the top of the window is draggable. diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/Services/ColorfulThemeProvider.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI/Services/ColorfulThemeProvider.cs index fe6c8e48e0..8e2a5748bd 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/Services/ColorfulThemeProvider.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/Services/ColorfulThemeProvider.cs @@ -4,6 +4,7 @@ using CommunityToolkit.WinUI.Helpers; using Microsoft.CmdPal.UI.Helpers; +using Microsoft.CmdPal.UI.ViewModels; using Microsoft.CmdPal.UI.ViewModels.Services; using Microsoft.UI.Xaml; using Windows.UI; @@ -34,7 +35,7 @@ internal sealed class ColorfulThemeProvider : IThemeProvider _uiSettings = uiSettings; } - public AcrylicBackdropParameters GetAcrylicBackdrop(ThemeContext context) + public BackdropParameters GetBackdropParameters(ThemeContext context) { var isLight = context.Theme == ElementTheme.Light || (context.Theme == ElementTheme.Default && @@ -53,7 +54,26 @@ internal sealed class ColorfulThemeProvider : IThemeProvider var colorIntensity = isLight ? 0.6f * colorIntensityUser : colorIntensityUser; var effectiveBgColor = ColorBlender.Blend(baseColor, blended, colorIntensity); - return new AcrylicBackdropParameters(effectiveBgColor, effectiveBgColor, 0.8f, 0.8f); + var transparencyMode = context.BackdropStyle ?? BackdropStyle.Acrylic; + var config = BackdropStyles.Get(transparencyMode); + + // For colorful theme, boost tint opacity to show color better through blur + // But not for styles with fixed opacity (Mica) - they handle their own opacity + var baseTintOpacity = config.ControllerKind == BackdropControllerKind.Solid || !config.SupportsOpacity + ? (float?)null // Use default + : Math.Max(config.BaseTintOpacity, 0.8f); + + var effectiveOpacity = config.ComputeEffectiveOpacity(context.BackdropOpacity, baseTintOpacity); + var effectiveLuminosityOpacity = config.SupportsOpacity + ? config.BaseLuminosityOpacity * context.BackdropOpacity + : config.BaseLuminosityOpacity; + + return new BackdropParameters( + TintColor: effectiveBgColor, + FallbackColor: effectiveBgColor, + EffectiveOpacity: effectiveOpacity, + EffectiveLuminosityOpacity: effectiveLuminosityOpacity, + Style: transparencyMode); } private static class ColorBlender diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/Services/IThemeProvider.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI/Services/IThemeProvider.cs index a9411c3656..af7e869e20 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/Services/IThemeProvider.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/Services/IThemeProvider.cs @@ -8,14 +8,14 @@ using Microsoft.CmdPal.UI.ViewModels.Services; namespace Microsoft.CmdPal.UI.Services; /// -/// Provides theme identification, resource path resolution, and creation of acrylic -/// backdrop parameters based on the current . +/// Provides theme identification, resource path resolution, and creation of backdrop +/// parameters based on the current . /// /// /// Implementations should expose a stable and a valid XAML resource /// dictionary path via . The -/// method computes -/// using the supplied theme context. +/// method computes +/// using the supplied theme context. /// internal interface IThemeProvider { @@ -30,9 +30,9 @@ internal interface IThemeProvider string ResourcePath { get; } /// - /// Creates acrylic backdrop parameters based on the provided theme context. + /// Creates backdrop parameters based on the provided theme context. /// - /// The current theme context, including theme, tint, and optional background details. - /// The computed for the backdrop. - AcrylicBackdropParameters GetAcrylicBackdrop(ThemeContext context); + /// The current theme context, including theme, tint, transparency mode, and optional background details. + /// The computed for the backdrop. + BackdropParameters GetBackdropParameters(ThemeContext context); } diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/Services/NormalThemeProvider.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI/Services/NormalThemeProvider.cs index c393894346..cee8aa86b2 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/Services/NormalThemeProvider.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/Services/NormalThemeProvider.cs @@ -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 Microsoft.CmdPal.UI.ViewModels; using Microsoft.CmdPal.UI.ViewModels.Services; using Microsoft.UI.Xaml; using Windows.UI; @@ -28,16 +29,28 @@ internal sealed class NormalThemeProvider : IThemeProvider public string ResourcePath => "ms-appx:///Styles/Theme.Normal.xaml"; - public AcrylicBackdropParameters GetAcrylicBackdrop(ThemeContext context) + public BackdropParameters GetBackdropParameters(ThemeContext context) { var isLight = context.Theme == ElementTheme.Light || (context.Theme == ElementTheme.Default && _uiSettings.GetColorValue(UIColorType.Background).R > 128); - return new AcrylicBackdropParameters( + var backdropStyle = context.BackdropStyle ?? BackdropStyle.Acrylic; + var config = BackdropStyles.Get(backdropStyle); + + // Apply light/dark theme adjustment to luminosity + var baseLuminosityOpacity = isLight + ? config.BaseLuminosityOpacity + : Math.Min(config.BaseLuminosityOpacity + 0.06f, 1.0f); + + var effectiveOpacity = config.ComputeEffectiveOpacity(context.BackdropOpacity); + var effectiveLuminosityOpacity = baseLuminosityOpacity * context.BackdropOpacity; + + return new BackdropParameters( TintColor: isLight ? LightBaseColor : DarkBaseColor, FallbackColor: isLight ? LightBaseColor : DarkBaseColor, - TintOpacity: 0.5f, - LuminosityOpacity: isLight ? 0.9f : 0.96f); + EffectiveOpacity: effectiveOpacity, + EffectiveLuminosityOpacity: effectiveLuminosityOpacity, + Style: backdropStyle); } } diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/Services/ThemeContext.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI/Services/ThemeContext.cs index 67432c8748..9862e6aa35 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/Services/ThemeContext.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/Services/ThemeContext.cs @@ -2,12 +2,16 @@ // 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.UI.Xaml; using Microsoft.UI.Xaml.Media; using Windows.UI; namespace Microsoft.CmdPal.UI.Services; +/// +/// Input parameters for theme computation, passed to theme providers. +/// internal sealed record ThemeContext { public ElementTheme Theme { get; init; } @@ -21,4 +25,8 @@ internal sealed record ThemeContext public double BackgroundImageOpacity { get; init; } public int? ColorIntensity { get; init; } + + public BackdropStyle? BackdropStyle { get; init; } + + public float BackdropOpacity { get; init; } = 1.0f; } diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/Services/ThemeService.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI/Services/ThemeService.cs index 65fbfb24d7..eb344780f0 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/Services/ThemeService.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/Services/ThemeService.cs @@ -72,10 +72,13 @@ internal sealed partial class ThemeService : IThemeService, IDisposable } // provider selection - var intensity = Math.Clamp(_settings.CustomThemeColorIntensity, 0, 100); - IThemeProvider provider = intensity > 0 && _settings.ColorizationMode is ColorizationMode.CustomColor or ColorizationMode.WindowsAccentColor or ColorizationMode.Image - ? _colorfulThemeProvider - : _normalThemeProvider; + var themeColorIntensity = Math.Clamp(_settings.CustomThemeColorIntensity, 0, 100); + var imageTintIntensity = Math.Clamp(_settings.BackgroundImageTintIntensity, 0, 100); + var effectiveColorIntensity = _settings.ColorizationMode == ColorizationMode.Image + ? imageTintIntensity + : themeColorIntensity; + + IThemeProvider provider = UseColorfulProvider(effectiveColorIntensity) ? _colorfulThemeProvider : _normalThemeProvider; // Calculate values var tint = _settings.ColorizationMode switch @@ -96,32 +99,39 @@ internal sealed partial class ThemeService : IThemeService, IDisposable }; var opacity = Math.Clamp(_settings.BackgroundImageOpacity, 0, 100) / 100.0; - // create context and offload to actual theme provider + // create input and offload to actual theme provider var context = new ThemeContext { Tint = tint, - ColorIntensity = intensity, + ColorIntensity = effectiveColorIntensity, Theme = effectiveTheme, BackgroundImageSource = imageSource, BackgroundImageStretch = stretch, BackgroundImageOpacity = opacity, + BackdropStyle = _settings.BackdropStyle, + BackdropOpacity = Math.Clamp(_settings.BackdropOpacity, 0, 100) / 100f, }; - var backdrop = provider.GetAcrylicBackdrop(context); + var backdrop = provider.GetBackdropParameters(context); var blur = _settings.BackgroundImageBlurAmount; var brightness = _settings.BackgroundImageBrightness; // Create public snapshot (no provider!) + var hasColorization = effectiveColorIntensity > 0 + && _settings.ColorizationMode is ColorizationMode.CustomColor or ColorizationMode.WindowsAccentColor or ColorizationMode.Image; + var snapshot = new ThemeSnapshot { Tint = tint, - TintIntensity = intensity / 100f, + TintIntensity = effectiveColorIntensity / 100f, Theme = effectiveTheme, BackgroundImageSource = imageSource, BackgroundImageStretch = stretch, BackgroundImageOpacity = opacity, BackdropParameters = backdrop, + BackdropOpacity = context.BackdropOpacity, BlurAmount = blur, BackgroundBrightness = brightness / 100f, + HasColorization = hasColorization, }; // Bundle with provider for internal use @@ -138,6 +148,12 @@ internal sealed partial class ThemeService : IThemeService, IDisposable ThemeChanged?.Invoke(this, new ThemeChangedEventArgs()); } + private bool UseColorfulProvider(int effectiveColorIntensity) + { + return _settings.ColorizationMode == ColorizationMode.Image + || (effectiveColorIntensity > 0 && _settings.ColorizationMode is ColorizationMode.CustomColor or ColorizationMode.WindowsAccentColor); + } + private static BitmapImage? LoadImageSafe(string? path) { if (string.IsNullOrWhiteSpace(path)) @@ -195,13 +211,15 @@ internal sealed partial class ThemeService : IThemeService, IDisposable { Tint = Colors.Transparent, Theme = ElementTheme.Light, - BackdropParameters = new AcrylicBackdropParameters(Colors.Black, Colors.Black, 0.5f, 0.5f), + BackdropParameters = new BackdropParameters(Colors.Black, Colors.Black, EffectiveOpacity: 0.5f, EffectiveLuminosityOpacity: 0.5f), + BackdropOpacity = 1.0f, BackgroundImageOpacity = 1, BackgroundImageSource = null, BackgroundImageStretch = Stretch.Fill, BlurAmount = 0, TintIntensity = 1.0f, BackgroundBrightness = 0, + HasColorization = false, }, Provider = _normalThemeProvider, }; diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/Settings/AppearancePage.xaml b/src/modules/cmdpal/Microsoft.CmdPal.UI/Settings/AppearancePage.xaml index b9f31d8443..8a66b54d89 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/Settings/AppearancePage.xaml +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/Settings/AppearancePage.xaml @@ -22,18 +22,50 @@ HorizontalAlignment="Stretch" Spacing="{StaticResource SettingsCardSpacing}"> - - - + + + + + + + + + @@ -62,19 +94,67 @@ + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + - + + + + - - + + - + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/ShortcutControl/ShortcutControl.xaml.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/ShortcutControl/ShortcutControl.xaml.cs index e7fa721277..b8aad6c323 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/ShortcutControl/ShortcutControl.xaml.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/ShortcutControl/ShortcutControl.xaml.cs @@ -11,6 +11,7 @@ using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Automation; using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Input; +using Microsoft.Windows.ApplicationModel.Resources; using Windows.System; namespace Microsoft.CmdPal.UI.Controls; @@ -36,6 +37,8 @@ public sealed partial class ShortcutControl : UserControl, IDisposable, IRecipie public static readonly DependencyProperty AllowDisableProperty = DependencyProperty.Register("AllowDisable", typeof(bool), typeof(ShortcutControl), new PropertyMetadata(false, OnAllowDisableChanged)); + private static ResourceLoader resourceLoader = Microsoft.CmdPal.UI.Helpers.ResourceLoaderInstance.ResourceLoader; + private static void OnAllowDisableChanged(DependencyObject d, DependencyPropertyChangedEventArgs? e) { var me = d as ShortcutControl; @@ -96,8 +99,7 @@ public sealed partial class ShortcutControl : UserControl, IDisposable, IRecipie { hotkeySettings = value; SetValue(HotkeySettingsProperty, value); - PreviewKeysControl.ItemsSource = HotkeySettings?.GetKeysList() ?? new List(); - AutomationProperties.SetHelpText(EditButton, HotkeySettings?.ToString() ?? string.Empty); + SetKeys(); c.Keys = HotkeySettings?.GetKeysList() ?? new List(); } } @@ -108,8 +110,6 @@ public sealed partial class ShortcutControl : UserControl, IDisposable, IRecipie InitializeComponent(); internalSettings = new HotkeySettings(); - var resourceLoader = Microsoft.CmdPal.UI.Helpers.ResourceLoaderInstance.ResourceLoader; - // We create the Dialog in C# because doing it in XAML is giving WinUI/XAML Island bugs when using dark theme. shortcutDialog = new ContentDialog { @@ -421,11 +421,9 @@ public sealed partial class ShortcutControl : UserControl, IDisposable, IRecipie hotkeySettings = null; SetValue(HotkeySettingsProperty, hotkeySettings); - PreviewKeysControl.ItemsSource = HotkeySettings?.GetKeysList() ?? new List(); + SetKeys(); lastValidSettings = hotkeySettings; - - AutomationProperties.SetHelpText(EditButton, HotkeySettings?.ToString() ?? string.Empty); shortcutDialog.Hide(); } @@ -436,8 +434,7 @@ public sealed partial class ShortcutControl : UserControl, IDisposable, IRecipie HotkeySettings = lastValidSettings with { }; } - PreviewKeysControl.ItemsSource = hotkeySettings?.GetKeysList() ?? new List(); - AutomationProperties.SetHelpText(EditButton, HotkeySettings?.ToString() ?? string.Empty); + SetKeys(); shortcutDialog.Hide(); } @@ -450,9 +447,7 @@ public sealed partial class ShortcutControl : UserControl, IDisposable, IRecipie var empty = new HotkeySettings(); HotkeySettings = empty; - - PreviewKeysControl.ItemsSource = HotkeySettings.GetKeysList(); - AutomationProperties.SetHelpText(EditButton, HotkeySettings.ToString()); + SetKeys(); shortcutDialog.Hide(); } @@ -508,4 +503,23 @@ public sealed partial class ShortcutControl : UserControl, IDisposable, IRecipie Dispose(disposing: true); GC.SuppressFinalize(this); } + + private void SetKeys() + { + var keys = HotkeySettings?.GetKeysList(); + + if (keys != null && keys.Count > 0) + { + VisualStateManager.GoToState(this, "Configured", true); + PreviewKeysControl.ItemsSource = keys; +#pragma warning disable CS8602 // Dereference of a possibly null reference. + AutomationProperties.SetHelpText(EditButton, HotkeySettings.ToString()); +#pragma warning restore CS8602 // Dereference of a possibly null reference. + } + else + { + VisualStateManager.GoToState(this, "Normal", true); + AutomationProperties.SetHelpText(EditButton, resourceLoader.GetString("ConfigureShortcut")); + } + } } diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/ShortcutControl/ShortcutDialogContentControl.xaml b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/ShortcutControl/ShortcutDialogContentControl.xaml index 0000685ac3..d2a5b7203f 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/ShortcutControl/ShortcutDialogContentControl.xaml +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/ShortcutControl/ShortcutDialogContentControl.xaml @@ -2,12 +2,16 @@ x:Class="Microsoft.CmdPal.UI.Controls.ShortcutDialogContentControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" - xmlns:controls="using:Microsoft.CmdPal.UI.Controls" + xmlns:converters="using:Microsoft.PowerToys.Common.UI.Controls" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:ptcontrols="using:Microsoft.PowerToys.Common.UI.Controls" xmlns:tkcontrols="using:CommunityToolkit.WinUI.Controls" x:Name="ShortcutContentControl" mc:Ignorable="d"> + + + @@ -33,13 +37,16 @@ - + State="{Binding ElementName=ShortcutContentControl, Path=IsError, Mode=OneWay, Converter={StaticResource BoolToKeyVisualStateConverter}, ConverterParameter=Error}" + Style="{StaticResource AccentKeyVisualStyle}" /> diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/ShortcutControl/ShortcutWithTextLabelControl.xaml b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/ShortcutControl/ShortcutWithTextLabelControl.xaml deleted file mode 100644 index c6f2a9fe2a..0000000000 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/ShortcutControl/ShortcutWithTextLabelControl.xaml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/ShortcutControl/ShortcutWithTextLabelControl.xaml.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/ShortcutControl/ShortcutWithTextLabelControl.xaml.cs deleted file mode 100644 index 5605d5b195..0000000000 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/ShortcutControl/ShortcutWithTextLabelControl.xaml.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) Microsoft Corporation -// The Microsoft Corporation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Collections.Generic; - -using Microsoft.UI.Xaml; -using Microsoft.UI.Xaml.Controls; - -namespace Microsoft.CmdPal.UI.Controls -{ - public sealed partial class ShortcutWithTextLabelControl : UserControl - { - public string Text - { - get { return (string)GetValue(TextProperty); } - set { SetValue(TextProperty, value); } - } - - public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(ShortcutWithTextLabelControl), new PropertyMetadata(default(string))); - - public List Keys - { - get { return (List)GetValue(KeysProperty); } - set { SetValue(KeysProperty, value); } - } - - public static readonly DependencyProperty KeysProperty = DependencyProperty.Register("Keys", typeof(List), typeof(ShortcutWithTextLabelControl), new PropertyMetadata(default(string))); - - public ShortcutWithTextLabelControl() - { - this.InitializeComponent(); - } - } -} diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/Microsoft.CmdPal.UI.csproj b/src/modules/cmdpal/Microsoft.CmdPal.UI/Microsoft.CmdPal.UI.csproj index a80b174cec..292c5a4e3d 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/Microsoft.CmdPal.UI.csproj +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/Microsoft.CmdPal.UI.csproj @@ -72,10 +72,8 @@ - - @@ -128,6 +126,7 @@ + @@ -255,17 +254,6 @@ - - - MSBuild:Compile - - - - - - MSBuild:Compile - - MSBuild:Compile diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/Settings/ExtensionPage.xaml b/src/modules/cmdpal/Microsoft.CmdPal.UI/Settings/ExtensionPage.xaml index df60c83362..72cf1f2f94 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/Settings/ExtensionPage.xaml +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/Settings/ExtensionPage.xaml @@ -11,6 +11,7 @@ xmlns:helpers="using:Microsoft.CmdPal.UI.Helpers" xmlns:local="using:Microsoft.CmdPal.UI.Settings" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:ptcontrols="using:Microsoft.PowerToys.Common.UI.Controls" xmlns:ui="using:CommunityToolkit.WinUI" xmlns:viewModels="using:Microsoft.CmdPal.UI.ViewModels" mc:Ignorable="d"> @@ -174,7 +175,7 @@ - diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/Settings/GeneralPage.xaml b/src/modules/cmdpal/Microsoft.CmdPal.UI/Settings/GeneralPage.xaml index 53994b345f..bd80615556 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/Settings/GeneralPage.xaml +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/Settings/GeneralPage.xaml @@ -1,4 +1,4 @@ - + @@ -44,10 +45,10 @@ - + - + diff --git a/src/settings-ui/Settings.UI/PowerToys.Settings.csproj b/src/settings-ui/Settings.UI/PowerToys.Settings.csproj index c1f15281c7..f44fe8315f 100644 --- a/src/settings-ui/Settings.UI/PowerToys.Settings.csproj +++ b/src/settings-ui/Settings.UI/PowerToys.Settings.csproj @@ -31,7 +31,6 @@ - @@ -113,6 +112,7 @@ + @@ -174,15 +174,9 @@ Always - - MSBuild:Compile - MSBuild:Compile - - MSBuild:Compile - MSBuild:Compile diff --git a/src/settings-ui/Settings.UI/SettingsXAML/App.xaml b/src/settings-ui/Settings.UI/SettingsXAML/App.xaml index 57cc0fb1ec..d99fb6d7b3 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/App.xaml +++ b/src/settings-ui/Settings.UI/SettingsXAML/App.xaml @@ -1,17 +1,19 @@ - - - + + + @@ -19,7 +21,7 @@ - + @@ -74,7 +76,7 @@ - - - - - - - @@ -109,7 +110,7 @@ - + - + - - diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Views/MouseWithoutBordersPage.xaml b/src/settings-ui/Settings.UI/SettingsXAML/Views/MouseWithoutBordersPage.xaml index 901c5634c4..91fa7631cb 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/Views/MouseWithoutBordersPage.xaml +++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/MouseWithoutBordersPage.xaml @@ -6,6 +6,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="using:Microsoft.PowerToys.Settings.UI.Helpers" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:ptcontrols="using:Microsoft.PowerToys.Common.UI.Controls" xmlns:tkcontrols="using:CommunityToolkit.WinUI.Controls" xmlns:tkconverters="using:CommunityToolkit.WinUI.Converters" xmlns:ui="using:CommunityToolkit.WinUI" @@ -77,7 +78,7 @@ - - + - + - + diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Views/PeekPage.xaml b/src/settings-ui/Settings.UI/SettingsXAML/Views/PeekPage.xaml index 49da343744..998a4559cb 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/Views/PeekPage.xaml +++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/PeekPage.xaml @@ -6,6 +6,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="using:Microsoft.PowerToys.Settings.UI.Helpers" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:ptcontrols="using:Microsoft.PowerToys.Common.UI.Controls" xmlns:tkcontrols="using:CommunityToolkit.WinUI.Controls" xmlns:ui="using:CommunityToolkit.WinUI" AutomationProperties.LandmarkType="Main" @@ -70,7 +71,7 @@ - diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Views/PowerLauncherPage.xaml b/src/settings-ui/Settings.UI/SettingsXAML/Views/PowerLauncherPage.xaml index 5bcdf7195c..23da2b2449 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/Views/PowerLauncherPage.xaml +++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/PowerLauncherPage.xaml @@ -9,6 +9,7 @@ xmlns:ic="using:Microsoft.Xaml.Interactions.Core" xmlns:local="using:Microsoft.PowerToys.Settings.UI.Helpers" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:ptcontrols="using:Microsoft.PowerToys.Common.UI.Controls" xmlns:tkcontrols="using:CommunityToolkit.WinUI.Controls" xmlns:ui="using:CommunityToolkit.WinUI" xmlns:viewModels="using:Microsoft.PowerToys.Settings.UI.ViewModels" @@ -45,7 +46,7 @@ BorderThickness="0,0,0,0" ContentAlignment="Left" CornerRadius="0"> - - - - - - + @@ -459,7 +460,7 @@ Value="{x:Bind ViewModel.SearchClickedItemWeight, Mode=TwoWay}" /> - + @@ -548,7 +549,7 @@ x:Uid="PowerLauncher_TitleFontSize" HeaderIcon="{ui:FontIcon Glyph=}"> - - - diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Views/PowerPreviewPage.xaml b/src/settings-ui/Settings.UI/SettingsXAML/Views/PowerPreviewPage.xaml index a6b44dfdf7..895dbd0782 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/Views/PowerPreviewPage.xaml +++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/PowerPreviewPage.xaml @@ -6,6 +6,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="using:Microsoft.PowerToys.Settings.UI.Helpers" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:ptcontrols="using:Microsoft.PowerToys.Common.UI.Controls" xmlns:tkcontrols="using:CommunityToolkit.WinUI.Controls" xmlns:ui="using:CommunityToolkit.WinUI" AutomationProperties.LandmarkType="Main" @@ -89,7 +90,7 @@ -