## Summary of the Pull Request <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [x] Closes: #47438 <!-- - [ ] Closes: #yyy (add separate lines for additional resolved issues) --> - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [x] **Tests:** Added/updated and all pass - [x] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed, or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments This PR includes a new reference guide feature for Quick Accent's Settings page to show the character mappings for each language. Previously, a language's mappings were unavailable to view unless the user inspected the source code or tested each key in turn after enabling a language. ## Interface Accessed via the new **Open reference guide** button on the Quick Accent settings page: <img width="983" height="437" alt="image" src="https://github.com/user-attachments/assets/5c05a90b-9bf2-471d-99fb-6ab592235d95" /> The user's selected language(s) are listed first, with the others beneath in alphabetical order: <img width="956" height="806" alt="image" src="https://github.com/user-attachments/assets/ac68be40-7bb1-49e1-a20a-883f67b2a359" /> Hover over any character to see its Unicode description. These often have great descriptions: <img width="432" height="176" alt="image" src="https://github.com/user-attachments/assets/caf95e9a-20f6-49eb-87a8-c17e72cf1d45" /> Click on any character to copy it to the clipboard: https://github.com/user-attachments/assets/67bfc14f-7ab3-492c-a345-d7fa5462b164 Search for any character to filter the list to only the language(s) where it is included: <img width="942" height="657" alt="image" src="https://github.com/user-attachments/assets/88a4a0c6-1732-4bf1-a120-af7b08139742" /> <img width="942" height="245" alt="image" src="https://github.com/user-attachments/assets/0a17d012-8307-411a-b12b-2d5bf88f7773" /> (Unfortunately, we don't have a language containing this emoji just yet.) ## Additional features ### Combining marks Some Unicode code points are combining marks like diacritics, which can be very small and difficult to discern. A standard way of illustrating the effect of a combining mark is to use the dotted circle (https://en.wikipedia.org/wiki/Dotted_circle). The reference guide uses this method to better show diacritics, as illustrated here for Hebrew: <img width="260" height="572" alt="image" src="https://github.com/user-attachments/assets/44d849f7-014a-4285-a43b-c17a5bcd1c44" /> We may wish to add this feature as an option for Quick Accent's main selection interface in the future. ### UnicodeInformation replacement Previously, Quick Accent relied upon the UnicodeInformation nuget package for Unicode character description information. This is a 1.5 MB DLL (with the package near 7.5 MB) and outdated, with the last release from more than 3 years ago. As such it doesn't include the latest changes and additions to the Unicode standard, which will be important when we move to support user-defined languages in the future. It would have needed to have been referenced by the Settings UI project as part of this update. Instead, this PR introduces a small UnicodeHelper class which retrieves the Unicode descriptions directly from the Windows ICU library, which is serviced as a standard Windows component, and is automatically updated when a new version of the Unicode standard releases. This also removes the previous need to load and prepare the cache for the Unicode information. The information retrieved is in the exact same format as before. (The ICU library has been a standard component since Windows 10 version 1903.) ### Miscellaneous This adds a re-entrancy guard to the All languages tri-state checkbox on the settings page. No functionality change, just a robustness improvement. A minor refactoring to `GetCharacterDescription()` (beyond now calling `UnicodeHelper` to get the underlying character information) simplifies the flow and hopefully makes this more readable. I added a note about removing Zero-Width Joiner descriptions in the future, as description length may become an issue in the future with fully custom mappings. <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed - 9 new unit tests under **Settings.UI.UnitTests/ViewModelTests/PowerAccentReferenceGuideViewModelTests** - Confirmed that all unit tests pass, including all **Settings.UI.UnitTests** and **PowerAccent*** tests. - Manual testing to confirm that: - Navigation to the guide and back (using the standard back arrow button) work - Ordering is correct and the groupings follow the user's currently selected sets - Filtering works as expected for simple characters and more complex instances like `°C` - Formatting and descriptions are the same as before for single- and multi-codepoint Unicode characters - The UnicodeInformation package is not referenced in any other project ### Unit tests <img width="260" height="52" alt="image" src="https://github.com/user-attachments/assets/e3d67cb4-4008-4911-bcdf-3d0299caf48f" /> <img width="317" height="71" alt="image" src="https://github.com/user-attachments/assets/5313fa5c-cfcf-4396-91f9-9074b57ba193" /> ## Screen recording This screen recording shows how the reference guide is opened via the main Quick Accent page, demonstrates the filtering and hover functionality, and finally shows using the back button to return to the originating Quick Accent settings page: https://github.com/user-attachments/assets/ebc1bb59-014e-423c-99b7-4cd3c7c58caf --------- Co-authored-by: Yu Leng <yuleng@microsoft.com> Co-authored-by: Niels Laute <nielslaute@microsoft.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
8.9 KiB
Quick Accent
Public overview - Microsoft Learn
Quick Links
Overview
Quick Accent (formerly known as Power Accent) is a PowerToys module that allows users to quickly insert accented characters by holding a key and pressing an activation key (like the Space key or arrow keys). For example, holding 'a' might display options like 'à', 'á', 'â', etc. This tool enhances productivity by streamlining the input of special characters without the need to memorize keyboard shortcuts.
Architecture
The Quick Accent module consists of six projects:
poweraccent/
├── PowerAccent.Common/ # Language data, character mappings, LetterKey enum
├── PowerAccent.Core/ # Accent logic, settings, positioning, usage statistics
├── PowerAccent.UI/ # WinUI 3 character selector app (PowerToys.PowerAccent.exe)
├── PowerAccentKeyboardService/ # WinRT keyboard-hook component
├── PowerAccentModuleInterface/ # Native runner module DLL
└── PowerAccent.UITests/ # winappcli end-to-end UI tests
Module Interface (PowerAccentModuleInterface)
The Module Interface, implemented in PowerAccentModuleInterface/dllmain.cpp, is responsible for:
- Handling communication between PowerToys Runner and the PowerAccent process
- Managing module lifecycle (enable/disable/settings)
- Launching and terminating the PowerToys.PowerAccent.exe process
Shared Data (PowerAccent.Common)
PowerAccent.Common holds the UI- and runtime-agnostic data the other projects share:
- The language / character-set definitions and per-letter accent mappings
- The managed
LetterKeyenum (kept in sync with the WinRTLetterKeyinPowerAccentKeyboardService/KeyboardListener.idl)
It has no UI or WinRT dependencies and is unit-tested in isolation (PowerAccent.Common.UnitTests).
Core Logic (PowerAccent.Core)
The Core component contains:
- Main accent character logic, consuming the language data from
PowerAccent.Common - Toolbar positioning math (9 anchor points with per-monitor DPI) and settings handling
- Management of special characters (currency, math symbols, etc.) and usage statistics
Core carries no UI-framework dependency: it raises events and accepts a UI-thread marshaller delegate instead of touching WPF/WinUI directly, and its positioning math is covered by PowerAccent.Core.UnitTests.
UI Layer (PowerAccent.UI)
The UI component is a self-contained WinUI 3 (Windows App SDK) app, migrated from WPF. It is responsible for:
- Displaying the accent toolbar — a non-activating, always-on-top
TransparentWindowoverlay shown withSW_SHOWNAso it never steals focus from the app being typed into - Handling selection and the toolbar's sizing / positioning
- Following the system theme while the long-lived process runs
It builds to PowerToys.PowerAccent.exe together with its .pri and the bundled Windows App SDK runtime, all under the WinUI3Apps output folder.
Keyboard Service (PowerAccentKeyboardService)
This component:
- Implements keyboard hooks to detect key presses
- Manages the trigger mechanism for displaying the accent toolbar
- Handles keyboard input processing
UI Tests (PowerAccent.UITests)
PowerAccent.UITests uses Microsoft.PowerToys.UITest.Next and winappcli to drive Quick Accent
through the Settings UI and a real Notepad window. The suite covers activation and character
selection, module lifecycle, language filtering, every toolbar position, input delay, excluded
applications, usage-frequency sorting, and start-from-left behavior.
Implementation Details
Activation Mechanism
Quick Accent supports two activation styles, selected by the Activation key setting.
Trigger-key modes (Left/Right arrow, Space, or Both — the default):
- A user presses and holds a character key (e.g., 'a')
- User presses the trigger key
- After a brief delay (around 300ms per setting), the accent toolbar appears
- The user can select an accented variant using the trigger key
- Upon releasing the keys, the selected accented character is inserted
Press-and-hold mode (Press and hold the letter, iOS/macOS style, opt-in):
- A user presses and holds an accent-capable character key (e.g., 'a'); the base letter is typed immediately
- After the configured Hold duration (around 500ms per setting), the accent toolbar appears automatically — no separate trigger key is required
- The user navigates the options with the arrow keys or Space
- Upon releasing the letter, the selected accent replaces the base letter; if no option was selected, the base letter that was already typed simply remains
- A quick tap (shorter than the Hold duration) types the base letter only, and modifier combinations (Ctrl/Alt/AltGr/Win + letter) are left untouched
Character Sets
The module includes multiple language-specific character sets and special character sets:
- Various language sets for different alphabets and writing systems
- Special character sets (currency symbols, mathematical notations, etc.)
- These sets are defined in the core component and can be extended
- The Settings UI includes a character reference guide for browsing and searching the same character data by language set. Standalone combining marks are displayed with a dotted circle placeholder while preserving the original character when copied.
Known Behaviors
- The module has a specific timing mechanism for activation that users have become accustomed to. Initially, this was considered a bug (where the toolbar would still appear even after quickly tapping and releasing keys), but it has been maintained as expected behavior since users rely on it.
- Multiple rapid key presses can trigger multiple background tasks.
Future Considerations
- Potential refinements to the activation timing mechanism
- Additional language and special character sets
- Improved UI positioning in different application contexts
UI tests
The UI tests require a live interactive desktop with the en-US keyboard layout selected and Caps Lock off. Build the test executable from the repository root:
tools\build\build.cmd -Path src\modules\poweraccent\PowerAccent.UITests -Platform x64 -Configuration Debug
Run the produced Microsoft Testing Platform executable with the PowerAccent category:
x64\Debug\tests\PowerAccent.UITests\net10.0-windows10.0.26100.0\PowerAccent.UITests.exe `
--filter "TestCategory=PowerAccent"
See the UI tests framework for local-VM and pipeline workflows.
Debugging
To debug the Quick Accent module via runner approach, follow these steps:
- Get familiar with the overall Debugging Process for PowerToys.
- Build the entire PowerToys solution in Visual Studio
- Navigate to the PowerAccent folder in Solution Explorer
- Open the file you want to debug and set breakpoints at the relevant locations
- Find the runner project in the root of the solution
- Right-click on the runner project and select "Set as Startup Project"
- Start debugging by pressing
F5or clicking the "Start" button - When the PowerToys Runner launches, enable the Quick Accent module in the UI
- Use the Visual Studio Debug menu or press
Ctrl+Alt+Pto open "Reattach to Process" - Find and select "PowerToys.PowerAccent.exe" in the process list
- Trigger the action in Quick Accent that should hit your breakpoint
- Verify that the debugger breaks at your breakpoint and you can inspect variables and step through code
This process allows you to debug the Quick Accent module while it's running as part of the full PowerToys application.
Alternative Debugging Approach
To directly debug the Quick Accent UI component:
- Get familiar with the overall Debugging Process for PowerToys.
- Build the entire PowerToys solution in Visual Studio
- Navigate to the PowerAccent folder in Solution Explorer
- Open the file you want to debug and set breakpoints at the relevant locations
- Right-click on the PowerAccent.UI project and select "Set as Startup Project"
- Start debugging by pressing
F5or clicking the "Start" button - Verify that the debugger breaks at your breakpoint and you can inspect variables and step through code
Known issue: A first incremental build can surface transient errors (for example from CsWinRT projection / WinUI XAML codegen ordering).
Solution: Right-click the PowerAccent folder in Solution Explorer and select "Rebuild", then start debugging again.