Commit Graph

896 Commits

Author SHA1 Message Date
Boliang Zhang
1980ca5ece [Runner][Interop] Authenticate Settings/Quick Access named-pipe clients before dispatch (CWE-732/CWE-862) (#49527)
## Summary of the Pull Request

The Runner is the **server** for the two-way named pipes it uses to talk
to `PowerToys.Settings.exe` and the Quick Access host, and it dispatched
privileged JSON commands (`killrunner`, `restart_elevation`,
`module_status`, `powertoys`, `language`, ...) **without authenticating
the caller**. When PowerToys runs elevated ("Run as administrator"), the
pipe DACL grants the shared **Logon SID**, so **any same-user Medium-IL
process could connect and inject commands** — a local privilege
escalation (CWE-732 / CWE-862). The pipe DACL cannot distinguish the
legitimate Medium-IL Settings child from a same-user attacker (identical
user SID, integrity level, and logon session), so this PR authenticates
the connecting process's **binary identity** before any dispatch.

## PR Checklist

- [x] **Tests:** Added/updated and all pass (native gate tests + C#
regression)
- [x] **Localization:** No new end-user-facing strings (only a
diagnostic runner log line)
- [x] **New binaries:** None — the new code compiles into the existing
`PowerToys.Interop` and `runner` binaries; tests were added to the
existing `Common.Utils.UnitTests` project

## Detailed Description of the Pull Request / Additional comments

New `src/common/interop/pipe_caller_auth.{h,cpp}` adds
`interop_auth::AuthenticateClient`, invoked from
`TwoWayPipeMessageIPC::handle_pipe_connection` **before** a message is
queued (fail-closed). A connecting client is accepted only if it is:

- under the **Runner-relative install directory**
(`get_module_folderpath()\WinUI3Apps`, so it adapts to installed and
dev-build layouts),
- an **allow-listed basename** (`PowerToys.Settings.exe` /
`PowerToys.QuickAccess.exe`),
- the Runner's **exact file version** (anti-downgrade), and
- **Microsoft Authenticode-signed**.

The signature is anchored to the **LOCAL MACHINE root store**
(`HCCE_LOCAL_MACHINE` +
`CertVerifyCertificateChainPolicy(AUTHENTICODE)`) rather than
`WinVerifyTrust`'s default user+machine union: the Runner runs as the
same user as a potential attacker and would otherwise trust a forged
signer added to `CurrentUser\Root`. Verdicts are cached per `(pid,
process-creation-time, policy)` with a short TTL so the check isn't
re-run on every message (each `send` opens a new connection). Rejections
are logged.

The gate is added via an **additive** `start(HANDLE, CallerPolicy)`
overload; the managed `start(nullptr)` path is unchanged (gate
disabled), so there is **no ABI break** to `PowerToys.Interop`.
`PIPE_REJECT_REMOTE_CLIENTS` is also set. In **Debug** builds only the
signature check is relaxed (directory/basename/version stay enforced) so
local unsigned builds still connect; the relaxation is compiled out of
Release.

**Scope:** this PR covers the two elevated Runner-server pipes (Settings
+ Quick Access), which are the actual EoP surface. The reverse
Runner->Settings response direction, the duplicated Workspaces
transport, and the AdvancedPaste/PowerDisplay module pipes are
intentionally out of scope and can be handled as follow-ups.

## Validation Steps Performed

**Automated**
- **Native unit tests** (`Common.Utils.UnitTests`,
`PipeCallerAuthTests`): legitimate self-caller accepted; wrong
basename/directory rejected with the reject-log callback firing; version
reading. 6/6 pass.
- **C# regression** (`Microsoft.Interop.Tests.TestSend`): managed
gate-disabled round-trip still works.
- **Builds:** runner Debug + Release, `PowerToys.Interop` Debug +
Release, and the test project all build/link clean.

**Official signed build (validates the Release-only signature path that
local Debug builds skip)**
- Queued the internal "PowerToys Signed YAML Release Build" for this
branch — **green** (`result: succeeded`). The produced installers are
Authenticode `Valid`, signer `Microsoft Corporation`.

**Manual testing on the signed installer (elevated Runner) — passed**
- Installed the signed build and ran the Runner **as administrator**.
Settings and Quick Access open and are fully functional; settings apply,
module toggles work, and the hotkey-conflict request/response
round-trips.
- **No** `Rejected unauthenticated ...` lines during legitimate use →
the genuine signed `PowerToys.Settings.exe` is accepted by the
machine-root signature + version + directory checks (verified in
`RunnerLogs\runner-log_*.log`, requests dispatched normally).
- **Security (negative) check:** a non-elevated `powershell.exe`
discovered the runner pipe via the pipe namespace and attempted
`{"killrunner":true}`; the write failed ("Pipe is broken") because the
Runner rejected the caller and disconnected before dispatch.
`PowerToys.exe` stayed running and logged: `Rejected unauthenticated
Settings pipe client: pid=... image='...\powershell.exe'
reason=bad-directory`.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1d8f85ec-aaee-468a-9348-ba79b059cbaf
2026-08-03 22:46:44 +08:00
moooyo
ba2e89c428 PowerDisplay: Fall back to persisted VCP values when a monitor read fails (#49445)
## Summary of the Pull Request

On a monitor whose DDC/CI engine answers intermittently, every discovery
pass starts from nothing. A panel that reported its brightness a minute
ago can lose that control — or drop out of the flyout entirely — because
one pass happened to fail.

This persists every range-valid VCP value read off a monitor, keyed by
its canonical DevicePath. In Maximum compatibility mode a later
discovery falls back to that value when the hardware will not answer.

Scope is intermittent failure, not permanent failure: the cache can only
replay a value the hardware answered at least once, so a panel that
never reads a code successfully sees no change. This partially addresses
#49342.

## PR Checklist

- [x] Closes: #49342
- [ ] **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 —
this PR adds none
- [ ] **Dev docs:** Added/updated
- [x] **New binaries:** Added on the required places — none added, so no
signing JSON, installer WXS or CI YML change is required
- [ ] **Documentation updated**

## Detailed Description of the Pull Request / Additional comments

### What is stored

`MonitorStateManager` implements `IKnownGoodVcpStore`, so the cache
rides in the existing `monitor_state.json` next to the user's saved
brightness rather than in a new file. Each entry is a
`KnownGoodVcpFeature`: code, current, maximum, and when it was last
read.

Only range-valid observations are stored, so the common `current=0 /
max=0` garbage reply never enters — it fails `VcpFeatureValue.IsValid`.

Writes are not gated on Maximum compatibility mode, only reads are. A
monitor that reads cleanly today can start failing after a cable or dock
change, and a lazily populated cache would be empty on exactly the first
pass that needs it.

### How a cached value is used

`VcpDiscoveryEvidence.Reconcile` gains the cache as a third source
alongside the parsed capabilities string and this pass's probe:

| this pass | cache | result |
| --- | --- | --- |
| read succeeded | — | live value wins, cache refreshed |
| replied, range unusable | hit | cached value applied,
`MonitorReadFlags` left clear |
| no reply | hit | cached value applied, `MonitorReadFlags` left clear |
| code never probed (caps parsed) | hit | value applied only after one
live read is attempted |

The last row matters: on the caps-parsed path nothing has confirmed the
cached value this pass, so the hardware is asked first. On the probe
path it has already been asked, and re-reading would be pure I2C noise.

`MonitorReadFlags` stays clear for anything the hardware did not answer,
so a cached value never masquerades as an observation — which #49577
depends on, since it made the restore path write whenever the flag is
unset. One consequence is worth naming: the flyout draws a slider at the
cached position while `powerdisplay get` reports that setting as
unknown, because `MonitorDtoProjector` gates on `supported && read`.

### Keeping the cache current

`RefreshKnownGoodAfterWrite` restamps an entry after a successful
`SetVCPFeature`, so a slider move cannot leave the cache holding the
pre-write value. It refreshes only an entry a real read established, and
only when the value was scaled against the maximum that entry holds — a
monitor whose discovery read failed still carries a placeholder max, and
writing that back would mis-scale every later write.

`RemoveKnownGoodFeatures` clears the cache for monitors a settings
reconciliation observably dropped, leaving the user's saved values
alone. Cleanup is driven by an observed drop, never by absence from the
rebuilt list: a missing or corrupt `settings.json` yields a defaults
object indistinguishable from a real one, and pruning by absence would
wipe every monitor not connected at that instant.

A re-observation that changes nothing refreshes the in-memory timestamp
but does not mark the file dirty, so a discovery pass no longer rewrites
`monitor_state.json` for a moved timestamp alone.

## Validation Steps Performed

- `PowerDisplay.Lib`, `PowerDisplay.Lib.UnitTests` and `PowerDisplay`
built for x64 Debug with VS MSBuild — 0 errors, 0 warnings;
`PowerDisplay.Lib.UnitTests.dll` under `vstest.console.exe`: **301
passed, 0 failed**
- **Affected-hardware validation on the AOC Q27G3XMN is still pending.**
That monitor, or an equivalent controllable DDC/CI setup, was not
available locally. The paths this PR changes are reachable only on
hardware whose capabilities string is unusable or whose VCP reads fail
intermittently, so this is the main outstanding risk.

---------

Co-authored-by: Yu Leng <yuleng@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot-Session: 6ea38c04-6f68-4c42-91d9-8a03b49bdd81
2026-08-03 09:10:44 +00:00
moooyo
160492abcf docs(skills): recommend WindowEx for WinUI 3 migrations (#49303)
## Summary of the Pull Request

Updates the WPF-to-WinUI 3 migration skill to make the established
PowerToys windowing pattern explicit:

- Default WinUI 3 top-level windows to `WinUIEx.WindowEx` or an existing
PowerToys base derived from it, such as `TransparentWindow` for
transient overlays.
- Keep supported size, presenter, title bar, topmost, backdrop, and
persistence behavior declarative in XAML instead of manual `AppWindow` /
`OverlappedPresenter` code-behind.
- Document the centrally managed `<PackageReference Include="WinUIEx"
/>`, WPF-to-`WindowEx` property mappings, and existing repository
examples.
- Add a value-converter decision guide that prefers
`VisualStateManager`, direct `x:Bind` conversion, WinUI theme resources,
and `CommunityToolkit.WinUI.Converters` over mechanically porting WPF
converters.

This follows the migration-skill feedback from @niels9001 in [PR
#49174](https://github.com/microsoft/PowerToys/pull/49174#discussion_r3535181101).

## PR Checklist

- [x] **Communication:** This change follows review feedback from a core
contributor in PR #49174.
- [x] **Tests:** The updated guidance passed 5/5 fresh agent migration
scenarios.
- [x] **Dev docs:** Added/updated.

## Detailed Description of the Pull Request / Additional comments

`SKILL.md` now states the default PowerToys pattern and limits raw
`AppWindow` / presenter code to behavior that `WindowEx` does not
expose. The package mapping reference records the exact centrally
managed dependency. The windowing reference adds a complete XAML
example, a WPF-to-`WindowEx` mapping table, regular-window examples, and
the `TransparentWindow` overlay exception.

The XAML migration reference now also documents converter selection and
reuse: control state belongs in `VisualState`s, count visibility can
share one Toolkit `DoubleToVisibilityConverter` with
`ConverterParameter=True`, and corner-radius converter resources come
from `XamlControlsResources`.

This is an atomic documentation-only change; no product code or
dependencies are modified.

## Validation Steps Performed

- Verified the documented `WindowEx` APIs and `TransparentWindow`
inheritance against the repository and compiled WinUIEx assembly.
- Verified all cited repository paths, the Markdown anchor, and central
package management entry.
- Ran five fresh current-branch agent scenarios; all selected
`<PackageReference Include="WinUIEx" />` without a version, `WindowEx`,
XAML-declared properties, and `CenterOnScreen()` only where required.
- Ran a focused converter migration scenario before and after the
guidance update; the updated skill selected `VisualState`s, one reusable
Toolkit numeric converter, and existing WinUI corner-radius resources
without custom converters.
- Ran `git diff --check` with no errors.
- Completed an independent read-only review with no findings.
- Product builds and unit tests were not run because this change only
updates agent guidance.

---------

Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: fe9b24eb-99f0-43e8-aaa4-839f4579f6f9
Copilot-Session: d5afc36b-3356-46af-b8cb-071b87a64532
2026-07-31 16:28:38 +08:00
moooyo
8f63402400 PowerDisplay: Adjust brightness by scrolling over the tray icon (#49446)
## Summary of the Pull Request

Scrolling the mouse wheel over the Power Display tray icon adjusts
brightness, without opening the flyout.

- New **Tray icon mouse wheel** setting: `Off` / `Primary display` /
`All displays`, defaulting to **`Off`**. It is scoped to the tray icon —
the flyout sliders accept wheel input regardless, as they always have.
The existing **Mouse wheel increment** setting supplies the per-notch
step.
- **Off by default.** The gesture consumes a wheel notch that would
otherwise reach the window under the pointer, and acting on it installs
a system-wide `WH_MOUSE_LL` hook. Neither is something an existing
installation should acquire silently on upgrade. With the setting `Off`
no hook is ever installed and no notch is ever consumed, so this PR
changes no existing behaviour until the user opts in: 1958 insertions, 2
deletions, and both deletions are refactors of lines this feature
reuses.
- **No feedback UI.** Brightness is self-evidencing — you scroll and the
screen changes — so the display itself is the feedback. The notification
icon is untouched: same tooltip, same text, same legacy
notification-icon protocol.

## PR Checklist

- [x] Closes: #49410
- [ ] **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
- [x] **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

No new binaries or projects — everything lands in existing assemblies.
Communication is unchecked because #49410 is still Needs-Triage.

## Detailed Description of the Pull Request / Additional comments

### Why a low-level hook

The Shell does not forward `WM_MOUSEWHEEL` to a notification icon's
callback window under any `NOTIFYICON_VERSION`, and a click-through
overlay placed over the icon cannot receive wheel input either.
`TrayIconMouseWheelListener` therefore installs a `WH_MOUSE_LL` hook —
but only transiently, and only when it will act on the result:

- Nothing is installed at all while the setting is `Off`, which is the
default.
- Installed in `EnsureHook()` when the UI thread confirms the pointer is
inside the rectangle from `Shell_NotifyIconGetRect` **and**
`CanAdjustBrightnessFromTrayWheel` says some monitor can accept a
brightness write.
- Removed in `DisarmCore()` as soon as either condition stops holding,
the pointer leaves the rectangle, or the mode changes.
- A notch is consumed (the hook proc returns non-zero) only while armed
and only for points inside the armed rectangle, so a wheel event Power
Display will not act on still reaches the window under the cursor.

The hook runs on a dedicated background thread with its own message
loop; the proc itself only enqueues a sample and posts a drain request.
Deltas are marshalled to the UI thread in batches, and
`WheelDeltaAccumulator` folds high-resolution deltas (precision wheels,
touchpads) into whole notches. Each sample carries the hover generation
it was captured under, so samples from a hover the UI thread has already
retired are discarded rather than applied late.

### Hover detection

The Shell sends `WM_MOUSEMOVE` to the icon's callback window while the
pointer is over it. `TrayIconService.HandleTrayMouseMove` resolves the
rectangle with `Shell_NotifyIconGetRect` and caches it for a second,
because that message repeats for every pixel of travel.

`TrayIconService` gains nothing else: no protocol change, no new hover
UI, no polling. The rest of the file — and `MainWindow.xaml` — is
untouched.

### Linked brightness

While linked brightness is on, a notch has to move the whole group, so
it goes through `MainViewModel.LinkedBrightness` rather than the
individual monitor setters. The new master value is taken from the
planner's value for the monitor the wheel named, **not** from the
current master. The master is positional only —
`SeedInitialLinkedBrightness` takes it from the lowest-numbered linked
monitor and never writes hardware, and every monitor-list rebuild
re-seeds it — so it can sit arbitrarily far from the monitor the wheel
is aimed at. Stepping it relative to itself would apply a wrong-sized or
wrong-signed change, and a master already clamped at 0/100 would swallow
the notch while writing nothing at all.

The setting description calls out that linked brightness widens the
scope, so `Primary display` is not literally a single display while it
is on.

### What is deliberately not here

An earlier revision of this PR showed the target and percentage in a
custom overlay as you scrolled. Doing that meant the standard Shell
tooltip would not do (it cannot be shown on demand), which meant an own
window, which meant suppressing the Shell tooltip so the two did not
collide, which meant `NOTIFYICON_VERSION_4`, which changed the callback
packing and made the app responsible for all hover text — including for
keyboard and touch users, who never reach a cursor-anchored overlay and
would have been left with no visible tooltip at all.

That chain was about half the diff, for a readout that adds little on
top of watching the screen change. It is gone. If a readout is wanted
later it can be argued on its own merits, separately from this feature.

The same revision also gated the flyout sliders on this setting. That
bundled two unrelated things behind one switch — turning off tray
scrolling would also have stopped the contrast and volume sliders
responding to the wheel — so the setting is now scoped to the tray icon
and named accordingly.

An earlier revision also routed the tray **Exit** action through
`Shutdown()`. That fixes a pre-existing teardown leak which has nothing
to do with this feature, so it now lives in #49580 and is out of scope
here. This branch does not depend on it: the hook thread is a background
thread and the process is ending either way.

## Validation Steps Performed

- Unit tests: `PowerDisplay.Lib.UnitTests` 215 passed,
`Settings.UI.UnitTests` 165 passed.
- Builds: `PowerDisplay` and Settings UI, x64 Debug, no warnings.
- Automated coverage is in `PowerDisplay.Lib.UnitTests`: target
selection per mode, wheel accumulation including negative deltas,
partial notches and direction reversal, half-open rectangle containment,
and settings serialization and round-trip for the new mode, including
that a settings file predating the feature loads as `Off`.
`Settings.UI.UnitTests` covers the view-model index mapping and pins the
enum values to the ComboBox item order.
- The Win32 glue in `TrayIconService` and `TrayIconMouseWheelListener`
is not unit tested.

Manual passes performed: scrolling over the icon in both modes, the icon
parked in the notification overflow, high-resolution wheel input,
brightness boundaries, live monitor refresh while hovering, tray icon
hidden and re-enabled, Explorer restart, the context menu and
left-click, `Off` stopping tray scrolling while the flyout sliders keep
working, and confirming a notch that Power Display will not act on still
reaches the window under the cursor.

Not verified, needing hardware this branch has not been run on:

- Multiple taskbars, where the tray icon is on a secondary display and
`Primary display` mode adjusts a monitor the user may not be looking at.
- Mixed-DPI setups, for the `Shell_NotifyIconGetRect` rectangle and the
hook's physical-pixel hit test.

---------

Co-authored-by: Yu Leng <yuleng@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot-Session: 5d7f36fe-d175-4aa9-a3c7-b370d952d1d3
2026-07-31 16:21:08 +08:00
Clint Rutkas
bb99c30edc New module: AltWindowCycle (#48281)
## Summary of the Pull Request

Introduces a new utility: AltWindowCycle to quickly switch between
windows from the same process using Alt + `.

In release notes give @wzhudev coauthor credits as he also had an
earlier PR

It works like Alt + Tab, but scoped to the app you’re already in.
Perfect for juggling multiple browser windows, terminals, or editor
instances.


https://github.com/user-attachments/assets/cd42f6af-fa5d-4f08-8f68-3c4e75c16d94

<img width="1835" height="971" alt="image"
src="https://github.com/user-attachments/assets/adea59cb-6c8d-4b44-87e2-0a792c4c0b4f"
/>

## PR Checklist

- [x] Closes: https://github.com/microsoft/PowerToys/issues/278
- [ ] **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

This PR adds AltWindowCycle (in-proc module + Settings integration),
then addresses follow-up check-spelling feedback without changing
runtime behavior:
- allow-list update for `ROOTOWNER`
- comment text adjustment for forbidden-pattern compliance
- local identifier rename (`wpx` → `whitePx`) for spelling compliance

## Validation Steps Performed

- Verified `ROOTOWNER` is present in
`.github/actions/spell-check/allow/code.txt`
- Verified `wpx` is removed and updated occurrences in
`src/modules/AltWindowCycle/AltWindowCycle.cpp`
- Ran targeted diff/verification for both updated files
- Ran final validation (code review + CodeQL trivial-change path)
- Ran secret scan for changed files

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Niels Laute <niels.laute@live.nl>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Clint Rutkas <crutkas@users.noreply.github.com>
Copilot-Session: dd5080ea-5001-4efb-87f8-1e7218e10a4e
2026-07-30 22:42:05 -07:00
moooyo
bc2d09abe8 PowerDisplay: Pace and retry the maximum-compatibility VCP probe (#49579)
## Summary of the Pull Request

In Maximum compatibility mode, when a monitor's capabilities string is
missing or unparsable, discovery falls back to probing each continuous
VCP code directly. That probe issues **one**
`GetVCPFeatureAndVCPFeatureReply` per code, back to back, and treats any
failure as final. On a panel whose DDC/CI engine answers intermittently,
a single transient I2C fault permanently drops that control for the
whole discovery pass — and if every code happens to fault, the monitor
disappears from the flyout entirely.

This replaces the probe with `VcpFeatureProbeService`:

- **paced** — 100 ms between transactions, instead of hammering the I2C
bus back to back
- **retried** — up to 3 attempts, but only for failures another attempt
can plausibly get past
- **classified** — `DdcErrorClassifier` decides what "transient" means,
so the retry budget is not burned on a definitive
`DDCCI_VCP_NOT_SUPPORTED` or on a dead physical-monitor handle
- **aborted early** — a handle-class error stops the remaining codes
rather than issuing more requests against a handle already known to be
invalid

Extracted from #49445, which bundles this with a persisted discovery
cache and a discovery restructure it does not depend on. This piece
stands alone and addresses one of the root causes in #49342 by itself.

## PR Checklist

- [ ] Closes: #xxx — partially addresses #49342; the remaining causes
are in #49445
- [ ] **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 —
this PR adds none
- [ ] **Dev docs:** Added/updated
- [x] **New binaries:** Added on the required places — none added; no
new project, so no signing JSON, installer WXS or CI YML change is
required
- [ ] **Documentation updated**

## Detailed Description of the Pull Request / Additional comments

### What is and is not retried

`DdcErrorClassifier` names the DDC/CI error codes after `winerror.h` and
splits them into two sets. `DdcErrorClassifierTests` pins both the
membership of each set **and** the numeric value of every constant
against `winerror.h`, so a typo cannot move production and tests
together and leave the suite green.

Retried — framing, arbitration and timing faults on the I2C bus:
`I2C_ERROR_TRANSMITTING_DATA`, `I2C_ERROR_RECEIVING_DATA`,
`DDCCI_INVALID_DATA`, `MCA_INTERNAL_ERROR`,
`DDCCI_INVALID_MESSAGE_COMMAND`, `DDCCI_INVALID_MESSAGE_LENGTH`,
`DDCCI_INVALID_MESSAGE_CHECKSUM`,
`DDCCI_CURRENT_CURRENT_VALUE_GREATER_THAN_MAXIMUM_VALUE`,
`ERROR_TIMEOUT`.

Not retried, each for a stated reason recorded on the predicate:
`DDCCI_VCP_NOT_SUPPORTED` is the device's final answer;
`I2C_NOT_SUPPORTED` and `I2C_DEVICE_DOES_NOT_EXIST` are permanent
bus-level facts; `MCA_INVALID_CAPABILITIES_STRING` belongs to the
capabilities path, not to a VCP read; and the two handle-class codes
must abort rather than retry.

### Behaviour preserved

`FetchCapabilitiesWithFallbackAsync` keeps its signature and still
returns `(string, VcpCapabilities?)`, so nothing outside the probe
changes. `BuildCapabilitiesFromProbe` synthesizes the same shape
`DdcCiNative.ProbeSupportedVcpFeatures` used to, and decides membership
the same way: a code counts as supported when the device *replied*, not
when the value was usable. A reply proves the opcode is implemented even
if the reported range cannot scale a percentage — an unimplemented code
fails with `DDCCI_VCP_NOT_SUPPORTED` instead.

The set of probed codes moves from a private array in `DdcCiNative` to
`NativeConstants.ContinuousVcpCodes`, where the follow-up work in #49445
also needs it.

### Cost

The probe only runs in Maximum compatibility mode, and only when the
capabilities string is already unusable — so this adds no I2C traffic to
a monitor that parses normally. For a monitor that does reach it, the
worst case grows from 3 transactions to 9 plus 900 ms of pacing, and it
is bounded: a definitive refusal stops after one attempt, and a
handle-class error stops the whole probe.

### What is deliberately left out

The probe's values are still discarded — `BuildMonitorFromPhysical`
re-reads each code immediately afterwards. Reusing them needs a carrier
for the observed value, which is `VcpDiscoveryEvidence` in #49445.
`VcpFeatureProbeService` already returns everything that needs
(`VcpProbeObservation` carries the value, the attempt count and the last
error); this PR simply does not consume it yet.

## Validation Steps Performed

- built `PowerDisplay.Lib.UnitTests` for x64 Debug with VS MSBuild — 0
errors, 0 warnings
- ran `PowerDisplay.Lib.UnitTests.dll` with `vstest.console.exe`: **223
passed, 0 failed** (186 on `main` + 37 added here)
- `VcpFeatureProbeServiceTests` drives the pacing, the retry budget, the
transient/definitive split, cancellation before and during the
inter-transaction delay, a throwing native read, and that reads run off
the caller's thread — all through an injected reader and an injected
delay, so no hardware is needed
- no hardware validation performed: reaching this path needs a panel
whose capabilities string is unusable **and** whose VCP reads fail
intermittently

---------

Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com>
2026-07-30 09:55:00 +00:00
Clint Rutkas
44fd627c3a Tighten IContextMenu::GetCommandString in Image Resizer (#48399)
## Summary

Corrects `IContextMenu::GetCommandString` handling in the Image Resizer
shell extension.

## Changes

- `GCS_VERBW` copies the Unicode canonical verb with `StringCchCopyW`,
preserving copy failures.
- Only `GCS_VALIDATEA` and `GCS_VALIDATEW` return `S_OK`.
- ANSI verb requests, help-text requests, and unknown request types
return `E_NOTIMPL`.
- ANSI string verbs are intentionally not advertised because
`InvokeCommand` cannot execute them.
- Updates spell-check expectations for the Windows constants used by
this implementation.

## Validation

The authoritative local versions of all three changed files are pushed
together. A Windows build was not run in this Linux environment.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-07-28 07:47:29 -07:00
moooyo
5c9c93d56d feat(powerdisplay): add CLI for monitor control (#48632)
## Summary of the Pull Request

Adds `PowerToys.PowerDisplay.Cli.exe`, a scriptable interface for
controlling monitors through the running PowerDisplay process. It
supports `list`, `get`, `set`, `up`, `down`, `capabilities`, `profiles`,
and `apply-profile`.

The CLI communicates over an authenticated, per-session named pipe;
PowerDisplay remains responsible for DDC/CI and WMI access.

## PR Checklist

- [x] Closes: #48713
- [x] **Communication:** Discussed with core contributors
- [x] **Tests:** Added/updated and all pass
- [x] **Localization:** Core errors are localizable; some help and
output text remains English-only
- [ ] **Dev docs:** N/A; built-in CLI help is the command reference
- [x] **New binaries:** Added on the required places
- [x] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
- [x] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetupVNext/Resources.wxs)
- [x] **YML for CI pipeline:** N/A; test assemblies are auto-discovered
- [x] **YML for signed pipeline:** N/A; signing is driven by
`ESRPSigning_core.json`
- [ ] **Documentation updated:** N/A

## Detailed Description of the Pull Request / Additional comments

- Adds an AOT-compatible CLI and shared request/response contracts.
- Uses a secured named-pipe server in PowerDisplay, with stable exit
codes and a bounded request timeout.
- Supports saved profiles by their existing stable profile IDs.
- Adds solution, signing, installer, and unit-test project integration.

## Validation Steps Performed

- PowerDisplay Lib, Contracts, CLI, and IPC unit-test suites pass.
- Native AOT publish completes without analyzer warnings.
- Manually validated the CLI on two DDC/CI monitors, including the
PowerDisplay-unavailable path.
- Rebuilt the PowerDisplay GUI after the shared-library changes.

---------

Co-authored-by: Yu Leng <yuleng@microsoft.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-16 23:08:27 +08:00
Gleb Khmyznikov
d5fe397b05 Follow-up: UITest framework Next - stability improvements (#49242)
This pull request addresses several CI flakiness and reliability issues
in the UI test automation harness, especially around foreground window
handling and build artifact resolution. The main improvements ensure
that UI interactions (like real mouse clicks) reliably target the
correct window, even in complex CI and build environments, and that test
code accurately locates module executables regardless of output layout.

**Foreground window handling and input reliability:**

* Added `Session.EnsureForeground()` and improved
`WindowControl.TryBringToForeground()` to reliably raise the target
window above others, defeating the Win32 foreground lock using
`AttachThreadInput` and related APIs. This prevents coordinate-based
clicks from landing on the wrong window, a common cause of CI test
flakiness. (`src/common/UITestAutomation.Next/Session.cs`,
`src/common/UITestAutomation.Next/WindowControl.cs`,
`src/common/UITestAutomation.Next/Element/Element.cs`,
`.github/skills/ui-tests-migration/references/ci-stability.md`,
`src/modules/MeasureTool/Tests/ScreenRuler.UITests.Next/TestHelper.cs`)
[[1]](diffhunk://#diff-713524f4ead9951000b3578248f2740088729981051b68c3fa3655ebb548f20fR91-R118)
[[2]](diffhunk://#diff-60be6ec24a99f8974cff00414fc47ea1e60e3ab9aee706b5d6845eb8df19165fR59-R76)
[[3]](diffhunk://#diff-60be6ec24a99f8974cff00414fc47ea1e60e3ab9aee706b5d6845eb8df19165fL247-R332)
[[4]](diffhunk://#diff-3c00581cb1d2b6a4302b8378b87c27cdad2f87c2aefc37eec0bdc6c39af9291aR100-R103)
[[5]](diffhunk://#diff-98e5aea12baaac99aba10e7dd341ed3f2efdd24cb80b29306bb500816de09e2fR96-R114)
[[6]](diffhunk://#diff-d8766b48614fe4a99e3f100e69e611ca2464de6ba0be257586c12d51f9278ed0L498-R504)

**Build artifact and executable path resolution:**

* Refactored `ModuleInfo.GetDevelopmentPath()` to dynamically walk up
from the test assembly and find the module executable in various build
output layouts, including CI artifacts and local builds. This eliminates
hardcoded path offsets and makes test launches robust to different build
structures. (`src/common/UITestAutomation/ModuleInfo.cs`)
* Updated `ModuleConfigData.GetModulePath()` to use the improved path
resolution and fall back to installed builds if necessary, ensuring that
test runs can always locate the correct executable.
(`src/common/UITestAutomation/ModuleConfigData.cs`)
* Simplified `SessionHelper` so that `locationPath` is always empty,
leveraging the fact that module paths are now absolute.
(`src/common/UITestAutomation/SessionHelper.cs`)
[[1]](diffhunk://#diff-c001f0fd3432c8b6102c3120597fc48f24902eaa0d755f51adfa7646344b3833L7-L10)
[[2]](diffhunk://#diff-c001f0fd3432c8b6102c3120597fc48f24902eaa0d755f51adfa7646344b3833L46-R54)

These changes collectively improve test reliability, especially in CI
environments, and make the harness more resilient to changes in build
output structure.

---------

Co-authored-by: Boliang Zhang (from Dev Box) <bozhang@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-09 20:57:18 -07:00
Muyuan Li
4881f23545 Add PR Needs-Author-Feedback lifecycle to fabricbot configuration (#49151)
## Summary

Adds fabricbot rules to manage the `Needs-Author-Feedback` label
lifecycle for **pull requests**, complementing the existing issue
management rules in `resourceManagement.yml`.

This is a **simpler alternative** to the GitHub Actions workflow
approach (PR #48812), trading advanced features (draft conversion,
author-specific activity tracking) for zero-maintenance fabricbot
automation.

## Behavior

### Flow diagram

```
┌──────────────────────────────────────────────────────────────────────┐
│  Maintainer adds "Needs-Author-Feedback" label to a PR              │
└──────────────────────────────────────────────────────────────────────┘
         │
         ▼
┌─────────────────────────────────────┐     ┌──────────────────────────────────┐
│  7 days, no activity                │────►│  Add "Status-No recent activity" │
│                                     │     │  + post warning comment          │
└─────────────────────────────────────┘     └──────────────────────────────────┘
         │                                               │
         ▼                                               ▼
┌─────────────────────────────────────┐     ┌──────────────────────────────────┐
│  7 more days (14 total), no activity│────►│  Close PR + post closing comment │
└─────────────────────────────────────┘     └──────────────────────────────────┘

┌──────────────────────────────────────────────────────────────────────┐
│  Author pushes commits OR comments on PR (at any point)              │
└──────────────────────────────────────────────────────────────────────┘
         │
         ▼
    Remove "Needs-Author-Feedback" → Add "Needs-Triage"
    Remove "Status-No recent activity" (if present)
```

### Scheduled searches (every 6 hours)

| Condition | Action |
|-----------|--------|
| PR + `Needs-Author-Feedback` + 7 days inactive + no `Status-No recent
activity` | Add `Status-No recent activity` label + warning comment |
| PR + `Needs-Author-Feedback` + `Status-No recent activity` + 7 more
days inactive | Post closing comment + close PR |

### Event responders

| Trigger | Action |
|---------|--------|
| Author comments on PR (`Issue_Comment` + `issueAuthor`) | Remove
`Needs-Author-Feedback`, add `Needs-Triage` + `Needs-Team-Response` |
| Author pushes commits (`Pull_Request` + `Synchronize` + `issueAuthor`)
| Remove `Needs-Author-Feedback`, add `Needs-Triage` |
| Any PR update activity | Remove `Status-No recent activity` |

### Bot messages

**Warning (at 7 days):**
> This pull request has been automatically marked as stale because it
has been marked as requiring author feedback but has not had any
activity for **7 days**. It will be closed if no further activity occurs
**within 7 days of this comment**. To keep this PR active, please push
your changes or leave a comment.

**Closing (at 14 days):**
> This pull request has been automatically closed because it has been
marked as requiring author feedback but has not had any activity for
**14 days**. If you would like to continue working on this, please
reopen the PR and push your changes.

## Comparison with GitHub Actions workflow (PR #48812)

| Feature | This PR (fabricbot) | PR #48812 (Actions) |
|---------|-------------------|-------------------|
| Convert to draft at 7 days |  Not supported |  Via GraphQL |
| Close at 14 days |  |  |
| Author-specific activity tracking |  Any activity resets timer | 
Only author activity counts |
| Bot comment resets timer | ⚠️ Yes (fabricbot limitation) |  No
(filtered out) |
| Maintenance burden | None (fabricbot managed) | Low (workflow file) |
| Testing before merge |  No local testing |  `workflow_dispatch` +
dry-run |
| Review comment detection |  Only issue comments |  Reviews + inline
comments |

## Trade-offs

**Pros:**
- Zero maintenance — fabricbot is a managed service
- Consistent with existing issue management patterns in the same file
- No workflow YAML to debug or maintain

**Cons:**
- No draft conversion (fabricbot cannot call GraphQL)
- `noActivitySince` counts **all** activity — bot comments, maintainer
comments, and label changes all reset the inactivity timer
- Cannot distinguish author activity from other activity
- No way to test locally or with dry-run before merge

## Relationship to existing automation

Mirrors the existing issue rules (lines 11-43) which use the same
pattern:
- Issues: 5 days → warning, 5 more days → close
- PRs (this change): 7 days → warning, 7 more days → close

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-09 15:37:19 +08:00
Gleb Khmyznikov
85f698677a [UITests] AI migration skill + ScreenRuler tests example port. (#48842)
This PR is build on top of
https://github.com/microsoft/PowerToys/pull/48717 and
https://github.com/microsoft/PowerToys/pull/48467

It adds the ui-tests-migration skill which should be used to migrate the
old UITest module by module to use new .Next UI framework.

As an example, the screen ruller tests was ported here.

---------

Co-authored-by: Boliang Zhang (from Dev Box) <bozhang@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-09 11:02:54 +08:00
Boliang Zhang
4395b1d0ca [skill] Generalize verification skill into 2 scenarios (module checklist / PR validation) (#48848)
## Summary of the Pull Request

Generalizes the `powertoys-verification` agent skill from "one module
checklist" into a **single shared engine that serves two verification
scenarios**, using the *shared engine + per-scenario reference docs*
design (no duplication of the winapp mechanics):

- **A — Module checklist**: verify a supplied module checklist against
the installed build.
- **B — PR validation**: derive each PR's checklist from its description
+ diff, then drive it. A single **bits sub-decision** picks the target —
drive the **installed** build when the PR's code is already shipped (a
merged PR, or a whole release/hotfix set, e.g. the 0.100.1 14-PR
sign-off), or **build + sideload** the affected module when it isn't (an
unmerged or not-yet-released PR, e.g. #45242).

Both scenarios share the same `winapp ui` drive techniques, helper
scripts, per-module profiles, taxonomy, and report format. They differ
mainly on **what bits you run**, so the only new content is a thin
scenario layer.

## PR Checklist

- [ ] **Closes:** N/A (follow-up to the merged `powertoys-verification`
skill)
- [x] **Communication:** design discussed and agreed before
implementation
- [x] **Tests:** N/A — docs/skill-only change; validated link/constraint
checks (see below)
- [x] **Localization:** N/A
- [x] **Dev docs:** this PR *is* skill documentation
- [x] **New binaries:** none

## Detailed Description of the Pull Request / Additional comments

**`SKILL.md` (shared engine)** — broaden `description` + "When to use"
to cover both scenarios, add a **Step-0 scenario router** (plus, for B,
the bits sub-decision "is the PR's code in the build under test?"), keep
the supplied-checklist read **Scenario-A-only**, and make the
bootstrap/placeholders/"What NOT to do" scenario-aware.

**`references/scenarios/`:**
- `index.md` — router table (A/B); the **"bits under test" contract**
(the one real conflict: installed-and-immutable, vs build-and-sideload
when the PR's code isn't in the build, echoed in the report header so
the evidence chain is trustworthy); and a verdict-vocabulary mapping
(engine `PASS/FAIL/BLOCKED` <-> legacy labels).
- `module-checklist.md` (A) — supplied checklist, installed bits.
- `pr-validation.md` (B, **new — merges the former release-PR and
active-PR docs**) — derive each PR's checklist from `gh pr view/diff`;
the **bits sub-decision**; a **PR-discovery model with a size gate**
(auto-verify hotfix-sized sets <=25; for full ~100-PR releases,
scope-and-confirm instead of blind-looping) and a non-runtime-PR
pre-filter; per-PR folders + roll-up; and the **build + sideload**
front-end (in-repo worktree helper + build commands), unpackaged (run
the built runner, dismiss the expected partial-build dialogs) vs
packaged/CmdPal (`Add-AppxPackage -Register`) deploy recipes,
prove-your-bits, and restore-to-shipped cleanup.

Removed the separate `release-pr-signoff.md` and
`active-pr-validation.md` (folded into `pr-validation.md`). The existing
engine docs (`winapp-ui-testing.md`, `pre-flight.md`,
`reporting-format.md`), per-module profiles, and helper scripts are
reused unchanged — single source of truth. The `BITS:` header version is
a `<version>` placeholder (not pinned to a release).

## Validation Steps Performed

- `SKILL.md` within authoring limits: **331 lines** (< 500) and
**description 999 chars** (< 1024).
- All relative markdown links in `references/scenarios/*.md` resolve,
and every engine doc they cite exists.
- Scenario B exercised end-to-end both ways: the 0.100.1 14-PR sign-off
(8 PASS / 6 BLOCKED, installed bits) and PR #45242 (Advanced Paste, 3/3
PASS, build + sideload).

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-08 14:53:38 -07:00
dependabot[bot]
f740d0b3e5 Build(deps): Bump actions/dependency-review-action from 4 to 5 (#47907)
Bumps
[actions/dependency-review-action](https://github.com/actions/dependency-review-action)
from 4 to 5.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/dependency-review-action/releases">actions/dependency-review-action's
releases</a>.</em></p>
<blockquote>
<h2>5.0.0</h2>
<p>This is a new major version of the Dependency Review Action which
updates the runtime to node24. This requires a minimum Actions Runner
version <a
href="https://github.com/actions/runner/releases/tag/v2.327.1">v2.327.1</a>
to run.</p>
<h2>What's Changed</h2>
<ul>
<li>Add .github/copilot-instructions.md for Copilot coding agent by <a
href="https://github.com/ahpook"><code>@​ahpook</code></a> in <a
href="https://redirect.github.com/actions/dependency-review-action/pull/1067">actions/dependency-review-action#1067</a></li>
<li>Update Node.js runtime from 20 to 24 by <a
href="https://github.com/scottschreckengaust"><code>@​scottschreckengaust</code></a>
in <a
href="https://redirect.github.com/actions/dependency-review-action/pull/1084">actions/dependency-review-action#1084</a></li>
<li>Bump spdx-license-ids from 3.0.20 to 3.0.23 by <a
href="https://github.com/mongolyy"><code>@​mongolyy</code></a> in <a
href="https://redirect.github.com/actions/dependency-review-action/pull/1091">actions/dependency-review-action#1091</a></li>
<li>docs: bump actions/checkout from v4 to v6 in workflow examples by <a
href="https://github.com/Marukome0743"><code>@​Marukome0743</code></a>
in <a
href="https://redirect.github.com/actions/dependency-review-action/pull/1077">actions/dependency-review-action#1077</a></li>
<li>fix: patched version display for advisories with non-strict semver
ranges (e.g. Maven beta versions) by <a
href="https://github.com/tspascoal"><code>@​tspascoal</code></a> in <a
href="https://redirect.github.com/actions/dependency-review-action/pull/1076">actions/dependency-review-action#1076</a></li>
<li>Resolve security findings by <a
href="https://github.com/AshelyTC"><code>@​AshelyTC</code></a> in <a
href="https://redirect.github.com/actions/dependency-review-action/pull/1094">actions/dependency-review-action#1094</a></li>
<li>v5.0.0 release branch by <a
href="https://github.com/ahpook"><code>@​ahpook</code></a> in <a
href="https://redirect.github.com/actions/dependency-review-action/pull/1098">actions/dependency-review-action#1098</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/scottschreckengaust"><code>@​scottschreckengaust</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/dependency-review-action/pull/1084">actions/dependency-review-action#1084</a></li>
<li><a href="https://github.com/mongolyy"><code>@​mongolyy</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/dependency-review-action/pull/1091">actions/dependency-review-action#1091</a></li>
<li><a
href="https://github.com/Marukome0743"><code>@​Marukome0743</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/dependency-review-action/pull/1077">actions/dependency-review-action#1077</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/dependency-review-action/compare/v4.9.0...v5.0.0">https://github.com/actions/dependency-review-action/compare/v4.9.0...v5.0.0</a></p>
<h2>Dependency Review Action 4.9.0</h2>
<p>This feature release contains a couple of notable changes:</p>
<ul>
<li>There is a new configuration option
<code>show_patched_versions</code> which will add a column to the
output, showing the fix version of each vulnerable dependency. Thanks <a
href="https://github.com/felickz"><code>@​felickz</code></a>!</li>
<li>Runs which do not display OpenSSF scorecards no longer fetch
scorecard information; previously it was fetched regardless of whether
or not it was displayed, causing unneccessary slowness. Great catch <a
href="https://github.com/jantiebot"><code>@​jantiebot</code></a>!</li>
<li>There are a couple of fixes to purl parsing which should improve
match accuracy for <code>allow-package-dependency</code> lists,
including case (in)sensitivity and url-encoded namespaces Thanks <a
href="https://github.com/juxtin"><code>@​juxtin</code></a>!</li>
</ul>
<h2>What's Changed</h2>
<ul>
<li>Compare normalized purls to account for encoding quirks by <a
href="https://github.com/juxtin"><code>@​juxtin</code></a> in <a
href="https://redirect.github.com/actions/dependency-review-action/pull/1056">actions/dependency-review-action#1056</a></li>
<li>Make purl comparisons case insensitive by <a
href="https://github.com/juxtin"><code>@​juxtin</code></a> in <a
href="https://redirect.github.com/actions/dependency-review-action/pull/1057">actions/dependency-review-action#1057</a></li>
<li>Feat: Add <code>Patched Version</code> to
<code>Vulnerabilities</code> summary by <a
href="https://github.com/felickz"><code>@​felickz</code></a> in <a
href="https://redirect.github.com/actions/dependency-review-action/pull/1045">actions/dependency-review-action#1045</a></li>
<li>fix: only get scorecard levels if user wants to see the OpenSSF
scorecard by <a
href="https://github.com/jantiebot"><code>@​jantiebot</code></a> in <a
href="https://redirect.github.com/actions/dependency-review-action/pull/1060">actions/dependency-review-action#1060</a></li>
<li>Bump actions/stale from 10.1.0 to 10.2.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/dependency-review-action/pull/1058">actions/dependency-review-action#1058</a></li>
<li>Bump actions/checkout from 4 to 6 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/dependency-review-action/pull/1021">actions/dependency-review-action#1021</a></li>
<li>Updates for release 4.9.0 by <a
href="https://github.com/ahpook"><code>@​ahpook</code></a> in <a
href="https://redirect.github.com/actions/dependency-review-action/pull/1064">actions/dependency-review-action#1064</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/jantiebot"><code>@​jantiebot</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/dependency-review-action/pull/1060">actions/dependency-review-action#1060</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/dependency-review-action/compare/v4.8.3...v4.9.0">https://github.com/actions/dependency-review-action/compare/v4.8.3...v4.9.0</a></p>
<h2>4.8.3</h2>
<h2>Dependency Review Action v4.8.3</h2>
<p>This is a bugfix release that updates a number of upstream
dependencies and includes a fix for the earlier feature that detected
oversized summaries and upload them as artifacts, which could
occasionally crash the action.</p>
<p>We have also updated the release process to use a long-lived
<code>v4</code> <strong>branch</strong> for the action, instead of a
force-pushed tag, which aligns better with git branching strategies; the
change should be transparent to end users.</p>
<h2>What's Changed</h2>
<ul>
<li>GitHub Actions can't push to our protected main by <a
href="https://github.com/dangoor"><code>@​dangoor</code></a> in <a
href="https://redirect.github.com/actions/dependency-review-action/pull/1017">actions/dependency-review-action#1017</a></li>
<li>Bump actions/stale from 9.1.0 to 10.1.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/dependency-review-action/pull/995">actions/dependency-review-action#995</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="a1d282b36b"><code>a1d282b</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/dependency-review-action/issues/1098">#1098</a>
from actions/ahpook/v5-release</li>
<li><a
href="eb6c199c5a"><code>eb6c199</code></a>
update examples to show <a
href="https://github.com/v5"><code>@​v5</code></a></li>
<li><a
href="3943c2c5be"><code>3943c2c</code></a>
v5.0.0 release branch</li>
<li><a
href="454943c880"><code>454943c</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/dependency-review-action/issues/1094">#1094</a>
from actions/ashelytc/security-findings</li>
<li><a
href="6d92a1228e"><code>6d92a12</code></a>
revert <code>@​typescript-eslint/parser</code> update</li>
<li><a
href="a8e5a7e936"><code>a8e5a7e</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/dependency-review-action/issues/1076">#1076</a>
from tspascoal/fix-version-matching-for-non-string-s...</li>
<li><a
href="b6b7079031"><code>b6b7079</code></a>
update <code>@​typescript-eslint/parser</code> to 8.40.0</li>
<li><a
href="821a21dd69"><code>821a21d</code></a>
update more dependencies</li>
<li><a
href="05aaaae45c"><code>05aaaae</code></a>
run npm audit fix</li>
<li><a
href="55d3e75450"><code>55d3e75</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/dependency-review-action/issues/1077">#1077</a>
from Marukome0743/docs/checkout</li>
<li>Additional commits viewable in <a
href="https://github.com/actions/dependency-review-action/compare/v4...v5">compare
view</a></li>
</ul>
</details>
<br />


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

You can trigger a rebase of this PR 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>

> **Note**
> Automatic rebases have been disabled on this pull request as it has
been open for over 30 days.

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-08 16:30:03 +02:00
Gleb Khmyznikov
74e6c3ad79 [UITests] New framework around WinApp CLI, no WinAppDriver or Selenium. (#48467)
# Add winappcli-based UI test harness (no WinAppDriver / Selenium)

## Summary

Introduces a new UI test harness — `Microsoft.PowerToys.UITest.Next` —
that drives PowerToys
modules through Microsoft's
[winappcli](https://github.com/microsoft/WinAppCli) (UI Automation
CLI) instead of WinAppDriver + Selenium. Engine is a single executable
shelled out from
C#; no third-party NuGet packages, no driver process, no Appium server.
Adds two real consumers:
a full ColorPicker end-to-end scenario and a Settings shell navigation
smoke test.

This is opt-in and additive — the existing `UITestAutomation` library
and the
WinAppDriver-based test projects are untouched. Both can coexist while
we evaluate the new
harness.

Inspired in part by
[#48414](https://github.com/microsoft/PowerToys/pull/48414), which lands
the same architectural bet (winappcli, AutomationId selectors, no
WinAppDriver) at a smaller
scope. This PR generalizes it into a reusable library.

## Why

WinAppDriver + Selenium is a legacy pre-agentic solution that is no
longer actively maintained. It's unreliable, heavyweight, and slow. To
achieve 100% UI test coverage, we should leverage modern, reliable
solutions, and WinApp CLI is a strong candidate.

## What's in this PR

### Harness library —
[`src/common/UITestAutomation.Next/`](src/common/UITestAutomation.Next/)

| File | Purpose |
|---|---|
| [`WinappCli.cs`](src/common/UITestAutomation.Next/WinappCli.cs) |
Process wrapper around `winapp.exe`. `Invoke` / `InvokeAssertSuccess` /
`InvokeJson` / `IsAvailable` / `TryResolveExecutable`. `Result` carries
the args and emits `DescribeFailure()` like `winapp ui invoke X -w 12345
-> exit 1; stderr: ...` |
| [`Session.cs`](src/common/UITestAutomation.Next/Session.cs) | Test
session, scoped by either HWND (`-w`) or process (`-a`) via
`TargetScope`. `Find<T>` / `FindAll<T>` / `Inspect` / `Screenshot` /
`SendKeys`. `Session.FromProcess(...)` factory for the
single-window-per-process case |
|
[`SessionHelper.cs`](src/common/UITestAutomation.Next/SessionHelper.cs)
| Owns the launch + window-readiness flow. Static `EnsureRunning(scope,
timeout)` returns whether the call had to launch (so cleanup only kills
what we started). Uses `UseShellExecute=true` so child handles don't
keep MSTest hanging |
| [`UITestBase.cs`](src/common/UITestAutomation.Next/UITestBase.cs) |
MSTest base class. Pre-flights `WinappCli.IsAvailable()` once per
process and fails fast with the install hint if `winapp.exe` isn't on
PATH |
| [`Element/*.cs`](src/common/UITestAutomation.Next/Element/) |
`Element`, `Button`, `ToggleSwitch`, `TextBox`, `NavigationViewItem`,
`Window`. `Click` / `MouseClick` / `Focus` / `GetProperty` / `GetValue`
/ `HelpText` / `WaitForProperty` / `WaitForGone` plus coords
(`X`/`Y`/`Width`/`Height`) |
| [`By.cs`](src/common/UITestAutomation.Next/By.cs) | `By.Name` /
`By.AccessibilityId` / `By.Id` / `By.Slug` |
| [`Windows.cs`](src/common/UITestAutomation.Next/Windows.cs) |
`WindowsFinder.ListAll` / `ListByApp` / `WaitForWindowByApp` /
`WaitForWindowByProcess`. Notes the winappcli bug where unfiltered
`list-windows` drops untitled windows |
|
[`WindowControl.cs`](src/common/UITestAutomation.Next/WindowControl.cs)
| Tolerant Win32 helpers — `TryCloseByApp` / `TryFocusByApp` /
`SafeCloseAndFocus` / `TryKillProcess` — for `finally` blocks |
|
[`KeyboardHelper.cs`](src/common/UITestAutomation.Next/KeyboardHelper.cs)
| Hybrid `keybd_event` + `SendKeys.SendWait` chord sender — required for
global PowerToys hotkeys |
| [`MouseHelper.cs`](src/common/UITestAutomation.Next/MouseHelper.cs) |
`MoveTo` / `LeftClick` / `RightClick` / `LeftClickAt` Win32 wrappers |
|
[`ClipboardHelper.cs`](src/common/UITestAutomation.Next/ClipboardHelper.cs)
| STA-thread `Clipboard` access with `WaitForText` |
|
[`ModuleConfigData.cs`](src/common/UITestAutomation.Next/ModuleConfigData.cs)
| `PowerToysModule` enum + path/process-name resolution |

### Tests


**[`src/modules/colorPicker/ColorPicker.UITests/`](src/modules/colorPicker/ColorPicker.UITests/)**
— replaces the previous empty `UITest-ColorPicker` stub. One test,
[`ColorPickerEndToEndTests.NavigateReadShortcutActivateAndCapture`](src/modules/colorPicker/ColorPicker.UITests/ColorPickerEndToEndTests.cs),
drives the full E2E:
1. Navigate to the Color Picker page via the dashboard utilities stack
2. Toggle the module OFF, verify `PowerToys.ColorPickerUI` exits; toggle
ON, verify it respawns
3. Read the activation shortcut from the page's `ShortcutControl`
(`EditButton.HelpText`)
4. Clear clipboard, park cursor, send the chord
5. Wait for the picker overlay window
6. Read the displayed HEX from a hidden XAML automation peer (see below)
7. Left-click to capture; assert the clipboard value matches the peer's
HEX
8. Wait for the editor window and assert the captured color appears in
its tree


**[`src/settings-ui/Settings.UITests/`](src/settings-ui/Settings.UITests/)**
— `SettingsNavigationSmokeTests.NavigationItem_NavigatesWithoutCrashing`
is one `[TestMethod]` parameterized with `[DynamicData]`, producing 31
discrete results — one per `NavigationViewItem` in
[`ShellPage.xaml`](src/settings-ui/Settings.UI/SettingsXAML/Views/ShellPage.xaml).
For each item: navigate, settle 250ms, assert `PowerToys.Settings` is
still alive. Catches FailFast regressions in
`ShellViewModel.Frame_NavigationFailed` that pure-logic unit tests can't
reach (the failure path needs a `NavigationFailedEventArgs` which is a
sealed WinRT projection).

### Product change


**[`src/modules/colorPicker/ColorPickerUI/Views/MainView.xaml`](src/modules/colorPicker/ColorPickerUI/Views/MainView.xaml)**
— adds a hidden `TextBlock` automation peer:

```xml
<TextBlock
    x:Name="ColorHexAutomationPeer"
    AutomationProperties.AutomationId="ColorHexAutomationPeer"
    IsHitTestVisible="False"
    Opacity="0"
    Text="{Binding ColorText}" />
```

The visible `ColorTextBlock` has `AutomationProperties.Name="{Binding
ColorName}"`, which masks the HEX value in the UIA tree (you see "White"
instead of `#FFFFFF`). This zero-impact peer mirrors `ColorText` so
tests can read the actually-displayed HEX. `Opacity=0` +
`IsHitTestVisible=False` keep it out of the visual layout and out of
accessibility focus.

### Project wiring

- [`PowerToys.slnx`](PowerToys.slnx) — registers `UITestAutomation.Next`
under `/common/`, `ColorPicker.UITests` under
`/modules/colorpicker/Tests/`, and `Settings.UITests` under
`/settings-ui/Tests/`. Original `UITest-ColorPicker` stub csproj
removed.
-
[`.github/actions/spell-check/expect.txt`](.github/actions/spell-check/expect.txt)
— adds `winapp` / `winappcli`.

### Not in this PR

- No pipeline changes. `winapp.exe` is expected to be pre-staged on the
test agent image. If it's missing, `UITestBase` fails the first test
with the install hint (`winget install Microsoft.winappcli`) rather than
producing 30 opaque per-test errors.
- No changes to the legacy `UITestAutomation` library or any of the
existing `*.UITests` projects.

## Validation

- All three projects build clean on `x64|Debug` (empty
`build.<config>.<plat>.errors.log`):
  - `src/common/UITestAutomation.Next/`
  - `src/modules/colorPicker/ColorPicker.UITests/`
  - `src/settings-ui/Settings.UITests/`
- Both tests run in Test Explorer / `dotnet test` via
Microsoft.Testing.Platform (already enabled repo-wide in
`Directory.Build.props`).
- Local runs: ColorPicker E2E green; Settings smoke green across all 31
nav items.
- `winapp 0.3.2` from `winget install Microsoft.winappcli`.

## Notes for reviewers

- **`UseShellExecute = true`** in `SessionHelper.EnsureRunning` is
intentional — `false` makes child processes inherit the test host's
stdin/stdout/stderr handles, which keeps MTP/Test Explorer marking the
run as "in progress" until the spawned PowerToys exits.
- **Process-scope (`-a`) targeting** in the Settings smoke test handles
single-instance handoff: the EXE you launch may exit with code 0
immediately after signalling an existing owner, so the alive check uses
`Process.GetProcessesByName` rather than the launcher PID.
- **AutomationId-only selectors** in the Settings smoke list keep the
test localization-independent. Parent groups have
`SelectsOnInvoked="False"` and only expand on click — `Element.Click`
tries `InvokePattern → TogglePattern → SelectionItemPattern →
ExpandCollapsePattern` so the same call works for both leaves and
groups.
- **Untitled-window discovery**: filtered `winapp ui list-windows -a
<name>` returns windows that the unfiltered call drops (e.g. ColorPicker
editor). `WindowsFinder.ListByApp` uses the filtered form. Reported
upstream.

## Before Merge

- Add the `winappcli` install step to the UI-test pipeline.
2026-07-08 13:58:08 +08:00
Dave Rayment
f5c6f50e30 [Quick Accent] Add Belarusian Latin and Belarusian Cyrillic character sets (#48344)
<!-- 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 adds support for Łacinka (Belarusian Latin) and Belarusian
Cyrillic character sets to Quick Accent.

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

- [x] Closes: #36571
<!-- - [ ] 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
- [x] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx

<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
This is a standard character set addition, with new entries in the
Language enum, the sets themselves added to CharacterMappings.All and
new resource strings for the user-facing names in the Settings page.

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
(Manual tests.)
- Confirmed that the new character set entries were present in the Quick
Accent settings page list.
- Tested that each of the characters in both the sets could be selected
and typed.
2026-07-08 13:56:28 +08:00
Clint Rutkas
af45c3ec7c Add press-and-hold activation mode to Quick Accent (#48937)
## Summary of the Pull Request

Adds an opt-in **press-and-hold** activation mode to Quick Accent, like
iOS / macOS: hold an accent-capable letter (e.g. `a`) and after a short,
configurable delay the accent picker opens automatically — no separate
trigger key (Space/arrows) required.

This is purely additive. The existing trigger-key modes (`Left/Right
arrow`, `Space`, `Both`) and all serialized settings values are
unchanged.


https://github.com/user-attachments/assets/faec298c-e42c-4fd1-84bd-6e74d1b481a0


### What it does

- Holding a letter types the base letter immediately, then arms the
picker. After the **Hold duration** (default **500 ms**) the toolbar
appears.
- Navigate the options with the arrow keys / Space, then **release the
letter** to insert the selected accent (it replaces the base letter).
- A quick tap types just the letter. Holding and releasing without
selecting leaves the base letter as-is.
- `Ctrl` / `Alt` / `AltGr` / `Win` + letter combinations are left
untouched, so shortcuts like `Ctrl+A` still work.

## PR Checklist

- [ ] **Closes:** N/A — feature enhancement (happy to link a tracking
issue if one is preferred)
- [x] **Communication:** Discussed direction with maintainers;
coordinated with #48891 (see below)
- [ ] **Tests:** No automated tests added — the activation decision
lives in the C++ low-level keyboard hook and isn't reachable from the
existing managed unit-test project. Validated manually (steps below).
Open to guidance on the preferred test surface.
- [x] **Localization:** All new end-user strings are in
`Settings.UI/Strings/en-us/Resources.resw` with translator comments.
- [x] **Dev docs:** `doc/devdocs/modules/quickaccent.md` updated with
the new mode.
- [x] **New binaries:** None.
- [x] **Documentation updated:** Dev docs updated; public Learn docs can
follow once shipped.

## Detailed Description of the Pull Request / Additional comments

- **`PowerAccentKeyboardService` (C++ hook):**
- Append `PressAndHold` to the internal `PowerAccentActivationKey` enum
(value `3`, appended to preserve serialized `0/1/2`).
- Add a `holdDuration` setting and `UpdateHoldDuration(Int32)` to the
WinRT projection (`.idl`).
- In `OnKeyDown`, arm the picker on the held letter itself; the base
letter still types on first press and auto-repeat is swallowed (reuses
the existing `m_toolbarVisible` repeat guard from #36853).
- In `OnKeyUp`, use the hold duration as the minimum-hold release
threshold for this mode (trigger modes keep using `inputTime`).
  - Modifier guard: Ctrl/Alt/AltGr/Win do not arm the mode.
- **Settings model (`Settings.UI.Library`):** append `PressAndHold` to
`PowerAccentActivationKey`; add `hold_duration_ms` (`IntProperty`,
default 500). Existing `settings.json` without the field falls back to
the 500 ms default.
- **`PowerAccent.Core`:** read and forward the hold duration to the
hook, and use it as the popup delay when `PressAndHold` is active.
- **Settings UI:** add the **"Press and hold the letter"** activation
option and a **"Hold duration (ms)"** control that is shown only when
that mode is selected.

### Enum sync note

`PowerAccentActivationKey` exists in both the C++ hook and the managed
settings library and is kept in sync by integer value. `PressAndHold`
was **appended** (never reordered) so existing serialized settings
(`0/1/2`) keep their meaning.

### Coordination with #48891 (Quick Accent WinUI migration)

This lands as its own atomic change on `main`. The overlap with the
in-progress WinUI migration (#48891) is tiny: only `PowerAccent.cs`'s
mode-aware popup delay (a single `Task.Delay` line). The C++ hook,
settings enum/model, and Settings UI are not touched by #48891, so it
can rebase onto this with minimal effort.

## Validation Steps Performed

- Built the full chain in `Debug|x64`:
- `PowerAccent.UI.csproj` → rebuilds the C++
`PowerAccentKeyboardService` projection (incl. `UpdateHoldDuration`) +
`PowerAccent.Core` + `Settings.UI.Library`. **0 errors.**
- `PowerToys.Settings.csproj` → Settings UI XAML / ViewModel / `.resw`
(XamlIndexBuilder search index regenerated). **0 errors.**
- Manual trial of the running module (`PowerToys.PowerAccent.exe`) with
`activation_key = 3`:
- Hold `a` → base letter types immediately; picker opens after ~500 ms;
arrows/Space navigate; releasing inserts the accent (replacing the base
letter).
- Quick tap → base letter only. Hold + release without selecting → base
letter remains.
  - `Ctrl+A` / `Alt`+letter unaffected.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-03 03:43:37 +00:00
moooyo
d6319516d0 [Skills] Fix wpf-to-winui3-migration SKILL.md failing to load (#49059)
## Summary of the Pull Request

The `wpf-to-winui3-migration` agent skill failed to load. The
`description` field in its `SKILL.md` YAML frontmatter was an
**unquoted** plain scalar containing `Keywords: ` (a colon followed by a
space). YAML interprets `: ` as a mapping key/value separator, so the
skill loader failed with:

> failed to parse YAML frontmatter: mapping values are not allowed in
this context at line 2 column 651

Because `.claude/skills` is a symlink to `.github/skills`, the CLI
enumerates the same file twice, so this single defect surfaced as
**two** skill load errors (`skill_error_count: 2`).

Fix: wrap the `description` value in single quotes so the colon is
treated literally. No wording changes; the description stays 926
characters (well under the 1024 limit).

## PR Checklist

- [ ] Closes: #xxx — N/A, trivial metadata fix, no tracking issue
- [x] **Communication:** Metadata-only fix; no design discussion needed
- [ ] **Tests:** N/A — no test harness for skill frontmatter; validated
by YAML parsing (see below)
- [x] **Localization:** N/A — not end-user-facing
- [ ] **Dev docs:** N/A
- [ ] **New binaries:** N/A

## Detailed Description of the Pull Request / Additional comments

`.github/skills/wpf-to-winui3-migration/SKILL.md` line 3 changed from:

```yaml
description: Guide for migrating ... after migration. Keywords: WPF, WinUI, ... SoftwareBitmap.
```

to:

```yaml
description: 'Guide for migrating ... after migration. Keywords: WPF, WinUI, ... SoftwareBitmap.'
```

The three other top-level skills already quote (or avoid `: ` in) their
descriptions, so only this one was affected. Single quotes are used
because the description contains no quote characters, so no escaping is
required.

## Validation Steps Performed

- Reproduced the loader error from the Copilot CLI logs: `mapping values
are not allowed in this context at line 2 column 651`.
- Parsed the frontmatter of all 9 `SKILL.md` files with a YAML parser:
before = 1 failure (this file), after = **0 failures**.
- Confirmed parsed `name` (`wpf-to-winui3-migration`), `description`
(926 chars, ≤ 1024), and `license` are intact and the literal `Keywords:
WPF...` text is preserved.

Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-02 10:48:23 +08:00
Copilot
4a27c5d5f9 New+: Fix French translation guidance (Nouveau+ not Nouveauté+) (#47225)
## Summary of the Pull Request

French translation of "New+" was rendered as "Nouveauté+" ("Novelty+")
instead of "Nouveau+" ("New+"), inconsistent with how Windows itself
translates the "New" context menu item in French. This updates
translator guidance comments in the English resource files to explicitly
call out the correct French form.

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

Translator-facing `<comment>` fields updated across three resource files
to explicitly state the correct French translation and flag the wrong
one:

- **`NewShellExtensionContextMenu/resources.resx`** and
**`NewShellExtensionContextMenu.win10/resources.resx`** —
`context_menu_item_new`:
> _"…e.g. Danish it would become Ny+, **French it would become Nouveau+
(not Nouveauté+)**"_

- **`Settings.UI/Strings/en-us/Resources.resw`** — five `NewPlus.*` /
`Oobe_NewPlus.*` strings:
> _"…Localize product name in accordance with Windows New. **e.g. French
would be Nouveau+ (not Nouveauté+)**"_

Actual `.lcl` translation files are managed by the CDPX localization
pipeline; these comment updates feed directly into the guidance the
localization team sees when updating those files.

## Validation Steps Performed

Comment-only changes to XML resource files; no runtime behavior
affected. Verified all targeted entries were updated and no existing
checked-in `Nouveauté` strings remain in the repo.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: niels9001 <9866362+niels9001@users.noreply.github.com>
2026-06-30 17:06:25 +08:00
Copilot
70ff4013b9 Add Shortcut Guide V2 manifest spec link to copilot-instructions.md (#48967)
Adds a reference to the WinGet Manifest Keyboard Shortcuts schema spec
in `.github/copilot-instructions.md` so AI agents know where to find the
correct field definitions, file naming conventions, and the `+` prefix
rule when creating or editing Shortcut Guide V2 manifest files.

## Summary of the Pull Request

Adds a new `## Shortcut Guide V2 Manifests` section to
`.github/copilot-instructions.md` linking to [`doc/specs/WinGet Manifest
Keyboard Shortcuts
schema.md`](../doc/specs/WinGet%20Manifest%20Keyboard%20Shortcuts%20schema.md).
This ensures agents authoring new manifest files follow the correct
schema and naming scheme (e.g., `<PackageId>.<locale>.yml`, `+` prefix
for apps without a WinGet package).

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

`.github/copilot-instructions.md` gains a dedicated section:

```markdown
## Shortcut Guide V2 Manifests

When creating or editing Shortcut Guide keyboard shortcut manifest files, follow the schema and naming conventions in the spec:

- [WinGet Manifest Keyboard Shortcuts schema](<../doc/specs/WinGet Manifest Keyboard Shortcuts schema.md>) – manifest file format, field definitions, file naming, and the `+` prefix convention for apps without a WinGet package
```

No production code changes.

## Validation Steps Performed

- Verified the relative link resolves to the correct spec file in the
repository.
- Confirmed the section is correctly placed before "Detailed
Documentation".

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-06-27 21:07:48 +00:00
ABHIJEET KALE
7a04d4c270 [ShortcutGuide] Add DaVinci Resolve keyboard shortcut manifest (#48651) (#48652)
Adds a shortcut manifest for DaVinci Resolve (professional video editing
and color grading application by Blackmagic Design) so it appears in the
Shortcut Guide overlay when the app is focused.

The manifest contains 88 of the most commonly used DaVinci Resolve
keyboard shortcuts organized into 8 categories:

| Section | Shortcuts | Highlights |
|---------|-----------|------------|
| Popular shortcuts | 25 | Page navigation (F5-F8), Playback (JKL,
Space), Edit basics (Cut, Blade, Ripple Delete) |
| Timeline navigation | 13 | Frame/clip/track navigation, zoom, edit
point jumping |
| Edit | 14 | Cut/Copy/Paste/Duplicate, Render in Place, Compound Clip |
| Color | 17 | Node management (Alt+S/P/L), viewer modes (1-5),
Grade/Keyframe |
| Fairlight | 8 | Mute/Solo/Record/Automation, Bounce Mix |
| Fusion | 8 | View switching (1-4), Merge, Keyframe |
| Media | 8 | Import, Smart Bin, Reveal in Explorer, Rename |
| Deliver | 5 | Render Queue, Start Render, Output settings |

The manifest follows the same YAML schema as existing manifests. No code
changes needed -- manifests are auto-discovered at startup.
2026-06-27 19:48:39 +00:00
Clint Rutkas
6dd1ce5dd1 Dev/crutkas/ripple v2.1 + spelling allow-list follow-up (#48232)
## Summary of the Pull Request

Adds a follow-up metadata fix to the existing Mouse Highlighter ripple
v2.1 work by allowing the term `xhair` in repo spell-check
configuration.

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

- Added `xhair` to `.github/actions/spell-check/expect.txt`.
- This addresses spelling feedback on MouseHighlighter ripple/crosshair
code without changing runtime behavior.
- No functional changes to Mouse Highlighter logic were made in this
follow-up commit.

## Validation Steps Performed

- Verified the only content change is the new `xhair` entry in
spell-check expected words.
- Ran secret scanning on changed file
(`.github/actions/spell-check/expect.txt`) with no findings.
- Ran parallel validation:
  - Code Review: no issues.
  - CodeQL: skipped as trivial metadata-only change.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Niels Laute <niels.laute@live.nl>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-06-26 21:35:27 +02:00
Michael Jolley
64f1243bdf Skip auto-labeling PRs that already have labels (#48877)
## Summary

The auto-labeler workflow now skips pull requests that already have
labels applied before running the AI classification. This avoids
overwriting or duplicating labels that were manually set by contributors
or maintainers.

## Changes

- Added a check in `labelIssue()` that returns early for PRs with
existing labels, logging which labels are already present.
- Issues continue to be labeled regardless (only PRs get the skip
logic).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-25 19:22:58 +00:00
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