Commit Graph

874 Commits

Author SHA1 Message Date
Michael Jolley
9ee0c7259b CmdPal: Dock Auto-hide (#48565)
This pull request introduces a new "Auto-hide" feature for the dock,
allowing users to collapse the dock until they hover over its screen
edge. The changes include updates to the settings model, UI,
localization resources, and automated tests to support and verify this
new functionality.

**Show me:**


https://github.com/user-attachments/assets/689625e8-9050-4a54-9c4b-9e303a3da63a

**Conflicted?**

"What if I have Taskbar and Dock on the same side and both with
auto-hide turned on?"

<img width="1437" height="264" alt="Screenshot 2026-06-14 144814"
src="https://github.com/user-attachments/assets/bd037a11-0653-4b9a-bd21-625aca03b901"
/>


Closes #46239

---------

Co-authored-by: root <root@io.bbq>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-24 16:39:58 -05:00
Boliang Zhang
7e877558b9 Add powertoys-module-verification agent skill (#48717)
## Summary of the Pull Request

Adds a new **GitHub Copilot Agent Skill**,
`powertoys-module-verification`, under `.github/skills/`. It packages
the workflow, drive techniques, helper scripts, and per-module reference
data an AI agent uses to verify a single PowerToys module's
release-checklist items end-to-end (each checkbox → a structured PASS /
FAIL / BLOCKED verdict with evidence).

This is **docs/automation tooling only** — no product code, binaries, or
end-user strings are touched.

## PR Checklist

- [ ] Closes: #xxx
- [x] **Communication:** Internal tooling for release sign-off; happy to
adjust scope/placement based on review.
- [x] **Tests:** N/A — documentation/skill bundle only (no product code
paths). The 12 bundled `.ps1` helpers are agent utilities, not part of
the product build/test.
- [x] **Localization:** N/A — no end-user-facing strings.
- [x] **New binaries:** N/A — no binaries added.
- [x] **Dev docs:** This PR *is* developer-facing documentation/tooling.

## Detailed Description of the Pull Request / Additional comments

Layout follows the repo's Agent Skill guidelines
(`.github/instructions/agent-skills.instructions.md`) and matches the
existing skills under `.github/skills/`:

```
.github/skills/powertoys-module-verification/
├── SKILL.md            # single entry doc (name/description/license frontmatter)
├── LICENSE.txt         # Apache 2.0 (matches existing skills)
├── scripts/            # 12 PowerShell helper utilities used by the agent
└── references/
    ├── winapp-ui-testing.md         # UIA-mechanics prerequisite doc
    ├── pre-flight.md / reporting-format.md / environment-setup.md / explorer-context-menu-flow.md
    ├── modules/                     # per-module verification profiles
    └── release-checklist/           # per-module checklists + index
```

Notes for reviewers:
- **`references/winapp-ui-testing.md`** is adapted from the
`winui-ui-testing` skill in
[microsoft/win-dev-skills](https://github.com/microsoft/win-dev-skills)
(MIT, © Microsoft Corporation and Contributors), with PowerToys-specific
edits. Provenance is recorded in the file header. Its skill frontmatter
was intentionally stripped so it is treated as a reference doc, not a
separately-discovered skill.
- **Checklist scope:** only modules already verified end-to-end (with a
sign-off report) are included for now — Environment Variables, File
Locksmith, Image Resizer, New+, Peek, PowerRename. Remaining modules'
checklists will be added as each is verified.
- No existing files are modified; this is purely additive under
`.github/skills/`.

## Validation Steps Performed

- Validated the bundle against the Agent Skill checklist in
`.github/instructions/agent-skills.instructions.md`: valid `name` (≤64
chars) + `description` + `license` frontmatter; `SKILL.md` body under
the 500-line guidance; single `SKILL.md`; `scripts/` + `references/`
resource buckets; all resource references use relative paths.
- Verified internal cross-references resolve after the migration (no
stale `helpers/`, `Winapp-SKILL.md`, or absolute-path tokens;
`src/modules/...` source citations left intact).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-24 13:45:26 -07:00
dependabot[bot]
5c63486dcb build(deps): bump actions/checkout from 6 to 7 (#48743)
Bumps [actions/checkout](https://github.com/actions/checkout) from 6 to
7.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/checkout/releases">actions/checkout's
releases</a>.</em></p>
<blockquote>
<h2>v7.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>block checking out fork pr for pull_request_target and workflow_run
by <a href="https://github.com/aiqiaoy"><code>@​aiqiaoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2454">actions/checkout#2454</a></li>
<li>Bump actions/publish-immutable-action from 0.0.3 to 0.0.4 in the
minor-actions-dependencies group across 1 directory by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2458">actions/checkout#2458</a></li>
<li>Bump flatted from 3.3.1 to 3.4.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2460">actions/checkout#2460</a></li>
<li>Bump js-yaml from 4.1.0 to 4.2.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2461">actions/checkout#2461</a></li>
<li>Bump <code>@​actions/core</code> and
<code>@​actions/tool-cache</code> and Remove uuid by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2459">actions/checkout#2459</a></li>
<li>upgrade module to esm and update dependencies by <a
href="https://github.com/aiqiaoy"><code>@​aiqiaoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2463">actions/checkout#2463</a></li>
<li>Bump the minor-npm-dependencies group across 1 directory with 3
updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2462">actions/checkout#2462</a></li>
<li>getting ready for checkout v7 release by <a
href="https://github.com/aiqiaoy"><code>@​aiqiaoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2464">actions/checkout#2464</a></li>
<li>update error wording by <a
href="https://github.com/aiqiaoy"><code>@​aiqiaoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2467">actions/checkout#2467</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/aiqiaoy"><code>@​aiqiaoy</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/checkout/pull/2454">actions/checkout#2454</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v6.0.3...v7.0.0">https://github.com/actions/checkout/compare/v6.0.3...v7.0.0</a></p>
<h2>v6.0.3</h2>
<h2>What's Changed</h2>
<ul>
<li>Update changelog by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2357">actions/checkout#2357</a></li>
<li>fix: expand merge commit SHA regex and add SHA-256 test cases by <a
href="https://github.com/yaananth"><code>@​yaananth</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2414">actions/checkout#2414</a></li>
<li>Fix checkout init for SHA-256 repositories by <a
href="https://github.com/yaananth"><code>@​yaananth</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2439">actions/checkout#2439</a></li>
<li>Update changelog for v6.0.3 by <a
href="https://github.com/yaananth"><code>@​yaananth</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2446">actions/checkout#2446</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/yaananth"><code>@​yaananth</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/checkout/pull/2414">actions/checkout#2414</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v6...v6.0.3">https://github.com/actions/checkout/compare/v6...v6.0.3</a></p>
<h2>v6.0.2</h2>
<h2>What's Changed</h2>
<ul>
<li>Add orchestration_id to git user-agent when ACTIONS_ORCHESTRATION_ID
is set by <a
href="https://github.com/TingluoHuang"><code>@​TingluoHuang</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/2355">actions/checkout#2355</a></li>
<li>Fix tag handling: preserve annotations and explicit fetch-tags by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2356">actions/checkout#2356</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v6.0.1...v6.0.2">https://github.com/actions/checkout/compare/v6.0.1...v6.0.2</a></p>
<h2>v6.0.1</h2>
<h2>What's Changed</h2>
<ul>
<li>Update all references from v5 and v4 to v6 by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2314">actions/checkout#2314</a></li>
<li>Add worktree support for persist-credentials includeIf by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2327">actions/checkout#2327</a></li>
<li>Clarify v6 README by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2328">actions/checkout#2328</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v6...v6.0.1">https://github.com/actions/checkout/compare/v6...v6.0.1</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/actions/checkout/blob/main/CHANGELOG.md">actions/checkout's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<h2>v7.0.0</h2>
<ul>
<li>Block checking out fork PR for pull_request_target and workflow_run
by <a href="https://github.com/aiqiaoy"><code>@​aiqiaoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2454">actions/checkout#2454</a></li>
<li>Bump actions/publish-immutable-action from 0.0.3 to 0.0.4 in the
minor-actions-dependencies group across 1 directory by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2458">actions/checkout#2458</a></li>
<li>Bump flatted from 3.3.1 to 3.4.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2460">actions/checkout#2460</a></li>
<li>Bump js-yaml from 4.1.0 to 4.2.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2461">actions/checkout#2461</a></li>
<li>Bump <code>@​actions/core</code> and
<code>@​actions/tool-cache</code> and Remove uuid by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2459">actions/checkout#2459</a></li>
<li>upgrade module to esm and update dependencies by <a
href="https://github.com/aiqiaoy"><code>@​aiqiaoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2463">actions/checkout#2463</a></li>
<li>Bump the minor-npm-dependencies group across 1 directory with 3
updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2462">actions/checkout#2462</a></li>
</ul>
<h2>v6.0.3</h2>
<ul>
<li>Fix checkout init for SHA-256 repositories by <a
href="https://github.com/yaananth"><code>@​yaananth</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2439">actions/checkout#2439</a></li>
<li>fix: expand merge commit SHA regex and add SHA-256 test cases by <a
href="https://github.com/yaananth"><code>@​yaananth</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2414">actions/checkout#2414</a></li>
</ul>
<h2>v6.0.2</h2>
<ul>
<li>Fix tag handling: preserve annotations and explicit fetch-tags by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2356">actions/checkout#2356</a></li>
</ul>
<h2>v6.0.1</h2>
<ul>
<li>Add worktree support for persist-credentials includeIf by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2327">actions/checkout#2327</a></li>
</ul>
<h2>v6.0.0</h2>
<ul>
<li>Persist creds to a separate file by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2286">actions/checkout#2286</a></li>
<li>Update README to include Node.js 24 support details and requirements
by <a href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/2248">actions/checkout#2248</a></li>
</ul>
<h2>v5.0.1</h2>
<ul>
<li>Port v6 cleanup to v5 by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2301">actions/checkout#2301</a></li>
</ul>
<h2>v5.0.0</h2>
<ul>
<li>Update actions checkout to use node 24 by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2226">actions/checkout#2226</a></li>
</ul>
<h2>v4.3.1</h2>
<ul>
<li>Port v6 cleanup to v4 by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2305">actions/checkout#2305</a></li>
</ul>
<h2>v4.3.0</h2>
<ul>
<li>docs: update README.md by <a
href="https://github.com/motss"><code>@​motss</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1971">actions/checkout#1971</a></li>
<li>Add internal repos for checking out multiple repositories by <a
href="https://github.com/mouismail"><code>@​mouismail</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1977">actions/checkout#1977</a></li>
<li>Documentation update - add recommended permissions to Readme by <a
href="https://github.com/benwells"><code>@​benwells</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2043">actions/checkout#2043</a></li>
<li>Adjust positioning of user email note and permissions heading by <a
href="https://github.com/joshmgross"><code>@​joshmgross</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2044">actions/checkout#2044</a></li>
<li>Update README.md by <a
href="https://github.com/nebuk89"><code>@​nebuk89</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2194">actions/checkout#2194</a></li>
<li>Update CODEOWNERS for actions by <a
href="https://github.com/TingluoHuang"><code>@​TingluoHuang</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/2224">actions/checkout#2224</a></li>
<li>Update package dependencies by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2236">actions/checkout#2236</a></li>
</ul>
<h2>v4.2.2</h2>
<ul>
<li><code>url-helper.ts</code> now leverages well-known environment
variables by <a href="https://github.com/jww3"><code>@​jww3</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/1941">actions/checkout#1941</a></li>
<li>Expand unit test coverage for <code>isGhes</code> by <a
href="https://github.com/jww3"><code>@​jww3</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1946">actions/checkout#1946</a></li>
</ul>
<h2>v4.2.1</h2>
<ul>
<li>Check out other refs/* by commit if provided, fall back to ref by <a
href="https://github.com/orhantoy"><code>@​orhantoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1924">actions/checkout#1924</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="9c091bb21b"><code>9c091bb</code></a>
update error wording (<a
href="https://redirect.github.com/actions/checkout/issues/2467">#2467</a>)</li>
<li><a
href="1044a6dea9"><code>1044a6d</code></a>
getting ready for checkout v7 release (<a
href="https://redirect.github.com/actions/checkout/issues/2464">#2464</a>)</li>
<li><a
href="f0282184c7"><code>f028218</code></a>
Bump the minor-npm-dependencies group across 1 directory with 3 updates
(<a
href="https://redirect.github.com/actions/checkout/issues/2462">#2462</a>)</li>
<li><a
href="d914b262ff"><code>d914b26</code></a>
upgrade module to esm and update dependencies (<a
href="https://redirect.github.com/actions/checkout/issues/2463">#2463</a>)</li>
<li><a
href="537c7ef99c"><code>537c7ef</code></a>
Bump <code>@​actions/core</code> and <code>@​actions/tool-cache</code>
and Remove uuid (<a
href="https://redirect.github.com/actions/checkout/issues/2459">#2459</a>)</li>
<li><a
href="130a169078"><code>130a169</code></a>
Bump js-yaml from 4.1.0 to 4.2.0 (<a
href="https://redirect.github.com/actions/checkout/issues/2461">#2461</a>)</li>
<li><a
href="7d09575332"><code>7d09575</code></a>
Bump flatted from 3.3.1 to 3.4.2 (<a
href="https://redirect.github.com/actions/checkout/issues/2460">#2460</a>)</li>
<li><a
href="0f9f3aa320"><code>0f9f3aa</code></a>
Bump actions/publish-immutable-action (<a
href="https://redirect.github.com/actions/checkout/issues/2458">#2458</a>)</li>
<li><a
href="f9e715a95f"><code>f9e715a</code></a>
block checking out fork pr for pull_request_target and workflow_run (<a
href="https://redirect.github.com/actions/checkout/issues/2454">#2454</a>)</li>
<li>See full diff in <a
href="https://github.com/actions/checkout/compare/v6...v7">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=6&new-version=7)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-24 09:51:55 +02:00
Clint Rutkas
968a7ac4b6 [Peek] Stop fail-fast in AppWindow.Closing path; reset cached preview-handler factories on release (#48564)
## Summary

Harden Peek's `AppWindow.Closing` path so a stale cached preview-handler
factory can't fail-fast the Peek process. Also clean up the matching
path in RegistryPreview.

## Background

Spotted while reading through Peek's `MainWindow` teardown sequence and
the `ShellPreviewHandlerPreviewer` cache for an unrelated review of how
Peek manages out-of-process preview-handler lifetimes.

The Peek `MainWindow` subscribes to `AppWindow.Closing`. The handler
doesn't actually close the window — it sets `args.Cancel = true` and
calls `Uninitialize()`, which in turn calls
`ShellPreviewHandlerPreviewer.ReleaseHandlerFactories()`.

`ReleaseHandlerFactories()` looked like this:

```csharp
public static void ReleaseHandlerFactories()
{
    foreach (var factory in HandlerFactories.Values)
    {
        try { Marshal.FinalReleaseComObject(factory); } catch { }
    }
}
```

Two problems:

1. The static `HandlerFactories` dictionary is never cleared. After
`FinalReleaseComObject`, the entries still point at separated RCWs. A
subsequent activation that races with this cleanup (or a second close in
the same process) can pick up the dead RCW from the cache.
2. The cached factory had `LockServer(true)` called on it when it was
first cached, but the matching `LockServer(false)` was never paired.

Any managed exception that escapes a WinRT event callback is projected
back to CFlat as a failed HRESULT and the CsWinRT dispatcher fail-fasts
the process. So a single `InvalidComObjectException` (HRESULT
0x80131527) thrown out of `Uninitialize()` is enough to terminate Peek.

## Changes

* **`ShellPreviewHandlerPreviewer.ReleaseHandlerFactories`** — snapshot
then clear the dictionary up front so that a subsequent call (or a
concurrent `LoadPreviewAsync`) can't pick up a stale RCW. Call
`LockServer(false)` before `FinalReleaseComObject` to mirror the
cache-time `LockServer(true)`. Both COM calls remain individually
wrapped because the RCW may already be unreachable during process
teardown.
* **`Peek.UI/MainWindow.xaml.cs` — `AppWindow_Closing`** — wrap the body
in try/catch + `Logger.LogError`. Any future exception in
`Uninitialize()` (or its callees) will now log instead of fail-fasting
the process.
* **`RegistryPreview/MainWindow.Events.cs` — `AppWindow_Closing`** —
same defensive try/catch, plus null-guard `jsonWindowPlacement` before
`SetNamedValue`. The placement dictionary can legitimately be null on
first run or after a corrupt placement file; previously that would NRE →
fail-fast.

## Risk

Low. The `ReleaseHandlerFactories` change matches the documented
`LockServer`/`FinalReleaseComObject` pairing and only widens the
lifetime window of the cache by `Clear()`-ing earlier; nothing in Peek
calls this method outside of teardown. The two try/catch wrappers
strictly add defense — the success path is unchanged.

## Validation

Spot-built locally; this repo's `dotnet restore` runtime-pack issue
(unrelated to this PR — same NU1102 pattern that's affecting other open
PRs) prevents a full `Build.cmd` here. The C++ side of Peek is
untouched.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---

ADO:
https://microsoft.visualstudio.com/DefaultCollection/OS/_workitems/edit/58765809/

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Boliang Zhang <122517415+LegendaryBlair@users.noreply.github.com>
2026-06-23 21:32:02 +08:00
Clint Rutkas
dd26d86580 [FancyZones] Fix stuck drag state and swallowed keys when a window is destroyed mid-drag (#48569)
## Summary
Fixes a class of "stuck drag" bugs in FancyZones where closing or
destroying a window **while it is being dragged** leaves FancyZones in a
half-dragging state — zone overlays stay on screen and subsequent
keystrokes (notably number keys) are swallowed or misrouted.

## What this changes
- **Subscribe to and dispatch `EVENT_OBJECT_DESTROY`.** `FancyZonesApp`
never subscribed to the destroy event, and the consumer's
`WM_PRIV_WINDOWDESTROYED` branch could therefore never fire. The event
is now registered and routed through `HandleWinHookEvent`.
- **Abort the drag (without snapping) when the dragged window is
destroyed.** On `WM_PRIV_WINDOWDESTROYED`, if the destroyed HWND is the
one being dragged, call the new `WindowMouseSnap::Abort()` (tears down
overlays/highlights/transparency) instead of `MoveSizeEnd()`, which
would try to snap the now-dead HWND and corrupt zone state. Dragging
state is then disabled.
- **Always clear dragging state in `MoveSizeEnd()`**, even when the
snapper was already null, so the state can't get stranded.
- **Require Win+Ctrl+Alt to switch layouts while dragging.** Previously
any digit switched layouts while `dragging` was true; if drag state was
stuck this "stole" number keys from the focused app. This is the
root-cause fix for the number-key-stealing symptom.
- **Only swallow the bare Shift key during a drag**, not `Shift+<other>`
combos, so real keystrokes are no longer eaten by an in-progress drag.

## Testing
- Builds Release x64 (FancyZones) clean against current `main`.
- Manually verified drag → close window mid-drag no longer leaves
overlays up or steals number keys. (FancyZones has no unit-test harness
for this path.)

This is one of a small set of related "stuck key / stuck state"
hardening fixes; each stands alone.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Muyuan Li <116717757+MuyuanMS@users.noreply.github.com>
2026-06-23 15:09:26 +02:00
moooyo
32ad98a0dd [PowerDisplay] Detect built-in panel when driven by the discrete GPU (#48637)
## Summary of the Pull Request

On dual-GPU laptops, Power Display stopped detecting the built-in panel
(and adjusting its brightness) when the **discrete GPU** drives the
display — it showed "can't detect the display". This fixes that by
classifying displays by **capability** (does WMI brightness work on it?)
instead of by the nominal `OutputTechnology` value, which the discrete
GPU misreports for the internal panel.

## PR Checklist

- [x] Closes: #48587
- [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
- [x] **Localization:** All end-user-facing strings can be localized (no
new user-facing strings added)
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places

## Detailed Description of the Pull Request / Additional comments

### Root cause

On a hybrid / MUX laptop, when the **discrete GPU** drives the built-in
eDP panel, `QueryDisplayConfig` reports the panel's
`DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY` as `DISPLAYPORT_EXTERNAL` (`10`)
instead of the `INTERNAL` flag (`0x80000000`) it reports under the
integrated GPU. It is the *same physical panel* (same EDID) — only the
reported connector type changes with the active GPU.

PR #47740 introduced a strict classifier: `OutputTechnology` →
internal/external, then **internal → WMI-only, external → DDC/CI-only,
with no fallback**. So under the discrete GPU the built-in panel was
classified *external* and sent to DDC/CI only — but a laptop eDP panel
does not speak DDC/CI, so it was dropped and Power Display reported it
couldn't detect any monitor. (`WmiMonitorBrightness` still exposes that
panel regardless of which GPU drives it, so the panel was actually
controllable — it just never got routed to WMI.)

### Fix: classify by capability, not by nominal output technology

- **`MonitorManager`** now runs **WMI discovery first** over the full
`QueryDisplayConfig` inventory. Every display `WmiMonitorBrightness`
exposes is treated as internal (WMI-controlled); whatever WMI does
**not** claim is routed to DDC/CI. The `OutputTechnology`-based
classifier is gone.
- **`WmiController`** matches the system-wide `WmiMonitorBrightness`
results against the full inventory by `Monitor.Id`. The persisted
`Monitor.Id` is still taken from the matched `DevicePath`
(byte-identical to the DDC route and to prior releases), so saved
brightness/per-monitor settings survive upgrades.
- New **`MonitorIdentity.FromInstanceName`** reduces a WMI
`InstanceName` to the same canonical `Monitor.Id` as `FromDevicePath`;
the separate `PnpHardwareKey` helper is removed.
- **Deleted** `DisplayClassifier` and `MonitorDisplayInfo.IsInternal`
(net ~150 fewer lines).

### Accepted trade-off

A monitor that exposes **both** `WmiMonitorBrightness` **and** DDC/CI is
now controlled via WMI only and won't get DDC-only features (contrast /
volume / input source / color temperature / power). This is uncommon
(typical laptop panels are WMI-only; typical external monitors are
DDC-only) and is a deliberate decision: it removes the entire class of
`OutputTechnology` misclassification bugs while keeping the performance
win of not DDC-probing internal panels.

## Validation Steps Performed

- Built the Power Display app (`PowerDisplay.csproj`) and
`PowerDisplay.Lib.UnitTests` (x64 / Debug) with MSBuild — both succeed,
including after merging latest `main` (Windows App SDK 2.2.0).
- Ran the unit test suite: **128/128 pass**, including new
`FromInstanceName` tests — the `FromInstanceName == FromDevicePath`
equivalence invariant and a concrete #48587 regression case (the BOE
panel reported as `OutputTechnology=10`).
- Traced the fix against the reporter's diagnostic logs: the panel that
previously went `OutputTechnology=10 → External → DDC → dropped` is now
claimed by WMI and controllable.
- Reviewed the diff for regressions (Monitor.Id persistence, monitor
blacklist, mirror mode, dual-internal-panel devices, external-only
desktops).

---------

Co-authored-by: Yu Leng <yuleng@microsoft.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 13:37:32 +08:00
Bryce Cindrich
a0e53de825 feat(shortcut-guide): add Postman manifest and fix numbered-key display (#48461)
## Summary of the Pull Request

Adds a Shortcut Guide manifest for **Postman** and fixes a rendering bug
where single-digit keys in manifests displayed incorrectly.

- **Fix numbered-key rendering** —
`src/modules/ShortcutGuide/ShortcutGuide.Ui/Converters/ShortcutDescriptionToKeysConverter.cs`:
a single digit (`0`–`9`) in a manifest's `Keys` was treated as a Windows
virtual-key code instead of the literal digit. Since VK `1` is the left
mouse button, VK `9` is Tab, and VK `0` is undefined, shortcuts such as
`Ctrl+0` (reset zoom) and `Ctrl+9` (last tab) rendered as
blank/incorrect glyphs. Single digits are now rendered as the literal
character.
- **Add Postman shortcuts** —
`src/modules/ShortcutGuide/ShortcutGuide.Ui/Assets/ShortcutGuide/Manifests/Postman.Postman.en-US.yml`:
new manifest for `Postman.exe` covering Tabs, Sidebar, Request,
Interface, Window and modals, and Console. Auto-included via the
existing `Manifests/*.yml` glob in `ShortcutGuide.Ui.csproj`.
- **Show tab-number ranges** — Edge, Chrome, Firefox, and Postman
manifests: the "switch to a specific tab" entry used the literal key
`1`, which (after the fix above) read as `Ctrl + 1`. It now uses a `1 -
8` range so the keycap conveys "any tab number 1 through 8". The
separate "last tab" (`9`) and "reset zoom" (`0`) entries remain literal
single keys.
- **Add unit tests** — new `ShortcutGuide.UnitTests` (MSTest) project
covering `ShortcutDescriptionToKeysConverter.GetKeysList`, including the
single-digit regression.

## PR Checklist

- [x] Closes: #48460
- [ ] **Communication:** I've discussed this with core contributors
already. <!-- Filed #48460; the v0.100 announcement invites app-shortcut
contributions via PR. -->
- [x] **Tests:** Added/updated and all pass <!-- New
ShortcutGuide.UnitTests (MSTest); 8 tests pass locally via
vstest.console. -->
- [x] **Localization:** All end-user-facing strings can be localized
<!-- Shortcut names live in per-language manifest files (`*.en-US.yml`);
other locales fall back to en-US, consistent with existing manifests.
-->
- [ ] **Dev docs:** Added/updated <!-- N/A: no behavior requiring
dev-doc changes. -->
- [ ] **New binaries:** Added on the required places <!-- N/A: the new
manifest is a data asset under an already-shipped, globbed folder. The
new test project is auto-discovered by the existing `**\*UnitTest*.dll`
VSTest glob, so no CI pipeline change is required. -->
- [ ] **Documentation updated:** <!-- N/A -->

## Detailed Description of the Pull Request / Additional comments

The Shortcut Guide displays per-app shortcuts from YAML manifests,
matched to the foreground window via `WindowFilter`. Keys are converted
to keycaps by `ShortcutDescriptionToKeysConverter`. Numeric key strings
were unconditionally parsed as virtual-key codes, so literal-digit
shortcuts rendered wrong. The fix adds a `>= 0 and <= 9` case that emits
the digit character as-is; non-digit numeric codes (arrows, etc.) are
unchanged.

The new Postman manifest exercises this with `Ctrl+0` / `Ctrl+9`. The
browser/Postman "specific tab" entries were updated from the literal `1`
to the `1 - 8` range string, rendered verbatim by `KeyVisual` (the same
path used by the existing `Number (1-9)` key in the Windows Explorer
manifest).

A new `ShortcutGuide.UnitTests` (MSTest) project covers the converter:
single digits render literally (regression test), modifier ordering,
non-numeric passthrough (e.g. `1 - 8`), and arrow-key VK mapping.

## Validation Steps Performed

Built and ran locally (x64 Debug):

- Built `ShortcutGuideModuleInterface`, `ShortcutGuide.Ui`, and
`ShortcutGuide.IndexYmlGenerator`; launched the Debug `PowerToys.exe`.
- Triggered Shortcut Guide (`Win+Shift+/`) with **Postman** focused: the
Postman section renders with all categories, and `Ctrl+1` / `Ctrl+9` /
`Ctrl+0` display correctly (previously blank/incorrect).
- Verified the "specific tab" entry renders as `Ctrl + 1 - 8` in
**Edge**, **Chrome**, **Firefox**, and **Postman**.
- Built `ShortcutGuide.UnitTests` and ran via `vstest.console.exe`:
**8/8 tests pass**.

<img width="845" height="1432" alt="PowerToys Shortcut Guide Running
Postman"
src="https://github.com/user-attachments/assets/6359617e-3e2c-48b0-8005-b3684594ec94"
/>

Co-Authored-By: Claude Opus 4.8

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 12:40:29 +08:00
Avirup
c41ac6df87 Add Pitjantjatjara language support to Quick Accent (#48561)
Closes #45025

## [QuickAccent] Add Pitjantjatjara / Yankunytjatjara Language Support

### Summary
This pull request adds support for Pitjantjatjara/Yankunytjatjara 
to the Quick Accent feature. Pitjantjatjara/Yankunytjatjara is an
Australian Aboriginal language
spoken in the Western and South Australian deserts.

### What's New
- Users can now access Pitjantjatjara/Yankunytjatjara retroflex
consonant characters (ḻ, ṉ, ṟ, ṯ)
  through Quick Accent
- Language is available in the Quick Accent settings dropdown menu
- Full localization support for UI display

### Why This Matters
Pitjantjatjara/Yankunytjatjara uses unique retroflex consonants that are
essential for:
- **Correct pronunciation:** Retroflex sounds are phonetically distinct
from regular consonants
- **Written accuracy:** Proper character representation in educational
materials
- **Cultural preservation:** Supporting Aboriginal language
documentation and teaching
- **Accessibility:** Users without specialized keyboards can now type
these characters easily

### Character Mappings
The implementation adds 4 retroflex consonants:
- **L → ḻ** (Retroflex lateral approximant)
- **N → ṉ** (Retroflex nasal)
- **R → ṟ** (Retroflex approximant)
- **T → ṯ** (Retroflex stop)

### Files Changed
1. **Language.cs** - Added `PJT` enum value
2. **CharacterMappings.cs** - Added language entry with character
mappings and display order
3. **Resources.resw** - Added localized UI string
4. **expect.txt** - Added language name to spell-check whitelist

### Testing
-  Language appears in Quick Accent settings dropdown
-  Retroflex characters appear when holding L/N/R/T + activation key
-  No build errors or warnings
2026-06-22 03:58:43 +00:00
Clint Rutkas
459bd56fb6 Grab and Move: tight warning-gold overlay border + Always On Top 4px default (#48474)
## Summary

Refines the **Grab and Move** drag/resize overlay so it matches the
polish of **Always on Top (AoT)**, and lowers the AoT default border
thickness. Created at the request of @crutkas.

Two related border-refinement changes, kept in one PR because the Grab
and Move "double layer" is designed around AoT's border.



https://github.com/user-attachments/assets/0b605f92-60bd-44a0-a540-70e6d425146a



### 1. Always on Top - default border thickness 15 -> 4
The default highlight border was `15px`, which is visually heavy.
Dropped to `4px` for a tighter, Fluent-style frame.
- `src/modules/alwaysontop/AlwaysOnTop/Settings.h` (C++ default)
- `src/settings-ui/Settings.UI.Library/AlwaysOnTopProperties.cs`
(`DefaultFrameThickness`)
- Existing users keep their configured value; only fresh installs /
"reset" pick up `4`. Slider range (1-30) is unchanged.

### 2. Grab and Move - tight, warning-gold overlay (fill + border)
Previously the overlay was a full translucent **white wash** sized to
`GetWindowRect`, which includes the invisible resize-border / shadow
margins (~7px) - so it sat *off* the visible window. It now hugs the
visible frame, mirroring AoT:

- **Keeps the translucent white wash** over the visible window (the
familiar "grabbed" feedback) and adds a tight **warning-gold border on
top**. Both hug the visible frame and are rounded to match the window
corners.
- **Tight geometry:** anchored to `DWMWA_EXTENDED_FRAME_BOUNDS` (inset
by the invisible-border margins) instead of `GetWindowRect`.
- **Corner detection:** matches the window's corner radius via
`DWMWA_WINDOW_CORNER_PREFERENCE` (same mapping AoT uses); border
thickness and radius scale with the target window DPI.
- **Distinct accent:** Fluent **warning gold `#FFB900`** - the literal
equivalent of WinUI
[`SystemFillColorCaution`](https://learn.microsoft.com/en-us/windows/apps/design/style/color)
(used as a `ThemeResource` for warnings across the Settings UI; a Win32
layered window can't resolve a `ThemeResource`, so a literal is
required). Keeps Grab and Move visually distinct from AoT's accent-blue.
- **Double layer, for free:** the Grab and Move border is drawn just
**inside** the visible edge, while AoT draws its border just **outside**
the visible edge. The two naturally stack into a clean double layer, so
Grab and Move stays a constant **4px** with no AoT detection / window
enumeration.

Rendering keeps the existing GDI + `UpdateLayeredWindow` per-pixel-alpha
path and adds **GDI+** (a Windows system library - no new third-party
dependency) for the antialiased, rounded fill and border. Frame metrics
are computed **once per drag/resize** (never in the mouse-move hot
path). The optional geometry label is unchanged.

## Before / After
| | Before | After |
|---|---|---|
| Grab and Move overlay | Full white wash, offset from the window edge |
Same wash, now tight to the visible frame + gold border, corner-matched
|
| AoT default border | 15px | 4px |
| AoT + Grab and Move together | white wash over AoT border | GM gold
inside the edge + AoT accent outside it = double layer |

## Validation
- Builds clean (exit 0, 0 warnings/errors) for **x64 Debug**:
`GrabAndMove`, `AlwaysOnTop`, and `Settings.UI.Library` (Code Analysis /
C26451 clean).
- Smoke-tested live by running the standalone module exes: tight gold
border + wash on Alt-drag / Alt-right-drag, AoT 4px border, and the
inside/outside double layer on a pinned window.
- WARNING: still **draft** pending broader visual validation (border
tightness across DPIs, the exact gold, rounded vs square corners, AoT
z-order during fast drags - AoT renders from a separate process and
follows on a ~100ms timer). Screenshots to be added.

## Follow-up (not in this PR)
AoT and Grab and Move remain **separate** overlay systems (AoT:
persistent per-window Direct2D border; Grab and Move: transient
GDI/`UpdateLayeredWindow` overlay). They can't share one runtime window,
but the frame-geometry + corner-detection + DPI helpers are worth
extracting into `src/common` (seeded by AoT's
`WindowCornersUtil`/`ScalingUtils`). Tracked separately to keep this PR
atomic (`src/common` is an ABI-careful area).

## Notes
- No IPC/JSON schema changes; no new settings.
- No new third-party dependencies (GDI+ is a system library).

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-20 05:06:39 -07:00
Gleb Khmyznikov
d2aa24786d [DOCS] Add auto-generated github page for dev docs (#48752)
This pull request introduces a new, automated workflow for building and
publishing the developer documentation website using
[docmd](https://docmd.io/). The static site is now generated from
`doc/devdocs`, built in the `doc/devdocs-website` folder, and deployed
to GitHub Pages via a GitHub Actions workflow. The build output is not
committed to the repository but is instead published as an artifact.
Supporting configuration files, documentation, and `.gitignore` entries
are also added to streamline local development and CI/CD.

**Automated build and deployment:**

* Added `.github/workflows/regenerate-devdocs-website.yml` to build the
static site with docmd and deploy it to GitHub Pages automatically on
changes to `doc/devdocs` or `doc/devdocs-website`, or via manual
trigger.

**Project setup and configuration:**

* Added `doc/devdocs-website/package.json` to define the Node.js
project, pin the docmd version, and provide scripts for local
development and builds.
* Added `doc/devdocs-website/docmd.config.json` to configure docmd (site
title, source, output directory, base path).
* Added `doc/devdocs-website/.npmrc` to disable lockfile generation,
ensuring fresh dependency installs each build.

**Documentation and housekeeping:**

* Added `doc/devdocs-website/README.md` with instructions for editing,
building, and publishing the docs website.
* Added `doc/devdocs-website/.gitignore` to exclude the generated
`site/` output from version control.
2026-06-19 15:59:12 -05:00
Michael Jolley
d31d0ab168 Update labeling action to support pull requests (#48733)
This pull request updates the `auto-labeler.yml` GitHub Actions workflow
to improve reliability and maintain compatibility. The most important
changes are an upgrade to the `actions/github-script` version and
improved error handling when applying labels, ensuring the workflow does
not fail due to restricted permissions.

**Dependency upgrade:**
* Upgraded `actions/github-script` from version 7 to version 9 in the
`Apply area labels with AI` step, ensuring continued support and access
to the latest features and security updates.

**Error handling improvements:**
* Added a `try/catch` block around the label application logic to
gracefully handle cases where the workflow lacks permission to write
labels (e.g., due to restricted integration tokens), logging a message
and skipping the operation instead of failing the entire workflow.
2026-06-18 19:13:01 -05:00
Michael Jolley
486015d400 Add permissions for PR labeling (#48731)
This pull request makes minor adjustments to the
`.github/workflows/auto-labeler.yml` GitHub Actions workflow, focusing
on permissions and event triggers.

Workflow configuration updates:

* Added `pull-requests: write` permission to the workflow to ensure it
has the necessary access for managing pull requests.
* Removed the `edited` event from the list of triggers for
`pull_request_target`, so the workflow will no longer run when a pull
request is edited.
2026-06-18 17:47:42 -05:00
Niels Laute
a294e73bb6 [CmdPal] Animated notification (#48176)
## Summary of the Pull Request

Gives the CmdPal toast notification a glow-up: it now slides in/out with
a nice fade, has acrylic + a soft shadow, and stops fighting with
`SizeToContent`.

Along the way, the toast guts got refactored into a couple of reusable
bits that live in `PowerToys.Common.UI.Controls` so other PowerToys
utilities can grab them for their own transient overlays:

- **`TransparentWindow`** — a `WindowEx`-derived host that strips the
native frame, hides from taskbar/Alt-Tab, uses `TransparentTintBackdrop`
for transparency, and runs show/hide implicit animations on its content.
Supply your own animations via `ShowAnimations` / `HideAnimations`, or
take the defaults (fade + slide).
- **`TransparentCard`** — a templated `ContentControl` with acrylic
(`AlwaysActiveDesktopAcrylicBackdrop`), rounded corners, border, and
shadow. Drop whatever XAML you want inside.
- **`AlwaysActiveDesktopAcrylicBackdrop`** — small `SystemBackdrop`
wrapper so the acrylic doesn''t go grey when the window isn''t focused
(transient overlays are never focused).

CmdPal''s `ToastWindow` is now basically a 16-line wrapper: derives from
`TransparentWindow`, drops a bound `TextBlock` inside, and handles its
own 2.5s auto-hide timer + bottom-center positioning.



https://github.com/user-attachments/assets/3a62080c-22f0-480c-ac4d-028bcc32f07d



## PR Checklist

- [x] Closes: #40886
- [x] **Communication:** I''ve discussed this with core contributors
already.
- [ ] **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

## Detailed Description of the Pull Request / Additional comments

A couple of design notes worth calling out:

- The window is sized slightly bigger than the visible card (~24px
breathing room on each side) so the shadow and slide animation have room
to render without clipping. That buffer area is transparent but NOT
click-through — kept it small on purpose. We explored `SetWindowRgn` and
`EnableWindow` tricks to make it click-through too, but neither plays
nicely with WinUI 3''s DesktopWindowXamlSource. Small transparent frame
is the pragmatic compromise.
- Animations use the Toolkit''s implicit `ShowAnimations` /
`HideAnimations` so there''s zero animation code in
`ToastWindow.xaml.cs`.
- `TransparentCard.xaml` is registered in `Themes/Generic.xaml` —
required for templated controls in a library project;
`<GenerateLibraryLayout>` alone doesn''t auto-merge per-control xaml.

## Validation Steps Performed

- Built clean (arm64 Debug).
- Triggered a CmdPal toast manually: fades + slides in, hangs for 2.5s,
fades + slides out.
- Acrylic stays active when the window isn''t focused (toasts are never
focused).
- Shadow renders fully without clipping.

---------

Co-authored-by: niels9001 <niels9001@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-18 12:53:51 -05:00
Michael Jolley
e8fee90f49 Enhance labeling action to support pull requests (#48729)
This pull request updates the auto-labeling workflow to support both
issues and pull requests, improves clarity in logs and prompts, and
renames the workflow file for broader applicability. The changes enhance
automation for triaging by enabling area label assignment to new or
updated pull requests in addition to issues.

**Expanded triage coverage and workflow improvements:**

* The workflow now triggers on both issue and pull request events
(`opened`, `reopened`, `edited`, `synchronize`), allowing automatic area
labeling for pull requests as well as issues.
(`.github/workflows/auto-labeler.yml`,
[.github/workflows/auto-labeler.ymlL1-R7](diffhunk://#diff-f874b1d773361dc46f2496bc3ce97ee3441e91257188b27a2bd83693c3b8a82eL1-R7))
* The concurrency group logic has been updated to handle pull request
events separately from issues, ensuring that rapid updates to a PR or
issue are managed correctly. (`.github/workflows/auto-labeler.yml`,
[.github/workflows/auto-labeler.ymlR24-R26](diffhunk://#diff-f874b1d773361dc46f2496bc3ce97ee3441e91257188b27a2bd83693c3b8a82eR24-R26))

**User experience and clarity enhancements:**

* Console logs and prompt messages now refer generically to "item" or
distinguish between "Issue" and "Pull request" as appropriate, improving
clarity in workflow output and AI prompts.
(`.github/workflows/auto-labeler.yml`,
[[1]](diffhunk://#diff-f874b1d773361dc46f2496bc3ce97ee3441e91257188b27a2bd83693c3b8a82eL41-R44)
[[2]](diffhunk://#diff-f874b1d773361dc46f2496bc3ce97ee3441e91257188b27a2bd83693c3b8a82eL58-R79)
[[3]](diffhunk://#diff-f874b1d773361dc46f2496bc3ce97ee3441e91257188b27a2bd83693c3b8a82eL139-R146)
[[4]](diffhunk://#diff-f874b1d773361dc46f2496bc3ce97ee3441e91257188b27a2bd83693c3b8a82eL212-R217)
* The system prompt for the AI labeling assistant has been updated to
clarify that both issues and pull requests should be classified and
labeled. (`.github/workflows/auto-labeler.yml`,
[.github/workflows/auto-labeler.ymlL127-R133](diffhunk://#diff-f874b1d773361dc46f2496bc3ce97ee3441e91257188b27a2bd83693c3b8a82eL127-R133))

**File naming:**

* The workflow file has been renamed from
`.github/workflows/auto-label-issues.yml` to
`.github/workflows/auto-labeler.yml` to reflect its broader scope.
(`.github/workflows/auto-labeler.yml`,
[.github/workflows/auto-labeler.ymlL1-R7](diffhunk://#diff-f874b1d773361dc46f2496bc3ce97ee3441e91257188b27a2bd83693c3b8a82eL1-R7))
2026-06-18 12:05:33 -05:00
moooyo
d221f84d8f [Skills] Update WinUI3 migration skills to add more migration mapping item (#47043)
<!-- 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: #46464
<!-- - [ ] 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.6 (1M context) <noreply@anthropic.com>
2026-06-18 12:17:49 +02:00
Gordon Lam
4d01062f76 Fix check-spelling: exclude ZoomIt rnnoise third-party tree and dedupe excludes (#48548)
## Summary

The `Check Spelling` workflow has been failing on PRs against `main`
(e.g. #48546) due to issues introduced by the recent ZoomIt webcam-blur
/ noise-cancellation change (#48266) plus two pre-existing duplicate
entries in `.github/actions/spell-check/excludes.txt`.

## What the bot reported

| Severity | Type | Location |
|---|---|---|
|  | `forbidden-pattern` (Should be `a`) |
`src/modules/ZoomIt/ZoomIt/rnnoise/kiss_fft.h:79` — third-party kiss_fft
header contains `an fft` |
| ⚠️ | `large-file` (~30 MB) |
`src/modules/ZoomIt/ZoomIt/rnnoise/rnnoise_data_little.c` |
| ⚠️ | `binary-file` |
`src/modules/ZoomIt/ZoomIt/selfie_segmentation.onnx` |
| ⚠️ | `duplicate-pattern` ×2 | `excludes.txt` lines 115/116 duplicate
lines 108/109 (`FuzzyMatcher{Comparison,Diacritics}Tests.cs`) |

## Fix

`.github/actions/spell-check/excludes.txt`:

- **Drop 2 duplicate** `FuzzyMatcher*Tests.cs` lines.
- **Add 2 new exclusions** for the new third-party ZoomIt assets:
- `^src/modules/ZoomIt/ZoomIt/rnnoise/` — entire third-party
rnnoise/kiss_fft tree (covers both the `an fft` forbidden-pattern in
`kiss_fft.h` and the 30 MB `rnnoise_data_little.c` large-file).
- `^src/modules/ZoomIt/ZoomIt/selfie_segmentation\.onnx$` — the ML model
binary.

Net change: `-2` duplicates, `+2` new exclusions → file count unchanged
at 148 lines.

## Notes

- Third-party content under `rnnoise/` should not be spell-checked; this
matches how other vendored/third-party trees in the repo are handled
(e.g. `src/common/CalculatorEngineCommon/exprtk.hpp`,
`src/common/sysinternals/Eula/`).
- No source code changes; pure config.
- Unblocks #48546 and any other PR currently failing `Check Spelling` on
`main`.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-15 09:25:03 +08:00
Knyrps
d7d1e543ae [CmdPal][TimeDate] Open notification center when clicking the clock dock band (#48514)
## Summary

Clicking the clock dock band in the CmdPal Dock now opens the Windows
notification center (Action Center). A separate bell-icon-only dock band
is also exposed for users who prefer a dedicated notification center
shortcut.

Closes #46327

## Detail

- **Clock band left-click**: replaced the previous `NoOpCommand` on
`NowDockBand` with `OpenUrlCommand("ms-actioncenter:")`, dismissing the
Dock on invoke. The `ms-actioncenter:` URI is the correct shell
mechanism - `SendInput` Win+N was tested but dropped because it requires
foreground focus, which the Dock holds at click time.
- **Notification center band**: new `NotificationCenterDockBand`
(`ListItem`) in `TimeDateCommandsProvider.cs`, with a bell icon
(`\uEA8F`, Segoe Fluent Icons) and the same `ms-actioncenter:` command.
Exposed as a second `WrappedDockItem` from `GetDockBands()` under the id
`com.microsoft.cmdpal.timedate.notificationCenterBand`. Users can pin it
from the Dock's edit mode.
- **New resource strings**:
`timedate_show_notification_center_command_name` and
`timedate_notification_center_band_title` added to `Resources.resx` /
`Resources.Designer.cs`.
- **VS 2026 C++ build fixes** (pre-existing failures on `HEAD`): added
`_SILENCE_EXPERIMENTAL_COROUTINE_DEPRECATION_WARNINGS` to
`CalculatorEngineCommon.vcxproj`.

## Screenshots

<img width="339" height="991" alt="image"
src="https://github.com/user-attachments/assets/e0ef8c9a-ec1f-40fa-9620-1e83e6aeeb8d"
/>

## How tested

- Built `Microsoft.CmdPal.UI.csproj` (Debug x64) - 0 errors.
- Launched dev `Microsoft.CmdPal.UI.exe`, clicked the clock band -
notification center opened correctly.
- Right-click context menu on the clock band still shows "Copy time" and
"Copy date" unchanged.
- Pinned the notification center band via edit mode - bell icon renders
icon-only, click opens notification center.
2026-06-12 19:23:46 +00:00
Alex Mihaiuc
272b725ff0 Add ZoomIt webcam backgroun (blur) and microphone noise cancellation (#48266)
<!-- 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 change adds the [RNNoise](https://github.com/xiph/rnnoise) filter
for noise cancellation (audio) and the [Google
mediapipe](https://github.com/google-ai-edge/mediapipe/tree/master)
`selfie_segmentation_cpu` model for webcam background detection and
blurring.

It also fixes an issue introduced with
ba68b88ca1 causing the ZoomIt shortcuts to
fail to register in the standalone version.

<!-- 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

The Settings UI has been extended with a Noise cancellation option, a
Background selection for the webcam and a Brightness slider.

The functionality for these is added to ZoomIt itself. Also, restored
the Mono checkbox which was accidentally masked by
b93fd97e80.

<!-- 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: Mario Hewardt <marioh@microsoft.com>
2026-06-12 00:12:35 +02:00
Jessica Dene Earley-Cha
582f3eb5c3 Move from testing to final for telemetry PR detection workflow (#47993)
<!-- 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

Transitions the telemetry PR detection workflow from testing phase to
ready status. All components are now fully functional and automatically
triggered on every new PR.

- Skips checks on draft PRs to avoid noise
- Prevents multiple concurrent runs per PR
- Safely requests `@chatasweetie` as reviewer on telemetry changes
- update commit messages

<!-- 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: Carlos Zamora <carlos.zamora@microsoft.com>
2026-06-08 22:56:09 +02:00
moooyo
cd5027fa1a [PowerDisplay] Fix false-positive crash detection on cooperative shutdown (#48173)
<!-- 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

Cooperative shutdowns of `PowerDisplay.exe` — Runner's `TerminateApp`
NamedPipe message, the `Terminate` named event, tray-quit, Runner-exit
detection, and PowerToys upgrades — all call `Environment.Exit(0)`
immediately. If DDC/CI discovery is mid-flight, that path skips the
`try/finally` that owns `CrashDetectionScope`, leaving `discovery.lock`
on disk. Phase 0 at the next `PowerDisplay.exe` startup then treats this
orphan as evidence of a real crash and auto-disables the module,
surfacing the "PowerDisplay has crashed" InfoBar in Settings UI.

This PR adds an `AppDomain.ProcessExit` safety-net inside
`CrashDetectionScope`. ProcessExit fires for `Environment.Exit` but
**not** for `FailFast` / BSOD / external `TerminateProcess` — exactly
the partition we need: cooperative exit → best-effort delete the lock;
involuntary kill → leave the lock for Phase 0 to detect (original design
intent preserved).

<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

- [x] Closes: #48169
- [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
- [x] **Localization:** All end-user-facing strings can be localized
<!-- no user-facing strings changed -->
- [x] **Dev docs:** Added/updated <!-- inline XML doc on
CrashDetectionScope explains the ProcessExit partition -->
- [ ] **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

### Root cause

`CrashDetectionScope.Begin()` writes `discovery.lock` before DDC/CI
capability fetch and `Dispose()` deletes it when the `using` block
exits. The lock is intentionally designed to survive any code path that
cannot run user-mode cleanup (BSOD, kernel OOM, `TerminateProcess`), so
that the next `PowerDisplay.exe` start can see it and run Phase 0 (write
`crash_detected.flag`, set `enabled.PowerDisplay=false` in global
`settings.json`, signal `AutoDisablePowerDisplayEvent`).

The bug is that several **cooperative** shutdown paths route to
`Environment.Exit(0)` immediately:

| Path | Code |
|---|---|
| Runner's `TerminateApp` NamedPipe | `App.xaml.cs::OnNamedPipeMessage`
→ `Shutdown()` → `Environment.Exit(0)` |
| `Terminate` named event | `App.xaml.cs::OnLaunched` →
`RegisterEvent(..., () => Environment.Exit(0), "Terminate")` |
| Tray-quit | `TrayIconService` callback → `Environment.Exit(0)` |
| Runner-exit detection | `RunnerHelper.WaitForPowerToysRunner` callback
→ `Environment.Exit(0)` |

`Environment.Exit` calls `ExitProcess` under the hood, which terminates
all threads abruptly. Background `Task.WhenAll` doing DDC capability
fetch is killed mid-flight; the `finally` block that calls
`scope.Dispose()` never runs; `discovery.lock` orphans; Phase 0 next
time false-positives.

Concrete repro from logs:
- `15:08:42.510` lock written
- `15:08:42.79` probe monitor #1
- `15:08:46.92` probe monitor #2 (started, not finished — typical probe
takes ~5s)
- `15:08:49.03` `TerminateApp` received → `Environment.Exit(0)` → no
`Dispose` log line
- `15:10:10.03` next startup: Phase 0 sees orphan lock with `pid:17712,
startedAt:2026-05-28T07:08:42Z` → writes `crash_detected.flag` →
auto-disables

### Fix

`CrashDetectionScope.Begin()` now also subscribes to
`AppDomain.CurrentDomain.ProcessExit`. The handler does a best-effort
`File.Delete(_lockPath)` (swallowing exceptions, as required for
ProcessExit handlers). `Dispose()` unsubscribes before deleting. An
`Interlocked.Exchange` guards the race between Dispose and ProcessExit
so only one of the two performs the delete.

ProcessExit's semantics match the cooperative/involuntary partition
exactly:

| Shutdown path | ProcessExit fires? | Behavior after this PR |
|---|---|---|
| `Environment.Exit(code)` (all 4 paths above) | yes | lock deleted by
handler |
| `Environment.FailFast` | no | lock survives → Phase 0 catches it
(correct: explicit FailFast = real failure) |
| BSOD / external `TerminateProcess` / kernel OOM | no | lock survives →
Phase 0 catches it (correct: original design) |
| Discovery completes normally / throws | n/a | `try/finally` calls
`Dispose()` as before; handler unsubscribed first |

### Testability

A new `IProcessExitHook` interface abstracts the subscription so unit
tests can simulate ProcessExit without terminating the test runner.
Production code uses the default `AppDomainProcessExitHook` singleton;
tests inject a fake whose `RaiseExit()` invokes subscribed handlers
synchronously.

### Files touched

-
`src/modules/powerdisplay/PowerDisplay.Lib/Services/IProcessExitHook.cs`
*(new)* — interface + production singleton
-
`src/modules/powerdisplay/PowerDisplay.Lib/Services/CrashDetectionScope.cs`
— subscribe in `Begin`, unsubscribe in `Dispose`, add `OnProcessExit`
handler, expanded class doc
-
`src/modules/powerdisplay/PowerDisplay.Lib.UnitTests/CrashDetectionScopeTests.cs`
*(new)* — 10 unit tests

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed

### Automated

10 new unit tests in `CrashDetectionScopeTests`, all passing:

```
Passed Begin_WritesLockFileAtomically
Passed Begin_SubscribesToProcessExit
Passed Dispose_UnsubscribesFromProcessExit
Passed Dispose_DeletesLockFile
Passed ProcessExitFired_BeforeDispose_DeletesLock      (core scenario)
Passed ProcessExitFired_AfterDispose_DoesNothing
Passed Dispose_AfterProcessExit_DoesNotThrow
Passed ProcessExitFired_LockFileMissing_DoesNotThrow
Passed Dispose_IsIdempotent
Passed MultipleScopes_DoNotShareState
```

Full `PowerDisplay.Lib.UnitTests` suite: **129 / 132 passing**. The 3
failures (`DetectOrphanAndDisable_RunsFullSequenceWhenOrphanPresent`,
`DetectOrphanAndDisable_HandlesUnknownVersionAsOrphan`,
`DetectOrphanAndDisable_LeavesLockIntactOnSignalFailure`) are
**pre-existing on `main`** — they fail with `REGDB_E_CLASSNOTREG` from
`Constants.AutoDisablePowerDisplayEvent()` (WinRT activation factory not
COM-registered in the test environment). Verified by stashing this PR's
changes and re-running the same 3 tests on baseline `main` — same
failures, same cause, unrelated to this change.

### Manual

1. Reproduced the original false-positive on `main`:
- Enable PowerDisplay → open Settings UI → quickly toggle PowerDisplay
off
- Observe `discovery.lock` left in
`%LOCALAPPDATA%\Microsoft\PowerToys\PowerDisplay\`
- Re-enable PowerDisplay → Phase 0 writes `crash_detected.flag` →
InfoBar appears
2. Repeated the same steps with this branch:
- Toggling PowerDisplay off cleanly deletes `discovery.lock`
(ProcessExit handler ran)
- Re-enabling PowerDisplay shows no InfoBar, no `crash_detected.flag`
created
3. BSOD path is unchanged (verified by inspecting the conditional logic
— `AppDomain.ProcessExit` does not fire for involuntary terminations;
the lock survives just as before).

---------

Co-authored-by: Yu Leng <yuleng@microsoft.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 09:02:14 +00:00
Mike Griese
65112a7b05 Move CmdPal API spec back to cmdpal/ directory (#48160)
Reverts 0819a62 / #46926

The cmdpal API is literally generated from this spec document. It needs
to live with the rest of the code to work correctly.

Docs for authoring cmdpal extensions are on
https://learn.microsoft.com/en-us/windows/powertoys/command-palette/extension-development,
and we should direct docs commentary there.
2026-05-28 00:05:12 +02:00
Boliang Zhang
8a7933c0b2 Migrate spdlog from submodule to vcpkg (#48039)
## Summary

Migrate `deps/spdlog` from a git submodule to **vcpkg manifest mode**
with an overlay port pinned to the **exact same commit**
(`gabime/spdlog@616866fc`). Replaces the polyfill shim added in #47910
with a proper port-level patch.

This is the follow-up to PR #47928, which I closed after @zadjii-msft /
@DHowett clarified that the intended direction was a single combined
"move to vcpkg **and** apply a patch file" (one change, not two stepping
stones).

## Guidance honored

Per @zadjii-msft (offline):
-  Convert each submodule to vcpkg **one at a time** — this PR is
**spdlog only**. `deps/expected-lite` stays a submodule (separate PR
next).
-  Atomic commit per dep (multiple commits on the branch for review
traceability; squash on merge gives the requested single commit).
-  **Don't bump the version.** Only variable changed: submodule →
vcpkg. Same commit (`616866fc`, v1.8.5 + 38) the submodule pointed at.

Per @DHowett
([review](https://github.com/microsoft/PowerToys/pull/48039#pullrequestreview-4338835150)):
-  No vcpkg submodule — vswhere-first detection via a Terminal-style
`steps-install-vcpkg.yml` template; three-tier `VcpkgRoot` fallback (env
var → VS-shipped → runtime clone pinned to manifest baseline).

## Design

- **Repo-root manifest**: `vcpkg.json` declares only `spdlog`, with
`builtin-baseline` pinned. `vcpkg-configuration.json` registers
`deps/vcpkg-overlays/` as overlay-ports.
- **Overlay port** `deps/vcpkg-overlays/spdlog/`: `vcpkg_from_github(REF
616866fc...)` with bundled fmt preserved (`-DSPDLOG_FMT_EXTERNAL=OFF`);
the MSVC 14.51 fix from #47910 carried as a proper vcpkg patch on
`include/spdlog/fmt/bundled/format.h`.
- **vcpkg integration is global** (set in `Cpp.Build.props`, imported
via `ForceImportBeforeCppProps` for every `.vcxproj`). An earlier
attempt to make vcpkg per-project-opt-in via `deps/spdlog.props` failed
because ~85 PowerToys `.vcxproj` files import `spdlog.props` AFTER
`Microsoft.Cpp.targets`, by which point `vcpkg.props`' `ClCompile` hook
is dead-on-arrival. The trade-off (every C++ project invokes `vcpkg
install` once at build time, ~0.5 s on cache hits, manifest declares
only spdlog so install set is fixed) is documented in the expanded
`Cpp.Build.props` comment.
- **`deps/spdlog.props`** is now a thin shim that only sets the
historical `SPDLOG_*` preprocessor defines for source-compat.
- **`Cpp.Build.targets`** is a new file imported via
`ForceImportAfterCppTargets` to load `vcpkg.targets` after
`Microsoft.Cpp.targets`. A fail-fast `<Target>` errors with a clear
message if `vcpkg.props` can't be found at the resolved `VcpkgRoot`.
- **Removes** `deps/spdlog-msvc-fix/` polyfill, in-tree wrapper
`src/logging/`, spdlog submodule, the single `<ProjectReference>` in
`logger.vcxproj`, plus 3 `.slnf` refs and 2 `.slnx` refs
(`PowerToys.slnx` + `installer/PowerToysSetup.slnx`), plus 3 hard-coded
`..\deps\spdlog\include` entries in `<AdditionalIncludeDirectories>`.
- **CI**: new reusable `.pipelines/v2/templates/steps-install-vcpkg.yml`
(vswhere-first, manifest-baseline-pinned fallback clone, respects
`useVSPreview`). Gated `Cache@2` for `%LOCALAPPDATA%\vcpkg\archives`
keyed on overlay-port contents. Same vcpkg detection added to
`tools\build\build-essentials.ps1` for local devs.

## Verification

Local build matrix (all 4 configs of `logger.vcxproj` and a
representative late-import consumer):

| Config | Result | Notes |
|--------|--------|-------|
| Release \| x64    |  | vcpkg install ~21 s, `logger.lib` produced |
| Debug \| x64 |  | **Validates patch fixes the actual MSVC 14.51 bug**
(`_ITERATOR_DEBUG_LEVEL > 0` → `_SECURE_SCL`) |
| Release \| ARM64 |  | vcpkg cross-installs `arm64-windows-static`
spdlog in ~16 s |
| Debug \| ARM64 |  | **Previously DISABLED for the in-tree spdlog**
(per `<Build Solution="Debug\|ARM64" Project="false" />` in
`PowerToysSetup.slnx`); this migration FIXES that latent gap |
| FancyZonesLib (Release \| x64) |  | Late-import-pattern consumer;
previously broke in v2 |

Full PowerToys CI (x64 + arm64 + CmdPal SDK + all GitHub Actions checks)
green.

**Consumer audit**: 72 `.vcxproj` files reference `logger.vcxproj`; all
72 also import `deps/spdlog.props`. No transitive-link breakage.

## Out of scope (intentional)

- `deps/expected-lite` migration — next PR per "one-at-a-time" rule.
- Remote vcpkg binary cache (Azure Artifacts NuGet feed). Local pipeline
`Cache@2` works for now, but a remote feed survives across pipelines and
is the long-term answer. Happy to split this into a follow-up.

## Notes for review

- Patch in the overlay port is identical content to PR #47928's patch
but regenerated with LF line endings (vcpkg's `vcpkg_apply_patches` is
strict; no `--ignore-whitespace`).
- Once PowerToys eventually bumps spdlog past v1.14 (which ships fmt
10.2 and drops the affected code path), the overlay port can be deleted
and we can use upstream vcpkg's `spdlog` directly.
- Re. official-release pipelines and terrapin / less-restricted network
isolation: VS-shipped vcpkg is the primary path (no network); the
fallback clone is only exercised when VS doesn't ship vcpkg. Happy to
wire terrapin into the fallback as a follow-up if the official build
template needs it.

Closes the work tracked in #47928 (which was closed unmerged).

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Dustin L. Howett <dustin@howett.net>
2026-05-27 15:45:24 +08:00
Niels Laute
b3bf154fa5 [General] Update issue tracker's duplicate resolution message (#47981)
Reopens the change from #46743 (which appears to be broken) on a fresh
branch.

Original author: @daverayment

## Summary

GitHub newcomers can be confused by the current duplicate resolution
message, as it doesn't clearly point to the original referenced issue -
see
https://github.com/microsoft/PowerToys/issues/46347#issuecomment-4103681050.
They may not realise that the #12345 in the duplicate comment is the
relevant link.

This small wording update to the duplicate resolution message tightens
up wording slightly and includes reference to the prior `/dup #nnn`
comment so newcomers don't miss it.

### Before
> Hi! We've identified this issue as a duplicate of another one that
already exists on this Issue Tracker. This specific instance is being
closed in favor of tracking the concern over on the referenced thread.
Thanks for your report!

### After
> We've identified this issue as a duplicate of an existing one and are
closing this thread so discussion stays in one place.<br/><br/>Please
see the comment above for the link to the original tracking issue, and
feel free to subscribe there for updates.

## Validation Steps Performed
N/A - bot reply text change only.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-26 13:44:34 +08:00
Boliang Zhang
6a5e320749 [CI] Prune orphan tokens from check-spelling expect.txt (#48110)
## Problem

Since #47119 (`Refresh check-spelling 0.0.26`, merged 2026-04-23)
refreshed the check-spelling tooling and rewrote
`.github/actions/spell-check/expect.txt` (938 lines / 633 deletions),
the check-spelling bot has been leaving a noisy advisory comment on
**every PR**:

> #### These words are not needed and should be removed
> ABlocked AClient AColumn ACR ADate ADifferent AHybrid ALarger
AModifier ANull AOklab APeriod ARandom ARemapped ASingle ASUS bck …

The same ~150-word list is appended verbatim to every PR the bot looks
at (verified against #48058, #48102, #48104 — the list is identical).
These tokens are residual orphans in `expect.txt` from before the 0.0.26
refresh and no longer match anything in source.

## Fix

Removes exactly the 147 orphan tokens that the bot has consistently
flagged as `now absent` from `.github/actions/spell-check/expect.txt`.
The removed tokens are exclusively the ones the bot itself identified.

All uppercase Win32 / DirectWrite identifiers that are still used in
source (`DWRITE`, `LWIN`, `VCENTER`, `VREDRAW`, etc.) are **preserved**.

## Verification

- Diff is a single file, deletions only: `expect.txt` shrinks from 2343
→ 2196 lines.
- Each of the 4 uppercase Win32 tokens (`DWRITE` line 514, `LWIN` 1074,
`VCENTER` 2105, `VREDRAW` 2144 in the original) remains in the file.
- The check-spelling job on this PR should now post a clean report (no
`should be removed` block).

## Background — which PR introduced the drift

| PR | Date | What it changed |
|----|------|-----------------|
| **#47119** | 2026-04-23 | Refreshed check-spelling to 0.0.26; rewrote
`expect.txt` with 938 line-changes (633 deletions, 305 additions). The
duplicated lowercase/uppercase entries and many obsolete tokens
originate here. |

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <Copilot@users.noreply.github.com>
2026-05-25 16:29:42 +08:00
Mike Griese
f998c38ac8 cmdpal: fix an AOT-only crash loading the extension page (#48065)
Okay I'll admit this is a clanker fix. 

There's currently a crash when you navigate to an individual extension
page, that only repro's in Release/AOT. And because of
release&trimming&AOT reasons, that's very very difficult to diagnose.
But the clanker added a shitload of logging, and was able to figure out
that:

We were binding to this `Screenshots` collection. Problem is that we
can't safely bind to an `IReadOnlyList` in trimmed scenarios. C#/AOT is
a wonderful world of horrors.

Fixing this is as simple as swapping it for a `ObservableCollection`.
2026-05-23 05:56:14 -05:00
moooyo
4edfcee87e [Power Display] Built-in monitor blacklist to mitigate DDC/CI BSOD (#47556, #47968) (#48051)
<!-- 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 a built-in monitor blacklist that skips known-bad monitor models at
the DDC/CI discovery stage — before PowerDisplay sends any capabilities
request to the firmware. Matches by EdidId (the PnP manufacturer +
product code from EDID). Two entries pre-populated from existing crash
reports:

| EdidId | Reported in | Notes |

|-----------|-------------|------------------------------------------------------------------------|
| `LTM2C02` | #47556 | Counterfeit-EDID LG 27MR400 (PnP claims Litemax
40" 2011, actual hw is LG 27" 2024) |
| `GSM7714` | #47968 | LG UltraWide HDR WFHD |

Also logs `[EdidId=…] [FriendlyName=…] [DevicePath=…]` immediately
before each `GetCapabilitiesString*` syscall in `DdcCiController`. If
the kernel call BSODs (`win32kfull` stack-cookie overrun), that is the
last log line that survives — adding a new blacklist entry then takes
one PR to `BuiltInMonitorBlacklist.json` instead of a memory-dump
triage.

<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

- [x] Mitigates: #47556
- [x] Mitigates: #47968
- [x] **Communication:** This is the "Add blacklist and prevent the API
call on broken monitor" mitigation outlined in [#47556
(comment)](https://github.com/microsoft/PowerToys/issues/47556#issuecomment-4505498427).
The underlying `win32kfull!DdcciGetCapabilitiesStringFromMonitor` stack
overrun is tracked separately by the Windows team.
- [x] **Tests:** 6 new MSTest unit tests under
`PowerDisplay.Lib.UnitTests`. All 120 PowerDisplay tests pass on x64
Debug.
- [ ] **Localization:** N/A — this PR ships no end-user-facing strings
(no UI surface).
- [ ] **Dev docs:** N/A.
- [ ] **New binaries:** N/A. Data ships as an `<EmbeddedResource>`
inside the existing `PowerDisplay.Models.dll`; no new .dll, no installer
change.
- [ ] **Documentation updated:** N/A.

<!-- 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

### Threat model

Some retail monitor firmwares ship non-conformant DDC/CI capabilities
strings — typically oversized, not NUL-terminated, or otherwise
malformed. When PowerDisplay calls `GetCapabilitiesStringLength` /
`CapabilitiesRequestAndCapabilitiesReply` on these monitors, the request
flows into
`win32kfull!CPhysicalMonitorHandle::DdcciGetCapabilitiesStringFromMonitor`,
which copies the reply into a stack buffer without bounding the length.
The kernel detects its own stack cookie corruption on the epilogue check
and `__fastfail`s with `BUGCHECK 0x139 / 2
(STACK_COOKIE_CHECK_FAILURE)`.

The kernel-side overrun is a Windows defect, not PowerDisplay's, but
PowerDisplay is currently the most widely deployed consumer of this API
on hot-plug. Until the Windows team fixes the kernel, the only safe
mitigation in user space is to **never call** the capabilities API on
monitor models known to trigger it.

### Architecture

| File | Role |
|---|---|
| `PowerDisplay.Models/MonitorBlacklistEntry.cs` | POCO: `{ edidId,
comments }` |
| `PowerDisplay.Models/BuiltInMonitorBlacklist.json` | Data file
(embedded resource) |
| `PowerDisplay.Models/BuiltInMonitorBlacklist.cs` | Lazy-loaded reader,
AOT-safe (source-gen `JsonSerializerContext`); silent fallback to empty
list on any IO/parse failure |
| `PowerDisplay.Lib/Services/MonitorBlacklistService.cs` |
`IsBlocked(monitorId)` — extracts EdidId via
`MonitorIdentity.EdidIdFromMonitorId`, checks a `HashSet<string>` with
`OrdinalIgnoreCase` |
| `PowerDisplay/Helpers/MonitorManager.cs` | Filters QueryDisplayConfig
inventory by EdidId **before** any controller (DDC/CI or WMI) is
dispatched; logs each skip with `[MonitorBlacklist] Skipping ...` |
| `PowerDisplay.Lib/Drivers/DDC/DdcCiController.cs` | Logs EdidId +
FriendlyName + DevicePath immediately before the first capabilities
syscall per-monitor |

Matching is **model-level granularity** (EdidId, e.g. `GSM7714`) rather
than device-level (full DevicePath). One entry covers every physical
port and every machine with the same monitor model.

### Adding new entries

Once the kernel overrun is fixed this list can shrink. Until then, when
a new BSOD surfaces:

1. User reports BSOD, attaches PowerDisplay log
2. The last line before the crash now reads `DDC: probing capabilities
[EdidId=XXXXXX] [FriendlyName='...'] [DevicePath=...]`
3. Add `{ "edidId": "XXXXXX", "comments": "See #issue" }` to
`BuiltInMonitorBlacklist.json`
4. Submit PR, ship in next release

### Scoped out (deliberate)

A user-customized blacklist surface (Settings UI dialog) was prototyped
and hit multiple WinUI 3 dialog parse / measure crashes inside a
`ContentDialog`. The custom-list code path was reverted in favor of
"built-in only" for v1 reliability. UI can be re-added later on top of
this foundation if needed — the data model and service already support
it.

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed

1. **Unit tests:** `dotnet test` on `PowerDisplay.Lib.UnitTests` →
**120/120 pass** (including 6 new tests for loader + service: built-in
JSON loads, EdidIds are normalized to upper-case, no blank entries,
`Lazy<>` cache returns same instance, `IsBlocked` returns `false` for
empty built-in list and for unidentifiable monitor IDs).
2. **Clean x64 Debug build** via `tools\build\build-essentials.cmd` +
per-project `tools\build\build.cmd`:
   - `PowerDisplay.Models` — 0 warning, 0 error
   - `PowerDisplay.Lib` — 0 warning, 0 error
   - `PowerDisplay` (app) — 0 warning, 0 error
3. **Smoke test (manual):** launched PowerDisplay, confirmed every
connected monitor produces a `DDC: probing capabilities [EdidId=…]
[FriendlyName=…] [DevicePath=…]` log line right before its caps request.
4. **Empty-list case:** `BuiltInMonitorBlacklist.json` with no entries →
`IsBlocked` returns `false` for any input (verified via unit test).
5. **Non-empty case (manual):** temporarily added a connected monitor's
EdidId to the built-in JSON → that monitor disappears from
`MonitorManager.Monitors` and `[MonitorBlacklist] Skipping ...` log line
appears; removed the entry → monitor reappears, all per-monitor settings
intact.

---------

Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com>
2026-05-22 23:18:13 +08:00
Noraa Junker
9699d8a802 Shortcut Guide V2 (#40834)
## Summary of the Pull Request


https://github.com/user-attachments/assets/f4afdaf8-2830-4993-82ea-1ee9a6978e4c


<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

- [x] Closes: Status: #890 #15405 #179 #129 #22419 #31289 #47297 #47464
#44816
- [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
- [x] **Localization:** All end-user-facing strings can be localized
- [x] **Dev docs:** Added/updated
- [x] **New binaries:** Added on the required places
- [x] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [x] [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)
- [x] **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:
https://github.com/MicrosoftDocs/windows-dev-docs/pull/5717

<!-- 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

Work for future PRs:

- [ ] Localization of built-in shortcut files
- [ ] Further customization (we can wait on user feedback for that)
- [ ] Reimplement holding windows key
- [ ] Search bar

<details>
<summary>Images</summary>


https://github.com/user-attachments/assets/f923daa4-d713-463b-ba33-ede72b986c12

<img width="726" height="1388" alt="image"
src="https://github.com/user-attachments/assets/781eff9a-2863-44be-bbe2-25371ef8838e"
/>
<img width="624" height="351" alt="image"
src="https://github.com/user-attachments/assets/ec8a44db-afbc-4e28-8285-ba2a9e345fb9"
/>
<img width="712" height="1086" alt="image"
src="https://github.com/user-attachments/assets/5a3775fc-36e9-4971-8d3f-491e8f8da45a"
/>
<img width="726" height="134" alt="image"
src="https://github.com/user-attachments/assets/7d0a8b1f-d10e-4466-820c-b3efdc5f3c84"
/>


</details>




<!-- 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: Gordon Lam (SH) <yeelam@microsoft.com>
Co-authored-by: Niels Laute <niels.laute@live.nl>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Muyuan Li <116717757+MuyuanMS@users.noreply.github.com>
Co-authored-by: Muyuan Li (from Dev Box) <muyuanli@microsoft.com>
2026-05-21 17:27:52 +02:00
Muyuan Li
fa2b7f6e5f Fix VALID_LABELS mismatches in auto-label-issues workflow (#48027)
## 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>
2026-05-21 12:58:46 +02:00
moooyo
f117bfc64e feat(PowerDisplay): migrate legacy "{Source}_{EdidId}_{N}" Ids to new stable ID (#47977)
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>
2026-05-21 14:21:20 +08:00
moooyo
8e74eb2ba8 [PowerDisplay] Auto-disable on detected DDC/CI capability fetch crash (#47556) (#47734)
<!-- 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>
2026-05-20 16:13:16 +08:00
Jessica Dene Earley-Cha
b893d633d9 [TEST Version] Event PR Check (#47889)
<!-- 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
2026-05-19 17:28:57 +00:00
Marco Guido
6e9b3b1536 [PowerAccent] adding greek polytonic (#47021)
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>
2026-05-20 00:19:06 +08:00
Copilot
9dff42627a Rename issue triage workflow, remove legacy product auto-label action, and sync with main (#47911)
## 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>
2026-05-19 05:40:18 +00:00
Mike Griese
b02e53dda5 CmdPal: Update the shell provider to be run (#47642)
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.
2026-05-18 12:59:51 -05:00
moooyo
38882fd392 [PowerDisplay] Rescan monitors on display wake (#47876)
<!-- 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>
2026-05-18 14:26:26 +08:00
Dave Rayment
e17454b553 [CmdPal Calculator] Add rand() and randi(). Expand result responses to differentiate between NaN and ParseError (#47725)
## 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"
/>
2026-05-16 19:50:58 +00:00
Mike Griese
42902eeba5 CmdPal: Add support for pages with parameters (redux) (#47826)
(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>
2026-05-15 20:31:32 -05:00
Boliang Zhang
b68b2a5583 Fix GrabAndMove LNK2038 C++/WinRT version mismatch (PowerToys CI break) (#47910)
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).
2026-05-15 14:13:24 -05:00
Boliang Zhang
e932fe6e61 Remove unused dependencies and shrink installer size (#47233)
## 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>
2026-05-15 17:15:11 +08:00
Niels Laute
c7d458b71d Fix auto-label-issues workflow (#47820)
## 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>
2026-05-15 14:39:00 +08:00
Jiří Polášek
c4ff073d01 CmdPal: Extension Gallery (#46636)
## 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>
2026-05-14 16:30:20 -05:00
Boliang Zhang
3948fcc19d [release-notes skill] Use local agent for PR summaries; vendor prepare-release-assets.ps1 (#47651)
## 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>
2026-05-14 22:07:38 +08:00
moooyo
c5d17913e4 [PowerDisplay] Add max compatibility mode setting (#47875)
<!-- 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>
2026-05-14 07:20:22 +00:00
Muyuan Li
be1f9dd2d8 Add auto-label-product GitHub Action for issue triage (#47485)
## 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>
2026-05-12 11:36:08 +02:00
Copilot
14f2ac1b78 Add AI-powered recurring workflow to auto-label new issues by area (#47808)
## 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>
2026-05-12 10:07:59 +02:00
moooyo
3796b244e5 [PowerDisplay] Pre-classify internal/external displays at discovery (#47740)
<!-- 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>
2026-05-12 16:07:40 +08:00
moooyo
95b70555bb [PowerDisplay] Stable monitor Id + survive transient discovery failures (#47712)
<!-- 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>
2026-05-08 15:25:40 +08:00
Alex Mihaiuc
b93fd97e80 Add ZoomIt webcam and append clip functionality (#47529)
<!-- 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>
2026-05-05 23:52:43 +02:00
Jeremy Sinclair
05cd66c9bc [Dev][Build] .NET 10 Upgrade (#41280)
## 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>
2026-04-30 14:40:43 +08:00
Alex Mihaiuc
f79df0663c Skip desktop / explorer targets in GrabAndMove (#47302)
<!-- 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
Added a few known Windows processes and window classes from desktop
elements to the implicit exclusion list, to avoid funny repositioning of
otherwise immovable content:

- The Windows Start menu.
- Tooltips from around the Notification Area (System Tray).
- The Alt-Tab and Win-Tab windows.
- Tooltips.

<!-- 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: Copilot <copilot@github.com>
2026-04-29 11:05:54 +08:00