mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-09-01 19:51:34 +02:00
1980ca5ecef4e9fd1b9af45ba6c18eb893900a40
896 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
1980ca5ece |
[Runner][Interop] Authenticate Settings/Quick Access named-pipe clients before dispatch (CWE-732/CWE-862) (#49527)
## Summary of the Pull Request
The Runner is the **server** for the two-way named pipes it uses to talk
to `PowerToys.Settings.exe` and the Quick Access host, and it dispatched
privileged JSON commands (`killrunner`, `restart_elevation`,
`module_status`, `powertoys`, `language`, ...) **without authenticating
the caller**. When PowerToys runs elevated ("Run as administrator"), the
pipe DACL grants the shared **Logon SID**, so **any same-user Medium-IL
process could connect and inject commands** — a local privilege
escalation (CWE-732 / CWE-862). The pipe DACL cannot distinguish the
legitimate Medium-IL Settings child from a same-user attacker (identical
user SID, integrity level, and logon session), so this PR authenticates
the connecting process's **binary identity** before any dispatch.
## PR Checklist
- [x] **Tests:** Added/updated and all pass (native gate tests + C#
regression)
- [x] **Localization:** No new end-user-facing strings (only a
diagnostic runner log line)
- [x] **New binaries:** None — the new code compiles into the existing
`PowerToys.Interop` and `runner` binaries; tests were added to the
existing `Common.Utils.UnitTests` project
## Detailed Description of the Pull Request / Additional comments
New `src/common/interop/pipe_caller_auth.{h,cpp}` adds
`interop_auth::AuthenticateClient`, invoked from
`TwoWayPipeMessageIPC::handle_pipe_connection` **before** a message is
queued (fail-closed). A connecting client is accepted only if it is:
- under the **Runner-relative install directory**
(`get_module_folderpath()\WinUI3Apps`, so it adapts to installed and
dev-build layouts),
- an **allow-listed basename** (`PowerToys.Settings.exe` /
`PowerToys.QuickAccess.exe`),
- the Runner's **exact file version** (anti-downgrade), and
- **Microsoft Authenticode-signed**.
The signature is anchored to the **LOCAL MACHINE root store**
(`HCCE_LOCAL_MACHINE` +
`CertVerifyCertificateChainPolicy(AUTHENTICODE)`) rather than
`WinVerifyTrust`'s default user+machine union: the Runner runs as the
same user as a potential attacker and would otherwise trust a forged
signer added to `CurrentUser\Root`. Verdicts are cached per `(pid,
process-creation-time, policy)` with a short TTL so the check isn't
re-run on every message (each `send` opens a new connection). Rejections
are logged.
The gate is added via an **additive** `start(HANDLE, CallerPolicy)`
overload; the managed `start(nullptr)` path is unchanged (gate
disabled), so there is **no ABI break** to `PowerToys.Interop`.
`PIPE_REJECT_REMOTE_CLIENTS` is also set. In **Debug** builds only the
signature check is relaxed (directory/basename/version stay enforced) so
local unsigned builds still connect; the relaxation is compiled out of
Release.
**Scope:** this PR covers the two elevated Runner-server pipes (Settings
+ Quick Access), which are the actual EoP surface. The reverse
Runner->Settings response direction, the duplicated Workspaces
transport, and the AdvancedPaste/PowerDisplay module pipes are
intentionally out of scope and can be handled as follow-ups.
## Validation Steps Performed
**Automated**
- **Native unit tests** (`Common.Utils.UnitTests`,
`PipeCallerAuthTests`): legitimate self-caller accepted; wrong
basename/directory rejected with the reject-log callback firing; version
reading. 6/6 pass.
- **C# regression** (`Microsoft.Interop.Tests.TestSend`): managed
gate-disabled round-trip still works.
- **Builds:** runner Debug + Release, `PowerToys.Interop` Debug +
Release, and the test project all build/link clean.
**Official signed build (validates the Release-only signature path that
local Debug builds skip)**
- Queued the internal "PowerToys Signed YAML Release Build" for this
branch — **green** (`result: succeeded`). The produced installers are
Authenticode `Valid`, signer `Microsoft Corporation`.
**Manual testing on the signed installer (elevated Runner) — passed**
- Installed the signed build and ran the Runner **as administrator**.
Settings and Quick Access open and are fully functional; settings apply,
module toggles work, and the hotkey-conflict request/response
round-trips.
- **No** `Rejected unauthenticated ...` lines during legitimate use →
the genuine signed `PowerToys.Settings.exe` is accepted by the
machine-root signature + version + directory checks (verified in
`RunnerLogs\runner-log_*.log`, requests dispatched normally).
- **Security (negative) check:** a non-elevated `powershell.exe`
discovered the runner pipe via the pipe namespace and attempted
`{"killrunner":true}`; the write failed ("Pipe is broken") because the
Runner rejected the caller and disconnected before dispatch.
`PowerToys.exe` stayed running and logged: `Rejected unauthenticated
Settings pipe client: pid=... image='...\powershell.exe'
reason=bad-directory`.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1d8f85ec-aaee-468a-9348-ba79b059cbaf
|
||
|
|
ba2e89c428 |
PowerDisplay: Fall back to persisted VCP values when a monitor read fails (#49445)
## Summary of the Pull Request On a monitor whose DDC/CI engine answers intermittently, every discovery pass starts from nothing. A panel that reported its brightness a minute ago can lose that control — or drop out of the flyout entirely — because one pass happened to fail. This persists every range-valid VCP value read off a monitor, keyed by its canonical DevicePath. In Maximum compatibility mode a later discovery falls back to that value when the hardware will not answer. Scope is intermittent failure, not permanent failure: the cache can only replay a value the hardware answered at least once, so a panel that never reads a code successfully sees no change. This partially addresses #49342. ## PR Checklist - [x] Closes: #49342 - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [x] **Tests:** Added/updated and all pass - [x] **Localization:** All end-user-facing strings can be localized — this PR adds none - [ ] **Dev docs:** Added/updated - [x] **New binaries:** Added on the required places — none added, so no signing JSON, installer WXS or CI YML change is required - [ ] **Documentation updated** ## Detailed Description of the Pull Request / Additional comments ### What is stored `MonitorStateManager` implements `IKnownGoodVcpStore`, so the cache rides in the existing `monitor_state.json` next to the user's saved brightness rather than in a new file. Each entry is a `KnownGoodVcpFeature`: code, current, maximum, and when it was last read. Only range-valid observations are stored, so the common `current=0 / max=0` garbage reply never enters — it fails `VcpFeatureValue.IsValid`. Writes are not gated on Maximum compatibility mode, only reads are. A monitor that reads cleanly today can start failing after a cable or dock change, and a lazily populated cache would be empty on exactly the first pass that needs it. ### How a cached value is used `VcpDiscoveryEvidence.Reconcile` gains the cache as a third source alongside the parsed capabilities string and this pass's probe: | this pass | cache | result | | --- | --- | --- | | read succeeded | — | live value wins, cache refreshed | | replied, range unusable | hit | cached value applied, `MonitorReadFlags` left clear | | no reply | hit | cached value applied, `MonitorReadFlags` left clear | | code never probed (caps parsed) | hit | value applied only after one live read is attempted | The last row matters: on the caps-parsed path nothing has confirmed the cached value this pass, so the hardware is asked first. On the probe path it has already been asked, and re-reading would be pure I2C noise. `MonitorReadFlags` stays clear for anything the hardware did not answer, so a cached value never masquerades as an observation — which #49577 depends on, since it made the restore path write whenever the flag is unset. One consequence is worth naming: the flyout draws a slider at the cached position while `powerdisplay get` reports that setting as unknown, because `MonitorDtoProjector` gates on `supported && read`. ### Keeping the cache current `RefreshKnownGoodAfterWrite` restamps an entry after a successful `SetVCPFeature`, so a slider move cannot leave the cache holding the pre-write value. It refreshes only an entry a real read established, and only when the value was scaled against the maximum that entry holds — a monitor whose discovery read failed still carries a placeholder max, and writing that back would mis-scale every later write. `RemoveKnownGoodFeatures` clears the cache for monitors a settings reconciliation observably dropped, leaving the user's saved values alone. Cleanup is driven by an observed drop, never by absence from the rebuilt list: a missing or corrupt `settings.json` yields a defaults object indistinguishable from a real one, and pruning by absence would wipe every monitor not connected at that instant. A re-observation that changes nothing refreshes the in-memory timestamp but does not mark the file dirty, so a discovery pass no longer rewrites `monitor_state.json` for a moved timestamp alone. ## Validation Steps Performed - `PowerDisplay.Lib`, `PowerDisplay.Lib.UnitTests` and `PowerDisplay` built for x64 Debug with VS MSBuild — 0 errors, 0 warnings; `PowerDisplay.Lib.UnitTests.dll` under `vstest.console.exe`: **301 passed, 0 failed** - **Affected-hardware validation on the AOC Q27G3XMN is still pending.** That monitor, or an equivalent controllable DDC/CI setup, was not available locally. The paths this PR changes are reachable only on hardware whose capabilities string is unusable or whose VCP reads fail intermittently, so this is the main outstanding risk. --------- Co-authored-by: Yu Leng <yuleng@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Copilot-Session: 6ea38c04-6f68-4c42-91d9-8a03b49bdd81 |
||
|
|
160492abcf |
docs(skills): recommend WindowEx for WinUI 3 migrations (#49303)
## Summary of the Pull Request Updates the WPF-to-WinUI 3 migration skill to make the established PowerToys windowing pattern explicit: - Default WinUI 3 top-level windows to `WinUIEx.WindowEx` or an existing PowerToys base derived from it, such as `TransparentWindow` for transient overlays. - Keep supported size, presenter, title bar, topmost, backdrop, and persistence behavior declarative in XAML instead of manual `AppWindow` / `OverlappedPresenter` code-behind. - Document the centrally managed `<PackageReference Include="WinUIEx" />`, WPF-to-`WindowEx` property mappings, and existing repository examples. - Add a value-converter decision guide that prefers `VisualStateManager`, direct `x:Bind` conversion, WinUI theme resources, and `CommunityToolkit.WinUI.Converters` over mechanically porting WPF converters. This follows the migration-skill feedback from @niels9001 in [PR #49174](https://github.com/microsoft/PowerToys/pull/49174#discussion_r3535181101). ## PR Checklist - [x] **Communication:** This change follows review feedback from a core contributor in PR #49174. - [x] **Tests:** The updated guidance passed 5/5 fresh agent migration scenarios. - [x] **Dev docs:** Added/updated. ## Detailed Description of the Pull Request / Additional comments `SKILL.md` now states the default PowerToys pattern and limits raw `AppWindow` / presenter code to behavior that `WindowEx` does not expose. The package mapping reference records the exact centrally managed dependency. The windowing reference adds a complete XAML example, a WPF-to-`WindowEx` mapping table, regular-window examples, and the `TransparentWindow` overlay exception. The XAML migration reference now also documents converter selection and reuse: control state belongs in `VisualState`s, count visibility can share one Toolkit `DoubleToVisibilityConverter` with `ConverterParameter=True`, and corner-radius converter resources come from `XamlControlsResources`. This is an atomic documentation-only change; no product code or dependencies are modified. ## Validation Steps Performed - Verified the documented `WindowEx` APIs and `TransparentWindow` inheritance against the repository and compiled WinUIEx assembly. - Verified all cited repository paths, the Markdown anchor, and central package management entry. - Ran five fresh current-branch agent scenarios; all selected `<PackageReference Include="WinUIEx" />` without a version, `WindowEx`, XAML-declared properties, and `CenterOnScreen()` only where required. - Ran a focused converter migration scenario before and after the guidance update; the updated skill selected `VisualState`s, one reusable Toolkit numeric converter, and existing WinUI corner-radius resources without custom converters. - Ran `git diff --check` with no errors. - Completed an independent read-only review with no findings. - Product builds and unit tests were not run because this change only updates agent guidance. --------- Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: fe9b24eb-99f0-43e8-aaa4-839f4579f6f9 Copilot-Session: d5afc36b-3356-46af-b8cb-071b87a64532 |
||
|
|
8f63402400 |
PowerDisplay: Adjust brightness by scrolling over the tray icon (#49446)
## Summary of the Pull Request Scrolling the mouse wheel over the Power Display tray icon adjusts brightness, without opening the flyout. - New **Tray icon mouse wheel** setting: `Off` / `Primary display` / `All displays`, defaulting to **`Off`**. It is scoped to the tray icon — the flyout sliders accept wheel input regardless, as they always have. The existing **Mouse wheel increment** setting supplies the per-notch step. - **Off by default.** The gesture consumes a wheel notch that would otherwise reach the window under the pointer, and acting on it installs a system-wide `WH_MOUSE_LL` hook. Neither is something an existing installation should acquire silently on upgrade. With the setting `Off` no hook is ever installed and no notch is ever consumed, so this PR changes no existing behaviour until the user opts in: 1958 insertions, 2 deletions, and both deletions are refactors of lines this feature reuses. - **No feedback UI.** Brightness is self-evidencing — you scroll and the screen changes — so the display itself is the feedback. The notification icon is untouched: same tooltip, same text, same legacy notification-icon protocol. ## PR Checklist - [x] Closes: #49410 - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [x] **Tests:** Added/updated and all pass - [x] **Localization:** All end-user-facing strings can be localized - [x] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx No new binaries or projects — everything lands in existing assemblies. Communication is unchecked because #49410 is still Needs-Triage. ## Detailed Description of the Pull Request / Additional comments ### Why a low-level hook The Shell does not forward `WM_MOUSEWHEEL` to a notification icon's callback window under any `NOTIFYICON_VERSION`, and a click-through overlay placed over the icon cannot receive wheel input either. `TrayIconMouseWheelListener` therefore installs a `WH_MOUSE_LL` hook — but only transiently, and only when it will act on the result: - Nothing is installed at all while the setting is `Off`, which is the default. - Installed in `EnsureHook()` when the UI thread confirms the pointer is inside the rectangle from `Shell_NotifyIconGetRect` **and** `CanAdjustBrightnessFromTrayWheel` says some monitor can accept a brightness write. - Removed in `DisarmCore()` as soon as either condition stops holding, the pointer leaves the rectangle, or the mode changes. - A notch is consumed (the hook proc returns non-zero) only while armed and only for points inside the armed rectangle, so a wheel event Power Display will not act on still reaches the window under the cursor. The hook runs on a dedicated background thread with its own message loop; the proc itself only enqueues a sample and posts a drain request. Deltas are marshalled to the UI thread in batches, and `WheelDeltaAccumulator` folds high-resolution deltas (precision wheels, touchpads) into whole notches. Each sample carries the hover generation it was captured under, so samples from a hover the UI thread has already retired are discarded rather than applied late. ### Hover detection The Shell sends `WM_MOUSEMOVE` to the icon's callback window while the pointer is over it. `TrayIconService.HandleTrayMouseMove` resolves the rectangle with `Shell_NotifyIconGetRect` and caches it for a second, because that message repeats for every pixel of travel. `TrayIconService` gains nothing else: no protocol change, no new hover UI, no polling. The rest of the file — and `MainWindow.xaml` — is untouched. ### Linked brightness While linked brightness is on, a notch has to move the whole group, so it goes through `MainViewModel.LinkedBrightness` rather than the individual monitor setters. The new master value is taken from the planner's value for the monitor the wheel named, **not** from the current master. The master is positional only — `SeedInitialLinkedBrightness` takes it from the lowest-numbered linked monitor and never writes hardware, and every monitor-list rebuild re-seeds it — so it can sit arbitrarily far from the monitor the wheel is aimed at. Stepping it relative to itself would apply a wrong-sized or wrong-signed change, and a master already clamped at 0/100 would swallow the notch while writing nothing at all. The setting description calls out that linked brightness widens the scope, so `Primary display` is not literally a single display while it is on. ### What is deliberately not here An earlier revision of this PR showed the target and percentage in a custom overlay as you scrolled. Doing that meant the standard Shell tooltip would not do (it cannot be shown on demand), which meant an own window, which meant suppressing the Shell tooltip so the two did not collide, which meant `NOTIFYICON_VERSION_4`, which changed the callback packing and made the app responsible for all hover text — including for keyboard and touch users, who never reach a cursor-anchored overlay and would have been left with no visible tooltip at all. That chain was about half the diff, for a readout that adds little on top of watching the screen change. It is gone. If a readout is wanted later it can be argued on its own merits, separately from this feature. The same revision also gated the flyout sliders on this setting. That bundled two unrelated things behind one switch — turning off tray scrolling would also have stopped the contrast and volume sliders responding to the wheel — so the setting is now scoped to the tray icon and named accordingly. An earlier revision also routed the tray **Exit** action through `Shutdown()`. That fixes a pre-existing teardown leak which has nothing to do with this feature, so it now lives in #49580 and is out of scope here. This branch does not depend on it: the hook thread is a background thread and the process is ending either way. ## Validation Steps Performed - Unit tests: `PowerDisplay.Lib.UnitTests` 215 passed, `Settings.UI.UnitTests` 165 passed. - Builds: `PowerDisplay` and Settings UI, x64 Debug, no warnings. - Automated coverage is in `PowerDisplay.Lib.UnitTests`: target selection per mode, wheel accumulation including negative deltas, partial notches and direction reversal, half-open rectangle containment, and settings serialization and round-trip for the new mode, including that a settings file predating the feature loads as `Off`. `Settings.UI.UnitTests` covers the view-model index mapping and pins the enum values to the ComboBox item order. - The Win32 glue in `TrayIconService` and `TrayIconMouseWheelListener` is not unit tested. Manual passes performed: scrolling over the icon in both modes, the icon parked in the notification overflow, high-resolution wheel input, brightness boundaries, live monitor refresh while hovering, tray icon hidden and re-enabled, Explorer restart, the context menu and left-click, `Off` stopping tray scrolling while the flyout sliders keep working, and confirming a notch that Power Display will not act on still reaches the window under the cursor. Not verified, needing hardware this branch has not been run on: - Multiple taskbars, where the tray icon is on a secondary display and `Primary display` mode adjusts a monitor the user may not be looking at. - Mixed-DPI setups, for the `Shell_NotifyIconGetRect` rectangle and the hook's physical-pixel hit test. --------- Co-authored-by: Yu Leng <yuleng@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Copilot-Session: 5d7f36fe-d175-4aa9-a3c7-b370d952d1d3 |
||
|
|
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 |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
d5fe397b05 |
Follow-up: UITest framework Next - stability improvements (#49242)
This pull request addresses several CI flakiness and reliability issues in the UI test automation harness, especially around foreground window handling and build artifact resolution. The main improvements ensure that UI interactions (like real mouse clicks) reliably target the correct window, even in complex CI and build environments, and that test code accurately locates module executables regardless of output layout. **Foreground window handling and input reliability:** * Added `Session.EnsureForeground()` and improved `WindowControl.TryBringToForeground()` to reliably raise the target window above others, defeating the Win32 foreground lock using `AttachThreadInput` and related APIs. This prevents coordinate-based clicks from landing on the wrong window, a common cause of CI test flakiness. (`src/common/UITestAutomation.Next/Session.cs`, `src/common/UITestAutomation.Next/WindowControl.cs`, `src/common/UITestAutomation.Next/Element/Element.cs`, `.github/skills/ui-tests-migration/references/ci-stability.md`, `src/modules/MeasureTool/Tests/ScreenRuler.UITests.Next/TestHelper.cs`) [[1]](diffhunk://#diff-713524f4ead9951000b3578248f2740088729981051b68c3fa3655ebb548f20fR91-R118) [[2]](diffhunk://#diff-60be6ec24a99f8974cff00414fc47ea1e60e3ab9aee706b5d6845eb8df19165fR59-R76) [[3]](diffhunk://#diff-60be6ec24a99f8974cff00414fc47ea1e60e3ab9aee706b5d6845eb8df19165fL247-R332) [[4]](diffhunk://#diff-3c00581cb1d2b6a4302b8378b87c27cdad2f87c2aefc37eec0bdc6c39af9291aR100-R103) [[5]](diffhunk://#diff-98e5aea12baaac99aba10e7dd341ed3f2efdd24cb80b29306bb500816de09e2fR96-R114) [[6]](diffhunk://#diff-d8766b48614fe4a99e3f100e69e611ca2464de6ba0be257586c12d51f9278ed0L498-R504) **Build artifact and executable path resolution:** * Refactored `ModuleInfo.GetDevelopmentPath()` to dynamically walk up from the test assembly and find the module executable in various build output layouts, including CI artifacts and local builds. This eliminates hardcoded path offsets and makes test launches robust to different build structures. (`src/common/UITestAutomation/ModuleInfo.cs`) * Updated `ModuleConfigData.GetModulePath()` to use the improved path resolution and fall back to installed builds if necessary, ensuring that test runs can always locate the correct executable. (`src/common/UITestAutomation/ModuleConfigData.cs`) * Simplified `SessionHelper` so that `locationPath` is always empty, leveraging the fact that module paths are now absolute. (`src/common/UITestAutomation/SessionHelper.cs`) [[1]](diffhunk://#diff-c001f0fd3432c8b6102c3120597fc48f24902eaa0d755f51adfa7646344b3833L7-L10) [[2]](diffhunk://#diff-c001f0fd3432c8b6102c3120597fc48f24902eaa0d755f51adfa7646344b3833L46-R54) These changes collectively improve test reliability, especially in CI environments, and make the harness more resilient to changes in build output structure. --------- Co-authored-by: Boliang Zhang (from Dev Box) <bozhang@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
4881f23545 |
Add PR Needs-Author-Feedback lifecycle to fabricbot configuration (#49151)
## Summary Adds fabricbot rules to manage the `Needs-Author-Feedback` label lifecycle for **pull requests**, complementing the existing issue management rules in `resourceManagement.yml`. This is a **simpler alternative** to the GitHub Actions workflow approach (PR #48812), trading advanced features (draft conversion, author-specific activity tracking) for zero-maintenance fabricbot automation. ## Behavior ### Flow diagram ``` ┌──────────────────────────────────────────────────────────────────────┐ │ Maintainer adds "Needs-Author-Feedback" label to a PR │ └──────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────┐ ┌──────────────────────────────────┐ │ 7 days, no activity │────►│ Add "Status-No recent activity" │ │ │ │ + post warning comment │ └─────────────────────────────────────┘ └──────────────────────────────────┘ │ │ ▼ ▼ ┌─────────────────────────────────────┐ ┌──────────────────────────────────┐ │ 7 more days (14 total), no activity│────►│ Close PR + post closing comment │ └─────────────────────────────────────┘ └──────────────────────────────────┘ ┌──────────────────────────────────────────────────────────────────────┐ │ Author pushes commits OR comments on PR (at any point) │ └──────────────────────────────────────────────────────────────────────┘ │ ▼ Remove "Needs-Author-Feedback" → Add "Needs-Triage" Remove "Status-No recent activity" (if present) ``` ### Scheduled searches (every 6 hours) | Condition | Action | |-----------|--------| | PR + `Needs-Author-Feedback` + 7 days inactive + no `Status-No recent activity` | Add `Status-No recent activity` label + warning comment | | PR + `Needs-Author-Feedback` + `Status-No recent activity` + 7 more days inactive | Post closing comment + close PR | ### Event responders | Trigger | Action | |---------|--------| | Author comments on PR (`Issue_Comment` + `issueAuthor`) | Remove `Needs-Author-Feedback`, add `Needs-Triage` + `Needs-Team-Response` | | Author pushes commits (`Pull_Request` + `Synchronize` + `issueAuthor`) | Remove `Needs-Author-Feedback`, add `Needs-Triage` | | Any PR update activity | Remove `Status-No recent activity` | ### Bot messages **Warning (at 7 days):** > This pull request has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for **7 days**. It will be closed if no further activity occurs **within 7 days of this comment**. To keep this PR active, please push your changes or leave a comment. **Closing (at 14 days):** > This pull request has been automatically closed because it has been marked as requiring author feedback but has not had any activity for **14 days**. If you would like to continue working on this, please reopen the PR and push your changes. ## Comparison with GitHub Actions workflow (PR #48812) | Feature | This PR (fabricbot) | PR #48812 (Actions) | |---------|-------------------|-------------------| | Convert to draft at 7 days | ❌ Not supported | ✅ Via GraphQL | | Close at 14 days | ✅ | ✅ | | Author-specific activity tracking | ❌ Any activity resets timer | ✅ Only author activity counts | | Bot comment resets timer | ⚠️ Yes (fabricbot limitation) | ✅ No (filtered out) | | Maintenance burden | None (fabricbot managed) | Low (workflow file) | | Testing before merge | ❌ No local testing | ✅ `workflow_dispatch` + dry-run | | Review comment detection | ❌ Only issue comments | ✅ Reviews + inline comments | ## Trade-offs **Pros:** - Zero maintenance — fabricbot is a managed service - Consistent with existing issue management patterns in the same file - No workflow YAML to debug or maintain **Cons:** - No draft conversion (fabricbot cannot call GraphQL) - `noActivitySince` counts **all** activity — bot comments, maintainer comments, and label changes all reset the inactivity timer - Cannot distinguish author activity from other activity - No way to test locally or with dry-run before merge ## Relationship to existing automation Mirrors the existing issue rules (lines 11-43) which use the same pattern: - Issues: 5 days → warning, 5 more days → close - PRs (this change): 7 days → warning, 7 more days → close Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
85f698677a |
[UITests] AI migration skill + ScreenRuler tests example port. (#48842)
This PR is build on top of https://github.com/microsoft/PowerToys/pull/48717 and https://github.com/microsoft/PowerToys/pull/48467 It adds the ui-tests-migration skill which should be used to migrate the old UITest module by module to use new .Next UI framework. As an example, the screen ruller tests was ported here. --------- Co-authored-by: Boliang Zhang (from Dev Box) <bozhang@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
4395b1d0ca |
[skill] Generalize verification skill into 2 scenarios (module checklist / PR validation) (#48848)
## Summary of the Pull Request Generalizes the `powertoys-verification` agent skill from "one module checklist" into a **single shared engine that serves two verification scenarios**, using the *shared engine + per-scenario reference docs* design (no duplication of the winapp mechanics): - **A — Module checklist**: verify a supplied module checklist against the installed build. - **B — PR validation**: derive each PR's checklist from its description + diff, then drive it. A single **bits sub-decision** picks the target — drive the **installed** build when the PR's code is already shipped (a merged PR, or a whole release/hotfix set, e.g. the 0.100.1 14-PR sign-off), or **build + sideload** the affected module when it isn't (an unmerged or not-yet-released PR, e.g. #45242). Both scenarios share the same `winapp ui` drive techniques, helper scripts, per-module profiles, taxonomy, and report format. They differ mainly on **what bits you run**, so the only new content is a thin scenario layer. ## PR Checklist - [ ] **Closes:** N/A (follow-up to the merged `powertoys-verification` skill) - [x] **Communication:** design discussed and agreed before implementation - [x] **Tests:** N/A — docs/skill-only change; validated link/constraint checks (see below) - [x] **Localization:** N/A - [x] **Dev docs:** this PR *is* skill documentation - [x] **New binaries:** none ## Detailed Description of the Pull Request / Additional comments **`SKILL.md` (shared engine)** — broaden `description` + "When to use" to cover both scenarios, add a **Step-0 scenario router** (plus, for B, the bits sub-decision "is the PR's code in the build under test?"), keep the supplied-checklist read **Scenario-A-only**, and make the bootstrap/placeholders/"What NOT to do" scenario-aware. **`references/scenarios/`:** - `index.md` — router table (A/B); the **"bits under test" contract** (the one real conflict: installed-and-immutable, vs build-and-sideload when the PR's code isn't in the build, echoed in the report header so the evidence chain is trustworthy); and a verdict-vocabulary mapping (engine `PASS/FAIL/BLOCKED` <-> legacy labels). - `module-checklist.md` (A) — supplied checklist, installed bits. - `pr-validation.md` (B, **new — merges the former release-PR and active-PR docs**) — derive each PR's checklist from `gh pr view/diff`; the **bits sub-decision**; a **PR-discovery model with a size gate** (auto-verify hotfix-sized sets <=25; for full ~100-PR releases, scope-and-confirm instead of blind-looping) and a non-runtime-PR pre-filter; per-PR folders + roll-up; and the **build + sideload** front-end (in-repo worktree helper + build commands), unpackaged (run the built runner, dismiss the expected partial-build dialogs) vs packaged/CmdPal (`Add-AppxPackage -Register`) deploy recipes, prove-your-bits, and restore-to-shipped cleanup. Removed the separate `release-pr-signoff.md` and `active-pr-validation.md` (folded into `pr-validation.md`). The existing engine docs (`winapp-ui-testing.md`, `pre-flight.md`, `reporting-format.md`), per-module profiles, and helper scripts are reused unchanged — single source of truth. The `BITS:` header version is a `<version>` placeholder (not pinned to a release). ## Validation Steps Performed - `SKILL.md` within authoring limits: **331 lines** (< 500) and **description 999 chars** (< 1024). - All relative markdown links in `references/scenarios/*.md` resolve, and every engine doc they cite exists. - Scenario B exercised end-to-end both ways: the 0.100.1 14-PR sign-off (8 PASS / 6 BLOCKED, installed bits) and PR #45242 (Advanced Paste, 3/3 PASS, build + sideload). --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
f740d0b3e5 |
Build(deps): Bump actions/dependency-review-action from 4 to 5 (#47907)
Bumps [actions/dependency-review-action](https://github.com/actions/dependency-review-action) from 4 to 5. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/actions/dependency-review-action/releases">actions/dependency-review-action's releases</a>.</em></p> <blockquote> <h2>5.0.0</h2> <p>This is a new major version of the Dependency Review Action which updates the runtime to node24. This requires a minimum Actions Runner version <a href="https://github.com/actions/runner/releases/tag/v2.327.1">v2.327.1</a> to run.</p> <h2>What's Changed</h2> <ul> <li>Add .github/copilot-instructions.md for Copilot coding agent by <a href="https://github.com/ahpook"><code>@ahpook</code></a> in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1067">actions/dependency-review-action#1067</a></li> <li>Update Node.js runtime from 20 to 24 by <a href="https://github.com/scottschreckengaust"><code>@scottschreckengaust</code></a> in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1084">actions/dependency-review-action#1084</a></li> <li>Bump spdx-license-ids from 3.0.20 to 3.0.23 by <a href="https://github.com/mongolyy"><code>@mongolyy</code></a> in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1091">actions/dependency-review-action#1091</a></li> <li>docs: bump actions/checkout from v4 to v6 in workflow examples by <a href="https://github.com/Marukome0743"><code>@Marukome0743</code></a> in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1077">actions/dependency-review-action#1077</a></li> <li>fix: patched version display for advisories with non-strict semver ranges (e.g. Maven beta versions) by <a href="https://github.com/tspascoal"><code>@tspascoal</code></a> in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1076">actions/dependency-review-action#1076</a></li> <li>Resolve security findings by <a href="https://github.com/AshelyTC"><code>@AshelyTC</code></a> in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1094">actions/dependency-review-action#1094</a></li> <li>v5.0.0 release branch by <a href="https://github.com/ahpook"><code>@ahpook</code></a> in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1098">actions/dependency-review-action#1098</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/scottschreckengaust"><code>@scottschreckengaust</code></a> made their first contribution in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1084">actions/dependency-review-action#1084</a></li> <li><a href="https://github.com/mongolyy"><code>@mongolyy</code></a> made their first contribution in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1091">actions/dependency-review-action#1091</a></li> <li><a href="https://github.com/Marukome0743"><code>@Marukome0743</code></a> made their first contribution in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1077">actions/dependency-review-action#1077</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/dependency-review-action/compare/v4.9.0...v5.0.0">https://github.com/actions/dependency-review-action/compare/v4.9.0...v5.0.0</a></p> <h2>Dependency Review Action 4.9.0</h2> <p>This feature release contains a couple of notable changes:</p> <ul> <li>There is a new configuration option <code>show_patched_versions</code> which will add a column to the output, showing the fix version of each vulnerable dependency. Thanks <a href="https://github.com/felickz"><code>@felickz</code></a>!</li> <li>Runs which do not display OpenSSF scorecards no longer fetch scorecard information; previously it was fetched regardless of whether or not it was displayed, causing unneccessary slowness. Great catch <a href="https://github.com/jantiebot"><code>@jantiebot</code></a>!</li> <li>There are a couple of fixes to purl parsing which should improve match accuracy for <code>allow-package-dependency</code> lists, including case (in)sensitivity and url-encoded namespaces Thanks <a href="https://github.com/juxtin"><code>@juxtin</code></a>!</li> </ul> <h2>What's Changed</h2> <ul> <li>Compare normalized purls to account for encoding quirks by <a href="https://github.com/juxtin"><code>@juxtin</code></a> in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1056">actions/dependency-review-action#1056</a></li> <li>Make purl comparisons case insensitive by <a href="https://github.com/juxtin"><code>@juxtin</code></a> in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1057">actions/dependency-review-action#1057</a></li> <li>Feat: Add <code>Patched Version</code> to <code>Vulnerabilities</code> summary by <a href="https://github.com/felickz"><code>@felickz</code></a> in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1045">actions/dependency-review-action#1045</a></li> <li>fix: only get scorecard levels if user wants to see the OpenSSF scorecard by <a href="https://github.com/jantiebot"><code>@jantiebot</code></a> in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1060">actions/dependency-review-action#1060</a></li> <li>Bump actions/stale from 10.1.0 to 10.2.0 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1058">actions/dependency-review-action#1058</a></li> <li>Bump actions/checkout from 4 to 6 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1021">actions/dependency-review-action#1021</a></li> <li>Updates for release 4.9.0 by <a href="https://github.com/ahpook"><code>@ahpook</code></a> in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1064">actions/dependency-review-action#1064</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/jantiebot"><code>@jantiebot</code></a> made their first contribution in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1060">actions/dependency-review-action#1060</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/dependency-review-action/compare/v4.8.3...v4.9.0">https://github.com/actions/dependency-review-action/compare/v4.8.3...v4.9.0</a></p> <h2>4.8.3</h2> <h2>Dependency Review Action v4.8.3</h2> <p>This is a bugfix release that updates a number of upstream dependencies and includes a fix for the earlier feature that detected oversized summaries and upload them as artifacts, which could occasionally crash the action.</p> <p>We have also updated the release process to use a long-lived <code>v4</code> <strong>branch</strong> for the action, instead of a force-pushed tag, which aligns better with git branching strategies; the change should be transparent to end users.</p> <h2>What's Changed</h2> <ul> <li>GitHub Actions can't push to our protected main by <a href="https://github.com/dangoor"><code>@dangoor</code></a> in <a href="https://redirect.github.com/actions/dependency-review-action/pull/1017">actions/dependency-review-action#1017</a></li> <li>Bump actions/stale from 9.1.0 to 10.1.0 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/dependency-review-action/pull/995">actions/dependency-review-action#995</a></li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href=" |
||
|
|
74e6c3ad79 |
[UITests] New framework around WinApp CLI, no WinAppDriver or Selenium. (#48467)
# Add winappcli-based UI test harness (no WinAppDriver / Selenium) ## Summary Introduces a new UI test harness — `Microsoft.PowerToys.UITest.Next` — that drives PowerToys modules through Microsoft's [winappcli](https://github.com/microsoft/WinAppCli) (UI Automation CLI) instead of WinAppDriver + Selenium. Engine is a single executable shelled out from C#; no third-party NuGet packages, no driver process, no Appium server. Adds two real consumers: a full ColorPicker end-to-end scenario and a Settings shell navigation smoke test. This is opt-in and additive — the existing `UITestAutomation` library and the WinAppDriver-based test projects are untouched. Both can coexist while we evaluate the new harness. Inspired in part by [#48414](https://github.com/microsoft/PowerToys/pull/48414), which lands the same architectural bet (winappcli, AutomationId selectors, no WinAppDriver) at a smaller scope. This PR generalizes it into a reusable library. ## Why WinAppDriver + Selenium is a legacy pre-agentic solution that is no longer actively maintained. It's unreliable, heavyweight, and slow. To achieve 100% UI test coverage, we should leverage modern, reliable solutions, and WinApp CLI is a strong candidate. ## What's in this PR ### Harness library — [`src/common/UITestAutomation.Next/`](src/common/UITestAutomation.Next/) | File | Purpose | |---|---| | [`WinappCli.cs`](src/common/UITestAutomation.Next/WinappCli.cs) | Process wrapper around `winapp.exe`. `Invoke` / `InvokeAssertSuccess` / `InvokeJson` / `IsAvailable` / `TryResolveExecutable`. `Result` carries the args and emits `DescribeFailure()` like `winapp ui invoke X -w 12345 -> exit 1; stderr: ...` | | [`Session.cs`](src/common/UITestAutomation.Next/Session.cs) | Test session, scoped by either HWND (`-w`) or process (`-a`) via `TargetScope`. `Find<T>` / `FindAll<T>` / `Inspect` / `Screenshot` / `SendKeys`. `Session.FromProcess(...)` factory for the single-window-per-process case | | [`SessionHelper.cs`](src/common/UITestAutomation.Next/SessionHelper.cs) | Owns the launch + window-readiness flow. Static `EnsureRunning(scope, timeout)` returns whether the call had to launch (so cleanup only kills what we started). Uses `UseShellExecute=true` so child handles don't keep MSTest hanging | | [`UITestBase.cs`](src/common/UITestAutomation.Next/UITestBase.cs) | MSTest base class. Pre-flights `WinappCli.IsAvailable()` once per process and fails fast with the install hint if `winapp.exe` isn't on PATH | | [`Element/*.cs`](src/common/UITestAutomation.Next/Element/) | `Element`, `Button`, `ToggleSwitch`, `TextBox`, `NavigationViewItem`, `Window`. `Click` / `MouseClick` / `Focus` / `GetProperty` / `GetValue` / `HelpText` / `WaitForProperty` / `WaitForGone` plus coords (`X`/`Y`/`Width`/`Height`) | | [`By.cs`](src/common/UITestAutomation.Next/By.cs) | `By.Name` / `By.AccessibilityId` / `By.Id` / `By.Slug` | | [`Windows.cs`](src/common/UITestAutomation.Next/Windows.cs) | `WindowsFinder.ListAll` / `ListByApp` / `WaitForWindowByApp` / `WaitForWindowByProcess`. Notes the winappcli bug where unfiltered `list-windows` drops untitled windows | | [`WindowControl.cs`](src/common/UITestAutomation.Next/WindowControl.cs) | Tolerant Win32 helpers — `TryCloseByApp` / `TryFocusByApp` / `SafeCloseAndFocus` / `TryKillProcess` — for `finally` blocks | | [`KeyboardHelper.cs`](src/common/UITestAutomation.Next/KeyboardHelper.cs) | Hybrid `keybd_event` + `SendKeys.SendWait` chord sender — required for global PowerToys hotkeys | | [`MouseHelper.cs`](src/common/UITestAutomation.Next/MouseHelper.cs) | `MoveTo` / `LeftClick` / `RightClick` / `LeftClickAt` Win32 wrappers | | [`ClipboardHelper.cs`](src/common/UITestAutomation.Next/ClipboardHelper.cs) | STA-thread `Clipboard` access with `WaitForText` | | [`ModuleConfigData.cs`](src/common/UITestAutomation.Next/ModuleConfigData.cs) | `PowerToysModule` enum + path/process-name resolution | ### Tests **[`src/modules/colorPicker/ColorPicker.UITests/`](src/modules/colorPicker/ColorPicker.UITests/)** — replaces the previous empty `UITest-ColorPicker` stub. One test, [`ColorPickerEndToEndTests.NavigateReadShortcutActivateAndCapture`](src/modules/colorPicker/ColorPicker.UITests/ColorPickerEndToEndTests.cs), drives the full E2E: 1. Navigate to the Color Picker page via the dashboard utilities stack 2. Toggle the module OFF, verify `PowerToys.ColorPickerUI` exits; toggle ON, verify it respawns 3. Read the activation shortcut from the page's `ShortcutControl` (`EditButton.HelpText`) 4. Clear clipboard, park cursor, send the chord 5. Wait for the picker overlay window 6. Read the displayed HEX from a hidden XAML automation peer (see below) 7. Left-click to capture; assert the clipboard value matches the peer's HEX 8. Wait for the editor window and assert the captured color appears in its tree **[`src/settings-ui/Settings.UITests/`](src/settings-ui/Settings.UITests/)** — `SettingsNavigationSmokeTests.NavigationItem_NavigatesWithoutCrashing` is one `[TestMethod]` parameterized with `[DynamicData]`, producing 31 discrete results — one per `NavigationViewItem` in [`ShellPage.xaml`](src/settings-ui/Settings.UI/SettingsXAML/Views/ShellPage.xaml). For each item: navigate, settle 250ms, assert `PowerToys.Settings` is still alive. Catches FailFast regressions in `ShellViewModel.Frame_NavigationFailed` that pure-logic unit tests can't reach (the failure path needs a `NavigationFailedEventArgs` which is a sealed WinRT projection). ### Product change **[`src/modules/colorPicker/ColorPickerUI/Views/MainView.xaml`](src/modules/colorPicker/ColorPickerUI/Views/MainView.xaml)** — adds a hidden `TextBlock` automation peer: ```xml <TextBlock x:Name="ColorHexAutomationPeer" AutomationProperties.AutomationId="ColorHexAutomationPeer" IsHitTestVisible="False" Opacity="0" Text="{Binding ColorText}" /> ``` The visible `ColorTextBlock` has `AutomationProperties.Name="{Binding ColorName}"`, which masks the HEX value in the UIA tree (you see "White" instead of `#FFFFFF`). This zero-impact peer mirrors `ColorText` so tests can read the actually-displayed HEX. `Opacity=0` + `IsHitTestVisible=False` keep it out of the visual layout and out of accessibility focus. ### Project wiring - [`PowerToys.slnx`](PowerToys.slnx) — registers `UITestAutomation.Next` under `/common/`, `ColorPicker.UITests` under `/modules/colorpicker/Tests/`, and `Settings.UITests` under `/settings-ui/Tests/`. Original `UITest-ColorPicker` stub csproj removed. - [`.github/actions/spell-check/expect.txt`](.github/actions/spell-check/expect.txt) — adds `winapp` / `winappcli`. ### Not in this PR - No pipeline changes. `winapp.exe` is expected to be pre-staged on the test agent image. If it's missing, `UITestBase` fails the first test with the install hint (`winget install Microsoft.winappcli`) rather than producing 30 opaque per-test errors. - No changes to the legacy `UITestAutomation` library or any of the existing `*.UITests` projects. ## Validation - All three projects build clean on `x64|Debug` (empty `build.<config>.<plat>.errors.log`): - `src/common/UITestAutomation.Next/` - `src/modules/colorPicker/ColorPicker.UITests/` - `src/settings-ui/Settings.UITests/` - Both tests run in Test Explorer / `dotnet test` via Microsoft.Testing.Platform (already enabled repo-wide in `Directory.Build.props`). - Local runs: ColorPicker E2E green; Settings smoke green across all 31 nav items. - `winapp 0.3.2` from `winget install Microsoft.winappcli`. ## Notes for reviewers - **`UseShellExecute = true`** in `SessionHelper.EnsureRunning` is intentional — `false` makes child processes inherit the test host's stdin/stdout/stderr handles, which keeps MTP/Test Explorer marking the run as "in progress" until the spawned PowerToys exits. - **Process-scope (`-a`) targeting** in the Settings smoke test handles single-instance handoff: the EXE you launch may exit with code 0 immediately after signalling an existing owner, so the alive check uses `Process.GetProcessesByName` rather than the launcher PID. - **AutomationId-only selectors** in the Settings smoke list keep the test localization-independent. Parent groups have `SelectsOnInvoked="False"` and only expand on click — `Element.Click` tries `InvokePattern → TogglePattern → SelectionItemPattern → ExpandCollapsePattern` so the same call works for both leaves and groups. - **Untitled-window discovery**: filtered `winapp ui list-windows -a <name>` returns windows that the unfiltered call drops (e.g. ColorPicker editor). `WindowsFinder.ListByApp` uses the filtered form. Reported upstream. ## Before Merge - Add the `winappcli` install step to the UI-test pipeline. |
||
|
|
f5c6f50e30 |
[Quick Accent] Add Belarusian Latin and Belarusian Cyrillic character sets (#48344)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request This PR adds support for Łacinka (Belarusian Latin) and Belarusian Cyrillic character sets to Quick Accent. <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [x] Closes: #36571 <!-- - [ ] Closes: #yyy (add separate lines for additional resolved issues) --> - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [x] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed, or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments This is a standard character set addition, with new entries in the Language enum, the sets themselves added to CharacterMappings.All and new resource strings for the user-facing names in the Settings page. <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed (Manual tests.) - Confirmed that the new character set entries were present in the Quick Accent settings page list. - Tested that each of the characters in both the sets could be selected and typed. |
||
|
|
af45c3ec7c |
Add press-and-hold activation mode to Quick Accent (#48937)
## Summary of the Pull Request Adds an opt-in **press-and-hold** activation mode to Quick Accent, like iOS / macOS: hold an accent-capable letter (e.g. `a`) and after a short, configurable delay the accent picker opens automatically — no separate trigger key (Space/arrows) required. This is purely additive. The existing trigger-key modes (`Left/Right arrow`, `Space`, `Both`) and all serialized settings values are unchanged. https://github.com/user-attachments/assets/faec298c-e42c-4fd1-84bd-6e74d1b481a0 ### What it does - Holding a letter types the base letter immediately, then arms the picker. After the **Hold duration** (default **500 ms**) the toolbar appears. - Navigate the options with the arrow keys / Space, then **release the letter** to insert the selected accent (it replaces the base letter). - A quick tap types just the letter. Holding and releasing without selecting leaves the base letter as-is. - `Ctrl` / `Alt` / `AltGr` / `Win` + letter combinations are left untouched, so shortcuts like `Ctrl+A` still work. ## PR Checklist - [ ] **Closes:** N/A — feature enhancement (happy to link a tracking issue if one is preferred) - [x] **Communication:** Discussed direction with maintainers; coordinated with #48891 (see below) - [ ] **Tests:** No automated tests added — the activation decision lives in the C++ low-level keyboard hook and isn't reachable from the existing managed unit-test project. Validated manually (steps below). Open to guidance on the preferred test surface. - [x] **Localization:** All new end-user strings are in `Settings.UI/Strings/en-us/Resources.resw` with translator comments. - [x] **Dev docs:** `doc/devdocs/modules/quickaccent.md` updated with the new mode. - [x] **New binaries:** None. - [x] **Documentation updated:** Dev docs updated; public Learn docs can follow once shipped. ## Detailed Description of the Pull Request / Additional comments - **`PowerAccentKeyboardService` (C++ hook):** - Append `PressAndHold` to the internal `PowerAccentActivationKey` enum (value `3`, appended to preserve serialized `0/1/2`). - Add a `holdDuration` setting and `UpdateHoldDuration(Int32)` to the WinRT projection (`.idl`). - In `OnKeyDown`, arm the picker on the held letter itself; the base letter still types on first press and auto-repeat is swallowed (reuses the existing `m_toolbarVisible` repeat guard from #36853). - In `OnKeyUp`, use the hold duration as the minimum-hold release threshold for this mode (trigger modes keep using `inputTime`). - Modifier guard: Ctrl/Alt/AltGr/Win do not arm the mode. - **Settings model (`Settings.UI.Library`):** append `PressAndHold` to `PowerAccentActivationKey`; add `hold_duration_ms` (`IntProperty`, default 500). Existing `settings.json` without the field falls back to the 500 ms default. - **`PowerAccent.Core`:** read and forward the hold duration to the hook, and use it as the popup delay when `PressAndHold` is active. - **Settings UI:** add the **"Press and hold the letter"** activation option and a **"Hold duration (ms)"** control that is shown only when that mode is selected. ### Enum sync note `PowerAccentActivationKey` exists in both the C++ hook and the managed settings library and is kept in sync by integer value. `PressAndHold` was **appended** (never reordered) so existing serialized settings (`0/1/2`) keep their meaning. ### Coordination with #48891 (Quick Accent WinUI migration) This lands as its own atomic change on `main`. The overlap with the in-progress WinUI migration (#48891) is tiny: only `PowerAccent.cs`'s mode-aware popup delay (a single `Task.Delay` line). The C++ hook, settings enum/model, and Settings UI are not touched by #48891, so it can rebase onto this with minimal effort. ## Validation Steps Performed - Built the full chain in `Debug|x64`: - `PowerAccent.UI.csproj` → rebuilds the C++ `PowerAccentKeyboardService` projection (incl. `UpdateHoldDuration`) + `PowerAccent.Core` + `Settings.UI.Library`. **0 errors.** - `PowerToys.Settings.csproj` → Settings UI XAML / ViewModel / `.resw` (XamlIndexBuilder search index regenerated). **0 errors.** - Manual trial of the running module (`PowerToys.PowerAccent.exe`) with `activation_key = 3`: - Hold `a` → base letter types immediately; picker opens after ~500 ms; arrows/Space navigate; releasing inserts the accent (replacing the base letter). - Quick tap → base letter only. Hold + release without selecting → base letter remains. - `Ctrl+A` / `Alt`+letter unaffected. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
d6319516d0 |
[Skills] Fix wpf-to-winui3-migration SKILL.md failing to load (#49059)
## Summary of the Pull Request The `wpf-to-winui3-migration` agent skill failed to load. The `description` field in its `SKILL.md` YAML frontmatter was an **unquoted** plain scalar containing `Keywords: ` (a colon followed by a space). YAML interprets `: ` as a mapping key/value separator, so the skill loader failed with: > failed to parse YAML frontmatter: mapping values are not allowed in this context at line 2 column 651 Because `.claude/skills` is a symlink to `.github/skills`, the CLI enumerates the same file twice, so this single defect surfaced as **two** skill load errors (`skill_error_count: 2`). Fix: wrap the `description` value in single quotes so the colon is treated literally. No wording changes; the description stays 926 characters (well under the 1024 limit). ## PR Checklist - [ ] Closes: #xxx — N/A, trivial metadata fix, no tracking issue - [x] **Communication:** Metadata-only fix; no design discussion needed - [ ] **Tests:** N/A — no test harness for skill frontmatter; validated by YAML parsing (see below) - [x] **Localization:** N/A — not end-user-facing - [ ] **Dev docs:** N/A - [ ] **New binaries:** N/A ## Detailed Description of the Pull Request / Additional comments `.github/skills/wpf-to-winui3-migration/SKILL.md` line 3 changed from: ```yaml description: Guide for migrating ... after migration. Keywords: WPF, WinUI, ... SoftwareBitmap. ``` to: ```yaml description: 'Guide for migrating ... after migration. Keywords: WPF, WinUI, ... SoftwareBitmap.' ``` The three other top-level skills already quote (or avoid `: ` in) their descriptions, so only this one was affected. Single quotes are used because the description contains no quote characters, so no escaping is required. ## Validation Steps Performed - Reproduced the loader error from the Copilot CLI logs: `mapping values are not allowed in this context at line 2 column 651`. - Parsed the frontmatter of all 9 `SKILL.md` files with a YAML parser: before = 1 failure (this file), after = **0 failures**. - Confirmed parsed `name` (`wpf-to-winui3-migration`), `description` (926 chars, ≤ 1024), and `license` are intact and the literal `Keywords: WPF...` text is preserved. Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
4a27c5d5f9 |
New+: Fix French translation guidance (Nouveau+ not Nouveauté+) (#47225)
## Summary of the Pull Request
French translation of "New+" was rendered as "Nouveauté+" ("Novelty+")
instead of "Nouveau+" ("New+"), inconsistent with how Windows itself
translates the "New" context menu item in French. This updates
translator guidance comments in the English resource files to explicitly
call out the correct French form.
## PR Checklist
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx
## Detailed Description of the Pull Request / Additional comments
Translator-facing `<comment>` fields updated across three resource files
to explicitly state the correct French translation and flag the wrong
one:
- **`NewShellExtensionContextMenu/resources.resx`** and
**`NewShellExtensionContextMenu.win10/resources.resx`** —
`context_menu_item_new`:
> _"…e.g. Danish it would become Ny+, **French it would become Nouveau+
(not Nouveauté+)**"_
- **`Settings.UI/Strings/en-us/Resources.resw`** — five `NewPlus.*` /
`Oobe_NewPlus.*` strings:
> _"…Localize product name in accordance with Windows New. **e.g. French
would be Nouveau+ (not Nouveauté+)**"_
Actual `.lcl` translation files are managed by the CDPX localization
pipeline; these comment updates feed directly into the guidance the
localization team sees when updating those files.
## Validation Steps Performed
Comment-only changes to XML resource files; no runtime behavior
affected. Verified all targeted entries were updated and no existing
checked-in `Nouveauté` strings remain in the repo.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: niels9001 <9866362+niels9001@users.noreply.github.com>
|
||
|
|
70ff4013b9 |
Add Shortcut Guide V2 manifest spec link to copilot-instructions.md (#48967)
Adds a reference to the WinGet Manifest Keyboard Shortcuts schema spec in `.github/copilot-instructions.md` so AI agents know where to find the correct field definitions, file naming conventions, and the `+` prefix rule when creating or editing Shortcut Guide V2 manifest files. ## Summary of the Pull Request Adds a new `## Shortcut Guide V2 Manifests` section to `.github/copilot-instructions.md` linking to [`doc/specs/WinGet Manifest Keyboard Shortcuts schema.md`](../doc/specs/WinGet%20Manifest%20Keyboard%20Shortcuts%20schema.md). This ensures agents authoring new manifest files follow the correct schema and naming scheme (e.g., `<PackageId>.<locale>.yml`, `+` prefix for apps without a WinGet package). ## PR Checklist - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx ## Detailed Description of the Pull Request / Additional comments `.github/copilot-instructions.md` gains a dedicated section: ```markdown ## Shortcut Guide V2 Manifests When creating or editing Shortcut Guide keyboard shortcut manifest files, follow the schema and naming conventions in the spec: - [WinGet Manifest Keyboard Shortcuts schema](<../doc/specs/WinGet Manifest Keyboard Shortcuts schema.md>) – manifest file format, field definitions, file naming, and the `+` prefix convention for apps without a WinGet package ``` No production code changes. ## Validation Steps Performed - Verified the relative link resolves to the correct spec file in the repository. - Confirmed the section is correctly placed before "Detailed Documentation". --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> |
||
|
|
7a04d4c270 |
[ShortcutGuide] Add DaVinci Resolve keyboard shortcut manifest (#48651) (#48652)
Adds a shortcut manifest for DaVinci Resolve (professional video editing and color grading application by Blackmagic Design) so it appears in the Shortcut Guide overlay when the app is focused. The manifest contains 88 of the most commonly used DaVinci Resolve keyboard shortcuts organized into 8 categories: | Section | Shortcuts | Highlights | |---------|-----------|------------| | Popular shortcuts | 25 | Page navigation (F5-F8), Playback (JKL, Space), Edit basics (Cut, Blade, Ripple Delete) | | Timeline navigation | 13 | Frame/clip/track navigation, zoom, edit point jumping | | Edit | 14 | Cut/Copy/Paste/Duplicate, Render in Place, Compound Clip | | Color | 17 | Node management (Alt+S/P/L), viewer modes (1-5), Grade/Keyframe | | Fairlight | 8 | Mute/Solo/Record/Automation, Bounce Mix | | Fusion | 8 | View switching (1-4), Merge, Keyframe | | Media | 8 | Import, Smart Bin, Reveal in Explorer, Rename | | Deliver | 5 | Render Queue, Start Render, Output settings | The manifest follows the same YAML schema as existing manifests. No code changes needed -- manifests are auto-discovered at startup. |
||
|
|
6dd1ce5dd1 |
Dev/crutkas/ripple v2.1 + spelling allow-list follow-up (#48232)
## Summary of the Pull Request Adds a follow-up metadata fix to the existing Mouse Highlighter ripple v2.1 work by allowing the term `xhair` in repo spell-check configuration. ## PR Checklist - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx ## Detailed Description of the Pull Request / Additional comments - Added `xhair` to `.github/actions/spell-check/expect.txt`. - This addresses spelling feedback on MouseHighlighter ripple/crosshair code without changing runtime behavior. - No functional changes to Mouse Highlighter logic were made in this follow-up commit. ## Validation Steps Performed - Verified the only content change is the new `xhair` entry in spell-check expected words. - Ran secret scanning on changed file (`.github/actions/spell-check/expect.txt`) with no findings. - Ran parallel validation: - Code Review: no issues. - CodeQL: skipped as trivial metadata-only change. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Niels Laute <niels.laute@live.nl> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> |
||
|
|
64f1243bdf |
Skip auto-labeling PRs that already have labels (#48877)
## Summary The auto-labeler workflow now skips pull requests that already have labels applied before running the AI classification. This avoids overwriting or duplicating labels that were manually set by contributors or maintainers. ## Changes - Added a check in `labelIssue()` that returns early for PRs with existing labels, logging which labels are already present. - Issues continue to be labeled regardless (only PRs get the skip logic). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
9ee0c7259b |
CmdPal: Dock Auto-hide (#48565)
This pull request introduces a new "Auto-hide" feature for the dock, allowing users to collapse the dock until they hover over its screen edge. The changes include updates to the settings model, UI, localization resources, and automated tests to support and verify this new functionality. **Show me:** https://github.com/user-attachments/assets/689625e8-9050-4a54-9c4b-9e303a3da63a **Conflicted?** "What if I have Taskbar and Dock on the same side and both with auto-hide turned on?" <img width="1437" height="264" alt="Screenshot 2026-06-14 144814" src="https://github.com/user-attachments/assets/bd037a11-0653-4b9a-bd21-625aca03b901" /> Closes #46239 --------- Co-authored-by: root <root@io.bbq> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
7e877558b9 |
Add powertoys-module-verification agent skill (#48717)
## Summary of the Pull Request
Adds a new **GitHub Copilot Agent Skill**,
`powertoys-module-verification`, under `.github/skills/`. It packages
the workflow, drive techniques, helper scripts, and per-module reference
data an AI agent uses to verify a single PowerToys module's
release-checklist items end-to-end (each checkbox → a structured PASS /
FAIL / BLOCKED verdict with evidence).
This is **docs/automation tooling only** — no product code, binaries, or
end-user strings are touched.
## PR Checklist
- [ ] Closes: #xxx
- [x] **Communication:** Internal tooling for release sign-off; happy to
adjust scope/placement based on review.
- [x] **Tests:** N/A — documentation/skill bundle only (no product code
paths). The 12 bundled `.ps1` helpers are agent utilities, not part of
the product build/test.
- [x] **Localization:** N/A — no end-user-facing strings.
- [x] **New binaries:** N/A — no binaries added.
- [x] **Dev docs:** This PR *is* developer-facing documentation/tooling.
## Detailed Description of the Pull Request / Additional comments
Layout follows the repo's Agent Skill guidelines
(`.github/instructions/agent-skills.instructions.md`) and matches the
existing skills under `.github/skills/`:
```
.github/skills/powertoys-module-verification/
├── SKILL.md # single entry doc (name/description/license frontmatter)
├── LICENSE.txt # Apache 2.0 (matches existing skills)
├── scripts/ # 12 PowerShell helper utilities used by the agent
└── references/
├── winapp-ui-testing.md # UIA-mechanics prerequisite doc
├── pre-flight.md / reporting-format.md / environment-setup.md / explorer-context-menu-flow.md
├── modules/ # per-module verification profiles
└── release-checklist/ # per-module checklists + index
```
Notes for reviewers:
- **`references/winapp-ui-testing.md`** is adapted from the
`winui-ui-testing` skill in
[microsoft/win-dev-skills](https://github.com/microsoft/win-dev-skills)
(MIT, © Microsoft Corporation and Contributors), with PowerToys-specific
edits. Provenance is recorded in the file header. Its skill frontmatter
was intentionally stripped so it is treated as a reference doc, not a
separately-discovered skill.
- **Checklist scope:** only modules already verified end-to-end (with a
sign-off report) are included for now — Environment Variables, File
Locksmith, Image Resizer, New+, Peek, PowerRename. Remaining modules'
checklists will be added as each is verified.
- No existing files are modified; this is purely additive under
`.github/skills/`.
## Validation Steps Performed
- Validated the bundle against the Agent Skill checklist in
`.github/instructions/agent-skills.instructions.md`: valid `name` (≤64
chars) + `description` + `license` frontmatter; `SKILL.md` body under
the 500-line guidance; single `SKILL.md`; `scripts/` + `references/`
resource buckets; all resource references use relative paths.
- Verified internal cross-references resolve after the migration (no
stale `helpers/`, `Winapp-SKILL.md`, or absolute-path tokens;
`src/modules/...` source citations left intact).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
||
|
|
5c63486dcb |
build(deps): bump actions/checkout from 6 to 7 (#48743)
Bumps [actions/checkout](https://github.com/actions/checkout) from 6 to 7. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/actions/checkout/releases">actions/checkout's releases</a>.</em></p> <blockquote> <h2>v7.0.0</h2> <h2>What's Changed</h2> <ul> <li>block checking out fork pr for pull_request_target and workflow_run by <a href="https://github.com/aiqiaoy"><code>@aiqiaoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2454">actions/checkout#2454</a></li> <li>Bump actions/publish-immutable-action from 0.0.3 to 0.0.4 in the minor-actions-dependencies group across 1 directory by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2458">actions/checkout#2458</a></li> <li>Bump flatted from 3.3.1 to 3.4.2 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2460">actions/checkout#2460</a></li> <li>Bump js-yaml from 4.1.0 to 4.2.0 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2461">actions/checkout#2461</a></li> <li>Bump <code>@actions/core</code> and <code>@actions/tool-cache</code> and Remove uuid by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2459">actions/checkout#2459</a></li> <li>upgrade module to esm and update dependencies by <a href="https://github.com/aiqiaoy"><code>@aiqiaoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2463">actions/checkout#2463</a></li> <li>Bump the minor-npm-dependencies group across 1 directory with 3 updates by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2462">actions/checkout#2462</a></li> <li>getting ready for checkout v7 release by <a href="https://github.com/aiqiaoy"><code>@aiqiaoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2464">actions/checkout#2464</a></li> <li>update error wording by <a href="https://github.com/aiqiaoy"><code>@aiqiaoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2467">actions/checkout#2467</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/aiqiaoy"><code>@aiqiaoy</code></a> made their first contribution in <a href="https://redirect.github.com/actions/checkout/pull/2454">actions/checkout#2454</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/checkout/compare/v6.0.3...v7.0.0">https://github.com/actions/checkout/compare/v6.0.3...v7.0.0</a></p> <h2>v6.0.3</h2> <h2>What's Changed</h2> <ul> <li>Update changelog by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2357">actions/checkout#2357</a></li> <li>fix: expand merge commit SHA regex and add SHA-256 test cases by <a href="https://github.com/yaananth"><code>@yaananth</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2414">actions/checkout#2414</a></li> <li>Fix checkout init for SHA-256 repositories by <a href="https://github.com/yaananth"><code>@yaananth</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2439">actions/checkout#2439</a></li> <li>Update changelog for v6.0.3 by <a href="https://github.com/yaananth"><code>@yaananth</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2446">actions/checkout#2446</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/yaananth"><code>@yaananth</code></a> made their first contribution in <a href="https://redirect.github.com/actions/checkout/pull/2414">actions/checkout#2414</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/checkout/compare/v6...v6.0.3">https://github.com/actions/checkout/compare/v6...v6.0.3</a></p> <h2>v6.0.2</h2> <h2>What's Changed</h2> <ul> <li>Add orchestration_id to git user-agent when ACTIONS_ORCHESTRATION_ID is set by <a href="https://github.com/TingluoHuang"><code>@TingluoHuang</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2355">actions/checkout#2355</a></li> <li>Fix tag handling: preserve annotations and explicit fetch-tags by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2356">actions/checkout#2356</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/checkout/compare/v6.0.1...v6.0.2">https://github.com/actions/checkout/compare/v6.0.1...v6.0.2</a></p> <h2>v6.0.1</h2> <h2>What's Changed</h2> <ul> <li>Update all references from v5 and v4 to v6 by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2314">actions/checkout#2314</a></li> <li>Add worktree support for persist-credentials includeIf by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2327">actions/checkout#2327</a></li> <li>Clarify v6 README by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2328">actions/checkout#2328</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/checkout/compare/v6...v6.0.1">https://github.com/actions/checkout/compare/v6...v6.0.1</a></p> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/actions/checkout/blob/main/CHANGELOG.md">actions/checkout's changelog</a>.</em></p> <blockquote> <h1>Changelog</h1> <h2>v7.0.0</h2> <ul> <li>Block checking out fork PR for pull_request_target and workflow_run by <a href="https://github.com/aiqiaoy"><code>@aiqiaoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2454">actions/checkout#2454</a></li> <li>Bump actions/publish-immutable-action from 0.0.3 to 0.0.4 in the minor-actions-dependencies group across 1 directory by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2458">actions/checkout#2458</a></li> <li>Bump flatted from 3.3.1 to 3.4.2 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2460">actions/checkout#2460</a></li> <li>Bump js-yaml from 4.1.0 to 4.2.0 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2461">actions/checkout#2461</a></li> <li>Bump <code>@actions/core</code> and <code>@actions/tool-cache</code> and Remove uuid by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2459">actions/checkout#2459</a></li> <li>upgrade module to esm and update dependencies by <a href="https://github.com/aiqiaoy"><code>@aiqiaoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2463">actions/checkout#2463</a></li> <li>Bump the minor-npm-dependencies group across 1 directory with 3 updates by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2462">actions/checkout#2462</a></li> </ul> <h2>v6.0.3</h2> <ul> <li>Fix checkout init for SHA-256 repositories by <a href="https://github.com/yaananth"><code>@yaananth</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2439">actions/checkout#2439</a></li> <li>fix: expand merge commit SHA regex and add SHA-256 test cases by <a href="https://github.com/yaananth"><code>@yaananth</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2414">actions/checkout#2414</a></li> </ul> <h2>v6.0.2</h2> <ul> <li>Fix tag handling: preserve annotations and explicit fetch-tags by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2356">actions/checkout#2356</a></li> </ul> <h2>v6.0.1</h2> <ul> <li>Add worktree support for persist-credentials includeIf by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2327">actions/checkout#2327</a></li> </ul> <h2>v6.0.0</h2> <ul> <li>Persist creds to a separate file by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2286">actions/checkout#2286</a></li> <li>Update README to include Node.js 24 support details and requirements by <a href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2248">actions/checkout#2248</a></li> </ul> <h2>v5.0.1</h2> <ul> <li>Port v6 cleanup to v5 by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2301">actions/checkout#2301</a></li> </ul> <h2>v5.0.0</h2> <ul> <li>Update actions checkout to use node 24 by <a href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2226">actions/checkout#2226</a></li> </ul> <h2>v4.3.1</h2> <ul> <li>Port v6 cleanup to v4 by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2305">actions/checkout#2305</a></li> </ul> <h2>v4.3.0</h2> <ul> <li>docs: update README.md by <a href="https://github.com/motss"><code>@motss</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1971">actions/checkout#1971</a></li> <li>Add internal repos for checking out multiple repositories by <a href="https://github.com/mouismail"><code>@mouismail</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1977">actions/checkout#1977</a></li> <li>Documentation update - add recommended permissions to Readme by <a href="https://github.com/benwells"><code>@benwells</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2043">actions/checkout#2043</a></li> <li>Adjust positioning of user email note and permissions heading by <a href="https://github.com/joshmgross"><code>@joshmgross</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2044">actions/checkout#2044</a></li> <li>Update README.md by <a href="https://github.com/nebuk89"><code>@nebuk89</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2194">actions/checkout#2194</a></li> <li>Update CODEOWNERS for actions by <a href="https://github.com/TingluoHuang"><code>@TingluoHuang</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2224">actions/checkout#2224</a></li> <li>Update package dependencies by <a href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2236">actions/checkout#2236</a></li> </ul> <h2>v4.2.2</h2> <ul> <li><code>url-helper.ts</code> now leverages well-known environment variables by <a href="https://github.com/jww3"><code>@jww3</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1941">actions/checkout#1941</a></li> <li>Expand unit test coverage for <code>isGhes</code> by <a href="https://github.com/jww3"><code>@jww3</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1946">actions/checkout#1946</a></li> </ul> <h2>v4.2.1</h2> <ul> <li>Check out other refs/* by commit if provided, fall back to ref by <a href="https://github.com/orhantoy"><code>@orhantoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1924">actions/checkout#1924</a></li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href=" |
||
|
|
968a7ac4b6 |
[Peek] Stop fail-fast in AppWindow.Closing path; reset cached preview-handler factories on release (#48564)
## Summary
Harden Peek's `AppWindow.Closing` path so a stale cached preview-handler
factory can't fail-fast the Peek process. Also clean up the matching
path in RegistryPreview.
## Background
Spotted while reading through Peek's `MainWindow` teardown sequence and
the `ShellPreviewHandlerPreviewer` cache for an unrelated review of how
Peek manages out-of-process preview-handler lifetimes.
The Peek `MainWindow` subscribes to `AppWindow.Closing`. The handler
doesn't actually close the window — it sets `args.Cancel = true` and
calls `Uninitialize()`, which in turn calls
`ShellPreviewHandlerPreviewer.ReleaseHandlerFactories()`.
`ReleaseHandlerFactories()` looked like this:
```csharp
public static void ReleaseHandlerFactories()
{
foreach (var factory in HandlerFactories.Values)
{
try { Marshal.FinalReleaseComObject(factory); } catch { }
}
}
```
Two problems:
1. The static `HandlerFactories` dictionary is never cleared. After
`FinalReleaseComObject`, the entries still point at separated RCWs. A
subsequent activation that races with this cleanup (or a second close in
the same process) can pick up the dead RCW from the cache.
2. The cached factory had `LockServer(true)` called on it when it was
first cached, but the matching `LockServer(false)` was never paired.
Any managed exception that escapes a WinRT event callback is projected
back to CFlat as a failed HRESULT and the CsWinRT dispatcher fail-fasts
the process. So a single `InvalidComObjectException` (HRESULT
0x80131527) thrown out of `Uninitialize()` is enough to terminate Peek.
## Changes
* **`ShellPreviewHandlerPreviewer.ReleaseHandlerFactories`** — snapshot
then clear the dictionary up front so that a subsequent call (or a
concurrent `LoadPreviewAsync`) can't pick up a stale RCW. Call
`LockServer(false)` before `FinalReleaseComObject` to mirror the
cache-time `LockServer(true)`. Both COM calls remain individually
wrapped because the RCW may already be unreachable during process
teardown.
* **`Peek.UI/MainWindow.xaml.cs` — `AppWindow_Closing`** — wrap the body
in try/catch + `Logger.LogError`. Any future exception in
`Uninitialize()` (or its callees) will now log instead of fail-fasting
the process.
* **`RegistryPreview/MainWindow.Events.cs` — `AppWindow_Closing`** —
same defensive try/catch, plus null-guard `jsonWindowPlacement` before
`SetNamedValue`. The placement dictionary can legitimately be null on
first run or after a corrupt placement file; previously that would NRE →
fail-fast.
## Risk
Low. The `ReleaseHandlerFactories` change matches the documented
`LockServer`/`FinalReleaseComObject` pairing and only widens the
lifetime window of the cache by `Clear()`-ing earlier; nothing in Peek
calls this method outside of teardown. The two try/catch wrappers
strictly add defense — the success path is unchanged.
## Validation
Spot-built locally; this repo's `dotnet restore` runtime-pack issue
(unrelated to this PR — same NU1102 pattern that's affecting other open
PRs) prevents a full `Build.cmd` here. The C++ side of Peek is
untouched.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
ADO:
https://microsoft.visualstudio.com/DefaultCollection/OS/_workitems/edit/58765809/
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Boliang Zhang <122517415+LegendaryBlair@users.noreply.github.com>
|
||
|
|
dd26d86580 |
[FancyZones] Fix stuck drag state and swallowed keys when a window is destroyed mid-drag (#48569)
## Summary Fixes a class of "stuck drag" bugs in FancyZones where closing or destroying a window **while it is being dragged** leaves FancyZones in a half-dragging state — zone overlays stay on screen and subsequent keystrokes (notably number keys) are swallowed or misrouted. ## What this changes - **Subscribe to and dispatch `EVENT_OBJECT_DESTROY`.** `FancyZonesApp` never subscribed to the destroy event, and the consumer's `WM_PRIV_WINDOWDESTROYED` branch could therefore never fire. The event is now registered and routed through `HandleWinHookEvent`. - **Abort the drag (without snapping) when the dragged window is destroyed.** On `WM_PRIV_WINDOWDESTROYED`, if the destroyed HWND is the one being dragged, call the new `WindowMouseSnap::Abort()` (tears down overlays/highlights/transparency) instead of `MoveSizeEnd()`, which would try to snap the now-dead HWND and corrupt zone state. Dragging state is then disabled. - **Always clear dragging state in `MoveSizeEnd()`**, even when the snapper was already null, so the state can't get stranded. - **Require Win+Ctrl+Alt to switch layouts while dragging.** Previously any digit switched layouts while `dragging` was true; if drag state was stuck this "stole" number keys from the focused app. This is the root-cause fix for the number-key-stealing symptom. - **Only swallow the bare Shift key during a drag**, not `Shift+<other>` combos, so real keystrokes are no longer eaten by an in-progress drag. ## Testing - Builds Release x64 (FancyZones) clean against current `main`. - Manually verified drag → close window mid-drag no longer leaves overlays up or steals number keys. (FancyZones has no unit-test harness for this path.) This is one of a small set of related "stuck key / stuck state" hardening fixes; each stands alone. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Muyuan Li <116717757+MuyuanMS@users.noreply.github.com> |
||
|
|
32ad98a0dd |
[PowerDisplay] Detect built-in panel when driven by the discrete GPU (#48637)
## Summary of the Pull Request On dual-GPU laptops, Power Display stopped detecting the built-in panel (and adjusting its brightness) when the **discrete GPU** drives the display — it showed "can't detect the display". This fixes that by classifying displays by **capability** (does WMI brightness work on it?) instead of by the nominal `OutputTechnology` value, which the discrete GPU misreports for the internal panel. ## PR Checklist - [x] Closes: #48587 - [x] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [x] **Tests:** Added/updated and all pass - [x] **Localization:** All end-user-facing strings can be localized (no new user-facing strings added) - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places ## Detailed Description of the Pull Request / Additional comments ### Root cause On a hybrid / MUX laptop, when the **discrete GPU** drives the built-in eDP panel, `QueryDisplayConfig` reports the panel's `DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY` as `DISPLAYPORT_EXTERNAL` (`10`) instead of the `INTERNAL` flag (`0x80000000`) it reports under the integrated GPU. It is the *same physical panel* (same EDID) — only the reported connector type changes with the active GPU. PR #47740 introduced a strict classifier: `OutputTechnology` → internal/external, then **internal → WMI-only, external → DDC/CI-only, with no fallback**. So under the discrete GPU the built-in panel was classified *external* and sent to DDC/CI only — but a laptop eDP panel does not speak DDC/CI, so it was dropped and Power Display reported it couldn't detect any monitor. (`WmiMonitorBrightness` still exposes that panel regardless of which GPU drives it, so the panel was actually controllable — it just never got routed to WMI.) ### Fix: classify by capability, not by nominal output technology - **`MonitorManager`** now runs **WMI discovery first** over the full `QueryDisplayConfig` inventory. Every display `WmiMonitorBrightness` exposes is treated as internal (WMI-controlled); whatever WMI does **not** claim is routed to DDC/CI. The `OutputTechnology`-based classifier is gone. - **`WmiController`** matches the system-wide `WmiMonitorBrightness` results against the full inventory by `Monitor.Id`. The persisted `Monitor.Id` is still taken from the matched `DevicePath` (byte-identical to the DDC route and to prior releases), so saved brightness/per-monitor settings survive upgrades. - New **`MonitorIdentity.FromInstanceName`** reduces a WMI `InstanceName` to the same canonical `Monitor.Id` as `FromDevicePath`; the separate `PnpHardwareKey` helper is removed. - **Deleted** `DisplayClassifier` and `MonitorDisplayInfo.IsInternal` (net ~150 fewer lines). ### Accepted trade-off A monitor that exposes **both** `WmiMonitorBrightness` **and** DDC/CI is now controlled via WMI only and won't get DDC-only features (contrast / volume / input source / color temperature / power). This is uncommon (typical laptop panels are WMI-only; typical external monitors are DDC-only) and is a deliberate decision: it removes the entire class of `OutputTechnology` misclassification bugs while keeping the performance win of not DDC-probing internal panels. ## Validation Steps Performed - Built the Power Display app (`PowerDisplay.csproj`) and `PowerDisplay.Lib.UnitTests` (x64 / Debug) with MSBuild — both succeed, including after merging latest `main` (Windows App SDK 2.2.0). - Ran the unit test suite: **128/128 pass**, including new `FromInstanceName` tests — the `FromInstanceName == FromDevicePath` equivalence invariant and a concrete #48587 regression case (the BOE panel reported as `OutputTechnology=10`). - Traced the fix against the reporter's diagnostic logs: the panel that previously went `OutputTechnology=10 → External → DDC → dropped` is now claimed by WMI and controllable. - Reviewed the diff for regressions (Monitor.Id persistence, monitor blacklist, mirror mode, dual-internal-panel devices, external-only desktops). --------- Co-authored-by: Yu Leng <yuleng@microsoft.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
a0e53de825 |
feat(shortcut-guide): add Postman manifest and fix numbered-key display (#48461)
## Summary of the Pull Request Adds a Shortcut Guide manifest for **Postman** and fixes a rendering bug where single-digit keys in manifests displayed incorrectly. - **Fix numbered-key rendering** — `src/modules/ShortcutGuide/ShortcutGuide.Ui/Converters/ShortcutDescriptionToKeysConverter.cs`: a single digit (`0`–`9`) in a manifest's `Keys` was treated as a Windows virtual-key code instead of the literal digit. Since VK `1` is the left mouse button, VK `9` is Tab, and VK `0` is undefined, shortcuts such as `Ctrl+0` (reset zoom) and `Ctrl+9` (last tab) rendered as blank/incorrect glyphs. Single digits are now rendered as the literal character. - **Add Postman shortcuts** — `src/modules/ShortcutGuide/ShortcutGuide.Ui/Assets/ShortcutGuide/Manifests/Postman.Postman.en-US.yml`: new manifest for `Postman.exe` covering Tabs, Sidebar, Request, Interface, Window and modals, and Console. Auto-included via the existing `Manifests/*.yml` glob in `ShortcutGuide.Ui.csproj`. - **Show tab-number ranges** — Edge, Chrome, Firefox, and Postman manifests: the "switch to a specific tab" entry used the literal key `1`, which (after the fix above) read as `Ctrl + 1`. It now uses a `1 - 8` range so the keycap conveys "any tab number 1 through 8". The separate "last tab" (`9`) and "reset zoom" (`0`) entries remain literal single keys. - **Add unit tests** — new `ShortcutGuide.UnitTests` (MSTest) project covering `ShortcutDescriptionToKeysConverter.GetKeysList`, including the single-digit regression. ## PR Checklist - [x] Closes: #48460 - [ ] **Communication:** I've discussed this with core contributors already. <!-- Filed #48460; the v0.100 announcement invites app-shortcut contributions via PR. --> - [x] **Tests:** Added/updated and all pass <!-- New ShortcutGuide.UnitTests (MSTest); 8 tests pass locally via vstest.console. --> - [x] **Localization:** All end-user-facing strings can be localized <!-- Shortcut names live in per-language manifest files (`*.en-US.yml`); other locales fall back to en-US, consistent with existing manifests. --> - [ ] **Dev docs:** Added/updated <!-- N/A: no behavior requiring dev-doc changes. --> - [ ] **New binaries:** Added on the required places <!-- N/A: the new manifest is a data asset under an already-shipped, globbed folder. The new test project is auto-discovered by the existing `**\*UnitTest*.dll` VSTest glob, so no CI pipeline change is required. --> - [ ] **Documentation updated:** <!-- N/A --> ## Detailed Description of the Pull Request / Additional comments The Shortcut Guide displays per-app shortcuts from YAML manifests, matched to the foreground window via `WindowFilter`. Keys are converted to keycaps by `ShortcutDescriptionToKeysConverter`. Numeric key strings were unconditionally parsed as virtual-key codes, so literal-digit shortcuts rendered wrong. The fix adds a `>= 0 and <= 9` case that emits the digit character as-is; non-digit numeric codes (arrows, etc.) are unchanged. The new Postman manifest exercises this with `Ctrl+0` / `Ctrl+9`. The browser/Postman "specific tab" entries were updated from the literal `1` to the `1 - 8` range string, rendered verbatim by `KeyVisual` (the same path used by the existing `Number (1-9)` key in the Windows Explorer manifest). A new `ShortcutGuide.UnitTests` (MSTest) project covers the converter: single digits render literally (regression test), modifier ordering, non-numeric passthrough (e.g. `1 - 8`), and arrow-key VK mapping. ## Validation Steps Performed Built and ran locally (x64 Debug): - Built `ShortcutGuideModuleInterface`, `ShortcutGuide.Ui`, and `ShortcutGuide.IndexYmlGenerator`; launched the Debug `PowerToys.exe`. - Triggered Shortcut Guide (`Win+Shift+/`) with **Postman** focused: the Postman section renders with all categories, and `Ctrl+1` / `Ctrl+9` / `Ctrl+0` display correctly (previously blank/incorrect). - Verified the "specific tab" entry renders as `Ctrl + 1 - 8` in **Edge**, **Chrome**, **Firefox**, and **Postman**. - Built `ShortcutGuide.UnitTests` and ran via `vstest.console.exe`: **8/8 tests pass**. <img width="845" height="1432" alt="PowerToys Shortcut Guide Running Postman" src="https://github.com/user-attachments/assets/6359617e-3e2c-48b0-8005-b3684594ec94" /> Co-Authored-By: Claude Opus 4.8 --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
c41ac6df87 |
Add Pitjantjatjara language support to Quick Accent (#48561)
Closes #45025 ## [QuickAccent] Add Pitjantjatjara / Yankunytjatjara Language Support ### Summary This pull request adds support for Pitjantjatjara/Yankunytjatjara to the Quick Accent feature. Pitjantjatjara/Yankunytjatjara is an Australian Aboriginal language spoken in the Western and South Australian deserts. ### What's New - Users can now access Pitjantjatjara/Yankunytjatjara retroflex consonant characters (ḻ, ṉ, ṟ, ṯ) through Quick Accent - Language is available in the Quick Accent settings dropdown menu - Full localization support for UI display ### Why This Matters Pitjantjatjara/Yankunytjatjara uses unique retroflex consonants that are essential for: - **Correct pronunciation:** Retroflex sounds are phonetically distinct from regular consonants - **Written accuracy:** Proper character representation in educational materials - **Cultural preservation:** Supporting Aboriginal language documentation and teaching - **Accessibility:** Users without specialized keyboards can now type these characters easily ### Character Mappings The implementation adds 4 retroflex consonants: - **L → ḻ** (Retroflex lateral approximant) - **N → ṉ** (Retroflex nasal) - **R → ṟ** (Retroflex approximant) - **T → ṯ** (Retroflex stop) ### Files Changed 1. **Language.cs** - Added `PJT` enum value 2. **CharacterMappings.cs** - Added language entry with character mappings and display order 3. **Resources.resw** - Added localized UI string 4. **expect.txt** - Added language name to spell-check whitelist ### Testing - ✅ Language appears in Quick Accent settings dropdown - ✅ Retroflex characters appear when holding L/N/R/T + activation key - ✅ No build errors or warnings |
||
|
|
459bd56fb6 |
Grab and Move: tight warning-gold overlay border + Always On Top 4px default (#48474)
## Summary Refines the **Grab and Move** drag/resize overlay so it matches the polish of **Always on Top (AoT)**, and lowers the AoT default border thickness. Created at the request of @crutkas. Two related border-refinement changes, kept in one PR because the Grab and Move "double layer" is designed around AoT's border. https://github.com/user-attachments/assets/0b605f92-60bd-44a0-a540-70e6d425146a ### 1. Always on Top - default border thickness 15 -> 4 The default highlight border was `15px`, which is visually heavy. Dropped to `4px` for a tighter, Fluent-style frame. - `src/modules/alwaysontop/AlwaysOnTop/Settings.h` (C++ default) - `src/settings-ui/Settings.UI.Library/AlwaysOnTopProperties.cs` (`DefaultFrameThickness`) - Existing users keep their configured value; only fresh installs / "reset" pick up `4`. Slider range (1-30) is unchanged. ### 2. Grab and Move - tight, warning-gold overlay (fill + border) Previously the overlay was a full translucent **white wash** sized to `GetWindowRect`, which includes the invisible resize-border / shadow margins (~7px) - so it sat *off* the visible window. It now hugs the visible frame, mirroring AoT: - **Keeps the translucent white wash** over the visible window (the familiar "grabbed" feedback) and adds a tight **warning-gold border on top**. Both hug the visible frame and are rounded to match the window corners. - **Tight geometry:** anchored to `DWMWA_EXTENDED_FRAME_BOUNDS` (inset by the invisible-border margins) instead of `GetWindowRect`. - **Corner detection:** matches the window's corner radius via `DWMWA_WINDOW_CORNER_PREFERENCE` (same mapping AoT uses); border thickness and radius scale with the target window DPI. - **Distinct accent:** Fluent **warning gold `#FFB900`** - the literal equivalent of WinUI [`SystemFillColorCaution`](https://learn.microsoft.com/en-us/windows/apps/design/style/color) (used as a `ThemeResource` for warnings across the Settings UI; a Win32 layered window can't resolve a `ThemeResource`, so a literal is required). Keeps Grab and Move visually distinct from AoT's accent-blue. - **Double layer, for free:** the Grab and Move border is drawn just **inside** the visible edge, while AoT draws its border just **outside** the visible edge. The two naturally stack into a clean double layer, so Grab and Move stays a constant **4px** with no AoT detection / window enumeration. Rendering keeps the existing GDI + `UpdateLayeredWindow` per-pixel-alpha path and adds **GDI+** (a Windows system library - no new third-party dependency) for the antialiased, rounded fill and border. Frame metrics are computed **once per drag/resize** (never in the mouse-move hot path). The optional geometry label is unchanged. ## Before / After | | Before | After | |---|---|---| | Grab and Move overlay | Full white wash, offset from the window edge | Same wash, now tight to the visible frame + gold border, corner-matched | | AoT default border | 15px | 4px | | AoT + Grab and Move together | white wash over AoT border | GM gold inside the edge + AoT accent outside it = double layer | ## Validation - Builds clean (exit 0, 0 warnings/errors) for **x64 Debug**: `GrabAndMove`, `AlwaysOnTop`, and `Settings.UI.Library` (Code Analysis / C26451 clean). - Smoke-tested live by running the standalone module exes: tight gold border + wash on Alt-drag / Alt-right-drag, AoT 4px border, and the inside/outside double layer on a pinned window. - WARNING: still **draft** pending broader visual validation (border tightness across DPIs, the exact gold, rounded vs square corners, AoT z-order during fast drags - AoT renders from a separate process and follows on a ~100ms timer). Screenshots to be added. ## Follow-up (not in this PR) AoT and Grab and Move remain **separate** overlay systems (AoT: persistent per-window Direct2D border; Grab and Move: transient GDI/`UpdateLayeredWindow` overlay). They can't share one runtime window, but the frame-geometry + corner-detection + DPI helpers are worth extracting into `src/common` (seeded by AoT's `WindowCornersUtil`/`ScalingUtils`). Tracked separately to keep this PR atomic (`src/common` is an ABI-careful area). ## Notes - No IPC/JSON schema changes; no new settings. - No new third-party dependencies (GDI+ is a system library). --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
d2aa24786d |
[DOCS] Add auto-generated github page for dev docs (#48752)
This pull request introduces a new, automated workflow for building and publishing the developer documentation website using [docmd](https://docmd.io/). The static site is now generated from `doc/devdocs`, built in the `doc/devdocs-website` folder, and deployed to GitHub Pages via a GitHub Actions workflow. The build output is not committed to the repository but is instead published as an artifact. Supporting configuration files, documentation, and `.gitignore` entries are also added to streamline local development and CI/CD. **Automated build and deployment:** * Added `.github/workflows/regenerate-devdocs-website.yml` to build the static site with docmd and deploy it to GitHub Pages automatically on changes to `doc/devdocs` or `doc/devdocs-website`, or via manual trigger. **Project setup and configuration:** * Added `doc/devdocs-website/package.json` to define the Node.js project, pin the docmd version, and provide scripts for local development and builds. * Added `doc/devdocs-website/docmd.config.json` to configure docmd (site title, source, output directory, base path). * Added `doc/devdocs-website/.npmrc` to disable lockfile generation, ensuring fresh dependency installs each build. **Documentation and housekeeping:** * Added `doc/devdocs-website/README.md` with instructions for editing, building, and publishing the docs website. * Added `doc/devdocs-website/.gitignore` to exclude the generated `site/` output from version control. |
||
|
|
d31d0ab168 |
Update labeling action to support pull requests (#48733)
This pull request updates the `auto-labeler.yml` GitHub Actions workflow to improve reliability and maintain compatibility. The most important changes are an upgrade to the `actions/github-script` version and improved error handling when applying labels, ensuring the workflow does not fail due to restricted permissions. **Dependency upgrade:** * Upgraded `actions/github-script` from version 7 to version 9 in the `Apply area labels with AI` step, ensuring continued support and access to the latest features and security updates. **Error handling improvements:** * Added a `try/catch` block around the label application logic to gracefully handle cases where the workflow lacks permission to write labels (e.g., due to restricted integration tokens), logging a message and skipping the operation instead of failing the entire workflow. |
||
|
|
486015d400 |
Add permissions for PR labeling (#48731)
This pull request makes minor adjustments to the `.github/workflows/auto-labeler.yml` GitHub Actions workflow, focusing on permissions and event triggers. Workflow configuration updates: * Added `pull-requests: write` permission to the workflow to ensure it has the necessary access for managing pull requests. * Removed the `edited` event from the list of triggers for `pull_request_target`, so the workflow will no longer run when a pull request is edited. |
||
|
|
a294e73bb6 |
[CmdPal] Animated notification (#48176)
## Summary of the Pull Request Gives the CmdPal toast notification a glow-up: it now slides in/out with a nice fade, has acrylic + a soft shadow, and stops fighting with `SizeToContent`. Along the way, the toast guts got refactored into a couple of reusable bits that live in `PowerToys.Common.UI.Controls` so other PowerToys utilities can grab them for their own transient overlays: - **`TransparentWindow`** — a `WindowEx`-derived host that strips the native frame, hides from taskbar/Alt-Tab, uses `TransparentTintBackdrop` for transparency, and runs show/hide implicit animations on its content. Supply your own animations via `ShowAnimations` / `HideAnimations`, or take the defaults (fade + slide). - **`TransparentCard`** — a templated `ContentControl` with acrylic (`AlwaysActiveDesktopAcrylicBackdrop`), rounded corners, border, and shadow. Drop whatever XAML you want inside. - **`AlwaysActiveDesktopAcrylicBackdrop`** — small `SystemBackdrop` wrapper so the acrylic doesn''t go grey when the window isn''t focused (transient overlays are never focused). CmdPal''s `ToastWindow` is now basically a 16-line wrapper: derives from `TransparentWindow`, drops a bound `TextBlock` inside, and handles its own 2.5s auto-hide timer + bottom-center positioning. https://github.com/user-attachments/assets/3a62080c-22f0-480c-ac4d-028bcc32f07d ## PR Checklist - [x] Closes: #40886 - [x] **Communication:** I''ve discussed this with core contributors already. - [ ] **Tests:** Added/updated and all pass - [x] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places ## Detailed Description of the Pull Request / Additional comments A couple of design notes worth calling out: - The window is sized slightly bigger than the visible card (~24px breathing room on each side) so the shadow and slide animation have room to render without clipping. That buffer area is transparent but NOT click-through — kept it small on purpose. We explored `SetWindowRgn` and `EnableWindow` tricks to make it click-through too, but neither plays nicely with WinUI 3''s DesktopWindowXamlSource. Small transparent frame is the pragmatic compromise. - Animations use the Toolkit''s implicit `ShowAnimations` / `HideAnimations` so there''s zero animation code in `ToastWindow.xaml.cs`. - `TransparentCard.xaml` is registered in `Themes/Generic.xaml` — required for templated controls in a library project; `<GenerateLibraryLayout>` alone doesn''t auto-merge per-control xaml. ## Validation Steps Performed - Built clean (arm64 Debug). - Triggered a CmdPal toast manually: fades + slides in, hangs for 2.5s, fades + slides out. - Acrylic stays active when the window isn''t focused (toasts are never focused). - Shadow renders fully without clipping. --------- Co-authored-by: niels9001 <niels9001@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
e8fee90f49 |
Enhance labeling action to support pull requests (#48729)
This pull request updates the auto-labeling workflow to support both issues and pull requests, improves clarity in logs and prompts, and renames the workflow file for broader applicability. The changes enhance automation for triaging by enabling area label assignment to new or updated pull requests in addition to issues. **Expanded triage coverage and workflow improvements:** * The workflow now triggers on both issue and pull request events (`opened`, `reopened`, `edited`, `synchronize`), allowing automatic area labeling for pull requests as well as issues. (`.github/workflows/auto-labeler.yml`, [.github/workflows/auto-labeler.ymlL1-R7](diffhunk://#diff-f874b1d773361dc46f2496bc3ce97ee3441e91257188b27a2bd83693c3b8a82eL1-R7)) * The concurrency group logic has been updated to handle pull request events separately from issues, ensuring that rapid updates to a PR or issue are managed correctly. (`.github/workflows/auto-labeler.yml`, [.github/workflows/auto-labeler.ymlR24-R26](diffhunk://#diff-f874b1d773361dc46f2496bc3ce97ee3441e91257188b27a2bd83693c3b8a82eR24-R26)) **User experience and clarity enhancements:** * Console logs and prompt messages now refer generically to "item" or distinguish between "Issue" and "Pull request" as appropriate, improving clarity in workflow output and AI prompts. (`.github/workflows/auto-labeler.yml`, [[1]](diffhunk://#diff-f874b1d773361dc46f2496bc3ce97ee3441e91257188b27a2bd83693c3b8a82eL41-R44) [[2]](diffhunk://#diff-f874b1d773361dc46f2496bc3ce97ee3441e91257188b27a2bd83693c3b8a82eL58-R79) [[3]](diffhunk://#diff-f874b1d773361dc46f2496bc3ce97ee3441e91257188b27a2bd83693c3b8a82eL139-R146) [[4]](diffhunk://#diff-f874b1d773361dc46f2496bc3ce97ee3441e91257188b27a2bd83693c3b8a82eL212-R217) * The system prompt for the AI labeling assistant has been updated to clarify that both issues and pull requests should be classified and labeled. (`.github/workflows/auto-labeler.yml`, [.github/workflows/auto-labeler.ymlL127-R133](diffhunk://#diff-f874b1d773361dc46f2496bc3ce97ee3441e91257188b27a2bd83693c3b8a82eL127-R133)) **File naming:** * The workflow file has been renamed from `.github/workflows/auto-label-issues.yml` to `.github/workflows/auto-labeler.yml` to reflect its broader scope. (`.github/workflows/auto-labeler.yml`, [.github/workflows/auto-labeler.ymlL1-R7](diffhunk://#diff-f874b1d773361dc46f2496bc3ce97ee3441e91257188b27a2bd83693c3b8a82eL1-R7)) |
||
|
|
d221f84d8f |
[Skills] Update WinUI3 migration skills to add more migration mapping item (#47043)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [x] Closes: #46464 <!-- - [ ] Closes: #yyy (add separate lines for additional resolved issues) --> - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed, or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed --------- Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
4d01062f76 |
Fix check-spelling: exclude ZoomIt rnnoise third-party tree and dedupe excludes (#48548)
## Summary The `Check Spelling` workflow has been failing on PRs against `main` (e.g. #48546) due to issues introduced by the recent ZoomIt webcam-blur / noise-cancellation change (#48266) plus two pre-existing duplicate entries in `.github/actions/spell-check/excludes.txt`. ## What the bot reported | Severity | Type | Location | |---|---|---| | ❌ | `forbidden-pattern` (Should be `a`) | `src/modules/ZoomIt/ZoomIt/rnnoise/kiss_fft.h:79` — third-party kiss_fft header contains `an fft` | | ⚠️ | `large-file` (~30 MB) | `src/modules/ZoomIt/ZoomIt/rnnoise/rnnoise_data_little.c` | | ⚠️ | `binary-file` | `src/modules/ZoomIt/ZoomIt/selfie_segmentation.onnx` | | ⚠️ | `duplicate-pattern` ×2 | `excludes.txt` lines 115/116 duplicate lines 108/109 (`FuzzyMatcher{Comparison,Diacritics}Tests.cs`) | ## Fix `.github/actions/spell-check/excludes.txt`: - **Drop 2 duplicate** `FuzzyMatcher*Tests.cs` lines. - **Add 2 new exclusions** for the new third-party ZoomIt assets: - `^src/modules/ZoomIt/ZoomIt/rnnoise/` — entire third-party rnnoise/kiss_fft tree (covers both the `an fft` forbidden-pattern in `kiss_fft.h` and the 30 MB `rnnoise_data_little.c` large-file). - `^src/modules/ZoomIt/ZoomIt/selfie_segmentation\.onnx$` — the ML model binary. Net change: `-2` duplicates, `+2` new exclusions → file count unchanged at 148 lines. ## Notes - Third-party content under `rnnoise/` should not be spell-checked; this matches how other vendored/third-party trees in the repo are handled (e.g. `src/common/CalculatorEngineCommon/exprtk.hpp`, `src/common/sysinternals/Eula/`). - No source code changes; pure config. - Unblocks #48546 and any other PR currently failing `Check Spelling` on `main`. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
d7d1e543ae |
[CmdPal][TimeDate] Open notification center when clicking the clock dock band (#48514)
## Summary Clicking the clock dock band in the CmdPal Dock now opens the Windows notification center (Action Center). A separate bell-icon-only dock band is also exposed for users who prefer a dedicated notification center shortcut. Closes #46327 ## Detail - **Clock band left-click**: replaced the previous `NoOpCommand` on `NowDockBand` with `OpenUrlCommand("ms-actioncenter:")`, dismissing the Dock on invoke. The `ms-actioncenter:` URI is the correct shell mechanism - `SendInput` Win+N was tested but dropped because it requires foreground focus, which the Dock holds at click time. - **Notification center band**: new `NotificationCenterDockBand` (`ListItem`) in `TimeDateCommandsProvider.cs`, with a bell icon (`\uEA8F`, Segoe Fluent Icons) and the same `ms-actioncenter:` command. Exposed as a second `WrappedDockItem` from `GetDockBands()` under the id `com.microsoft.cmdpal.timedate.notificationCenterBand`. Users can pin it from the Dock's edit mode. - **New resource strings**: `timedate_show_notification_center_command_name` and `timedate_notification_center_band_title` added to `Resources.resx` / `Resources.Designer.cs`. - **VS 2026 C++ build fixes** (pre-existing failures on `HEAD`): added `_SILENCE_EXPERIMENTAL_COROUTINE_DEPRECATION_WARNINGS` to `CalculatorEngineCommon.vcxproj`. ## Screenshots <img width="339" height="991" alt="image" src="https://github.com/user-attachments/assets/e0ef8c9a-ec1f-40fa-9620-1e83e6aeeb8d" /> ## How tested - Built `Microsoft.CmdPal.UI.csproj` (Debug x64) - 0 errors. - Launched dev `Microsoft.CmdPal.UI.exe`, clicked the clock band - notification center opened correctly. - Right-click context menu on the clock band still shows "Copy time" and "Copy date" unchanged. - Pinned the notification center band via edit mode - bell icon renders icon-only, click opens notification center. |
||
|
|
272b725ff0 |
Add ZoomIt webcam backgroun (blur) and microphone noise cancellation (#48266)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request This change adds the [RNNoise](https://github.com/xiph/rnnoise) filter for noise cancellation (audio) and the [Google mediapipe](https://github.com/google-ai-edge/mediapipe/tree/master) `selfie_segmentation_cpu` model for webcam background detection and blurring. It also fixes an issue introduced with |
||
|
|
582f3eb5c3 |
Move from testing to final for telemetry PR detection workflow (#47993)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request Transitions the telemetry PR detection workflow from testing phase to ready status. All components are now fully functional and automatically triggered on every new PR. - Skips checks on draft PRs to avoid noise - Prevents multiple concurrent runs per PR - Safely requests `@chatasweetie` as reviewer on telemetry changes - update commit messages <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [ ] Closes: #xxx <!-- - [ ] Closes: #yyy (add separate lines for additional resolved issues) --> - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed, or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed --------- Co-authored-by: Carlos Zamora <carlos.zamora@microsoft.com> |
||
|
|
cd5027fa1a |
[PowerDisplay] Fix false-positive crash detection on cooperative shutdown (#48173)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request Cooperative shutdowns of `PowerDisplay.exe` — Runner's `TerminateApp` NamedPipe message, the `Terminate` named event, tray-quit, Runner-exit detection, and PowerToys upgrades — all call `Environment.Exit(0)` immediately. If DDC/CI discovery is mid-flight, that path skips the `try/finally` that owns `CrashDetectionScope`, leaving `discovery.lock` on disk. Phase 0 at the next `PowerDisplay.exe` startup then treats this orphan as evidence of a real crash and auto-disables the module, surfacing the "PowerDisplay has crashed" InfoBar in Settings UI. This PR adds an `AppDomain.ProcessExit` safety-net inside `CrashDetectionScope`. ProcessExit fires for `Environment.Exit` but **not** for `FailFast` / BSOD / external `TerminateProcess` — exactly the partition we need: cooperative exit → best-effort delete the lock; involuntary kill → leave the lock for Phase 0 to detect (original design intent preserved). <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [x] Closes: #48169 - [x] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [x] **Tests:** Added/updated and all pass - [x] **Localization:** All end-user-facing strings can be localized <!-- no user-facing strings changed --> - [x] **Dev docs:** Added/updated <!-- inline XML doc on CrashDetectionScope explains the ProcessExit partition --> - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed, or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments ### Root cause `CrashDetectionScope.Begin()` writes `discovery.lock` before DDC/CI capability fetch and `Dispose()` deletes it when the `using` block exits. The lock is intentionally designed to survive any code path that cannot run user-mode cleanup (BSOD, kernel OOM, `TerminateProcess`), so that the next `PowerDisplay.exe` start can see it and run Phase 0 (write `crash_detected.flag`, set `enabled.PowerDisplay=false` in global `settings.json`, signal `AutoDisablePowerDisplayEvent`). The bug is that several **cooperative** shutdown paths route to `Environment.Exit(0)` immediately: | Path | Code | |---|---| | Runner's `TerminateApp` NamedPipe | `App.xaml.cs::OnNamedPipeMessage` → `Shutdown()` → `Environment.Exit(0)` | | `Terminate` named event | `App.xaml.cs::OnLaunched` → `RegisterEvent(..., () => Environment.Exit(0), "Terminate")` | | Tray-quit | `TrayIconService` callback → `Environment.Exit(0)` | | Runner-exit detection | `RunnerHelper.WaitForPowerToysRunner` callback → `Environment.Exit(0)` | `Environment.Exit` calls `ExitProcess` under the hood, which terminates all threads abruptly. Background `Task.WhenAll` doing DDC capability fetch is killed mid-flight; the `finally` block that calls `scope.Dispose()` never runs; `discovery.lock` orphans; Phase 0 next time false-positives. Concrete repro from logs: - `15:08:42.510` lock written - `15:08:42.79` probe monitor #1 - `15:08:46.92` probe monitor #2 (started, not finished — typical probe takes ~5s) - `15:08:49.03` `TerminateApp` received → `Environment.Exit(0)` → no `Dispose` log line - `15:10:10.03` next startup: Phase 0 sees orphan lock with `pid:17712, startedAt:2026-05-28T07:08:42Z` → writes `crash_detected.flag` → auto-disables ### Fix `CrashDetectionScope.Begin()` now also subscribes to `AppDomain.CurrentDomain.ProcessExit`. The handler does a best-effort `File.Delete(_lockPath)` (swallowing exceptions, as required for ProcessExit handlers). `Dispose()` unsubscribes before deleting. An `Interlocked.Exchange` guards the race between Dispose and ProcessExit so only one of the two performs the delete. ProcessExit's semantics match the cooperative/involuntary partition exactly: | Shutdown path | ProcessExit fires? | Behavior after this PR | |---|---|---| | `Environment.Exit(code)` (all 4 paths above) | yes | lock deleted by handler | | `Environment.FailFast` | no | lock survives → Phase 0 catches it (correct: explicit FailFast = real failure) | | BSOD / external `TerminateProcess` / kernel OOM | no | lock survives → Phase 0 catches it (correct: original design) | | Discovery completes normally / throws | n/a | `try/finally` calls `Dispose()` as before; handler unsubscribed first | ### Testability A new `IProcessExitHook` interface abstracts the subscription so unit tests can simulate ProcessExit without terminating the test runner. Production code uses the default `AppDomainProcessExitHook` singleton; tests inject a fake whose `RaiseExit()` invokes subscribed handlers synchronously. ### Files touched - `src/modules/powerdisplay/PowerDisplay.Lib/Services/IProcessExitHook.cs` *(new)* — interface + production singleton - `src/modules/powerdisplay/PowerDisplay.Lib/Services/CrashDetectionScope.cs` — subscribe in `Begin`, unsubscribe in `Dispose`, add `OnProcessExit` handler, expanded class doc - `src/modules/powerdisplay/PowerDisplay.Lib.UnitTests/CrashDetectionScopeTests.cs` *(new)* — 10 unit tests <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed ### Automated 10 new unit tests in `CrashDetectionScopeTests`, all passing: ``` Passed Begin_WritesLockFileAtomically Passed Begin_SubscribesToProcessExit Passed Dispose_UnsubscribesFromProcessExit Passed Dispose_DeletesLockFile Passed ProcessExitFired_BeforeDispose_DeletesLock (core scenario) Passed ProcessExitFired_AfterDispose_DoesNothing Passed Dispose_AfterProcessExit_DoesNotThrow Passed ProcessExitFired_LockFileMissing_DoesNotThrow Passed Dispose_IsIdempotent Passed MultipleScopes_DoNotShareState ``` Full `PowerDisplay.Lib.UnitTests` suite: **129 / 132 passing**. The 3 failures (`DetectOrphanAndDisable_RunsFullSequenceWhenOrphanPresent`, `DetectOrphanAndDisable_HandlesUnknownVersionAsOrphan`, `DetectOrphanAndDisable_LeavesLockIntactOnSignalFailure`) are **pre-existing on `main`** — they fail with `REGDB_E_CLASSNOTREG` from `Constants.AutoDisablePowerDisplayEvent()` (WinRT activation factory not COM-registered in the test environment). Verified by stashing this PR's changes and re-running the same 3 tests on baseline `main` — same failures, same cause, unrelated to this change. ### Manual 1. Reproduced the original false-positive on `main`: - Enable PowerDisplay → open Settings UI → quickly toggle PowerDisplay off - Observe `discovery.lock` left in `%LOCALAPPDATA%\Microsoft\PowerToys\PowerDisplay\` - Re-enable PowerDisplay → Phase 0 writes `crash_detected.flag` → InfoBar appears 2. Repeated the same steps with this branch: - Toggling PowerDisplay off cleanly deletes `discovery.lock` (ProcessExit handler ran) - Re-enabling PowerDisplay shows no InfoBar, no `crash_detected.flag` created 3. BSOD path is unchanged (verified by inspecting the conditional logic — `AppDomain.ProcessExit` does not fire for involuntary terminations; the lock survives just as before). --------- Co-authored-by: Yu Leng <yuleng@microsoft.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
65112a7b05 |
Move CmdPal API spec back to cmdpal/ directory (#48160)
Reverts
|
||
|
|
8a7933c0b2 |
Migrate spdlog from submodule to vcpkg (#48039)
## Summary Migrate `deps/spdlog` from a git submodule to **vcpkg manifest mode** with an overlay port pinned to the **exact same commit** (`gabime/spdlog@616866fc`). Replaces the polyfill shim added in #47910 with a proper port-level patch. This is the follow-up to PR #47928, which I closed after @zadjii-msft / @DHowett clarified that the intended direction was a single combined "move to vcpkg **and** apply a patch file" (one change, not two stepping stones). ## Guidance honored Per @zadjii-msft (offline): - ✅ Convert each submodule to vcpkg **one at a time** — this PR is **spdlog only**. `deps/expected-lite` stays a submodule (separate PR next). - ✅ Atomic commit per dep (multiple commits on the branch for review traceability; squash on merge gives the requested single commit). - ✅ **Don't bump the version.** Only variable changed: submodule → vcpkg. Same commit (`616866fc`, v1.8.5 + 38) the submodule pointed at. Per @DHowett ([review](https://github.com/microsoft/PowerToys/pull/48039#pullrequestreview-4338835150)): - ✅ No vcpkg submodule — vswhere-first detection via a Terminal-style `steps-install-vcpkg.yml` template; three-tier `VcpkgRoot` fallback (env var → VS-shipped → runtime clone pinned to manifest baseline). ## Design - **Repo-root manifest**: `vcpkg.json` declares only `spdlog`, with `builtin-baseline` pinned. `vcpkg-configuration.json` registers `deps/vcpkg-overlays/` as overlay-ports. - **Overlay port** `deps/vcpkg-overlays/spdlog/`: `vcpkg_from_github(REF 616866fc...)` with bundled fmt preserved (`-DSPDLOG_FMT_EXTERNAL=OFF`); the MSVC 14.51 fix from #47910 carried as a proper vcpkg patch on `include/spdlog/fmt/bundled/format.h`. - **vcpkg integration is global** (set in `Cpp.Build.props`, imported via `ForceImportBeforeCppProps` for every `.vcxproj`). An earlier attempt to make vcpkg per-project-opt-in via `deps/spdlog.props` failed because ~85 PowerToys `.vcxproj` files import `spdlog.props` AFTER `Microsoft.Cpp.targets`, by which point `vcpkg.props`' `ClCompile` hook is dead-on-arrival. The trade-off (every C++ project invokes `vcpkg install` once at build time, ~0.5 s on cache hits, manifest declares only spdlog so install set is fixed) is documented in the expanded `Cpp.Build.props` comment. - **`deps/spdlog.props`** is now a thin shim that only sets the historical `SPDLOG_*` preprocessor defines for source-compat. - **`Cpp.Build.targets`** is a new file imported via `ForceImportAfterCppTargets` to load `vcpkg.targets` after `Microsoft.Cpp.targets`. A fail-fast `<Target>` errors with a clear message if `vcpkg.props` can't be found at the resolved `VcpkgRoot`. - **Removes** `deps/spdlog-msvc-fix/` polyfill, in-tree wrapper `src/logging/`, spdlog submodule, the single `<ProjectReference>` in `logger.vcxproj`, plus 3 `.slnf` refs and 2 `.slnx` refs (`PowerToys.slnx` + `installer/PowerToysSetup.slnx`), plus 3 hard-coded `..\deps\spdlog\include` entries in `<AdditionalIncludeDirectories>`. - **CI**: new reusable `.pipelines/v2/templates/steps-install-vcpkg.yml` (vswhere-first, manifest-baseline-pinned fallback clone, respects `useVSPreview`). Gated `Cache@2` for `%LOCALAPPDATA%\vcpkg\archives` keyed on overlay-port contents. Same vcpkg detection added to `tools\build\build-essentials.ps1` for local devs. ## Verification Local build matrix (all 4 configs of `logger.vcxproj` and a representative late-import consumer): | Config | Result | Notes | |--------|--------|-------| | Release \| x64 | ✅ | vcpkg install ~21 s, `logger.lib` produced | | Debug \| x64 | ✅ | **Validates patch fixes the actual MSVC 14.51 bug** (`_ITERATOR_DEBUG_LEVEL > 0` → `_SECURE_SCL`) | | Release \| ARM64 | ✅ | vcpkg cross-installs `arm64-windows-static` spdlog in ~16 s | | Debug \| ARM64 | ✅ | **Previously DISABLED for the in-tree spdlog** (per `<Build Solution="Debug\|ARM64" Project="false" />` in `PowerToysSetup.slnx`); this migration FIXES that latent gap | | FancyZonesLib (Release \| x64) | ✅ | Late-import-pattern consumer; previously broke in v2 | Full PowerToys CI (x64 + arm64 + CmdPal SDK + all GitHub Actions checks) green. **Consumer audit**: 72 `.vcxproj` files reference `logger.vcxproj`; all 72 also import `deps/spdlog.props`. No transitive-link breakage. ## Out of scope (intentional) - `deps/expected-lite` migration — next PR per "one-at-a-time" rule. - Remote vcpkg binary cache (Azure Artifacts NuGet feed). Local pipeline `Cache@2` works for now, but a remote feed survives across pipelines and is the long-term answer. Happy to split this into a follow-up. ## Notes for review - Patch in the overlay port is identical content to PR #47928's patch but regenerated with LF line endings (vcpkg's `vcpkg_apply_patches` is strict; no `--ignore-whitespace`). - Once PowerToys eventually bumps spdlog past v1.14 (which ships fmt 10.2 and drops the affected code path), the overlay port can be deleted and we can use upstream vcpkg's `spdlog` directly. - Re. official-release pipelines and terrapin / less-restricted network isolation: VS-shipped vcpkg is the primary path (no network); the fallback clone is only exercised when VS doesn't ship vcpkg. Happy to wire terrapin into the fallback as a follow-up if the official build template needs it. Closes the work tracked in #47928 (which was closed unmerged). --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Dustin L. Howett <dustin@howett.net> |
||
|
|
b3bf154fa5 |
[General] Update issue tracker's duplicate resolution message (#47981)
Reopens the change from #46743 (which appears to be broken) on a fresh branch. Original author: @daverayment ## Summary GitHub newcomers can be confused by the current duplicate resolution message, as it doesn't clearly point to the original referenced issue - see https://github.com/microsoft/PowerToys/issues/46347#issuecomment-4103681050. They may not realise that the #12345 in the duplicate comment is the relevant link. This small wording update to the duplicate resolution message tightens up wording slightly and includes reference to the prior `/dup #nnn` comment so newcomers don't miss it. ### Before > Hi! We've identified this issue as a duplicate of another one that already exists on this Issue Tracker. This specific instance is being closed in favor of tracking the concern over on the referenced thread. Thanks for your report! ### After > We've identified this issue as a duplicate of an existing one and are closing this thread so discussion stays in one place.<br/><br/>Please see the comment above for the link to the original tracking issue, and feel free to subscribe there for updates. ## Validation Steps Performed N/A - bot reply text change only. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
6a5e320749 |
[CI] Prune orphan tokens from check-spelling expect.txt (#48110)
## Problem Since #47119 (`Refresh check-spelling 0.0.26`, merged 2026-04-23) refreshed the check-spelling tooling and rewrote `.github/actions/spell-check/expect.txt` (938 lines / 633 deletions), the check-spelling bot has been leaving a noisy advisory comment on **every PR**: > #### These words are not needed and should be removed > ABlocked AClient AColumn ACR ADate ADifferent AHybrid ALarger AModifier ANull AOklab APeriod ARandom ARemapped ASingle ASUS bck … The same ~150-word list is appended verbatim to every PR the bot looks at (verified against #48058, #48102, #48104 — the list is identical). These tokens are residual orphans in `expect.txt` from before the 0.0.26 refresh and no longer match anything in source. ## Fix Removes exactly the 147 orphan tokens that the bot has consistently flagged as `now absent` from `.github/actions/spell-check/expect.txt`. The removed tokens are exclusively the ones the bot itself identified. All uppercase Win32 / DirectWrite identifiers that are still used in source (`DWRITE`, `LWIN`, `VCENTER`, `VREDRAW`, etc.) are **preserved**. ## Verification - Diff is a single file, deletions only: `expect.txt` shrinks from 2343 → 2196 lines. - Each of the 4 uppercase Win32 tokens (`DWRITE` line 514, `LWIN` 1074, `VCENTER` 2105, `VREDRAW` 2144 in the original) remains in the file. - The check-spelling job on this PR should now post a clean report (no `should be removed` block). ## Background — which PR introduced the drift | PR | Date | What it changed | |----|------|-----------------| | **#47119** | 2026-04-23 | Refreshed check-spelling to 0.0.26; rewrote `expect.txt` with 938 line-changes (633 deletions, 305 additions). The duplicated lowercase/uppercase entries and many obsolete tokens originate here. | --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Copilot <Copilot@users.noreply.github.com> |
||
|
|
f998c38ac8 |
cmdpal: fix an AOT-only crash loading the extension page (#48065)
Okay I'll admit this is a clanker fix. There's currently a crash when you navigate to an individual extension page, that only repro's in Release/AOT. And because of release&trimming&AOT reasons, that's very very difficult to diagnose. But the clanker added a shitload of logging, and was able to figure out that: We were binding to this `Screenshots` collection. Problem is that we can't safely bind to an `IReadOnlyList` in trimmed scenarios. C#/AOT is a wonderful world of horrors. Fixing this is as simple as swapping it for a `ObservableCollection`. |
||
|
|
4edfcee87e |
[Power Display] Built-in monitor blacklist to mitigate DDC/CI BSOD (#47556, #47968) (#48051)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request Adds a built-in monitor blacklist that skips known-bad monitor models at the DDC/CI discovery stage — before PowerDisplay sends any capabilities request to the firmware. Matches by EdidId (the PnP manufacturer + product code from EDID). Two entries pre-populated from existing crash reports: | EdidId | Reported in | Notes | |-----------|-------------|------------------------------------------------------------------------| | `LTM2C02` | #47556 | Counterfeit-EDID LG 27MR400 (PnP claims Litemax 40" 2011, actual hw is LG 27" 2024) | | `GSM7714` | #47968 | LG UltraWide HDR WFHD | Also logs `[EdidId=…] [FriendlyName=…] [DevicePath=…]` immediately before each `GetCapabilitiesString*` syscall in `DdcCiController`. If the kernel call BSODs (`win32kfull` stack-cookie overrun), that is the last log line that survives — adding a new blacklist entry then takes one PR to `BuiltInMonitorBlacklist.json` instead of a memory-dump triage. <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [x] Mitigates: #47556 - [x] Mitigates: #47968 - [x] **Communication:** This is the "Add blacklist and prevent the API call on broken monitor" mitigation outlined in [#47556 (comment)](https://github.com/microsoft/PowerToys/issues/47556#issuecomment-4505498427). The underlying `win32kfull!DdcciGetCapabilitiesStringFromMonitor` stack overrun is tracked separately by the Windows team. - [x] **Tests:** 6 new MSTest unit tests under `PowerDisplay.Lib.UnitTests`. All 120 PowerDisplay tests pass on x64 Debug. - [ ] **Localization:** N/A — this PR ships no end-user-facing strings (no UI surface). - [ ] **Dev docs:** N/A. - [ ] **New binaries:** N/A. Data ships as an `<EmbeddedResource>` inside the existing `PowerDisplay.Models.dll`; no new .dll, no installer change. - [ ] **Documentation updated:** N/A. <!-- Provide a more detailed description of the PR, other things fixed, or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments ### Threat model Some retail monitor firmwares ship non-conformant DDC/CI capabilities strings — typically oversized, not NUL-terminated, or otherwise malformed. When PowerDisplay calls `GetCapabilitiesStringLength` / `CapabilitiesRequestAndCapabilitiesReply` on these monitors, the request flows into `win32kfull!CPhysicalMonitorHandle::DdcciGetCapabilitiesStringFromMonitor`, which copies the reply into a stack buffer without bounding the length. The kernel detects its own stack cookie corruption on the epilogue check and `__fastfail`s with `BUGCHECK 0x139 / 2 (STACK_COOKIE_CHECK_FAILURE)`. The kernel-side overrun is a Windows defect, not PowerDisplay's, but PowerDisplay is currently the most widely deployed consumer of this API on hot-plug. Until the Windows team fixes the kernel, the only safe mitigation in user space is to **never call** the capabilities API on monitor models known to trigger it. ### Architecture | File | Role | |---|---| | `PowerDisplay.Models/MonitorBlacklistEntry.cs` | POCO: `{ edidId, comments }` | | `PowerDisplay.Models/BuiltInMonitorBlacklist.json` | Data file (embedded resource) | | `PowerDisplay.Models/BuiltInMonitorBlacklist.cs` | Lazy-loaded reader, AOT-safe (source-gen `JsonSerializerContext`); silent fallback to empty list on any IO/parse failure | | `PowerDisplay.Lib/Services/MonitorBlacklistService.cs` | `IsBlocked(monitorId)` — extracts EdidId via `MonitorIdentity.EdidIdFromMonitorId`, checks a `HashSet<string>` with `OrdinalIgnoreCase` | | `PowerDisplay/Helpers/MonitorManager.cs` | Filters QueryDisplayConfig inventory by EdidId **before** any controller (DDC/CI or WMI) is dispatched; logs each skip with `[MonitorBlacklist] Skipping ...` | | `PowerDisplay.Lib/Drivers/DDC/DdcCiController.cs` | Logs EdidId + FriendlyName + DevicePath immediately before the first capabilities syscall per-monitor | Matching is **model-level granularity** (EdidId, e.g. `GSM7714`) rather than device-level (full DevicePath). One entry covers every physical port and every machine with the same monitor model. ### Adding new entries Once the kernel overrun is fixed this list can shrink. Until then, when a new BSOD surfaces: 1. User reports BSOD, attaches PowerDisplay log 2. The last line before the crash now reads `DDC: probing capabilities [EdidId=XXXXXX] [FriendlyName='...'] [DevicePath=...]` 3. Add `{ "edidId": "XXXXXX", "comments": "See #issue" }` to `BuiltInMonitorBlacklist.json` 4. Submit PR, ship in next release ### Scoped out (deliberate) A user-customized blacklist surface (Settings UI dialog) was prototyped and hit multiple WinUI 3 dialog parse / measure crashes inside a `ContentDialog`. The custom-list code path was reverted in favor of "built-in only" for v1 reliability. UI can be re-added later on top of this foundation if needed — the data model and service already support it. <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed 1. **Unit tests:** `dotnet test` on `PowerDisplay.Lib.UnitTests` → **120/120 pass** (including 6 new tests for loader + service: built-in JSON loads, EdidIds are normalized to upper-case, no blank entries, `Lazy<>` cache returns same instance, `IsBlocked` returns `false` for empty built-in list and for unidentifiable monitor IDs). 2. **Clean x64 Debug build** via `tools\build\build-essentials.cmd` + per-project `tools\build\build.cmd`: - `PowerDisplay.Models` — 0 warning, 0 error - `PowerDisplay.Lib` — 0 warning, 0 error - `PowerDisplay` (app) — 0 warning, 0 error 3. **Smoke test (manual):** launched PowerDisplay, confirmed every connected monitor produces a `DDC: probing capabilities [EdidId=…] [FriendlyName=…] [DevicePath=…]` log line right before its caps request. 4. **Empty-list case:** `BuiltInMonitorBlacklist.json` with no entries → `IsBlocked` returns `false` for any input (verified via unit test). 5. **Non-empty case (manual):** temporarily added a connected monitor's EdidId to the built-in JSON → that monitor disappears from `MonitorManager.Monitors` and `[MonitorBlacklist] Skipping ...` log line appears; removed the entry → monitor reappears, all per-monitor settings intact. --------- Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com> |
||
|
|
9699d8a802 |
Shortcut Guide V2 (#40834)
## Summary of the Pull Request https://github.com/user-attachments/assets/f4afdaf8-2830-4993-82ea-1ee9a6978e4c <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [x] Closes: Status: #890 #15405 #179 #129 #22419 #31289 #47297 #47464 #44816 - [x] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [x] **Localization:** All end-user-facing strings can be localized - [x] **Dev docs:** Added/updated - [x] **New binaries:** Added on the required places - [x] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [x] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [x] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: https://github.com/MicrosoftDocs/windows-dev-docs/pull/5717 <!-- Provide a more detailed description of the PR, other things fixed, or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments Work for future PRs: - [ ] Localization of built-in shortcut files - [ ] Further customization (we can wait on user feedback for that) - [ ] Reimplement holding windows key - [ ] Search bar <details> <summary>Images</summary> https://github.com/user-attachments/assets/f923daa4-d713-463b-ba33-ede72b986c12 <img width="726" height="1388" alt="image" src="https://github.com/user-attachments/assets/781eff9a-2863-44be-bbe2-25371ef8838e" /> <img width="624" height="351" alt="image" src="https://github.com/user-attachments/assets/ec8a44db-afbc-4e28-8285-ba2a9e345fb9" /> <img width="712" height="1086" alt="image" src="https://github.com/user-attachments/assets/5a3775fc-36e9-4971-8d3f-491e8f8da45a" /> <img width="726" height="134" alt="image" src="https://github.com/user-attachments/assets/7d0a8b1f-d10e-4466-820c-b3efdc5f3c84" /> </details> <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed --------- Co-authored-by: Gordon Lam (SH) <yeelam@microsoft.com> Co-authored-by: Niels Laute <niels.laute@live.nl> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Muyuan Li <116717757+MuyuanMS@users.noreply.github.com> Co-authored-by: Muyuan Li (from Dev Box) <muyuanli@microsoft.com> |
||
|
|
fa2b7f6e5f |
Fix VALID_LABELS mismatches in auto-label-issues workflow (#48027)
## Summary Corrects four label names in the \VALID_LABELS\ allow-list of the \uto-label-issues.yml\ workflow to match existing repository labels exactly. ## Root Cause The GitHub Actions \ddLabels\ API creates a brand-new label when the name doesn't exactly match an existing one. The hardcoded list had typos/mismatches: | Workflow had | Repo actually has | |---|---| | \Product-Power Display\ | \Product-PowerDisplay\ | | \Product-ColorPicker\ | \Product-Color Picker\ | | \Product-Command Not Found\ | \Product-CommandNotFound\ | | \Product-Hosts\ | \Product-Hosts File Editor\ | ## Changes - Fixed all 4 label strings in \VALID_LABELS\ array - Deleted the spurious \Product-Power Display\ label that was created by the mismatch Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |