Commit Graph

9457 Commits

Author SHA1 Message Date
Clint Rutkas
bb99c30edc New module: AltWindowCycle (#48281)
## Summary of the Pull Request

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

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

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


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

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

## PR Checklist

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

## Detailed Description of the Pull Request / Additional comments

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

## Validation Steps Performed

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Niels Laute <niels.laute@live.nl>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Clint Rutkas <crutkas@users.noreply.github.com>
Copilot-Session: dd5080ea-5001-4efb-87f8-1e7218e10a4e
2026-07-30 22:42:05 -07:00
Mike Griese
331f88a1a0 CmdPal: bump to 0.12 (#49586)
title
2026-07-30 19:08:20 -07:00
Clint Rutkas
ffc839afea [PowerAccent] Fix injection hygiene and reset state on hide (#48572)
## Summary
Keeps Quick Accent-injected keys from retriggering centralized shortcuts
and clears native keyboard-listener state whenever the toolbar closes.

## What this changes
- Tags backspace, Unicode, and arrow `SendInput` events with
`dwExtraInfo = 0x110`, mirroring
`CENTRALIZED_KEYBOARD_HOOK_DONT_TRIGGER_FLAG`.
- Uses the existing `SendArrowKey(bool)` implementation as the single
arrow-injection path, preserving `KEYEVENTF_EXTENDEDKEY` on key-down and
key-up.
- Checks the number of events sent by every `SendInput` call and logs
incomplete sends.
- Adds `ForceReset()` to the keyboard service WinRT API and invokes it
from the core hide path immediately before `OnChangeDisplay(false)`.
- Keeps listener state non-atomic because the low-level hook is
installed on the WinUI thread and its callbacks execute on that same
thread, as documented by `MainWindow.RunOnUiThread`.

## Testing
- Built `PowerAccent.Core.csproj` in Release x64, including
`PowerAccentKeyboardService`.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 122a9176-ce18-437c-8af4-c39f83fb2fa6
2026-07-30 17:34:02 -07:00
Mike Griese
70e0fc2295 CmdPal: when expanding compact mode, don't be too tall (#49532)
If you open command palette on one display and resize its expanded size
to be very tall, then you move command palette to a monitor that is not
that tall and expand it, we will still expand our control to fit the
full size of our HWND, which is taller than this new monitor. This PR
fixes that by making sure to measure the size that's available on the
current monitor and limit the max height of our control when we're
expanding it, so that the bottom of the control always fits on the
current monitor.

Closes: not filed I don't think
2026-07-30 14:30:23 -05:00
chakrik73
7d1dde7aa5 [ZoomIt] Port recording/editing features from Mac ZoomIt (trim editor, snip-to-clipboard, recording border) and fix video trim reliability (#49553)
## Summary of the Pull Request

Ports several recording and editing features from the Sysinternals **Mac
ZoomIt** into the Windows PowerToys ZoomIt module, and hardens the video
**trim/save** pipeline against a sporadic "Failed to trim the video"
failure.

Highlights:
- **Video trim editor — interior "Delete Region" editing.** In the
post-recording trim dialog you can now select and delete interior
segments (not just trim the head/tail). Includes red timeline overlays
with drag grips, right-drag to select, `Delete` to remove, `Ctrl+Z` to
undo, and `Esc` to cancel a pending selection.
- **Reliable trim/render.** Fixed a sporadic *"Failed to trim the
video"* error. The live capture pipeline produces **fragmented** MP4s
(moof/mdat) that play in preview but fail `MediaComposition` render/seek
with `0xC00DA7FC`. The render path now (a) sources resolution from the
clip's encoding properties first, (b) retries transient failures (0×0
dimensions from a fragmented-MP4 metadata race, `!CanTranscode()`,
post-remux render failure), and (c) remuxes fragmented MP4s to a
standard seekable MP4 via `MediaTranscoder` before rendering.
- **Snip → Copy to clipboard.** New ZoomIt setting to copy a snip
directly to the clipboard.
- **Recording border color.** The screen-recording selection border now
uses a distinct color, and turns orange while recording is active.
- **GIF recording robustness.** First-frame timeout so GIF capture
doesn't hang when no frames arrive.
- **Audio hardening.** Stereo downmix handling and defensive guards in
the audio sample generator.
- **Opt-in diagnostics.** Recording diagnostics (`[RecDiag]`) are gated
behind a registry DWORD
`HKCU\Software\Sysinternals\ZoomIt\EnableDebugTrace` (off by default),
and all module debug output is prefixed with `[ZoomIt]` for easy
filtering in DebugView.
- **Fix:** GDI bitmap leak in the snip-to-clipboard path when
`SetClipboardData` fails.

## PR Checklist

- [ ] **Tests:** ZoomIt is native Win32/WinRT with no unit-test harness;
validated manually (see Validation Steps)
- [ ] - [x] **Localization:** All end-user-facing strings can be
localized <!-- new strings added to Settings.UI en-us Resources.resw -->
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** N/A: no new binaries/projects 
  - [ ] JSON for signing — N/A
  - [ ] WXS for installer — N/A
  - [ ] YML for CI pipeline — N/A
  - [ ] YML for signed pipeline — N/A
- [ ] **Documentation updated:** N/A

## Detailed Description of the Pull Request / Additional comments

Files changed (17):

**ZoomIt module (native)**
- `VideoRecordingSession.cpp/.h` — interior delete-region trim editor;
render/trim reliability (resolution from clip encoding properties, retry
loop, fragmented-MP4 → seekable remux); registry-gated `[RecDiag]`
diagnostics.
- `GifRecordingSession.cpp` — first-frame timeout / no-frames handling.
- `AudioSampleGenerator.cpp` — stereo downmix + defensive guards.
- `SelectRectangle.cpp/.h`, `PanoramaCapture.cpp` — recording border
color parameter.
- `Zoomit.cpp` — snip → clipboard workflow; GDI bitmap leak fix on
`SetClipboardData` failure.
- `ZoomItSettings.h`, `ZoomIt.h`, `ZoomIt.rc`, `resource.h` — new
setting + "Delete Region" button + message id.
- `pch.h` — `[ZoomIt]` debug-output prefix wrapper.

**Settings UI**
- `ZoomItProperties.cs`, `ZoomItViewModel.cs`, `ZoomItPage.xaml`,
`Resources.resw` — "Copy snip to clipboard" setting and localized
strings.

Note: ZoomIt is a Sysinternals port kept in its upstream code style, so
it is intentionally exempt from the repo `.clang-format` (changed lines
follow the surrounding Sysinternals convention).

## Validation Steps Performed

Manual validation (no automated ZoomIt harness):
- **Trim reliability:** Recorded multiple clips and used Trim → Save
repeatedly (including 3-clip compositions produced by Delete Region);
render now succeeds consistently (previously failed sporadically with
"Failed to trim the video").
- **Delete Region editor:** Right-drag to select an interior segment,
`Delete` to remove, `Ctrl+Z` to undo, `Esc` to cancel; saved output
reflects the removed segments.
- **Snip → clipboard:** Enabled the new setting; snip is placed on the
clipboard and pastes correctly. Verified no GDI handle leak when
clipboard set fails.
- **Recording border:** Verified border color and the orange
active-recording state (full-monitor and region).
- **GIF:** Confirmed capture no longer hangs when no frames arrive.
- **Diagnostics:** With `EnableDebugTrace` unset, no
`%TEMP%\ZoomIt_RecDiag.log` and no `[RecDiag]` output; with it set to
`1`, `[ZoomIt] [RecDiag ...]` traces appear.
- **Style checks:** XamlStyler (clean), StyleCop via building
`Settings.UI.Library` and `PowerToys.Settings` (no `SA####` warnings),
ZoomIt x64 Release builds with exit code 0.
2026-07-30 09:17:52 -07:00
Mike Griese
5803bc7ec5 BUILD: Fix the version.vcxproj FastUpToDate check (#49534)
This has been my personal enemy for a year now.

VS will skip doing work for your build if it thinks everything is up-to-
date. But this version project has been treated as dirty for a long time
now. What that means is that incremental builds (READ: dev inner loop
builds) end up building the world CONSTANTLY. Because VS thinks FOR SOME
REASON that this project needs to rebuild.

By setting the `Inputs`/`Outputs` for this `Target`, VS is smart enough
to only re-run the task if the inputs actually changed since the last
build.

Tested by building the code, then building again, and observing that
all the projects were successfully noted as up-to-date

drive-by: fix some of the other `csproj` files for cmdpal. 


Closes #45296
2026-07-30 09:19:27 -05:00
moooyo
4b3f961b12 [PowerDisplay] Run the tray Exit through Shutdown so teardown is not skipped (#49580)
## Summary of the Pull Request

PowerDisplay's tray context menu **Exit** ended the process with
`Environment.Exit(0)`, skipping the teardown that `App.Shutdown()`
already
performs. Point it at `Shutdown()` instead — a one-line change.

What Exit was skipping:

- `TrayIconService.Destroy()` — `Shell_NotifyIcon(NIM_DELETE)`, the icon
and
popup-menu handles, and restoring the subclassed window procedure.
Without the
`NIM_DELETE`, the notification area can keep showing a stale
PowerDisplay icon
until the Shell next validates it, which in practice is when the pointer
passes
  over it.
- `MainWindow.Dispose()` — which cancels the CLI named-pipe server's
`CancellationTokenSource` and disposes the hotkey service, the message
hook and
`MainViewModel` (monitor manager, display-change watcher, per-monitor
view
  models).

`Environment.Exit` does not run finalizers, so none of that happened by
another
route.

The named-pipe terminate message (`PowerDisplayTerminateAppMessage`) has
always
gone through `Shutdown()`, so this only makes the tray menu agree with a
path
that is already shipping. The tray menu command is dispatched from the
subclassed main-window procedure, so it already runs on the UI thread
that owns
these objects, and `Shutdown()` still ends with `Environment.Exit(0)` —
the
process exits unconditionally either way.

## PR Checklist

- [ ] Closes: #xxx — no filed issue. Found while working on #49410;
split out so
      it can be reviewed on its own.
- [ ] **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 — none added. The change is
process-exit wiring inside `App.OnLaunched`, which has no test harness;
      validated manually.
- [x] **Localization:** All end-user-facing strings can be localized —
no new or
      changed strings.
- [ ] **Dev docs:** Added/updated — no doc change warranted for a
one-line
      teardown fix.
- [ ] **New binaries:** Added on the required places — none.
- [ ] **Documentation updated:** no user-facing behaviour change.

## Detailed Description of the Pull Request / Additional comments

### Deliberately not in scope

Two other paths still call `Environment.Exit(0)` directly, and both are
pre-existing and unchanged here:

- The runner **Terminate** event
(`Constants.TerminatePowerDisplayEvent()`) —
the module-disable and PowerToys-exit path. Its callback is already
marshalled
to the UI thread by `NativeEventWaiter`, so it *could* be routed the
same way,
but adding teardown work to the runner's shutdown path should be
validated
against the runner's shutdown timeout on its own rather than riding
along with
  a tray-menu fix.
- The `RunnerHelper.WaitForPowerToysRunner` watchdog, whose callback
runs on a
  background thread and would need marshalling to the UI thread first.

Happy to follow up on either if reviewers would rather see them fixed
together.

## Validation Steps Performed

- Tray icon → right-click → **Exit**: PowerDisplay exits, the
notification icon
  disappears immediately rather than lingering until hover.
- Re-launch from PowerToys Settings after a tray Exit: the tray icon
comes back
  once, not twice.
- `powerdisplay` CLI still works after a launch/tray-Exit/launch cycle,
confirming the named pipe was released rather than left to process
teardown.
- Existing terminate paths unchanged: disabling PowerDisplay in Settings
and
  quitting PowerToys both still exit the process.

Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com>
2026-07-30 09:59:58 +00:00
moooyo
bc2d09abe8 PowerDisplay: Pace and retry the maximum-compatibility VCP probe (#49579)
## Summary of the Pull Request

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

This replaces the probe with `VcpFeatureProbeService`:

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

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

## PR Checklist

- [ ] Closes: #xxx — partially addresses #49342; the remaining causes
are in #49445
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [x] **Tests:** Added/updated and all pass
- [x] **Localization:** All end-user-facing strings can be localized —
this PR adds none
- [ ] **Dev docs:** Added/updated
- [x] **New binaries:** Added on the required places — none added; no
new project, so no signing JSON, installer WXS or CI YML change is
required
- [ ] **Documentation updated**

## Detailed Description of the Pull Request / Additional comments

### What is and is not retried

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

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

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

### Behaviour preserved

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

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

### Cost

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

### What is deliberately left out

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

## Validation Steps Performed

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

---------

Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com>
2026-07-30 09:55:00 +00:00
Gordon Lam
efc0258cda Validate the update installer before PowerToys.Update launches it (#48903)
## Summary

PowerToys' self-updater downloads the installer into
`%LOCALAPPDATA%\Microsoft\PowerToys\Updates` and then launches it from
`PowerToys.Update.exe` (Stage 2). This makes that launch path more
robust:

- Open the downloaded installer with a read-only share so the file stays
consistent while we inspect and run it.
- Confirm it is a valid, Authenticode-signed **Microsoft** PowerToys
installer (valid signing chain + Microsoft organization) before
executing it. This single chokepoint covers both freshly downloaded and
previously downloaded installers.
- If the check does not pass, log and skip the launch instead of running
an incomplete or invalid file.

## Implementation

- Added `updating::verify_installer_trust` to the shared
`common/updating` library (`installer.h` / `installer.cpp`):
`WinVerifyTrust` for the signing chain, and `CryptQueryObject` /
`CertGetNameString` to confirm the signer's organization is `Microsoft
Corporation`. `Wintrust.lib` / `Crypt32.lib` are linked via `#pragma
comment(lib, ...)`.
- `InstallNewVersionStage2` opens the installer with `FILE_SHARE_READ`,
verifies it, and keeps the handle open across `MsiInstallProductW` / the
bootstrapper launch so the file stays stable during install.

## Validation

- `ApplicationUpdate` and `PowerToys.Update` build clean (x64 Debug).
- Existing updating unit tests pass (30/30).
- Checked end-to-end against real binaries: a Microsoft
Authenticode-signed binary is accepted; a corrupted copy and an unsigned
file are both declined.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Muyuan Li <muyuanli@microsoft.com>
Co-authored-by: Boliang Zhang (from Dev Box) <bozhang@microsoft.com>
Copilot-Session: d168a794-8cce-483d-9c46-10787893dbe2
2026-07-30 16:29:55 +08:00
moooyo
af5665eaa8 PowerDisplay: Always write the saved value when restoring monitor settings (#49577)
## Summary of the Pull Request

`TryRestore` skipped writing a saved monitor value when it already
equalled the value `MonitorViewModel` was showing. That displayed value
is only an observation when the discovery-time VCP read succeeded. When
the read failed it is a placeholder:

| setting | value when the read failed | source |
| --- | --- | --- |
| brightness | `50` | `MonitorDiscoveryHelper` stamps it — *"Initial
placeholder; overwritten if the VCP read succeeds"* |
| contrast | `50` | `Monitor` backing-field default |
| volume | `50` | `Monitor` backing-field default |
| color temperature | `0x05` (6500K) | `Monitor` backing-field default |

A saved value that happened to equal one of those silently suppressed
the restore, and the monitor kept whatever it powered on with. `50` is
the mid-slider value and `0x05` is the most common preset, so the
coincidence is not rare.

This drops the comparison: a restore now always writes.

## PR Checklist

- [ ] Closes: #xxx — no issue; found while splitting up #49445
- [ ] **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 — none added; `TryRestore`
is a private helper in the `PowerDisplay` app project, which has no test
project
- [x] **Localization:** All end-user-facing strings can be localized —
this PR adds none
- [ ] **Dev docs:** Added/updated
- [x] **New binaries:** Added on the required places — none added; no
new project, so no signing JSON, installer WXS or CI YML change is
required
- [ ] **Documentation updated**

## Detailed Description of the Pull Request / Additional comments

### Why remove the check rather than refine it

The skip-if-equal check dates from PowerDisplay's first commit (#42642,
where it read `// Restore brightness if different from current`); #47051
only refactored it into the shared `TryRestore` helper. It is day-one
"obviously we shouldn't write twice" code, not a response to a reported
problem.

Removing it is correct by construction: with no skip branch there is no
state in which a restore silently does nothing. Any narrower fix has to
decide *when* the displayed value can be trusted, and gets that decision
wrong in exactly the cases that are hardest to reproduce.

### Cost

Two, both bounded:

- **A redundant VCP write when the monitor already sits at the saved
value.** Some panels surface a write on their OSD. Both paths that reach
here are user-initiated: startup restore only runs when
`RestoreSettingsOnStartup` is enabled, and a profile apply happens
because the user invoked that profile.
- **Time.** At most four writes per monitor, serialised on that
monitor's I2C bus (~100 ms each). Monitors still run in parallel through
the existing `Task.WhenAll`.

The `isVisible` guard is untouched, so a monitor still never receives a
write for a feature it does not expose — an unsupported VCP `0x14` is
not written just because a profile carries a color temperature. Input
source and power state are not restored here at all.

### If the redundant write turns out to matter

The narrower fix is to keep the comparison and add one clause: also
write when `(monitor.ReadValues & flag) != flag`, i.e. when the compared
value was never read off the hardware. `MonitorReadFlags` already
carries exactly that information, and `Monitor.ReadValues` is already
maintained by the discovery-time `Initialize*` methods, so it is a small
change on top of this one. I went with the simpler version first — happy
to switch if a maintainer would rather keep the optimisation.

## Validation Steps Performed

- built `PowerDisplay` and `PowerDisplay.Lib.UnitTests` for x64 Debug
with VS MSBuild — 0 errors, 0 warnings
- ran `PowerDisplay.Lib.UnitTests.dll` with `vstest.console.exe`: **186
passed, 0 failed** — unchanged from `main`; this PR touches only the app
project and adds no tests
- no hardware validation performed: the placeholder path this PR fixes
is reachable only on a monitor whose VCP read fails during discovery

Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com>
2026-07-30 15:08:59 +08:00
moooyo
32f738bd45 PowerDisplay: Release physical-monitor handles that discovery abandons (#49578)
## Summary of the Pull Request

`DdcCiController.DiscoverFromHandleAsync` abandons a physical monitor on
three paths without destroying its handle.

Handles only reach `PhysicalMonitorHandleManager` through monitors that
were successfully built: the map is rebuilt from the returned monitor
list, and its cleanup pass only destroys handles that were in the
*previous* map. A handle dropped on an abandon path therefore never gets
destroyed. A discovery runs on every display-topology change, so a
monitor that keeps failing leaks one more handle per discovery for the
process lifetime — a docking-station user accumulates them.

Extracted from #49445, where the same fix is bundled with
maximum-compatibility-mode work it does not depend on.

## PR Checklist

- [ ] Closes: #xxx — no issue; extracted from #49445
- [ ] **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 — none added; rationale
below
- [x] **Localization:** All end-user-facing strings can be localized —
this PR adds none
- [ ] **Dev docs:** Added/updated
- [x] **New binaries:** Added on the required places — none added; no
new project, so no signing JSON, installer WXS or CI YML change is
required
- [ ] **Documentation updated**

## Detailed Description of the Pull Request / Additional comments

### The three leaking paths

| path | before this PR |
| --- | --- |
| more physical monitors than `QueryDisplayConfig` entries for the GDI
name | `break` leaves `physicals[i..]` unreleased — the whole tail, not
just the current one |
| capabilities unavailable | `continue` |
| `BuildMonitorFromPhysical` returned null (construction failed, or it
threw and was caught) | no `else` branch at all |

`ReleaseAbandonedPhysical` is null-handle safe and swallows a failing
`DestroyPhysicalMonitor` at warn level: one handle that cannot be
destroyed must not take down the rest of the discovery pass.

### Why there are no tests

Reaching these call sites means faking the whole native enumeration
surface — `EnumDisplayMonitors`, `GetMonitorInfo`,
`GetPhysicalMonitorsFromHMONITOR` — which is a larger seam than a
one-file leak fix should introduce. The paths were verified by reading
instead. Happy to add the seam if a maintainer would rather have it
covered.

### Known remaining leaks, deliberately out of scope

- `GetPhysicalMonitorsWithRetryAsync`'s retry loop discards a whole
array of live handles when it retries after seeing NULL handles.
- Cancellation unwinds `DiscoverMonitorsAsync` before `UpdateHandleMap`
runs, so that pass's handles never enter the map and are never
destroyed.

Both predate this change and are better addressed separately.

## Validation Steps Performed

- built `PowerDisplay.Lib` and `PowerDisplay.Lib.UnitTests` for x64
Debug with VS MSBuild — 0 errors, 0 warnings
- ran `PowerDisplay.Lib.UnitTests.dll` with `vstest.console.exe`: **186
passed, 0 failed** — no new tests; this only confirms nothing regressed
- no hardware validation performed: reaching an abandon path needs a
monitor whose capabilities fetch fails or whose construction throws

Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com>
2026-07-30 15:08:52 +08:00
Noraa Junker
135291d456 [Shortcut Guide] Add Less Than and greater than characters and fix crash if key is empty or invalid (#49562)
<!-- 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:  #49558
<!-- - [ ] 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
- [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
2026-07-30 08:29:05 +02:00
Anthony Thompson
e6bbf4428e docs: add Quick Shell to third-party Run plugins (#49567)
## Summary

Adds [Quick Shell](https://github.com/tonythethompson/QuickShell) to the
community PowerToys Run plugins list.

- **Plugin:** Quick Shell (`qs` keyword)
- **Author:** [tonythethompson](https://github.com/tonythethompson)
- **Description:** Open saved project folders in any terminal; shared
shortcuts with the Quick Shell Command Palette extension

## Install

- WinGet (bundled CmdPal + Run): `winget install
tonythethompson.QuickShell`
- Run-only ZIP:
[`QuickShell.Run-x64.zip`](https://github.com/tonythethompson/QuickShell/releases/latest)
/
[`QuickShell.Run-ARM64.zip`](https://github.com/tonythethompson/QuickShell/releases/latest)
- Run-only EXE: `QuickShellforRun-Setup-*-x64.exe` / `*-arm64.exe` from
the same release

Docs:
https://github.com/tonythethompson/QuickShell/blob/master/docs/powertoys-run-plugin.md

## Validation

- [x] Listed under General plugins
- [x] Links to GitHub repo and author profile
- [x] Release assets include Run plugin ZIP and installer


Made with [Cursor](https://cursor.com)

Co-authored-by: Anthony Thompson <>
2026-07-30 08:27:52 +02:00
Clint Rutkas
d72fa2ea6e Update Monaco Editor from 0.47.0 to 0.52.2 (#48415)
## Summary of the Pull Request

Updates the vendored Monaco Editor from 0.47.0 (Mar 2024) to 0.52.2 (Dec
2024).

## PR Checklist

- [x] **Communication:** Discussed in #46692 review
- [x] **Tests:** Headless-browser smoke tests pass (syntax highlighting,
custom languages, context-menu hack, addAction registration)
- [x] **Dev docs:** No doc changes needed (update process unchanged)

## Detailed Description

### What changed

| Area | Detail |
|------|--------|
| `src/Monaco/monacoSRC/min/` | Replaced with `monaco-editor@0.52.2`
from npm |
| NLS layout | `editor.main.nls.*.js` / `simpleWorker.nls.*.js` removed
upstream → `vs/nls.messages.*.js` added |
| New language | `typespec` shipped upstream (+1 language, 100→101
total) |
| `monacoSpecialLanguages.js` | Inline grammar snapshots
(cpp/xml/razor/vb/ini/shell) refreshed from 0.52.2 shipped files |
| `monaco_languages.json` | Regenerated; all PowerToys custom languages
+ extension mappings intact |

### Supply-chain verification

- npm tarball SHA-512 verified against registry SRI:
`sha512-GEQWEZmfkOGLdd3XK8ryrfWz3AIP8YymVXiPHEdewrUq7mh0qrKrfHLNCXcbB6sTnMLnOZ3ztSiKcciFUkIJwQ==`
- Vendored tree hash-verified file-by-file (103 files, all match)

### Why 0.52.2 and not 0.55.1 (latest)?

Monaco 0.53+ completely restructured the `min/` bundle: flat hashed
chunks instead of per-language AMD modules,
`vs/platform/actions/common/actions` removed,
`vs/basic-languages/<id>/<id>` modules eliminated. PowerToys'
`index.html` (context-menu stripping via MenuRegistry) and
`monacoSpecialLanguages.js` (language cloning via AMD require) depend on
these internals. **0.52.2 is the last release compatible without a
glue-code rewrite.** The 0.55.x port is tracked separately.

## Validation Steps Performed

- [x] Tarball SRI integrity verified against npm registry
- [x] Vendored tree == tarball (SHA-256 per file, 103/103 match)
- [x] `monacoSpecialLanguages.js` passes Node.js syntax check
- [x] Headless smoke test (Edge via puppeteer-core): editor creates,
tokenization paints (5+ classes), `addAction` entries register,
`MenuRegistry` context-menu hack works
- [x] Same smoke test passes identically on 0.47.0 baseline (no
regressions)
- [x] `monaco_languages.json`: 101 languages, all custom IDs present
(reg, gitignore, srt, cppExt, xmlExt, txtExt, razorExt, vbExt, iniExt,
shellExt)

## Related

- Supersedes automation approach in #46692 (which has fatal bugs; will
close separately)
- 0.55.x port tracked as follow-up issue

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b6bd2181-eff3-4f2a-b25e-dcd1065ead6a
2026-07-28 20:54:52 -07:00
Clint Rutkas
d127511c7d Fix runner APPLICATION_HANG_QUIESCE: handle WM_ENDSESSION and skip blocking shutdown cleanup (#48363)
## Summary

The runner WndProc (`tray_icon_window_proc`) does not handle
`WM_QUERYENDSESSION` / `WM_ENDSESSION`, **and** its `WM_DESTROY`
teardown performs blocking cross-process cleanup. Both contribute to the
Watson failure
`APPLICATION_HANG_QUIESCE_cfffffff_PowerToys.exe!run_message_loop` on OS
shutdown, sign-out, or restart:

1. Without a `WM_ENDSESSION` handler, `DefWindowProc` returns `0`
without posting a quit message, so `run_message_loop` stays parked in
`GetMessageW` until the OS quiesce timeout (~5 s) force-terminates the
process.
2. Even once teardown starts, `WM_DESTROY` calls
`close_settings_window()`, which blocks up to 1.5 s on
`WaitForSingleObject` against `PowerToys.Settings.exe`
(`src/runner/settings_window.cpp:712`), plus
`Shell_NotifyIcon(NIM_DELETE)` during Explorer teardown. The Windows
[shutdown
guidance](https://learn.microsoft.com/windows/win32/shutdown/shutting-down)
is explicit that handlers must not block.

This PR fixes both issues for the always-on runner. Rollout to
module-owned windows is intentionally separate and tracked in #49539.

> Supersedes #48378 (same Watson bucket) by combining its
no-blocking-cleanup fix with a reusable helper and unit tests. The
cleanup-skip insight is credited to @yeelam-gordon.

Related (same failure class, different binary): #41260.

## Root cause

`src/runner/tray_icon.cpp` → `tray_icon_window_proc` had no case for
`WM_QUERYENDSESSION` / `WM_ENDSESSION`, and `WM_DESTROY` unconditionally
ran cross-process cleanup. On a full Windows session end, the OS
delivers `WM_ENDSESSION` to child applications and reaps them
independently, so the runner's waits consume the quiesce budget without
helping shutdown complete.

## Fix

### 1. Explicitly stateless helper in `src/common/utils/window.h`

`handle_stateless_session_end_message`:

- `WM_QUERYENDSESSION` → returns `TRUE`. The name makes clear that this
helper is only for processes with no unsaved user state.
- `WM_ENDSESSION(TRUE)` → calls `DestroyWindow(window)`, driving the
existing `WM_DESTROY → PostQuitMessage(0)` path so `run_message_loop`
unwinds.
- `WM_ENDSESSION(FALSE)` → leaves the window alone because another
application cancelled shutdown.
- The optional `out_system_session_ending` flag is set only when the
full Windows session is ending. `ENDSESSION_CLOSEAPP` still closes the
runner but leaves the flag false so Restart Manager requests retain
normal child-process cleanup.

Stateful modules must implement their own save/permission behavior
rather than adopt this helper. `tray_icon_window_proc` calls it at the
top of dispatch and returns immediately when the message is handled.

### 2. Skip blocking cleanup only for a full Windows session end

`WM_DESTROY` branches on `g_system_session_ending`:

- **User-initiated close or Restart Manager `ENDSESSION_CLOSEAPP`:**
unchanged full cleanup (`Shell_NotifyIcon(NIM_DELETE)`,
`close_settings_window()`, and `QuickAccessHost::stop()`).
- **Full OS shutdown, sign-out, or restart:** posts `WM_QUIT` without
waiting on child processes the OS is already reaping in parallel.

### Scope and follow-up

This PR intentionally fixes the highest-volume contributor: the
always-on runner. Native module processes with their own windows/message
loops require module-specific review before adopting the pattern; that
inventory and rollout is tracked in #49539.

### Why not centralize handling inside `run_message_loop`?

`WM_QUERYENDSESSION` / `WM_ENDSESSION` invoke the WndProc directly
during `GetMessage`; they do not appear as a `MSG` returned to the loop.
Handling must therefore live in, or be called from, each relevant
WndProc.

## Tests

8 focused tests in `src/common/UnitTests-CommonUtils/Window.Tests.cpp`:

| Test | Guards |
|---|---|
| `HandleStatelessSessionEndMessage_QueryEndSession_AllowsShutdown` |
`WM_QUERYENDSESSION` returns `TRUE`. |
| `HandleStatelessSessionEndMessage_EndSessionCancelled_DoesNotTearDown`
| `WM_ENDSESSION(FALSE)` does not destroy the window. |
|
`HandleStatelessSessionEndMessage_EndSessionConfirmed_TearsDownAndExitsLoop`
| `WM_ENDSESSION(TRUE)` destroys the window and exits before the longer
timer fallback. |
| `HandleStatelessSessionEndMessage_UnrelatedMessage_NotHandled` |
Unrelated messages fall through untouched. |
|
`HandleStatelessSessionEndMessage_EndSessionConfirmed_SignalsSystemSessionEnding`
| A full session end enables the no-wait teardown path. |
|
`HandleStatelessSessionEndMessage_CloseApp_DoesNotSignalSystemSessionEnding`
| Restart Manager closes the window while retaining normal child
cleanup. |
|
`HandleStatelessSessionEndMessage_EndSessionCancelled_DoesNotSignalSystemSessionEnding`
| Cancelled shutdown does not flag teardown. |
|
`HandleStatelessSessionEndMessage_QueryEndSession_DoesNotSignalSystemSessionEnding`
| The query phase does not flag teardown. |

**Build:** `runner.vcxproj` and `UnitTests-CommonUtils.vcxproj` build
clean (`x64|Release`). The 8 focused tests pass.

## Manual validation

1. Build PowerToys and start the runner.
2. Initiate a sign-off (`logoff`) or restart.
3. Confirm Event Viewer (`Windows Logs → Application`) shows no
`Application Hang` event for `PowerToys.exe`.
4. Right-click tray → Exit: confirm Settings.exe and the Quick Access
host shut down gracefully and no ghost tray icon remains.

(#48378 additionally captured real logoff/restart runs showing
`WM_ENDSESSION → WM_DESTROY` completing in 1–8 ms with no hang
events—the same full-session path used here.)

## Quality checklist

- [x] Linked work item: AB#55588441
- [x] Module follow-up: #49539
- [x] Cross-references #41260; supersedes #48378
- [x] Unit tests (8 in `Window.Tests.cpp`)
- [x] No new binaries
- [x] Localization: no end-user strings changed
- [x] Shared helper documents its stateless contract

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 8d70b986-081a-43dd-bbfd-7e6351baef7a
2026-07-28 19:58:00 -07:00
Clint Rutkas
6d89ade9ad Fix PT Run ThreadPool worker leak from stale query cancellation (#48394)
## Summary

Fixes a ThreadPool worker leak in PowerToys Run that can eventually
surface as `System.OutOfMemoryException` from `Thread.StartInternal`
after rapid typing and repeated stale-query cancellation.

Related: #36041 and duplicate reports #45704, #36587, #39942, #20264,
and #8878.

## Root cause

`MainViewModel.QueryResults` stored the active cancellation token in a
mutable field. When a new query replaced that field, older workers could
observe the new, non-cancelled token instead of the token belonging to
their own query. The previous `CancellationTokenSource` was also
disposed while its consumers could still be running.

As stale queries accumulated, they continued invoking plugins and
consuming ThreadPool workers until the process could no longer create
another worker thread.

## Changes

- Adds `QuerySession`, which owns one captured token and the complete
task lifetime for a query. Superseded sessions are cancelled immediately
and their token sources are disposed only after their work completes.
- Uses a suspended session start so query state is published before
workers can return results.
- Adds generation checks before scheduling and applying work so
superseded queries cannot enqueue stale plugin tasks or update current
results.
- Adds a per-plugin execution gate. Calls to the same plugin do not
overlap, while unrelated plugins can execute independently; cancelled
waiters do not occupy ThreadPool workers.
- Preserves legacy `IResultUpdated` compatibility by correlating
generation-0 events using `RawQuery`.
- Preserves the original two-phase query contract: all non-delayed
plugin queries complete and their results are applied before delayed
queries start. Delayed queries remain globally parallel, and
`noInitialResults` is computed from the complete non-delayed phase.
- Cancels and performs a bounded wait for the active query during
shutdown.

## Tests

`Wox.Test`: **142/142 passing** locally.

Coverage includes:

- token ownership, cancellation, deferred disposal, shutdown timeout,
and suspended session startup;
- current-query generation matching and legacy generation-0
compatibility;
- per-plugin execution gating and queued latest-query behavior;
- deterministic verification that delayed queries cannot start until
every non-delayed query completes.

## Manual validation

1. Hold a key in PowerToys Run for 10–15 seconds and confirm the
PowerToys Run process thread count stabilizes instead of growing
monotonically.
2. Exercise normal Calculator, file, web, and indexer queries.
3. Enable search query tuning and waiting for slow results; confirm
results appear and final sorting completes.
4. Start a slow query and type again before it completes; only the
newest query should update results.
5. Exit PowerToys with a query in flight; shutdown should complete
cleanly without orphaned processes.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Copilot-Session: 54e1bb28-edae-496b-8211-0e1592ddc985
2026-07-28 07:49:05 -07:00
Clint Rutkas
44fd627c3a Tighten IContextMenu::GetCommandString in Image Resizer (#48399)
## Summary

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

## Changes

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

## Validation

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-07-28 07:47:29 -07:00
Clint Rutkas
0d335ffbbd Add Peek.Common unit tests (MathHelper, PathHelper) (#49105)
## Summary

Adds a **Peek.Common.UnitTests** project (MSTest) with unit coverage for
Peek.Common.Helpers:

- **MathHelper.Modulo** — positive/zero results, negative-dividend
wrap-around, large values, and the new non-positive-divisor guard.
- **MathHelper.NumberOfDigits** — single/multi-digit, negative, and 9/10
& 99/100 boundary values.
- **PathHelper.IsUncPath** — standard UNC, subfolders, dotted-server and
IP hosts, plus negatives: drive-letter, relative, empty, HTTP URL,
ile:// URI, single backslash, and null.

Also adds a small correctness guard to MathHelper.Modulo: a non-positive
divisor now throws ArgumentOutOfRangeException instead of silently
throwing DivideByZeroException (b == 0) or returning a misleading result
(b < 0). Registers the test project in `PowerToys.slnx` (ARM64 + x64).

**37 tests pass** locally (x64 Debug).

## Context

This is a clean, **tests-only split of #46684** (the Peek.Common
portion), intentionally **without** the bundled global dependency bump
from that PR. The PowerAccent.Core portion of #46684 was shipped
separately in #49104.

## Test coverage

| Area | Tests |
|------|-------|
| MathHelper.Modulo / NumberOfDigits | included |
| PathHelper.IsUncPath | included |

No production behavior changes beyond the Modulo argument guard, which
is covered by the new tests.

Co-authored-by: Clint Rutkas <crutkas@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-07-28 07:46:33 -07:00
Clint Rutkas
7afcb8ce42 Fixing a WindowBase warning during compile (#49049)
Removing a warning that pops up a lot.

**With fix:**
<img width="694" height="674" alt="image"
src="https://github.com/user-attachments/assets/2a496935-0d4b-45e6-97f2-62b8d4004faa"
/>

**Without fix:** here it is commented out to show the warning. 
<img width="1033" height="654" alt="Screenshot 2026-06-30 111523"
src="https://github.com/user-attachments/assets/5d8f5df9-3c45-4155-a995-4b666df894fd"
/>

Found conflicts between different versions of "WindowsBase" that could
not be resolved.
There was a conflict between "WindowsBase, Version=4.0.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35" and "WindowsBase,
Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35".
"WindowsBase, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" was chosen because it was primary and
"WindowsBase, Version=5.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" was not.
References which depend on "WindowsBase, Version=4.0.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35" [C:\Program
Files\dotnet\packs\Microsoft.NETCore.App.Ref\10.0.8\ref\net10.0\WindowsBase.dll].
C:\Program
Files\dotnet\packs\Microsoft.NETCore.App.Ref\10.0.8\ref\net10.0\WindowsBase.dll
Project file item includes which caused reference "C:\Program
Files\dotnet\packs\Microsoft.NETCore.App.Ref\10.0.8\ref\net10.0\WindowsBase.dll".
C:\Program
Files\dotnet\packs\Microsoft.NETCore.App.Ref\10.0.8\ref/net10.0/WindowsBase.dll
References which depend on or have been unified to "WindowsBase,
Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" [].

C:\Users\crutkas\.nuget\packages\microsoft.web.webview2\1.0.3719.77\lib_manual\net5.0-windows10.0.17763.0\Microsoft.Web.WebView2.Wpf.dll
Project file item includes which caused reference
"C:\Users\crutkas\.nuget\packages\microsoft.web.webview2\1.0.3719.77\lib_manual\net5.0-windows10.0.17763.0\Microsoft.Web.WebView2.Wpf.dll".

C:\Users\crutkas\.nuget\packages\microsoft.web.webview2\1.0.3719.77\buildTransitive\..\\lib_manual\net5.0-windows10.0.17763.0\Microsoft.Web.WebView2.Wpf.dll
2026-07-28 07:45:56 -07:00
Clint Rutkas
021ca6aee0 Add Runner C++ hotkey conflict unit test seed (#48352)
Adds the C++ counterpart to #48346: a focused Runner native unit-test
seed for core hotkey conflict behavior.

Why this one:
- Runner is core infrastructure rather than another C# module test.
- It adds the missing native C++ test-project path for Runner.
- The seed test is deterministic and covers in-app hotkey conflict
detection.
- It keeps the active rollout to two PRs: one C# module-services PR
(#48346) and one C++ core/runner PR.

Validation:
- `tools\build\build.ps1 -Platform x64 -Configuration Debug -Path
src\runner\UnitTests`
- `vstest.console.exe x64\Debug\tests\Runner\Runner.UnitTests.dll
/Tests:HasConflict_TwoModulesSameHotkey_InAppConflict` → 1 passed

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-28 07:45:20 -07:00
Clint Rutkas
7f1cdece68 Update SharpCompress to 0.50.1 (#49520)
## Summary of the Pull Request

Updates `SharpCompress` from **0.37.2** to **0.50.1** (latest listed
stable) and migrates Peek's `ArchivePreviewer` to the renamed APIs.

0.37.2 is subject to
[GHSA-6c8g-7p36-r338](https://github.com/advisories/GHSA-6c8g-7p36-r338)
(moderate severity), which currently produces an `NU1902` warning on
restore. This upgrade clears it.

The bump also required a real behavioral fix: `.tar.gz` / `.tgz`
previews break outright on 0.50.1 without it. Details below.

## PR Checklist

- [ ] Closes: #xxx <!-- N/A: no tracking issue, this is a
dependency/security bump -->
- [ ] **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 <!-- See "Validation Steps
Performed" - Peek has no unit test project today, so this was validated
with a differential harness. Happy to add coverage if desired. -->
- [x] **Localization:** All end-user-facing strings can be localized
<!-- N/A: no strings added or changed -->
- [ ] **Dev docs:** Added/updated <!-- N/A -->
- [ ] **New binaries:** Added on the required places <!-- N/A: no new
binaries. SharpCompress.dll already ships with Peek; only its version
changes. -->
- [ ] [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 -->

## Detailed Description of the Pull Request / Additional comments

Two files change:

**`Directory.Packages.props`** - central version pin moves `0.37.2` to
`0.50.1`. `Peek.FilePreviewer.csproj` needs no edit because its
`PackageReference` is versionless under Central Package Management.


**`src/modules/peek/Peek.FilePreviewer/Previewers/Archives/ArchivePreviewer.cs`**
- the only SharpCompress consumer in the repo.

### API renames

Verified by reflecting over the shipped 0.50.1 assembly rather than
guessing:

| 0.37.2 | 0.50.1 |
|---|---|
| `ArchiveFactory.Open(...)` | `ArchiveFactory.OpenArchive(...)` |
| `ReaderFactory.Open(...)` | `ReaderFactory.OpenReader(...)` |
| `IArchive.TotalUncompressSize` | `IArchive.TotalUncompressedSize` |

`ArchiveEncoding`, `ReaderOptions.Forced`, and
`IEntry.Key`/`Size`/`IsDirectory` are unchanged, so the existing zip
CP437 encoding-probe logic ported over without modification.

### Behavioral fix: `.tar.gz` / `.tgz`

The renames alone are not sufficient. On 0.50.1,
`ArchiveFactory.OpenArchive` can no longer open a gzip-compressed tar as
a random-access archive; it throws `ArchiveOperationException: Cannot
determine compressed stream type`. On 0.37.2 the same call succeeded and
returned `type=Tar`.

I probed six alternatives before settling on a fix: `OpenArchive(path)`,
`ExtensionHint="tar.gz"`, `ExtensionHint=".tar.gz"`,
`LookForHeader=true`, the `FileInfo` overload, and `OpenReader`. Only
`ReaderFactory.OpenReader` works.

The branch is now forward-only through `OpenReader`, and the
`OpenArchive` + `stream.Seek(0)` preamble is removed.

This path is user-reachable, so the break would have shipped:
`FileItem.Extension` returns `.gz` for `foo.tar.gz`, and `.gz` is in
`_supportedFileTypes`, so Peek does preview these files.

### Incidental correctness fix

While rewriting that branch, the reported size changes. The old code
used `archive.TotalUncompressSize`, which for a `.tar.gz` reported the
size of the intermediate **tar container** rather than the sum of the
entries. It now accumulates `reader.Entry.Size`, so the footer
count/size line is correct for these archives.

## Validation Steps Performed

`Peek.FilePreviewer` builds clean (x64 Release) resolving SharpCompress
0.50.1.

Peek has no unit test project, and the only archive coverage in
`Peek.UITests` is `Peek.FilePreview.ZIPArchive`, which previews
`TestAssets\7.zip` and asserts via screenshot comparison. There is no
`.tar.gz` test asset, so nothing in the existing suite would have caught
the regression above.

Given that, I validated with a standalone differential harness that
replicates `LoadPreviewAsync` verbatim and runs it against **both**
0.37.2 and 0.50.1 over the same set of archives, comparing entry names
and sizes:

| Archive | 0.37.2 | 0.50.1 |
|---|---|---|
| `test.zip` | `sub/nested.txt (19)`, `hello.txt (11)`, total 30 |
identical |
| `utf8.zip` | names correct | names correct |
| `sjis.zip` | `日本語/テスト.txt` correct | identical |
| `short.zip` | `caf‚.txt`, `na‹ve.md`, `a¤o.log` (mangled, detected
windows-1252) | `café.txt`, `naïve.md`, `año.log` (correct, detected
utf-8) |
| `test.tar.gz` | opens, total 4096 (container size) | opens, total 30
(correct) |
| `test.tar` | ok | ok |
| `hello.gz` | ok | ok |

All entry names and sizes match. 0.50.1 is strictly more correct on
short non-ASCII entry names and on `.tar.gz` sizing.

One subtle difference worth flagging for reviewers: on `utf8.zip`,
0.50.1 honors `ArchiveEncoding.Forced` even for UTF-8-flagged zips, so
the strict CP437 round-trip no longer throws and `encodingDetermined`
comes back `false` where it was `true` before. The decoded names are
still correct, because charset detection then correctly identifies
UTF-8. No tested case produced wrong output.

Manual validation: previewed `.zip`, `.tar`, `.tar.gz`, and `.gz` files
in Peek.

`NOTICE.md` lists SharpCompress by name without a version, so it needs
no update.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: cb1e58a5-de5b-420e-8153-ef9b15810211
2026-07-28 07:44:33 -07:00
moooyo
130a77907b [Keyboard Manager] Build the WinUI 3 editor self-contained to fix launch crash (0xC0000409) (#49524)
## Summary of the Pull Request

`PowerToys.KeyboardManagerEditorUI.exe` fail-fasts with `0xC0000409`
(`STATUS_STACK_BUFFER_OVERRUN`) during `MainWindow` construction, so the
new Keyboard Manager editor never opens.
`KeyboardManagerEditorUI.csproj` was the **only WinUI 3 executable in
the repo missing
`<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>`**, so it
was built framework-package-dependent and mixed two Windows App SDK
provenances in one process.

## PR Checklist

- [x] Closes: #49399
- [ ] **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
<!-- no user-facing strings added -->
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places <!-- no new
binaries -->
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx

## Detailed Description of the Pull Request / Additional comments

### Root cause

The reporter's WinDbg capture shows a first-chance `Core::ApiException`
carrying `0x800704DF` (`ERROR_ALREADY_INITIALIZED`):

```
MainWindow.SetTitleBar
-> Microsoft.UI.Xaml.Window.set_ExtendsContentIntoTitleBar
-> Microsoft.UI.Input!InputNonClientPointerSourceWinRTStatics::GetForWindowIdHelper
-> Microsoft.UI.Windowing.Core!RegisterWindowFeature
-> Core::NamedApiObject::Init
-> Core::ApiException
```

`ExtendsContentIntoTitleBar` is the **site**, not the cause — it is
simply the first user statement that crosses XAML -> Windowing -> Input.


`microsoft.windowsappsdk.foundation/*/buildTransitive/Microsoft.WindowsAppSDK.BootstrapCommon.targets`
turns the bootstrapper on precisely when this project's shape is hit:

```xml
<PropertyGroup Condition="'$(WindowsAppSdkBootstrapInitialize)'=='' and '$(WindowsAppSDKSelfContained)'!='true' and '$(WindowsPackageType)'=='None' and ('$(OutputType)'=='Exe' or '$(OutputType)'=='Winexe')">
    <WindowsAppSdkBootstrapInitialize>true</WindowsAppSdkBootstrapInitialize>
</PropertyGroup>
```

That compiles in `MddBootstrapAutoInitializer.cs`, which joins the
machine-wide `Microsoft.WindowsAppRuntime` MSIX framework package to the
process package graph before `Main`. Meanwhile the exe's own directory —
`WinUI3Apps` — is first in the Win32 DLL search order and already
contains a complete app-local Windows App SDK payload, deployed there by
the other 14 self-contained apps. One process, two Windows App SDK
provenances, and the one-time feature-type registration in
`Microsoft.UI.Input` collides.

The omission was easy to miss: the project imports
`src\Common.SelfContained.props`, whose name suggests it covers this —
but it only sets the **.NET** `<SelfContained>` property, which is
unrelated.

This also explains why the reporter could not shake it off: the
framework package is machine state, so uninstall/reinstall and wiping
`%LOCALAPPDATA%\Microsoft\PowerToys` change nothing. The classic C++
editor is unaffected because it uses WinUI 2 XAML Islands and ships no
Windows App SDK at all. `PowerToys.Settings.exe` ran healthily in the
same elevated session on the same day while doing strictly more
title-bar work (it sets `ExtendsContentIntoTitleBar` twice and drives
`InputNonClientPointerSource.GetForWindowId` on every `SizeChanged`) —
because it *is* self-contained.

### Two additional defects fixed

Both were found while investigating why the crash left no diagnostics at
all:

1. **`App.xaml.cs` initialized the logger via fire-and-forget
`Task.Run`** — the only one of ~30 `Logger.InitializeLogger` call sites
in the repo to do so. That races window creation, and `Logger` has no
buffering or replay (`Trace.WriteLine` straight through, listener
attached in `InitializeLogger`), so anything logged before the listener
is attached is lost permanently. This is why the user's bug report
bundle contains a `WinUI3Editor` log for the day it worked and **no log
file at all** for the day it crashed. Made synchronous, ordered to match
`FileLocksmithXAML/App.xaml.cs`, plus a log line before the window is
constructed.

2. **`MainWindow` never called
`WindowHelpers.ForceTopBorder1PixelInsetOnWindows10`**, unlike the other
PowerToys WinUI 3 module windows (AdvancedPaste, EnvironmentVariables,
FileLocksmith, Hosts, ImageResizer, Peek, RegistryPreview, Settings). It
is a no-op on Windows 11 and fixes the black top border from
microsoft/microsoft-ui-xaml#6901 on Windows 10 — the OS this issue was
reported against. Happy to drop this hunk if reviewers prefer a minimal
diff.

Deliberately **not** done: wrapping `new MainWindow()` in `try/catch`.
The failure is a WIL `RaiseFailFastException`, which managed code cannot
intercept; and swallowing managed exceptions there would leave a
windowless zombie process still holding the runner's `m_hEditorProcess`
handle, making the runner take its "editor already open" branch and
breaking every subsequent launch. That is why #49477 cannot work.

### Repo-wide audit

All 15 WinUI 3 executables (`UseWinUI=true` and `OutputType=WinExe`)
were checked. **KeyboardManagerEditorUI was the only one missing the
property**; the other 14 already set it. Also verified as correct and
unchanged: the 7 WinUI class libraries (property is app-level, N/A),
`runner.vcxproj` and `PowerRenameUI.vcxproj` (native exes, both already
`true`), and `PowerToys.MeasureToolCore.vcxproj` / `FindMyMouse.vcxproj`
(deliberately `false` — in-proc module DLLs whose host already
establishes the self-contained context).

There is no repo-level default or build guard for this property; it is
hand-copied into 17 project files, which is how the hole opened. A
`Directory.Build.targets` guard that errors when an unpackaged Windows
App SDK executable omits it would prevent recurrence, but it would catch
nothing today, so I left it out of this PR to keep the diff scoped.
Happy to open it separately.

## Validation Steps Performed

Built `KeyboardManagerEditorUI.csproj` (x64/Debug) and diffed the build
output before and after the change:

| | before | after | `PowerToys.Hosts.exe` (reference) |
|---|---|---|---|
| `obj\x64\Debug\Manifests\` (created only by `CreateWinRTRegistration`)
| absent | **present** | present |
| `activatableClass` registrations embedded in the exe | **0** |
**1912** | 1912 |
| assembly references `Microsoft.WindowsAppRuntime.Bootstrap.Net` /
`MddBootstrap` | **yes** | **no** | no |

The editor now resolves every `Microsoft.UI.*` activation app-locally
through registration-free WinRT instead of the machine framework
package, which removes the mixing hazard.

**Not yet validated on Windows 10.** I do not have a Windows 10 19045
machine, so the crash repro itself is unverified end-to-end. The
deployment-mode change is verified from build output as above;
confirmation from the issue reporter would be valuable. A useful
discriminator if anyone has the reporter's ProcDump dump: `lm v m
Microsoft.UI.*` — if `Microsoft.UI.Input.dll` is listed twice from two
different paths, the mechanism is confirmed directly.

Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-07-28 08:00:36 +00:00
Clint Rutkas
837fe46ed3 Add Awake module services unit test seed (#48346)
Adds an Awake module-services unit-test seed for runtime state creation
from timed settings. This is product/module coverage, not Settings UI
model serialization.\n\nValidation:\n- Restored and built
Awake.ModuleServices.UnitTests x64 Debug\n- Ran the filtered test
CreateState_TimedSettings_ReturnsTimedStateWithDuration: 1 passed

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-28 15:24:28 +08:00
Clint Rutkas
7ddfd2f3e0 [Updater] Open PowerToys handle before WM_CLOSE to avoid PID-recycle race (#46973)
Narrows this PR to @yeelam-gordon's review feedback.

The wait-for-exit before launching the installer is **already in
`main`** (landed separately), so the original change here is now
redundant. What's **not** in main is the PID-recycle hazard Gordon
flagged, so this PR applies just that fix:

Open the PowerToys process handle **before** sending `WM_CLOSE`.
PowerToys can exit inside its own `WM_CLOSE` handler, after which the OS
may recycle its PID — opening by PID afterwards could then fail or
attach to an unrelated process that reused it, and `WaitForSingleObject`
would wait on the wrong thing. Holding the handle first anchors the
kernel object to the original process, so PID reuse is impossible while
we wait on it.

Rebased onto latest `main` (resolves the previous merge conflict).

Originally fixes #46966.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-27 09:36:21 -07:00
Jiří Polášek
e7b3346aff CmdPal: Improve performance of Window Walker extension (#49317)
## Summary of the Pull Request

This PR improves performance of Window Walker, to make it faster (or at
least make it look like it is faster).

- Adds cached Window Walker list items and window snapshots for faster
page loading.
- Changes window enumeration to refresh asynchronously without blocking
initial results.
- Adds lazy, sequential icon loading with cached icon data.
- Reuses existing list items when window metadata changes.
- Fixes incorrect destruction of borrowed window icon handles.

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

- [x] Closes: #49315
<!-- - [ ] 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-07-27 06:35:29 -05:00
Niels Laute
346b498fb5 Shortcut Guide: Replace dual windows with single transparent overlay and add holding windows button (#48683)
## Summary

Refactors Shortcut Guide from two separate `WindowEx` instances
(`MainWindow` + `TaskbarWindow`) into a single full-monitor transparent
`OverlayWindow` that hosts both surfaces as XAML UserControls. This
enables shared animations and a more polished visual experience, and
makes the taskbar shortcut indicators **edge-aware** for Windows 11's
top/bottom/left/right taskbar positioning.



https://github.com/user-attachments/assets/e40a25f6-4ab3-4073-b1a8-906ef7782877


<img width="507" height="968" alt="image"
src="https://github.com/user-attachments/assets/2e06a3d9-32d9-482e-90fe-1f0f8a7d7598"
/>


## Changes

Closes: #48435
Closes #48491
Closes: #49200
Closes: #48552 (theme flash on Light/System theme + shortcut-list scroll
flutter)
Closes: #48773

### Architecture
- **OverlayWindow**: Single transparent host covering the full monitor
work area, using `TransparentTintBackdrop`
- **MainPaneControl**: The shortcut list pseudo-window, reusing the
shared `TransientSurface` control for chrome (acrylic backdrop, theme
shadow, rounded corners)
- **TaskbarPaneControl + TaskbarIndicator**: Tooltip-style indicators
with triangle tails, positioned above taskbar buttons

### Edge-aware taskbar indicators (Windows 11 top/bottom/left/right)
- Detects the taskbar edge via the public, documented `SHAppBarMessage`
/ `ABM_GETTASKBARPOS` API (the same API CmdPal Dock uses)
- Indicators lay out along the correct axis — horizontally for a
top/bottom taskbar, vertically for a left/right taskbar — with the
triangle tail always pointing toward the taskbar (4-direction tail +
per-edge slide-in animation)
- For a left/right taskbar, the main pane is inset so the order reads
**taskbar | indicators | pane**
- **Adaptive sizing**: each indicator's body size is derived from the
actual measured UIA taskbar button rect, so the bubbles shrink when
Windows uses small icons or combines buttons (many apps open). Uses the
smallest button slot (clamped to a readable range) so neighbouring
bubbles never overlap; the font scales with it

### Visual polish
- Windows 11 system flyout entry/exit animations (slide + fade, ~367ms
entrance / ~200ms exit with cubic easing)
- Animation direction is position-aware (slides from left when
left-aligned, from right when right-aligned)
- Taskbar indicators slide in from the taskbar edge with the same timing
- Close button on the main flyout title bar

### Robustness
- Multi-monitor DPI handling via WM_DPICHANGED suppression (prevents
double-scaling on cross-monitor moves)
- Win11 phantom border elimination (comprehensive DWM/style stripping)
- Click-outside-to-close with animated exit transition
- Process lifetime fix (`Application.Current.Exit()` on close)

## Validation
- Build clean (x64 Debug, exit 0, empty errors log)
- Tested on multi-monitor mixed-DPI setup (150% + 100%)
- Tested with the taskbar docked to each edge (top/bottom/left/right)
and with small/combined taskbar icons

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Noraa Junker <noraa.junker@outlook.com>
Co-authored-by: Clint Rutkas <clint@rutkas.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-07-27 12:21:35 +02:00
Clint Rutkas
d7afa69048 Fix _snwprintf_s size argument in BugReportTool EventViewer (#48398)
## Summary

Caught while reading through `BugReportTool` for an unrelated review:
the two `_snwprintf_s` calls in `EventViewer.cpp` pass `sizeof(buff)` as
the buffer-size argument, but `buff` is a `wchar_t[1000]`.
`_snwprintf_s` measures its size and count arguments in **wide
characters**, not bytes, so the current code advertises a 2000-wchar
destination for a buffer that only holds 1000.

`cpp
wchar_t buff[1000]; // 2000 bytes, 1000 wchars
memset(buff, 0, sizeof(buff));
_snwprintf_s(buff, sizeof(buff), fmt, ...); // <-- 2000 passed as wchar
count
`

If the formatted output ever exceeds 1000 wchars, the Secure CRT bounds
check fires (in debug) and - depending on which `_snwprintf_s` overload
the compiler selects against the safe template - it can write past the
end of the stack buffer in release. Neither format string here is likely
to produce 1000+ characters in practice (one substitutes a process name,
the other a channel name + integer), so this is more of a latent footgun
than a known crash, but the bounds are simply wrong.

## Fix

Use `_countof(buff)` for the size argument (which is what `_snwprintf_s`
actually wants - element count, not byte count) and pass `_TRUNCATE` for
the count so output is safely capped at 999 wchars plus the null
terminator:

`cpp
_snwprintf_s(buff, _countof(buff), _TRUNCATE, fmt, ...);
`

Applied to both `GetQuery` and `GetQueryByChannel`.

## Scope

Searched the rest of the repo for the same pattern (`_snwprintf_s(buf,
sizeof(...))` / `_snprintf_s(buf, sizeof(...))`) - these two call sites
are the only occurrences in the codebase.

## Validation

- `BugReportTool.sln` rebuilds clean locally (Release|x64) and produces
`PowerToys.BugReportTool.exe`.
- No behavior change on the happy path - both formats are well under
1000 wchars in normal use.

## Risk

Low. Two-line change in a single utility that builds event-log queries
for bug reports. Truncation on overflow is strictly safer than the prior
behavior.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-27 12:20:13 +02:00
Jeremy Sinclair
354a43bd8c [Deps] Update .NET packages from 10.0.9 to 10.0.10 (#49419)
## Summary of the Pull Request

Updates the centrally pinned .NET 10 `Microsoft.*` packages in
`Directory.Packages.props` from `10.0.9` to `10.0.10`.

## PR Checklist

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

## Detailed Description of the Pull Request / Additional comments

Bumps the .NET 10 `Microsoft.*` package pins from `10.0.9` to `10.0.10`
to match the latest servicing release.

## Validation Steps Performed

Not run locally here; change is a package version bump only.

Co-authored-by: Copilot <copilot@github.com>
2026-07-27 10:48:20 +08:00
John Surles
fc680d350f [Quick Accent] Fix window width when descriptions are disabled (#49402)
## Summary of the Pull Request

Fixes Quick Accent clipping or horizontally shifting the last character
when Unicode descriptions are disabled and the character list is short.

The WinUI window width was calculated as `item count × 48 DIPs`, but the
selector surface also has 24-DIP left and right margins and a 1-DIP
border on each side. Those values reduced the usable list width.
Fractional layout rounding at scaled display settings could then leave
the viewport one physical pixel too narrow even after accounting for the
nominal XAML dimensions.

The sizing calculation now reads the surface's live horizontal margin
and border thickness and includes them in the requested window width. It
also adds a 1-DIP layout-rounding allowance so the character list is not
truncated at fractional display scales.

## PR Checklist

- [x] Closes: #49346
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- The proposed root cause and approach were posted in the [contribution
thread](https://github.com/microsoft/PowerToys/issues/28769#issuecomment-5013633279);
maintainer confirmation is still pending.
- [ ] **Tests:** Added/updated and all pass
- No automated test was added because this fix connects runtime WinUI
layout values and display scaling to the window-size calculation; a unit
test that duplicated the XAML dimensions would not catch the integration
regression.
- [x] **Localization:** All end-user-facing strings can be localized
  - No strings changed.
- [x] **Dev docs:** Added/updated
- No developer documentation changes are needed for this focused layout
correction.
- [x] **New binaries:** Added on the required places
  - No binaries or projects were added.
- [x] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries — not applicable
- [x] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder — not applicable
- [x] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects — not applicable
- [x] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
— not applicable
- [ ] **Documentation updated:** Not applicable; there is no user-facing
behavior or documentation change.

## Detailed Description of the Pull Request / Additional comments

`SelectorControl.xaml` gives the `TransientSurface` a
`Margin=24,24,24,16`, and `DefaultTransientSurfaceStyle` supplies a
1-DIP border on each side. For the four-character reproduction in
#49346, the previous calculation requested a 192-DIP window (`4 × 48`).
After the 48 DIPs of horizontal surface margin, only 144 DIPs remained
for the list, which is exactly three character cells.

`SelectorControl` now exposes the computed left-plus-right surface
margin and border thickness internally. `MainWindow.SizeAndPosition()`
adds that live overhead to the character-driven width before applying
the existing description minimum and monitor-width clamp. A further
1-DIP allowance covers fractional physical-pixel rounding at scaled
display settings.

With four characters, the calculation reserves the complete 192-DIP list
width, the 50-DIP surface overhead, and the 1-DIP layout-rounding
allowance. This leaves long-list scrolling, selected-character
scrolling, description sizing, monitor clamping, DPI conversion, and
window positioning unchanged.

## Validation Steps Performed

- `git diff --check` passes.
- Built `PowerAccent.UI` locally with Visual Studio 2026 in `Debug|x64`;
the build completed successfully with 0 warnings and 0 errors.
- Runtime-tested with Unicode descriptions disabled and only `SPECIAL`
enabled. Holding `X` and pressing `Space` displayed all four mapped
characters (`ẋ`, `×`, `ˣ`, `ₓ`) without clipping or scrolling.
- Reproduced the one-pixel horizontal shift with all character sets
enabled at 150% and 175% display scaling.
- Retested the 1-DIP layout-rounding allowance at both 150% and 175%;
all seven `F` characters remained stationary while cycling through the
selection.
- Verified the description minimum and maximum monitor-width clamp
remain in the same order after the corrected content width is
calculated.

---------

Co-authored-by: Dave Rayment <dave.rayment@gmail.com>
2026-07-23 05:39:32 +08:00
Jiří Polášek
b69bfe7f86 CmdPal: Replace custom sign(x) function with built-in sgn(x) function (#49392)
## Summary of the Pull Request

This PR allow use of built-in `sgn` function in exprtk in Calculator and
uses it to implement `sign` function.

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

- [x] Closes: #49391 
<!-- - [ ] 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-07-21 10:30:04 -05:00
Jiří Polášek
c87ef67103 CmdPal: Ensure visual state groups set properties exclusively (#49319)
## Summary of the Pull Request

This PR updates DockItemControl to ensure that visual state groups
exclusively set properties and don't overlap to prevent unexpected and
undeterministic result.

- TextVisibilityStates and TextAlignmentStates shared
SubtitleText.Visibility
- TextVisibilityStates and IconVisibilityStates shared
ContentGrid.ColumnSpacing

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

- [x] Closes: #47980
- [x] Closes: #49156
<!-- - [ ] 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-07-21 10:29:03 -05:00
Jiří Polášek
bc32d4216c CmdPal: Prevent selection from overriding ListView scrolling (#49354)
## Summary of the Pull Request

This PR make ensuring selected item visibility on the list view optional
and avoids it when user scrolls list view viewport manually (using
scrollbar or mouse wheel), without touching selection.

- Implicitly keep selection when using incrementel loading (incrementel
loading)
- Make ensuring the selected item is visible optional, and skip it when
the user scrolls the ListView viewport using the scrollbar or mouse
wheel


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

- [x] Closes: #46592
<!-- - [ ] 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-07-21 10:25:09 -05:00
Jiří Polášek
526216562b CmdPal: Deduplicate Windows Settings based on title and target (#49340)
## Summary of the Pull Request

This PR prevent deduplication of Windows Settings items with the same
name but different targets.

For example, Display appears in both the System and Ease of Access
sections, along with 16 other duplicated settings.

- Deduplicates items based on both name and target.
- Adds an extra scoring hint for items with duplicate names.
- When the name matches, prefer Windows Settings over other sources.

## Pictures? Pictures!

| Before | After |
|--------|-------|
| <img width="1298" height="1246" alt="image"
src="https://github.com/user-attachments/assets/9ff67756-7f03-49f8-994c-cdb17fdd589b"
/> | <img width="1286" height="1240" alt="image"
src="https://github.com/user-attachments/assets/7105cfea-84c2-4edf-971d-c1b47859cc8e"
/> |

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

- [x] Closes: #49335
<!-- - [ ] 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-07-21 10:24:09 -05:00
Rishabh Jain
ccb647b2f0 Spec: Power Display ambient-light (ALS) adaptive brightness for external monitors (#49199)
## Summary

Design spec for **ambient-light (ALS) adaptive brightness for external
monitors** in Power Display, as discussed and agreed in #49038.

The feature continuously maps the device''s ambient light sensor reading
(the same ALS **Light Switch** already reads) to each external
monitor''s brightness over **DDC/CI** (the path **Power Display**
already uses) — i.e. auto-brightness for external monitors, the
continuous/sensor-driven counterpart to the schedule-based #47480.

This PR adds only the spec doc
(`doc/specs/power-display-adaptive-brightness.md`), per the repo''s
spec-first process (`doc/specs/readme.md`). No code.

## What the spec covers

- **Core model** — a single per-monitor formula: `target =
clamp(curve(lux) + offset, min, max)`.
- **Per-monitor calibration curve** — the mechanism that keeps
differently-behaving panels visually matched across the whole ambient
range.
- **Per-monitor offset** — live, phone-style personalization; manual/CLI
nudges become an offset (default) with an optional `pause` behaviour.
- **Live slider UX** — when adaptive is on, the slider reflects the
computed value and dragging it sets the offset.
- **Sensor trust & lifecycle** — lid-closed / clamshell detection
(`GUID_LIDSWITCH_STATE_CHANGE` + `QueryDisplayConfig`), hold-last-good
instead of dimming to black, and honest fallbacks.
- Smoothing/hysteresis/rate-limiting for flicker- and wear-safe DDC/CI
writes, settings persistence, telemetry, a11y/localization, risks, and
phased delivery.

## Discussion / sign-off

Behaviour was reviewed with @moooyo on #49038 (configurability,
CLI/manual +/- while adaptive, slider behaviour) — agreed to proceed.

Closes nothing yet; tracks #49038. Related: #47480, #42566, #35564.

---------

Co-authored-by: Rishabh Jain <14334305+MrRishabhJain@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-21 09:21:44 +00:00
Jiří Polášek
babf5792d2 CmdPal: Fix dock item titles and icons for bookmarks (#49336)
## Summary of the Pull Request

This PR adds a specialized wrapper for bookmarks so they are displayed
correctly in the dock's Add band flyout.

Bookmark items are updated lazily. When a WrappedDockItem was created
and its properties were locked in place, the bookmark's icon and title
had not yet been resolved.

- Adds BookmarkDockItem, a specialized version of WrappedDockItem that
updates when the underlying bookmark changes.
- Ignores the temporary "Reloading" bookmark icon and provides a
fallback bookmark icon.

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

- [x] Closes: #49025
<!-- - [ ] 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-07-17 15:41:08 -05:00
Subhro-ai
bf14ebcec9 [CmdPal Calculator] Add reciprocal/inverse trig functions and n-th log/root; fix inverse function parse errors (#49356)
## Summary of the Pull Request

Adds the missing trigonometric functions requested in #47093 to the
Command Palette calculator, and fixes a regression where **all inverse
trig/hyperbolic functions (`arcsin`, `arccos`, `arctan`, `arsinh`,
`arcosh`, `artanh`) silently failed with a parse error**.

**Bug fix:** since the mages → exprtk migration (#39972), the
user-facing inverse-function names have still been accepted by input
validation (`CalculateHelper.cs`) — they are native Mages function names
and worked before the swap — but nothing maps them to exprtk's built-in
names (`asin`, `acos`, `atan`, `asinh`, `acosh`, `atanh`), so exprtk
returns a compile error and the calculator shows no result. The existing
unit tests only covered the string transformation
(`UpdateTrigFunctions`), never evaluation, so this went unnoticed. This
PR registers the user-facing names as engine aliases and adds
evaluation-level regression tests.

**New functions:**
- `cot`, `sec`, `csc` — exprtk-native; unblocked in input validation and
wired into the degree/gradian trig-unit conversion
- `arccot`, `arcsec`, `arccsc` — added to the engine (`arccot` uses
`atan2(1, x)` for the continuous (0, π) branch, so `arccot(0) = π/2` and
negative inputs land in (π/2, π)); also wired into trig-unit conversion
- `coth`, `sech`, `csch` and `arcoth`, `arsech`, `arcsch` — added to the
engine (hyperbolic, so no angle-unit conversion, consistent with
`sinh`/`arsinh`)
- `logn(x, base)` and `root(x, n)` — exprtk-native, unblocked in input
validation (covers the "logarithm of n-th power" / "root of n-th degree"
asks in the issue)

## PR Checklist

- [x] Closes: #47093
- [x] **Communication:** The issue is labeled `Help Wanted` ("We
encourage anyone to jump in on these and submit a PR.")
- [x] **Tests:** Added/updated and all pass
- [ ] **Localization:** No new end-user-facing strings (error paths
reuse existing localized messages)
- [ ] **Dev docs:** n/a
- [ ] **New binaries:** n/a
- [ ] **Documentation updated:** The docs page listing calculator
functions may need updating; happy to file the docs PR once this is
reviewed.

## Detailed Description of the Pull Request / Additional comments

- `src/common/CalculatorEngineCommon/ExprtkEvaluator.cpp`
- Registers aliases `arcsin/arccos/arctan/arsinh/arcosh/artanh` →
`std::asin/acos/atan/asinh/acosh/atanh` (the bug fix).
- Adds `coth/sech/csch` (reciprocal hyperbolics),
`arccot/arcsec/arccsc`, and `arcoth/arsech/arcsch`, which exprtk does
not provide.
- `Microsoft.CmdPal.Ext.Calc/Helper/CalculateHelper.cs`
  - Whitelists the new function names in the input-validation regex.
- Adds `cot/sec/csc` (argument conversion) and `arccot/arcsec/arccsc`
(result conversion) to the degree/gradian handling in
`UpdateTrigFunctions`. The existing `(?<!c)` look-behind logic correctly
keeps `cot`↔`arccot`, `sec`↔`arcsec`, `csc`↔`arccsc`, and `cot`↔`coth`
etc. apart (covered by tests).
- `Microsoft.CmdPal.Ext.Calc/Helper/NumberTranslator.cs`
- Adds the new names to the function-arity table so argument-separator
protection works in decimal-comma locales (e.g. `logn(8; 2)` in de-DE).
- The `log(` → `log10(` remapping in `CalculateEngine.cs` does not touch
`logn(` (regex requires `(` directly after `log`); covered by a passing
check.

Behavior at undefined points maps to the existing error messages:
`cot(0)`/`csch(0)` → ∞ → "out of bounds" error; `arcsin(2)`,
`arcsec(0.5)`, `arcoth(0.5)` → NaN → "not a number" error (all covered
by tests).

PowerToys Run is unaffected: it still uses the Mages engine, which
already supports the inverse-function names natively.

## Validation Steps Performed

- Unit tests added:
- Evaluation tests (`Interpret_NoErrors_WhenCalledWithRounding`) for all
new functions **and** for the previously broken inverse functions
(regression tests).
- `InputValid` acceptance tests for every new name and rejection tests
for bare names.
- `UpdateTrigFunctions` transformation tests for degrees and gradians,
including nesting (`sec(arcsec(2))`) and confirming hyperbolics are
untouched.
- End-to-end `TrigModeSettingsTest` rows through `CalculatorListPage`
(e.g. `sec(60)` = 2 in degrees, `arccot(1)` = 45°, `cot(50)` = 1 in
gradians).
- Error-path tests for `cot(0)`, `csch(0)`, `arcsin(2)`, `arcsec(0.5)`,
`arcoth(0.5)`.
- The modified `ExprtkEvaluator.cpp` was additionally exercised
standalone against the vendored `exprtk.hpp` with the exact parser
settings used in production: 27 evaluation cases (including degree-mode
composites exactly as `CalculateHelper` emits them) all pass, and all
expected values in the test `DataRow`s are taken verbatim from the
engine output.


### Screenshots
**Built and ran locally (Debug build — note the "DBG | NO AOT" badge in
the shots).**

**_Before (shipping 0.100.2 — these all fail):_**
<img width="786" alt="failed-arcsin"
src="https://github.com/user-attachments/assets/4116c428-2804-43d7-b04b-9b02f7d374cc"
/>
<img width="784" alt="failed-cot"
src="https://github.com/user-attachments/assets/b81d39df-dffd-4e8d-8af8-9d21552c5e89"
/>
<img width="784" alt="failed-logn"
src="https://github.com/user-attachments/assets/b2eec32c-95e8-4b0a-b44f-47a30193a012"
/>

**_After (this PR):_**
<img width="766" alt="arcsin"
src="https://github.com/user-attachments/assets/9d8b2235-1330-433d-b0d5-5ad2527c1c01"
/>
<img width="766" alt="cot"
src="https://github.com/user-attachments/assets/c2a4454f-1e46-4022-8107-7e0c9aff5a7e"
/>
<img width="767" alt="logn"
src="https://github.com/user-attachments/assets/e6476cb9-3bf5-40e0-9b45-08a0add42124"
/>
<img width="764" alt="root"
src="https://github.com/user-attachments/assets/97036055-1ee0-4355-b99f-891f4129e463"
/>
<img width="764" alt="sec1"
src="https://github.com/user-attachments/assets/b82119f4-e6bb-47a7-8da7-0c3fd1272d70"
/>
<img width="766" alt="sech"
src="https://github.com/user-attachments/assets/6363f938-8cbf-4d86-8784-d8288953786e"
/>

**_Recording_**


https://github.com/user-attachments/assets/42c11e25-c342-4461-a9d4-e40d836d060c

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 13:54:11 -05:00
Jiří Polášek
44ae9df5ef CmdPal: Prevent scaling empty icon size (#49385)
## Summary of the Pull Request

This PR prevents a crash caused by attempting to apply DPI scaling to an
empty icon. Size.Empty has width and height values of negative infinity.
Scaling those values still produces negative infinity, which is not
valid for a Size.

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

- [x] Closes: #49360
<!-- - [ ] 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-07-17 13:48:09 -05:00
Jiří Polášek
e6cd68e60e CmdPal: Remove [ComImport] from Bookmarks extension (#49357)
## Summary of the Pull Request

This PR fixes invalid Native AOT code generation issue in Bookmarks
built-in extension.

CommandLauncher+ApplicationActivationManager was marked with
[ComImport], not compatible with AOT.

```
29>  ILC: Method '[Microsoft.CmdPal.Ext.Bookmarks]Microsoft.CmdPal.Ext.Bookmarks.Helpers.CommandLauncher+ApplicationActivationManager+_ApplicationActivationManager..ctor()' will always throw because: Invalid IL or CLR metadata in 'Void _ApplicationActivationManager..ctor()'
```

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

- [x] Closes: #49355 
<!-- - [ ] 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-07-17 13:47:25 -05:00
Jiří Polášek
0425140cac CmdPal: Fix default alias mapping to commands (#49384)
## Summary of the Pull Request

This PR fixes an invalid command ID for the **Run** page in the default
alias map.

- Updates the map to use the new command ID.
- Adds a migration from the old command ID to the new one.
- Introduces shared constants for command IDs to help prevent future
regressions.
- Adds unit tests for the migration and to guard against future
regressions.

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

- [x] Closes: #49371
<!-- - [ ] 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-07-17 13:13:39 -05:00
Jake Scott
c2d505dd4d [CmdPal][Performance Monitor] Add disk activity monitoring (#48844)
<!-- 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: #46724
<!-- - [ ] 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
- (All Cmd Pal tests passed, but there were none specifically for
Performance Monitor)
- [X] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [X] **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
Added the ability to see the Disk Stats in the Performance Monitor of
Command Palette. It is also able to be pinned to the dock. It functions
similarly to the Network Stats, in that you can cycle between different
disks and can see the read & write speed.

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Ran the dev version of Command Palette and cycled through my devices
disk and compared them with Task Manager. Turned on the Dock and
compared the values with Task Manager as well on all my disks.

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-07-17 12:56:24 -05:00
Jiří Polášek
dc330354a0 CmdPal: Upgrade AdaptiveCards nuget packages (#49362)
## Summary of the Pull Request

This PR upgrade Adaptive Cards nugets packages to the latest versions:

- Upgrades the three Adaptive Cards packages:
    - AdaptiveCards.ObjectModel.WinUI3: 2.0.0-beta -> 2.0.2-beta
    - AdaptiveCards.Rendering.WinUI3: 2.1.0-beta -> 2.2.4-beta
    - AdaptiveCards.Templating: 2.0.5 -> 2.0.6
- Upgrades Microsoft.Bot.AdaptiveExpressions.Core to 4.23.1.
- Since the new packages uses portable RIDs, nuget will automatically
handle the copying of matching dll and we can remove workaround for
that.

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

- [x] Closes: #49361
- [x] Fixes: #49359
- [x] Fixes: #48800
<!-- - [ ] 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
- I've opened the Settings pages for all built-in extensions.
- I've opened all forms.
- I've opened all sample forms and content pages.
2026-07-17 09:59:37 -05:00
Clint Rutkas
f81689de3a [PowerDisplay] Drop redundant hardcoded PlatformToolset (inherit Cpp.Build.props) (#49370)
## Summary

Remove the redundant hardcoded `<PlatformToolset>v143</PlatformToolset>`
from two C++ projects so they inherit the toolset from the shared
`Cpp.Build.props` like every other project.

## Why

`Cpp.Build.props` is force-imported into **every** C++ project via
`Directory.Build.props`:

```xml
<ForceImportBeforeCppProps>$(RepoRoot)Cpp.Build.props</ForceImportBeforeCppProps>
```

MSBuild imports it during `Microsoft.Cpp.props` — i.e. *after* each
project's own PropertyGroups — and it sets the toolset for the whole
repo:

```xml
<PlatformToolset>v143</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '18.0'">v145</PlatformToolset>
```

Two projects set `<PlatformToolset>v143</PlatformToolset>` directly in
their Configuration PropertyGroups:

-
`src/modules/powerdisplay/PowerDisplayModuleInterface/PowerDisplayModuleInterface.vcxproj`
(Debug + Release)
- `src/common/UnitTests-CommonUtils/UnitTests-CommonUtils.vcxproj`

That value was dead config — the force-imported prop already overrode it
to `v145` on VS2026 (v18). The other module interfaces (Awake,
FancyZones, …) don't set `PlatformToolset` at all; these two were just
over-specified VS-template projects.

## Change

Delete the redundant `PlatformToolset` lines so both projects inherit
from `Cpp.Build.props`.

## Validation

Built both projects locally with VS2026 (v18), Release x64, with no
`PlatformToolset` in the vcxproj:
- Both resolve to the `v145` toolset (MSVC `14.51`, `VC\v180`) via the
force-imported prop.
- Both produce their DLLs with no errors
(`PowerToys.PowerDisplayModuleInterface.dll`,
`Common.Utils.UnitTests.dll`).

## Risk

Very low — no change to the produced binaries (effective toolset is
unchanged); this just removes dead config and makes these two projects
consistent with the rest of the repo.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-17 16:49:00 +08:00
Pratyush Nalam
9b654d21d2 Fix GPU Stats not cycling through multiple GPUs (#48503)
## Summary of the Pull Request

Command Palette's Performance Monitor dock band exposes "Previous GPU" /
"Next GPU" commands, but on multi-GPU machines they did nothing and only
one GPU was ever shown.

Root cause: `GPUStats` keyed GPUs by the `phys_N` token in the "GPU
Engine" perf-counter instance names, assuming it enumerated physical
adapters. On modern Windows that token is effectively always `phys_0`
(verified on a desktop with an RTX 4090 + AMD iGPU — all 1640 instances
were `phys_0`), so every adapter collapsed into one bucket and the
reported usage was the *sum* across adapters. The real per-adapter
identifier is the LUID.

----------
_Note from 6/24 after latest rebase on top of #48710_: Rebased onto
latest main, which now includes #48710 ("CmdPal: Accurate GPU usage in
Dock"). The two changes overlap in GPUStats.GetData(), so I merged them
rather than picking a side — #48710's accuracy fix is fully preserved,
just re-keyed.

#48710 buckets utilization by (physId, engineId), takes the max engine
per adapter, and clamps to [0, 100]. The catch is that phys_N is
effectively always phys_0 on modern Windows (the exact reason this PR
switched to LUID keying), so on a multi-GPU machine #48710 alone still
collapses all adapters into one bucket. So I kept its max-per-engine +
clamp + NaN/negative filtering verbatim and only changed the key from
(phys, engine) to (LUID, engine). Net result: each adapter is tracked
separately and reports a correct, bounded 0–100% value.

Verified on a desktop with an RTX 4090 + AMD Radeon iGPU:

Prev/Next GPU cycles between the two adapters (WARP hidden).
GPU usage stays ≤ 100% under load and matches Task Manager.
Load on the 4090 doesn't move the idle iGPU's reading (per-adapter
independence holds).
No other behavior from #48710 changed.

----------

## PR Checklist

- [x] Closes: #47583 
- [x] **Communication:** Posted in #28769
- [x] **Tests:** No tests exist for
`Microsoft.CmdPal.Ext.PerformanceMonitor` so did not add any.
- [ ] **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

- Key GPUs by **LUID** (parsed from the instance name) instead of
`phys`.
- Resolve friendly adapter names via DXGI
(`IDXGIFactory1`/`IDXGIAdapter1` through CsWin32, AOT-safe) and **filter
out software adapters** (Microsoft Basic Render Driver / WARP).
- Discover adapters on each tick as well as at construction, so a GPU
that registers counters later still appears.
- Show the active GPU's name in the dock band subtitle so cycling is
visible.
 
## Validation Steps Performed

Tested on a desktop (RTX 4090 + AMD Radeon iGPU). Prev/Next GPU now
cycles between "NVIDIA GeForce RTX 4090" and "AMD Radeon(TM) Graphics",
each showing its own utilization; WARP is hidden.
2026-07-16 21:44:53 -05:00
moooyo
5c9c93d56d feat(powerdisplay): add CLI for monitor control (#48632)
## Summary of the Pull Request

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

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

## PR Checklist

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

## Detailed Description of the Pull Request / Additional comments

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

## Validation Steps Performed

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

---------

Co-authored-by: Yu Leng <yuleng@microsoft.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-16 23:08:27 +08:00
Moli
85d0c890de Docs: Fix broken links and incorrect source file references (#49294)
## Description

Fixes #49285

This PR fixes three documentation files with broken links or incorrect
source file references:

### 1. `doc/devdocs/modules/fileexploreraddons.md` — broken source code
link

The "Source code folder" link pointed to
`src/modules/fileexplorerpreview`, which does not exist in the
repository. Changed to `src/modules/previewpane` (the actual directory).

### 2. `doc/devdocs/modules/launcher/plugins/calculator.md` — broken
unit test links (10 occurrences)

All 10 links in the "Unit Tests" section pointed to
`Microsoft.PowerToys.Run.Plugin.Calculator.UnitTests` (plural), but the
actual test project directory is
`Microsoft.PowerToys.Run.Plugin.Calculator.UnitTest` (singular). All
link references have been corrected.

### 3. `doc/devdocs/core/runner.md` — incorrect file reference

The "Centralized Keyboard Hook" section referenced
`centralized_keyboard_hook.cpp`, but the actual file is
`centralized_kb_hook.cpp` (at `src/runner/centralized_kb_hook.cpp`).

## Validation

Each fix was verified against the actual repository structure:

| Fix | Verified path exists |
|-----|---------------------|
| `fileexploreraddons.md` | `src/modules/previewpane/` (contains
`powerpreview/` subproject) |
| `calculator.md` |
`src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator.UnitTest/`
(contains `BracketHelperTests.cs`, `ExtendedCalculatorParserTests.cs`,
`NumberTranslatorTests.cs`, `QueryTests.cs`) |
| `runner.md` | `src/runner/centralized_kb_hook.cpp` |

## PR Checklist

- [x] Docs-only change — no code or tests affected
- [x] Links verified against actual repository structure
2026-07-16 12:50:09 +00:00
Noraa Junker
8746378762 [Monaco] Fix .uproject and .uplugin extensions registration (#49300)
<!-- 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 some wrong procedure in #47931

<!-- 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-07-16 13:55:29 +02:00
moooyo
2b8e6247fc [PowerDisplay] Add stable profile IDs (#49175)
## Summary of the Pull Request

Gives every saved PowerDisplay profile a stable, auto-incrementing
integer ID and makes the app address profiles by that ID instead of by
name. Duplicate profile names are allowed, renames preserve identity,
and LightSwitch stores stable profile references.

> Split out of the PowerDisplay CLI branch (#48632). CLI-specific
contracts and commands remain in that stacked PR.

## PR Checklist

- [x] **Closes:** N/A - split from #48632.
- [x] **Communication:** Discussed with core contributors.
- [x] **Tests:** Added and passing in `PowerDisplay.Lib.UnitTests`.
- [x] **Localization:** The composed profile label uses a shared
localized format resource.
- [x] **New binaries:** None.
- [x] **Documentation updated:**
`doc/devdocs/modules/powerdisplay/design.md`.

## Implementation

### Profile model and persistence

- `PowerDisplayProfile.Id` is the stable JSON `id`; `0` means
unassigned.
- `PowerDisplayProfiles.NextId` is monotonic and IDs are never reused.
- `SetProfile` assigns IDs to new profiles and replaces existing
profiles by ID.
- Duplicate names are supported; name lookup remains only for migration
of legacy references.
- `ProfileStore` serializes cross-process load/modify/save operations
with a named mutex and atomically replaces `profiles.json`.
- Production callers use asynchronous `ProfileHelper` APIs.

### Migration and application

- Initial PowerDisplay discovery assigns missing profile IDs and
migrates legacy monitor IDs.
- LightSwitch legacy name references are reconciled to IDs and written
back to the current typed settings schema.
- Native LightSwitch publishes pure light/dark theme events;
PowerDisplay exclusively validates profile enablement and stable IDs.
- Settings UI and Named Pipe ApplyProfile actions send invariant
positive profile IDs.
- PowerDisplay validates the ID, loads the current profile, and applies
its monitor settings.

### Settings UI

- Create, edit, apply, and delete operations use stable IDs.
- LightSwitch selectors store profile IDs and keep legacy name fields
only for migration.
- Profile lists use a localized name-and-ID label so duplicate names
remain distinguishable.

## Accepted Trade-offs

- Profile ID migration remains dependent on the initial monitor
discovery; a failed or delayed discovery can temporarily hide legacy
ID-less profiles.
- The one-time PowerDisplay LightSwitch migration rewrites the complete
current typed settings object and does not add a new cross-process
settings transaction.

## Validation

- Built the affected x64 Debug projects with the repository build
scripts.
- `PowerDisplay.Lib.UnitTests`: 186 passed, 0 failed.

---------

Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-16 14:33:21 +08:00
Dave Rayment
ec0830396b [QuickAccent] Clarify, expand and correct currency symbol mappings (#49343)
<!-- 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
After a review of the current currency-related mappings, this PR makes a
few corrections, adds explanatory comments where certain mappings may be
confusing, and adds a small number of new mappings to fill gaps and to
complete euro area country coverage for `€`.

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

1. Removed `z` from the Currency set. I think this was mistakenly added
alongside `ł` for the Polish Złoty (`zł`), but it's just a plain `z`
character so does not need to be present.
2. Added comments for all the characters in the currency set which do
not independently represent a currency. For example, c with caron `č` is
required for Czech Koruna (`Kč`), but `K` is a standard letter.
3. Added the Euro `€` character to the **E** key for the Greece set. It
has been the currency in Greece since 2001, so this was a real gap. Now
all the eurozone countries represented in Quick Accent have the same
mapping.
4. Added the Shekel (or NIS/ILS) `₪` to the Hebrew set.
5. Added the Dong `₫` to the Vietnamese set.

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Compiled and ran locally to confirm new additions were present:

<img width="750" height="108" alt="image"
src="https://github.com/user-attachments/assets/ce30e425-446f-4288-bb52-72e29768ef76"
/>


Confirmed all Quick Accent unit tests still ran successfully:

<img width="348" height="78" alt="image"
src="https://github.com/user-attachments/assets/b275a966-65d9-406e-838e-675b9dcd2c50"
/>
2026-07-16 14:29:24 +08:00
Dave Rayment
1f00859680 [Quick Accent] Correction and additions to Bulgarian key mappings (#49344)
<!-- 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 corrects the short I being present on the **I** key, and adds the
euro and common punctuation characters for the Bulgarian set.

<!-- 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
`й` was present in the Bulgarian set, which made no sense because every
Bulgarian keyboard layout includes the short I. This must have been a
mis-type for `ѝ`, which is present on most layouts, but absent on the
traditional non-BDS layout. This update replaces the short I with `ѝ`.

Bulgaria adopted the euro currency in January 2026, replacing the lev,
so including it on **E** makes sense, as it will become more and more
common in written communication and is not present on one of the
keyboard layouts.

Finally, Bulgarian typographic quotes (the `„` low-9 and `“` high-6) are
added, along with the double angle quotes for compatibility with other
Belarusian sets.

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

Compiled locally and checked that the new characters were available:
<img width="750" height="110" alt="image"
src="https://github.com/user-attachments/assets/d5ac0ac1-5814-492e-b2ba-e7747204e668"
/>

Confirmed that all unit tests still pass:

<img width="336" height="75" alt="image"
src="https://github.com/user-attachments/assets/eb4360c1-ac7e-4e5c-9cfb-a51a95c41c2a"
/>
2026-07-16 14:29:19 +08:00
Jiří Polášek
0bc78235cc CmdPal: Reorder CommandPalette.slnf (#49337)
## Summary of the Pull Request

This PR reorders the items in CommandPalette.slnf lexicographically
because:

1. It is easier to read.
1. Visual Studio goes bonkers and reorders them anyway, creating extra
noise in the diff.

Regressed in #49252

<!-- 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-07-15 11:18:44 -05:00