9910 Commits
Author SHA1 Message Date
Clint Rutkas 8056ba0972 CmdPal: Fix double-speed Performance Monitor histories and long GPU names (#51206)
<!-- 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

Independent PR split out of #51125, which redesigns the Performance
Monitor cards; see it for the full picture. This PR can merge in any
order with the rest of that split.

It fixes two Performance Monitor bugs on `main`:

- **A metric shown in two places records its history at double speed.**
For example, with the Memory dock band pinned and the Performance
Monitor page open, two one-second timers each add a point to the same
chart history, so the chart fills twice as fast and covers half the time
it should. Now every metric (CPU, memory, network, disk, GPU, and
battery) gets one sample per second, however many places show it.
- **Some GPU names make the dock label too long.** Some drivers append
details in parentheses: `NVIDIA RTX Spark N1X (6144-core Blackwell RTX
GPU)` showed as `RTX Spark N1X (6144-core Blackwell RTX GPU)`. It now
shows as `RTX Spark N1X`.

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

- [ ] Closes: N/A. Split out of #51125.
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [x] **Tests:** Added/updated and all pass
- [x] **Localization:** All end-user-facing strings can be localized (no
new strings)
- [ ] **Dev docs:** Added/updated (N/A)
- [ ] **New binaries:** Added on the required places (N/A: no new
binaries or projects)
- [ ] [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 (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

### Double-speed histories

On `main`, `PerformanceMonitorCommandsProvider` creates the main page,
the combined dock band, and a dock band for each metric. Each is a
`PerformanceWidgetsPage` with its own `SystemXxxUsageWidgetPage` for
each metric it shows, and each of those has its own `DataManager` with a
one-second timer that runs while the page or band is shown. Every
`DataManager` samples the same `SystemData.Shared` stats, and for CPU,
memory, network, disk, and GPU, each sample appends a point to the
shared chart history (`ChartHelper.AddNextChartValue`). So each extra
place that shows a metric adds another point per second.

`DataManager.ShouldSample` records when each stats object was last
sampled, in a `ConditionalWeakTable` keyed by the stats object, and
skips the sample if the last one was less than 750 ms ago. The check
runs under the stats lock that each sampler already takes. 750 ms leaves
room for timer jitter: a late tick from the same timer still samples,
but a second timer's tick within the same second doesn't. Every timer
still calls its page's update, so every place keeps showing the latest
values.

All six metrics are gated: CPU, memory, network, disk, GPU, and battery.
Every CPU page on `main` uses `DataType.CPU`, so all CPU timers ask for
the same sample; `includeTopProcesses` and
`DataType.CpuWithTopProcesses` are unchanged.

### Long GPU names

`GpuAdapterNames.GetShortName` removes known branding, such as `NVIDIA`,
`GeForce`, `(R)`, `(TM)`, and a trailing ` GPU`. Nothing removed a
trailing part in parentheses, so it stayed in the label. It's now
dropped before the other rules run, so they see the model name. Names
without one are unchanged.

### Tests

- `DataManagerTests` (new) covers `ShouldSample`: the first sample, a
second timer within the same second, a late tick, and separate schedules
for each stats object.
- `GpuAdapterNamesTests` gets a row for `NVIDIA RTX Spark N1X (6144-core
Blackwell RTX GPU)`.

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

ARM64, Debug, from the repo root:

- `MSBuild.exe
src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.PerformanceMonitor\Microsoft.CmdPal.Ext.PerformanceMonitor.csproj
-nologo -m -restore -t:Build -v:minimal -p:Configuration=Debug
-p:Platform=ARM64 -p:RuntimeIdentifier=win-arm64 -p:CIBuild=false
-p:GeneratePackageLocally=false -p:GenerateAppxPackageOnBuild=false
-p:PublishAppxPackage=false -p:SkipLongPathsCheck=true`: exit code 0, 0
warnings.
- The same command for
`src\modules\cmdpal\Tests\Microsoft.CmdPal.Ext.PerformanceMonitor.UnitTests\Microsoft.CmdPal.Ext.PerformanceMonitor.UnitTests.csproj`:
exit code 0, 0 warnings.
- `vstest.console.arm64.exe
ARM64\Debug\WinUI3Apps\CmdPal\tests\Microsoft.CmdPal.Ext.PerformanceMonitor.UnitTests.dll
/Platform:ARM64`: 103 passed, 0 failed, including the four new
`DataManagerTests` and the new GPU name row.
- With `main`'s `GpuAdapterNames.cs`, the new GPU name row fails:
`Expected:<RTX Spark N1X>. Actual:<RTX Spark N1X (6144-core Blackwell
RTX GPU)>`.
- A throwaway test (not in this PR) reproduced the double-speed history.
It called the samplers of two `DataManager` instances for the same
metric 500 ms apart, once per second each, for 5 seconds, with the real
`MemoryStats` and `CPUStats`:

  | Metric | History points without this PR | With this PR |
  |---|---|---|
  | Memory | 10 | 5 |
  | CPU | 10 | 5 |
2026-10-28 00:25:56 +00:00
Dustin L. Howett a9fd278731 Allow official builds to pull-through and populate the NuGet feed (#51631)
This will allow our maintainers to preflight .NET SDK version upgrades
(and more) to pull all the packages into the proper feed.
2026-10-27 17:24:42 -05:00
Clint Rutkas 784bab1b17 [Deps] Bump System.CommandLine from 2.0.1 to 2.0.12 (#51323)
<!-- 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

Finishes DEP-3 by moving the central System.CommandLine pin from `2.0.1`
to `2.0.12`, the latest 2.0.x servicing release. No code changes are
needed. CLI help, errors, and exit codes stay the same.

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

- [ ] Closes: N/A (DEP-3 roadmap item; follows #50884)
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [x] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [x] **Tests:** Added/updated and all pass (existing tests; version
bump only)
- [ ] **Localization:** All end-user-facing strings can be localized (no
new strings)
- [x] **Dev docs:** Added/updated (`doc/devdocs/cli-conventions.md`)
- [ ] **New binaries:** Added on the required places (none)
- [ ] [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:** 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

- **Library source is unchanged.** The 2.0.12 commit (dotnet/dotnet
`95017c7`) descends from the 2.0.1 commit (`fad253f`). The last commit
that touches `src/command-line-api/src/System.CommandLine` is `4ad7638`
(2025-11-14) in both, so 2.0.2–2.0.12 are .NET 10 servicing rebuilds.
- **The package layout matches 2.0.1:** the same `net8.0` and
`netstandard2.0` targets, 13 satellite cultures, and no `net8.0`
dependencies. `generateAllFileComponents.ps1` harvests satellites at
build time, so the installer needs no change.
- **AssemblyVersion is now `2.0.12.0`** with the same public key token.
.NET doesn't need binding redirects.
- **Restored anonymously** from `PowerToysPublicDependencies`, where
2.0.12 was already saved. Nothing new was pulled from nuget.org.
NOTICE.md doesn't list this package.

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

- `msbuild <proj> -t:Restore -p:RestorePackagesConfig=true
-p:SolutionDir=<repo>\`, run with `NUGET_PLUGIN_PATHS` pointing at an
empty folder, for all 10 consumers and their test projects: all exit 0.
- `tools\build\build.ps1 -Platform x64 -Configuration Debug -Path <dir>`
for 11 consumer and test projects: all exit 0, with no new warnings.
- `vstest.console.exe <dll> /Platform:x64`: LightSwitch.Cli 221/221,
AdvancedPaste.Cli 154/154, PowerDisplay.Cli 130/130, DSC 115/115,
ImageResizer 213/213, Awake 7/7, CmdPal Shell 128 passed and 1 skipped.
- Settings.UI.UnitTests: 426/448 pass, including all 19
`SettingsCliTests`. The 22 failures are `ImageResizer`/`KeyboardManager`
view-model tests where `ResourceLoaderInstance` throws
`FileNotFoundException`. The same 22 tests fail on a 2.0.1 baseline.
- A/B test: 31 calls across 7 CLIs (`--help`, unknown command or option,
invalid values) built against 2.0.1 and 2.0.12. stdout, stderr, and exit
codes are byte-identical.
2026-10-27 22:24:17 +00:00
Denis Mahmutovic 5868a0a124 [CmdPal] Add Mica and Mica Alt materials to the Dock (#51470)
## Summary of the Pull Request

The Dock currently offers Acrylic and Transparent, while the main
Command Palette window also supports Mica materials. This adds **Mica**
and **Mica Alt** to **Dock > Appearance > Material**, with live
switching and an independent saved selection.

## PR Checklist

- [ ] **Closes:** No linked issue yet; this is a feature proposal.
- [ ] **Communication:** Seeking maintainer feedback; prior agreement
has not been obtained.
- [x] **Tests:** Added persistence coverage; all 262 focused Dock and
settings-page tests pass.
- [x] **Localization:** Reuses existing localized material labels and
Mica explanation.
- [ ] **Dev docs:** Not applicable; no developer documentation changes.
- [x] **New binaries:** None; no dependency or installer changes.
- [ ] **Documentation updated:** The separate MicrosoftDocs user guide
is not updated in this PR.

## Detailed Description of the Pull Request / Additional comments

- Render Mica and Mica Alt with native `MicaController` instances using
`MicaKind.Base` and `MicaKind.BaseAlt`.
- Synchronize the system backdrop with the Dock's theme and dispose the
previous controller when switching materials or closing the Dock.
- Preserve the existing Acrylic and Transparent rendering paths and enum
values.
- Disable background colorization and images while a Mica material is
selected. Retain those settings for switching back to Acrylic or
Transparent.
- Keep the Dock material independent of the main palette's material.
- Show the Mica explanation inside the Material expander, using the same
card and text styling as the Appearance page.
- Fall back from unsupported Mica/Mica Alt to Acrylic, then Transparent
if Acrylic is also unsupported. Keep Acrylic tint and opacity parameters
ready for the fallback.

## Validation Steps Performed

- Built the x64 Release Command Palette UI successfully with Visual
Studio MSBuild and .NET 10.
- Ran the focused Dock and settings-page tests through VSTest: **262
passed, 0 failed**, including four new save/reload cases covering every
material and palette independence.
- Exercised the production backdrop methods with native support results
simulated: **19 cases passed**, covering both Mica variants,
Acrylic/Transparent fallbacks, configuration availability, repeated
updates, theme changes and controller cleanup. This checks control flow,
not rendering on an older OS.
- Verified the Dock Mica explanation uses the same text styling and
SettingsCard-inside-SettingsExpander layout as the Appearance page.
- Manually validated the four-item Material dropdown and Mica/Mica Alt
in an installed local test build on Windows 11 x64; the requester
confirmed the feature works.
- `git diff --cached --check`: passed.

Build limitation: unchanged native components were reused from the
installed PowerToys package because the local C++ toolchain is
unavailable. This was a non-AOT app build; a full native/AOT build and
multi-monitor/ARM64 validation remain for CI or maintainer testing.
Actual fallback rendering on Windows 10 (including build 19041) has not
been tested; that still needs an older supported system.

## Video: Dock material with another app focused

Tested Mica and Mica Alt on Windows 11 x64 with Notepad focused. The
Dock retained its appearance in both cases; no switch to a flat fallback
background was observed. The recording below shows the material settings
and switching to Notepad.



https://github.com/user-attachments/assets/3cf8df62-a67c-4cdd-b261-5527b29b126e
2026-10-27 19:50:33 +00:00
Mike Griese f0a6c26738 cmdpal: fix CA1860 (#51619)
Apparently I got a VS update and this is like, an error now or
something. Whatever.

closes nothing
2026-10-27 13:34:58 -05:00
Jiří Polášek 9227a84977 CmdPal: Remove the live host log mesages view (#51575)
## Summary of the Pull Request

This PR removes Log view page and writes message directly to the log
file.

- Removes Log messages page and replaces it with Open logs folder.
- Messages are not stored in memory but written directly to the log
file.

<img width="383" height="260" alt="image"
src="https://github.com/user-attachments/assets/59e49c4f-5ede-4d47-a22d-0be0e53f90fe"
/>


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

- [x] Closes: #51546
2026-10-27 10:30:10 -05:00
Jiří Polášek cbd22d5439 CmdPal: Bringing dock to the front should not reveal the auto-hidden dock (#51556)
## Summary of the Pull Request

This PR stops BringToTopMessage handler in Dock window from revealing
the hidden dock. The message is supposed to just change the Z-order.

## PR Checklist

- [x] Closes: #51553
2026-10-27 10:27:53 -05:00
Boliang Zhang 9e6593c349 build(release): advance release train to 0.103 (#51603)
<!--
HARD RULE: You (the human contributor) must write this PR description in
your own words.
AI tools and agents: Do NOT write the Summary, Detailed Description, or
Validation Steps sections.
Leave them for the human. You may put AI-generated text ONLY inside an
"AI-generated summary" <details> block at the bottom.
Maintainers will close PRs whose description they think was not written
by a human.
See
https://github.com/microsoft/PowerToys/blob/main/CONTRIBUTING.md#pull-request-descriptions-must-be-written-by-a-human
-->

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

Going forward, releases built from `main` will be called **Development
preview**, and the minor version on `main` will stay ahead of the stable
release.

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

<details>
<summary>AI-generated summary</summary>

Following the one-line release-train transition in #51111, change
`src/Version.props` on main:

```diff
-    <ReleaseTrainVersion>0.102</ReleaseTrainVersion>
+    <ReleaseTrainVersion>0.103</ReleaseTrainVersion>
```

Automatic main builds will use `0.103.<YDDDB>.0`. Keep
`ReleaseTrainEpoch=2026-01-01` because the transition remains in the
same calendar year. Leave `Version=0.0.1` and `VersionChannel=private`
unchanged.

This branch starts directly from main at `06e6ae43e2`. It contains no
stable-branch history, release-tooling changes, or published-release
operations. It does not change the configuration on the existing stable
branch.

### Validation

Run from `D:\PowerToys-release-train-0103-20261027`:

```powershell
Import-Module Pester -RequiredVersion 3.4.0
$result = Invoke-Pester -Script .\.pipelines\tests\resolveBuildMetadata.Tests.ps1 -PassThru -Quiet
$result | Select-Object TotalCount,PassedCount,FailedCount,SkippedCount
if ($result.FailedCount -gt 0 -or $result.TotalCount -eq 0) { exit 1 }
```

**Passed: 25/25 tests, zero failures or skips; exit code 0.**

Also exercise the actual changed `src\Version.props`, rather than only
the suite's fixture:

```powershell
$common = @{
    VersionOverride = 'auto'
    ReleaseIntent = 'auto'
    BuildNumber = 'PowerToys Signed YAML Release Build_2610.27001-main'
    BuildDate = '20261027'
    DailyVersionSequence = '1'
    VersionPropsPath = (Resolve-Path .\src\Version.props).Path
}
& .\.pipelines\resolveBuildMetadata.ps1 @common -SourceBranch refs/heads/main -BuildReason Schedule
& .\.pipelines\resolveBuildMetadata.ps1 @common -SourceBranch refs/heads/main -BuildReason Manual
& .\.pipelines\resolveBuildMetadata.ps1 @common -SourceBranch refs/heads/stable -BuildReason Manual
& .\.pipelines\resolveBuildMetadata.ps1 @common -SourceBranch refs/heads/LegendaryBlair/release-train-0.103 -BuildReason Manual
```

All four invocations passed with version, channel and intent assertions:

| Simulated resolver scenario | Version | Channel | Intent |
| --- | --- | --- | --- |
| Scheduled main | `0.103.3001.0` | preview | preview-release |
| Manual main | `0.103.3001.0` | preview | preview-validation |
| Manual stable using the changed main configuration | `0.103.3001.0` |
stable | stable-release |
| Private feature branch | `0.0.30001.0` | private | private-validation
|

`git diff --check` passed. `git diff -- src\Version.props` confirmed
exactly one changed line. XML checks confirmed the epoch and
local/private defaults remain unchanged.

No new constant-only tests were added. A full product build and UI tests
were not run because this changes release metadata only; the existing
resolver suite and actual-configuration checks cover the change. No ADO
build was queued.

The human author must fill in the template sections and checklist before
review.

</details>

Copilot-Session: f0dee2a1-0a99-47cc-ac9e-9d9c8a3774f9
2026-10-27 09:32:19 +00:00
Boliang ZhangandCopilot 06e6ae43e2 feat(workspaces): add list and launch CLI (#51114)
<!-- 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

Add Workspaces **list** and synchronous **launch** through a thin native
CLI and shared GUI/CLI execution core. Related to #49900;
capture/create/CRUD are excluded. Usage and contracts:
`doc\devdocs\modules\workspaces-cli.md`.

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

- [ ] Closes: N/A - partial scope of #49900.
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [x] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [x] **Tests:** Added/updated and all pass (scoped local runs below;
CI/release gates remain)
- [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 - current integration:
`installer\PowerToysSetupVNext\CliShims.wxs`
- [x] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects - existing discovery; session-peer companion
signing updated
- [x] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- N/A: existing signing pipeline
- [ ] **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: N/A - follow-up not filed.

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

### Shared execution, conditional process boundary

```mermaid
flowchart TB
    EDITOR["Editor process<br/>C# / WPF"] -->|"start GUI Launcher"| ADAPTER
    SHELL["Terminal / script"] -->|"CLI shim starts CLI"| ADAPTER

    subgraph CALLER["Caller process: CLI.exe OR Launcher.exe in GUI mode"]
        ADAPTER["Thin entry adapter"]
        START["WorkspacesSession::Start<br/>snapshot + context check"]
        LOCAL["WorkspacesSession::Execute()<br/>function inside the caller process"]
        ADAPTER -->|"in-process"| START
        START -->|"verified Medium: in-process"| LOCAL
        LOCAL -.->|"typed return via Start"| ADAPTER
    end

    subgraph HOST["Elevated callers only: Medium host process<br/>PowerToys.WorkspacesLauncher.exe"]
        HANDOFF["Host entry<br/>receive and validate SessionHandoff"]
        REMOTE["WorkspacesSession::Execute()<br/>function inside this host process"]
        HANDOFF -->|"function call within the same process"| REMOTE
    end

    START -->|"elevated: create host<br/>read-only snapshot + restricted handles"| HANDOFF
    REMOTE -.->|"private anonymous result pipe"| START
    START -.->|"host outcome returned"| ADAPTER
    LOCAL <-->|"named pipes"| ARRANGER["WindowArranger process"]
    REMOTE <-->|"named pipes"| ARRANGER
    LOCAL <-->|"named pipes"| UI["Existing WPF Launcher UI process"]
    REMOTE <-->|"named pipes"| UI

    classDef shared fill:#dbeafe,stroke:#2563eb,color:#172554
    class START,LOCAL,REMOTE shared
```

The caller box represents **one of the two entry executables**, not both
in one process. Blue nodes are code statically linked from
`WorkspacesLib.lib`, not a DLL or shared service. **Medium GUI/CLI
callers execute in their own process without another Launcher host.**
Only elevated callers create a verified Medium host through the existing
`run_non_elevated` helper; it calls the same
`WorkspacesLib\LaunchExecution.cpp` core. No elevated fallback.

**`Execute()` is a function, not another EXE.** The host entry and its
`Execute()` share the same process ID. Execution uses a worker thread
inside that process, not another Launcher process. The two `Execute()`
nodes represent the same library implementation running in alternative
caller/host contexts.

- **Shared behavior:** one preparation, launch, arrangement,
confirmation and history flow. GUI retains progress; CLI shows only
required existing confirmation UI. GUI Cancel and console cancellation
use the shared stop/result path; already-started apps survive. Arranger
callbacks are stopped and joined before their helper owner is released.
An unresponsive inline Shell call yields `outcomeUnknown` before the
one-shot adapter exits, rather than killing a thread or claiming
cancellation succeeded.
- **Contracts:** `list` is read-only; summary JSON reuses existing
names. All arranged = `completed`/0; partial progress = `partial`/10; no
progress = `failed`/10. Incomplete, fractional or invalid final states
yield `outcomeUnknown`/9. Persistence verification failure retains exit
11 and displays application results in both text and JSON modes. The
existing `LaunchedAndMoved` enum and numeric IPC values are unchanged.
- **Persistence/integration:** preserve IDs, initialize missing legacy
IDs, update history best-effort; unsaved GUI drafts do not write saved
configuration/history. Only shim `bin` goes on PATH. Editor sibling-tool
resolution is executable-relative.
- **Telemetry:** one frontend `Workspaces_CLICommand` event when
optional diagnostics are enabled, following #50507's fixed command
category + success model. No workspace names/IDs, paths, arguments or
error text; the Medium host does not double-count. Uses the existing
native telemetry channel; documented in `DATA_AND_PRIVACY.md`.
- **Release IPC:** exact session-owner PID and official CLI/Launcher
identities remain checked. CI companion signing now includes CLI,
Launcher, arranger and Launcher UI; production signature checks are not
disabled.
- **Console isolation:** console workspace targets get their own
console; inline execution does not detach, redirect or share the CLI's
console.
- **Launch and Edit:** a missing temporary draft now falls back to the
saved workspace before GUID validation; malformed existing drafts still
fail. The existing UI regression explicitly checks that no draft is
present.
- **GUI file errors:** unreadable saved files and drafts show the
existing localized file-reading dialog with the correct source filename;
malformed-file dialogs also retain that context. Public CLI error JSON
is unchanged.
- **UI-test transport:** shared value setters place target options
before `--` and pass selectors/values literally. This fixes the
leading-dash command-line inputs rejected by CI's winapp 0.7.1 without
changing Workspaces test payloads or assertions.

### Changed-file breakdown

Full PR versus main, not just the latest commit. Each file is counted
once; test projects and fixtures are grouped under tests. These are file
categories, not process or library boundaries.

| Category | Files |
|---|---:|
| CLI adapter, output, resources and project | 7 |
| Shared session/execution entry, contracts, IPC, storage and telemetry
| 19 |
| Launcher engine/host adapter, arranger and UI | 18 |
| Managed storage and Editor path compatibility | 4 |
| Common helpers | 9 |
| Tests and fixtures | 24 |
| Build, installer and signing | 6 |
| Documentation and privacy catalog | 4 |
| **Total** | **91** |

The Launcher engine sources are compiled into `WorkspacesLib` even
though their source files remain under `WorkspacesLauncher`; the table
does not imply a separate engine process.

**Scope/known follow-ups:** general Editor save/conflict redesign and
the pre-existing localized-name/package-version matching bug are
deferred. Final GUI progress presentation still needs follow-up; this
update does not claim to fix its spinner-before-close behavior. The
native C++ parser is retained by the PR author's decision; a managed
System.CommandLine migration is not included. This does not amend the
repository-wide CLI convention.

<details>
<summary>List output and shared confirmation UI</summary>

![Workspaces CLI
list](https://github.com/user-attachments/assets/3755c810-0b85-4afe-b80f-f17f12e7f07d)
![Shared confirmation UI; controlled probe, no target
executed](https://github.com/user-attachments/assets/fbd09160-725d-47b7-907e-307bb2d749dc)

</details>

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

x64 Debug builds of the affected product and UI-test/fixture projects
passed; Release core, ModuleInterface, arranger, Launcher and CLI builds
also passed. The pre-GUI-error scoped native run passed **160 tests**.
Two deterministic paused-dispatch regressions reproduced `0xC0000005`
before the teardown fix (snapshot and final-result callbacks); both now
return acknowledged cancellation. Test hooks are compiled only into the
fixture, not production builds. **48 signing-selection** tests passed
earlier against unchanged selection logic. The preceding missing-draft
fix passed **39 focused tests** plus the complete local-host `winapp`
Launch and Edit flow, with settings/pointer/Editor state restored. This
is targeted host validation, not full local OS-matrix sign-off.

The GUI error follow-up `8ea5619586` passed **33 focused native tests in
each of Debug and Release**, including a regression that failed before
the fix. Both real saved-file/draft error dialogs were driven locally
with UIA; original configuration bytes and draft absence were restored.

The CI transport follow-up `e0945376e6` passed **19 focused
shared-harness tests in each of Debug and Release**. Using the
hash-verified winapp **0.7.1** archive from the failing CI revision, the
original invocation reproduced `invalid_arguments`; the fixed wrappers
passed **nine owned-UI setter checks** for leading options, quoted text,
empty text, and negative numeric values. The TextBox, editable ComboBox,
NumberBox, and Slider setters share the corrected argument boundary.
This is focused wrapper validation, not a claim that the full Workspaces
suite ran locally.

<details>
<summary>Commands and results</summary>

Used the verified side-by-side SDK 10.0.303; no global/repository SDK or
package-source change. With `$root='D:\PowerToys-workspace-cli'`, from
each affected project directory:

```powershell
& "$root\tools\build\build.ps1" -Platform x64 -Configuration Debug -ExtraArgs @("/p:SolutionDir=$root\", '/p:BuildProjectReferences=false', '/p:WorkspacesCliLiveTests=true')
# Passed, exit 0.
& "$root\tools\build\build.ps1" -Platform x64 -Configuration Release -ExtraArgs @("/p:SolutionDir=$root\", '/p:BuildProjectReferences=false')
# Passed, exit 0, for core/arranger/Launcher/CLI.
```

Missing Release UI dependencies were first built with project references
enabled:

```powershell
# From src\modules\Workspaces\WorkspacesLauncherUI:
& "$root\tools\build\build.ps1" -Platform x64 -Configuration Release -ExtraArgs @("/p:SolutionDir=$root\")
# Passed, exit 0.
```

Pre-GUI-error scoped native run (`$evidence` is the local report
directory):

```powershell
$env:WORKSPACES_CLI_LIVE_TESTS='1'
& 'C:\Program Files\Microsoft Visual Studio\18\Enterprise\Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe' "$root\x64\Debug\tests\Workspaces\Workspaces.Lib.UnitTests.dll" '/TestCaseFilter:FullyQualifiedName~CliContractTests|FullyQualifiedName~CliJsonOutputTests|FullyQualifiedName~CliRuntimeTests|FullyQualifiedName~CliHandoffTests|FullyQualifiedName~CliWorkerTests|FullyQualifiedName~WorkspaceStoreTests|FullyQualifiedName~SignatureVerificationTests|FullyQualifiedName~SignatureTrustTests|FullyQualifiedName~ExecutableTargetTests|FullyQualifiedName~ElevatedLaunchGateTests|FullyQualifiedName~PendingLaunchApprovalTests' "/ResultsDirectory:$evidence" '/Logger:trx;LogFileName=teardown-race-green.trx' '/Logger:console;verbosity=minimal'
# Passed: 160; failed/skipped: 0; exit 0.
& 'C:\Program Files\Microsoft Visual Studio\18\Enterprise\Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe' "$root\x64\Debug\tests\Workspaces\Workspaces.Lib.UnitTests.dll" '/TestCaseFilter:FullyQualifiedName~CliContractTests|FullyQualifiedName~JsonUtilsTests' "/ResultsDirectory:$evidence" '/Logger:trx;LogFileName=missing-draft-headless.trx' '/Logger:console;verbosity=minimal'
# Passed after the draft fix: 39; failed/skipped: 0; exit 0.
Invoke-Pester -Script 'D:\PowerToys-workspace-cli\.pipelines\tests\uiTestSigningSelection.Tests.ps1' -PassThru
# Passed: 48; failed: 0.
git diff --check
# Passed, exit 0.
```

Telemetry lifecycle tests use a recording sink and synthetic commands;
they neither transmit telemetry nor change diagnostic consent.

Recorded host UI actions (3892 was this run's owned Editor PID, not a
reusable PID):

```powershell
winapp ui 'invoke' 'EditButton' '-a' '3892' '--json'
winapp ui 'invoke' 'LaunchEditButton' '-a' '3892' '--json'
winapp ui 'invoke' 'SnapshotButton' '-a' '3892' '--json'
winapp ui 'invoke' 'SaveButton' '-a' '3892' '--json'
# All passed, exit 0; fixture startup, exact placement, recapture and persisted IDs were asserted.
```

</details>

Latest shared-harness build/test commands, from
`src\common\UITestAutomation.Next.UnitTests`:

```powershell
& "$root\tools\build\build.ps1" -Platform x64 -Configuration Debug -ExtraArgs @("/p:SolutionDir=$root\")
& "$root\tools\build\build.ps1" -Platform x64 -Configuration Release -ExtraArgs @("/p:SolutionDir=$root\")
# Both passed, exit 0, including analyzers.
& "$root\x64\Debug\tests\UITestAutomation.Next.UnitTests\net10.0-windows10.0.26100.0\UITestAutomation.Next.UnitTests.exe" --filter 'FullyQualifiedName~WinappCliTests|FullyQualifiedName~SessionTests' --report-trx --report-trx-filename ci-set-value-unit.trx --results-directory $evidence
& "$root\x64\Release\tests\UITestAutomation.Next.UnitTests\net10.0-windows10.0.26100.0\UITestAutomation.Next.UnitTests.exe" --filter 'FullyQualifiedName~WinappCliTests|FullyQualifiedName~SessionTests' --report-trx --report-trx-filename ci-set-value-unit-release.trx --results-directory $evidence
# Each passed: 19; failed/skipped: 0; exit 0.
```

**CI status:**
[391837](https://dev.azure.com/shine-oss/62769a65-d989-45e3-803c-9ad21fcf2ea2/_build/results?buildId=391837)
**succeeded** on current head `e0945376e6`, tested as merge `e27f537028`
with main `79ceeee01c`. SDK/x64/ARM64 builds passed, and **34/34
Workspaces UI tests passed on each of Windows 10 x64, Windows 11 x64,
and Windows 11 ARM64**, with zero failures or skips. Finished 2026-10-26
16:18:46 UTC.

The preceding
[391820](https://dev.azure.com/shine-oss/62769a65-d989-45e3-803c-9ad21fcf2ea2/_build/results?buildId=391820)
on `8ea5619586` passed product builds but had 29/34 UI tests pass on
each platform. All five failures were leading-dash textbox values
rejected by winapp 0.7.1; the shared helper was identical to main and
predates this PR. The setter fix resolves those failures without
changing Workspaces product code or weakening assertions. Fresh
High-parent/UAC, installer servicing and broader mixed-DPI validation
remain release gates.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 664ee900-ce2d-4112-ac57-395314d818dc
2026-10-27 11:29:49 +08:00
Boliang Zhang d6c59de74e fix(quick-accent): defer selection until the current list is ready (#51583)
<!--
HARD RULE: You (the human contributor) must write this PR description in
your own words.
AI tools and agents: Do NOT write the Summary, Detailed Description, or
Validation Steps sections.
Leave them for the human. You may put AI-generated text ONLY inside an
"AI-generated summary" <details> block at the bottom.
Maintainers will close PRs whose description they think was not written
by a human.
See
https://github.com/microsoft/PowerToys/blob/main/CONTRIBUTING.md#pull-request-descriptions-must-be-written-by-a-human
-->

<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request

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

- [ ] Closes: #xxx
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx

<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments

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

<details>
<summary>AI-generated summary</summary>

### Change

Fixes a Quick Accent crash when the initial arrow selection for a new
character list is applied to the retained list from the preceding
gesture. The source-level regression traces to #49633, which
deliberately stopped clearing the list on hide to prevent a blank first
frame.


`src\modules\poweraccent\PowerAccent.UI\PowerAccentXAML\MainWindow.xaml.cs`
now caches selection while the current list is not ready. After the
delayed display installs the current items, it applies the cached
selection. Live navigation remains immediate. Hiding/canceling resets
readiness; the existing generation checks and retained-content
first-frame protection remain in place.

No settings schema, native interface, localization, dependency or
installer changes.

### Reproduction observed before this fix

On installed `0.102.2933.0`, with start-from-left disabled and arrow
activation allowed:

1. Select Currency, hold S and press Right, then release.
2. Select French without restarting Quick Accent.
3. Hold E and press Right.

The module terminated with an unhandled native exception (`e06d7363`)
and `ucrtbase.dll` fatal exit (`0xc0000409`, offset `0xA527E`). Currency
S leaves two UI items; French E computes initial index 2 for its
five-item list before the delayed UI replacement. The same signature was
independently observed during manual reproduction.

### Added regression coverage


`src\modules\poweraccent\PowerAccent.UITests\PowerAccentEndToEndTests.cs`
adds:

- `ArrowActivationUsesNewCharacterListAfterLanguageChange`: Currency S
-> French E with Right; verifies selected and inserted character.
- `ArrowActivationUsesNewCharacterListAfterShortList`: French C -> E
with Left and Right as separate data rows; no module restart between
gestures.

### Validation completed

Worktree: `D:\PT-QA`. Commands ran in the installed Visual Studio 2022
x64 developer environment, selecting the existing .NET 10.0.100 SDK
through `DOTNET_MSBUILD_SDK_RESOLVER_CLI_DIR`,
`DOTNET_MSBUILD_SDK_RESOLVER_SDKS_DIR` and
`DOTNET_MSBUILD_SDK_RESOLVER_SDKS_VER`. The default VS 2026 Build Tools
installation lacks its .NET SDK resolver. This fallback emitted
`NETSDK1233` compatibility warnings; it is not a claim of a warning-free
VS 2026 build.

The shortened worktree has no source paths exceeding MAX_PATH.
`SkipLongPathsCheck` avoids changing the host's system-wide long-path
setting.

| Exact command | Result |
|---|---|
| `pwsh -NoProfile -File D:\PT-QA\tools\build\build.ps1 -Path
D:\PT-QA\src\modules\poweraccent\PowerAccent.UI -Platform x64
-Configuration Debug /restore /p:RestorePackagesConfig=true
/p:SolutionDir=D:\PT-QA\ /p:SkipLongPathsCheck=true /nr:false` | Passed,
exit 0; actual UI executable/DLL produced; 0 errors |
| `pwsh -NoProfile -File D:\PT-QA\tools\build\build.ps1 -Path
D:\PT-QA\src\modules\poweraccent\PowerAccent.UITests -Platform x64
-Configuration Debug /restore /p:RestorePackagesConfig=true
/p:SolutionDir=D:\PT-QA\ /p:SkipLongPathsCheck=true /nr:false` | Passed,
exit 0; regression test executable/DLL produced; 0 errors |
| `pwsh -NoProfile -File D:\PT-QA\tools\build\build.ps1 -Path
D:\PT-QA\src\modules\poweraccent\PowerAccent.Core.UnitTests -Platform
x64 -Configuration Debug /restore /p:RestorePackagesConfig=true
/p:SolutionDir=D:\PT-QA\ /p:SkipLongPathsCheck=true /nr:false` | Passed,
exit 0 |
|
`D:\PT-QA\x64\Debug\tests\PowerAccent.Core.UnitTests\PowerToys.PowerAccent.Core.UnitTests.exe
--report-trx --report-trx-filename core-tests.trx --results-directory
D:\PowerToys-qa-diagnostic-20261026\fix-build\core-test-results` |
Passed, exit 0; 35 executed, 35 passed, 0 skipped |
| `dotnet format whitespace D:\PT-QA --folder --include
src\modules\poweraccent\PowerAccent.UI\PowerAccentXAML\MainWindow.xaml.cs
src\modules\poweraccent\PowerAccent.UITests\PowerAccentEndToEndTests.cs
--verify-no-changes --verbosity quiet` | Passed, exit 0 |
| `git -C D:\PT-QA diff --check` | Passed |

### Local runtime verification completed

On 2026-10-26, the verification skill's Scenario B local-build path
exercised the exact candidate `78c027449e590341e1ebe155713e7686768d36cf`
and its unchanged main parent
`1c39ab3492e0e90c133500c1cb3848704fe6ce5c`. Only the local Quick Accent
module was launched; installed Runner/Settings and unrelated modules
remained in place, with no installation overlay.

| Exact command | Result |
|---|---|
| `pwsh -NoProfile -File D:\PT-QA\tools\build\build.ps1 -Path
D:\PT-QA\src\modules\poweraccent\PowerAccent.UI -Platform x64
-Configuration Release /restore /p:RestorePackagesConfig=true
/p:SolutionDir=D:\PT-QA\ /p:SkipLongPathsCheck=true /nr:false` | Passed,
exit 0; fixed Release output built |
| `pwsh -NoProfile -File D:\PT-QA-Base\tools\build\build.ps1 -Path
D:\PT-QA-Base\src\modules\poweraccent\PowerAccent.UI -Platform x64
-Configuration Release /restore /p:RestorePackagesConfig=true
/p:SolutionDir=D:\PT-QA-Base\ /p:SkipLongPathsCheck=true /nr:false` |
Passed, exit 0; unchanged parent Release output built |
| `& "$w\drivers\run.ps1"` from `D:\PT-QA`, with `$w` the recorded
`verify-QuickAccent-PR51583-20261026-release` workspace | Completed with
exit 0 and verified cleanup; fixed checks **5 PASS / 0 FAIL / 0
BLOCKED**, separate unfixed control **FAIL (product)** |

The driver used actual held-key input, scoped `winapp ui` captures, UIA
candidate/selection reads and exact text readback from an owned Latin
editor. It did not replace keyboard navigation with UIA selection.

| Fixed-build check | Result |
|---|---|
| Currency S+Right -> French E+Right, without restarting | PASS;
selected and inserted U+20AA then U+00EA |
| French C+Space -> E+Left, without restarting | PASS; U+00E7 then
U+00E8 |
| French C+Space -> E+Right, without restarting | PASS; U+00E7 then
U+00EA |
| Right/Left/Space/Shift+Space navigation, wrap and Unicode descriptions
| PASS; final selected U+00E9 inserted exactly once |
| Early release before a 1000-ms delay, no stale toolbar, then sustained
reactivation | PASS; ordinary base `e` retained after cancellation, then
U+00EA selected and inserted |

**Release red/green evidence:** the unfixed parent successfully inserted
the Currency warm-up, then crashed on French E+Right (`ucrtbase.dll`,
`0xc0000409`, offset `0xA527E`). The fixed Release process survived all
five checks. Exact running paths, loaded assembly identities,
timestamps, candidate images and original errors are retained in the
local archive.

Earlier Debug verification passed all five fixed checks, but its one
parent control also passed. That non-reproduction is retained; the final
differential evidence above is specifically **Release**, not a claim
that Debug reproduced the crash.

Cleanup restored original settings bytes, UsageInfo absence, enabled
preference, shipped module, Settings geometry/scroll, foreground and
pointer. Installed file hashes and all 16 pre-existing unrelated
PowerToys process identities matched; owned fixtures exited. No
clipboard operations were performed.

**Separate known finding:** documented exit-event cleanup can raise
`Application.Exit / coreclr.dll / 0xc0000005` in both the installed
build and local modules. It was recorded separately from this
selector-crash fix and was not silently fixed or counted as a selector
failure.

### Remaining validation boundaries

These are targeted local verification results, **not execution of the
MSTest UI-test project**, complete module sign-off or the Windows 10/11
default/constrained, ARM64 and UI-test CI matrix. The local VM root is
not configured; no VM provisioning or machine permission changes were
made. Exact first-visible-frame timing was not measured.

The first inconclusive driver attempt, repaired Debug run and final
Release comparison are all retained separately. Reports, scripts, raw
actions and hash manifests are under the local
`PowerToys\Module-Signoff\verify-QuickAccent-PR51583-20261026-local`
archive, with final Release evidence in `release\report.md`. No private
backups or media were uploaded to this PR. The human contributor still
needs to fill the visible description and review the template checklist.

</details>

Copilot-Session: f8993945-7828-4e7a-bb4d-e7f55ba992da
2026-10-27 03:25:28 +00:00
Boliang Zhang 08e9edb3d3 fix(release): reconcile preview deltas against full history (#50132)
## Summary of the Pull Request

Fixes preview release branch-transition deltas that incorrectly report
stable cherry-picks as removed when the matching PR exists before the
merge base in `main`.

The resolver now compares PR identities and equivalent patches against
each branch's full reachable history. It also excludes content-free
aggregate promotion merges, such as `main`-to-`stable` release merges,
from semantic release notes.

## PR Checklist

- [x] **Tests:** Added/updated and all pass
- [x] **Dev docs:** Added/updated
- [x] **New binaries:** N/A

## Detailed Description of the Pull Request / Additional comments

`get-preview-release-delta.ps1` previously built identity sets only from
commits after the merge base. A stable cherry-pick after that merge base
was therefore reported as removed even when the same PR had already
merged into `main` earlier with a different SHA.

The updated resolver:

- Collects PR identities from the full reachable history of both release
commits.
- Uses `git cherry` to recognize equivalent patches across the full
histories.
- Ignores merge commits with no independent patch when they only promote
a parent already contained by the opposite branch.
- Documents the full-history comparison in
`.github/skills/release-note-generation/references/preview-delta-resolution.md`.
- Adds regression coverage in
`.github/skills/release-note-generation/tests/preview-release.Tests.ps1`.

This was exercised against preview build `155850552`, where the
corrected delta changed from 11 added / 71 removed PRs to 11 added / 0
removed PRs. Of the false removals, 68 had the same PR identity in
`main`, and three were aggregate promotion merges.

## Validation Steps Performed

- `Invoke-Pester
.\.github\skills\release-note-generation\tests\preview-release.Tests.ps1
-EnableExit` - 26/26 passed.
- Recomputed build `155850552` against published stable `v0.101.2362.0`:
11 added, 0 removed, 0 unattributed commits.
- Ran the canonical preview dry-run verifier: PASS with 7/7 assets
verified.

---------

Copilot-Session: 5e9606ff-44ec-4d35-990e-a1fb2c0a10b1
Copilot-Session: 4953c1b4-3f0f-45b3-84a5-1d26d8800de1
2026-10-27 10:49:46 +08:00
Boliang Zhang b701ce788f [Release tooling] Standardize release tags and branch-specific titles (#51582)
<!--
HARD RULE: You (the human contributor) must write this PR description in
your own words.
AI tools and agents: Do NOT write the Summary, Detailed Description, or
Validation Steps sections.
Leave them for the human. You may put AI-generated text ONLY inside an
"AI-generated summary" <details> block at the bottom.
Maintainers will close PRs whose description they think was not written
by a human.
See
https://github.com/microsoft/PowerToys/blob/main/CONTRIBUTING.md#pull-request-descriptions-must-be-written-by-a-human
-->

<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request

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

- [ ] Closes: #xxx
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx

<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments

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

<details>
<summary>AI-generated summary</summary>

### Change

Update the Prepare Preview Release agent and release-note-generation
skill to derive GitHub tags from only the first three numeric components
of the official build version. For example, build `0.102.2991.0`
produces tag `v0.102.2991`, while installer filenames, GPO filenames,
artifact lookup and audit versions retain `0.102.2991.0`.

The original v0.100.2 updater rejects four-component GitHub release tags
and subsequently reports "up to date." A three-component tag remains
parseable by that updater. This PR prepares compatible release
identities; it does not publish a release or make prereleases visible to
the stable-channel latest-release endpoint.

- Generate the three-component tag in
`scripts/get-release-build-metadata.ps1` and use `context.tag`
throughout the documented workflow.
- Add an explicit `-ReleaseTag` option to
`scripts/prepare-release-assets.ps1`, so preview installer links target
the correct tag without renaming assets. Calls that omit it keep their
existing full-version URLs.
- Reject four-component and suffixed tags in draft creation and
verification, and reject asset-link tags that do not match the build
version.
- Preserve draft/prerelease-only behavior, immutable source-commit
checks, published-release protections, and historical four-component
baselines.
- Update the agent description, skill instructions, safety
documentation, and offline regression tests together.

### Release titles

Use the requested GitHub release type and immutable build source branch,
rather than the build's original intent/channel:

| Release type | Build source | Title |
| --- | --- | --- |
| Stable release | stable | `Release <tag>` |
| Prerelease | stable | `Release preview <tag>` |
| Prerelease | main | `Development preview <tag>` |

A shared title helper is used by generic draft creation, preview upsert,
and preview verification. Preview commands require `-SourceBranch`;
verification rejects a branch that conflicts with the build context. A
stable-intent build requested as a preview stays a draft prerelease with
a `Release preview` title. The preview workflow still cannot create a
stable release or publish anything.

### Validation

Executed from the new worktree using PowerShell and the existing Pester
3.4.0 installation:

```powershell
$env:GIT_CONFIG_COUNT = '1'
$env:GIT_CONFIG_KEY_0 = 'core.safecrlf'
$env:GIT_CONFIG_VALUE_0 = 'false'
Import-Module Pester -RequiredVersion 3.4.0
$result = Invoke-Pester -Script .\.github\skills\release-note-generation\tests\preview-release.Tests.ps1 -PassThru
if ($result.FailedCount -gt 0 -or $result.TotalCount -eq 0) { exit 1 }
```

**Passed: 34 tests, 0 failures, exit code 0.** The process-local Git
override lets the existing temporary-repository tests accept
PowerShell-generated CRLF fixtures without changing global Git settings.

New coverage verifies three-component metadata tags with unchanged
four-component versions, installer URLs for both architectures and
scopes, unchanged default URLs, draft-only operations with unchanged
asset names, and rejection of invalid tags. Asset-link tests use local
fixtures and mocked Azure CLI, HTTP hash responses, and Authenticode
results; they do not establish the signature validity of any real
candidate installer.

Title coverage exercises all three default titles through generic draft
creation, preview upsert and report generation for both branches, a
stable-intent build used as a preview, and missing, unsupported, or
conflicting source branches.

`git diff --check` **passed**. PowerShell AST parsing **passed for all
seven PowerShell files in the PR**, and skill description/body length
checks **passed**.

No product build, real installer upgrade, Azure build, or GitHub release
operation was performed. No product code, Store/WinGet publication, or
automatic release pipeline was changed.

The human author must fill in the template sections and checklist before
review.

</details>

---------

Copilot-Session: f0dee2a1-0a99-47cc-ac9e-9d9c8a3774f9
2026-10-27 10:49:14 +08:00
Mike Griese 415e04ebd3 CmdPal: Improve flexibility of our global hotkey handler (#51598)
Some updates to improve the flexibility of our global hotkey handler. 

prior art here: [Settings | Raycast
Manual](https://manual.raycast.com/settings#raycast-hotkey)

You'll need run `setx CMDPAL_ENABLE_WIN_HOTKEY 1` before launching this
build to see it.

Closes #43818
2026-10-26 20:34:11 +00:00
Mike Griese 20b0a65629 CmdPal: don't add extension name weight if we don't need it (#51588)
We were unconditionally adding the extension's name to every command's
weight. This meant that commands almost always outweighed apps. Oof.

Closes #51458
2026-10-26 14:41:10 -05:00
Mike Griese 79ceeee01c cmdpal: split TLVM into a subclass TopLevelFallbackViewModel (#51527)
Sensible refactoring ahead of fallbacksv2 support.

TLVM has a lot of gross code that's all like
`if(IsFallback) { doFallbackThing(); } else { doNormal(); }`. Well
that's OOP 101 folks. Don't do that.

This creates a proper TopLevel**Fallback**ViewModel class, which
inherits from TopLevelViewModel class. That way we can encapsulate all
the fallback code into one sensible class.

Derived from work in 7eab9b4b75...3c902c158e

Closes nothing, I work here
2026-10-26 05:29:45 -05:00
Gleb KhmyznikovandCopilot 1c39ab3492 [UI tests] Alt Windows new UI tests (#51552)
<!--
HARD RULE: You (the human contributor) must write this PR description in
your own words.
AI tools and agents: Do NOT write the Summary, Detailed Description, or
Validation Steps sections.
Leave them for the human. You may put AI-generated text ONLY inside an
"AI-generated summary" <details> block at the bottom.
Maintainers will close PRs whose description they think was not written
by a human.
See
https://github.com/microsoft/PowerToys/blob/main/CONTRIBUTING.md#pull-request-descriptions-must-be-written-by-a-human
-->

<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request

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

- [ ] Closes: #51548
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [x] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
- [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

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

<details>
<summary>AI-generated summary</summary>

### Implementation

Adds a greenfield `AltWindowCycle.UITests` suite using
`Microsoft.PowerToys.UITest.Next` for **Window Hopper**, the Settings
name of Alt Window Cycle. Addresses the sanity checks in #51548 without
changing product behavior.

The 13 cases cover:

- Same-application filtering with three separate same-image processes
and an interleaved different-image application.
- Forward and reverse cycling with one through four held-Alt key
presses, exact selected-window activation, and wraparound.
- Direction changes while the switcher is open; releasing Shift alone
must not commit the selection.
- Escape cancellation, subsequent activation, and the single-window
application case.
- Editing both shortcuts through the real Settings UI, using the new
Ctrl-based chords without restarting the Runner, and verifying the old
chords are unregistered.
- Disabling through Settings, verifying immediate module HWND
destruction and inactive shortcuts, then re-enabling and cycling again.

A small WinForms fixture supplies deterministic window titles and
distinct preview colors rather than depending on an installed
application's version or tab behavior. Tests inspect composed preview
pixels and actual foreground HWNDs because the GDI-painted switcher does
not expose a UIA card tree. They preserve module settings, release held
modifiers, clean up owned fixture processes, and remove abandoned
fixture processes before each test. The immutable different-image
fixture payload is copied once per class, while windows and processes
remain isolated per test.

Both projects are registered in `PowerToys.slnx`. The existing UI-test
pipeline now includes this suite in standard-user dispatch and
authenticated Runner/Settings companion signing, with positive and
negative Pester regression cases. The fixture and runner are test-only
binaries, not new product installer payloads. Developer documentation is
added at `doc/devdocs/modules/alt_window_cycle.md` and linked from the
module index.

### Main integration and warning policy

Merge commit `ba77aad6d0807b4874b8bb9be5e4922e29230d6b` includes
`main@e393ce2c23e5b29e6fc45fd01c5d3ecad8488023` and its stricter UI-test
warning policy. `AltWindowCycle.UITests`, `AltWindowCycle.TestApp`, and
their shared `UITestAutomation.Next` dependency already inherit
`TreatWarningsAsErrors=True`; none overrides it to `false`, adds blanket
project-local warning exclusions, or duplicates the shared
`GlobalSuppressions.cs` include. MSBuild evaluation confirmed nullable
analysis enabled, .NET analyzers enabled, and exactly one linked
global-suppression file for each project in all three configurations. No
additional suppressions were necessary.

Forced rebuilds from
`src\modules\AltWindowCycle\Tests\AltWindowCycle.UITests` each exited 0
with **0 warnings and 0 errors**:

```powershell
X:\Develop\PowerToys-alt-window\tools\build\build.cmd -Platform x64 -Configuration Debug -ExtraArgs '/t:Rebuild'
X:\Develop\PowerToys-alt-window\tools\build\build.cmd -Platform x64 -Configuration Release -ExtraArgs '/t:Rebuild'
X:\Develop\PowerToys-alt-window\tools\build\build.cmd -Platform ARM64 -Configuration Release -ExtraArgs '/t:Rebuild'
```

The merge does not change the AltWindowCycle test source, fixture,
shared test harness, or their root build/dependency properties. [Public
PR CI
391794](https://dev.azure.com/shine-oss/62769a65-d989-45e3-803c-9ad21fcf2ea2/_build/results?buildId=391794)
**succeeded** for this merge revision: x64 and ARM64 builds passed, all
13 PR checks passed, and the AltWindowCycle suite passed **39/39**
(13/13 on ARM64, Windows 10 x64, and Windows 11 x64), with no
non-passing selected UI results. The older validation details below
remain explicitly associated with the pre-merge revision.

### Claude Opus 5.5 review

Claude Opus 5.5 reviewed the initial revision using
`.claude/commands/review-pr.prompt.md`. All five findings were addressed
in `f3b39b03484bae099722404eb1b5d41726efed7c`:

| Finding | Resolution |
|---|---|
| Shift-release assertion could miss a premature commit | Select a
non-anchor window before releasing Shift; observe exact-HWND hide events
for one second; verify the same observer detects the later real
Alt-release commit |
| Aborted runs could leave same-image fixture processes in the cycle set
| Extend pre-test stale-process hygiene; explicitly validate with a
seeded, live standard-user fixture window before the full Windows 10
suite |
| Pipeline opt-ins lacked regression coverage | Add exact-suite and
lookalike-negative signing cases plus normal-user dispatch coverage |
| Developer documentation was not discoverable from its index | Add the
Window Hopper entry to the module documentation index |
| Each case copied the entire fixture payload | Cache the immutable copy
per class and remove it at class cleanup; verify one copied path across
all 13 cases and its absence afterward |

### Validation evidence

Previously validated suite source:
`f3b39b03484bae099722404eb1b5d41726efed7c` (the current merge revision
is documented above).

**CI:** [UI Test Automation 20261024.5 /
161586359](https://dev.azure.com/microsoft/Dart/_build/results?buildId=161586359),
pipeline 161438, attempt 2, `buildSource=buildNow`,
`uiTestModules=[AltWindowCycle.UITests]`, **succeeded** at the exact
reviewed-fix source above. Both full product builds succeeded, and
Runner/Settings companion signing was verified in all three test jobs.
The x64 build stage was retried once at the same SHA after an unrelated
Mouse Without Borders unit-test command timeout; no unrelated code was
changed.

| CI target | Result |
|---|---|
| Windows 10 x64 | 13/13 passed |
| Windows 11 x64 | 13/13 passed |
| Windows 11 ARM64 | 13/13 passed |

All **39/39** selected UI results passed; no selected tests were
skipped, inconclusive, or unexecuted.
The public [PowerToys PR CI run
391769](https://dev.azure.com/shine-oss/62769a65-d989-45e3-803c-9ad21fcf2ea2/_build/results?buildId=391769)
and every PR check for that pre-merge revision also succeeded.

**Local VMs:** the reviewed unfiltered Release suite passed on Windows
10 and Windows 11 under both Default (4 vCPU / 8 GB) and Constrained (1
vCPU / 4 GB): **52/52 passed**, with zero evidence-export errors. These
runs used a retained `0.0.1.0` runtime with the current-source
AltWindowCycle Release DLL and test-signed Runner/Settings companions;
CI rebuilds the full pushed source revision. One initial Windows 11
constrained run was interrupted by a OneDrive backup prompt taking
foreground. The PNG/MP4 evidence confirmed that desktop interference;
dismissing the prompt in the disposable guest restored the focused cases
and full suite without changing code or weakening assertions.

The successful build commands, run from
`src\modules\AltWindowCycle\Tests\AltWindowCycle.UITests`, were:

```powershell
X:\Develop\PowerToys-alt-window\tools\build\build.cmd -Platform x64 -Configuration Release
X:\Develop\PowerToys-alt-window\tools\build\build.cmd -Platform ARM64 -Configuration Release
```

Both exited 0. The x64 and ARM64 test and fixture apphosts were also
checked for the correct PE architecture.

The exact successful local suite invocations were:

```powershell
# Windows 10 Default: PASS, 13/13.
pwsh -NoProfile -File X:\Develop\PowerToys-alt-window\.github\skills\ui-tests-local-vm\scripts\Invoke-LocalVmUiTest.ps1 -VmName PowerToysUiTest-Win10 -VmRoot X:\PowerToysUiTestVm\Win10 -ExchangeRoot X:\PowerToysUiTestVm\Win10\shared\PowerToysUiTests\AltWindowCycle -TestExecutable AltWindowCycle.UITests.exe -ProductOverlayArchive product-overlay.zip -Platform x64Win10 -BuildLabel a32e3b6f6c-review-fixes -SuiteTimeout 15m -TimeoutMinutes 25 -ReuseStagedPayload

# Windows 11 Default: PASS, 13/13.
pwsh -NoProfile -File X:\Develop\PowerToys-alt-window\.github\skills\ui-tests-local-vm\scripts\Invoke-LocalVmUiTest.ps1 -VmName PowerToysUiTest-Win11 -VmRoot X:\PowerToysUiTestVm\Win11 -ExchangeRoot X:\PowerToysUiTestVm\Win11\shared\PowerToysUiTests\AltWindowCycle -TestExecutable AltWindowCycle.UITests.exe -ProductOverlayArchive product-overlay.zip -Platform x64Win11 -BuildLabel a32e3b6f6c-review-fixes -SuiteTimeout 15m -TimeoutMinutes 25 -ReuseStagedPayload

# Windows 10 Constrained, after stopping the guest: PASS, 13/13.
pwsh -NoProfile -File X:\Develop\PowerToys-alt-window\.github\skills\ui-tests-local-vm\scripts\Invoke-LocalVmUiTest.ps1 -VmName PowerToysUiTest-Win10 -VmRoot X:\PowerToysUiTestVm\Win10 -ConfigurationPath X:\PowerToysUiTestVm\Win10\vm.config.psd1 -ResourceProfile Constrained -ExchangeRoot X:\PowerToysUiTestVm\Win10\shared\PowerToysUiTests\AltWindowCycle -TestExecutable AltWindowCycle.UITests.exe -ProductOverlayArchive product-overlay.zip -Platform x64Win10 -BuildLabel a32e3b6f6c-review-fixes -SuiteTimeout 20m -TimeoutMinutes 30 -ReuseStagedPayload

# Windows 11 Constrained, after stopping the guest: PASS, 13/13.
pwsh -NoProfile -File X:\Develop\PowerToys-alt-window\.github\skills\ui-tests-local-vm\scripts\Invoke-LocalVmUiTest.ps1 -VmName PowerToysUiTest-Win11 -VmRoot X:\PowerToysUiTestVm\Win11 -ConfigurationPath X:\PowerToysUiTestVm\Win11\vm.config.psd1 -ResourceProfile Constrained -ExchangeRoot X:\PowerToysUiTestVm\Win11\shared\PowerToysUiTests\AltWindowCycle -TestExecutable AltWindowCycle.UITests.exe -ProductOverlayArchive product-overlay.zip -Platform x64Win11 -BuildLabel a32e3b6f6c-review-fixes -SuiteTimeout 20m -TimeoutMinutes 30 -ReuseStagedPayload
```

Additional checks, run from the worktree root:

```powershell
# PASS, exit 0.
pwsh -NoProfile -File .pipelines\verifyCommonProps.ps1 -sourceDir src\modules\AltWindowCycle\Tests

# PASS, exit 0.
dotnet format whitespace .\src\modules\AltWindowCycle\Tests\AltWindowCycle.UITests\AltWindowCycle.UITests.csproj --no-restore --verify-no-changes --include src\modules\AltWindowCycle\Tests\AltWindowCycle.UITests\AltWindowCycleTests.cs src\modules\AltWindowCycle\Tests\AltWindowCycle.UITests\WindowFixture.cs --verbosity quiet

# PASS, 135/135; zero failed or skipped.
Import-Module Pester -RequiredVersion 3.4.0
$result=Invoke-Pester -Script @('.pipelines\tests\uiTestSigningSelection.Tests.ps1','.pipelines\tests\runUiTestAsUser.Tests.ps1') -PassThru -Quiet
```

</details>

<img width="641" height="349" alt="image"
src="https://github.com/user-attachments/assets/6644dc5b-1bb6-4de1-a942-16fbb304edbc"
/>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-26 07:15:23 +01:00
007978a311 [UI Tests] ShortcutGuide: expand unit test coverage for search, converter, and models (#49953)
<!--
HARD RULE: You (the human contributor) must write this PR description in
your own words.
AI tools and agents: Do NOT write the Summary, Detailed Description, or
Validation Steps sections.
Leave them for the human. You may put AI-generated text ONLY inside an
"AI-generated summary" <details> block at the bottom.
Maintainers will close PRs whose description they think was not written
by a human.
See
https://github.com/microsoft/PowerToys/blob/main/CONTRIBUTING.md#pull-request-descriptions-must-be-written-by-a-human
-->

<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request

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

- [ ] Closes: #49813
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [x] **Tests:** Added/updated and all pass
- [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

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

<details>
<summary>AI-generated summary</summary>

### Scope

Expands Shortcut Guide's existing unit tests and adds a CI-validated
`ShortcutGuide.UITests` executable using the winappcli-based
`UITestAutomation.Next` framework. Addresses #49813.

The branch includes `main` through
`a5e83e5e2472647395c4f1fa455433a31cf0d4a1`. The review-fix and
CI-validated head is `3af1f472568cc4ab4b7ccdd6743b7e79b80932ba`.

### Unit-test coverage

- Search matching: null descriptions, empty shortcut collections,
alternative shortcut descriptions, special and composite key labels,
generic angle-bracket labels, and numeric arrow virtual-key codes.
- Key conversion: directional names, Backspace, numeric arrow codes, and
empty key/modifier combinations.
- Model contracts: equality, inequality, null operands, differing
shortcut content/modifiers, and hash-code consistency for
`ShortcutEntry` and `ShortcutDescription`.
- Enables nullable annotations in the new model-test files so they build
under the repository's warnings-as-errors policy.

### UI-test coverage and CI integration

The three tests cover:

1. Navigate through the collapsed System Tools group to Shortcut Guide
settings and read the actual activation shortcut from the shortcut
control.
2. Disable and re-enable through the Settings UI, verifying both toggle
state and the immediate listener-process lifecycle.
3. Activate the visible overlay with the configured shortcut, dismiss it
with Escape while preserving its listener, verify the shortcut is
suppressed while disabled, and activate again after re-enabling.

The tests handle the default `Win + Shift + /` chord on the explicitly
required en-US keyboard layout, distinguish visible overlay windows from
a persistent background process, and wait for a real host to remain
hidden before checking startup behavior. They wait for initialized
overlay content after activation and capture failures in derived MSTest
`[TestCleanup]` methods before restoring state or closing windows. They
do not bypass Settings IPC or replace lifecycle checks with
settings-file/restart fallbacks.

Registers the new test project in `PowerToys.slnx`, adds
`AutomationProperties.AutomationId="Toggle_ShortcutGuide"` to the
Settings switch, and opts `ShortcutGuide.UITests` into the existing
Runner/Settings companion-signing path for Release CI. Signing-selection
regression coverage includes all three CI platforms and rejects
similarly named unrelated projects. Developer documentation describes
the suite and lifecycle invariant.

The new executable is test-only; it is not a shipped module binary and
needs no installer or release-signing entry. No new third-party
dependencies or settings/IPC schema changes are introduced.

### Claude Opus review and follow-up

Claude Opus 5.5 reviewed all 14 PR files at
`fe69469fefcea6faf5baee4171a2f2b4958ad4a8` using
`.github\prompts\review-pr.prompt.md`. It found one medium and six low
actionable issues. All seven were addressed in
`3af1f472568cc4ab4b7ccdd6743b7e79b80932ba`:

- Move failure capture and state restoration from test bodies into
`[TestCleanup]`, where MSTest has set the outcome.
- Require an existing overlay host and a stable hidden interval instead
of passing before any window exists.
- Rename the angle-bracket search test to describe only the public
behavior it can observe.
- Compare entries containing separate, value-equal nested descriptions,
and add raw Back/Backspace alias coverage.
- Explicitly require and diagnose the prepared en-US keyboard layout
rather than claiming multi-layout support.
- Apply and verify the repository's XAML formatting.
- Document complete runtime, Release signing/trust cleanup, non-elevated
execution and the FTE-only CI boundary.

Also fixed the optional disappearing-window diagnostic race. A
temporary, deliberately failing local diagnostic build verified that the
original assertion survives and both the screenshot and recording
capture the visible overlay before cleanup. That temporary assertion was
removed before the final builds and complete green local matrix.

### Validation results

**Latest CI succeeded:** [UI Test Automation 20261024.4 / build
161586241](https://dev.azure.com/microsoft/Dart/_build/results?buildId=161586241),
attempt 2/3, pipeline `161438`, branch
`copilot/add-unittests-shortcut-guide`, source
`3af1f472568cc4ab4b7ccdd6743b7e79b80932ba`, `buildSource=buildNow`,
`uiTestModules=[ShortcutGuide.UITests]`, platforms `x64` and `arm64`.

| CI target | UI tests | Azure Test run |
|---|---:|---:|
| Windows 10 x64 | 3/3 passed | 1724447180 |
| Windows 11 x64 | 3/3 passed | 1724447630 |
| Windows ARM64 | 3/3 passed | 1724447467 |

Both full source product builds succeeded. All nine selected UI results
passed with no skipped or other non-passing outcomes, and both required
IPC companions were successfully signed and verified in every UI-test
job. The x64 and ARM64 infrastructure suites each passed 628/628. The
prior baseline build `161579647` also passed all nine selected UI tests
before review.

Local validation passed the full, unfiltered three-test suite in each of
these configurations, with no result-export errors:

| Guest | Default: 4 CPU / 8 GB | Constrained: 1 CPU / 4 GB |
|---|---:|---:|
| Windows 10 x64 | 3/3 passed | 3/3 passed |
| Windows 11 x64 | 3/3 passed | 3/3 passed |

Local runs used retained, standard-user VMs at 1920x1080, a hash-pinned
winappcli release, and current relevant-component Release builds over a
cached runtime. They are not a clean-profile or clean full-product-build
claim; CI built the pushed revision from source. Disposable signing
trust was removed and both VMs were stopped afterward.

<details>
<summary>Build and test commands</summary>

All commands below completed successfully:

```powershell
.\tools\build\build.cmd -Path src\modules\ShortcutGuide\Tests\ShortcutGuide.UITests -Platform x64 -Configuration Release
.\tools\build\build.cmd -Path src\modules\ShortcutGuide\Tests\ShortcutGuide.UITests -Platform ARM64 -Configuration Release
.\tools\build\build.cmd -Path src\modules\ShortcutGuide\ShortcutGuide.UnitTests -Platform x64 -Configuration Release /p:SolutionDir=C:\Develop\GitHub\PowerToys\
.\tools\build\build.cmd -Path src\modules\ShortcutGuide\ShortcutGuideModuleInterface -Platform x64 -Configuration Release
.\tools\build\build.cmd -Path src\settings-ui\Settings.UI -Platform x64 -Configuration Release
.\tools\build\build.cmd -Path src\runner -Platform x64 -Configuration Release
```

The current unit-test executable passed **115/115**:

```powershell
& .\x64\Release\tests\ShortcutGuide.UnitTests\ShortcutGuide.UnitTests.exe --report-trx --report-trx-filename shortcutguide-units.trx --results-directory $results
```

`$results` was the session-local evidence directory.

Signing-selection regression tests passed **53/53**:

```powershell
Invoke-Pester -Script .\.pipelines\tests\uiTestSigningSelection.Tests.ps1 -PassThru
```

The UI-test whitespace check passed:

```powershell
dotnet format whitespace .\src\modules\ShortcutGuide\Tests\ShortcutGuide.UITests\ShortcutGuide.UITests.csproj --no-restore --include src\modules\ShortcutGuide\Tests\ShortcutGuide.UITests\TestHelper.cs src\modules\ShortcutGuide\Tests\ShortcutGuide.UITests\ShortcutGuideActivationTests.cs src\modules\ShortcutGuide\Tests\ShortcutGuide.UITests\ShortcutGuideSettingsTests.cs --verify-no-changes --verbosity quiet
```

The Settings XAML format check passed:

```powershell
dotnet tool run xstyler -p -c src\Settings.XamlStyler -f src\settings-ui\Settings.UI\SettingsXAML\Views\ShortcutGuidePage.xaml
```

All four unfiltered local runs used `Invoke-LocalVmUiTest.ps1` with the
suite executable, the corresponding OS/platform and configuration, and
the recorded Default or Constrained resource profile. Each returned
**PASS, 3 executed, 3 passed, 0 failed, 0 not-executed**. The respective
guest was stopped before changing profiles. Full controller requests,
payload fingerprints, desktop probes and TRX are retained in the local
exchange.

`git diff --check` passed. No manual UI verification or clean-profile
confirmation is claimed.

</details>
</details>

<img width="711" height="353" alt="image"
src="https://github.com/user-attachments/assets/1b38ddf6-4dc5-40a5-90b3-4568995e4048"
/>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: noraa-junker <58633848+noraa-junker@users.noreply.github.com>
Co-authored-by: Gleb Khmyznikov <gleb.khmyznikov@gmail.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-26 13:08:30 +08:00
Clint Rutkas cfdb1d7af5 fix(FileLocksmith): stop abandoned handle-scan workers from using freed memory (#51507)
File lock smith crashes.
https://github.com/microsoft/PowerToys/issues/45158

We fixed one aspect of it in an earlier PR as we had the dmp from that
but could never repro it internally. Xeno provided an updated dmp and
validated this fix solves the issue.

<!-- 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: #45158
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [x] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx

<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments

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

<details>
<summary>AI-generated summary</summary>

**Root cause (confirmed from XenoPanther's 0.102.2933 dump):**
`NtdllExtensions::handles()` ran its loop on a detached `std::thread`
lambda capturing locals by reference. The stall watchdog called
`TerminateThread(offload_function.native_handle())` *after* `detach()`,
which leaves the handle null, so "hung" workers were never terminated.
They kept running after `handles()` returned and used its destroyed
stack (`object_info_buffer`, `result`, `pid_to_handle`, `info_ptr`,
`this`). In the dump, the crashing thread is a `thread_start` worker
right after `NtQueryObject`, reading `object_info_buffer` from the
caller thread's stack, while the caller has already moved on to
`processes()` → `process_modules`. This matches every reported fault
offset (memcpy from a freed source, indexed load from freed handle info)
and the CLI crashing after it has printed its results.

**Fix:** The scan runs on the calling thread again. Only the calls that
can block (`GetFileType`, `NtQueryObject(ObjectNameInformation)`) go to
a helper thread created with `CreateThread`. That helper uses no CRT and
touches only a ref-counted `HeapAlloc` block. When a query stalls, an
interlocked Busy/Done/Abandoned handshake hands handle ownership to the
helper. The helper then closes the handle, frees the block, and exits by
itself, so it stays safe even if it wakes during process shutdown. An
earlier `shared_ptr` version fixed the AV but deadlocked at `exit()`
when a stale worker ran STL destructors during CRT teardown.

**Validation**
- New `NtdllExtensionsTests` in `FileLocksmithCLIUnitTests`: finds a
file held by the test process, and survives repeated 1 ms stall timeouts
that force abandonment. All 8 tests pass (`vstest.console.exe
FileLocksmithCLI.UnitTests.dll /Platform:x64`).
- Interleaved A/B, 25 runs each, `FileLocksmithCLI.exe <empty dir>` on
an ARM64 machine: installed 0.102.2933 gave 4 AVs (0xC0000005) and 1
hang; this branch gave 0 AVs and 0 hangs.
- Built `FileLocksmithLibInterop` x64 Release (exit 0) and sideloaded it
into the installed UI; no AVs.

</details>
2026-10-26 03:53:05 +00:00
Clint Rutkas e393ce2c23 [UI Tests] Treat warnings as errors in module UI test projects (#51283)
## Summary of the Pull Request

Removes `<TreatWarningsAsErrors>false</TreatWarningsAsErrors>` from 26
module UI test projects so they follow the repo default (warnings are
errors), and updates the `ui-tests-migration` skill template and docs so
new UI test projects start strict.

Part of the split of #51088, now one PR per analyzer rule so each
pattern can be reviewed across all modules at once.

## PR Checklist

- [ ] Closes: #xxx
- [x] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **Tests:** Added/updated and all pass
- [x] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx

## Detailed Description of the Pull Request / Additional comments

**Merge this last.** It builds only after all of these rule PRs are
merged:

- #51257 SA1118 (Parameter must not span multiple lines)
- #51258 SA1518 (Use line endings correctly at end of file)
- #51259 SA1402/SA1649 (One type per file / file name must match first
type name)
- #51260 CA1305 (Specify IFormatProvider)
- #51261 CA1304 (Specify CultureInfo)
- #51262 SA1208 (System using directives must be placed before other
using directives)
- #51263 SA1512 (Single-line comments must not be followed by blank
line)
- #51264 SA1515 (Single-line comment must be preceded by blank line)
- #51265 SA1116/SA1117 (Split parameters must start on line after
declaration / parameters must be on same line or separate lines)
- #51266 SA1114 (Parameter list must follow declaration)
- #51267 SA1119 (Statement must not use unnecessary parentheses)
- #51268 SA1137 (Elements should have the same indentation)
- #51269 SA1516 (Elements must be separated by blank line)
- #51270 SA1214 (Readonly fields must appear before non-readonly fields)
- #51271 SA1313 (Parameter names must begin with lower-case letter)
- #51272 SA1507 (Code must not contain multiple blank lines in a row)
- #51273 SA1508 (Closing brace must not be preceded by blank line)
- #51274 CS8602 (Dereference of a possibly null reference)
- #51275 CS8604 (Possible null reference argument)
- #51276 CS8620 (Argument nullability mismatch)
- #51277 CA1716 (Identifiers should not match keywords)
- #51278 CA1826 (Use indexer instead of Enumerable method on indexable
collection)
- #51279 CA1861 (Avoid constant arrays as arguments)
- #51280 CA1869 (Cache and reuse JsonSerializerOptions)
- #51281 CA2219 (Do not raise exceptions in finally clauses)
- #51282 CS2002 (Source file specified multiple times)

Projects: AdvancedPaste, AlwaysOnTop, ColorPicker, CropAndLock (UITests
and TestApp), EnvironmentVariables, FancyZones, FancyZonesEditor,
FileLocksmith, Hosts, ImageResizer, KeyboardManager, LightSwitch,
MouseUtils, NewPlus, Peek, PowerAccent, PowerRename.Next, PreviewPane,
RegistryPreview, ScreenRuler, Settings, Workspaces (UITests.Next and
TestApp), ZoomIt.

## Validation Steps Performed

- Built all 26 projects plus the legacy `PowerRename.UITests` x64
Release on current `main` with this PR and every rule PR applied:
`MSBuild.exe <project>.csproj /restore /p:Platform=x64
/p:Configuration=Release` -> exit 0, 0 warnings, 0 errors for every
project.
- Earlier, as #51088, the same changes built x64 and ARM64 Release in
CI.
- On its own (without the rule PRs) this PR is expected to fail the
build; that is the point of merging it last.
- UI tests were not run locally.
2026-10-25 15:39:56 -07:00
a5e83e5e24 [UITests][MouseWithoutBorder] new UI tests (#51041)
<!-- 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

Add a maintained twelve-case Mouse Without Borders UI-test suite using
`Microsoft.PowerToys.UITest.Next` and official **winappcli v0.7.1**. It
runs two real MWB endpoints in a dedicated Windows test VM and its
run-owned Windows Sandbox, without using the development machine as a
peer.

Closes #40678

Address the [review
findings](https://github.com/microsoft/PowerToys/pull/51041#issuecomment-6228571883),
remove the temporary MWB diagnostics after verified green owner reruns,
and resolve the merge with `main`. Follow-up validation replaces the
unstable average-hash visual metric with full-image structural
comparison at the normal 95% threshold, and fixes Screen Ruler's
ambiguous app-name targeting with an exact toolbar HWND.

**Validation: current-source public CI succeeded.** The latest executed
platform jobs passed **279/279 active UI cases**, including **24/24
MWB**, plus exactly 15 approved quarantines. Both architecture
infrastructure gates passed **628/628** (1,256 executions). The shared
execution/cleanup flow, child-console output and failure-only diagnostic
publication are verified. The Windows 11 foreground failures were
reproduced and fixed by recognizing shell-cloaked windows without
extending the timeout. One unrelated native Windows 10 Sandbox startup
failure passed on an unchanged retry of only that job; its original
evidence is retained. Local outcomes and approved environment
limitations are recorded below. Full physical-device/module sign-off is
not claimed.

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

- [ ] Closes: none; partial automation toward #40678, not completion of
the module checklist
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [x] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [x] **Tests:** Added/updated and all pass
- [x] **Localization:** All end-user-facing strings can be localized
- [x] **Dev docs:** Added/updated
- [x] **New binaries:** Added on the required places; the new executable
and isolated MWB variant are test-only
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries - N/A: no new shipped binary
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder - N/A: no new installer payload
- [x] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects - registered in the v2 build/dispatch flow
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- N/A: no new shipped binary
- [ ] **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: N/A, developer/test documentation only

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

### Review corrections and runtime boundaries

- Exercise real Settings New key / Connect, acknowledged persistence,
bidirectional TCP transport, physical keyboard/mouse routing, clipboard
isolation/transfer, and failure recovery.
- Restore settings and clipboard ownership; stop only run-owned
processes and remove only owned provisioning resources.
- Shipping Release builds **ignore** hidden non-console opt-ins. Sandbox
validation uses an isolated `MwbUiTestBuild=true` Release variant with
test-only compilation and same-source metadata; shipping output is not
overwritten.
- Preserve service/System, secure-desktop, authentication, peer
verification, and existing policy restrictions. Companion signing
applies only to the private test cohort; private keys never enter
payloads.
- Derive MWB execution from module selection, without an independent
enable/disable checkbox. The owner-requested follow-up defaults
automation to `buildNow`. Implicit all-module official runs still skip
unsupported MWB with a warning; explicit unsupported MWB selection still
blocks.
- Gate costly MWB packaging on resolved affected modules, preserving
ordinary non-PR builds.
- Sequence immutable settings snapshots and reject stale writes after a
newer successful write, including retry/reordering tests. Reuse one
settings serializer.
- Bound Settings RPC responses to 15 seconds, release owned channels,
retain user input, and do not replay ambiguous commands. Use the shared
process-lifetime semaphore, localized assertive error announcements, and
two-second socket polling.
- Reuse Windows argument escaping for PS5.1 recovery children; expose
recording failures and document final-status timing.
- Replace reflection-based persistence fixtures with a deterministic
scheduler and update related documentation.
- Advanced Paste OCR acceptance activates the actual WinUI owner and
sends real Enter. Peek single-file visuals use isolated folders without
changing multi-file/pinning coverage.

### Shared UI execution and failure-only diagnostics

At the owner's request, `81433384f275d6211233a22a0ade171bbff1b4c8` folds
MWB into the existing **Run UI Tests** step, after the other selected
suites and inside its normal per-suite log group. Its specialized
executor retains isolated child processes, the original 12/15/103-minute
setup/prepare/run deadlines, standard-user MTP dispatch and strict
complete-suite TRX validation. Ordinary suite failures are aggregated
without suppressing MWB.

The always-running **Restore UI-test prerequisites** step independently
attempts MWB recovery, privileged cleanup, allowlisted diagnostic
collection and Light Switch restoration. The existing 6/5/2-minute MWB
cleanup/export bounds and 15-minute cancellation budget remain. Cleanup
failures cannot become successful runs.

The separate MWB step template and per-job selection artifacts are
removed. Selection, unsupported-source and ARM64 reasons remain explicit
in logs. Prerequisite diagnostics upload only for selected MWB execution
that is failed, canceled or incomplete, including failures before TRX
exists. This small sanitized artifact is published before potentially
lengthy test attachment uploads; raw protected logs and authentication
state remain excluded. Successful jobs retain the normal build artifacts
and test-result attachments, without additional selection/prerequisite
artifacts.

No product code, UI-test assertions, source-provenance checks, signing,
ownership or privilege boundaries changed. The new 31-case fixture suite
executes the real YAML scripts and isolated child-process dispatch
against inert phase fixtures, exercises mixed/MWB-only/unsupported/ARM64
paths, verifies environment isolation and owned timeout termination, and
proves cleanup continuation and failure-only publication. One obsolete
wiring-only contract was replaced by this behavioral coverage.

CI16 passed all tests and produced only the two normal build artifacts,
but inspection of the actual common execution log caught a remaining
regression: inherited child console handles did not forward MWB output
into Azure's PowerShell log. `82b322fa364b8907f36c55f70ac1ecb74d474c9b`
explicitly drains both redirected streams concurrently on the parent
runspace, retaining the phase deadline, owned process termination and
bounded output completion. Seven stdout/stderr assertions fail against
the CI16 helper and pass after the fix. An additional real-process test
writes a one-MiB unterminated prefix to each pipe before either newline,
proving both streams drain without deadlock. Final acceptance requires
the actual MWB full-suite sign-off to appear inside the common **Run UI
Tests** log, not merely a green pipeline status.

### Automatic MWB wiring follow-up

At the owner's request, `d15fe299ff` removes the separate
`mwbSandboxExperiment` parameter and its `ExplicitlyDisabled` selection
path. Manual x64 runtime preparation derives from the selected modules;
affected-PR preparation retains its exact resolved `hasMwbUiTests`
guard. MWB test steps remain runtime-gated by selection and platform,
with the same strict results, provenance, signing, recovery and cleanup
requirements.

The default is now **`buildNow`**. The build-source UI label states that
**`latestMainOfficialBuild` and `specificBuildId` do not support MWB**.
ARM64 skipping and implicit-versus-explicit official-source handling are
unchanged. Saved REST/queue requests must omit the removed parameter.

No product or UI-test code changed in this follow-up. Existing local
UI-suite evidence remains applicable; pipeline behavior was checked
with:

- **295/295 focused Pester contracts passed**, zero skipped.
- **Nine exact-source Azure YAML previews passed**: omitted-source
defaults with mixed modules, MWB only, unrelated modules and all
modules; slim; explicit/implicit official; explicit specific-build;
ARM64 only. The default resolves to `buildNow` without supplying an
override, and MWB preparation appears only for selected x64
current-source builds.
- The optional affected-PR inline-YAML override preview was denied
because it requires `EditBuild`. No permissions were bypassed. A normal
access preflight recheck passed; affected-PR wiring is covered by the
local contracts, not a live PR-triggered run.

Exact contract command, **PASS: 295 passed, 0 failed, 0 skipped**:

```powershell
Invoke-Pester -Script @(
  '.pipelines\tests\mwbUiTestSelection.Tests.ps1',
  '.pipelines\tests\mwbPilotResults.Tests.ps1',
  '.pipelines\tests\mwbSandboxCiPreparation.Tests.ps1',
  '.pipelines\tests\mwbSandboxClientSetup.Tests.ps1'
) -PassThru -Quiet
```

### Grouped scripts and enforced infrastructure tests

`c2eac99159` groups the seven remaining MWB pipeline scripts under
`.pipelines/mwb`, leaving the shared CLI helper at the pipeline root.
The separate 64-line TRX helper is consolidated into the MWB common
library; its token/literal stream and all result checks are unchanged.
YAML, local-controller, test and current documentation callers are
updated. Historical links pinned to old commits are preserved.

The protected client setup still uses its original flat directory,
identity and ACL model. It now stages only its three required scripts,
without the unused portable-CLI helper dependency. A real
isolated-staging subprocess test covers this layout.

Seven duplicate, obsolete or directory-layout-only tests were removed,
along with a comment-text assertion. Real UI binding/staging, signing,
ownership, recovery, failure-handling and redaction coverage remains.
Five tests exercise the actual new CI result guard, and an additional
case covers the isolated client payload.

Full builds with `buildTests=true` and UI-tests-only builds now execute
the fast MWB/shared CLI Pester suites before compilation and always
publish NUnit results. Empty, failed or skipped selected tests fail the
build. Pester 3.4.0 was already present on the CI agents; no framework
installation was needed.

- **596/596 fast tests passed locally**, zero skipped; the edited
shared-signing consumer separately passed **48/48**.
- Five normal Azure previews passed, checking the gate and publishers on
full, tests-only, unrelated-module, specific-build and ARM64 paths.
- Six native compiler integration cases remain available under the
explicit `NativeCompiler` tag and are excluded from the fast gate. They
are not deleted or counted as passing.
- CI12 correctly stopped both builds at **595/596** when the
large-output fixture exceeded its 30-second deadline. `15761bcc7b`
changes only the test producer to write directly to the redirected OS
streams, avoiding console-host text rendering. It retains the one-MiB
unterminated prefixes, over-five-MiB output per stream, completion
markers, exit code and the same 30-second limit. The production
provisioning wrapper is unchanged.
- CI13 passed both 596-case gates and all generic UI tests, but exposed
a missed shared-dispatcher path introduced by the grouping. `feb526baf0`
resolves one canonical parent-directory launcher for both Run and
Recover, preserving exact scheduled-task identity checks. Two dispatch
regressions failed before the fix and pass afterward; the final local
fast gate is **598/598**.
- CI14's x64 build exposed an existing lease-publisher unit race:
readers could observe a truncated, in-place status JSON update.
`edec893923` atomically replaces only the controller-local publisher
status, leaving mapped immutable lease generations, schemas, identities
and deadlines unchanged. A deterministic open-reader snapshot test fails
before the fix and passes afterward; all **6 publisher lifecycle
cases**, both architecture builds and the **598-case fast gate** pass
locally.

### Diagnostic rollback and merge

- `7d22de9d70` reverts only `d93fe7086f` and `51e82fb54f`; there is no
history rewrite. Its complete repository tree matched the verified green
`78ceb8c880` tree.
- The owner reruns of builds
[160920795](https://dev.azure.com/microsoft/Dart/_build/results?buildId=160920795)
and
[161000191](https://dev.azure.com/microsoft/Dart/_build/results?buildId=161000191)
were independently verified **Succeeded, 339/339 active passed each**.
- Merge `bed0eed863` incorporates `main` at `3d6827a53a`. Conflict
resolution preserves #51305 service-mode key protection and typed RPC
behavior alongside ordered persistence, timeouts, and accessible errors.
- Temporary Defender/runtime diagnostic collection is no longer in the
branch. No Defender settings, signature checks, ownership rules, or
recovery assertions were weakened.

### Visual comparison root fix

`aa19b7da58` replaces the `.Next` harness's coarse 64-bit average hash
with pixel-weighted local structural similarity (8x8 blocks, including
partial edge blocks and every pixel). RGB and alpha are checked
independently; image dimensions must match.

- Restore **95% for every Peek case**, including ARM64 PNG; remove the
former 93% exception.
- Keep all baseline images, capture geometry, and captured pixels
unchanged: no crop, border mask, resize, or baseline refresh.
- Exact production-method checks: actual CI7 image **98.898443%**;
removed PNG preview **91.561796%**; blank image **85.289191%**. The real
capture passes, both negative controls fail at 95%.
- **35 visual/capture-bound unit cases passed**; the legacy harness
remains unchanged. Remove the unused CoenM dependency without adding a
dependency.
- All **45 Peek cases passed in CI8**, across Windows 10, Windows 11 and
ARM64.

### Screen Ruler targeting root fix

CI8's Windows 10 failure had a visible toolbar but four
`PowerToys.MeasureToolUI` processes. A deterministic two-process local
reproduction proved that `winapp ui search ... -a
PowerToys.MeasureToolUI` fails with an ambiguous-process error; it was
not a missing toolbar or stale cached PID.

`bd8babb5d4` changes the test helper to discover the toolbar through
Win32 and pin its exact HWND. A new regression opens an additional real
ruler, invokes Close through the original session, and requires the
original process to exit while the additional toolbar remains visible.
UIA Invoke deliberately isolates target ownership from
foreground-dependent clicks on overlapping windows. The normal Bounds
case still performs a real 100x100 drag and verifies its clipboard
measurement. Lookup failures retain the actual error message.

### Deliberate exclusions

- The owner requested delivery in this existing PR. Optional PR
splitting and extracting linked pure test helpers into a core library
remain follow-ups. A direct test-project reference was not retained
because it produced `NETSDK1150`.
- No live ARM64 MWB/Sandbox sign-off; ARM64 builds and generic UI suites
are separate coverage.
- Five pre-existing Advanced Paste clipboard-history cases remain
quarantined with explicit owner approval. No clipboard-history sign-off
is claimed.
- Physical two-PC behavior, installed per-user/per-machine flows,
service/System, secure/locked desktops, and the remaining manual
checklist are not signed off.
- Human review and sanitized Settings evidence remain readiness work.
Recordings containing generated pairing keys stay private.

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

### Current-head cloaked-window correction and validation

Source: `bd3c8d38b5c8e6ca11fcb46f150923b1b2e2e9d0`.

The prior public failure was reproduced with the same hidden-launcher
behavior in a local Windows 11 VM: after twelve successful Start-menu
cycles, closing a receiver restored foreground to a
`Windows.UI.Core.CoreWindow` with **Win32 visibility still true but
`DWMWA_CLOAKED = 2` (shell-cloaked)**. That explains the absence of a
visible menu in the failure screenshots. A normal visible console masked
the problem by providing another foreground window.

The C# 5-compatible payload now queries DWM cloaking before classifying
the verified shell window as actionable. Cloaked windows receive no
Escape; DWM query failures are explicit errors. Exact OS
image/class/session/identity checks, modifier checks, the single-Escape
rule and the three-second dismissal deadline remain. The existing focus
test now also requires the dismissed menu to stop being classified as
actionable. No mouse/Alt shortcut, privilege bypass,
foreground-activation hack or weaker assertion was added.

The normal, automatically triggered [PowerToys CI_2610.23002 / build
391666](https://dev.azure.com/shine-oss/PowerToys/_build/results?buildId=391666)
tests PR merge `9d987064ecc45390d531e697e7398d71cd844d80`, with source
commit `bd3c8d38b5c8e6ca11fcb46f150923b1b2e2e9d0`: **Succeeded**,
finishing 2026-10-23 at 05:44:15 UTC. No additional internal UI Test
Automation run was manually queued.

| Current executed job | Attempt | Passed | Approved quarantines |
Published test run |
|---|---|---|---|---|
| Infrastructure, ARM64 | 1 | 628/628 | 0 | 936468 |
| Infrastructure, x64 | 1 | 628/628 | 0 | 936470 |
| UI, ARM64 | 1 | 85/85 | 5 | 936686 |
| UI, Windows 11 x64 | 1 | 97/97 | 5 | 936860 |
| UI, Windows 10 x64 | 2 | 97/97 | 5 | 936876 |

The Windows 11 job passed every MWB test on its first attempt, including
all five formerly failing foreground cases. Windows 10's first attempt
failed only `AbortedSandboxStartupRefusesUnownedInstance`: the inspected
recording shows the native Sandbox splash for the entire unchanged
three-minute deadline, with no viewer HWND or guest acknowledgement.
Only that failed Windows 10 job was retried, unchanged, through
`Build_x64` with `forceRetryAllJobs=false`; successful builds, ARM64 and
Windows 11 jobs were not rerun. The retry passed all 97 active cases.
The original failed test run 936862 remains historical evidence, not a
passing run.

All current jobs have one common **Run UI Tests**, one successful
**Restore UI-test prerequisites** and one shared result publisher. Both
x64 common execution logs contain the **12/12 MWB** sign-off. Diagnostic
publication is skipped by every successful current job. The build
retains the two normal build artifacts plus the **original** Windows 10
failure's diagnostic report; its unchanged artifact identity/size was
verified, and the successful retry did not upload another report.
Retaining that historical failure artifact is intentional. No selection
artifacts or separate MWB execution flow remain. No prior antivirus/PUA
error pattern appeared in the successful logs.

Local evidence uses the rebuilt test payload with the unchanged prepared
Release test runtime:

| Local validation | Result |
|---|---|
| UI-test project, Release x64 and ARM64 | Both builds passed |
| Complete fast infrastructure gate | 628/628 passed |
| Actual seven-case infrastructure suite, Windows 10 and Windows 11, 4
CPU / 8 GiB | 7/7 passed on each |
| Complete MWB suite, Windows 10, 8 CPU / 16 GiB | 12/12 passed |
| Complete MWB suite, Windows 10, 2 CPU / 8 GiB | 12/12 passed |
| Complete MWB suite, Windows 11, 8 CPU / 16 GiB | 11/12 passed; smoke
blocked by guest bootstrap before the changed receiver code executed |
| Actual infrastructure suite, Windows 11, 1 CPU / 4 GiB | 7/7 passed |

All five formerly failing foreground/recovery cases pass locally. The
Windows 11 smoke's first `LoadingReceiverTypes` bootstrap marker arrived
after the unchanged 35-minute readiness deadline; this is retained as a
startup limitation, not a passing test. No host-suspension overlap
occurred. The previously documented full nested-Sandbox constrained-host
exception remains; Windows 11 again lost host communication after its
successful seven-case constrained run. Exported results were preserved
before recovering that exact test VM.

Exact validation entry points:

```powershell
tools\build\build.cmd -Path src\modules\MouseWithoutBorders\MouseWithoutBorders.UITests -Platform x64 -Configuration Release
tools\build\build.cmd -Path src\modules\MouseWithoutBorders\MouseWithoutBorders.UITests -Platform arm64 -Configuration Release

$tests = @(Get-ChildItem .pipelines\tests\mwb*.Tests.ps1) +
    (Get-Item .pipelines\tests\winappCliRelease.Tests.ps1)
Invoke-Pester -Script $tests.FullName -ExcludeTag NativeCompiler -PassThru -Quiet
```

**Results:** both builds passed; 628/628 selected Pester cases passed.
The six opt-in compiler cases remain outside the fast gate. Real VM runs
used `Invoke-LocalVmUiTest.ps1` with `-Filter
'TestCategory=MwbInfrastructure'`, and `Invoke-AutonomousLocalVm.ps1`
without a filter for full suites, with the OS-specific configuration and
Default/Constrained profiles above. Every provisioning cleanup receipt
reports `Removed`. Both original non-elevated PTUser startup task
definitions/enabled states were restored from their preserved, validated
XML; both VMs are stopped at 4 CPU / 8 GiB.

### Previous shared-flow validation

Source: `82b322fa364b8907f36c55f70ac1ecb74d474c9b`.

- Internal [UI Test Automation 20261022.3 / build
161358211](https://dev.azure.com/microsoft/Dart/_build/results?buildId=161358211):
**Succeeded** at 2026-10-22 23:27:50 UTC. Both infrastructure gates
passed **628/628** (1,256 executions). Windows 10 passed **118/118**,
Windows 11 **118/118**, and ARM64 **106/106** active UI cases:
**342/342**, plus exactly 15 approved quarantines. This includes **24/24
MWB, 18/18 Ruler and 45/45 Peek** cases.
- Automatically triggered public [PowerToys CI_2610.22026 / build
391652](https://dev.azure.com/shine-oss/PowerToys/_build/results?buildId=391652):
**Failed**. Its PR merge revision is
`fd1ed3599f7a02e1216748fec0750cdc25d1295c`, with source commit
`82b322fa364b8907f36c55f70ac1ecb74d474c9b`. Both 628-case infrastructure
gates and both product builds passed. Its affected-project UI matrix
passed **97/97 Windows 10**, **85/85 ARM64**, and **92/97 Windows 11**
active cases: **274/279**, plus the same 15 approved quarantine records.
This is a different selected-module matrix from the internal run; its
totals are not combined with the internal 342.
- **Flow and artifact shape verified:** each platform has one common
execution step, one always-running prerequisite cleanup and one shared
result publisher. MWB console output and full-suite sign-off now appear
inside the common execution logs. The successful internal run publishes
only the two normal build artifacts. The public run likewise publishes
no selection artifacts; only its failed Windows 11 job adds the
**14,219-byte allowlisted UI-test diagnostic artifact**. Both successful
public jobs skip that publication. Cleanup succeeded on all three public
platforms; the failed Windows 11 recovery reported settings and
clipboard restored with an empty errors array.

The public Windows 11 failures all report **"The identified Start menu
did not release foreground after dismissal"**, in:

- `StartMenuDismissalDoesNotActOnAnOrdinaryForegroundWindow`
- `ReceiverInfrastructureRemainsResponsiveToUiAutomation`
- `DesktopAndWindowVideosSurviveAnEarlyFailure`
- `ControllerExitBeforePairingRestoresOriginalSettings`
- `KilledClipboardOwnerRequiresBaselineReset`

The ordered two-endpoint smoke and the other seven MWB cases passed on
that public worker. The foreground-recovery code had not been changed by
the wiring cleanup. Both available recovery screenshots were inspected:
they show the receiver without a visible Start menu. The failures happen
during input focus/bootstrap, before recording starts; the attached
recording manifests are empty. Agent logs also warn of 95.48% memory
usage, but this did not establish the cause. **No prior antivirus/PUA
error pattern was found.** Subsequent local reproduction identified the
shell-cloaking issue described above; the timeout was not extended.

All three additional authorized internal runs (15-17) were used. The
owner then requested autonomous continuation; the cloaking correction
uses normal PR-triggered CI rather than another manually queued internal
run.

Local validation:

- Complete enforced fast Pester gate: **628/628 passed**, zero
failed/skipped selected cases; the six opt-in `NativeCompiler` cases
remain outside this gate.
- `Invoke-Pester -Script
.pipelines\tests\uiTestSigningSelection.Tests.ps1,.pipelines\tests\configureLightSwitchLocation.Tests.ps1
-PassThru -Quiet`: **73/73 passed**, covering shared signing and Light
Switch behavior.
- The new pipeline fixture suite below passed **31/31 on each of four
guest runs**: Windows 10 and Windows 11, each at 4 CPU / 8 GiB and 1 CPU
/ 4 GiB. Both guests used PowerShell 7.6.4. These are pipeline
orchestration fixtures, not new full local product UI-suite runs. Both
VMs were stopped and their original 4 CPU / 8 GiB settings restored.

```powershell
$result = Invoke-Pester -Script "$env:FLOW_ROOT\.pipelines\tests\mwbUiTestFlow.Tests.ps1" `
  -PassThru -Quiet -OutputFormat NUnitXml -OutputFile "$env:FLOW_ROOT\$env:FLOW_LABEL.xml"
```

`FLOW_ROOT` is the guest-local staging directory and `FLOW_LABEL`
identifies its OS/resource profile. **Result: 124/124 fixture executions
passed.**

Eight normal exact-source Azure YAML previews passed: full mixed, MWB
only, unrelated suites, ARM64-only MWB, slim mixed, official unrelated,
official all and specific-build MWB. Every generated test job has one
common execution step, one always-running prerequisite cleanup, one
common result publisher and failure-only diagnostic publication. No
inline YAML override or permission workaround was used.

This follow-up uses CI16 and CI17, the remaining two of the owner's
additional authorized runs 15-17. No further internal queue is
authorized. The first public run, 391644, was automatically
superseded/canceled after the corrected source was pushed; it is not
counted as a passing validation.

### Previous validated consolidation head

[UI Test Automation 20261022.1 / build
161319902](https://dev.azure.com/microsoft/Dart/_build/results?buildId=161319902)
completed **Succeeded** on 2026-10-22 at 16:19:53 UTC, testing exact
source `edec8939230879c6cc6dabcbe9636423e7a4b3d1`.

| Gate / platform | Passed | Approved quarantines | Azure test run |
|---|---|---|---|
| Infrastructure, x64 build | 598/598 | 0 | 1722115765 |
| Infrastructure, ARM64 build | 598/598 | 0 | 1722115721 |
| UI, Windows 10 x64 | 118/118 | 5 | 1722208994 |
| UI, Windows 11 x64 | 118/118 | 5 | 1722213084 |
| UI, ARM64 | 106/106 | 5 | 1722190620 |

Infrastructure results are separate from the **342 active UI cases**.
Both product builds and both relocated MWB execution/recovery paths
passed; the UI totals include **24/24 MWB** cases. All 15 non-executed
UI records exactly match the owner-approved Advanced Paste quarantine
set. No selected infrastructure test was skipped or failed. Run
ownership was verified through the respective infrastructure and UI
publication logs.

The final MWB logs contain none of the prior virus/PUA, `0x800700E1`, or
Bearfoos errors. No signing, identity, lease-freshness, runtime
assertion or deadline was weakened.

The exact Pester invocation executed by both CI gates was:

```powershell
$result = Invoke-Pester -Script $tests.FullName -ExcludeTag NativeCompiler -PassThru -Quiet `
  -OutputFile "$(LogOutputDirectory)\pipeline-powershell-tests.xml" -OutputFormat NUnitXml
```

`$tests` contains the MWB test files and the shared CLI release test;
the Azure log-directory macro is expanded by the task. **Result: 598
passed, zero failed/skipped, for each build architecture.**

The selected matrix is `[MouseWithoutBorders.UITests,
ScreenRuler.UITests.Next, AdvancedPaste.UITests.Next, Peek.UITests.Next,
FancyZones.UITests.Next]`, x64/ARM64. **Neither `buildSource` nor the
removed MWB flag was supplied**: the run validates the real `buildNow`
default and automatic MWB selection. Caching, VS Preview and
latest-WebView2 overrides are disabled.

This was attempt 15 overall, the first of the three further
owner-authorized runs (15-17). No further run was needed for that
consolidation; the later owner-requested shared-flow follow-up uses CI16
above.

With the new Ruler regression, the expected active count is **342**:
Windows 10 **118**, Windows 11 **118**, ARM64 **106**, plus **15 exact
approved quarantine records** (five Advanced Paste cases per platform).

### Historical CI evidence retained

| Attempt | Build | Outcome |
|---|---|---|
| 1 |
[160877925](https://dev.azure.com/microsoft/Dart/_build/results?buildId=160877925)
| Peek PNG failures led to single-file fixture isolation. |
| 2 |
[160887683](https://dev.azure.com/microsoft/Dart/_build/results?buildId=160887683)
| 338/339 active passed; ARM64 PNG average hash 93.75%. |
| 3 |
[160916177](https://dev.azure.com/microsoft/Dart/_build/results?buildId=160916177)
| 338/339 active passed; Win10 native Sandbox startup failure. |
| 4 |
[160920795](https://dev.azure.com/microsoft/Dart/_build/results?buildId=160920795)
| Initial antivirus/native-startup failures retained; latest owner rerun
succeeded, 339/339. |
| 5 |
[160983500](https://dev.azure.com/microsoft/Dart/_build/results?buildId=160983500)
| 333/339 active passed; Defender access denial and Sandbox/recovery
failures. |
| 6 |
[161000191](https://dev.azure.com/microsoft/Dart/_build/results?buildId=161000191)
| Initial 337/339 antivirus-blocked result retained; latest owner rerun
succeeded, 339/339. |
| 7 |
[161106387](https://dev.azure.com/microsoft/Dart/_build/results?buildId=161106387)
| Merged source: 336/339; Win10 MWB antivirus failures and ARM64 PNG
hash 92.1875%. |
| 8 |
[161133682](https://dev.azure.com/microsoft/Dart/_build/results?buildId=161133682)
| Structural fix: all 45 Peek passed. 326/327 executed active passed;
Win10 Ruler Bounds failed and its subsequent 12 MWB cases did not run. |
| 9 |
[161155440](https://dev.azure.com/microsoft/Dart/_build/results?buildId=161155440)
| All 18 Ruler and 45 Peek passed. 340/342 active passed; Win10 MWB
cursor settling and Start-menu dismissal failed. All active cases
executed; no antivirus errors. |
| 10 |
[161197747](https://dev.azure.com/microsoft/Dart/_build/results?buildId=161197747)
| **Succeeded, 342/342 active passed** on unchanged source. All 15
non-executed records exactly match the approved quarantine set. |
| 11 |
[161232122](https://dev.azure.com/microsoft/Dart/_build/results?buildId=161232122)
| **Succeeded, 342/342 active passed** with default `buildNow` and
automatic MWB selection; neither control was supplied in the request. |
| 12 |
[161265853](https://dev.azure.com/microsoft/Dart/_build/results?buildId=161265853)
| New infrastructure gates blocked both builds at 595/596: the
large-output fixture exceeded 30 seconds. NUnit failures published; no
product compilation or UI tests ran. |
| 13 |
[161266859](https://dev.azure.com/microsoft/Dart/_build/results?buildId=161266859)
| Both 596-case gates and product builds passed. All 318 executed
generic UI cases passed, plus 15 quarantines; 24 MWB cases did not run
because of the missed dispatcher path. |
| 14 |
[161275806](https://dev.azure.com/microsoft/Dart/_build/results?buildId=161275806)
| Both 598-case gates passed. ARM64 product and 106 active UI cases
passed, plus 5 quarantines. The x64 build failed the lease-status unit
race; 236 x64 UI cases did not run. |
| 15 |
[161319902](https://dev.azure.com/microsoft/Dart/_build/results?buildId=161319902)
| **Succeeded:** 598/598 infrastructure cases on each build, both
products, and 342/342 active UI cases passed. |
| 16 |
[161344209](https://dev.azure.com/microsoft/Dart/_build/results?buildId=161344209)
| **Succeeded:** 627/627 infrastructure cases on each build and 342/342
active UI cases passed; only the two normal build artifacts were
published. Post-run log inspection nevertheless found missing MWB child
stdout/stderr, corrected before CI17. |
| 17 |
[161358211](https://dev.azure.com/microsoft/Dart/_build/results?buildId=161358211)
| **Succeeded:** 628/628 infrastructure cases on each build, 342/342
active UI cases and the exact common-step console/artifact checks
passed. The separate public PR run's Windows 11 foreground failures are
documented above. |

CI8's missing Win10 MWB coverage could not establish antivirus
resolution. CI9 executed the complete MWB suite on both Windows versions
with no antivirus errors; both previously antivirus-blocked recovery
cases passed. Its two separate Win10 input/focus failures are retained.

### Local, build and contract evidence

- Diagnostic rollback: x64/ARM64 MWB test builds, 83 Pester checks and
15 visual-threshold cases passed.
- Merge resolution: 183 MWB unit cases, 120 Settings MWB cases and 125
Pester contracts passed.
- Merged default generic suites: **105/105 on each OS**. MWB default **8
CPUs / 16 GiB: 12/12 on each OS**.
- Merged Win10 MWB pressure **2 CPUs / 8 GiB: 11/12**; native viewer
startup timed out before the injected aborted-startup boundary. This
remains the owner's accepted native-startup local exception, not a PASS.
- Structural Peek follow-up: **15/15 Win10 default, 15/15 Win11 default,
15/15 final Win10 constrained**. Earlier OneDrive/Explorer activation
failures are retained; unchanged repeats passed without changing OS
preferences or assertions.
- Earlier Win11 constrained guest hangs/lost control remain explicitly
accepted local blockers, not successful full generic pressure coverage.
- Ruler regression failed before the HWND fix with the exact CLI
ambiguity error, then passed. Final x64 and ARM64 test builds passed.
- Final Ruler closure: **6/6 on both OSes at default 4 CPUs / 8 GiB and
constrained 1 CPU / 4 GiB**, zero skips/errors/export failures. The
first final Win11 constrained run was 5/6 (Spacing clipboard empty); its
unchanged full repeat passed 6/6. This is preserved as an intermittent
pressure failure, not a claimed spacing root fix.
- Retain earlier Ruler pressure failures: empty spacing clipboard
results after toolbar/overlay readiness, plus the initial regression's
foreground-dependent physical Close. These were not relabeled PASS; the
final regression uses UIA Invoke.

The local product payload is the retained merged private runtime:
relevant merged MWB/Runner/Settings components were rebuilt; unchanged
generic modules reused repository outputs. This is **not a clean
full-product local build**. CI supplies fresh complete selected-platform
builds.

Exact final Ruler build commands, both **PASS (exit 0)**:

```powershell
Set-Location C:\Develop\GitHub\PowerToys\src\modules\MeasureTool\Tests\ScreenRuler.UITests.Next
& C:\Develop\GitHub\PowerToys\tools\build\build.cmd -Platform x64 -Configuration Release
& C:\Develop\GitHub\PowerToys\tools\build\build.cmd -Platform ARM64 -Configuration Release
```

Final local invocation (repository root; expanded once per OS/profile
below):

```powershell
$exchange = 'C:\PowerToysUiTestVm\shared\PowerToysUiTests\Merge51041'
& .\.github\skills\ui-tests-local-vm\scripts\Invoke-LocalVmUiTest.ps1 `
  -VmName $vm -VmRoot C:\PowerToysUiTestVm `
  -ConfigurationPath "$exchange\generic-$os.psd1" -ResourceProfile $profile `
  -ExchangeRoot $exchange -TestExecutable ScreenRuler.UITests.Next.exe `
  -TestsArchive ui-tests-ruler-final.zip -Platform $platform `
  -BuildLabel aa19b7da58-ruler-final -SuiteTimeout 25m -TimeoutMinutes 40 `
  -ReuseStagedPayload
```

| `$vm` / `$os` / `$platform` | `$profile` | Result | Run |
|---|---|---|---|
| `PowerToysUiTest-Win10` / `win10` / `x64Win10` | `Default` | PASS 6/6
| `localvm-20261021-025750-2a3848c0` |
| `PowerToysUiTest-Win11` / `win11` / `x64Win11` | `Default` | PASS 6/6
| `localvm-20261021-030354-63e48d2b` |
| `PowerToysUiTest-Win10` / `win10` / `x64Win10` | `Constrained` | PASS
6/6 | `localvm-20261021-030825-531b4cd9` |
| `PowerToysUiTest-Win11` / `win11` / `x64Win11` | `Constrained` | FAIL
5/6, Spacing clipboard empty | `localvm-20261021-031458-9df461e5` |
| Same Win11 constrained command, with `-BuildLabel
aa19b7da58-ruler-final-unchanged-repeat` only | `Constrained` | PASS 6/6
| `localvm-20261021-032537-7a36fe71` |

The labels identify the tested working diff subsequently committed as
`bd8babb5d4`; the product archive was unchanged.

Final Ruler test archive SHA-256:
`F683C57F298CC42CC6D958A9B17EC46C7D5C24B710A70C97DF2FE04FADCDB604`.

Both local VMs are stopped, restored to their original startup task
state and **4 CPUs / 8 GiB**, and have no task-owned test signing trust.
No host signing private keys were created for the Ruler follow-up; the
earlier marked keys were removed. Failed-run evidence and reusable
private payloads remain outside the repository.

---------

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: khmyznikov <6115884+khmyznikov@users.noreply.github.com>
2026-10-24 14:47:25 +02:00
Jiří Polášek 115665ec32 CmdPal: Improve ExtensionObject<T> contract and implementation (#51505)
## Summary of the Pull Request

This PR updates behavior and contract of ExtensionObject<T> class. The
major change is moving from away from (remote) object equality to proxy
identity. This might look like a problem, but it actually matches how we
treat them right now (see ListViewModel caching or DockBanViewModel).

- Compares wrappers by identity of the wrapped object instead of calling
its equality.
- Fixes equality on null, makes ExtensionObject<T>.Equal reflexive when
wrapping null.
- Adds XML doc to explain purpose and contract for toasters and meatbags
alike (and to make Zadjii happy, because I know how much he loves a good
prose).
- Adds HasValue property to simplify conditions; follow-up PRs will use
it.
- Seals the class, adds constraint for T as class, and implements
IEquatable.
2026-10-23 05:59:14 -05:00
Mike Griese f5f61ea984 Update contributor guidance to enforce human-only PR bodies (#51457)
I think we need to implement a hard rule that PR bodies should be
authored by a human and never by a robot. The point of a PR is not only
to contribute code and make modifications to the code base, but it is
also to convey the learnings from the contributor to the rest of the
maintainers. Important part of that process is being able to explain the
change in your own words. If a contributor can't explain the change in
their own words, then they don't understand what that change does to the
codebase. And if the contributor can't understand it, then what hope
would the maintainer have?

I think we need to implement this as a hard rule when merging PRs. It's
not something that we can try to detect or actually have an actual block
on PRs for. But we should block PRs with prejudice when we suspect that
the body was not authored by a human being. If you want to include the
AI generated body in the PR, I think we should allow that with the
caveat that the AI text MUST be in a details section.

This PR adds a pile of text to all our files that LLMs read to try to
enforce this. It removes some of the earlier tooling that would auto-
generate PR bodies for fixes.

To be clear: I'm not making any commentary on AI usage for code fixes
here, nor should we discuss that at this time. The **only** thing I want
to discuss here is AI usage in PR bodies.
2026-10-22 10:51:21 -05:00
Boliang ZhangandCopilot b9c2d3c1c5 fix(runner): unload modules before CRT teardown (#51433)
<!-- 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

Restore Hybrid CRT together with the Runner shutdown fix for the
tray-Quit process hang introduced by #50899. Without explicit early
cleanup, Runner's static module-map destruction can hold the shared UCRT
exit lock while waiting for a module worker that needs that same lock.

Main temporarily disabled Hybrid CRT through #51432. This PR now
reverses that rollback **in the same change as the shutdown fix**,
completing module shutdown before CRT teardown and before releasing
Runner's lifetime guards. The rollback reversal must not be merged
independently of the fix.

The original three commits were rebased onto main
`e7afd3fa439906a8e4ff4388a961511ca5cf81e7` without conflicts or patch
changes, followed by the exact revert of #51432. The combined fix was
validated at `d62d5e004e70a1f8a4eaca7f591fab8bf7eebd8f`; follow-ups
remove both `runner.md` changes and the manual shutdown-check script
from this PR without changing product code. Stable and the published
0.102 release are not changed.

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

- [ ] Closes: N/A; regression introduced by #50899, restoring Hybrid CRT
after the mitigation in #51432
<!-- - [ ] 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 — existing native tests and
prior manual shutdown checks passed; no new automated test is retained
in this PR, and broader restart/elevation/session-ending runtime
coverage remains incomplete
- [x] **Localization:** All end-user-facing strings can be localized —
no new end-user strings
- [x] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places — N/A, no new
shipping binaries
- [ ] [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: N/A; repository developer documentation only

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

- `src\runner\main.cpp`: a local cleanup guard cancels deferred Settings
startup, stops the centralized hook, revokes module hotkey callbacks,
and clears the module map before the settings-CLI and single-instance
guards are released. It covers ordinary exit and exception unwinding as
well as restart; the old restart-only clear is removed.
- `src\runner\centralized_hotkeys.cpp`: revoke every matching callback
and avoid trying to unregister window-owned hotkeys after their window
has been destroyed.
- Advanced Paste and PowerDisplay process-manager headers: declare the
executor last so its worker joins before the pipe/state accessed by its
tasks is destroyed.
- `Cpp.Build.props` and `doc\devdocs\development\guidelines.md`: exactly
revert `cf45de4118c22dbe80a2aa55c6ea0935ea7e2b3b` (#51432), restoring
the shared-UCRT default and its runtime guidance. Existing
project-specific CRT choices remain intact. The New+ and logger fixes
from #50899 are not reverted.

The commit order keeps the shutdown fix before Hybrid CRT is re-enabled.
Rebasing already reapplied the fix; it was not duplicated. The final
diff against the PR base contains six files. The Runner documentation,
new Runner verification profile, and manual shutdown-check script are
excluded.

Existing Windows session-ending skips for Settings and Quick Access are
unchanged. No settings schema, IPC contract, elevation policy, or
pipeline changes.

The initial diagnosis used matching PDBs on lingering installed
0.102.2883.0 processes and an isolated static/Hybrid CRT linkage
experiment. These support the root cause but do not replace runtime
validation.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-22 16:08:51 +08:00
Jiří Polášek cb0766ae5a Solution: Preserve LightSwitchService unit test project GUID in solution (#51402)
<!-- 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 updates SLNX to include correct project id used by
LightSwitchService.UnitTests.vcxproj.

The project entry in PowerToys.slnx was missing an explicit id, so the
solution parser generated a GUID different from the project's existing
ProjectGuid. Visual Studio then rewrote the vcxproj file, producing
unwanted Git changes whenever the solution was loaded.


https://github.com/microsoft/PowerToys/blob/ef43bf8ff5f3678f860a05227ea668825b967bf6/src/modules/LightSwitch/Tests/LightSwitchService.UnitTests/LightSwitchService.UnitTests.vcxproj#L7

- Sets the solution entry's Id to the existing ProjectGuid to keep both
identities consistent and prevent the automatic rewrite.

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

- [ ] Closes: #xxx
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx

<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
2026-10-22 13:17:53 +08:00
Clint Rutkas 3af8627f69 PRI249 fix to cleanup warnings. (#51476)
This should clean up 132 warnings per arch.
https://dev.azure.com/shine-oss/62769a65-d989-45e3-803c-9ad21fcf2ea2/_apis/build/builds/391265/logs/72
shows 132 for x64.

This pull request makes a targeted build configuration improvement for
the `ShortcutGuide.Ui` project. The main change ensures that manifest
files with a `.en-US.yml` suffix are treated as plain content files, not
as MRT (Multilingual Resource Toolkit) resources, preventing build tool
misinterpretation.

**Build configuration and asset handling:**

* Updated `ShortcutGuide.Ui.csproj` to explicitly include manifest files
with a `.en-US.yml` suffix as plain content, avoiding issues with
MakePri misreading them as resource qualifiers.
2026-10-22 12:58:54 +08:00
Mike Griese 48c4bad072 cmdpal: make sure Mike reviews things (#51469)
Couple minor updates given the shape of the team

* Update our CODEOWNERS so that I get assigned to all CmdPal PRs. Given
I'm the only one still allocated here, I want to make sure I have eyes
on everything trying to sneak in
* Move Jolley to "former" team members. Best of luck in your new role
dude!
2026-10-21 15:50:42 -05:00
Mike Griese 967b33a608 CmdPal: Safely handle invoking an extension that died (#51443)
This is an issue I noticed while debugging the dock with a dev build. If
I quit out of the dev build, then try to click on a dock item on my
stable build. If that item was from an extension, I would no longer be
able to run any commands in command palette at all.

Turns out the issue is much bigger than just dock items. It seems if we
tried to perform the command for any item from an extension that has
died, we would throw an exception outside of the try/catch in
`ShellViewModel::PerformCommand`. That would cause us to never release
the `_handleInvokeTask`, and we'd never be able to start invoking
another command.

Looks like the call to `command.Unsave.Name` got moved from inside the
try/catch to outside in #43905. Whoops.

While I was here, I thought it best that we remove this footgun.
PerformCommandMessage now carries around a `CommandViewModel` instead of
just an `ExtensionObject<ICommand>`, so that consumers can use the
cached name & Id rather than begging to use `.Unsafe` on it.

Closes: probably nothing, maybe something though?
2026-10-21 20:45:02 +02:00
Niels LauteandCopilot App e7afd3fa43 Update README for PowerToys 0.102 (#51396)
<!-- 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

Updates the README for the PowerToys 0.102 release by:

- Replacing the What's new banner with the 0.102 release artwork
- Updating the roadmap for v0.103: a new Awake flyout, Screen Ruler
improvements, and continued WinUI 3 modernization of utilities

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

- [ ] Closes: #xxx
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [x] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx

<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments

`doc/images/readme/Release-Banner.png` is replaced with the supplied
1200×252 PowerToys 0.102 artwork (same dimensions as the previous
banner). The roadmap now links to the [PowerToys 0.103
milestone](https://github.com/microsoft/PowerToys/milestone/47). The
utilities table is unchanged because the new Mouse Button Lock and
CursorHide utilities are part of Mouse Utilities.

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

- `Get-FileHash` comparison: the committed banner matches the supplied
image exactly (passed); dimensions confirmed at 1200×252
- `Invoke-WebRequest -Method Head
https://github.com/microsoft/PowerToys/milestone/47`: returned 200
(passed)
- `git diff --check`: no whitespace errors (passed)

Documentation and image-only change; automated tests are not applicable.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b1b02d2d-b163-46ea-972d-dc623debc895
2026-10-21 14:59:25 +02:00
Boliang ZhangandCopilot cf45de4118 fix(build): disable Hybrid CRT by default (#51432)
<!-- 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

Disable Hybrid CRT by default as a scoped rollback of the build-policy
change in #50899, mitigating Runner exit hangs involving the shared UCRT
exit-table lock.

`Cpp.Build.props` now defaults `EnableHybridCRT` to `false` when no
value is supplied. Native projects return to private static UCRT
linkage, while explicit opt-ins and independent project-level Hybrid CRT
linker settings remain supported.

The New+ locale/environment-variable changes and the logger
environment-variable fix from #50899 are intentionally retained. Only
`Cpp.Build.props` and the directly related runtime guidance in
`doc/devdocs/development/guidelines.md` change.

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

- [ ] Closes: N/A (partial rollback of #50899; no separate issue linked)
<!-- - [ ] 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. No new application unit
tests; native build and effective-linkage validation are listed below.
- [x] **Localization:** All end-user-facing strings can be localized
(N/A: no user-facing strings)
- [x] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places (N/A: no new
binaries)
- [ ] [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: N/A (developer guidance is updated in this PR; no user
documentation changes)

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

### Why restore private UCRT linkage?

Matching-symbol inspection of installed 0.102.2883.0 found Runner
performing static module destruction inside
`ucrtbase!execute_onexit_table`. In one confirmed wait cycle:

- The Runner main thread holds the CRT exit-table lock and joins the
PowerDisplay executor while destroying the module.
- The executor creates an ATL `CString` while sending the shutdown
message. Lazy static initialization calls
`atexit`/`register_onexit_function`, which needs the same shared CRT
lock.

Other captured remnants show related exit-table/loader waits involving
Light Switch listener cleanup and Mouse Highlighter DLL detach. Sharing
the UCRT makes these previously separate runtime locks shared across the
executable and module DLLs.

The reported working/failing boundary is 0.101.2362.0 to 0.102.2803.0.
Git ancestry confirms that the latter includes #50899 but does not yet
include #50897 or #51115. This is a build-policy mitigation, not a
rewrite of Runner shutdown sequencing.

### Scope and tradeoffs

- Preserve `/MT` and `/MTd`; disable the default `libucrt` exclusion and
shared-UCRT import-library selection by making their existing condition
false.
- Preserve `CalculatorEngineCommon`'s explicit opt-in, the Command
Palette Extensions SDK's independent Hybrid CRT linker configuration,
and existing project opt-outs.
- No CI/workflow/build-script override re-enables Hybrid CRT for Runner
or its affected native modules.
- Preserve the New+ and logger fixes, settings/IPC formats, and
installed-user state.
- Accept losing the default binary-size reduction until shutdown
lifetimes are made safe for a shared CRT. No current installer-size
measurement is claimed.

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

### Native builds: passed

The following commands were run in the isolated worktree. All completed
with exit code 0 after restoring the fresh worktree's missing native
packages.

```powershell
# PASS: native package restore.
& 'C:\Program Files\PowerShell\7\pwsh.exe' -NoProfile -File 'D:\PowerToys-hybrid-crt-rollback\tools\build\build.ps1' -Platform x64 -Configuration Release -Path 'D:\PowerToys-hybrid-crt-rollback\src\modules\powerdisplay\PowerDisplayModuleInterface' '/t:Restore' '/p:RestorePackagesConfig=true' '/p:SolutionDir=D:\PowerToys-hybrid-crt-rollback\' '/p:SkipLongPathsCheck=true'

# PASS: PowerDisplayModuleInterface and native dependencies; 0 errors, 0 warnings.
& 'C:\Program Files\PowerShell\7\pwsh.exe' -NoProfile -File 'D:\PowerToys-hybrid-crt-rollback\tools\build\build.ps1' -Platform x64 -Configuration Release -Path 'D:\PowerToys-hybrid-crt-rollback\src\modules\powerdisplay\PowerDisplayModuleInterface' '/p:SolutionDir=D:\PowerToys-hybrid-crt-rollback\' '/p:SkipLongPathsCheck=true'

# PASS: Runner and native dependencies; 0 errors, 1 host LIB-path warning.
& 'C:\Program Files\PowerShell\7\pwsh.exe' -NoProfile -File 'D:\PowerToys-hybrid-crt-rollback\tools\build\build.ps1' -Platform x64 -Configuration Release -Path 'D:\PowerToys-hybrid-crt-rollback\src\runner' '/restore' '/p:RestorePackagesConfig=true' '/p:SolutionDir=D:\PowerToys-hybrid-crt-rollback\' '/p:SkipLongPathsCheck=true'
```

The host has Windows long-path support disabled; the repository's
documented `SkipLongPathsCheck` override was used for these scoped
native builds without changing machine policy. Runner's warning was
CS1668 for a nonexistent Visual Studio `LIB` search directory, not a
source warning introduced by this change.

### Effective compiler/linker configuration: 25 cases passed

A local-only MSBuild diagnostic target imported the original
`Cpp.Build.targets`, added a non-built `Link` probe item to obtain
evaluated item-definition metadata, and returned `EnableHybridCRT`, the
actual `ClCompile.RuntimeLibrary` values,
`Link.IgnoreSpecificDefaultLibraries`, and `Link.AdditionalOptions`.

For each project/configuration/platform row, the command was:

```powershell
# PASS for all 24 matrix rows; $probe is the local ReportCrtLinkage.targets file.
& $msbuild $project /nologo /v:q /t:ReportCrtLinkage /getTargetResult:ReportCrtLinkage "/p:Platform=$platform" "/p:Configuration=$configuration" '/p:SolutionDir=D:\PowerToys-hybrid-crt-rollback\' "/p:ForceImportAfterCppTargets=$probe" /p:SkipLongPathsCheck=true

# PASS: additional Runner x64 Release positive control, using the same command with:
# /p:EnableHybridCRT=true
```

| Projects | Configurations | Platforms | Result |
|---|---|---|---|
| Runner, PowerDisplayModuleInterface, LightSwitchModuleInterface,
MouseHighlighter | Debug, Release | x64, ARM64 | Private UCRT; `/MTd` or
`/MT`; no shared-UCRT linker overrides |
| CalculatorEngineCommon | Debug, Release | x64, ARM64 | Explicit Hybrid
CRT opt-in retained |
| Command Palette Extensions SDK | Debug, Release | x64, ARM64 |
Independent Hybrid CRT linker configuration retained |
| Runner with explicit `EnableHybridCRT=true` | Release | x64 | Opt-in
still selects the shared UCRT |

The four affected native projects and the positive control were
evaluated with VS 2026 MSBuild. The two unchanged UWP opt-in projects
were evaluated with installed VS 2022 MSBuild because the VS 2026 Build
Tools installation lacks the UWP XAML targets. These are configuration
evaluations, not ARM64 build/runtime passes.

### Rebuilt binary imports: passed

```powershell
# PASS: both dumpbin commands exited 0.
& $dumpbin /nologo /imports 'D:\PowerToys-hybrid-crt-rollback\x64\Release\PowerToys.exe'
& $dumpbin /nologo /imports 'D:\PowerToys-hybrid-crt-rollback\x64\Release\PowerToys.PowerDisplayModuleInterface.dll'
```

Both rebuilt binaries have no `api-ms-win-crt-*`, `ucrtbase.dll`, or
`ucrtbased.dll` imports. This checks the resulting linkage, not only the
property value.

`git diff --check` also passed.

Not claimed: application unit/UI test execution, a full installer or
ARM64 build, or a post-change installed-product shutdown/restart A/B.
The installed PowerToys binaries and existing hung-process evidence were
not replaced or terminated.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: cf21252c-f253-42f2-a45c-3146c2481127
2026-10-21 11:28:38 +08:00
Gordon LamandCopilot 10e819a6b2 fix(settings-ui): prevent Welcome navigation and close crashes (#51437)
<!-- 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

Fix two Welcome lifecycle failures: navigating away from the intro with
animations disabled could crash Welcome, and closing Welcome could
trigger an exception in the shared Settings process. Keep both
corrections scoped to Welcome.

No visual appearance, layout, style, asset or string change is intended.

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

- [ ] Closes: N/A — reported directly; no linked issue.
<!-- - [ ] 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 — no automated lifecycle
test added; candidate runtime validation and existing related tests are
listed below.
- [x] **Localization:** All end-user-facing strings can be localized —
no strings changed.
- [ ] **Dev docs:** Added/updated — N/A.
- [ ] **New binaries:** Added on the required places — N/A; no binaries
added.
- [ ] [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: 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

-
`src/settings-ui/Settings.UI/SettingsXAML/Controls/WelcomeHero/WelcomeHero.xaml.cs`:
initialize reveal targets' Translation in `OnLoaded`, before the
static/animated playback branch and asset loading. Both animation and
cleanup consume that initialized state instead of enabling it
themselves. The page configures all targets before Loaded; the
collection contract now documents that ordering.
- `src/settings-ui/Settings.UI/SettingsXAML/OobeWindow.xaml.cs` and
`OobeWindow.xaml`: set the existing icon once during live initialization
and remove the icon-only activation subscription. This avoids looking up
an AppWindow from a late activation after Welcome has closed.

These are view-layer lifecycle responsibilities: composition visuals
stay in the control and the native window icon stays in live window
initialization. No new view-model dependency, tracking state, flags,
catches, theme/navigation changes, dependencies, settings schema
changes, or unrelated window fixes.

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

Windows x64 Debug candidate, built in an isolated worktree. Commands
below use repository-root-relative paths rather than machine-specific
paths.

**Builds**

```powershell
tools\build\build-essentials.cmd -Platform x64 -Configuration Debug

$repo = (git rev-parse --show-toplevel)
pwsh -NoProfile -File tools\build\build.ps1 -Platform x64 -Configuration Debug -Path "$repo\src\settings-ui\Settings.UI" "/p:SolutionDir=$repo\"
```

Essentials build: **exit 0**. After the initialization-ownership
follow-up, the final Settings build completed with **exit 0**, **zero
warnings/errors**, in **2m18.67s**, with an explicit 1800-second
timeout. The runtime checks below used that rebuilt candidate.

**Candidate runtime validation**

**Recorded candidate demo (40 seconds, reduced motion)**

Real candidate at `1ce948463f7ee45f2b079a5e13f1db41bf9b5def`: open
Welcome, navigate to Advanced Paste, close Welcome, navigate Settings
Home → General, reopen Welcome and close it again. The cropped app-only
recording keeps Settings visible after both closes. It was captured with
`winapp ui record` while native UI Automation drove the candidate; no
recreated UI. Only capture borders were cropped, with no cuts or speed
changes. No audio.


https://github.com/user-attachments/assets/6945a117-d917-42e7-b81c-66ece5786cde

Capture command (the HWND belongs to the candidate Settings window):

```powershell
winapp ui record -w <Settings-HWND> --capture-screen --duration-sec 40 --fps 10 --max-edge 1600 --frames -o welcome-lifecycle-public.mp4
```

Recording and action driver: **exit 0**. The uploaded H.264 MP4 is
950×708 after privacy cropping. All distinct capture frames and
representative frames extracted from the final video were inspected
before upload. The animation preference was not changed.

From the candidate output directory, with its matching PDBs:

```powershell
winapp run . --exe PowerToys.Settings.exe --debug-output --symbols --unregister-on-exit
```

The unpackaged output required a temporary development manifest in the
build output:

```powershell
winapp manifest generate . --package-name PowerToysWelcomeCrashDiag20261020 --publisher-name CN=PowerToysWelcomeCrashDiag --executable .\PowerToys.Settings.exe --description "Temporary Welcome crash diagnostics"
```

| Check | Result |
|---|---|
| Animations disabled: navigate Welcome to Advanced Paste, then close
Welcome | PASS; fresh candidate process; Settings survived |
| Animations disabled: independently open Welcome and close it without
navigating, with Settings visible | PASS; separate fresh candidate
process; Settings survived |
| Animations enabled: navigate Welcome to Advanced Paste, then close
Welcome | PASS; fresh candidate process; Settings survived |
| Animations enabled: independently open Welcome and close it without
navigating, with Settings visible | PASS; separate fresh candidate
process; Settings survived |
| Reopen Welcome after closing it, then close it again | PASS in all
four completed runs |
| Navigate Settings to General after closing Welcome; verify actual page
content | PASS in all four completed runs |

All four fresh candidate runs used both requested debugger flags and
matching PDBs; each UI driver exited **0**. Complete captured debugger
logs contained no new matching Translation/icon, unhandled-exception or
crash signatures. This is not a claim of zero generic first-chance CLR
events. The animation preference and candidate-written shared version
metadata were restored afterward.

After assertions, owned candidate processes were deliberately terminated
for bounded cleanup. Their debugger exit `-1` reflects that cleanup,
**not a crash**. The temporary development package was explicitly
unregistered (exit 0).

**Existing related tests**

The Settings unit-test project was built successfully, then:

```powershell
& 'C:\Program Files\Microsoft Visual Studio\18\Enterprise\Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe' `
  '.\Debug\x64\tests\SettingsTests\net10.0-windows10.0.26100.0\Settings.UI.UnitTests.dll' `
  /Platform:x64 `
  '/TestCaseFilter:FullyQualifiedName~WelcomeHeroLayoutTests|FullyQualifiedName~WelcomeHeroWarpTests' `
  '/Logger:trx;LogFileName=welcome-hero-focused.trx'
```

**28/28 passed, exit 0.** These cover related layout/warp behavior and
were run during the Translation-fix stage; they are not lifecycle
regression tests. The focused lifecycle proof is the actual
final-candidate UI flow above. No source-text assertion test was
retained, and no new runtime-test infrastructure was introduced for this
small fix.

`git diff --check` also passed. Remote CI and maintainer review are
separate from this local validation; no CI-completion claim is made.
Only the newly captured sanitized demo is uploaded; private diagnostic
logs, dumps and earlier screenshots remain local.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7f3af42f-9cdd-4046-a665-c12b9d6c1aff
2026-10-21 11:26:26 +08:00
Yu LengandYu Leng 3d6827a53a [BugReportTool] Fix report generation while PowerToys is running (#51427)
## Summary of the Pull Request

Generating a bug report while PowerToys is running fails with `Failed to
copy PowerToys folder` because the Runner holds `settings.json.cli-lock`
exclusively. Exclude that root synchronization file before copying
settings so report generation can proceed. This fixes the regression
introduced by #50507.

## PR Checklist

- [ ] Closes: No linked issue.
- [ ] **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: Not applicable.

Validation is manual; no automated test additions are included in this
PR. There are no new user-facing strings, development documentation,
binaries, packaging changes, or external documentation changes.

## Detailed Description of the Pull Request / Additional comments

In `tools/BugReportTool/BugReportTool/Main.cpp`, create the report
directory and copy each settings-root entry recursively, skipping
`settings.json.cli-lock` with a case-insensitive filename comparison.
The file is excluded before any copy attempts to open it. Other
diagnostic files and nested directories are preserved, and unrelated
copy errors retain the existing failure path.

## Validation Steps Performed

- Built `BugReportTool` in Release x64 using the repository build
wrapper: exit code 0 for commit
`27489cd9746830a3a196074bf47409b47a2f6242`.
- On local Windows, ran the installed `0.102.2883.0` report tool and
then the PR executable against real PowerToys user data while the same
installed Runner held the root CLI lock exclusively throughout. Each
child used separate temporary and output directories; installed binaries
were untouched. The baseline exited naturally with code 1, `Failed to
copy PowerToys folder`, and no ZIP.
- The PR executable exited naturally with code 0 and generated a
919,234-byte ZIP containing 641 entries. Verified parseable settings
JSON, 43 nonempty nested Runner logs, nonempty GPO/Windows/monitor
reports, and exclusion of the root `settings.json.cli-lock`. The full
run took about 97 minutes because registry collection was slow on this
host.
- CI run 391437 passed all 10 checks. Release x64 and ARM64 builds
completed with 0 errors and 0 warnings. The existing x64 native suite
reported 11,066 passed, 21 skipped, and 0 failed; ARM64 tests were
skipped.

---------

Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com>
2026-10-21 01:08:56 +08:00
Muyuan LiandCopilot bce86ab181 [Settings] Fix What's New caption and Markdown code contrast (#51431)
## Summary of the Pull Request

Fix unreadable caption-button glyphs and Markdown code in the separate
**What's New** window when the PowerToys theme differs from Windows'
default app mode.

With Windows Dark and PowerToys Light, minimize/maximize/close glyphs
and inline-code text can be almost white on a light surface. The caption
issue is a regression; the Markdown code-brush gap predates it.

This is a targeted follow-up to #48910 and #49786, **not a revert of the
shared native title-bar implementation**.

## Before / after screenshots

Both captures use **Windows Dark + PowerToys Light** and display the
same April 2026 release notes. The displayed v0.99.1 is the notes'
version, not the executable's version.

### Before: installed v0.102.2911.0

The minimize/maximize/close glyphs are almost invisible against the
light title bar. Inline-code examples such as `DockSettings`,
`settings.json`, `G`, and `Win` also have nearly white text on a pale
background.

![Before the fix: nearly invisible caption buttons and inline-code text
with Windows Dark and PowerToys
Light](https://github.com/user-attachments/assets/9a5fca87-f3ba-46bb-be5d-d2c509492596)

### After: patched local x64 Debug Settings

Caption glyphs and inline-code text are readable, while the existing
heading/link styling is retained.

![After the fix: readable caption buttons and inline-code text with the
same Windows Dark and PowerToys Light
configuration](https://github.com/user-attachments/assets/1cd6bdc4-fa64-472e-aed5-6108289cc783)

## PR Checklist

- **Related work:** #48910, #49786; no existing issue is closed by this
PR.
- [ ] **Communication:** Separate contributor agreement has not been
established; this follows the previously identified theme-override
concern linked below.
- [x] **Tests:** Added a repeatable UI regression-capture script;
existing focused Settings tests pass. Screenshot review remains manual,
not an automated contrast assertion.
- [x] **Localization:** No new user-facing strings.
- **Dev docs / product documentation / new binaries:** Not applicable;
no new dependencies, settings fields, IPC contracts, or installer
entries.

## Detailed Description of the Pull Request / Additional comments

### Caption buttons: follow the window, not Windows' default app mode

`TitleBarTheme.UseDefaultAppMode` follows Windows' default app mode.
Settings applies its own Light/Dark preference to the window content, so
these can disagree.

- Add an explicit-theme overload to
`src/common/Common.UI.Controls/Window/TitleBarHelper.cs`. Preserve the
original one-argument API, its Windows-default behavior, and the
supported-platform guard.
- In `src/settings-ui/Settings.UI/SettingsXAML/ScoobeWindow.xaml.cs`,
apply the initial content theme after `InitializeComponent`, then set
native `TitleBarTheme.Light`/`Dark` from the root's resolved
`ActualTheme`.
- Track live `ActualThemeChanged` events and unsubscribe when the window
closes.

This retains #49786's shared helper and native caption rendering rather
than restoring manually assigned caption-button colors. Other
windows/modules keep their existing one-argument behavior; this PR does
not broaden the change to OOBE or Shortcut Conflict.

### Markdown: extend the existing element-theme workaround to code

The pinned Markdown control captures brushes from application resources
rather than the selected element theme. The existing workaround corrects
headings and links, but not inline/fenced-code foreground, background,
or border brushes.

In `ScoobeReleaseNotesPage.xaml` / `.xaml.cs`:

- Resolve code-surface brushes through a collapsed, noninteractive,
theme-aware provider, following the existing link-provider pattern.
- Apply the element-themed primary foreground and code background/border
to both inline-code and fenced-code theme properties.
- Retain heading/link handling and the existing re-render path on theme
changes.

No hardcoded palette or dependency upgrade is introduced. The workaround
still points to the pending upstream fix,
[CommunityToolkit/Labs-Windows#785](https://github.com/CommunityToolkit/Labs-Windows/pull/785).

### Investigation timeline

| Date (UTC) | Change / inspected release | Relevance |
|---|---|---|
| April 29, 2026 | v0.99.1 | Inspected source already has the Markdown
code-brush problem; the old code-rendering issue is not explained by the
later caption regression. |
| June 29, 2026 | #48910, merged 18:33:41 | Corrected What's New
headings/links and tracked the actual window theme for caption colors.
It did not correct code brushes. |
| August 25, 2026 | v0.101.2362.0 | Contains the June caption handling,
before its September replacement. This explains correct caption icons
but unreadable code in the older comparison build. |
| September 2, 2026 | #49786, merged 14:58:31 | Adopted the shared
native `UseDefaultAppMode` helper and explicitly removed the SCOOBE
caption handling as redundant. This lost the app-specific theme
override. |
| September 21, 2026 | v0.101.2632.0 | Already contains the September
replacement: the caption regression predates the October candidate. |
| October 16 / 19, 2026 | v0.102.2883.0 / v0.102.2911.0 | Both contain
the replacement; the reported mixed-theme symptoms were reproduced on
installed 2911. |

#49786's consolidation and native theme-change fixes were intentional.
Its history does not establish an intent to drop PowerToys' independent
theme preference. An [inline discussion posted at 15:00:33 UTC, about
two minutes after
merge](https://github.com/microsoft/PowerToys/pull/49786#discussion_r3915503538),
already identifies that `UseDefaultAppMode` does not follow
`RequestedTheme` and recommends tracking `ActualTheme`.

Release containment above comes from source/tag inspection, not a
runtime bisect of every listed installer. The April version displayed
inside What's New is release-note content, not the installed
executable's version.

## Validation Steps Performed

- Built the release-targeted x64 Debug candidate with
`tools\build\build-essentials.ps1`, including runner and Settings; no
replacement of the installed PowerToys binaries.
- Built the Settings unit-test project and ran `ScoobeReleaseTests` plus
`ViewModelTests.General` with `vstest.console.exe`: **18 passed, 0
failed**.
- Visually checked the same What's New window with Windows Dark while
selecting PowerToys **Light -> Dark -> Windows default -> Light**.
Caption glyphs, headings, links, and April's inline-code examples
(`DockSettings`, `settings.json`, `G`, `Win`) remain readable.
- The reporter also inspected the patched window and confirmed it looks
correct.
- Restored the original PowerToys Light setting after the capture.
- Ported the identical four production files onto current `main`,
avoiding unrelated stable-branch history.
- Repeated `build-essentials.ps1 -Platform x64 -Configuration Debug` on
the actual main-based PR branch: solution restore, runner and Settings
all succeeded with zero MSBuild errors/warnings.
- Rebuilt the Settings test project on that branch and repeated the same
focused test run: **18 passed, 0 failed**.

The checked-in `src\settings-ui\Settings.UITests\Test-WhatsNewTheme.ps1`
repeats that live-switch capture, checks that the same notes window
survives, verifies the selected theme, restores the original app theme,
and writes PNGs plus a JSON receipt. It requires an explicitly selected
Settings PID and checks its executable identity. Run from the checkout
after opening General and a separate What's New window containing code:

```powershell
.\src\settings-ui\Settings.UITests\Test-WhatsNewTheme.ps1 -AppPid <settings-process-id>
```

The script uses English UI labels and winapp CLI. Its default executable
is the checkout's x64 Debug build; use `-ExpectedExecutable` when
deliberately comparing a different build. Review the PNGs manually; a
successful capture is **not** a visual PASS.

### Remaining manual coverage

- Windows Light + PowerToys Dark, and high-contrast transitions.
- Caption hover, inactive, and maximized states.
- Actual fenced-code rendering: the corresponding renderer properties
compile and its implementation was inspected, but no retained
fenced-code fixture was found in the fetched stable notes after
installer-hash sections were removed.

These are explicitly unverified, not claimed as passing. No full
release/module verification is claimed.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b53a83e5-69a1-4b97-a4c6-378bdf88657a
2026-10-20 18:34:00 +08:00
Gordon LamandCopilot 5c9fddcddd Enhance key storage (#51305)
<!-- 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

Enhances Mouse Without Borders service-mode key storage. Elevated
Settings manages service-mode pairing changes, service-mode keys are
encrypted at rest, and the service decrypts them for use. Existing
service-mode installations receive guidance to generate or replace an
incompatible pairing key.

Administrator Settings can display and copy the current service-mode
pairing key, including after reopening the page.

**UX change:** Switching between service mode and normal mode requires
re-entering the pairing key. You can reuse the key from another paired
computer, or generate a new key and enter it on the other computers.

The original MWB UI remains available in its worker process, including
service mode, and its key changes use the same encrypted service-mode
storage.

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

- [ ] Closes: None
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [x] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [x] **Tests:** Added/updated and all pass
- [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: Not applicable

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

### Architecture

This diagram summarizes code relationships, not runtime validation.

```mermaid
flowchart LR
    INPUT["EXISTING: Generate or enter a key"]
    KEY["UPDATED: Existing MyKey property<br/>Encrypt on set; decrypt on get"]
    JSON["EXISTING: settings.json<br/>Existing save/load"]
    CODEC["NEW: IPairingKeyCodec"]
    DPAPI["NEW: DPAPI implementation<br/>Service mode"]
    PASS["NEW: Passthrough implementation<br/>Normal mode"]
    RUNTIME["EXISTING: MWB runtime"]
    BASE["NEW: PairingKeyCodec base<br/>Module-owned prefix and version"]
    UI["UPDATED: MWB UI / ViewModel<br/>Display, controls and guidance"]
    RPC["UPDATED: Existing Settings request handler<br/>Administrator service-key access"]

    INPUT --> KEY
    KEY <-->|"Stored string"| JSON
    KEY <-->|"Value conversion"| CODEC
    CODEC --> DPAPI
    CODEC --> PASS
    DPAPI --> BASE
    PASS --> BASE
    KEY -->|"Plaintext pairing key"| RUNTIME
    UI -.->|"Format recognition only"| BASE
    UI -->|"Current-key read"| RPC
    RUNTIME -->|"Current pairing key"| RPC
    RPC -->|"Authorized response"| UI
```

| Layer | Change | Main files |
|---|---|---|
| Key conversion | **New** interface, shared format-owning base, and two
implementations: `Encrypt`, `Decrypt`, `IsEncrypted` |
`IPairingKeyCodec.cs`, `PairingKeyCodec.cs`, `DpapiPairingKeyCodec.cs`,
`PassthroughPairingKeyCodec.cs` |
| Key property | **Updated** existing getter/setter; `Settings` receives
`IPairingKeyCodec` through its constructor | `Setting.cs` |
| Original UI | **Updated** forms read `PairingKeyDisplayText`; runtime
consumers continue to read `MyKey` | Existing MWB Settings and forms |
| UI decisions | **Updated** controls, current-key display and localized
guidance directly in the existing view model/page | Existing MWB view
model and page |
| Current-key access | **Updated** existing request handler supplies the
active pairing key to administrator Settings | `Program.cs`, existing
Settings request contract |
| Shared transport ownership | **Moved** the existing generic IPC
channel out of the clipboard-specific file, without changing its
behavior | `IpcChannel.cs`, existing helper project source link |
| Generation and persistence | **Existing** key generation, JSON
property and save/load paths retained | No credential manager, separate
store or notification framework |
| Upgrade / mode transition | **Explicit re-pairing**, not automatic
conversion: generate or replace an incompatible key; service-mode
changes use elevated Settings | Existing page with setup guidance |

The existing service host and network protocol are retained.
Service-mode transitions wait for the previous worker to exit and verify
the replacement. The passthrough implementation returns its input
unchanged; an incompatible saved representation requires explicit
pairing setup.

Ordinary callers continue to assign and read `settings.MyKey`; they do
not handle encoded values or choose an implementation.

Settings UI source-links only the module-owned codec base and interface
for format recognition. No new project, assembly or package is
introduced.

Pairing controls use a local pending flag to prevent duplicate clicks.

Connection text-box inputs remain owned by the page and are passed as
request arguments, without additional ViewModel input copies. They are
cleared after successful connection, on page exit, and when service mode
changes.

The existing pairing requests return the generated key or an error to
Settings. Current-key reads use the same request boundary.

Key conversion completes before changing runtime or machine state. The
existing best-effort save contract is unchanged. Normal-mode key
conversion remains unchanged; administrator Settings loads the current
service-mode key when the page opens and when settings refresh.

Each Settings request uses its own verified pipe. Pairing requests have
bounded waits, repeated file notifications are coalesced, and page entry
reloads settings before reading the current key. Service-mode transition
failures use localized feedback.

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

Automated checks passed: **154 MWB tests** with one pre-existing skip,
and **516 Settings tests** with no failures or skips.

<details>
<summary>Automated test commands and results</summary>

- `MouseWithoutBorders.UnitTests.exe --timeout 5m --no-progress
--report-trx --report-trx-filename fork-startup-final-mwb.trx`: passed;
one pre-existing skip.
- `Settings.UI.UnitTests.exe --timeout 5m --no-progress --report-trx
--report-trx-filename fork-startup-final-ui.trx`: passed.

</details>

Automated coverage includes key conversion and persistence, local IPC
ownership/reconnection, pairing presentation, mode-switch ordering and
failure handling, and ViewModel state. Source/XAML contracts cover page
wiring; these are not substitutes for live UI or two-computer testing.

### Manual validation (author-reported)

- **Completed:** elevated/non-elevated Settings and service-mode on/off
combinations on two physical computers, including worker replacement and
completing pairing by entering or generating a key.
- **Completed:** administrator Settings displays/copies the current
service-mode key after leaving and reopening the page; non-elevated
Settings masks the key and prevents service-mode key changes.
- **Completed:** two-computer mouse sharing and reconnection after
restarts and desktop switches, checking actual input sharing rather than
only the green device indicator.
- **Upgrade observation:** after upgrading, a new pairing key needs to
be generated again.

Development testing also exercised connection refreshes, re-entering the
same shared key, enabling service mode on either computer, and the
original MWB tray UI. These combinations helped identify the issues
addressed during iteration.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: bc5794a9-436f-4202-8522-134926c08a5a
2026-10-20 11:14:24 +08:00
Mike Griese ef43bf8ff5 CmdPal: Add a new dedicated dock flyout (#51092)
_Targets https://github.com/microsoft/PowerToys/pull/51091_
Part 4 of the dock flyout refactor, for
https://github.com/microsoft/PowerToys/issues/45861
Closes #45861
<img width="628" height="663" alt="image"
src="https://github.com/user-attachments/assets/d2e6a828-86a9-4ccc-a28c-097dde204a50"
/>
<img width="583" height="413" alt="image"
src="https://github.com/user-attachments/assets/93b094fd-ed02-4609-b358-795a5831b5d4"
/>


Lots of new controls, but kind of a lot of the same stuff we already do
in ShellViewModel.

Admittedly, brought over the finish line with AI. I started this
refactor back when the Dock first shipped, but it was still too far from
shipping to work. AI created the flyout control which was a lot better
than the original "just use our context menu control" which was kinda
terrible. And also just generally splitting the humongous refactor into
bits that could be reviewed more easily
2026-10-19 13:46:44 +02:00
Clint Rutkas 1b33221dfa [UI Tests] Let Calculator settle before verifying foreground in KBM tests (#51373)
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
Fixes the flaky `KeyboardManager.Remapping.AltF4Target` failure
"Calculator did not own foreground after launch." It failed on arm64 in
CI build 391265 (#51283).

A screen recording of the run shows Calculator flashing at startup. The
test took the first window titled "Calculator", and on Win11 it accepted
any window class. If that first window was a short-lived startup window,
its handle never became the foreground window, so the focus wait timed
out.

<!-- 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
This only changes the test helper `CalculatorInputWindow.cs`:
- After Calculator's window first appears, the helper waits 1 s for
startup to settle. It then looks the window up again, choosing only a
visible (uncloaked) Calculator window, and verifies foreground with a 5
s timeout.
- It tries this up to 3 times. Each try waits 1 s and looks the window
up again.
- The failure message now includes the number of tries, the Calculator
HWND and window class, and `WindowControl.GetForegroundWindowInfo()`,
the same style as the Notepad fix in #51345.
- `ClassName` now uses `FirstOrDefault`, so a window that disappears no
longer throws an unhelpful `InvalidOperationException`.

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
- `MSBuild KeyboardManager.UITests.csproj /restore /p:Platform=x64
/p:Configuration=Release`: exit 0, 0 warnings, 0 errors.
- I didn't run the UI tests locally. This PR touches
`src/modules/keyboardmanager`, so CI selects and runs the Keyboard
Manager UI tests automatically.
2026-10-19 13:46:31 +08:00
Niels Laute fbff588b2c Welcome hero: subtle Fluent hover, fix parallax top gap, soften intro streaks (#51367)
<!-- 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

Polish for the new OOBE "Welcome to PowerToys" hero animation (#50873):

1. **Hover highlight**: replaces the rainbow/brand-gradient stroke on
tool tiles with a subtle Fluent-style hover: a faint fill plus a 1px
neutral stroke on the tile edge. In high contrast it uses
`SystemColorHighlight` with a 2px stroke.
2. **Parallax top gap**: the aurora dome could slide down during pointer
parallax and impact shake, leaving a gap between the blue background and
the top edge of the hero. The dome now extends 24px above the hero
(`DomeBleed`), so that gap no longer appears.
3. **Intro streaks**: the light trails that shoot out during the intro
had hard, rectangular edges. They now use a `CompositionMaskBrush` with
a radial falloff mask, so they have soft edges and a tapered tail.

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

Changes are limited to
`src/settings-ui/Settings.UI/SettingsXAML/Controls/WelcomeHero/`:

- `WelcomeHeroPalette.cs`: `Color[] Highlight` is replaced by
`HighlightFill`, `HighlightStroke` and `HighlightStrokeThickness` for
Dark, Light and HighContrast.
- `WelcomeHeroScene.cs`:
- The highlight shape reuses the tile's glass geometry and sits beneath
the icon. Ghost tiles have no highlight, and `SetHighlightedTile` is
null-safe.
  - Theme changes animate the highlight fill and stroke colors.
- `DomeBleed` offsets the dome and its center, and the intro dawn center
accounts for it.
- A new shared radial `_trailMask` masks the trail gradients.
`CreateTrailBrush` still returns the stops so theme updates keep
working.

No new strings, binaries or settings.

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

- `tools\build\build.ps1 -Platform x64 -Configuration Debug` in
`src\settings-ui\Settings.UI`: passed (exit code 0, empty errors log).
- Manual: ran the Debug Settings build, opened **Welcome to PowerToys**,
watched the intro streaks, hovered over the tiles, and moved the pointer
to trigger the parallax. No automated tests cover this animation.

Copilot-Session: 16eac730-9023-44c4-8d02-358ace31b45c
2026-10-19 11:12:20 +08:00
Clint Rutkas 88a197d891 [UI Tests] Park cursor off taskbar during ZoomIt tray wait (Win10 News feed) (#51395)
<!-- 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

UI-test-only fix for a Windows 10 flake in
`ZoomIt.UITests.ZoomItTests.ShowTrayIconSettingRemovesAndRestoresShellIcon`.
The tray-icon wait now parks the cursor at (screen width / 4, screen
height / 2) before waiting and right after each overflow-chevron click,
so the cursor never rests on a taskbar hover target. Follows #51344 and
unblocks #51283.

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

- [ ] Closes: #xxx
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [x] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **Tests:** Added/updated and all pass
- [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

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

**Failure:** PowerToys CI build 391328 for #51283 (which already
includes #51344) failed only on the x64 **Windows 10** job:

> Expected one ZoomIt notification icon in the taskbar or opened
overflow. Last mismatch: found 1 icon at (1783, 1020), but that point is
not hit-testable in the taskbar or overflow. Consecutive matches: 0/3.

**Root cause (from the Shell tree dump and failure screenshot):**
- The Win10 `NotifyIconOverflowWindow` was open and the ZoomIt button
was inside it, but `WindowFromPoint` returned another window.
- The screenshot shows the Windows 10 **News and Interests** feed open
over the right side of the screen, covering the overflow. The cursor was
on the right edge of the taskbar weather button.
- `MouseHelper.LeftClickAt` moves the real cursor (`SetCursorPos`) to
the chevron. After the click, the notification area shrank, the weather
button slid under the parked cursor, and the hover feed stayed open for
the rest of the 30s wait.

**Fix:**
- `WaitForTrayIcon` parks the cursor at (width/4, height/2) at start.
Before this change it used the screen center, which is inside the feed's
area.
- It parks the cursor again right after each chevron click. A
hover-opened feed also closes once the cursor leaves.
- No assertions or timeouts changed. The README notes the new behavior.

Files changed:
- `src/modules/ZoomIt/Tests/ZoomIt.UITests/ZoomItCaptureAndTrayTests.cs`
- `src/modules/ZoomIt/Tests/ZoomIt.UITests/README.md`

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

- `dotnet restore
src\modules\ZoomIt\Tests\ZoomIt.UITests\ZoomIt.UITests.csproj
-p:Platform=x64 -p:Configuration=Debug`: **passed** (exit 0)
- `tools\build\build.ps1 -Path src\modules\ZoomIt\Tests\ZoomIt.UITests
-Platform x64 -Configuration Debug`: **passed** (exit 0)
- Local Hyper-V VM suite runs were **skipped** at the maintainer's
request. Validation goes straight to UI Test Automation CI.
- UI Test Automation CI (`buildNow`, platforms `arm64` + `x64`,
`uiTestModules=[ZoomIt.UITests]`): **results to follow** in a comment.
The Windows 10 x64 job result for
`ShowTrayIconSettingRemovesAndRestoresShellIcon` will be checked
explicitly.
2026-10-18 21:26:50 +00:00
Clint Rutkas bd916bd773 [UI Tests] Retry ZoomIt tray overflow and clarify tray icon failures (#51344) 2026-10-16 23:03:11 -05:00
Mike Griese 0180425f49 CmdPal: batch DockBands updated into a single event (#51362)
`TopLevelCommandManager` added/removed dock bands one at a time, raising
a `CollectionChanged` per band. Every `DockViewModel` (one per monitor)
rebuilt all of its bands on each event. Yikes.

This PR instead adds `AddRange`/`RemoveRange` methods to
`DockBandsCollection`. Now each provider load/enable/disable/removal
raises just one `Reset`.

If you're thinking "you're just moving the Add, won't that still raise
events", it doesn't.
`ObservableCollection.Add` is the thing that actually raises
`CollectionChanged` events. Since we're not calling that, and are
instead just writing to the underlying collection directly, then the
only event raised is the one we raise ourselves.



Robots did some measuring on my machine

Measured on a 2-monitor machine, Debug x64 Dev build, 10 pinned bands
(builtin + Azure/GitHub/VirtualDesktops extensions), 5 cold launches
each, via temporary counters (not committed). Values identical across
runs except times (medians shown).

| Variant | DockBands events | Rebuilds | Band inits | Band init time |
"failed to find" warnings |

|--------------------|-----------------:|---------:|-----------:|---------------:|--------------------------:|
| main (baseline) | 23 | 24 | 138 | 3829 ms | 102 |
| batching (A) | 2 | 3 | 15 | 199 ms | 15 |

* "Band init time" is total time spent in
DockBandViewModel.InitializeProperties (cross-process calls on
background threads).
2026-10-16 12:53:09 -05:00
Clint Rutkas bc8c0f3067 [UI Tests] Retry Notepad focus in Keyboard Manager UI tests (#51345)
<!-- 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

Reduces flakiness in Keyboard Manager UI tests by retrying Notepad focus
when the test helper opens its input document, and makes the failure
message diagnosable. Test-helper only; no product code changes.

Evidence: PowerToys CI build 391160 (job `Test x64Win11 Release`, on
#51283, which only changed csproj `TreatWarningsAsErrors`, so this is
pre-existing flakiness):

```
failed KeyboardManager.Remapping.ShortcutToKey ("Win+A to B, modifier first",91,65,66,True)
  Assert.IsTrue failed. Notepad did not own foreground after opening the test file.
    at NotepadInputWindow..ctor(String initialText) in NotepadInputWindow.cs:65
```

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

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

`NotepadInputWindow`'s constructor retried *launching* Notepad but
called `FocusInput()` only once before asserting. Focus can fail
transiently (foreground lock) or because modern Notepad restored
previous tabs, leaving a different tab active in the bound window.

Changes in
`src/modules/keyboardmanager/Tests/KeyboardManager.UITests/NotepadInputWindow.cs`:
- Constructor now calls `FocusInitialDocument()`, which tries focusing
up to 3 times.
- Between attempts, `ReactivateBoundDocument()` reopens the file path in
modern Notepad when the test document tab isn't active. This switches
the existing window back to that tab. Otherwise it waits briefly before
the next attempt.
- `FocusInput()` now wraps a private `TryFocusInput(timeoutMS, out
failure)`. The public behavior and signature stay the same.
- The final assert reports which check failed (foreground vs.
test-document tab, before or after moving the caret), the bound HWND,
and `WindowControl.GetForegroundWindowInfo()`.

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

- `tools\build\build.cmd -Platform x64 -Configuration Release` from
`src\modules\keyboardmanager\Tests\KeyboardManager.UITests`: **passed**
(exit 0, 0 warnings, 0 errors).
- UI tests were not run locally (they need an interactive desktop). CI
will run them.
2026-10-16 09:20:19 -07:00
Clint Rutkas d89c233a94 [UI Tests] Wait for Screen Ruler toolbar window before building session (#51343)
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request

Fixes a flaky `TestScreenRulerBoundsTool` failure seen in CI build
391160 (Test x64Win11 Release, on #51283, which only touched csproj
settings):

```
FromProcess('PowerToys.MeasureToolUI'): no UIA-visible window appeared within 5000ms.
  at ScreenRuler.UITests.Next.TestHelper.ActivateScreenRuler(...) TestHelper.cs:372
```

`SendShortcutUntilVisible` returns as soon as the `MeasureToolUI`
**process** exists, then `ActivateScreenRuler` gave
`Session.FromProcess` only 5s to find a UIA-visible window. On slow
agents the toolbar window isn't created/visible yet.

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

<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments

Test-helper-only change in
`src/modules/MeasureTool/Tests/ScreenRuler.UITests.Next/TestHelper.cs`
(no change to shared `UITestAutomation.Next`):

- New `WaitForScreenRulerWindow`: cheap Win32 poll
(`Process.MainWindowHandle`, no UIA tree walk) for up to 15s until
`MeasureToolUI` owns a visible main window.
- `ActivateScreenRuler` calls it after the process is detected, then
builds the session with `Session.FromProcess(..., timeoutMS: 20000)`
(was 5000). Timeouts are upper bounds only, so fast runs aren't slowed.

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

- `tools\build\build.cmd -Platform x64 -Configuration Release` from
`src\modules\MeasureTool\Tests\ScreenRuler.UITests.Next` → exit 0, 0
warnings.
- UI tests not run locally; relying on CI UI test run.
2026-10-16 09:18:49 -07:00
Jiří Polášek f9ec2ecf12 CmdPal: Remove CmdPalKeyboardService C++ project and replace it (#50981)
## Summary of the Pull Request

This PR removes the CmdPalKeyboardService C++ project, and replaces it
with GlobalKeyboardListener class.

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

- [x] Closes: #50973 
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx

<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
2026-10-16 11:03:51 -05:00
Mike Griese bd179cb4ea CmdPal: Add a context menu to the 'home' item on the dock (#51304)
Give the CmdPal logo item a context menu with:
* settings
* reload
* logs
* quit

Stuff that would be great to have one click away, but are kinda hidden

Closes nothing, I work here.
2026-10-16 09:58:44 -05:00
Clint Rutkas 8ecd599e06 [UI Tests] Give Quick Accent scroll checks time on slow agents (#51346)
<!-- 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

Stabilizes the Quick Accent
`ScrollbarSpacingAppearsOnlyForOverflowingCharacterLists` UI test, which
timed out in [CI build
391160](https://microsoft.visualstudio.com/Dart/_build/results?buildId=391160)
(Test x64Win10 Release) on a PR that only changed csproj settings, so
the flakiness was already there.

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

- [ ] Closes: #xxx
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [x] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx

<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments

The failure message was:

```
Keyboard navigation did not scroll the selected character into view. Viewport X=100, width=1720; selected last item X=1779, width=34; first item X=108 -> 0.
```

That last observed state already satisfies the geometry check (the last
item spans 1779..1813, inside the 100..1820 viewport, and the first item
has scrolled away). So the wait ran out of time; the UI was not wrong.
In `AssertKeyboardNavigationScrollsIntoView`, every poll runs three
winappcli UIA lookups (the viewport `Find` plus two `FindCharacterItem`
calls). On CI agents each lookup can take seconds (other logs show
`winappcli slow call 4864ms`), so 5 s with 3 consecutive matches leaves
room for only one or two polls.

Changes, all in `PowerAccentTestHelper.cs`:
- The scroll-forward wait and the return-navigation wait now share a
`ScrollIntoViewTimeoutMs` of 15 s instead of 5 s, and need 2 consecutive
matches instead of 3. Because the predicate still requires a selected
item that is fully inside the viewport, 2 matches is enough to confirm
the layout is stable.
- Failure details now report `Selected` for the checked item, the width
of the first item, and how many consecutive matches were reached. With
that, the next failure will show whether selection lagged, whether the
off-screen item reported an empty rect (X=0 means a virtualized or
empty-rect peer, which still passes the `< initialFirstX - 1` check), or
whether the wait simply timed out.

No product code changed.

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

- `tools\build\build.ps1 -Platform x64 -Configuration Release
'/restore'` from `src\modules\poweraccent\PowerAccent.UITests`:
**passed**, exit 0, 0 warnings, 0 errors (warnings are treated as
errors).
- I did not run the UI test locally. It needs an interactive desktop and
installed PowerToys bits, so CI will exercise it.
2026-10-16 17:32:52 +08:00
Yu LengandYu Leng 1c11fa0921 [Image Resizer] Honor encoding options and preserve metadata (#51359)
## Summary of the Pull Request

Image Resizer ignores explicit PNG interlacing and TIFF compression
while retaining metadata, resizes only the first TIFF page, and drops
JPEG author/title fields. This fixes the shared encoding path used by
the UI and CLI, restores the WMPhoto fallback mapping, and rejects
undefined numeric CLI unit/fit values before processing files.

## PR Checklist

- [ ] **Communication:** Discussed with core contributors.
- [x] **Tests:** Added regression coverage for image output and CLI
validation.
- [x] **Localization:** The new invalid-enum diagnostic uses the Image
Resizer resource file.
- No new dependencies, binaries, settings schema, or IPC changes.

## Detailed Description of the Pull Request / Additional comments

- `src/modules/imageresizer/ui/Models/ResizeOperation.cs` uses a fresh
encoder when PNG/TIFF options require it and processes every TIFF page
with its own dimensions, metadata, and encoding options. Metadata is
written before committing each page.
- Copy supported native metadata blocks after pixel data in occurrence
order, retain JPEG author/title values and existing EXIF fallbacks, and
retain 16-bit sample precision. JPEG quantization tables are excluded so
the requested quality still applies.
- Preserve PNG color metadata. Convert fresh TIFF pixels to sRGB because
the WinRT TIFF encoder discards the source ICC profile even when copying
IFD metadata.
- `src/modules/imageresizer/ui/Utilities/CodecHelper.cs` maps the
existing WMPhoto settings GUID to JPEG XR, rather than silently falling
back to PNG.
- `src/modules/imageresizer/ui/Cli/Options/UnitOption.cs` and
`FitOption.cs` reject undefined enum values such as `99` and `-1`, while
preserving valid names, numeric values, and aliases.

The GIF animation limitation and the CLI input allowlist for ICO/HEIC
are outside this fix. Unknown enum names were already rejected and
remain covered as controls.

## Validation Steps Performed

- Built the repository prerequisites, `ImageResizer.UnitTests.csproj`,
and `ImageResizerCLI.csproj` with the repository build wrappers, x64
Debug: exit 0. Final target builds have no warnings or errors.
- Ran `ImageResizer.Test.dll` with Visual Studio VSTest on the matching
candidate: **304 passed, 0 failed, 0 skipped**.
- Test settings are isolated from the user's running PowerToys
configuration.
- Native WinRT controls confirmed that repeated PNG metadata chunks must
be copied in occurrence order, that PNG ICC data must be copied after
pixel data, and that the TIFF encoder discards its ICC profile.

Coverage exercises the shared image engine and CLI parser/executor. A
new Explorer/Settings UI acceptance run and an installed-package upgrade
were not performed.

Added runtime-generated fixtures and independent output checks for PNG
IHDR/CRC and native text, all six TIFF compression tags and monochrome
pixels, distinct multi-page TIFF contents/metadata, 16-bit samples,
embedded color profiles, Unicode JPEG metadata and EXIF orientation,
JPEG quality, actual JPEG XR output, and CLI rejection without output or
source modification.

Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com>
2026-10-16 08:58:14 +00:00
Yu LengandYu Leng bd1dff8934 Color Picker: enforce the editor color history limit (#51356)
## Summary of the Pull Request

When Color Picker already has 20 colors in its history, selecting a
newly adjusted color in the editor adds a 21st entry. Picking a color
from the screen respects the configured limit, but the editor's
insertion command only removes duplicates and inserts the new color.

Trim the oldest entries after an editor insertion using
`ColorHistoryLimit`, keeping the selected color first. This also brings
an already oversized history back within the configured limit when a
color is selected. The same command handles adjusted colors and
similar-color selections.

## PR Checklist

- [ ] **Communication:** Discussed with core contributors.
- [x] **Tests:** Added 6 regression cases; all 45 ColorEditorViewModel
tests pass locally.
- [x] **Localization:** No new user-facing strings.
- [x] **Dev docs:** No documentation changes required.
- [x] **New binaries:** No new binaries or dependencies.

## Detailed Description of the Pull Request / Additional comments

The change is confined to the editor's history insertion command.
Regression tests check new-color insertion at limits of 20 and 3,
trimming a history that is already over its limit, and promoting an
existing first/middle/last color without duplication or removing other
colors. They also check the selected color and synchronization with the
settings history collection.

## Validation Steps Performed

- Previously reproduced on installed PowerToys 0.102.2814.0: with 20
distinct history entries and a limit of 20, a real Picker insertion
retained 20 entries; editing a color to HEX `123457` and selecting it
produced 21 distinct entries in both the editor history and the observed
history file contents.
- Built `ColorPickerUI.UnitTests.csproj` and its project references with
the repository build wrapper, x64 Debug; exit code 0 and an empty errors
log.
- Ran `vstest.console.exe` filtered to
`ColorPicker.UnitTests.ViewModels.ColorEditorViewModelTests`: **45/45
passed**, including all 6 new regression cases.
- The initial essentials run completed solution package restore, then
was interrupted during Runner compilation without an error diagnostic.
It is not counted as a successful essentials build; the targeted
module/test build above completed independently.
- The patched UI has not been exercised interactively. The installed
application was not replaced or modified for this change.

Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com>
2026-10-16 15:52:50 +08:00
Yu LengandYu Leng 3b8c2a7697 PowerRename: fix EXIF GPS and XMP creator extraction (#51357)
## Summary of the Pull Request

PowerRename replaces valid EXIF GPS coordinates with
`0°0.00'N-0°0.00'E`, and leaves XMP `$AUTHOR`/`$CREATOR` tokens
unchanged even when the same image's camera and title tokens work.

Fix the two metadata reads and add regression coverage using the
existing sample image:

- WIC returns GPS coordinates as three packed `VT_UI8` rationals. The
parser treated every vector as a byte buffer and required 24
**elements**, so the three-element rational vector was rejected and both
coordinates became zero. Decode the typed vector and scalar rationals,
retaining byte-buffer support and reference directions.
- XMP `dc:creator` is an ordered RDF sequence. Reading its container as
a scalar string yielded no creator, which prevented both aliases from
being populated. Read the indexed string elements, retain their order,
and join multiple creators with `; `, following the existing
subject-array convention.

## PR Checklist

- [ ] **Communication:** Discussed with core contributors.
- [x] **Tests:** All 76 native metadata tests pass, including 9 new
regression tests.
- [x] **Localization:** No new user-facing strings.
- [x] **Dev docs:** No documentation change required.
- [x] **New binaries:** No new binaries or dependencies.

## Detailed Description of the Pull Request / Additional comments

The real-image regression tests cover extraction and filename-token
substitution together:

| Metadata source and template | Expected result |
| --- | --- |
| EXIF `$LATITUDE-$LONGITUDE.jpg` | `26°34.95'N-80°12.01'W.jpg` |
| EXIF `$CAMERA_MAKE_$CAMERA_MODEL.jpg` | `samsung_SM-G930P.jpg` |
| XMP `$AUTHOR-$CREATOR` | `Carl Seibert (XMP)-Carl Seibert (XMP)` |
| XMP `$TITLE` | `object name here` |

The existing `exif_test.jpg` and `xmp_test.jpg` fixtures match the image
used to reproduce both problems. The previous extraction tests asserted
camera/title values but omitted GPS coordinates and the XMP creator.
Additional tests cover malformed GPS vectors, packed rationals, legacy
byte vectors, missing creators, and a generated one-pixel JPEG with
ordered Unicode creators and an empty entry.

## Validation Steps Performed

- The original UI failures and the camera/title positive controls were
reproduced on installed PowerToys 0.102.2814.0. Read-only system WPF/WIC
inspection independently confirmed the GPS rational-vector
representation and the XMP sequence/indexed-string query results.
- Completed the repository essentials build, then built
`PowerRenameLib.vcxproj` and `PowerRenameLibUnitTests.vcxproj` in x64
Debug with the repository build wrappers. All final build stages exited
0.
- Ran `vstest.console.exe` for `MetadataFormatHelperTests`,
`ExtractEXIFMetadataTests`, `ExtractXMPMetadataTests`, and
`FactoryLifetimeTests`: **76/76 passed**, including all **9 new
regression tests**. This includes actual WIC extraction and the
filename-substitution outputs listed above.
- The scope excludes unrelated regex/settings tests and HEIF/AVIF tests
that require optional codecs.
- Interactive preview/Apply validation with the patched PowerRename UI
has not been performed.

---------

Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com>
2026-10-16 15:52:42 +08:00
matthudson 85d7ed7bd3 [Settings] Fix CA2227 in remaining persisted models (#50738)
## Summary of the Pull Request

Resolves the remaining CA2227 warnings in persisted Settings models and
`LanguageModelProvider` while preserving their JSON contracts and
runtime mutation behavior.

Collection properties become init-only, and code paths that previously
replaced persisted collections now update their contents in place.

## PR Checklist

- [ ] Closes: N/A — follow-up to #11646 and #50702
- [x] Communication: Continuation requested during review of #50702
- [x] Tests: Settings serialization, profile-editor, PowerDisplay, and
full Settings UI tests pass
- [x] Localization: N/A — no user-facing strings changed
- [x] Dev docs: N/A — no developer-facing behavior changed
- [x] New binaries: N/A
- [x] Documentation updated: N/A — internal analyzer cleanup only

## Detailed Description of the Pull Request / Additional comments

- Makes the remaining affected collection properties in
`Settings.UI.Library` and `LanguageModelProvider` init-only.
- Updates runtime paths in PowerDisplay, Mouse Without Borders, Advanced
Paste, and monitor refresh handling to mutate existing collections
rather than replace them.
- Preserves the existing serialized property names and shapes.
- Normalizes explicit JSON `null` values to empty mutable collections
for the affected Mouse Without Borders and PowerDisplay properties,
preserving the pre-change runtime safety of their setters.
- Adds explicit-null deserialization and post-deserialization mutability
coverage.
- Removes 20 targeted CA2227 diagnostics.

## Validation Steps Performed

- Built `Settings.UI.UnitTests` successfully in Release x64.
- Ran the full Settings UI unit-test suite: **326 passed, 0 failed**.
- Built `LanguageModelProvider` with `AnalysisMode=All`; no targeted
CA2227 warnings remain.
- An analyzer-wide Settings build reports only five CA2227 diagnostics
in files covered by separate follow-up PRs; none are in this PR's
changed files.
- Ran `git diff --check origin/main...HEAD`: clean.
2026-10-16 15:08:36 +08:00
Mike Griese 0b305162b7 CmdPal: don't save settings on load unless they changed (#51353)
Looking at the logs from a debug startup and holy hell batman, it's so
noisy.

Looks like every time that we added a fallback command to a provider,
we'd save the settings. Even if we'd already seen that fallback. In
practice, this resulted in **46** saves, because of all the PT
fallbacks. Literally every load - 46 saves. Even if nothing changed.

This PR skips writing the file if nothing changed. Saves about 2s[^1] of
startup time.

Closes nothing, I know what I'm doing

[^1]: LLM measurment, not my own
2026-10-15 20:15:08 -05:00
Jiří Polášek 64a28089c7 CmdPal: Prevent intermittent DetailsViewModel test failures (#51355)
<!-- 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 fixes intermitten failures in CmdPal unit tests, caused by page
contexts being collected while view models still hold weak references to
them.

Fix keeps contexts alive through test execution and cleanup using
fixture ownership, returning contexts from helpers, or GC.KeepAlive.

Updated test classes:

- DetailsViewModel 
- ListItemDoubleTapTargetTests
- ShowToastMessageTests
- DockLabelPersistenceTests
- CommandContextSourceTests
- DockBandViewModelLifecycleTests
- DockItemViewModelTests
- MainListPageCacheTests
- CommandItemViewModelTests

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

- [x] Closes: #51351
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx

<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
2026-10-15 20:13:52 -05:00