This PR:
- Adds a MaxWidth to the SCOOBE and OOBE pages, inline with Fluent
design guidance
- Updates the imagery for PowerToys
- Tweaks some small nits in the General settings page: re-ordering,
adding icons, replacing a ToggleSwitch with a CheckBox
<img width="1774" height="1325" alt="image"
src="https://github.com/user-attachments/assets/d825047a-27be-4e8b-a6ce-7f1a71f39dfe"
/>
The PowerDisplay flyout had no keyboard close path: pressing Tab kept
focus inside the window so it never deactivated, and there was no
KeyDown / KeyboardAccelerator wired up. Handle Escape on RootGrid to
hide the window, matching the behavior of other PowerToys flyouts.
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [x] Closes: #48016
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [ ] **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
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
## Summary
Corrects four label names in the \VALID_LABELS\ allow-list of the
\uto-label-issues.yml\ workflow to match existing repository labels
exactly.
## Root Cause
The GitHub Actions \ddLabels\ API creates a brand-new label when the
name doesn't exactly match an existing one. The hardcoded list had
typos/mismatches:
| Workflow had | Repo actually has |
|---|---|
| \Product-Power Display\ | \Product-PowerDisplay\ |
| \Product-ColorPicker\ | \Product-Color Picker\ |
| \Product-Command Not Found\ | \Product-CommandNotFound\ |
| \Product-Hosts\ | \Product-Hosts File Editor\ |
## Changes
- Fixed all 4 label strings in \VALID_LABELS\ array
- Deleted the spurious \Product-Power Display\ label that was created by
the mismatch
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Carry per-monitor user preferences from the pre-#47712 Id format onto
the current DevicePath-based Ids by matching on EdidId. Without this,
every upgrade silently resets Enable* toggles (input source, color
temperature, power state) for monitors users had already opted in on,
because the direct-Id lookup in ApplyPreservedUserSettings can never
match the old "DDC_DELD1A8_1" / "WMI_BOE0900_2" keys.
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [ ] Closes: #xxx
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [ ] **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
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
---------
Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Currently, if the user clicks on a dock item which is a Page command,
then we'll attempt to show the cmdpal where the user clicked on a dock
item. This works great. However, if the user right-clicks a dock item to
invoke the context menu, then from that menu clicks on a Page command,
then nothing happens - we don't show the cmdpal window.
Similarly - IInvokableCommand's that return a CommandResult.Confirm - we
never show the cmdpal window so that the confirmation ContentDialog is
shown to the user.
Yes in the long run, these will make more sense to have a better UI for
the "dock flyout" (see #45861). But until then, this fixes these
scenarios.
Closes#45963
very relevant for #47989
## Summary of the Pull Request
This PR introduces real-time settings synchronisation for Image Resizer.
External changes to `settings.json` (via the Settings application or
manual edits to the file) are detected and reloaded immediately without
requiring a restart.
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [x] Closes: #36943
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [ ] **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
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
### Reload updates
The reload detection is via an `IFileSystemWatcher` (as file system
operations are abstracted in Image Resizer), which monitors the
`settings.json` file for creation and changes. There is a half second
debounce for changes, as the settings file can rapidly change when the
user is editing the preset name field.
Hot reloading of the properties required refactoring `ReloadCore`, which
replaces the `Sizes` preset collection and updates the Custom and AI
presets, in addition to the application-wide properties like compression
options and the fallback encoder choice.
I changed the combo box data binding from the `SelectedSize` object to
the int `SelectedSizeIndex`. This was required to resolve a specific WPF
issue where reloading the `Sizes` collection would cause issues with
restoring the current combo box selection to the prior value. Binding to
the index decouples the selection state from the object lifecycle during
the reload process.
Selection preservation is based on the preset ID (for user presets) and
preset type (for Custom and AI presets). This ensures that matches are
robust even if the user is in the process of renaming an entry in the
Settings application. If the preset cannot be matched (for example, if
the user deletes the item or changes the ID manually in the file), the
Custom preset is selected.
Selection range checks are maintained from the old code, and additional
checks have been added to ensure that Custom and AI presets will be
present even if they're deleted from the settings file.
The AI preset check from before has been inlined; this guarantees that
the AI resize option will not display if the facility is unavailable on
the current PC, even if it's present in the settings file.
The reload routine is dispatched to the UI thread, as changes involve
updates to the combo box.
### ID recovery
Preset IDs are key to preserving the combo box selection between
reloads, and a couple of changes were necessary to ensure round-tripping
changes were robust.
1. IDs are not reused. The old code could reuse IDs under certain
circumstances, for example if a preset was deleted and re-added via
Settings.
2. The ID Recovery Helper routine sorted the supplied presets by ID
before performing duplicate conflict resolution. This is not required
and it is more natural to assume that the order in the settings file and
the client UI is the source of truth.
New ID assignment is now based on a monotonically increasing ID (seeded
at application start) rather than `Current Maximum ID + 1`. This means
that IDs cannot be reused in the same Settings application session. This
makes the matching process in the client application more reliable.
A small update was made to the ID Recovery Helper to use `HashSet.Add()`
instead of splitting up the check and addition steps (`Add` will return
false if the value already exists), which saves a massive one line of
code.
There were comments about the ID Recovery Helper resolving "empty" or
"invalid" entries; this was inaccurate, as IDs are ints, which must by
definition always have a valid value. The routine only guards against
duplicates, so the comments have been updated to reflect this.
### Miscellaneous
The `Default` Settings property getter previously called `Reload` every
time it was accessed. This is fine when the file is only read at
application startup, but I changed this to lazily instantiate and call
`Reload` a single time.
I refactored duplicate code related to settings file/folder strings, and
also the creation of the Custom and AI size instances.
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Manual testing:
1. Add new preset in the Settings application. The new entry is
reflected in the client application as it is running.
2. Delete new preset. The entry is removed in the client application
list.
3. Edit an existing preset. The property change is reflected in the
client application.
4. Add new preset in the Settings application. Select the new preset in
the client application. Edit the properties of the new preset in the
Settings application and confirm that the updates appear in the client
application.
5. Add new preset in the Settings application. Select the new preset in
the client application. Delete the new preset in Settings. Confirm that
the current preset is removed and the selection changes to the default
in the client application.
6. Change one or more application-wide properties in the settings file
which are represented in the client application, too, e.g. "Make
pictures smaller but not larger" (`imageresizer_shrinkOnly`) or
"Overwrite files" (`imageresizer_replace`). Upon saving, confirm the
checkbox changes immediately in the client application.
7. Edit the `settings.json` file manually by e.g. adding a new Size
preset or editing the width or height property of an existing preset.
Upon saving, the change(s) should be reflected in the client
application.
8. Make a change to an existing or new preset which affects the resize
operation itself, e.g. the dimensions or the "Make pictures smaller but
not larger" setting. Proceed with the resize operation and confirm that
the new changes have been applied.
14 new unit tests have been added to `SetingsTests.cs` to exercise the
`Settings` and `IDRecoveryHelper` functionality.
---------
Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
## Summary
Adds the four Google.* DLLs shipped by AdvancedPaste (via
`Microsoft.SemanticKernel.Connectors.Google` for Gemini support) to the
ESRP sign list.
## Problem
The `Verify all binaries are signed and versioned` pipeline step
(`.pipelines/versionAndSignCheck.ps1`) was failing with:
```
Not Signed: + ...\extractedMachineMsi\File\WinUI3ApplicationsFiles_File_Google.Apis.Auth.dll
Not Signed: + ...\extractedMachineMsi\File\WinUI3ApplicationsFiles_File_Google.Apis.Core.dll
Not Signed: + ...\extractedMachineMsi\File\WinUI3ApplicationsFiles_File_Google.Apis.dll
Not Signed: + ...\extractedMachineMsi\File\WinUI3ApplicationsFiles_File_Google.GenAI.dll
```
These DLLs are transitive NuGet dependencies of
`Microsoft.SemanticKernel.Connectors.Google` (referenced by
`src/modules/AdvancedPaste/AdvancedPaste/AdvancedPaste.csproj`) and
deploy to `WinUI3Apps\`, but were never added to
`.pipelines/ESRPSigning_core.json`.
## Fix
Added the four DLLs to the second `SignBatch` (`CP-231522`, the
third-party / OSS-library identity) — same batch used for other
connector DLLs like `OpenAI.dll`, `OllamaSharp.dll` and
`Microsoft.SemanticKernel.Connectors.Ollama.dll`.
## Validation
- `ConvertFrom-Json` on the modified file confirms valid JSON.
- Sign-list entries match the actual deploy paths flagged by
`versionAndSignCheck.ps1`.
- The next ESRP signing run will pick them up; the verify step should
pass.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary
Mitigation for issue #47556 — `KERNEL_SECURITY_CHECK_FAILURE` BSOD
originating in `win32kfull!DdcciGetCapabilitiesStringFromMonitor` when
PowerDisplay calls DDC/CI capability APIs against monitors with
malformed capability strings.
After a detected crash, PowerDisplay auto-disables itself via
`settings.json`, shows an error InfoBar at the top of the PowerDisplay
settings page (page is locked except the Ignore button), so users can
avoid getting stuck in an infinite reboot loop after a crash. And the
user must explicitly dismiss the warning before re-enabling the module.
The actual kernel-side fix is the Windows team's responsibility — this
PR only prevents users from BSOD-ing repeatedly on the same monitor
without warning.
settings page:
<img width="1743" height="1475" alt="image"
src="https://github.com/user-attachments/assets/8cf1b72f-c51a-4955-82d7-213cae49fd4e"
/>
## Mechanism
1. `CrashDetectionScope` IDisposable wraps Phase 2 capability fetch in
`DdcCiController.DiscoverMonitorsAsync`, writing `discovery.lock`
(`WriteThrough` + `Flush(flushToDisk: true)`) before, deleting it on
Dispose.
2. If the process is killed externally (BSOD, FailFast), the lock
survives.
3. On next PowerDisplay.exe startup (Phase 0), `CrashRecovery` detects
the orphan lock and runs a strict fail-fast sequence: write
`crash_detected.flag` → set `enabled.PowerDisplay=false` in global
`settings.json` → signal the new `POWER_DISPLAY_AUTO_DISABLE_EVENT` →
delete the lock (commit point).
4. The runner-loaded `PowerDisplayModuleInterface.dll` runs a one-shot
listener thread that wakes on the event and calls `disable()` to sync
`m_enabled`.
5. `PowerDisplayViewModel` reads the flag at construction and binds
`IsCrashLockActive` to lock the page.
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [x] Closes: #47556
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [ ] **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
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
---------
Co-authored-by: Yu Leng <yuleng@microsoft.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Reverts the noraajunker.ch -> PR link change. As confirmed by @niels9001,
personal contributor links are standard in PowerToys settings pages.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This allows users to drag files & URLS to the dock, to immediately
create a bookmark, and pin that bookmark to the dock.
It also updates the bookmark provider's dock bands. If you bookmark a
folder, then pin that to the dock, when you click it on the dock, we'll
default to the "browse" experience, which will open the list of files in
cmdpal, rather than open in explorer.
Had to make miscellaneous changes to make this all a bit faster:
* DirectoryPage didn't load icons smartly, like we do for bookmarks
* I added a different "observable" collection for dock top-level items,
because it caused a flippin CollectionChanged cascade any time a single
provider had more than one item pinned in the dock. Each item from each
provider would cause us to recreate all the dock view models (???) crazy
* I alas had to make `IBookmarksManager` public, so that the UI could
use it. I hate it, but I couldn't figure out a better way. Bookmarks are
a pretty built-in part, so it's _fine i guess_
re: #45584
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
This PR checks if future PRs has added or refines telemetry events, if
so, the bot will add a message to the PR about the needed steps
depending on the PR.
**NOTE**: This PR is submitting a test version, which is only manually
triggered, once tested and confirmed then will move to it being
automatic
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [ ] Closes: #xxx
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [ ] **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
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
## Summary of the Pull Request
This PR fixes several issues around the popup selection window's size
and position, selection-related issues which result in flashing or
glitching, and includes more reliable detection of the Shift key.
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [x] Closes: #44332
- [x] Closes: #44980
- [x] Closes: #35094
- [x] Closes: #40498
- [ ] **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
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
This PR includes fixes for the Quick Accent's selection window position,
its width measurement, and letter selection-related issues. In addition,
glitches such as the window flashing the selection colour and the window
appearing blank should be reduced or eliminated entirely.
### Popup width bug
When opening Quick Accent from a letter with many mappings, it would
appear too wide for the display. Even though letters could be selected,
they may be entirely off-screen:
<img width="1578" height="134" alt="image"
src="https://github.com/user-attachments/assets/cfcb2ddb-3cf3-47d5-9386-133a2fc70550"
/>
This was because of this flaw in `GetDisplayMaxWidth`, which is used
directly by the popup to set the maximum width of the characters area:
```csharp
// In Selector.xaml.cs
private void SetWindowsSize()
{
this.characters.MaxWidth = _powerAccent.GetDisplayMaxWidth();
}
...
// In PowerAccent.cs
public double GetDisplayMaxWidth()
{
return WindowsFunctions.GetActiveDisplay().Size.Width - ScreenMinPadding;
}
```
`GetActiveDisplay` uses the `GetMonitorInfo` API, which exposes the
working area of the display. It returns its values in _raw unscaled
pixel_ values:
```csharp
public static (Point Location, Size Size, double Dpi) GetActiveDisplay()
{
...
var res = PInvoke.MonitorFromWindow(guiInfo.hwndActive, MONITOR_FROM_FLAGS.MONITOR_DEFAULTTONEAREST);
MONITORINFO monitorInfo = default;
monitorInfo.cbSize = (uint)Marshal.SizeOf(monitorInfo);
PInvoke.GetMonitorInfo(res, ref monitorInfo);
...
return (location, monitorInfo.rcWork.Size, dpi);
}
```
However, the `MaxWidth` property must be a _pre-scaled_ value, i.e. in
logical WPF units not physical pixels. The fix is straightforward:
```csharp
public double GetDisplayMaxWidth()
{
var activeDisplay = WindowsFunctions.GetActiveDisplay();
return (activeDisplay.Size.Width / activeDisplay.Dpi) - ScreenMinPadding;
}
```
### Popup positioning bug
This is related to a subtle DPI issue in `GetActiveDisplay()`:
```csharp
public static (Point Location, Size Size, double Dpi) GetActiveDisplay()
{
GUITHREADINFO guiInfo = default;
guiInfo.cbSize = (uint)Marshal.SizeOf(guiInfo);
PInvoke.GetGUIThreadInfo(0, ref guiInfo);
var res = PInvoke.MonitorFromWindow(guiInfo.hwndActive, MONITOR_FROM_FLAGS.MONITOR_DEFAULTTONEAREST);
MONITORINFO monitorInfo = default;
monitorInfo.cbSize = (uint)Marshal.SizeOf(monitorInfo);
PInvoke.GetMonitorInfo(res, ref monitorInfo);
double dpi = PInvoke.GetDpiForWindow(guiInfo.hwndActive) / 96d;
var location = new Point(monitorInfo.rcWork.left, monitorInfo.rcWork.top);
return (location, monitorInfo.rcWork.Size, dpi);
}
```
Here, the application window's DPI is returned. Unfortunately, the
window may report a value which is different from the monitor's own DPI
value. This will consistently happen if the application is not
Per-Monitor DPI-Aware, and the monitor is not at 100% Scale. The effects
are that the Quick Accent popup can appear misaligned or even off-screen
entirely. Quick Accent can still be used, but the user may not be able
to see what they are selecting.
As Quick Accent is using monitor coordinates for setting its location,
the solution is to use the monitor's own DPI value. The fix is to add
this in place of the `GetDpiForWindow` line:
```csharp
uint dpiRaw = 96; // Safe default
if (PInvoke.GetDpiForMonitor(res, MONITOR_DPI_TYPE.MDT_EFFECTIVE_DPI, out uint dpiX, out _) == 0)
{
dpiRaw = dpiX;
}
double dpi = dpiRaw / 96d;
```
### Selection bugs
After dismissing the Quick Accent window, the `_selectedIndex` state was
not properly reset. The next time the window opened, it could attempt to
scroll to or highlight an index that was out-of-bounds for the new
character set. This could result in glitching, such as the window
flashing the selection colour or the initial selection being incorrect.
In this fix, I:
1. Explicitly set `_selectedIndex` to `-1` when the UI hides.
2. Reset the `SelectedIndex` inside Selector.xaml.cs before updating the
`ItemsSource`.
### Shift key activation
In certain cases, a quick press of Shift could fail to move back through
the character list. In this fix, I:
1. Added a native fallback usign GetAsyncKeyState(VK_SHIFT).
2. Updated `ProcessNextChar()` to evaluate `shiftPressed ||
WindowsFunctions.IsShiftState()`.
3. Updated the multiple `if`s in `ProcessNextChar` to be an if/else
structure, to prevent bugs when more than one trigger key is pressed.
### Support added for multi-codepoint graphemes
The current code loops through each `char` of a mapping, calling
`SendInput` multiple times for multi-char sequences. This will fail for
multi-codepoint graphemes, i.e. where the mapping 'letter' is more than
one UTF-16 codepoint. Those characters may appear as `[]`. The amended
`Insert()` in `WindowsFunctions` appends all characters before calling
`SendInput`.
### Miscelleneous
- Added an `OnDpiChanged` handler for the Selector control, so changing
the DPI of the screen should be picked up automatically. (It's
questionable whether this is essential, as the DPI would have to change
while the control was displayed, but it's worth having for robustness.)
- Now using `SetWindowPos` instead of setting the `Left` and `Top` of
the popup control. Also now initialising the popup offscreen to attempt
to reduce flicker and the occurrence of blank window flashes.
- Changed the `Focusable` property of the characters `ListBox` to
`False`, to attempt to reduce flicker and the window flashing the
selector colour.
- Removed `Width` and added `MinWidth` to the letter control in
Selector.xaml. This allows for wider letters or longer multi-letter
mappings.
- Changed the `VirtualizingStackPanel` to a regular `StackPanel`. We do
not have mappings with enough entries for a virtual control to be
necessary, and using StackPanel seemed to have a positive effect on the
appearance of blank window glitches.
- Added `TextTrimming`, `TextWrapping` and `MaxHeight` to the unicode
description `TextBlock`. This helps support extremely long unicode
descriptions. Again, this will enable us to support longer
multi-character mappings in the future.
- Added CsWin32 to the PowerAccent.UI project, to support the
`SetWindowPos` call.
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
See separate doc for full test details:
https://docs.google.com/document/d/19uClcUiv7RUDRlbFhazG-Cmu46oNmrAVoJf9bHSjSJU/edit?usp=sharing
---------
Co-authored-by: Muyuan Li (from Dev Box) <muyuanli@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Niels Laute <niels.laute@live.nl>
Adds Greek Polytonic characters set to power accent, based on
https://github.com/microsoft/PowerToys/pull/29709
### PR Checklist
- [x] Closes#46941
- [x] Communication: I've discussed this with core contributors already.
- [ ] Tests: Not sure if there are specific tests for this
- [ ] Documentation updated: Power accent docs
### Detailed Description of the Pull Request / Additional comments
Added all greek polytonic letters to their corresponding english letter
(some duplicated)
(if you wondered about GRC -> ISO 639-3)
### Validation Steps Performed
Compiled and Observed Power Accent
---------
Co-authored-by: Niels Laute <niels.laute@live.nl>
Co-authored-by: Dave Rayment <dave.rayment@gmail.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## Summary of the Pull Request
Renames the issue-triage GitHub Action to **Automatic Triaging on Issue
Creation** and removes the redundant `auto-label-product.yml` workflow.
This consolidates issue labeling/triage under a single workflow surface.
Also syncs this PR branch with the latest `main` via a merge commit to
keep it up to date with upstream.
## PR Checklist
- [ ] **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
- **Workflow rename**
- Updated `.github/workflows/auto-label-issues.yml`:
- `name: Auto-label Issues by Area` → `name: Automatic Triaging on Issue
Creation`
- Updated the manual-trigger comment to reference the new action name.
- **Workflow cleanup**
- Removed `.github/workflows/auto-label-product.yml` to eliminate
overlapping automation.
- **Branch sync requested in PR comments**
- Merged latest `origin/main` into this branch (`4f831bc`) to keep the
PR current.
```yaml
# .github/workflows/auto-label-issues.yml
name: Automatic Triaging on Issue Creation
```
## Validation Steps Performed
- Verified clean merge of `origin/main` into this PR branch (no merge
conflicts).
- Confirmed targeted workflow changes remain present after merge.
- Ran PR validation tooling:
- Code Review completed successfully.
- CodeQL scan timed out in validation tooling.
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: niels9001 <9866362+niels9001@users.noreply.github.com>
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
This PR reverts #47900: it causes an exception in the Release+AOT build
configuration when retrieving a storyboard from XAML resources and
casting it to a local field.
- [x] Closes: #47970
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [ ] **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
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
This PR updates the shell command provider to work (almost) exactly like
run. The current shell provider is close, but not technically correct.
It does enumerate files. Sure. But as it turns out, it doesn't enumerate
things **exactly** correctly. It doesn't handle network paths super
well. It doesn't handle NTFS file paths. Basically, there's a lot of
weird edge cases in the way the run dialog enumerates file paths for
suggestions. And the only way to match that is to just use the code from
the old run dialog.
This is code that is taken pretty verbatim from the new run dialog.
Instead of trying to enumerate paths manually and shellexecuting command
lines, We're using the actual APIs that the original run dialog used,
more or less. They've been pretty much ported to C#.
This should make us feel just as correct as the original run dialog did.
And exactly the same as the new Run dialog.
The one major change is the introduction of a static item at the top of
the list for running the command that the user typed. This command is
used to just immediately take whatever is in the search box and fire it
off as the command the user typed. This is essentially what happens with
the run dialog. When you press the button, we run the command in the
text box.
See: [The new Run dialog: faster, cleaner, and more capable - Windows
Command
Line](https://devblogs.microsoft.com/commandline/the-new-run-dialog-faster-cleaner-and-more-capable/)
Honestly, most of this PR is just deleting the files we no longer need
from the shell list provider and adding the tests from the OS side here.
I also had to update CsWinRT for this.
## Summary
Adds a Battery widget to the CmdPal Performance Monitor dock, exposing
live charge percentage, charging/AC status, and estimated time
remaining. The dock-band icon updates each tick to reflect the current
charge level and charging state, matching the existing
CPU/RAM/GPU/Network widget pattern.
Closes#47218
## Detail
- New `SystemBatteryUsageWidgetPage` in `PerformanceWidgetsPage.cs`,
mirroring the existing widget pattern.
- Data source: `GetSystemPowerStatus` via CsWin32 (AOT-safe), wrapped in
`BatteryStats` and surfaced through `SystemData` / `DataManager` on the
shared 1 s timer.
- Live dock-band icon: `Icons.cs` caches 23 `IconInfo` instances
(`BatteryIcons[0..10]`, `BatteryChargingIcons[0..10]`,
`BatteryUnknownIcon`); alloc-free `BatteryGlyph()` selects the glyph per
tick. Codepoints `0xEBA0`–`0xEBB5` / `0xEC02` (Segoe Fluent Icons
MobBattery family).
- Adaptive card template `SystemBatteryTemplate.json` registered as
`<None Update … PreserveNewest>`, consistent with the other PerfMon
templates.
- New `Battery_*` strings under `Strings\en-US\Resources.resw`.
- Handles `GetSystemPowerStatus` sentinels: `BatteryLifePercent == 255`,
`BatteryLifeTime == 0xFFFFFFFF`, `BatteryFlag == 0xFF`, `0x80` (no
battery), `0x08` (charging).
## Screenshots
<img width="1660" height="401" alt="image"
src="https://github.com/user-attachments/assets/6e26f10a-267b-4f6b-b43a-b2c63c092a6d"
/>
When the battery is at 100%, the widget will always show the "full" icon
(`MobBatteryCharging10`).
<img width="537" height="37" alt="image"
src="https://github.com/user-attachments/assets/d925a328-b9b6-4760-a488-f936910a1715"
/>
Otherwise and when on AC, it will show the "charging" variant of the
icon:
<img width="85" height="61" alt="image"
src="https://github.com/user-attachments/assets/065e3a53-c210-4d65-8ca2-02dccf63edf6"
/>
The icon also always reflects the current charging state: It resolves to
the correct glyph in both charging and discharging states, rounded to
the nearest 10% (so 0%, 10%, … 100%).
## How tested
- `MSBuild CommandPalette.slnf /p:Configuration=Release /p:Platform=x64
/m /restore` — green, 0 errors, 0 warnings.
- Launched dev `Microsoft.CmdPal.UI.exe`, opened PerfMon dock, confirmed
Battery widget renders charge %, status, time remaining, and that the
dock-band glyph matches the current charge level (verified on AC, on
battery, and while charging).
## Summary
Fixes#38317 — "Too many tags on a list item looks hilarious"
When CmdPal list items have many tags (e.g., GitHub issue labels), the
tag pills dominated the row and pushed the title text out of view.
### Changes
**Two-pronged fix:**
1. **Cap visible tags at 3** — ViewModel exposes `VisibleTags` (first 3)
and `OverflowTagText` (`+N`) properties. Original `Tags`/`HasTags`
bindings are preserved (no contract breaks).
2. **Overflow badge** — A `[+N]` badge appears when more than 3 tags
exist, reusing existing `Tag*` theme resources for visual consistency.
Includes `AutomationProperties.Name` for accessibility.
### Files Changed
| File | Change |
|------|--------|
| `ListItemViewModel.cs` | Added `MaxVisibleTags`, `VisibleTags`,
`OverflowTagCount`, `HasOverflowTags`, `OverflowTagText` properties and
`UpdateVisibleTags()` |
| `ListPage.xaml` | `ItemsRepeater` binds `VisibleTags`, wrapped in
`StackPanel` with overflow `Border` badge |
### Validation
- [x] Build clean (`Microsoft.CmdPal.UI.ViewModels` +
`Microsoft.CmdPal.UI`)
- [x] Handles 0, 1-3, and 4+ tags correctly
- [x] No ABI/contract breaks (original `Tags`/`HasTags` preserved)
- [x] Overflow badge reuses existing theme resources
- [x] Accessibility: `AutomationProperties.Name` on overflow badge
### Follow-up
- Overflow badge accessible name could be enriched (e.g., "+3 more tags"
instead of "+3")
### Screenshots
<img width="972" height="545" alt="image"
src="https://github.com/user-attachments/assets/327dcdd0-2e62-435a-9b07-0432189cc947"
/>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## Summary of the Pull Request
Sets `IsLoading = true` before querying open windows in
`WindowWalkerListPage.GetItems()` and resets it in a `finally` block, so
the UI shows a loading indicator while Window Walker results are being
fetched.
Closes#38314
## PR Checklist
- [x] Closes: #38314
- [ ] **Communication:** I've discussed this with core contributors
already.
- [ ] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
## Detailed Description
The Window Walker extension was not setting `IsLoading` during its
search operation. This meant users got no visual feedback that a search
was in progress. This follows the same pattern used by other extensions
(AllAppsPage, IndexerPage, etc.).
## Validation Steps Performed
- Verified the change follows existing patterns in AllAppsPage.cs and
IndexerPage.cs
- The try/finally ensures IsLoading is always reset even if Query throws
Co-authored-by: root <root@io.bbq>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## Summary of the Pull Request
Enables dragging dock bands between monitors in edit mode. Previously,
drag-and-drop only worked within bands on the same monitor's dock.
Closes#47920
## PR Checklist
- [x] Closes: #47920
- [ ] **Communication:** I've discussed this with core contributors
already.
- [ ] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
## Detailed Description
The existing drag-and-drop implementation used a local `_draggedBand`
field per `DockControl` instance, which meant the target DockControl on
another monitor had no reference to the dragged band. This PR fixes that
by:
1. **DataPackage properties** — `DragItemsStarting` now stores the band
ID and source monitor device ID in `DataPackage.Properties`, making the
identity available to any drop target in the same process.
2. **Cross-window drop acceptance** — `DragOver` and `DragEnter` now
check for `DockBandId` in `DataView.Properties` in addition to the local
`_draggedBand` field.
3. **CrossMonitorBandDropMessage** — A new `WeakReferenceMessenger`
message coordinates removal from the source dock after a successful
cross-monitor drop.
4. **ViewModel methods** — `DockViewModel.AcceptBandFromMonitor()`
creates a new band ViewModel on the target dock using the same factory
pattern as `AddBandToSection`. `RemoveBandById()` handles cleanup on the
source dock.
Both methods call `EnsureMonitorForked()` to fork per-monitor band
settings from global when needed, maintaining the existing customization
model.
## Validation Steps Performed
- Verified existing same-monitor drag-and-drop behavior is preserved
(local path unchanged)
- Verified cross-monitor handler properly stores/retrieves DataPackage
properties
- Reviewed against existing patterns in DockControl (AddBandToSection,
MoveBandWithoutSaving)
---------
Co-authored-by: root <root@io.bbq>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## Summary of the Pull Request
Clicking **Reset** in the Quick Access hotkey shortcut dialog crashes
PowerToys Settings. The root cause is that `C_ResetClick` sets the
`HotkeySettingsProperty` DependencyProperty to `null`, which causes the
WinUI3 XAML runtime to dereference a null pointer during two-way binding
property-change notification — a native E_POINTER crash (0x80004003).
## PR Checklist
- [ ] **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
### Root Cause
`C_ResetClick` previously did:
```csharp
hotkeySettings = null;
SetValue(HotkeySettingsProperty, null);
```
The `HotkeySettingsProperty` is bound two-way (`{x:Bind Mode=TwoWay}`)
to the ViewModel. `SetValue(null)` synchronously triggers the binding
chain: ViewModel setter → `NotifyPropertyChanged` → XAML runtime reads
back the DP value → null pointer → **native E_POINTER crash** in
`CoreMessagingXP.dll`.
### Fix
Use `new HotkeySettings()` instead of `null` — matching the existing
`C_ClearClick` pattern that never crashes:
```csharp
// C_ResetClick — fixed
hotkeySettings = new HotkeySettings();
SetValue(HotkeySettingsProperty, hotkeySettings);
SetKeys();
lastValidSettings = hotkeySettings;
shortcutDialog.Hide();
```
An empty `HotkeySettings` (`IsEmpty() == true`) semantically means "no
shortcut configured" — the same intent as null, but the XAML binding
chain always has a valid object to dereference.
Also added null-conditional guards in `OpenDialogButton_Click` as
defense-in-depth:
- `HotkeySettings?.GetKeysList() ?? new List<object>()` ensures `c.Keys`
is never null, preventing `{x:Bind Keys.Count}` in
`ShortcutDialogContentControl.xaml` from throwing.
- `hotkeySettings?.HasConflict ?? false` and
`hotkeySettings?.ConflictDescription` guard the remaining property
accesses.
- A null guard in `Hotkey_KeyDown` prevents a crash if the user presses
keys after Reset.
## Validation Steps Performed
- Reproduced crash: Settings → General → Quick Access shortcut → Edit →
Reset → crash (before fix)
- Verified fix: Same steps → no crash, dialog closes cleanly, shortcut
shows as empty
- Verified reopening dialog after Reset works without crash
- Verified pressing keys in dialog after Reset works without crash
- Built and tested with full Runner IPC (debug PowerToys.exe → Settings)
---------
Co-authored-by: Muyuan Li (from Dev Box) <muyuanli@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: MuyuanMS <116717757+MuyuanMS@users.noreply.github.com>
Adds a **"Show file preview tooltip"** toggle to Peek's Behavior
settings, letting users disable the metadata tooltip (filename, type,
date modified, size) shown on hover over the preview.
## Changes
- **`PeekProperties`** — new `ShowFilePreviewTooltip: BoolProperty`
(default `true`)
- **`IUserSettings` / `UserSettings`** — expose the setting; updated by
the existing file watcher on settings change
- **`FilePreview.xaml`** — `ImagePreview` and `VideoPreview` now bind
`ToolTipService.ToolTip` directly to `InfoTooltip` (the same
attached-property form already used by `AudioControl`). The previous
explicit `<ToolTip Content="{x:Bind InfoTooltip}"/>` element form left a
`ToolTip` instance permanently attached, so nulling the content still
produced an empty popup on hover. With the attached-property form, a
`null` `InfoTooltip` detaches the tooltip entirely and no popup is
shown.
- **`FilePreview.xaml.cs`** — new `ShowFilePreviewTooltip`
DependencyProperty; sets `InfoTooltip = null` when disabled; re-triggers
`UpdateTooltipAsync` when re-enabled with a file loaded; `infoTooltip`
field changed to `string?`
- **`MainWindow.xaml.cs`** — reads setting from `IUserSettings` and
pushes it to `FilePreviewer.ShowFilePreviewTooltip` on each
`Initialize()` call, picking up the latest user preference each time
Peek activates
- **`PeekViewModel`** — `ShowFilePreviewTooltip` property for two-way
Settings UI binding
- **`PeekPage.xaml`** — toggle in the Behavior group, consistent with
existing toggles
- **`Resources.resw`** — localizable strings for header and description
## PR Checklist
- [x] Closes: #46621
- [ ] **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
Setting defaults to `true` — no behavior change for existing users.
The tooltip is suppressed by setting `InfoTooltip` to `null` while bound
through `ToolTipService.ToolTip` as an attached property. A `null` value
on the attached property prevents WinUI from creating a tooltip popup at
all (this is the same pattern `AudioControl` already used and behaves
correctly with null). The earlier explicit `<ToolTip>` element form did
*not* behave this way — the `ToolTip` instance stayed attached and an
empty popup appeared on hover — so the XAML was switched to the
attached-property form on `ImagePreview` and `VideoPreview`. The custom
tooltip placement logic (top/bottom based on cursor Y) is unaffected.
## Validation Steps Performed
- Verified toggle appears in Peek Settings > Behavior
- Toggling off fully suppresses the hover tooltip on image, video, and
audio previews (no empty bubble)
- Toggling back on restores tooltip with file metadata on next file load
- Default `true` preserves existing behavior
<img width="688" height="99" alt="image"
src="https://github.com/user-attachments/assets/369d0ba7-fc9a-495e-9603-f4b2b95ba68e"
/>
<img width="692" height="305" alt="image"
src="https://github.com/user-attachments/assets/cb5dfc69-a445-46b0-9c0a-041fbf4c89c2"
/>
<img width="684" height="73" alt="image"
src="https://github.com/user-attachments/assets/8088caa7-9536-4384-91dc-dbdbbe0ae755"
/>
<img width="686" height="430" alt="image"
src="https://github.com/user-attachments/assets/0d9d2d6f-bc42-4497-89c5-06ac9c18a2b7"
/>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: niels9001 <9866362+niels9001@users.noreply.github.com>
Co-authored-by: Niels Laute <niels.laute@live.nl>
Co-authored-by: Muyuan Li (from Dev Box) <muyuanli@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
`NavigateToString` throws `ArgumentException` when previewing Markdown
files containing many multi-byte UTF-8 characters (e.g., CJK) — file
size exceeds 2MB but character count stays under 1.5M, bypassing the
guard.
## Summary of the Pull Request
The size guard in `MarkdownPreviewHandlerControl` used
`markdownHTML.Length` (character count / UTF-16 code units), but
WebView2's `NavigateToString` limit is measured in **bytes**. A string
with 700K CJK characters has only 700K `.Length` units but ~2.1MB of
UTF-8 bytes — enough to crash the API while passing the old check.
**Changes:**
- **`MarkdownPreviewHandlerControl.cs`**: Replace character-count guard
with UTF-8 byte count:
```csharp
// Before
if (markdownHTML.Length > 1_500_000)
// After
if (System.Text.Encoding.UTF8.GetByteCount(markdownHTML) > 1_500_000)
```
When the byte threshold is exceeded, content is written to a temp file
and loaded via `_browser.Source` instead of `NavigateToString` —
existing fallback path, now correctly triggered.
- **`MarkdownPreviewHandlerTest.cs`**: Added 3 regression tests to
prevent this class of bug from recurring:
1. Multi-byte UTF-8 content (CJK, <1.5M chars but >2MB bytes) →
temp-file navigation path
2. Small ASCII content within both thresholds → `NavigateToString` path
3. Large ASCII content exceeding 1.5M chars → temp-file navigation path
## PR Checklist
- [ ] **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
The existing fallback (write HTML to a temp file, navigate via
`_browser.Source`) was already correct and handles arbitrarily large
content safely. The only bug was in the guard condition that decides
when to use it — it measured the wrong unit (characters vs. bytes).
Single-byte ASCII content is unaffected; only multi-byte Unicode content
was under-counted.
The tests use reflection to read the private `_localFileURI` field.
Since this field is set synchronously before `Controls.Add(_browser)`,
the check is race-free: once the wait loop exits with `Controls.Count >
0`, `_localFileURI` is guaranteed to have its final value.
## Validation Steps Performed
- Verified the fix by reasoning through the byte math: a file with 700K
CJK characters → `Length` = 700K (passes old check) → UTF-8 bytes ≈
2.1MB (fails new check → uses temp file path, no crash).
- Added 3 targeted unit tests in `UnitTests-MarkdownPreviewHandler`
covering the multi-byte threshold boundary; all 14 tests in the suite
pass (14/14).
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: MuyuanMS <116717757+MuyuanMS@users.noreply.github.com>
Co-authored-by: Muyuan Li (from Dev Box) <muyuanli@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
1. Subscribes to GUID_CONSOLE_DISPLAY_STATE so PowerDisplay rescans
monitors when the console display wakes from sleep — previously, woken
monitors stayed unrecognized until the user manually re-triggered
discovery.
2. Locks the PowerDisplay UI immediately on wake to block stale
interactions before the rescan completes.
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [x] Closes: #47951
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [x] **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
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
---------
Co-authored-by: Yu Leng <yuleng@microsoft.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
This PR moves storyboard that handles showing and hiding breadcrumbs in
Settings windows to a XAML resources.
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [ ] Closes: #xxx
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [ ] **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
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
These 7 files exist on main but were dropped by the bad merge. Git's
rename detection paired them with newly-resurrected files at different
paths, so the earlier --diff-filter=DM restore pass missed them.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
These files were intentionally deleted on main by recent PRs but were
resurrected when 7aae7343aa merged main with a bad conflict resolution:
- HideWindowMessage.cs (deleted by #47826 CmdPal parameters)
- BookmarkPlaceholderForm.cs (deleted by #47886 bookmarks-as-parameters)
- NativeMethods.json/.txt + WindowsPackageManager.Interop/* (deleted by
#46636 Extension Gallery)
- Ext.Indexer/Assets/Actions.png (moved/deleted by #46636)
- DdcCiValidationResult.cs (deleted by #47875 PowerDisplay max-compat)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Restores 114 deleted files and re-applies 129 file modifications that
were lost when a divergent merge of main into feature/shortcutguidev2
resolved conflicts by dropping recent CmdPal/Settings work from main
(ExtensionGallery, ListItemsView, ParametersViewModels, HttpCaching,
DangerousFeatureWarningDialog, etc.).
Source: tree of bf8493225d (the good merge sibling of 7aae7343aa).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## Summary of the Pull Request
This adds `rand()` and `randi()` functions to Command Palette's
Calculator, making it consistent with Run.
It also expands upon the return values from `ToWStringFullPrecision()`,
so NaN, ParseError and +/-infinity results are passed back to the
caller, improving the specificity of the error message display.
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [x] Closes: #47707
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [ ] **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
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
The two new functions have been added to **ExprtkEvaluator.cpp**,
alongside `sign()` and `factorial()`. As they need to handle the state
of the RNG, they're slightly more complex in implementation. I used the
Mersenne Twister RNG with a uniform distribution, and the instances are
marked `static thread_local` in case the engine moves to multithreaded
evaluation in the future.
It's possible for the RNG to return a value out of the range of
`double`, and this is caught and `quiet_NaN()` is returned. To prevent
this being caught as a generic parse error, I updated
`ToWStringFullPrecision()` to distinguish between `NaN`, expression
parsing errors and infinity values. This should improve the accuracy of
error messages for other expressions, too.
Finally, I corrected a comment in **CalculateEngine.cs,** which still
referred to the Mages calculation engine. The log/ln mapping is the same
for both engines, so the comment was still accurate except for this
reference.
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Unit tests were added to exercise the new functions. All Calculator
tests pass:
<img width="375" height="59" alt="image"
src="https://github.com/user-attachments/assets/5a33e1ed-a4fd-4d53-b9ba-6b44000f1bf4"
/>
Confirmed that error messages are displaying correctly for the
newly-exposed result types:
**Not a number**
<img width="787" height="128" alt="image"
src="https://github.com/user-attachments/assets/8c73dcf6-122b-4af8-bf1a-62284842433a"
/>
<img width="786" height="145" alt="image"
src="https://github.com/user-attachments/assets/fe14338c-1160-4aae-83dd-5ca3491ae59e"
/>
**+/- Infinity**
<img width="898" height="137" alt="image"
src="https://github.com/user-attachments/assets/20cfacda-72a7-44bb-a875-af7be39ee7e2"
/>
**Parser failure**
<img width="607" height="139" alt="image"
src="https://github.com/user-attachments/assets/7d7120b2-a2cf-45b6-ab89-79af4051fa50"
/>
<img width="587" height="140" alt="image"
src="https://github.com/user-attachments/assets/2dc7a365-7ee6-4379-8b3f-47b3912e6891"
/>
## Summary of the Pull Request
This fixes Calculator functions with multiple arguments in cultures
where the number group separator and list separator are identical, e.g.
**en-US** and **en-GB**.
It maintains existing parsing behaviour for other cultures where the
separators differ, e.g. **de-DE**.
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [x] Closes: #47726
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [ ] **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
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
The root issue was in the number translation step. In cultures such as
en-US, commas were being consumed as part of numeric tokens and were
treated as number group separators, which broke functions whcih took
multiple arguments. For example, `max(1,2)` would be translated as
`max(12)` and `pow(2,3)` as `pow(23)`. The number translator's result
would be passed on to ExprTK, which could sometimes still interpret the
input and would give a result (`12` in the case of `max(1,2)`); for
cases like `pow(2,3)`, it would surface an error, as the expression
`pow(23)` is invalid.
This fix resolves the ambiguity in two ways:
- It uses stricter grouped number matching when the culture's list
separator and number group separator are the same.
- It preserves separator characters for multi-argument functions. This
means that expressions like `max(123,456)` are correctly interpreted as
two arguments inside the function call, while `123,456` outside a
function call is still interpreted as a grouped number.
Care has been taken to preserve grouped numbers inside single-argument
functions, e.g. `ceil(123,456.23)`.
The more permissive parsing for cultures which do not have this
ambiguity has been retained. (Arguably this is too loose, but that's
something to consider separately.)
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Added and updated unit tests, with **en-US** used as the representative
'ambiguous culture'. Coverage includes:
- `max()`, `min()` and `pow()`
- Grouped numbers in single-argument functions like `ceil()`, `floor()`,
`round()`, `log()` and `sin()`.
- Nested expressions
- Spacing around function calls
- Scientific notation
- Hexadecimal, binary and octal literals
All tests pass:
<img width="696" height="52" alt="image"
src="https://github.com/user-attachments/assets/ed89fbb9-70e0-4cf7-8e13-12f1f36b6037"
/>
Manual testing was also performed to confirm:
- Multi-argument functions now evaluate correctly
<img width="243" height="136" alt="image"
src="https://github.com/user-attachments/assets/b5c96954-ee6d-4842-b599-561ccbd10607"
/>
- Grouped numbers inside single-argument functions still work
<img width="356" height="135" alt="image"
src="https://github.com/user-attachments/assets/918425b0-cce4-4708-855b-c8b4916e6a4a"
/>
- Nested expressions and spacing variations are handled correctly
<img width="606" height="137" alt="image"
src="https://github.com/user-attachments/assets/12be5aa9-ba33-4000-96d5-444a2932bbe7"
/>
<img width="482" height="135" alt="image"
src="https://github.com/user-attachments/assets/aea2ebce-7c88-469e-b9e4-bdb7099ef538"
/>
## Summary of the Pull Request
This PR fixes WMC1506 warnings introduced by the extension gallery PR.
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [ ] Closes: #xxx
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [ ] **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
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
## Summary of the Pull Request
This PR filters URIs from extension gallery and allows only HTTP/HTTPS
URIs as links for the installation page.
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [ ] Closes: #xxx
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [ ] **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
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
This pull request updates the logging behavior in the `LogMessage`
method to ensure that log messages are categorized and logged according
to their severity (Error, Warning, or Info), instead of always using
debug-level logging.
Logging improvements:
* Updated the `LogMessage` method in `AppExtensionHost.cs` to log
messages using `CoreLogger.LogError`, `CoreLogger.LogWarning`, or
`CoreLogger.LogInfo` based on the `MessageState` of the incoming
message, improving log clarity and severity categorization.
Previously, any logging sent to LogMessage (which is exposed in the
toolkit) would only be written when debugging. Any error/warning/info
messages sent as part of the normal operation would be bypassed because
it only used `CoreLogger.LogDebug`
Now extension developers can log errors/warnings and use PowerToys log
export / bug report feature to help their users provide them with
actionable data to make their extensions better.
(this PR is an updated version of #43784)
This PR adds a new type of page to Command Palette:
The `ParametersPage`.
This allows extensions to create commands that require a set of
parameters
before invoking the command. Previously, extensions could create
commands with a
form page to use an adaptive card for parameter input, but that was a
relatively
heavyweight UX.
Instead, the `ParametersPage` allows extensions to define a set of
lightweight
inputs, which allows for a more streamlined experience.
The parameters page is made up of a set of "runs". Each run represents a
single element in the search box. Runs can be either:
* A label run: a static piece of text
* An value run: some input for the user to provide a value. These fall
into several categories:
* String input
* Command Input
* `IInvokableCommand`s become buttons in the search box
* `IListPage`s become a list input to pick from (**these will be added
in a follow-up PR**)
There are a ton of samples included.
I also added all my draft notes in the drafts folder, to see how we got
here.
I'd skip reviewing those.
Furthermore, I added the "dumb" token support, where an extension can
opt in to
having tokens in the search box, delimited by ZWSP characters.
The XAML styling was fixed by Niels a few months back
Closes#40948
---------
Co-authored-by: Niels Laute <niels.laute@live.nl>
## Summary
Adds a **Hide app descriptions** toggle setting to the Command Palette
All Apps extension. When enabled, the descriptive subtitle text next to
app results is hidden for a cleaner look.
### Changes
| File | Change |
|------|--------|
| `AllAppsSettings.cs` | New `HideAppDescriptions` `ToggleSetting`
(default: `false`), following the existing `EnableStartMenuSource`
pattern |
| `AllAppsPage.cs` | Conditionally clears `Subtitle` on each
`AppListItem` in `GetPrograms()` when setting is enabled |
| `Resources.resx` / `Resources.Designer.cs` | Resource strings for the
setting label and description |
| `AllAppsPageTests.cs` | Two new tests verifying subtitle visibility
with setting on/off |
### Validation
- [x] Build clean (exit code 0)
- [x] All 14 unit tests pass (including 2 new tests)
- [x] Setting defaults to `false` (preserves current behavior)
- [x] Empty subtitle renders gracefully (no placeholder shown)
- [x] No ABI breaks — all changes scoped to All Apps extension
Closes#46634
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## Summary
Fixes#46810 — When navigating backward in CmdPal (Esc/Backspace), the
bottom command bar retained stale commands from the previous page until
the user changed selection.
## Root Cause
In `ListPage.xaml.cs` `OnNavigatedTo()`, the back-navigation path sets
selection using `SuppressSelectionChangedScope()`, which prevents
`Items_SelectionChanged` from firing. This means `PushSelectionToVm()`
is never called, so `UpdateCommandBarMessage` is never sent to
`CommandBarViewModel`, and the command bar displays stale state.
## Fix
Added `PushSelectionToVm()` after the selection restoration block inside
the back-navigation dispatcher callback. This is safe because:
- `PushSelectionToVm()` is idempotent (guards with
`ReferenceEquals(_lastPushedToVm, li)`)
- Handles both selected items (pushes to VM) and no selection (sends
null)
- Triggers `UpdateCommandBarMessage` which refreshes the command bar
## Validation
### Manual Test Steps
| Scenario | Expected |
|----------|----------|
| **Esc navigation** — Navigate into nested page, press Esc | Bottom bar
commands update immediately to parent page |
| **Backspace navigation** — Navigate into nested page, press Backspace
| Bottom bar commands update immediately to parent page |
| **Forward navigation** — Navigate forward into a page | Commands
update (no regression) |
| **Selection change** — Change selection on any page | Commands update
(no regression) |
| **No flicker** — Navigate back and observe command bar | Single clean
update, no double-fire |
| **Empty page** — Navigate back to page with no selectable items |
Graceful handling, no crash |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## Summary
Fixes the pluralization bug in Command Palette settings where extensions
with a single command displayed "1 commands" and "1 fallback commands"
instead of the correct singular forms.
### Changes
**`ProviderSettingsViewModel.cs`** — Rewrote the `ExtensionSubtext`
property to use tuple pattern matching that selects the correct
singular/plural format string based on whether command count and
fallback count equal 1.
**`Resources.resx`** — Added 4 new resource strings for singular form
combinations:
- `builtin_extension_subtext_singular` — "{0}, {1} command"
- `builtin_extension_subtext_with_fallback_singular_command` — "{0}, {1}
command, {2} fallback commands"
- `builtin_extension_subtext_with_fallback_singular_fallback` — "{0},
{1} commands, {2} fallback command"
- `builtin_extension_subtext_with_fallback_singular_both` — "{0}, {1}
command, {2} fallback command"
**`ProviderSettingsViewModelPluralizationTests.cs`** — 17 new test cases
covering all singular/plural combinations for command and fallback
command counts.
### Validation
- [x] Matches existing `CompositeFormat` pattern used elsewhere in
CmdPal
- [x] Follows `.editorconfig` and StyleCop conventions
- [x] All files within `CommandPalette.slnf` scope
Closes#47110
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Diagnostic / prototype fix for the LNK2038 C++/WinRT version mismatch
that has been failing PowerToys CI on every batched-CI run since commit
`59eefd9581` (5/14):
`
SettingsAPI.lib(settings_objects.obj): error LNK2038: mismatch detected
for 'C++/WinRT version':
value '2.0.250303.1' doesn't match value '2.0.250303.5' in main.obj
[src/modules/GrabAndMove/GrabAndMove/GrabAndMove.vcxproj]
`
## Root cause
GrabAndMove.vcxproj does not import the `Microsoft.Windows.CppWinRT`
NuGet package, so `main.cpp` picks up `<winrt/Windows.Foundation.h>`
(included transitively via `SettingsAPI/settings_objects.h` ->
`common/utils/json.h`) from the **Windows SDK's in-box CppWinRT**
instead of the repo-pinned NuGet version.
After the SHINE-VS18-Latest agent image picked up a newer Windows SDK
shipping `CppWinRT 2.0.250303.5`, `main.obj` began emitting that version
via `#pragma detect_mismatch`, while `SettingsAPI.lib` continued to be
built against the pinned NuGet `2.0.250303.1`. The linker rejects the
mix.
This was masked while the agent SDK happened to ship a matching CppWinRT
version, and surfaced after #47470 (Bump WindowsAppSDK to 2.0.1) plus
the agent image roll.
## Fix
Mirror the canonical CppWinRT NuGet wiring used by every other native
vcxproj in the repo (see `src/common/SettingsAPI/SettingsAPI.vcxproj`
for the reference pattern):
- Add `packages.config` pinning `Microsoft.Windows.CppWinRT
2.0.250303.1`.
- Import the props after `Microsoft.Cpp.Default.props`.
- Import the targets in an `ExtensionTargets` `ImportGroup`.
- Add `EnsureNuGetPackageBuildImports` for restore-time validation.
## Validation
- Local x64/Release build of GrabAndMove.vcxproj clean (linked against
SettingsAPI.lib without LNK2038).
- (Local SDK on the dev box already ships matching CppWinRT
2.0.250303.1, so the LNK2038 cannot reproduce locally; the CI pool agent
has the newer SDK that exposes the latent issue.)
- Awaiting PowerToys CI to confirm fix on the agent image.
## Related
- #47470 (Bump WindowsAppSDK to 2.0.1) — preceded but did not directly
cause this; just changed which CppWinRT was sitting in the include path.
- Failing CI runs: 319304, 319351, 319593 (all on shine-oss PowerToys CI
definition 3).
## Summary of the Pull Request
Prevents users from clearing the name field in ImageResizer size preset
edit dialog. Empty names made the UI confusing without causing errors.
## PR Checklist
- [ ] **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
- [x] **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
Added validation guard in `ImageSize.Name` property setter:
```csharp
public string Name
{
get => _name;
set
{
if (!string.IsNullOrWhiteSpace(value))
{
SetProperty(ref _name, value);
}
}
}
```
Invalid assignments (empty, null, whitespace) are silently ignored,
preserving the existing value. This matches the existing pattern used
for `FileName` validation in `ImageResizerViewModel`.
TwoWay binding in UI causes the TextBox to revert when users attempt to
clear the field—standard behavior for required fields.
## Validation Steps Performed
- Added unit test `ImageSizeNameShouldNotBeSetToEmptyOrNull()` covering
all rejection and acceptance cases
- Verified silent rejection behavior matches `FileName` property pattern
> [!WARNING]
>
> <details>
> <summary>Firewall rules blocked me from connecting to one or more
addresses (expand for details)</summary>
>
> #### I tried to connect to the following addresses, but was blocked by
firewall rules:
>
> - `i1qvsblobprodcus353.vsblob.vsassets.io`
> - Triggering command: `/usr/bin/dotnet dotnet build
/home/REDACTED/work/PowerToys/PowerToys/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Registry/Helpers/ResultHelper.cs
/home/REDACTED/work/PowerToys/PowerToys/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Registry/Helpers/RegistryHelper.cs
/home/REDACTED/work/PowerToys/PowerToys/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Registry/Enumerations/TruncateSide.cs
/home/REDACTED/work/PowerToys/PowerToys/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Registry/Constants/KeyName.cs
/home/REDACTED/work/PowerToys/PowerToys/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Registry/Constants/MaxTextLength.cs
/home/REDACTED/work/PowerToys/PowerToys/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Registry/Commands/CopyRegistryInfoCommand.cs
/home/REDACTED/work/PowerToys/PowerToys/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Registry/Commands/OpenKeyInEditorCommand.cs
/home/REDACTED/work/PowerToys/PowerToys/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Re
/home/REDACTED/work/PowerToys/PowerToys/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Registry/CopyType.cs
/home/REDACTED/work/PowerToys/PowerToys/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Registry/Icons.cs`
(dns block)
>
> If you need me to access, download, or install something from one of
these locations, you can either:
>
> - Configure [Actions setup
steps](https://gh.io/copilot/actions-setup-steps) to set up my
environment, which run before the firewall is enabled
> - Add the appropriate URLs or hosts to the custom allowlist in this
repository's [Copilot coding agent
settings](https://github.com/microsoft/PowerToys/settings/copilot/coding_agent)
(admins only)
>
> </details>
<!-- START COPILOT ORIGINAL PROMPT -->
<details>
<summary>Original prompt</summary>
>
> ----
>
> *This section details on the original issue you should resolve*
>
> <issue_title>[Settings: ImageResizer] Edit size dialog: Add validation
against empty name</issue_title>
> <issue_description>There is one small thing we should add. (But I
don't know how.)
> The data in the name field of the edit dialog should be validated
against `.NullOrEmpty`!
> _Originally posted by @htcfreek in
https://github.com/microsoft/PowerToys/pull/13285#issuecomment-924113251_
>
> **Detailed description:**
> While users edit an image size in the ImageResizer settings on PT's
settings ux they are able to clear the name of the image size. This
doesn't lead to errors/exceptions, but it also doesn't make sense to
have sizes without a name. So we should prevent user from doing this in
the edit dialog.
>
> _**Note:**_
> This is the second and last change that is needed to prevent the users
from having incorrect image size settings (#8698). But I think this is
not as relevant, because a missing name won't break image resizing._
>
> ---
>
> cc: @niels9001 </issue_description>
>
> <agent_instructions>Implement a proper fix for this issue. Do NOT
create placeholder stub files. Create actual working code that addresses
the issue described. Follow PowerToys coding guidelines and
conventions.</agent_instructions>
>
> ## Comments on the Issue (you are @copilot in this section)
>
> <comments>
> <comment_new><author>@TheJoeFin</author><body>
> does this issue still happen with v0.73.0?
/needinfo</body></comment_new>
> </comments>
>
</details>
<!-- START COPILOT CODING AGENT SUFFIX -->
- Fixesmicrosoft/PowerToys#13336
<!-- START COPILOT CODING AGENT TIPS -->
---
✨ Let Copilot coding agent [set things up for
you](https://github.com/microsoft/PowerToys/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot)
— coding agent works faster and does higher quality work when set up for
your repo.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: yeelam-gordon <73506701+yeelam-gordon@users.noreply.github.com>
## Summary of the Pull Request
Two related installer changes to (1) eliminate genuinely-unused
dependencies and (2) deduplicate shared WinAppSDK files between
`<install>\` and `<install>\WinUI3Apps\` to shrink the installer
download.
### 1. Remove unused dependencies (~11 MB savings per output location)
- **System.Data.SqlClient**: Removed from MouseWithoutBorders projects
and the central `Directory.Packages.props` pin. It was a transitive
dependency of `Microsoft.Windows.Compatibility` but PowerToys has zero
SQL database usage.
- **Unused `using` import**: Removed `using
System.ServiceModel.Channels` from MouseWithoutBorders `Program.cs` (no
WCF usage).
- **MFC / C++ AMP / OpenMP DLLs**: Added `RemoveUnusedVCRuntimeDlls`
target in `Directory.Build.targets` to clean up `mfc140*`, `mfcm140*`,
`vcamp140*`, and `vcomp140*` DLLs that leak from the VC++
Redistributable tree but are not imported by any PowerToys binary
(verified with `dumpbin /dependents` across all installed binaries).
Also excluded MFC DLLs from installer file collection.
### 2. WinAppSDK file deduplication (build-time only; install-time uses
copy)
**Background**: The `WinUI3Apps` subfolder must remain a real directory
because MSIX sparse package registration applies DACL changes to the
`ExternalLocation` folder (PR #47177). Flattening is not viable.
**Build-time** (`generateAllFileComponents.ps1`): computes the SHA256
intersection of root and `WinUI3Apps` files, and for each file that is
also present in the BaseApplications WXS file list, removes the
duplicate from the WinUI3Apps WXS component list and writes its name to
a `hardlinks.txt` manifest. The BaseApplications cross-check ensures we
never deduplicate a file the MSI does not actually deploy at the install
root, which would otherwise leave both copies missing post-install. The
manifest is written as UTF-8 without BOM (via
`[System.IO.File]::WriteAllLines` with `UTF8Encoding($false)`) so its
encoding is identical regardless of the build host's PowerShell version.
This step produces the **MSI download-size win** (~97 MB smaller cab;
LZX:21 was already deduplicating most byte-identical content
automatically inside the cab).
**Install-time** (`CreateWinAppSDKHardlinksCA` custom action):
- Reads `hardlinks.txt` after `InstallFiles` as a raw byte stream and
converts each line to a `std::wstring` via `MultiByteToWideChar(CP_UTF8,
MB_ERR_INVALID_CHARS, ...)`. Avoids `std::wifstream`'s ANSI-codepage
codecvt so non-ASCII paths can never be silently mangled.
- For each entry, computes `(installDir / fileName).lexically_normal()`
and `(winui3Dir / fileName).lexically_normal()`, then verifies via
`std::mismatch` that each resolved path is still rooted at its
respective folder. Manifest entries containing `..`, absolute paths, or
alternate-stream syntax are logged and skipped.
- Materialises each validated entry from `<install>\<name>` into
`<install>\WinUI3Apps\<name>` via `fs::copy_file` (overwrite_existing).
- Reports the per-file copy / failure counts to the install log. If
every entry failed (`created == 0 && failed > 0`), the CA escalates to
`E_FAIL` so the install does not silently succeed with an unusable
WinUI3Apps tree.
`DeleteWinAppSDKHardlinksCA` removes the materialised copies before
`RemoveFiles` on uninstall, using the same UTF-8 reader and per-entry
containment check.
**WiX sequencing**: `CreateWinAppSDKHardlinks` runs
`After="InstallFiles"` with `Condition="NOT Installed OR
WIX_UPGRADE_DETECTED OR REINSTALL"` so a `msiexec /fa` repair refreshes
the deduplicated copies (otherwise `RemoveFiles` would orphan them).
#### Why copy and not hard-link
A hard-linked variant of this CA was originally proposed but caused a
Monaco preview-handler regression. Hard-links share an NTFS inode (and
therefore one DACL) between `<install>\<file>` and
`<install>\WinUI3Apps\<file>`. The MSIX sparse-package registrations for
PowerRename / ImageResizer / FileLocksmith / NewPlus run after the dedup
CA and propagate the `WinUI3Apps` parent's rich DACL (Capability SID, 5×
Package SIDs, 5× conditional SYSAPPID ACE, RC SID) onto the shared
inode. The root path then also exposes the rich DACL, which trips a
kernel "stricter access evaluation" path that blocks the LOW-IL
`prevhost.exe` from `LoadLibrary`-ing `hostfxr.dll` (and the rest of the
.NET runtime), turning the Monaco preview pane blank for `.json` / `.md`
/ `.cs` / `.xaml` / `.svg` / `.xml` files.
`fs::copy_file` creates a **fresh inode** for the WinUI3Apps copy. The
root inode keeps its simple DACL (`SY:F + BA:F + owner:F` + inherited
`BU:RX`) so LOW-IL `prevhost.exe` can still load it — Monaco preview
works. The WinUI3Apps copy inherits the WinUI3Apps parent's rich DACL
via normal NTFS inheritance (matches 0.99.1 behaviour exactly) — MSIX
context-menu shells continue to work.
#### Trade-off
| Metric | Hard-link variant (rejected) | This PR (file copy) | 0.99.1
(no dedup) |
|---|---|---|---|
| MSI size | ~296 MB | ~296 MB | ~393 MB |
| On-disk after install | ~2,475 MB | ~2,772 MB | ~2,772 MB |
| DACL contamination risk | YES (broke Monaco) | NO | NO |
The on-disk savings (~297 MB) are given up in exchange for eliminating
the DACL contamination risk; the **installer download savings (~97 MB)**
are preserved by the build-time WiX/cab dedup.
#### Edge cases handled
- Empty duplicate list: `hardlinks.txt` always written, CA handles
empty.
- All files duplicated: `Generate-FileComponents` returns early for
empty list.
- File stripped from BaseApplications by an earlier build step:
BaseApplications cross-check skips it during dedup so neither copy goes
missing.
- Manifest entry escapes install root (`..`, absolute path): rejected
per-entry, install continues.
- Manifest line is non-UTF-8: rejected per-entry, install continues.
- Source missing at install time: per-entry skip, install continues.
- All copies fail: install aborts loudly via `E_FAIL` (catastrophic-case
escalation).
- Upgrade or `msiexec /fa` repair: CA fires (`NOT Installed OR
WIX_UPGRADE_DETECTED OR REINSTALL`).
**MSI repair risk**: Burn bundle uses `SuppressRepair=yes` and
`MajorUpgrade` (full uninstall + reinstall) for all version upgrades, so
the standard upgrade path is unaffected. The `OR REINSTALL` clause
covers power users running `msiexec /fa` directly.
## PR Checklist
- [x] **Communication:** Discussed approach via PRs #46866, #47177,
#46745
- [ ] **Tests:** Installer infrastructure only — no runtime behaviour
changes
- [ ] **Localization:** N/A
- [ ] **Dev docs:** N/A
- [ ] **New binaries:** N/A
## Detailed Description of the Pull Request / Additional comments
Based on the approach from PR #46745 by @yeelam-gordon, rebased onto
latest main and switched from hard-links to file copies after the DACL
contamination root cause was identified. Hardening (UTF-8 read, path
containment, catastrophic-case escalation, REINSTALL repair,
BaseApplications-filtered dedup) added in response to review feedback.
These changes are purely build/installer infrastructure — no runtime
behaviour changes to any PowerToys module.
## Validation Steps Performed
Validated on a 0.99.4 / 0.99.5 local install (per-user
`%LocalAppData%\PowerToys`):
- ✅ `dumpbin /dependents` across the installed PowerToys tree confirmed
zero binaries import `mfc140*`, `mfcm140*`, `vcamp140*`, or `vcomp140*`
— the cleanup target removes ~11 MB of genuinely unused VC runtime DLLs.
- ✅ `System.Data.SqlClient` has zero call-sites in PowerToys source.
- ✅ Local installer build produces a 296 MB MSI (down from 393 MB
pre-dedup, ~97 MB cab savings purely from the build-time WiX dedup).
- ✅ MSI table inspection (`wix msi decompile`) confirms the deferred CAs
are present (`CreateWinAppSDKHardlinks`, `DeleteWinAppSDKHardlinks`) and
the `hardlinks.txt` File row is registered.
- ✅ MSI table inspection confirms .NET runtime DLLs (`hostfxr.dll`,
`coreclr.dll`, `hostpolicy.dll`, `clretwrc.dll`, `Accessibility.dll`,
`backup_restore_settings.json`) appear ONLY in
`BaseApplicationsFiles_File_*`, NOT in `WinUI3ApplicationsFiles_File_*`
— proving the build-time dedup worked.
- ✅ Post-install verification: deduplicated files materialised at both
root and WinUI3Apps with byte-identical SHA256 hashes, and `fsutil
hardlink list` returns link-count == 1 for each — proving the
install-time copy approach worked, not hard-link.
- ✅ DACL on root .NET runtime DLLs is clean: no Package SID, no
Capability SID, no SYSAPPID conditional ACE, no `ALL APPLICATION
PACKAGES` ACE — Monaco preview load path is safe.
- ✅ DACL on WinUI3Apps copies has the rich MSIX inheritance —
context-menu shells continue to work (matches 0.99.1).
- ✅ All four MSIX sparse packages (PowerRename, ImageResizer,
FileLocksmith, NewPlus) registered after install.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## Summary
Fixes the `Auto-label Issues by Area` workflow, which currently logs
`GITHUB_TOKEN is not set; skipping.` on every run and never applies
labels.
Failing run on issue #47818:
https://github.com/microsoft/PowerToys/actions/runs/25722067064/job/75525452318
## Root cause
`actions/github-script@v7` consumes its `github-token` input only to
authenticate the injected `github` Octokit object. It does **not**
export that value to `process.env.GITHUB_TOKEN`. The inline script reads
`process.env.GITHUB_TOKEN` to authorize a direct `fetch()` against
`https://models.inference.ai.azure.com/chat/completions`, so the token
check at the top of `labelIssue()` always fails and the function returns
early before calling the model.
## Fix
Add a step-level `env:` block exposing `GITHUB_TOKEN` to the Node
process running the inline script. The existing `with.github-token`
input is preserved so the injected `github` Octokit continues to
authenticate.
`yaml
- name: Apply area labels with AI
uses: actions/github-script@v7
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
`
5 lines added, 0 removed.
## Security
- `secrets.GITHUB_TOKEN` is the workflow's built-in ephemeral token
(auto-issued per run, auto-revoked at job end). Not a PAT.
- Scope is already constrained by `permissions: models: read, issues:
write` at the top of the workflow. No widening.
- Exposure is unchanged: the token is already loaded into the same Node
process by `actions/github-script` via `github-token:`. The `env:`
mapping just lets the script body read what the action already has in
the same process.
- The token is sent only to GitHub's own GitHub Models inference
endpoint, which is the documented use of `models: read`.
- Triggers are safe: `issues: opened/reopened` (issue body is
JSON-encoded into the request body, never interpolated into a shell) and
`workflow_dispatch` (write-access required).
- Token is never logged.
## Validation
After merge, re-run the workflow on issue #47818 via Actions ->
"Auto-label Issues by Area" -> Run workflow, and confirm logs show
`Model response: ...` instead of `GITHUB_TOKEN is not set; skipping.`
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## Summary of the Pull Request
Adds the **Extension Gallery** to Command Palette — a built-in page
where users can discover, browse, and install community extensions
without leaving the app.
https://github.com/user-attachments/assets/e4565333-b970-4085-9e40-5cfd207e533b
## How it works
### 1. The extension author's side
Extensions are listed in the external repo
**[`microsoft/CmdPal-Extensions`](https://github.com/microsoft/CmdPal-Extensions)**.
To get an extension into the in-app gallery, an author opens a PR there
that adds a single entry to `extensions.json`. Nothing in PowerToys
itself needs to change. A typical entry looks like:
```json
{
"id": "contoso.sample",
"title": "Sample Extension",
"description": "Short blurb shown in the list and detail view.",
"author": { "name": "Contoso", "url": "https://github.com/contoso" },
"homepage": "https://github.com/contoso/sample",
"iconUrl": "https://.../icon.png",
"screenshotUrls": ["https://.../screenshot-1.png"],
"tags": ["sample"],
"installSources": [
{ "type": "winget", "id": "Contoso.SampleExtension" },
{ "type": "msstore", "id": "9P..." },
{ "type": "url", "uri": "https://github.com/contoso/sample/releases/latest" }
],
"detection": { "packageFamilyName": "Contoso.SampleExtension_8wekyb..." }
}
```
- `id`, `title`, `description`, `author.name`, and at least one
`installSources` entry are required; everything else is optional.
- `installSources` can mix and match `winget` / `msstore` / `url`. The
gallery shows an install button for the first source it can handle
(WinGet preferred) and exposes any remaining sources as links.
- `detection.packageFamilyName` lets CmdPal recognise an
already-installed packaged extension before any WinGet lookup resolves,
so the "Installed" badge appears instantly.
Once the PR is merged into `CmdPal-Extensions`, every running copy of
CmdPal picks the new entry up the next time its feed cache expires
(within 4 hours) or when the user clicks **Refresh**.
### 2. What CmdPal does with it
`ExtensionGalleryService` (in `Microsoft.CmdPal.Common`) owns the whole
pipeline:
1. **Resolve the feed URL.** Default is
`https://raw.githubusercontent.com/microsoft/CmdPal-Extensions/refs/heads/main/extensions.json`.
A hidden setting (`GalleryFeedUrl`) lets developers point at a custom
URL or a `file://` path for local testing.
2. **Fetch** the feed through `ExtensionGalleryHttpClient`, which wraps
`HttpCachingClient` — a conditional-GET + on-disk cache layer built on
`HttpClient` (ETag / `If-None-Match`, 30 s timeout, UA
`PowerToys-CmdPal/1.0`).
3. **Parse** with the source-generated `GallerySerializationContext`
into a strongly-typed `GalleryRemoteIndex` (`{ "extensions": [ ... ]
}`). Entries without an `id` are dropped.
4. **Normalize** relative `iconUrl` / `screenshotUrls` against the feed
URL (useful for local `file://` feeds).
5. **Localize icons.** Each HTTP icon URL is pulled through the same
cache and rewritten to a local `file://` URI before the view model binds
to it, so the list renders instantly on subsequent loads and works
offline.
6. **Prune** cached resources that are no longer referenced, but only
after a successful forced refresh.
The gallery page itself is built on top of `ExtensionGalleryViewModel`,
with `ExtensionGalleryItemViewModel` handling per-entry concerns —
install/update/uninstall (via the shared WinGet service),
installed-state detection, and joining in-flight install progress so the
global `WinGetOperationsButton` in the top bar stays in sync.
### 3. Caching + offline behaviour
The cache lives under
`ApplicationData.Current.LocalCacheFolder\GalleryCache\` when CmdPal
runs packaged, or
`%LOCALAPPDATA%\Microsoft\PowerToys\Microsoft.CmdPal\Cache\GalleryCache\`
when unpackaged.
| Resource | TTL |
|-----------------|----------|
| `extensions.json` feed | 4 hours |
| Icons (per URL) | 24 hours |
Each fetch returns a `GalleryFetchResult` whose flags drive the UI:
- `FromCache` — cache was still fresh, no network call was made.
- `UsedFallbackCache` — network failed; the last-known-good cached copy
was served instead. The page shows a "showing cached data" info bar.
- `RateLimited` — origin returned `429` and no fallback was available.
The page shows a rate-limit error.
`RefreshAsync` (wired up to the gallery's refresh button) forces a fresh
conditional GET, then prunes any cached files that the new feed no
longer references.
### 4. WinGet install flow
- `installSources[type=winget].id` is handed to the shared WinGet
service for install/update/uninstall.
- In-flight operations are surfaced by `WinGetOperationsButton` in the
top bar with per-operation progress.
- `detection.packageFamilyName` is consulted first so that the gallery
can show "Installed" / "Update available" without waiting on WinGet
metadata.
### Top-level command cleanup
- Removed the separate "Find extensions from WinGet" and "Find
extensions from the Store" top-level commands — the gallery replaces
both.
- Renamed the gallery command to **"Find and install Command Palette
extensions"** and gave it the extensions puzzle-piece icon.
## PR Checklist
- [ ] **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
## New projects / areas
| Area | What |
|------|------|
| Microsoft.CmdPal.Common | Gallery models, `ExtensionGalleryService`
(fetch + cache), HTTP caching layer (`HttpCachingClient`,
`FileSystemHttpResourceCacheStore`), WinGet service abstractions and
implementations |
| Microsoft.CmdPal.UI.ViewModels | `ExtensionGalleryViewModel`,
`ExtensionGalleryItemViewModel`, WinGet operation view models, gallery
sort options |
| Microsoft.CmdPal.UI | `ExtensionGalleryPage.xaml`,
`ExtensionGalleryItemPage.xaml`, `IconCarouselControl`,
`WinGetOperationsButton`, service registrations |
| Microsoft.CmdPal.Ext.WinGet | Streamlined — removed the two redundant
"find extensions" top-level commands, kept the general WinGet search
page |
| Tests | Unit tests for gallery service, gallery view models, WinGet
services |
| Docs |
[`doc/devdocs/modules/cmdpal/extension-gallery/extension-gallery.md`](https://github.com/microsoft/PowerToys/blob/dev/jpolasek/f/46628-cmdpal-extension-gallery/doc/devdocs/modules/cmdpal/extension-gallery/extension-gallery.md)
— dev reference for the runtime, caching, and feed shape |
## Validation Steps Performed
- Gallery loads and displays extensions from the remote index
- Search, sort, and filtering work as expected
- WinGet install/update/uninstall flow works end-to-end with progress
tracking
- Loading state correctly hides all content until data is fetched
- Offline / cache-fallback path surfaces the info bar as expected
- Spell-check CI workflow passes
---------
Co-authored-by: Niels Laute <niels.laute@live.nl>
Co-authored-by: niels9001 <9866362+niels9001@users.noreply.github.com>
## Summary of the Pull Request
The Calculator components in Command Palette and Run produced incorrect
results or errors for `log` and `ln` inputs where spaces exist between
the function name and the argument list. This is because input
validation allowed for those spaces, but this was not respected in the
log mapping code which transforms user input into a string for
consumption by the expression evaluator engine.
The result of this is discrepancy was that:
- Natural log would be called instead of log base 10 for `log (n)`.
- An error would be shown for `ln (n)`.
For example:
<img width="556" height="166" alt="image"
src="https://github.com/user-attachments/assets/d2110292-ca8f-4635-bdef-9fa4f2211deb"
/>
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [x] Closes: #47759
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [ ] **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
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
The issue was with this code:
a650504640/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/CalculateEngine.cs (L56-L58)
This maps user input such as `log(10)` or `ln(10)` to the functions the
back-end expression evaluator understands. For Mages and ExprTK, this is
mapped to `log10(n)` for base 10 logs or `log(n)` for natural logs.
Unfortunately, the input validator regex allows for spaces between the
function name and the start of the argument list, and the string replace
does not. When spaces exist:
- For `log (n)` - the log10 match is missed and the expression is
interpreted as a natural log, producing incorrect results.
- For `ln (n)` - the string is passed as-is to the back-end. Neither
Mages nor ExprTK recognise it, so an error is returned.
The fix is to replace the string replacement code with two regexes.
These are both forgiving of spaces between the function name and
argument list:
For log base 10: `"log(?![0-9])\\s*\\("`
For natural log: `"ln\\s*\\("`
Both are culture-agnostic and have `IgnoreCase` set. I took the
opportunity to remove the "en-US" culture from the
`DivisionByZeroRegex`, as it is not required.
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Added unit tests which ensure the log and ln functions perform
identically with or without spaces. Confirmed all unit tests for Command
Palette and Run still pass.
Manually confirmed that `log` and `ln` now produce correct results in
both applications.
## Problem
The scheduled UI Test Automation pipeline
([Dart/161438](https://microsoft.visualstudio.com/Dart/_build?definitionId=161438))
has been failing daily since 2026-04-30 because PR #41280 (`.NET 10
Upgrade`) updated the main build template (`job-build-project.yml`) for
.NET 10 / VS 2026 but the parallel changes were missed in the UI Test
Automation templates.
Symptoms in recent runs (e.g. build
[#20260512.1](https://microsoft.visualstudio.com/Dart/_build/results?buildId=146803928)):
```
error NETSDK1045: The current .NET SDK does not support targeting .NET 10.0.
Either target .NET 9.0 or lower, or use a version of the .NET SDK that supports .NET 10.0.
```
…emitted ×179 across every csproj during the *Restore solution-level
NuGet packages* step on both `Build UI Tests Only Release_x64` and
`…_arm64` jobs.
## Changes
This PR mirrors the two pipeline changes that PR #41280 already applied
to the main CI templates.
**1. Install the .NET 10 SDK on the build agent**
- File: `.pipelines/v2/templates/job-build-ui-tests.yml`
- Bump the pinned `steps-ensure-dotnet-version.yml` parameter from
`version: '9.0'` → `'10.0'`.
- Matches `job-build-project.yml`, which already installs the .NET 10
SDK alongside 6.0/8.0.
**2. Pin the build agent image to VS 2026 (MSBuild 18)**
- File: `.pipelines/v2/templates/pipeline-ui-tests-official-build.yml`
- Add `demands: ImageOverride -equals SHINE-VS18-Latest` to the agent
pool spec.
- The .NET 10 SDK (≥ 10.0.300) requires MSBuild 18, which only ships
with VS 2026. Without this demand, the SHINE pool selects a default
image with VS 2022 / MSBuild 17 and restore fails with `MSB4236: The SDK
'Microsoft.NET.Sdk' specified could not be found`.
- Mirrors the unconditional pattern in `pipeline-ci-build.yml` (lines
56–67), which applies the same demand across both `SHINE-INT-L` and
`SHINE-OSS-L` pools.
## Validation
Queued pipeline 161438 against this branch:
| Build | Commit | Result |
| --- | --- | --- |
|
[`146821554`](https://microsoft.visualstudio.com/Dart/_build/results?buildId=146821554)
| `4dd13b9` (SDK fix only) | `NETSDK1045` gone ✅ — exposed VS 2022 /
MSBuild 17 mismatch |
|
[`146825355`](https://microsoft.visualstudio.com/Dart/_build/results?buildId=146825355)
| `97cadbb` (SDK + agent demand) | Both errors gone ✅ — agent now
`Visual Studio\18\Enterprise\` |
After this PR, the pipeline reaches NuGet restore and now hits a
separate, **pre-existing** issue from the April 13–29 failure window:
`401 Unauthorized` on the `shine-oss/PowerToysPublicDependencies`
Artifacts feed for newly-released `Microsoft.NETCore.App.*/8.0.27`
packages. That requires feed-admin action (granting the Dart pipeline
build identity "save from upstream" on the feed, or pre-seeding those
package versions) and is **out of scope for this PR**.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## Summary
Two related changes to the `release-note-generation` agent skill:
### 1. Step 3 reviews: use the local agent instead of
`mcp_github_request_copilot_review`
Step 3.1 previously instructed the agent to call
`mcp_github_request_copilot_review` for every milestone PR so that the
`CopilotSummary` column in `sorted_prs.csv` would be populated by the
GitHub-side Copilot bot.
When this skill is driven from a CLI / coding agent, that request comes
from a bot identity, and the GitHub API rejects it (`Bot reviewers
cannot be requested`). The PR ends up with no Copilot review and
`CopilotSummary` stays empty.
`references/step3-review-grouping.md` has been rewritten to instead have
**the local agent** that is running the skill perform the review itself:
- Fetch each PR's diff with a non-mutating tool
(`mcp_github_pull_request_read` `get_diff` / `get_files`, or `gh pr
diff`).
- Produce a 1-3 sentence user-facing summary in the same style as a
Copilot PR review.
- Write the summary directly into the `CopilotSummary` column of
`Generated Files/ReleaseNotes/sorted_prs.csv`, preserving row order and
skipping rows that already have a non-empty summary.
Step 3.2 (re-run `dump-prs-since-commit.ps1`) is demoted to optional,
with a note that re-running the dump will overwrite the
locally-generated summaries.
`SKILL.md` was updated to match: front-matter description, "When to
Use", workflow diagram, the 3.1-3.3 row in the summary table,
prerequisites (no longer requires "GitHub Copilot code review enabled
for the org/repo"; mentions MCP for fetching diffs), and the
troubleshooting row for empty `CopilotSummary` now points at Step 3.1
with the bot-rejection caveat.
### 2. Vendor `prepare-release-assets.ps1` into the skill
Added `scripts/prepare-release-assets.ps1` -- previously kept in
OneDrive at `Tools/prepare-release.ps1`. Renamed because the script does
more than download installers: it also pulls per-arch symbol archives,
computes SHA256, and emits the **Installer Hashes** markdown table for
the GitHub release page. "Release assets" captures all of that.
Header `.SYNOPSIS` / `.DESCRIPTION` / `.EXAMPLE` blocks were updated to
reflect the new filename and the symbol-archive behavior (the original
synopsis only mentioned installers).
`SKILL.md` registers the new script in the "Available Scripts" table,
lists Azure CLI + the `azure-devops` extension as a prerequisite (only
when running this script), adds a "Prepare GitHub release assets" entry
to "When to Use", and adds a troubleshooting row for the most common
failure (`Failed to acquire ADO access token` -> `az login`).
## Files changed
| File | Change |
|------|--------|
| `.github/skills/release-note-generation/SKILL.md` | Updated
description, prerequisites, workflow, scripts table, troubleshooting |
|
`.github/skills/release-note-generation/references/step3-review-grouping.md`
| Rewritten to use local-agent review; demoted refresh step |
|
`.github/skills/release-note-generation/scripts/prepare-release-assets.ps1`
| New (vendored from OneDrive) |
## Validation
- PowerShell parser ([`Parser]::ParseFile`) reports no errors on the new
script.
- Documentation-only / scripts-only change -- no product code touched,
so the standard PowerToys build / test gates do not apply.
- The change preserves the existing CSV schema (`Id, Title, Labels,
Author, Url, Body, CopilotSummary, NeedThanks`), so downstream Step 3.3
(`group-prs-by-label.ps1`) and Step 4 summarization continue to work
without modification.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
1. Adds an opt-in Max compatibility mode in PowerDisplay's Advanced
settings. When enabled, DDC discovery probes monitors that don't
advertise capabilities, picking up displays that would otherwise be
skipped.
2. Toggling the setting triggers an immediate rescan via a new
RescanPowerDisplayMonitorsEvent IPC event from Settings to PowerDisplay.
3. Hides the brightness slider on monitors that lack VCP 0x10.
Also fixed animation issue #47868
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [x] Closes: #47878
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [x] **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
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
---------
Co-authored-by: Yu Leng <yuleng@microsoft.com>
Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
This pull request introduces per-monitor dock customization support and
refactors how dock band settings are managed to enable independent
layouts on different monitors. The changes add a new
`DockMonitorConfigViewModel` for monitor-specific configuration, update
`DockViewModel` to handle per-monitor band lists and settings, and
refactor band movement and ordering logic to respect per-monitor
overrides.
**Per-monitor dock customization:**
* Added `DockMonitorConfigViewModel` to encapsulate the configuration
and state for each monitor, exposing properties for binding and
persisting changes using `ISettingsService`.
* Updated `DockViewModel` to track an optional `MonitorDeviceId`,
enabling docks to be associated with a specific monitor and to expose
per-monitor settings and methods.
[[1]](diffhunk://#diff-b661a9311de64dd1123860e858f1f4963f05ccee06b5bd218916635495b2ff06L17-R33)
[[2]](diffhunk://#diff-b661a9311de64dd1123860e858f1f4963f05ccee06b5bd218916635495b2ff06L41-R56)
**Band management refactor for per-monitor settings:**
* Refactored band retrieval and update logic in `DockViewModel` to use
new helper methods (`GetActiveBands`, `WithActiveBands`) that select and
modify either global or per-monitor band lists as appropriate.
* Updated band movement and ordering methods (`SyncBandPosition`,
`MoveBandWithoutSaving`, `SaveBandOrder`) to operate on the correct band
lists for each monitor, ensuring that changes apply to the intended
scope (global or per-monitor).
[[1]](diffhunk://#diff-b661a9311de64dd1123860e858f1f4963f05ccee06b5bd218916635495b2ff06L205-R399)
[[2]](diffhunk://#diff-b661a9311de64dd1123860e858f1f4963f05ccee06b5bd218916635495b2ff06L250-R413)
[[3]](diffhunk://#diff-b661a9311de64dd1123860e858f1f4963f05ccee06b5bd218916635495b2ff06L263-R424)
[[4]](diffhunk://#diff-b661a9311de64dd1123860e858f1f4963f05ccee06b5bd218916635495b2ff06L280-R437)
[[5]](diffhunk://#diff-b661a9311de64dd1123860e858f1f4963f05ccee06b5bd218916635495b2ff06L290-R447)
[[6]](diffhunk://#diff-b661a9311de64dd1123860e858f1f4963f05ccee06b5bd218916635495b2ff06L300-R465)
[[7]](diffhunk://#diff-b661a9311de64dd1123860e858f1f4963f05ccee06b5bd218916635495b2ff06L329-R491)
**Resource management:**
* Implemented `IDisposable` on `DockViewModel` to clean up event
handlers and prevent resource leaks.
[[1]](diffhunk://#diff-b661a9311de64dd1123860e858f1f4963f05ccee06b5bd218916635495b2ff06L17-R33)
[[2]](diffhunk://#diff-b661a9311de64dd1123860e858f1f4963f05ccee06b5bd218916635495b2ff06R85-R235)
Closes#46939
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Niels Laute <niels.laute@live.nl>
Co-authored-by: Mike Griese <migrie@microsoft.com>
## Summary of the Pull Request
The system-wide CPU counter in the Command Palette Performance monitor
used `% Processor Utility`, which is scaled by `% Processor Performance`
and is intentionally unbounded above 100% when cores boost above their
nominal base frequency. Under load this produced values like 144% in the
dock, as reported in #46381.
Switch to `% Processor Time` — the same counter Task Manager renders —
which is naturally bounded to 0-100%.
The per-process branch is unaffected; it already divides by
`Environment.ProcessorCount` and continues to use `% Processor Time`, so
individual process readings remain correct.
## PR Checklist
- [x] **Closes:** #46381
- [x] **Communication:** I've discussed this with the team/maintainers
via the linked issue.
- [x] **Tests:** Manually tested locally. Built
`Microsoft.CmdPal.Ext.PerformanceMonitor` and the full
`CommandPalette.slnf` (Debug|x64). Verified the built DLL contains `%
Processor Time` and no longer contains `% Processor Utility`.
- [x] **Manual tests:** Ran the rebuilt dev build under sustained CPU
load; the system CPU figure now stays bounded to 100%.
- [x] **Localization:** Not applicable — counter name is an OS API
string, not user-visible text.
## Detailed Description of the Pull Request / Additional comments
`% Processor Utility` is documented by Microsoft as deliberately
unbounded; it represents an "effective" utilization that accounts for
turbo/boost frequencies. It is well-suited for billing/capacity contexts
but not for a "% of CPU used" UI element where users expect a 0-100%
reading consistent with Task Manager and Resource Monitor.
`_procPerformance` (the `% Processor Performance` counter) is retained
because it is still used by `CpuSpeed` to compute the live frequency
display, so removing it would regress the speed readout.
### Before
System CPU dock showed values >100% under load (reported 144% in the
issue).
### After
System CPU dock is bounded to 0-100%, matching Task Manager.
## Summary of the Pull Request
ZoomIt derives three recording hotkeys from one base key via XOR:
fullscreen (base), crop (base XOR Shift), window (base XOR Alt). When
Alt is the sole modifier, `base XOR Alt = 0`, registering a
modifier-less hotkey that captures every bare keypress (e.g., pressing
`5` triggers window recording).
**`Zoomit.cpp`** — 4 hotkey registration sites:
- Guard `RECORD_CROP_HOTKEY` registration behind `(g_RecordToggleMod ^
MOD_SHIFT) != 0`
- Guard `RECORD_WINDOW_HOTKEY` registration behind `(g_RecordToggleMod ^
MOD_ALT) != 0`
```cpp
// Before (all 4 sites):
registerHotkey( RECORD_CROP_HOTKEY, ( g_RecordToggleMod ^ MOD_SHIFT ) | MOD_NOREPEAT, ... );
registerHotkey( RECORD_WINDOW_HOTKEY, ( g_RecordToggleMod ^ MOD_ALT ) | MOD_NOREPEAT, ... );
// After:
if ( g_RecordToggleMod ^ MOD_SHIFT ) {
registerHotkey( RECORD_CROP_HOTKEY, ( g_RecordToggleMod ^ MOD_SHIFT ) | MOD_NOREPEAT, ... );
}
if ( g_RecordToggleMod ^ MOD_ALT ) {
registerHotkey( RECORD_WINDOW_HOTKEY, ( g_RecordToggleMod ^ MOD_ALT ) | MOD_NOREPEAT, ... );
}
```
**`ZoomItViewModel.cs`** — `RecordToggleKeyCrop` /
`RecordToggleKeyWindow` computed properties:
- Return `null` when the derived hotkey would have no modifier keys, so
the Settings UI omits the inapplicable shortcut description rather than
displaying a bare-key shortcut.
## 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
ZoomIt registers crop and window recording variants by XOR-ing the base
modifier with `MOD_SHIFT` and `MOD_ALT` respectively. This design breaks
when the base modifier equals the XOR target — the result is `0`, and
`RegisterHotKey` with no modifiers intercepts every bare keypress of
that key system-wide.
The fix is symmetric across all 4 registration sites (standalone
`registerHotkey()` in `RegisterAllHotkeys`, the legacy dialog OK path,
and two `WM_CREATE`-adjacent paths): skip the derived hotkey
registration when the computed modifier is zero. The Settings UI
ViewModel mirrors this logic by returning `null` for the affected
computed properties, causing the converter to emit an empty string
instead of a modifier-less shortcut label.
## Validation Steps Performed
- Code review confirmed fix is applied consistently across all 4
`RegisterHotKey` call sites in `Zoomit.cpp`
- Verified `HotkeySettingsToLocalizedStringConverter` returns
`string.Empty` for `null` input — no display regression in Settings UI
- Confirmed the default `Ctrl+5` hotkey is unaffected (`MOD_CONTROL ^
MOD_ALT = MOD_CONTROL | MOD_ALT ≠ 0`)
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: MuyuanMS <116717757+MuyuanMS@users.noreply.github.com>
Co-authored-by: Muyuan Li (from Dev Box) <muyuanli@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Two FancyZones Editor strings have misleading Japanese translations due
to ambiguous English phrasing:
- **"Space around zones"** → 「ゾーン周りのスペース」 (generic space/room) — should
be 「ゾーン周りの余白」 (margin/padding)
- **"Highlight distance"** → 「距離を強調表示」 (distance to visually emphasize)
— should be 「隣接するゾーンの検知距離」 (detection distance for adjacent zones)
## PR Checklist
- [ ] **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
Changes to `FancyZonesEditor/Properties/Resources.resx`:
- **`Distance_adjacent_zones`** — Rewrote existing comment to explicitly
state this is a *detection/snapping proximity distance* (px at which a
nearby zone activates), not a visual-emphasis concept. Prevents
translators from reaching for 強調表示 ("visually highlight/emphasize").
- **`Space_Around_Zones`** — Added comment clarifying this is
*padding/margin* (empty gap in pixels) between zones, not a generic
space/area. Guides translators toward 余白 over スペース.
- **`Show_Space_Zones`** — Added comment clarifying this is a toggle for
enabling/disabling the padding display.
```xml
<data name="Distance_adjacent_zones" xml:space="preserve">
<value>Highlight distance</value>
<comment>The pixel distance at which an adjacent zone highlights (lights up) when a window is dragged near it. This is about detection/snapping range proximity, not about making something visually stand out.</comment>
</data>
<data name="Space_Around_Zones" xml:space="preserve">
<value>Space around zones</value>
<comment>The size (in pixels) of the padding or margin (empty gap) surrounding each zone. This is about blank space/whitespace between zones, not an area or region.</comment>
</data>
```
## Validation Steps Performed
Verified `Resources.resx` is well-formed XML and that the modified
entries render correctly in the resource file. No runtime behavior is
changed — comments are translator-only metadata consumed by the
Touchdown Build localization pipeline.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: niels9001 <9866362+niels9001@users.noreply.github.com>
The Korean translation of "Activation modifier key"
(`GrabAndMove_ModifierKey.Header`) was rendered as "정품인증 보조키" ("product
authentication/genuine certification modifier key") — conflating feature
activation with Windows product licensing. The correct translation is
"활성화 보조 키".
## Change
- **`src/settings-ui/Settings.UI/Strings/en-us/Resources.resw`**:
Expanded the `<comment>` on `GrabAndMove_ModifierKey.Header` to
explicitly disambiguate "Activation" for translators:
```xml
<comment>Drop-down to choose which modifier key (Alt or Win) activates Grab And Move drag and resize.
"Activation" here means to enable/trigger the feature (활성화 in Korean),
NOT product authentication/genuine certification (정품인증 in Korean).</comment>
```
## PR Checklist
- [ ] **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
The word "Activation" is ambiguous in Korean: it can refer to Windows
product license activation (정품인증) or feature enablement (활성화). The
localization pipeline picked the wrong interpretation. Adding an
explicit in-source comment with both the correct and incorrect Korean
terms guides the translation tooling and human reviewers to use "활성화 보조
키" going forward.
## Validation Steps Performed
- Verified the updated comment appears correctly in the `.resw` file.
- No runtime behavior changes; comment-only modification to the resource
file.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: niels9001 <9866362+niels9001@users.noreply.github.com>
The German locale translated the system tray tooltip `AppName` ("Power
Display") to "Leistungsanzeige", despite the Settings UI keeping the
utility name untranslated. The affected resource entries had no
translator guidance, so "Power Display" was treated as a localizable
phrase rather than a fixed product name. This PR adds consistent "do not
translate" comments across all touchpoints in both resource files.
## Summary of the Pull Request
- `src/modules/powerdisplay/PowerDisplay/Strings/en-us/Resources.resw`:
Added `Product name, do not translate.` comment to the `AppName` entry
(system tray tooltip)
- `src/settings-ui/Settings.UI/Strings/en-us/Resources.resw`: Added
`{Locked="Power Display"}` comments to all 15 entries containing "Power
Display" — including the module title, enable/toggle/open/launch
strings, OOBE title/description/activation text, LearnMore link,
QuickProfiles description, group header, and flyout header — following
the same convention already used for FancyZones and other product names
in that file
## PR Checklist
- [ ] **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
- [x] **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
The system tray tooltip is populated via `GetString("AppName")` in
`TrayIconService.cs`. Because the resource had no comment, translators
localized "Power Display" as a common phrase ("performance display")
rather than treating it as a fixed product name.
To ensure consistency across all touchpoints, `{Locked="Power Display"}`
comments have been added to every entry in the Settings UI resource file
that contains the product name, matching the convention already in use
for `Shell_PowerDisplay.Content` (`Product name: Navigation view item
name for Power Display`) and for other utilities such as FancyZones
(`{Locked="FancyZones"}`).
## Validation Steps Performed
Verified that all `AppName` and Settings UI resource entries containing
"Power Display" now carry the appropriate translator comment. No runtime
behavior changes — the English values are unchanged; the comments solely
guide translators to leave the product name as-is in all locales.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: niels9001 <9866362+niels9001@users.noreply.github.com>
The nittiest of nits: "No shortcuts to show.." message should be "No
shortcuts to show." when no modules are enabled.
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [ ] Closes: #xxx
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [x] **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
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
This one is pretty self-explanatory.
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
(Manual testing.)
<img width="240" height="141" alt="image"
src="https://github.com/user-attachments/assets/a036d345-dc1d-4040-9111-187619453dcd"
/>
## Summary of the Pull Request
Adds the Mouse Without Borders "Refresh connections" action to both the
Quick Access tray flyout and the Settings Dashboard, so users can
trigger a reconnect without navigating into MWB settings.
## PR Checklist
- [ ] **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
### Quick Access flyout (`Settings.UI.Controls`)
- **`QuickAccessViewModel`**: Added `MouseWithoutBorders` to
`InitializeItems()`; tooltip shows the configured `ReconnectShortcut`.
- **`QuickAccessLauncher`**: Added `case ModuleType.MouseWithoutBorders`
— signals `MWBReconnectEvent` (same named Windows event used by the
CmdPal `MWBReconnectCommand`).
### Settings Dashboard (`Settings.UI`)
- **`DashboardViewModel`**: Added `GetModuleItemsMouseWithoutBorders()`
returning a `DashboardModuleButtonItem` wired to a new
`MouseWithoutBordersReconnectClicked` handler that fires
`MWBReconnectEvent`. Added the module to the `GetModuleItems()` switch.
Added `using System.Threading` and `using PowerToys.Interop`.
No new strings — reuses existing
`MouseWithoutBorders_ReconnectButton.Text` ("Refresh connections") and
`MouseWithoutBorders_ReconnectTooltip.Text` for the button label and
description.
## Validation Steps Performed
- Verified `MWBReconnectEvent` is the same event used by
`MWBReconnectCommand` in the CmdPal extension.
- Confirmed `MouseWithoutBorders.png` icon exists in
`Assets/Settings/Icons/`.
- Confirmed `PowerToys.Interop` is already referenced by
`PowerToys.Settings.csproj`.
> [!WARNING]
>
> <details>
> <summary>Firewall rules blocked me from connecting to one or more
addresses (expand for details)</summary>
>
> #### I tried to connect to the following addresses, but was blocked by
firewall rules:
>
> - `o3svsblobprodcus318.vsblob.vsassets.io`
> - Triggering command: `/usr/bin/dotnet dotnet build
Settings.UI/PowerToys.Settings.csproj -c Debug` (dns block)
>
> If you need me to access, download, or install something from one of
these locations, you can either:
>
> - Configure [Actions setup
steps](https://gh.io/copilot/actions-setup-steps) to set up my
environment, which run before the firewall is enabled
> - Add the appropriate URLs or hosts to the custom allowlist in this
repository's [Copilot coding agent
settings](https://github.com/microsoft/PowerToys/settings/copilot/coding_agent)
(admins only)
>
> </details>
<!-- START COPILOT ORIGINAL PROMPT -->
<details>
<summary>Original prompt</summary>
>
> ----
>
> *This section details on the original issue you should resolve*
>
> <issue_title>Add Refresh Connections (from Mouse Without Borders) to
Quick Access</issue_title>
> <issue_description>### Description of the new feature / enhancement
>
> As per subject ... add Refresh Connections (_from Mouse Without
Borders_) to Quick Access
>
> ### Scenario when this would be used?
>
> There are a number of scenarios (_in my use case_) where I have one of
my machines connected to a business VPN .... which in 90% of the cases
triggers a small network drop resulting in the machine dropping off
mouse w/o borders - a refresh connections fixes it - but is currently a
bit annoying to get to.
>
> ### Supporting information
>
> _No response_</issue_description>
>
> ## Comments on the Issue (you are @copilot in this section)
>
> <comments>
> </comments>
>
</details>
<!-- START COPILOT CODING AGENT SUFFIX -->
- Fixesmicrosoft/PowerToys#45935
<!-- START COPILOT CODING AGENT TIPS -->
---
🔒 GitHub Advanced Security automatically protects Copilot coding agent
pull requests. You can protect all pull requests by enabling Advanced
Security for your repositories. [Learn more about Advanced
Security.](https://gh.io/cca-advanced-security)
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: niels9001 <9866362+niels9001@users.noreply.github.com>
Co-authored-by: Niels Laute <niels.laute@live.nl>
## Summary
Adds a GitHub Action workflow that **automatically applies `Product-*`
labels** to issues, reducing manual triage effort.
### How it works
**Two-tier approach:**
1. **Deterministic mapping** — Parses the structured "Area(s) with
issue?" dropdown from bug report templates and maps selections to the
correct `Product-` label via a hardcoded lookup table.
2. **AI inference (Copilot fallback)** — When no product is resolved
from the structured field (e.g., feature requests without the area
field), calls GitHub Models API (`gpt-4.1-mini`) to infer the product
from issue title + body.
### Trigger modes
| Trigger | Use case |
|---------|----------|
| `issues: [opened]` | Auto-labels every new issue |
| `workflow_dispatch` (single) | Test on one specific issue with dry-run
|
| `workflow_dispatch` (batch) | Process all open issues missing Product-
labels |
### Safety features
- **Label validation** — checks each label exists in the repo before
applying
- **Dry-run mode** — logs what would happen without modifying issues
- **Concurrency control** — prevents duplicate runs
- **Conservative AI prompt** — only labels products the issue is
*primarily* about
### Testing performed
Tested locally against 10 real issues with `Needs-Triage` and no
`Product-*` label:
- **6/10 resolved deterministically** (correct labels applied via `gh
issue edit`)
- **4/10 tested AI inference** via GitHub Models API:
- #47482 (CmdPal Dock) → `Product-Command Palette` ✅
- #47474 (grab and move + fancy zones) → `Product-FancyZones` ✅
- #47476 (modular download) → `[]` (correctly abstained) ✅
- #47478 (Quick Access pinning) → improved prompt to avoid over-labeling
### Files changed
| File | Purpose |
|------|---------|
| `.github/workflows/auto-label-product.yml` | The GitHub Action |
| `.github/policies/resourceManagement.yml` | Removed redundant
Workspaces-only regex rule |
| `tools/Test-AutoLabelProduct.ps1` | Local PowerShell test script for
dry-run testing |
### Mapping validated against actual repo labels
Confirmed all label names in the mapping exist in the repo via `gh label
list --search "Product-"`.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## Summary of the Pull Request
Adds a GitHub Actions workflow that fires on every new/reopened issue
and uses `gpt-4o-mini` (via GitHub Models) to classify the issue and
apply the correct `Product-*` / `Area-*` label(s) automatically. Also
adds a `workflow_dispatch` path so maintainers can manually backfill
labels on existing untriaged issues by supplying a comma-separated list
of issue numbers.
## PR Checklist
- [ ] **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
**New file:** `.github/workflows/auto-label-issues.yml`
- **Trigger:** `issues: [opened, reopened]` for the automatic path;
`workflow_dispatch` with an `issue_numbers` input (comma-separated) for
manual backfill
- **Model call:** issue title + body (≤4 000 chars) → `gpt-4o-mini` at
the GitHub Models inference endpoint (`models.inference.ai.azure.com`);
uses `GITHUB_TOKEN` — no extra secrets required; `temperature: 0` for
deterministic output
- **Safety:** model output is filtered through a hard-coded allow-list
of 37 `Product-*` / `Area-*` labels before any API call — hallucinated
labels are dropped silently
- **Permissions:** `models: read` + `issues: write` only (same
minimal-permission pattern as the existing dedup workflow)
- **Concurrency:** per-issue group for automatic events; per-run-ID for
manual dispatch — prevents races without blocking unrelated runs
## Validation Steps Performed
- Manually triggered via `workflow_dispatch` against several untriaged
issues; step logs confirmed correct JSON output from the model and
matching labels applied via the GitHub Issues API.
- Verified the allow-list filter correctly discards any label not in the
predefined set.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: niels9001 <9866362+niels9001@users.noreply.github.com>
Co-authored-by: Niels Laute <niels.laute@live.nl>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
Adds an explicit Phase 0 classification step in `MonitorManager` that
uses `DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY` (from `QueryDisplayConfig`)
to label every connected display as **internal** (built-in) or
**external** before any controller runs. Each controller is then
dispatched a strictly-scoped target list:
- **WMI controller** → only internal displays
- **DDC/CI controller** → only external displays
Two practical wins:
1. **Performance** — DDC/CI's ~4-second I2C capabilities probe (per
monitor) is now skipped entirely for internal laptop panels, which never
respond to DDC/CI in the first place. On a typical laptop with one
built-in panel + one external monitor, discovery is noticeably faster.
2. **Layering** — `WmiController` no longer reaches into the
`Drivers/DDC/` namespace to call
`DdcCiNative.GetAllMonitorDisplayInfo()`. Both controllers receive their
input from `MonitorManager` via a single `QueryDisplayConfig` call.
Strict classification is enforced: a display classified as internal but
not returned by `WmiMonitorBrightness` is dropped + logged (Warning),
with **no fallback to DDC/CI**. This is a deliberate design choice — the
spec discusses the trade-off in detail.
Adds a Phase 0 classification log (Info level) so misclassifications are
diagnosable from logs alone:
```
[DisplayClassification] Found 2 displays:
[Path 1] \\.\DISPLAY1 / "Built-in display": OutputTechnology=0x80000000 → Internal
[Path 2] \\.\DISPLAY2 / "Dell U2723QE": OutputTechnology=10 → External
[DisplayClassification] Summary: 1 internal, 1 external
```
The classification rule (in `DisplayClassifier.IsInternal`) is
deliberately conservative — misclassifying an external display as
internal would silently drop it from DDC/CI discovery with no fallback,
so we err on the side of external:
- **Internal**: the bare `INTERNAL` flag (`0x80000000`) alone, the
`INTERNAL` flag combined with a documented embedded subtype
(`DISPLAYPORT_EMBEDDED` 11 or `UDI_EMBEDDED` 13), or one of those
embedded subtypes on its own
- **External**: everything else, including the `INTERNAL` flag combined
with an undocumented subtype (HDMI, DP_EXTERNAL, MIRACAST, etc.)
- LVDS (6) is intentionally **not** classified internal — the [Microsoft
docs](https://learn.microsoft.com/en-us/windows/win32/api/wingdi/ne-wingdi-displayconfig_video_output_technology)
describe it only as a connector type, not as an internal-display marker
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [ ] Closes: #xxx
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [x] **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
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
---------
Co-authored-by: Yu Leng <yuleng@microsoft.com>
Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
Adding missing Grab And Move and Power Display events
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [ ] Closes: #xxx
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [ ] **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
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
## Summary of the Pull Request
Bumps `Microsoft.WindowsAppSDK` (and split sub-packages) from
**`1.8.260209005`** to public NuGet''s **`2.0.1`** GA, plus the
centrally-pinned `Microsoft.Web.WebView2` to **`1.0.3719.77`** to
satisfy the new transitive requirement from
`Microsoft.WindowsAppSDK.WinUI 2.0.12`.
This is the minimum mechanical version-bump set required for the
WinAppSDK 2.0 upgrade ΓÇö no API migration or behavioral changes.
Subsequent commits on this branch will address breaking-change
migrations as they surface.
NuGet source-of-truth used to pick sub-package versions: WinAppSDK 2.0.1
catalog `dependencyGroup`
(https://api.nuget.org/v3/catalog0/data/2026.04.29.22.25.36/microsoft.windowsappsdk.2.0.1.json).
## Detailed Description of the Pull Request / Additional comments
### Scope
| Package | Pinned |
|---|---|
| `Microsoft.WindowsAppSDK` | `2.0.1` |
| `Microsoft.WindowsAppSDK.Foundation` | `2.0.20` |
| `Microsoft.WindowsAppSDK.AI` | `2.0.185` |
| `Microsoft.WindowsAppSDK.Runtime` | `2.0.1` |
| `Microsoft.Web.WebView2` | `1.0.3719.77` |
## Validation Steps Performed
`tools\build\build-essentials.cmd` results on the temp branch (x64
Debug, VS 2026 Insiders 14.51.36231):
| Stage | Errors | Warnings | Time |
|---|---|---|---|
| `PowerToys.slnx` NuGet restore | **0** | 0 | 1:05 |
| Native C++ `src\runner\runner.vcxproj` | **0** | 0 | 4:08 |
| Managed `src\settings-ui\Settings.UI\PowerToys.Settings.csproj` |
**0** | 0 | 3:35 |
Exit code: **0**. The end-to-end `build-essentials` flow passes locally
ΓÇö the WinAppSDK 2.0 upgrade is verified to compile against the runner
+ Settings.UI projects.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## Summary of the Pull Request
The brightness / contrast / volume sliders in the PowerDisplay flyout
previously committed to hardware (DDC/CI) only on `PointerCaptureLost`
plus arrow-key `KeyUp`. That doesn't work reliably on touchscreens —
tap-on-track issues no pointer capture, and the Slider / Thumb doesn't
always bubble `PointerCaptureLost` on touch — so the value the user
dialed in never reached the monitor.
This PR replaces that wiring with the simpler approach we actually
wanted: a TwoWay `Value` binding plus a debounced commit in the
view-model. `ValueChanged` runs the setter on every move, but a 200 ms
`DispatcherQueueTimer` (restarted on each change) collapses the entire
interaction into a single DDC/CI write once the user stops sliding.
Mouse, touch, tap-on-track, and held arrow keys all use the same code
path.
It also adds a small `SliderExtensions` helper (Toolkit-style attached
properties) so the brightness / contrast / volume sliders can be
adjusted by mouse-wheel scroll. The wheel event is marked handled so the
parent `ScrollViewer` does not also scroll, and the existing 200 ms
debounce coalesces wheel input into a single DDC/CI write.
## PR Checklist
- [x] Closes: #47724
- [x] **Communication:** I've discussed this with core contributors
already.
- [x] **Tests:** Manual smoke; no automated coverage exists for the
slider flyout.
- [x] **Localization:** No new end-user-facing strings.
- [x] **Dev docs:** N/A
- [x] **New binaries:** N/A
- [x] **Documentation updated:** N/A
## Detailed Description of the Pull Request / Additional comments
### Debounced commit
- `MonitorViewModel.Brightness/Contrast/Volume` setters now: assign
field → `OnPropertyChanged()` → `ScheduleCommit(...)` which (re)starts a
per-metric `DispatcherQueueTimer`. On `Tick` the closure calls
`SetBrightnessAsync(_brightness)` (etc.), reading the latest field value
so intermediate drag values are coalesced into one hardware write.
- `SetBrightnessAsync` / `SetContrastAsync` / `SetVolumeAsync` (used by
hotkeys, profile load, hardware refresh) keep their immediate-apply
behavior — they bypass the public setters, so a TwoWay source-update
from one of those paths does **not** reschedule a commit.
- `MonitorViewModel.Dispose()` stops the three timers. Pending writes
are intentionally dropped: `Dispose` only runs when the monitor is gone
(unplug / refresh) or the app is shutting down, in which case a hardware
write would race a half-torn-down `MonitorManager`.
- `AppConstants.UI.SliderCommitDebounceMs = 200` is the single source of
truth for the delay.
- Removed the six
`Handle{Brightness|Contrast|Volume}{PointerCaptureLost|KeyUp}` methods
and the now-unused `IsArrowKey` helper.
- `using DispatcherQueueTimer =
Microsoft.UI.Dispatching.DispatcherQueueTimer;` alias avoids ambiguity
with `Windows.System.DispatcherQueueTimer`.
### Wheel-scrollable sliders
- New `PowerDisplay.Helpers.SliderExtensions` — a Toolkit-style `public
static class <Control>Extensions` with two attached properties:
- `SliderExtensions.IsMouseWheelEnabled` (bool) — opt in to wheel input.
- `SliderExtensions.MouseWheelChange` (double, default `NaN` → falls
back to the slider's own `Slider.SmallChange`) — per-notch delta.
- Handler computes `notches = MouseWheelDelta / 120`, clamps to
`[Minimum, Maximum]`, sets `Value`, and marks `e.Handled = true` so the
enclosing `MainScrollViewer` doesn't also scroll.
- Wired on the brightness, contrast, and volume sliders with
`MouseWheelChange="5"` (20 notches for a full sweep).
- Body has zero PowerDisplay-specific dependencies (only
`Microsoft.UI.Xaml.*`) so the helper is straightforward to lift into the
WinUI Community Toolkit later.
## Validation Steps Performed
- `tools/build/build.cmd` against
`src/modules/powerdisplay/PowerDisplay/PowerDisplay.csproj` — exit code
0.
- Manual smoke on a touchscreen device:
- Touch drag thumb 50 → 80, lift finger → monitor commits once at 80.
- Tap on the track at 25 % → monitor commits once at 25 %.
- Manual smoke with mouse:
- Drag 50 → 80, release → exactly one DDC/CI write at 80.
- Manual smoke with keyboard:
- Hold Right arrow on the brightness slider → repeated nudges collapse
into a single write 200 ms after key release.
- Manual smoke with mouse wheel:
- Hover brightness slider, scroll wheel → value moves by 5 per notch,
monitor commits once after scrolling stops.
- Wheel over a slider does **not** scroll the flyout's
`MainScrollViewer`; wheel outside the sliders still scrolls.
- Wheel past `Minimum` / `Maximum` clamps at the boundary.
- Hotkey-driven brightness change still applies immediately (regression
check on the `SetBrightnessAsync` path).
- `DisplayChangeWatcher`-driven hardware refresh does not schedule a
spurious commit.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This PR solves the following issues:
- Narrator announced the Resize button as 'button', now it's 'resize'.
- The app window was still 'WinUI Desktop', it's now 'Image Resizer'
Binding is hard.
The tooltip is bound to `.Tooltip`. But we forgot to raise a property
changed event for `Tooltip` when title or subtitle change.
Closes: issue filed on teams
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
Fixes#47458 — on monitors that advertise a non-100 raw VCP maximum
(e.g. Samsung S27DG602SN reports 50), the DDC controller was writing the
slider's 0–100 percentage directly as the raw VCP value. Anything above
the device's max was silently clamped, so only the bottom half of the
brightness / contrast / volume sliders had any visible effect.
The same root cause affects all three continuous-range VCPs (0x10
brightness, 0x12 contrast, 0x62 volume).
- Capture the device-reported `max` at discovery into new
`Monitor.{Brightness,Contrast,Volume}VcpMax` fields.
- Add `VcpFeatureValue.FromPercentage(percent, max, min)` as the
symmetric inverse of the existing `ToPercentage()`.
- Scale percent → raw inside `DdcCiController.Set{Brightness,Contrast,
Volume}Async` before each `SetVCPFeature` call.
- WMI is unaffected — Windows already standardises WMI brightness to
0–100.
The whole stack above the controller (ViewModel, MonitorManager, slider,
settings persistence, IPC) stays in the percent domain. The only place
percent ↔ raw conversion happens is the controller boundary.
#47458
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [x] Closes: #
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [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
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Co-authored-by: Yu Leng <yuleng@microsoft.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
Fixes#47665 — users report the per-monitor "Show input source control"
/ "Show power state control" toggles silently revert to off over time.
Three independent log captures pin the root cause to two layers in
`MainViewModel`:
- **Data-loss layer**: `SaveMonitorsToSettings` rebuilds
`settings.Properties.Monitors` from the currently-discovered list and
only re-adds entries with `IsHidden=true`. Whenever monitor discovery
transiently fails (DDC `GetPhysicalMonitors` NULL handle, DDC `empty
capabilities string`, WMI 4200 — all common in production logs),
affected monitors get **deleted** from settings.json. Next successful
discovery initialises them with the post-#47303 defaults
(`EnableInputSource=false`, `EnableColorTemperature=false`,
`EnablePowerState=false`), and `ApplyPreservedUserSettings` cannot
recover what is no longer there.
- **Identity layer**: `Monitor.Id` is
`{Source}_{EdidId}_{MonitorNumber}` — `EdidId` is not unique for
identical-model monitors, and `MonitorNumber` is OS-assigned and changes
after sleep/wake / GPU reset / display reorder. Even fixing the
data-loss layer would still apply preserved settings to the wrong
physical monitor for users with multiple identical displays.
This PR addresses both layers:
- **30-day retention** — `MonitorSettingsRebuilder` (in
`PowerDisplay.Lib`) replaces the inline `IsHidden`-only loop.
Currently-discovered monitors get a fresh `LastSeenUtc` stamp;
missing-but-recent (< 30 days) entries are preserved with all `Enable*`
flags intact; missing-and-stale entries are dropped with a single info
log. `IsHidden=true` entries are still preserved unconditionally.
- **DevicePath-based Id** — `Monitor.Id` is now the Windows `DevicePath`
minus the trailing device-class GUID (e.g.
`\\?\DISPLAY#DELD1A8#5&abc&0&UID12345`). The middle PnP-instance segment
is unique per (physical device × physical port) and stable across
reboots, sleep/wake, and OS-level reordering —
`MonitorDisplayInfo.DevicePath` already carries this value from
`QueryDisplayConfig`; it just wasn't being used as the Id.
The order of commits keeps the app behaviourally identical to today
through the first 8 commits (only adds dormant helpers / fields /
wiring); the actual ID-format flip is the very last commit.
Bisect-friendly.
#47599
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [x] Closes: #
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [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
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
---------
Co-authored-by: Yu Leng <yuleng@microsoft.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
Exposes the 16:9 aspect ratio toggle for the ZoomIt screen region
recording (default: `Ctrl`+`Shift`+`5`) in the settings UI.
<img width="1047" height="817" alt="image"
src="https://github.com/user-attachments/assets/4117a6a1-9f57-44c5-9a21-1b1b65bc2992"
/>
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [ ] Closes: #xxx
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [ ] **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
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Checked that the toggle works and that it's compatible with the
standalone ZoomIt, too.
## Summary
Fixes#47645.
The ADMX policy definition (`src/gpo/assets/PowerToys.admx`) declares
`revision="1.20"` and `<resources minRequiredRevision="1.20"/>`, but the
en-US ADML language resource (`src/gpo/assets/en-US/PowerToys.adml`) was
still at `revision="1.19"`. Group Policy Editor refuses to load the
PowerToys template because the language resource does not meet the
minimum required revision, producing the error reported in the issue.
## Change
Bump `revision` on the `policyDefinitionResources` root element of
`PowerToys.adml` from `1.19` to `1.20` so it matches the ADMX
`minRequiredRevision`.
## Validation
- Diffed against `src/gpo/assets/PowerToys.admx` to confirm the
revisions now align (both `1.20`).
- Documentation/asset-only change; no code build required.
## PR Checklist
- [x] Closes#47645
- [x] Tests added/passed — N/A (asset-only revision bump)
- [x] Requires documentation to be updated — No
- [x] I know how to test these changes — Open `gpedit.msc` and confirm
PowerToys policies load without the resource-version error.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## Summary of the Pull Request
ZoomItBreak.vcxproj contained a leftover Import of
Microsoft.Windows.ImplementationLibrary.targets pinned to version
1.0.231216.1, plus the matching EnsureNuGetPackageBuildImports guard.
The project has no packages.config and its source files
(BreakTimer.cpp/.h, ZoomItBreakScr.cpp) include no wil headers, so the
import was dead code copy-pasted from ZoomIt.vcxproj when the
screensaver project was introduced in #46506.
Until PR #41280 (.NET 10 upgrade), the sibling ZoomIt project restored
WIL 1.0.231216.1 via its own packages.config, so the folder
coincidentally existed and the stale Import silently succeeded. PR
#41280 bumped that dependency to 1.0.260126.7, leaving nothing in the
repo that requests the old version. NuGet no longer creates the
1.0.231216.1 folder, the EnsureNuGetPackage target fires, and the
official build fails with:
ZoomItBreak.vcxproj(227,5): Error : This project references
NuGet package(s) that are missing on this computer ...
Microsoft.Windows.ImplementationLibrary.1.0.231216.1\...targets
Fix: drop the unused import and guard target. Verified by clean rebuild
of x64 Release and ARM64 Release; ZoomItBreak64.scr / ZoomItBreak64a.scr
produced with empty error logs.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
This adds the capability to include a webcam in the ZoomIt recording.
Also, the trim editor now supports appending multiple clips with
selectable transitions.
<img width="451" height="570" alt="image"
src="https://github.com/user-attachments/assets/025a7840-2e40-424c-af57-5ed523af8646"
/>
Also fixed some minor bugs in the ZoomIt settings within PowerToys and
added the options there, too.
<img width="1556" height="962" alt="image"
src="https://github.com/user-attachments/assets/dfe4209c-1b59-47c3-9170-36832d37f880"
/>
There was a bug in the microphone selection, fixed it together with the
webcam selection dialog, too.
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [x] Closes: #47230
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [ ] **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
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
---------
Co-authored-by: markrussinovich <markrussinovich@users.noreply.github.com>
Co-authored-by: Copilot <copilot@github.com>
Updated instructions for downloading the .exe file and release notes
link.
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [ ] Closes: #xxx
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [ ] **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
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
## Summary of the Pull Request
Fixes `tools\build\build-common.ps1` so a clean
`tools\build\build-essentials.cmd` (or `build.ps1`) run discovers and
uses **Visual Studio 2026 Insiders** without any manual
`Enter-VsDevShell` preamble. Today the script lands on the first VS 2022
BuildTools instance it finds (which lacks the C++ workload) and every
native `.vcxproj` errors with `MSB4086: $(PlatformToolsetVersion)
evaluates to ""` during NuGet restore.
Two scoped commits, **only `tools\build\build-common.ps1` is touched**
(+58 / −36 net).
## 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
- [ ] **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 (n/a — build-script
change only)
- [ ] [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
### What''s broken
`build-common.ps1`''s `vswhere` lookup runs **without `-prerelease`**,
so VS 2026 Insiders / Preview installs are invisible to it. The explicit
fallback path list also only contains VS 2022 entries. On a machine that
has VS 2022 BuildTools (typical for CI hosts and many dev boxes) but
only has VS 2026 in *Insiders* form, the script:
1. Picks `C:\Program Files (x86)\Microsoft Visual
Studio\2022\BuildTools` because it''s a candidate `vswhere` returned and
it''s in the fallback list.
2. Enters its DevShell — but BuildTools has no C++ workload installed,
so `$(VCToolsInstallDir)` and `$(PlatformToolsetVersion)` are unset.
3. NuGet restore over `PowerToys.slnx` fans out to every `.vcxproj` and
they each hit `Microsoft.CodeAnalysis.targets(401,15): error MSB4086: A
numeric comparison was attempted on "$(PlatformToolsetVersion)" that
evaluates to "" instead of a number, in condition
"''$(PlatformToolsetVersion)''<''120''".` The build dies before any
project compiles.
This was reproduced today against `origin/main` — confirming this is a
pre-existing breakage independent of any in-flight feature work.
### What this PR changes
Commit **`30acf72c` — Fix build scripts to discover VS 2026 / Insiders
installations**
- Adds `-prerelease` to `vswhere` calls, tried **before** the stable
lookup so prerelease VS is preferred when it''s the only one with a
working C++ workload.
- Adds VS 2026 year-name and internal-version (`18\Insiders`) paths to
the explicit fallback list.
- Keeps VS 2022 paths as the final fallback so existing setups keep
working.
- Priority order: `prerelease+VC tools` → `prerelease` → `stable+VC
tools` → `stable`.
Commit **`18b27209` — build: simplify VS environment initialization with
VS2022/VS2026 support**
- Adds `-prerelease` to `vswhere` (consolidates with the above; the
prerelease query subsumes the stable one now).
- Restricts the SKU query to `Community` / `Professional` / `Enterprise`
(explicitly excludes `BuildTools`) so the script can no longer
accidentally pick a SKU without the C++ workload.
- Reduces vswhere from **4 calls to 2**.
- Removes the destructive BuildTools env-var cleanup block (no longer
needed once vswhere refuses to return BuildTools in the first place).
- Adds `VsDevCmd.bat` exit-code validation so a partial DevShell init
fails loudly instead of silently producing a half-initialized
environment.
- Adds VS 2022 / VS 2026 Preview entries to the explicit fallback list.
### Why two commits instead of a squash
The first commit is the minimum-viable fix that addresses the reported
MSB4086 failure. The second commit is a follow-up cleanup that''s only
safe **once** prerelease is preferred and BuildTools is excluded.
Splitting them keeps each commit independently revert-able if a
regression shows up on a specific dev environment shape.
## Validation Steps Performed
| Step | Result |
|---|---|
| Reproduce on `main`: cold `tools\build\build-essentials.cmd` in a
non-DevShell PowerShell | **MSB4086** on
`Microsoft.CommandPalette.Extensions.vcxproj`,
`Microsoft.Terminal.UI.vcxproj`, `PowerToys.MeasureToolCore.vcxproj`,
`PowerRenameUI.vcxproj` — confirmed broken |
| With this branch checked out: same cold `build-essentials.cmd`
invocation | `[VS] vswhere found: ... C:\Program Files (x86)\Microsoft
Visual Studio\Installer\vswhere.exe` → `[VS] Checking candidate:
C:\Program Files\Microsoft Visual Studio\18\Insiders` → `[VS] Entered
Visual Studio DevShell at C:\Program Files\Microsoft Visual
Studio\18\Insiders` — VS 2026 Insiders selected directly, restore step
proceeds past the MSB4086 wall |
| Manual workaround pre-init via `Import-Module
Microsoft.VisualStudio.DevShell.dll` + `Enter-VsDevShell` | Now
**unnecessary** — the script self-initializes correctly |
After this fix, the next failure mode the build hits is unrelated NuGet
feed coverage for in-flight WinAppSDK upgrade work, which is the gated
dependency this PR was extracted from to keep this change atomic.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## Summary of the Pull Request
.NET 10 Upgrade. Requires Visual Studio 2026.
## PR Checklist
- [x] **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
- Upgraded target framework from `net9.0` to `net10.0` across all
projects
- Removed redundant package references now included by default in .NET
10
- Updated package versions to .NET 10 releases
- Modernized regex usage with source generators for better performance
- Added `vbcscompiler` to the spell-check allowlist
(`.github/actions/spell-check/expect.txt`)
## Validation Steps Performed
<!-- START COPILOT CODING AGENT TIPS -->
---
🔒 GitHub Advanced Security automatically protects Copilot coding agent
pull requests. You can protect all pull requests by enabling Advanced
Security for your repositories. [Learn more about Advanced
Security.](https://gh.io/cca-advanced-security)
---------
Co-authored-by: Jeroen van Warmerdam <jeronevw@hotmail.com>
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
The influx of Copilot-originated pull requests has made it impossible
for our CI to keep up; this is in part because for some reason Copilot
is treated as a team member and therefore automatically scheduled for CI
on the build pool.
## Summary of the Pull Request
This updates the spell-check allowlist at
`.github/actions/spell-check/expect.txt` to remove duplicate entries and
enforce a single alphabetical ordering. Matching remains case-sensitive
(e.g., `AAA` and `aaa` are treated as distinct entries).
## PR Checklist
- [ ] **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
- **Scope**
- Updated only `.github/actions/spell-check/expect.txt`.
- **Changes**
- Removed exact duplicate words.
- Reordered file into strict alphabetical order.
- Preserved case-sensitive distinctions.
- **Example**
```bash
LC_ALL=C sort -u .github/actions/spell-check/expect.txt -o
.github/actions/spell-check/expect.txt
```
## Validation Steps Performed
N/A (no behavioral/code-path changes; list normalization only).
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: noraa-junker <58633848+noraa-junker@users.noreply.github.com>
reply:Hi! Your last comment indicates to our system, that you might want to contribute to this feature/fix this bug. Thank you! Please make us aware on our ["Would you like to contribute to PowerToys?" thread](https://github.com/microsoft/PowerToys/issues/28769), as we don't see all the comments. <br /><br />_I'm a bot (beep!) so please excuse any mistakes I may make_
THIS IS A TEST | @chatasweetie is testing this functionality
Thanks for contributing to PowerToys. This change might include a new or modified telemetry event, and we want to help make sure you can get your data end to end.
1. Reach out to Jessica (@chatasweetie) to follow up on the next steps to add these telemetry events to our pipelines.`;
THIS IS A TEST | @chatasweetie is testing this functionality
Thanks for contributing to PowerToys. This change might include a new or modified telemetry event, and we want to help make sure you can get your data end to end.
1. Make sure to add your telemetry events to DATA_AND_PRIVACY.md.
2. Reach out to Jessica (@chatasweetie) to follow up on the next steps to add these telemetry events to our pipelines.`;
description: Toolkit for generating PowerToys release notes from GitHub milestone PRs or commit ranges. Use when asked to create release notes, summarize milestone PRs, generate changelog, prepare release documentation, request Copilot reviews for PRs, update README for a new release, manage PR milestones, or collect PRs between commits/tags. Supports PR collection by milestone or commit range, milestone assignment, grouping by label, summarization with external contributor attribution, and README version bumping.
description: Toolkit for generating PowerToys release notes from GitHub milestone PRs or commit ranges. Use when asked to create release notes, summarize milestone PRs, generate changelog, prepare release documentation, generate PR review summaries locally for release notes, update README for a new release, manage PR milestones, collect PRs between commits/tags, or prepare release assets (download installers and compute installer hashes).
license: Complete terms in LICENSE.txt
---
# Release Note Generation Skill
Generate professional release notes for PowerToys milestones by collecting merged PRs, requesting Copilot code reviews, grouping by label, and producing user-facing summaries.
Generate professional release notes for PowerToys milestones by collecting merged PRs, summarizing each PR with the local CLI agent, grouping by label, and producing user-facing summaries.
## Output Directory
@@ -26,16 +26,17 @@ Generated Files/ReleaseNotes/
- Generate release notes for a milestone
- Summarize PRs merged in a release
-Request Copilot reviews for milestone PRs
-Generate per-PR review summaries locally for release-notes copy
- **GitHub CLI (`gh`) installed and authenticated** — The collection script uses `gh pr view` and `gh api graphql` to fetch PR metadata and co-author information. Run `gh auth status` to verify; if not logged in, run `gh auth login` first. See [Step 1.0.0](./references/step1-collection.md) for details.
- MCP Server: github-mcp-server installed
-GitHub Copilot code review enabled for the org/repo
- MCP Server: github-mcp-server installed (used to fetch PR diffs/files for the local-agent review step)
-For [prepare-release-assets.ps1](./scripts/prepare-release-assets.ps1) only: **Azure CLI** authenticated against the Microsoft tenant (`az login`) with the `azure-devops` extension; access to the `microsoft/Dart` ADO project
## Required Variables
@@ -65,12 +66,12 @@ Generated Files/ReleaseNotes/
└────────────────────────────────┘
↓
┌────────────────────────────────┐
│ 3.1 Request Reviews (Copilot) │
│ 3.1 Local-agent PR summaries │
│ (writes CopilotSummary) │
└────────────────────────────────┘
↓
┌────────────────────────────────┐
│ 3.2 Refresh PR data │
│ (CopilotSummary) │
│ 3.2 (Optional) Refresh PR data │
└────────────────────────────────┘
↓
┌────────────────────────────────┐
@@ -93,7 +94,7 @@ Generated Files/ReleaseNotes/
| 1.1 | Collect PRs | From previous release tag on `stable` branch → `sorted_prs.csv` |
| 1.2 | Assign Milestones | Ensure all PRs have correct milestone |
| [prepare-release-assets.ps1](./scripts/prepare-release-assets.ps1) | Download installers + symbols from an ADO build, compute SHA256, emit the "Installer Hashes" markdown table for the GitHub release page |
## References
@@ -133,5 +135,6 @@ Do not read all steps at once—only read the step you are executing.
|-------|----------|
| `gh` command not found | Install GitHub CLI and add to PATH |
| No PRs returned | Verify milestone title matches exactly |
| Empty `CopilotSummary` for many PRs | Run Step 3.1 (local-agent summaries). Do **not** use `mcp_github_request_copilot_review` from a CLI/coding agent — the GitHub API rejects bot-initiated review requests, so the column will stay empty. |
| Many unlabeled PRs | Return to labeling step before grouping |
| `prepare-release-assets.ps1` fails with "Failed to acquire ADO access token" | Run `az login` and ensure you have access to the `microsoft/Dart` ADO project |
Use MCP tools to request Copilotreviews for all PRs in `Generated Files/ReleaseNotes/sorted_prs.csv`:
> ⚠️ **Do not use `mcp_github_request_copilot_review` (or any "request Copilot review" tool that calls the GitHub API).**
> When this skill is driven from a CLI / coding agent, the request is made from a bot identity and the GitHub API rejects it ("Bot reviewers cannot be requested"). The PR ends up with no Copilot review and `CopilotSummary` stays empty.
>
> Instead, **the local agent that is running this skill performs the review itself** and writes the summary directly into `sorted_prs.csv`.
- Use `mcp_github_request_copilot_review` for each PR ID
- Do NOT generate or run scripts for this step
For every PR listed in `Generated Files/ReleaseNotes/sorted_prs.csv` whose `CopilotSummary` is empty:
1. Fetch the PR diff using a tool that does **not** post anything back to GitHub. Any of these works:
-`mcp_github_pull_request_read` with `method: get_diff`
-`mcp_github_pull_request_read` with `method: get_files` (when the diff is large)
2. Read the PR title, body, and diff. Produce a 1–3 sentence, user-facing summary in the same style as a Copilot PR review (focus on observable behavior change, not implementation details).
3. Write the summary into the `CopilotSummary` column for that PR row in `Generated Files/ReleaseNotes/sorted_prs.csv`. Preserve all other columns and the existing row order.
**Batching guidance**
- Process PRs in the order they appear in `sorted_prs.csv`.
- Generate summaries for **all** PRs in one pass before continuing to Step 3.3, so the human reviewer can validate them together.
- For very large diffs, summarize from `get_files` (filenames + per-file patches) rather than the full diff.
- Skip PRs that already have a non-empty `CopilotSummary` (e.g. PRs where a human reviewer already pasted one). Do not overwrite existing summaries.
**Why not post the summary back to the PR?** Posting a comment from the agent's identity would not be picked up by `dump-prs-since-commit.ps1` (which only matches Copilot bot authors), and it adds noise to the PR. Writing straight into the CSV keeps the artifact self-contained.
---
## 3.2 Refresh PR Data
## 3.2 (Optional) Refresh PR Data
Re-run the collection script to capture Copilot review summaries into the `CopilotSummary` column:
Only re-run the collection script if PR metadata on GitHub has changed (new labels, retitled PRs, etc.) since Step 1.1. **Skip this step if you only want to preserve the locally generated `CopilotSummary` values from Step 3.1**, because re-running the dump will overwrite the CSV.
Creates `Generated Files/ReleaseNotes/grouped_csv/` with one CSV per label combination.
**Validation:** The `Unlabeled.csv` file should be minimal (ideally empty). If many PRs remain unlabeled, return to Step 2 (see [step2-labeling.md](./step2-labeling.md)).
Write-Error"Failed to acquire ADO access token. Run 'az login' first. (az: $script:LastAzError)"
exit1
}
# --- Step 5: Define the four installers to download ---
$targets=@(
[pscustomobject]@{Description="Per user - x64";Scope="perUser";Arch="x64";Artifact="build-x64-Release";FileName="PowerToysUserSetup-$versionParam-x64.exe"}
[pscustomobject]@{Description="Per user - ARM64";Scope="perUser";Arch="arm64";Artifact="build-arm64-Release";FileName="PowerToysUserSetup-$versionParam-arm64.exe"}
@@ -242,6 +242,13 @@ Thank you for using PowerToys!
| Microsoft.PowerToys.FindMyMouse_EnableFindMyMouse | Triggered when Find My Mouse is enabled. |
| Microsoft.PowerToys.FindMyMouse_MousePointerFocused | Occurs when the mouse pointer is focused using Find My Mouse, including the activation method (double-tap left/right Ctrl, shake mouse, or shortcut). |
### Grab And Move
| Event Name | Description |
| --- | --- |
| Microsoft.PowerToys.GrabAndMove_EnableGrabAndMove | Triggered when Grab And Move is enabled or disabled. |
| Microsoft.PowerToys.GrabAndMove_ShortcutUse | Logs an attempt to move or resize a window via the Alt+Drag shortcut, including whether it succeeded, the action type (move or resize), and the reason (e.g., started, blocked by game mode). |
### Hosts File Editor
| Event Name | Description |
@@ -362,6 +369,15 @@ Thank you for using PowerToys!
| Microsoft.PowerToys.Peek_Settings | Triggered when the settings for Peek are modified. |
| Microsoft.PowerToys.Peek_SpaceModeEnabled | Triggered when the Space key activation mode is enabled or disabled in Peek. |
### Power Display
| Event Name | Description |
| --- | --- |
| Microsoft.PowerToys.PowerDisplay_EnablePowerDisplay | Triggered when Power Display is enabled or disabled. |
| Microsoft.PowerToys.PowerDisplay_Activate | Triggered when Power Display is activated via hotkey or tray toggle. |
| Microsoft.PowerToys.PowerDisplay_Start | Triggered when the Power Display application process starts. |
| Microsoft.PowerToys.PowerDisplay_Settings | Periodic snapshot of Power Display settings, including whether the hotkey and tray icon are enabled, the number of detected monitors, and the number of saved profiles. |
<!-- dotnet.exe seems to access files after builds. Temporarily putting in this entry for testing if we get further. This looks to be related to a .NET Roslyn Analyzer in .NET 10-->
This repo uses a common output directory with many projects writing duplicate outputs. Allow everything, but note this costs some performance in the form of requiring
the cache to use copies instead of hardlinks when pulling from cache.
<!-- Including MessagePack to force version, since it's used by StreamJsonRpc but contains vulnerabilities. After StreamJsonRpc updates the version of MessagePack, we can upgrade StreamJsonRpc instead. -->
<!-- Package Microsoft.Win32.SystemEvents added as a hack for being able to exclude the runtime assets so they don't conflict with 8.0.1. This is a dependency of System.Drawing.Common but the 8.0.1 version wasn't published to nuget. -->
<!-- Package System.CodeDom added as a hack for being able to exclude the runtime assets so they don't conflict with 8.0.1. This is a dependency of System.Management but the 8.0.1 version wasn't published to nuget. -->
<!-- Package System.Data.SqlClient added to force it as a dependency of Microsoft.Windows.Compatibility to the latest version available at this time. -->
<!-- Package System.Diagnostics.EventLog added as a hack for being able to exclude the runtime assets so they don't conflict with 8.0.1. This is a dependency of System.Data.OleDb but the 8.0.1 version wasn't published to nuget. -->
<!-- Package System.Diagnostics.PerformanceCounter added as a hack for being able to exclude the runtime assets so they don't conflict with 8.0.11. -->
@@ -47,21 +47,7 @@ But to get started quickly, choose one of the installation methods below:
<summary><strong>Download the .exe file from GitHub</strong></summary>
<br/>
Go to the [PowerToys GitHub releases](https://aka.ms/installPowerToys), select **Assets** to reveal the installation files, and choose the one that matches your architecture and install scope. For most devices, that would be _x64 per-user_.
<!-- items that need to be updated release to release -->
Go to the [PowerToys GitHub releases](https://aka.ms/installPowerToys), scroll down and select **Assets** to reveal the installation files, and choose the one that matches your architecture and install scope. For most devices, that would be _x64 per-user_.
</details>
@@ -106,7 +92,7 @@ There are [community driven install methods](https://learn.microsoft.com/windows
[](https://github.com/microsoft/PowerToys/releases)
To see what's new, check out the [release notes](https://github.com/microsoft/PowerToys/releases/tag/v0.99.0).
To see what's new, check out the [release notes](https://github.com/microsoft/PowerToys/releases/).
## 🛣️ Roadmap
@@ -131,3 +117,4 @@ The application logs basic diagnostic data (telemetry). For more privacy informa
In my head, I am still leaning towards a more full-featured version of draft C,
but with full CommandItem's in the `ISearchUpdateArgs` instead of just strings.
We'd almost need a new page type to support that, where the extension can add
`ICommandItem`s to the search box directly.
## Addenda IV: Dock bands
The "dock" is another way to surface commands to the user. This is a
@@ -2158,7 +2342,6 @@ because that method is was designed for two main purposes:
In neither of those scenarios was the full "display" of the item needed. In
pinning scenarios, however, we need everything that the user would see in the UI
for that item, which is all in the `ICommandItem`.
## Class diagram
This is a diagram attempting to show the relationships between the various types we've defined for the SDK. Some elements are omitted for clarity. (Notably, `IconData` and `IPropChanged`, which are used in many places.)
Shortcut Guide is a PowerToy that displays an overlay of available keyboard shortcuts when the Windows key is pressed and held. It provides a visual reference for Windows key combinations, helping users discover and utilize built-in Windows shortcuts.
Shortcut Guide is a PowerToy that displays an overlay of available keyboard shortcuts when a user-set keyboard shortcut is pressed. It helps users discover and remember keyboard shortcuts for Windows and apps.
> [!NOTE]
> The spec for the manifest files is in development and will be linked here once available.
## Usage
- Press and hold the Windows key to display the overlay of available shortcuts
- Press the hotkey again to dismiss the overlay
- The overlay displays Windows shortcuts with their corresponding actions
- Press the user-defined hotkey to display the overlay
- Press the hotkey again or press ESC to dismiss the overlay
## Build and Debug Instructions
@@ -25,67 +27,89 @@ Shortcut Guide is a PowerToy that displays an overlay of available keyboard shor
4. The executable is named PowerToys.ShortcutGuide.exe
### Debug
1. Right-click the ShortcutGuide project and select 'Set as Startup Project'
1. Right-click the ShortcutGuide.Ui project and select 'Set as Startup Project'
2. Right-click the project again and select 'Debug'
## Code Structure
> [!NOTE]
> When run in debug mode, the window behaves differently than in release mode. It will not automatically close when loosing focus, it will be displayed on top of all other windows, and it is not hidden from the taskbar.

## Project Structure
### Core Files
The Shortcut Guide module consists of the following 4 projects:
Contains DLL boilerplate code. Implements the PowertoyModuleIface, including enable/disable functionality and GPO policy handling. Captures hotkey events and starts the PowerToys.ShortcutGuide.exe process to display the shortcut guide window.
Contains the module interface code. It initializes the settings values and the keyboard event listener. Defines the OverlayWindow class, which manages the overall logic and event handling for the PowerToys Shortcut Guide.
This is the main UI project for the Shortcut Guide module. Upon startup it does the following tasks:
Contains the code for loading the SVGs, creating and rendering of the overlay window. Manages and displays overlay windows with SVG graphics through two main classes:
- D2DOverlaySVG: Handles loading, resizing, and manipulation of SVG graphics
- D2DOverlayWindow: Manages the display and behavior of the overlay window
1. Copies the built-in manifest files to the users manifest directory (overwriting existing files).
2. Generate the `index.yml` manifest file.
3. Populate the PowerToys shortcut manifest with the user-defined shortcuts.
State machine that handles the keyboard events. It's responsible for deciding when to show the overlay, when to suppress the Start menu (if the overlay is displayed long enough), etc. Handles state transitions and synchronization to ensure the overlay is shown or hidden appropriately based on user interactions.
Handles the timing and interpolation of animations. Calculates the current value of an animation based on elapsed time and a specified easing function.
This function checks if the current window is excluded from the Shortcut Guide overlay. It returns `true` if the current window is excluded otherwise it returns `false`.
Waits for a named event and executes a specified action when the event is triggered. Uses a separate thread to handle event waiting and action execution.
This function retrieves the positions of the taskbar buttons for a given monitor. It returns an array of `TasklistButton` structures (max 10), which contain the position and size of each button.
The entry point for the PowerToys Shortcut Guide application. Handles initialization, ensures single instance execution, manages parent process termination, creates and displays the overlay window, and runs the main event loop.
`size` will contain the resulting array size.
It determines the positions through Windows `FindWindowEx` function.
For the primary taskbar it searches for:
* A window called "Shell_TrayWnd"
* that contains a window called "ReBarWindow32"
* that contains a window called "MSTaskSwWClass"
* that contains a window called "MSTaskListWClass"
For any secondary taskbar it searches for:
* A window called "Shell_SecondaryTrayWnd"
* that contains a window called "WorkerW"
* that contains a window called "MSTaskListWClass"
It then enumerates all the button elements inside "MSTaskListWClass" while skipping such with a same name (which implies the user does not use combining taskbar buttons)
If this method fails, which it will for newer versions of Windows, it falls back to searching for:
* A window called "Shell_TrayWnd" or "Shell_SecondaryTrayWnd"
* that contains a window called "Windows.UI.Composition.DesktopWindowContentBridge"
* that contains a window called "Windows.UI.Input.InputSite.WindowClass"
* the first child element
It then enumerates all the button elements inside the selected while skipping such with a same name (which implies the user does not use combining taskbar buttons) and such that do not start with "Appid:" (which are not actual taskbar buttons related to apps, but others like the widgets or the search button).
This spec provides an extension to the existing [WinGet manifest schema](https://github.com/microsoft/winget-pkgs/blob/master/doc/manifest/README.md) in form of an additional yaml file, that describes keyboard shortcuts the application provides.
These yaml files are saved on a per-user base and so called manifest interpreters can then display these manifests in a human-friendly version.
### 1.1 What this spec is not about
This spec does not provide a way to back up or save user-defined keyboard shortcuts.
## 2 Save location of manifests
### 2.1 WinGet
These files are saved online along with the other manifest files in the [WinGet Package repository](https://github.com/microsoft/winget-pkgs).
### 2.2 Locally
All manifests and one index file are saved locally under `%LocalAppData%/Microsoft/WinGet/KeyboardShortcuts`. All apps are allowed to add their manifest files there. In addition Package Managers (like WinGet) and manifest interpreters (like PowerToys Shortcut Guide) can control and add other manifests themselves.
#### 2.2.1 Downloading manifests
When WinGet or other package managers download a package, they should also download the corresponding keyboard shortcuts manifest file and save it in the local directory, given such a file exists in the WinGet repository.
The downloader is also responsible for updating the local `index.yaml` file, which contains all the information about the different manifest files that are saved in the same directory.
#### 2.2.2 Updating manifests
When a manifest interpreter starts, it should download the latest version of the manifests from the WinGet repository and save them in the local directory. If a manifest interpreter is not able to download the manifests or they do not exist, it should use the locally saved manifests.
The updater is also responsible for updating the local `index.yaml` file, which contains all the information about the different manifest files that are saved in the same directory.
> Note: WinGet must provide a way to update the keyboard shortcuts manifests given a package id.
### 2.3 File names
The file name of a keyboard shortcuts file is the WinGet package identifier, plus the locale of the strings of the file and at last the `.KBSC.yaml` file extension.
For example the package "test.bar" saves its manifest with `en-US` strings in `test.bar.en-US.KBSC.yaml`.
#### 2.3.1 No winget package available
If an application has no corresponding WinGet package its name starts with a plus (`+`) symbol.
### 2.4 Reserved namespaces
Every name starting with `+WindowsNT` is reserved for the Windows OS and its components.
## 3 File syntax
All relevant files are written in [YAML](https://yaml.org/spec).
> Note: A JSON schema will be provided as soon as the spec reaches a further step
WindowFilter: # The filter of window processes to which the shortcuts apply to
BackgroundProcess: # Optionally allows applying WindowFilter to background processes
Shortcuts: # List of sections with keyboard shortcuts
- SectionName: # Name of the category of shortcuts
Properties: # List of shortcuts in the category
- Name: # Name of the shortcut
Description: # Optional description of the shortcut
AdditionalInfo: # Optional additional information about the shortcut
Recommended: # Optionally determines if the shortcut is displayed in a designated recommended area
Shortcut: # An array of shortcuts that need to be pressed
- Win: # Determines if the Windows Key is part of the shortcut
Ctrl: # Determines if the Ctrl Key is part of the shortcut
Shift: # Determines if the Shift Key is part of the shortcut
Alt: # Determines if the Alt Key is part of the shortcut
Keys: # Array of keys that need to be pressed
```
Per Application/Package one or more Keyboard manifests can be declared. Every manifest must have a different locale and the same `PackageName`, `WindowFilter` and `BackgroundProcess` fields.
<details>
<summary><b>PackageName</b> - The package unique identifier</summary>
Package identifier (see 2.1 for more information on the package identifier).
</details>
<details>
<summary><b>WindowFilter</b> - The filter of window processes to which the shortcuts apply to</summary>
This field declares for which process name the shortcuts should be showed (To rephrase: For which processes the shortcut will have an effect if pressed). You can use an asterisk to leave out a certain part. For example `*.PowerToys.*.exe` targets all PowerToys processes and `*` apply to any process.
</details>
<details>
<summary><b>BackgroundProcess</b> - Optionally allows applying WindowFilter to background processes.</summary>
**Optional field**
Defaults to `False`. Determines if WindowFilter should apply to background processes as well (Rephrased: When the process is running, the shortcuts will apply).
</details>
<details>
<summary><b>Shortcuts</b> - List of sections with keyboard shortcuts</summary>
List of different section (also called categories) of shortcuts.
</details>
<details>
<summary><b>SectionName</b> - Name of the category of shortcuts</summary>
Name of the section of shortcuts.
**Special sections**:
Special sections start with an identifier enclosed between `<` and `>`. This declares the category as a special display. If the interpreter of the manifest file can't understand the content this section should be left out.
</details>
<details>
<summary><b>Properties</b> - List of shortcuts in the category</summary>
</details>
<details>
<summary><b>Name</b> - Name of the shortcut</summary>
Name of the shortcut. This is the name that will be displayed in the interpreter.
</details>
<details>
<summary><b>Description</b> - Optional description of the shortcut</summary>
Optional description of the shortcut. This is the description that will be displayed by the interpreter.
</details>
<details>
<summary><b>AdditionalInfo</b> - Optional additional information about the shortcut</summary>
Array of additional information about the shortcut. This is the additional information that will be displayed by the interpreter and are not part of this manifest.
**Example**:
For example, if the shortcut is only available on a certain Windows version, this information could be added here.
```yaml
AdditionalInfo:
- MinWindowsVersion: "10.0.19041.0"
```
</details>
<details>
<summary><b>Shortcut</b> - An array of shortcuts that need to be pressed</summary>
An array of shortcuts that need to be pressed. This allows defining sequential shortcuts that need to be pressed in order to trigger the action.
</details>
<details>
<summary><b>Win</b> - Determines if the Windows Key is part of the shortcut</summary>
Refers to the left Windows Key on the keyboard.
</details>
<details>
<summary><b>Ctrl</b> - Determines if the Ctrl Key is part of the shortcut</summary>
Refers to the left Ctrl Key on the keyboard.
</details>
<details>
<summary><b>Shift</b> - Determines if the Shift Key is part of the shortcut</summary>
Refers to the left Shift Key on the keyboard.
</details>
<details>
<summary><b>Alt</b> - Determines if the Alt Key is part of the shortcut</summary>
Refers to the left Alt Key on the keyboard.
</details>
<details>
<summary><b>Recommended</b> - Optionally determines if the shortcut is displayed in a designated recommended area</summary>
**Optional field**
Defaults to `False`. Determines if the shortcut should be displayed in a designated recommended area. This is a visual hint for the user that this shortcut is important.
</details>
<details>
<summary><b>Keys</b> - Array of keys that need to be pressed</summary>
A string array of all the keys that need to be pressed. If a number is supplied, it should be read as a [KeyCode](https://learn.microsoft.com/windows/win32/inputdev/virtual-key-codes) and displayed accordingly (based on the Keyboard Layout of the user).
**Special keys**:
Special keys are enclosed between `<` and `>` and correspond to a key that should be displayed in a certain way. If the interpreter of the manifest file can't understand the content, the brackets should be left out.
|Name|Description|
|----|-----------|
|`<Office>`| Corresponds to the Office key on some Windows keyboards |
|`<Copilot>`| Corresponds to the Copilot key on some Windows keyboards |
|`<Left>`| Corresponds to the left arrow key |
|`<Right>`| Corresponds to the right arrow key |
|`<Up>`| Corresponds to the up arrow key |
|`<Down>`| Corresponds to the down arrow key |
|`<Enter>`| Corresponds to the Enter key |
|`<Space>`| Corresponds to the Space key |
|`<Tab>`| Corresponds to the Tab key |
|`<Backspace>`| Corresponds to the Backspace key |
|`<Delete>`| Corresponds to the Delete key |
|`<Insert>`| Corresponds to the Insert key |
|`<Home>`| Corresponds to the Home key |
|`<End>`| Corresponds to the End key |
|`<PrtScr>`| Corresponds to the Print Screen key |
|`<Pause>`| Corresponds to the pause key |
|`<PageUp>`| Corresponds to the Page Up key |
|`<PageDown>`| Corresponds to the Page Down key |
|`<Escape>`| Corresponds to the Escape key |
|`<Arrow>`| Corresponds to either the left, right, up or down arrow key |
|`<ArrowLR>`| Corresponds to either the left or right arrow key |
|`<ArrowUD>`| Corresponds to either the up or down arrow key |
|`<Underlined letter>`| Corresponds to any letter that is _underlined_ in the UI |
</details>
#### 3.2.2 Example
```yaml
PackageName: Microsoft.PowerToys
WindowFilter: "*"
BackgroundProcess: True
Shortcuts:
- SectionName: General
Properties:
- Name: Advanced Paste
Shortcut:
- Win: True
Ctrl: False
Alt: False
Shift: False
Keys:
- 86
Description: Open Advanced Paste window
- Name: Advanced Paste
Shortcut:
- Win: True
Ctrl: True
Alt: True
Shift: False
Keys:
- 86
Description: Paste as plain text directly
```
### 3.2 `index.yaml` file
The `index.yaml` file is a file that contains all the information about the different manifest files that are saved in the same directory. This file is only available locally and is not saved in the WinGet repository as it is specific to the user.
```yaml
DefaultShellName: # The package identifier of the default shell used in Windows
Index: # List of all manifest files
- WindowFilter: # The filter of window processes to which the shortcuts apply to
BackgroundProcess: # Optionally allows applying WindowFilter to background processes
Apps: # List of all manifest files for the filter
```
<details>
<summary><b>DefaultShellName</b> - The package identifier of the default shell used in Windows</summary>
This declares the package identifier of the default shell used in Windows. Most commonly it is `+WindowsNT.Shell`. Although not enforced, only the shell declared in the registry key `HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Shell` should be used here.
</details>
<details>
<summary><b>Index</b> - List of all manifest files</summary>
</details>
<details>
<summary><b>WindowFilter</b> - The filter of window processes to which the shortcuts apply to</summary>
See the `WindowFilter` field in the manifest file for more information.
</details>
<details>
<summary><b>BackgroundProcess</b> - Optionally allows applying WindowFilter to background processes</summary>
**Optional field**
See the `BackgroundProcess` field in the manifest file for more information.
</details>
<details>
<summary><b>Apps</b> - List of all the package identifiers applying for the filter</summary>
<Custom Action="TelemetryLogUninstallSuccess" After="InstallFinalize" Condition="Installed and (NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")" />
<Custom Action="DeleteWinAppSDKHardlinks" Before="RemoveFiles" Condition="Installed AND (REMOVE="ALL")" />
<Custom Action="UnApplyModulesRegistryChangeSets" Before="RemoveFiles" Condition="Installed AND (REMOVE="ALL")" />
<Custom Action="UnRegisterContextMenuPackages" Before="RemoveFiles" Condition="Installed AND (REMOVE="ALL")" />
<Custom Action="CleanImageResizerRuntimeRegistry" Before="RemoveFiles" Condition="Installed AND (REMOVE="ALL")" />
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
<PackageReferenceInclude="System.Data.SqlClient"/><!-- It's a dependency of Microsoft.Windows.Compatibility. We're adding it here to force it to the version specified in Directory.Packages.props -->
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.