Compare commits

..

1 Commits

Author SHA1 Message Date
Enrico Giordani
db88616bc6 [FanzyZones] app history and zone settings granular saving (#9489)
move DeleteFancyZonesRegistryData to proper place
add logging
2021-02-04 14:52:10 +01:00
2701 changed files with 194042 additions and 153470 deletions

38
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,38 @@
---
name: 🐛 Bug report
about: Report errors or unexpected behavior
title: ''
labels: Issue-Bug,Triage-Needed
assignees: ''
---
<!--
**Important: When reporting BSODs or security issues, DO NOT attach memory dumps, logs, or traces to Github issues**.
Instead, send dumps/traces to secure@microsoft.com, referencing this GitHub issue.
-->
## Computer information
- PowerToys version:
- PowerToy Utility:
- Running PowerToys as Admin:
- Windows build number: [run "winver"]
## 📝 Provide detailed reproduction steps (if any)
1.
2.
3.
### ✔️ Expected result
_What is the expected result of the above steps?_
### ❌ Actual result
_What is the actual result of the above steps?_
## 📷 Screenshots
_Are there any useful screenshots? WinKey+Shift+S and then just paste them directly into the form_

View File

@@ -1,94 +0,0 @@
name: "🐛 Bug report"
description: Report errors or unexpected behavior
labels:
- Issue-Bug
- Needs-Triage
body:
- type: markdown
attributes:
value: |
Please make sure to [search for existing issues](https://github.com/microsoft/PowerToys/issues) before filing a new one!
- type: input
attributes:
label: Microsoft PowerToys version
placeholder: |
"0.53.0"
description: |
Hover over system tray icon or look at Settings
validations:
required: true
- type: checkboxes
attributes:
label: Running as admin
description: Are you running PowerToys as Admin?
options:
- label: "Yes"
- type: dropdown
attributes:
label: Area(s) with issue?
description: What things had an issue? Check all that apply.
multiple: true
options:
- General
- Always on Top
- Awake
- ColorPicker
- Developer file preview
- FancyZones
- FancyZones Editor
- Image Resizer
- Keyboard Manager
- MD Preview
- Mouse Utilities
- PDF Preview
- PDF Thumbnail
- G-code Preview
- G-code Thumbnail
- PowerRename
- PowerToys Run
- Shortcut Guide
- STL Thumbnail
- SVG Preview
- SVG Thumbnail
- Settings
- Video Conference Mute
- Welcome / PowerToys Tour window
- System tray interaction
- Installer
validations:
required: true
- type: textarea
attributes:
label: Steps to reproduce
description: We highly suggest including a screenshots and a bug report log (System tray->Report bug).
placeholder: Tell us the steps required to trigger your bug.
validations:
required: true
- type: textarea
attributes:
label: ✔️ Expected Behavior
placeholder: What were you expecting?
validations:
required: false
- type: textarea
attributes:
label: ❌ Actual Behavior
placeholder: What happened instead?
validations:
required: false
- type: textarea
attributes:
label: Other Software
description: If you're reporting a bug about our interaction with other software, what software? What versions?
placeholder: |
vim 8.2 (inside WSL)
OpenSSH_for_Windows_8.1p1
My Cool Application v0.3 (include a code snippet if it would help!)
validations:
required: false

View File

@@ -1,12 +1,15 @@
blank_issues_enabled: false
contact_links:
- name: "\U0001F4F7 Video Conference Mute Issue"
url: https://github.com/microsoft/PowerToys/issues/6246
about: Report Bug for the Video Conference Mute utility
- name: "\U0001F6A8 Microsoft Security Response Center (MSRC)"
url: https://msrc.microsoft.com/create-report
about: Report security bugs
- name: "\U0001F4DA PowerToys user documentation"
url: https://aka.ms/powertoys-docs
url: https://github.com/microsoft/PowerToys/wiki
about: Documentation for users of PowerToys utilities
- name: "\U0001F4DA PowerToys dev documentation"
url: https://github.com/microsoft/PowerToys/tree/main/doc/devdocs
url: https://github.com/microsoft/PowerToys/tree/master/doc/devdocs
about: Documentation for people interested in developing and contributing for PowerToys

View File

@@ -0,0 +1,14 @@
---
name: "\U0001F4DA Documentation Issue"
about: Report issues in our documentation
title: ''
labels: Issue-Docs,Triage-Needed
assignees: ''
---
<!-- Briefly describe which document needs to be corrected and why. -->
## 📝 Provide a description of requested docs changes
_What is the purpose and what should be changed?_

View File

@@ -1,12 +0,0 @@
name: "📚 Documentation Issue"
description: Report issues in our documentation
labels:
- Issue-Docs
- Needs-Triage
body:
- type: textarea
attributes:
label: Provide a description of requested docs changes
placeholder: Briefly describe which document needs to be corrected and why.
validations:
required: true

View File

@@ -0,0 +1,16 @@
---
name: "⭐ Feature request"
about: Propose something new.
title: ''
labels: Triage-Needed
assignees: ''
---
## 📝 Provide a description of the new feature
_What is the expected behavior of the proposed feature? What is the scenario this would be used?_
---
If you'd like to see this feature implemented, add a 👍 reaction to this post.

View File

@@ -1,30 +0,0 @@
name: "⭐ Feature / enhancement request"
description: Propose something new.
labels:
- Needs-Triage
body:
- type: textarea
attributes:
label: Description of the new feature / enhancement
placeholder: |
What is the expected behavior of the proposed feature?
validations:
required: true
- type: textarea
attributes:
label: Scenario when this would be used?
placeholder: |
What is the scenario this would be used? Why is this important to your workflow as a power user?
validations:
required: true
- type: textarea
attributes:
label: Supporting information
placeholder: |
Having additional evidence, data, tweets, blog posts, research, ... anything is extremely helpful. This information provides context to the scenario that may otherwise be lost.
validations:
required: false
- type: markdown
attributes:
value: |
Please limit one request per issue.

View File

@@ -0,0 +1,30 @@
---
name: 📖 Localization/Translation issue
about: Report incorrect translations.
title: ''
labels: Issue-Bug,Area-Localization,Issue-Translation,Triage-Needed
assignees: ''
---
## Computer information
- PowerToys version:
- PowerToy utility:
- Language:
## 📝 Provide where the issue is / 📷 Screenshots
_Are there any useful screenshots? WinKey+Shift+S and then just paste them directly into the form_
### ❌ Actual phrase(s)
_What is there?_
### ✔️ Expected phrase(s)
_What do you expect?_
### Why is the current translation wrong
_If it is opinion based issue, why do you feel this is incorrect? Example: term is outdated_

View File

@@ -1,75 +0,0 @@
name: "🌐 Localization/Translation issue"
description: Report incorrect translations.
labels:
- Issue-Bug
- Area-Localization
- Issue-Translation
- Needs-Triage
body:
- type: markdown
attributes:
value: |
Please make sure to [search for existing issues](https://github.com/microsoft/PowerToys/issues) before filing a new one!
- type: input
attributes:
label: Microsoft PowerToys version
placeholder: "0.53.0"
description: |
Hover over system tray icon or look at Settings
validations:
required: true
- type: dropdown
attributes:
label: Utility with translation issue
options:
- General
- Always on Top
- Awake
- ColorPicker
- Developer file preview
- FancyZones
- FancyZones Editor
- Image Resizer
- Keyboard Manager
- MD Preview
- Mouse Utilities
- PDF Preview
- PDF Thumbnail
- G-code Preview
- G-code Thumbnail
- PowerRename
- PowerToys Run
- Shortcut Guide
- SVG Preview
- SVG Thumbnail
- Settings
- Video Conference Mute
- Welcome / PowerToys Tour window
- System tray interaction
- Installer
validations:
required: true
- type: input
attributes:
label: 🌐 Language affected
placeholder: "German"
validations:
required: true
- type: textarea
attributes:
label: ❌ Actual phrase(s)
placeholder: What is there? Please include a screenshot as that is extremely helpful.
validations:
required: true
- type: textarea
attributes:
label: ✔️ Expected phrase(s)
placeholder: What was expected?
validations:
required: true
- type: textarea
attributes:
label: Why is the current translation wrong
placeholder: Why do you feel this is incorrect?
validations:
required: true

View File

@@ -1,25 +0,0 @@
<!-- See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-advice --> <!-- markdownlint-disable MD033 MD041 -->
<details><summary>If the flagged items do not appear to be text</summary>
If items relate to a ...
* well-formed pattern.
If you can write a [pattern](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns) that would match it,
try adding it to the `patterns.txt` file.
Patterns are Perl 5 Regular Expressions - you can [test](
https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your lines.
Note that patterns can't match multiline strings.
* binary file.
Please add a file path to the `excludes.txt` file matching the containing file.
File paths are Perl 5 Regular Expressions - you can [test](
https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your files.
`^` refers to the file's path from the root of the repository, so `^README\.md$` would exclude [README.md](
../tree/HEAD/README.md) (on whichever branch you're using).
</details>

View File

@@ -1,50 +1,19 @@
# See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-excludes
(?:^|/)monacoSRC/
(?:^|/)MonacoPreviewHandler/languages.json
(?:^|/)MonacoPreviewHandler/index.html
(?:^|/)MonacoPreviewHandler/generateLanguagesJson.html
(?:^|/)(?i)COPYRIGHT
(?:^|/)(?i)LICEN[CS]E
(?:^|/)package(?:-lock)\.json$
(?:^|/)vendor/
(?:^|/)WindowsSettings\.json$
/package(?:-lock|)\.json$
/pinyindb/
/settings-html/
ignore$
[/.][a-z]{2}(?:-[a-zA-Z]{2}|)\.
\.ai$
\.bmp$
\.dat$
\.dll$
\.filters$
\.gcode$
\.gif$
\.gitignore$
\.ico$
\.jpg$
\.lcl$
\.lock$
\.min\.
\.mod$
\.pdf$
\.PNG$
\.png$
\.stl$
\.PNG$
\.woff$
\.zip$
^doc/devdocs/akaLinks\.md$
^src/common/logger/logger\.vcxproj\.filters$
^src/common/notifications/BackgroundActivatorDLL/BackgroundActivator\.vcxproj\.filters$
^src/common/notifications/BackgroundActivatorDLL/cpp\.hint$
^src/modules/colorPicker/ColorPickerUI/Resources/colorPicker\.cur$
^src/modules/fancyzones/lib/FancyZonesWinHookEventIDs\.h$
^src/modules/imageresizer/dll/ContextMenuHandler\.rgs$
^src/modules/imageresizer/dll/ImageResizerExt\.rgs$
^src/modules/powerrename/testapp/PowerRenameTest\.vcxproj\.filters$
^src/modules/previewpane/PreviewPaneUnitTests/HelperFiles/MarkdownWithHTMLImageTag\.txt$
^src/modules/previewpane/UnitTests-MarkdownPreviewHandler/HelperFiles/MarkdownWithHTMLImageTag.txt$
^tools/CleanUp_tool/CleanUp_tool\.vcxproj\.filters$
^\.github/
^\.github/actions/spell-check/
^\.gitmodules$
/package(?:-lock|)\.json$
/pinyindb/
/settings-html/
[/.][a-z]{2}(?:-[a-zA-Z]{2}|)\.

File diff suppressed because it is too large Load Diff

View File

@@ -1,38 +1,11 @@
# See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns
https?://(?:(?:www\.|)youtube\.com|youtu.be)/[-a-zA-Z0-9?&=]*
# GitHub SHAs
\bapi.github\.com/repos/[^/]+/[^/]+/[^/]+/[0-9a-f]+\b
://github\.(?:com|blog)/[^\w")]+
(?:\[[0-9a-f]+\]\(https:/|)/github\.com/[^/]+/[^/]+/[^/]+/[0-9a-f]+(?:[-0-9a-zA-Z/#.]*|)\b
# githubusercontent
://githubusercontent\.com/[^\w")]+
# gist github
/gist\.github\.com/[^/]+/[0-9a-f]+
# msdn
\b(?:download\.visualstudio|docs|msdn)\.microsoft\.com/[-_a-zA-Z0-9()=./]*
publicKeyToken=(['"]|)[0-9a-f]+\g{-1}
\@sha256:[0-9a-f]{64}\b
# data urls
(['"])data:.*?\g{-1}
data:[-a-zA-Z=;:/0-9+]*,\S*
# uuid:
L?(["']|[-<({>]|\b)[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}(?:\g{-1}|[<})>])
# c99 hex digits (not the full format, just one I've seen)
data:[a-zA-Z=;,/0-9+-]+
0x[0-9a-fA-F](?:\.[0-9a-fA-F]*|)[pP]
# wregex
std::wregex\(L"[^"]*"\)
# hex digits including css/html color classes:
(?:[\\0][xX]|\\u|[uU]\+|#x?|\%23|L")[0-9a-fA-FgGrR_]{2,}(?:[uU]?[lL]{0,2}|u\d+)\b
# ignore long runs of a single character:
\b([A-Za-z])\g{-1}{3,}\b
(?:0[Xx]|U\+|#)[a-f0-9A-FGgRr]{2,}[Uu]?[Ll]{0,2}\b
[{"][0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}[}"]
\b([A-Za-z])\1{3,}\b
(?:L"[abAB]+", ){3}L"[abAB]+"
"Lorem[^"]+?\."
TestCase\("[^"]+"
@@ -44,8 +17,6 @@ TestCase\("[^"]+"
# Windows paths
\\native
\\netcoreapp
\\netstandard
\\notifications
\\recyclebin
\\reinstall
@@ -56,7 +27,6 @@ TestCase\("[^"]+"
\\restore
\\result
\\runner
\\runtimes
\\Telemetry
\\telemetry
\\testapp
@@ -72,11 +42,6 @@ TestCase\("[^"]+"
# Id info inside markdown file (registry.md)
^\|\s+ID\s+\|\s*\`[0-9A-F]{32}\`
# TestCase strings intentionally have non dictionary items
\[TestCase\(new string.*\]
# marker for ignoring a comment to the end of the line
^.*/\* #no-spell-check-line \*/.*$
// #no-spell-check.*$
http://tes/
// #no-spell-check.*$

View File

@@ -2,7 +2,7 @@
**What is this about:**
**What is included in the PR:**
**What is include in the PR:**
**How does someone test / validate:**
@@ -16,8 +16,8 @@
- [ ] **Docs:** Added/ updated
- [ ] **Binaries:** Any new files are added to WXS / YML
- [ ] No new binaries
- [ ] [YML for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/pipeline.user.windows.yml#L68) for new binaries
- [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries
- [ ] [YML for signing](https://github.com/microsoft/PowerToys/blob/master/.pipelines/pipeline.user.windows.yml#L68) for new binaries
- [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/master/installer/PowerToysSetup/Product.wxs) for new binaries
## Contributor License Agreement (CLA)
A CLA must be signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/PowerToys) and sign the CLA.

20
.github/workflows/spelling.yml vendored Normal file
View File

@@ -0,0 +1,20 @@
name: Spell checking
on:
push:
schedule:
# * is a special character in YAML so you have to quote this string
- cron: '15 * * * *'
jobs:
build:
name: Spell checking
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.0.0
with:
fetch-depth: 5
- uses: check-spelling/check-spelling@0.0.16-alpha
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
bucket: .github/actions
project: spell-check

View File

@@ -1,77 +0,0 @@
# spelling.yml is blocked per https://github.com/check-spelling/check-spelling/security/advisories/GHSA-g86g-chm8-7r2p
name: Spell checking
on:
pull_request_target:
push:
branches: ["**"]
tags-ignore: ["**"]
jobs:
spelling:
name: Spell checking
permissions:
contents: read
pull-requests: read
outputs:
internal_state_directory: ${{ steps.spelling.outputs.internal_state_directory }}
runs-on: ubuntu-latest
if: "contains(github.event_name, 'pull_request') || github.event_name == 'push'"
concurrency:
group: spelling-${{ github.event.pull_request.number || github.ref }}
# note: If you use only_check_changed_files, you do not want cancel-in-progress
cancel-in-progress: true
steps:
- name: checkout-merge
if: "contains(github.event_name, 'pull_request')"
uses: actions/checkout@v2
with:
ref: refs/pull/${{github.event.pull_request.number}}/merge
- name: checkout
if: github.event_name == 'push'
uses: actions/checkout@v2
- name: check-spelling
id: spelling
uses: check-spelling/check-spelling@v0.0.20-alpha3
with:
config: .github/actions/spell-check
suppress_push_for_open_pull_request: 1
post_comment: 0
extra_dictionaries:
cspell:filetypes/filetypes.txt
cspell:html/html.txt
cspell:css/css.txt
check_extra_dictionaries: ''
- name: store-comment
if: failure()
uses: actions/upload-artifact@v2
with:
retention-days: 1
name: "check-spelling-comment-${{ github.run_id }}"
path: |
${{ steps.spelling.outputs.internal_state_directory }}
comment:
name: Comment
runs-on: ubuntu-latest
needs: spelling
permissions:
contents: write
pull-requests: write
if: always() && needs.spelling.result == 'failure' && needs.spelling.outputs.internal_state_directory
steps:
- name: checkout
uses: actions/checkout@v2
- name: set up
run: |
mkdir /tmp/data
- name: retrieve-comment
uses: actions/download-artifact@v2
with:
name: "check-spelling-comment-${{ github.run_id }}"
path: /tmp/data
- name: comment
uses: check-spelling/check-spelling@v0.0.20-alpha3
with:
config: .github/actions/spell-check
custom_task: comment
internal_state_directory: /tmp/data

5
.gitignore vendored
View File

@@ -342,8 +342,3 @@ src/common/Telemetry/*.etl
!**/MergeModules/Release/
!**/MergeModules/Debug/
/src/modules/previewpane/SvgThumbnailProvider/$(SolutionDir)$(Platform)/$(Configuration)/modules/FileExplorerPreview/SvgThumbnailProvider.xml
/src/modules/powerrename/ui/RCa24464
/src/modules/powerrename/ui/RCb24464
# Generated installer file for Monaco source files.
/installer/PowerToysSetup/MonacoSRC.wxs

View File

@@ -1,41 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<SiPolicy xmlns="urn:schemas-microsoft-com:sipolicy">
<VersionEx>10.0.0.0</VersionEx>
<PlatformID>{2E07F7E4-194C-4D20-B7C9-6F44A6C5A234}</PlatformID>
<Rules>
<Rule>
<Option>Enabled:Unsigned System Integrity Policy</Option>
</Rule>
<Rule>
<Option>Enabled:Audit Mode</Option>
</Rule>
<Rule>
<Option>Enabled:Advanced Boot Options Menu</Option>
</Rule>
<Rule>
<Option>Required:Enforce Store Applications</Option>
</Rule>
<Rule>
<Option>Disabled:Script Enforcement</Option>
</Rule>
</Rules>
<!--EKUS-->
<EKUs />
<!--File Rules-->
<FileRules />
<!--Signers-->
<Signers />
<!--Driver Signing Scenarios-->
<SigningScenarios>
<SigningScenario Value="131" ID="ID_SIGNINGSCENARIO_DRIVERS_1" FriendlyName="Auto generated policy on 01-26-2021">
<ProductSigners />
</SigningScenario>
<SigningScenario Value="12" ID="ID_SIGNINGSCENARIO_WINDOWS" FriendlyName="Auto generated policy on 01-26-2021">
<ProductSigners />
</SigningScenario>
</SigningScenarios>
<UpdatePolicySigners />
<CiSigners />
<HvciOptions>0</HvciOptions>
<PolicyTypeID>{A244370E-44C9-4C06-B551-F6016E563076}</PolicyTypeID>
</SiPolicy>

View File

@@ -1,243 +0,0 @@
{
"Version": "1.0.0",
"UseMinimatch": false,
"SignBatches": [
{
"MatchedPath": [
"*.resources.dll",
"PowerToysSetupCustomActions.dll",
"PowerToys.ActionRunner.exe",
"PowerToys.Update.exe",
"PowerToys.BackgroundActivatorDLL.dll",
"Notifications.dll",
"os-detection.dll",
"PowerToys.exe",
"PowerToys.Interop.dll",
"BugReportTool\\PowerToys.BugReportTool.exe",
"WebcamReportTool\\PowerToys.WebcamReportTool.exe",
"Telemetry.dll",
"PowerToys.ManagedTelemetry.dll",
"PowerToys.ManagedCommon.dll",
"PowerToys.Common.UI.dll",
"PowerToys.Settings.UI.Lib.dll",
"modules\\AlwaysOnTop\\PowerToys.AlwaysOnTop.exe",
"modules\\AlwaysOnTop\\PowerToys.AlwaysOnTopModuleInterface.dll",
"modules\\ColorPicker\\ColorPicker.dll",
"modules\\ColorPicker\\ColorPickerUI.dll",
"modules\\ColorPicker\\ColorPickerUI.exe",
"modules\\ColorPicker\\PowerToys.ColorPicker.dll",
"modules\\ColorPicker\\PowerToys.ColorPickerUI.dll",
"modules\\ColorPicker\\PowerToys.ColorPickerUI.exe",
"modules\\Awake\\PowerToys.AwakeModuleInterface.dll",
"modules\\Awake\\PowerToys.Awake.exe",
"modules\\Awake\\PowerToys.Awake.dll",
"modules\\FancyZones\\fancyzones.dll",
"modules\\FancyZones\\PowerToys.FancyZonesEditor.exe",
"modules\\FancyZones\\PowerToys.FancyZonesEditor.dll",
"modules\\FancyZones\\PowerToys.FancyZonesModuleInterface.dll",
"modules\\FancyZones\\PowerToys.FancyZones.exe",
"modules\\FileExplorerPreview\\PowerToys.GcodePreviewHandler.dll",
"modules\\FileExplorerPreview\\PowerToys.GcodePreviewHandler.comhost.dll",
"modules\\FileExplorerPreview\\PowerToys.GcodeThumbnailProvider.dll",
"modules\\FileExplorerPreview\\PowerToys.GcodeThumbnailProvider.comhost.dll",
"modules\\FileExplorerPreview\\PowerToys.ManagedTelemetry.dll",
"modules\\FileExplorerPreview\\PowerToys.MarkdownPreviewHandler.dll",
"modules\\FileExplorerPreview\\PowerToys.MarkdownPreviewHandler.comhost.dll",
"modules\\FileExplorerPreview\\PowerToys.MonacoPreviewHandler.dll",
"modules\\FileExplorerPreview\\PowerToys.MonacoPreviewHandler.comhost.dll",
"modules\\FileExplorerPreview\\PowerToys.PdfPreviewHandler.dll",
"modules\\FileExplorerPreview\\PowerToys.PdfPreviewHandler.comhost.dll",
"modules\\FileExplorerPreview\\PowerToys.PdfThumbnailProvider.dll",
"modules\\FileExplorerPreview\\PowerToys.PdfThumbnailProvider.comhost.dll",
"modules\\FileExplorerPreview\\PowerToys.powerpreview.dll",
"modules\\FileExplorerPreview\\PowerToys.PreviewHandlerCommon.dll",
"modules\\FileExplorerPreview\\PowerToys.StlThumbnailProvider.dll",
"modules\\FileExplorerPreview\\PowerToys.StlThumbnailProvider.comhost.dll",
"modules\\FileExplorerPreview\\PowerToys.SvgPreviewHandler.dll",
"modules\\FileExplorerPreview\\PowerToys.SvgPreviewHandler.comhost.dll",
"modules\\FileExplorerPreview\\PowerToys.SvgThumbnailProvider.dll",
"modules\\FileExplorerPreview\\PowerToys.SvgThumbnailProvider.comhost.dll",
"modules\\ImageResizer\\PowerToys.ImageResizer.exe",
"modules\\ImageResizer\\PowerToys.ImageResizer.dll",
"modules\\ImageResizer\\PowerToys.ImageResizerExt.dll",
"modules\\KeyboardManager\\PowerToys.KeyboardManager.dll",
"modules\\KeyboardManager\\KeyboardManagerEditor\\PowerToys.KeyboardManagerEditor.exe",
"modules\\KeyboardManager\\KeyboardManagerEngine\\PowerToys.KeyboardManagerEngine.exe",
"modules\\launcher\\PowerToys.Launcher.dll",
"modules\\launcher\\PowerToys.PowerLauncher.dll",
"modules\\launcher\\PowerToys.PowerLauncher.exe",
"modules\\launcher\\PowerToys.PowerLauncher.Telemetry.dll",
"modules\\launcher\\Wox.dll",
"modules\\launcher\\Wox.Infrastructure.dll",
"modules\\launcher\\Wox.Plugin.dll",
"modules\\launcher\\Plugins\\Calculator\\Microsoft.PowerToys.Run.Plugin.Calculator.dll",
"modules\\launcher\\Plugins\\Folder\\Microsoft.Plugin.Folder.dll",
"modules\\launcher\\Plugins\\Indexer\\Microsoft.Plugin.Indexer.dll",
"modules\\launcher\\Plugins\\Program\\Microsoft.Plugin.Program.dll",
"modules\\launcher\\Plugins\\Registry\\Microsoft.PowerToys.Run.Plugin.Registry.dll",
"modules\\launcher\\Plugins\\WindowsSettings\\Microsoft.PowerToys.Run.Plugin.WindowsSettings.dll",
"modules\\launcher\\Plugins\\Shell\\Microsoft.Plugin.Shell.dll",
"modules\\launcher\\Plugins\\Uri\\Microsoft.Plugin.Uri.dll",
"modules\\launcher\\Plugins\\WindowWalker\\Microsoft.Plugin.WindowWalker.dll",
"modules\\launcher\\Plugins\\UnitConverter\\Community.PowerToys.Run.Plugin.UnitConverter.dll",
"modules\\launcher\\Plugins\\VSCodeWorkspaces\\Community.PowerToys.Run.Plugin.VSCodeWorkspaces.dll",
"modules\\launcher\\Plugins\\Service\\Microsoft.PowerToys.Run.Plugin.Service.dll",
"modules\\launcher\\Plugins\\System\\Microsoft.PowerToys.Run.Plugin.System.dll",
"modules\\launcher\\Plugins\\WebSearch\\Community.PowerToys.Run.Plugin.WebSearch.dll",
"modules\\launcher\\Plugins\\WindowsTerminal\\Microsoft.PowerToys.Run.Plugin.WindowsTerminal.dll",
"modules\\MouseUtils\\PowerToys.FindMyMouse.dll",
"modules\\MouseUtils\\PowerToys.MouseHighlighter.dll",
"modules\\MouseUtils\\PowerToys.MousePointerCrosshairs.dll",
"modules\\PowerRename\\PowerToys.PowerRenameExt.dll",
"modules\\PowerRename\\PowerToys.PowerRenameUILib.dll",
"modules\\PowerRename\\PowerToys.PowerRename.exe",
"modules\\ShortcutGuide\\ShortcutGuide\\PowerToys.ShortcutGuide.exe",
"modules\\ShortcutGuide\\ShortcutGuideModuleInterface\\PowerToys.ShortcutGuideModuleInterface.dll",
"modules\\VideoConference\\PowerToys.VideoConferenceModule.dll",
"modules\\VideoConference\\PowerToys.VideoConferenceProxyFilter_x86.dll",
"modules\\VideoConference\\PowerToys.VideoConferenceProxyFilter_x64.dll",
"Settings\\PowerToys.Settings.UI.exe",
"Settings\\PowerToys.Settings.dll",
"Settings\\PowerToys.Settings.exe"
],
"SigningInfo": {
"Operations": [
{
"KeyCode": "CP-230012",
"OperationSetCode": "SigntoolSign",
"Parameters": [
{
"parameterName": "OpusName",
"parameterValue": "Microsoft"
},
{
"parameterName": "OpusInfo",
"parameterValue": "http://www.microsoft.com"
},
{
"parameterName": "FileDigest",
"parameterValue": "/fd \"SHA256\""
},
{
"parameterName": "PageHash",
"parameterValue": "/NPH"
},
{
"parameterName": "TimeStamp",
"parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
}
],
"ToolName": "sign",
"ToolVersion": "1.0"
},
{
"KeyCode": "CP-230012",
"OperationSetCode": "SigntoolVerify",
"Parameters": [],
"ToolName": "sign",
"ToolVersion": "1.0"
}
]
}
},
{
"MatchedPath": [
"Microsoft.Search.Interop.dll",
"ModernWpf.dll",
"ModernWpf.Controls.dll",
"System.IO.Abstractions.dll",
"Mono.Cecil.dll",
"Mono.Cecil.Mdb.dll",
"Mono.Cecil.Pdb.dll",
"Mono.Cecil.Rocks.dll",
"NLog.dll",
"HtmlAgilityPack.dll",
"Markdig.Signed.dll",
"HelixToolkit.dll",
"HelixToolkit.Core.Wpf.dll",
"Mages.Core.dll",
"JetBrains.Annotations.dll",
"NLog.Extensions.Logging.dll",
"concrt140_app.dll",
"msvcp140_1_app.dll",
"msvcp140_2_app.dll",
"msvcp140_app.dll",
"vcamp140_app.dll",
"vccorlib140_app.dll",
"vcomp140_app.dll",
"vcruntime140_1_app.dll",
"vcruntime140_app.dll",
"modules\\FileExplorerPreview\\Microsoft.Web.WebView2.Core.dll",
"modules\\FileExplorerPreview\\Microsoft.Web.WebView2.WinForms.dll",
"modules\\FileExplorerPreview\\Microsoft.Web.WebView2.Wpf.dll",
"modules\\FileExplorerPreview\\runtimes\\win-x64\\native\\WebView2Loader.dll",
"modules\\launcher\\e_sqlite3.dll",
"modules\\launcher\\SQLitePCLRaw.batteries_v2.dll",
"modules\\launcher\\SQLitePCLRaw.core.dll",
"modules\\launcher\\SQLitePCLRaw.provider.e_sqlite3.dll",
"ColorCode.Core.dll",
"ColorCode.UWP.dll",
"UnitsNet.dll"
],
"SigningInfo": {
"Operations": [
{
"KeyCode": "CP-231522",
"OperationSetCode": "SigntoolSign",
"Parameters": [
{
"parameterName": "OpusName",
"parameterValue": "Microsoft"
},
{
"parameterName": "OpusInfo",
"parameterValue": "http://www.microsoft.com"
},
{
"parameterName": "FileDigest",
"parameterValue": "/fd \"SHA256\""
},
{
"parameterName": "Append",
"parameterValue": "/as"
},
{
"parameterName": "PageHash",
"parameterValue": "/NPH"
},
{
"parameterName": "TimeStamp",
"parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
}
],
"ToolName": "sign",
"ToolVersion": "1.0"
},
{
"KeyCode": "CP-231522",
"OperationSetCode": "SigntoolVerify",
"Parameters": [],
"ToolName": "sign",
"ToolVersion": "1.0"
}
]
}
}
]
}

View File

@@ -1,51 +0,0 @@
{
"Version": "1.0.0",
"UseMinimatch": false,
"SignBatches": [
{
"MatchedPath": [
"PowerToysSetup-*.exe",
"PowerToysSetup-*.msi"
],
"SigningInfo": {
"Operations": [
{
"KeyCode": "CP-230012",
"OperationSetCode": "SigntoolSign",
"Parameters": [
{
"parameterName": "OpusName",
"parameterValue": "Microsoft"
},
{
"parameterName": "OpusInfo",
"parameterValue": "http://www.microsoft.com"
},
{
"parameterName": "FileDigest",
"parameterValue": "/fd \"SHA256\""
},
{
"parameterName": "PageHash",
"parameterValue": "/NPH"
},
{
"parameterName": "TimeStamp",
"parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
}
],
"ToolName": "sign",
"ToolVersion": "1.0"
},
{
"KeyCode": "CP-230012",
"OperationSetCode": "SigntoolVerify",
"Parameters": [],
"ToolName": "sign",
"ToolVersion": "1.0"
}
]
}
}
]
}

View File

@@ -1,50 +0,0 @@
{
"Version": "1.0.0",
"UseMinimatch": false,
"SignBatches": [
{
"MatchedPath": [
"modules\\VideoConference\\PowerToys.VideoConferenceProxyFilter_x86.dll"
],
"SigningInfo": {
"Operations": [
{
"KeyCode": "CP-230012",
"OperationSetCode": "SigntoolSign",
"Parameters": [
{
"parameterName": "OpusName",
"parameterValue": "Microsoft"
},
{
"parameterName": "OpusInfo",
"parameterValue": "http://www.microsoft.com"
},
{
"parameterName": "FileDigest",
"parameterValue": "/fd \"SHA256\""
},
{
"parameterName": "PageHash",
"parameterValue": "/NPH"
},
{
"parameterName": "TimeStamp",
"parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
}
],
"ToolName": "sign",
"ToolVersion": "1.0"
},
{
"KeyCode": "CP-230012",
"OperationSetCode": "SigntoolVerify",
"Parameters": [],
"ToolName": "sign",
"ToolVersion": "1.0"
}
]
}
}
]
}

View File

@@ -0,0 +1,10 @@
cd /D "%~dp0"
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64 -winsdk=10.0.18362.0
pushd .
cd ..
set SolutionDir=%cd%
popd
SET IsPipeline=1
call msbuild ../installer/PowerToysBootstrapper/PowerToysBootstrapper.sln /p:Configuration=Release /p:Platform=x64 /p:CIBuild=true || exit /b 1

View File

@@ -2,4 +2,4 @@ cd /D "%~dp0"
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64 -winsdk=10.0.18362.0
SET IsPipeline=1
call msbuild ../installer/PowerToysSetup.sln /target:PowerToysInstaller /p:Configuration=Release /p:Platform=x64 /p:CIBuild=true || exit /b 1
call msbuild ../installer/PowerToysSetup.sln /p:Configuration=Release /p:Platform=x64 /p:CIBuild=true || exit /b 1

View File

@@ -0,0 +1,33 @@
@echo off
rem This script will fail to run unless you have the appropriate permissions
cd /D "%~dp0"
echo Preparing localization build...
setlocal
rem In this sample, the repo root is identical to the script directory path. Adjust the value of the RepoRoot variable accordingly based on your environment.
rem Again, ensure the RepoRoot variable is set to the real repo root location, otherwise the localization toolset wouldn't work as intended.
rem Note that the resolved %~dp0 ends with \.
set RepoRootWithoutBackslash=%~dp0..
set RepoRoot=%RepoRootWithoutBackslash%\
set OutDir=%RepoRoot%out
set NUGET_PACKAGES=%RepoRoot%packages
set LocalizationXLocPkgVer=2.0.0
echo Running localization build...
set XLocPath=%NUGET_PACKAGES%\Localization.XLoc.%LocalizationXLocPkgVer%
set LocProjectDirectory=%RepoRootWithoutBackslash%
rem Run the localization tool on all LocProject.json files in the src directory and it's subdirectories (directory format must not end with \)
dotnet "%XLocPath%\tools\netcore\Microsoft.Localization.XLoc.dll" /f "%LocProjectDirectory%"
echo Localization build finished with exit code '%errorlevel%'.
rem Move UWP resource files to correct file paths as per file path expected by UWP project
cd %RepoRootWithoutBackslash%
powershell -NonInteractive -executionpolicy Unrestricted ".\tools\localization\move_uwp_resources.ps1"
exit /b %errorlevel%

View File

@@ -0,0 +1,10 @@
cd /D "%~dp0"
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64 -winsdk=10.0.18362.0
pushd .
cd ..
set SolutionDir=%cd%
popd
SET IsPipeline=1
call msbuild ../tools/BugReportTool/BugReportTool.sln /p:Configuration=Release /p:Platform=x64 /p:CIBuild=true || exit /b 1

6
.pipelines/build.cmd Normal file
View File

@@ -0,0 +1,6 @@
cd /D "%~dp0"
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64 -winsdk=10.0.18362.0
call msbuild -m ../PowerToys.sln /p:Configuration=Release /p:Platform=x64 /p:CIBuild=true || exit /b 1
SET PTRoot=..
call "..\installer\PowerToysSetup\publish.cmd"

View File

@@ -2,7 +2,7 @@ trigger:
batch: true
branches:
include:
- main
- master
- stable
paths:
exclude:
@@ -13,7 +13,7 @@ trigger:
pr:
branches:
include:
- main
- master
- stable
# 0.0.yyMM.dd##

View File

@@ -9,11 +9,7 @@ jobs:
variables:
BuildConfiguration: ${{ parameters.configuration }}
BuildPlatform: ${{ parameters.platform }}
pool:
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
name: WinDevPoolOSS-L
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
name: WinDevPool-L
pool: "windevbuildagents"
timeoutInMinutes: 120
strategy:
maxParallel: 10

View File

@@ -1,20 +0,0 @@
parameters:
configuration: 'Release'
platform: ''
additionalBuildArguments: '-m'
jobs:
- job: Build${{ parameters.platform }}${{ parameters.configuration }}
displayName: Build ${{ parameters.platform }} ${{ parameters.configuration }}
variables:
BuildConfiguration: ${{ parameters.configuration }}
BuildPlatform: ${{ parameters.platform }}
pool:
name: WinDevPool-L
timeoutInMinutes: 120
strategy:
maxParallel: 10
steps:
- template: build-powertoys-steps.yml
parameters:
additionalBuildArguments: ${{ parameters.additionalBuildArguments }}

View File

@@ -55,25 +55,6 @@ steps:
msbuildArgs: ${{ parameters.additionalBuildArguments }}
maximumCpuCount: true
- task: NuGetCommand@2
displayName: Restore NuGet packages for WebcamReportTool.sln
inputs:
command: restore
feedsToUse: config
configPath: NuGet.config
restoreSolution: tools\WebcamReportTool\WebcamReportTool.sln
restoreDirectory: '$(Build.SourcesDirectory)\tools\WebcamReportTool\packages'
- task: VSBuild@1
displayName: 'Build WebcamReportTool.sln'
inputs:
solution: '**\WebcamReportTool.sln'
vsVersion: 16.0
platform: '$(BuildPlatform)'
configuration: '$(BuildConfiguration)'
msbuildArgs: ${{ parameters.additionalBuildArguments }}
maximumCpuCount: true
- task: NuGetCommand@2
displayName: Restore NuGet packages for PowerToysSetup.sln
inputs:
@@ -93,51 +74,65 @@ steps:
msbuildArgs: ${{ parameters.additionalBuildArguments }}
maximumCpuCount: true
- task: NuGetCommand@2
displayName: Restore NuGet packages for PowerToysBootstrapper.sln
inputs:
command: restore
feedsToUse: config
configPath: NuGet.config
restoreSolution: installer\PowerToysBootstrapper\PowerToysBootstrapper.sln
restoreDirectory: '$(Build.SourcesDirectory)\installer\PowerToysBootstrapper\packages'
- task: VSBuild@1
displayName: 'Build PowerToysBootstrapper.sln'
inputs:
solution: '**\installer\PowerToysBootstrapper\PowerToysBootstrapper.sln'
vsVersion: 16.0
platform: '$(BuildPlatform)'
configuration: '$(BuildConfiguration)'
msbuildArgs: ${{ parameters.additionalBuildArguments }}
maximumCpuCount: true
# directly not doing WinAppDriver testing
- task: VSTest@2
displayName: 'MS Tests'
displayName: 'Run .Net Core Tests 1'
inputs:
platform: '$(BuildPlatform)'
configuration: '$(BuildConfiguration)'
testSelector: 'testAssemblies'
testAssemblyVer2: |
**\UnitTests-GcodeThumbnailProvider.dll
**\UnitTests-SvgThumbnailProvider.dll
**\UnitTests-StlThumbnailProvider.dll
**\UnitTests-PdfThumbnailProvider.dll
**\Settings.UI.UnitTests.dll
**\UnitTests-MarkdownPreviewHandler.dll
**\UnitTests-GcodePreviewHandler.dll
**\UnitTests-PdfPreviewHandler.dll
**\UnitTests-SvgPreviewHandler.dll
**\UnitTests-PreviewHandlerCommon.dll
**\PreviewPaneUnitTests.dll
**\Microsoft.PowerToys.Run.Plugin.Registry.UnitTests.dll
**\UnitTest-ColorPickerUI.dll
**\Microsoft.Interop.Tests.dll
**\ImageResizer.Test.dll
**\Community.PowerToys.Run.Plugin.UnitConverter.UnitTest.dll
**\Microsoft.Plugin.Folder.UnitTests.dll
**\Microsoft.Plugin.Folder.UnitTest.dll
**\Microsoft.Plugin.Program.UnitTests.dll
**\Microsoft.PowerToys.Run.Plugin.Calculator.UnitTest.dll
**\Microsoft.Plugin.Uri.UnitTests.dll
**\Wox.Test.dll
**\Microsoft.PowerToys.Run.Plugin.System.UnitTests.dll
**\Microsoft.PowerToys.Run.Plugin.WindowsTerminal.UnitTests.dll
**\Microsoft.PowerToys.Settings.UI.UnitTests.dll
**\UnitTest-ColorPickerUI.dll
**\Microsoft.Interop.Tests.dll
!**\obj\**
!**\ref\**
# Native dlls
- task: VSTest@2
displayName: 'Native Tests'
displayName: 'Run .Net Core Tests 2'
inputs:
platform: '$(BuildPlatform)'
configuration: '$(BuildConfiguration)'
testSelector: 'testAssemblies'
testAssemblyVer2: |
**\KeyboardManagerEngineTest.dll
**\KeyboardManagerEditorTest.dll
**\UnitTests-CommonLib.dll
**\PowerRenameUnitTests.dll
**\PreviewPaneUnitTests.dll #this is the markdown tests
**\UnitTests-PreviewHandlerCommon.dll
**\UnitTests-SvgPreviewHandler.dll
**\ImageResizer.Test.dll
**\powerpreviewTest.dll
!**\obj\**
# Native dlls
- task: VSTest@2
displayName: 'Run Native Tests'
inputs:
platform: '$(BuildPlatform)'
configuration: '$(BuildConfiguration)'
testSelector: 'testAssemblies'
testAssemblyVer2: |
**\KeyboardManagerTest.dll
**\UnitTests-CommonLib.dll
**\PowerRenameUnitTests.dll
!**\obj\**

View File

@@ -1,52 +0,0 @@
trigger: none
pr: none
schedules:
- cron: "0 3 * * 2-6" # Run at 03:00 UTC Tuesday through Saturday (After the work day in Pacific, Mon-Fri)
displayName: "Nightly Localization Build"
branches:
include:
- main
always: false # only run if there's code changes!
pool:
vmImage: windows-2019
resources:
repositories:
- repository: self
type: git
ref: master
steps:
- checkout: self
clean: true
submodules: false
fetchDepth: 1 # Don't need a deep checkout for loc files!
persistCredentials: true
- task: MicrosoftTDBuild.tdbuild-task.tdbuild-task.TouchdownBuildTask@1
displayName: 'Touchdown Build - 37400, PRODEXT'
inputs:
teamId: 37400
authId: '$(TouchdownApplicationID)'
authKey: '$(TouchdownApplicationKey)'
resourceFilePath: |
**\Resources.resx
**\Resource.resx
**\Resources.resw
outputDirectoryRoot: LocOutput
appendRelativeDir: true
pseudoSetting: Included
# Saving one of these makes it really easy to inspect the loc output...
- powershell: 'tar czf LocOutput.tar.gz LocOutput'
displayName: 'PowerShell Script'
- task: PublishBuildArtifacts@1
displayName: 'Publish Artifact: LocOutput'
inputs:
PathtoPublish: LocOutput.tar.gz
ArtifactName: LocOutput

View File

@@ -0,0 +1,21 @@
static_analysis_options:
fxcop_options:
disable_tool_scan: false
policheck_options:
fail_on_error: true
moderncop_options:
fail_on_error: true
files_to_scan:
- from: 'src'
exclude:
- '**/just.config.js'
- '**/webpack.config.js'
- '**/webpack.serve.config.js'
- '**/dist/bundle.js'
binskim_options:
disable_tool_scan: false
files_to_scan:
- from: 'installer/packages'
exclude:
- 'WiX.3.11.1/**/*.dll'
- 'Wix.3.11.1/**/*.exe'

View File

@@ -0,0 +1,232 @@
environment:
host:
os: 'windows'
flavor: 'server'
version: '2019'
runtime:
provider: 'appcontainer'
# we will want to shift this to latest in the near future but this unblocks us
image: 'cdpxwin1809.azurecr.io/global/vse2019@sha256:44a8af0de5efa68829dbdfc3ecef3864d9770f1fc426b897fc37888032c9f60c'
source_mode: 'map'
version:
name: 'PowerToys'
major: 1
minor: 0
signing_options:
profile: 'external_distribution'
package_sources:
nuget:
feeds:
'Nuget': 'https://api.nuget.org/v3/index.json'
'Toolset': 'https://msazure.pkgs.visualstudio.com/_packaging/Toolset/nuget/v3/index.json'
'PipelineBuildSupplement': 'https://msazure.pkgs.visualstudio.com/_packaging/PipelineBuildSupplement/nuget/v3/index.json'
restore:
commands:
- !!defaultcommand
name: 'Restore Power Toys Telemetry'
command: '.pipelines\restore-telemetry.cmd'
- !!defaultcommand
name: 'Restore Power Toys'
command: '.pipelines\restore.cmd'
- !!defaultcommand
name: 'Restore Installer'
command: '.pipelines\restore-installer.cmd'
- !!defaultcommand
name: 'Restore Localization packages'
command: '.pipelines\restore-localization.cmd'
- !!defaultcommand
name: 'Restore Tools packages'
command: '.pipelines\restore-tools.cmd'
build:
commands:
# Localize the files before the Build PowerToys step to generate translated resx files from the lcl files
- !!buildcommand
name: 'Localize Power Toys'
command: '.pipelines\build-localization.cmd'
artifacts:
- from: 'out\loc'
to: 'loc'
include:
- '**/*'
- !!buildcommand
name: 'Build Power Toys'
command: '.pipelines\build.cmd'
artifacts:
- to: 'Symbols'
include:
- 'x64/**/*.pdb'
exclude:
- 'x64/Release/obj/**/*.pdb'
- from: 'x64/Release'
to: 'Build_Output'
include:
- 'action_runner.exe'
- 'BugReportTool\BugReportTool.exe'
- 'modules\ColorPicker\ColorPicker.dll'
- 'modules\ColorPicker\ColorPickerUI.dll'
- 'modules\ColorPicker\ColorPickerUI.exe'
- 'modules\ColorPicker\ManagedCommon.dll'
- 'modules\ColorPicker\Microsoft.PowerToys.Common.UI.dll'
- 'modules\ColorPicker\Microsoft.PowerToys.Settings.UI.Lib.dll'
- 'modules\ColorPicker\PowerToysInterop.dll'
- 'modules\ColorPicker\Telemetry.dll'
- '**\*.resources.dll'
- 'modules\FancyZones\fancyzones.dll'
- 'modules\FancyZones\FancyZonesEditor.exe'
- 'modules\FancyZones\FancyZonesEditor.dll'
- 'modules\FancyZones\ManagedCommon.dll'
- 'modules\FancyZones\Telemetry.dll'
- 'modules\FileExplorerPreview\MarkdownPreviewHandler.dll'
- 'modules\FileExplorerPreview\MarkdownPreviewHandler.comhost.dll'
- 'modules\FileExplorerPreview\powerpreview.dll'
- 'modules\FileExplorerPreview\PreviewHandlerCommon.dll'
- 'modules\FileExplorerPreview\SvgPreviewHandler.dll'
- 'modules\FileExplorerPreview\SvgPreviewHandler.comhost.dll'
- 'modules\FileExplorerPreview\SvgThumbnailProvider.dll'
- 'modules\FileExplorerPreview\SvgThumbnailProvider.comhost.dll'
- 'modules\FileExplorerPreview\Telemetry.dll'
- 'modules\ImageResizer\ImageResizer.exe'
- 'modules\ImageResizer\ImageResizer.dll'
- 'modules\ImageResizer\ImageResizerExt.dll'
- 'modules\ImageResizer\PowerToysInterop.dll'
- 'modules\ImageResizer\ManagedCommon.dll'
- 'modules\ImageResizer\ManagedTelemetry.dll'
- 'modules\ImageResizer\Microsoft.PowerToys.Common.UI.dll'
- 'modules\KeyboardManager\KeyboardManager.dll'
- 'modules\launcher\Microsoft.PowerToys.Settings.UI.Lib.dll'
- 'modules\launcher\ManagedCommon.dll'
- 'modules\launcher\Microsoft.PowerToys.Common.UI.dll'
- 'modules\launcher\Microsoft.Launcher.dll'
- 'modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.Calculator\Microsoft.PowerToys.Run.Plugin.Calculator.dll'
- 'modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.Calculator\Wox.Infrastructure.dll'
- 'modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.Calculator\Wox.Plugin.dll'
- 'modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.Calculator\Telemetry.dll'
- 'modules\launcher\Plugins\Microsoft.Plugin.Folder\Microsoft.Plugin.Folder.dll'
- 'modules\launcher\Plugins\Microsoft.Plugin.Folder\Wox.Infrastructure.dll'
- 'modules\launcher\Plugins\Microsoft.Plugin.Folder\Wox.Plugin.dll'
- 'modules\launcher\Plugins\Microsoft.Plugin.Folder\Telemetry.dll'
- 'modules\launcher\Plugins\Microsoft.Plugin.Indexer\Microsoft.Plugin.Indexer.dll'
- 'modules\launcher\Plugins\Microsoft.Plugin.Indexer\Wox.Infrastructure.dll'
- 'modules\launcher\Plugins\Microsoft.Plugin.Indexer\Telemetry.dll'
- 'modules\launcher\Plugins\Microsoft.Plugin.Program\Microsoft.Plugin.Program.dll'
- 'modules\launcher\Plugins\Microsoft.Plugin.Program\Wox.Infrastructure.dll'
- 'modules\launcher\Plugins\Microsoft.Plugin.Program\Wox.Plugin.dll'
- 'modules\launcher\Plugins\Microsoft.Plugin.Program\Telemetry.dll'
- 'modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.Registry\Microsoft.PowerToys.Run.Plugin.Registry.dll'
- 'modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.Registry\ManagedTelemetry.dll'
- 'modules\launcher\Plugins\Microsoft.Plugin.Shell\Microsoft.Plugin.Shell.dll'
- 'modules\launcher\Plugins\Microsoft.Plugin.Shell\Wox.Infrastructure.dll'
- 'modules\launcher\Plugins\Microsoft.Plugin.Shell\Wox.Plugin.dll'
- 'modules\launcher\Plugins\Microsoft.Plugin.Shell\Telemetry.dll'
- 'modules\launcher\Plugins\Microsoft.Plugin.Uri\Microsoft.Plugin.Uri.dll'
- 'modules\launcher\Plugins\Microsoft.Plugin.Uri\Wox.Infrastructure.dll'
- 'modules\launcher\Plugins\Microsoft.Plugin.Uri\Wox.Plugin.dll'
- 'modules\launcher\Plugins\Microsoft.Plugin.Uri\Telemetry.dll'
- 'modules\launcher\Plugins\Microsoft.Plugin.WindowWalker\Microsoft.Plugin.WindowWalker.dll'
- 'modules\launcher\Plugins\Microsoft.Plugin.WindowWalker\Wox.Infrastructure.dll'
- 'modules\launcher\Plugins\Microsoft.Plugin.WindowWalker\Wox.Plugin.dll'
- 'modules\launcher\Plugins\Microsoft.Plugin.WindowWalker\Telemetry.dll'
- 'modules\launcher\Plugins\Service\Microsoft.PowerToys.Run.Plugin.Service.dll'
- 'modules\launcher\Plugins\System\Microsoft.PowerToys.Run.Plugin.System.dll'
- 'modules\launcher\PowerLauncher.dll'
- 'modules\launcher\PowerLauncher.exe'
- 'modules\launcher\PowerLauncher.Telemetry.dll'
- 'modules\launcher\PowerLauncher.UI.exe'
- 'modules\launcher\PowerToysInterop.dll'
- 'modules\launcher\Telemetry.dll'
- 'modules\launcher\Wox.dll'
- 'modules\launcher\Wox.Infrastructure.dll'
- 'modules\launcher\Wox.Plugin.dll'
- 'modules\Microsoft.Launcher.dll'
- 'modules\PowerRename\PowerRenameExt.dll'
- 'modules\ShortcutGuide\ShortcutGuide.dll'
- 'Notifications.dll'
- 'os-detection.dll'
- 'PowerToys.exe'
- 'PowerToysInterop.dll'
- 'PowerToysSettings.exe'
- 'SettingsUIRunner\Microsoft.PowerToys.Settings.UI.exe'
- 'SettingsUIRunner\Microsoft.PowerToys.Settings.UI.Lib.dll'
- 'SettingsUIRunner\Microsoft.PowerToys.Settings.UI.Runner.dll'
- 'SettingsUIRunner\Microsoft.PowerToys.Settings.UI.Runner.exe'
- 'SettingsUIRunner\PowerToysInterop.dll'
- 'SettingsUIRunner\Telemetry.dll'
- 'SettingsUIRunner\ManagedCommon.dll'
signing_options:
sign_inline: true # This does signing a soon as this command completes
- !!buildcommand
name: 'Build Power Toys Tools'
command: '.pipelines\build-tools.cmd'
artifacts:
- from: 'x64\Release'
to: 'Build_Output'
include:
- 'BugReportTool\BugReportTool.exe'
signing_options:
sign_inline: true # This does signing a soon as this command completes
- !!buildcommand
name: 'Build Power Toys Installer'
command: '.pipelines\build-installer.cmd'
artifacts:
- from: 'installer\PowerToysSetup\x64\Release'
to: 'Build_Installer_Output'
include:
- 'PowerToysSetup-*.msi'
signing_options:
sign_inline: true # This does signing a soon as this command completes
- !!buildcommand
name: 'Build Power Toys Bootstrapper'
command: '.pipelines\build-bootstrapper.cmd'
artifacts:
- to: 'Symbols'
include:
- 'installer\PowerToysBootstrapper\x64\Release\PowerToysSetup-*.pdb'
- from: 'installer\PowerToysBootstrapper\x64\Release'
to: 'Build_Installer_Output'
include:
- 'PowerToysSetup-*.exe'
signing_options:
sign_inline: true # This does signing a soon as this command completes
#package:
# commands:
# - !!buildcommand
# name: 'Build MSIX package'
# command: 'installer\msix\build_msix_cdpx.cmd'
# artifacts:
# - from: 'installer\msix\bin'
# to: 'Build_MSIX_Package_Output'
# include:
# - '*.msix'
# - '*.msixbundle'
# signing_options:
# profile: '400'
static_analysis_options:
binskim_options:
files_to_scan:
- from: 'installer/packages'
exclude:
- 'WiX.*/**/*.dll'
- 'Wix.*/**/*.exe'
moderncop_options:
files_to_scan:
- from: 'src'
exclude:
- '**/just.config.js'
- '**/webpack.config.js'
- '**/webpack.serve.config.js'
- '**/dist/bundle.js'
policheck_options:
files_to_scan:
- exclude:
- '**/*.lcl'

View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="PowerToysCDPX_Feed" value="https://github-private.pkgs.visualstudio.com/microsoft/_packaging/PowerToysCDPX_Feed/nuget/v3/index.json" />
</packageSources>
<disabledPackageSources>
<clear />
</disabledPackageSources>
</configuration>

View File

@@ -1,331 +0,0 @@
# This build should never run as CI or against a pull request.
trigger: none
pr: none
pool:
name: WinDevPool-L
demands: ImageOverride -equals WinDevVS16-latest
parameters:
- name: buildConfigurations
type: object
default:
- Release
- name: buildPlatforms
type: object
default:
- x64
- name: versionNumber
type: string
default: '0.0.1'
variables:
IsPipeline: 1 # The installer uses this to detect whether it should pick up localizations
name: $(BuildDefinitionName)_$(date:yyMM).$(date:dd)$(rev:rrr)
resources:
repositories:
- repository: self
type: git
ref: main
jobs:
- job: Build
strategy:
matrix:
${{ each config in parameters.buildConfigurations }}:
${{ each platform in parameters.buildPlatforms }}:
${{ config }}_${{ platform }}:
BuildConfiguration: ${{ config }}
BuildPlatform: ${{ platform }}
displayName: Build
timeoutInMinutes: 120 # Some of the loc stuff adds quite a bit of time.
cancelTimeoutInMinutes: 1
steps:
- checkout: self
clean: true
submodules: true
persistCredentials: True
# Sets versions for all PowerToy created DLLs
- task: PowerShell@1
displayName: Set Versions.Prop
inputs:
scriptName: .pipelines/versionSetting.ps1
arguments: -versionNumber '${{ parameters.versionNumber }}' -DevEnvironment ''
- task: MicrosoftTDBuild.tdbuild-task.tdbuild-task.TouchdownBuildTask@1
displayName: 'Download Localization Files -- PowerToys 37400'
inputs:
teamId: 37400
authId: '$(TouchdownApplicationID)'
authKey: '$(TouchdownApplicationKey)'
resourceFilePath: |
**\Resources.resx
**\Resource.resx
**\Resources.resw
appendRelativeDir: true
localizationTarget: false
pseudoSetting: Included
- task: PowerShell@2
displayName: Move Loc files into correct locations
inputs:
targetType: inline
script: >-
$VerbosePreference = "Continue"
./tools/build/move-and-rename-resx.ps1
./tools/build/move-uwp-resw.ps1
pwsh: true
- task: NuGetAuthenticate@0
inputs:
nuGetServiceConnections: PowerToysCDPxFeed
- task: NuGetToolInstaller@1
displayName: Use NuGet 5.10
inputs:
versionSpec: 5.10
# this will restore the following nugets:
# - main solution
# - Bug report tool
# - Webcam report tool
# - Installer
# - Bootstrapper Installer
- task: NuGetCommand@2
displayName: NuGet restore solutions dependencies
inputs:
command: restore
restoreSolution: '**/*.sln'
selectOrConfig: config
nugetConfigPath: .pipelines/release-nuget.config
- task: CmdLine@2
displayName: Moving telem files
inputs:
script: |
call nuget.exe restore -configFile .pipelines/release-nuget.config -PackagesDirectory . .pipelines/packages.config || exit /b 1
move /Y "Microsoft.PowerToys.Telemetry.2.0.0\build\include\TraceLoggingDefines.h" "src\common\Telemetry\TraceLoggingDefines.h" || exit /b 1
move /Y "Microsoft.PowerToys.Telemetry.2.0.0\build\include\TelemetryBase.cs" "src\common\Telemetry\TelemetryBase.cs" || exit /b 1
## ALL BUT INSTALLER BUILDING
- task: VSBuild@1
displayName: Build PowerToys main project
inputs:
solution: '**\PowerToys.sln'
vsVersion: 16.0
msbuildArgs: /p:CIBuild=true /bl:$(Build.SourcesDirectory)\msbuild.binlog
platform: $(BuildPlatform)
configuration: $(BuildConfiguration)
clean: true
maximumCpuCount: true
- task: VSBuild@1
displayName: Build BugReportTool
inputs:
solution: '**/tools/BugReportTool/BugReportTool.sln'
vsVersion: 16.0
msbuildArgs: /p:CIBuild=true /bl:$(Build.SourcesDirectory)\msbuild.binlog
platform: $(BuildPlatform)
configuration: $(BuildConfiguration)
clean: true
maximumCpuCount: true
- task: VSBuild@1
displayName: Build WebcamReportTool
inputs:
solution: '**/tools/WebcamReportTool/WebcamReportTool.sln'
vsVersion: 16.0
msbuildArgs: /p:CIBuild=true /bl:$(Build.SourcesDirectory)\msbuild.binlog
platform: $(BuildPlatform)
configuration: $(BuildConfiguration)
clean: true
maximumCpuCount: true
- task: VSBuild@1
displayName: Build PowerToysSetupCustomActions
inputs:
solution: '**/installer/PowerToysSetup.sln'
vsVersion: 16.0
msbuildArgs: /target:PowerToysSetupCustomActions /p:CIBuild=true /bl:$(Build.SourcesDirectory)\msbuild.binlog
platform: $(BuildPlatform)
configuration: $(BuildConfiguration)
clean: true
maximumCpuCount: true
- task: VSBuild@1
displayName: Publish Settings for Packaging
inputs:
solution: 'src/settings-ui/PowerToys.Settings/PowerToys.Settings.csproj'
vsVersion: 16.0
msbuildArgs: >-
/target:Publish
/p:Configuration=$(BuildConfiguration);Platform=$(BuildPlatform);AppxBundle=Never
/p:VCRTForwarders-IncludeDebugCRT=false
/p:PowerToysRoot=$(Build.SourcesDirectory)
/p:PublishProfile=InstallationPublishProfile.pubxml
platform: $(BuildPlatform)
configuration: $(BuildConfiguration)
maximumCpuCount: true
- task: VSBuild@1
displayName: Publish Launcher for Packaging
inputs:
solution: 'src/modules/launcher/PowerLauncher/PowerLauncher.csproj'
vsVersion: 16.0
# The arguments should be the same as the ones for Settings; make sure they are.
msbuildArgs: >-
/target:Publish
/p:Configuration=$(BuildConfiguration);Platform=$(BuildPlatform);AppxBundle=Never
/p:VCRTForwarders-IncludeDebugCRT=false
/p:PowerToysRoot=$(Build.SourcesDirectory)
/p:PublishProfile=InstallationPublishProfile.pubxml
platform: $(BuildPlatform)
configuration: $(BuildConfiguration)
maximumCpuCount: true
#### MAIN SIGNING AREA
# reference https://dev.azure.com/microsoft/Dart/_git/AppDriver?path=/ESRPSigning.json&version=GBarm64-netcore&_a=contents for winappdriver
# https://dev.azure.com/microsoft/Dart/_git/AppDriver?path=/CIPolicy.xml&version=GBarm64-netcore&_a=contents
- task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1
displayName: Sign Core PT
inputs:
ConnectedServiceName: 'Terminal/Console/WinAppDriver Team Code Signing Connection'
FolderPath: '$(BuildPlatform)/$(BuildConfiguration)' # Video conf uses x86 and x64. This path will also work for PowerToysSetupCustomActions which is in a different root dir
signType: batchSigning
batchSignPolicyFile: '$(build.sourcesdirectory)\.pipelines\ESRPSigning_core.json'
ciPolicyFile: '$(build.sourcesdirectory)\.pipelines\CIPolicy.xml'
- task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1
displayName: Sign x86 directshow VCM
inputs:
ConnectedServiceName: 'Terminal/Console/WinAppDriver Team Code Signing Connection'
FolderPath: 'x86/$(BuildConfiguration)' # Video conf uses x86 and x64. This path will also work for PowerToysSetupCustomActions which is in a different root dir
signType: batchSigning
batchSignPolicyFile: '$(build.sourcesdirectory)\.pipelines\ESRPSigning_vcm.json'
ciPolicyFile: '$(build.sourcesdirectory)\.pipelines\CIPolicy.xml'
#### END SIGNING
## END MAIN
## INSTALLER START
#### MSI BUILDING AND SIGNING
- task: VSBuild@1
displayName: Build MSI
inputs:
solution: '**/installer/PowerToysSetup.sln'
vsVersion: 16.0
msbuildArgs: /p:CIBuild=true /target:PowerToysInstaller /bl:$(Build.SourcesDirectory)\msbuild.binlog
platform: $(BuildPlatform)
configuration: $(BuildConfiguration)
clean: true
maximumCpuCount: true
- task: CmdLine@2
displayName: 'Extracting MSI to verify contents'
inputs:
script: |
.\installer\packages\WiX.3.11.2\tools\dark.exe -x $(build.sourcesdirectory)\extractedMsi installer\PowerToysSetup\$(BuildPlatform)\$(BuildConfiguration)\PowerToysSetup-${{ parameters.versionNumber }}-$(BuildPlatform).msi
dir $(build.sourcesdirectory)\extractedMsi
# Did we sign all files
- task: PowerShell@1
displayName: Verifying entire build is signed and version set
inputs:
scriptName: .pipelines/versionAndSignCheck.ps1
arguments: -targetDir '$(build.sourcesdirectory)\extractedMsi\File'
- task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1
displayName: Sign MSI
inputs:
ConnectedServiceName: 'Terminal/Console/WinAppDriver Team Code Signing Connection'
FolderPath: 'installer/PowerToysSetup/$(BuildPlatform)\$(BuildConfiguration)'
signType: batchSigning
batchSignPolicyFile: '$(build.sourcesdirectory)\.pipelines\ESRPSigning_installer.json'
ciPolicyFile: '$(build.sourcesdirectory)\.pipelines\CIPolicy.xml'
#### END MSI
#### BOOTSTRAP BUILDING AND SIGNING
- task: VSBuild@1
displayName: Build Bootstrapper
inputs:
solution: '**/installer/PowerToysSetup.sln'
vsVersion: 16.0
msbuildArgs: /p:CIBuild=true /bl:$(Build.SourcesDirectory)\msbuild.binlog
platform: $(BuildPlatform)
configuration: $(BuildConfiguration)
clean: true
maximumCpuCount: true
- task: CmdLine@2
displayName: 'Insignia: Extract Engine from Bundle'
inputs:
script: '.\installer\packages\WiX.3.11.2\tools\insignia.exe -ib installer\PowerToysSetup\$(BuildPlatform)\$(BuildConfiguration)\PowerToysSetup-${{ parameters.versionNumber }}-$(BuildPlatform).exe -o installer\engine.exe'
- task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1
displayName: 'ESRP CodeSigning (Engine)'
inputs:
ConnectedServiceName: 'Terminal/Console/WinAppDriver Team Code Signing Connection'
FolderPath: 'installer'
Pattern: engine.exe
signConfigType: inlineSignParams
inlineOperation: |
[
{
"KeyCode": "CP-230012",
"OperationCode": "SigntoolSign",
"Parameters": {
"OpusName": "Microsoft",
"OpusInfo": "http://www.microsoft.com",
"FileDigest": "/fd \"SHA256\"",
"PageHash": "/NPH",
"TimeStamp": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
},
"ToolName": "sign",
"ToolVersion": "1.0"
},
{
"KeyCode": "CP-230012",
"OperationCode": "SigntoolVerify",
"Parameters": {},
"ToolName": "sign",
"ToolVersion": "1.0"
}
]
- task: CmdLine@2
displayName: 'Insignia: Merge Engine into Bundle'
inputs:
script: '.\installer\packages\WiX.3.11.2\tools\insignia.exe -ab installer\engine.exe installer\PowerToysSetup\$(BuildPlatform)\$(BuildConfiguration)\PowerToysSetup-${{ parameters.versionNumber }}-$(BuildPlatform).exe -o installer\PowerToysSetup\$(BuildPlatform)\$(BuildConfiguration)\PowerToysSetup-${{ parameters.versionNumber }}-$(BuildPlatform).exe'
- task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1
displayName: Sign Boostrapper
inputs:
ConnectedServiceName: 'Terminal/Console/WinAppDriver Team Code Signing Connection'
FolderPath: 'installer/PowerToysSetup/$(BuildPlatform)\$(BuildConfiguration)'
signType: batchSigning
batchSignPolicyFile: '$(build.sourcesdirectory)\.pipelines\ESRPSigning_installer.json'
ciPolicyFile: '$(build.sourcesdirectory)\.pipelines\CIPolicy.xml'
#### END BOOTSTRAP
## END INSTALLER
- task: PublishBuildArtifacts@1
displayName: 'Publish Artifact: binlog'
condition: failed()
continueOnError: True
inputs:
PathtoPublish: $(Build.SourcesDirectory)\msbuild.binlog
ArtifactName: binlog-$(BuildPlatform)
- task: ComponentGovernanceComponentDetection@0
displayName: Component Detection
- task: CopyFiles@2
inputs:
contents: '**/PowerToysSetup-*.exe'
flattenFolders: True
targetFolder: $(Build.ArtifactStagingDirectory)
- task: PublishBuildArtifacts@1
displayName: 'Publish Artifact: PowerToySetup'
inputs:
PathtoPublish: $(System.ArtifactsDirectory)
ArtifactName: BuildArtifacts
...

View File

@@ -0,0 +1,32 @@
# not using this but keeping around in case we need it in the future.
# good use case here could be to set up a new machine, we just point people at it.
# https://github.com/microsoft/PowerToys/tree/master/doc/devdocs#prerequisites-for-compiling-powertoys
# improvements if this script is used to replace the snippet
# Add in a param for passive versus quiet. Could be a IsSettingUpDevComputer true/false flag
# default it to true which would be passive flag for normal people, false would set to quiet
$VS_DOWNLOAD_LINK = "https://aka.ms/vs/16/release/vs_buildtools.exe"
$VS_INSTALL_ARGS = @("--nocache","--quiet","--wait",
"--add Microsoft.VisualStudio.Workload.NativeDesktop",
"--add Microsoft.VisualStudio.Workload.ManagedDesktop",
"--add Microsoft.VisualStudio.Workload.Universal",
"--add Microsoft.VisualStudio.ComponentGroup.UWP.VC",
"--add Microsoft.VisualStudio.Component.Windows10SDK.17134",
"--add Microsoft.VisualStudio.Component.VC.Runtimes.x86.x64.Spectre",
"--add Microsoft.NetCore.Component.Runtime.3.1",
"--add Microsoft.VisualStudio.Component.VC.ATL.Spectre")
curl.exe --retry 3 -kL $VS_DOWNLOAD_LINK --output vs_installer.exe
if ($LASTEXITCODE -ne 0) {
echo "Download of the VS 2019 installer failed"
exit 1
}
$process = Start-Process "${PWD}\vs_installer.exe" -ArgumentList $VS_INSTALL_ARGS -NoNewWindow -Wait -PassThru
Remove-Item -Path vs_installer.exe -Force
$exitCode = $process.ExitCode
if (($exitCode -ne 0) -and ($exitCode -ne 3010)) {
echo "VS 2019 installer exited with code $exitCode, which should be one of [0, 3010]."
exit 1
}

View File

@@ -0,0 +1,15 @@
parameters:
sdkVersion: 17134
steps:
- task: powershell@2
inputs:
targetType: filePath
filePath: .\.pipelines\restore-dependencies.ps1
displayName: 'Install VS dependencies'
- task: powershell@2
inputs:
targetType: filePath
filePath: .\.pipelines\restore-windowsSdk17134.ps1
arguments: ${{ parameters.sdkVersion }}
displayName: 'Install Windows SDK 17134'

View File

@@ -0,0 +1,3 @@
cd /D "%~dp0"
nuget restore ../installer/PowerToysSetup.sln || exit /b 1

View File

@@ -0,0 +1,32 @@
@echo off
cd /D "%~dp0"
echo Installing nuget packages
setlocal
rem In this sample, the repo root is identical to the script directory path. Adjust the value of the RepoRoot variable accordingly based on your environment.
rem Again, ensure the RepoRoot variable is set to the real repo root location, otherwise the localization toolset wouldn't work as intended.
rem Note that the resolved %~dp0 ends with \.
set RepoRoot=%~dp0..\
set OutDir=%RepoRoot%out
set NUGET_PACKAGES=%RepoRoot%packages
set LocalizationXLocPkgVer=2.0.0
nuget install Localization.XLoc -Version %LocalizationXLocPkgVer% -OutputDirectory "%NUGET_PACKAGES%" -NonInteractive -Verbosity detailed
if "%errorlevel%" neq "0" (
exit /b %errorlevel%
)
nuget install LSBuild.XLoc -OutputDirectory "%NUGET_PACKAGES%" -NonInteractive -Verbosity detailed
if "%errorlevel%" neq "0" (
exit /b %errorlevel%
)
nuget install Localization.Languages -OutputDirectory "%NUGET_PACKAGES%" -NonInteractive -Verbosity detailed
if "%errorlevel%" neq "0" (
exit /b %errorlevel%
)
exit /b %errorlevel%

View File

@@ -0,0 +1,6 @@
cd /D "%~dp0"
call nuget.exe restore -PackagesDirectory . packages.config || exit /b 1
move /Y "Microsoft.PowerToys.Telemetry.2.0.0\build\include\TraceLoggingDefines.h" "..\src\common\Telemetry\TraceLoggingDefines.h" || exit /b 1
move /Y "Microsoft.PowerToys.Telemetry.2.0.0\build\include\TelemetryBase.cs" "..\src\common\Telemetry\TelemetryBase.cs" || exit /b 1

View File

@@ -0,0 +1,3 @@
cd /D "%~dp0"
nuget restore ../tools/BugReportTool/BugReportTool.sln || exit /b 1

View File

@@ -0,0 +1,286 @@
# Not using this but keeping around in case we need it in the future.
# It will install 17134 and can be modified to support iso's.
[CmdletBinding()]
param([Parameter(Mandatory=$true, Position=0)]
[string]$buildNumber)
# Ensure the error action preference is set to the default for PowerShell3, 'Stop'
$ErrorActionPreference = 'Stop'
# Constants
$WindowsSDKOptions = @("OptionId.UWPCpp", "OptionId.DesktopCPPx64", "OptionId.DesktopCPPx86", "OptionId.DesktopCPPARM64", "OptionId.DesktopCPPARM", "OptionId.WindowsDesktopDebuggers")
$WindowsSDKRegPath = "HKLM:\Software\WOW6432Node\Microsoft\Windows Kits\Installed Roots"
$WindowsSDKRegRootKey = "KitsRoot10"
$WindowsSDKVersion = "10.0.$buildNumber.0"
$WindowsSDKInstalledRegPath = "$WindowsSDKRegPath\$WindowsSDKVersion\Installed Options"
$StrongNameRegPath = "HKLM:\SOFTWARE\Microsoft\StrongName\Verification"
$PublicKeyTokens = @("31bf3856ad364e35")
if ($buildNumber -notmatch "^\d{5,}$")
{
Write-Host "ERROR: '$buildNumber' doesn't look like a windows build number"
Write-Host
Exit 1
}
function Download-File
{
param ([string] $outDir,
[string] $downloadUrl,
[string] $downloadName)
$downloadPath = Join-Path $outDir "$downloadName.download"
$downloadDest = Join-Path $outDir $downloadName
$downloadDestTemp = Join-Path $outDir "$downloadName.tmp"
Write-Host -NoNewline "Downloading $downloadName..."
$retries = 10
$downloaded = $false
while (-not $downloaded)
{
try
{
$webclient = new-object System.Net.WebClient
$webclient.DownloadFile($downloadUrl, $downloadPath)
$downloaded = $true
}
catch [System.Net.WebException]
{
Write-Host
Write-Warning "Failed to fetch updated file from $downloadUrl : $($error[0])"
if (!(Test-Path $downloadDest))
{
if ($retries -gt 0)
{
Write-Host "$retries retries left, trying download again"
$retries--
start-sleep -Seconds 10
}
else
{
throw "$downloadName was not found at $downloadDest"
}
}
else
{
Write-Warning "$downloadName may be out of date"
}
}
}
Unblock-File $downloadPath
$downloadDestTemp = $downloadPath;
# Delete and rename to final dest
Write-Host "testing $downloadDest"
if (Test-Path $downloadDest)
{
Write-Host "Deleting: $downloadDest"
Remove-Item $downloadDest -Force
}
Move-Item -Force $downloadDestTemp $downloadDest
Write-Host "Done"
return $downloadDest
}
function Disable-StrongName
{
param ([string] $publicKeyToken = "*")
reg ADD "HKLM\SOFTWARE\Microsoft\StrongName\Verification\*,$publicKeyToken" /f | Out-Null
if ($env:PROCESSOR_ARCHITECTURE -eq "AMD64")
{
reg ADD "HKLM\SOFTWARE\Wow6432Node\Microsoft\StrongName\Verification\*,$publicKeyToken" /f | Out-Null
}
}
function Test-Admin
{
$identity = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = New-Object Security.Principal.WindowsPrincipal $identity
$principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}
function Test-RegistryPathAndValue
{
param (
[parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string] $path,
[parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string] $value)
try
{
if (Test-Path $path)
{
Get-ItemProperty -Path $path | Select-Object -ExpandProperty $value -ErrorAction Stop | Out-Null
return $true
}
}
catch
{
}
return $false
}
function Test-InstallWindowsSDK
{
$retval = $true
if (Test-RegistryPathAndValue -Path $WindowsSDKRegPath -Value $WindowsSDKRegRootKey)
{
# A Windows SDK is installed
# Is an SDK of our version installed with the options we need?
$allRequiredSdkOptionsInstalled = $true
foreach($sdkOption in $WindowsSDKOptions)
{
if (!(Test-RegistryPathAndValue -Path $WindowsSDKInstalledRegPath -Value $sdkOption))
{
$allRequiredSdkOptionsInstalled = $false
}
}
if($allRequiredSdkOptionsInstalled)
{
# It appears we have what we need. Double check the disk
$sdkRoot = Get-ItemProperty -Path $WindowsSDKRegPath | Select-Object -ExpandProperty $WindowsSDKRegRootKey
if ($sdkRoot)
{
if (Test-Path $sdkRoot)
{
$refPath = Join-Path $sdkRoot "References\$WindowsSDKVersion"
if (Test-Path $refPath)
{
$umdPath = Join-Path $sdkRoot "UnionMetadata\$WindowsSDKVersion"
if (Test-Path $umdPath)
{
# Pretty sure we have what we need
$retval = $false
}
}
}
}
}
}
return $retval
}
function Test-InstallStrongNameHijack
{
foreach($publicKeyToken in $PublicKeyTokens)
{
$key = "$StrongNameRegPath\*,$publicKeyToken"
if (!(Test-Path $key))
{
return $true
}
}
return $false
}
Write-Host -NoNewline "Checking for installed Windows SDK $WindowsSDKVersion..."
$InstallWindowsSDK = Test-InstallWindowsSDK
if ($InstallWindowsSDK)
{
Write-Host "Installation required"
}
else
{
Write-Host "INSTALLED"
}
$StrongNameHijack = Test-InstallStrongNameHijack
Write-Host -NoNewline "Checking if StrongName bypass required..."
if ($StrongNameHijack)
{
Write-Host "REQUIRED"
}
else
{
Write-Host "Done"
}
if ($StrongNameHijack -or $InstallWindowsSDK)
{
if (!(Test-Admin))
{
Write-Host
throw "ERROR: Elevation required"
}
}
if ($InstallWindowsSDK)
{
# Static(ish) link for Windows SDK
# Note: there is a delay from Windows SDK announcements to availability via the static link
# $uri = "https://software-download.microsoft.com/download/sg/Windows_InsiderPreview_SDK_en-us_$($buildNumber)_1.iso";
# https://developer.microsoft.com/en-us/windows/downloads/sdk-archive/
$uri = "https://go.microsoft.com/fwlink/p/?linkid=870807"
if ($env:TEMP -eq $null)
{
$env:TEMP = Join-Path $env:SystemDrive 'temp'
}
$winsdkTempDir = Join-Path (Join-Path $env:TEMP ([System.IO.Path]::GetRandomFileName())) "WindowsSDK"
if (![System.IO.Directory]::Exists($winsdkTempDir))
{
[void][System.IO.Directory]::CreateDirectory($winsdkTempDir)
}
# $file = "winsdk_$buildNumber.iso"
$file = "winsdk_$buildNumber.exe"
Write-Host -NoNewline "Getting WinSDK from $uri"
$downloadFile = Download-File $winsdkTempDir $uri $file
Write-Host -NoNewline "File is at $downloadFile"
$downloadFileItem = Get-Item $downloadFile
# Check to make sure the file is at least 10 MB.
# if ($downloadFileItem.Length -lt 10*1024*1024)
# {
# Write-Host
# Write-Host "ERROR: Downloaded file doesn't look large enough to be an ISO. The requested version may not be on microsoft.com yet."
# Write-Host
# Exit 1
# }
# TODO Check if zip, exe, iso, etc.
try
{
Write-Host -NoNewLine "Installing WinSDK..."
Start-Process -Wait $downloadFileItem "/features $WindowsSDKOptions /q"
Write-Host "Done installing"
}
finally
{
Write-Host "Done"
}
}
if ($StrongNameHijack)
{
Write-Host -NoNewline "Disabling StrongName for Windows SDK..."
foreach($key in $PublicKeyTokens)
{
Disable-StrongName $key
}
Write-Host "Done"
}

3
.pipelines/restore.cmd Normal file
View File

@@ -0,0 +1,3 @@
cd /D "%~dp0"
nuget restore ../PowerToys.sln || exit /b 1

View File

@@ -1,53 +0,0 @@
[CmdletBinding()]
# todo: send in arch / conf, could send in actual path
Param(
[Parameter(Mandatory=$True,Position=1)]
[AllowEmptyString()]
[string]$targetDir = $PSScriptRoot + '/../extractedMsi/File'
)
$DirPath = $targetDir; #this file is in pipeline, we need root.
$items = Get-ChildItem -Path $DirPath -File -Include *.exe,*.dll,*.ttf -Recurse -Force -ErrorAction SilentlyContinue
$totalFailure = 0;
Write-Host $DirPath;
if(-not (Test-Path $DirPath))
{
Write-Host "Folder does not exist!"
}
Write-Host "Total items: " $items.Count
if($items.Count -eq 0)
{
# no items means something bad happened. We should fail ASAP
exit 1;
}
$items | ForEach-Object {
if($_.VersionInfo.FileVersion -eq "1.0.0.0" )
{
if(-not $_.Name.EndsWith("Microsoft.Search.Interop.dll"))
{
Write-Host "Version not set: " + $_.FullName
$totalFailure++;
}
}
}
$items | ForEach-Object {
$auth = Get-AuthenticodeSignature $_.FullName
if($auth.SignerCertificate -eq $null)
{
Write-Host "Not Signed: " + $_.FullName
$totalFailure++;
}
}
if($totalFailure -gt 0)
{
exit 1
}
exit 0

View File

@@ -1,42 +0,0 @@
[CmdletBinding()]
Param(
[Parameter(Mandatory=$True,Position=1)]
[string]$versionNumber = "0.0.1",
[Parameter(Mandatory=$True,Position=2)]
[AllowEmptyString()]
[string]$DevEnvironment = "Local"
)
Write-Host $PSScriptRoot
$versionRegex = "(\d+)\.(\d+)\.(\d+)"
if($versionNumber -match $versionRegEx)
{
#$buildDayOfYear = (Get-Date).DayofYear;
#$buildTime = Get-Date -Format HH;
#$buildTime = Get-Date -Format HHmmss;
#$buildYear = Get-Date -Format yy;
#$revision = [string]::Format("{0}{1}{2}", $buildYear, $buildDayOfYear, $buildTime )
# max UInt16, 65535
#$revision = [string]::Format("{0}{1}", $buildDayOfYear, $buildTime )
#Write-Host "Revision" $revision
$versionNumber = [int]::Parse($matches[1]).ToString() + "." + [int]::Parse($matches[2]).ToString() + "." + [int]::Parse($matches[3]).ToString() # + "." + $revision
Write-Host "Version Number" $versionNumber
}
else
{
throw "Build format does not match the expected pattern (buildName_w.x.y.z)"
}
$verPropWriteFileLocation = $PSScriptRoot + '/../src/Version.props';
$verPropReadFileLocation = $verPropWriteFileLocation;
[XML]$verProps = Get-Content $verPropReadFileLocation
$verProps.Project.PropertyGroup.Version = $versionNumber;
$verProps.Project.PropertyGroup.DevEnvironment = $DevEnvironment;
Write-Host "xml" $verProps.Project.PropertyGroup.Version
$verProps.Save($verPropWriteFileLocation);

View File

@@ -1,15 +0,0 @@
{
"version": "1.0",
"components": [
"Microsoft.VisualStudio.Component.CoreEditor",
"Microsoft.VisualStudio.Workload.CoreEditor",
"Microsoft.VisualStudio.Workload.NativeDesktop",
"Microsoft.VisualStudio.Workload.ManagedDesktop",
"Microsoft.VisualStudio.Workload.Universal",
"Microsoft.VisualStudio.Component.Windows10SDK.17134",
"Microsoft.VisualStudio.Component.Windows10SDK.18362",
"Microsoft.VisualStudio.ComponentGroup.UWP.VC",
"Microsoft.VisualStudio.Component.VC.Runtimes.x86.x64.Spectre",
"Microsoft.VisualStudio.Component.VC.ATL.Spectre"
]
}

View File

@@ -6,24 +6,9 @@ Names are in alphabetical order based on first name.
## High impact community members
### [@Aaron-Junker](https://github.com/Aaron-Junker) - [Aaron Junker](https://aaron-junker.github.io)
Aaron has helped triaging, discussing, and creating a substantial number of issues and contributed features/fixes as well as work on an upcoming utility.
### [@davidegiacometti](https://github.com/davidegiacometti) - [Davide Giacometti](https://www.linkedin.com/in/davidegiacometti/)
Davide has helped fix multiple bugs, added new features, as well as help us with the ARM64 effort by porting applications to .NET Core.
### [@franky920920](https://github.com/franky920920) - [Franky Chen](https://frankychen.net)
Franky has helped triaging, discussing, and creating a substantial number of issues and contributed features/fixes to PowerToys.
### [@htcfreek](https://github.com/htcfreek) - Heiko
Heiko has helped triaging, discussing, and creating a substantial number of issues and contributed features/fixes to PowerToys.
### [@Jay-o-Way](https://github.com/Jay-o-Way) - Jay
Jay has helped triaging, discussing, creating a substantial number of issues and PRs.
### [@jsoref](https://github.com/jsoref) - [Josh Soref](https://check-spelling.dev/)
Helping keep our spelling correct :)
### [@Niels9001](https://github.com/niels9001/) - [Niels Laute](https://nielslaute.com/)
Niels has helped drive large sums of our update toward a new [consistent and modern UX](https://github.com/microsoft/PowerToys/issues/891). This includes the [launcher work](https://github.com/microsoft/PowerToys/issues/44), color picker UX update and [icon design](https://github.com/microsoft/PowerToys/issues/1118).
@@ -33,13 +18,7 @@ Niels has helped drive large sums of our update toward a new [consistent and mod
Rafael has helped do the [upgrade from CppWinRT 1.x to 2.0](https://github.com/microsoft/PowerToys/issues/1907). He directly provided feedback to the CppWinRT team for bugs from this migration as well.
### [@royvou](https://github.com/royvou)
Roy has helped out contributing multiple features to PowerToys Run
### [@TobiasSekan](https://github.com/TobiasSekan) - Tobias Sekan
Tobias Sekan has helped out contributing features to PowerToys Run such as Settings plugin, Registry plugin
### [@ThiefZero](https://github.com/ThiefZero)
ThiefZero has helped out contributing a features to PowerToys Run such as the unit converter plugin
Roy has helped out contributing a features to PowerToys Run
## Open source projects
@@ -73,18 +52,10 @@ Image Resizer is from Brice.
PowerRename is from Chris's SmartRename and icon rendering for SVGs in File Explorer
### [@dend](https://github.com/dend/) - Den Delimarsky
PowerToys Awake is a tool to keep your computer awake.
### [@martinchrzan](https://github.com/martinchrzan/) - Martin Chrzan
Color Picker is from Martin.
### [@oldnewthing](https://github.com/oldnewthing) - Raymond Chen
Find My Mouse is based on Raymond Chen's SuperSonar.
### Microsoft InVEST team
This amazing team helped PowerToys develop PowerToys Run and Keyboard manager as well as update our Settings to v2. @alekhyareddy28, @arjunbalgovind, @jyuwono @laviusmotileng-ms, @ryanbodrug-microsoft, @saahmedm, @somil55, @traies, @udit3333

View File

@@ -1,18 +1,20 @@
# PowerToys Contributor's Guide
# Power Toys Contributor's Guide
Below is our guidance for how to report issues, propose new features, and submit contributions via Pull Requests (PRs). Our philosophy is heavily based around understanding the problem and scenarios first, this is why we follow this pattern before work has started.
Below is our guidance for how to report issues, propose new features, and submit contributions via Pull Requests (PRs).
1. There is an issue
2. There has been a conversation
3. There is agreement on the problem, the fit for PowerToys, and the solution to the problem (implementation)
## Filing an issue
## Before you start, file an issue
Please follow this simple rule to help us eliminate any unnecessary wasted effort & frustration, and ensure an efficient and effective use of everyone's time - yours, ours, and other community members':
> 👉 If you have a question, think you've discovered an issue, would like to propose a new feature, etc., then find/file an issue **BEFORE** starting work to fix/implement it.
When requesting new features / enhancements, understanding problem and scenario around it is extremely important. Having additional evidence, data, tweets, blog posts, research, ... anything is extremely helpful. This information provides context to the scenario that may otherwise be lost.
### Search existing issues first
Before filing a new issue, search existing open and closed issues first: It is likely someone else has found the problem you're seeing, and someone may be working on or have already contributed a fix!
If no existing item describes your issue/feature, great - please file a new issue:
### File a new Issue
* Don't know whether you're reporting an issue or requesting a feature? File an issue
* Have a question that you don't see answered in docs, videos, etc.? File an issue
@@ -21,39 +23,88 @@ When requesting new features / enhancements, understanding problem and scenario
* Don't understand how to do something? File an issue/Community Guidance Request
* Found an existing issue that describes yours? Great - upvote and add additional commentary / info / repro-steps / etc.
A quick search before filing an issue also could be helpful. It is likely someone else has found the problem you're seeing, and someone may be working on or have already contributed a fix!
### Complete the template
### How to tell the PowerToys team this is an interesting thing to focus on
**Please include as much information as possible in your issue**. The more information you provide, the more likely your issue/ask will be understood and implemented. Helpful information includes:
Upvote the original issue by clicking its [+😊] button and hitting 👍 (+1) icon or a different one. This way allows us to measure how impactful different issues are compared to others. The issue with comments like "+1", "me too", or similar is they actually make it harder to have a conversation and harder to quickly determine trending important requests.
* What device you're running (inc. CPU type, memory, disk, etc.)
* What build of Windows your device is running
👉 Tip: Run the following in PowerShell Core
```powershell
C:\> $PSVersionTable.OS
Microsoft Windows 10.0.18909
```
... or in Windows PowerShell
```powershell
C:\> $PSVersionTable.BuildVersion
Major Minor Build Revision
----- ----- ----- --------
10 0 18912 1001
```
... or Cmd:
```cmd
C:\> ver
Microsoft Windows [Version 10.0.18900.1001]
```
* What tools and apps you're using (e.g. VS 2019, VSCode, etc.)
* Don't assume we're experts in setting up YOUR environment and don't assume we are experts in YOUR workflow. Teach us to help you!
* **We LOVE detailed repro steps!** What steps do we need to take to reproduce the issue? Assume we love to read repro steps. As much detail as you can stand is probably _barely_ enough detail for us!
* Prefer error message text where possible or screenshots of errors if text cannot be captured
* **If you intend to implement the fix/feature yourself then say so!** If you do not indicate otherwise we will assume that the issue is ours to solve, or may label the issue as `Help-Wanted`.
### DO NOT post "+1" comments
> ⚠ DO NOT post "+1", "me too", or similar comments - they just add noise to an issue.
If you don't have any additional info/context to add but would like to indicate that you're affected by the issue, upvote the original issue by clicking its [+😊] button and hitting 👍 (+1) icon. This way we can actually measure how impactful an issue is.
---
## Contributing fixes / features
Please comment on an issue to let us know you're interested in working on something before you start the work. Not only does this avoid multiple people unexpectedly working on the same thing at the same time but it enables us to make sure everyone is clear on what should be done to implement any new functionality. It's less work for everyone, in the long run, to establish this up front.
For those able & willing to help fix issues and/or implement features ...
### To Spec or not to Spec
A key point is for everyone to understand the approach that will be taken. We want to be sure if anyone does work, we will accept it in. Items that are larger in scope we'll want some type of spec to understand what is being planned and have a discussion. Specs help collaborators discuss different approaches to solve a problem, describe how the feature will behave, how the feature will impact the user, what happens if something goes wrong, etc. Driving towards agreement in a spec, before any code is written, often results in simpler code, and less wasted effort in the long run.
Some issues/features may be quick and simple to describe and understand. For such scenarios, once a team member has agreed with your approach, skip ahead to the section headed "Fork, Branch, and Create your PR", below.
For such scenarios, once a team member has agreed with your approach, skip ahead to the section headed "Development" section below.
Small issues that do not require a spec will be labelled Issue-Bug or Issue-Task.
However, some issues/features will require careful thought & formal design before implementation. For these scenarios, we'll request that a spec is written and the associated issue will be labeled Issue-Feature.
Specs help collaborators discuss different approaches to solve a problem, describe how the feature will behave, how the feature will impact the user, what happens if something goes wrong, etc. Driving towards agreement in a spec, before any code is written, often results in simpler code, and less wasted effort in the long run.
Specs will be managed in a very similar manner as code contributions so please follow the "Fork, Branch and Create your PR" below.
### Writing / Contributing-to a Spec
To write/contribute to a spec: fork, branch and commit via PRs, as you would with any code changes.
Specs are written in markdown, stored under the `doc/specs` folder and named `[issue id] - [spec description].md`.
👉 **It is important to follow the spec templates and complete the requested information**. The available spec templates will help ensure that specs contain the minimum information & decisions necessary to permit development to begin. In particular, specs require you to confirm that you've already discussed the issue/idea with the team in an issue and that you provide the issue ID for reference.
Team members will be happy to help review specs and guide them to completion.
### Help Wanted
Once the team has approved an issue/spec approach to solving, development can proceed. If no developers are immediately available, the spec can be parked ready for a developer to get started. Parked specs' issues will be labeled "Help Wanted". To find a list of development opportunities waiting for developer involvement, visit the Issues and filter on [the Help-Wanted label](https://github.com/microsoft/PowerToys/labels/Help%20Wanted).
Once the team have approved an issue/spec, development can proceed. If no developers are immediately available, the spec can be parked ready for a developer to get started. Parked specs' issues will be labeled "Help Wanted". To find a list of development opportunities waiting for developer involvement, visit the Issues and filter on [the Help-Wanted label](https://github.com/microsoft/PowerToys/labels/Help%20Wanted).
---
## Development
Follow the [development guidelines](https://github.com/microsoft/PowerToys/blob/main/doc/devdocs/readme.md).
Follow the [development guidelines](https://github.com/microsoft/PowerToys/blob/master/doc/devdocs/readme.md).
### Naming of features and functionality
Naming should be descriptive and straight forward. We want names to be clear about functionality and usefulness moving forward.
### How can I become a collaborator on the PowerToys team

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- Project configurations -->
<ItemGroup Label="ProjectConfigurations">
@@ -13,7 +12,7 @@
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<!-- Props that should be disabled while building on CI server -->
<ItemDefinitionGroup Condition="'$(CIBuild)'!='true'">
<ClCompile>
@@ -23,15 +22,10 @@
</ItemDefinitionGroup>
<!-- C++ source compile-specific things for all configurations -->
<PropertyGroup>
<ExternalIncludePath>$(MSBuildThisFileFullPath)\..\deps\;$(ExternalIncludePath)</ExternalIncludePath>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<WarningLevel>Level3</WarningLevel>
<DisableAnalyzeExternal >true</DisableAnalyzeExternal>
<ExternalWarningLevel>TurnOffAllWarnings</ExternalWarningLevel>
<ConformanceMode>false</ConformanceMode>
<TreatWarningAsError>true</TreatWarningAsError>
<LanguageStandard>stdcpplatest</LanguageStandard>
@@ -40,10 +34,10 @@
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
</Link>
</Link>
<Lib>
<TreatLibWarningAsErrors>true</TreatLibWarningAsErrors>
</Lib>
</Lib>
</ItemDefinitionGroup>
<!-- C++ source compile-specific things for Debug/Release configurations -->
@@ -56,7 +50,7 @@
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
@@ -66,35 +60,36 @@
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
</ClCompile>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</Link>
</ItemDefinitionGroup>
<!-- Global props -->
<PropertyGroup Label="Globals" Condition="'$(OverrideWindowsTargetPlatformVersion)'!='True'">
<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<!-- Props that are constant for both Debug and Release configurations -->
<PropertyGroup Label="Configuration">
<PlatformToolset Condition="'$(OverridePlatformToolset)'!='True'">v142</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)\obj\$(ProjectName)\</IntDir>
<CharacterSet>Unicode</CharacterSet>
<SpectreMitigation>Spectre</SpectreMitigation>
</PropertyGroup>
<!-- Debug/Release props -->
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<UseDebugLibraries>true</UseDebugLibraries>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
</Project>

View File

@@ -1,13 +1,7 @@
# NOTICES AND INFORMATION
This software incorporates material from third parties.
- Color Picker
- File Explorer Add-ins
- ImageResizer
- PowerToys Run
- Installer/Runner
## Utility: Color Picker
## PowerToy: Color Picker
### Martin Chrzan's Color Picker
@@ -35,37 +29,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
## Utility: File Explorer Add-ins
### Monaco Editor
**Source**: https://github.com/Microsoft/monaco-editor
**Additional third party notifications:** https://github.com/microsoft/monaco-editor/blob/main/ThirdPartyNotices.txt
The MIT License (MIT)
Copyright (c) 2016 - present Microsoft Corporation
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
## Utility: ImageResizer
## PowerToy: ImageResizer
### Brice Lams's Image Resizer License
@@ -93,7 +57,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
## Utility: PowerToys Run
## PowerToy: Launcher
### Wox License
@@ -135,7 +99,7 @@ The above copyright notice and this permission notice shall be included in all c
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
## Utility: PowerRename
## PowerToy: PowerRename
### Chris Davis's SmartRename License

File diff suppressed because it is too large Load Diff

184
README.md
View File

@@ -1,55 +1,62 @@
# Microsoft PowerToys
# Welcome to the Microsoft PowerToys repo
![Hero image for Microsoft PowerToys](doc/images/overview/PT_hero_image.png)
<img src="./doc/images/overview/PT%20hero%20image.png"/>
[How to use PowerToys][usingPowerToys-docs-link] | [Downloads & Release notes][github-release-link] | [Contributing to PowerToys](#contributing) | [What's Happening](#whats-happening) | [Roadmap](#powertoys-roadmap)
[Downloads & Release notes][github-release-link] | [Contributing to PowerToys](#contributing) | [What's Happening](#whats-happening) | [Roadmap](#powertoys-roadmap) | [Known issues](#known-issues)
## Build status
| Architecture | Solution (Main) | Solution (Stable) | Installer (Main) |
|--------------|-----------------|-------------------|------------------|
| x64 | [![Build Status for Main](https://dev.azure.com/ms/PowerToys/_apis/build/status/microsoft.PowerToys?branchName=main)](https://dev.azure.com/ms/PowerToys/_build/latest?definitionId=219&branchName=main) | [![Build Status for Stable](https://dev.azure.com/ms/PowerToys/_apis/build/status/microsoft.PowerToys?branchName=stable)](https://dev.azure.com/ms/PowerToys/_build/latest?definitionId=219&branchName=stable) | [![Build Status Installer pipeline](https://dev.azure.com/microsoft/Dart/_apis/build/status/microsoft.PowerToys?branchName=main)](https://dev.azure.com/microsoft/Dart/_build/latest?definitionId=76541&branchName=main) |
| ARM64 | Currently investigating | [Issue #490](https://github.com/microsoft/PowerToys/issues/490) | |
| Architecture | Master | Stable | Installer |
|--------------|--------|--------|-----------|
| x64 | [![Build Status for Master](https://dev.azure.com/ms/PowerToys/_apis/build/status/microsoft.PowerToys?branchName=master)](https://dev.azure.com/ms/PowerToys/_build/latest?definitionId=219&branchName=master) | [![Build Status for Stable](https://dev.azure.com/ms/PowerToys/_apis/build/status/microsoft.PowerToys?branchName=stable)](https://dev.azure.com/ms/PowerToys/_build/latest?definitionId=219&branchName=stable) | [![Build Status for Installer](https://github-private.visualstudio.com/microsoft/_apis/build/status/CDPX/powertoys/powertoys-Windows-Official-master-Test?branchName=master)](https://github-private.visualstudio.com/microsoft/_build/latest?definitionId=61&branchName=master) |
## About
Microsoft PowerToys is a set of utilities for power users to tune and streamline their Windows experience for greater productivity. For more info on [PowerToys overviews and how to use the utilities][usingPowerToys-docs-link], or any other tools and resources for [Windows development environments](https://docs.microsoft.com/windows/dev-environment/overview), head over to [docs.microsoft.com][usingPowerToys-docs-link]!
Microsoft PowerToys is a set of utilities for power users to tune and streamline their Windows 10 experience for greater productivity. For more info on [PowerToys overviews and guides][usingPowerToys-docs-link], or any other tools and resources for [Windows development environments](https://docs.microsoft.com/windows/dev-environment/overview), head over to [docs.microsoft.com][usingPowerToys-docs-link]!
| | Current utilities: | |
|--------------|--------------------|--------------|
| [Always on Top](https://aka.ms/PowerToysOverview_AoT) | [PowerToys Awake](https://aka.ms/PowerToysOverview_Awake) | [Color Picker](https://aka.ms/PowerToysOverview_ColorPicker) |
| [FancyZones](https://aka.ms/PowerToysOverview_FancyZones) | [File Explorer Add-ons](https://aka.ms/PowerToysOverview_FileExplorerAddOns) | [Image Resizer](https://aka.ms/PowerToysOverview_ImageResizer) |
| [Keyboard Manager](https://aka.ms/PowerToysOverview_KeyboardManager) | [Mouse utilities](https://aka.ms/PowerToysOverview_MouseUtilities) | [PowerRename](https://aka.ms/PowerToysOverview_PowerRename) |
| [PowerToys Run](https://aka.ms/PowerToysOverview_PowerToysRun) | [Shortcut Guide](https://aka.ms/PowerToysOverview_ShortcutGuide) | [Video Conference Mute](https://aka.ms/PowerToysOverview_VideoConference) |
| | Current utilities: | |
|--------------|--------|--------|
| [Color Picker](https://aka.ms/PowerToysOverview_ColorPicker) | [FancyZones](https://aka.ms/PowerToysOverview_FancyZones) | [File Explorer Add-ons](https://aka.ms/PowerToysOverview_FileExplorerAddOns) |
| [Image Resizer](https://aka.ms/PowerToysOverview_ImageResizer) | [Keyboard Manager](https://aka.ms/PowerToysOverview_KeyboardManager) | [PowerRename](https://aka.ms/PowerToysOverview_PowerRename) |
| [PowerToys Run](https://aka.ms/PowerToysOverview_PowerToysRun) | [Shortcut Guide](https://aka.ms/PowerToysOverview_ShortcutGuide) | [Video Conference Mute (Experimental)](https://aka.ms/PowerToysOverview_VideoConference) |
## Installing and running Microsoft PowerToys
### Requirements
- Windows 11 or Windows 10 v1903 (18362) or newer.
- [.NET Core 3.1.22 Desktop Runtime](https://dotnet.microsoft.com/download/dotnet/thank-you/runtime-desktop-3.1.22-windows-x64-installer) or a newer 3.1.x runtime. The installer will handle this if not present.
- Windows 10 v1903 (build 18362) or better preferred, Windows 10 v1803 (build 17134) minimum.
- Have [.NET Core 3.1 Desktop Runtime](https://dotnet.microsoft.com/download/dotnet-core/thank-you/runtime-desktop-3.1.10-windows-x64-installer). The installer should handle this but we want to directly make people aware.
### Via GitHub with EXE [Recommended]
[Microsoft PowerToys GitHub releases page][github-release-link], click on `Assets` at the bottom to show the files available in the release and then click on `PowerToysSetup-0.53.3-x64.exe` to download the PowerToys installer.
#### Stable version
Install from the [Microsoft PowerToys GitHub releases page][github-release-link]. Click on `Assets` to show the files available in the release and then click on `PowerToysSetup-0.29.3-x64.exe` to download the PowerToys installer.
This is our preferred method.
### Via Microsoft Store
Install from the [Microsoft Store's PowerToys page][microsoft-store-link]. You must be using the [new Microsoft Store](https://blogs.windows.com/windowsExperience/2021/06/24/building-a-new-open-microsoft-store-on-windows-11/) which will be available for both Windows 11 and Windows 10.
#### Experimental version
To install the Video Conference mute, please use the [v0.28 pre-release experimental version of PowerToys][github-prerelease-link] to try out this version. It includes all improvements from v0.27 in addition to the Video conference utility. Click on `Assets` to show the files available in the release and then download the .exe installer.
### Via WinGet (Preview)
Download PowerToys from [WinGet][winget-link]. To install PowerToys, run the following command from the command line / PowerShell:
Download PowerToys from [WinGet](https://github.com/microsoft/winget-cli/releases). To install PowerToys, run the following command from the command line / PowerShell:
```powershell
winget install Microsoft.PowerToys -s winget
WinGet install powertoys
```
### Other install methods
There are [community driven install methods](./doc/unofficialInstallMethods.md) such as Chocolatey and Scoop. If these are your preferred install solutions, this will have the install instructions.
### Processor support
We currently support the matrix below.
| x64 | x86 | ARM64 |
|:---:|:---:|:---:|
| [Supported][github-release-link] | [Issue #602](https://github.com/microsoft/PowerToys/issues/602) | [Issue #490](https://github.com/microsoft/PowerToys/issues/490) |
## Contributing
This project welcomes contributions of all types. Help spec'ing, design, documentation, finding bugs are ways everyone can help on top of coding features / bug fixes. We are excited to work with the power user community to build a set of tools for helping you get the most out of Windows.
@@ -66,98 +73,65 @@ 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.53 - December 2021 Update
### 0.29 - December 2020 Update
We hope everyone has had a wonderful December 2021. The PowerToys community has been busy with a bunch of improvements. We're still working on improving the installer but this should drastically improve things. 3 things you will want to check out are G-code support in file explorer preview pane and thumbnails, the new web search plugin from PowerToys Run via <kbd>??</kbd> action phrase, and the new Always on Top utility via <kbd>Win</kbd>+<kbd>Ctrl</kbd>+<kbd>T</kbd>.
Our goals for [v0.29 release cycle][github-release-link] were to focus on adding on end-user experience, stability, accessibility, localization and quality of life improvements for both the development team and our end users. Due to the short dev cycle due to the holidays this month, larger work items will show up next release such as FZ editor improvements and three new plug-ins for PowerToys Run (service, regkey, system commands).
[@Aaron-Junker](https://github.com/Aaron-Junker) also has done some great progress on [implementing developer file preview pane](https://github.com/microsoft/PowerToys/issues/1527) via the Monaco engine from Visual Studio Code.
Our [prioritized roadmap][roadmap] of features and utilities that the core team is focusing on for the near future. We fixed a lot of localization issues from our initial release but we may not still be perfect. If you find an issue, please file a [localization bug][loc-bug].
#### Things to be aware of
- The new installer currently has a visual quirk when upgrade if you have a custom install path. It will show the default install path but it will actually overwrite the current location. We are investigating how to fix this.
#### Highlights from v0.29
#### Always on Top
- Welcome to the family! With a quick <kbd>Win</kbd>+<kbd>Ctrl</kbd>+<kbd>T</kbd>, the window in focus is toggled to be on top. Toggle again, and it reverts back to normal.
**General**
- Bug report tool and improved logging.
- Various localization improvements.
- CodeQL added. Triggered via a cron timer twice a day.
- "How to use" docs moved to https://docs.microsoft.com/windows/powertoys/
- This will allow the community to do direct PRs against those documents
#### ColorPicker
- HEX input improvements for adjust color menu including support for hex code without hashtag and short hex code like #CF0. Thanks @htcfreek!
- Better bottom right screen detection for overlay
**ARM64 Progress**
- .NET Core upgrade for code bases the PowerToys team controls is complete. We still have two external dependencies that are .NET Framework that need to be updated.
#### FancyZones
- Increased negative space margin
- Fix for not snapping child windows
- Fix for clearing keyboard focus on editor launch
- Fix to improve overlays to reduce brightness and hide numbers. Thanks @davidegiacometti
**Color Picker**
- General bug fixes
- Added ability to provide the name of the color at parity with Office and WinUI Color Picker.
#### File Explorer
- Added G-code support for thumbnails and preview pane. Thanks @pedrolamas
**FancyZones**
- Allows to use Windows Snap on desktops that don't have a layout applied and for apps that are in the excluded list.
- Bug fixes
#### Image Resizer
- Fixed regression from Metadata tag removal of ColorSpace. Thanks @CleanCodeDeveloper
**PowerToys Run**
- Improved performance
- PT Run now supports accented characters.
#### PowerRename
- Row highlighting + preview support now implemented. Thanks @niels9001
- Fixed AltGR input issue
- Improved folder renaming support
- Opens on active monitor
**Installer**
- Option to extract the MSI from the .exe for enterprise scenarios and more options to do unattended installations.
- Removed toast notifications during installation.
#### PowerToys Run
- Web searching has been added! `?? What is the answer to life` will go to your favorite search engine via your browser. You can change the default action key too! Thanks @cyberrex5 for primary implementation and @franky920920 and @htcfreek for supporting
- VS Code workspace improvements. Thanks @ricardosantos9521
- Binary and Hex number support. Thanks @gsuberland
- Ability to use factorials in calculations
- PT Run will not show in Window Walker results anymore. Thanks @davidegiacometti
- Fix log / ln calculations
- Fix to make previous results clear
- Fix to detect symlinks and prevent recursive loops
- Fix for trackpad scrolling being too fast
- Removed unneeded nuget package. Thanks @ChaseKnowlden
- Better detection for if a packaged app can be elevated
- Improve crash resiliency for Program plugin. Thanks @davidegiacometti
- Improved Windows setting results. Thanks @htcfreek
- Fixed a bug where some similar activation phrases aren't working as expected. Thanks @htcfreek and @cyberrex5.
We'd like to directly mention (in alphabetical order) for their continued community support this month and helping directly make PowerToys a better piece of software.
#### Video conference mute
- Disabled by default as this requires elevation to register the virtual camera.
- Changed (default) hotkey for mute camera & microphone from <kbd>Win</kbd>+<kbd>N</kbd> to <kbd>Win</kbd>+<kbd>Shift</kbd>+<kbd>Q</kbd> to not conflict with a Windows 11 keyboard shortcut
[@Aaron-Junker](https://github.com/Aaron-Junker),
[@benjamhooper](https://github.com/benjamhooper),
[@davidegiacometti](https://github.com/davidegiacometti),
[@eriawan](https://github.com/eriawan),
[@htcfreek](https://github.com/htcfreek),
[@jay-o-way](https://github.com/jay-o-way),
[@jhutchings1](https://github.com/jhutchings1),
[@jsoref](https://github.com/jsoref),
[@martinchrzan](https://github.com/martinchrzan),
[@niels9001](https://github.com/niels9001),
[@riverar](https://github.com/riverar),
[@snickler](https://github.com/snickler),
and
[@TobiasSekan](https://github.com/TobiasSekan)
#### Settings
- Multiple accessibility, layout, image, string and icons fixes. Thanks @niels9001
#### What is being planned for v0.31 - January 2021
#### Runner
- Improved mutex support to prevent multiple PT Run instances from running
For [v0.31][github-next-release-work], we are proactively working on:
#### Installer
- **NOTE:** The new installer currently has a visual quirk when upgrade if you have a custom install path. It will show the default install path but it will actually overwrite the current location. We are investigating how to fix this.
- Large progress toward user based installing vs machine wide. Upgrade scenario still needs additional work.
- Removed custom bootstrapper and now are using a WiX bundle.
- Removed unused image assets that were still being shipped. Thanks @niels9001
#### ARM64 support
- Setting WinUI3 proof-of-concept and validate we do need at least one more feature, elevation support from WinUI 3 unpackaged applications.
#### Dev improvements
- New YAML based pipeline for building our signed installer. This will allow us to consolidate our CI to use same file. This was critical for us to unblock ARM64 and .NET 6 migration.
- Our submodules will no longer auto fetch to prevent locking issues. If you want a refresher on how to do this, head to [our dev docs](https://github.com/microsoft/PowerToys/tree/main/doc/devdocs#get-submodules-to-compile)
- Localization system shifted to Touchdown from CDPx. This should remove many of the loc issues.
- Consolidated a lot of the naming of EXEs and DLLs along with projects
- Update to spell checker. Thanks @jsoref
- /dup response has been added
- /reportbug /bugreport will ask for a "report bug" zip
#### Community contributions
We'd like to directly mention certain contributors (in alphabetical order) for their continued community support this month and helping directly make PowerToys a better piece of software.
[@Aaron-Junker](https://github.com/Aaron-Junker), [@ChaseKnowlden](https://github.com/ChaseKnowlden), [@CleanCodeDeveloper](https://github.com/CleanCodeDeveloper), [@cyberrex5](https://github.com/cyberrex5), [@davidegiacometti](https://github.com/davidegiacometti), [@franky920920](https://github.com/franky920920), [@gsuberland](https://github.com/gsuberland), [@jay-o-way](https://github.com/jay-o-way), [@jsoref](https://github.com/jsoref), [@niels9001](https://github.com/niels9001), and [@ricardosantos9521](https://github.com/ricardosantos9521)
#### What is being planned for v0.55
For [v0.55][github-next-release-work], we'll work on adding more stability in with VCM and getting dev file preview pane added in so we get 150 file types :)
- We are working to heavily reduce / remove the UAC prompt over the next few releases on install. This is a big shift so it is spanning multiple releases so we can isolate issues if they do occur. Work is tracked in [#10126](https://github.com/microsoft/PowerToys/issues/10126)
- Getting the dev file preview pane work integrated. (Monaco Editor)
- .NET 6 upgrade to all available surfaces
- Find my mouse feature, accessibility cross-hair
- Stability
- ARM64 work
- Video conference mute investigation toward a DirectShow filter versus a driver
- OOBE work
## PowerToys Community
@@ -174,15 +148,13 @@ The application logs basic telemetry. Our Telemetry Data page (Coming Soon) has
[oss-CLA]: https://cla.opensource.microsoft.com
[oss-conduct-code]: CODE_OF_CONDUCT.md
[community-link]: COMMUNITY.md
[github-release-link]: https://aka.ms/installPowerToys
[microsoft-store-link]: https://aka.ms/getPowertoys
[winget-link]: https://github.com/microsoft/winget-cli#installing-the-client
[github-release-link]: https://github.com/microsoft/PowerToys/releases/
[roadmap]: https://github.com/microsoft/PowerToys/wiki/Roadmap
[privacy-link]: http://go.microsoft.com/fwlink/?LinkId=521839
[vidConfOverview]: https://aka.ms/PowerToysOverview_VideoConference
[loc-bug]: https://github.com/microsoft/PowerToys/issues/new?assignees=&labels=&template=translation_issue.md&title=
[usingPowerToys-docs-link]: https://aka.ms/powertoys-docs
[usingPowerToys-docs-link]: https://docs.microsoft.com/windows/powertoys/
<!-- items that need to be updated release to release -->
[github-next-release-work]: https://github.com/microsoft/PowerToys/issues?q=is%3Aopen+is%3Aissue+project%3Amicrosoft%2FPowerToys%2F28
[github-current-release-work]: https://github.com/microsoft/PowerToys/issues?q=is%3Aopen+is%3Aissue+project%3Amicrosoft%2FPowerToys%2F27
[github-next-release-work]: https://github.com/microsoft/PowerToys/issues?q=is%3Aopen+is%3Aissue+project%3Amicrosoft%2FPowerToys%2F16
[github-prerelease-link]: https://github.com/microsoft/PowerToys/releases/tag/v0.28.0

View File

@@ -1,10 +1,5 @@
# Support
## How to use Microsoft PowerToys
For more info on [PowerToys overviews and how to use the utilities][usingPowerToys-docs-link], or any other tools and resources for [Windows development environments](https://docs.microsoft.com/windows/dev-environment/overview), head over to [docs.microsoft.com][usingPowerToys-docs-link]!
## How to file issues and get help
This project uses [GitHub Issues][gh-issue] to [track bugs][gh-bug] and [feature requests][gh-feature]. Please search the existing issues before filing new issues to avoid duplicates. For new issues, file your bug or
@@ -20,5 +15,4 @@ Support for PowerToys is limited to the resources listed above.
[gh-bug]: https://github.com/microsoft/PowerToys/issues/new?assignees=&labels=Issue-Bug&template=bug_report.md&title=
[gh-feature]: https://github.com/microsoft/PowerToys/issues/new?assignees=&labels=&template=feature_request.md&title=
[wiki]: https://github.com/microsoft/PowerToys/wiki
[contributor]: https://github.com/microsoft/PowerToys/blob/main/CONTRIBUTING.md
[usingPowerToys-docs-link]: https://aka.ms/powertoys-docs
[contributor]: https://github.com/microsoft/PowerToys/blob/master/CONTRIBUTING.md

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<GeneratedFilesDir>$(IntDir)Generated Files\</GeneratedFilesDir>
</PropertyGroup>
</Project>

1
deps/cxxopts.props vendored
View File

@@ -1,4 +1,5 @@
<Project>
<Import Project="restore_git_submodules.props" Condition="'$(RestoreGitSubmodulesImported)' == ''" />
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)cxxopts\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>

2
deps/cziplib vendored

1
deps/expected.props vendored
View File

@@ -1,4 +1,5 @@
<Project>
<Import Project="restore_git_submodules.props" Condition="'$(RestoreGitSubmodulesImported)' == ''" />
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)expected-lite\include\nonstd\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>

12
deps/restore_git_submodules.props vendored Normal file
View File

@@ -0,0 +1,12 @@
<Project>
<PropertyGroup>
<RestoreGitSubmodulesImported>true</RestoreGitSubmodulesImported>
</PropertyGroup>
<Target Name="RestoreGitSubmodules" BeforeTargets="PrepareForBuild">
<Exec IgnoreExitCode="true"
EchoOff="true"
StandardOutputImportance="low"
StandardErrorImportance="low"
Command="git submodule update --init" />
</Target>
</Project>

2
deps/spdlog vendored

1
deps/spdlog.props vendored
View File

@@ -1,4 +1,5 @@
<Project>
<Import Project="restore_git_submodules.props" Condition="'$(RestoreGitSubmodulesImported)' == ''" />
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)spdlog\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>

View File

@@ -1,47 +0,0 @@
# Full list of aka links
| ShortUrl | TargetUrl |
|----------|----------|
| getpowertoys | ms-windows-store://pdp/?productid=XP89DCGQ3K6VLD |
| installpowertoys | https://github.com/microsoft/PowerToys/releases/latest |
| powertoys-license | https://github.com/microsoft/PowerToys/blob/main/LICENSE |
| powertoys | https://github.com/microsoft/PowerToys |
| PowerToysAppCompat | https://github.com/microsoft/PowerToys/wiki/Application-Compatibility |
| powerToysCannotRemapKeys | https://docs.microsoft.com/windows/powertoys/keyboard-manager#keys-that-cannot-be-remapped |
| powerToysColorPickerImageSmall | https://github.com/microsoft/PowerToys/wiki/images/overview/ColorPicker_small.png |
| powerToysColorPickerSettingImage | https://raw.githubusercontent.com/microsoft/PowerToys/main/doc/images/overview/ColorPicker_large.png |
| powertoysDetectedElevatedHelp | https://docs.microsoft.com/windows/powertoys/administrator |
| powertoys-docs | https://docs.microsoft.com/windows/powertoys/?WT.mc_id=twitter-0000-docsmsft |
| powerToysFancyZoneImageSmall | https://github.com/microsoft/PowerToys/wiki/images/overview/FancyZones_small.png |
| powerToysFancyZoneSettingImage | https://raw.githubusercontent.com/microsoft/PowerToys/main/doc/images/overview/FancyZones_large.png |
| powerToysGiveFeedback | https://github.com/microsoft/PowerToys/issues |
| powerToysImageResizerImageSmall | https://github.com/microsoft/PowerToys/wiki/images/overview/ImageResizer_small.png |
| powerToysImageResizerSettingImage | https://raw.githubusercontent.com/microsoft/PowerToys/main/doc/images/overview/ImageResizer_large.png |
| powerToysKBMImageSmall | https://github.com/microsoft/PowerToys/wiki/images/overview/KBM_small.png |
| powerToysKBMSettingImage | https://raw.githubusercontent.com/microsoft/PowerToys/main/doc/images/overview/KBM_large.png |
| PowerToysOverview | https://docs.microsoft.com/windows/powertoys/ |
| PowerToysOverview_ColorPicker | https://docs.microsoft.com/windows/powertoys/color-picker |
| PowerToysOverview_FancyZones | https://docs.microsoft.com/windows/powertoys/fancyzones |
| PowerToysOverview_FileExplorerAddOns | https://docs.microsoft.com/windows/powertoys/file-explorer |
| PowerToysOverview_ImageResizer | https://docs.microsoft.com/windows/powertoys/image-resizer |
| PowerToysOverview_KeyboardManager | https://docs.microsoft.com/windows/powertoys/keyboard-manager |
| PowerToysOverview_MouseUtilities | https://docs.microsoft.com/windows/powertoys/mouse-utilities |
| PowerToysOverview_PowerRename | https://docs.microsoft.com/windows/powertoys/powerrename |
| PowerToysOverview_PowerToysRun | https://docs.microsoft.com/windows/powertoys/run |
| PowerToysOverview_ShortcutGuide | https://docs.microsoft.com/windows/powertoys/shortcut-guide |
| PowerToysOverview_VideoConference | https://docs.microsoft.com/windows/powertoys/video-conference-mute |
| powerToysPowerLauncherImageSmall | https://github.com/microsoft/PowerToys/wiki/images/overview/PowerLauncher_small.png |
| powerToysPowerLauncherSettingImage | https://raw.githubusercontent.com/microsoft/PowerToys/main/doc/images/overview/PowerLauncher_large.png |
| powerToysPowerPreviewImageSmall | https://github.com/microsoft/PowerToys/wiki/images/overview/PowerPreview_small.png |
| powerToysPowerPreviewSettingImage | https://raw.githubusercontent.com/microsoft/PowerToys/main/doc/images/overview/PowerPreview_large.png |
| powerToysPowerRenameImageSmall | https://github.com/microsoft/PowerToys/wiki/images/overview/PowerRename_small.png |
| powerToysPowerRenameSettingImage | https://raw.githubusercontent.com/microsoft/PowerToys/main/doc/images/overview/PowerRename_large.png |
| powerToysPTImageSmall | https://github.com/microsoft/PowerToys/wiki/images/overview/PT_small.png |
| powerToysPTSettingImage | https://raw.githubusercontent.com/microsoft/PowerToys/main/doc/images/overview/PT_large.png |
| powerToysReportBug | https://github.com/microsoft/PowerToys/issues/new?assignees=&labels=Issue-Bug%2CTriage-Needed&template=bug_report.yml&title= |
| powerToysRequestFeature | https://github.com/microsoft/PowerToys/issues/new?assignees=&labels=&template=feature_request.md&title= |
| powerToysShortcutGuideImageSmall | https://github.com/microsoft/PowerToys/wiki/images/overview/ShortcutGuide_small.png |
| powerToysShortcutGuideSettingImage | https://raw.githubusercontent.com/microsoft/PowerToys/main/doc/images/overview/ShortcutGuide_large.png |
| powerToysVideoConferenceImageSmall | https://github.com/microsoft/PowerToys/wiki/images/overview/VideoConference_small.png |
| powerToysVideoConferenceSettingImage | https://github.com/microsoft/PowerToys/wiki/images/overview/VideoConference_large.png |
| powertoyswiki | https://github.com/microsoft/PowerToys/wiki |

View File

@@ -1,30 +0,0 @@
# How to integrate new MSIX module with PowerToys Settings and WiX installer
[`issue_11705_with_example` branch](https://github.com/microsoft/PowerToys/tree/issue_11705_with_example) contains HelloWorld UWP C# MSIX application which reads its module settings and is installed along PowerToys.
## Steps
- uncomment everything near "TODO: Use to activate embedded MSIX" comments
- build PowerToys solution
- deploy HelloModule module and sign it with a self-signed certificate (don't forget to put it into a trusted store)
- build PowerToysSetup solution and install it
Type HelloModule into start search and observe that it was installed:
<img src="../images/msix/hello-module-start.png">
Open PowerToys settings and change the stub setting to something:
<img src="../images/msix/hello-module-settings-page.png">
Open HelloModule:
<img src="../images/msix/hello-module-screen.png">
First time you press "Load Settings", it'll detect that it doesn't have permissions to access local file system and open its system settings window, toggle it there:
<img src="../images/msix/hello-module-app-permissions.png">
(it's a known uwp limitation, see https://stackoverflow.com/a/53533414/657390)
HelloModule will close then, restart it, press "Load Settings" and you should see that the application was able to load the setting string which was set by the settings app:
<img src="../images/msix/hello-module-loaded-settings.png">

View File

@@ -1,8 +1,5 @@
# Localization
> **NOTE**: THIS DOCUMENT IS OUTDATED.
> Follow [issue 15243](https://github.com/microsoft/PowerToys/issues/15243) for updates.
## Table of Contents
1. [Localization on the pipeline (CDPX)](#localization-on-the-pipeline-cdpx)
1. [UWP Special case](#uwp-special-case)
@@ -15,11 +12,11 @@
5. [Enabling localized MSI for a new project](#enabling-localized-msi-for-a-new-project)
## Localization on the pipeline (CDPX)
[The localization step](https://github.com/microsoft/PowerToys/blob/86d77103e9c69686c297490acb04775d43ef8b76/.pipelines/pipeline.user.windows.yml#L45-L52) is run on the pipeline before the solution is built. This step runs the [build-localization](https://github.com/microsoft/PowerToys/blob/main/.pipelines/build-localization.cmd) script, which generates resx files for all the projects with localization enabled using the `Localization.XLoc` package.
[The localization step](https://github.com/microsoft/PowerToys/blob/86d77103e9c69686c297490acb04775d43ef8b76/.pipelines/pipeline.user.windows.yml#L45-L52) is run on the pipeline before the solution is built. This step runs the [build-localization](https://github.com/microsoft/PowerToys/blob/master/.pipelines/build-localization.cmd) script, which generates resx files for all the projects with localization enabled using the `Localization.XLoc` package.
The [`Localization.XLoc`](https://github.com/microsoft/PowerToys/blob/86d77103e9c69686c297490acb04775d43ef8b76/.pipelines/build-localization.cmd#L24-L25) tool is run on the repo root, and it checks for all occurrences of `LocProject.json`. Each localized project has a `LocProject.json` file in the project root, which contains the location of the English resx file, list of languages for localization, and the output path where the localized resx files are to be copied to. In addition to this, some other parameters can be set, such as whether the language ID should be added as a folder in the file path or in the file name. When the CDPX pipeline is run, the localization team is notified of changes in the English resx files. For each project with localization enabled, a `loc` folder (see [this](https://github.com/microsoft/PowerToys/tree/main/src/modules/launcher/Microsoft.Launcher/loc) for example) is created in the same directory as the `LocProject.json` file. The folder contains language specific folders which in turn have a nested folder path equivalent to `OutputPath` in the `LocProject.json`. Each of these folders contain one `lcl` file. The `lcl` files contain the English resources along with their translation for that language. These are described in more detail [here](#lcl-files). Once the `.resx` files are generated, they will be used during the `Build PowerToys` step for localized versions of the modules.
The [`Localization.XLoc`](https://github.com/microsoft/PowerToys/blob/86d77103e9c69686c297490acb04775d43ef8b76/.pipelines/build-localization.cmd#L24-L25) tool is run on the repo root, and it checks for all occurrences of `LocProject.json`. Each localized project has a `LocProject.json` file in the project root, which contains the location of the English resx file, list of languages for localization, and the output path where the localized resx files are to be copied to. In addition to this, some other parameters can be set, such as whether the language ID should be added as a folder in the file path or in the file name. When the CDPX pipeline is run, the localization team is notified of changes in the English resx files. For each project with localization enabled, a `loc` folder (see [this](https://github.com/microsoft/PowerToys/tree/master/src/modules/launcher/Microsoft.Launcher/loc) for example) is created in the same directory as the `LocProject.json` file. The folder contains language specific folders which in turn have a nested folder path equivalent to `OutputPath` in the `LocProject.json`. Each of these folders contain one `lcl` file. The `lcl` files contain the English resources along with their translation for that language. These are described in more detail [here](#lcl-files). Once the `.resx` files are generated, they will be used during the `Build PowerToys` step for localized versions of the modules.
Since the localization script requires certain nuget packages, the [`restore-localization`](https://github.com/microsoft/PowerToys/blob/main/.pipelines/restore-localization.cmd) script is run before running `build-localization` to install all the required packages. This script must [run in the `restore` step](https://github.com/microsoft/PowerToys/blob/86d77103e9c69686c297490acb04775d43ef8b76/.pipelines/pipeline.user.windows.yml#L37-L39) of pipeline because [the host is network isolated](https://onebranch.visualstudio.com/Pipeline/_wiki/wikis/Pipeline.wiki/2066/Consuming-Packages-in-a-CDPx-Pipelinhttps://onebranch.visualstudio.com/Pipeline/_wiki/wikis/Pipeline.wiki/2066/Consuming-Packages-in-a-CDPx-Pipeline?anchor=overview) at the `build` step. The [Toolset package source](https://github.com/microsoft/PowerToys/blob/86d77103e9c69686c297490acb04775d43ef8b76/.pipelines/pipeline.user.windows.yml#L23) is used for this.
Since the localization script requires certain nuget packages, the [`restore-localization`](https://github.com/microsoft/PowerToys/blob/master/.pipelines/restore-localization.cmd) script is run before running `build-localization` to install all the required packages. This script must [run in the `restore` step](https://github.com/microsoft/PowerToys/blob/86d77103e9c69686c297490acb04775d43ef8b76/.pipelines/pipeline.user.windows.yml#L37-L39) of pipeline because [the host is network isolated](https://onebranch.visualstudio.com/Pipeline/_wiki/wikis/Pipeline.wiki/2066/Consuming-Packages-in-a-CDPx-Pipelinhttps://onebranch.visualstudio.com/Pipeline/_wiki/wikis/Pipeline.wiki/2066/Consuming-Packages-in-a-CDPx-Pipeline?anchor=overview) at the `build` step. The [Toolset package source](https://github.com/microsoft/PowerToys/blob/86d77103e9c69686c297490acb04775d43ef8b76/.pipelines/pipeline.user.windows.yml#L23) is used for this.
The process and variables that can be tweaked on the pipeline are described in more detail [here](https://onebranch.visualstudio.com/Pipeline/_wiki/wikis/Pipeline.wiki/290/Localization).
@@ -34,7 +31,7 @@ UWP differs from this as it expects the resources to have the same Resources.res
For example, `path\en-us\Resources.resw` for English and `path\fr-fr\Resources.resw` for French.
Since the pipeline generates it in this format, [a script is run](https://github.com/microsoft/PowerToys/blob/86d77103e9c69686c297490acb04775d43ef8b76/.pipelines/build-localization.cmd#L29-L31) to move these resw files to the correct format expected by all UWP projects. Currently the only UWP project is [Settings.UI](https://github.com/microsoft/PowerToys/tree/main/src/core/Settings.UI). The script used for moving the resources can be [found here](https://github.com/microsoft/PowerToys/blob/main/tools/localization/move_uwp_resources.ps1). The equivalent full language IDs for each shortened language ID obtained from the pipeline has been hardcoded in the script.
Since the pipeline generates it in this format, [a script is run](https://github.com/microsoft/PowerToys/blob/86d77103e9c69686c297490acb04775d43ef8b76/.pipelines/build-localization.cmd#L29-L31) to move these resw files to the correct format expected by all UWP projects. Currently the only UWP project is [Microsoft.PowerToys.Settings.UI](https://github.com/microsoft/PowerToys/tree/master/src/core/Microsoft.PowerToys.Settings.UI). The script used for moving the resources can be [found here](https://github.com/microsoft/PowerToys/blob/master/tools/localization/move_uwp_resources.ps1). The equivalent full language IDs for each shortened language ID obtained from the pipeline has been hardcoded in the script.
## Enabling localization on a new project
To enable localization on a new project, the first step is to create a file `LocProject.json` in the project root.
@@ -61,7 +58,7 @@ The rest of the steps depend on the project type and are covered in the sections
### C++
C++ projects do not support `resx` files, and instead use `rc` files along with `resource.h` files. The CDPX pipeline however doesn't support localizing `rc` files and the other alternative they support is directly translating the resources from the binary which makes it harder to maintain resources. To avoid this, a custom script has been added which expects a resx file and converts the entries to an rc file with a string table and adds resource declarations to a resource.h file so that the resources can be compiled with the C++ project.
If you already have a .rc file, copy the string table to a separate txt file and run the [convert-stringtable-to-resx.ps1](https://github.com/microsoft/PowerToys/blob/main/tools/build/convert-stringtable-to-resx.ps1) script on it. This script is not very robust to input, and requires the data in a specific format, where `IDS_ResName L"ResourceValue"` and any number of spaces can be present in between. The script converts this file to the format expected by [`resgen`](https://docs.microsoft.com/en-us/dotnet/framework/tools/resgen-exe-resource-file-generator#Convert), which will convert it to resx. The resource names are changed from all uppercase to title case, and the `IDS_` prefix is removed. Escape characters might have to be manually replaced, for example .rc files would have escaped double quotes as `""`, so this should be replaced with just `"` before converting to the resx files.
If you already have a .rc file, copy the string table to a separate txt file and run the [convert-stringtable-to-resx.ps1](https://github.com/microsoft/PowerToys/blob/master/tools/build/convert-stringtable-to-resx.ps1) script on it. This script is not very robust to input, and requires the data in a specific format, where `IDS_ResName L"ResourceValue"` and any number of spaces can be present in between. The script converts this file to the format expected by [`resgen`](https://docs.microsoft.com/en-us/dotnet/framework/tools/resgen-exe-resource-file-generator#Convert), which will convert it to resx. The resource names are changed from all uppercase to title case, and the `IDS_` prefix is removed. Escape characters might have to be manually replaced, for example .rc files would have escaped double quotes as `""`, so this should be replaced with just `"` before converting to the resx files.
After generating the resx file, rename the existing rc and h files to ProjName.base.rc and resource.base.h. In the rc file remove the string table which is to be localized and in the .h file remove all `#define`s corresponding to localized resources. In the vcxproj of the C++ project, add the following build event:
```
@@ -70,7 +67,7 @@ After generating the resx file, rename the existing rc and h files to ProjName.b
</Target>
```
This event runs a script which generates a resource.h and ProjName.rc in the `Generated Files` folder using the strings in all the resx files along with the existing information in resource.base.h and ProjName.base.rc. The script can be found [here](https://github.com/microsoft/PowerToys/blob/main/tools/build/convert-resx-to-rc.ps1). The script uses [`resgen`](https://docs.microsoft.com/en-us/dotnet/framework/tools/resgen-exe-resource-file-generator#Convert) to convert the resx file to a string table expected in the .rc file format. When the resources are added to the rc file the `IDS_` prefix is added and resource names are in upper case (as it was originally). Any occurrences of `"` in the string resource is escaped as `""` to prevent build errors. The string tables are added to the rc file in the following format:
This event runs a script which generates a resource.h and ProjName.rc in the `Generated Files` folder using the strings in all the resx files along with the existing information in resource.base.h and ProjName.base.rc. The script can be found [here](https://github.com/microsoft/PowerToys/blob/master/tools/build/convert-resx-to-rc.ps1). The script uses [`resgen`](https://docs.microsoft.com/en-us/dotnet/framework/tools/resgen-exe-resource-file-generator#Convert) to convert the resx file to a string table expected in the .rc file format. When the resources are added to the rc file the `IDS_` prefix is added and resource names are in upper case (as it was originally). Any occurrences of `"` in the string resource is escaped as `""` to prevent build errors. The string tables are added to the rc file in the following format:
```
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
@@ -87,7 +84,7 @@ Since there is no API to identify the `AFX_TARG_*`, `LANG_*` or `SUBLANG_*` valu
<None Include="Resources.resx" />
```
Some rc/resource.h files might be used in multiple projects (for example, KBM). To ensure the projects build for these cases, the build event can be added to the entire directory so that the rc files are generated before any project is built. See [Directory.Build.targets](https://github.com/microsoft/PowerToys/blob/main/src/modules/keyboardmanager/Directory.Build.targets) for an example.
Some rc/resource.h files might be used in multiple projects (for example, KBM). To ensure the projects build for these cases, the build event can be added to the entire directory so that the rc files are generated before any project is built. See [Directory.Build.targets](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/Directory.Build.targets) for an example.
Check [this PR](https://github.com/microsoft/PowerToys/pull/6104) for an example for making these changes for a C++ project.

View File

@@ -6,4 +6,4 @@ We use the awesome [spdlog](https://github.com/gabime/spdlog) library for loggin
<Import Project="..\..\..\deps\spdlog.props" />
```
It'll add the required include dirs and link the library binary itself.
You can see many example usage of the library in its repository or in the [bootstrapper project](../../installer/PowerToysBootstrapper/bootstrapper/bootstrapper.cpp).

View File

@@ -15,7 +15,7 @@ TODO
#### [`ZoneSet.cpp`](/src/modules/fancyzones/lib/ZoneSet.cpp)
TODO
#### [`WorkArea.cpp`](/src/modules/fancyzones/lib/WorkArea.cpp)
#### [`ZoneWindow.cpp`](/src/modules/fancyzones/lib/ZoneWindow.cpp)
TODO
## FancyZones Editor

View File

@@ -66,10 +66,10 @@ This file contains documentation for all the methods involved in key/shortcut re
[This method](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L126-L176) was added to support a feature for converting the behavior of a key from behaving like a toggle (like Caps Lock/Num Lock) to a modifier (like Ctrl), such that when you hold Caps Lock it would behave as if Caps Lock was active, and when it was not pressed Caps Lock would be off. For Caps Lock this would be similar to behaving like Shift, but for Num Lock there is no existing key which can substitute for this. This was added while testing out remapping for the KBM PoC, but wasn't added as a feature since it wasn't a priority.
## Tests
In order to test the remapping logic, a mocked keyboard input handler had to be created because otherwise the tests would process and send actual key events. For this the [`InputInterface`](https://github.com/microsoft/PowerToys/blob/main/src/modules/keyboardmanager/common/InputInterface.h) was made, and in production code the methods are implemented using [`SendInput`](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-sendinput) and [`GetAsyncKeyState`](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getasynckeystate). In addition to this, [`GetCurrentApplication`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/Helpers.cpp#L226-L268) had to be mocked so that app-specific remapping can be tested.
In order to test the remapping logic, a mocked keyboard input handler had to be created because otherwise the tests would process and send actual key events. For this the [`InputInterface`](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/common/InputInterface.h) was made, and in production code the methods are implemented using [`SendInput`](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-sendinput) and [`GetAsyncKeyState`](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getasynckeystate). In addition to this, [`GetCurrentApplication`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/Helpers.cpp#L226-L268) had to be mocked so that app-specific remapping can be tested.
### MockedInput
The [`MockedInput`](https://github.com/microsoft/PowerToys/blob/main/src/modules/keyboardmanager/test/MockedInput.h) class uses a 256 size `bool` vector to store the key state for each key code. Identifying the foreground process is mocked by simply setting and getting a string value for the name of the current process.
The [`MockedInput`](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/test/MockedInput.h) class uses a 256 size `bool` vector to store the key state for each key code. Identifying the foreground process is mocked by simply setting and getting a string value for the name of the current process.
[To mock the `SendInput` method](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/test/MockedInput.cpp#L10-L110), the steps for processing the input are as follows. This implementation is based on public documentation for SendInput and the behavior of key messages and keyboard hooks:
- Iterate over all the inputs in the INPUT array argument
@@ -81,4 +81,4 @@ The [`MockedInput`](https://github.com/microsoft/PowerToys/blob/main/src/modules
- For modifiers the behavior is slightly different as if the key state of the L/R version is modified, it should also modify the common version, and if a common version is released, it should release both the L and R versions.
### Tests for single key remaps and shortcut remaps
Using the MockedInput handler, all the expected (and known) key scenarios that can occur for while pressing a [remapped key](https://github.com/microsoft/PowerToys/blob/main/src/modules/keyboardmanager/test/SingleKeyRemappingTests.cpp) or [remapped shortcut](https://github.com/microsoft/PowerToys/blob/main/src/modules/keyboardmanager/test/OSLevelShortcutRemappingTests.cpp) are tested. The foreground app behavior which is specific to app-specific shortcuts is tested [here](https://github.com/microsoft/PowerToys/blob/main/src/modules/keyboardmanager/test/AppSpecificShortcutRemappingTests.cpp).
Using the MockedInput handler, all the expected (and known) key scenarios that can occur for while pressing a [remapped key](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/test/SingleKeyRemappingTests.cpp) or [remapped shortcut](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/test/OSLevelShortcutRemappingTests.cpp) are tested. The foreground app behavior which is specific to app-specific shortcuts is tested [here](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/test/AppSpecificShortcutRemappingTests.cpp).

View File

@@ -185,7 +185,7 @@ This method is used by [SharpKeys](https://github.com/randyrants/sharpkeys) and
Using a driver approach has the benefit of not depending on precedence orders as KBM could always run before low level hooks, and it also has the benefit of differentiating between different keyboards, allowing [multi keyboard-specific remaps](https://github.com/microsoft/PowerToys/issues/1460). The disadvantages are however that any bug or crash could have system level consequences. [Interception](https://github.com/oblitum/Interception) is an open source driver that could be used for implementing this. The approach was deprioritized due to the potential side effects.
## Telemetry
Keyboard Manager emits the following telemetry events (implemented in [trace.h](https://github.com/microsoft/PowerToys/blob/main/src/modules/keyboardmanager/common/trace.h) and [trace.cpp](https://github.com/microsoft/PowerToys/blob/main/src/modules/keyboardmanager/common/trace.cpp)):
Keyboard Manager emits the following telemetry events (implemented in [trace.h](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/common/trace.h) and [trace.cpp](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/common/trace.cpp)):
- **`KeyboardManager_EnableKeyboardManager`:** Logs a `boolean` value storing the KBM toggle state. It is logged whenever KBM is enabled or disabled (emitted [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/dllmain.cpp#L305-L316)).
- **`KeyboardManager_KeyRemapCount`:** Logs the number of key to key and key to shortcut remaps (i.e. all the remaps on the Remap a key window). This gets logged on saving new settings in the Remap a key window (emitted [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/LoadingAndSavingRemappingHelper.cpp#L159-L163)).
- **`KeyboardManager_OSLevelShortcutRemapCount`:** Logs the number of global shortcut to shortcut and shortcut to key remaps. This gets logged on saving new settings in the Remap a shortcut window (emitted [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/LoadingAndSavingRemappingHelper.cpp#L220)).

View File

@@ -17,7 +17,7 @@ This project contains any code that is to be shared between the backend and UI p
1. [Foreground App Detection](#Foreground-App-Detection)
## KeyboardManagerState
[This class](https://github.com/microsoft/PowerToys/blob/main/src/modules/keyboardmanager/common/KeyboardManagerState.cpp) stores all the data related to remappings and is also used in the sense of a View Model as it used to communicate common data that is shared between the KBM UI and the backend. They are accessed on the UI controls using static class members of `SingleKeyRemapControl` and `ShortcutControl`.
[This class](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/common/KeyboardManagerState.cpp) stores all the data related to remappings and is also used in the sense of a View Model as it used to communicate common data that is shared between the KBM UI and the backend. They are accessed on the UI controls using static class members of `SingleKeyRemapControl` and `ShortcutControl`.
### UI States
[UI states](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/KeyboardManagerState.h#L27-L42) are used to keep track in which step of the UI flow is the user at, such as which Remap window they are on, or if they have one of the Type windows open. This is required because the hook needs to suppress input and update UI in some cases, and in some cases remappings have to be disabled altogether.
@@ -37,12 +37,12 @@ The [`SaveConfigToFile`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a
To prevent the UI thread and low level hook thread from concurrently accessing the remap tables we use an [`atomic bool` variable](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/KeyboardManagerState.h#L91-L92), which is set to `true` while the tables are getting updated. When this is `true` the hook will skip all remappings. Use of mutexes in the hook were removed to prevent re-entrant mutex bugs.
## KeyDelay
[This class](https://github.com/microsoft/PowerToys/blob/main/src/modules/keyboardmanager/common/KeyDelay.cpp) implements a queue based approach for processing key events and based on the time difference between key down and key up events [executes separate methods for `ShortPress`, `LongPress` or `LongPressReleased`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/KeyDelay.h#L69-L72). The class is used for the hold Enter/Esc functionality required for making the Type window accessible and prevent keyboard traps (see [this](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/SingleKeyRemapControl.cpp#L273-L292) for an example of it's usage). The `KeyEvents` are added to the queue from the hook thread of KBM, and a separate [`DelayThread`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/KeyDelay.cpp#L142-L166) is used to process the key events by checking the `time` member in the key event. The thresholds for short vs long press and hold wait timeouts are `static` constants, but if the module is extended for other purposes these could be made into arguments.
[This class](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/common/KeyDelay.cpp) implements a queue based approach for processing key events and based on the time difference between key down and key up events [executes separate methods for `ShortPress`, `LongPress` or `LongPressReleased`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/KeyDelay.h#L69-L72). The class is used for the hold Enter/Esc functionality required for making the Type window accessible and prevent keyboard traps (see [this](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/SingleKeyRemapControl.cpp#L273-L292) for an example of it's usage). The `KeyEvents` are added to the queue from the hook thread of KBM, and a separate [`DelayThread`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/KeyDelay.cpp#L142-L166) is used to process the key events by checking the `time` member in the key event. The thresholds for short vs long press and hold wait timeouts are `static` constants, but if the module is extended for other purposes these could be made into arguments.
**Note:** [Deletion of the `KeyDelay`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/KeyDelay.cpp#L4-L12) object should never be called from the `DelayThread` i.e. from within one of the 3 handlers, as it can re-enter the mutex and would lead to a deadlock. This can be avoided by either deleting it on a separate thread or as done in the KBM UI, on the dispatcher thread. See [this PR](https://github.com/microsoft/PowerToys/pull/6959#issue-496583547) for more details on this issue.
## Shortcut and RemapShortcut classes
The [`Shortcut` class](https://github.com/microsoft/PowerToys/blob/main/src/modules/keyboardmanager/common/Shortcut.h) is a data structure for storing key combinations which are valid shortcuts and it contains several methods which are used for shortcut specific operations. [`RemapShortcut`](https://github.com/microsoft/PowerToys/blob/main/src/modules/keyboardmanager/common/RemapShortcut.h) consists of a shortcut/key union (`std::variant`), along with other boolean flags which are required on the hook side for storing any relevant keyboard states mid-execution.
The [`Shortcut` class](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/common/Shortcut.h) is a data structure for storing key combinations which are valid shortcuts and it contains several methods which are used for shortcut specific operations. [`RemapShortcut`](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/common/RemapShortcut.h) consists of a shortcut/key union (`std::variant`), along with other boolean flags which are required on the hook side for storing any relevant keyboard states mid-execution.
### IsKeyboardStateClearExceptShortcut
[This method](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/Shortcut.cpp#L665-L813) is used by the `HandleShortcutRemapEvent` to check if any other keys on the keyboard have been pressed apart from the keys in the shortcut. This is required because shortcut to shortcut remaps should not be applied if the shortcut is pressed with other keys. The method iterates over all the possible key codes, except any keys that are considered reserved, unassigned, OEM-specific or undefined, as well as mouse buttons (see list [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/Shortcut.cpp#L628-L663)).
@@ -51,13 +51,13 @@ The [`Shortcut` class](https://github.com/microsoft/PowerToys/blob/main/src/modu
[This method](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/Shortcut.cpp#L517-L614) uses `GetVirtualKeyState` (internally calls `GetAsyncKeyState` in production code), to check if all the modifiers of the current shortcut are being pressed. Since Win doesn't have a non-L/R key code we check this by checking both LWIN and RWIN.
### Tests
Tests for some methods in the `Shortcut` class can be found [here](https://github.com/microsoft/PowerToys/blob/main/src/modules/keyboardmanager/test/ShortcutTests.cpp).
Tests for some methods in the `Shortcut` class can be found [here](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/test/ShortcutTests.cpp).
## Helpers
[This namespace](https://github.com/microsoft/PowerToys/blob/main/src/modules/keyboardmanager/common/Helpers.cpp) has any methods which are used across either UI or the backend which aren't specific to either. Some of these methods have tests [here](https://github.com/microsoft/PowerToys/blob/main/src/modules/keyboardmanager/test/SetKeyEventTests.cpp).
[This namespace](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/common/Helpers.cpp) has any methods which are used across either UI or the backend which aren't specific to either. Some of these methods have tests [here](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/test/SetKeyEventTests.cpp).
### Foreground App Detection
[`GetCurrentApplication`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/Helpers.cpp#L226-L268) is used for detecting the foreground process for App-specific shortcuts. The logic is very similar to that used for FZ's app exception feature, involving `GetForegroundWindow` and `get_process_path`. The one additional case which has been added is for full-screen UWP apps, where the above method fails and returns `ApplicationFrameHost.exe`. The [`GetFullscreenUWPWindowHandle`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/Helpers.cpp#L210-L224) uses `GetGUIThreadInfo` API to find the window linked to the GUI thread. This logic is based on [this stackoverflow answer](https://stackoverflow.com/questions/39702704/connecting-uwp-apps-hosted-by-applicationframehost-to-their-real-processes/55353165#55353165).
**Note:** The [`GetForegroundProcess` method](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/Input.cpp#L17-L21) performs string allocation in a weird way because of exceptions that were occurring while running tests as a result of memory being allocated or deallocated across dll boundaries. Here's the comment from the PR where this was added
> To make app-specific logic test-able, a GetForegroundProcess was added to the input interface which internally calls GetCurrentApplication. This allows us to mock this method in the test project by just setting some process name as the foreground process for that function. When I set this to just return the string name, it would goes runtime errors on the test project in debug_heap with `__acrt_first_block == header`. Based on [this stackoverflow answer](https://stackoverflow.com/a/35311928), this would happen if allocation happens in one dll's code space and deallocation happens in another. One way to avoid this is to change both the projects to MD (multi threaded dll) instead of MT(multi threaded), however that results in many compile-time errors since all the PT projects are configured as MT. To solve this, the GetForegroundProcess was rewritten such that its argument is the output variable, and we allocate memory for that string within the AppSpecificHandler method rather than in that function.
> To make app-specific logic test-able, a GetForegroundProcess was added to the input interface which internally calls GetCurrentApplication. This allows us to mock this method in the test project by just setting some process name as the foreground process for that function. When I set this to just return the string name, it would goes runtime errors on the test project in debug_heap with `__acrt_first_block == header`. Based on [this stackoverflow answer](https://stackoverflow.com/a/35311928), this would happen if allocation happens in one dll's code space and deallocation happens in another. One way to avoid this is to change both the projects to MD (multi threaded dll) instead of MT(multi threaded), however that results in many compile-time errors since all the PT projects are configured as MT. To solve this, the GetForegroundProcess was rewritten such that its argument is the output variable, and we allocate memory for that string within the AppSpecificHandler method rather than in that function.

View File

@@ -24,7 +24,7 @@ The KBM UI is implemented as a C++ XAML Island, but all the controls are impleme
The windows are [created as C++ windows](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp#L128-L140) and the window sizes are set to default by [scaling them as per DPI](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp#L120-L126) using the `DPIAware::Convert` API from common lib. Since the UI is launched on a new thread, the window may not be in the foreground, so [we call `SetForegroundWindow`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp#L146-L150).
`DesktopWindowXamlSource` has to be declared and [it is initialized](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp#L159-L162) using the [`XamlBridge`](https://github.com/microsoft/PowerToys/blob/main/src/modules/keyboardmanager/ui/XamlBridge.cpp), and [a second window handle](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp#L161-L162) is generated for the internal Xaml Island window. Most of the code was based on the [Xaml Island Sample](https://github.com/microsoft/Xaml-Islands-Samples/blob/master/Samples/Win32/SampleCppApp/XamlBridge.cpp). The `XamlBridge` class contains code which handles initializing the Xaml Island containers as well as handling special messages like keyboard navigation, and focus between islands and between the C++ window and the island. It also has methods for clearing the xaml islands and closing the window.
`DesktopWindowXamlSource` has to be declared and [it is initialized](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp#L159-L162) using the [`XamlBridge`](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/ui/XamlBridge.cpp), and [a second window handle](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp#L161-L162) is generated for the internal Xaml Island window. Most of the code was based on the [Xaml Island Sample](https://github.com/microsoft/Xaml-Islands-Samples/blob/master/Samples/Win32/SampleCppApp/XamlBridge.cpp). The `XamlBridge` class contains code which handles initializing the Xaml Island containers as well as handling special messages like keyboard navigation, and focus between islands and between the C++ window and the island. It also has methods for clearing the xaml islands and closing the window.
Once the UI controls are created, the parent container is set as the content for the `DesktopWindowXamlSource` and the `XamlBridge.MessageLoop` is executed. Messages are processed by the C++ window handler like [`EditKeyboardWindowProc`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp#L364-L404). The general structure we use for this is, for any `WM_PAINT` or `WM_SIZE` message we resize the Xaml Island window. For `WM_GETMINMAXINFO` we set minimum widths so that the window cannot be resized beyond a minimum height and width. This is done to prevent the WinUI elements from overlapping and getting cropped. If it is neither of these cases we send the message to the [`XamlBridge.MessageHandler`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/XamlBridge.cpp#L291-L301) which handles Destroy, Activation and Focus. If `WM_NCDESTROY` is received when the `XamlBridge` is `nullptr`, the window thread is terminated.
@@ -41,7 +41,7 @@ To access the brushes available on C# Xaml, it has to be done with the `Resource
`primaryButton.Background(Windows::UI::Xaml::Application::Current().Resources().Lookup(box_value(L"SystemControlBackgroundBaseMediumLowBrush")).as<Windows::UI::Xaml::Media::SolidColorBrush>());`
## UI Structure
The KBM UI consists of a [`Grid` with several columns](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp#L200-L218). Rows are added dynamically when [the add button is pressed](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp#L305-L309). [A vector of vector of unique pointers to `SingleKeyRemapControl`/`ShortcutControl`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp#L248-L249) is created so that references to the UI components and their data are not lost until the window is closed. [`SingleKeyRemapControl`](https://github.com/microsoft/PowerToys/blob/main/src/modules/keyboardmanager/ui/SingleKeyRemapControl.cpp) is the UI class for each row of the Remap keys table, and [`ShortcutControl`](https://github.com/microsoft/PowerToys/blob/main/src/modules/keyboardmanager/ui/ShortcutControl.cpp) is the UI class for each row of the Remap shortcuts table. [`KeyDropDownControl`](https://github.com/microsoft/PowerToys/blob/main/src/modules/keyboardmanager/ui/KeyDropDownControl.cpp) is used for handling the ComboBox operations. Each of these two classes [have vectors of unique pointers to the `KeyDropDownControl` objects](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/ShortcutControl.h#L44-L45) so that references to the objects are active until the control is deleted.
The KBM UI consists of a [`Grid` with several columns](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp#L200-L218). Rows are added dynamically when [the add button is pressed](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp#L305-L309). [A vector of vector of unique pointers to `SingleKeyRemapControl`/`ShortcutControl`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp#L248-L249) is created so that references to the UI components and their data are not lost until the window is closed. [`SingleKeyRemapControl`](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/ui/SingleKeyRemapControl.cpp) is the UI class for each row of the Remap keys table, and [`ShortcutControl`](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/ui/ShortcutControl.cpp) is the UI class for each row of the Remap shortcuts table. [`KeyDropDownControl`](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/ui/KeyDropDownControl.cpp) is used for handling the ComboBox operations. Each of these two classes [have vectors of unique pointers to the `KeyDropDownControl` objects](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/ShortcutControl.h#L44-L45) so that references to the objects are active until the control is deleted.
When the UI windows are activated the `KeyboardManagerState` object [sets the `UIState` variable](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp#L251-L252) which is used for distinguishing if the UI is up from the keyboard hook thread. The [states are also updated](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/SingleKeyRemapControl.cpp#L53) on opening and closing the Type window.
@@ -89,7 +89,7 @@ On making a selection in the drop down, [the selection handler](https://github.c
- Conflicting modifier previously remapped (Ctrl->A and Ctrl(left)->B, since Ctrl also includes Ctrl(left))
If the selection is found to be valid, the `singleKeyRemapBuffer` is updated accordingly.
For handling `Shortcut` and key in the remap buffer for the right column, we use `std::variant`, which allows us to store either of the two types and check which one of them is present in the buffer by using the `index` method.
[`ValidateAndUpdateKeyBufferElement`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/BufferValidationHelpers.cpp#L8-L66) does not reference any UI components and instead takes all the relevant data as arguments. This method [has tests](https://github.com/microsoft/PowerToys/blob/main/src/modules/keyboardmanager/test/BufferValidationTests.cpp) which covers all the cases that could arise from making selections on the UI.
[`ValidateAndUpdateKeyBufferElement`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/BufferValidationHelpers.cpp#L8-L66) does not reference any UI components and instead takes all the relevant data as arguments. This method [has tests](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/test/BufferValidationTests.cpp) which covers all the cases that could arise from making selections on the UI.
### Shortcut ComboBox Selection Handler
On making a selection in the drop down, [the selection handler](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/KeyDropDownControl.cpp#L215-L295) validates the input with the buffer from the other column and other rows. Error messages are shown using flyouts if the selection is not considered valid and the drop down and buffer for that entry are reset to empty selection.
@@ -115,7 +115,7 @@ Unlike the Single Key handler, there is a different set of errors that can occur
- Conflicting shortcut previously remapped for same target app (Ctrl+A->B and Ctrl(left)+A->C, since Ctrl also includes Ctrl(left))
- Illegal shortcut remaps like Win+L or Ctrl+Alt+Del (since these cannot be remapped using LL hooks)
[`ValidateShortcutBufferElement`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/BufferValidationHelpers.cpp#L68-L304) does not reference any UI components and instead takes all the relevant data as arguments. This method [has tests](https://github.com/microsoft/PowerToys/blob/main/src/modules/keyboardmanager/test/BufferValidationTests.cpp) which covers all the cases that could arise from making selections on the UI.
[`ValidateShortcutBufferElement`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/BufferValidationHelpers.cpp#L68-L304) does not reference any UI components and instead takes all the relevant data as arguments. This method [has tests](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/test/BufferValidationTests.cpp) which covers all the cases that could arise from making selections on the UI.
**Note:** After updating the buffer we have [code to handle a special case](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/KeyDropDownControl.cpp#L269-L279), which was required to prevent scenarios where a drop down can get deleted but the corresponding `KeyDropDownControl` object isn't deleted. The code checks if the drop down is still linked to the parent and accordingly deletes the `KeyDropDownControl` object from the vector.

View File

@@ -3,7 +3,7 @@
## Debugging Prerequisite
Setup development environment for PowerToys by following instruction [here.](https://github.com/microsoft/PowerToys/tree/main/doc/devdocs#prerequisites-for-compiling-powertoys)
Setup development environment for PowerToys by following instruction [here.](https://github.com/microsoft/PowerToys/tree/master/doc/devdocs#prerequisites-for-compiling-powertoys)
## Direct debugging
This approach is used to test UI, plugins, and core `PowerToys Run` functionality. This **cannot** be used to test `PowerToys Run` settings. The approach is significantly faster compared to `Debugging with runner`, as it requires compiling projects relevant to `PowerToys Run`. Please follow the steps below for direct debugging.

View File

@@ -1,36 +0,0 @@
# New plugin checklist
- [ ] The plugin is a project under `modules\launcher\Plugins`
- [ ] Microsoft plugin project name pattern: `Microsoft.PowerToys.Run.Plugin.{PluginName}`
- [ ] Community plugin project name pattern: `Community.PowerToys.Run.Plugin.{PluginName}`
- [ ] [`GlobalSuppressions.cs`](/src/codeAnalysis/GlobalSuppressions.cs) and [`StyleCop.json`](/src/codeAnalysis/StyleCop.json) have to be included in the plugin project so it follows PowerToys code guidelines
- [ ] The project file should import `Version.props` and specify `<Version>$(Version).0</Version>`
- [ ] Make sure `*.csproj` specify only x64 platform target
- [ ] The plugin has to contain a `plugin.json` file of the following format in its root folder
```
{
"ID": string, // GUID string
"ActionKeyword": string, // Direct activation phrase
"IsGlobal": boolean,
"Name": string, // Has to be unique, same as 'PluginName' in the project name pattern
"Author": string,
"Version": "1.0.0", // For future compatibility
"Language": "csharp", // So far we support only csharp
"Website": "https://aka.ms/powertoys",
"ExecuteFileName": string, // Should be {Type}.PowerToys.Run.Plugin.{PluginName}.dll
"IcoPathDark": string, // Path to dark theme icon. The path is relative to the root plugin folder
"IcoPathLight": string // Path to light theme icon. The path is relative to the root plugin folder
}
```
- [ ] Do not use plugin name or PowerToys as prefixes for entities inside of the plugin project
- [ ] The plugin has to have Unit tests. Use MSTest framework
- [ ] Plugin's output code and assets have to be included in the installer [`Product.wxs`](/installer/PowerToysSetup/Product.wxs)
- [ ] Test the plugin with a local build. Build the installer, install, check that the plugin works as expected
- [ ] All plugin's binaries have to be included in the signed build [`pipeline.user.windows.yml`](/.pipelines/pipeline.user.windows.yml)
- [ ] The plugin target framework has to be .NET Core 3.1. All dependencies have to have .NET 5 version
Some localization steps can only be done after the first pass by the localization team to provide the localized resources.
In the PR that adds a new plugin, reference a new issue to track the work for fully enabling localization for the new plugin.
- [ ] Add the resource folder to https://github.com/microsoft/PowerToys/blob/21247c0bb09a1bee3d14d6efa53d0c247f7236af/installer/PowerToysSetup/Product.wxs#L825
- [ ] Add the resource files under the section https://github.com/microsoft/PowerToys/blob/21247c0bb09a1bee3d14d6efa53d0c247f7236af/installer/PowerToysSetup/Product.wxs#L882

View File

@@ -1,31 +0,0 @@
# Unit Converter Plugin
The Unit Convert plugin as the name suggests is used to perform unit conversion on the user entered query.
This plugin uses a package called [UnitsNet](https://github.com/angularsen/UnitsNet).
![Image of Calculator plugin](/doc/images/launcher/plugins/community.unitconverter.png)
### Currently Supported Units
- [Acceleration](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/AccelerationUnit.g.cs)
- [Angle](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/AngleUnit.g.cs)
- [Area](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/AreaUnit.g.cs)
- [Duration](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/DurationUnit.g.cs)
- [Energy](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/EnergyUnit.g.cs)
- [Information](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/InformationUnit.g.cs)
- [Length](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/LengthUnit.g.cs)
- [Mass](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/MassUnit.g.cs)
- [Power](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/PowerUnit.g.cs)
- [Pressure](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/PressureUnit.g.cs)
- [Speed](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/SpeedUnit.g.cs)
- [Temperature](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/TemperatureUnit.g.cs)
- [Volume](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/VolumeUnit.g.cs)
These are the ones that are currently enabled (though UnitsNet supports many more). They are defined in [`Main.cs`](/src/modules/launcher/Plugins/Community.PowerToys.Run.UnitConverter/Main.cs).
### [`InputInterpreter`](/src/modules/launcher/Plugins/Community.PowerToys.Run.UnitConverter/InputInterpreter.cs)
- Class which manipulates user input such that it may be interpreted correctly and thus converted.
- Uses a regex amongst other things to do this.
### [`UnitHandler`](/src/modules/launcher/Plugins/Community.PowerToys.Run.UnitConverter/UnitHandler.cs)
- Class that does the actual conversion.
- Supports abbreviations in user input (single, double, or none).

View File

@@ -32,7 +32,4 @@ Each plugin implements the `IPlugin` interface which comprises of the `Init()` a
### Score
- The user query is executed against each of the plugins and the result list view is updated with results from each of the plugins.
- The ordering of the results is based on the `Score` of each Result.
- Each plugin assigns a score to a result based on it's relevance. The results with higher scores are displayed higher in the list view and vice versa.
## Plugin settings
Plugin settings that are editable from the settings are stored in `PowerToys Run\settings.json`. In the very first run, those settings are populated from plugin' `plugin.json` file. Unlike Wox we do not support multiple action keywords. Instead, we have `ActionKeyword` and `IsGlobal` options.
- Each plugin assigns a score to a result based on it's relevance. The results with higher scores are displayed higher in the list view and vice versa.

View File

@@ -78,7 +78,7 @@ The plugin use only these interfaces (all inside the `Main.cs`):
| Name | Value |
| --------------- | ------------------------------------------------------------------------------ |
| TargetFramework | `net5.0-windows` (.NET 5) or `net5.0-windows10.0.18362.0` (OS version specific)|
| TargetFramework | `netcoreapp3.1` (means .NET Core 3.1) |
| LangVersion | `8.0` (mean C# 8.0) |
| Platforms | `x64` |
| Nullable | `true` |

View File

@@ -1,11 +0,0 @@
## Web Search Plugin
The Web Search Plugin, as the name suggests, is used to perform a web search - in the default search engine in the default browser - on the query that has been entered by the user.
![Image of Web Search plugin](/doc/images/launcher/plugins/WebSearch.png)
## Default Browser Icon
- The icon for each web search result is that of the default browser set by the user.
- It, and the browser path, are obtained from the user registry and updated each time the theme of PT Run is changed.
## Score
- The web search result always has a score of 0 which indicates that it would show up after each of the other plugins, other than the indexer plugin and possibly the uri plugin which both have a score of 0.

View File

@@ -1,161 +0,0 @@
# Windows Settings Plugin
The Windows settings Plugin allows users to search the Windows settings.
## Special functions (differ from the regular functions)
* Support modern Windows settings (Windows 10+)
* Support legacy Windows settings (Windows 7, 8.1)
* Support extra programs for setting (like ODBC)
* Support search by the area of the setting (like `Privacy`)
* Support search for alternative names of a setting
## How to add a new Windows Setting or change one
All Windows settings are located in `WindowsSettings.json` in root folder of the project.
The `WindowsSettings.json` use a JSON schema file that make it easier to edit it.
| Key | Optional | Value type | String prefix |
| ------------------- | -------- | ----------------- | ------------- |
| `Name` | **No** | String | |
| `Type` | **No** | String | `App` |
| `Command` | **No** | String | |
| `Areas` | Yes | List with strings | `Area` |
| `AltNames` | Yes | List with strings | |
| `Note` | Yes | String | `Note` |
| `IntroducedInBuild` | Yes | Integer | |
| `DeprecatedInBuild` | Yes | Integer | |
| `ShowAsFirstResult` | Yes | Boolean | |
A minimum entry for the `WindowsSettings.json` looks like:
```json
{
"Name": "mySetting",
"Type": "AppSettingsApp",
"Command": "ms-settings:mySetting"
}
```
A full entry for the `WindowsSettings.json` looks like:
```json
{
"Name": "mySetting",
"Type": "AppSettingsApp",
"Command": "ms-settings:mySetting",
"Areas": [ "AreaMySettingArea" ],
"AltNames": [ "NiceSetting" ],
"Note": "NoteMySettingNote",
"IntroducedInBuild" : 1903,
"DeprecatedInBuild" : 2004,
"ShowAsFirstResult" : true
}
```
### Remarks
* The `Command` for modern Windows settings should start with `ms-settings:`
* The `Command` for legacy Windows settings should start with `control`
* The integer value for `IntroducedInBuild` and `DeprecatedInBuild` must be in range of `0` to `4294967295`
* The strings for `Name`, `AltNames`, `Areas`, `Type` and `Note` must not contain whitespace(s) or special characters (#, €, $, etc.)
* The strings for `Name`, `AltNames`, `Areas`, `Type` and `Note` are used as ids for the resource file under `Properties\Resources.resx`
* When you add new strings make sure you have add add all translations for it.
## Scores
There are three different score types with different start values.
| Score type | Start value |
| ------------------ | ------------ |
| First result score | 10500 |
| High score | 10000 |
| Medium score | 5000 |
| Low score | 1000 |
Each score will decreased by one when a condition match.
| Priority | Condition | Score type |
| -------- | ----------------------------------------------------------------- | ------------ |
| 1. | Settings name starts with the search value | High score |
| 2. | Settings name contain the search value | Medium score |
| 3. | Setting has no area | Low score |
| 4. | One area of the settings starts with the search value | Low score |
| 5. | Setting has no alternative name | Low score |
| 6. | One alternative name of the settings starts with the search value | Medium score |
| x. | no condition match | Low score |
### Remarks
* For each score condition we check if the property "ShowAsFirstResult" of the setting is true. If yes we use the firstResultScore instead of condition`s score.
## Important for developers
### General
* The assembly name is cached into `_assemblyName` (to avoid to many calls of `Assembly.GetExecutingAssembly()`)
## Microsoft.PowerToys.Run.Plugin.WindowsSettings project
### Important plugin values (meta-data)
| Name | Value |
| --------------- | ---------------------------------------------------- |
| ActionKeyword | `$` |
| ExecuteFileName | `Microsoft.PowerToys.Run.Plugin.WindowsSettings.dll` |
| ID | `5043CECEE6A748679CBE02D27D83747A` |
### Interfaces used by this plugin
The plugin use only these interfaces (all inside the `Main.cs`):
* `Wox.Plugin.IPlugin`
* `Wox.Plugin.IContextMenu`
* `Wox.Plugin.IPluginI18n`
### Program files
| File | Content |
| ------------------------------------- | ----------------------------------------------------------------------- |
| `Classes\WindowsSetting.cs` | A class that represent one Windows setting |
| `Classes\WindowsSettings.cs` | A wrapper class that only contains a list with Windows settings (see 1) |
| `Helper\ContextMenuHelper.cs` | All functions to build the context menu (for each result entry) |
| `Helper\JsonSettingsListHelper.cs` | All functions to load the windows settings from a JSON file |
| `Helper\ResultHelper.cs` | All functions to convert internal results into WOX results |
| `Helper\TranslationHelper.cs` | All functions to translate the result in the surface language |
| `Helper\UnsupportedSettingsHelper.cs` | All functions to filter not supported Windows settings out |
| `Helper\WindowsSettingsPathHelper.cs` | All functions to build the area paths |
| `Images\WindowsSettings.dark.png` | Symbol for the results for the dark theme |
| `Images\WindowsSettings.light.png` | Symbol for the results for the light theme |
| `Properties\Resources.Designer.resx` | File that contain all translatable keys |
| `Properties\Resources.resx` | File that contain all translatable strings in the neutral language |
| `GlobalSuppressions.cs` | Code suppressions (no real file, linked via *.csproj) |
| `Main.cs` | Main class, the only place that implement the WOX interfaces |
| `plugin.json` | All meta-data for this plugin |
| `StyleCop.json` | Code style (no real file, linked via *.csproj) |
1. We need this extra wrapper class to make it possible that the JSON file can have and use a JSON schema file.
Because the JSON file must have a object as root type, instead of a array.
### Important project values (*.csproj)
| Name | Value |
| --------------- | --------------------------------------------------------------------------------------------------- |
| TargetFramework | `net5.0-windows` (.NET 5) or `net5.0-windows10.0.18362.0` (OS version specific) |
| Platforms | `x64` |
| Output | `..\..\..\..\..\x64\Debug\modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.WindowsSettings\` |
| RootNamespace | `Microsoft.PowerToys.Run.Plugin.WindowsSettings` |
| AssemblyName | `Microsoft.PowerToys.Run.Plugin.WindowsSettings` |
### Project dependencies
#### Packages
| Package | Version |
| ------------------------------------------------------------------------------------- | ------- |
| [`StyleCop.Analyzers`](https://github.com/DotNetAnalyzers/StyleCopAnalyzers) | 1.1.118 |
#### Projects
* `Wox.Infrastructure`
* `Wox.Plugin`

View File

@@ -3,19 +3,16 @@ The window walker plugin matches the user entered query with the open windows on
![Image of Window Walker plugin](/doc/images/launcher/plugins/windowwalker.png)
### [`OpenWindows.cs`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/OpenWindows.cs)
- The window walker plugin uses the `EnumWindows` function to enumerate all the open windows in the [`OpenWindows.cs`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/OpenWindows.cs) class.
### [`OpenWindows.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/OpenWindows.cs)
- The window walker plugin uses the `EnumWindows` function to enumerate all the open windows in the [`OpenWindows.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/OpenWindows.cs) class.
### [`SearchController.cs`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/SearchController.cs)
- The [`SearchController`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/SearchController.cs) encapsulates the functions needed to search and find matches.
- It is responsible for updating the search text and performing a fuzzy search on all the open windows.
### [`Window.cs`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/Window.cs)
- The [`Window`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/Window.cs) class represents a specific window and has functions to get the name of the window, the state of the window (whether it is visible or not), and the `SwitchTowindow` function which switches the desktop focus to the selected window. This action is performed when the user clicks on a window walker plugin result.
- The `Window` class holds a static cache with the process information of all windows we know so far and each window instance has a property which holds its process information (name, file, ...). The process data in the cache and the window property are of the type `WindowProcess`.
### [`SearchController.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/SearchController.cs)
- The [`SearchController`](src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/SearchController.cs) encapsulates the functions needed to search and find matches.
- It is responsible for updating the search text and performing a fuzzy search on all the open windows in an asynchronous manner.
### [`WindowProcess.cs`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/WindowProcess.cs)
- The [`WindowProcess`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/WindowProcess.cs) class represents a specific process for a window. It contains static methods to query process information from the system. And it contains instance methods and properties to hold/retrieve the process information we want to know about a window's process.
### [`Window.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/Window.cs)
- The [`Window`](src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/Window.cs) class represents a specific window and has functions to get the name of the process, the state of the window (whether it is visible or not), and the `SwitchTowindow` function which switches the desktop focus to the selected window. This action is performed when the user clicks on a window walker plugin result.
### Score
The window walker plugin uses [`FuzzyMatching`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/FuzzyMatching.cs) to get the matching indices and calculates the score by creating a 2 dimensional array of the window and the query text.
The window walker plugin uses [`FuzzyMatching`](src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/FuzzyMatching.cs) to get the matching indices and calculates the score by creating a 2 dimensional array of the window and the query text.

View File

@@ -14,4 +14,3 @@
- [Sys](/doc/devdocs/modules/launcher/plugins/sys.md)
- [Uri](/doc/devdocs/modules/launcher/plugins/uri.md)
- [Window Walker](/doc/devdocs/modules/launcher/plugins/windowwalker.md)
- [Web Search](/doc/devdocs/modules/launcher/plugins/WebSearch.md)

View File

@@ -1,22 +0,0 @@
# Developer Preview (Monaco)
Developer preview is based on [Microsofts Monaco Editor](https://microsoft.github.io/monaco-editor/) which is maintained by the Visual Studio Code team.
## Update monaco editor
1. Download Monaco editor with npm: `npm i monaco-editor`.
2. Delete everything except the `min` folder (the minimised code).
3. Copy the `min` folder inside the [`monacoSRC`](/src/modules/previewpane/MonacoPreviewHandler/monacoSRC) folder.
4. Generate the JSON file (see section below)
## languages.json
[`languages.json`](/src/modules/previewpane/MonacoPreviewHandler/languages.json) contains all extensions and Id's for the supported languages of Monaco. The [`FileHandler`](/src/modules/previewpane/MonacoPreviewHandler/FileHandler.cs) class and the installer are using this file.
### Generate languages.json file
After you updated monaco editor or adding a new language you should update the [`languages.json`](/src/modules/previewpane/MonacoPreviewHandler/languages.json) file.
1. Build monaco in debug mode.
2. Open [generateLanguagesJson.html](/src/modules/previewpane/MonacoPreviewHandler/generateLanguagesJson.html) in a browser.
3. Replace the old JSON file.

View File

@@ -21,3 +21,6 @@ TODO
#### [`trace.cpp`](/src/modules/powerrename/lib/trace.cpp)
TODO
#### [`PowerRenameUI.cpp`](/src/modules/powerrename/ui/PowerRenameUI.cpp)
TODO

View File

@@ -33,22 +33,61 @@ Once you've discussed your proposed feature/fix/etc. with a team member, and you
- don't close the issue if it's a bug in the current released version since users tend to not search for closed issues, we will close the resolved issues when a new version is released.
- if it's not a code fix that effects the end user, the issue can be closed (for example a fix in the build or a code refactoring and so on).
## Repository Overview
General project organization:
### The [`doc`](/doc) folder
Documentation for the project.
### The [`Wiki`](https://github.com/microsoft/PowerToys/wiki)
The Wiki contains the current specs for the project.
### The [`installer`](/installer) folder
Contains the source code of the PowerToys installer.
### The [`src`](/src) folder
Contains the source code of the PowerToys runner and of all of the PowerToys modules. **This is where most of the magic happens.**
### The [`tools`](/tools) folder
Various tools used by PowerToys. Includes the Visual Studio 2019 project template for new PowerToys.
## Compiling PowerToys
### Prerequisites for Compiling PowerToys
1. Windows 10 April 2018 Update (version 1803) or newer
2. Visual Studio Community/Professional/Enterprise 2019
3. Once you've cloned and started the `PowerToys.sln`, in the solution explorer, if you see a dialog that says `install extra components`, click `install`
3. Run the command below in cmd/terminal to install all the workloads and components for VS.
### Get Submodules to compile
We have submodules that need to be initialized before you can compile most parts of PowerToys. This should be a one time step.
```shell
cd "%ProgramFiles(x86)%\Microsoft Visual Studio\2019"
SET targetFolder="\"
IF EXIST Preview\NUL (SET targetFolder=Preview)
IF EXIST Enterprise\NUL (SET targetFolder=Enterprise)
IF EXIST Professional\NUL (SET targetFolder=Professional)
IF EXIST Community\NUL (SET targetFolder=Community)
1. Open a terminal
2. Navigate to the folder you cloned PowerToys to.
3. Run `git submodule update --init --recursive`
ECHO %targetFolder%
### Compiling Source Code
"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vs_installer.exe" ^
modify --installpath "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\%targetFolder%" ^
--add Microsoft.VisualStudio.Workload.NativeDesktop ^
--add Microsoft.VisualStudio.Workload.ManagedDesktop ^
--add Microsoft.VisualStudio.Workload.Universal ^
--add Microsoft.VisualStudio.Component.Windows10SDK.17134 ^
--add Microsoft.VisualStudio.ComponentGroup.UWP.VC ^
--add Microsoft.VisualStudio.Component.VC.Runtimes.x86.x64.Spectre ^
--add Microsoft.VisualStudio.Component.VC.ATL.Spectre
```
### Compile source code
- Open `PowerToys.sln` in Visual Studio, in the `Solutions Configuration` drop-down menu select `Release` or `Debug`, from the `Build` menu choose `Build Solution`.
- The PowerToys binaries will be in your repo under `x64\Release\`.
@@ -62,35 +101,25 @@ Our installer is two parts, an EXE and an MSI. The EXE (Bootstrapper) contains
The installer can only be compiled in `Release` mode, step 1 and 2 must be done before the MSI will be able to be compiled.
1. Compile `PowerToys.sln`. Instructions are listed above.
2. Compile `BugReportTool.sln` tool. Path from root: `tools\BugReportTool\BugReportTool.sln` (details listed below)
3. Compile `WebcamReportTool.sln` tool. Path from root: `tools\WebcamReportTool\WebcamReportTool.sln` (details listed below)
4. Compile `PowerToysSetup.sln` Path from root: `installer\PowerToysSetup.sln` (details listed below)
1. Compile PowerToys.sln. Instructions are listed above.
2. Compile Bug reporting tool. Path from root: `tools\BugReportTool\BugReportTool.sln` (details listed below)
3. Compile PowerToysSetup.sln Path from root: `installer\PowerToysSetup.sln` (details listed below)
### Prerequisites for building the MSI installer
1. Install the [WiX Toolset Visual Studio 2019 Extension](https://marketplace.visualstudio.com/items?itemName=WixToolset.WixToolsetVisualStudio2019Extension).
2. Install the [WiX Toolset build tools](https://wixtoolset.org/releases/).
1. Build `tools\BugReportTool\BugReportTool.sln`: in Visual Studio, in the `Solutions Configuration` drop-down menu select `Release`, from the `Build` menu choose `Build Solution`.
2. Install the [WiX Toolset Visual Studio 2019 Extension](https://marketplace.visualstudio.com/items?itemName=RobMensching.WiXToolset).
3. Install the [WiX Toolset build tools](https://wixtoolset.org/releases/).
### Locally compiling the Bug reporting tool
### Locally compiling the .MSI installer
1. Open `tools\BugReportTool\BugReportTool.sln`
2. In Visual Studio, in the `Solutions Configuration` drop-down menu select `Release`
3. From the `Build` menu, choose `Build Solution`.
- Open `installer\PowerToysSetup.sln`: in Visual Studio, in the `Solutions Configuration` drop-down menu select `Release`, from the `Build` menu choose `Build Solution`.
- The resulting `PowerToysSetup.msi` installer will be available in the `installer\PowerToysSetup\x64\Release\` folder.
### Locally compiling the Webcam reporting tool
### Locally compiling the .EXE Bootstrapper installer
1. Open `tools\WebcamReportTool\WebcamReportTool.sln`
2. In Visual Studio, in the `Solutions Configuration` drop-down menu select `Release`
3. From the `Build` menu, choose `Build Solution`.
### Locally compiling the installer
1. Open `installer\PowerToysSetup.sln`
2. In Visual Studio, in the `Solutions Configuration` drop-down menu select `Release`
3. From the `Build` menu choose `Build Solution`.
The resulting `PowerToysSetup.msi` installer will be available in the `installer\PowerToysSetup\x64\Release\` folder.
- Open `installer\PowerToysBootstrapper\PowerToysBootstrapper.sln`: in Visual Studio, in the `Solutions Configuration` drop-down menu select `Release`, from the `Build` menu choose `Build Solution`.
- The `PowerToysSetup-0.0.1-x64.exe` binary is created in the `installer\PowerToysBootstrapper\x64\Release\` folder.
#### Supported arguments for the .EXE Bootstrapper installer
@@ -134,6 +163,29 @@ Definition of the interface used by the [`runner`](/src/runner) to manage the Po
The common lib, as the name suggests, contains code shared by multiple PowerToys components and modules, e.g. [json parsing](/src/common/json.h) and [IPC primitives](/src/common/two_way_pipe_message_ipc.h).
### [`Settings`](settingsv2/)
### [`Settings`](settings.md)
Settings v2 is our current settings implementation. Please head over to the dev docs that goes into the current settings system.
WebView project for editing the PowerToys settings.
The html portion of the project that is shown in the WebView is contained in [`settings-html`](/src/settings/settings-html).
Instructions on how build a new version and update this project are in the [Web project for the Settings UI](./settings-web.md).
While developing, it's possible to connect the WebView to the development server running in localhost by setting the `_DEBUG_WITH_LOCALHOST` flag to `1` and following the instructions near it in `./main.cpp`.
### [`Settings-web`](settings-web.md)
This project generates the web UI shown in the [PowerToys Settings](/src/editor).
It's a `ReactJS` project created using [Fluent UI](https://developer.microsoft.com/en-us/fluentui#/).
#### Options
This module has a setting to serve as an example for each of the currently implemented settings property:
- BoolToggle property
- IntSpinner property
- String property
- ColorPicker property
- CustomAction property
![Image of the Options](/doc/images/settings/example_settings.png)
[installerArgWiki]: https://github.com/microsoft/PowerToys/wiki/Installer-arguments-for-exe

View File

@@ -1,6 +1,7 @@
#### [`main.cpp`](/src/runner/main.cpp)
Contains the executable starting point, initialization code and the list of known PowerToys. All singletones are also initialized here at the start. Loads all the powertoys by scanning the `./modules` folder and `enable()`s those marked as enabled in `%LOCALAPPDATA%\Microsoft\PowerToys\settings.json` config. Then it runs [a message loop](https://docs.microsoft.com/en-us/windows/win32/winmsg/using-messages-and-message-queues) for the tray UI. Note that this message loop also [handles lowlevel_keyboard_hook events](https://github.com/microsoft/PowerToys/blob/1760af50c8803588cb575167baae0439af38a9c1/src/runner/lowlevel_keyboard_event.cpp#L24).
#### [`general_settings.cpp`](./general_settings.cpp)
#### [`powertoy_module.h`](/src/runner/powertoy_module.h) and [`powertoy_module.cpp`](/src/runner/powertoy_module.cpp)
Contains code for initializing and managing the PowerToy modules. `PowertoyModule` is a RAII-style holder for the `PowertoyModuleIface` pointer, which we got by [invoking module DLL's `powertoy_create` function](https://github.com/microsoft/PowerToys/blob/1760af50c8803588cb575167baae0439af38a9c1/src/runner/powertoy_module.cpp#L13-L24).

View File

@@ -0,0 +1,597 @@
# Settings
While the module interface passes the settings and values thorough a JSON string, **use our helper functions**. In future we might move to a different implementation. All current modules use:
* `load_module_settings` to load the settings from the disk.
* `PowerToySettings::Settings` class to define module properties and the settings screen.
* `PowerToySettings::PowerToyValues` class to parse the JSON passed by the runner.
* `save_module_settings` to store the settings on the disk.
Most functions provide two overloads - one that accepts UINT with a resource ID and one that accepts strings. **Put all strings in the resource file and use the resource ID overload.**
The following documents internal workings of the settings system.
## Overview
PowerToys runner provides a generic way for modules to define their settings.
Each module on startup is responsible for loading its own settings and initializing accordingly. When the user wants to edit settings, the runner will call [`get_config()`](modules/interface.md#get_config) module method. The module must provide a JSON which includes the module name, description but also what settings options are provided.
When settings from all modules are collected, a separate [settings editor app](/src/settings) is spawned. The editor wraps [an React app](/src/settings-web) and handles the communication with the runner.
When loaded, the React app receives the JSON passed by the runner. When user saves the settings, the editor passes the new settings values as JSON string to the runner. Runner in turn will call [`set_config()`](modules/interface.md#set_config) for all modules with appropriate JSON. When user initiates a custom action (like the Zone Editor in FancyZones), the runner will call [`call_custom_action()`](modules/interface.md#call_custom_action) providing the action name in a JSON.
There are C++ helper functions in [/src/common/settings_objects.h](/src/common/settings_objects.h) and [/src/common/settings_helpers.h](/src/common/settings_helpers.h). Those include classes for creating the settings options JSON and ones for parsing the incoming settings JSON.
### Module settings
The value returned by the [`get_config()`](modules/interface.md#get_config) call should provide a JSON object with following fields:
* `name` - The name of the PowerToy. Used on the nav panel on the left.
* `version` - The settings version. Needs to be set to `"1.0"`.
* `description` - Description of the PowerToy module.
* `overview_link`, `video_link` - Optional links to the documentation and video preview of the PowerToy module.
* `icon_key` - Name of the icon of the PowerToy. The SVGs for the icons are located in [/src/settings-web/src/svg](/src/settings-web/src/svg). They also need to be added in [/settings-web/src/setup_icons.tsx](/settings-web/src/setup_icons.tsx).
* `properties` - Optional object that contains the definition of the settings screen.
The `properties` JSON object defines what settings controls are available to the user. Each key defines one control. The controls have some common properties:
* The key in the `properties` which identifies the control.
* `editor_type` - Defines the type of the control. Those are listed further.
* `order` - Defines the order of the elements on the settings screen.
Each `editor_type` has its own set of properties.
Example module JSON (taken from Shortcut Guide):
```json
{
"name": "Shortcut Guide",
"version": "1.0",
"description": "Shows a help overlay with Windows shortcuts when the Windows key is pressed.",
"overview_link": "https://github.com/.../README.md",
"icon_key": "pt-shortcut-guide",
"properties": {
"press_time": {
"editor_type": "int_spinner",
"order": 1,
"display_name": "How long to press the Windows key before showing the Shortcut Guide (ms)",
"value": 900,
"min": 100,
"max": 10000,
"step": 100
},
"overlay_opacity": {
"editor_type": "int_spinner",
"order": 2,
"display_name": "Opacity of the Shortcut Guide's overlay background (%)",
"value": 90,
"min": 0,
"max": 100,
"step": 1
},
"theme":{
"editor_type": "choice_group",
"order": 3,
"display_name": "Choose Shortcut Guide overlay color",
"value": "system",
"options": [ {"key": "system", "text": "System default app mode"},
{"key": "light", "text": "Light"},
{"key": "dark", "text": "Dark"} ]
}
}
}
```
produces this settings screen:
![Shortcut Guide settings](../images/settings/shortcut_guide_settings.png)
### Helper methods
PowerToys provides [a helper class](/src/common/json.h) to parse and generate JSON strings.
In [`settings_helpers.h`](/src/common/settings_helpers.h) there are two helper functions: `load_module_settings(powertoy_name)` and `save_general_settings(settings)` for loading and saving the module configuration.
In [`settings_objects.h`](/src/common/settings_objects.h) there are some helper classes:
* `Settings` - for generating JSON with module settings definition.
* `PowerToyValues` - for parsing JSON with settings - either loaded from file or from the settings editor.
* `CustomActionObject` and `HotkeyObject` - for parsing custom actions and hotkey input specific JSON.
### General settings
General settings control the PowerToys runner and decide which modules are enabled and which are not. The general settings screen is special - while modules provide the definition of the settings controls, the available settings on the general screen are hardcoded.
General settings has following properties:
* `enabled` - Enabled/disabled status of each PowerToy.
* `startup` - Should PowerToys start at user logon.
* `theme` - Settings editor theme - `light`, `dark` or `system`.
* `system_theme` - Current Windows theme - `light` or `dark`.
* `powertoys_version` - The version of the PowerToys.
This JSON:
```json
{
"enabled": {
"FancyZones": true,
"PowerRename": true,
"Shortcut Guide": true
},
"startup": true,
"theme": "light",
"system_theme": "dark",
"powertoys_version": "0.14.2.0"
}
```
Produces this general settings screen:
![General settings](../images/settings/general_settings.png)
## Putting it all together
The runner combines general settings and each module settings into a single JSON that is passed to the settings editor. Example combined settings look like this:
```json
{
"general": {
"enabled": {
"FancyZones": true,
"PowerRename": true,
"Shortcut Guide": true
},
"startup": true,
"theme": "light",
"system_theme": "dark",
"powertoys_version": "0.14.2.0"
},
"powertoys": {
"FancyZones": { ... },
"PowerRename": { ... },
"Shortcut Guide":{
"name": "Shortcut Guide",
"version": "1.0",
"description": "Shows a help overlay with Windows shortcuts when the Windows key is pressed.",
"overview_link": "https://github.com/.../README.md",
"icon_key": "pt-shortcut-guide",
"properties": { ... }
}
}
}
```
## C++ helpers
While you can generate and parse JSON yourself there are helper methods provided.
### Loading settings
When a PowerToy module is created, it should load its configuration. This can be done by calling
```c++
json::JsonObject PTSettingsHelper::load_module_settings(std::wstring_view powertoy_name);
```
declared in [`settings_helpers.h`](/src/common/settings_helpers.h). The function will return an `json::JsonObject` object containing the module settings.
Another option is using [`PowerToySettings::PowerToyValues`](/src/common/settings_objects.h#L67) class. A static method
```c++
PowerToyValues PowerToyValues::load_from_settings_file(std::wstring_view powertoy_name);
```
will load and parse the settings. You can also use
```c++
PowerToyValues PowerToyValues::from_json_string(std::wstring_view json);
```
to parse JSON string - for example when implementing [`set_config()`](modules/interface.md#set_config). The returned `PowerToyValues` object has helper methods that return `std::optional` with values, for example:
```c++
auto settings = PowerToyValues::load_from_settings_file(L"some_powertoy");
std::optional<std::wstring> str_prop = settings.get_string_value(L"some_string_property");
auto int_prop = settings.get_int_value(L"some_int_property");
```
### Generating settings screen
The [`PowerToySettings::Settings`](/src/common/settings_objects.h) can be used to generate settings:
```c++
// Need to get strings from the resource file.
extern "C" IMAGE_DOS_HEADER __ImageBase;
auto hinstance = reinterpret_cast<HINSTANCE>(&__ImageBase);
PowerToysSettings::Settings settings(hinstance, L"example_powertoy");
settings.set_description(L"Example powertoy.");
settings.set_overview_link(L"https://example.com");
settings.set_icon_key(L"pt-example");
settings.add_string(L"string_val", L"Example string label", L"example value");
settings.add_int_spinner(L"int_val", L"Example int label", 0, 0, 100, 10);
```
You can then use `std::wstring serialize()` or `bool serialize_to_buffer(wchar_t* buffer, int* buffer_size)` methods to generate output JSON string.
### Saving settings
Use
```c++
void PTSettingsHelper::save_module_settings(std::wstring_view powertoy_name, json::JsonObject& settings);
```
declared in [`settings_helpers.h`](/src/common/settings_helpers.h).
## Module settings elements
### Bool toggle
```c++
add_bool_toggle(name, description, value)
```
A simple on-off toggle. Parameters:
* `name` - Key for the element in the JSON.
* `description` - String or resource ID of the text displayed to the user.
* `value` - Initial state of the toggle (`true` - on, `false` - off).
This C++:
```c++
settings.add_bool_toggle(L"bool_name", L"description", true);
```
produces this settings element:
![Bool Toggle](../images/settings/bool_toggle.png)
and this generated JSON:
```json
{
"properties": {
"bool_name": {
"editor_type": "bool_toggle",
"order": autoincremented_number,
"display_name": "description",
"value": true
}
}
}
```
The toggle value is stored as bool:
```c++
std::optional<bool> bool_value = settings.get_bool_value(L"bool_name");
```
### Int Spinner
```c++
add_int_spinner(name, description, value, min, max, step)
```
Numeric input with dials to increment and decrement the value. Parameters:
* `name` - Key for element in the JSON.
* `description` - String or resource ID of the text displayed to the user.
* `value` - Initial control value.
* `min`, `max` - Minimum and maximum values for the input. User cannot use dials to move beyond those values, if a value out of range is inserted using the keyboard, it will get clamped to the allowed range.
* `step` - How much the dials change the value.
This C++:
```c++
settings.add_int_spinner(L"int_spinner_name", L"description", 50, -100, 100, 10);
```
produces this settings element:
![Int Spinner](../images/settings/int_spinner.png)
and this generated JSON:
```json
{
"properties": {
"int_spinner_name": {
"editor_type": "int_spinner",
"order": autoincremented_number,
"display_name": "description",
"value": 50,
"min": -100,
"max": 100,
"step": 10
}
}
}
```
The spinner value is stored as int:
```c++
std::optional<int> int_value = settings.get_int_value(L"int_spinner_name");
```
### String
```c++
add_string(name, description, value)
```
Single line text input. Parameters:
* `name` - Key for element in the JSON.
* `description` - String or resource ID of the text displayed to the user.
* `value` - Default value for the input.
This C++:
```c++
settings.add_string(L"string_name", L"description", L"value");
```
produces this settings element:
![String](../images/settings/string.png)
and this generated JSON:
```json
{
"properties": {
"string_name": {
"editor_type": "string_text",
"order": autoincremented_number,
"display_name": "description",
"value": "value"
}
}
}
```
The input value is stored as `std::wstring`:
```c++
std::optional<std::wstring> string_value = settings.get_string_value(L"string_name");
```
### Multiline string
```c++
add_multiline_string(name, description, value)
```
Multiline text input. Parameters:
* `name` - Key for element in the JSON.
* `description` - String or resource ID of the text displayed to the user.
* `value` - Default value for the input. Can have multiple lines.
This C++:
```c++
settings.add_multiline_string(L"multiline_name", L"description", L"multiline1\nmultiline2");
```
produces this settings element:
![Multiline](../images/settings/multiline.png)
and this generated JSON:
```json
{
"properties": {
"multiline_name": {
"editor_type": "string_text",
"multiline": true,
"order": autoincremented_number,
"display_name": "description",
"value": "multiline1\nmultiline2"
}
}
}
```
The input value is stored as string:
```c++
std::optional<std::wstring> value = settings.get_string_value(L"multiline_name");
```
### Color picker
```c++
add_color_picker(name, description, value)
```
Allows user to pick a color. Parameters:
* `name` - Key for element in the JSON.
* `description` - String or resource ID of the text displayed to the user.
* `value` - Initial color, as a string in `"#RRGGBB"` format.
This C++:
```c++
settings.add_color_picker(L"colorpicker_name", L"description", L"#102040");
```
produces this settings element:
![Color Picker](../images/settings/color_picker.png)
and this generated JSON:
```json
{
"properties": {
"colorpicker_name": {
"editor_type": "color_picker",
"order": autoincremented_number,
"display_name": "description",
"value": "#102040"
}
}
}
```
The color picker value is stored as `std::wstring`:
```c++
std::optional<std::wstring> value = settings.get_string_value(L"colorpicker_name");
```
### Hotkey
```c++
settings.add_hotkey(name, description, hotkey)
```
Input for capturing hotkeys. Parameters:
* `name` - Key for element in the JSON.
* `description` - String or resource ID of the text displayed to the user.
* `hotkey` - Instance of `PowerToysSettings::HotkeyObject` class.
You can create `PowerToysSettings::HotkeyObject` object either by using helper `from_settings` static method or by providing JSON object to `from_json` static method:
The `PowerToysSettings::HotkeyObject::from_settings` take following parameters:
* `win_pressed` - Is the WinKey pressed.
* `ctrl_pressed` - Is the Ctrl key pressed.
* `alt_pressed` - Is the Alt key pressed.
* `shift_pressed` - Is the Shift key pressed.
* `vk_code` - The [virtual key-code](https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes) of the key.
The displayed key is deduced from the `vk_code` using the users keyboard layout and language settings.
Similar parameters can be passed using the `from_json` static method:
```c++
json::JsonObject json;
json.SetNamedValue(L"win", json::value(win_pressed));
json.SetNamedValue(L"ctrl", json::value(ctrl_pressed));
json.SetNamedValue(L"alt", json::value(alt_pressed));
json.SetNamedValue(L"shift", json::value(shift_pressed));
json.SetNamedValue(L"code", json::value(vk_code));
json.SetNamedValue(L"key", json::value(L"string with key name"));
auto hotkey = PowerToysSettings::HotkeyObject::from_json(json);
```
This C++:
```c++
settings.add_hotkey(L"hotkey_name",
L"description",
PowerToysSettings::HotkeyObject::from_settings(true, true, true, true, VK_F5));
```
produces this settings element:
![Hotkey](../images/settings/hotkey.png)
and this generated JSON (`114` is the value of `VK_F5`):
```json
{
"properties": {
"hotkey_name": {
"editor_type": "hotkey",
"order": autoincremented_number,
"display_name": "description",
"value": {
"win": true,
"ctrl": true,
"alt": true,
"shift": true,
"code": 114,
"key": "F5"
}
}
}
}
```
The hotkey value is returned as JSON, with the same format as `from_json` method uses. You can use `HotkeyObject` class to parse this JSON, since it offers some helper methods. A typical example of registering a hotkey:
```c++
std::optional<json::JsonObject> value = settings.get_json(L"hotkey_name");
if (value) {
auto hotkey = PowerToysSettings::HotkeyObject::from_json(*value);
RegisterHotKey(hwnd, 1, hotkey.get_modifiers(), hotkey.get_code());
}
```
### Choice group
```c++
add_choice_group(name, description, value, vector<pair<wstring, wstring>> keys_and_texts)
add_choice_group(name, description, value, vector<pair<wstring, UINT>> keys_and_texts)
```
A radio buttons group. Parameters:
* `name` - Key for element in the JSON.
* `description` - String or resource ID of the text displayed to the user.
* `value` - Key selected by default.
* `keys_and_text` - Vector of radio buttons definitions: key and the displayed label. The texts can either be strings or resource IDs.
This C++:
```c++
settings.add_choice_group(L"choice_group_name", L"description", L"val1", { { L"val1", L"value-1" },
{ L"val2", L"value-2" },
{ L"val3", L"value-3" } });
```
produces this settings element:
![Choice group](../images/settings/choice_group.png)
and this generated JSON:
```json
{
"properties": {
"choice_group_name": {
"editor_type": "choice_group",
"order": autoincremented_number,
"display_name": "description",
"value": "val1",
"options": [ {"key": "val1", "text": "value-1"},
{"key": "val2", "text": "value-2"},
{"key": "val3", "text": "value-3"} ]
}
}
}
}
```
The chosen button value is stored as a string with the key of the button selected by the user:
```c++
std::optional<std::wstring> value = settings.get_string_value(L"choice_group_name");
```
### Dropdown
```c++
add_dropdown(name, description, value, vector<pair<wstring, wstring>> keys_and_texts)
add_dropdown(name, description, value, vector<pair<wstring, UINT>> keys_and_texts)
```
A dropdown. Parameters:
* `name` - Key for element in the JSON.
* `description` - String or resource ID of the text displayed to the user.
* `value` - Key selected by default.
* `keys_and_text` - Vector of the options definitions: key and the displayed label. The texts can either be strings or resource IDs.
This C++:
```c++
settings.add_dropdown(L"dropdown_name", L"description", L"val2", { { L"val1", L"value-1" },
{ L"val2", L"value-2" },
{ L"val3", L"value-3" } });
```
produces this settings element:
![Dropdown 1](../images/settings/dropdown_1.png)
![Dropdown 2](../images/settings/dropdown_2.png)
and this generated JSON:
```json
{
"properties": {
"dropdown_name": {
"editor_type": "dropdown",
"order": autoincremented_number,
"display_name": "description",
"value": "val1",
"options": [ {"key": "val1", "text": "value-1"},
{"key": "val2", "text": "value-2"},
{"key": "val3", "text": "value-3"} ]
}
}
}
}
```
The chosen value is stored as a string with the key of the option selected by the user:
```c++
std::optional<std::wstring> value = settings.get_string_value(L"dropdown_name");
```
### Custom action
```c++
add_custom_action(name, description, button_text, ext_description)
```
Adds a button with a description. Parameters:
* `name` - Key for element in the JSON.
* `description` - String or resource ID of the text displayed to the user.
* `button_text` - String or resource ID for the button label.
* `ext_description` - String or resource ID for the extended description.
This C++:
```c++
settings.add_custom_action(L"custom_action_name", L"description", L"button_text", L"ext_description");
```
produces this settings element:
![Custom action](../images/settings/custom_action.png)
and this generated JSON:
```json
{
"properties": {
"custom_action_name": {
"editor_type": "custom_action",
"order": autoincremented_number,
"display_name": "description",
"button_text": "button_text",
"value": "ext_description"
}
}
}
```
When the button is pressed, the `call_custom_action` method of the module will be called, with JSON containing the name of the action. In our example:
```json
{
"action_name":"custom_action_name",
"value":"ext_description"
}
```

181
doc/devdocs/settings-web.md Normal file
View File

@@ -0,0 +1,181 @@
## Build Commands
Here are the commands to build and test this project:
### To start the development server
```
npm install
npm run start
```
### Building and integrating into PowerToys settings project
```
npm run build
```
**Note:** you will need to rebuild the settings project to pick up the changes
## Updating the icons
Icons inside [`src/icons/`](/src/settings-web/src/icons/) were generated from the [Office UI Fabric Icons subset generation tool.](https://uifabricicons.azurewebsites.net/)
In case the subset needs to be changed, additional steps are needed to include the icon font in the built `dist/bundle.js`:
- Copy the inline font data taken from [`src/icons/css/fabric-icons-inline.css`](src/icons/css/fabric-icons-inline.css) and place it in the `fontFace` `src` value in [`src/icons/src/fabric-icons.ts`](src/icons/src/fabric-icons.ts).
A list of the current icons in the subset can be seen in the `icons` object in [`src/icons/src/fabric-icons.ts`](src/icons/src/fabric-icons.ts).
SVG icons, including the icons for each PowerToy listed in the Settings, are contained in [`src/svg/`](src/svg/). To add additional SVG icons add them to [`src/svg/`](src/svg/) and register them in [`src/setup_icons.tsx`](src/setup_icons.tsx).
## Code Structure
The project structure is based on the [`UI Fabric` scaffold](https://developer.microsoft.com/en-us/fabric#/get-started/web#option-1-quick-start) obtained by initializing it with `npm init uifabric`.
#### [index.html](/src/settings-web/index.html)
The HTML entry-point of the project.
Loads the `ReactJS` distribution script.
Defines JavaScript functions to receive and send messages to the [PowerToys Settings](/src/editor) window.
#### [src/index.tsx](/src/settings-web/src/index.tsx)
Main `ReactJS` entrypoint, initializing the `ReactDOM`.
#### [src/setup_icons.tsx](/src/settings-web/src/setup_icons.tsx)
Defines the `setup_powertoys_icons` function that registers the icons to be used in the components.
#### [src/components/](/src/settings-web/src/components/)
Contains the `ReactJS` components, including the Settings controls for each type of setting.
#### [src/components/App.tsx](/src/settings-web/src/components/App.tsx)
Defines the main App component, containing the UI layout, navigation menu, dialogs and main load/save logic.
#### [src/components/GeneralSettings.tsx](/src/settings-web/src/components/GeneralSettings.tsx)
Defines the PowerToys General Settings component, including logic to construct the object sent to PowerToys to change the General settings.
#### [src/components/ModuleSettings.tsx](/src/settings-web/src/components/ModuleSettings.tsx)
Defines the component that generates the settings screen for a PowerToy depending on its settings definition.
#### [src/components/BaseSettingsControl.tsx](/src/settings-web/src/components/BaseSettingsControl.tsx)
Defines the base class for a Settings control.
#### [src/css/layout.css](/src/settings-web/src/css/layout.css)
General layout styles.
#### [src/icons/](/src/settings-web/src/icons/)
Icons generated from the [Office UI Fabric Icons subset generation tool.](https://uifabricicons.azurewebsites.net/)
#### [src/svg/](/src/settings-web/src/svg/)
SVG icon assets.
## Creating a new settings control
The [`BaseSettingsControl` class](/src/settings-web/src/components/BaseSettingsControl.tsx) can be extended to create a new Settings control type.
```tsx
export class BaseSettingsControl extends React.Component <any, any> {
parent_on_change: Function;
constructor(props:any) {
super(props);
this.parent_on_change=props.on_change;
}
public get_value():any {
return null;
}
}
```
A settings control overrides the `get_value` function to return the value to be used for the Setting the control is representing.
It will use the `parent_on_change` property to signal that the user made some changes to the settings.
Here's the [`StringTextSettingsControl`](/src/settings-web/src/components/StringTextSettingsControl.tsx) component to serve as an example:
```tsx
export class StringTextSettingsControl extends BaseSettingsControl {
textref:any = null; // Keeps a reference to the corresponding TextField in the DOM.
constructor(props:any) {
super(props);
this.textref = null;
this.state={
property_values: props.setting
}
}
componentWillReceiveProps(props: any) {
// Fully controlled component.
// Reacting to a property change so that the control is redrawn properly.
this.setState({ property_values: props.setting })
}
public get_value() : any {
// Returns the TextField value.
return {value: this.textref.value};
}
public render(): JSX.Element {
// Renders a UI Fabric TextField.
return (
<TextField
onChange = {
(_event,_new_value) => {
// Updates the state with the new value introduced in the TextField.
this.setState( (prev_state:any) => ({
property_values: {
...(prev_state.property_values),
value: _new_value
}
})
);
// Signal the parent that the user changed a value.
this.parent_on_change();
}
}
value={this.state.property_values.value}
label={this.state.property_values.display_name}
componentRef= {(input) => {this.textref=input;}}
/>
);
}
}
```
Each settings property has a `editor_type` field that's used to differentiate between the Settings control types:
```js
'test string_text': {
display_name: 'This is what a string_text looks like',
editor_type: 'string_text',
value: 'A sample string value'
}
```
A new Settings control component can be added to [`src/components/`](/src/settings-web/src/components/).
To render the new Settings control, its `editor_type` and component instance need to be added to the [`ModuleSettings` component render()](/src/settings-web/src/components/ModuleSettings.tsx):
```tsx
import React from 'react';
import {StringTextSettingsControl} from './StringTextSettingsControl';
...
export class ModuleSettings extends React.Component <any, any> {
references: any;
parent_on_change: Function;
...
public render(): JSX.Element {
let power_toys_properties = this.state.powertoy.properties;
return (
<Stack tokens={{childrenGap:20}}>
...
{
Object.keys(power_toys_properties).
map( (key) => {
switch(power_toys_properties[key].editor_type) {
...
case 'string_text':
return <StringTextSettingsControl
setting = {power_toys_properties[key]}
key={key}
on_change={this.parent_on_change}
ref={(input) => {this.references[key]=input;}}
/>;
...
```

287
doc/devdocs/settings.md Normal file
View File

@@ -0,0 +1,287 @@
# Settings
## Overview
PowerToys provides a common framework for settings. It can be used to save and load settings on disk, and provides a user interface for changing the options.
## Initialization
When a PowerToy module is created, it should load its configuration using [`PowerToyValues`](/src/common/settings_objects.h) class. The class provides static `load_from_settings_file` method which takes one parameter - the PowerToy module name. The `PowerToyValues` class provides methods to extract values. The method return `std::optional` - it is possible, that the method will return `std::nullopt` in which case you must use defaults.
```c++
class ExamplePowertoy : public PowertoyModuleIface
{
public:
ExamplePowertoy()
{
auto settings = PowerToySettings::PowerToyValues::load_from_settings_file(L"Example Powertoy");
// See if value is set, otherwise keep the default value
if (auto int_value = settings.get_int_value(L"int_setting"))
{
m_int_setting = *int_value;
}
if (auto string_value = setting.get_string_value("string_setting"))
{
m_string_setting = *string_value;
}
}
// ...
private:
// Settings and their default values
int m_int_setting = 10;
std::wstring m_string_setting = L"default";
}
```
## Settings screen
When users starts the settings screen, the runner will call the [`get_config()`](modules/interface.md) method. The interface expects the method to fill provided buffer. Use the [`Settings`](/src/common/settings_objects.h) class to construct proper response with proper format. The class has helper method to set description and links fields, it also provides a way to define the content of the settings screen. Keep all the strings in the resource file and provide the resource IDs to the methods.
```c++
extern "C" IMAGE_DOS_HEADER __ImageBase; // Needed to get strings from the resource file
bool ExamplePowertoy::get_config(wchar_t* buffer, int* buffer_size)
{
PowerToySettings::Settings settings(reinterpret_cast<HINSTANCE>(&__ImageBase), L"Example Powertoy");
// Set PowerToy description
settings.set_description(IDS_POWERTOY_DESCRIPTION);
settings.set_icon_key("pt_icon_key");
settings.set_overview_link(IDS_POWERTOY_OVERVIEW_LINK);
settings.set_video_link(IDS_POWERTOY_OVERVIEW_LINK);
// Add int and string settings, provide current values:
settings.add_int_spinner(L"int_setting", IDS_INT_SETTING_DESCRIPTION, m_int_setting, 0, 100, 10);
settings.add_string(L"string_setting", IDS_STRING_SETTING_DESCRIPTION, m_string_setting);
// Use the build-in machinery to return the configuration:
return settings.serialize_to_buffer(buffer, buffer_size);
}
```
The list of all the available settings elements and their description is [further in this doc](#available-settings-elements). New PowerToy icons need to be [added to the `settings-web` project](https://github.com/microsoft/PowerToys/blob/master/doc/devdocs/settings-web.md#updating-the-icons).
## User changes settings
When user closes the settings screen, the runner will call the [`get_config()`](modules/interface.md) method. Use [`PowerToyValues`](/src/common/settings_objects.h) class static `from_json_string` method to parse the settings. After that, the code is similar to loading the settings from disk:
```c++
void ExamplePowertoy::set_config(const wchar_t* config)
{
auto settings = PowerToySettings::PowerToyValues::from_json_string(config);
// See if value is set update the values
if (auto int_value = settings.get_int_value(L"int_setting"))
{
m_int_setting = *int_value;
}
if (auto string_value = setting.get_string_value("string_setting"))
{
m_string_setting = *string_value;
}
// Save the new settings to disk
settings.save_to_settings_file();
}
```
## Detailed reference
For a detailed reference of how the settings are implemented in the runner and in the settings editor, consult [this detailed guide](settings-reference.md).
# Available settings elements
## Bool toggle
<table><tr><td align="center">
<img src="../images/settings/bool_toggle.png" width="80%">
</td></tr></table>
```c++
settings.add_bool_toggle(name, description, value)
```
A simple on-off toggle. Parameters:
* `name` - Key for the element in the JSON.
* `description` - Resource ID of the text displayed to the user.
* `value` - Initial state of the toggle (`true` - on, `false` - off).
The toggle value is stored as bool:
```c++
std::optional<bool> bool_value = settings.get_bool_value(L"bool_name");
```
## Int Spinner
<table><tr><td align="center">
<img src="../images/settings/int_spinner.png" width="80%">
</td></tr></table>
```c++
settings.add_int_spinner(name, description, value, min, max, step)
```
Numeric input with dials to increment and decrement the value. Parameters:
* `name` - Key for element in the JSON.
* `description` - Resource ID of the text displayed to the user.
* `value` - Initial control value.
* `min`, `max` - Minimum and maximum values for the input. User cannot use dials to move beyond those values, if a value out of range is inserted using the keyboard, it will get clamped to the allowed range.
* `step` - How much the dials change the value.
The spinner value is stored as int:
```c++
std::optional<int> int_value = settings.get_int_value(L"int_spinner_name");
```
## String
<table><tr><td align="center">
<img src="../images/settings/string.png" width="80%">
</td></tr></table>
```c++
settings.add_string(name, description, value)
```
Single line text input. Parameters:
* `name` - Key for element in the JSON.
* `description` - Resource ID of the text displayed to the user.
* `value` - Default value for the input.
The input value is stored as `std::wstring`:
```c++
std::optional<std::wstring> string_value = settings.get_string_value(L"string_name");
```
## Multiline string
<table><tr><td align="center">
<img src="../images/settings/multiline.png" width="80%">
</td></tr></table>
```c++
settings.add_multiline_string(name, description, value)
```
Multiline text input. Parameters:
* `name` - Key for element in the JSON.
* `description` - Resource ID of the text displayed to the user.
* `value` - Default value for the input. Can have multiple lines.
The input value is stored as string:
```c++
std::optional<std::wstring> value = settings.get_string_value(L"multiline_name");
```
## Color picker
<table><tr><td align="center">
<img src="../images/settings/color_picker.png" width="80%">
</td></tr></table>
```c++
settings.add_color_picker(name, description, value)
```
Allows user to pick a color. Parameters:
* `name` - Key for element in the JSON.
* `description` - Resource ID of the text displayed to the user.
* `value` - Initial color, as a string in `"#RRGGBB"` format.
The color picker value is stored as `std::wstring` as `#RRGGBB`:
```c++
std::optional<std::wstring> value = settings.get_string_value(L"colorpicker_name");
```
## Hotkey
<table><tr><td align="center">
<img src="../images/settings/hotkey.png" width="80%">
</td></tr></table>
```c++
settings.add_hotkey(name, description, hotkey)
```
Input for capturing hotkeys. Parameters:
* `name` - Key for element in the JSON.
* `description` - Resource ID of the text displayed to the user.
* `hotkey` - Instance of `PowerToysSettings::HotkeyObject` class.
You can create `PowerToysSettings::HotkeyObject` object either by using helper `from_settings` static method or by providing a JSON object to `from_json` static method.
The `PowerToysSettings::HotkeyObject::from_settings` take following parameters:
* `win_pressed` - Is the WinKey pressed.
* `ctrl_pressed` - Is the Ctrl key pressed.
* `alt_pressed` - Is the Alt key pressed.
* `shift_pressed` - Is the Shift key pressed.
* `vk_code` - The [virtual key-code](https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes) of the key.
The displayed key is deduced from the `vk_code` using the users keyboard layout and language settings.
The hotkey value is returned as JSON, which can be used with the `from_json` method to create a `HotkeyObject` object. A typical example of registering a hotkey:
```c++
std::optional<json::JsonObject> value = settings.get_json(L"hotkey_name");
if (value) {
auto hotkey = PowerToysSettings::HotkeyObject::from_json(*value);
RegisterHotKey(hwnd, 1, hotkey.get_modifiers(), hotkey.get_code());
}
```
## Choice group
<table><tr><td align="center">
<img src="../images/settings/choice_group.png" width="80%">
</td></tr></table>
```c++
add_choice_group(name, description, value, vector<pair<wstring, UINT>> keys_and_texts)
```
A radio buttons group. Parameters:
* `name` - Key for element in the JSON.
* `description` - Resource ID of the text displayed to the user.
* `value` - Key selected by default.
* `keys_and_text` - Vector of radio buttons definitions: key and the displayed label.
The chosen button value is stored as a string with the key of the button selected by the user:
```c++
std::optional<std::wstring> value = settings.get_string_value(L"choice_group_name");
```
## Dropdown
<table>
<tr><td align="center">
<img src="../images/settings/dropdown_1.png" width="80%">
</td></tr>
<tr><td align="center">
<img src="../images/settings/dropdown_2.png" width="80%">
</td></tr>
</table>
```c++
add_dropdown(name, description, value, vector<pair<wstring, UINT>> keys_and_texts)
```
A dropdown. Parameters:
* `name` - Key for element in the JSON.
* `description` - Resource ID of the text displayed to the user.
* `value` - Key selected by default.
* `keys_and_text` - Vector of the options definitions: key and the displayed label.
The chosen value is stored as a string with the key of the option selected by the user:
```c++
std::optional<std::wstring> value = settings.get_string_value(L"dropdown_name");
```
## Custom action
<table><tr><td align="center">
<img src="../images/settings/custom_action.png" width="80%">
</td></tr></table>
```c++
add_custom_action(name, description, button_text, ext_description)
```
Adds a button with a description. Parameters:
* `name` - Key for element in the JSON.
* `description` - Resource ID of the text displayed to the user.
* `button_text` - Resource ID for the button label.
* `ext_description` - Resource ID for the extended description.
When the button is pressed, the `call_custom_action` method of the module will be called, with JSON containing the name of the action. Parse it using `PowerToysSettings::CustomActionObject`:
```c++
void ExamplePowertoy::call_custom_action(const wchar_t* action) override
{
auto action_object = PowerToysSettings::CustomActionObject::from_json_string(action);
auto name = action_object.get_name(); // same value as the 'name' parameter
// .. do stuff ..
}
```
# File organization
### [main.cpp](/src/settings/main.cpp)
Contains the main executable code, initializing and managing the Window containing the WebView and communication with the main PowerToys executable.
### [StreamURIResolverFromFile.cpp](/src/settings/StreamURIResolverFromFile.cpp)
Defines a class implementing `IUriToStreamResolver`. Allows the WebView to navigate to filesystem files in this Win32 project.
### [settings-html/](/src/settings/settings-html/)
Contains the assets file from building the [Web project for the Settings UI](/src/settings/settings-html). It will be loaded by the WebView.

View File

@@ -6,7 +6,7 @@ The following must be kept in mind regarding compatibility with settings v1 and
- The name of the settings folder for each powertoy is the same as the `ModuleName`. It is set within each of the viewModel files. This name must not be changed to ensure that the user configurations for each of the powertoys rolls over on update.
### 2. Communication with runner
- The status of each of the modules is communicated with the runner in the form of a json object. The names of all the powerToys is set in the [`EnableModules.cs`](src/settings-ui/Settings.UI.Library/EnabledModules.cs) file. The `JsonPropertyName` must not be changed to ensure that the information is dispatched properly to all the modules by the runner.
- The status of each of the modules is communicated with the runner in the form of a json object. The names of all the powerToys is set in the [`EnableModules.cs`](src/core/Microsoft.PowerToys.Settings.UI.Library/EnabledModules.cs) file. The `JsonPropertyName` must not be changed to ensure that the information is dispatched properly to all the modules by the runner.
### ImageResizer anomaly
All the powertoys have the same folder name as well as JsonPropertyName to communicate information with the runner. However that is not the case with ImageResizer. The folder name is `ImageResizer` whereas the JsonPropertyName is `Image Resizer`(Note the additional space). This should not be changed to ensure backward compatibility as well as proper functioning of the module.

View File

@@ -7,7 +7,7 @@ The Settings project provides a custom hotkey control which consumes key presses
## Hotkey related files
#### [`HotkeySettingsControlHook.cs`](/src/settings-ui/Settings.UI.Library/HotkeySettingsControlHook.cs)
#### [`HotkeySettingsControlHook.cs`](/src/core/Microsoft.PowerToys.Settings.UI.Library/HotkeySettingsControlHook.cs)
- This function initializes and starts the [`keyboardHook`](src/common/interop/KeyboardHook.cpp) for the hotkey control.
@@ -24,7 +24,7 @@ The Settings project provides a custom hotkey control which consumes key presses
```
#### [`HotkeySettingsControl.xaml.cs`](/src/settings-ui/Settings.UI/HotkeySettingsControl.xaml.cs)
#### [`HotkeySettingsControl.xaml.cs`](/src/core/Microsoft.PowerToys.Settings.UI/HotkeySettingsControl.xaml.cs)
- The function of this class is to update the state of the keys being pressed within the custom control. This information is stored in `internalSettings`.
@@ -35,7 +35,7 @@ The Settings project provides a custom hotkey control which consumes key presses
- `isActive`: Sets the current status of the keyboard hook.
- `FilterAccessibleKeyboardEvents`: This function is used to ignore the `Tab` and `Shift+Tab` key presses to meet the accessibility requirements.
#### [`HotkeySettings.cs`](/src/settings-ui/Settings.UI.Library/HotkeySettings.cs)
#### [`HotkeySettings.cs`](/src/core/Microsoft.PowerToys.Settings.UI.Library/HotkeySettings.cs)
- Contains the structure of a HotKey where it is represented as a combination of one of the modifier keys (`Alt`, `Shift`, `Win` and `Ctrl`) and a non-modifier key.

View File

@@ -5,13 +5,13 @@
The Settings project is a XAML island based project which
follows the [MVVM architectural pattern][MVVM] where the graphical user interface is separated from the view models.
#### [UI Components:](/src/settings-ui/Settings.UI)
#### [UI Components:](/src/core/Microsoft.PowerToys.Settings.UI)
The Settings.UI project contains the xaml files for each of the UI components. It also contains the Hotkey logic for the settings control.
#### [Viewmodels:](/src/settings-ui/Settings.UI.Library)
#### [Viewmodels:](/src/core/Microsoft.PowerToys.Settings.UI.Library)
The Settings.UI.Library project contains the data that is to be rendered by the UI components.
#### [Settings Runner:](/src/settings-ui/PowerToys.Settings)
#### [Settings Runner:](/src/core/Microsoft.PowerToys.Settings.UI.Runner)
The function of the settings runner project is to communicate all changes that the user makes in the user interface, to the runner so that it can be dispatched and reflected in all the modules.
[MVVM]: https://docs.microsoft.com/en-us/windows/uwp/data-binding/data-binding-and-mvvm

View File

@@ -3,8 +3,8 @@
The Settings v2 process uses two way IPC to communicate with the runner process.
## Initialization
- On the settings' side, the two way IPC delegates are contained with the [`ShellPage.xaml.cs`](/src/settings-ui/Settings.UI/Views/ShellPage.xaml.cs) file. The delegates are static and the views for all the powerToys send the ipc information to the viewmodels as `ShellPage.DefaultSndMSGCallBack`.
- These delegates are initialized within the [`Mainwindow.xaml.cs`](/src/settings-ui/PowerToys.Settings/MainWindow.xaml.cs) file in the `Settings.Runner` project.
- On the settings' side, the two way IPC delegates are contained with the [`ShellPage.xaml.cs`](/src/core/Microsoft.PowerToys.Settings.UI/Views/ShellPage.xaml.cs) file. The delegates are static and the views for all the powerToys send the ipc information to the viewmodels as `ShellPage.DefaultSndMSGCallBack`.
- These delegates are initialized within the [`Mainwindow.xaml.cs`](/src/core/Microsoft.PowerToys.Settings.UI.Runner/MainWindow.xaml.cs) file in the `Settings.Runner` project.
## Types of IPC delegates
@@ -14,7 +14,7 @@ The Settings v2 process uses two way IPC to communicate with the runner process.
3. `CheckForUpdates`
## Sending information to runner
- The settings process communicates with the runner by using the delegates defined within the [`ShellPage.xaml.cs`](/src/settings-ui/Settings.UI/Views/ShellPage.xaml.cs) file.
- The settings process communicates with the runner by using the delegates defined within the [`ShellPage.xaml.cs`](/src/core/Microsoft.PowerToys.Settings.UI/Views/ShellPage.xaml.cs) file.
- Depending on the type of object sending the information, the json is created accordingly.
- If any information has been modified by the user in the GeneralSettings page, then the json file sent to the runner has the name set to `general`, whereas if any information has been modified by the user in any powertoy related settings page, the name of the json file being communicated with the runner is set to `powertoy`.
@@ -43,4 +43,4 @@ Program.IPCMessageReceivedCallback = (string msg) =>
```
- Whenever any information is sent from the runner each of the functions in the handle list perform their action on that json object.
- One example of where information sent from the runner is being processed by the settings is in [`GeneralPage.xaml.cs`](/src/settings-ui/Settings.UI/Views/GeneralPage.xaml.cs) when the user clicks the check for updates button. The information displayed after, such as the user has the latest version installed is a result of this handle.
- One example of where information sent from the runner is being processed by the settings is in [`GeneralPage.xaml.cs`](/src/core/Microsoft.PowerToys.Settings.UI/Views/GeneralPage.xaml.cs) when the user clicks the check for updates button. The information displayed after, such as the user has the latest version installed is a result of this handle.

View File

@@ -1,6 +1,6 @@
# Settings Utilities
- Abstractions for each of the file/folder related operations are present in [`SettingsUtils.cs`](src/settings-ui/Settings.UI.Library/SettingsUtils.cs).
- Abstractions for each of the file/folder related operations are present in [`SettingsUtils.cs`](src/core/Microsoft.PowerToys.Settings.UI.Library/SettingsUtils.cs).
- To reduce contention between the settings process and runner while trying to access the `settings.json` file of any powertoy, the settings process tries to access the file only when it needs to load the information for the first time. However, there is still no mechanism in place which ensures that both the settings and runner processes do not access the information simultaneously leading to `IOExceptions`.
## Utilities
@@ -8,6 +8,6 @@
### `GetSettings<T>(powertoy, filename)`
- The GetSettings function tries to read the file in the powertoy settings folder and creates a new file with default configurations if it does not exist.
- Ideally this function should only be called by the [`SettingsRepository`](src/settings-ui/Settings.UI.Library/SettingsRepository`1.cs) which would be accessed only when a powertoy settings object is being loaded for the first time.
- Ideally this function should only be called by the [`SettingsRepository`](src/core/Microsoft.PowerToys.Settings.UI.Library/SettingsRepository`1.cs) which would be accessed only when a powertoy settings object is being loaded for the first time.
- The reason behind ensuring that it is not accessed elsewhere is to avoid contention with the runner during file access.
- Each of the objects which are deserialized using this function must implement the `ISettingsConfig` interface.

View File

@@ -1,8 +1,8 @@
# Telemetry
## Overview
[`Settings.UI.Library/Telemetry`](/src/settings-ui/Settings.UI.Library/Telemetry) contains telemetry events generated by `Settingsv2.` These event classes are derived from the [`EventBase`](/src/common/ManagedTelemetry/Telemetry/Events/EventBase.cs) class and [`IEvent`](/src/common/ManagedTelemetry/Telemetry/Events/IEvent.cs) class. [`IEvent`](/src/common/ManagedTelemetry/Telemetry/Events/IEvent.cs) class provides the lowest level abstraction, containing attributes such as privacy tags needed for every telemetry data. [`EventBase`](/src/common/ManagedTelemetry/Telemetry/Events/EventBase.cs) class provides a higher-level abstraction, having attributes common to all `PowerToys` telemetry events.
[`Microsoft.PowerToys.Settings.UI.Library/Telemetry`](/src/core/Microsoft.PowerToys.Settings.UI.Library/Telemetry) contains telemetry events generated by `Settingsv2.` These event classes are derived from the [`EventBase`](/src/common/ManagedTelemetry/Telemetry/Events/EventBase.cs) class and [`IEvent`](/src/common/ManagedTelemetry/Telemetry/Events/IEvent.cs) class. [`IEvent`](/src/common/ManagedTelemetry/Telemetry/Events/IEvent.cs) class provides the lowest level abstraction, containing attributes such as privacy tags needed for every telemetry data. [`EventBase`](/src/common/ManagedTelemetry/Telemetry/Events/EventBase.cs) class provides a higher-level abstraction, having attributes common to all `PowerToys` telemetry events.
## Events
The following events are generated by `Settingsv2`:
1. [`SettingsBootEvent`](/src/settings-ui/Settings.UI.Library/Telemetry/Events/SettingsBootEvent.cs): This event captures the time taken by `Settingsv2` to initialize `MainWindow` UI control.
2. [`SettingsEnabledEvent.cs`](/src/settings-ui/Settings.UI.Library/Telemetry/Events/SettingsEnabledEvent.cs): This event is generated when a module is enabled or disabled.
1. [`SettingsBootEvent`](/src/core/Microsoft.PowerToys.Settings.UI.Library/Telemetry/Events/SettingsBootEvent.cs): This event captures the time taken by `Settingsv2` to initialize `MainWindow` UI control.
2. [`SettingsEnabledEvent.cs`](/src/core/Microsoft.PowerToys.Settings.UI.Library/Telemetry/Events/SettingsEnabledEvent.cs): This event is generated when a module is enabled or disabled.

View File

@@ -1,9 +1,9 @@
# UI Architecture
The UI code is distributed between two projects: [`PowerToys.Settings`](/src/settings-ui/PowerToys.Settings) and [`Settings.UI`](/src/settings-ui/Settings.UI.Library). [`PowerToys.Settings`](/src/settings-ui/PowerToys.Settings) is a WPF .net core application. It contains the parent display window and corresponding code is present in [`MainWindow.xaml.`](/src/settings-ui/PowerToys.Settings/MainWindow.xaml) [`Settings.UI`](/src/settings-ui/Settings.UI.Library) is UWP applications and contains views for base navigation and modules. Fig 1 provides a description of the UI controls hierarchy and each of the controls have been summarized below :
- [`MainWindow.xaml`](/src/settings-ui/PowerToys.Settings/MainWindow.xaml) is the parent WPF control.
- `WindowsXamlHost` control is used to host UWP control to [`MainWindow.xaml`](/src/settings-ui/PowerToys.Settings/MainWindow.xaml) parent control.
- [`ShellPage.xaml`](/src/settings-ui/Settings.UI/Views/ShellPage.xaml) is a UWP control, consisting of a side navigation panel with an icon for each module. Clicking on a module icon loads the corresponding `setting.json` file and displays the data in the UI.
The UI code is distributed between two projects: [`Microsoft.PowerToys.Settings.UI.Runner`](/src/core/Microsoft.PowerToys.Settings.UI.Runner) and [`Microsoft.PowerToys.Settings.UI`](/src/core/Microsoft.PowerToys.Settings.UI.Library). [`Microsoft.PowerToys.Settings.UI.Runner`](/src/core/Microsoft.PowerToys.Settings.UI.Runner) is a WPF .net core application. It contains the parent display window and corresponding code is present in [`MainWindow.xaml.`](/src/core/Microsoft.PowerToys.Settings.UI.Runner/MainWindow.xaml) [`Microsoft.PowerToys.Settings.UI`](/src/core/Microsoft.PowerToys.Settings.UI.Library) is UWP applications and contains views for base navigation and modules. Fig 1 provides a description of the UI controls hierarchy and each of the controls have been summarized below :
- [`MainWindow.xaml`](/src/core/Microsoft.PowerToys.Settings.UI.Runner/MainWindow.xaml) is the parent WPF control.
- `WindowsXamlHost` control is used to host UWP control to [`MainWindow.xaml`](/src/core/Microsoft.PowerToys.Settings.UI.Runner/MainWindow.xaml) parent control.
- [`ShellPage.xaml`](/src/core/Microsoft.PowerToys.Settings.UI/Views/ShellPage.xaml) is a UWP control, consisting of a side navigation panel with an icon for each module. Clicking on a module icon loads the corresponding `setting.json` file and displays the data in the UI.
![Settings UI architecture](/doc/images/settingsv2/ui-architecture.png)
**Fig 1: UI Architecture for settingsv2**

View File

@@ -1,5 +1,5 @@
# Viewmodels
The viewmodels are located within the [`Settings.UI.Library`](/src/settings-ui/Settings.UI.Library) project.
The viewmodels are located within the [`Microsoft.PowerToys.Settings.UI.Library`](/src/core/Microsoft.PowerToys.Settings.UI.Library) project.
## Components
- Each viewmodel takes in the general `settingsRepository`, the `moduleSettingsRepository` if it exists and the delegates for IPC communication.
@@ -7,11 +7,11 @@ The viewmodels are located within the [`Settings.UI.Library`](/src/settings-ui/S
- Whenever there is a change in the UI, the `OnPropertyChanged` event is invoked and the viewmodel sends a corresponding IPC message to the runner which would perform the designated action such as dispatching the change to the modules or enabling/disabling the powertoy etc.
#### Difference between viewmodels
- The [`GeneralViewModel`](/src/settings-ui/Settings.UI.Library/ViewModels/GeneralViewModel.cs) is different from the rest of the view models with regard to the IPC communication wherein it sends special IPC messages to the runner to check for updates and to restart as admin.
- The [`GeneralViewModel`](/src/core/Microsoft.PowerToys.Settings.UI.Library/ViewModels/GeneralViewModel.cs) is different from the rest of the view models with regard to the IPC communication wherein it sends special IPC messages to the runner to check for updates and to restart as admin.
- Each of the powerToy viewmodels have two types of IPC communications, one for the general status of the powerToy and the other for communication powerToy specific change in properties to the runner.
## [`SettingsRepository`](src/settings-ui/Settings.UI.Library/SettingsRepository`1.cs)
- The [`SettingsRepository`](src/settings-ui/Settings.UI.Library/SettingsRepository`1.cs) is a generic singleton which contains the configurations for each viewmodel.
## [`SettingsRepository`](src/core/Microsoft.PowerToys.Settings.UI.Library/SettingsRepository`1.cs)
- The [`SettingsRepository`](src/core/Microsoft.PowerToys.Settings.UI.Library/SettingsRepository`1.cs) is a generic singleton which contains the configurations for each viewmodel.
- As it is a generic singleton, there can only be one instance of the settings repository of a particular type. This ensures that all the viewmodels are modifying a common object and a change made in one locations reflects everywhere.
- The singleton implementation is thread-safe. Unit tests have been added for the same.

View File

@@ -6,7 +6,7 @@
## Formatting
- We use [`.clang-format`](https://github.com/microsoft/PowerToys/blob/main/src/.clang-format) style file to enable automatic code formatting. You can [easily format source files from Visual Studio](https://devblogs.microsoft.com/cppblog/clangformat-support-in-visual-studio-2017-15-7-preview-1/). For example, `CTRL+K CTRL+D` formats the current document.
- If you prefer another text editor or have ClangFormat disabled in Visual Studio, you could invoke [`format_sources`](https://github.com/microsoft/PowerToys/blob/main/src/codeAnalysis/format_sources.ps1) powershell script from command line. It gets a list of all currently modified files from `git` and invokes clang-format on them.
- We use [`.clang-format`](https://github.com/microsoft/PowerToys/blob/master/.clang-format) style file to enable automatic code formatting. You can [easily format source files from Visual Studio](https://devblogs.microsoft.com/cppblog/clangformat-support-in-visual-studio-2017-15-7-preview-1/). For example, `CTRL+K CTRL+D` formats the current document.
- If you prefer another text editor or have ClangFormat disabled in Visual Studio, you could invoke [`format_sources`](https://github.com/microsoft/PowerToys/blob/master/src/codeAnalysis/format_sources.ps1) powershell script from command line. It gets a list of all currently modified files from `git` and invokes clang-format on them.
Please note that you should also have `clang-format.exe` in `%PATH%` for it to work. The script can infer the path of `clang-format.exe` version which is shipped with Visual Studio at `%VCINSTALLDIR%\Tools\Llvm\bin\`, if you launch it from the *Native Tools Command Prompt for VS*.
- CI doesn't enforce code formatting yet, since we're gradually applying code formatting to the codebase, but please adhere to our formatting style for any new code.

BIN
doc/images/FZTutorial.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

View File

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 52 KiB

View File

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 52 KiB

View File

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Some files were not shown because too many files have changed in this diff Show More