mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-07-09 20:09:28 +02:00
## Summary of the Pull Request Migrates the **Quick Accent (PowerAccent)** module's UI from WPF (`System.Windows.*`) to **WinUI 3 (Windows App SDK)**, following the pattern used by other migrated modules (ImageResizer, PowerDisplay). The accent selector is now a self-contained WinUI 3 app (`PowerToys.PowerAccent.exe`) shipped under `WinUI3Apps`, and `PowerAccent.Core` is UI-framework-agnostic. demo: https://github.com/user-attachments/assets/400c33ee-0fc0-491e-841b-a546438edf91 ## PR Checklist - [x] Closes: #48889 - [x] **Communication:** Tracked task (#48889) agreed with core contributors - [x] **Tests:** Added/updated and all pass — new `PowerAccent.Core.UnitTests` (21 tests for the positioning / DPI math); existing `PowerAccent.Common.UnitTests` unaffected - [x] **Localization:** No new localizable end-user strings — new accessibility metadata uses non-localized `AutomationProperties.AutomationId`, and the window title is the brand name `"Quick Accent"` (literal, matching ColorPicker) - [x] **Dev docs:** Updated `doc/devdocs/modules/quickaccent.md` - [x] **New binaries:** Added on the required places - [x] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json): the `WinUI3Apps\` PowerAccent payloads are listed in `ESRPSigning_core.json` - [x] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs): no manual `Product.wxs` entry — the self-contained `WinUI3Apps` output (exe + `.pri` + Windows App SDK runtime) is harvested by the `WinUI3ApplicationsFiles` glob (same as ImageResizer) - [x] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml): no change needed — `PowerAccent.Core.UnitTests` is discovered by the existing `**\*UnitTest*.dll` VSTest glob - [x] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml): covered by `ESRPSigning_core.json`; no `release.yml` change needed - [ ] **Documentation updated:** N/A — internal UI-framework migration with no user-facing behavior change ## Detailed Description of the Pull Request / Additional comments The migration spans three areas (tracked in #48889): **UI (WPF → WinUI 3)** - `PowerAccent.UI` is now a WinUI 3 app shell (custom `Program.Main`, `WindowsPackageType=None`, `WindowsAppSDKSelfContained=true`). - The accent selector is a non-activating `TransparentWindow` overlay shown with `SW_SHOWNA` (never steals focus). It is made always-on-top only while shown — the WinUIEx `WindowEx.IsAlwaysOnTop` property is toggled `true` on show / `false` on hide in `OnChangeDisplay` (matching the WPF original's `Topmost = isActive`), so the dormant, never-destroyed overlay does not pin a discrete GPU awake on hybrid-graphics laptops (issue #34849 / PR #41044). - The accent "pill" selection visual is reproduced with `VisualStateManager` (WinUI 3 has no `Style.Triggers`). - **WinUI 3 gotcha:** x:Bind on a Window-rooted XAML initializes only on `Window.Activated`, which never fires for this `SW_SHOWNA` overlay — so the selector calls `Bindings.Update()` after `InitializeComponent()`; without it the `ListView` renders empty. - **Theme:** the long-lived, never-activated process follows the system app theme automatically — `App.xaml` leaves `Application.RequestedTheme` unset, so WinUI re-resolves the `{ThemeResource}` brushes (and retints the acrylic) on a live light/dark switch with no manual `ThemeListener` needed. - **Layout parity with the WPF original:** the bar width hugs its content (`itemCount × 48`, clamped to the monitor width — computed, not measured, to avoid a racy `ListView` measure), and each cell pins `MinWidth=48` (WinUI's `ListViewItem` defaults to 88, which would otherwise leave wide gaps). - **Accessibility:** UIA window name + `AutomationId`s on the character list and description. **Dependency** - `PowerAccent.Core` no longer depends on WPF — it raises events and takes an injected UI-thread marshaller. - WinForms `SendKeys` → `SendInput` (CsWin32 P/Invoke); WPF-UI (Lepo) removed; language data moved to the UI-/WinRT-agnostic `PowerAccent.Common`. - MVVM via CommunityToolkit.Mvvm with `[ObservableProperty]` **partial properties** (WinRT-correct, clears MVVMTK0045). **CI / Build / Installer** - Signing config, WinUI3Apps glob harvest, and the new unit-test project — see the checklist above. ## Validation Steps Performed - **Build:** `x64 Debug` builds with **0 warnings / 0 errors**. - **Unit tests:** `PowerAccent.Core.UnitTests` — **21/21 pass** (9 anchor positions × DPI 1.0/1.5/2.0, the offset and negative-origin monitors, caret centering + edge clamping + flip-below). - **XamlStyler:** `PowerAccentXAML/MainWindow.xaml` passes the passive format check (CI mode). - **Manual (single monitor, Top-center, light theme):** - Accent popup appears with the full accent list rendered. - Bar hugs the characters and is centered; cell spacing matches the WPF original. - Switching the system theme (light/dark) is followed live by the popup. - With `show_description` enabled, the description row is wide (≥600px) and readable, with the accent bar centered above it. - **Remaining manual validation** (tracked in #48889): multi-monitor, per-monitor DPI, all 9 `toolbar_position` values, and high-contrast theme. --------- Co-authored-by: Yu Leng <yuleng@microsoft.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: Niels Laute <niels.laute@live.nl> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>