mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-09-01 19:51:34 +02:00
dev/migrie/f/fallbackv2-impl
707 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
01271fcb52 |
fix(shortcut-guide): prevent orphaned processes during shutdown (#50091)
## Summary of the Pull Request Prevents Shortcut Guide processes from surviving Runner shutdown and blocking PowerToys upgrades. - Shuts down WinUI through its dispatcher instead of forcing CLR termination from a worker thread. - Opens and retains the Runner process handle before WinUI initialization so early Runner exits cannot be missed. - Gives the native module deterministic ownership of the Shortcut Guide process handle, with graceful shutdown and a bounded forced-termination fallback. - Keeps telemetry subprocess handles separate from the persistent UI process. - Adds `PowerToys.ShortcutGuide.exe` to the installer termination fallback so affected existing installations can recover during upgrade. ## PR Checklist - [x] **Communication:** Discussed and requested by a core contributor after investigating the release regression. - [x] **Tests:** Existing tests pass; process lifecycle and installer file replacement were also validated. ## Detailed Description of the Pull Request / Additional comments The Shortcut Guide lifecycle introduced by #48683 could call `Environment.Exit` from a Runner-watcher worker thread while WinUI was still tearing down. The native module also overwrote its persistent child-process handle when launching telemetry and did not close completed handles. Repeated Runner lifetimes could therefore leave `PowerToys.ShortcutGuide.exe` processes retaining shared WinUI files. The installer did not recover from that state: Restart Manager is disabled, the bundle and WiX close-application steps target only `PowerToys.exe`, and `TerminateProcessesCA` did not include `PowerToys.ShortcutGuide.exe`. Locked files could consequently remain at the previous version while installation continued, producing a mixed payload. `src/modules/ShortcutGuide/ShortcutGuide.Ui/Program.cs` now synchronously captures the Runner process handle and publishes its exit through a wait handle. `src/modules/ShortcutGuide/ShortcutGuide.Ui/ShortcutGuideXAML/App.xaml.cs` registers that wait with the UI dispatcher, centralizes idempotent shutdown, and disposes activation listeners and hooks deterministically. `src/modules/ShortcutGuide/ShortcutGuideModuleInterface/dllmain.cpp` now uses RAII for the tracked UI process, avoids replacing it with telemetry handles, signals the existing native exit event, waits for graceful shutdown, and terminates only as a bounded fallback. The event is projected to managed code through `src/common/interop/Constants.idl`. `installer/PowerToysSetupCustomActionsVNext/CustomAction.cpp` now includes `PowerToys.ShortcutGuide.exe` in the MSI process-termination fallback, allowing upgrades from already-affected builds. ## Validation Steps Performed - Built `PowerToys.Interop.vcxproj`, `ShortcutGuideModuleInterface.vcxproj`, `ShortcutGuide.Ui.csproj`, and `PowerToysSetupCustomActionsVNext.vcxproj` for x64 Release. - Built and ran `ShortcutGuide.UnitTests`: 48/48 passed. - Repeated Runner/Shortcut Guide startup and parent-exit teardown 10 times; every child exited with code 0. - Verified the race where the Runner exits before Shortcut Guide initializes. - Verified `PowerToys.ShortcutGuide.exe`, `PowerToys.Interop.dll`, and `Microsoft.UI.Xaml.dll` were immediately replaceable after shutdown. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7f6c4822-53e0-42ae-a51a-a302a7c6d3ab |
||
|
|
6cfe2179c4 |
fix(shortcut-guide): restore transparent overlay on Windows 10 (#50094)
## Summary of the Pull Request Restores the transparent Shortcut Guide overlay on Windows 10 by removing the full-bleed DWM hardening introduced for the monitor-sized host window. The hardening set `DWMWA_NCRENDERING_POLICY` to `DWMNCRP_DISABLED`, which disables earlier `DwmEnableBlurBehindWindow` and `DwmExtendFrameIntoClientArea` behavior used by WinUIEx's transparent backdrop. Shortcut Guide now relies on the existing baseline transparent chrome instead. ## PR Checklist - [x] Closes: #49975 - [x] Closes: #50076 - [x] **Communication:** Investigated from the active reports and validated with a core contributor - [x] **Tests:** Existing build validation and manual end-to-end validation pass; no automated test covers DWM composition behavior - [x] **Localization:** N/A; no end-user-facing strings changed ## Detailed Description of the Pull Request / Additional comments - Removes `ApplyFullBleedHardening` and its DWM/style interop from `src/common/Common.UI.Controls/Window/TransparentWindow/TransparentWindow.cs`. - Removes both Shortcut Guide call sites and updates the related comments in `src/modules/ShortcutGuide/ShortcutGuide.Ui/ShortcutGuideXAML/OverlayWindow.xaml` and `OverlayWindow.xaml.cs`. - Keeps `ApplyTransparentChrome`, including native-frame removal, DWM border suppression, corner suppression, and tool-window behavior. It is still reapplied after cross-monitor moves. This avoids disabling the DWM path required for transparency while preserving the normal borderless overlay setup. ## Validation Steps Performed - Built the complete x64 Debug `PowerToys.slnx` successfully with an empty errors log. - Launched `x64\Debug\PowerToys.exe` and confirmed the rebuilt Shortcut Guide process was active. - Invoked Shortcut Guide through the Runner and manually confirmed the overlay rendered transparently and behaved correctly on the Windows 11 development machine. Copilot-Session: e7fa0065-bbdd-403c-9444-23ab3ca9d56a |
||
|
|
5759a62d4a |
[UITests][Keyboard Manager] UI tests for new keyboard manager. (#50059)
<!-- Suggested title: [UITests][Keyboard Manager] Add and stabilize UI tests for the unified editor --> ## Summary of the Pull Request Closes: #40662 Adds a new `Microsoft.PowerToys.UITest.Next` end-to-end suite for Keyboard Manager and hardens the unified editor behavior uncovered while exercising it on Windows 10, Windows 11, x64, and ARM64. The Keyboard Manager suite executes 32 test cases covering: - Unified editor create, edit, save, enable/disable, delete, restart persistence, missing-profile recovery, validation, and special actions. - Single-key, key-to-shortcut, shortcut-to-shortcut, shortcut-to-key, disabled-key, and app-specific remapping. - Modifier ordering and release behavior, including Alt+Tab and Alt+F4 targets. - Real keyboard behavior through Windows Notepad and Calculator fixtures rather than synthetic input windows. The PR also adds 26 managed unit tests around settings normalization, profile reconciliation, metadata ownership, active-state changes, and canonical modifier ordering. ## Detailed Description of the Pull Request / Additional comments ### Keyboard Manager UI tests Adds `src/modules/keyboardmanager/Tests/KeyboardManager.UITests` as a Microsoft Testing Platform executable using `UITestAutomation.Next` and winappcli. The suite includes: - `KeyboardManager.Editor.CreateEditPersistDelete` - Creates and edits mappings. - Verifies native profile and editor metadata persistence across restarts. - Exercises active-state toggling, row deletion, and missing native-profile recovery. - `KeyboardManager.Editor.InputAndValidation` - Covers key recording, dropdown input, keyboard navigation, cancellation, and app-specific validation. - `KeyboardManager.Editor.ActionPersistence` - Covers Open URL, Open app, and Insert text actions and verifies canonical readback after restart. - Parameterized runtime tests for key/shortcut combinations, disabled targets, app-specific mappings, modifier release order, Alt+Tab, and Alt+F4. The test support code provides: - A shared cross-process fixture lock and isolated Keyboard Manager settings scope. - Real Notepad documents with exact window/document ownership and cleanup. - Win10/Win11-aware Calculator window ownership for Alt+F4 assertions. - A low-level keyboard event recorder that validates injected key-down/key-up sequences and flags. - Authoritative persisted JSON assertions instead of relying only on transient UI state. ### Keyboard Manager correctness fixes found by the suite The tests exposed product races and persistence issues that are fixed in the same PR: - Native profile JSON is written through checked same-directory atomic replacement instead of a truncation-prone direct write. - Editor metadata and native mappings are normalized and reconciled per profile. - Create, edit, delete, and active-state mutations commit metadata and native state transactionally under a cross-process lock. - Startup reconciliation preserves inactive metadata owned by other profiles and repairs legacy/profileless settings. - Native Boolean return values use one-byte marshaling to match the C++ ABI. - Modifier keys and serialized targets are canonicalized consistently. - Unit-test initialization no longer starts real settings synchronization. ### CI stability hardening The editor workflows use coordinate-free UIA invocation for command buttons and authoritative-signal retries for idempotent row interactions. Window fixtures bind exact top-level HWNDs and distinguish the Win10 Calculator `ApplicationFrameWindow` from its child content window. The child-specific `UITestAutomation.Next` updates add or improve: - `WindowShowWatcher` lifecycle handling used by the Keyboard Manager window fixtures. - Exact HWND foreground, close, and process-tree cleanup helpers required by the Win10/Win11 tests. ### Pipeline workflow Adds the internal `ui-tests-pipeline-ci` skill and Azure DevOps helper used during stabilization: - Uses an existing Azure CLI session plus Azure DevOps REST APIs without per-call authentication prompts. - Supports paged branch/build discovery, preview and queue operations, exact-SHA reconciliation, stage retry/cancel, logs, test results, artifacts, and direct result-attachment downloads. - Uses build-scoped one-shot completion monitoring and retains the three-run stabilization guardrail. ## Validation Steps Performed ### Azure DevOps UI Test Automation Final verification build: - https://microsoft.visualstudio.com/Dart/_build/results?buildId=155512681&view=results - https://microsoft.visualstudio.com/Dart/_build/results?buildId=155525972&view=results ## Reviewer guide Suggested review order: 1. `src/modules/keyboardmanager/Tests/KeyboardManager.UITests/` - intended workflows and assertions. 2. `KeyboardManagerEditorUI/Settings/SettingsManager.cs` and `Pages/MainPage.xaml.cs` - transaction and reconciliation ownership. 3. `common/MappingConfiguration.cpp` and `Interop/KeyboardManagerInterop.cs` - native persistence and ABI fixes. 4. `src/common/UITestAutomation.Next/WindowControl.cs` and `WindowShowWatcher.cs` - child-specific window lifecycle hardening. 5. `.github/skills/ui-tests-pipeline-ci/` - internal Azure CLI/REST stabilization workflow. Local evidence: <img width="1237" height="854" alt="image" src="https://github.com/user-attachments/assets/ff49652e-fbc8-4581-a48f-836dbed37b6e" /> |
||
|
|
d68980a81b |
[UITests][FancyZones + Editor] Migrate FZ UI tests to .Next framework + add new tests (#49985)
# test(fancyzones): migrate and expand UI tests to winappcli ## Summary of the Pull Request Part of #40658. Adds `FancyZones.UITests.Next`, a Microsoft.Testing.Platform test executable built on `UITestAutomation.Next` and winappcli. It ports the 18 active legacy FancyZones tests and adds 3 conservative backend scenarios selected from the larger manual plan: - quick-layout switching during an active window drag - excluded-app enforcement - one-monitor keyboard snapping, zone cycling, and last-zone restore on reopen The suite now contains 21 tests. Editor CRUD and layout-authoring coverage remains in the separate `FancyZonesEditor.UITests` project. The migration also fixes two FancyZones defects exposed by the new tests: swallowed Shift input did not update drag state, and the first Shift-triggered zone highlight was reset after it was calculated. ## PR Checklist - [ ] Closes: #49426 - [x] CI Green https://microsoft.visualstudio.com/Dart/_build/results?buildId=155118915 ## Detailed Description of the Pull Request / Additional comments ### FancyZones test migration - Registers `FancyZones.UITests.Next` for x64 and ARM64 in `PowerToys.slnx`. - Ports dragging, quick-layout, virtual-desktop, window-switching, transparency, editor-launch, and process-start coverage. - Adds focused coverage for excluded apps, keyboard snap override/cycling, last-zone restore, and quick-layout switching during a drag. - Uses per-monitor-v2 DPI awareness and keeps the legacy WinAppDriver suite in place. ### Stable behavioral signals - Uses `app-zone-history.json`, `applied-layouts.json`, and per-HWND `FancyZones_zones` properties instead of relying on visual geometry alone. - Uses WinEvent hooks for transient zone flashes and Win32 window/process queries for cheap readiness checks. - Drives the layout editor through its named event and verifies the resulting files. - Tracks Explorer windows by HWND, validates title-bar point ownership, recomputes grab coordinates after failures, and retries the complete drag gesture. - Keeps modifier state through `MOVESIZEEND` and avoids cursor movement that changes the selected zone. ### Product fixes - Records Shift state before the low-level hook swallows the key during an active move loop. - Enters snapping mode before calculating the first highlighted zone so the transition does not reset that result. ### Shared framework and CI hardening - Adds reusable named-event, window-show watcher, keyboard-state, window-property, alpha, foreground, and capture helpers to `UITestAutomation.Next`. - Advances the centrally managed .NET package set from `10.0.10` to `10.0.11` to match the runtime packs selected by SDK `10.0.400` and prevent dependency-audit collisions. - Documents Azure Artifacts runtime-pack cache misses and the authenticated upstream-cache workflow. The broader manual checklist remains intentionally manual where automation would be costly or fragile: multi-monitor/span scenarios, lock/reboot and device reconnect, administrator boundaries, child/popup windows, appearance color rendering, and overlap-algorithm visuals. FancyZones Editor creation/copy/delete/grid/canvas workflows are already covered by its dedicated UI-test project. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: khmyznikov <6115884+khmyznikov@users.noreply.github.com> |
||
|
|
ab1f521067 |
fix(shortcutguide): separate hotkey and Win hold activation (#50000)
## Summary of the Pull Request Fixes a regression where `Win+Shift+/` was treated as a Windows-key hold because both activation paths signaled the same event. Regular activation now opens the full Shortcut Guide independently of the **Hold Windows key** setting and remains visible after Win is released. ## PR Checklist - [x] Closes: #49990 - [ ] **Communication:** Core contributor review is still required - [x] **Tests:** Added/updated and all pass - [x] **Localization:** N/A - no end-user-facing strings changed - [x] **Dev docs:** N/A - no developer-facing contract or workflow changed ## Detailed Description of the Pull Request / Additional comments - Keeps regular activation on `OnHotkeyEx()` and routes Win-only holds through the existing `on_hotkey(size_t)` module seam with a reserved ID. - Adds a dedicated named event for Win-key hold activation while preserving the existing regular trigger event and module ABI layout. - Removes `GetAsyncKeyState` trigger-source inference from Shortcut Guide UI. - Tracks the source and visible surface explicitly so Win release closes only hold-owned UI: - regular hotkey always opens the full guide and is unaffected by hold settings; - **Off** ignores Win-only holds; - **Taskbar indicators** closes on Win release; - **Open Shortcut Guide** follows the configured close-on-release value. - Handles both left and right Windows keys. - Clears stale held-key registrations and pending timers before re-registering them. - Uses `MOD_NOREPEAT` for centralized activation hotkeys so a held chord cannot repeatedly toggle the overlay. - Normalizes `MOD_NOREPEAT` before centralized action lookup, validates queued hold activations against the current Win-key state, and transfers hold-owned full-guide surfaces to regular-hotkey ownership. - Adds a pure activation policy and a data-driven unit-test matrix. Touched areas: - `src/runner/` - source-specific dispatch, held-key registration cleanup, and repeat suppression. - `src/common/interop/` - additive hold-event constant and WinRT projection. - `src/modules/ShortcutGuide/ShortcutGuideModuleInterface/` - dedicated hold event signaling and hold-setting guard. - `src/modules/ShortcutGuide/ShortcutGuide.Ui/` - explicit activation routing and source-aware release behavior. - `src/modules/ShortcutGuide/ShortcutGuide.UnitTests/` - activation and release policy coverage. **Risks and mitigations** - The existing regular event and settings JSON remain unchanged. - No virtual method or data member was added to `PowertoyModuleIface`; the existing `on_hotkey(size_t)` method is reused. - Duplicate hold callbacks are prevented during settings refresh, and duplicate hold events are UI no-ops. - No new telemetry or user-content logging was added. ## Validation Steps Performed - Built the full x64 Release solution and confirmed the complete payload starts without missing-module dialogs or Runner startup errors. - After rebasing onto current `main`, reran `tools\build\build-essentials.cmd -Platform x64 -Configuration Release` and built the affected interop, Runner, module-interface, index-generator, UI, and unit-test projects; all error logs were empty. - Ran the x64 Release `ShortcutGuide.UnitTests.dll` with `vstest.console.exe`: **43/43 passed**, including all 15 activation-policy cases. - After addressing review feedback, rebuilt the x64 Release Runner, Shortcut Guide UI, and unit-test projects; all builds passed and the unit tests remained **43/43**. - Signaled a queued hold after Win was released and confirmed no overlay opened. Then exercised hold-owned full-guide to regular-hotkey ownership transfer and confirmed both activations resolved to `ShowFullGuide` and the guide remained visible after Win release. - Held an injected `Win+Shift+/` chord for 1.4 seconds over Notepad: the full guide opened, remained visible after Win release, and logs recorded two regular activations (open/close) with **zero** hold activations. - Triggered the dedicated hold event over Notepad in both hold modes: - **Taskbar indicators:** the 2048x1104 overlay was visible and `WS_EX_TOPMOST`. - **Open Shortcut Guide:** the full guide and taskbar indicators were visible in the same topmost overlay. Manual verification matrix for a preview build: 1. Set **Hold Windows key** to Off, Taskbar indicators, and Open Shortcut Guide. 2. In each mode, press and release `Win+Shift+/`; confirm one full panel remains visible. 3. Hold LWin and RWin separately; confirm only the selected hold behavior runs. 4. For Open Shortcut Guide, verify close-on-release enabled and disabled. 5. Verify a second regular activation toggles the full panel closed. For physical Win-hold checks, run PowerToys at the same or higher integrity level as the foreground app. `RegisterHotKey` activation can work across an elevation mismatch while Runner's low-level hold hook cannot observe the key. Closes #49990 --------- Copilot-Session: 8271bded-18e8-474e-8e3b-addd71f67f50 |
||
|
|
4494a96be6 |
chore(common): remove unused shared UI dependencies (#49895)
## Summary of the Pull Request Removes unused dependencies, stale API surface, and unreachable managed settings deep-link aliases from the shared UI libraries. ## PR Checklist - [x] **Communication:** Cleanup scope was reviewed before implementation - [x] **Tests:** No automated tests were needed for unused dependency/API removal; affected projects build successfully - [x] **Localization:** No end-user-facing strings are changed - [x] **New binaries:** No new binaries are introduced ## Detailed Description of the Pull Request / Additional comments - Removes unused `CommunityToolkit.WinUI.Controls.Primitives` and `CommunityToolkit.WinUI.Converters` package references from `src/common/Common.UI.Controls/Common.UI.Controls.csproj`. - Removes the unused `FlyoutWindowHelper.GetDpiScale(WindowEx)` overload from `src/common/Common.UI.Controls/Window/FlyoutWindowHelper.cs`. - Removes the unused `SettingsDeepLink.SettingsWindow.PowerDisplay` value; PowerDisplay uses its module-local settings deep-link helper. - Removes unreachable `Run` and `PowerPreview` managed aliases, superseded by `PowerLauncher` and `FileExplorer`, plus their dead CmdPal lookup cases. - Preserves the runner's raw `--open-settings=Run` and `--open-settings=PowerPreview` routes for backward compatibility. - Intentionally leaves the existing WinForms configuration and compatibility project references unchanged. ## Validation Steps Performed - Built `src/common/Common.UI/Common.UI.csproj` for x64 Debug. - Built `src/common/Common.UI.Controls/Common.UI.Controls.csproj` for x64 Debug. - Built `src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.PowerToys/Microsoft.CmdPal.Ext.PowerToys.csproj` for x64 Debug. - Ran `git diff --check`. --------- Copilot-Session: f4b96463-079f-47c2-ae9b-7f4c59baf591 |
||
|
|
69a600e249 |
feat(File Explorer): Add configurable local image rendering to Markdown previewer (#47857)
## Summary - Adds a "Show local images" toggle in PowerToys Settings (File Explorer > Markdown) - When enabled, renders images referenced via relative paths or local file paths in the Markdown preview pane - Serves validated local image files on a WebView2 virtual host (`https://localmdimages/`) directly from the handler's resource filter - Supports local paths and UNC/network share paths - Default: OFF (preserves existing behavior) - GPO support: Admins can force-enable or force-disable via Group Policy Fixes #40787 Fixes #3713 ## Security model | Scenario | Behavior | |----------|----------| | Setting OFF (default) | All images blocked, info bar shown. Raw HTML `src` is rewritten to `#` in this state too, so a `data:` image cannot render (it is resolved internally and never reaches the resource filter) | | Setting ON + relative path (`media/img.png`) | Resolved against .md directory, rendered if under that tree | | Setting ON + path traversal (`../../secret.png`) | Blocked — resolved with `Path.GetFullPath` and checked with `Path.GetRelativePath`, including percent-encoded traversal on the serving side | | Setting ON + junction/symlink below the allowed path | Blocked — each component of the resolved path is rejected if it carries `FileAttributes.ReparsePoint`, since lexical containment alone does not prevent redirection | | Setting ON + UNC relative path (`images/pic.png` on `\\server\share`) | Allowed within share root | | Setting ON + remote URL (`https://evil.com/track.png`) | Always blocked | | data:/javascript: URI | Always blocked, in both setting states | | `srcset` on a raw HTML `<img>` | Attribute removed, in both setting states — its candidates are not validated by the `src` sanitizer | | Script execution | Always disabled (`IsScriptEnabled = false`) | | Mark-of-the-Web (MotW) | Explorer blocks preview of MotW-tagged files before our code runs (OS-level protection) | ## GPO Policy - Policy name: `MarkdownAllowLocalImages` - Registry: `HKLM\SOFTWARE\Policies\PowerToys\MarkdownAllowLocalImages` (DWORD: 1=enabled, 0=disabled) - ADMX category: **PowerToys > File Explorer Preview** - Uses `getConfiguredValue()` (individual module setting pattern, no global utility fallback) ## Screenshots ### Settings UI — new toggle _"Show local images" toggle nested under the Markdown preview section (File Explorer add-ons). Captured from a Debug build of this branch (the Settings app only runs standalone in Debug builds):_ <img width="1904" height="1014" alt="07-settings-ui-toggle" src="https://raw.githubusercontent.com/st-gr/PowerToys/pr-47857-assets/07-settings-ui-toggle.png" /> ### Settings UI — locked by GPO _With the `MarkdownAllowLocalImages` policy set to Disabled, the toggle is forced Off and grayed out, and the "managed by your organization" info bar appears:_ <img width="1904" height="1014" alt="08-settings-ui-gpo-locked" src="https://raw.githubusercontent.com/st-gr/PowerToys/pr-47857-assets/08-settings-ui-gpo-locked.png" /> ### GPO in Group Policy Editor _New "File Explorer Preview" category under PowerToys, showing the policy and its description:_ <img width="1472" height="847" alt="01-gpedit-category" src="https://github.com/user-attachments/assets/54acb539-345b-4512-9685-35930966a142" /> ### GPO set to Enabled _Policy enabled state in gpedit.msc:_ <img width="1473" height="848" alt="02-gpedit-policy-enabled" src="https://github.com/user-attachments/assets/883f6b22-179d-4311-983d-2d835e4d897a" /> ### Preview with local images rendered _Markdown preview with local image rendering enabled — relative path image renders:_ <img width="1430" height="881" alt="03-preview-images-shown" src="https://github.com/user-attachments/assets/4a7ac7f0-d57d-4feb-bf2f-7e3c9093ab52" /> ### Info bar for blocked remote images _When the document contains remote (http/https) image URLs, they are always blocked and an info bar is shown:_ <img width="1412" height="1035" alt="04-preview-infobar" src="https://github.com/user-attachments/assets/0f798bbc-ae1b-43bf-b343-394080fff8e3" /> ### GPO disabled — all images blocked _With GPO set to disabled, all images (local and remote) are blocked. Info bar reads "Some pictures have been blocked...":_ <img width="1417" height="704" alt="05-gpo-disabled-blocked" src="https://github.com/user-attachments/assets/1c7a09a7-f4b9-467c-a0c0-f670680d6a2d" /> ### Mark-of-the-Web protection _Files copied from a network source carry a Zone Identifier (MotW). Explorer blocks the preview entirely before our code runs — an OS-level security layer:_ <img width="1114" height="591" alt="06-MotW-tagged" src="https://github.com/user-attachments/assets/09cc2055-1e12-4c11-81fb-abd83ab8249c" /> ## Implementation Two layers were blocking images: 1. **Markdig AST layer** (`HTMLParsingExtension.cs`): replaced image URLs with `#` 2. **WebView2 layer** (`MarkdownPreviewHandlerControl.cs`): returned HTTP 403 for all non-HTML requests Changes: - `HTMLParsingExtension`: conditionally resolves markdown `` images to virtual host URLs with path traversal protection - `MarkdownHelper`: regex-rewrites relative `src=""` in raw HTML `<img>` tags to virtual host URLs - `MarkdownPreviewHandlerControl`: serves `https://localmdimages/` requests in the `WebResourceRequested` handler — the URL is resolved back to a file path, re-validated for containment against the allowed base path (document directory, or share root for UNC), and the bytes are returned via `CreateWebResourceResponse` with the proper content type. Note: `SetVirtualHostNameToFolderMapping` is deliberately NOT used for images — WebView2 Runtime 150+ no longer serves files from UNC/network folder mappings (verified by A/B test on 150.0.4078.48); serving from the handler works uniformly for local and UNC paths - Settings UI: new toggle nested under the Markdown preview expander, with GPO lock support - Handler `Settings.cs`: reads `EnableMdLocalImages` via `SettingsUtils`, GPO override via `GPOWrapper` - GPO: `gpo.h` individual module setting, ADMX/ADML with `FileExplorerPreview` category ## Known limitation Peek also renders Markdown through `FilePreviewCommon.MarkdownHelper`, but calls it without the local-images arguments, so **Peek does not show local images even when the setting is enabled** — it keeps the existing behavior of blocking every image. With the setting on, the same file therefore renders differently in the preview pane (images shown) and in Peek (images blocked). This is deliberate for now: wiring the setting through Peek means changing a module that is otherwise untouched by this PR. Verified that Peek itself is unaffected — it still renders Markdown correctly against the shared assembly, with images blocked as before. ## Test plan - [x] Toggle OFF: images blocked, "pictures blocked" info bar shows (existing behavior) - [x] Toggle ON with relative paths: `` renders - [x] Toggle ON with HTML img: `<img src="images/test.png">` renders - [x] Toggle ON with path traversal: `` — blocked - [x] Toggle ON with remote URL: `` — blocked, info bar shown - [x] UNC path: preview works on `\\server\share\...\file.md` with relative images - [x] UNC path with `../` within share: allowed (resolves within share root) - [x] Regression tested on WebView2 Runtime 150.0.4078.48: local + UNC images render, blocked cases (traversal, data:, remote, encoded traversal) stay blocked - [x] GPO Enabled: images forced on - [x] GPO Disabled: images forced off - [x] GPO Not Configured: user controls toggle - [x] gpedit.msc: policy appears under PowerToys > File Explorer Preview - [x] MotW-tagged files: Explorer blocks preview before our code runs - [x] Settings UI toggle locked when GPO configured (grayed out for both forced states) - [x] Other preview handlers (Monaco, SVG, PDF) unaffected 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
fe4a86a54d |
[Quick Accent] Cloak the accent bar instead of hiding it (#49655)
## Summary of the Pull Request Follow-up to #49633: replace the way the accent bar's first frame is protected. #49633 fixed the blank/stale first frame (#49489) by masking it — `Selector.Opacity = 0`, unveil after two `CompositionTarget.Rendering` ticks, backed by a 150 ms watchdog. This PR removes the cause instead, using the technique the Command Palette and Quick Access already ship: **DWM-cloak the overlay instead of hiding it**, so it never stops rendering and there is no stale frame to put back on screen. No user-visible behaviour change is intended beyond removing the fixed two-render-tick reveal delay; this is a mechanism swap plus the cleanup it enables. ## PR Checklist - [x] **Closes:** N/A — #49489 was already closed by #49633; this replaces that fix's mechanism - [x] **Communication:** follow-up to a merged PR in the same module, no new feature surface - [x] **Tests:** `PowerAccent.Core.UnitTests` 32/32 still pass (the pure width logic from #49633 is untouched). The current-head CI status is tracked in the PR checks; the compositor-specific manual measurements below were captured before the final commit-fence follow-up and are labeled accordingly - [x] **Localization:** no new end-user-facing strings - [x] **Dev docs:** N/A - [x] **New binaries:** none - [x] **Documentation updated:** N/A ## Detailed Description of the Pull Request / Additional comments ### Why cloaking A hidden WinUI 3 window renders nothing. Its composition surface therefore still holds the frame it was showing when it was hidden, and `ShowWindow` puts that stale frame back on screen before the rebuilt accent list has been laid out — that is #49489. Everything downstream of that follows from "the window does not render while hidden": * the bar cannot be measured before it is shown (a `Collapsed` subtree is never measured), hence #49633's measure-twice workaround; * #49633 deferred reveal using rendering ticks because it did not have a composition-commit fence; * this PR calls `Microsoft.UI.Composition.Compositor.RequestCommitAsync()` after the bar has been laid out, sized, positioned and scrolled, and only reveals after that commit completes. This replaces the frame counter and watchdog with an explicit compositor fence. A cloaked window is equally invisible to the user but stays `SW_SHOWNA`-shown, so XAML keeps laying it out and painting it. This is exactly what `Microsoft.CmdPal.UI\MainWindow.xaml.cs` does, and its comment names the same symptom: ```csharp // TRICKY: show our HWND again. This will trick XAML into painting our // HWND again, so that we avoid the "flicker" caused by a WinUI3 app // window being first shown ``` `QuickAccess.UI\QuickAccessXAML\MainWindow.xaml.cs` uses the same pattern, including the "warm up the window while cloaked" prewarm that this PR also picks up — which is what removes the *first summon of the process* case that #49633's second measurement existed for. ### What the summon looks like now `Show()` still raises `Showing`, so the surface leaves `Collapsed` and the bar lays out — but the window is still cloaked, so nothing reaches the screen. The bar is then measured **once** (on a templated, laid-out, non-collapsed subtree), sized, positioned and scrolled to the selection. The compositor commit is then awaited, and only after it completes does `Reveal()` uncloak the window. The first visible frame is a finished bar by construction rather than by timing. Removed as a result: `RevealTimeoutMs`, `FramesBeforeReveal`, `_revealTimer`, `_revealGeneration`, `_renderedFrames`, `_measuredContentWidthDip`, `ArmRevealTimeout`, `CancelPendingReveal`, `WaitForFirstFrameThenReveal`, `OnRenderingBeforeReveal`, the local `Reveal`, and the `Selector.Opacity` dance — 87 net lines out of `MainWindow`. `_showGeneration` stays: a layout callback queued by a dismissed summon still has to be dropped. ### `TransparentWindow` The cloak lives in the shared window because `Hide()` owns the `AppWindow.Hide()` that has to be replaced. It is **opt-in** (`EnableCloakedHide()`), so Shortcut Guide's overlay and CmdPal's toast keep hiding exactly as they do today; only Quick Accent enables it. `Reveal()` is a no-op for them. Two details worth review attention: * **Hit-testing.** Cloaking takes a window out of composition but *not* out of hit-testing, and this HWND sits exactly where the user is typing. While cloaked the window is therefore made click-through (`WS_EX_TRANSPARENT`), restored on reveal. Without this, an invisible accent bar would swallow clicks meant for the app underneath. * **`SW_HIDE` then `SW_SHOWNA`.** Same order as CmdPal: the hide is what hands the foreground back to whatever window should own it, and the show that follows leaves the window "shown" — which is what keeps XAML painting — while the cloak keeps it off screen. If DWM refuses to cloak, the HWND remains hidden; a later `Show()` retries instead of exposing an un-laid-out frame. ### Relationship to #34849 / #41044 Always-on-top is still released on hide, so the dormant overlay is `WS_EX_TOPMOST=False` exactly as before — verified below. Cloaking is orthogonal to topmost. The one honest trade-off is that the HWND is now permanently `WS_VISIBLE` (cloaked), so it keeps participating in composition while dormant, the same as CmdPal and Quick Access already do; it stays out of Alt-Tab and the taskbar via a hidden owner plus `WS_EX_TOOLWINDOW`. ## Validation Steps Performed > The build/test/live-state results below were recorded at `e372cdf`. Current head `ea658bb` adds the explicit `RequestCommitAsync` fence after that validation. Current-head CI is tracked by the PR checks, and the live window-state/frame-capture checks should be repeated before merge. * `build-essentials`, `Common.UI.Controls`, `PowerAccent.UI` and `PowerAccent.Core.UnitTests` all build clean (Debug|x64), 0 warnings. * `PowerAccent.Core.UnitTests`: 32/32 pass. * Live window-state measurement against the built `PowerToys.PowerAccent.exe` (`DwmGetWindowAttribute(DWMWA_CLOAKED)` + `IsWindowVisible` + ex-styles), driving a real summon of the <kbd>R</kbd> bar with **All languages** selected: | phase | state | |---|---| | dormant (prewarmed, before any summon) | `visible=True cloaked=1 topmost=False clickThrough=True` | | summoned | `visible=True cloaked=0 topmost=True clickThrough=False` | | dismissed | `visible=True cloaked=1 topmost=False clickThrough=True` | i.e. the window is shown-and-painting the whole time, invisible and click-through while dormant, and topmost/interactive only while summoned. * Screen-captured the summoned bar: all 22 characters for <kbd>R</kbd> render (including the wide `₹ ៛ ﷼`), leading and trailing padding are symmetric, nothing is clipped and the selection is on the first cell. --------- Co-authored-by: Yu Leng <yuleng@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
e48152c52d |
[UITests] Add UITest.Next suites (Image Resizer, Peek, File Explorer add‑ons, File Locksmith) + local‑VM tooling and CI test‑signing (#49671)
## Summary Adds end‑to‑end UI tests on the `Microsoft.PowerToys.UITest.Next` (winappcli) framework for three modules, grows the shared `.Next` test framework with the helpers those suites needed, and adds the CI plumbing that lets shell‑extension tests exercise the **real** Windows 11 modern context menu. Also ships two agent skills that document how to write and run these tests. Product runtime behavior is **unchanged** — the only product edits are test‑observability hooks in Peek and a unit‑test project exclude. Closes: https://github.com/microsoft/PowerToys/issues/40660 https://github.com/microsoft/PowerToys/issues/49424 https://github.com/microsoft/PowerToys/issues/40661 ## What's added ### New UI test suites - **Image Resizer** — `src/modules/imageresizer/tests/ImageResizer.UITests`: context‑menu enable/disable tracking, the resize dialog, custom presets, every fit mode, every unit, filename format, keep‑date, shrink‑only, replace‑in‑place, and orientation. - **Peek** — `src/modules/peek/Peek.UITests.Next`: file‑preview coverage across image/text/archive/ markdown types with per‑arch visual baselines. - **File Explorer add‑ons** — `src/modules/previewpane/PreviewPane.UITests`: Preview Pane handlers and thumbnail providers. ### `UITestAutomation.Next` framework - New helpers: `ExplorerShell` (Shell selection/view‑mode interop), `WaitHelper` (structured stable waits), `WindowControl` (foreground/context‑menu/process control), `VisualAssert` (image compare), `WindowHelper`. - Updates to `Session`, `UITestBase`, `SettingsConfigHelper`, `WinappCli`. - New `UITestAutomation.Next.UnitTests` project covering the new wait/settings/CLI helpers. ### CI — sign sparse MSIX so the modern menu registers - **`.pipelines/signSparsePackages.ps1`** — self‑signs each sparse context‑menu MSIX with a publisher‑matching test certificate and force‑trusts it (machine stores), so `AddPackageByUriAsync` succeeds on otherwise‑unsigned PR builds. Robust `signtool` discovery with a NuGet fallback; test‑only trust that asserts no security. - Wired into **`.pipelines/v2/templates/job-test-project.yml`** as a best‑effort step covering the run‑in‑place, machine‑install, and per‑user‑install locations. Signs nothing it can't (skips already‑signed packages) and never fails the job. ### Product changes (test observability only) - **Peek `FilePreview.xaml` / `.xaml.cs`** — a named `LoadingIndicator` and a hidden automation peer that exposes the current preview state as text, so tests can read load state deterministically. No runtime behavior change. - **`ImageResizer.UnitTests.csproj`** — exclude the sibling `ImageResizer.UITests\**` folder from the unit‑test compilation. ### Agent skills & docs - **New `ui-tests-local-vm` skill** — run `.Next` suites in persistent dockur/windows VMs: setup, agentic loop, image customization, troubleshooting, the shell‑extension **signing** reference, plus controller/guest scripts and VM templates. - **Updated `ui-tests-migration` skill** — WinAppDriver/Selenium → `.Next` porting guidance (CI stability, Explorer/shell‑extension test design, patterns & pitfalls). - **`doc/devdocs/development/ui-tests.md`** — updated for the `.Next` workflow. ## Testing - All three suites pass locally and in CI across **x64 Win10**, **x64 Win11**, and **arm64** (machine and per‑user install legs). ## Reviewer notes - No product runtime behavior changes; product edits are limited to the Peek test hooks above. - The CI signing step is a **test‑only** trust anchor (self‑signed, scoped to the agent) and is best‑effort, so it can only add modern‑menu coverage and never regress the job. |
||
|
|
731f2e3b5f |
Prefer running executable location when resolving PowerToys install path (#48905)
## Summary of the Pull Request `PowerToysPathResolver.GetPowerToysInstallPath()` now resolves the PowerToys installation directory from the **running executable''s own location** first, and only falls back to the registry when the caller is not running from within the PowerToys install tree. Previously the resolver always went through the registry (the `powertoys` protocol registration) for release builds. For the common callers — module executables that ship in the PowerToys install folder (Settings deep links from Color Picker, FancyZones, Image Resizer, Workspaces, etc.) — the install directory is simply the folder the binary was loaded from, so reading it from the running process is more direct and does not depend on the registry registration being present or up to date. The registry path is retained as a fallback for callers that legitimately run **outside** the install tree — notably the packaged Command Palette extension host (MSIX, deployed under `WindowsApps`), which has no other way to locate a separately-installed PowerToys to launch `WinUI3Apps\PowerToys.Peek.UI.exe`. ## PR Checklist - [ ] Closes: #xxx - [x] **Communication:** discussed with core contributors - [ ] **Tests:** Added/updated and all pass - [x] **Localization:** No end-user-facing strings changed - [x] **Dev docs:** Not applicable - [x] **New binaries:** None added ## Detailed Description of the Pull Request / Additional comments `GetPowerToysInstallPath()` (release path) now: 1. Resolves from the current process location first via the existing `GetPathFromCurrentProcess()` helper. This works for both per-user and per-machine installs and for any caller that runs from inside the install tree. 2. Falls back to the registry only when step 1 yields nothing — i.e. for the packaged Command Palette extension host that runs from `WindowsApps`. The per-machine (HKLM) registration is consulted for any process running with administrator rights, since the per-user (HKCU) registration is only meaningful for the interactive user. The change reuses existing helpers (`GetPathFromCurrentProcess`, `GetPathFromRegistry`) and adds no new public API, dependencies, or binaries. Debug-build behavior is unchanged. ## Validation Steps Performed - Built `ManagedCommon` (Release) — compiles clean, 0 warnings / 0 errors. - Verified the three callers of `GetPowerToysInstallPath()`: - In-tree module callers (Settings deep links, Workspaces) resolve via the running executable location. - The packaged Command Palette Indexer (`PeekFileCommand`) still resolves via the registry fallback, since it runs from `WindowsApps` and PowerToys is installed separately. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Boliang Zhang (from Dev Box) <bozhang@microsoft.com> Copilot-Session: 41b6b39b-b620-4e02-b7ca-8ae470a9c1e2 |
||
|
|
ed7595f3a7 |
Harden IPC pipe ownership and shutdown lifecycle (#48902)
## Summary of the Pull Request The two-way named-pipe IPC server (`TwoWayPipeMessageIPC`, shared by the runner, Settings, and Quick Access host) created every pipe instance without `FILE_FLAG_FIRST_PIPE_INSTANCE`. If a pipe with the same name already existed — for example a leftover instance from a previous run or another process — `CreateNamedPipe` would quietly create an *additional* instance and share the name instead of owning it. This makes `start_named_pipe_server` create the **first** instance with `FILE_FLAG_FIRST_PIPE_INSTANCE`, so `CreateNamedPipe` fails fast on a name collision and the server is the authoritative owner of its pipe name. ## PR Checklist - [ ] **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 (N/A — no user-facing strings) - [x] **Dev docs:** Added/updated (N/A) - [x] **New binaries:** Added on the required places (N/A — no new binaries) ## Detailed Description of the Pull Request / Additional comments - The flag is applied **only** to the first instance. Subsequent instances continue to omit it, so the existing `PIPE_UNLIMITED_INSTANCES` behavior is fully preserved. - The change is contained to a single function in `src/common/interop/two_way_pipe_message_ipc.cpp`. Public signatures and the `PowerToys.Interop` ABI are unchanged, so the runner, Settings, and Quick Access host all benefit without any code changes on their side. ## Validation Steps Performed - The existing `Common.Interop.UnitTests` `TestSend` exercises the modified first-instance code path (`Start()` → `start_named_pipe_server`) and continues to pass — a full IPC round-trip still works. - Verified the updated `CreateNamedPipe` open-mode logic compiles cleanly. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 49797c8c-784d-47e6-bc0f-53464eecec4b |
||
|
|
558e633c59 |
Add preview release versioning and update channel support (#49414)
## Summary - Publish scheduled `main` builds as GitHub prereleases while keeping manual `main` runs as preview validation builds. - Add an opt-in Settings switch for prerelease update checks; stable updates remain the default. - Use one MSI-safe version across bundles, MSI packages, binaries, symbols, and package manifests. - Prevent preview releases from triggering Microsoft Store, WinGet, or public-symbol publication. - Label preview builds explicitly in Settings, update notifications, and What's New. ## Build intent | Source | Trigger | Intent | | --- | --- | --- | | `main` | Scheduled | Publish a preview release | | `main` | Manual | Validate a preview build without publishing | | `stable` | Manual | Produce a stable release | | Other branches | Any supported trigger | Produce a private validation build | ## MSI-safe release versioning Windows Installer compares only `major.minor.build` and ignores the fourth version component. Preview and stable release builds therefore use: ```text major.minor.YDDDB.0 ``` - `Y`: zero-based number of calendar years since `ReleaseTrainEpoch`. - `DDD`: three-position calendar day of year. - `B`: daily release sequence `1-9`. - The fourth component is always `0`. With `ReleaseTrainVersion=0.100` and `ReleaseTrainEpoch=2026-01-01`: ```text 0.100.2111.0 = July 30, 2026, release build 1 0.100.3659.0 = December 31, 2026, release build 9 0.100.10011.0 = January 1, 2027, release build 1 ``` The allocator formats `DDD` as exactly three digits before converting the MSI component to its numeric representation. Leading zeros may not be displayed because Windows version components are numeric; decoding remains positional: ```text B = component % 10 DDD = (component / 10) % 1000 Y = component / 10000 ``` `ReleaseTrainVersion` and `ReleaseTrainEpoch` are checked in under `src/Version.props`. The epoch remains January 1 of the active epoch year and advances on the first release-train minor change in a new year. ## Daily release counter Azure DevOps persists the daily sequence server-side using a counter keyed as `release-YYYYMMDD`. - `main` and `stable` share the same daily counter. - Other branches do not evaluate or consume the release counter. - Failed or canceled `main`/`stable` runs may leave gaps. - The build fails when the daily sequence exceeds `9`. - The counter date and encoded `YDDD` date both use `pipeline.startTime`. Private branches retain independent `0.0.<extended-day><NN>.0` validation versions. ## Update behavior - Stable users continue to query GitHub's stable latest-release path. - Users who explicitly enable preview updates can select newer GitHub prereleases. - Preview releases and notifications are labeled as PowerToys Preview. - What's New separates preview entries from stable release history and hides previews by default. ## Validation - 17 Pester tests cover `main`, `stable`, private branches, year rollover, epoch reset, monotonicity, override validation, sequence limits, and date alignment. - Version propagation verified `0.100.2111.0` in `Version.props` and all affected AppX/MSIX manifests. - Azure DevOps pipeline dry-runs succeeded for both `refs/heads/main` and `refs/heads/stable`. - The affected native version project builds successfully. - PR CI is green for x64, ARM64, Command Palette SDK, dependency review, telemetry detection, and CLA. ## Remaining end-to-end checks - Install two locally or officially produced installers with consecutive MSI-visible `YDDDB` versions and verify the upgrade preserves binaries, package registrations, hardlinks, and shell integrations. - On the first natural post-merge `main` or `stable` run, verify the production counter value and resolved version in the release logs. ## Local GPO verification Validated locally with the signed `v0.100.2171` build from Azure DevOps build [153961073](https://microsoft.visualstudio.com/Dart/_build/results?buildId=153961073). These checks cover the administrative-template integration and Settings behavior. ### Policy enabled: preview updates are disabled With `PreviewUpdatesDisabled=1`, **Include prerelease updates** is forced off and locked, and Settings displays the managed-by-your-organization notice.  ### Policy removed: the user preference is preserved After removing `PreviewUpdatesDisabled` and restarting PowerToys, the previously selected preview-update preference is restored and editable. The policy suppresses the preference without overwriting it.  ### Group Policy Editor After importing the updated ADMX/ADML templates, **Disable preview build updates** appears under **Microsoft PowerToys > Installer and Updates**. The policy dialog documents that **Enabled** blocks preview updates, while **Disabled** or **Not Configured** leaves the choice available to the user.  --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ad8b7909-0472-4464-bdee-deaeca726f94 Copilot-Session: 8e04a72e-3b0f-4ac4-8156-d04ea9b8bb85 |
||
|
|
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
|
||
|
|
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 |
||
|
|
5803bc7ec5 |
BUILD: Fix the version.vcxproj FastUpToDate check (#49534)
This has been my personal enemy for a year now. VS will skip doing work for your build if it thinks everything is up-to- date. But this version project has been treated as dirty for a long time now. What that means is that incremental builds (READ: dev inner loop builds) end up building the world CONSTANTLY. Because VS thinks FOR SOME REASON that this project needs to rebuild. By setting the `Inputs`/`Outputs` for this `Target`, VS is smart enough to only re-run the task if the inputs actually changed since the last build. Tested by building the code, then building again, and observing that all the projects were successfully noted as up-to-date drive-by: fix some of the other `csproj` files for cmdpal. Closes #45296 |
||
|
|
efc0258cda |
Validate the update installer before PowerToys.Update launches it (#48903)
## Summary PowerToys' self-updater downloads the installer into `%LOCALAPPDATA%\Microsoft\PowerToys\Updates` and then launches it from `PowerToys.Update.exe` (Stage 2). This makes that launch path more robust: - Open the downloaded installer with a read-only share so the file stays consistent while we inspect and run it. - Confirm it is a valid, Authenticode-signed **Microsoft** PowerToys installer (valid signing chain + Microsoft organization) before executing it. This single chokepoint covers both freshly downloaded and previously downloaded installers. - If the check does not pass, log and skip the launch instead of running an incomplete or invalid file. ## Implementation - Added `updating::verify_installer_trust` to the shared `common/updating` library (`installer.h` / `installer.cpp`): `WinVerifyTrust` for the signing chain, and `CryptQueryObject` / `CertGetNameString` to confirm the signer's organization is `Microsoft Corporation`. `Wintrust.lib` / `Crypt32.lib` are linked via `#pragma comment(lib, ...)`. - `InstallNewVersionStage2` opens the installer with `FILE_SHARE_READ`, verifies it, and keeps the handle open across `MsiInstallProductW` / the bootstrapper launch so the file stays stable during install. ## Validation - `ApplicationUpdate` and `PowerToys.Update` build clean (x64 Debug). - Existing updating unit tests pass (30/30). - Checked end-to-end against real binaries: a Microsoft Authenticode-signed binary is accepted; a corrupted copy and an unsigned file are both declined. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Muyuan Li <muyuanli@microsoft.com> Co-authored-by: Boliang Zhang (from Dev Box) <bozhang@microsoft.com> Copilot-Session: d168a794-8cce-483d-9c46-10787893dbe2 |
||
|
|
d127511c7d |
Fix runner APPLICATION_HANG_QUIESCE: handle WM_ENDSESSION and skip blocking shutdown cleanup (#48363)
## Summary The runner WndProc (`tray_icon_window_proc`) does not handle `WM_QUERYENDSESSION` / `WM_ENDSESSION`, **and** its `WM_DESTROY` teardown performs blocking cross-process cleanup. Both contribute to the Watson failure `APPLICATION_HANG_QUIESCE_cfffffff_PowerToys.exe!run_message_loop` on OS shutdown, sign-out, or restart: 1. Without a `WM_ENDSESSION` handler, `DefWindowProc` returns `0` without posting a quit message, so `run_message_loop` stays parked in `GetMessageW` until the OS quiesce timeout (~5 s) force-terminates the process. 2. Even once teardown starts, `WM_DESTROY` calls `close_settings_window()`, which blocks up to 1.5 s on `WaitForSingleObject` against `PowerToys.Settings.exe` (`src/runner/settings_window.cpp:712`), plus `Shell_NotifyIcon(NIM_DELETE)` during Explorer teardown. The Windows [shutdown guidance](https://learn.microsoft.com/windows/win32/shutdown/shutting-down) is explicit that handlers must not block. This PR fixes both issues for the always-on runner. Rollout to module-owned windows is intentionally separate and tracked in #49539. > Supersedes #48378 (same Watson bucket) by combining its no-blocking-cleanup fix with a reusable helper and unit tests. The cleanup-skip insight is credited to @yeelam-gordon. Related (same failure class, different binary): #41260. ## Root cause `src/runner/tray_icon.cpp` → `tray_icon_window_proc` had no case for `WM_QUERYENDSESSION` / `WM_ENDSESSION`, and `WM_DESTROY` unconditionally ran cross-process cleanup. On a full Windows session end, the OS delivers `WM_ENDSESSION` to child applications and reaps them independently, so the runner's waits consume the quiesce budget without helping shutdown complete. ## Fix ### 1. Explicitly stateless helper in `src/common/utils/window.h` `handle_stateless_session_end_message`: - `WM_QUERYENDSESSION` → returns `TRUE`. The name makes clear that this helper is only for processes with no unsaved user state. - `WM_ENDSESSION(TRUE)` → calls `DestroyWindow(window)`, driving the existing `WM_DESTROY → PostQuitMessage(0)` path so `run_message_loop` unwinds. - `WM_ENDSESSION(FALSE)` → leaves the window alone because another application cancelled shutdown. - The optional `out_system_session_ending` flag is set only when the full Windows session is ending. `ENDSESSION_CLOSEAPP` still closes the runner but leaves the flag false so Restart Manager requests retain normal child-process cleanup. Stateful modules must implement their own save/permission behavior rather than adopt this helper. `tray_icon_window_proc` calls it at the top of dispatch and returns immediately when the message is handled. ### 2. Skip blocking cleanup only for a full Windows session end `WM_DESTROY` branches on `g_system_session_ending`: - **User-initiated close or Restart Manager `ENDSESSION_CLOSEAPP`:** unchanged full cleanup (`Shell_NotifyIcon(NIM_DELETE)`, `close_settings_window()`, and `QuickAccessHost::stop()`). - **Full OS shutdown, sign-out, or restart:** posts `WM_QUIT` without waiting on child processes the OS is already reaping in parallel. ### Scope and follow-up This PR intentionally fixes the highest-volume contributor: the always-on runner. Native module processes with their own windows/message loops require module-specific review before adopting the pattern; that inventory and rollout is tracked in #49539. ### Why not centralize handling inside `run_message_loop`? `WM_QUERYENDSESSION` / `WM_ENDSESSION` invoke the WndProc directly during `GetMessage`; they do not appear as a `MSG` returned to the loop. Handling must therefore live in, or be called from, each relevant WndProc. ## Tests 8 focused tests in `src/common/UnitTests-CommonUtils/Window.Tests.cpp`: | Test | Guards | |---|---| | `HandleStatelessSessionEndMessage_QueryEndSession_AllowsShutdown` | `WM_QUERYENDSESSION` returns `TRUE`. | | `HandleStatelessSessionEndMessage_EndSessionCancelled_DoesNotTearDown` | `WM_ENDSESSION(FALSE)` does not destroy the window. | | `HandleStatelessSessionEndMessage_EndSessionConfirmed_TearsDownAndExitsLoop` | `WM_ENDSESSION(TRUE)` destroys the window and exits before the longer timer fallback. | | `HandleStatelessSessionEndMessage_UnrelatedMessage_NotHandled` | Unrelated messages fall through untouched. | | `HandleStatelessSessionEndMessage_EndSessionConfirmed_SignalsSystemSessionEnding` | A full session end enables the no-wait teardown path. | | `HandleStatelessSessionEndMessage_CloseApp_DoesNotSignalSystemSessionEnding` | Restart Manager closes the window while retaining normal child cleanup. | | `HandleStatelessSessionEndMessage_EndSessionCancelled_DoesNotSignalSystemSessionEnding` | Cancelled shutdown does not flag teardown. | | `HandleStatelessSessionEndMessage_QueryEndSession_DoesNotSignalSystemSessionEnding` | The query phase does not flag teardown. | **Build:** `runner.vcxproj` and `UnitTests-CommonUtils.vcxproj` build clean (`x64|Release`). The 8 focused tests pass. ## Manual validation 1. Build PowerToys and start the runner. 2. Initiate a sign-off (`logoff`) or restart. 3. Confirm Event Viewer (`Windows Logs → Application`) shows no `Application Hang` event for `PowerToys.exe`. 4. Right-click tray → Exit: confirm Settings.exe and the Quick Access host shut down gracefully and no ghost tray icon remains. (#48378 additionally captured real logoff/restart runs showing `WM_ENDSESSION → WM_DESTROY` completing in 1–8 ms with no hang events—the same full-session path used here.) ## Quality checklist - [x] Linked work item: AB#55588441 - [x] Module follow-up: #49539 - [x] Cross-references #41260; supersedes #48378 - [x] Unit tests (8 in `Window.Tests.cpp`) - [x] No new binaries - [x] Localization: no end-user strings changed - [x] Shared helper documents its stateless contract Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8d70b986-081a-43dd-bbfd-7e6351baef7a |
||
|
|
346b498fb5 |
Shortcut Guide: Replace dual windows with single transparent overlay and add holding windows button (#48683)
## Summary Refactors Shortcut Guide from two separate `WindowEx` instances (`MainWindow` + `TaskbarWindow`) into a single full-monitor transparent `OverlayWindow` that hosts both surfaces as XAML UserControls. This enables shared animations and a more polished visual experience, and makes the taskbar shortcut indicators **edge-aware** for Windows 11's top/bottom/left/right taskbar positioning. https://github.com/user-attachments/assets/e40a25f6-4ab3-4073-b1a8-906ef7782877 <img width="507" height="968" alt="image" src="https://github.com/user-attachments/assets/2e06a3d9-32d9-482e-90fe-1f0f8a7d7598" /> ## Changes Closes: #48435 Closes #48491 Closes: #49200 Closes: #48552 (theme flash on Light/System theme + shortcut-list scroll flutter) Closes: #48773 ### Architecture - **OverlayWindow**: Single transparent host covering the full monitor work area, using `TransparentTintBackdrop` - **MainPaneControl**: The shortcut list pseudo-window, reusing the shared `TransientSurface` control for chrome (acrylic backdrop, theme shadow, rounded corners) - **TaskbarPaneControl + TaskbarIndicator**: Tooltip-style indicators with triangle tails, positioned above taskbar buttons ### Edge-aware taskbar indicators (Windows 11 top/bottom/left/right) - Detects the taskbar edge via the public, documented `SHAppBarMessage` / `ABM_GETTASKBARPOS` API (the same API CmdPal Dock uses) - Indicators lay out along the correct axis — horizontally for a top/bottom taskbar, vertically for a left/right taskbar — with the triangle tail always pointing toward the taskbar (4-direction tail + per-edge slide-in animation) - For a left/right taskbar, the main pane is inset so the order reads **taskbar | indicators | pane** - **Adaptive sizing**: each indicator's body size is derived from the actual measured UIA taskbar button rect, so the bubbles shrink when Windows uses small icons or combines buttons (many apps open). Uses the smallest button slot (clamped to a readable range) so neighbouring bubbles never overlap; the font scales with it ### Visual polish - Windows 11 system flyout entry/exit animations (slide + fade, ~367ms entrance / ~200ms exit with cubic easing) - Animation direction is position-aware (slides from left when left-aligned, from right when right-aligned) - Taskbar indicators slide in from the taskbar edge with the same timing - Close button on the main flyout title bar ### Robustness - Multi-monitor DPI handling via WM_DPICHANGED suppression (prevents double-scaling on cross-monitor moves) - Win11 phantom border elimination (comprehensive DWM/style stripping) - Click-outside-to-close with animated exit transition - Process lifetime fix (`Application.Current.Exit()` on close) ## Validation - Build clean (x64 Debug, exit 0, empty errors log) - Tested on multi-monitor mixed-DPI setup (150% + 100%) - Tested with the taskbar docked to each edge (top/bottom/left/right) and with small/combined taskbar icons --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Noraa Junker <noraa.junker@outlook.com> Co-authored-by: Clint Rutkas <clint@rutkas.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> |
||
|
|
b69bfe7f86 |
CmdPal: Replace custom sign(x) function with built-in sgn(x) function (#49392)
## Summary of the Pull Request This PR allow use of built-in `sgn` function in exprtk in Calculator and uses it to implement `sign` function. <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [x] Closes: #49391 <!-- - [ ] Closes: #yyy (add separate lines for additional resolved issues) --> - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed, or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed |
||
|
|
bf14ebcec9 |
[CmdPal Calculator] Add reciprocal/inverse trig functions and n-th log/root; fix inverse function parse errors (#49356)
## Summary of the Pull Request Adds the missing trigonometric functions requested in #47093 to the Command Palette calculator, and fixes a regression where **all inverse trig/hyperbolic functions (`arcsin`, `arccos`, `arctan`, `arsinh`, `arcosh`, `artanh`) silently failed with a parse error**. **Bug fix:** since the mages → exprtk migration (#39972), the user-facing inverse-function names have still been accepted by input validation (`CalculateHelper.cs`) — they are native Mages function names and worked before the swap — but nothing maps them to exprtk's built-in names (`asin`, `acos`, `atan`, `asinh`, `acosh`, `atanh`), so exprtk returns a compile error and the calculator shows no result. The existing unit tests only covered the string transformation (`UpdateTrigFunctions`), never evaluation, so this went unnoticed. This PR registers the user-facing names as engine aliases and adds evaluation-level regression tests. **New functions:** - `cot`, `sec`, `csc` — exprtk-native; unblocked in input validation and wired into the degree/gradian trig-unit conversion - `arccot`, `arcsec`, `arccsc` — added to the engine (`arccot` uses `atan2(1, x)` for the continuous (0, π) branch, so `arccot(0) = π/2` and negative inputs land in (π/2, π)); also wired into trig-unit conversion - `coth`, `sech`, `csch` and `arcoth`, `arsech`, `arcsch` — added to the engine (hyperbolic, so no angle-unit conversion, consistent with `sinh`/`arsinh`) - `logn(x, base)` and `root(x, n)` — exprtk-native, unblocked in input validation (covers the "logarithm of n-th power" / "root of n-th degree" asks in the issue) ## PR Checklist - [x] Closes: #47093 - [x] **Communication:** The issue is labeled `Help Wanted` ("We encourage anyone to jump in on these and submit a PR.") - [x] **Tests:** Added/updated and all pass - [ ] **Localization:** No new end-user-facing strings (error paths reuse existing localized messages) - [ ] **Dev docs:** n/a - [ ] **New binaries:** n/a - [ ] **Documentation updated:** The docs page listing calculator functions may need updating; happy to file the docs PR once this is reviewed. ## Detailed Description of the Pull Request / Additional comments - `src/common/CalculatorEngineCommon/ExprtkEvaluator.cpp` - Registers aliases `arcsin/arccos/arctan/arsinh/arcosh/artanh` → `std::asin/acos/atan/asinh/acosh/atanh` (the bug fix). - Adds `coth/sech/csch` (reciprocal hyperbolics), `arccot/arcsec/arccsc`, and `arcoth/arsech/arcsch`, which exprtk does not provide. - `Microsoft.CmdPal.Ext.Calc/Helper/CalculateHelper.cs` - Whitelists the new function names in the input-validation regex. - Adds `cot/sec/csc` (argument conversion) and `arccot/arcsec/arccsc` (result conversion) to the degree/gradian handling in `UpdateTrigFunctions`. The existing `(?<!c)` look-behind logic correctly keeps `cot`↔`arccot`, `sec`↔`arcsec`, `csc`↔`arccsc`, and `cot`↔`coth` etc. apart (covered by tests). - `Microsoft.CmdPal.Ext.Calc/Helper/NumberTranslator.cs` - Adds the new names to the function-arity table so argument-separator protection works in decimal-comma locales (e.g. `logn(8; 2)` in de-DE). - The `log(` → `log10(` remapping in `CalculateEngine.cs` does not touch `logn(` (regex requires `(` directly after `log`); covered by a passing check. Behavior at undefined points maps to the existing error messages: `cot(0)`/`csch(0)` → ∞ → "out of bounds" error; `arcsin(2)`, `arcsec(0.5)`, `arcoth(0.5)` → NaN → "not a number" error (all covered by tests). PowerToys Run is unaffected: it still uses the Mages engine, which already supports the inverse-function names natively. ## Validation Steps Performed - Unit tests added: - Evaluation tests (`Interpret_NoErrors_WhenCalledWithRounding`) for all new functions **and** for the previously broken inverse functions (regression tests). - `InputValid` acceptance tests for every new name and rejection tests for bare names. - `UpdateTrigFunctions` transformation tests for degrees and gradians, including nesting (`sec(arcsec(2))`) and confirming hyperbolics are untouched. - End-to-end `TrigModeSettingsTest` rows through `CalculatorListPage` (e.g. `sec(60)` = 2 in degrees, `arccot(1)` = 45°, `cot(50)` = 1 in gradians). - Error-path tests for `cot(0)`, `csch(0)`, `arcsin(2)`, `arcsec(0.5)`, `arcoth(0.5)`. - The modified `ExprtkEvaluator.cpp` was additionally exercised standalone against the vendored `exprtk.hpp` with the exact parser settings used in production: 27 evaluation cases (including degree-mode composites exactly as `CalculateHelper` emits them) all pass, and all expected values in the test `DataRow`s are taken verbatim from the engine output. ### Screenshots **Built and ran locally (Debug build — note the "DBG | NO AOT" badge in the shots).** **_Before (shipping 0.100.2 — these all fail):_** <img width="786" alt="failed-arcsin" src="https://github.com/user-attachments/assets/4116c428-2804-43d7-b04b-9b02f7d374cc" /> <img width="784" alt="failed-cot" src="https://github.com/user-attachments/assets/b81d39df-dffd-4e8d-8af8-9d21552c5e89" /> <img width="784" alt="failed-logn" src="https://github.com/user-attachments/assets/b2eec32c-95e8-4b0a-b44f-47a30193a012" /> **_After (this PR):_** <img width="766" alt="arcsin" src="https://github.com/user-attachments/assets/9d8b2235-1330-433d-b0d5-5ad2527c1c01" /> <img width="766" alt="cot" src="https://github.com/user-attachments/assets/c2a4454f-1e46-4022-8107-7e0c9aff5a7e" /> <img width="767" alt="logn" src="https://github.com/user-attachments/assets/e6476cb9-3bf5-40e0-9b45-08a0add42124" /> <img width="764" alt="root" src="https://github.com/user-attachments/assets/97036055-1ee0-4355-b99f-891f4129e463" /> <img width="764" alt="sec1" src="https://github.com/user-attachments/assets/b82119f4-e6bb-47a7-8da7-0c3fd1272d70" /> <img width="766" alt="sech" src="https://github.com/user-attachments/assets/6363f938-8cbf-4d86-8784-d8288953786e" /> **_Recording_** https://github.com/user-attachments/assets/42c11e25-c342-4461-a9d4-e40d836d060c Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
f81689de3a |
[PowerDisplay] Drop redundant hardcoded PlatformToolset (inherit Cpp.Build.props) (#49370)
## Summary Remove the redundant hardcoded `<PlatformToolset>v143</PlatformToolset>` from two C++ projects so they inherit the toolset from the shared `Cpp.Build.props` like every other project. ## Why `Cpp.Build.props` is force-imported into **every** C++ project via `Directory.Build.props`: ```xml <ForceImportBeforeCppProps>$(RepoRoot)Cpp.Build.props</ForceImportBeforeCppProps> ``` MSBuild imports it during `Microsoft.Cpp.props` — i.e. *after* each project's own PropertyGroups — and it sets the toolset for the whole repo: ```xml <PlatformToolset>v143</PlatformToolset> <PlatformToolset Condition="'$(VisualStudioVersion)' == '18.0'">v145</PlatformToolset> ``` Two projects set `<PlatformToolset>v143</PlatformToolset>` directly in their Configuration PropertyGroups: - `src/modules/powerdisplay/PowerDisplayModuleInterface/PowerDisplayModuleInterface.vcxproj` (Debug + Release) - `src/common/UnitTests-CommonUtils/UnitTests-CommonUtils.vcxproj` That value was dead config — the force-imported prop already overrode it to `v145` on VS2026 (v18). The other module interfaces (Awake, FancyZones, …) don't set `PlatformToolset` at all; these two were just over-specified VS-template projects. ## Change Delete the redundant `PlatformToolset` lines so both projects inherit from `Cpp.Build.props`. ## Validation Built both projects locally with VS2026 (v18), Release x64, with no `PlatformToolset` in the vcxproj: - Both resolve to the `v145` toolset (MSVC `14.51`, `VC\v180`) via the force-imported prop. - Both produce their DLLs with no errors (`PowerToys.PowerDisplayModuleInterface.dll`, `Common.Utils.UnitTests.dll`). ## Risk Very low — no change to the produced binaries (effective toolset is unchanged); this just removes dead config and makes these two projects consistent with the rest of the repo. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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. |
||
|
|
93669df118 |
TransparentWindow: opt-in Esc / focus-lost dismiss + multi-surface docs (#48950)
## Summary Hardens the shared `TransparentWindow` (in `src/common/Common.UI.Controls/`) with two **opt-in** dismissal behaviors and documents multi-surface hosting. No consumer changes; everything defaults off. ### 1. `DismissOnEscape` (default `false`) Pressing <kbd>Esc</kbd> while the window content has keyboard focus calls `Hide()`. Input is hooked lazily at show time because `Content` is assigned by the consumer after construction. ### 2. `DismissOnFocusLost` (default `false`) Light dismiss: hides when the window is deactivated. Guarded by a "seen activated" flag (reset on each `Show()`) so the transient deactivation that can occur during the show sequence doesn't dismiss prematurely. This mirrors the guards that **PowerDisplay** (`_isShowingWindow`) and **Quick Access** (`_hasSeenInteractiveActivation`) currently hand-roll — they can drop their bespoke logic once they derive from `TransparentWindow`. > Both properties are no-ops unless the consumer activates the window (it shows no-activate / `SW_SHOWNA`). ### 3. Multi-surface hosting (docs only — already works) Added class `<remarks>` documenting that multiple `TransientSurface`s can `SubscribeTo` one window: `HidingEventArgs` aggregates deferrals so the window hides only after **all** surfaces finish animating out, and plain `Show()` lets each surface play its own configured transition. ## Why no DWM "full-bleed" hardening here The extra DWM hardening Shortcut Guide uses (NCRENDERING disabled, `DwmExtendFrameIntoClientArea(-1)`, etc.) is only needed for **full-monitor, edge-to-edge** overlays. Content-sized surfaces (Quick Accent, CmdPal Toast) inset their acrylic card behind transparent padding, so any phantom border sits in the transparent margin and is invisible. Applying it universally would add compositing risk for zero benefit, so it's deferred to the Shortcut Guide refactor (where it's actually exercised) as an opt-in. ## Testing - `Common.UI.Controls` builds clean (Debug/x64). - Behavior is opt-in and off by default, so existing consumers are unaffected. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
2dd802f367 |
Fixing Windows.ImplementationLibrary mismatch between proj and package.config (#49050)
In the vcxproj files, it lists it correctly for Microsoft.Windows.ImplementationLibrary.1.0.260126.7 but the package files are incorrect |
||
|
|
fb6843b0f1 |
Refactor transparent overlay into TransparentWindow + TransientSurface (#48915)
## Summary Refactors the reusable transparent-overlay infrastructure in `src/common/Common.UI.Controls/` into a clean separation between a pure host window and a self-animating acrylic surface. ### What changed - **`TransparentWindow`** is now animation-agnostic. It raises `Showing` / `Hiding` events; `Hiding` exposes a deferral so the HWND stays visible until the surface's out-animation finishes. - **`TransientSurface`** (renamed from `TransparentCard`) is a self-animating "pseudo-window" content control. It owns all chrome — `ThemeShadow`, always-active desktop acrylic, 1px border, rounded corners — and its own show/hide slide animations. - `SlideFrom` (`None`/`Left`/`Top`/`Right`/`Bottom`) selects the slide edge. `None` is the default and plays **no animation at all** (instant show/hide). - `AcrylicKind` (new) is exposed and bound to the backdrop via `TemplateBinding`, defaulting to **thin acrylic**. Consumers can override to `Default`/`Base`. - **`AlwaysActiveDesktopAcrylicBackdrop`** gains a matching `Kind` dependency property. - **CmdPal `ToastWindow`** is migrated to the new pattern as the proving consumer (`Surface.SubscribeTo(this)`). ### Coordination model A module declares a `<TransientSurface>` as the window's content and calls `SubscribeTo(window)` once. The window raises `Showing`/`Hiding`; the surface animates itself in/out and uses the `Hiding` deferral to keep the window alive until the out-animation completes. ## Testing - `Common.UI.Controls` builds clean (x64 Debug, exit 0). - `Microsoft.CmdPal.UI` builds clean (x64 Debug, exit 0). - ToastWindow keeps its slide-up animation (`SlideFrom="Bottom"`). https://github.com/user-attachments/assets/a06b0f1a-740a-4fcd-bba8-6f7a64ed261b --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
334d1c8054 |
Validate cached installer filename from UpdateState.json in the updater (#48741)
## Summary of the Pull Request `PowerToys.Update` reads `downloadedInstallerFilename` from the persisted `UpdateState.json` and combines it with the `Updates` folder to locate the installer to run. If that cached state is stale, corrupted, or otherwise unexpected, the stored value could contain path separators or an absolute path, which would make the updater look for the installer outside the `Updates` folder. This PR validates that the cached value is a plain filename and that the resolved path stays inside the `Updates` folder before using it; otherwise the update is treated as unavailable. The normal update flow (a bare asset filename produced by the download step) is unaffected. ## PR Checklist - [ ] **Communication:** I've discussed this with core contributors already. - [x] **Tests:** Added/updated and all pass - [x] **Localization:** No end-user-facing strings added - [x] **Dev docs:** N/A - [x] **New binaries:** None ## Detailed Description of the Pull Request / Additional comments - The filename check is factored into an inline helper `updating::IsSafeDownloadedInstallerFilename` in `src/common/updating/updateLifecycle.h` (next to the other inline update helpers) so it can be unit-tested without a project reference. - `ObtainInstaller` in `src/Update/PowerToys.Update.cpp` now calls that helper and additionally confirms, via `weakly_canonical`, that the resolved installer path's parent is the `Updates` directory. - No behavior change for normal installer filenames, so the regular update flow does not regress. ## Validation Steps Performed - Added `IsSafeDownloadedInstallerFilenameTests` to `Updating.UnitTests` covering normal filenames, empty values, parent-directory components, nested path components, and absolute/drive-relative/UNC paths. - Built `Updating.UnitTests` (Debug x64): 0 warnings, 0 errors. - Ran the full `Updating.UnitTests` suite: 36/36 passed (30 existing + 6 new). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
106c970c8c |
Fix full rebuild: upgrade CalculatorEngineCommon to C++20 coroutines (#48790)
Remove _SILENCE_EXPERIMENTAL_COROUTINE_DEPRECATION_WARNINGS and upgrade LanguageStandard from stdcpp17 to stdcpp20 so that <coroutine> is used instead of the removed <experimental/coroutine> header on VS 2026. <img width="946" height="348" alt="image" src="https://github.com/user-attachments/assets/53392fd8-1a81-4852-9913-d84575f2f3e1" /> was part of https://github.com/microsoft/PowerToys/pull/48102 prior <!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [ ] Closes: #xxx <!-- - [ ] Closes: #yyy (add separate lines for additional resolved issues) --> - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed, or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
2ffc248792 |
[Build] Increase sleep time in InteropTests to attempt to reduce CI failures (#48156)
<!-- 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 Increase sleep duration while waiting for IPC setup in the interop unit test. A number of PRs have had failures recently even though they do not touch interop, likely due to this sleep being too short. An existing comment points to the addition of the delay being because of this, and resource-constrained build agents/environments could need a longer duration. <!-- 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 See comments on #47211 and #48106. <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed N/A |
||
|
|
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> |
||
|
|
f87b14d5b9 |
Fix grammar and typos (#47539)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request Fixes some typos and grammar mistakes inside docs, strings, and comments. <!-- 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 None --------- Co-authored-by: Niels Laute <niels.laute@live.nl> Co-authored-by: Copilot <175728472+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. |
||
|
|
109c63ba33 |
Remove our dependency on expected-lite (#48159)
This removes our last git submodule dependency! We were using `expected-lite` in one place, which was being compiled out _anyway_ in favor of using `std::expected`. |
||
|
|
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> |
||
|
|
f02b66c88d |
Fix auto-update relaunch, add config backup, enable auto-download by default (#46889)
## Summary Addresses three critical issues with the PowerToys update experience that cause user fragmentation across old versions. ### Changes **1. Fix relaunch after update (Fixes #42004, #43011, #44071)** - Stage 1 now passes the PowerToys install directory to Stage 2 as an argument - After successful install, Stage 2 relaunches `PowerToys.exe` with `-report_update_success` - Users will see a 'successfully updated' toast and PT resumes automatically **2. Config backup/restore (Fixes #46179)** - `BackupConfigFiles()` snapshots all JSON configs to `ConfigBackup/` before update begins - `RestoreCorruptedConfigs()` checks for null-byte corruption after install and auto-restores - Protects Workspaces, FancyZones, Keyboard Manager, and all other module settings **3. Enable auto-download by default** - New installations default `AutoDownloadUpdates` to `true` (was `false`) - Existing users' preferences are preserved — this only affects first-run defaults - The runner already defaulted to `true`; this aligns the C# settings model ### Why this matters The current updater kills all PowerToys processes, runs the installer, then **exits without relaunching**. Users lose keyboard remappings, FancyZones layouts, and Awake settings with no indication why. Combined with auto-download being off by default, most users are multiple versions behind. ### Testing - Verified update flow: Stage 1 → Stage 2 → PT relaunches with success toast - Config backup creates mirror of all JSON settings before update - Corruption detection catches null-byte pattern from #46179 - Graceful fallback: if install dir not provided (old Stage 1), logs warning but doesn't crash --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Muyuan Li (from Dev Box) <muyuanli@microsoft.com> Co-authored-by: Niels Laute <niels.laute@live.nl> |
||
|
|
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> |
||
|
|
94b7e3eea2 |
[Image Resizer] Automatically reload settings changes (#45266)
## Summary of the Pull Request This PR introduces real-time settings synchronisation for Image Resizer. External changes to `settings.json` (via the Settings application or manual edits to the file) are detected and reloaded immediately without requiring a restart. <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [x] Closes: #36943 <!-- - [ ] Closes: #yyy (add separate lines for additional resolved issues) --> - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [x] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed, or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments ### Reload updates The reload detection is via an `IFileSystemWatcher` (as file system operations are abstracted in Image Resizer), which monitors the `settings.json` file for creation and changes. There is a half second debounce for changes, as the settings file can rapidly change when the user is editing the preset name field. Hot reloading of the properties required refactoring `ReloadCore`, which replaces the `Sizes` preset collection and updates the Custom and AI presets, in addition to the application-wide properties like compression options and the fallback encoder choice. I changed the combo box data binding from the `SelectedSize` object to the int `SelectedSizeIndex`. This was required to resolve a specific WPF issue where reloading the `Sizes` collection would cause issues with restoring the current combo box selection to the prior value. Binding to the index decouples the selection state from the object lifecycle during the reload process. Selection preservation is based on the preset ID (for user presets) and preset type (for Custom and AI presets). This ensures that matches are robust even if the user is in the process of renaming an entry in the Settings application. If the preset cannot be matched (for example, if the user deletes the item or changes the ID manually in the file), the Custom preset is selected. Selection range checks are maintained from the old code, and additional checks have been added to ensure that Custom and AI presets will be present even if they're deleted from the settings file. The AI preset check from before has been inlined; this guarantees that the AI resize option will not display if the facility is unavailable on the current PC, even if it's present in the settings file. The reload routine is dispatched to the UI thread, as changes involve updates to the combo box. ### ID recovery Preset IDs are key to preserving the combo box selection between reloads, and a couple of changes were necessary to ensure round-tripping changes were robust. 1. IDs are not reused. The old code could reuse IDs under certain circumstances, for example if a preset was deleted and re-added via Settings. 2. The ID Recovery Helper routine sorted the supplied presets by ID before performing duplicate conflict resolution. This is not required and it is more natural to assume that the order in the settings file and the client UI is the source of truth. New ID assignment is now based on a monotonically increasing ID (seeded at application start) rather than `Current Maximum ID + 1`. This means that IDs cannot be reused in the same Settings application session. This makes the matching process in the client application more reliable. A small update was made to the ID Recovery Helper to use `HashSet.Add()` instead of splitting up the check and addition steps (`Add` will return false if the value already exists), which saves a massive one line of code. There were comments about the ID Recovery Helper resolving "empty" or "invalid" entries; this was inaccurate, as IDs are ints, which must by definition always have a valid value. The routine only guards against duplicates, so the comments have been updated to reflect this. ### Miscellaneous The `Default` Settings property getter previously called `Reload` every time it was accessed. This is fine when the file is only read at application startup, but I changed this to lazily instantiate and call `Reload` a single time. I refactored duplicate code related to settings file/folder strings, and also the creation of the Custom and AI size instances. <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed Manual testing: 1. Add new preset in the Settings application. The new entry is reflected in the client application as it is running. 2. Delete new preset. The entry is removed in the client application list. 3. Edit an existing preset. The property change is reflected in the client application. 4. Add new preset in the Settings application. Select the new preset in the client application. Edit the properties of the new preset in the Settings application and confirm that the updates appear in the client application. 5. Add new preset in the Settings application. Select the new preset in the client application. Delete the new preset in Settings. Confirm that the current preset is removed and the selection changes to the default in the client application. 6. Change one or more application-wide properties in the settings file which are represented in the client application, too, e.g. "Make pictures smaller but not larger" (`imageresizer_shrinkOnly`) or "Overwrite files" (`imageresizer_replace`). Upon saving, confirm the checkbox changes immediately in the client application. 7. Edit the `settings.json` file manually by e.g. adding a new Size preset or editing the width or height property of an existing preset. Upon saving, the change(s) should be reflected in the client application. 8. Make a change to an existing or new preset which affects the resize operation itself, e.g. the dimensions or the "Make pictures smaller but not larger" setting. Proceed with the resize operation and confirm that the new changes have been applied. 14 new unit tests have been added to `SetingsTests.cs` to exercise the `Settings` and `IDRecoveryHelper` functionality. --------- Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
8e74eb2ba8 |
[PowerDisplay] Auto-disable on detected DDC/CI capability fetch crash (#47556) (#47734)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary Mitigation for issue #47556 — `KERNEL_SECURITY_CHECK_FAILURE` BSOD originating in `win32kfull!DdcciGetCapabilitiesStringFromMonitor` when PowerDisplay calls DDC/CI capability APIs against monitors with malformed capability strings. After a detected crash, PowerDisplay auto-disables itself via `settings.json`, shows an error InfoBar at the top of the PowerDisplay settings page (page is locked except the Ignore button), so users can avoid getting stuck in an infinite reboot loop after a crash. And the user must explicitly dismiss the warning before re-enabling the module. The actual kernel-side fix is the Windows team's responsibility — this PR only prevents users from BSOD-ing repeatedly on the same monitor without warning. settings page: <img width="1743" height="1475" alt="image" src="https://github.com/user-attachments/assets/8cf1b72f-c51a-4955-82d7-213cae49fd4e" /> ## Mechanism 1. `CrashDetectionScope` IDisposable wraps Phase 2 capability fetch in `DdcCiController.DiscoverMonitorsAsync`, writing `discovery.lock` (`WriteThrough` + `Flush(flushToDisk: true)`) before, deleting it on Dispose. 2. If the process is killed externally (BSOD, FailFast), the lock survives. 3. On next PowerDisplay.exe startup (Phase 0), `CrashRecovery` detects the orphan lock and runs a strict fail-fast sequence: write `crash_detected.flag` → set `enabled.PowerDisplay=false` in global `settings.json` → signal the new `POWER_DISPLAY_AUTO_DISABLE_EVENT` → delete the lock (commit point). 4. The runner-loaded `PowerDisplayModuleInterface.dll` runs a one-shot listener thread that wakes on the event and calls `disable()` to sync `m_enabled`. 5. `PowerDisplayViewModel` reads the flag at construction and binds `IsCrashLockActive` to lock the page. <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [x] Closes: #47556 <!-- - [ ] Closes: #yyy (add separate lines for additional resolved issues) --> - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed, or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed --------- Co-authored-by: Yu Leng <yuleng@microsoft.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
e17454b553 |
[CmdPal Calculator] Add rand() and randi(). Expand result responses to differentiate between NaN and ParseError (#47725)
## Summary of the Pull Request This adds `rand()` and `randi()` functions to Command Palette's Calculator, making it consistent with Run. It also expands upon the return values from `ToWStringFullPrecision()`, so NaN, ParseError and +/-infinity results are passed back to the caller, improving the specificity of the error message display. <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [x] Closes: #47707 <!-- - [ ] Closes: #yyy (add separate lines for additional resolved issues) --> - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [x] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed, or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments The two new functions have been added to **ExprtkEvaluator.cpp**, alongside `sign()` and `factorial()`. As they need to handle the state of the RNG, they're slightly more complex in implementation. I used the Mersenne Twister RNG with a uniform distribution, and the instances are marked `static thread_local` in case the engine moves to multithreaded evaluation in the future. It's possible for the RNG to return a value out of the range of `double`, and this is caught and `quiet_NaN()` is returned. To prevent this being caught as a generic parse error, I updated `ToWStringFullPrecision()` to distinguish between `NaN`, expression parsing errors and infinity values. This should improve the accuracy of error messages for other expressions, too. Finally, I corrected a comment in **CalculateEngine.cs,** which still referred to the Mages calculation engine. The log/ln mapping is the same for both engines, so the comment was still accurate except for this reference. <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed Unit tests were added to exercise the new functions. All Calculator tests pass: <img width="375" height="59" alt="image" src="https://github.com/user-attachments/assets/5a33e1ed-a4fd-4d53-b9ba-6b44000f1bf4" /> Confirmed that error messages are displaying correctly for the newly-exposed result types: **Not a number** <img width="787" height="128" alt="image" src="https://github.com/user-attachments/assets/8c73dcf6-122b-4af8-bf1a-62284842433a" /> <img width="786" height="145" alt="image" src="https://github.com/user-attachments/assets/fe14338c-1160-4aae-83dd-5ca3491ae59e" /> **+/- Infinity** <img width="898" height="137" alt="image" src="https://github.com/user-attachments/assets/20cfacda-72a7-44bb-a875-af7be39ee7e2" /> **Parser failure** <img width="607" height="139" alt="image" src="https://github.com/user-attachments/assets/7d7120b2-a2cf-45b6-ab89-79af4051fa50" /> <img width="587" height="140" alt="image" src="https://github.com/user-attachments/assets/2dc7a365-7ee6-4379-8b3f-47b3912e6891" /> |
||
|
|
c5d17913e4 |
[PowerDisplay] Add max compatibility mode setting (#47875)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request 1. Adds an opt-in Max compatibility mode in PowerDisplay's Advanced settings. When enabled, DDC discovery probes monitors that don't advertise capabilities, picking up displays that would otherwise be skipped. 2. Toggling the setting triggers an immediate rescan via a new RescanPowerDisplayMonitorsEvent IPC event from Settings to PowerDisplay. 3. Hides the brightness slider on monitors that lack VCP 0x10. Also fixed animation issue #47868 <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [x] Closes: #47878 <!-- - [ ] Closes: #yyy (add separate lines for additional resolved issues) --> - [x] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed, or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed --------- Co-authored-by: Yu Leng <yuleng@microsoft.com> Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com> |
||
|
|
05cd66c9bc |
[Dev][Build] .NET 10 Upgrade (#41280)
## Summary of the Pull Request .NET 10 Upgrade. Requires Visual Studio 2026. ## PR Checklist - [x] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx ## Detailed Description of the Pull Request / Additional comments - Upgraded target framework from `net9.0` to `net10.0` across all projects - Removed redundant package references now included by default in .NET 10 - Updated package versions to .NET 10 releases - Modernized regex usage with source generators for better performance - Added `vbcscompiler` to the spell-check allowlist (`.github/actions/spell-check/expect.txt`) ## Validation Steps Performed <!-- START COPILOT CODING AGENT TIPS --> --- 🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. [Learn more about Advanced Security.](https://gh.io/cca-advanced-security) --------- Co-authored-by: Jeroen van Warmerdam <jeronevw@hotmail.com> Co-authored-by: Copilot <copilot@github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> |
||
|
|
2e5c7d2ee6 |
Refresh check-spelling 0.0.26 (#47119)
This is a refresh based on
|
||
|
|
8ad571dcde |
Fix Common.Interop.UnitTests.TestSend infinite hang on CI (#47123)
## Summary Fixes an infinite hang in Common.Interop.UnitTests.TestSend that caused the x64 CI job to time out at 80 minutes on retried runs (originally observed on #47106, but the race is latent in any run that shares a CI agent with a previous run). ## Root cause The test used two machine-global named pipes (\\.\pipe\serverside and \\.\pipe\clientside) as fixed constants, and waited for the pipe callback with an **unbounded** eset.WaitOne(). If a prior test run on the same CI agent left a pipe handle alive (e.g. after a job cancellation or a flaky cleanup), the next run's TwoWayPipeMessageIPCManaged handshake would silently never complete, and `WaitOne()` would block until the pipeline's job-level timeout (~80 minutes) killed the agent. ## Fix Two small, orthogonal changes in `InteropTests.cs`: 1. **Unique pipe names per run** — suffix the pipe paths with `Environment.ProcessId` + a fresh `Guid`, so runs on the same agent can never collide. 2. **Bounded wait** — `reset.WaitOne(TimeSpan.FromSeconds(30))` wrapped in `Assert.IsTrue` with a diagnostic message identifying the pipes. A broken handshake now fails the test in 30 s with a clear error, instead of hanging the CI job. The inner `Assert.AreEqual(testString, msg)` — the actual correctness check — is unchanged. On the happy path the callback fires in milliseconds and the test behaves identically to before. ## Verification Built and ran locally with VS2026 MSBuild (x64 Release): `TestSend` passes in ~139 ms. ## Follow-up (not in this PR) `TwoWayPipeMessageIPC.cpp` still relies on a `Thread.Sleep(100)` race workaround (comment in the test) for server-ready timing. A proper handshake there would let us drop the sleep; out of scope here. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
bf00c1b94f |
[Common][PowerDisplay][QuickAccess] Shared flyout positioning helper (#47097)
## Summary Introduces a shared FlyoutWindowHelper in Common.UI.Controls and migrates both **PowerDisplay** and **QuickAccess** to it, eliminating two pre-existing flyout positioning bugs and removing duplicated math. ## Bugs fixed ### 1. PowerDisplay flyout overlapped the taskbar at 100% scaling The previous PowerDisplay-only positioning math anchored to the screen bounds rather than `DisplayArea.WorkArea` on certain monitor configurations, so the bottom edge of the flyout could land on top of the taskbar. ### 2. QuickAccess flyout rendered too large / partially off-screen after switching DPI between 150% and 100% The previous code passed `WindowEx.Width`/`Height` into `MoveAndResize` on every summon. Those properties are **not** the XAML literals — they are computed live as `AppWindow.Size / GetDpiForWindow() * 96`. After a system-scaling switch, the runtime size has drifted, that wrong "DIP" value got fed into `MoveAndResize`, and the destination DPI multiplier scaled it again → wrong size, and the wrong size shifted the bottom-right anchor off-screen. QuickAccess now caches the XAML design size once at construction (when the values are still trustworthy) and uses the cache as the source of truth. ## How the helper works - Uses **absolute screen coordinates** against `DisplayArea.WorkArea`, so it handles non-primary and negatively-positioned monitors correctly. - Performs a **1×1 `MoveAndResize` "teleport"** onto the target display before the final visible-size call. The 1×1 jump may cross a DPI boundary, but it's invisible; the second call sets the real size while the window is already on the destination monitor, so no DPI boundary is crossed for the rendered size and `WM_DPICHANGED` never fires on a visible window. - Exposes overloads for bottom-right anchoring (both flyouts) and centered placement (PowerDisplay's `IdentifyWindow`). This teleport-then-size approach matches the technique the original Settings.UI flyout used for years before it was removed. ## Cleanup - Deletes the PowerDisplay-only `DpiSuppressor` — its WM_DPICHANGED-suppression code path is now dead because the helper sidesteps the message entirely. - The `DpiSuppressor` class also doubled as a generic WndProc subclass to route `WM_HOTKEY` into `HotkeyService`. That piece is preserved as `WindowMessageHook` in `Common.UI.Controls/Window/` since PowerDisplay still needs in-process hotkey handling. ## Validation - `Common.UI.Controls`, `PowerDisplay`, and `QuickAccess` build clean (x64/Debug). - Manual repro: - PowerDisplay flyout no longer overlaps taskbar at 100% scaling, on multiple invocations. - QuickAccess renders at the correct size and position when switching system scaling between 150% and 100%. - PowerDisplay hotkey toggle still works after the `DpiSuppressor` → `WindowMessageHook` rename. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
e4f98897ce |
Add window positioning and sizing with Alt+mouse button (#47024)
Re-creation of #46817 from an internal branch to work around stale code-scanning merge protection. ## Original PR See #46817 for full context, discussion, and review history. ## Summary This adds a new toy, GrabAndMove (previously WinPos), that allows dragging (left click) or resizing (right click) of windows while the Alt key is pressed. Closes: #269 ## PR Checklist - [x] Communication: discussed with core contributors - [ ] Tests: Added/updated and all pass - [ ] Localization: All end-user-facing strings can be localized - [ ] Dev docs: Added/updated --------- Co-authored-by: foxmsft <foxmsft@hotmail.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Muyuan Li (from Dev Box) <muyuanli@microsoft.com> Co-authored-by: Niels Laute <niels.laute@live.nl> Co-authored-by: Alex Mihaiuc <amihaiuc@microsoft.com> |
||
|
|
daeb2e1ef4 |
Fix CmdPal Calc extension unit test failure in non-English cultures (#46911)
## Summary of the Pull Request `TrigModeSettingsTest` fails under cultures using `,` as decimal separator (e.g., `de-DE`, `fr-FR`). Two root causes: the C++ calculator engine's `ToWStringFullPrecision` doesn't pin the stream locale, and the test classes don't set a deterministic thread culture. ## PR Checklist - [x] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated ## Detailed Description of the Pull Request / Additional comments **C++ locale fix** — `ExprtkEvaluator.cpp`: `std::wostringstream` defaults to the global C++ locale, which can be changed to the system locale by the runtime. Pin it to `std::locale::classic()` so the decimal separator is always `.` across the WinRT boundary: ```cpp std::wostringstream oss; oss.imbue(std::locale::classic()); oss << std::fixed << std::setprecision(15) << value; ``` **Test culture setup** — `QueryTests.cs`, `QueryHelperTests.cs`: Added `TestInitialize`/`TestCleanup` to set thread culture to `en-US`, matching the existing pattern across all TimeDate test classes. **Non-English culture test cases** — New `TrigModeSettingsTest_NonEnglishCulture` parameterized over `de-DE` and `fr-FR` verifies `outputUseEnglishFormat: true` produces `.`-separated output regardless of `CurrentCulture`. ## Validation Steps Performed - Code review passed with no actionable findings (naming convention matches existing TimeDate test pattern across 7+ files) - New `TrigModeSettingsTest_NonEnglishCulture` test exercises the exact failure scenario from the issue --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: niels9001 <9866362+niels9001@users.noreply.github.com> |
||
|
|
36a5b77e6c |
chore: Update to WIL 1.0.250325.1 (#43503)
## Summary of the Pull Request Updates the Windows Implementation Library (WIL) to version 1.0.250325.1. This fixes some static analysis warnings in C++ projects that use WIL. The version is now managed centrally via `Directory.Packages.props` (Central Package Management), replacing the previous per-project `packages.config` approach. ## 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 - Updated `Microsoft.Windows.ImplementationLibrary` from `1.0.231216.1` to `1.0.250325.1` in `Directory.Packages.props`. - The change is a single-line update since the codebase uses Central Package Management — all C++ projects reference WIL via `PackageReference` without specifying a version number directly. ## Validation Steps Performed - Verified `Directory.Packages.props` correctly reflects the new WIL version `1.0.250325.1`. - Merged latest `main` branch to resolve conflicts arising from the migration to Central Package Management. Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: niels9001 <9866362+niels9001@users.noreply.github.com> |
||
|
|
d27594c4f7 |
Settings: Fix settings arrow render (#46454)
<!-- 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 Existing: <img width="1201" height="150" alt="image" src="https://github.com/user-attachments/assets/5e764875-bed8-45b5-97a8-60e5f475c296" /> A box icon for whatever up, down, left, right, they are not treated as Glyph icon rendered, instead as normal text <!-- 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 <img width="1273" height="714" alt="image" src="https://github.com/user-attachments/assets/4d2ffa92-e0ca-44f4-8eda-9c4a7e05bbde" /> |
||
|
|
dc533fbdb3 |
[Keyboard Manager] Remove service enable/disable separate from module, fix editor clear shortcut (#46530)
Two changes to shortcuts here: 1) Remove toggling the KBM service with a shortcut or via command palette 2) Ensure that shortcut is disabled for editor when shortcut is cleared |