Compare commits

..

57 Commits

Author SHA1 Message Date
Gleb Khmyznikov
8efd9bc361 fix neatpicks 2025-07-01 13:23:27 +02:00
Gleb Khmyznikov
6e9a5c2673 Merge branch 'main' into docs-overhaul 2025-07-01 13:11:28 +02:00
Gleb Khmyznikov
7beea60256 update newplus debug steps 2025-06-25 21:05:47 +02:00
Gleb Khmyznikov
4513882108 small mouse tools debug addition 2025-06-25 18:19:14 +02:00
Gleb Khmyznikov
e3a3373f13 update the file locksmith debug steps 2025-06-25 17:09:22 +02:00
Gleb Khmyznikov
aaeb3f9822 Add missing step 2025-06-25 13:14:25 +02:00
Gleb Khmyznikov
82343aee7f Merge branch 'docs-overhaul' of https://github.com/microsoft/PowerToys into docs-overhaul 2025-06-25 13:09:21 +02:00
Gleb Khmyznikov
70c4324612 Fix filelocksmith doc 2025-06-25 13:08:40 +02:00
Mengyuan
04e8eb3bf3 Update filelocksmith.md 2025-06-25 13:56:06 +08:00
Gleb Khmyznikov
03ddde98d8 initial fix of the locksmith 2025-06-24 18:18:27 +02:00
Jaylyn Barbee
7a1e906e9b Update zoomit.md
Updated ZoomIt docs to add Debug instructions.
2025-06-24 10:01:01 -04:00
Gleb Khmyznikov
6ffce05f8c Add quick accent debug 2025-06-24 15:16:08 +02:00
Gleb Khmyznikov
7cd88a0602 add debug doc for kb manager 2025-06-23 21:43:01 +02:00
zhaopeng wang
79c52c7a32 Update cropandlock.md 2025-06-23 21:53:27 +08:00
zhaopeng wang
012d87eabd Update alwaysontop.md 2025-06-23 21:49:59 +08:00
Gleb Khmyznikov
4dc97cf44d Add debug info 2025-06-23 13:59:53 +02:00
Gleb Khmyznikov
244997db8b Add overview and links hat to all modules 2025-06-20 22:26:16 +02:00
Gleb Khmyznikov
9ab92bc5b7 Add awake and imageresizer docs 2025-06-20 15:10:56 +02:00
Gleb Khmyznikov
a753d86819 add text extractor basics 2025-06-20 14:23:32 +02:00
Gleb Khmyznikov
d0d8a5ad46 Update power rename doc 2025-06-20 13:20:03 +02:00
Gleb Khmyznikov
e056454535 add settings new steps, add command not found module 2025-06-20 13:11:38 +02:00
Gleb Khmyznikov
5eb74dd59a Add Color Picker doc 2025-06-20 12:33:36 +02:00
Gleb Khmyznikov
f9afda5190 update documentation links 2025-06-20 11:58:44 +02:00
Gleb Khmyznikov
fd037a9d97 add AOT and Crop docs 2025-06-20 11:31:33 +02:00
Gleb Khmyznikov
7b1a9cf275 update fuzzing test doc 2025-06-20 11:13:08 +02:00
Mengyuan
1dfc7a8fcf Update fuzzingtesting.md 2025-06-20 10:53:46 +08:00
Gleb Khmyznikov
df4f863529 Add UI tests link 2025-06-19 21:05:07 +02:00
Gleb Khmyznikov
b5ff8f748a add mouse utilities doc 2025-06-19 18:32:58 +02:00
Gleb Khmyznikov
e7aba2202e move and rename settingsv2 2025-06-19 18:11:18 +02:00
Gleb Khmyznikov
71da4b254e add links and diagrams 2025-06-19 15:18:23 +02:00
Gleb Khmyznikov
f0cbb20ba5 add filelocksmith doc 2025-06-19 15:15:06 +02:00
Gleb Khmyznikov
941ef05e69 Add links for editor 2025-06-19 14:41:35 +02:00
Gleb Khmyznikov
04eebad845 add hosts editor doc 2025-06-19 14:26:30 +02:00
Gleb Khmyznikov
e9741c8fc4 revamp fuzzing doc 2025-06-19 12:33:03 +02:00
Peiyao Zhao
d41109ec98 Update environmentvariables.md
Add checklist link for environment variables
2025-06-19 16:32:55 +08:00
Peiyao Zhao
e346601328 Update registrypreview.md
Add release checklist for registry preview
2025-06-19 16:26:33 +08:00
Peiyao Zhao
2d10298240 Update monaco-editor.md
Add peek to the Monaco usage
2025-06-19 16:20:47 +08:00
Hao Liu
2d15bf9b28 Update quickaccent.md 2025-06-19 13:19:05 +08:00
Gleb Khmyznikov
6eea58fe70 add diagram 2025-06-18 21:17:24 +02:00
Gleb Khmyznikov
a018f47b7a update shortcut_guide 2025-06-18 21:12:19 +02:00
Gleb Khmyznikov
d25fb664a6 add screen ruller doc 2025-06-18 20:54:23 +02:00
Gleb Khmyznikov
ef455521ce add quick accent doc 2025-06-18 19:10:32 +02:00
Gleb Khmyznikov
7aa26aec5b remove duplicates for FZ 2025-06-18 16:23:43 +02:00
Zhaopeng Wang (from Dev Box)
c7b885bf03 add fancyzone doc 2025-06-18 20:14:15 +08:00
Gleb Khmyznikov
b3d2a5a1f8 add env variables 2025-06-17 15:10:52 +02:00
Gleb Khmyznikov
d24b535a0a add quick links 2025-06-17 14:46:46 +02:00
Gleb Khmyznikov
4ef58f1695 Add registry preview and monaco editor 2025-06-17 13:46:50 +02:00
Gleb Khmyznikov
663c3555d3 Add new plus and context menus docs 2025-06-16 19:05:21 +02:00
Gleb Khmyznikov
3895538a06 update settings doc 2025-06-16 17:34:40 +02:00
Gleb Khmyznikov
34532a6350 update runner 2025-06-16 17:12:08 +02:00
Gleb Khmyznikov
3f4b0acae7 update zoomit 2025-06-16 17:00:21 +02:00
Gleb Khmyznikov
22d1fd4d53 update fancyzones 2025-06-16 16:38:27 +02:00
Gleb Khmyznikov
d0e16049a6 add links to issues 2025-06-16 16:17:15 +02:00
Gleb Khmyznikov
a1e10e6410 fancyzones images 2025-06-16 15:23:23 +02:00
Gleb Khmyznikov
afe5c2e27c zoomit doc 2025-06-16 14:25:43 +02:00
Gleb Khmyznikov
ea50dd6d79 update fancyzones doc 2025-06-13 16:23:31 +02:00
Gleb Khmyznikov
9ee9ad3fa6 initial 2025-06-13 16:10:31 +02:00
33 changed files with 376 additions and 1872 deletions

View File

@@ -55,7 +55,6 @@ clayton
Coplen
craigloewen
crutkas
Chubercik
damienleroy
daverayment
davidegiacometti

View File

@@ -141,7 +141,6 @@ boxmodel
BPBF
bpmf
bpp
breadcrumb
Breadcrumb
Browsable
BROWSEINFO

View File

@@ -11,13 +11,14 @@
"PowerToys.ActionRunner.exe",
"PowerToys.Update.exe",
"PowerToys.BackgroundActivatorDLL.dll",
"Notifications.dll",
"os-detection.dll",
"PowerToys.exe",
"PowerToys.FilePreviewCommon.dll",
"PowerToys.Interop.dll",
"Tools\\PowerToys.BugReportTool.exe",
"StylesReportTool\\PowerToys.StylesReportTool.exe",
"Telemetry.dll",
"CalculatorEngineCommon.dll",
"PowerToys.ManagedTelemetry.dll",
"PowerToys.ManagedCommon.dll",
@@ -32,7 +33,7 @@
"PowerToys.AlwaysOnTopModuleInterface.dll",
"PowerToys.CmdNotFoundModuleInterface.dll",
"PowerToys.CmdNotFound.dll",
"PowerToys.ColorPicker.dll",
"PowerToys.ColorPickerUI.dll",
@@ -53,7 +54,7 @@
"PowerToys.Awake.exe",
"PowerToys.Awake.dll",
"fancyzones.dll",
"PowerToys.FancyZonesEditor.exe",
"PowerToys.FancyZonesEditor.dll",
"PowerToys.FancyZonesEditorCommon.dll",
@@ -135,7 +136,7 @@
"PowerToys.PowerLauncher.dll",
"PowerToys.PowerLauncher.exe",
"PowerToys.PowerLauncher.Telemetry.dll",
"Wox.dll",
"Wox.Infrastructure.dll",
"Wox.Plugin.dll",
"RunPlugins\\Calculator\\Microsoft.PowerToys.Run.Plugin.Calculator.dll",
@@ -274,16 +275,16 @@
"Mono.Cecil.Pdb.dll",
"Mono.Cecil.Rocks.dll",
"Newtonsoft.Json.dll",
"Newtonsoft.Json.Bson.dll",
"NLog.dll",
"HtmlAgilityPack.dll",
"Markdig.Signed.dll",
"HelixToolkit.dll",
"HelixToolkit.Core.Wpf.dll",
"Mages.Core.dll",
"JetBrains.Annotations.dll",
"NLog.Extensions.Logging.dll",
"getfilesiginforedist.dll",
"concrt140_app.dll",
"msvcp140_1_app.dll",
"msvcp140_2_app.dll",
@@ -293,8 +294,22 @@
"vcomp140_app.dll",
"vcruntime140_1_app.dll",
"vcruntime140_app.dll",
"WinUI3Apps\\CommunityToolkit.Labs.WinUI.SettingsControls.dll",
"UnicodeInformation.dll",
"Vanara.Core.dll",
"Vanara.PInvoke.ComCtl32.dll",
"Vanara.PInvoke.Cryptography.dll",
"Vanara.PInvoke.Gdi32.dll",
"Vanara.PInvoke.Kernel32.dll",
"Vanara.PInvoke.Ole.dll",
"Vanara.PInvoke.Rpc.dll",
"Vanara.PInvoke.Security.dll",
"Vanara.PInvoke.Shared.dll",
"Vanara.PInvoke.Shell32.dll",
"Vanara.PInvoke.ShlwApi.dll",
"Vanara.PInvoke.User32.dll",
"WinUI3Apps\\clrcompression.dll",
"WinUI3Apps\\Microsoft.Graphics.Canvas.Interop.dll",
"Microsoft.Web.WebView2.Core.dll",
"Microsoft.Web.WebView2.WinForms.dll",
"Microsoft.Web.WebView2.Wpf.dll",
@@ -321,7 +336,7 @@
"Testably.Abstractions.FileSystem.Interface.dll",
"WinUI3Apps\\Testably.Abstractions.FileSystem.Interface.dll",
"ColorCode.Core.dll",
"ColorCode.UWP.dll",
"UnitsNet.dll",
"UtfUnknown.dll",
"Wpf.Ui.dll"

234
README.md
View File

@@ -35,19 +35,19 @@ Microsoft PowerToys is a set of utilities for power users to tune and streamline
Go to the [Microsoft PowerToys GitHub releases page][github-release-link] and click on `Assets` at the bottom to show the files available in the release. Please use the appropriate PowerToys installer that matches your machine's architecture and install scope. For most, it is `x64` and per-user.
<!-- items that need to be updated release to release -->
[github-next-release-work]: https://github.com/microsoft/PowerToys/issues?q=is%3Aissue+milestone%3A%22PowerToys+0.93%22
[github-current-release-work]: https://github.com/microsoft/PowerToys/issues?q=is%3Aissue+milestone%3A%22PowerToys+0.92%22
[ptUserX64]: https://github.com/microsoft/PowerToys/releases/download/v0.92.0/PowerToysUserSetup-0.92.0-x64.exe
[ptUserArm64]: https://github.com/microsoft/PowerToys/releases/download/v0.92.0/PowerToysUserSetup-0.92.0-arm64.exe
[ptMachineX64]: https://github.com/microsoft/PowerToys/releases/download/v0.92.0/PowerToysSetup-0.92.0-x64.exe
[ptMachineArm64]: https://github.com/microsoft/PowerToys/releases/download/v0.92.0/PowerToysSetup-0.92.0-arm64.exe
[github-next-release-work]: https://github.com/microsoft/PowerToys/issues?q=is%3Aissue+milestone%3A%22PowerToys+0.92%22
[github-current-release-work]: https://github.com/microsoft/PowerToys/issues?q=is%3Aissue+milestone%3A%22PowerToys+0.91%22
[ptUserX64]: https://github.com/microsoft/PowerToys/releases/download/v0.91.1/PowerToysUserSetup-0.91.1-x64.exe
[ptUserArm64]: https://github.com/microsoft/PowerToys/releases/download/v0.91.1/PowerToysUserSetup-0.91.1-arm64.exe
[ptMachineX64]: https://github.com/microsoft/PowerToys/releases/download/v0.91.1/PowerToysSetup-0.91.1-x64.exe
[ptMachineArm64]: https://github.com/microsoft/PowerToys/releases/download/v0.91.1/PowerToysSetup-0.91.1-arm64.exe
| Description | Filename |
|----------------|----------|
| Per user - x64 | [PowerToysUserSetup-0.92.0-x64.exe][ptUserX64] |
| Per user - ARM64 | [PowerToysUserSetup-0.92.0-arm64.exe][ptUserArm64] |
| Machine wide - x64 | [PowerToysSetup-0.92.0-x64.exe][ptMachineX64] |
| Machine wide - ARM64 | [PowerToysSetup-0.92.0-arm64.exe][ptMachineArm64] |
| Description | Filename | sha256 hash |
|----------------|----------|-------------|
| Per user - x64 | [PowerToysUserSetup-0.91.1-x64.exe][ptUserX64] | 42EA4A3E8C79A5456476D19E72B3E2AB9393A89C4DC7442EB7EE5A1E3490D38A |
| Per user - ARM64 | [PowerToysUserSetup-0.91.1-arm64.exe][ptUserArm64] | F3F433FE04049F9197411D792AADEBF34E3BE7FE16327BD8B73D2A046ED8BAF6 |
| Machine wide - x64 | [PowerToysSetup-0.91.1-x64.exe][ptMachineX64] | EC4BC3A8625775866B0ED4577CCF83E6EC7B1A0AD267379DDBAF4FE49C7B5BDD |
| Machine wide - ARM64 | [PowerToysSetup-0.91.1-arm64.exe][ptMachineArm64] | 9CB8911008420D0E446AE3D5CE365E447FA4DF9DCF9337F3A80F933C00FC3689 |
This is our preferred method.
@@ -85,7 +85,7 @@ We ask that **before you start work on a feature that you would like to contribu
Most contributions require you to agree to a [Contributor License Agreement (CLA)][oss-CLA] declaring that you grant us the rights to use your contribution and that you have permission to do so.
For guidance on developing for PowerToys, please read the [developer docs](./doc/devdocs) for a detailed breakdown. This includes how to setup your computer to compile.
For guidance on developing for PowerToys, please read the [developer docs](/doc/devdocs) for a detailed breakdown. This includes how to setup your computer to compile.
## What's Happening
@@ -93,138 +93,166 @@ For guidance on developing for PowerToys, please read the [developer docs](./doc
Our [prioritized roadmap][roadmap] of features and utilities that the core team is focusing on.
### 0.92 - June 2025 Update
### 0.91 - May 2025 Update
In this release, we focused on new features, stability, optimization improvements, and automation.
In this release, we focused on new features, stability, and automation.
**✨Highlights**
- PowerToys settings now has a toggle for the system tray icon, giving users control over its visibility based on personal preference. Thanks [@BLM16](https://github.com/BLM16)!
- Command Palette now has Ahead-of-Time ([AOT](https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot)) compatibility for all first-party extensions, improved extensibility, and core UX fixes, resulting in better performance and stability across commands.
- Color Picker now has customizable mouse button actions, enabling more personalized workflows by assigning functions to left, right, and middle clicks. Thanks [@PesBandi](https://github.com/PesBandi)!
- Bug Report Tool now has a faster and clearer reporting process, with progress indicators, improved compression, auto-cleanup of old trace logs, and inclusion of MSIX installer logs for more efficient diagnostics.
- File Explorer add-ons now have improved rendering stability, resolving issues with PDF previews, blank thumbnails, and text file crashes during file browsing.
- We focused on greatly improving the Command Palette's performance and fixing a large number of bugs. Some new features we've added are:
- Added the ability for Command Palette to search any file using a fallback command.
- Added the ability to make the Command Palette global hotkey a low-level keyboard hook.
- Added open URL fallback command for the WebSearch extension, enabling users to directly open URLs in the browser from Command Palette.
- You can now define custom formats in the Date and Time plugins of PT Run and Command Palette. Thanks [@htcfreek](https://github.com/htcfreek)!
### Advanced Paste
- Fixed an issue where Advanced Paste failed to create the OCR engine for certain English language tags (e.g., en-CA) by initializing the OCR engine with the user profile language. Thanks [@cryolithic](https://github.com/cryolithic)!
### Color Picker
- Added mouse button actions so you can choose what left, right, or middle click does. Thanks [@PesBandi](https://github.com/PesBandi)!
- Fixed an issue where a resource leak caused hangs or crashes by properly disposing of the Graphics object. Thanks [@dcog989](https://github.com/dcog989)!
- Fixed an issue where Color Picker exited on Backspace keypress by ensuring it only closes when focused and aligning Escape/Backspace behavior. Thanks [@PesBandi](https://github.com/PesBandi)!
- Added support for Oklab and Oklch color formats in Color Picker. Thanks [@lemonyte](https://github.com/lemonyte)!
### Crop & Lock
### Command Not Found
- Aligned window styling with current Windows theme for a cleaner look. Thanks [@sadirano](https://github.com/sadirano)!
- Updated the WinGet Command Not Found script to only enable the experimental features if they exist.
### Command Palette
- Enhanced performance by resolving a regression in page loading.
- Applied consistent hotkey handling across all Command Palette commands for a smoother user experience.
- Improved graceful closing of Command Palette. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
- Fixed consistency issue for extensions' alias with "Direct" setting and enabled localization for "Direct" and "Indirect" for better user understanding. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
- Improved visual clarity by styling critical context items correctly.
- Automatically focused the field when only one is present on the content page.
- Improved stability and efficiency when loading file icons in SDK ThumbnailHelper.cs by removing unnecessary operations. Thanks [@OldUser101](https://github.com/OldUser101)!
- Enhanced details view with commands implementation. (See [Extension sample](./src/modules/cmdpal/ext/SamplePagesExtension/Pages/SampleListPageWithDetails.cs))
- Updated bug template to include Command Palette module.
- Fixed an issue where the toast window was not scaled for DPI, causing layout issues under display scaling.
- Fixed an issue where Up/Down keyboard navigation didn't move selection when the caret was at position 0, and added continuous navigation like PT Run v1. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
- Updated the Time and Date extension code to simplify it and improve clarity.
- Fixed an issue where capitalization in the command causes failure when trying to go to the mouse pointer, resolved by adjusting the command to lowercase.
- Added open URL fallback command for the WebSearch extension, enabling users to directly open URLs in the browser from the Command Palette. Thanks [@htcfreek](https://github.com/htcfreek)!
- Added setting to enable/disable system tray icon in CmdPal and aligned terminology with Windows 11. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
- Fixed an alias update issue by removing the old alias when a new one is set.
- Resolved GitHub casing conflict by migrating Exts and exts into a new ext directory, ensuring consistent structure across platforms and preventing path fragmentation.
- Fix an issue where the 'Create New Extension' command generated empty file names.
- Added the ability to make the global hotkey a low-level keyboard hook.
- Added support for JUMBO thumbnails, enabling access to high-resolution icons.
- Fixed crashes when CmdPal auto-hid itself while an MSAL dialog was opened, by preventing CmdPal from hiding if it's disabled.
- Added support for immediately selecting search text when a page is loaded.
- Fixed a bug where extension settings pages failed to reload on reopen by updating the settings form when extension settings are saved.
- Fixed an issue where the Command Palette failed to launch from the runner.
- Refactored and ported the PowerToys Run v1 calculator logic into Command Palette, added settings support, and improved fallback behavior.
- Re-added support for list item keyboard shortcuts.
- Enhanced accessibility in Command Palette by adding proper labels, refining animations, improving localization, and fixed a11y related issues.
- Ported custom format support to the Time and Date plugin, reordered and cleaned up settings, improved error messaging, and fixed edge-case crashes for more robust and user-friendly behavior. Thanks [@htcfreek](https://github.com/htcfreek)!
- Added fallback item for system command.
- Fixed a bug in Windows System Command where the key prompt incorrectly displayed "Empty" for the "Open Recycle Bin" action. Thanks [@jironemo](https://github.com/jironemo)!
- Fixed an issue where the 'more commands' list showed commands that shouldn't be visible. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
- Fixed an issue where the details view in Command Palette displayed an oversized icon and misaligned text, aligning it with Windows Search behavior.
- Fixed a bug where empty screen content and command bar commands were cut off when using long labels, ensuring proper layout and visibility.
- Improved CmdPals WinGet integration by fixing version display for installed packages, enabling updates with icons, and migrating the preview winget API to a stable version.
- Fixed a bug where commands for ContentPage didn't update until after exit, by ensuring context menus are fully initialized when they change.
- Added fallback support to the TimeDate extension, enabling direct date/time queries without pre-selecting the command.
- Added import of Common.Dotnet.AotCompatibility.props across multiple CmdPal project files to enhance AOT compilation support.
- Fixed a crash in CmdPal settings caused by a null HotKey when settings.json is missing or lacks a defined hotkey. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
- Added support for filterable, nested context menus in CmdPal, including a search box to maintain focus behavior.
- Refactored CmdPal classes to improve JSON serialization and introduced new serialization contexts for better performance and maintainability.
- Added support for ahead-of-time (AoT) compilation.
- Added retry mechanism for CmdPal launch.
- Removed some unused files from CmdPal.Common to simplify the codebase and facilitate marking it as AoT-compatible.
- Fixed a bug where a race condition in the update of SearchText caused the cursor in the input box to automatically jump to the end of the line, ensuring SearchText is only updated after it has actually been changed.
- Added support for searching any file in the fallback command.
- Cleaned up AoT-related code to prevent duplicate operations during testing.
- Reduced CmdPal load time by parallelizing extension startup and adding timeouts to prevent misbehaving extensions from blocking others.
- Enhanced UI behavior by dismissing the details pane when the list gets emptied, avoiding inconsistent visual states.
- Added support to unset the fallback command in CmdPal when no matching command is found, ensuring cleaner reload behavior.
- Fixed a leak in the CmdPal extension template by addressing improper ComServer use.
- Prevented CmdPal window from maximizing on title bar double-click to maintain intended window behavior. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
- Fixed an issue where the Settings UI launched too small by making window dimensions DPI-aware and enforcing minimum width and height using WinUIEx.
- Fixed white flash and one-time animation issues in CmdPal by cloaking the window instead of hiding it.
- Fixed a bug where all extension settings were fetched on startup by lazy-loading extension settings, reducing initialization overhead.
- Added support for protecting CmdPal from crashes on Adaptive Card parse failure.
- Replaced shell:AppsFolder with URI activation in CmdPal to improve reliability.
- Added ability to open CmdPal settings from PowerToys Settings.
- Added ability for CmdPal to observe and dynamically update extension details by tracking property changes on the selected item.
- Bumped the toolkit version used in the CmdPal extension template to 0.2.0.
### Command Palette extensions
### Image Resizer
- Added "Copy Path" command to *App* search results for convenience. Thanks [@PesBandi](https://github.com/PesBandi)!
- Improved *Calculator* input experience by ignoring leading equal signs. Thanks [@PesBandi](https://github.com/PesBandi)!
- Corrected input handling in the *Calculator* extension to avoid showing errors for input with only leading whitespace.
- Improved *New Extension* wizard by validating names to prevent namespace errors.
- Ensured consistent context items display for the *Run* extension between fallback and top-level results.
- Fixed missing *Time & Date* commands in fallback results. Thanks [@htcfreek](https://github.com/htcfreek)!
- Fixed outdated results in the *Time & Date* extension. Thanks [@htcfreek](https://github.com/htcfreek)!
- Fixed an issue where *Web Search* always opened Microsoft Edge instead of the user's default browser on Windows 11 24H2 and later. Thanks [@RuggMatt](https://github.com/RuggMatt)!
- Improved ordering of *Windows Settings* extension search results from alphabetical to relevance-based for quicker access.
- Added "Restart Windows Explorer" command to the *Windows System Commands* provider for gracefully terminate and relaunch explorer.exe. Thanks [@jiripolasek](https://github.com/jiripolasek)!
- Fixed an issue where deleting an Image Resizer preset removed the wrong preset.
### Command Palette Ahead-of-Time (AOT) readiness
### Keyboard Manager
- Weve made foundational changes to prepare the Command Palette for future Ahead-of-Time (AOT) publishing. This includes replacing the calculator library with ExprTk, improving COM object handling, refining Win32 interop, and correcting trimming behavior—all to ensure compatibility, performance, and reliability under AOT constraints. All first-party extensions are now AOT-compatible. These improvements lay the groundwork for publishing Command Palette as an AOT application in the next release.
- Special thanks to [@Sergio0694](https://github.com/Sergio0694) for guidance on making COM APIs AOT-compatible, [@jtschuster](https://github.com/jtschuster) for fixing COM object handling, [@ArashPartow](https://github.com/ArashPartow) from ExprTk for integration suggestions, and [@tian-lt](https://github.com/tian-lt) from the Windows Calculator team for valuable suggestion throughout the migration journey and review.
- As part of the upcoming release, were also enabling AOT compatibility for key dependencies, including markdown rendering, Adaptive Cards, internal logging and telemetry library, and the core Command Palette UX.
### FancyZones
- Fixed DPI-scaling issues to ensure FancyZones Editor displays crisply on high-resolution monitors. Thanks [@HO-COOH](https://github.com/HO-COOH)! This inspired us a broader review across other PowerToys modules, leading to DPI display optimizations in Awake, Color Picker, PowerAccent, and more.
### File Explorer add-ons
- Fixed potential failures in PDF previewer and thumbnail generation, improving reliability when browsing PDF files. Thanks [@mohiuddin-khan-shiam](https://github.com/mohiuddin-khan-shiam)!
- Prevented Monaco Preview Handler crash when opening UTF-8-BOM text files.
### Hosts File Editor
- Added an in-app *“Learn more”* link to warning dialogs for quick guidance. Thanks [@PesBandi](https://github.com/PesBandi)!
### Mouse Without Borders
- Fixed firewall rule so MWB now accepts connections from IPs outside your local subnet.
- Cleaned legacy logs to reduce disk usage and noise.
### Peek
- Updated QOI reader so 3-channel QOI images preview correctly in Peek and File Explorer. Thanks [@mbartlett21](https://github.com/mbartlett21)!
- Added codec detection with a clear warning when a video cant be previewed, along with a link to the Microsoft Store to download the required codec.
- Fixed an issue where a modifier key, when set without specifying left or right, would get stuck due to incorrect key handling by tracking the pressed keys and sending the correct key accordingly. Thanks [@mantaionut](https://github.com/mantaionut)!
### PowerRename
- Added support for $YY-$MM-$DD in ModificationTime and AccessTime to enable flexible date-based renaming.
- Enhanced PowerRename's time formatting capabilities by adding 12-hour time format patterns with AM/PM support. Thanks [@bitmap4](https://github.com/bitmap4)!
### PowerToys Run
- Suppressed error UI for known WPF-related crashes to reduce user confusion, while retaining diagnostic logging for analysis. This targets COMException 0xD0000701 and 0x80263001 caused by temporary DWM unavailability.
- Added support for custom formats in the "Time and Date" plugin and improved error messages for invalid input formats. Thanks [@htcfreek](https://github.com/htcfreek)!
- Fix two crashes: one for WFT on very early dates and another for calculating the week of the month on very late dates (e.g., 31.12.9999), and reorder UI settings. Thanks [@htcfreek](https://github.com/htcfreek)!
- Fix an issue where capitalization in the command causes failure when trying to go to the mouse pointer, resolved by adjusting the command to lowercase.
- Added version details to plugin error messages for 'Loading error' and 'Init error'. Thanks [@htcfreek](https://github.com/htcfreek)!
- Enhanced result model by adding support for preventing usage-based ordering, giving plugin developers greater control over sorting behavior. Thanks [@CoreyHayward](https://github.com/CoreyHayward) and [@htcfreek](https://github.com/htcfreek)!
### Quick Accent
- Updated the letter mapping in GetDefaultLetterKeyEPO, replacing "ǔ" with "ŭ" for the VK_U key to accurately reflect Esperanto phonetics. Thanks [@OlegKharchevkin](https://github.com/OlegKharchevkin)!
- Fixed an issue where Quick Accent did not work properly when using the on-screen keyboard. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
### Registry Preview
- Added "Extended data preview" via magnifier icon and context menu in the Data Grid, enabled easier inspection of complex registry types like REG_BINARY, REG_EXPAND_SZ, and REG_MULTI_SZ, etc. Thanks [@htcfreek](https://github.com/htcfreek)!
- Improved file-saving experience in Registry Preview by aligning with Notepad-like behavior, enhancing user prompts, error handling, and preventing crashes during unsaved or interrupted actions. Thanks [@htcfreek](https://github.com/htcfreek)!
- Enhanced Registry Preview to support pasting registry keys and values without manually writing the file header, and added a new button for resetting the app. Thanks [@htcfreek](https://github.com/htcfreek)!
### Settings
- Added an option to hide or show the PowerToys system tray icon. Thanks [@BLM16](https://github.com/BLM16)!
- Improved settings to show progress while a bug report package is being generated.
- Fix an issue where the Settings app randomly showed a blank icon in the taskbar by deferring icon assignment until the window is activated.
- Added the ability to maximize the "What's New" window for a more comfortable reading experience.
### Workspaces
- Stored Workspaces icons in user AppData to ensure profile portability and prevent loss during temporary folder cleanup.
- Enabled capture and launch of PWAs on non-default Edge or Chrome profiles, ensuring consistent behavior during creation and execution.
- Fixed bugs where Steam games were not captured or launched correctly by updating window filtering and integrating Steam URL protocol handling.
### Documentation
- Added SpeedTest and Dictionary Definition to the third-party plugins documentation for PowerToys Run. Thanks [@ruslanlap](https://github.com/ruslanlap)!
- Corrected sample links and typo in Command Palette documentation. Thanks [@daverayment](https://github.com/daverayment) and [@roycewilliams](https://github.com/roycewilliams)!
- Added QuickNotes to the third-party plugins documentation for PowerToys Run. Thanks [@ruslanlap](https://github.com/ruslanlap)!
- Added Weather and Pomodoro plugins to the PowerToys Run third-party plugin documentation. Thanks [@ruslanlap](https://github.com/ruslanlap)!
- Added the Linear plugin to PowerToys Run's third-party plugin documentation. Thanks [@vednig](https://github.com/vednig)!
- Fixed formatting issues in documentation files and updated contributor and team member information. Thanks [@DanielEScherzer](https://github.com/DanielEScherzer) and [@RokyZevon](https://github.com/RokyZevon)!
### Development
- Updated .NET libraries to 9.0.6 for performance and security. Thanks [@snickler](https://github.com/snickler)!
- Updated WinAppSDK to 1.7.2 for better stability and Windows support.
- Introduced a one-step local build script that generates a signed installer, enhancing developer productivity.
- Generated portable PDBs so cross-platform debuggers can read symbol files, improving debugging experience in VSCode and other tools.
- Simplified WinGet configuration files by using the [Microsoft.Windows.Settings](https://www.powershellgallery.com/packages/Microsoft.Windows.Settings) module to enable Developer Mode. Thanks [@mdanish-kh](https://github.com/mdanish-kh)!
- Adjusted build scripts for the latest Az.Accounts module to keep CI green.
- Streamlined release pipeline by removing hard-coded telemetry version numbers, and unified Command Palette versioning with Windows Terminal's versioning method for consistent updates.
- Enhanced the build validation step to show detailed differences between NOTICE.md and actual package dependencies and versions.
- Improved spell-checking accuracy across the repo. Thanks [@rovercoder](https://github.com/rovercoder)!
- Upgraded CI to TouchdownBuild v5 for faster pipelines.
- Added context comments to *Resources.resw* to help translators.
- Expanded fuzz testing coverage to include FancyZones.
- Integrated all unit tests into the CI pipeline, increasing from ~3,000 to ~5,000 tests.
- Enabled daily UI test automation on the main branch, now covering over 370 UI tests for end-to-end validation.
- Newly added unit tests for WorkspacesLib to improve reliability and maintainability.
- Updated GitHub Action to install .NET 9 for MSStore release support.
- Updated version placeholder in bug_report.yml to prevent incorrect v0.70.0 versioning in issue reports.
- Updated GitHub Action to upgrade actions/setup-dotnet from version 3 to version 4 for MSStore release.
- Added securityContext to WinGet configuration files, allowing invocation from user context and prompting a single UAC for elevated resources in a separate process. Thanks [@mdanish-kh](https://github.com/mdanish-kh)!
- Changed log file extensions from .txt to .log to support proper file associations and tooling compatibility, and added logs for Workspace. Thanks [@benwa](https://github.com/benwa)!
- Upgraded testing framework dependencies and aligned package versions across components.
- Upgraded dependencies to fix vulnerabilities.
- Enhanced repository security by pinning GitHub Actions and Docker tags to immutable full-length commits and integrating automated dependency vulnerability scanning via Dependency Review Workflow. Thanks [@Nick2bad4u](https://github.com/Nick2bad4u)!
- Upgraded Boost dependencies to a newer version.
- Upgraded toolkit to the latest version, suppressed AoT-related warnings.
- Fixed an issue where missing signing for newly added files caused build failures.
- Update release pipeline to prevent publishing private symbols for 100 years.
- Introduced fuzzing for PowerRename to improve reliability and added setup guidance for extending fuzzing to other C++ modules.
- Added centralized pre-creation of generated folders for all .csproj projects to prevent build failures.
- Updated WinAppSDK to the latest 1.7 version.
- Upgraded Boost dependencies to the latest version for the PowerRename Fuzzing project.
- Updated the ADO area path in tsa.json to resolve TSA pipeline errors caused by a deprecated path.
- Initiated AoT support for CmdPal with foundational work in progress.
### Tool/General
### General
- Added support for automating bug report creation by generating a pre-filled GitHub issue URL with system and diagnostic information. Thanks [@donlaci](https://github.com/donlaci)!
- Added scripts to locally build the installer, ensuring the CmdPal can also be launched in a local environment.
- Removed export PFX logic to eliminate hardcoded password usage and resolve PSScriptAnalyzer security warning.
- Added PowerShell script and CI integration to enforce consistent use of Common.Dotnet.CsWinRT.props across all C# projects under the src folder.
### What is being planned for version 0.92
- Updated bug report compression library (cziplib 0.3.3) for faster and more reliable package creation. Thanks [@Chubercik](https://github.com/Chubercik)!
- Included App Installer (“AppX Deployment Server”) event logs in bug reports for more thorough diagnostics.
### What is being planned for version 0.93
For [v0.93][github-next-release-work], we'll work on the items below:
For [v0.92][github-next-release-work], we'll work on the items below:
- Continued Command Palette polish
- New UI automation tests
- New UI Automation tests
- Working on installer upgrades
- Working on shortcut conflict detection
- Upgrading Keyboard Manager's editor UI
- Stability, bug fixes

View File

@@ -55,7 +55,7 @@ The `OneFuzzConfig.json` file provides critical information for deploying fuzzin
],
"adoTemplate": [
{
"AssignedTo": "leilzh@microsoft.com",
"AssignedTo": "PowerToys@microsoft.com",
"jobNotificationEmail": "PowerToys@microsoft.com"
}
],

View File

@@ -11,35 +11,26 @@ namespace Common.UI
{
public enum SettingsWindow
{
Dashboard = 0,
Overview,
AlwaysOnTop,
Overview = 0,
Awake,
ColorPicker,
CmdNotFound,
FancyZones,
FileLocksmith,
Run,
ImageResizer,
KBM,
MouseUtils,
MouseWithoutBorders,
Peek,
PowerAccent,
PowerLauncher,
PowerPreview,
PowerRename,
FileExplorer,
ShortcutGuide,
Hosts,
MeasureTool,
PowerOCR,
Workspaces,
RegistryPreview,
CropAndLock,
EnvironmentVariables,
Dashboard,
AdvancedPaste,
NewPlus,
Workspaces,
CmdPal,
ZoomIt,
}
@@ -48,22 +39,14 @@ namespace Common.UI
{
switch (value)
{
case SettingsWindow.Dashboard:
return "Dashboard";
case SettingsWindow.Overview:
return "Overview";
case SettingsWindow.AlwaysOnTop:
return "AlwaysOnTop";
case SettingsWindow.Awake:
return "Awake";
case SettingsWindow.ColorPicker:
return "ColorPicker";
case SettingsWindow.CmdNotFound:
return "CmdNotFound";
case SettingsWindow.FancyZones:
return "FancyZones";
case SettingsWindow.FileLocksmith:
return "FileLocksmith";
case SettingsWindow.Run:
return "Run";
case SettingsWindow.ImageResizer:
@@ -72,16 +55,6 @@ namespace Common.UI
return "KBM";
case SettingsWindow.MouseUtils:
return "MouseUtils";
case SettingsWindow.MouseWithoutBorders:
return "MouseWithoutBorders";
case SettingsWindow.Peek:
return "Peek";
case SettingsWindow.PowerAccent:
return "PowerAccent";
case SettingsWindow.PowerLauncher:
return "PowerLauncher";
case SettingsWindow.PowerPreview:
return "PowerPreview";
case SettingsWindow.PowerRename:
return "PowerRename";
case SettingsWindow.FileExplorer:
@@ -94,18 +67,18 @@ namespace Common.UI
return "MeasureTool";
case SettingsWindow.PowerOCR:
return "PowerOcr";
case SettingsWindow.Workspaces:
return "Workspaces";
case SettingsWindow.RegistryPreview:
return "RegistryPreview";
case SettingsWindow.CropAndLock:
return "CropAndLock";
case SettingsWindow.EnvironmentVariables:
return "EnvironmentVariables";
case SettingsWindow.Dashboard:
return "Dashboard";
case SettingsWindow.AdvancedPaste:
return "AdvancedPaste";
case SettingsWindow.NewPlus:
return "NewPlus";
case SettingsWindow.Workspaces:
return "Workspaces";
case SettingsWindow.CmdPal:
return "CmdPal";
case SettingsWindow.ZoomIt:

View File

@@ -21,7 +21,7 @@ public static partial class Kernel32
out int pBytesReturned,
IntPtr lpOverlapped);
[LibraryImport("kernel32.dll", SetLastError = true, StringMarshalling = StringMarshalling.Utf16, EntryPoint = "CreateFileW")]
[LibraryImport("kernel32.dll", SetLastError = true, StringMarshalling = StringMarshalling.Utf16)]
public static partial int CreateFile(
string lpFileName,
FileAccessType dwDesiredAccess,

View File

@@ -4,9 +4,18 @@
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Xml.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Appium;
using OpenQA.Selenium.Appium.Windows;
using Windows.Devices.Display.Core;
using Windows.Foundation.Metadata;
using static Microsoft.PowerToys.UITest.UITestBase.NativeMethods;
using static Microsoft.PowerToys.UITest.WindowHelper;
namespace Microsoft.PowerToys.UITest
{

View File

@@ -11,7 +11,7 @@ using System.Threading.Tasks;
namespace Microsoft.PowerToys.UITest
{
public static class WindowHelper
internal static class WindowHelper
{
internal const string AdministratorPrefix = "Administrator: ";

View File

@@ -16,7 +16,7 @@
// project, where bugs will be filed
"org": "microsoft",
"project": "OS",
"AssignedTo": "leilzh@microsoft.com",
"AssignedTo": "PowerToys@microsoft.com",
"AreaPath": "OS\\Windows Client and Services\\WinPD\\DFX-Developer Fundamentals and Experiences\\DEFT\\SALT",
"IterationPath": "OS\\Future"
},

View File

@@ -16,7 +16,7 @@
// project, where bugs will be filed
"org": "microsoft",
"project": "OS",
"AssignedTo": "leilzh@microsoft.com",
"AssignedTo": "PowerToys@microsoft.com",
"AreaPath": "OS\\Windows Client and Services\\WinPD\\DFX-Developer Fundamentals and Experiences\\DEFT\\SALT",
"IterationPath": "OS\\Future"
},
@@ -57,7 +57,7 @@
// project, where bugs will be filed
"org": "microsoft",
"project": "OS",
"AssignedTo": "leilzh@microsoft.com",
"AssignedTo": "PowerToys@microsoft.com",
"AreaPath": "OS\\Windows Client and Services\\WinPD\\DFX-Developer Fundamentals and Experiences\\DEFT\\SALT",
"IterationPath": "OS\\Future"
},
@@ -98,7 +98,7 @@
// project, where bugs will be filed
"org": "microsoft",
"project": "OS",
"AssignedTo": "leilzh@microsoft.com",
"AssignedTo": "PowerToys@microsoft.com",
"AreaPath": "OS\\Windows Client and Services\\WinPD\\DFX-Developer Fundamentals and Experiences\\DEFT\\SALT",
"IterationPath": "OS\\Future"
},
@@ -139,7 +139,7 @@
// project, where bugs will be filed
"org": "microsoft",
"project": "OS",
"AssignedTo": "leilzh@microsoft.com",
"AssignedTo": "PowerToys@microsoft.com",
"AreaPath": "OS\\Windows Client and Services\\WinPD\\DFX-Developer Fundamentals and Experiences\\DEFT\\SALT",
"IterationPath": "OS\\Future"
},

View File

@@ -1,4 +1,4 @@
<Page
<Page
x:Class="WorkspacesEditor.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
@@ -172,7 +172,7 @@
VerticalContentAlignment="Stretch"
VerticalScrollBarVisibility="Auto"
Visibility="{Binding IsWorkspacesViewEmpty, Mode=OneWay, Converter={StaticResource BooleanToInvertedVisibilityConverter}, UpdateSourceTrigger=PropertyChanged}">
<ItemsControl x:Name="WorkspacesItemsControl" ItemsSource="{Binding WorkspacesView, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}">
<ItemsControl ItemsSource="{Binding WorkspacesView, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel
@@ -235,10 +235,7 @@
Grid.Column="1"
Margin="12,12,12,12"
Orientation="Vertical">
<StackPanel
x:Name="WorkspaceActionGroup"
HorizontalAlignment="Right"
Orientation="Horizontal">
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
<Button
x:Name="MoreButton"
HorizontalAlignment="Right"
@@ -251,8 +248,7 @@
</Button>
<Popup
AllowsTransparency="True"
Closed="PopupClosed"
IsOpen="{Binding IsPopupVisible, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
IsOpen="{Binding IsPopupVisible, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
Placement="Left"
PlacementTarget="{Binding ElementName=MoreButton}"
StaysOpen="False">

View File

@@ -4,8 +4,7 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using ManagedCommon;
using WorkspacesEditor.Models;
using WorkspacesEditor.ViewModels;
@@ -43,28 +42,17 @@ namespace WorkspacesEditor
e.Handled = true;
Button button = sender as Button;
Project selectedProject = button.DataContext as Project;
selectedProject.IsPopupVisible = false;
_mainViewModel.DeleteProject(selectedProject);
}
private void MoreButton_Click(object sender, RoutedEventArgs e)
{
_mainViewModel.CloseAllPopups();
e.Handled = true;
Button button = sender as Button;
Project project = button.DataContext as Project;
project.IsPopupVisible = true;
}
private void PopupClosed(object sender, object e)
{
if (sender is Popup p && p.DataContext is Project proj)
{
proj.IsPopupVisible = false;
}
}
private void LaunchButton_Click(object sender, RoutedEventArgs e)
{
e.Handled = true;

View File

@@ -437,11 +437,7 @@ namespace WorkspacesEditor.ViewModels
private void RunSnapshotTool(bool isExistingProjectLaunched)
{
Process process = new Process();
var exeDir = Path.GetDirectoryName(Environment.ProcessPath);
var snapshotUtilsPath = Path.Combine(exeDir, "PowerToys.WorkspacesSnapshotTool.exe");
process.StartInfo = new ProcessStartInfo(snapshotUtilsPath);
process.StartInfo = new ProcessStartInfo(@".\PowerToys.WorkspacesSnapshotTool.exe");
process.StartInfo.CreateNoWindow = true;
process.StartInfo.Arguments = isExistingProjectLaunched ? $"{(int)InvokePoint.LaunchAndEdit}" : string.Empty;

View File

@@ -51,8 +51,6 @@
MouseLeave="AppBorder_MouseLeave">
<Expander
Margin="0,0,20,0"
AutomationProperties.AutomationId="{Binding AppName}"
AutomationProperties.Name="{Binding AppName}"
FlowDirection="RightToLeft"
IsEnabled="{Binding IsIncluded, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
IsExpanded="{Binding IsExpanded, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
@@ -401,11 +399,7 @@
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ItemsControl
x:Name="CapturedAppList"
AutomationProperties.Name="Captured Application List"
ItemTemplateSelector="{StaticResource AppListDataTemplateSelector}"
ItemsSource="{Binding ApplicationsListed, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" />
<ItemsControl ItemTemplateSelector="{StaticResource AppListDataTemplateSelector}" ItemsSource="{Binding ApplicationsListed, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</StackPanel>
</ScrollViewer>

View File

@@ -1,605 +0,0 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Diagnostics;
using Microsoft.PowerToys.UITest;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace WorkspacesEditorUITest;
[TestClass]
[Ignore("not stable")]
public class WorkspacesEditingPageTests : WorkspacesUiAutomationBase
{
public WorkspacesEditingPageTests()
: base()
{
}
[TestMethod("WorkspacesEditingPage.RemoveApp")]
[TestCategory("Workspaces Editing Page UI")]
public void TestRemoveAppFromWorkspace()
{
// Find app list
var appList = Find<Custom>("AppList");
var initialAppCount = appList.FindAll<Custom>(By.ClassName("AppItem")).Count;
if (initialAppCount == 0)
{
Assert.Inconclusive("No apps in workspace to remove");
return;
}
// Remove first app
var firstApp = appList.FindAll<Custom>(By.ClassName("AppItem"))[0];
var appName = firstApp.GetAttribute("Name");
var removeButton = firstApp.Find<Button>("Remove");
removeButton.Click();
Thread.Sleep(500);
// Verify app removed from list
var finalAppCount = appList.FindAll<Custom>(By.ClassName("AppItem")).Count;
Assert.AreEqual(initialAppCount - 1, finalAppCount, "App should be removed from list");
// Verify preview updated
var previewPane = Find<Pane>("Preview");
var windowPreviews = previewPane.FindAll<Custom>(By.ClassName("WindowPreview"));
Assert.AreEqual(finalAppCount, windowPreviews.Count, "Preview should show correct number of windows");
}
[TestMethod("WorkspacesEditingPage.RemoveAndAddBackApp")]
[TestCategory("Workspaces Editing Page UI")]
public void TestRemoveAndAddBackApp()
{
// Find app list
var appList = Find<Custom>("AppList");
var apps = appList.FindAll<Custom>(By.ClassName("AppItem"));
if (apps.Count == 0)
{
Assert.Inconclusive("No apps in workspace to test");
return;
}
var firstApp = apps[0];
var appName = firstApp.GetAttribute("Name");
// Remove app
var removeButton = firstApp.Find<Button>("Remove");
removeButton.Click();
Thread.Sleep(500);
// Verify removed app shows in "removed apps" section
Assert.IsTrue(Has<Button>("Add back"), "Should have 'Add back' button for removed apps");
// Add back the app
var addBackButton = Find<Button>("Add back");
addBackButton.Click();
Thread.Sleep(500);
// Verify app is back in the list
var restoredApp = appList.Find<Custom>(By.Name(appName), timeoutMS: 2000);
Assert.IsNotNull(restoredApp, "App should be restored to the list");
// Verify preview updated
var previewPane = Find<Pane>("Preview");
var windowPreviews = previewPane.FindAll<Custom>(By.ClassName("WindowPreview"));
var currentAppCount = appList.FindAll<Custom>(By.ClassName("AppItem")).Count;
Assert.AreEqual(currentAppCount, windowPreviews.Count, "Preview should show all windows again");
}
[TestMethod("WorkspacesEditingPage.SetAppMinimized")]
[TestCategory("Workspaces Editing Page UI")]
public void TestSetAppMinimized()
{
// Find first app
var appList = Find<Custom>("AppList");
var apps = appList.FindAll<Custom>(By.ClassName("AppItem"));
if (apps.Count == 0)
{
Assert.Inconclusive("No apps in workspace to test");
return;
}
var firstApp = apps[0];
// Find and toggle minimized checkbox
var minimizedCheckbox = firstApp.Find<CheckBox>("Minimized");
bool wasMinimized = minimizedCheckbox.IsChecked;
minimizedCheckbox.Click();
Thread.Sleep(500);
// Verify state changed
Assert.AreNotEqual(wasMinimized, minimizedCheckbox.IsChecked, "Minimized state should toggle");
// Verify preview reflects the change
var previewPane = Find<Pane>("Preview");
var windowPreviews = previewPane.FindAll<Custom>(By.ClassName("WindowPreview"));
// The first window preview should indicate minimized state
if (minimizedCheckbox.IsChecked && windowPreviews.Count > 0)
{
var firstPreview = windowPreviews[0];
var opacity = firstPreview.GetAttribute("Opacity");
// Minimized windows might have reduced opacity or other visual indicator
Assert.IsNotNull(opacity, "Minimized window should have visual indication in preview");
}
}
[TestMethod("WorkspacesEditingPage.SetAppMaximized")]
[TestCategory("Workspaces Editing Page UI")]
public void TestSetAppMaximized()
{
// Find first app
var appList = Find<Custom>("AppList");
var apps = appList.FindAll<Custom>(By.ClassName("AppItem"));
if (apps.Count == 0)
{
Assert.Inconclusive("No apps in workspace to test");
return;
}
var firstApp = apps[0];
// Find and toggle maximized checkbox
var maximizedCheckbox = firstApp.Find<CheckBox>("Maximized");
bool wasMaximized = maximizedCheckbox.IsChecked;
maximizedCheckbox.Click();
Thread.Sleep(500);
// Verify state changed
Assert.AreNotEqual(wasMaximized, maximizedCheckbox.IsChecked, "Maximized state should toggle");
// Verify preview reflects the change
var previewPane = Find<Pane>("Preview");
if (maximizedCheckbox.IsChecked)
{
// Maximized window should fill the preview area
var windowPreviews = previewPane.FindAll<Custom>(By.ClassName("WindowPreview"));
if (windowPreviews.Count > 0)
{
var firstPreview = windowPreviews[0];
// Check if preview shows maximized state
var width = firstPreview.GetAttribute("Width");
var height = firstPreview.GetAttribute("Height");
Assert.IsNotNull(width, "Maximized window should have width in preview");
Assert.IsNotNull(height, "Maximized window should have height in preview");
}
}
}
[TestMethod("WorkspacesEditingPage.LaunchAsAdmin")]
[TestCategory("Workspaces Editing Page UI")]
public void TestSetLaunchAsAdmin()
{
// Find app that supports admin launch
var appList = Find<Custom>("AppList");
var apps = appList.FindAll<Custom>(By.ClassName("AppItem"));
bool foundAdminCapableApp = false;
foreach (var app in apps)
{
try
{
var adminCheckbox = app.Find<CheckBox>("Launch as admin", timeoutMS: 1000);
if (adminCheckbox != null && adminCheckbox.IsChecked)
{
foundAdminCapableApp = true;
bool wasAdmin = adminCheckbox.IsChecked;
adminCheckbox.Click();
Thread.Sleep(500);
// Verify state changed
Assert.AreNotEqual(wasAdmin, adminCheckbox.IsChecked, "Admin launch state should toggle");
break;
}
}
catch
{
// This app doesn't support admin launch
continue;
}
}
if (!foundAdminCapableApp)
{
Assert.Inconclusive("No apps in workspace support admin launch");
}
}
[TestMethod("WorkspacesEditingPage.AddCLIArgs")]
[TestCategory("Workspaces Editing Page UI")]
public void TestAddCommandLineArguments()
{
// Find first app
var appList = Find<Custom>("AppList");
var apps = appList.FindAll<Custom>(By.ClassName("AppItem"));
if (apps.Count == 0)
{
Assert.Inconclusive("No apps in workspace to test");
return;
}
var firstApp = apps[0];
// Find CLI args textbox
var cliArgsTextBox = firstApp.Find<TextBox>("Command line arguments", timeoutMS: 2000);
if (cliArgsTextBox == null)
{
Assert.Inconclusive("App does not support command line arguments");
return;
}
// Add test arguments
string testArgs = "--test-arg value";
cliArgsTextBox.SetText(testArgs);
Thread.Sleep(500);
// Verify arguments were entered
Assert.AreEqual(testArgs, cliArgsTextBox.Text, "Command line arguments should be set");
}
[TestMethod("WorkspacesEditingPage.ChangeAppPosition")]
[TestCategory("Workspaces Editing Page UI")]
public void TestManuallyChangeAppPosition()
{
// Find first app
var appList = Find<Custom>("AppList");
var apps = appList.FindAll<Custom>(By.ClassName("AppItem"));
if (apps.Count == 0)
{
Assert.Inconclusive("No apps in workspace to test");
return;
}
var firstApp = apps[0];
// Find position controls
var xPositionBox = firstApp.Find<TextBox>("X position", timeoutMS: 2000);
var yPositionBox = firstApp.Find<TextBox>("Y position", timeoutMS: 2000);
if (xPositionBox == null || yPositionBox == null)
{
// Try alternate approach with spinners
var positionSpinners = firstApp.FindAll<Custom>(By.ClassName("SpinBox"));
if (positionSpinners.Count >= 2)
{
xPositionBox = positionSpinners[0].Find<TextBox>(By.ClassName("TextBox"));
yPositionBox = positionSpinners[1].Find<TextBox>(By.ClassName("TextBox"));
}
}
if (xPositionBox != null && yPositionBox != null)
{
// Change position
xPositionBox.SetText("200");
Thread.Sleep(500);
yPositionBox.SetText("150");
Thread.Sleep(500);
// Verify preview updated
var previewPane = Find<Pane>("Preview");
var windowPreviews = previewPane.FindAll<Custom>(By.ClassName("WindowPreview"));
Assert.IsTrue(windowPreviews.Count > 0, "Preview should show window at new position");
}
else
{
Assert.Inconclusive("Could not find position controls");
}
}
[TestMethod("WorkspacesEditingPage.ChangeWorkspaceName")]
[TestCategory("Workspaces Editing Page UI")]
public void TestChangeWorkspaceName()
{
// Find workspace name textbox
var nameTextBox = Find<TextBox>("Workspace name");
string originalName = nameTextBox.Text;
// Change name
string newName = "Renamed_Workspace_" + DateTime.Now.Ticks;
nameTextBox.SetText(newName);
Thread.Sleep(500);
// Save changes
var saveButton = Find<Button>("Save");
saveButton.Click();
Thread.Sleep(1000);
// Verify we're back at main list
Assert.IsTrue(Has<Custom>("WorkspacesList"), "Should return to main list after saving");
// Verify workspace was renamed
var workspacesList = Find<Custom>("WorkspacesList");
var renamedWorkspace = workspacesList.Find<Custom>(By.Name(newName), timeoutMS: 2000);
Assert.IsNotNull(renamedWorkspace, "Workspace should be renamed in the list");
}
[TestMethod("WorkspacesEditingPage.SaveAndCancelWork")]
[TestCategory("Workspaces Editing Page UI")]
public void TestSaveAndCancelButtons()
{
// Make a change
var nameTextBox = Find<TextBox>("Workspace name");
string originalName = nameTextBox.Text;
string tempName = originalName + "_temp";
nameTextBox.SetText(tempName);
Thread.Sleep(500);
// Test Cancel button
var cancelButton = Find<Button>("Cancel");
cancelButton.Click();
Thread.Sleep(1000);
// Verify returned to main list without saving
Assert.IsTrue(Has<Custom>("WorkspacesList"), "Should return to main list");
// Go back to editing
var workspacesList = Find<Custom>("WorkspacesList");
var workspace = workspacesList.FindAll<Custom>(By.ClassName("WorkspaceItem"))[0];
workspace.Click();
Thread.Sleep(1000);
// Verify name wasn't changed
nameTextBox = Find<TextBox>("Workspace name");
Assert.AreEqual(originalName, nameTextBox.Text, "Name should not be changed after cancel");
// Now test Save button
nameTextBox.SetText(tempName);
Thread.Sleep(500);
var saveButton = Find<Button>("Save");
saveButton.Click();
Thread.Sleep(1000);
// Verify saved
workspacesList = Find<Custom>("WorkspacesList");
var savedWorkspace = workspacesList.Find<Custom>(By.Name(tempName), timeoutMS: 2000);
Assert.IsNotNull(savedWorkspace, "Workspace should be saved with new name");
}
[TestMethod("WorkspacesEditingPage.NavigateWithoutSaving")]
[TestCategory("Workspaces Editing Page UI")]
public void TestNavigateToMainPageWithoutSaving()
{
// Make a change
var nameTextBox = Find<TextBox>("Workspace name");
string originalName = nameTextBox.Text;
nameTextBox.SetText(originalName + "_unsaved");
Thread.Sleep(500);
// Click on "Workspaces" navigation/breadcrumb
if (Has<NavigationViewItem>("Workspaces", timeoutMS: 1000))
{
var workspacesNav = Find<NavigationViewItem>("Workspaces");
workspacesNav.Click();
Thread.Sleep(1000);
}
else if (Has<HyperlinkButton>("Workspaces", timeoutMS: 1000))
{
var workspacesBreadcrumb = Find<HyperlinkButton>("Workspaces");
workspacesBreadcrumb.Click();
Thread.Sleep(1000);
}
// If there's a confirmation dialog, handle it
if (Has<Button>("Discard", timeoutMS: 1000))
{
Find<Button>("Discard").Click();
Thread.Sleep(500);
}
// Verify returned to main list
Assert.IsTrue(Has<Custom>("WorkspacesList"), "Should return to main list");
// Verify changes weren't saved
var workspacesList = Find<Custom>("WorkspacesList");
var unsavedWorkspace = workspacesList.Find<Custom>(By.Name(originalName + "_unsaved"), timeoutMS: 1000);
Assert.IsNull(unsavedWorkspace, "Unsaved changes should not persist");
}
[TestMethod("WorkspacesEditingPage.CreateDesktopShortcut")]
[TestCategory("Workspaces Editing Page UI")]
public void TestCreateDesktopShortcut()
{
// Find desktop shortcut checkbox
var shortcutCheckbox = Find<CheckBox>("Create desktop shortcut");
// Get desktop path
string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
// Get workspace name to check for shortcut
var nameTextBox = Find<TextBox>("Workspace name");
string workspaceName = nameTextBox.Text;
string shortcutPath = Path.Combine(desktopPath, $"{workspaceName}.lnk");
// Clean up any existing shortcut
if (File.Exists(shortcutPath))
{
File.Delete(shortcutPath);
Thread.Sleep(500);
}
// Check the checkbox
if (!shortcutCheckbox.IsChecked)
{
shortcutCheckbox.Click();
Thread.Sleep(500);
}
// Save
var saveButton = Find<Button>("Save");
saveButton.Click();
Thread.Sleep(2000); // Give time for shortcut creation
// Verify shortcut was created
Assert.IsTrue(File.Exists(shortcutPath), "Desktop shortcut should be created");
// Clean up
if (File.Exists(shortcutPath))
{
File.Delete(shortcutPath);
}
}
[TestMethod("WorkspacesEditingPage.DesktopShortcutState")]
[TestCategory("Workspaces Editing Page UI")]
public void TestDesktopShortcutCheckboxState()
{
// Get workspace name
var nameTextBox = Find<TextBox>("Workspace name");
string workspaceName = nameTextBox.Text;
string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string shortcutPath = Path.Combine(desktopPath, $"{workspaceName}.lnk");
// Find checkbox
var shortcutCheckbox = Find<CheckBox>("Create desktop shortcut");
// Test 1: When shortcut exists
if (!File.Exists(shortcutPath))
{
// Create shortcut first
if (!shortcutCheckbox.IsChecked)
{
shortcutCheckbox.Click();
Thread.Sleep(500);
}
Find<Button>("Save").Click();
Thread.Sleep(2000);
// Navigate back to editing
NavigateToEditingPage();
}
shortcutCheckbox = Find<CheckBox>("Create desktop shortcut");
Assert.IsTrue(shortcutCheckbox.IsChecked, "Checkbox should be checked when shortcut exists");
// Test 2: Remove shortcut
if (File.Exists(shortcutPath))
{
File.Delete(shortcutPath);
Thread.Sleep(500);
}
// Re-navigate to refresh state
Find<Button>("Cancel").Click();
Thread.Sleep(1000);
NavigateToEditingPage();
shortcutCheckbox = Find<CheckBox>("Create desktop shortcut");
Assert.IsFalse(shortcutCheckbox.IsChecked, "Checkbox should be unchecked when shortcut doesn't exist");
}
[TestMethod("WorkspacesEditingPage.LaunchAndEdit")]
[TestCategory("Workspaces Editing Page UI")]
public void TestLaunchAndEditCapture()
{
// Find Launch and Edit button
var launchEditButton = Find<Button>("Launch and Edit");
launchEditButton.Click();
Thread.Sleep(3000); // Wait for apps to launch
// Open a new application
Process.Start("calc.exe");
Thread.Sleep(2000);
// Click Capture
var captureButton = Find<Button>("Capture");
captureButton.Click();
Thread.Sleep(2000);
// Verify new app was added
var appList = Find<Custom>("AppList");
var apps = appList.FindAll<Custom>(By.ClassName("AppItem"));
bool foundCalculator = false;
foreach (var app in apps)
{
var appName = app.GetAttribute("Name");
if (appName.Contains("Calculator", StringComparison.OrdinalIgnoreCase))
{
foundCalculator = true;
break;
}
}
Assert.IsTrue(foundCalculator, "Newly opened Calculator should be captured and added");
// Clean up
foreach (var process in Process.GetProcessesByName("CalculatorApp"))
{
process.Kill();
}
foreach (var process in Process.GetProcessesByName("Calculator"))
{
process.Kill();
}
}
// Helper methods
private void NavigateToEditingPage()
{
// Ensure we have at least one workspace
if (!Has<Custom>("WorkspacesList", timeoutMS: 1000))
{
CreateTestWorkspace();
}
// Click on first workspace to edit
var workspacesList = Find<Custom>("WorkspacesList");
var workspaceItems = workspacesList.FindAll<Custom>(By.ClassName("WorkspaceItem"));
if (workspaceItems.Count == 0)
{
CreateTestWorkspace();
workspaceItems = workspacesList.FindAll<Custom>(By.ClassName("WorkspaceItem"));
}
workspaceItems[0].Click();
Thread.Sleep(1000);
}
private void CreateTestWorkspace()
{
// Open a test app
Process.Start("notepad.exe");
Thread.Sleep(1000);
// Create workspace
var createButton = Find<Button>("Create Workspace");
createButton.Click();
Thread.Sleep(1000);
// Capture
var captureButton = Find<Button>("Capture");
captureButton.Click();
Thread.Sleep(2000);
// Save with default name
var saveButton = Find<Button>("Save");
saveButton.Click();
Thread.Sleep(1000);
// Close test app
foreach (var process in Process.GetProcessesByName("notepad"))
{
process.Kill();
}
}
}

View File

@@ -8,10 +8,10 @@ using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace WorkspacesEditorUITest;
[TestClass]
public class WorkspacesEditorTests : WorkspacesUiAutomationBase
public class WorkspacesEditorTests : UITestBase
{
public WorkspacesEditorTests()
: base()
: base(PowerToysModule.Workspaces, WindowSize.Medium)
{
}
@@ -21,217 +21,4 @@ public class WorkspacesEditorTests : WorkspacesUiAutomationBase
{
Assert.IsTrue(this.Has<Button>("Create Workspace"), "Should have create workspace button");
}
/*
[TestMethod("WorkspacesEditor.Editor.NewWorkspaceAppearsInList")]
[TestCategory("Workspaces UI")]
public void TestNewWorkspaceAppearsInListAfterCapture()
{
// Open test application
OpenNotepad();
Thread.Sleep(2000);
// Create workspace
var createButton = Find<Button>("Create Workspace");
createButton.Click();
Thread.Sleep(1000);
// Capture
var captureButton = Find<Button>("Capture");
captureButton.Click();
Thread.Sleep(2000);
// Save workspace
var saveButton = Find<Button>("Save");
saveButton.Click();
Thread.Sleep(1000);
// Verify workspace appears in list
var workspacesList = Find<Custom>("WorkspacesList");
var workspaceItems = workspacesList.FindAll<Custom>(By.ClassName("WorkspaceItem"));
Assert.IsTrue(workspaceItems.Count > 0, "New workspace should appear in the list");
CloseNotepad();
}
[TestMethod("WorkspacesEditor.Editor.CancelCaptureDoesNotAddWorkspace")]
[TestCategory("Workspaces UI")]
public void TestCancelCaptureDoesNotAddWorkspace()
{
// Count existing workspaces
var workspacesList = Find<Custom>("WorkspacesList");
var initialCount = workspacesList.FindAll<Custom>(By.ClassName("WorkspaceItem")).Count;
// Create workspace
var createButton = Find<Button>("Create Workspace");
createButton.Click();
Thread.Sleep(1000);
// Cancel
var cancelButton = Find<Button>("Cancel");
cancelButton.Click();
Thread.Sleep(1000);
// Verify count hasn't changed
var finalCount = workspacesList.FindAll<Custom>(By.ClassName("WorkspaceItem")).Count;
Assert.AreEqual(initialCount, finalCount, "Workspace count should not change after canceling");
}
[TestMethod("WorkspacesEditor.Editor.SearchFiltersWorkspaces")]
[TestCategory("Workspaces UI")]
public void TestSearchFiltersWorkspaces()
{
// Create test workspaces first
CreateTestWorkspace("TestWorkspace1");
CreateTestWorkspace("TestWorkspace2");
CreateTestWorkspace("DifferentName");
// Find search box
var searchBox = Find<TextBox>("Search");
searchBox.SetText("TestWorkspace");
Thread.Sleep(1000);
// Verify filtered results
var workspacesList = Find<Custom>("WorkspacesList");
var visibleItems = workspacesList.FindAll<Custom>(By.ClassName("WorkspaceItem"));
// Should only show items matching "TestWorkspace"
Assert.IsTrue(visibleItems.Count >= 2, "Should show at least 2 TestWorkspace items");
// Clear search
searchBox.SetText(string.Empty);
Thread.Sleep(500);
}
[TestMethod("WorkspacesEditor.Editor.SortByWorks")]
[TestCategory("Workspaces UI")]
public void TestSortByFunctionality()
{
// Find sort dropdown
var sortDropdown = Find<ComboBox>("SortBy");
sortDropdown.Click();
Thread.Sleep(500);
// Select different sort options
var sortOptions = FindAll<Custom>(By.ClassName("ComboBoxItem"));
if (sortOptions.Count > 1)
{
sortOptions[1].Click(); // Select second option
Thread.Sleep(1000);
// Verify list is updated (we can't easily verify sort order in UI tests)
var workspacesList = Find<Custom>("WorkspacesList");
Assert.IsNotNull(workspacesList, "Workspaces list should still be visible after sorting");
}
}
[TestMethod("WorkspacesEditor.Editor.SortByPersists")]
[TestCategory("Workspaces UI")]
public void TestSortByPersistsAfterRestart()
{
// Set sort option
var sortDropdown = Find<ComboBox>("SortBy");
sortDropdown.Click();
Thread.Sleep(500);
var sortOptions = FindAll<Custom>(By.ClassName("ComboBoxItem"));
string selectedOption = string.Empty;
if (sortOptions.Count > 1)
{
sortOptions[1].Click(); // Select second option
selectedOption = sortDropdown.Text;
Thread.Sleep(1000);
}
// Restart editor
RestartScopeExe();
Thread.Sleep(2000);
// Verify sort option persisted
sortDropdown = Find<ComboBox>("SortBy");
Assert.AreEqual(selectedOption, sortDropdown.Text, "Sort option should persist after restart");
}
[TestMethod("WorkspacesEditor.Editor.RemoveWorkspace")]
[TestCategory("Workspaces UI")]
public void TestRemoveWorkspace()
{
// Create a test workspace
CreateTestWorkspace("WorkspaceToRemove");
// Find the workspace in the list
var workspacesList = Find<Custom>("WorkspacesList");
var workspaceItem = workspacesList.Find<Custom>(By.Name("WorkspaceToRemove"));
// Click remove button
var removeButton = workspaceItem.Find<Button>("Remove");
removeButton.Click();
Thread.Sleep(1000);
// Confirm removal if dialog appears
if (Has<Button>("Yes"))
{
Find<Button>("Yes").Click();
Thread.Sleep(1000);
}
// Verify workspace is removed
Assert.IsFalse(Has(By.Name("WorkspaceToRemove")), "Workspace should be removed from list");
}
[TestMethod("WorkspacesEditor.Editor.EditOpensEditingPage")]
[TestCategory("Workspaces UI")]
public void TestEditOpensEditingPage()
{
// Create a test workspace if none exist
if (!Has<Custom>("WorkspacesList"))
{
CreateTestWorkspace("TestWorkspace");
}
// Find first workspace
var workspacesList = Find<Custom>("WorkspacesList");
var workspaceItem = workspacesList.FindAll<Custom>(By.ClassName("WorkspaceItem"))[0];
// Click edit button
var editButton = workspaceItem.Find<Button>("Edit");
editButton.Click();
Thread.Sleep(1000);
// Verify editing page opened
Assert.IsTrue(Has<Button>("Save"), "Should have Save button on editing page");
Assert.IsTrue(Has<Button>("Cancel"), "Should have Cancel button on editing page");
// Go back
Find<Button>("Cancel").Click();
Thread.Sleep(1000);
}
[TestMethod("WorkspacesEditor.Editor.ClickWorkspaceOpensEditingPage")]
[TestCategory("Workspaces UI")]
public void TestClickWorkspaceOpensEditingPage()
{
// Create a test workspace if none exist
if (!Has<Custom>("WorkspacesList"))
{
CreateTestWorkspace("TestWorkspace");
}
// Find first workspace
var workspacesList = Find<Custom>("WorkspacesList");
var workspaceItem = workspacesList.FindAll<Custom>(By.ClassName("WorkspaceItem"))[0];
// Click on the workspace item itself
workspaceItem.Click();
Thread.Sleep(1000);
// Verify editing page opened
Assert.IsTrue(Has<Button>("Save"), "Should have Save button on editing page");
Assert.IsTrue(Has<Button>("Cancel"), "Should have Cancel button on editing page");
// Go back
Find<Button>("Cancel").Click();
Thread.Sleep(1000);
}
*/
}

View File

@@ -23,7 +23,6 @@
<ItemGroup>
<ProjectReference Include="..\..\..\common\UITestAutomation\UITestAutomation.csproj" />
<ProjectReference Include="..\WorkspacesEditor\WorkspacesEditor.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,100 +0,0 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Microsoft.PowerToys.UITest;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace WorkspacesEditorUITest;
[TestClass]
[Ignore("NOT STABLE")]
public class WorkspacesLauncherTest : WorkspacesUiAutomationBase
{
public WorkspacesLauncherTest()
: base()
{
}
[TestMethod("WorkspacesEditor.Launcher.LaunchFromEditor")]
[TestCategory("Workspaces UI")]
public void TestLaunchWorkspaceFromEditor()
{
ClearWorkspaces();
var uuid = Guid.NewGuid().ToString("N").Substring(0, 8);
CreateTestWorkspace(uuid);
CloseNotepad();
var launchButton = Find<Button>(By.Name("Launch"));
launchButton.Click();
Task.Delay(2000).Wait();
var processes = System.Diagnostics.Process.GetProcessesByName("notepad");
Assert.IsTrue(processes?.Length > 0);
}
[TestMethod("WorkspacesEditor.Launcher.CancelLaunch")]
[TestCategory("Workspaces UI")]
public void TestCancelLaunch()
{
// Create workspace with multiple apps
CreateWorkspaceWithApps();
// Launch workspace
var workspacesList = Find<Custom>("WorkspacesList");
var workspaceItem = workspacesList.FindAll<Custom>(By.ClassName("WorkspaceItem"))[0];
var launchButton = workspaceItem.Find<Button>("Launch");
launchButton.Click();
Thread.Sleep(1000);
// Cancel launch
if (Has<Button>("Cancel launch"))
{
Find<Button>("Cancel launch").Click();
Thread.Sleep(1000);
// Verify launcher closed
Assert.IsFalse(Has<Window>("Workspaces Launcher"), "Launcher window should close after cancel");
}
// Close any apps that may have launched
CloseTestApplications();
}
[TestMethod("WorkspacesEditor.Launcher.DismissKeepsLaunching")]
[TestCategory("Workspaces UI")]
public void TestDismissKeepsAppsLaunching()
{
// Create workspace with apps
CreateWorkspaceWithApps();
// Launch workspace
var workspacesList = Find<Custom>("WorkspacesList");
var workspaceItem = workspacesList.FindAll<Custom>(By.ClassName("WorkspaceItem"))[0];
var launchButton = workspaceItem.Find<Button>("Launch");
launchButton.Click();
Thread.Sleep(1000);
// Dismiss launcher
if (Has<Button>("Dismiss"))
{
Find<Button>("Dismiss").Click();
Thread.Sleep(1000);
// Verify launcher closed but apps continue launching
Assert.IsFalse(Has<Window>("Workspaces Launcher"), "Launcher window should close after dismiss");
// Wait for apps to finish launching
Thread.Sleep(3000);
// Verify apps launched (notepad should be open)
Assert.IsTrue(WindowHelper.IsWindowOpen("Notepad"), "Apps should continue launching after dismiss");
}
// Close launched apps
CloseTestApplications();
}
}

View File

@@ -1,195 +0,0 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Microsoft.PowerToys.UITest;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace WorkspacesEditorUITest;
[TestClass]
public class WorkspacesSettingsTests : UITestBase
{
public WorkspacesSettingsTests()
: base(PowerToysModule.PowerToysSettings, WindowSize.Medium)
{
}
[TestMethod("WorkspacesSettings.LaunchFromSettings")]
[TestCategory("Workspaces Settings UI")]
public void TestLaunchEditorFromSettingsPage()
{
GoToSettingsPageAndEnable();
}
[TestMethod("WorkspacesSettings.ActivationShortcut")]
[TestCategory("Workspaces Settings UI")]
public void TestActivationShortcutCustomization()
{
GoToSettingsPageAndEnable();
// Find the activation shortcut control
var shortcutButton = Find<Button>("Activation shortcut");
Assert.IsNotNull(shortcutButton, "Activation shortcut control should exist");
// Test customizing the shortcut
shortcutButton.Click();
Task.Delay(1000).Wait();
// Send new key combination (Win+Ctrl+W)
SendKeys(Key.Win, Key.Ctrl, Key.W);
var saveButton = Find<Button>("Save");
Assert.IsNotNull(saveButton, "Save button should exist after editing shortcut");
saveButton.Click();
var helpText = shortcutButton.HelpText;
Assert.AreEqual("Win + Ctrl + W", helpText, "Activation shortcut should be updated to Win + Ctrl + W");
}
[TestMethod("WorkspacesSettings.EnableToggle")]
[TestCategory("Workspaces Settings UI")]
public void TestEnableDisableModule()
{
GoToSettingsPageAndEnable();
// Find the enable toggle
var enableToggle = Find<ToggleSwitch>("Enable Workspaces");
Assert.IsNotNull(enableToggle, "Enable Workspaces toggle should exist");
Assert.IsTrue(enableToggle.IsOn, "Enable Workspaces toggle should be in the 'on' state");
// Toggle the state
enableToggle.Click();
Task.Delay(500).Wait();
// Verify state changed
Assert.IsFalse(enableToggle.IsOn, "Toggle state should change");
// Verify related controls are enabled/disabled accordingly
var launchButton = Find<Button>("Launch editor");
Assert.IsFalse(launchButton.Enabled, "Launch editor button should be disabled when module is disabled");
}
[TestMethod("WorkspacesSettings.LaunchByActivationShortcut")]
[TestCategory("Workspaces Settings UI")]
[Ignore("Wait until settings & runner can be connected in framework")]
public void TestLaunchEditorByActivationShortcut()
{
// Ensure module is enabled
var enableToggle = Find<ToggleSwitch>("Enable Workspaces");
if (!enableToggle.IsOn)
{
enableToggle.Click();
Thread.Sleep(500);
}
// Close settings window to test shortcut
ExitScopeExe();
Thread.Sleep(1000);
// Default shortcut is Win+Ctrl+`
SendKeys(Key.Win, Key.Ctrl, Key.W);
Thread.Sleep(2000);
// Verify editor opened
Assert.IsTrue(WindowHelper.IsWindowOpen("Workspaces Editor"), "Workspaces Editor should open with activation shortcut");
// Reopen settings for next tests
RestartScopeExe();
NavigateToWorkspacesSettings();
}
[TestMethod("WorkspacesSettings.DisableModuleNoLaunch")]
[TestCategory("Workspaces Settings UI")]
[Ignore("Wait until settings & runner can be connected in framework")]
public void TestDisabledModuleDoesNotLaunchByShortcut()
{
// Disable the module
var enableToggle = Find<ToggleSwitch>("Enable Workspaces");
if (enableToggle.IsOn)
{
enableToggle.Click();
Thread.Sleep(500);
}
// Close settings to test shortcut
ExitScopeExe();
Thread.Sleep(1000);
// Try to launch with shortcut
SendKeys(Key.Win, Key.Ctrl, Key.W);
Thread.Sleep(2000);
// Verify editor did not open
Assert.IsFalse(WindowHelper.IsWindowOpen("Workspaces Editor"), "Workspaces Editor should not open when module is disabled");
// Reopen settings and re-enable the module
RestartScopeExe();
NavigateToWorkspacesSettings();
enableToggle = Find<ToggleSwitch>("Enable Workspaces");
if (!enableToggle.IsOn)
{
enableToggle.Click();
Thread.Sleep(500);
}
}
[TestMethod("WorkspacesSettings.QuickAccessLaunch")]
[TestCategory("Workspaces Settings UI")]
[Ignore("Wait until tray icon supported is in framework")]
public void TestLaunchFromQuickAccess()
{
// This test verifies the "quick access" mention in settings
// Look for any quick access related UI elements
var quickAccessInfo = FindAll(By.LinkText("quick access"));
if (quickAccessInfo.Count > 0)
{
Assert.IsTrue(quickAccessInfo.Count > 0, "Quick access information should be present in settings");
}
// Note: Actual system tray/quick access interaction would require
// more complex automation that might be platform-specific
}
private void NavigateToWorkspacesSettings()
{
// Find and click Workspaces in the navigation
var workspacesNavItem = Find<NavigationViewItem>("Workspaces");
workspacesNavItem.Click();
Thread.Sleep(1000);
}
private void GoToSettingsPageAndEnable()
{
if (this.FindAll<NavigationViewItem>("Workspaces").Count == 0)
{
this.Find<NavigationViewItem>("Windowing & Layouts").Click();
}
this.Find<NavigationViewItem>("Workspaces").Click();
var enableButton = this.Find<ToggleSwitch>("Enable Workspaces");
Assert.IsNotNull(enableButton, "Enable Workspaces toggle should exist");
if (!enableButton.IsOn)
{
enableButton.Click();
Task.Delay(500).Wait(); // Wait for the toggle animation and state change
}
// Verify it's now enabled
Assert.IsTrue(enableButton.IsOn, "Enable Workspaces toggle should be in the 'on' state");
}
private void AttachWorkspacesEditor()
{
Task.Delay(200).Wait();
this.Session.Attach(PowerToysModule.Workspaces);
}
}

View File

@@ -1,82 +0,0 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Microsoft.PowerToys.UITest;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using WorkspacesEditor.Utils;
namespace WorkspacesEditorUITest;
[TestClass]
public class WorkspacesSnapshotTests : WorkspacesUiAutomationBase
{
public WorkspacesSnapshotTests()
: base()
{
}
[TestMethod("WorkspacesSnapshot.CancelCapture")]
[TestCategory("Workspaces Snapshot UI")]
public void TestCaptureCancel()
{
AttachWorkspacesEditor();
var createButton = Find<Button>("Create Workspace");
createButton.Click();
Task.Delay(1000).Wait();
AttachSnapshotWindow();
var cancelButton = Find<Button>("Cancel");
Assert.IsNotNull(cancelButton, "Capture button should exist");
cancelButton.Click();
}
[TestMethod("WorkspacesSnapshot.CapturePackagedApps")]
[TestCategory("Workspaces Snapshot UI")]
public void TestCapturePackagedApplications()
{
OpenCalculator();
// OpenWindowsSettings();
Task.Delay(2000).Wait();
AttachWorkspacesEditor();
var createButton = Find<Button>("Create Workspace");
createButton.Click();
Task.Delay(1000).Wait();
AttachSnapshotWindow();
var captureButton = Find<Button>("Capture");
captureButton.Click();
Task.Delay(3000).Wait();
// Verify captured windows by reading the temporary workspaces file as the ground truth.
var editorIO = new WorkspacesEditorIO();
var workspace = editorIO.ParseTempProject();
Assert.IsNotNull(workspace, "Workspace data should be deserialized.");
Assert.IsNotNull(workspace.Applications, "Workspace should contain a list of apps.");
bool isCalculatorFound = workspace.Applications.Any(app => app.AppPath.Contains("Calculator", StringComparison.OrdinalIgnoreCase));
// bool isSettingsFound = workspace.Applications.Any(app => app.AppPath.Contains("Settings", StringComparison.OrdinalIgnoreCase));
Assert.IsTrue(isCalculatorFound, "Calculator should be captured in the workspace data.");
// Assert.IsTrue(isSettingsFound, "Settings should be captured in the workspace data.");
// Cancel to clean up
AttachWorkspacesEditor();
Find<Button>("Cancel").Click();
Task.Delay(1000).Wait();
// Close test applications
CloseCalculator();
// CloseWindowsSettings();
}
}

View File

@@ -1,253 +0,0 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Diagnostics;
using Microsoft.PowerToys.UITest;
namespace WorkspacesEditorUITest
{
public class WorkspacesUiAutomationBase : UITestBase
{
public WorkspacesUiAutomationBase()
: base(PowerToysModule.Workspaces, WindowSize.Medium)
{
}
protected void CreateTestWorkspace(string name)
{
// Open notepad for capture
OpenNotepad();
Task.Delay(1000).Wait();
// Create workspace
AttachWorkspacesEditor();
var createButton = Find<Button>("Create Workspace");
createButton.Click();
Task.Delay(500).Wait();
// Capture
AttachSnapshotWindow();
var captureButton = Find<Button>("Capture");
captureButton.Click();
Task.Delay(5000).Wait();
// Set name
var nameTextBox = Find<TextBox>("EditNameTextBox");
nameTextBox.SetText(name);
// Save
Find<Button>("Save Workspace").Click();
// Close notepad
CloseNotepad();
}
// DO NOT USE UNTIL FRAMEWORK AVAILABLE, CAN'T FIND BUTTON FOR SECOND LOOP
protected void ClearWorkspaces()
{
while (true)
{
try
{
var root = Find<Element>(By.AccessibilityId("WorkspacesItemsControl"));
var buttons = root.FindAll<Button>(By.AccessibilityId("MoreButton"));
Debug.WriteLine($"Found {buttons.Count} button");
var button = buttons[^1];
button.Click();
Task.Delay(500).Wait();
var remove = Find<Button>(By.Name("Remove"));
remove.Click();
Task.Delay(500).Wait();
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
break;
}
}
}
protected void CreateWorkspaceWithApps()
{
// Open multiple test applications
OpenTestApplications();
Thread.Sleep(3000);
// Create workspace
var createButton = Find<Button>("Create Workspace");
createButton.Click();
Thread.Sleep(1000);
// Capture
var captureButton = Find<Button>("Capture");
captureButton.Click();
Thread.Sleep(2000);
// Save
Find<Button>("Save").Click();
Thread.Sleep(1000);
// Close test applications
CloseTestApplications();
}
protected void OpenTestApplications()
{
OpenNotepad();
// Could add more applications here
Thread.Sleep(1000);
}
protected void CloseTestApplications()
{
CloseNotepad();
}
protected void CloseWorkspacesEditor()
{
// Find and close the Workspaces Editor window
if (WindowHelper.IsWindowOpen("Workspaces Editor"))
{
var editorWindow = Find<Window>("Workspaces Editor");
editorWindow.Close();
Thread.Sleep(1000);
}
}
protected void ResetShortcutToDefault(Custom shortcutControl)
{
// Right-click on the shortcut control to open context menu
shortcutControl.Click(rightClick: true);
Thread.Sleep(500);
// Look for a "Reset to default" or similar option in the context menu
try
{
// Try to find various possible menu item texts for reset option
var resetOption = Find("Reset to default");
resetOption?.Click();
}
catch
{
try
{
// Try alternative text
var resetOption = Find("Reset");
resetOption?.Click();
}
catch
{
try
{
// Try another alternative
var resetOption = Find("Default");
resetOption?.Click();
}
catch
{
// If context menu doesn't have reset option, try keyboard shortcut
// ESC to close any open menus first
SendKeys(Key.Esc);
Thread.Sleep(200);
// Click on the control and try to clear it with standard shortcuts
shortcutControl.Click();
Thread.Sleep(200);
// Try Ctrl+A to select all, then Delete to clear
SendKeys(Key.Ctrl, Key.A);
Thread.Sleep(100);
SendKeys(Key.Delete);
Thread.Sleep(500);
}
}
}
}
protected void OpenNotepad()
{
var process = System.Diagnostics.Process.Start("notepad.exe");
Task.Delay(1000).Wait();
}
protected void CloseNotepad()
{
var processes = System.Diagnostics.Process.GetProcessesByName("notepad");
foreach (var process in processes)
{
try
{
process.Kill();
process.WaitForExit();
}
catch
{
// ignore
}
}
}
private void AttachPowertoySetting()
{
Task.Delay(200).Wait();
this.Session.Attach(PowerToysModule.PowerToysSettings);
}
protected void AttachWorkspacesEditor()
{
Task.Delay(200).Wait();
this.Session.Attach(PowerToysModule.Workspaces);
}
protected void AttachSnapshotWindow()
{
Task.Delay(5000).Wait();
this.Session.Attach("Snapshot Creator");
}
protected void OpenCalculator()
{
Process.Start("calc.exe");
Task.Delay(1000).Wait();
}
protected void CloseCalculator()
{
foreach (var process in Process.GetProcessesByName("CalculatorApp"))
{
process.Kill();
}
foreach (var process in Process.GetProcessesByName("Calculator"))
{
process.Kill();
}
}
protected void OpenWindowsSettings()
{
Process.Start(new ProcessStartInfo
{
FileName = "ms-settings:",
UseShellExecute = true,
});
Task.Delay(500).Wait();
}
protected void CloseWindowsSettings()
{
foreach (var process in Process.GetProcessesByName("SystemSettings"))
{
process.Kill();
}
}
}
}

View File

@@ -82,7 +82,7 @@ public static class CalculateEngine
return default;
}
var decimalResult = Convert.ToDecimal(result, new CultureInfo("en-US"));
var decimalResult = Convert.ToDecimal(result, cultureInfo);
var roundedResult = FormatMax15Digits(decimalResult, cultureInfo);

View File

@@ -16,7 +16,7 @@
// project, where bugs will be filed
"org": "microsoft",
"project": "OS",
"AssignedTo": "leilzh@microsoft.com",
"AssignedTo": "PowerToys@microsoft.com",
"AreaPath": "OS\\Windows Client and Services\\WinPD\\DFX-Developer Fundamentals and Experiences\\DEFT\\SALT",
"IterationPath": "OS\\Future"
},

View File

@@ -11,7 +11,7 @@
// project, where bugs will be filed
"org": "microsoft",
"project": "OS",
"AssignedTo": "leilzh@microsoft.com",
"AssignedTo": "PowerToys@microsoft.com",
"AreaPath": "OS\\Windows Client and Services\\WinPD\\DFX-Developer Fundamentals and Experiences\\DEFT\\SALT",
"IterationPath": "OS\\Future"
},

View File

@@ -19,7 +19,7 @@
// project, where bugs will be filed
"org": "microsoft",
"project": "OS",
"AssignedTo": "leilzh@microsoft.com",
"AssignedTo": "PowerToys@microsoft.com",
"AreaPath": "OS\\Windows Client and Services\\WinPD\\DFX-Developer Fundamentals and Experiences\\DEFT\\SALT",
"IterationPath": "OS\\Future"
},
@@ -60,7 +60,7 @@
// project, where bugs will be filed
"org": "microsoft",
"project": "OS",
"AssignedTo": "leilzh@microsoft.com",
"AssignedTo": "PowerToys@microsoft.com",
"AreaPath": "OS\\Windows Client and Services\\WinPD\\DFX-Developer Fundamentals and Experiences\\DEFT\\SALT",
"IterationPath": "OS\\Future"
},

View File

@@ -671,22 +671,14 @@ std::string ESettingsWindowNames_to_string(ESettingsWindowNames value)
{
switch (value)
{
case ESettingsWindowNames::Dashboard:
return "Dashboard";
case ESettingsWindowNames::Overview:
return "Overview";
case ESettingsWindowNames::AlwaysOnTop:
return "AlwaysOnTop";
case ESettingsWindowNames::Awake:
return "Awake";
case ESettingsWindowNames::ColorPicker:
return "ColorPicker";
case ESettingsWindowNames::CmdNotFound:
return "CmdNotFound";
case ESettingsWindowNames::FancyZones:
return "FancyZones";
case ESettingsWindowNames::FileLocksmith:
return "FileLocksmith";
case ESettingsWindowNames::Run:
return "Run";
case ESettingsWindowNames::ImageResizer:
@@ -695,16 +687,6 @@ std::string ESettingsWindowNames_to_string(ESettingsWindowNames value)
return "KBM";
case ESettingsWindowNames::MouseUtils:
return "MouseUtils";
case ESettingsWindowNames::MouseWithoutBorders:
return "MouseWithoutBorders";
case ESettingsWindowNames::Peek:
return "Peek";
case ESettingsWindowNames::PowerAccent:
return "PowerAccent";
case ESettingsWindowNames::PowerLauncher:
return "PowerLauncher";
case ESettingsWindowNames::PowerPreview:
return "PowerPreview";
case ESettingsWindowNames::PowerRename:
return "PowerRename";
case ESettingsWindowNames::FileExplorer:
@@ -725,6 +707,8 @@ std::string ESettingsWindowNames_to_string(ESettingsWindowNames value)
return "CropAndLock";
case ESettingsWindowNames::EnvironmentVariables:
return "EnvironmentVariables";
case ESettingsWindowNames::Dashboard:
return "Dashboard";
case ESettingsWindowNames::AdvancedPaste:
return "AdvancedPaste";
case ESettingsWindowNames::NewPlus:
@@ -744,18 +728,10 @@ std::string ESettingsWindowNames_to_string(ESettingsWindowNames value)
ESettingsWindowNames ESettingsWindowNames_from_string(std::string value)
{
if (value == "Dashboard")
{
return ESettingsWindowNames::Dashboard;
}
else if (value == "Overview")
if (value == "Overview")
{
return ESettingsWindowNames::Overview;
}
else if (value == "AlwaysOnTop")
{
return ESettingsWindowNames::AlwaysOnTop;
}
else if (value == "Awake")
{
return ESettingsWindowNames::Awake;
@@ -764,18 +740,10 @@ ESettingsWindowNames ESettingsWindowNames_from_string(std::string value)
{
return ESettingsWindowNames::ColorPicker;
}
else if (value == "CmdNotFound")
{
return ESettingsWindowNames::CmdNotFound;
}
else if (value == "FancyZones")
{
return ESettingsWindowNames::FancyZones;
}
else if (value == "FileLocksmith")
{
return ESettingsWindowNames::FileLocksmith;
}
else if (value == "Run")
{
return ESettingsWindowNames::Run;
@@ -792,26 +760,6 @@ ESettingsWindowNames ESettingsWindowNames_from_string(std::string value)
{
return ESettingsWindowNames::MouseUtils;
}
else if (value == "MouseWithoutBorders")
{
return ESettingsWindowNames::MouseWithoutBorders;
}
else if (value == "Peek")
{
return ESettingsWindowNames::Peek;
}
else if (value == "PowerAccent")
{
return ESettingsWindowNames::PowerAccent;
}
else if (value == "PowerLauncher")
{
return ESettingsWindowNames::PowerLauncher;
}
else if (value == "PowerPreview")
{
return ESettingsWindowNames::PowerPreview;
}
else if (value == "PowerRename")
{
return ESettingsWindowNames::PowerRename;
@@ -852,6 +800,10 @@ ESettingsWindowNames ESettingsWindowNames_from_string(std::string value)
{
return ESettingsWindowNames::EnvironmentVariables;
}
else if (value == "Dashboard")
{
return ESettingsWindowNames::Dashboard;
}
else if (value == "AdvancedPaste")
{
return ESettingsWindowNames::AdvancedPaste;

View File

@@ -6,21 +6,13 @@ enum class ESettingsWindowNames
{
Dashboard = 0,
Overview,
AlwaysOnTop,
Awake,
ColorPicker,
CmdNotFound,
FancyZones,
FileLocksmith,
Run,
ImageResizer,
KBM,
MouseUtils,
MouseWithoutBorders,
Peek,
PowerAccent,
PowerLauncher,
PowerPreview,
PowerRename,
FileExplorer,
ShortcutGuide,

View File

@@ -436,10 +436,6 @@ namespace Microsoft.PowerToys.Settings.UI
case "KBM": return typeof(KeyboardManagerPage);
case "MouseUtils": return typeof(MouseUtilsPage);
case "MouseWithoutBorders": return typeof(MouseWithoutBordersPage);
case "Peek": return typeof(PeekPage);
case "PowerAccent": return typeof(PowerAccentPage);
case "PowerLauncher": return typeof(PowerLauncherPage);
case "PowerPreview": return typeof(PowerPreviewPage);
case "PowerRename": return typeof(PowerRenamePage);
case "QuickAccent": return typeof(PowerAccentPage);
case "FileExplorer": return typeof(PowerPreviewPage);
@@ -448,6 +444,7 @@ namespace Microsoft.PowerToys.Settings.UI
case "MeasureTool": return typeof(MeasureToolPage);
case "Hosts": return typeof(HostsPage);
case "RegistryPreview": return typeof(RegistryPreviewPage);
case "Peek": return typeof(PeekPage);
case "CropAndLock": return typeof(CropAndLockPage);
case "EnvironmentVariables": return typeof(EnvironmentVariablesPage);
case "NewPlus": return typeof(NewPlusPage);

View File

@@ -12,7 +12,6 @@
<UserControl.Resources>
<x:Double x:Key="PageMaxWidth">1000</x:Double>
<x:Double x:Key="PageHeaderMaxWidth">1020</x:Double>
<tkconverters:DoubleToVisibilityConverter
x:Name="doubleToVisibilityConverter"
FalseValue="Collapsed"
@@ -27,7 +26,7 @@
</Grid.RowDefinitions>
<TextBlock
x:Name="Header"
MaxWidth="{StaticResource PageHeaderMaxWidth}"
MaxWidth="{StaticResource PageMaxWidth}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
AutomationProperties.HeadingLevel="1"

View File

@@ -88,9 +88,16 @@
</tkcontrols:SettingsExpander.Items>
</tkcontrols:SettingsExpander>
<tkcontrols:SettingsCard x:Uid="AlwaysOnTop_Sound" HeaderIcon="{ui:FontIcon Glyph=&#xE7F3;}">
<ToggleSwitch IsOn="{x:Bind ViewModel.SoundEnabled, Mode=TwoWay}" />
</tkcontrols:SettingsCard>
<tkcontrols:SettingsExpander
x:Uid="AlwaysOnTop_SoundTitle"
HeaderIcon="{ui:FontIcon Glyph=&#xE7F3;}"
IsExpanded="True">
<tkcontrols:SettingsExpander.Items>
<tkcontrols:SettingsCard ContentAlignment="Left">
<CheckBox x:Uid="AlwaysOnTop_Sound" IsChecked="{x:Bind ViewModel.SoundEnabled, Mode=TwoWay}" />
</tkcontrols:SettingsCard>
</tkcontrols:SettingsExpander.Items>
</tkcontrols:SettingsExpander>
</controls:SettingsGroup>
<controls:SettingsGroup x:Uid="ExcludedApps" IsEnabled="{x:Bind ViewModel.IsEnabled, Mode=OneWay}">

View File

@@ -294,7 +294,7 @@
<tkcontrols:SettingsCard x:Uid="General_SettingsBackupAndRestoreLocationText">
<Grid ColumnSpacing="8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock
@@ -405,83 +405,76 @@
</InfoBar.IconSource>
</InfoBar>
</controls:SettingsGroup>
<controls:SettingsGroup x:Uid="General_DiagnosticsAndFeedback">
<tkcontrols:SettingsExpander
x:Uid="GeneralPage_EnableDataDiagnostics"
HeaderIcon="{ui:FontIcon Glyph=&#xE9D9;}"
IsEnabled="{x:Bind ViewModel.IsDataDiagnosticsGPOManaged, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}"
IsExpanded="True">
<tkcontrols:SettingsExpander.Description>
<StackPanel Orientation="Vertical">
<TextBlock
x:Uid="GeneralPage_EnableDataDiagnosticsText"
Style="{StaticResource SecondaryTextStyle}"
TextWrapping="WrapWholeWords" />
<HyperlinkButton
x:Uid="GeneralPage_DiagnosticsAndFeedback_Link"
Margin="0,2,0,0"
FontWeight="SemiBold"
NavigateUri="https://aka.ms/powertoys-data-and-privacy-documentation" />
</StackPanel>
</tkcontrols:SettingsExpander.Description>
<ToggleSwitch x:Uid="ToggleSwitch" IsOn="{x:Bind ViewModel.EnableDataDiagnostics, Mode=TwoWay}" />
<tkcontrols:SettingsExpander.Items>
<tkcontrols:SettingsCard x:Uid="GeneralPage_EnableViewDiagnosticData" IsEnabled="{x:Bind ViewModel.EnableDataDiagnostics, Mode=TwoWay}">
<ToggleSwitch x:Uid="ToggleSwitch" IsOn="{x:Bind ViewModel.EnableViewDataDiagnostics, Mode=TwoWay}" />
<tkcontrols:SettingsCard.Description>
<StackPanel Orientation="Vertical">
<TextBlock
x:Uid="GeneralPage_EnableViewDiagnosticDataText"
Style="{StaticResource SecondaryTextStyle}"
TextWrapping="WrapWholeWords" />
<HyperlinkButton
Margin="0,2,0,0"
Click="ViewDiagnosticData_Click"
Content="View diagnostic data"
FontWeight="SemiBold" />
</StackPanel>
</tkcontrols:SettingsCard.Description>
</tkcontrols:SettingsCard>
</tkcontrols:SettingsExpander.Items>
<tkcontrols:SettingsExpander.ItemsFooter>
<InfoBar
x:Uid="GeneralPage_ViewDiagnosticDataViewerInfo"
BorderThickness="0"
CornerRadius="0,0,4,4"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.ViewDiagnosticDataViewerChanged}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.ViewDiagnosticDataViewerChanged}"
Severity="Informational">
<InfoBar.ActionButton>
<Button x:Uid="GeneralPage_ViewDiagnosticDataViewerInfoButton" Click="Click_ViewDiagnosticDataViewerRestart" />
</InfoBar.ActionButton>
</InfoBar>
</tkcontrols:SettingsExpander.ItemsFooter>
</tkcontrols:SettingsExpander>
<InfoBar
x:Uid="GPO_SettingIsManaged"
IsClosable="False"
IsOpen="{x:Bind ViewModel.IsDataDiagnosticsGPOManaged, Mode=OneWay}"
IsTabStop="{x:Bind ViewModel.IsDataDiagnosticsGPOManaged, Mode=OneWay}"
Severity="Informational">
<InfoBar.IconSource>
<FontIconSource FontFamily="{StaticResource SymbolThemeFontFamily}" Glyph="&#xE72E;" />
</InfoBar.IconSource>
</InfoBar>
<tkcontrols:SettingsCard x:Uid="GeneralPage_ReportBugPackage" HeaderIcon="{ui:FontIcon Glyph=&#xEBE8;}">
<StackPanel Orientation="Horizontal">
<controls:SettingsGroup x:Uid="General_DiagnosticsAndFeedback" Visibility="Visible">
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
<HyperlinkButton
x:Uid="GeneralPage_DiagnosticsAndFeedback_Link"
Margin="0,0,0,8"
Padding="0"
NavigateUri="https://aka.ms/powertoys-data-and-privacy-documentation" />
<tkcontrols:SettingsCard
x:Uid="GeneralPage_EnableDataDiagnostics"
HeaderIcon="{ui:FontIcon Glyph=&#xE9D9;}"
IsEnabled="{x:Bind ViewModel.IsDataDiagnosticsGPOManaged, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}">
<ToggleSwitch x:Uid="ToggleSwitch" IsOn="{x:Bind ViewModel.EnableDataDiagnostics, Mode=TwoWay}" />
</tkcontrols:SettingsCard>
<InfoBar
x:Uid="GPO_SettingIsManaged"
IsClosable="False"
IsOpen="{x:Bind ViewModel.IsDataDiagnosticsGPOManaged, Mode=OneWay}"
IsTabStop="{x:Bind ViewModel.IsDataDiagnosticsGPOManaged, Mode=OneWay}"
Severity="Informational">
<InfoBar.IconSource>
<FontIconSource FontFamily="{StaticResource SymbolThemeFontFamily}" Glyph="&#xE72E;" />
</InfoBar.IconSource>
</InfoBar>
<tkcontrols:SettingsExpander
x:Uid="GeneralPage_ViewDiagnosticData"
HeaderIcon="{ui:FontIcon Glyph=&#xE7EF;}"
IsEnabled="{x:Bind ViewModel.IsDataDiagnosticsGPOManaged, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}"
IsExpanded="True">
<tkcontrols:SettingsExpander.Items>
<tkcontrols:SettingsCard x:Uid="GeneralPage_EnableViewDiagnosticData" IsEnabled="{x:Bind ViewModel.EnableDataDiagnostics, Mode=TwoWay}">
<ToggleSwitch x:Uid="ToggleSwitch" IsOn="{x:Bind ViewModel.EnableViewDataDiagnostics, Mode=TwoWay}" />
</tkcontrols:SettingsCard>
<tkcontrols:SettingsCard
x:Uid="GeneralPage_ViewDiagnosticDataViewer"
ActionIcon="{ui:FontIcon Glyph=&#xE8A7;}"
Click="ViewDiagnosticData_Click"
IsClickEnabled="True" />
</tkcontrols:SettingsExpander.Items>
</tkcontrols:SettingsExpander>
<InfoBar
x:Uid="GeneralPage_ViewDiagnosticDataViewerInfo"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.ViewDiagnosticDataViewerChanged}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.ViewDiagnosticDataViewerChanged}"
Severity="Informational">
<InfoBar.ActionButton>
<Button x:Uid="GeneralPage_ViewDiagnosticDataViewerInfoButton" Click="Click_ViewDiagnosticDataViewerRestart" />
</InfoBar.ActionButton>
</InfoBar>
<tkcontrols:SettingsCard
x:Uid="GeneralPage_ReportBugPackage"
HeaderIcon="{ui:FontIcon Glyph=&#xEBE8;}"
Visibility="{x:Bind ViewModel.IsBugReportRunning, Converter={StaticResource ReverseBoolToVisibilityConverter}, Mode=OneWay}">
<Button
x:Uid="GeneralPageReportBugPackage"
HorizontalAlignment="Right"
Click="BugReportToolClicked"
Visibility="{x:Bind ViewModel.IsBugReportRunning, Converter={StaticResource ReverseBoolToVisibilityConverter}, Mode=OneWay}" />
IsEnabled="{x:Bind ViewModel.IsBugReportRunning, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}" />
</tkcontrols:SettingsCard>
<tkcontrols:SettingsCard
x:Uid="GeneralPage_ReportBugPackage"
HeaderIcon="{ui:FontIcon Glyph=&#xEBE8;}"
Visibility="{x:Bind ViewModel.IsBugReportRunning, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}">
<ProgressRing
Width="24"
Height="24"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Visibility="{x:Bind ViewModel.IsBugReportRunning, Mode=OneWay}" />
</StackPanel>
</tkcontrols:SettingsCard>
VerticalAlignment="Center" />
</tkcontrols:SettingsCard>
</StackPanel>
</controls:SettingsGroup>
</StackPanel>

View File

@@ -152,10 +152,10 @@
<comment>"Screen Ruler" is the name of the utility</comment>
</data>
<data name="MeasureTool_DefaultMeasureStyle.Header" xml:space="preserve">
<value>Default mode</value>
<value>Default measure style</value>
</data>
<data name="MeasureTool_DefaultMeasureStyle.Description" xml:space="preserve">
<value>The measuring mode that is used when activated</value>
<value>The utility will start having the selected style activated</value>
</data>
<data name="MeasureTool_DefaultMeasureStyle_None.Content" xml:space="preserve">
<value>None</value>
@@ -234,7 +234,7 @@
<value>Security key</value>
</data>
<data name="MouseWithoutBorders_SecurityKey.Description" xml:space="preserve">
<value>To set up, generate the key on one machine, and enter it manually on other machines.</value>
<value>The key must be auto generated in one machine by clicking on New Key, then typed in other machines</value>
</data>
<data name="MouseWithoutBorders_NewKey.Content" xml:space="preserve">
<value>New key</value>
@@ -274,7 +274,7 @@
<value>Adding a firewall rule might help solve connection issues.</value>
</data>
<data name="MouseWithoutBorders_RunAsAdminText.Title" xml:space="preserve">
<value>This setting can only be changed when running as administrator</value>
<value>You need to run as administrator to modify this setting.</value>
</data>
<data name="MouseWithoutBorders_ServiceUserUninstallWarning.Title" xml:space="preserve">
<value>If PowerToys is installed as a user, uninstalling/upgrading may require the Mouse Without Borders service to be removed manually later.</value>
@@ -361,7 +361,7 @@
<value>Hide the mouse cursor at the top edge of the screen when switching to other machine. This option also steals the focus from any full-screen app to ensure the keyboard input is redirected.</value>
</data>
<data name="MouseWithoutBorders_DrawMouseCursor.Description" xml:space="preserve">
<value>The mouse cursor may not appear on Windows 10 and later if no physical mouse is connected.</value>
<value>Mouse cursor may not be visible in Windows 10 and later versions of Windows when there is no physical mouse attached.</value>
</data>
<data name="MouseWithoutBorders_ValidateRemoteMachineIP.Description" xml:space="preserve">
<value>Reverse DNS lookup to validate machine IP Address.</value>
@@ -804,7 +804,7 @@
<comment>launches the FancyZones layout editor application</comment>
</data>
<data name="FancyZones_MakeDraggedWindowTransparentCheckBoxControl.Content" xml:space="preserve">
<value>Make the dragged window transparent</value>
<value>Make dragged window transparent</value>
</data>
<data name="FancyZones_MouseDragCheckBoxControl_Header.Content" xml:space="preserve">
<value>Use a non-primary mouse button to toggle zone activation</value>
@@ -1304,7 +1304,7 @@
<value>Always run as administrator</value>
</data>
<data name="GeneralSettings_AlwaysRunAsAdminText.Description" xml:space="preserve">
<value>This setting can only be changed when running as administrator</value>
<value>You need to run as administrator to use this setting</value>
</data>
<data name="GeneralSettings_RunningAsUserText" xml:space="preserve">
<value>Running as user</value>
@@ -1465,7 +1465,7 @@ Made with 💗 by Microsoft and the PowerToys community.</value>
<comment>Preview Pane and File Explorer are app/feature names in Windows. 'Alt + P' is a shortcut</comment>
</data>
<data name="FileExplorerPreview_RunAsAdminRequired.Title" xml:space="preserve">
<value>This setting can only be changed when running as administrator</value>
<value>You need to run as administrator to modify these settings.</value>
</data>
<data name="FileExplorerPreview_RebootRequired.Title" xml:space="preserve">
<value>A reboot may be required for changes to these settings to take effect</value>
@@ -1520,7 +1520,7 @@ Made with 💗 by Microsoft and the PowerToys community.</value>
<value>Mouse actions</value>
</data>
<data name="ColorPicker_MouseActions.Description" xml:space="preserve">
<value>Customize the function of each mouse button</value>
<value>Choose what clicking individual buttons does</value>
</data>
<data name="ColorPicker_PrimaryClick.Header" xml:space="preserve">
<value>Primary click</value>
@@ -1544,7 +1544,7 @@ Made with 💗 by Microsoft and the PowerToys community.</value>
<value>Picker behavior</value>
</data>
<data name="ColorPicker_CopiedColorRepresentation.Description" xml:space="preserve">
<value>Format will be copied to your clipboard</value>
<value>This format will be copied to your clipboard</value>
</data>
<data name="KBM_KeysCannotBeRemapped.Text" xml:space="preserve">
<value>Learn more about remapping limitations</value>
@@ -1736,7 +1736,7 @@ Made with 💗 by Microsoft and the PowerToys community.</value>
<value>Show color name</value>
</data>
<data name="ColorPicker_ShowColorName.Description" xml:space="preserve">
<value>Displays the color name while picking a color</value>
<value>This will show the name of the color when picking a color</value>
</data>
<data name="ImageResizer_DefaultSize_Large" xml:space="preserve">
<value>Large</value>
@@ -2056,7 +2056,7 @@ Take a moment to preview the various utilities listed or view our comprehensive
<value>Diagnostic data</value>
</data>
<data name="Oobe_Overview_EnableDataDiagnostics.Description" xml:space="preserve">
<value>Helps us make PowerToys faster, more stable, and better over time</value>
<value>Helps inform bug fixes, performance, and product decisions</value>
</data>
<data name="Oobe_WhatsNew_DataDiagnostics_InfoBar.Header" xml:space="preserve">
<value>Turn on diagnostic data to help us improve PowerToys?</value>
@@ -2710,7 +2710,7 @@ Right-click to remove the key combination, thereby deactivating the shortcut.</v
<value>Spotlight initial zoom</value>
</data>
<data name="MouseUtils_FindMyMouse_SpotlightInitialZoom.Description" xml:space="preserve">
<value>Spotlight zoom factor at the start of the animation</value>
<value>Spotlight zoom factor at animation start</value>
</data>
<data name="MouseUtils_FindMyMouse_AnimationDurationMs.Header" xml:space="preserve">
<value>Animation duration (ms)</value>
@@ -2724,23 +2724,23 @@ Right-click to remove the key combination, thereby deactivating the shortcut.</v
<value>Animations are disabled in your system settings.</value>
</data>
<data name="MouseUtils_FindMyMouse_ShakingMinimumDistance.Header" xml:space="preserve">
<value>Minimum shake distance</value>
<value>Shake minimum distance</value>
</data>
<data name="MouseUtils_FindMyMouse_ShakingMinimumDistance.Description" xml:space="preserve">
<value>The minimum distance the mouse must move to be considered a shake. Lower values increase sensitivity.</value>
<value>The minimum distance for mouse shaking activation, for adjusting sensitivity</value>
</data>
<data name="MouseUtils_FindMyMouse_ShakingIntervalMs.Header" xml:space="preserve">
<value>Shake detection interval (ms)</value>
<value>Shake Interval (ms)</value>
<comment>ms = milliseconds</comment>
</data>
<data name="MouseUtils_FindMyMouse_ShakingIntervalMs.Description" xml:space="preserve">
<value>Time window used to monitor mouse movement for shake detection. Shorter intervals may detect quicker shakes.</value>
<value>The span of time during which we track mouse movement to detect shaking, for adjusting sensitivity</value>
</data>
<data name="MouseUtils_FindMyMouse_ShakingFactor.Header" xml:space="preserve">
<value>Shake sensitivity factor (percent)</value>
<value>Shake factor (percent)</value>
</data>
<data name="MouseUtils_FindMyMouse_ShakingFactor.Description" xml:space="preserve">
<value>Determines how far the pointer must move, relative to the screen diagonal, to count as a shake. Lower values make it more sensitive.</value>
<value>Mouse shaking is detected by checking how much the mouse pointer has travelled when compared to the diagonal of the movement area. Reducing this factor increases sensitivity.</value>
</data>
<data name="MouseUtils_MouseHighlighter.Header" xml:space="preserve">
<value>Mouse Highlighter</value>
@@ -2840,7 +2840,7 @@ Right-click to remove the key combination, thereby deactivating the shortcut.</v
<value>Windows default</value>
</data>
<data name="ColorModeHeader.Header" xml:space="preserve">
<value>Theme</value>
<value>App theme</value>
</data>
<data name="FancyZones_Zone_Appearance.Description" xml:space="preserve">
<value>Customize the way zones look</value>
@@ -2848,6 +2848,9 @@ Right-click to remove the key combination, thereby deactivating the shortcut.</v
<data name="FancyZones_Zone_Appearance.Header" xml:space="preserve">
<value>Zone appearance</value>
</data>
<data name="LearnMore.Content" xml:space="preserve">
<value>Learn more</value>
</data>
<data name="FileExplorerPreview_ToggleSwitch_Thumbnail_GCODE.Header" xml:space="preserve">
<value>Geometric Code</value>
<comment>File type, do not translate</comment>
@@ -2903,13 +2906,13 @@ Right-click to remove the key combination, thereby deactivating the shortcut.</v
<value>Reparent shortcut</value>
</data>
<data name="CropAndLock_ReparentActivation_Shortcut.Description" xml:space="preserve">
<value>Creates a cropped version of an applications window by embedding the original app into a new window. This is experimental and may cause issues due to the reparenting behavior.</value>
<value>Shortcut to crop an application's window into a cropped window. This is experimental and can cause issues with some applications, since the cropped window will contain the original application window.</value>
</data>
<data name="CropAndLock_ThumbnailActivation_Shortcut.Header" xml:space="preserve">
<value>Thumbnail shortcut</value>
</data>
<data name="CropAndLock_ThumbnailActivation_Shortcut.Description" xml:space="preserve">
<value>Creates a cropped, non-interactive thumbnail of another window. Improves app compatibility.</value>
<value>Shortcut to crop and create a thumbnail of another window. The application isn't controllable through the thumbnail but it'll have less compatibility issues. </value>
</data>
<data name="CropAndLock.SecondaryLinksHeader" xml:space="preserve">
<value>Attribution</value>
@@ -2977,6 +2980,12 @@ Right-click to remove the key combination, thereby deactivating the shortcut.</v
<value>Do not activate when Game Mode is on</value>
<comment>Game Mode is a Windows feature</comment>
</data>
<data name="AlwaysOnTop_SoundTitle.Header" xml:space="preserve">
<value>Sound</value>
</data>
<data name="AlwaysOnTop_Sound.Content" xml:space="preserve">
<value>Play a sound when pinning a window</value>
</data>
<data name="AlwaysOnTop_Behavior.Header" xml:space="preserve">
<value>Behavior</value>
</data>
@@ -3052,10 +3061,10 @@ Right-click to remove the key combination, thereby deactivating the shortcut.</v
<value>Behavior</value>
</data>
<data name="Peek_AlwaysRunNotElevated.Header" xml:space="preserve">
<value>Always run without elevation (even if PowerToys is elevated)</value>
<value>Always run not elevated, even when PowerToys is elevated</value>
</data>
<data name="Peek_AlwaysRunNotElevated.Description" xml:space="preserve">
<value>Runs Peek without admin permissions to improve access to network shares. To apply this change, you must disable and re-enable Peek.</value>
<value>Tries to run Peek without elevated permissions, to fix access to network shares. You need to disable and re-enable Peek for changes to this value to take effect.</value>
<comment>Peek is a product name, do not loc</comment>
</data>
<data name="Peek_CloseAfterLosingFocus.Header" xml:space="preserve">
@@ -3063,13 +3072,13 @@ Right-click to remove the key combination, thereby deactivating the shortcut.</v
<comment>Peek is a product name, do not loc</comment>
</data>
<data name="Peek_ConfirmFileDelete.Header" xml:space="preserve">
<value>Confirm before deleting files</value>
<value>Ask for confirmation before deleting files</value>
</data>
<data name="Peek_ConfirmFileDelete.Description" xml:space="preserve">
<value>You'll be asked to confirm before files are moved to the Recycle Bin</value>
<value>When enabled, you will be prompted to confirm before moving files to the Recycle Bin.</value>
</data>
<data name="FancyZones_DisableRoundCornersOnWindowSnap.Content" xml:space="preserve">
<value>Disable rounded corners when a window is snapped</value>
<value>Disable round corners when window is snapped</value>
</data>
<data name="PowerLauncher_SearchQueryTuningEnabled.Description" xml:space="preserve">
<value>Fine tune results ordering</value>
@@ -3102,7 +3111,7 @@ Right-click to remove the key combination, thereby deactivating the shortcut.</v
<value>Global sort order score modifier</value>
</data>
<data name="AlwaysOnTop_RoundCorners.Content" xml:space="preserve">
<value>Enable rounded corners</value>
<value>Enable round corners</value>
</data>
<data name="LearnMore_QuickAccent.Text" xml:space="preserve">
<value>Learn more about Quick Accent</value>
@@ -3155,6 +3164,9 @@ Activate by holding the key for the character you want to add an accent to, then
<data name="AlwaysOnTop_ShortDescription" xml:space="preserve">
<value>Pin a window</value>
</data>
<data name="Awake_ShortDescription" xml:space="preserve">
<value>Keep your PC awake</value>
</data>
<data name="ColorPicker_ShortDescription" xml:space="preserve">
<value>Pick a color</value>
</data>
@@ -3173,6 +3185,9 @@ Activate by holding the key for the character you want to add an accent to, then
<data name="FindMyMouse_ShortDescription" xml:space="preserve">
<value>Find the mouse</value>
</data>
<data name="ImageResizer_ShortDescription" xml:space="preserve">
<value>Resize images from right-click context menu</value>
</data>
<data name="MouseHighlighter_ShortDescription" xml:space="preserve">
<value>Highlight clicks</value>
</data>
@@ -3182,6 +3197,9 @@ Activate by holding the key for the character you want to add an accent to, then
<data name="MouseCrosshairs_ShortDescription" xml:space="preserve">
<value>Draw crosshairs centered on the mouse pointer</value>
</data>
<data name="MouseWithoutBorders_ShortDescription" xml:space="preserve">
<value>Move your cursor across multiple devices</value>
</data>
<data name="AdvancedPaste_ShortDescription" xml:space="preserve">
<value>An AI powered tool to put your clipboard content into any format you need, focused towards developer workflows.</value>
</data>
@@ -3194,6 +3212,9 @@ Activate by holding the key for the character you want to add an accent to, then
<data name="Peek_ShortDescription" xml:space="preserve">
<value>Quick and easy previewer</value>
</data>
<data name="PowerRename_ShortDescription" xml:space="preserve">
<value>Rename files and folders from right-click context menu</value>
</data>
<data name="Run_ShortDescription" xml:space="preserve">
<value>A quick launcher</value>
</data>
@@ -3294,7 +3315,7 @@ Activate by holding the key for the character you want to add an accent to, then
<comment>ms = milliseconds</comment>
</data>
<data name="QuickAccent_InputTimeMs.Description" xml:space="preserve">
<value>How long a key must be held before the accent menu appears</value>
<value>Hold the key down for this much time to make the accent menu appear (ms)</value>
<comment>ms = milliseconds</comment>
</data>
<data name="QuickAccent_ExcludedApps.Description" xml:space="preserve">
@@ -3625,7 +3646,7 @@ Activate by holding the key for the character you want to add an accent to, then
<comment>"Hosts File Editor" is a product name</comment>
</data>
<data name="Hosts_AdditionalLinesPosition.Header" xml:space="preserve">
<value>Placement of additional content</value>
<value>Position of additional content</value>
</data>
<data name="Hosts_AdditionalLinesPosition_Bottom.Content" xml:space="preserve">
<value>Bottom</value>
@@ -3653,7 +3674,7 @@ Activate by holding the key for the character you want to add an accent to, then
<comment>"Hosts File Editor" is the name of the utility</comment>
</data>
<data name="Hosts_Toggle_LaunchAdministrator.Description" xml:space="preserve">
<value>Required in order to make changes to the hosts file</value>
<value>Needs to be launched as administrator in order to make changes to the hosts file</value>
</data>
<data name="Hosts_Toggle_LaunchAdministrator.Header" xml:space="preserve">
<value>Launch as administrator</value>
@@ -3695,7 +3716,7 @@ Activate by holding the key for the character you want to add an accent to, then
<value>Environment Variables</value>
</data>
<data name="EnvironmentVariables_Toggle_LaunchAdministrator.Description" xml:space="preserve">
<value>Required in order to make changes to the system environment variables</value>
<value>Needs to be launched as administrator in order to make changes to the system environment variables</value>
</data>
<data name="EnvironmentVariables_Toggle_LaunchAdministrator.Header" xml:space="preserve">
<value>Launch as administrator</value>
@@ -3736,7 +3757,7 @@ Activate by holding the key for the character you want to add an accent to, then
<value>This setting is managed by your organization.</value>
</data>
<data name="Hosts_AdditionalLinesPosition.Description" xml:space="preserve">
<value>Includes items like the file header and any lines that cant be parsed</value>
<value>Additional content includes the file header and lines that can't parse</value>
</data>
<data name="TextExtractor_Languages.Header" xml:space="preserve">
<value>Preferred language</value>
@@ -3773,7 +3794,7 @@ Activate by holding the key for the character you want to add an accent to, then
<value>Experimentation</value>
</data>
<data name="GeneralPage_EnableExperimentation.Description" xml:space="preserve">
<value>Only Windows Insider builds may be selected for experimentation</value>
<value>Note: Only Windows Insider builds may be selected for experimentation</value>
<comment>{Locked="Windows Insider"}</comment>
</data>
<data name="GeneralPage_EnableExperimentation.Header" xml:space="preserve">
@@ -3783,13 +3804,28 @@ Activate by holding the key for the character you want to add an accent to, then
<value>Diagnostics &amp; feedback</value>
</data>
<data name="GeneralPage_DiagnosticsAndFeedback_Link.Content" xml:space="preserve">
<value>Learn more about the logged information and how it's used</value>
<value>Learn more about the information we log &amp; how it gets used</value>
</data>
<data name="GeneralPage_EnableDataDiagnostics.Header" xml:space="preserve">
<value>Diagnostic data</value>
</data>
<data name="GeneralPage_EnableDataDiagnostics.Description" xml:space="preserve">
<value>Helps inform bug fixes, performance, and improvements</value>
</data>
<data name="GeneralPage_ViewDiagnosticData.Header" xml:space="preserve">
<value>View diagnostic data</value>
</data>
<data name="GeneralPage_EnableViewDiagnosticData.Header" xml:space="preserve">
<value>Save logs to this device</value>
<value>Enable viewing</value>
</data>
<data name="GeneralPage_EnableViewDiagnosticData.Description" xml:space="preserve">
<value>Uses up to 1GB (or more) of hard drive space on your PC</value>
</data>
<data name="GeneralPage_ViewDiagnosticDataViewer.Header" xml:space="preserve">
<value>Diagnostic data viewer</value>
</data>
<data name="GeneralPage_ViewDiagnosticDataViewer.Description" xml:space="preserve">
<value>Generate .xml files containing readable diagnostic data. Folder may include .xml and .etl files</value>
</data>
<data name="Shell_AdvancedPaste.Content" xml:space="preserve">
<value>Advanced Paste</value>
@@ -3952,6 +3988,9 @@ Activate by holding the key for the character you want to add an accent to, then
<data name="QuickAccessTxt.Text" xml:space="preserve">
<value>Quick access</value>
</data>
<data name="UpdateAvailable.Title" xml:space="preserve">
<value>Update available</value>
</data>
<data name="FileExplorerPreview_Toggle_Monaco_Max_File_Size.Header" xml:space="preserve">
<value>Maximum file size to preview</value>
<comment>Size refers to the disk space used by a file</comment>
@@ -4016,7 +4055,7 @@ Activate by holding the key for the character you want to add an accent to, then
<value>Activation shortcut</value>
</data>
<data name="MouseUtils_MouseJump_ThumbnailSize.Header" xml:space="preserve">
<value>Thumbnail size</value>
<value>Thumbnail Size</value>
</data>
<data name="MouseUtils_MouseJump_ThumbnailSize_Description_Prefix.Text" xml:space="preserve">
<value>Constrain thumbnail image size to a maximum of</value>
@@ -4151,7 +4190,11 @@ Activate by holding the key for the character you want to add an accent to, then
<value>Launch Registry Preview</value>
</data>
<data name="RegistryPreview_DefaultRegApp.Header" xml:space="preserve">
<value>Make Registry Preview the default app for .reg files</value>
<value>Default app</value>
</data>
<data name="RegistryPreview_DefaultRegApp.Description" xml:space="preserve">
<value>Make Registry Preview default app for opening .reg files</value>
<comment>Registry Preview is app name. Do not localize.</comment>
</data>
<data name="AdvancedPaste_ShortcutWarning.Title" xml:space="preserve">
<value>Using this shortcut may prevent non-text paste actions (e.g. images, files) or built-in paste plain text actions in other applications from functioning.</value>
@@ -4229,6 +4272,12 @@ Activate by holding the key for the character you want to add an accent to, then
<data name="Shell_Dashboard.Content" xml:space="preserve">
<value>Dashboard</value>
</data>
<data name="DisabledModules.Text" xml:space="preserve">
<value>Disabled modules</value>
</data>
<data name="EnabledModules.Text" xml:space="preserve">
<value>Enabled modules</value>
</data>
<data name="Peek_Preview_GroupSettings.Header" xml:space="preserve">
<value>Preview</value>
</data>
@@ -4272,7 +4321,7 @@ Activate by holding the key for the character you want to add an accent to, then
<value>Show the release notes after an update</value>
</data>
<data name="ShowSystemTrayIcon.Description" xml:space="preserve">
<value>To access settings, run the PowerToys executable again</value>
<value>This settings page is accessible by running the PowerToys executable again</value>
</data>
<data name="ShowSystemTrayIcon.Header" xml:space="preserve">
<value>Show system tray icon</value>
@@ -4372,6 +4421,10 @@ Activate by holding the key for the character you want to add an accent to, then
<value>New+</value>
<comment>New+ is the name of the utility. Localize product name in accordance with Windows New</comment>
</data>
<data name="NewPlus_Product_Description.Description" xml:space="preserve">
<value>Create files and folders from a personalized set of templates</value>
<comment>New+ product description</comment>
</data>
<data name="NewPlus_Learn_More.Text" xml:space="preserve">
<value>Learn more about New+</value>
<comment>New+ learn more link. Localize product name in accordance with Windows New</comment>
@@ -4408,15 +4461,15 @@ Activate by holding the key for the character you want to add an accent to, then
<comment>Display options label</comment>
</data>
<data name="NewPlus_Hide_File_Extension_Toggle.Header" xml:space="preserve">
<value>Hide the file extension in template names</value>
<value>Hide template filename extension</value>
<comment>Template file name extension settings toggle</comment>
</data>
<data name="NewPlus_Hide_Starting_Digits_Toggle.Header" xml:space="preserve">
<value>Hide leading digits, spaces, and dots in template filenames</value>
<value>Hide template filename starting digits, spaces, and dots</value>
<comment>Template filename starting digits settings toggle</comment>
</data>
<data name="NewPlus_Hide_Starting_Digits_Description.Text" xml:space="preserve">
<value>Ignores digits, spaces, and dots at the start of filenames—useful for sorting templates without showing those characters</value>
<value>This option is useful when using digits, spaces and dots at the beginning of filenames to control the display order of templates</value>
<comment>Template filename starting digits settings toggle</comment>
</data>
<data name="NewPlus_behavior.Header" xml:space="preserve">
@@ -4803,13 +4856,13 @@ To record a specific window, enter the hotkey with the Alt key in the opposite m
<value>Open settings</value>
</data>
<data name="LanguageHeader.Header" xml:space="preserve">
<value>Language</value>
<value>Application language</value>
</data>
<data name="LanguageHeader.Description" xml:space="preserve">
<value>PowerToys matches your Windows language by default</value>
<value>PowerToys will use OS language by default.</value>
</data>
<data name="LanguageRestartInfo.Title" xml:space="preserve">
<value>Restart PowerToys to apply language changes</value>
<value>Restart PowerToys for language change to take effect.</value>
</data>
<data name="LanguageRestartInfoButton.Content" xml:space="preserve">
<value>Restart</value>
@@ -5004,7 +5057,7 @@ To record a specific window, enter the hotkey with the Alt key in the opposite m
<value>Generate bug report package</value>
</data>
<data name="GeneralPage_ReportBugPackage.Description" xml:space="preserve">
<value>Log files will be zipped to your desktop</value>
<value>Create zip folder with logs on the Desktop</value>
</data>
<data name="GeneralPageReportBugPackage.Content" xml:space="preserve">
<value>Generate package</value>
@@ -5027,41 +5080,4 @@ To record a specific window, enter the hotkey with the Alt key in the opposite m
<data name="HighlightMode_Spotlight_Mode.Content" xml:space="preserve">
<value>Spotlight</value>
</data>
<data name="LearnMore.Content" xml:space="preserve">
<value>Learn more</value>
</data>
<data name="Awake_ShortDescription" xml:space="preserve">
<value>Keep your PC awake</value>
</data>
<data name="ImageResizer_ShortDescription" xml:space="preserve">
<value>Resize images from right-click context menu</value>
</data>
<data name="MouseWithoutBorders_ShortDescription" xml:space="preserve">
<value>Move your cursor across multiple devices</value>
</data>
<data name="PowerRename_ShortDescription" xml:space="preserve">
<value>Rename files and folders from right-click context menu</value>
</data>
<data name="GeneralPage_EnableDataDiagnosticsText.Text" xml:space="preserve">
<value>Helps us make PowerToys faster, more stable, and better over time</value>
</data>
<data name="UpdateAvailable.Title" xml:space="preserve">
<value>Update available</value>
</data>
<data name="DisabledModules.Text" xml:space="preserve">
<value>Disabled modules</value>
</data>
<data name="EnabledModules.Text" xml:space="preserve">
<value>Enabled modules</value>
</data>
<data name="NewPlus_Product_Description.Description" xml:space="preserve">
<value>Create files and folders from a personalized set of templates</value>
<comment>New+ product description</comment>
</data>
<data name="AlwaysOnTop_Sound.Header" xml:space="preserve">
<value>Play a sound when pinning a window</value>
</data>
<data name="GeneralPage_EnableViewDiagnosticDataText.Text" xml:space="preserve">
<value>Stores diagnostic data locally in .xml format; folder may include .etl files as well. May use up 1GB or more of disk space.</value>
</data>
</root>