mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-01-06 12:27:01 +01:00
Compare commits
205 Commits
v0.60.0
...
temp/test-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b6c7ca9ccd | ||
|
|
8499a44dfe | ||
|
|
232f979c30 | ||
|
|
fe00f720cd | ||
|
|
6c4365851f | ||
|
|
b7d1986be5 | ||
|
|
9178285a9c | ||
|
|
5df9f04dbd | ||
|
|
4daf5714dc | ||
|
|
f869768b0b | ||
|
|
8061e1a527 | ||
|
|
61fd8cc8f5 | ||
|
|
9654daa62e | ||
|
|
c25c7a97b8 | ||
|
|
56a5d783c8 | ||
|
|
c4f49a0fc9 | ||
|
|
d9c0af232b | ||
|
|
1f3dcb3ea6 | ||
|
|
e46e645d3d | ||
|
|
785160653c | ||
|
|
82d265ca80 | ||
|
|
f08900925a | ||
|
|
0669b5cbba | ||
|
|
562f8a5f37 | ||
|
|
7e18881967 | ||
|
|
10728e4e66 | ||
|
|
5268411ace | ||
|
|
edd80fc01e | ||
|
|
f1f95fe151 | ||
|
|
07fb01e178 | ||
|
|
44f7065b9e | ||
|
|
cf67208871 | ||
|
|
0dde07cc23 | ||
|
|
5c71808af1 | ||
|
|
b0606dde9b | ||
|
|
fe3e7e14d9 | ||
|
|
461e3c6a21 | ||
|
|
8431164bc6 | ||
|
|
0ee620988e | ||
|
|
12c11908c1 | ||
|
|
eedea3159c | ||
|
|
98a870db09 | ||
|
|
d93991a914 | ||
|
|
798c3eaf6f | ||
|
|
4405e4bfb6 | ||
|
|
56ee3fc558 | ||
|
|
8c75a71e70 | ||
|
|
39fe726690 | ||
|
|
c3da4a923a | ||
|
|
768603eb61 | ||
|
|
efe712f969 | ||
|
|
98eba357e1 | ||
|
|
b91780b903 | ||
|
|
614bf7fee3 | ||
|
|
a69a450899 | ||
|
|
db2e1d5985 | ||
|
|
bb67764be6 | ||
|
|
16c7a22410 | ||
|
|
e7d3aadec3 | ||
|
|
a3b7c70fe0 | ||
|
|
f44bf99dfd | ||
|
|
13db8575e0 | ||
|
|
58f49e1861 | ||
|
|
de1d18f8d9 | ||
|
|
45f4a83dab | ||
|
|
9128ca63c9 | ||
|
|
c26e23b904 | ||
|
|
5c431b5ac5 | ||
|
|
c85305695e | ||
|
|
4c796c0b53 | ||
|
|
8cea22aaf1 | ||
|
|
78d4f66669 | ||
|
|
48a79819f3 | ||
|
|
bde578522e | ||
|
|
5d39f44233 | ||
|
|
ddf7b5a7ba | ||
|
|
b6fe34cada | ||
|
|
64bf10e74e | ||
|
|
d39c129bd0 | ||
|
|
bc0e83b59a | ||
|
|
714626aca8 | ||
|
|
a17425b0f7 | ||
|
|
88900a55d6 | ||
|
|
87ec6254ad | ||
|
|
e9d0f16d2e | ||
|
|
7160eb3a1e | ||
|
|
df80bd461d | ||
|
|
5d8856330b | ||
|
|
3414d6d2c4 | ||
|
|
6b7a0698f5 | ||
|
|
89e6849e60 | ||
|
|
e18c435bc6 | ||
|
|
b231d89171 | ||
|
|
ce501489b4 | ||
|
|
54ad5ff41f | ||
|
|
a1d5df23a8 | ||
|
|
de72a9860d | ||
|
|
e116358723 | ||
|
|
bbd108be7e | ||
|
|
39c5177c43 | ||
|
|
1ea75e9421 | ||
|
|
4c26699ad6 | ||
|
|
123de4fbc0 | ||
|
|
0ddd3e8395 | ||
|
|
66870a61ec | ||
|
|
de130171e9 | ||
|
|
aff1020ab0 | ||
|
|
da3626cb51 | ||
|
|
4e3c965511 | ||
|
|
ae57ca07f0 | ||
|
|
4332571aa3 | ||
|
|
c6018eb87c | ||
|
|
405d79e72f | ||
|
|
094eeee194 | ||
|
|
0f7100508f | ||
|
|
434a9023c3 | ||
|
|
7054d4c183 | ||
|
|
8a89a567d1 | ||
|
|
733041ba2b | ||
|
|
9100e03be9 | ||
|
|
a5ecbc4088 | ||
|
|
172d57c69a | ||
|
|
c86903f7c6 | ||
|
|
6d66921720 | ||
|
|
d6769f52cf | ||
|
|
ac9425ee81 | ||
|
|
fceeb1b51f | ||
|
|
a47d49d5c2 | ||
|
|
a32b7361c8 | ||
|
|
ae65e55c14 | ||
|
|
efa09182d3 | ||
|
|
9e4dcf9d36 | ||
|
|
c0217a3cc4 | ||
|
|
c218adf3fd | ||
|
|
9b9cdabf4e | ||
|
|
a85fdd7b72 | ||
|
|
9258353f6c | ||
|
|
ea850fff75 | ||
|
|
60451a3e19 | ||
|
|
183300cb8b | ||
|
|
5033fd3db1 | ||
|
|
7f4a2ca6db | ||
|
|
5d6160cf7a | ||
|
|
3753642f23 | ||
|
|
dae63ce3b9 | ||
|
|
1fe9d95322 | ||
|
|
5443c07468 | ||
|
|
6ef439bda4 | ||
|
|
dd14fe0c42 | ||
|
|
b2bcbcc6af | ||
|
|
59c0db2c39 | ||
|
|
6564a4f427 | ||
|
|
cd10bf3ae6 | ||
|
|
02f43b9cbb | ||
|
|
3d54cb8385 | ||
|
|
792331e5a6 | ||
|
|
6caf472798 | ||
|
|
0d0aaca0e6 | ||
|
|
00dfe5427f | ||
|
|
5a0f9a3a2d | ||
|
|
65f457e9d1 | ||
|
|
b1ad9160cc | ||
|
|
58905ab301 | ||
|
|
a249d0f99b | ||
|
|
bdddea9b04 | ||
|
|
9fb9c6a61e | ||
|
|
a397e72eb0 | ||
|
|
da9c2b649b | ||
|
|
7f6c91e166 | ||
|
|
6d97fb2dc8 | ||
|
|
2979bfbc42 | ||
|
|
c8458dc059 | ||
|
|
6ea274a4e4 | ||
|
|
f0e045d17d | ||
|
|
3caef119a7 | ||
|
|
b395001808 | ||
|
|
e11bafcc93 | ||
|
|
28751d2d36 | ||
|
|
f519a88ee0 | ||
|
|
bb65085727 | ||
|
|
bf2a107d7d | ||
|
|
915663e7db | ||
|
|
31fd6258e0 | ||
|
|
af4dc80ce9 | ||
|
|
996a235e12 | ||
|
|
8e2570033c | ||
|
|
c08135d6e3 | ||
|
|
680f89e0f7 | ||
|
|
98ef328331 | ||
|
|
0c78b12f59 | ||
|
|
98d312a9d4 | ||
|
|
35797e8680 | ||
|
|
ca64239809 | ||
|
|
e6be44623a | ||
|
|
3d8fbd0507 | ||
|
|
de4b66b51e | ||
|
|
45d0e7da2b | ||
|
|
35d0cc5104 | ||
|
|
0fbec1ca02 | ||
|
|
d37bab3d2d | ||
|
|
ad28c41c46 | ||
|
|
db06840338 | ||
|
|
73c259342b | ||
|
|
c36a80dad5 | ||
|
|
cfff0a2af8 |
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -15,3 +15,5 @@
|
||||
*.rc diff
|
||||
|
||||
*.gcode linguist-detectable=false
|
||||
|
||||
*.vsconfig linguist-language=json
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -46,8 +46,10 @@ body:
|
||||
- PDF Thumbnail
|
||||
- G-code Preview
|
||||
- G-code Thumbnail
|
||||
- PowerAccent
|
||||
- PowerRename
|
||||
- PowerToys Run
|
||||
- Screen ruler
|
||||
- Shortcut Guide
|
||||
- STL Thumbnail
|
||||
- SVG Preview
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/translation_issue.yml
vendored
2
.github/ISSUE_TEMPLATE/translation_issue.yml
vendored
@@ -37,8 +37,10 @@ body:
|
||||
- PDF Thumbnail
|
||||
- G-code Preview
|
||||
- G-code Thumbnail
|
||||
- PowerAccent
|
||||
- PowerRename
|
||||
- PowerToys Run
|
||||
- Screen Ruler
|
||||
- Shortcut Guide
|
||||
- SVG Preview
|
||||
- SVG Thumbnail
|
||||
|
||||
1
.github/actions/spell-check/README.md
vendored
1
.github/actions/spell-check/README.md
vendored
@@ -7,6 +7,7 @@ File | Purpose | Format | Info
|
||||
[excludes.txt](excludes.txt) | Files to ignore entirely | perl regular expression | [excludes](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-excludes)
|
||||
[only.txt](only.txt) | Only check matching files (applied after excludes) | perl regular expression | [only](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-only)
|
||||
[patterns.txt](patterns.txt) | Patterns to ignore from checked lines | perl regular expression (order matters, first match wins) | [patterns](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-patterns)
|
||||
[candidate.patterns](candidate.patterns) | Patterns that might be worth adding to [patterns.txt](patterns.txt) | perl regular expression with optional comment block introductions (all matches will be suggested) | [candidates](https://github.com/check-spelling/check-spelling/wiki/Feature:-Suggest-patterns)
|
||||
[line_forbidden.patterns](line_forbidden.patterns) | Patterns to flag in checked lines | perl regular expression (order matters, first match wins) | [patterns](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-patterns)
|
||||
[expect.txt](expect.txt) | Expected words that aren't in the dictionary | one word per line (sorted, alphabetically) | [expect](https://github.com/check-spelling/check-spelling/wiki/Configuration#expect)
|
||||
[advice.md](advice.md) | Supplement for GitHub comment when unrecognized words are found | GitHub Markdown | [advice](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-advice)
|
||||
|
||||
22
.github/actions/spell-check/advice.md
vendored
22
.github/actions/spell-check/advice.md
vendored
@@ -1,7 +1,17 @@
|
||||
<!-- 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>
|
||||
<details><summary>If the flagged items are :exploding_head: false positives</summary>
|
||||
|
||||
If items relate to a ...
|
||||
* binary file (or some other file you wouldn't want to check at all).
|
||||
|
||||
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).
|
||||
|
||||
* well-formed pattern.
|
||||
|
||||
If you can write a [pattern](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns) that would match it,
|
||||
@@ -12,14 +22,4 @@ https://www.regexplanet.com/advanced/perl/) yours before committing to verify it
|
||||
|
||||
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>
|
||||
|
||||
1
.github/actions/spell-check/allow.txt
vendored
1
.github/actions/spell-check/allow.txt
vendored
@@ -1 +0,0 @@
|
||||
wil
|
||||
9
.github/actions/spell-check/allow/allow.txt
vendored
Normal file
9
.github/actions/spell-check/allow/allow.txt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
bkmeneguello
|
||||
FWest
|
||||
github
|
||||
https
|
||||
obairka
|
||||
ssh
|
||||
ubuntu
|
||||
unuing
|
||||
wil
|
||||
9
.github/actions/spell-check/allow/names.txt
vendored
9
.github/actions/spell-check/allow/names.txt
vendored
@@ -1,17 +1,16 @@
|
||||
adamchilders
|
||||
ABradley
|
||||
azchohfi
|
||||
bdoserror
|
||||
crutkas
|
||||
dependabot
|
||||
Deuchert
|
||||
edwinzap
|
||||
eltociear
|
||||
hallatore
|
||||
harvastum
|
||||
jefflord
|
||||
mshtang
|
||||
naveensrinivasan
|
||||
nVidia
|
||||
rcmaehl
|
||||
robmen
|
||||
shandsj
|
||||
skycommand
|
||||
snickler
|
||||
sinclairinat
|
||||
|
||||
523
.github/actions/spell-check/candidate.patterns
vendored
Normal file
523
.github/actions/spell-check/candidate.patterns
vendored
Normal file
@@ -0,0 +1,523 @@
|
||||
# marker to ignore all code on line
|
||||
^.*/\* #no-spell-check-line \*/.*$
|
||||
# marker for ignoring a comment to the end of the line
|
||||
// #no-spell-check.*$
|
||||
|
||||
# patch hunk comments
|
||||
^\@\@ -\d+(?:,\d+|) \+\d+(?:,\d+|) \@\@ .*
|
||||
# git index header
|
||||
index [0-9a-z]{7,40}\.\.[0-9a-z]{7,40}
|
||||
|
||||
# cid urls
|
||||
(['"])cid:.*?\g{-1}
|
||||
|
||||
# data url in parens
|
||||
\(data:[^)]*?(?:[A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,})[^)]*\)
|
||||
# data url in quotes
|
||||
([`'"])data:.*?(?:[A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,}).*\g{-1}
|
||||
# data url
|
||||
data:[-a-zA-Z=;:/0-9+]*,\S*
|
||||
|
||||
# mailto urls
|
||||
mailto:[-a-zA-Z=;:/?%&0-9+@.]{3,}
|
||||
|
||||
# magnet urls
|
||||
magnet:[?=:\w]+
|
||||
|
||||
# magnet urls
|
||||
"magnet:[^"]+"
|
||||
|
||||
# obs:
|
||||
"obs:[^"]*"
|
||||
|
||||
# The `\b` here means a break, it's the fancy way to handle urls, but it makes things harder to read
|
||||
# In this examples content, I'm using a number of different ways to match things to show various approaches
|
||||
# asciinema
|
||||
\basciinema\.org/a/[0-9a-zA-Z]+
|
||||
|
||||
# apple
|
||||
\bdeveloper\.apple\.com/[-\w?=/]+
|
||||
# Apple music
|
||||
\bembed\.music\.apple\.com/fr/playlist/usr-share/[-\w.]+
|
||||
|
||||
# appveyor api
|
||||
\bci\.appveyor\.com/api/projects/status/[0-9a-z]+
|
||||
# appveyor project
|
||||
\bci\.appveyor\.com/project/(?:[^/\s"]*/){2}builds?/\d+/job/[0-9a-z]+
|
||||
|
||||
# Amazon
|
||||
|
||||
# Amazon
|
||||
\bamazon\.com/[-\w]+/(?:dp/[0-9A-Z]+|)
|
||||
# AWS S3
|
||||
\b\w*\.s3[^.]*\.amazonaws\.com/[-\w/&#%_?:=]*
|
||||
# AWS execute-api
|
||||
\b[0-9a-z]{10}\.execute-api\.[-0-9a-z]+\.amazonaws\.com\b
|
||||
# AWS ELB
|
||||
\b\w+\.[-0-9a-z]+\.elb\.amazonaws\.com\b
|
||||
# AWS SNS
|
||||
\bsns\.[-0-9a-z]+.amazonaws\.com/[-\w/&#%_?:=]*
|
||||
# AWS VPC
|
||||
vpc-\w+
|
||||
|
||||
# While you could try to match `http://` and `https://` by using `s?` in `https?://`, sometimes there
|
||||
# YouTube url
|
||||
\b(?:(?:www\.|)youtube\.com|youtu.be)/(?:channel/|embed/|user/|playlist\?list=|watch\?v=|v/|)[-a-zA-Z0-9?&=_%]*
|
||||
# YouTube music
|
||||
\bmusic\.youtube\.com/youtubei/v1/browse(?:[?&]\w+=[-a-zA-Z0-9?&=_]*)
|
||||
# YouTube tag
|
||||
<\s*youtube\s+id=['"][-a-zA-Z0-9?_]*['"]
|
||||
# YouTube image
|
||||
\bimg\.youtube\.com/vi/[-a-zA-Z0-9?&=_]*
|
||||
# Google Accounts
|
||||
\baccounts.google.com/[-_/?=.:;+%&0-9a-zA-Z]*
|
||||
# Google Analytics
|
||||
\bgoogle-analytics\.com/collect.[-0-9a-zA-Z?%=&_.~]*
|
||||
# Google APIs
|
||||
\bgoogleapis\.(?:com|dev)/[a-z]+/(?:v\d+/|)[a-z]+/[-@:./?=\w+|&]+
|
||||
# Google Storage
|
||||
\b[-a-zA-Z0-9.]*\bstorage\d*\.googleapis\.com(?:/\S*|)
|
||||
# Google Calendar
|
||||
\bcalendar\.google\.com/calendar(?:/u/\d+|)/embed\?src=[@./?=\w&%]+
|
||||
\w+\@group\.calendar\.google\.com\b
|
||||
# Google DataStudio
|
||||
\bdatastudio\.google\.com/(?:(?:c/|)u/\d+/|)(?:embed/|)(?:open|reporting|datasources|s)/[-0-9a-zA-Z]+(?:/page/[-0-9a-zA-Z]+|)
|
||||
# The leading `/` here is as opposed to the `\b` above
|
||||
# ... a short way to match `https://` or `http://` since most urls have one of those prefixes
|
||||
# Google Docs
|
||||
/docs\.google\.com/[a-z]+/(?:ccc\?key=\w+|(?:u/\d+|d/(?:e/|)[0-9a-zA-Z_-]+/)?(?:edit\?[-\w=#.]*|/\?[\w=&]*|))
|
||||
# Google Drive
|
||||
\bdrive\.google\.com/(?:file/d/|open)[-0-9a-zA-Z_?=]*
|
||||
# Google Groups
|
||||
\bgroups\.google\.com/(?:(?:forum/#!|d/)(?:msg|topics?|searchin)|a)/[^/\s"]+/[-a-zA-Z0-9$]+(?:/[-a-zA-Z0-9]+)*
|
||||
# Google Maps
|
||||
\bmaps\.google\.com/maps\?[\w&;=]*
|
||||
# Google themes
|
||||
themes\.googleusercontent\.com/static/fonts/[^/\s"]+/v\d+/[^.]+.
|
||||
# Google CDN
|
||||
\bclients2\.google(?:usercontent|)\.com[-0-9a-zA-Z/.]*
|
||||
# Goo.gl
|
||||
/goo\.gl/[a-zA-Z0-9]+
|
||||
# Google Chrome Store
|
||||
\bchrome\.google\.com/webstore/detail/[-\w]*(?:/\w*|)
|
||||
# Google Books
|
||||
\bgoogle\.(?:\w{2,4})/books(?:/\w+)*\?[-\w\d=&#.]*
|
||||
# Google Fonts
|
||||
\bfonts\.(?:googleapis|gstatic)\.com/[-/?=:;+&0-9a-zA-Z]*
|
||||
# Google Forms
|
||||
\bforms\.gle/\w+
|
||||
# Google Scholar
|
||||
\bscholar\.google\.com/citations\?user=[A-Za-z0-9_]+
|
||||
# Google Colab Research Drive
|
||||
\bcolab\.research\.google\.com/drive/[-0-9a-zA-Z_?=]*
|
||||
|
||||
# GitHub SHAs (api)
|
||||
\bapi.github\.com/repos(?:/[^/\s"]+){3}/[0-9a-f]+\b
|
||||
# GitHub SHAs (markdown)
|
||||
(?:\[`?[0-9a-f]+`?\]\(https:/|)/(?:www\.|)github\.com(?:/[^/\s"]+){2,}(?:/[^/\s")]+)(?:[0-9a-f]+(?:[-0-9a-zA-Z/#.]*|)\b|)
|
||||
# GitHub SHAs
|
||||
\bgithub\.com(?:/[^/\s"]+){2}[@#][0-9a-f]+\b
|
||||
# GitHub wiki
|
||||
\bgithub\.com/(?:[^/]+/){2}wiki/(?:(?:[^/]+/|)_history|[^/]+(?:/_compare|)/[0-9a-f.]{40,})\b
|
||||
# githubusercontent
|
||||
/[-a-z0-9]+\.githubusercontent\.com/[-a-zA-Z0-9?&=_\/.]*
|
||||
# githubassets
|
||||
\bgithubassets.com/[0-9a-f]+(?:[-/\w.]+)
|
||||
# gist github
|
||||
\bgist\.github\.com/[^/\s"]+/[0-9a-f]+
|
||||
# git.io
|
||||
\bgit\.io/[0-9a-zA-Z]+
|
||||
# GitHub JSON
|
||||
"node_id": "[-a-zA-Z=;:/0-9+]*"
|
||||
# Contributor
|
||||
\[[^\]]+\]\(https://github\.com/[^/\s"]+\)
|
||||
# GHSA
|
||||
GHSA(?:-[0-9a-z]{4}){3}
|
||||
|
||||
# GitLab commit
|
||||
\bgitlab\.[^/\s"]*/\S+/\S+/commit/[0-9a-f]{7,16}#[0-9a-f]{40}\b
|
||||
# GitLab merge requests
|
||||
\bgitlab\.[^/\s"]*/\S+/\S+/-/merge_requests/\d+/diffs#[0-9a-f]{40}\b
|
||||
# GitLab uploads
|
||||
\bgitlab\.[^/\s"]*/uploads/[-a-zA-Z=;:/0-9+]*
|
||||
# GitLab commits
|
||||
\bgitlab\.[^/\s"]*/(?:[^/\s"]+/){2}commits?/[0-9a-f]+\b
|
||||
|
||||
# binanace
|
||||
accounts.binance.com/[a-z/]*oauth/authorize\?[-0-9a-zA-Z&%]*
|
||||
|
||||
# bitbucket diff
|
||||
\bapi\.bitbucket\.org/\d+\.\d+/repositories/(?:[^/\s"]+/){2}diff(?:stat|)(?:/[^/\s"]+){2}:[0-9a-f]+
|
||||
# bitbucket repositories commits
|
||||
\bapi\.bitbucket\.org/\d+\.\d+/repositories/(?:[^/\s"]+/){2}commits?/[0-9a-f]+
|
||||
# bitbucket commits
|
||||
\bbitbucket\.org/(?:[^/\s"]+/){2}commits?/[0-9a-f]+
|
||||
|
||||
# bit.ly
|
||||
\bbit\.ly/\w+
|
||||
|
||||
# bitrise
|
||||
\bapp\.bitrise\.io/app/[0-9a-f]*/[\w.?=&]*
|
||||
|
||||
# bootstrapcdn.com
|
||||
\bbootstrapcdn\.com/[-./\w]+
|
||||
|
||||
# cdn.cloudflare.com
|
||||
\bcdnjs\.cloudflare\.com/[./\w]+
|
||||
|
||||
# circleci
|
||||
\bcircleci\.com/gh(?:/[^/\s"]+){1,5}.[a-z]+\?[-0-9a-zA-Z=&]+
|
||||
|
||||
# gitter
|
||||
\bgitter\.im(?:/[^/\s"]+){2}\?at=[0-9a-f]+
|
||||
|
||||
# gravatar
|
||||
\bgravatar\.com/avatar/[0-9a-f]+
|
||||
|
||||
# ibm
|
||||
[a-z.]*ibm\.com/[-_#=:%!?~.\\/\d\w]*
|
||||
|
||||
# imgur
|
||||
\bimgur\.com/[^.]+
|
||||
|
||||
# Internet Archive
|
||||
\barchive\.org/web/\d+/(?:[-\w.?,'/\\+&%$#_:]*)
|
||||
|
||||
# discord
|
||||
/discord(?:app\.com|\.gg)/(?:invite/)?[a-zA-Z0-9]{7,}
|
||||
|
||||
# Disqus
|
||||
\bdisqus\.com/[-\w/%.()!?&=_]*
|
||||
|
||||
# medium link
|
||||
\blink\.medium\.com/[a-zA-Z0-9]+
|
||||
# medium
|
||||
\bmedium\.com/\@?[^/\s"]+/[-\w]+
|
||||
|
||||
# microsoft
|
||||
\b(?:https?://|)(?:(?:download\.visualstudio|docs|msdn2?|research)\.microsoft|blogs\.msdn)\.com/[-_a-zA-Z0-9()=./%]*
|
||||
# powerbi
|
||||
\bapp\.powerbi\.com/reportEmbed/[^"' ]*
|
||||
# vs devops
|
||||
\bvisualstudio.com(?::443|)/[-\w/?=%&.]*
|
||||
# microsoft store
|
||||
\bmicrosoft\.com/store/apps/\w+
|
||||
|
||||
# mvnrepository.com
|
||||
\bmvnrepository\.com/[-0-9a-z./]+
|
||||
|
||||
# now.sh
|
||||
/[0-9a-z-.]+\.now\.sh\b
|
||||
|
||||
# oracle
|
||||
\bdocs\.oracle\.com/[-0-9a-zA-Z./_?#&=]*
|
||||
|
||||
# chromatic.com
|
||||
/\S+.chromatic.com\S*[")]
|
||||
|
||||
# codacy
|
||||
\bapi\.codacy\.com/project/badge/Grade/[0-9a-f]+
|
||||
|
||||
# compai
|
||||
\bcompai\.pub/v1/png/[0-9a-f]+
|
||||
|
||||
# mailgun api
|
||||
\.api\.mailgun\.net/v3/domains/[0-9a-z]+\.mailgun.org/messages/[0-9a-zA-Z=@]*
|
||||
# mailgun
|
||||
\b[0-9a-z]+.mailgun.org
|
||||
|
||||
# /message-id/
|
||||
/message-id/[-\w@./%]+
|
||||
|
||||
# Reddit
|
||||
\breddit\.com/r/[/\w_]*
|
||||
|
||||
# requestb.in
|
||||
\brequestb\.in/[0-9a-z]+
|
||||
|
||||
# sched
|
||||
\b[a-z0-9]+\.sched\.com\b
|
||||
|
||||
# Slack url
|
||||
slack://[a-zA-Z0-9?&=]+
|
||||
# Slack
|
||||
\bslack\.com/[-0-9a-zA-Z/_~?&=.]*
|
||||
# Slack edge
|
||||
\bslack-edge\.com/[-a-zA-Z0-9?&=%./]+
|
||||
# Slack images
|
||||
\bslack-imgs\.com/[-a-zA-Z0-9?&=%.]+
|
||||
|
||||
# shields.io
|
||||
\bshields\.io/[-\w/%?=&.:+;,]*
|
||||
|
||||
# stackexchange -- https://stackexchange.com/feeds/sites
|
||||
\b(?:askubuntu|serverfault|stack(?:exchange|overflow)|superuser).com/(?:questions/\w+/[-\w]+|a/)
|
||||
|
||||
# Sentry
|
||||
[0-9a-f]{32}\@o\d+\.ingest\.sentry\.io\b
|
||||
|
||||
# Twitter markdown
|
||||
\[\@[^[/\]:]*?\]\(https://twitter.com/[^/\s"')]*(?:/status/\d+(?:\?[-_0-9a-zA-Z&=]*|)|)\)
|
||||
# Twitter hashtag
|
||||
\btwitter\.com/hashtag/[\w?_=&]*
|
||||
# Twitter status
|
||||
\btwitter\.com/[^/\s"')]*(?:/status/\d+(?:\?[-_0-9a-zA-Z&=]*|)|)
|
||||
# Twitter profile images
|
||||
\btwimg\.com/profile_images/[_\w./]*
|
||||
# Twitter media
|
||||
\btwimg\.com/media/[-_\w./?=]*
|
||||
# Twitter link shortened
|
||||
\bt\.co/\w+
|
||||
|
||||
# facebook
|
||||
\bfburl\.com/[0-9a-z_]+
|
||||
# facebook CDN
|
||||
\bfbcdn\.net/[\w/.,]*
|
||||
# facebook watch
|
||||
\bfb\.watch/[0-9A-Za-z]+
|
||||
|
||||
# dropbox
|
||||
\bdropbox\.com/sh?/[^/\s"]+/[-0-9A-Za-z_.%?=&;]+
|
||||
|
||||
# ipfs protocol
|
||||
ipfs://[0-9a-z]*
|
||||
# ipfs url
|
||||
/ipfs/[0-9a-z]*
|
||||
|
||||
# w3
|
||||
\bw3\.org/[-0-9a-zA-Z/#.]+
|
||||
|
||||
# loom
|
||||
\bloom\.com/embed/[0-9a-f]+
|
||||
|
||||
# regex101
|
||||
\bregex101\.com/r/[^/\s"]+/\d+
|
||||
|
||||
# figma
|
||||
\bfigma\.com/file(?:/[0-9a-zA-Z]+/)+
|
||||
|
||||
# freecodecamp.org
|
||||
\bfreecodecamp\.org/[-\w/.]+
|
||||
|
||||
# image.tmdb.org
|
||||
\bimage\.tmdb\.org/[/\w.]+
|
||||
|
||||
# mermaid
|
||||
\bmermaid\.ink/img/[-\w]+|\bmermaid-js\.github\.io/mermaid-live-editor/#/edit/[-\w]+
|
||||
|
||||
# Wikipedia
|
||||
\ben\.wikipedia\.org/wiki/[-\w%.#]+
|
||||
|
||||
# gitweb
|
||||
[^"\s]+/gitweb/\S+;h=[0-9a-f]+
|
||||
|
||||
# HyperKitty lists
|
||||
/archives/list/[^@/]+\@[^/\s"]*/message/[^/\s"]*/
|
||||
|
||||
# lists
|
||||
/thread\.html/[^"\s]+
|
||||
|
||||
# list-management
|
||||
\blist-manage\.com/subscribe(?:[?&](?:u|id)=[0-9a-f]+)+
|
||||
|
||||
# kubectl.kubernetes.io/last-applied-configuration
|
||||
"kubectl.kubernetes.io/last-applied-configuration": ".*"
|
||||
|
||||
# pgp
|
||||
\bgnupg\.net/pks/lookup[?&=0-9a-zA-Z]*
|
||||
|
||||
# Spotify
|
||||
\bopen\.spotify\.com/embed/playlist/\w+
|
||||
|
||||
# Mastodon
|
||||
\bmastodon\.[-a-z.]*/(?:media/|\@)[?&=0-9a-zA-Z_]*
|
||||
|
||||
# scastie
|
||||
\bscastie\.scala-lang\.org/[^/]+/\w+
|
||||
|
||||
# images.unsplash.com
|
||||
\bimages\.unsplash\.com/(?:(?:flagged|reserve)/|)[-\w./%?=%&.;]+
|
||||
|
||||
# pastebin
|
||||
\bpastebin\.com/[\w/]+
|
||||
|
||||
# heroku
|
||||
\b\w+\.heroku\.com/source/archive/\w+
|
||||
|
||||
# quip
|
||||
\b\w+\.quip\.com/\w+(?:(?:#|/issues/)\w+)?
|
||||
|
||||
# badgen.net
|
||||
\bbadgen\.net/badge/[^")\]'\s]+
|
||||
|
||||
# statuspage.io
|
||||
\w+\.statuspage\.io\b
|
||||
|
||||
# media.giphy.com
|
||||
\bmedia\.giphy\.com/media/[^/]+/[\w.?&=]+
|
||||
|
||||
# tinyurl
|
||||
\btinyurl\.com/\w+
|
||||
|
||||
# getopts
|
||||
\bgetopts\s+(?:"[^"]+"|'[^']+')
|
||||
|
||||
# ANSI color codes
|
||||
(?:\\(?:u00|x)1b|\x1b)\[\d+(?:;\d+|)m
|
||||
|
||||
# URL escaped characters
|
||||
\%[0-9A-F][A-F]
|
||||
# IPv6
|
||||
\b(?:[0-9a-fA-F]{0,4}:){3,7}[0-9a-fA-F]{0,4}\b
|
||||
# c99 hex digits (not the full format, just one I've seen)
|
||||
0x[0-9a-fA-F](?:\.[0-9a-fA-F]*|)[pP]
|
||||
# Punycode
|
||||
\bxn--[-0-9a-z]+
|
||||
# sha
|
||||
sha\d+:[0-9]*[a-f]{3,}[0-9a-f]*
|
||||
# sha-... -- uses a fancy capture
|
||||
(['"]|")[0-9a-f]{40,}\g{-1}
|
||||
# hex runs
|
||||
\b[0-9a-fA-F]{16,}\b
|
||||
# hex in url queries
|
||||
=[0-9a-fA-F]*?(?:[A-F]{3,}|[a-f]{3,})[0-9a-fA-F]*?&
|
||||
# ssh
|
||||
(?:ssh-\S+|-nistp256) [-a-zA-Z=;:/0-9+]{12,}
|
||||
|
||||
# PGP
|
||||
\b(?:[0-9A-F]{4} ){9}[0-9A-F]{4}\b
|
||||
# GPG keys
|
||||
\b(?:[0-9A-F]{4} ){5}(?: [0-9A-F]{4}){5}\b
|
||||
# Well known gpg keys
|
||||
.well-known/openpgpkey/[\w./]+
|
||||
|
||||
# uuid:
|
||||
\b[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}\b
|
||||
# hex digits including css/html color classes:
|
||||
(?:[\\0][xX]|\\u|[uU]\+|#x?|\%23)[0-9_a-fA-FgGrR]*?[a-fA-FgGrR]{2,}[0-9_a-fA-FgGrR]*(?:[uUlL]{0,3}|u\d+)\b
|
||||
# integrity
|
||||
integrity="sha\d+-[-a-zA-Z=;:/0-9+]{40,}"
|
||||
|
||||
# https://www.gnu.org/software/groff/manual/groff.html
|
||||
# man troff content
|
||||
\\f[BCIPR]
|
||||
# '
|
||||
\\\(aq
|
||||
|
||||
# .desktop mime types
|
||||
^MimeTypes?=.*$
|
||||
# .desktop localized entries
|
||||
^[A-Z][a-z]+\[[a-z]+\]=.*$
|
||||
# Localized .desktop content
|
||||
Name\[[^\]]+\]=.*
|
||||
|
||||
# IServiceProvider
|
||||
\bI(?=(?:[A-Z][a-z]{2,})+\b)
|
||||
|
||||
# crypt
|
||||
"\$2[ayb]\$.{56}"
|
||||
|
||||
# scrypt / argon
|
||||
\$(?:scrypt|argon\d+[di]*)\$\S+
|
||||
|
||||
# Input to GitHub JSON
|
||||
content: "[-a-zA-Z=;:/0-9+]*="
|
||||
|
||||
# Python stringprefix / binaryprefix
|
||||
# Note that there's a high false positive rate, remove the `?=` and search for the regex to see if the matches seem like reasonable strings
|
||||
(?<!')\b(?:B|BR|Br|F|FR|Fr|R|RB|RF|Rb|Rf|U|UR|Ur|b|bR|br|f|fR|fr|r|rB|rF|rb|rf|u|uR|ur)'(?:[A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,})
|
||||
|
||||
# Regular expressions for (P|p)assword
|
||||
\([A-Z]\|[a-z]\)[a-z]+
|
||||
|
||||
# JavaScript regular expressions
|
||||
# javascript test regex
|
||||
/.*/[gim]*\.test\(
|
||||
# javascript match regex
|
||||
\.match\(/[^/\s"]*/[gim]*\s*
|
||||
# javascript match regex
|
||||
\.match\(/\\[b].*?/[gim]*\s*\)(?:;|$)
|
||||
# javascript regex
|
||||
^\s*/\\[b].*/[gim]*\s*(?:\)(?:;|$)|,$)
|
||||
# javascript replace regex
|
||||
\.replace\(/[^/\s"]*/[gim]*\s*,
|
||||
|
||||
# Go regular expressions
|
||||
regexp?\.MustCompile\(`[^`]*`\)
|
||||
|
||||
# sed regular expressions
|
||||
sed 's/(?:[^/]*?[a-zA-Z]{3,}[^/]*?/){2}
|
||||
|
||||
# go install
|
||||
go install(?:\s+[a-z]+\.[-@\w/.]+)+
|
||||
|
||||
# kubernetes pod status lists
|
||||
# https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase
|
||||
\w+(?:-\w+)+\s+\d+/\d+\s+(?:Running|Pending|Succeeded|Failed|Unknown)\s+
|
||||
|
||||
# kubectl - pods in CrashLoopBackOff
|
||||
\w+-[0-9a-f]+-\w+\s+\d+/\d+\s+CrashLoopBackOff\s+
|
||||
|
||||
# kubernetes object suffix
|
||||
-[0-9a-f]{10}-\w{5}\s
|
||||
|
||||
# posthog secrets
|
||||
posthog\.init\((['"])phc_[^"',]+\g{-1},
|
||||
|
||||
# xcode
|
||||
|
||||
# xcodeproject scenes
|
||||
(?:Controller|ID|id)="\w{3}-\w{2}-\w{3}"
|
||||
|
||||
# xcode api botches
|
||||
customObjectInstantitationMethod
|
||||
|
||||
# font awesome classes
|
||||
\.fa-[-a-z0-9]+
|
||||
|
||||
# Update Lorem based on your content (requires `ge` and `w` from https://github.com/jsoref/spelling; and `review` from https://github.com/check-spelling/check-spelling/wiki/Looking-for-items-locally )
|
||||
# grep '^[^#].*lorem' .github/actions/spelling/patterns.txt|perl -pne 's/.*i..\?://;s/\).*//' |tr '|' "\n"|sort -f |xargs -n1 ge|perl -pne 's/^[^:]*://'|sort -u|w|sed -e 's/ .*//'|w|review -
|
||||
# Warning, while `(?i)` is very neat and fancy, if you have some binary files that aren't proper unicode, you might run into:
|
||||
## Operation "substitution (s///)" returns its argument for non-Unicode code point 0x1C19AE (the code point will vary).
|
||||
## You could manually change `(?i)X...` to use `[Xx]...`
|
||||
## or you could add the files to your `excludes` file (a version after 0.0.19 should identify the file path)
|
||||
# Lorem
|
||||
(?:\w|\s|[,.])*\b(?i)(?:amet|consectetur|cursus|dolor|eros|ipsum|lacus|libero|ligula|lorem|magna|neque|nulla|suscipit|tempus)\b(?:\w|\s|[,.])*
|
||||
|
||||
# Non-English
|
||||
[a-zA-Z]*[ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź][a-zA-Z]{3}[a-zA-ZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź]*
|
||||
|
||||
# French
|
||||
# This corpus only had capital letters, but you probably want lowercase ones as well.
|
||||
\b[LN]'+[a-z]{2,}\b
|
||||
|
||||
# latex
|
||||
\\(?:n(?:ew|ormal|osub)|r(?:enew)|t(?:able(?:of|)|he|itle))(?=[a-z]+)
|
||||
|
||||
# the negative lookahead here is to allow catching 'templatesz' as a misspelling
|
||||
# but to otherwise recognize a Windows path with \templates\foo.template or similar:
|
||||
\\(?:necessary|r(?:eport|esolve[dr]?|esult)|t(?:arget|emplates?))(?![a-z])
|
||||
# ignore long runs of a single character:
|
||||
\b([A-Za-z])\g{-1}{3,}\b
|
||||
# Note that the next example is no longer necessary if you are using
|
||||
# to match a string starting with a `#`, use a character-class:
|
||||
[#]backwards
|
||||
# version suffix <word>v#
|
||||
(?:(?<=[A-Z]{2})V|(?<=[a-z]{2}|[A-Z]{2})v)\d+(?:\b|(?=[a-zA-Z_]))
|
||||
# Compiler flags (Scala)
|
||||
(?:^|[\t ,>"'`=(])-J-[DPWXY](?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,})
|
||||
# Compiler flags
|
||||
#(?:^|[\t ,"'`=(])-[DPWXYLlf](?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,})
|
||||
|
||||
# Compiler flags (linker)
|
||||
,-B
|
||||
# curl arguments
|
||||
\b(?:\\n|)curl(?:\s+-[a-zA-Z]{1,2}\b)*(?:\s+-[a-zA-Z]{3,})(?:\s+-[a-zA-Z]+)*
|
||||
# set arguments
|
||||
\bset(?:\s+-[abefimouxE]{1,2})*\s+-[abefimouxE]{3,}(?:\s+-[abefimouxE]+)*
|
||||
# tar arguments
|
||||
\b(?:\\n|)g?tar(?:\.exe|)(?:(?:\s+--[-a-zA-Z]+|\s+-[a-zA-Z]+|\s[ABGJMOPRSUWZacdfh-pr-xz]+\b)(?:=[^ ]*|))+
|
||||
# tput arguments -- https://man7.org/linux/man-pages/man5/terminfo.5.html -- technically they can be more than 5 chars long...
|
||||
\btput\s+(?:(?:-[SV]|-T\s*\w+)\s+)*\w{3,5}\b
|
||||
# macOS temp folders
|
||||
/var/folders/\w\w/[+\w]+/(?:T|-Caches-)/
|
||||
39
.github/actions/spell-check/excludes.txt
vendored
39
.github/actions/spell-check/excludes.txt
vendored
@@ -1,12 +1,13 @@
|
||||
# See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-excludes
|
||||
(?:^|/)(?i)COPYRIGHT
|
||||
(?:^|/)(?i)LICEN[CS]E
|
||||
(?:^|/)3rdparty/
|
||||
(?:^|/)go\.sum$
|
||||
(?:^|/)MonacoPreviewHandler/customLanguages/
|
||||
(?:^|/)MonacoPreviewHandler/generateLanguagesJson.html
|
||||
(?:^|/)MonacoPreviewHandler/index.html
|
||||
(?:^|/)MonacoPreviewHandler/monacoSpecialLanguages.js
|
||||
(?:^|/)MonacoPreviewHandler/monaco_languages.json
|
||||
(?:^|/)MonacoPreviewHandler/monacoSpecialLanguages.js
|
||||
(?:^|/)monacoSRC/
|
||||
(?:^|/)package(?:-lock|)\.json$
|
||||
(?:^|/)timezones\.json$
|
||||
@@ -15,17 +16,21 @@
|
||||
/package(?:-lock|)\.json$
|
||||
/pinyindb/
|
||||
/settings-html/
|
||||
ignore$
|
||||
[/.][a-z]{2}(?:-[a-zA-Z]{2}|)\.
|
||||
\.a$
|
||||
\.ai$
|
||||
\.avi$
|
||||
\.bmp$
|
||||
\.bz2$
|
||||
\.class$
|
||||
\.crt$
|
||||
\.dat$
|
||||
\.dll$
|
||||
\.docx?$
|
||||
\.drawio$
|
||||
\.DS_Store$
|
||||
\.eot$
|
||||
\.exe$
|
||||
\.filters$
|
||||
\.gcode$
|
||||
\.gif$
|
||||
@@ -36,14 +41,17 @@ ignore$
|
||||
\.icns$
|
||||
\.ico$
|
||||
\.jar$
|
||||
\.jks$
|
||||
\.jpe?g$
|
||||
\.key$
|
||||
\.lcl$
|
||||
\.lib$
|
||||
\.lock$
|
||||
\.map$
|
||||
\.min\..
|
||||
\.mod$
|
||||
\.mp[34]$
|
||||
\.o$
|
||||
\.ocf$
|
||||
\.otf$
|
||||
\.pdf$
|
||||
@@ -51,12 +59,34 @@ ignore$
|
||||
\.PNG$
|
||||
\.png$
|
||||
\.psd$
|
||||
\.pyc$
|
||||
\.s$
|
||||
\.stl$
|
||||
\.svg$
|
||||
\.svgz?$
|
||||
\.tar$
|
||||
\.tiff?$
|
||||
\.ttf$
|
||||
\.wav$
|
||||
\.webm$
|
||||
\.webp$
|
||||
\.woff2?$
|
||||
\.xlsx?$
|
||||
\.zip$
|
||||
^\.github/actions/spell-check/
|
||||
^\.gitmodules$
|
||||
^\Q.github/workflows/spelling2.yml\E$
|
||||
^\Q.pipelines/ESRPSigning_core.json\E$
|
||||
^\Qsrc/modules/colorPicker/ColorPickerUI/Shaders/GridShader.cso\E$
|
||||
^\Qsrc/settings-ui/Settings.UI.UnitTests/BackwardsCompatibility/TestFiles/CorruptJson/Microsoft/PowerToys/settings.json\E$
|
||||
^\Qsrc/settings-ui/Settings.UI.UnitTests/BackwardsCompatibility/TestFiles/v0.18.2/Microsoft/PowerToys/PowerRename/power-rename-ui-flags\E$
|
||||
^\Qsrc/settings-ui/Settings.UI.UnitTests/BackwardsCompatibility/TestFiles/v0.19.2/Microsoft/PowerToys/PowerRename/power-rename-ui-flags\E$
|
||||
^\Qsrc/settings-ui/Settings.UI.UnitTests/BackwardsCompatibility/TestFiles/v0.20.1/Microsoft/PowerToys/PowerRename/power-rename-ui-flags\E$
|
||||
^\Qsrc/settings-ui/Settings.UI.UnitTests/BackwardsCompatibility/TestFiles/V0.21.1/Microsoft/PowerToys/FancyZones/settings.json\E$
|
||||
^\Qsrc/settings-ui/Settings.UI.UnitTests/BackwardsCompatibility/TestFiles/V0.21.1/Microsoft/PowerToys/PowerRename/power-rename-ui-flags\E$
|
||||
^\Qsrc/settings-ui/Settings.UI.UnitTests/BackwardsCompatibility/TestFiles/v0.22.0/Microsoft/PowerToys/FancyZones/settings.json\E$
|
||||
^\Qsrc/settings-ui/Settings.UI.UnitTests/BackwardsCompatibility/TestFiles/v0.22.0/Microsoft/PowerToys/PowerRename/power-rename-ui-flags\E$
|
||||
^\Qtools/project_template/ModuleTemplate/resource.h\E$
|
||||
^doc/devdocs/akaLinks\.md$
|
||||
^installer/PowerToysSetup/WebView2/MicrosoftEdgeWebview2Setup.exe$
|
||||
^src/common/logger/logger\.vcxproj\.filters$
|
||||
@@ -71,7 +101,4 @@ ignore$
|
||||
^src/modules/previewpane/UnitTests-MarkdownPreviewHandler/HelperFiles/MarkdownWithHTMLImageTag.txt$
|
||||
^tools/CleanUp_tool/CleanUp_tool\.vcxproj\.filters$
|
||||
^tools/Verification scripts/Check preview handler registration\.ps1$
|
||||
^\.github/
|
||||
^\.github/actions/spell-check/
|
||||
^\.gitmodules$
|
||||
^\Q.pipelines/ESRPSigning_core.json\E$
|
||||
ignore$
|
||||
|
||||
670
.github/actions/spell-check/expect.txt
vendored
670
.github/actions/spell-check/expect.txt
vendored
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,11 @@
|
||||
# reject `m_data` as there's a certain OS which has evil defines that break things if it's used elsewhere
|
||||
# \bm_data\b
|
||||
|
||||
# If you have a framework that uses `it()` for testing and `fit()` for debugging a specific test,
|
||||
# you might not want to check in code where you were debugging w/ `fit()`, in which case, you might want
|
||||
# to use this:
|
||||
#\bfit\(
|
||||
|
||||
# s.b. GitHub
|
||||
\bGithub\b
|
||||
|
||||
@@ -14,19 +19,44 @@
|
||||
\bMicroSoft\b
|
||||
|
||||
# s.b. another
|
||||
\ban other\b
|
||||
\ban[- ]other\b
|
||||
|
||||
# s.b. greater than
|
||||
\bgreater then\b
|
||||
|
||||
# s.b. into
|
||||
\sin to\s
|
||||
|
||||
# s.b. opt-in
|
||||
\sopt in\s
|
||||
|
||||
# s.b. less than
|
||||
\bless then\b
|
||||
|
||||
# s.b. otherwise
|
||||
\bother wise\b
|
||||
\bother[- ]wise\b
|
||||
|
||||
# s.b. nonexistent
|
||||
\bnon existing\b
|
||||
\b[Nn]o[nt][- ]existent\b
|
||||
|
||||
# s.b. preexisting
|
||||
[Pp]re-existing
|
||||
[Pp]re[- ]existing
|
||||
|
||||
# s.b. preempt
|
||||
[Pp]re[- ]empt\b
|
||||
|
||||
# s.b. preemptively
|
||||
[Pp]re-emptively
|
||||
[Pp]re[- ]emptively
|
||||
|
||||
# s.b. reentrancy
|
||||
[Rr]e[- ]entrancy
|
||||
|
||||
# s.b. reentrant
|
||||
[Rr]e[- ]entrant
|
||||
|
||||
# s.b. workaround(s)
|
||||
#\bwork[- ]arounds?\b
|
||||
|
||||
# Reject duplicate words
|
||||
\s([A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,})\s\g{-1}\s
|
||||
|
||||
71
.github/actions/spell-check/patterns.txt
vendored
71
.github/actions/spell-check/patterns.txt
vendored
@@ -1,4 +1,50 @@
|
||||
# See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns
|
||||
|
||||
# Automatically suggested patterns
|
||||
# hit-count: 2206 file-count: 617
|
||||
# IServiceProvider
|
||||
\bI(?=(?:[A-Z][a-z]{2,})+\b)
|
||||
|
||||
# hit-count: 111 file-count: 57
|
||||
# hex runs
|
||||
\b[0-9a-fA-F]{16,}\b
|
||||
|
||||
# hit-count: 89 file-count: 36
|
||||
# GitHub SHAs (markdown)
|
||||
(?:\[`?[0-9a-f]+`?\]\(https:/|)/(?:www\.|)github\.com(?:/[^/\s"]+){2,}(?:/[^/\s")]+)(?:[0-9a-f]+(?:[-0-9a-zA-Z/#.]*|)\b|)
|
||||
|
||||
# hit-count: 67 file-count: 59
|
||||
# w3
|
||||
\bw3\.org/[-0-9a-zA-Z/#.]+
|
||||
|
||||
# hit-count: 47 file-count: 3
|
||||
# Contributor
|
||||
\[[^\]]+\]\(https://github\.com/[^/\s"]+\)
|
||||
|
||||
# hit-count: 45 file-count: 2
|
||||
# Non-English
|
||||
[a-zA-Z]*[ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź][a-zA-Z]{3}[a-zA-ZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź]*
|
||||
|
||||
# hit-count: 22 file-count: 18
|
||||
# stackexchange -- https://stackexchange.com/feeds/sites
|
||||
\b(?:askubuntu|serverfault|stack(?:exchange|overflow)|superuser).com/(?:questions/\w+/[-\w]+|a/)
|
||||
|
||||
# hit-count: 7 file-count: 3
|
||||
# Wikipedia
|
||||
\ben\.wikipedia\.org/wiki/[-\w%.#]+
|
||||
|
||||
# hit-count: 5 file-count: 3
|
||||
# vs devops
|
||||
\bvisualstudio.com(?::443|)/[-\w/?=%&.]*
|
||||
|
||||
# hit-count: 3 file-count: 3
|
||||
# githubusercontent
|
||||
/[-a-z0-9]+\.githubusercontent\.com/[-a-zA-Z0-9?&=_\/.]*
|
||||
|
||||
# hit-count: 2 file-count: 2
|
||||
# mailto urls
|
||||
mailto:[-a-zA-Z=;:/?%&0-9+@.]{3,}
|
||||
|
||||
https?://(?:(?:www\.|)youtube\.com|youtu.be)/[-a-zA-Z0-9?&=]*
|
||||
# GitHub SHAs
|
||||
\bapi.github\.com/repos/[^/]+/[^/]+/[^/]+/[0-9a-f]+\b
|
||||
@@ -93,7 +139,7 @@ TestCase\("[^"]+"
|
||||
\[TestCase\(new string.*\]
|
||||
|
||||
# D2D
|
||||
D2D
|
||||
D?2D
|
||||
|
||||
# marker for ignoring a comment to the end of the line
|
||||
^.*/\* #no-spell-check-line \*/.*$
|
||||
@@ -104,13 +150,30 @@ http://tes/
|
||||
# tar arguments
|
||||
\b(?:\\n|)tar(?:\s+-[a-zA-Z]+|\s[a-z]+)+
|
||||
|
||||
# fabricbot.json
|
||||
"id": "\S+"
|
||||
"commentPattern": ".*"
|
||||
# Questionably acceptable forms of `in to`
|
||||
# Personally, I prefer `log into`, but people object
|
||||
# https://www.tprteaching.com/log-into-log-in-to-login/
|
||||
\b[Ll]og in to\b
|
||||
|
||||
# acceptable duplicates
|
||||
# ls directory listings
|
||||
# /bin/ls -l output
|
||||
[-bcdlpsw](?:[-r][-w][-sx]){3}\s+\d+\s+(\S+)\s+\g{-1}\s+\d+\s+
|
||||
# C types
|
||||
\s(long|LONG) \g{-1}\s
|
||||
# C types and repeated CSS values
|
||||
\s(center|div|inherit|long|LONG|none|normal|solid|thin|transparent|very)(?: \g{-1})+\s
|
||||
# go templates
|
||||
\s(\w+)\s+\g{-1}\s+\`(?:graphql|json|yaml):
|
||||
# javadoc / .net
|
||||
(?:\@(?:groupname|param)|(?:public|private)(?:\s+static|\s+readonly)*)\s+(\w+)\s+\g{-1}\s
|
||||
(?:[\\@](?:groupname|param)|(?:public|private)(?:\s+static|\s+readonly)*)\s+(\w+)\s+\g{-1}\s
|
||||
|
||||
# Commit message -- Signed-off-by and friends
|
||||
^\s*(?:(?:Based-on-patch|Co-authored|Helped|Mentored|Reported|Reviewed|Signed-off)-by|Thanks-to): (?:[^<]*<[^>]*>|[^<]*)\s*$
|
||||
|
||||
# Autogenerated revert commit message
|
||||
^This reverts commit [0-9a-f]{40}\.$
|
||||
|
||||
# ignore long runs of a single character:
|
||||
\b([A-Za-z])\g{-1}{3,}\b
|
||||
|
||||
6
.github/workflows/msstore-submissions.yml
vendored
6
.github/workflows/msstore-submissions.yml
vendored
@@ -41,14 +41,14 @@ jobs:
|
||||
"packageUrl":"${{ steps.releaseVars.outputs.powerToysInstallerX64Url }}",
|
||||
"languages":["zh-hans", "zh-hant", "en", "cs", "nl", "fr", "pt", "pt-br", "de", "hu", "it", "ja", "ko", "pl", "ru", "es", "tr"],
|
||||
"architectures":["X64"],
|
||||
"installerParameters":"/passive /norestart",
|
||||
"installerParameters":"/quiet /norestart",
|
||||
"isSilentInstall":true
|
||||
},
|
||||
{
|
||||
"packageUrl":"${{ steps.releaseVars.outputs.powerToysInstallerArm64Url }}",
|
||||
"languages":["zh-hans", "zh-hant", "en", "cs", "nl", "fr", "pt", "pt-br", "de", "hu", "it", "ja", "ko", "pl", "ru", "es", "tr"],
|
||||
"architectures":["Arm64"],
|
||||
"installerParameters":"/passive /norestart",
|
||||
"installerParameters":"/quiet /norestart",
|
||||
"isSilentInstall":true
|
||||
}
|
||||
]
|
||||
@@ -57,4 +57,4 @@ jobs:
|
||||
- name: Publish Submission
|
||||
uses: microsoft/store-submission@v1
|
||||
with:
|
||||
command: publish
|
||||
command: publish
|
||||
|
||||
94
.github/workflows/spelling2.yml
vendored
94
.github/workflows/spelling2.yml
vendored
@@ -1,10 +1,54 @@
|
||||
# spelling.yml is blocked per https://github.com/check-spelling/check-spelling/security/advisories/GHSA-g86g-chm8-7r2p
|
||||
name: Spell checking
|
||||
|
||||
# Comment management is handled through a secondary job, for details see:
|
||||
# https://github.com/check-spelling/check-spelling/wiki/Feature%3A-Restricted-Permissions
|
||||
#
|
||||
# `jobs.comment-push` runs when a push is made to a repository and the `jobs.spelling` job needs to make a comment
|
||||
# (in odd cases, it might actually run just to collapse a commment, but that's fairly rare)
|
||||
# it needs `contents: write` in order to add a comment.
|
||||
#
|
||||
# `jobs.comment-pr` runs when a pull_request is made to a repository and the `jobs.spelling` job needs to make a comment
|
||||
# or collapse a comment (in the case where it had previously made a comment and now no longer needs to show a comment)
|
||||
# it needs `pull-requests: write` in order to manipulate those comments.
|
||||
|
||||
# Updating pull request branches is managed via comment handling.
|
||||
# For details, see: https://github.com/check-spelling/check-spelling/wiki/Feature:-Update-expect-list
|
||||
#
|
||||
# These elements work together to make it happen:
|
||||
#
|
||||
# `on.issue_comment`
|
||||
# This event listens to comments by users asking to update the metadata.
|
||||
#
|
||||
# `jobs.update`
|
||||
# This job runs in response to an issue_comment and will push a new commit
|
||||
# to update the spelling metadata.
|
||||
#
|
||||
# `with.experimental_apply_changes_via_bot`
|
||||
# Tells the action to support and generate messages that enable it
|
||||
# to make a commit to update the spelling metadata.
|
||||
#
|
||||
# `with.ssh_key`
|
||||
# In order to trigger workflows when the commit is made, you can provide a
|
||||
# secret (typically, a write-enabled github deploy key).
|
||||
#
|
||||
# For background, see: https://github.com/check-spelling/check-spelling/wiki/Feature:-Update-with-deploy-key
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
push:
|
||||
branches: ["**"]
|
||||
tags-ignore: ["**"]
|
||||
branches:
|
||||
- "**"
|
||||
tags-ignore:
|
||||
- "**"
|
||||
pull_request_target:
|
||||
branches:
|
||||
- "**"
|
||||
tags-ignore:
|
||||
- "**"
|
||||
types:
|
||||
- 'opened'
|
||||
- 'reopened'
|
||||
- 'synchronize'
|
||||
|
||||
jobs:
|
||||
spelling:
|
||||
@@ -24,35 +68,55 @@ jobs:
|
||||
steps:
|
||||
- name: check-spelling
|
||||
id: spelling
|
||||
uses: check-spelling/check-spelling@v0.0.20-alpha7
|
||||
uses: check-spelling/check-spelling@v0.0.21
|
||||
with:
|
||||
config: .github/actions/spell-check
|
||||
suppress_push_for_open_pull_request: 1
|
||||
checkout: true
|
||||
check_file_names: 1
|
||||
spell_check_this: check-spelling/spell-check-this@prerelease
|
||||
post_comment: 0
|
||||
use_magic_file: 1
|
||||
extra_dictionary_limit: 10
|
||||
extra_dictionaries:
|
||||
cspell:software-terms/src/software-terms.txt
|
||||
cspell:cpp/src/stdlib-cpp.txt
|
||||
cspell:filetypes/filetypes.txt
|
||||
cspell:cpp/src/stdlib-c.txt
|
||||
cspell:fullstack/fullstack.txt
|
||||
cspell:html/html.txt
|
||||
cspell:css/css.txt
|
||||
check_extra_dictionaries: ''
|
||||
|
||||
comment:
|
||||
name: Comment
|
||||
comment-push:
|
||||
name: Report (Push)
|
||||
# If your workflow isn't running on push, you can remove this job
|
||||
runs-on: ubuntu-latest
|
||||
needs: spelling
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
if: (success() || failure()) && needs.spelling.outputs.followup
|
||||
if: (success() || failure()) && needs.spelling.outputs.followup && github.event_name == 'push'
|
||||
steps:
|
||||
- name: comment
|
||||
uses: check-spelling/check-spelling@v0.0.20-alpha7
|
||||
uses: check-spelling/check-spelling@v0.0.21
|
||||
with:
|
||||
config: .github/actions/spell-check
|
||||
checkout: true
|
||||
spell_check_this: check-spelling/spell-check-this@prerelease
|
||||
task: ${{ needs.spelling.outputs.followup }}
|
||||
|
||||
comment-pr:
|
||||
name: Report (PR)
|
||||
# If you workflow isn't running on pull_request*, you can remove this job
|
||||
runs-on: ubuntu-latest
|
||||
needs: spelling
|
||||
permissions:
|
||||
pull-requests: write
|
||||
if: (success() || failure()) && needs.spelling.outputs.followup && contains(github.event_name, 'pull_request')
|
||||
steps:
|
||||
- name: comment
|
||||
uses: check-spelling/check-spelling@v0.0.21
|
||||
with:
|
||||
config: .github/actions/spell-check
|
||||
checkout: true
|
||||
spell_check_this: check-spelling/spell-check-this@prerelease
|
||||
task: ${{ needs.spelling.outputs.followup }}
|
||||
extra_dictionaries:
|
||||
cspell:filetypes/filetypes.txt
|
||||
cspell:html/html.txt
|
||||
cspell:css/css.txt
|
||||
check_extra_dictionaries: ''
|
||||
|
||||
@@ -25,14 +25,14 @@
|
||||
"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\\PowerOCR\\PowerToys.PowerOCRModuleInterface.dll",
|
||||
"modules\\PowerOCR\\PowerToys.PowerOCR.dll",
|
||||
"modules\\PowerOCR\\PowerToys.PowerOCR.exe",
|
||||
|
||||
"modules\\Awake\\PowerToys.AwakeModuleInterface.dll",
|
||||
"modules\\Awake\\PowerToys.Awake.exe",
|
||||
"modules\\Awake\\PowerToys.Awake.dll",
|
||||
@@ -86,6 +86,7 @@
|
||||
"modules\\launcher\\Plugins\\Folder\\Microsoft.Plugin.Folder.dll",
|
||||
"modules\\launcher\\Plugins\\Indexer\\Microsoft.Plugin.Indexer.dll",
|
||||
"modules\\launcher\\Plugins\\OneNote\\Microsoft.PowerToys.Run.Plugin.OneNote.dll",
|
||||
"modules\\launcher\\Plugins\\History\\Microsoft.PowerToys.Run.Plugin.History.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",
|
||||
@@ -101,10 +102,22 @@
|
||||
"modules\\launcher\\Plugins\\WebSearch\\Community.PowerToys.Run.Plugin.WebSearch.dll",
|
||||
"modules\\launcher\\Plugins\\WindowsTerminal\\Microsoft.PowerToys.Run.Plugin.WindowsTerminal.dll",
|
||||
|
||||
"modules\\MeasureTool\\PowerToys.MeasureToolModuleInterface.dll",
|
||||
"modules\\MeasureTool\\PowerToys.MeasureToolCore.dll",
|
||||
"modules\\MeasureTool\\PowerToys.MeasureToolUI.dll",
|
||||
"modules\\MeasureTool\\PowerToys.MeasureToolUI.exe",
|
||||
|
||||
"modules\\MouseUtils\\PowerToys.FindMyMouse.dll",
|
||||
"modules\\MouseUtils\\PowerToys.MouseHighlighter.dll",
|
||||
"modules\\MouseUtils\\PowerToys.MousePointerCrosshairs.dll",
|
||||
|
||||
"modules\\PowerAccent\\PowerAccent.Core.dll",
|
||||
"modules\\PowerAccent\\PowerAccent.dll",
|
||||
"modules\\PowerAccent\\PowerAccent.exe",
|
||||
"modules\\PowerAccent\\PowerToys.PowerAccent.dll",
|
||||
"modules\\PowerAccent\\PowerToys.PowerAccent.exe",
|
||||
"modules\\PowerAccent\\PowerToys.PowerAccentModuleInterface.dll",
|
||||
|
||||
"modules\\PowerRename\\PowerToys.PowerRenameExt.dll",
|
||||
"modules\\PowerRename\\PowerToys.PowerRename.exe",
|
||||
"modules\\PowerRename\\PowerToys.PowerRenameContextMenu.dll",
|
||||
@@ -186,7 +199,12 @@
|
||||
"vccorlib140_app.dll",
|
||||
"vcomp140_app.dll",
|
||||
"vcruntime140_1_app.dll",
|
||||
"vcruntime140_app.dll",
|
||||
"vcruntime140_app.dll",
|
||||
"modules\\PowerAccent\\Vanara.Core.dll",
|
||||
"modules\\PowerAccent\\Vanara.PInvoke.Gdi32.dll",
|
||||
"modules\\PowerAccent\\Vanara.PInvoke.Kernel32.dll",
|
||||
"modules\\PowerAccent\\Vanara.PInvoke.Shared.dll",
|
||||
"modules\\PowerAccent\\Vanara.PInvoke.User32.dll",
|
||||
"modules\\FileExplorerPreview\\Microsoft.Web.WebView2.Core.dll",
|
||||
"modules\\FileExplorerPreview\\Microsoft.Web.WebView2.WinForms.dll",
|
||||
"modules\\FileExplorerPreview\\Microsoft.Web.WebView2.Wpf.dll",
|
||||
|
||||
@@ -7,6 +7,41 @@ steps:
|
||||
submodules: true
|
||||
clean: true
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: Verify Arm64 configuration for PowerToys.sln
|
||||
inputs:
|
||||
filePath: '$(build.sourcesdirectory)\.pipelines\verifyArm64Configuration.ps1'
|
||||
arguments: -solution '$(build.sourcesdirectory)\PowerToys.sln'
|
||||
pwsh: true
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: Verify Arm64 configuration for BugReportTool.sln
|
||||
inputs:
|
||||
filePath: '$(build.sourcesdirectory)\.pipelines\verifyArm64Configuration.ps1'
|
||||
arguments: -solution '$(build.sourcesdirectory)\tools\BugReportTool\BugReportTool.sln'
|
||||
pwsh: true
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: Verify Arm64 configuration for WebcamReportTool.sln
|
||||
inputs:
|
||||
filePath: '$(build.sourcesdirectory)\.pipelines\verifyArm64Configuration.ps1'
|
||||
arguments: -solution '$(build.sourcesdirectory)\tools\WebcamReportTool\WebcamReportTool.sln'
|
||||
pwsh: true
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: Verify Arm64 configuration for StylesReportTool.sln
|
||||
inputs:
|
||||
filePath: '$(build.sourcesdirectory)\.pipelines\verifyArm64Configuration.ps1'
|
||||
arguments: -solution '$(build.sourcesdirectory)\tools\StylesReportTool\StylesReportTool.sln'
|
||||
pwsh: true
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: Verify Arm64 configuration for PowerToysSetup.sln
|
||||
inputs:
|
||||
filePath: '$(build.sourcesdirectory)\.pipelines\verifyArm64Configuration.ps1'
|
||||
arguments: -solution '$(build.sourcesdirectory)\installer\PowerToysSetup.sln'
|
||||
pwsh: true
|
||||
|
||||
- task: UseDotNet@2
|
||||
displayName: 'Use .NET 6 SDK'
|
||||
inputs:
|
||||
@@ -184,4 +219,5 @@ steps:
|
||||
**\UnitTests-CommonLib.dll
|
||||
**\PowerRenameUnitTests.dll
|
||||
**\powerpreviewTest.dll
|
||||
**\UnitTests-FancyZones.dll
|
||||
!**\obj\**
|
||||
|
||||
@@ -279,6 +279,22 @@ jobs:
|
||||
configuration: $(BuildConfiguration)
|
||||
maximumCpuCount: true
|
||||
|
||||
- task: VSBuild@1
|
||||
displayName: Publish Measure Tool UI for Packaging
|
||||
inputs:
|
||||
solution: 'src/modules/MeasureTool/MeasureToolUI/MeasureToolUI.csproj'
|
||||
vsVersion: 17.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
|
||||
|
||||
- task: VSBuild@1
|
||||
displayName: Build PowerToysSetupCustomActions DLL # This dll needs to be build and signed before building the MSI.
|
||||
inputs:
|
||||
@@ -471,7 +487,7 @@ jobs:
|
||||
displayName: 'Publish Artifact: Symbols'
|
||||
inputs:
|
||||
PathtoPublish: $(System.ArtifactsDirectory)/Symbols-$(BuildPlatform)/
|
||||
ArtifactName: Symbols-$(BuildPlatform)
|
||||
ArtifactName: Symbols-${{ parameters.versionNumber }}-$(BuildPlatform)
|
||||
|
||||
- task: DeleteFiles@1
|
||||
displayName: 'Remove symbols from ArtifactStagingDirectory'
|
||||
|
||||
63
.pipelines/verifyArm64Configuration.ps1
Normal file
63
.pipelines/verifyArm64Configuration.ps1
Normal file
@@ -0,0 +1,63 @@
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[Parameter(Mandatory=$True,Position=1)]
|
||||
[string]$solution
|
||||
)
|
||||
|
||||
Write-Output "Verifying Arm64 configuration for $solution"
|
||||
|
||||
$errorTable = @{}
|
||||
|
||||
$MSBuildLoc = & "C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -prerelease -requires Microsoft.Component.MSBuild -find MSBuild\**\Bin\Microsoft.Build.dll
|
||||
if ($null -eq $MSBuildLoc) {
|
||||
throw "Unable to locate Microsoft.Build.dll"
|
||||
}
|
||||
|
||||
try {
|
||||
Add-Type -Path $MSBuildLoc
|
||||
}
|
||||
catch {
|
||||
# Catching because it may error on loading all the types from the assembly, but we only need one
|
||||
}
|
||||
|
||||
$solutionFile = [Microsoft.Build.Construction.SolutionFile]::Parse($solution);
|
||||
$arm64SlnConfigs = $solutionFile.SolutionConfigurations | Where-Object {
|
||||
$_.PlatformName -eq "ARM64"
|
||||
};
|
||||
|
||||
# Should have two configurations. Debug and Release.
|
||||
if($arm64SlnConfigs.Length -lt 2) {
|
||||
Write-Host -ForegroundColor Red "Missing Solution-level Arm64 platforms"
|
||||
exit 1;
|
||||
}
|
||||
|
||||
# List projects only.
|
||||
$projects = $solutionFile.ProjectsInOrder | Where-Object {
|
||||
$_.ProjectType -eq "KnownToBeMSBuildFormat"
|
||||
};
|
||||
|
||||
# Enumerate through the projects and add any project with a mismatched platform and project configuration
|
||||
foreach ($project in $projects) {
|
||||
foreach ($slnConfig in $arm64SlnConfigs.FullName) {
|
||||
if ($project.ProjectConfigurations.$slnConfig.FullName -ne $slnConfig) {
|
||||
$errorTable[$project.ProjectName] += @(""
|
||||
| Select-Object @{n = "Configuration"; e = { $project.ProjectConfigurations.$slnConfig.FullName } },
|
||||
@{n = "ExpectedConfiguration"; e = { $slnConfig } })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($errorTable.Count -gt 0) {
|
||||
Write-Host -ForegroundColor Red "Verification failed for the following projects:`n"
|
||||
$errorTable.Keys | ForEach-Object {
|
||||
Write-Host -ForegroundColor Red $_`:;
|
||||
$errorTable[$_] | ForEach-Object {
|
||||
Write-Host -ForegroundColor Red "$($_.ExpectedConfiguration)=$($_.Configuration)";
|
||||
};
|
||||
Write-Host -ForegroundColor Red `r
|
||||
}
|
||||
exit 1;
|
||||
}
|
||||
|
||||
Write-Output "Verification Complete"
|
||||
exit 0;
|
||||
@@ -25,7 +25,7 @@ if($items.Count -eq 0)
|
||||
exit 1;
|
||||
}
|
||||
|
||||
$items | ForEach-Object {
|
||||
$items | ForEach-Object {
|
||||
if($_.VersionInfo.FileVersion -eq "1.0.0.0" )
|
||||
{
|
||||
# These items are exceptions that actually have the 1.0.0.0 version.
|
||||
@@ -39,6 +39,30 @@ $items | ForEach-Object {
|
||||
(-not $_.Name.EndsWith("Microsoft.Xaml.Interactivity.dll")) -and
|
||||
(-not $_.Name.EndsWith("Microsoft.WindowsAppRuntime.Release.Net.dll"))
|
||||
)
|
||||
{
|
||||
Write-Host "Version set to 1.0.0.0: " + $_.FullName
|
||||
$totalFailure++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$items | ForEach-Object {
|
||||
if($_.VersionInfo.FileVersion -eq $null )
|
||||
{
|
||||
# These items are exceptions that actually a version not set.
|
||||
if ((-not $_.Name.EndsWith("codicon.ttf")) -and
|
||||
(-not $_.Name.EndsWith("e_sqlite3.dll")) -and
|
||||
(-not $_.Name.EndsWith("vcamp140_app.dll")) -and
|
||||
(-not $_.Name.EndsWith("marshal.dll")) -and
|
||||
(-not $_.Name.EndsWith("Microsoft.UI.Composition.OSSupport.dll")) -and
|
||||
(-not $_.Name.EndsWith("Microsoft.UI.Xaml.Internal.dll")) -and
|
||||
(-not $_.Name.EndsWith("Microsoft.Windows.ApplicationModel.Resources.dll")) -and
|
||||
(-not $_.Name.EndsWith("Microsoft.WindowsAppRuntime.dll")) -and
|
||||
(-not $_.Name.EndsWith("Microsoft.WindowsAppRuntime.Bootstrap.dll")) -and
|
||||
(-not $_.Name.EndsWith("MRM.dll")) -and
|
||||
(-not $_.Name.EndsWith("PushNotificationsLongRunningTask.ProxyStub.dll")) -and
|
||||
(-not $_.Name.EndsWith("WindowsAppSdk.AppxDeploymentExtensions.Desktop.dll"))
|
||||
)
|
||||
{
|
||||
Write-Host "Version not set: " + $_.FullName
|
||||
$totalFailure++;
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
"Microsoft.VisualStudio.Workload.NativeDesktop",
|
||||
"Microsoft.VisualStudio.Workload.ManagedDesktop",
|
||||
"Microsoft.VisualStudio.Workload.Universal",
|
||||
"Microsoft.VisualStudio.Component.Windows10SDK.18362",
|
||||
"Microsoft.VisualStudio.Component.Windows10SDK.19041",
|
||||
"Microsoft.VisualStudio.Component.Windows10SDK.20348",
|
||||
"Microsoft.VisualStudio.ComponentGroup.UWP.VC",
|
||||
"Microsoft.VisualStudio.Component.VC.Runtimes.x86.x64.Spectre",
|
||||
"Microsoft.VisualStudio.Component.VC.ATL.Spectre"
|
||||
|
||||
@@ -12,14 +12,14 @@
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|ARM64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|ARM64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|ARM64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|ARM64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Props that should be disabled while building on CI server -->
|
||||
@@ -32,11 +32,12 @@
|
||||
|
||||
<!-- C++ source compile-specific things for all configurations -->
|
||||
<PropertyGroup>
|
||||
<VcpkgEnabled>false</VcpkgEnabled>
|
||||
<ExternalIncludePath>$(MSBuildThisFileFullPath)\..\deps\;$(ExternalIncludePath)</ExternalIncludePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DisableAnalyzeExternal >true</DisableAnalyzeExternal>
|
||||
<ExternalWarningLevel>TurnOffAllWarnings</ExternalWarningLevel>
|
||||
@@ -83,8 +84,10 @@
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
<!-- Global props -->
|
||||
<PropertyGroup Label="Globals" Condition="'$(OverrideWindowsTargetPlatformVersion)'!='True'">
|
||||
<PropertyGroup Label="Globals"
|
||||
Condition="'$(OverrideWindowsTargetPlatformVersion)'!='True'">
|
||||
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
|
||||
<TargetPlatformVersion>10.0.19041.0</TargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Props that are constant for both Debug and Release configurations -->
|
||||
@@ -92,14 +95,17 @@
|
||||
<PlatformToolset Condition="'$(OverridePlatformToolset)'!='True'">v143</PlatformToolset>
|
||||
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)\obj\$(ProjectName)\</IntDir>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<DesktopCompatible>true</DesktopCompatible>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Debug/Release props -->
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Debug'"
|
||||
Label="Configuration">
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Release'"
|
||||
Label="Configuration">
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
|
||||
@@ -28,4 +28,18 @@
|
||||
<ForceImportBeforeCppProps>$(MsbuildThisFileDirectory)\Cpp.Build.props</ForceImportBeforeCppProps>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Condition="'$(MSBuildProjectExtension)' == '.csproj'">
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)\src\codeAnalysis\GlobalSuppressions.cs" Link="GlobalSuppressions.cs" />
|
||||
<AdditionalFiles Include="$(MSBuildThisFileDirectory)\src\codeAnalysis\StyleCop.json" Link="StyleCop.json" />
|
||||
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="6.0.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
24
NOTICE.md
24
NOTICE.md
@@ -6,6 +6,7 @@ This software incorporates material from third parties.
|
||||
- ImageResizer
|
||||
- PowerToys Run
|
||||
- Installer/Runner
|
||||
- Measure tool
|
||||
|
||||
## Utility: Color Picker
|
||||
|
||||
@@ -274,3 +275,26 @@ OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more information, please refer to <http://unlicense.org/>
|
||||
|
||||
## Utility: Measure tool
|
||||
|
||||
### sse2neon
|
||||
We adopted some functions from it.
|
||||
|
||||
**Source**: https://github.com/DLTcollab/sse2neon
|
||||
|
||||
sse2neon is freely redistributable under the MIT License.
|
||||
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.
|
||||
|
||||
173
PowerToys.sln
173
PowerToys.sln
@@ -284,6 +284,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "utils", "utils", "{B39DC643
|
||||
src\common\utils\process_path.h = src\common\utils\process_path.h
|
||||
src\common\utils\registry.h = src\common\utils\registry.h
|
||||
src\common\utils\resources.h = src\common\utils\resources.h
|
||||
src\common\utils\serialized.h = src\common\utils\serialized.h
|
||||
src\common\utils\string_utils.h = src\common\utils\string_utils.h
|
||||
src\common\utils\timeutil.h = src\common\utils\timeutil.h
|
||||
src\common\utils\UnhandledExceptionHandler.h = src\common\utils\UnhandledExceptionHandler.h
|
||||
@@ -407,7 +408,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerRenameUI", "src\module
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerRenameContextMenu", "src\modules\powerrename\PowerRenameContextMenu\PowerRenameContextMenu.vcxproj", "{1DBBB112-4BB1-444B-8EBB-E66555C76BA6}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.PowerToys.Run.Plugin.TimeZone.UnitTests", "src\modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.TimeZone.UnitTests\Microsoft.PowerToys.Run.Plugin.TimeZone.UnitTests.csproj", "{C5D46169-5334-48C3-8C28-644C72832E54}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerToys.Run.Plugin.TimeZone.UnitTests", "src\modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.TimeZone.UnitTests\Microsoft.PowerToys.Run.Plugin.TimeZone.UnitTests.csproj", "{C5D46169-5334-48C3-8C28-644C72832E54}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerToys.Run.Plugin.OneNote", "src\modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.OneNote\Microsoft.PowerToys.Run.Plugin.OneNote.csproj", "{5A1DB2F0-0715-4B3B-98E6-79BC41540045}"
|
||||
EndProject
|
||||
@@ -415,6 +416,37 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ImageResizerContextMenu", "
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ImageResizerLib", "src\modules\imageresizer\ImageResizerLib\ImageResizerLib.vcxproj", "{18B3DB45-4FFE-4D01-97D6-5223FEEE1853}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PowerAccent", "PowerAccent", "{0F14491C-6369-4C45-AAA8-135814E66E6B}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerAccentModuleInterface", "src\modules\poweraccent\PowerAccentModuleInterface\PowerAccentModuleInterface.vcxproj", "{34A354C5-23C7-4343-916C-C52DAF4FC39D}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PowerAccent", "src\modules\poweraccent\PowerAccent\PowerAccent.csproj", "{7B4CDB0D-28C9-4F95-88AA-73FCC06E354C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PowerAccent.Core", "src\modules\poweraccent\PowerAccent.Core\PowerAccent.Core.csproj", "{3264DF53-C805-4B0C-867C-FCEAF7AEF762}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PowerAccent.UI", "src\modules\poweraccent\PowerAccent.UI\PowerAccent.UI.csproj", "{31CAD28E-778A-441C-85BC-40AB3EAA2A10}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PowerOCR", "PowerOCR", "{A50C70A6-2DA0-4027-B90E-B1A40755A8A5}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PowerOCR", "src\modules\PowerOCR\PowerOCR\PowerOCR.csproj", "{25C91A4E-BA4E-467A-85CD-8B62545BF674}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerOCRModuleInterface", "src\modules\PowerOCR\PowerOCRModuleInterface\PowerOCRModuleInterface.vcxproj", "{6AB6A2D6-F859-4A82-9184-0BD29C9F07D1}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerToys.Run.Plugin.History", "src\modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.History\Microsoft.PowerToys.Run.Plugin.History.csproj", "{212AD910-8488-4036-BE20-326931B75FB2}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MeasureTool", "MeasureTool", "{7AC943C9-52E8-44CF-9083-744D8049667B}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerToys.MeasureToolCore", "src\modules\MeasureTool\MeasureToolCore\PowerToys.MeasureToolCore.vcxproj", "{54A93AF7-60C7-4F6C-99D2-FBB1F75F853A}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{6955446D-23F7-4023-9BB3-8657F904AF99} = {6955446D-23F7-4023-9BB3-8657F904AF99}
|
||||
{CABA8DFB-823B-4BF2-93AC-3F31984150D9} = {CABA8DFB-823B-4BF2-93AC-3F31984150D9}
|
||||
{CC6E41AC-8174-4E8A-8D22-85DD7F4851DF} = {CC6E41AC-8174-4E8A-8D22-85DD7F4851DF}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MeasureToolModuleInterface", "src\modules\MeasureTool\MeasureToolModuleInterface\MeasureToolModuleInterface.vcxproj", "{92C39820-9F84-4529-BC7D-22AAE514D63B}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MeasureToolUI", "src\modules\MeasureTool\MeasureToolUI\MeasureToolUI.csproj", "{515554D1-D004-4F7F-A107-2211FC0F6B2C}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|ARM64 = Debug|ARM64
|
||||
@@ -1632,6 +1664,132 @@ Global
|
||||
{18B3DB45-4FFE-4D01-97D6-5223FEEE1853}.Release|x64.Build.0 = Release|x64
|
||||
{18B3DB45-4FFE-4D01-97D6-5223FEEE1853}.Release|x86.ActiveCfg = Release|x64
|
||||
{18B3DB45-4FFE-4D01-97D6-5223FEEE1853}.Release|x86.Build.0 = Release|x64
|
||||
{34A354C5-23C7-4343-916C-C52DAF4FC39D}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{34A354C5-23C7-4343-916C-C52DAF4FC39D}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{34A354C5-23C7-4343-916C-C52DAF4FC39D}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{34A354C5-23C7-4343-916C-C52DAF4FC39D}.Debug|x64.Build.0 = Debug|x64
|
||||
{34A354C5-23C7-4343-916C-C52DAF4FC39D}.Debug|x86.ActiveCfg = Debug|x64
|
||||
{34A354C5-23C7-4343-916C-C52DAF4FC39D}.Debug|x86.Build.0 = Debug|x64
|
||||
{34A354C5-23C7-4343-916C-C52DAF4FC39D}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{34A354C5-23C7-4343-916C-C52DAF4FC39D}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{34A354C5-23C7-4343-916C-C52DAF4FC39D}.Release|x64.ActiveCfg = Release|x64
|
||||
{34A354C5-23C7-4343-916C-C52DAF4FC39D}.Release|x64.Build.0 = Release|x64
|
||||
{34A354C5-23C7-4343-916C-C52DAF4FC39D}.Release|x86.ActiveCfg = Release|x64
|
||||
{34A354C5-23C7-4343-916C-C52DAF4FC39D}.Release|x86.Build.0 = Release|x64
|
||||
{7B4CDB0D-28C9-4F95-88AA-73FCC06E354C}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{7B4CDB0D-28C9-4F95-88AA-73FCC06E354C}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{7B4CDB0D-28C9-4F95-88AA-73FCC06E354C}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{7B4CDB0D-28C9-4F95-88AA-73FCC06E354C}.Debug|x64.Build.0 = Debug|x64
|
||||
{7B4CDB0D-28C9-4F95-88AA-73FCC06E354C}.Debug|x86.ActiveCfg = Debug|x64
|
||||
{7B4CDB0D-28C9-4F95-88AA-73FCC06E354C}.Debug|x86.Build.0 = Debug|x64
|
||||
{7B4CDB0D-28C9-4F95-88AA-73FCC06E354C}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{7B4CDB0D-28C9-4F95-88AA-73FCC06E354C}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{7B4CDB0D-28C9-4F95-88AA-73FCC06E354C}.Release|x64.ActiveCfg = Release|x64
|
||||
{7B4CDB0D-28C9-4F95-88AA-73FCC06E354C}.Release|x64.Build.0 = Release|x64
|
||||
{7B4CDB0D-28C9-4F95-88AA-73FCC06E354C}.Release|x86.ActiveCfg = Release|x64
|
||||
{7B4CDB0D-28C9-4F95-88AA-73FCC06E354C}.Release|x86.Build.0 = Release|x64
|
||||
{3264DF53-C805-4B0C-867C-FCEAF7AEF762}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{3264DF53-C805-4B0C-867C-FCEAF7AEF762}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{3264DF53-C805-4B0C-867C-FCEAF7AEF762}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{3264DF53-C805-4B0C-867C-FCEAF7AEF762}.Debug|x64.Build.0 = Debug|x64
|
||||
{3264DF53-C805-4B0C-867C-FCEAF7AEF762}.Debug|x86.ActiveCfg = Debug|x64
|
||||
{3264DF53-C805-4B0C-867C-FCEAF7AEF762}.Debug|x86.Build.0 = Debug|x64
|
||||
{3264DF53-C805-4B0C-867C-FCEAF7AEF762}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{3264DF53-C805-4B0C-867C-FCEAF7AEF762}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{3264DF53-C805-4B0C-867C-FCEAF7AEF762}.Release|x64.ActiveCfg = Release|x64
|
||||
{3264DF53-C805-4B0C-867C-FCEAF7AEF762}.Release|x64.Build.0 = Release|x64
|
||||
{3264DF53-C805-4B0C-867C-FCEAF7AEF762}.Release|x86.ActiveCfg = Release|x64
|
||||
{3264DF53-C805-4B0C-867C-FCEAF7AEF762}.Release|x86.Build.0 = Release|x64
|
||||
{31CAD28E-778A-441C-85BC-40AB3EAA2A10}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{31CAD28E-778A-441C-85BC-40AB3EAA2A10}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{31CAD28E-778A-441C-85BC-40AB3EAA2A10}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{31CAD28E-778A-441C-85BC-40AB3EAA2A10}.Debug|x64.Build.0 = Debug|x64
|
||||
{31CAD28E-778A-441C-85BC-40AB3EAA2A10}.Debug|x86.ActiveCfg = Debug|x64
|
||||
{31CAD28E-778A-441C-85BC-40AB3EAA2A10}.Debug|x86.Build.0 = Debug|x64
|
||||
{31CAD28E-778A-441C-85BC-40AB3EAA2A10}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{31CAD28E-778A-441C-85BC-40AB3EAA2A10}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{31CAD28E-778A-441C-85BC-40AB3EAA2A10}.Release|x64.ActiveCfg = Release|x64
|
||||
{31CAD28E-778A-441C-85BC-40AB3EAA2A10}.Release|x64.Build.0 = Release|x64
|
||||
{31CAD28E-778A-441C-85BC-40AB3EAA2A10}.Release|x86.ActiveCfg = Release|x64
|
||||
{31CAD28E-778A-441C-85BC-40AB3EAA2A10}.Release|x86.Build.0 = Release|x64
|
||||
{25C91A4E-BA4E-467A-85CD-8B62545BF674}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{25C91A4E-BA4E-467A-85CD-8B62545BF674}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{25C91A4E-BA4E-467A-85CD-8B62545BF674}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{25C91A4E-BA4E-467A-85CD-8B62545BF674}.Debug|x64.Build.0 = Debug|x64
|
||||
{25C91A4E-BA4E-467A-85CD-8B62545BF674}.Debug|x86.ActiveCfg = Debug|x64
|
||||
{25C91A4E-BA4E-467A-85CD-8B62545BF674}.Debug|x86.Build.0 = Debug|x64
|
||||
{25C91A4E-BA4E-467A-85CD-8B62545BF674}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{25C91A4E-BA4E-467A-85CD-8B62545BF674}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{25C91A4E-BA4E-467A-85CD-8B62545BF674}.Release|x64.ActiveCfg = Release|x64
|
||||
{25C91A4E-BA4E-467A-85CD-8B62545BF674}.Release|x64.Build.0 = Release|x64
|
||||
{25C91A4E-BA4E-467A-85CD-8B62545BF674}.Release|x86.ActiveCfg = Release|x64
|
||||
{25C91A4E-BA4E-467A-85CD-8B62545BF674}.Release|x86.Build.0 = Release|x64
|
||||
{6AB6A2D6-F859-4A82-9184-0BD29C9F07D1}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{6AB6A2D6-F859-4A82-9184-0BD29C9F07D1}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{6AB6A2D6-F859-4A82-9184-0BD29C9F07D1}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{6AB6A2D6-F859-4A82-9184-0BD29C9F07D1}.Debug|x64.Build.0 = Debug|x64
|
||||
{6AB6A2D6-F859-4A82-9184-0BD29C9F07D1}.Debug|x86.ActiveCfg = Debug|x64
|
||||
{6AB6A2D6-F859-4A82-9184-0BD29C9F07D1}.Debug|x86.Build.0 = Debug|x64
|
||||
{6AB6A2D6-F859-4A82-9184-0BD29C9F07D1}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{6AB6A2D6-F859-4A82-9184-0BD29C9F07D1}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{6AB6A2D6-F859-4A82-9184-0BD29C9F07D1}.Release|x64.ActiveCfg = Release|x64
|
||||
{6AB6A2D6-F859-4A82-9184-0BD29C9F07D1}.Release|x64.Build.0 = Release|x64
|
||||
{6AB6A2D6-F859-4A82-9184-0BD29C9F07D1}.Release|x86.ActiveCfg = Release|x64
|
||||
{6AB6A2D6-F859-4A82-9184-0BD29C9F07D1}.Release|x86.Build.0 = Release|x64
|
||||
{212AD910-8488-4036-BE20-326931B75FB2}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{212AD910-8488-4036-BE20-326931B75FB2}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{212AD910-8488-4036-BE20-326931B75FB2}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{212AD910-8488-4036-BE20-326931B75FB2}.Debug|x64.Build.0 = Debug|x64
|
||||
{212AD910-8488-4036-BE20-326931B75FB2}.Debug|x86.ActiveCfg = Debug|x64
|
||||
{212AD910-8488-4036-BE20-326931B75FB2}.Debug|x86.Build.0 = Debug|x64
|
||||
{212AD910-8488-4036-BE20-326931B75FB2}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{212AD910-8488-4036-BE20-326931B75FB2}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{212AD910-8488-4036-BE20-326931B75FB2}.Release|x64.ActiveCfg = Release|x64
|
||||
{212AD910-8488-4036-BE20-326931B75FB2}.Release|x64.Build.0 = Release|x64
|
||||
{212AD910-8488-4036-BE20-326931B75FB2}.Release|x86.ActiveCfg = Release|x64
|
||||
{212AD910-8488-4036-BE20-326931B75FB2}.Release|x86.Build.0 = Release|x64
|
||||
{54A93AF7-60C7-4F6C-99D2-FBB1F75F853A}.Debug|ARM64.ActiveCfg = Debug|arm64
|
||||
{54A93AF7-60C7-4F6C-99D2-FBB1F75F853A}.Debug|ARM64.Build.0 = Debug|arm64
|
||||
{54A93AF7-60C7-4F6C-99D2-FBB1F75F853A}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{54A93AF7-60C7-4F6C-99D2-FBB1F75F853A}.Debug|x64.Build.0 = Debug|x64
|
||||
{54A93AF7-60C7-4F6C-99D2-FBB1F75F853A}.Debug|x86.ActiveCfg = Debug|x64
|
||||
{54A93AF7-60C7-4F6C-99D2-FBB1F75F853A}.Debug|x86.Build.0 = Debug|x64
|
||||
{54A93AF7-60C7-4F6C-99D2-FBB1F75F853A}.Release|ARM64.ActiveCfg = Release|arm64
|
||||
{54A93AF7-60C7-4F6C-99D2-FBB1F75F853A}.Release|ARM64.Build.0 = Release|arm64
|
||||
{54A93AF7-60C7-4F6C-99D2-FBB1F75F853A}.Release|x64.ActiveCfg = Release|x64
|
||||
{54A93AF7-60C7-4F6C-99D2-FBB1F75F853A}.Release|x64.Build.0 = Release|x64
|
||||
{54A93AF7-60C7-4F6C-99D2-FBB1F75F853A}.Release|x86.ActiveCfg = Release|x64
|
||||
{54A93AF7-60C7-4F6C-99D2-FBB1F75F853A}.Release|x86.Build.0 = Release|x64
|
||||
{92C39820-9F84-4529-BC7D-22AAE514D63B}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{92C39820-9F84-4529-BC7D-22AAE514D63B}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{92C39820-9F84-4529-BC7D-22AAE514D63B}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{92C39820-9F84-4529-BC7D-22AAE514D63B}.Debug|x64.Build.0 = Debug|x64
|
||||
{92C39820-9F84-4529-BC7D-22AAE514D63B}.Debug|x86.ActiveCfg = Debug|x64
|
||||
{92C39820-9F84-4529-BC7D-22AAE514D63B}.Debug|x86.Build.0 = Debug|x64
|
||||
{92C39820-9F84-4529-BC7D-22AAE514D63B}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{92C39820-9F84-4529-BC7D-22AAE514D63B}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{92C39820-9F84-4529-BC7D-22AAE514D63B}.Release|x64.ActiveCfg = Release|x64
|
||||
{92C39820-9F84-4529-BC7D-22AAE514D63B}.Release|x64.Build.0 = Release|x64
|
||||
{92C39820-9F84-4529-BC7D-22AAE514D63B}.Release|x86.ActiveCfg = Release|x64
|
||||
{92C39820-9F84-4529-BC7D-22AAE514D63B}.Release|x86.Build.0 = Release|x64
|
||||
{515554D1-D004-4F7F-A107-2211FC0F6B2C}.Debug|ARM64.ActiveCfg = Debug|arm64
|
||||
{515554D1-D004-4F7F-A107-2211FC0F6B2C}.Debug|ARM64.Build.0 = Debug|arm64
|
||||
{515554D1-D004-4F7F-A107-2211FC0F6B2C}.Debug|ARM64.Deploy.0 = Debug|arm64
|
||||
{515554D1-D004-4F7F-A107-2211FC0F6B2C}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{515554D1-D004-4F7F-A107-2211FC0F6B2C}.Debug|x64.Build.0 = Debug|x64
|
||||
{515554D1-D004-4F7F-A107-2211FC0F6B2C}.Debug|x64.Deploy.0 = Debug|x64
|
||||
{515554D1-D004-4F7F-A107-2211FC0F6B2C}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{515554D1-D004-4F7F-A107-2211FC0F6B2C}.Debug|x86.Build.0 = Debug|x86
|
||||
{515554D1-D004-4F7F-A107-2211FC0F6B2C}.Debug|x86.Deploy.0 = Debug|x86
|
||||
{515554D1-D004-4F7F-A107-2211FC0F6B2C}.Release|ARM64.ActiveCfg = Release|arm64
|
||||
{515554D1-D004-4F7F-A107-2211FC0F6B2C}.Release|ARM64.Build.0 = Release|arm64
|
||||
{515554D1-D004-4F7F-A107-2211FC0F6B2C}.Release|ARM64.Deploy.0 = Release|arm64
|
||||
{515554D1-D004-4F7F-A107-2211FC0F6B2C}.Release|x64.ActiveCfg = Release|x64
|
||||
{515554D1-D004-4F7F-A107-2211FC0F6B2C}.Release|x64.Build.0 = Release|x64
|
||||
{515554D1-D004-4F7F-A107-2211FC0F6B2C}.Release|x64.Deploy.0 = Release|x64
|
||||
{515554D1-D004-4F7F-A107-2211FC0F6B2C}.Release|x86.ActiveCfg = Release|x86
|
||||
{515554D1-D004-4F7F-A107-2211FC0F6B2C}.Release|x86.Build.0 = Release|x86
|
||||
{515554D1-D004-4F7F-A107-2211FC0F6B2C}.Release|x86.Deploy.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -1770,6 +1928,19 @@ Global
|
||||
{5A1DB2F0-0715-4B3B-98E6-79BC41540045} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{93B72A06-C8BD-484F-A6F7-C9F280B150BF} = {6C7F47CC-2151-44A3-A546-41C70025132C}
|
||||
{18B3DB45-4FFE-4D01-97D6-5223FEEE1853} = {6C7F47CC-2151-44A3-A546-41C70025132C}
|
||||
{0F14491C-6369-4C45-AAA8-135814E66E6B} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{34A354C5-23C7-4343-916C-C52DAF4FC39D} = {0F14491C-6369-4C45-AAA8-135814E66E6B}
|
||||
{7B4CDB0D-28C9-4F95-88AA-73FCC06E354C} = {0F14491C-6369-4C45-AAA8-135814E66E6B}
|
||||
{3264DF53-C805-4B0C-867C-FCEAF7AEF762} = {0F14491C-6369-4C45-AAA8-135814E66E6B}
|
||||
{31CAD28E-778A-441C-85BC-40AB3EAA2A10} = {0F14491C-6369-4C45-AAA8-135814E66E6B}
|
||||
{A50C70A6-2DA0-4027-B90E-B1A40755A8A5} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{25C91A4E-BA4E-467A-85CD-8B62545BF674} = {A50C70A6-2DA0-4027-B90E-B1A40755A8A5}
|
||||
{6AB6A2D6-F859-4A82-9184-0BD29C9F07D1} = {A50C70A6-2DA0-4027-B90E-B1A40755A8A5}
|
||||
{212AD910-8488-4036-BE20-326931B75FB2} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{7AC943C9-52E8-44CF-9083-744D8049667B} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{54A93AF7-60C7-4F6C-99D2-FBB1F75F853A} = {7AC943C9-52E8-44CF-9083-744D8049667B}
|
||||
{92C39820-9F84-4529-BC7D-22AAE514D63B} = {7AC943C9-52E8-44CF-9083-744D8049667B}
|
||||
{515554D1-D004-4F7F-A107-2211FC0F6B2C} = {7AC943C9-52E8-44CF-9083-744D8049667B}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0}
|
||||
|
||||
133
README.md
133
README.md
@@ -26,18 +26,18 @@ Microsoft PowerToys is a set of utilities for power users to tune and streamline
|
||||
|
||||
### Requirements
|
||||
|
||||
- Windows 11 or Windows 10 v1903 (18362) or newer.
|
||||
- Windows 11 or Windows 10 version 2004 (code name 20H1 / build number 19041) or newer.
|
||||
- Our installer will install the following items:
|
||||
- [.NET 6.0.5 Desktop Runtime](https://dotnet.microsoft.com/download/dotnet/6.0#runtime-desktop-6.0.5) or a newer 6.0.x runtime.
|
||||
- [Microsoft Edge WebView2 Runtime](https://go.microsoft.com/fwlink/p/?LinkId=2124703) bootstrapper. This will install the latest version.
|
||||
- [.NET 6.0.7 Desktop Runtime](https://dotnet.microsoft.com/download/dotnet/6.0#runtime-desktop-6.0.7) or a newer 6.0.x runtime.
|
||||
- [Microsoft Edge WebView2 Runtime](https://go.microsoft.com/fwlink/p/?LinkId=2124703) bootstrapper. This will install the latest version.
|
||||
- [Microsoft Visual C++ Redistributable](https://docs.microsoft.com/cpp/windows/latest-supported-vc-redist?view=msvc-170#visual-studio-2015-2017-2019-and-2022) installer. This will install one of the latest versions available.
|
||||
|
||||
### 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. Please use the appropriate the PowerToys installer that matches your machine's architecture. For most people, it is `x64`.
|
||||
|
||||
- **For x64 processors (most common):** click on `PowerToysSetup-0.59.1-x64.exe`
|
||||
- **For ARM64 processors:** `PowerToysSetup-0.59.1-arm64.exe`
|
||||
- **For x64 processors (most common):** [PowerToysSetup-0.61.1-x64.exe](https://github.com/microsoft/PowerToys/releases/download/v0.61.1/PowerToysSetup-0.61.1-x64.exe)
|
||||
- **For ARM64 processors:** [PowerToysSetup-0.61.1-arm64.exe](https://github.com/microsoft/PowerToys/releases/download/v0.61.1/PowerToysSetup-0.61.1-arm64.exe)
|
||||
|
||||
This is our preferred method.
|
||||
|
||||
@@ -72,116 +72,91 @@ 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.59 - May 2022 Update
|
||||
### 0.61 - July 2022 Update
|
||||
|
||||
In this release, we focused on wrapping up building for native ARM64 and releasing the first experimental build. Below are some of the highlights!
|
||||
This is a lighter release, with a shorter development cycle and focused on stability and improvements.
|
||||
|
||||
**Highlights**
|
||||
|
||||
- The work for running natively on ARM64 has been wrapped up and a build is released. Thanks [@snickler](https://github.com/snickler)!
|
||||
- Power Rename now is running on WinUI 3.
|
||||
- Keyboard Manager now allows up to 4 modifier keys for shortcuts and has received some quality fixes.
|
||||
- Upgraded the Windows App SDK runtimes to 1.1.0, fixing an issue where Settings wouldn't start with UAC off and improving performance.
|
||||
- The Windows App SDK runtime binaries are being shipped with PowerToys which should resolve the installations issues reported with WinAppSDK.
|
||||
- Quality of life improvements for Always on Top, FancyZones and PowerToys Run.
|
||||
|
||||
### Known issues
|
||||
- There are reports of users who are [unable to open the Settings window](https://github.com/microsoft/PowerToys/issues/18015). This is being caused by incompatibilities with some applications (RTSS RivaTuner Statistics Server and MSI AfterBurner are known examples of this). If you're affected by this, please check the linked issue to verify if any of the presented solutions works for you.
|
||||
- After installing PowerToys, [the new Windows 11 context menu entries for PowerRename and Image Resizer might not appear before a system restart](https://github.com/microsoft/PowerToys/issues/19124).
|
||||
- There are reports of users who are [unable to open the Settings window](https://github.com/microsoft/PowerToys/issues/18015). This is being caused by incompatibilities with some applications (RTSS RivaTuner Statistics Server and MSI AfterBurner are known examples of this). If you're affected by this, please check the linked issue to verify if any of the presented solutions works for you.
|
||||
|
||||
### General
|
||||
|
||||
- Some typos were fixed. Thanks [@eltociear](https://github.com/eltociear), [@rcmaehl](https://github.com/rcmaehl) and [@ShyPixie](https://github.com/ShyPixie)!
|
||||
|
||||
### ARM64
|
||||
|
||||
- ARM64 support now fully added!
|
||||
- Fixed PowerRename to work on ARM64.
|
||||
- Fixed File Explorer tools to work on ARM64.
|
||||
- Made changes for the installer projects to build ARM64 installers.
|
||||
- Configured the CI and Release pipelines to build for ARM64.
|
||||
- Added ARM64 build status to the README.
|
||||
- Upgraded the Windows App SDK runtimes to 1.1.4.
|
||||
- The new Windows 11 context menu entries are now correctly added to Windows 11 dev channel insider builds. (This was a hotfix for 0.60)
|
||||
- The old context menu entries are shown alongside the new Windows 11 context menu entries to be compatible with software that overrides the Windows 11 context menu behavior. (This was a hotfix for 0.60)
|
||||
- Consolidated C# language version across the solution. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
|
||||
- Removed deprecated Segoe icon glyph codes and replaced them with the correct ones. Thanks [@niels9001](https://github.com/niels9001) and [@Jay-o-Way](https://github.com/Jay-o-Way)!
|
||||
- Fixed an issue that caused a random accent key to be pressed on certain keyboard layouts when enabling some modules.
|
||||
|
||||
### Always on Top
|
||||
|
||||
- Fixed an issue where the borders where sticking around when a window was minimized with Win+D.
|
||||
- Fixed border flickering when activating. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
|
||||
- Fixed a bug causing Always on Top to activate and hang when exiting PowerToys. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
|
||||
- Fixed black edges appearing on rounded corners.
|
||||
- Fixed a bug that was causing 100% CPU consumption.
|
||||
|
||||
### FancyZones
|
||||
|
||||
- Fixed a bug that was consuming CPU cycles when the default layout was set.
|
||||
- Fixed a bug where apps were not opened in their last known zones due to Virtual Desktop ID changes.
|
||||
- Fixed a bug that was snapping popup menus opened by applications.
|
||||
- Fixed a bug causing windows not to be snapped under some configurations.
|
||||
- Fixed a bug that caused layouts to not be applied correctly when many monitors reported having the same serial number. (This was a hotfix for 0.60)
|
||||
- Fixed a bug that caused layouts to not be applied correctly on some virtual monitor setups (This was a hotfix for 0.60)
|
||||
- A "Rows" default layout is now applied to vertical monitors, instead of a "Columns" layout. Thanks [@augustkarlstedt](https://github.com/augustkarlstedt)!
|
||||
|
||||
### Image Resizer
|
||||
|
||||
- No longer tries to change metadata on files that were not actually resized. Thanks [@adamchilders](https://github.com/adamchilders)!
|
||||
- Screen reader now announces the size name instead of the class name.
|
||||
|
||||
### File explorer add-ons
|
||||
|
||||
- Fixed a bug where modules depending on WebView2 would be limited to opening files smaller than 2 MB. Now the resulting html is generated into a temporary file before presenting it.
|
||||
- Add a viewBox attribute to svg files that don't have one so that the preview tries to show the whole image.
|
||||
- Remove scrollbar that was showing when rendering svg thumbnails.
|
||||
- Fixed an issue when creating thumbnails for SVG files created using Inkscape.
|
||||
|
||||
### Keyboard Manager
|
||||
|
||||
- Now up to four modifier keys can be used in shortcuts. This will allow you to use the Office key (which sends Win+Ctrl+Shift+Alt), for example.
|
||||
- Fixed a bug locking Keyboard Manager when two shortcut mapping were pressed at the same time.
|
||||
- Removed event spam for certain telemetry events.
|
||||
- Adjusted wording on the editor when keys are orphaned.
|
||||
|
||||
### Mouse utility
|
||||
|
||||
- Fixed a bug that caused the current Find My Mouse spotlight to hang when activated in the top left corner of the screen. (This was a hotfix for 0.60)
|
||||
|
||||
### PowerRename
|
||||
|
||||
- Ported to use WinUI 3 instead of WinUI 2.
|
||||
- The PowerRename window reacts to current dpi when created.
|
||||
|
||||
### PowerToys Run
|
||||
|
||||
- The Services plugin is able to search for parts of the name, display name or the service type or state. Thanks [@htcfreek](https://github.com/htcfreek)!
|
||||
- The Services plugin now supports the startup type 'Automatic (Delayed Autostart)'. Thanks [@htcfreek](https://github.com/htcfreek)!
|
||||
- The Services plugin now has tooltips for large service names and other UI improvements. Thanks [@htcfreek](https://github.com/htcfreek)!
|
||||
- The TimeDate plugin gave results for queries containing just numbers on global queries. This has been fixed. Thanks [@htcfreek](https://github.com/htcfreek)!
|
||||
- We've introduced a throttle before a query is done to ensure typing is done to increase performance. Thanks [@shandsj](https://github.com/shandsj)!
|
||||
- Fixed a crash in WebSearch when there's an empty pattern setup for the system's default browser.
|
||||
- Fixed a bug where VSCodeWorkspaces was not finding portable installations of VSCode. Thanks [@harvastum](https://github.com/harvastum)!
|
||||
- The Calculator plugin reacts better to invalid input and internal errors. Thanks [@htcfreek](https://github.com/htcfreek)!
|
||||
- The Calculator plugin can now be configured to use the US number format instead of the system one. Thanks [@htcfreek](https://github.com/htcfreek)!
|
||||
- The Folder plugin supports paths containing "/". Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
|
||||
- Fixed a typo in the WindowWalker plugin UI. Thanks [@rohanrdy](https://github.com/rohanrdy)!
|
||||
- Improved performance by saving the search history files only on exit. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
|
||||
- PowerToys Run no longer shows results for some plugins when querying for empty spaces in a global query. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
|
||||
- Added support for showing localized names for some win32 programs in the programs plugin. Thanks [@htcfreek](https://github.com/htcfreek)!
|
||||
- The program plugin will now consider settings changed directly in ProgramPluginSettings.json. Thanks [@bezgumption](https://github.com/bezgumption)!
|
||||
|
||||
### Settings
|
||||
|
||||
- Now the UI for adding excluded apps for FindMyMouse is disabled when the module is disabled. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
|
||||
- Text was improved in the Settings UI for File Explorer. Thanks [@Jay-o-Way](https://github.com/Jay-o-Way)!
|
||||
- Settings won't try to launch if everything runs elevated in the machine, and a warning message is shown instead.
|
||||
- Some minor UI fixes. Thanks [@niels9001](https://github.com/niels9001)!
|
||||
- The Settings screen should now open correctly if the OOBE screen was opened first.
|
||||
- The rounded corner settings for FancyZones now only show on Windows 11. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
|
||||
- Fixed a UI freeze when entering the Keyboard Manager page with clean settings.
|
||||
- Fixed a UI glitch where a message was being shown that all PowerToys Run plugins were disabled when using the search function. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
|
||||
- Upgraded the Windows App SDK runtimes to 1.1.0, fixing an issue where Settings wouldn't start with UAC off and improving performance.
|
||||
|
||||
### Runner
|
||||
|
||||
- Auto-update takes into account if it's running on x64 or arm64 to download the right installer.
|
||||
- PowerToys Run settings page properly greys out the score adjustment setting when a plugin is not global. Thanks [@jefflord](https://github.com/jefflord)!
|
||||
- PowerToys Run plugins score adjustment field accepts only numeric characters. Thanks [@jefflord](https://github.com/jefflord)!
|
||||
- Will not run if started directly from its executable, as it was before the WinUI 3 upgrade.
|
||||
- Fixed a typo in a PowerToys Run settings page description. Thanks [@eltociear](https://github.com/eltociear)!
|
||||
|
||||
### Installer
|
||||
|
||||
- Updated the .NET dependency to 6.0.5.
|
||||
- The installer is now built using a beta version of Wix 3.14 for arm64 support.
|
||||
- Added the VC++ Redistributable binary as a requirement.
|
||||
- The Windows App SDK runtime binaries are being shipped with PowerToys instead of running its installer. This should fix most of the install issues with 0.58.
|
||||
- Removed the dead code to make a msix installer.
|
||||
- Updated the .NET dependency to 6.0.7.
|
||||
- Won't create a new PowerToys shortcut on update if it's been removed manually by the user.
|
||||
|
||||
### Development
|
||||
|
||||
- New action added to GitHub to publish the winget package to PowerToys.
|
||||
- New action added to GitHub to publish for the Microsoft Store. Thanks [azchohfi](https://github.com/azchohfi)!
|
||||
- Documentation for installing the Windows App SDK dependencies and building the installer was updated.
|
||||
- FxCop removed from the PowerToys Run TimeZone plugin and was replaced with NetAnalyzers. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
|
||||
- Updated the Windows Store Package submission script to show less UI while installing PowerToys. (This was a hotfix for 0.60)
|
||||
- Added more functionality to the Monitor Report Tool.
|
||||
- The release CI now includes the version number in the symbols artifacts.
|
||||
- GitHub should now show .vsconfig as a JSON file. Thanks [@osfanbuff63](https://github.com/osfanbuff63)!
|
||||
- Centralized the configurations for NetAnalyzers and StyleCop. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
|
||||
- Check-spelling has been upgraded to version 0.0.20. Thanks [@jsoref](https://github.com/jsoref)!
|
||||
|
||||
#### Community contributions
|
||||
#### What is being planned for v0.62
|
||||
|
||||
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), [@CleanCodeDeveloper](https://github.com/CleanCodeDeveloper), [@davidegiacometti](https://github.com/davidegiacometti), [@dend](https://github.com/dend), [@franky920920](https://github.com/franky920920), [@htcfreek](https://github.com/htcfreek), [@jay-o-way](https://github.com/jay-o-way), [@jsoref](https://github.com/jsoref), [@niels9001](https://github.com/niels9001), [@snickler](https://github.com/snickler).
|
||||
|
||||
#### What is being planned for v0.60
|
||||
|
||||
For [v0.60][github-next-release-work], we'll work on below:
|
||||
For [v0.62][github-next-release-work], we'll work on below:
|
||||
|
||||
- Environment Variables Editor PowerToy
|
||||
- Screen Measure PowerToy
|
||||
@@ -189,7 +164,7 @@ For [v0.60][github-next-release-work], we'll work on below:
|
||||
|
||||
## PowerToys Community
|
||||
|
||||
The PowerToys team is extremely grateful to have the [support of an amazing active community][community-link]. The work you do is incredibly important. PowerToys wouldn’t be nearly what it is today without your help filing bugs, updating documentation, guiding the design, or writing features. We want to say thank you and take time to recognize your work.
|
||||
The PowerToys team is extremely grateful to have the [support of an amazing active community][community-link]. The work you do is incredibly important. PowerToys wouldn’t be nearly what it is today without your help filing bugs, updating documentation, guiding the design, or writing features. We want to say thank you and take time to recognize your work. Month over month, you directly help make PowerToys a better piece of software.
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
@@ -212,5 +187,5 @@ The application logs basic telemetry. Our Telemetry Data page (Coming Soon) has
|
||||
[usingPowerToys-docs-link]: https://aka.ms/powertoys-docs
|
||||
|
||||
<!-- 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%2F33
|
||||
[github-current-release-work]: https://github.com/microsoft/PowerToys/issues?q=is%3Aopen+is%3Aissue+project%3Amicrosoft%2FPowerToys%2F32
|
||||
[github-next-release-work]: https://github.com/microsoft/PowerToys/issues?q=is%3Aopen+is%3Aissue+project%3Amicrosoft%2FPowerToys%2F35
|
||||
[github-current-release-work]: https://github.com/microsoft/PowerToys/issues?q=is%3Aopen+is%3Aissue+project%3Amicrosoft%2FPowerToys%2F34
|
||||
|
||||
2
deps/expected-lite
vendored
2
deps/expected-lite
vendored
Submodule deps/expected-lite updated: 076e96f683...95b9cb015f
@@ -2,7 +2,6 @@
|
||||
- [ ] 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
|
||||
|
||||
103
doc/devdocs/modules/launcher/plugins/history.md
Normal file
103
doc/devdocs/modules/launcher/plugins/history.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# History Plugin
|
||||
|
||||
The History Plugin allows users to search or display results they have used (selected).
|
||||
|
||||
## How it works
|
||||
The plugin uses data that was already being captured which is, what results were clicked, and how many times. We do add a little more data to this set now.
|
||||
When this plugin is queried, it creates results based on this previously selected results data.
|
||||
|
||||
In order to make sure selected results in the history are still valid, we re-query the plugin the relevant plug using the PluginManager. If there are no results,
|
||||
this history item is not included. This usually means that the result is no longer valid. For instance, if a file was deleted, but it's still in the selected history
|
||||
we don't want to show it as a selectable result.
|
||||
|
||||
Because the results from the History Plugin are actually created from calls to the PluginManager, they will be exactly the same is if they did not come from the History Plugin.
|
||||
|
||||
## Special notes
|
||||
While the results returned from the plugin are from the PluginManager, they are sometimes modified before returning. One example is the Calculator plugin.
|
||||
Since the Calculator plugin operates on the current query input by the user, the results from Calculator plugin don't include that in the title. However, as a history item,
|
||||
the query is very important. In this case, and maybe others in the future, we modify the tile to also include the search.
|
||||
|
||||
### Modified title example:
|
||||
|
||||
This is what the Calculator plugin normally might show:
|
||||

|
||||
|
||||
But this is how it will look returned from the History plugin
|
||||
|
||||

|
||||
|
||||
As you can see, here and maybe other places, other non-history plugin might be able to include extra data for the History plugin to use later.
|
||||
For example, in future, plugins might be able to also set a "History Title", "History Icon", etc... But for now, it's not needed.
|
||||
|
||||
|
||||
## Duplicates from the History Plugin in global results
|
||||
If the History plugin is set to show in the global results, it might return a result that is also returned from another plugin. If a match is found,
|
||||
the result from the history plugin is discarded.
|
||||
|
||||
## Removing items from history
|
||||
A new context menu item is added to each History result, which can be used to delete it from the history.
|
||||

|
||||
|
||||
## Context menus
|
||||
Because these results are coming from the History plugin, this plugin must invoke each menu items `LoadContextMenus` method.
|
||||
We then also add the "Remove this from history" context menu action.
|
||||
|
||||
## Results score
|
||||
When the plugin is used with the activation command, the scores are configured so the results show with the more recently selected items at the top.
|
||||
If the history results are shown in the global results, the scores are not modified from that the original plugin set.
|
||||
|
||||
## Old Data
|
||||
Items selected before this plugin was created will not show in the history because they don't contain enough data.
|
||||
|
||||
## Important for developers
|
||||
|
||||
### Important plugin values (meta-data)
|
||||
|
||||
| Name | Value |
|
||||
| --------------- | ---------------------------------------------------- |
|
||||
| ActionKeyword | `!!` |
|
||||
| ExecuteFileName | `Microsoft.PowerToys.Run.Plugin.History.dll` |
|
||||
| ID | `C88512156BB74580AADF7252E130BA8D` |
|
||||
|
||||
### Interfaces used by this plugin
|
||||
|
||||
The plugin uses only these interfaces (all inside the `Main.cs`):
|
||||
|
||||
* `Wox.Plugin.IPlugin`
|
||||
* `Wox.Plugin.IContextMenu`
|
||||
* `Wox.Plugin.IPluginI18n`
|
||||
|
||||
### Program files
|
||||
|
||||
| File | Content |
|
||||
| ------------------------------------- | ----------------------------------------------------------------------- |
|
||||
| `Images\history.dark.png` | Symbol for the results for the dark theme |
|
||||
| `Images\history.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 contains all translatable strings in the neutral language |
|
||||
| `Main.cs` | Main class, the only place that implements the WOX interfaces |
|
||||
| `ErrorHandler.cs` | Class to build error result on plugin failure |
|
||||
| `plugin.json` | All meta-data for this plugin |
|
||||
|
||||
### Important project values (*.csproj)
|
||||
|
||||
| Name | Value |
|
||||
| --------------- | ------------------------------------------------- |
|
||||
| TargetFramework | `net6.0-windows10.0.19041.0` |
|
||||
|
||||
### Project dependencies
|
||||
|
||||
#### Projects
|
||||
|
||||
* `Wox.Infrastructure`
|
||||
* `Wox.Plugin`
|
||||
* `PowerToys.PowerLauncher`
|
||||
|
||||
|
||||
#### Build Dependency
|
||||
Access to PluginManager was needed to make this plugin work. Because of this a reference to PowerToys.PowerLauncher was needed.
|
||||
Since History Plugin needs a reference to PowerToys.PowerLauncher, it can not be set as a dependency reference in PowerToys.PowerLauncher project (else a circular reference would exist).
|
||||
This means that if you build PowerToys.PowerLauncher only it will not build History Plugin. You will need to manually build History Plugin at least once and again manually if you change it.
|
||||
|
||||
### Caching
|
||||
Right now, there is no caching. But since this plugin does cause more queries than expected to many plugins, the `BuildResult` method is likely to be improved with some level of caching.
|
||||
@@ -1,7 +1,7 @@
|
||||
# OneNote Plugin
|
||||
The OneNote plugin searches your locally synced OneNote notebooks based on the user query.
|
||||
|
||||

|
||||

|
||||
|
||||
The code itself is very simple, basically just a call into OneNote interop via the https://github.com/scipbe/ScipBe-Common-Office library.
|
||||
|
||||
|
||||
@@ -69,10 +69,8 @@ The plugin use only these interfaces (all inside the `Main.cs`):
|
||||
| `Images\reg.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) |
|
||||
|
||||
### Important project values (*.csproj)
|
||||
|
||||
@@ -88,13 +86,6 @@ The plugin use only these interfaces (all inside the `Main.cs`):
|
||||
|
||||
### Project dependencies
|
||||
|
||||
#### Packages
|
||||
|
||||
| Package | Version |
|
||||
| ------------------------------------------------------------------------------------- | ------- |
|
||||
| [`Microsoft.CodeAnalysis.FxCopAnalyzers`](https://github.com/dotnet/roslyn-analyzers) | 3.3.0 |
|
||||
| [`StyleCop.Analyzers`](https://github.com/DotNetAnalyzers/StyleCopAnalyzers) | 1.1.118 |
|
||||
|
||||
#### Projects
|
||||
|
||||
* `Wox.Infrastructure`
|
||||
|
||||
@@ -115,13 +115,10 @@ The plugin use only these interfaces (all inside the `Main.cs`):
|
||||
| `Images\timeZone.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) |
|
||||
| `timezones.json` | File that contains all time zone information |
|
||||
| `timeZones.schema.json` | JSON schema for `timezones.json` |
|
||||
| `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.
|
||||
@@ -138,12 +135,6 @@ Because the JSON file must have a object as root type, instead of a array.
|
||||
|
||||
### Project dependencies
|
||||
|
||||
#### Packages
|
||||
|
||||
| Package | Version |
|
||||
| ------------------------------------------------------------------------------------- | ------- |
|
||||
| [`StyleCop.Analyzers`](https://github.com/DotNetAnalyzers/StyleCopAnalyzers) | 1.1.118 |
|
||||
|
||||
#### Projects
|
||||
|
||||
* `Wox.Infrastructure`
|
||||
|
||||
@@ -129,10 +129,8 @@ The plugin use only these interfaces (all inside the `Main.cs`):
|
||||
| `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.
|
||||
@@ -149,12 +147,6 @@ Because the JSON file must have a object as root type, instead of a array.
|
||||
|
||||
### Project dependencies
|
||||
|
||||
#### Packages
|
||||
|
||||
| Package | Version |
|
||||
| ------------------------------------------------------------------------------------- | ------- |
|
||||
| [`StyleCop.Analyzers`](https://github.com/DotNetAnalyzers/StyleCopAnalyzers) | 1.1.118 |
|
||||
|
||||
#### Projects
|
||||
|
||||
* `Wox.Infrastructure`
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
<PackagingLayout xmlns="http://schemas.microsoft.com/appx/makeappx/2017">
|
||||
<PackageFamily ID="PowerToys" FlatBundle="true" ManifestPath="appxmanifest.xml" ResourceManager="false">
|
||||
|
||||
<Package ID="PowerToys-x64" ProcessorArchitecture="x64">
|
||||
<Files>
|
||||
<File DestinationPath="License.rtf" SourcePath="..\License.rtf"/>
|
||||
|
||||
<File DestinationPath="action_runner.exe" SourcePath="..\..\x64\Release\action_runner.exe"/>
|
||||
<File DestinationPath="PowerToys.exe" SourcePath="..\..\x64\Release\PowerToys.exe"/>
|
||||
<File DestinationPath="PowerToysSettings.exe" SourcePath="..\..\x64\Release\PowerToysSettings.exe"/>
|
||||
|
||||
<File DestinationPath="modules\PowerToys.FancyZonesEditor.exe" SourcePath="..\..\x64\Release\modules\PowerToys.FancyZonesEditor.exe"/>
|
||||
<File DestinationPath="modules\ControlzEx.dll" SourcePath="..\..\x64\Release\modules\ControlzEx.dll"/>
|
||||
<File DestinationPath="modules\fancyzones.dll" SourcePath="..\..\x64\Release\modules\fancyzones.dll"/>
|
||||
<File DestinationPath="modules\MahApps.Metro.dll" SourcePath="..\..\x64\Release\modules\MahApps.Metro.dll"/>
|
||||
<File DestinationPath="modules\Microsoft.Xaml.Behaviors.dll" SourcePath="..\..\x64\Release\modules\Microsoft.Xaml.Behaviors.dll"/>
|
||||
<File DestinationPath="modules\PowerToys.PowerRenameExt.dll" SourcePath="..\..\x64\Release\modules\PowerToys.PowerRenameExt.dll"/>
|
||||
<File DestinationPath="modules\shortcut_guide.dll" SourcePath="..\..\x64\Release\modules\shortcut_guide.dll"/>
|
||||
<File DestinationPath="modules\PowerToys.ImageResizer.exe" SourcePath="..\..\x64\Release\modules\PowerToys.ImageResizer.exe"/>
|
||||
<File DestinationPath="modules\PowerToys.ImageResizerExt.dll" SourcePath="..\..\x64\Release\modules\PowerToys.ImageResizerExt.dll"/>
|
||||
<File DestinationPath="modules\GalaSoft.MvvmLight.dll" SourcePath="..\..\x64\Release\modules\GalaSoft.MvvmLight.dll"/>
|
||||
<File DestinationPath="modules\GalaSoft.MvvmLight.Platform.dll" SourcePath="..\..\x64\Release\modules\GalaSoft.MvvmLight.Platform.dll"/>
|
||||
<File DestinationPath="modules\GalaSoft.MvvmLight.Extras.dll" SourcePath="..\..\x64\Release\modules\GalaSoft.MvvmLight.Extras.dll"/>
|
||||
<File DestinationPath="modules\System.Windows.Interactivity.dll" SourcePath="..\..\x64\Release\modules\System.Windows.Interactivity.dll"/>
|
||||
<File DestinationPath="modules\Newtonsoft.Json.dll" SourcePath="..\..\x64\Release\modules\Newtonsoft.Json.dll"/>
|
||||
<File DestinationPath="modules\PowerKeys.dll" SourcePath="..\..\x64\Release\modules\PowerKeys.dll"/>
|
||||
<File DestinationPath="modules\System.Text.Json.dll" SourcePath="..\..\x64\Release\modules\System.Text.Json.dll"/>
|
||||
<File DestinationPath="modules\System.Management.dll" SourcePath="..\..\x64\Release\modules\System.Management.dll"/>
|
||||
<File DestinationPath="modules\System.Memory.dll" SourcePath="..\..\x64\Release\modules\System.Memory.dll"/>
|
||||
<File DestinationPath="modules\System.Buffers.dll" SourcePath="..\..\x64\Release\modules\System.Buffers.dll"/>
|
||||
<File DestinationPath="modules\System.Runtime.CompilerServices.Unsafe.dll" SourcePath="..\..\x64\Release\modules\System.Runtime.CompilerServices.Unsafe.dll"/>
|
||||
<File DestinationPath="modules\System.Text.Encodings.Web.dll" SourcePath="..\..\x64\Release\modules\System.Text.Encodings.Web.dll"/>
|
||||
<File DestinationPath="modules\System.Threading.Tasks.Extensions.dll" SourcePath="..\..\x64\Release\modules\System.Threading.Tasks.Extensions.dll"/>
|
||||
<File DestinationPath="modules\System.ValueTuple.dll" SourcePath="..\..\x64\Release\modules\System.ValueTuple.dll"/>
|
||||
<File DestinationPath="modules\System.Numerics.Vectors.dll" SourcePath="..\..\x64\Release\modules\System.Numerics.Vectors.dll"/>
|
||||
<File DestinationPath="modules\Microsoft.Bcl.AsyncInterfaces.dll" SourcePath="..\..\x64\Release\modules\Microsoft.Bcl.AsyncInterfaces.dll"/>
|
||||
<File DestinationPath="modules\Microsoft.Win32.Registry.dll" SourcePath="..\..\x64\Release\modules\Microsoft.Win32.Registry.dll"/>
|
||||
<File DestinationPath="modules\PowerToys.powerpreview.dll" SourcePath="..\..\x64\Release\modules\PowerToys.powerpreview.dll"/>
|
||||
<File DestinationPath="modules\PowerToys.PreviewHandlerCommon.dll" SourcePath="..\..\x64\Release\modules\PowerToys.PreviewHandlerCommon.dll"/>
|
||||
<File DestinationPath="modules\PowerToys.SvgPreviewHandler.dll" SourcePath="..\..\x64\Release\modules\PowerToys.SvgPreviewHandler.dll"/>
|
||||
<File DestinationPath="modules\PowerToys.MarkdownPreviewHandler.dll" SourcePath="..\..\x64\Release\modules\PowerToys.MarkdownPreviewHandler.dll"/>
|
||||
<File DestinationPath="modules\PowerToys.GcodePreviewHandler.dll" SourcePath="..\..\x64\Release\modules\PowerToys.GcodePreviewHandler.dll"/>
|
||||
<File DestinationPath="modules\Markdig.Signed.dll" SourcePath="..\..\x64\Release\modules\Markdig.Signed.dll"/>
|
||||
<File DestinationPath="modules\HtmlAgilityPack.dll" SourcePath="..\..\x64\Release\modules\HtmlAgilityPack.dll"/>
|
||||
<File DestinationPath="registry.dat" SourcePath="registry.dat"/>
|
||||
|
||||
<File DestinationPath="modules\PowerToys.FancyZonesEditor.exe.config" SourcePath="..\..\x64\Release\modules\PowerToys.FancyZonesEditor.exe.config"/>
|
||||
|
||||
<File DestinationPath="Notifications.dll" SourcePath="..\..\x64\Release\Notifications.dll"/>
|
||||
|
||||
<File DestinationPath="svgs\*" SourcePath="..\..\x64\Release\svgs\*"/>
|
||||
<File DestinationPath="settings-html\**" SourcePath="..\..\x64\Release\settings-html\**"/>
|
||||
<File DestinationPath="Images\*.png" SourcePath="Images\*.png"/>
|
||||
|
||||
<!-- Resource files for ar,bg,ca,cs,de,es,eu-ES,fr,he,hu,it,nb-NO,nl,pl,pt-BR,ru,sk,tr,zh-Hans -->
|
||||
<File DestinationPath="modules\ar\**" SourcePath="..\..\x64\Release\modules\ar\**"/>
|
||||
<File DestinationPath="modules\bg\**" SourcePath="..\..\x64\Release\modules\bg\**"/>
|
||||
<File DestinationPath="modules\ca\**" SourcePath="..\..\x64\Release\modules\ca\**"/>
|
||||
<File DestinationPath="modules\cs\**" SourcePath="..\..\x64\Release\modules\cs\**"/>
|
||||
<File DestinationPath="modules\de\**" SourcePath="..\..\x64\Release\modules\de\**"/>
|
||||
<File DestinationPath="modules\es\**" SourcePath="..\..\x64\Release\modules\es\**"/>
|
||||
<File DestinationPath="modules\eu-ES\**" SourcePath="..\..\x64\Release\modules\eu-ES\**"/>
|
||||
<File DestinationPath="modules\fr\**" SourcePath="..\..\x64\Release\modules\fr\**"/>
|
||||
<File DestinationPath="modules\he\**" SourcePath="..\..\x64\Release\modules\he\**"/>
|
||||
<File DestinationPath="modules\hu\**" SourcePath="..\..\x64\Release\modules\hu\**"/>
|
||||
<File DestinationPath="modules\it\**" SourcePath="..\..\x64\Release\modules\it\**"/>
|
||||
<File DestinationPath="modules\nb-NO\**" SourcePath="..\..\x64\Release\modules\nb-NO\**"/>
|
||||
<File DestinationPath="modules\nl\**" SourcePath="..\..\x64\Release\modules\nl\**"/>
|
||||
<File DestinationPath="modules\pl\**" SourcePath="..\..\x64\Release\modules\pl\**"/>
|
||||
<File DestinationPath="modules\pt-BR\**" SourcePath="..\..\x64\Release\modules\pt-BR\**"/>
|
||||
<File DestinationPath="modules\ru\**" SourcePath="..\..\x64\Release\modules\ru\**"/>
|
||||
<File DestinationPath="modules\sk\**" SourcePath="..\..\x64\Release\modules\sk\**"/>
|
||||
<File DestinationPath="modules\tr\**" SourcePath="..\..\x64\Release\modules\tr\**"/>
|
||||
<File DestinationPath="modules\zh-Hans\**" SourcePath="..\..\x64\Release\modules\zh-Hans\**"/>
|
||||
</Files>
|
||||
</Package>
|
||||
</PackageFamily>
|
||||
</PackagingLayout>
|
||||
@@ -1,121 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
|
||||
xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"
|
||||
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
|
||||
xmlns:uap2="http://schemas.microsoft.com/appx/manifest/uap/windows10/2"
|
||||
xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
|
||||
xmlns:uap5="http://schemas.microsoft.com/appx/manifest/uap/windows10/5"
|
||||
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
|
||||
xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
|
||||
xmlns:desktop2="http://schemas.microsoft.com/appx/manifest/desktop/windows10/2"
|
||||
xmlns:desktop4="http://schemas.microsoft.com/appx/manifest/desktop/windows10/4"
|
||||
xmlns:desktop5="http://schemas.microsoft.com/appx/manifest/desktop/windows10/5" IgnorableNamespaces="desktop4">
|
||||
<Identity Name="Microsoft.PowerToys" Version="0.15.2.0" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" ProcessorArchitecture="x64" />
|
||||
<Properties>
|
||||
<DisplayName>PowerToys</DisplayName>
|
||||
<PublisherDisplayName>Microsoft Corporation</PublisherDisplayName>
|
||||
<Description>Windows system utilities to maximize productivity</Description>
|
||||
<Logo>Images\logo.png</Logo>
|
||||
</Properties>
|
||||
<Resources>
|
||||
<Resource Language="en-us" />
|
||||
</Resources>
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.0" MaxVersionTested="10.0.18362.30" />
|
||||
</Dependencies>
|
||||
<Capabilities>
|
||||
<rescap:Capability Name="runFullTrust"/>
|
||||
<rescap:Capability Name="allowElevation"/>
|
||||
</Capabilities>
|
||||
<Applications>
|
||||
<Application Id="PowerToys" Executable="PowerToys.exe" EntryPoint="Windows.FullTrustApplication">
|
||||
<uap:VisualElements DisplayName="PowerToys (Experimental)" Description="Windows system utilities to maximize productivity" Square150x150Logo="Images\logo150.png" Square44x44Logo="Images\logo44.png" BackgroundColor="transparent" />
|
||||
<Extensions>
|
||||
<uap:Extension Category="windows.protocol">
|
||||
<uap:Protocol Name="powertoys">
|
||||
<uap:Logo>images\logo.png</uap:Logo>
|
||||
<uap:DisplayName>Powertoys custom protocol</uap:DisplayName>
|
||||
</uap:Protocol>
|
||||
</uap:Extension>
|
||||
<uap5:Extension Category="windows.startupTask" Executable="PowerToys.exe" EntryPoint="Windows.FullTrustApplication">
|
||||
<uap5:StartupTask TaskId="PowerToysStartupTaskID" Enabled="true" DisplayName="PowerToys" />
|
||||
</uap5:Extension>
|
||||
<com:Extension Category="windows.comServer">
|
||||
<com:ComServer>
|
||||
<com:SurrogateServer DisplayName="ImageResizerExt">
|
||||
<com:Class Id="51B4D7E5-7568-4234-B4BB-47FB3C016A69" Path="modules\PowerToys.ImageResizerExt.dll" ThreadingModel="STA"/>
|
||||
</com:SurrogateServer>
|
||||
</com:ComServer>
|
||||
</com:Extension>
|
||||
<desktop4:Extension Category="windows.fileExplorerContextMenus">
|
||||
<desktop4:FileExplorerContextMenus>
|
||||
<desktop4:ItemType Type="*">
|
||||
<desktop4:Verb Id="FilePowerRename" Clsid="0440049F-D1DC-4E46-B27B-98393D79486B" />
|
||||
</desktop4:ItemType>
|
||||
<desktop5:ItemType Type="Directory">
|
||||
<desktop5:Verb Id="DirectoryPowerRename" Clsid="0440049F-D1DC-4E46-B27B-98393D79486B" />
|
||||
</desktop5:ItemType>
|
||||
<desktop4:ItemType Type="*">
|
||||
<desktop4:Verb Id="ImageResizer" Clsid="51B4D7E5-7568-4234-B4BB-47FB3C016A69" />
|
||||
</desktop4:ItemType>
|
||||
</desktop4:FileExplorerContextMenus>
|
||||
</desktop4:Extension>
|
||||
<uap:Extension Category="windows.fileTypeAssociation">
|
||||
<uap3:FileTypeAssociation Name="mdpreviewhandler" desktop2:AllowSilentDefaultTakeOver="true">
|
||||
<uap:SupportedFileTypes>
|
||||
<uap:FileType>.md</uap:FileType>
|
||||
</uap:SupportedFileTypes>
|
||||
<desktop2:DesktopPreviewHandler Clsid="E0907A95-6F9A-4D1B-A97A-7D9D2648881E"/>
|
||||
</uap3:FileTypeAssociation>
|
||||
</uap:Extension>
|
||||
<uap:Extension Category="windows.fileTypeAssociation">
|
||||
<uap3:FileTypeAssociation Name="svgpreviewhandler" desktop2:AllowSilentDefaultTakeOver="true">
|
||||
<uap:SupportedFileTypes>
|
||||
<uap:FileType>.svg</uap:FileType>
|
||||
</uap:SupportedFileTypes>
|
||||
<desktop2:DesktopPreviewHandler Clsid="74619BDA-A66B-451D-864C-A7726F5FE650"/>
|
||||
</uap3:FileTypeAssociation>
|
||||
</uap:Extension>
|
||||
<uap:Extension Category="windows.fileTypeAssociation">
|
||||
<uap3:FileTypeAssociation Name="pdfpreviewhandler" desktop2:AllowSilentDefaultTakeOver="true">
|
||||
<uap:SupportedFileTypes>
|
||||
<uap:FileType>.pdf</uap:FileType>
|
||||
</uap:SupportedFileTypes>
|
||||
<desktop2:DesktopPreviewHandler Clsid="4F6D533B-4185-43A6-AD75-9B20034B14CA"/>
|
||||
</uap3:FileTypeAssociation>
|
||||
</uap:Extension>
|
||||
<uap:Extension Category="windows.fileTypeAssociation">
|
||||
<uap3:FileTypeAssociation Name="gcodepreviewhandler" desktop2:AllowSilentDefaultTakeOver="true">
|
||||
<uap:SupportedFileTypes>
|
||||
<uap:FileType>.gcode</uap:FileType>
|
||||
</uap:SupportedFileTypes>
|
||||
<desktop2:DesktopPreviewHandler Clsid="516CB24F-562F-422F-8B01-6B580474D093"/>
|
||||
</uap3:FileTypeAssociation>
|
||||
</uap:Extension>
|
||||
<com:Extension Category="windows.comServer">
|
||||
<com:ComServer>
|
||||
<com:SurrogateServer DisplayName="Preview Handler" AppId="E39A92FE-D89A-417B-9B9D-F0B6BD564B36" SystemSurrogate="PreviewHost">
|
||||
<com:Class Id="74619BDA-A66B-451D-864C-A7726F5FE650" Path="modules\PowerToys.powerpreview.dll" ThreadingModel="Both"/>
|
||||
<com:Class Id="E0907A95-6F9A-4D1B-A97A-7D9D2648881E" Path="modules\PowerToys.powerpreview.dll" ThreadingModel="Both"/>
|
||||
<com:Class Id="4F6D533B-4185-43A6-AD75-9B20034B14CA" Path="modules\PowerToys.powerpreview.dll" ThreadingModel="Both"/>
|
||||
<com:Class Id="516CB24F-562F-422F-8B01-6B580474D093" Path="modules\PowerToys.powerpreview.dll" ThreadingModel="Both"/>
|
||||
</com:SurrogateServer>
|
||||
</com:ComServer>
|
||||
</com:Extension>
|
||||
<Extension Category="windows.backgroundTasks" EntryPoint="PowerToysNotifications.BackgroundHandler">
|
||||
<BackgroundTasks>
|
||||
<Task Type="general" />
|
||||
</BackgroundTasks>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</Application>
|
||||
</Applications>
|
||||
<Extensions>
|
||||
<Extension Category="windows.activatableClass.inProcessServer">
|
||||
<InProcessServer>
|
||||
<Path>Notifications.dll</Path>
|
||||
<ActivatableClass ActivatableClassId="PowerToysNotifications.BackgroundHandler" ThreadingModel="both"/>
|
||||
</InProcessServer>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</Package>
|
||||
@@ -1,13 +0,0 @@
|
||||
param (
|
||||
[bool]$debug = 0
|
||||
)
|
||||
|
||||
$PackagingLayoutFile = "PackagingLayout.xml"
|
||||
|
||||
if ($debug) {
|
||||
(Get-Content $PackagingLayoutFile) `
|
||||
-replace 'x64\\Release\\', 'x64\Debug\' `
|
||||
| Out-File -Encoding utf8 "$env:temp\$PackagingLayoutFile"
|
||||
$PackagingLayoutFile = "$env:temp\$PackagingLayoutFile"
|
||||
}
|
||||
makeappx build /v /overwrite /f $PackagingLayoutFile /id "PowerToys-x64" /op bin\
|
||||
@@ -1,14 +0,0 @@
|
||||
cd /D "%~dp0"
|
||||
|
||||
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64 -winsdk=10.0.19041.0
|
||||
|
||||
powershell -file update_appxmanifest_version.ps1 || exit /b 1
|
||||
|
||||
call makeappx build /v /overwrite /f PackagingLayout.xml /id "PowerToys-x64" /op bin\ || exit /b 1
|
||||
|
||||
setlocal EnableDelayedExpansion
|
||||
for /f "tokens=3delims=<>" %%i in ('findstr "<Version>" "..\Version.props"') do (
|
||||
set MSIXVERSION=%%i
|
||||
)
|
||||
setlocal DisableDelayedExpansion
|
||||
ren "bin\PowerToys-x64.msix" PowerToysSetup-%MSIXVERSION%-x64.msix
|
||||
@@ -1,5 +0,0 @@
|
||||
$expirationDate = {Get-Date}.Invoke().AddYears(5)
|
||||
$pass = ConvertTo-SecureString -String "12345" -Force -AsPlainText
|
||||
$thumbprint = (New-SelfSignedCertificate -notafter $expirationDate -Type CodeSigningCert -Subject "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" -FriendlyName "PowerToys Test Certificate" -KeyDescription "PowerToys Test Certificate" -KeyFriendlyName "PowerToys Test Key" -KeyUsage "DigitalSignature" -CertStoreLocation Cert:\LocalMachine\My).Thumbprint
|
||||
Export-PfxCertificate -Cert cert:\LocalMachine\My\$thumbprint -FilePath PowerToys_TemporaryKey.pfx -Password $pass
|
||||
Import-PfxCertificate -CertStoreLocation Cert:\LocalMachine\Root -FilePath PowerToys_TemporaryKey.pfx -Password $pass
|
||||
@@ -1 +0,0 @@
|
||||
Add-AppxPackage .\bin\PowerToys.msixbundle
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,5 +0,0 @@
|
||||
.\uninstall_msix.ps1
|
||||
.\build_msix.ps1
|
||||
.\sign_msix.ps1
|
||||
.\install_msix.ps1
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
signtool sign /debug /a /fd SHA256 /f PowerToys_TemporaryKey.pfx /p 12345 bin\PowerToys-x64.msix
|
||||
signtool sign /debug /a /fd SHA256 /f PowerToys_TemporaryKey.pfx /p 12345 bin\PowerToys.msixbundle
|
||||
@@ -1 +0,0 @@
|
||||
Get-AppxPackage -Name '*PowerToys' | select -ExpandProperty "PackageFullName" | Remove-AppxPackage
|
||||
@@ -1,5 +0,0 @@
|
||||
$version = ([xml](Get-Content ..\Version.props)).Project.PropertyGroup.Version
|
||||
|
||||
(Get-Content appxmanifest.xml) `
|
||||
-replace '(Name="[\.\w]+"\sVersion=")([\d\.]+)"', -join('${1}', $version, '.0"') `
|
||||
| Out-File -Encoding utf8 appxmanifest.xml
|
||||
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
@@ -6,9 +6,9 @@
|
||||
<?define BinDir="$(var.RepoDir)$(var.Platform)\$(var.Configuration)\" ?>
|
||||
<?define PowerToysPlatform="x64"?>
|
||||
|
||||
<?define Dotnet6DownloadUrl="https://download.visualstudio.microsoft.com/download/pr/9d6b6b34-44b5-4cf4-b924-79a00deb9795/2f17c30bdf42b6a8950a8552438cf8c1/windowsdesktop-runtime-6.0.6-win-x64.exe"?>
|
||||
<?define Dotnet6PayloadSize="57665648"?>
|
||||
<?define Dotnet6PayloadHash="06E76968E4CE87C77F34AE5AFA6D63B0DEDFE6D2"?>
|
||||
<?define Dotnet6DownloadUrl="https://download.visualstudio.microsoft.com/download/pr/dc0e0e83-0115-4518-8b6a-590ed594f38a/65b63e41f6a80decb37fa3c5af79a53d/windowsdesktop-runtime-6.0.7-win-x64.exe"?>
|
||||
<?define Dotnet6PayloadSize="57708544"?>
|
||||
<?define Dotnet6PayloadHash="16DDD34B1E1AEA0D89D3B0A8786026436CD17234"?>
|
||||
|
||||
<?define VCRedistDownloadUrl="https://download.visualstudio.microsoft.com/download/pr/ed95ef9e-da02-4735-9064-bd1f7f69b6ed/CE6593A1520591E7DEA2B93FD03116E3FC3B3821A0525322B0A430FAA6B3C0B4/VC_redist.x64.exe"?>
|
||||
<?define VCRedistPayloadSize="25234792"?>
|
||||
@@ -20,9 +20,9 @@
|
||||
<?define BinDir="$(var.RepoDir)ARM64\$(var.Configuration)\" ?>
|
||||
<?define PowerToysPlatform="ARM64"?>
|
||||
|
||||
<?define Dotnet6DownloadUrl="https://download.visualstudio.microsoft.com/download/pr/d09acad2-0abb-4ec8-8388-b8b42b31cd58/517cff2da8fbcdcb514bb4e2f1dc8879/windowsdesktop-runtime-6.0.6-win-arm64.exe"?>
|
||||
<?define Dotnet6PayloadSize="51535984"?>
|
||||
<?define Dotnet6PayloadHash="599CF13A1B0E3F1C2DBC2FE6210062C3795094A7"?>
|
||||
<?define Dotnet6DownloadUrl="https://download.visualstudio.microsoft.com/download/pr/f33cf7ce-bf03-428c-8aa7-e32ef6d7ddc6/e61dc60fce686844c41ec2901ad5b01e/windowsdesktop-runtime-6.0.7-win-arm64.exe"?>
|
||||
<?define Dotnet6PayloadSize="51539968"?>
|
||||
<?define Dotnet6PayloadHash="F98232B9B572848B8425462F9458E92710BBF55F"?>
|
||||
|
||||
<?define VCRedistDownloadUrl="https://download.visualstudio.microsoft.com/download/pr/ed95ef9e-da02-4735-9064-bd1f7f69b6ed/8E126191012691AE22A0D5A89FAC01B59BABC7B680E5D9B65828935FD366E375/VC_redist.arm64.exe"?>
|
||||
<?define VCRedistPayloadSize="11500416"?>
|
||||
@@ -44,12 +44,12 @@
|
||||
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense">
|
||||
<bal:WixStandardBootstrapperApplication
|
||||
LicenseFile="$(var.RepoDir)\installer\License.rtf"
|
||||
LogoFile="$(var.RepoDir)\installer\MSIX\Images\logo44.png"
|
||||
LogoFile="$(var.RepoDir)\installer\PowerToysSetup\Images\logo44.png"
|
||||
SuppressOptionsUI="no"
|
||||
SuppressRepair="yes" />
|
||||
</BootstrapperApplicationRef>
|
||||
|
||||
<util:FileSearch Variable="HasDotnet606" Path="$(var.PlatformProgramFiles)dotnet\shared\Microsoft.WindowsDesktop.App\6.0.6\System.Xaml.dll" Result="exists" />
|
||||
<util:FileSearch Variable="HasDotnet607" Path="$(var.PlatformProgramFiles)dotnet\shared\Microsoft.WindowsDesktop.App\6.0.7\System.Xaml.dll" Result="exists" />
|
||||
<util:RegistrySearch Variable="HasWebView2PerMachine" Root="HKLM" Key="SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" Result="exists" />
|
||||
<util:RegistrySearch Variable="HasWebView2PerUser" Root="HKCU" Key="Software\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" Result="exists" />
|
||||
|
||||
@@ -73,10 +73,10 @@
|
||||
|
||||
<Chain>
|
||||
<ExePackage
|
||||
Name="windowsdesktop-runtime-6.0.6-win-$(var.PowerToysPlatform).exe"
|
||||
Name="windowsdesktop-runtime-6.0.7-win-$(var.PowerToysPlatform).exe"
|
||||
Compressed="no"
|
||||
Id="DotnetRuntime6"
|
||||
DetectCondition="HasDotnet606"
|
||||
DetectCondition="HasDotnet607"
|
||||
DownloadUrl="$(var.Dotnet6DownloadUrl)"
|
||||
InstallCommand="/install /quiet /norestart"
|
||||
RepairCommand="/repair /passive /norestart"
|
||||
@@ -85,10 +85,10 @@
|
||||
UninstallCommand="/uninstall /quiet /norestart">
|
||||
<ExitCode Value="1638" Behavior="success"/>
|
||||
<RemotePayload
|
||||
Description="Microsoft Windows Desktop Runtime - 6.0.6 ($(var.PowerToysPlatform))"
|
||||
ProductName="Microsoft Windows Desktop Runtime - 6.0.6 ($(var.PowerToysPlatform))"
|
||||
Description="Microsoft Windows Desktop Runtime - 6.0.7 ($(var.PowerToysPlatform))"
|
||||
ProductName="Microsoft Windows Desktop Runtime - 6.0.7 ($(var.PowerToysPlatform))"
|
||||
Size="$(var.Dotnet6PayloadSize)"
|
||||
Version="6.0.6.31318"
|
||||
Version="6.0.7.31422"
|
||||
Hash="$(var.Dotnet6PayloadHash)" />
|
||||
</ExePackage>
|
||||
<ExePackage
|
||||
|
||||
@@ -6,12 +6,15 @@
|
||||
<?define FancyZonesProjectName="FancyZones"?>
|
||||
<?define ImageResizerProjectName="ImageResizer"?>
|
||||
<?define KeyboardManagerProjectName="KeyboardManager"?>
|
||||
<?define PowerAccentProjectName="PowerAccent"?>
|
||||
<?define PowerRenameProjectName="PowerRename"?>
|
||||
<?define ColorPickerProjectName="ColorPicker"?>
|
||||
<?define PowerOCRProjectName="PowerOCR"?>
|
||||
<?define VideoConferenceProjectName="VideoConference"?>
|
||||
<?define AwakeProjectName="Awake"?>
|
||||
<?define MouseUtilsProjectName="MouseUtils"?>
|
||||
<?define AlwaysOnTopProjectName="AlwaysOnTop"?>
|
||||
<?define MeasureToolProjectName="MeasureTool"?>
|
||||
|
||||
<?define RepoDir="$(var.ProjectDir)..\..\" ?>
|
||||
<?if $(var.Platform) = x64?>
|
||||
@@ -48,11 +51,11 @@
|
||||
|
||||
<?define SettingsV2Files=Ijwhost.dll;ColorCode.Core.dll;ColorCode.WinUI.dll;CommunityToolkit.Common.dll;CommunityToolkit.WinUI.dll;CommunityToolkit.WinUI.UI.Controls.Core.dll;CommunityToolkit.WinUI.UI.Controls.DataGrid.dll;CommunityToolkit.WinUI.UI.Controls.Input.dll;CommunityToolkit.WinUI.UI.Controls.Layout.dll;CommunityToolkit.WinUI.UI.Controls.Markdown.dll;CommunityToolkit.WinUI.UI.Controls.Media.dll;CommunityToolkit.WinUI.UI.Controls.Primitives.dll;CommunityToolkit.WinUI.UI.dll;icon.ico;Microsoft.Graphics.Canvas.Interop.dll;Microsoft.InteractiveExperiences.Projection.dll;Microsoft.Windows.ApplicationModel.DynamicDependency.Projection.dll;Microsoft.Windows.ApplicationModel.Resources.Projection.dll;Microsoft.Windows.ApplicationModel.WindowsAppRuntime.Projection.dll;Microsoft.Windows.AppLifecycle.Projection.dll;Microsoft.Windows.SDK.NET.dll;Microsoft.Windows.System.Power.Projection.dll;Microsoft.WindowsAppRuntime.Bootstrap.Net.dll;Microsoft.WinUI.dll;Microsoft.Xaml.Interactions.dll;Microsoft.Xaml.Interactivity.dll;PowerToys.Interop.dll;PowerToys.ManagedCommon.dll;System.Management.dll;PowerToys.ManagedTelemetry.dll;PowerToys.Settings.deps.json;PowerToys.Settings.dll;PowerToys.Settings.exe;PowerToys.Settings.runtimeconfig.json;PowerToys.Settings.UI.Lib.dll;resources.pri;System.IO.Abstractions.dll;System.Text.Json.dll;WinRT.Runtime.dll;Microsoft.Graphics.Canvas.dll;Microsoft.WindowsAppRuntime.Bootstrap.dll;CoreMessagingXP.dll;dcompi.dll;dwmcorei.dll;DwmSceneI.dll;DWriteCore.dll;marshal.dll;Microsoft.DirectManipulation.dll;Microsoft.InputStateManager.dll;Microsoft.Internal.FrameworkUdk.dll;Microsoft.UI.Composition.OSSupport.dll;Microsoft.UI.Input.dll;Microsoft.UI.Windowing.Core.dll;Microsoft.UI.Xaml.Controls.dll;Microsoft.UI.Xaml.Controls.pri;Microsoft.ui.xaml.dll;Microsoft.UI.Xaml.Internal.dll;Microsoft.UI.Xaml.Phone.dll;Microsoft.ui.xaml.resources.19h1.dll;Microsoft.ui.xaml.resources.common.dll;Microsoft.Web.WebView2.Core.dll;Microsoft.Windows.ApplicationModel.Resources.dll;Microsoft.Windows.AppNotifications.Projection.dll;Microsoft.Windows.PushNotifications.Projection.dll;Microsoft.Windows.System.Projection.dll;Microsoft.WindowsAppRuntime.dll;Microsoft.WindowsAppRuntime.Insights.Resource.dll;Microsoft.WindowsAppRuntime.Release.Net.dll;MRM.dll;PushNotificationsLongRunningTask.ProxyStub.dll;WindowsAppRuntime.png;WindowsAppSdk.AppxDeploymentExtensions.Desktop.dll;WinUIEdit.dll;wuceffectsi.dll?>
|
||||
|
||||
<?define SettingsV2AssetsModulesFiles=ColorPicker.png;FancyZones.png;AlwaysOnTop.png;Awake.png;ImageResizer.png;KBM.png;MouseUtils.png;PowerLauncher.png;PowerPreview.png;PowerRename.png;PT.png;ShortcutGuide.png;VideoConference.png?>
|
||||
<?define SettingsV2AssetsModulesFiles=ColorPicker.png;FancyZones.png;AlwaysOnTop.png;Awake.png;ImageResizer.png;KBM.png;MouseUtils.png;PowerAccent.png;PowerOCR.png;PowerLauncher.png;PowerPreview.png;PowerRename.png;PT.png;ScreenRuler.png;ShortcutGuide.png;VideoConference.png?>
|
||||
|
||||
<?define SettingsV2OOBEAssetsModulesFiles=ColorPicker.gif;AlwaysOnTop.png;Awake.png;FancyZones.gif;FileExplorer.png;ImageResizer.gif;KBM.gif;MouseUtils.gif;PowerRename.gif;Run.gif;OOBEShortcutGuide.png;VideoConferenceMute.png;OOBEPTHero.png?>
|
||||
<?define SettingsV2OOBEAssetsModulesFiles=ColorPicker.gif;AlwaysOnTop.png;Awake.png;FancyZones.gif;FileExplorer.png;ImageResizer.gif;KBM.gif;MouseUtils.gif;PowerAccent.gif;PowerOCR.gif;PowerRename.gif;Run.gif;ScreenRuler.gif;OOBEShortcutGuide.png;VideoConferenceMute.png;OOBEPTHero.png?>
|
||||
|
||||
<?define SettingsV2OOBEAssetsFluentIconsFiles=ColorPicker.png;FancyZones.png;AlwaysOnTop.png;Awake.png;FileExplorerPreview.png;FindMyMouse.png;ImageResizer.png;KeyboardManager.png;MouseHighlighter.png;MouseCrosshairs.png;MouseUtils.png;PowerRename.png;PowerToys.png;PowerToysRun.png;Settings.png;ShortcutGuide.png;VideoConferenceMute.png?>
|
||||
<?define SettingsV2OOBEAssetsFluentIconsFiles=ColorPicker.png;FancyZones.png;AlwaysOnTop.png;Awake.png;FileExplorerPreview.png;FindMyMouse.png;ImageResizer.png;KeyboardManager.png;MouseHighlighter.png;MouseCrosshairs.png;MouseUtils.png;PowerAccent.png;PowerOcr.png;PowerRename.png;PowerToys.png;PowerToysRun.png;ScreenRuler.png;Settings.png;ShortcutGuide.png;VideoConferenceMute.png?>
|
||||
|
||||
<?define SettingsV2MicrosoftUIXamlAssetsInstallFiles=NoiseAsset_256x256_PNG.png?>
|
||||
|
||||
@@ -70,6 +73,8 @@
|
||||
|
||||
<?define ShellComponentFiles=plugin.json;Microsoft.Plugin.Shell.deps.json;Microsoft.Plugin.Shell.dll;PowerToys.ManagedTelemetry.dll?>
|
||||
|
||||
<?define HistoryPluginComponentFiles=plugin.json;Microsoft.PowerToys.Run.Plugin.History.deps.json;Microsoft.PowerToys.Run.Plugin.History.dll?>
|
||||
|
||||
<?define ShellImagesComponentFiles=shell.light.png;shell.dark.png;user.light.png;user.dark.png?>
|
||||
|
||||
<?define IndexerComponentFiles=Microsoft.Plugin.Indexer.deps.json;Microsoft.Plugin.Indexer.dll;plugin.json;PowerToys.ManagedTelemetry.dll;Ijwhost.dll?>
|
||||
@@ -114,8 +119,13 @@
|
||||
|
||||
<?define ImageResizerSparsePackageAssets=LargeTile.png;SmallTile.png;SplashScreen.png;Square150x150Logo.png;Square44x44Logo.png;storelogo.png;Wide310x150Logo.png?>
|
||||
|
||||
<?define MeasureToolFiles=CoreMessagingXP.dll;dcompi.dll;dwmcorei.dll;DwmSceneI.dll;DWriteCore.dll;marshal.dll;Microsoft.DirectManipulation.dll;Microsoft.InputStateManager.dll;Microsoft.InteractiveExperiences.Projection.dll;Microsoft.Internal.FrameworkUdk.dll;Microsoft.UI.Composition.OSSupport.dll;Microsoft.UI.Input.dll;Microsoft.UI.Windowing.Core.dll;Microsoft.UI.Xaml.Controls.dll;Microsoft.UI.Xaml.Controls.pri;Microsoft.ui.xaml.dll;Microsoft.UI.Xaml.Internal.dll;Microsoft.UI.Xaml.Phone.dll;Microsoft.ui.xaml.resources.19h1.dll;Microsoft.ui.xaml.resources.common.dll;Microsoft.Web.WebView2.Core.dll;Microsoft.Windows.ApplicationModel.Resources.dll;Microsoft.Windows.ApplicationModel.WindowsAppRuntime.Projection.dll;Microsoft.Windows.AppLifecycle.Projection.dll;Microsoft.Windows.AppNotifications.Projection.dll;Microsoft.Windows.PushNotifications.Projection.dll;Microsoft.Windows.SDK.NET.dll;Microsoft.Windows.System.Projection.dll;Microsoft.WindowsAppRuntime.Bootstrap.dll;Microsoft.WindowsAppRuntime.Bootstrap.Net.dll;Microsoft.WindowsAppRuntime.dll;Microsoft.WindowsAppRuntime.Insights.Resource.dll;Microsoft.WindowsAppRuntime.Release.Net.dll;Microsoft.WinUI.dll;MRM.dll;PowerToys.ManagedCommon.dll;PowerToys.ManagedTelemetry.dll;PowerToys.MeasureToolCore.dll;PowerToys.MeasureToolUI.deps.json;PowerToys.MeasureToolUI.dll;PowerToys.MeasureToolUI.exe;PowerToys.MeasureToolUI.runtimeconfig.json;PushNotificationsLongRunningTask.ProxyStub.dll;resources.pri;System.CodeDom.dll;System.Management.dll;WindowsAppRuntime.png;WindowsAppSdk.AppxDeploymentExtensions.Desktop.dll;WinRT.Runtime.dll;WinUIEdit.dll;WinUIEx.dll;wuceffectsi.dll?>
|
||||
|
||||
|
||||
<?define PowerRenameMicrosoftUIXamlAssetsInstallFiles=NoiseAsset_256x256_PNG.png?>
|
||||
|
||||
<?define PowerAccentFiles=ControlzEx.dll;GongSolutions.WPF.DragDrop.dll;Ijwhost.dll;MahApps.Metro.dll;Microsoft.Xaml.Behaviors.dll;PowerAccent.Core.dll;PowerAccent.deps.json;PowerAccent.dll;PowerAccent.exe;PowerAccent.runtimeconfig.json;PowerToys.PowerAccentModuleInterface.dll;PowerToys.Interop.dll;PowerToys.ManagedCommon.dll;PowerToys.ManagedTelemetry.dll;PowerToys.PowerAccent.deps.json;PowerToys.PowerAccent.dll;PowerToys.PowerAccent.exe;PowerToys.PowerAccent.runtimeconfig.json;PowerToys.Settings.UI.Lib.dll;System.IO.Abstractions.dll;System.Management.dll;System.Text.Json.dll;Vanara.Core.dll;Vanara.PInvoke.Gdi32.dll;Vanara.PInvoke.Kernel32.dll;Vanara.PInvoke.Shared.dll;Vanara.PInvoke.User32.dll?>
|
||||
|
||||
<Product Id="*"
|
||||
Name="PowerToys (Preview)"
|
||||
Language="1033"
|
||||
@@ -409,6 +419,8 @@
|
||||
<Directory Id="ImageResizerInstallFolder" Name="$(var.ImageResizerProjectName)">
|
||||
<Directory Id="ImageResizerAssetsFolder" Name="Assets" />
|
||||
</Directory>
|
||||
<Directory Id="PowerAccentInstallFolder" Name="$(var.PowerAccentProjectName)">
|
||||
</Directory>
|
||||
<Directory Id="PowerRenameInstallFolder" Name="$(var.PowerRenameProjectName)">
|
||||
<Directory Id="PowerRenameAssetsFolder" Name="Assets" />
|
||||
<Directory Id="PowerRenameMicrosoftUIXamlInstallFolder" Name="Microsoft.UI.Xaml">
|
||||
@@ -429,6 +441,7 @@
|
||||
<Directory Id="MonacoPreviewHandlerMonacoSRCFolder" Name="monacoSRC" />
|
||||
</Directory>
|
||||
<Directory Id="FancyZonesInstallFolder" Name="$(var.FancyZonesProjectName)" />
|
||||
<Directory Id="PowerOCRInstallFolder" Name="$(var.PowerOCRProjectName)" />
|
||||
<Directory Id="AwakeInstallFolder" Name="$(var.AwakeProjectName)">
|
||||
<Directory Id="AwakeImagesFolder" Name="Images" />
|
||||
</Directory>
|
||||
@@ -452,6 +465,10 @@
|
||||
<Directory Id="AlwaysOnTopInstallFolder" Name="$(var.AlwaysOnTopProjectName)">
|
||||
</Directory>
|
||||
|
||||
<!-- MeasureTool -->
|
||||
<Directory Id="MeasureToolInstallFolder" Name="$(var.MeasureToolProjectName)">
|
||||
</Directory>
|
||||
|
||||
<!-- Launcher -->
|
||||
<Directory Id="LauncherInstallFolder" Name="launcher">
|
||||
<Directory Id="LauncherImagesFolder" Name="Images" />
|
||||
@@ -487,6 +504,10 @@
|
||||
<Directory Id="UriImagesFolder" Name="Images" />
|
||||
<Directory Id="UriLanguagesFolder" Name="Languages" />
|
||||
</Directory>
|
||||
<Directory Id="HistoryPluginFolder" Name="History">
|
||||
<Directory Id="HistoryImagesFolder" Name="Images" />
|
||||
<Directory Id="HistoryLanguagesFolder" Name="Languages" />
|
||||
</Directory>
|
||||
<Directory Id="UnitConverterPluginFolder" Name="UnitConverter">
|
||||
<Directory Id="UnitConverterImagesFolder" Name="Images" />
|
||||
<Directory Id="UnitConverterLanguagesFolder" Name="Languages" />
|
||||
@@ -746,6 +767,15 @@
|
||||
</Component>
|
||||
</DirectoryRef>
|
||||
|
||||
<!-- PowerAccent -->
|
||||
<DirectoryRef Id="PowerAccentInstallFolder" FileSource="$(var.BinDir)modules\$(var.PowerAccentProjectName)">
|
||||
<?foreach File in $(var.PowerAccentFiles)?>
|
||||
<Component Id="PowerAccent_$(var.File)" Win64="yes">
|
||||
<File Id="PowerAccentFile_$(var.File)" Source="$(var.BinDir)modules\$(var.PowerAccentProjectName)\$(var.File)" />
|
||||
</Component>
|
||||
<?endforeach?>
|
||||
</DirectoryRef>
|
||||
|
||||
<!-- PowerRename -->
|
||||
<DirectoryRef Id="PowerRenameInstallFolder" FileSource="$(var.BinDir)modules\$(var.PowerRenameProjectName)">
|
||||
<?foreach File in $(var.PowerRenameFiles)?>
|
||||
@@ -888,6 +918,16 @@
|
||||
</Component>
|
||||
</DirectoryRef>
|
||||
|
||||
<!-- PowerOCR Resources -->
|
||||
<DirectoryRef Id="PowerOCRInstallFolder" FileSource="$(var.BinDir)modules\$(var.PowerOCRProjectName)">
|
||||
<!-- !Warning! Make sure to change Component Guid if you update the file list -->
|
||||
<Component Id="Module_PowerOCR" Guid="5640A7E8-E165-4368-8F08-F8E1E9242BDD" Win64="yes">
|
||||
<?foreach File in PowerToys.PowerOCR.dll;ControlzEx.dll;Ijwhost.dll;Microsoft.Windows.SDK.NET.dll;Microsoft.Xaml.Behaviors.dll;PowerToys.Common.UI.dll;PowerToys.Interop.dll;PowerToys.ManagedCommon.dll;PowerToys.ManagedTelemetry.dll;PowerToys.PowerOCR.deps.json;PowerToys.PowerOCR.exe;PowerToys.PowerOCR.runtimeconfig.json;PowerToys.PowerOCRModuleInterface.dll;PowerToys.Settings.UI.Lib.dll;System.ComponentModel.Composition.dll;System.IO.Abstractions.dll;System.Management.dll;System.Text.Json.dll;WinRT.Runtime.dll?>
|
||||
<File Id="PowerOCRFile_$(var.File)" Source="$(var.BinDir)modules\$(var.PowerOCRProjectName)\$(var.File)" />
|
||||
<?endforeach?>
|
||||
</Component>
|
||||
</DirectoryRef>
|
||||
|
||||
<!-- Awake -->
|
||||
<DirectoryRef Id="AwakeInstallFolder" FileSource="$(var.BinDir)modules\$(var.AwakeProjectName)">
|
||||
<!-- !Warning! Make sure to change Component Guid if you update the file list -->
|
||||
@@ -929,6 +969,20 @@
|
||||
|
||||
</DirectoryRef>
|
||||
|
||||
<!-- Measure Tool -->
|
||||
<DirectoryRef Id="MeasureToolInstallFolder" FileSource="$(var.BinDir)modules\$(var.MeasureToolProjectName)">
|
||||
<Component Id="Module_MeasureToolInterface" Win64="yes">
|
||||
<File Source="$(var.BinDir)modules\$(var.MeasureToolProjectName)\PowerToys.MeasureToolModuleInterface.dll" />
|
||||
</Component>
|
||||
|
||||
<?foreach File in $(var.MeasureToolFiles)?>
|
||||
<Component Id="MEASURE_TOOL_$(var.File)" Win64="yes">
|
||||
<File Id="MEASURE_TOOL_$(var.File)" Source="$(var.BinDir)modules\$(var.MeasureToolProjectName)\$(var.File)" />
|
||||
</Component>
|
||||
<?endforeach?>
|
||||
|
||||
</DirectoryRef>
|
||||
|
||||
<!-- SettingsV2 components -->
|
||||
<DirectoryRef Id="SettingsV2InstallFolder" FileSource="$(var.BinDir)Settings\">
|
||||
<?foreach File in $(var.SettingsV2Files)?>
|
||||
@@ -1036,6 +1090,9 @@
|
||||
<?endforeach?>
|
||||
<ComponentRef Id="DesktopShortcut" />
|
||||
<ComponentRef Id="Module_PowerRename" />
|
||||
<?foreach File in $(var.PowerAccentFiles)?>
|
||||
<ComponentRef Id="PowerAccent_$(var.File)" />
|
||||
<?endforeach?>
|
||||
<?foreach File in $(var.PowerRenameFiles)?>
|
||||
<ComponentRef Id="PowerRename_$(var.File)" />
|
||||
<?endforeach?>
|
||||
@@ -1057,6 +1114,7 @@
|
||||
<ComponentRef Id="Module_KeyboardManager" />
|
||||
<ComponentRef Id="Module_KeyboardManager_Editor" />
|
||||
<ComponentRef Id="Module_KeyboardManager_Engine" />
|
||||
<ComponentRef Id="Module_PowerOCR" />
|
||||
<ComponentRef Id="Module_ColorPicker" />
|
||||
<ComponentRef Id="Module_ColorPicker_Icon"/>
|
||||
<ComponentRef Id="Module_ColorPicker_Cursor"/>
|
||||
@@ -1067,6 +1125,11 @@
|
||||
<ComponentRef Id="Module_MousePointerCrosshairs" />
|
||||
<ComponentRef Id="Module_AlwaysOnTop"/>
|
||||
<ComponentRef Id="Module_AlwaysOnTopInterface"/>
|
||||
<ComponentRef Id="Module_MeasureToolInterface"/>
|
||||
<?foreach File in $(var.MeasureToolFiles)?>
|
||||
<ComponentRef Id="MEASURE_TOOL_$(var.File)" />
|
||||
<?endforeach?>
|
||||
|
||||
<?foreach File in $(var.SettingsV2Files)?>
|
||||
<ComponentRef Id="SV2C_$(var.File)" />
|
||||
<?endforeach?>
|
||||
@@ -1105,7 +1168,7 @@
|
||||
<Fragment>
|
||||
<!-- Resource directories should be added only if the installer is built on the build farm -->
|
||||
<?ifdef env.IsPipeline?>
|
||||
<?foreach ParentDirectory in LauncherInstallFolder;FancyZonesInstallFolder;ImageResizerInstallFolder;ColorPickerInstallFolder;FileExplorerPreviewInstallFolder;CalculatorPluginFolder;FolderPluginFolder;ProgramPluginFolder;ShellPluginFolder;IndexerPluginFolder;UnitConverterPluginFolder;UriPluginFolder;WindowWalkerPluginFolder;OneNotePluginFolder;RegistryPluginFolder;VSCodeWorkspacesPluginFolder;ServicePluginFolder;SystemPluginFolder;TimeDatePluginFolder;TimeZonePluginFolder;WindowsSettingsPluginFolder;WindowsTerminalPluginFolder;WebSearchPluginFolder?>
|
||||
<?foreach ParentDirectory in LauncherInstallFolder;FancyZonesInstallFolder;ImageResizerInstallFolder;ColorPickerInstallFolder;FileExplorerPreviewInstallFolder;HistoryPluginFolder;CalculatorPluginFolder;FolderPluginFolder;ProgramPluginFolder;ShellPluginFolder;IndexerPluginFolder;UnitConverterPluginFolder;UriPluginFolder;WindowWalkerPluginFolder;OneNotePluginFolder;RegistryPluginFolder;VSCodeWorkspacesPluginFolder;ServicePluginFolder;SystemPluginFolder;TimeDatePluginFolder;TimeZonePluginFolder;WindowsSettingsPluginFolder;WindowsTerminalPluginFolder;WebSearchPluginFolder?>
|
||||
<DirectoryRef Id="$(var.ParentDirectory)">
|
||||
<!-- Resource file directories -->
|
||||
<?foreach Language in $(var.LocLanguageList)?>
|
||||
@@ -1391,6 +1454,18 @@
|
||||
Directory="Resource$(var.IdSafeLanguage)OneNotePluginFolder">
|
||||
<File Id="Launcher_OneNote_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)modules\launcher\Plugins\OneNote\$(var.Language)\Microsoft.PowerToys.Run.Plugin.OneNote.resources.dll" />
|
||||
</Component>
|
||||
<Component
|
||||
Id="MonacoPreviewHandler_$(var.IdSafeLanguage)_Component"
|
||||
Directory="Resource$(var.IdSafeLanguage)FileExplorerPreviewInstallFolder"
|
||||
Guid="$(var.CompGUIDPrefix)1A">
|
||||
<File Id="MonacoPreviewHandler_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)modules\FileExplorerPreview\$(var.Language)\PowerToys.MonacoPreviewHandler.resources.dll" />
|
||||
</Component>
|
||||
<Component
|
||||
Id="Launcher_History_$(var.IdSafeLanguage)_Component"
|
||||
Directory="Resource$(var.IdSafeLanguage)HistoryPluginFolder"
|
||||
Guid="$(var.CompGUIDPrefix)1B">
|
||||
<File Id="Launcher_History_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)modules\launcher\Plugins\History\$(var.Language)\Microsoft.PowerToys.Run.Plugin.History.resources.dll" />
|
||||
</Component>
|
||||
<?undef IdSafeLanguage?>
|
||||
<?undef CompGUIDPrefix?>
|
||||
<?endforeach?>
|
||||
@@ -1830,6 +1905,19 @@
|
||||
<File Id="WebSearchDark" Source="$(var.BinDir)modules\launcher\Plugins\WebSearch\Images\WebSearch.dark.png" />
|
||||
</Component>
|
||||
|
||||
<!-- History Plugin -->
|
||||
<?foreach File in $(var.HistoryPluginComponentFiles)?>
|
||||
<Component Id="HistoryComponent_$(var.File)" Win64="yes" Directory="HistoryPluginFolder">
|
||||
<File Id="HistoryComponentFile_$(var.File)" Source="$(var.BinDir)modules\launcher\Plugins\History\$(var.File)" />
|
||||
</Component>
|
||||
<?endforeach?>
|
||||
<Component Id="HistoryImagesComponentLight" Directory="HistoryImagesFolder" >
|
||||
<File Id="HistoryLightIcon" Source="$(var.BinDir)modules\launcher\Plugins\History\Images\history.light.png" />
|
||||
</Component>
|
||||
<Component Id="HistoryImagesComponentDark" Directory="HistoryImagesFolder" >
|
||||
<File Id="HistoryDarkIcon" Source="$(var.BinDir)modules\launcher\Plugins\History\Images\history.dark.png" />
|
||||
</Component>
|
||||
|
||||
<!-- Uri Plugin -->
|
||||
<?foreach File in $(var.UriComponentFiles)?>
|
||||
<Component Id="UriComponent_$(var.File)" Win64="yes" Directory="UriPluginFolder">
|
||||
|
||||
@@ -18,3 +18,5 @@ msbuild !PTRoot!\src\modules\previewpane\MarkdownPreviewHandler\MarkdownPreviewH
|
||||
msbuild !PTRoot!\src\modules\previewpane\SvgPreviewHandler\SvgPreviewHandler.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml
|
||||
|
||||
msbuild !PTRoot!\src\modules\previewpane\SvgThumbnailProvider\SvgThumbnailProvider.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml
|
||||
|
||||
msbuild !PTRoot!\src\modules\MeasureTool\MeasureToolUI\MeasureToolUI.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include <windows.h>
|
||||
#include "resource.h"
|
||||
#include "../../src/common/version/version.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
@@ -12,6 +14,39 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
1 VERSIONINFO
|
||||
FILEVERSION FILE_VERSION
|
||||
PRODUCTVERSION PRODUCT_VERSION
|
||||
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS VS_FF_DEBUG
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS VOS_NT_WINDOWS32
|
||||
FILETYPE VFT_DLL
|
||||
FILESUBTYPE VFT2_UNKNOWN
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0" // US English (0x0409), Unicode (0x04B0) charset
|
||||
BEGIN
|
||||
VALUE "CompanyName", COMPANY_NAME
|
||||
VALUE "FileDescription", FILE_DESCRIPTION
|
||||
VALUE "FileVersion", FILE_VERSION_STRING
|
||||
VALUE "InternalName", INTERNAL_NAME
|
||||
VALUE "LegalCopyright", COPYRIGHT_NOTE
|
||||
VALUE "OriginalFilename", ORIGINAL_FILENAME
|
||||
VALUE "ProductName", PRODUCT_NAME
|
||||
VALUE "ProductVersion", PRODUCT_VERSION_STRING
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200 // US English (0x0409), Unicode (1200) charset
|
||||
END
|
||||
END
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (United States) resources
|
||||
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by Resource.rc
|
||||
|
||||
#define FILE_DESCRIPTION "PowerToys Setup Custom Actions"
|
||||
#define INTERNAL_NAME "PowerToysSetupCustomActions"
|
||||
#define ORIGINAL_FILENAME "PowerToysSetupCustomActions.dll"
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
|
||||
@@ -170,29 +170,6 @@ bool InstallNewVersionStage2(std::wstring installer_path, std::wstring_view inst
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& entry : fs::directory_iterator(updating::get_pending_updates_path()))
|
||||
{
|
||||
auto entryPath = entry.path().wstring();
|
||||
std::transform(entryPath.begin(), entryPath.end(), entryPath.begin(), ::towlower);
|
||||
|
||||
// Delete only .msi and .exe
|
||||
if (entryPath.ends_with(L".msi") || entryPath.ends_with(L".exe"))
|
||||
{
|
||||
// Skipping current installer in case of failed update
|
||||
if (installer_path.find(entryPath) != std::string::npos && !success)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
std::error_code err;
|
||||
fs::remove(entry, err);
|
||||
if (err.value())
|
||||
{
|
||||
Logger::warn("Failed to delete file {}. {}", entry.path().string(), err.message());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!success)
|
||||
{
|
||||
return false;
|
||||
|
||||
@@ -50,7 +50,7 @@ using System.Diagnostics.CodeAnalysis;
|
||||
[assembly: SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Windows.Documents.InlineCollection.Add(System.String)", Scope = "member", Target = "Microsoft.Templates.UI.Extensions.TextBlockExtensions.#OnSequentialFlowStepChanged(System.Windows.DependencyObject,System.Windows.DependencyPropertyChangedEventArgs)", Justification = "No text here")]
|
||||
[assembly: SuppressMessage("Globalization", "CA1309:Use ordinal string comparison", Justification = "The user's search term should be compared with culture based rules.", Scope = "type", Target = "~T:Microsoft.PowerToys.Run.Plugin.TimeDate.Components.SearchController")]
|
||||
|
||||
// FxCop warning suppression for uninstantiated TestFixture classes
|
||||
// Uninstantiated TestFixture classes
|
||||
[assembly: SuppressMessage("Microsoft.Performance", "CA1812: Avoid uninstantiated internal classes", Scope = "module", Justification = "CA1812 will be thrown for every file in the test project. This is mentioned here: dotnet/roslyn-analyzers#1830")]
|
||||
|
||||
// Code quality
|
||||
|
||||
@@ -12,33 +12,6 @@
|
||||
<PackageReference Include="ControlzEx" Version="5.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="6.0.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="StyleCop.Analyzers">
|
||||
<Version>1.1.118</Version>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<AdditionalFiles Include="..\..\codeAnalysis\StyleCop.json">
|
||||
<Link>StyleCop.json</Link>
|
||||
</AdditionalFiles>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\..\codeAnalysis\GlobalSuppressions.cs">
|
||||
<Link>GlobalSuppressions.cs</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ManagedCommon\ManagedCommon.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -2,72 +2,53 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace
|
||||
Box MonitorInfo::GetScreenSize(const bool includeNonWorkingArea) const
|
||||
{
|
||||
// TODO: use compare
|
||||
bool operator<(const RECT& lhs, const RECT& rhs)
|
||||
{
|
||||
auto lhs_tuple = std::make_tuple(lhs.left, lhs.right, lhs.top, lhs.bottom);
|
||||
auto rhs_tuple = std::make_tuple(rhs.left, rhs.right, rhs.top, rhs.bottom);
|
||||
return lhs_tuple < rhs_tuple;
|
||||
}
|
||||
return includeNonWorkingArea ? Box{ info.rcMonitor } : Box{ info.rcWork };
|
||||
}
|
||||
|
||||
bool operator==(const ScreenSize& lhs, const ScreenSize& rhs)
|
||||
bool MonitorInfo::IsPrimary() const
|
||||
{
|
||||
auto lhs_tuple = std::make_tuple(lhs.rect.left, lhs.rect.right, lhs.rect.top, lhs.rect.bottom);
|
||||
auto rhs_tuple = std::make_tuple(rhs.rect.left, rhs.rect.right, rhs.rect.top, rhs.rect.bottom);
|
||||
return lhs_tuple == rhs_tuple;
|
||||
return static_cast<bool>(info.dwFlags & MONITORINFOF_PRIMARY);
|
||||
}
|
||||
|
||||
MonitorInfo::MonitorInfo(HMONITOR h) :
|
||||
handle{ h }
|
||||
{
|
||||
info.cbSize = sizeof(MONITORINFOEX);
|
||||
GetMonitorInfoW(handle, &info);
|
||||
}
|
||||
|
||||
static BOOL CALLBACK GetDisplaysEnumCb(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM data)
|
||||
{
|
||||
MONITORINFOEX monitorInfo;
|
||||
monitorInfo.cbSize = sizeof(MONITORINFOEX);
|
||||
if (GetMonitorInfo(monitor, &monitorInfo))
|
||||
{
|
||||
reinterpret_cast<std::vector<MonitorInfo>*>(data)->emplace_back(monitor, monitorInfo.rcWork);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
static BOOL CALLBACK GetDisplaysEnumCbWithNonWorkingArea(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM data)
|
||||
{
|
||||
MONITORINFOEX monitorInfo;
|
||||
monitorInfo.cbSize = sizeof(MONITORINFOEX);
|
||||
if (GetMonitorInfo(monitor, &monitorInfo))
|
||||
{
|
||||
reinterpret_cast<std::vector<MonitorInfo>*>(data)->emplace_back(monitor, monitorInfo.rcMonitor);
|
||||
}
|
||||
auto* monitors = reinterpret_cast<std::vector<MonitorInfo>*>(data);
|
||||
monitors->emplace_back(monitor);
|
||||
return true;
|
||||
};
|
||||
|
||||
std::vector<MonitorInfo> MonitorInfo::GetMonitors(bool includeNonWorkingArea)
|
||||
{
|
||||
std::vector<MonitorInfo> monitors;
|
||||
EnumDisplayMonitors(NULL, NULL, includeNonWorkingArea ? GetDisplaysEnumCbWithNonWorkingArea : GetDisplaysEnumCb, reinterpret_cast<LPARAM>(&monitors));
|
||||
std::sort(begin(monitors), end(monitors), [](const MonitorInfo& lhs, const MonitorInfo& rhs) {
|
||||
return lhs.rect < rhs.rect;
|
||||
EnumDisplayMonitors(nullptr, nullptr, GetDisplaysEnumCb, reinterpret_cast<LPARAM>(&monitors));
|
||||
std::sort(begin(monitors), end(monitors), [=](const MonitorInfo& lhs, const MonitorInfo& rhs) {
|
||||
const auto lhsSize = lhs.GetScreenSize(includeNonWorkingArea);
|
||||
const auto rhsSize = rhs.GetScreenSize(includeNonWorkingArea);
|
||||
|
||||
return lhsSize < rhsSize;
|
||||
});
|
||||
return monitors;
|
||||
}
|
||||
|
||||
static BOOL CALLBACK GetPrimaryDisplayEnumCb(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM data)
|
||||
{
|
||||
MONITORINFOEX monitorInfo;
|
||||
monitorInfo.cbSize = sizeof(MONITORINFOEX);
|
||||
|
||||
if (GetMonitorInfo(monitor, &monitorInfo) && (monitorInfo.dwFlags & MONITORINFOF_PRIMARY))
|
||||
{
|
||||
reinterpret_cast<MonitorInfo*>(data)->handle = monitor;
|
||||
reinterpret_cast<MonitorInfo*>(data)->rect = monitorInfo.rcWork;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
MonitorInfo MonitorInfo::GetPrimaryMonitor()
|
||||
{
|
||||
MonitorInfo primary({}, {});
|
||||
EnumDisplayMonitors(NULL, NULL, GetPrimaryDisplayEnumCb, reinterpret_cast<LPARAM>(&primary));
|
||||
return primary;
|
||||
auto monitors = MonitorInfo::GetMonitors(false);
|
||||
if (monitors.size() > 1)
|
||||
{
|
||||
for (auto monitor : monitors)
|
||||
{
|
||||
if (monitor.IsPrimary())
|
||||
return monitor;
|
||||
}
|
||||
}
|
||||
return monitors[0];
|
||||
}
|
||||
|
||||
@@ -1,12 +1,20 @@
|
||||
#pragma once
|
||||
#include <Windows.h>
|
||||
|
||||
#include <compare>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
struct ScreenSize
|
||||
// TODO: merge with FZ::Rect
|
||||
struct Box
|
||||
{
|
||||
explicit ScreenSize(RECT rect) :
|
||||
rect(rect) {}
|
||||
RECT rect;
|
||||
|
||||
explicit Box(RECT rect = {}) :
|
||||
rect(rect) {}
|
||||
Box(const Box&) = default;
|
||||
Box& operator=(const Box&) = default;
|
||||
|
||||
int left() const { return rect.left; }
|
||||
int right() const { return rect.right; }
|
||||
int top() const { return rect.top; }
|
||||
@@ -22,17 +30,31 @@ struct ScreenSize
|
||||
POINT bottom_left() const { return { rect.left, rect.bottom }; };
|
||||
POINT bottom_middle() const { return { rect.left + width() / 2, rect.bottom }; };
|
||||
POINT bottom_right() const { return { rect.right, rect.bottom }; };
|
||||
inline bool inside(const POINT point) const { return PtInRect(&rect, point); }
|
||||
|
||||
inline friend auto operator<=>(const Box& lhs, const Box& rhs)
|
||||
{
|
||||
auto lhs_tuple = std::make_tuple(lhs.rect.left, lhs.rect.right, lhs.rect.top, lhs.rect.bottom);
|
||||
auto rhs_tuple = std::make_tuple(rhs.rect.left, rhs.rect.right, rhs.rect.top, rhs.rect.bottom);
|
||||
return lhs_tuple <=> rhs_tuple;
|
||||
}
|
||||
};
|
||||
|
||||
struct MonitorInfo : ScreenSize
|
||||
class MonitorInfo
|
||||
{
|
||||
explicit MonitorInfo(HMONITOR monitor, RECT rect) :
|
||||
handle(monitor), ScreenSize(rect) {}
|
||||
HMONITOR handle;
|
||||
MONITORINFOEX info = {};
|
||||
|
||||
public:
|
||||
explicit MonitorInfo(HMONITOR h);
|
||||
inline HMONITOR GetHandle() const
|
||||
{
|
||||
return handle;
|
||||
}
|
||||
Box GetScreenSize(const bool includeNonWorkingArea) const;
|
||||
bool IsPrimary() const;
|
||||
|
||||
// Returns monitor rects ordered from left to right
|
||||
static std::vector<MonitorInfo> GetMonitors(bool includeNonWorkingArea);
|
||||
static MonitorInfo GetPrimaryMonitor();
|
||||
};
|
||||
|
||||
bool operator==(const ScreenSize& lhs, const ScreenSize& rhs);
|
||||
|
||||
@@ -13,10 +13,6 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="6.0.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
|
||||
<PackageReference Include="System.Management" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
@@ -24,21 +20,4 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ManagedTelemetry\Telemetry\ManagedTelemetry.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AdditionalFiles Include="..\..\codeAnalysis\StyleCop.json">
|
||||
<Link>StyleCop.json</Link>
|
||||
</AdditionalFiles>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="StyleCop.Analyzers">
|
||||
<Version>1.1.118</Version>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\..\codeAnalysis\GlobalSuppressions.cs">
|
||||
<Link>GlobalSuppressions.cs</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -14,28 +14,4 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="..\..\Telemetry\TelemetryBase.cs" Link="TelemetryBase.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<AdditionalFiles Include="..\..\..\codeAnalysis\StyleCop.json">
|
||||
<Link>StyleCop.json</Link>
|
||||
</AdditionalFiles>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="6.0.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="StyleCop.Analyzers">
|
||||
<Version>1.1.118</Version>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\..\..\codeAnalysis\GlobalSuppressions.cs">
|
||||
<Link>GlobalSuppressions.cs</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -25,6 +25,22 @@ namespace PTSettingsHelper
|
||||
return result;
|
||||
}
|
||||
|
||||
std::wstring get_local_low_folder_location()
|
||||
{
|
||||
PWSTR local_app_path;
|
||||
winrt::check_hresult(SHGetKnownFolderPath(FOLDERID_LocalAppDataLow, 0, NULL, &local_app_path));
|
||||
std::wstring result{ local_app_path };
|
||||
CoTaskMemFree(local_app_path);
|
||||
|
||||
result += L"\\Microsoft\\PowerToys";
|
||||
std::filesystem::path save_path(result);
|
||||
if (!std::filesystem::exists(save_path))
|
||||
{
|
||||
std::filesystem::create_directories(save_path);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::wstring get_module_save_folder_location(std::wstring_view powertoy_key)
|
||||
{
|
||||
std::wstring result = get_root_save_folder_location();
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace PTSettingsHelper
|
||||
std::wstring get_module_save_file_location(std::wstring_view powertoy_key);
|
||||
std::wstring get_module_save_folder_location(std::wstring_view powertoy_name);
|
||||
std::wstring get_root_save_folder_location();
|
||||
std::wstring get_local_low_folder_location();
|
||||
|
||||
void save_module_settings(std::wstring_view powertoy_name, json::JsonObject& settings);
|
||||
json::JsonObject load_module_settings(std::wstring_view powertoy_name);
|
||||
|
||||
@@ -217,7 +217,8 @@ namespace PowerToysSettings
|
||||
}
|
||||
std::array<BYTE, 256> key_states{}; // Zero-initialize
|
||||
std::array<wchar_t, 256> output;
|
||||
auto output_bytes = ToUnicodeEx(key_code, scan_code, key_states.data(), output.data(), (int)output.size() - 1, 0, layout);
|
||||
const UINT wFlags = 1 << 2; // If bit 2 is set, keyboard state is not changed (Windows 10, version 1607 and newer)
|
||||
auto output_bytes = ToUnicodeEx(key_code, scan_code, key_states.data(), output.data(), (int)output.size() - 1, wFlags, layout);
|
||||
if (output_bytes <= 0)
|
||||
{
|
||||
// If ToUnicodeEx fails (e.g. for F1-F12 keys) use GetKeyNameTextW
|
||||
|
||||
@@ -57,27 +57,6 @@
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="6.0.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="StyleCop.Analyzers">
|
||||
<Version>1.1.118</Version>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\..\..\codeAnalysis\GlobalSuppressions.cs">
|
||||
<Link>GlobalSuppressions.cs</Link>
|
||||
</Compile>
|
||||
<AdditionalFiles Include="..\..\..\codeAnalysis\StyleCop.json">
|
||||
<Link>StyleCop.json</Link>
|
||||
</AdditionalFiles>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\PowerToys.Interop.vcxproj" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -195,8 +195,17 @@ public
|
||||
return gcnew String(CommonSharedConstants::SHOW_COLOR_PICKER_SHARED_EVENT);
|
||||
}
|
||||
|
||||
static String ^ ShowPowerOCRSharedEvent() {
|
||||
return gcnew String(CommonSharedConstants::SHOW_POWEROCR_SHARED_EVENT);
|
||||
}
|
||||
|
||||
static String ^ AwakeExitEvent() {
|
||||
return gcnew String(CommonSharedConstants::AWAKE_EXIT_EVENT);
|
||||
}
|
||||
|
||||
static String ^ PowerAccentExitEvent() {
|
||||
return gcnew String(CommonSharedConstants::POWERACCENT_EXIT_EVENT);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -55,7 +55,8 @@ bool mapKeycodeToUnicode(const int vCode, HKL layout, const BYTE* keyState, std:
|
||||
// Get the scan code from the virtual key code
|
||||
const UINT scanCode = MapVirtualKeyExW(vCode, MAPVK_VK_TO_VSC, layout);
|
||||
// Get the unicode representation from the virtual key code and scan code pair
|
||||
const int result = ToUnicodeEx(vCode, scanCode, keyState, outBuffer.data(), (int)outBuffer.size(), 0, layout);
|
||||
const UINT wFlags = 1 << 2; // If bit 2 is set, keyboard state is not changed (Windows 10, version 1607 and newer)
|
||||
const int result = ToUnicodeEx(vCode, scanCode, keyState, outBuffer.data(), (int)outBuffer.size(), wFlags, layout);
|
||||
return result != 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,12 @@ namespace CommonSharedConstants
|
||||
// Path to the event used by AlwaysOnTop
|
||||
const wchar_t ALWAYS_ON_TOP_PIN_EVENT[] = L"Local\\AlwaysOnTopPinEvent-892e0aa2-cfa8-4cc4-b196-ddeb32314ce8";
|
||||
|
||||
// Path to the event used by PowerAccent
|
||||
const wchar_t POWERACCENT_EXIT_EVENT[] = L"Local\\PowerToysPowerAccentExitEvent-53e93389-d19a-4fbb-9b36-1981c8965e17";
|
||||
|
||||
// Path to the event used by PowerOCR
|
||||
const wchar_t SHOW_POWEROCR_SHARED_EVENT[] = L"Local\\PowerOCREvent-dc864e06-e1af-4ecc-9078-f98bee745e3a";
|
||||
|
||||
// Max DWORD for key code to disable keys.
|
||||
const DWORD VK_DISABLED = 0x100;
|
||||
}
|
||||
|
||||
@@ -18,11 +18,13 @@ struct LogSettings
|
||||
inline const static std::string launcherLoggerName = "launcher";
|
||||
inline const static std::wstring launcherLogPath = L"LogsModuleInterface\\launcher-log.txt";
|
||||
inline const static std::wstring awakeLogPath = L"Logs\\awake-log.txt";
|
||||
inline const static std::wstring powerAccentLogPath = L"poweraccent.log";
|
||||
inline const static std::string fancyZonesLoggerName = "fancyzones";
|
||||
inline const static std::wstring fancyZonesLogPath = L"fancyzones-log.txt";
|
||||
inline const static std::wstring fancyZonesOldLogPath = L"FancyZonesLogs\\"; // needed to clean up old logs
|
||||
inline const static std::string shortcutGuideLoggerName = "shortcut-guide";
|
||||
inline const static std::wstring shortcutGuideLogPath = L"ShortcutGuideLogs\\shortcut-guide-log.txt";
|
||||
inline const static std::wstring powerOcrLogPath = L"Logs\\power-ocr-log.txt";
|
||||
inline const static std::string keyboardManagerLoggerName = "keyboard-manager";
|
||||
inline const static std::wstring keyboardManagerLogPath = L"Logs\\keyboard-manager-log.txt";
|
||||
inline const static std::string findMyMouseLoggerName = "find-my-mouse";
|
||||
@@ -31,6 +33,7 @@ struct LogSettings
|
||||
inline const static std::string imageResizerLoggerName = "imageresizer";
|
||||
inline const static std::string powerRenameLoggerName = "powerrename";
|
||||
inline const static std::string alwaysOnTopLoggerName = "always-on-top";
|
||||
inline const static std::string powerOcrLoggerName = "power-ocr";
|
||||
inline const static std::wstring alwaysOnTopLogPath = L"always-on-top-log.txt";
|
||||
inline const static int retention = 30;
|
||||
std::wstring logLevel;
|
||||
|
||||
@@ -9,10 +9,10 @@ struct UpdateState
|
||||
{
|
||||
enum State
|
||||
{
|
||||
upToDate = 0,
|
||||
errorDownloading = 1,
|
||||
readyToDownload = 2,
|
||||
readyToInstall = 3
|
||||
upToDate = 0,
|
||||
errorDownloading = 1,
|
||||
readyToDownload = 2,
|
||||
readyToInstall = 3
|
||||
} state = upToDate;
|
||||
std::wstring releasePageUrl;
|
||||
std::optional<std::time_t> githubUpdateLastCheckedDate;
|
||||
|
||||
30
src/common/utils/serialized.h
Normal file
30
src/common/utils/serialized.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <shared_mutex>
|
||||
|
||||
template<typename StateT>
|
||||
class Serialized
|
||||
{
|
||||
mutable std::shared_mutex m;
|
||||
StateT s;
|
||||
|
||||
public:
|
||||
void Read(std::function<void(const StateT&)> fn) const
|
||||
{
|
||||
std::shared_lock lock{ m };
|
||||
fn(s);
|
||||
}
|
||||
|
||||
void Access(std::function<void(StateT&)> fn)
|
||||
{
|
||||
std::unique_lock lock{ m };
|
||||
fn(s);
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
std::unique_lock lock{ m };
|
||||
s = {};
|
||||
}
|
||||
};
|
||||
@@ -25,7 +25,7 @@ inline std::optional<std::wstring> get_last_error_message(const DWORD dw)
|
||||
inline std::wstring get_last_error_or_default(const DWORD dw)
|
||||
{
|
||||
auto message = get_last_error_message(dw);
|
||||
return message.has_value() ? message.value() : L"";
|
||||
return message.has_value() ? *message : L"";
|
||||
}
|
||||
|
||||
inline void show_last_error_message(const wchar_t* functionName, DWORD dw, const wchar_t* errorTitle)
|
||||
|
||||
@@ -8,24 +8,24 @@
|
||||
#include <optional>
|
||||
|
||||
// Initializes and runs windows message loop
|
||||
inline int run_message_loop(const bool until_idle = false, const std::optional<uint32_t> timeout_seconds = {})
|
||||
inline int run_message_loop(const bool until_idle = false, const std::optional<uint32_t> timeout_ms = {})
|
||||
{
|
||||
MSG msg{};
|
||||
bool stop = false;
|
||||
UINT_PTR timerId = 0;
|
||||
if (timeout_seconds.has_value())
|
||||
if (timeout_ms.has_value())
|
||||
{
|
||||
timerId = SetTimer(nullptr, 0, *timeout_seconds * 1000, nullptr);
|
||||
timerId = SetTimer(nullptr, 0, *timeout_ms, nullptr);
|
||||
}
|
||||
|
||||
while (!stop && GetMessageW(&msg, nullptr, 0, 0))
|
||||
while (!stop && (until_idle ? PeekMessageW(&msg, nullptr, 0, 0, PM_REMOVE) : GetMessageW(&msg, nullptr, 0, 0)))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessageW(&msg);
|
||||
stop = until_idle && !PeekMessageW(&msg, nullptr, 0, 0, PM_NOREMOVE);
|
||||
stop = stop || (msg.message == WM_TIMER && msg.wParam == timerId);
|
||||
}
|
||||
if (timeout_seconds.has_value())
|
||||
if (timeout_ms.has_value())
|
||||
{
|
||||
KillTimer(nullptr, timerId);
|
||||
}
|
||||
@@ -55,3 +55,24 @@ inline bool is_system_window(HWND hwnd, const char* class_name)
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T GetWindowCreateParam(LPARAM lparam)
|
||||
{
|
||||
static_assert(sizeof(T) <= sizeof(void*));
|
||||
T data{ (T)(reinterpret_cast<CREATESTRUCT*>(lparam)->lpCreateParams) };
|
||||
return data;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void StoreWindowParam(HWND window, T data)
|
||||
{
|
||||
static_assert(sizeof(T) <= sizeof(void*));
|
||||
SetWindowLongPtrW(window, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(data));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T GetWindowParam(HWND window)
|
||||
{
|
||||
return (T)GetWindowLongPtrW(window, GWLP_USERDATA);
|
||||
}
|
||||
|
||||
73
src/modules/MeasureTool/MeasureToolCore/BGRATextureView.cpp
Normal file
73
src/modules/MeasureTool/MeasureToolCore/BGRATextureView.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include "BGRATextureView.h"
|
||||
|
||||
#if defined(DEBUG_TEXTURE)
|
||||
void BGRATextureView::SaveAsBitmap(const char* filename) const
|
||||
{
|
||||
wil::unique_hbitmap bitmap{ CreateBitmap(static_cast<int>(pitch), static_cast<int>(height), 1, 32, pixels) };
|
||||
const HBITMAP hBitmap = bitmap.get();
|
||||
DWORD dwPaletteSize = 0, dwBmBitsSize = 0, dwDIBSize = 0, dwWritten = 0;
|
||||
LPBITMAPINFOHEADER lpBitmapInfo;
|
||||
HANDLE hDib, hPal, hOldPal2 = NULL;
|
||||
HDC hDC = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
|
||||
const int iBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
|
||||
DeleteDC(hDC);
|
||||
WORD wBitCount = 24;
|
||||
if (iBits <= 1)
|
||||
wBitCount = 1;
|
||||
else if (iBits <= 4)
|
||||
wBitCount = 4;
|
||||
else if (iBits <= 8)
|
||||
wBitCount = 8;
|
||||
|
||||
BITMAP Bitmap0;
|
||||
GetObject(hBitmap, sizeof(Bitmap0), (LPSTR)&Bitmap0);
|
||||
BITMAPINFOHEADER bi = {};
|
||||
bi.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bi.biWidth = Bitmap0.bmWidth;
|
||||
bi.biHeight = -Bitmap0.bmHeight;
|
||||
bi.biPlanes = 1;
|
||||
bi.biBitCount = wBitCount;
|
||||
bi.biCompression = BI_RGB;
|
||||
bi.biClrUsed = 256;
|
||||
dwBmBitsSize = ((Bitmap0.bmWidth * wBitCount + 31) & ~31) / 8 * Bitmap0.bmHeight;
|
||||
hDib = GlobalAlloc(GHND, dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER));
|
||||
lpBitmapInfo = (LPBITMAPINFOHEADER)GlobalLock(hDib);
|
||||
*lpBitmapInfo = bi;
|
||||
|
||||
hPal = GetStockObject(DEFAULT_PALETTE);
|
||||
if (hPal)
|
||||
{
|
||||
hDC = GetDC(NULL);
|
||||
hOldPal2 = SelectPalette(hDC, (HPALETTE)hPal, FALSE);
|
||||
RealizePalette(hDC);
|
||||
}
|
||||
|
||||
GetDIBits(hDC, hBitmap, 0, (UINT)Bitmap0.bmHeight, (LPSTR)lpBitmapInfo + sizeof(BITMAPINFOHEADER) + dwPaletteSize, (BITMAPINFO*)lpBitmapInfo, DIB_RGB_COLORS);
|
||||
|
||||
if (hOldPal2)
|
||||
{
|
||||
SelectPalette(hDC, (HPALETTE)hOldPal2, TRUE);
|
||||
RealizePalette(hDC);
|
||||
ReleaseDC(NULL, hDC);
|
||||
}
|
||||
|
||||
wil::unique_handle fh{ CreateFileA(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL) };
|
||||
|
||||
if (!fh)
|
||||
return;
|
||||
|
||||
BITMAPFILEHEADER bitmapFileHeader = {};
|
||||
bitmapFileHeader.bfType = 0x4D42; // "BM"
|
||||
dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize;
|
||||
bitmapFileHeader.bfSize = dwDIBSize;
|
||||
bitmapFileHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize;
|
||||
|
||||
WriteFile(fh.get(), (LPSTR)&bitmapFileHeader, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
|
||||
|
||||
WriteFile(fh.get(), (LPSTR)lpBitmapInfo, dwDIBSize, &dwWritten, NULL);
|
||||
GlobalUnlock(hDib);
|
||||
GlobalFree(hDib);
|
||||
}
|
||||
#endif
|
||||
127
src/modules/MeasureTool/MeasureToolCore/BGRATextureView.h
Normal file
127
src/modules/MeasureTool/MeasureToolCore/BGRATextureView.h
Normal file
@@ -0,0 +1,127 @@
|
||||
#pragma once
|
||||
|
||||
#include <cinttypes>
|
||||
#include <wil/resource.h>
|
||||
#ifdef _M_ARM64
|
||||
#include <arm64_neon.h.>
|
||||
#else
|
||||
#include <emmintrin.h>
|
||||
#endif
|
||||
#include <cassert>
|
||||
#include <limits>
|
||||
|
||||
//#define DEBUG_TEXTURE
|
||||
|
||||
#if defined(_M_ARM64)
|
||||
|
||||
// Adopted from https://github.com/DLTcollab/sse2neon/blob/master/sse2neon.h
|
||||
|
||||
using __m128i = int64x2_t;
|
||||
|
||||
inline __m128i _mm_cvtsi32_si128(int a)
|
||||
{
|
||||
return vreinterpretq_s64_s32(vsetq_lane_s32(a, vdupq_n_s32(0), 0));
|
||||
}
|
||||
|
||||
inline __m128i _mm_or_si128(__m128i a, __m128i b)
|
||||
{
|
||||
return vreinterpretq_s64_s32(
|
||||
vorrq_s32(vreinterpretq_s32_s64(a), vreinterpretq_s32_s64(b)));
|
||||
}
|
||||
|
||||
inline __m128i _mm_subs_epu8(__m128i a, __m128i b)
|
||||
{
|
||||
return vreinterpretq_s64_u8(
|
||||
vqsubq_u8(vreinterpretq_u8_s64(a), vreinterpretq_u8_s64(b)));
|
||||
}
|
||||
|
||||
inline __m128i _mm_sad_epu8(__m128i a, __m128i b)
|
||||
{
|
||||
uint16x8_t t = vpaddlq_u8(vabdq_u8((uint8x16_t)a, (uint8x16_t)b));
|
||||
return vreinterpretq_s64_u64(vpaddlq_u32(vpaddlq_u16(t)));
|
||||
}
|
||||
|
||||
inline __m128i _mm_setzero_si128(void)
|
||||
{
|
||||
return vreinterpretq_s64_s32(vdupq_n_s32(0));
|
||||
}
|
||||
|
||||
inline int _mm_cvtsi128_si32(__m128i a)
|
||||
{
|
||||
return vgetq_lane_s32(vreinterpretq_s32_s64(a), 0);
|
||||
}
|
||||
|
||||
inline __m128i _mm_set1_epi16(short w)
|
||||
{
|
||||
return vreinterpretq_s64_s16(vdupq_n_s16(w));
|
||||
}
|
||||
|
||||
inline __m128i _mm_cmpgt_epi16(__m128i a, __m128i b)
|
||||
{
|
||||
return vreinterpretq_s64_u16(
|
||||
vcgtq_s16(vreinterpretq_s16_s64(a), vreinterpretq_s16_s64(b)));
|
||||
}
|
||||
|
||||
inline __m128i _mm_cvtepu8_epi16(__m128i a)
|
||||
{
|
||||
uint8x16_t u8x16 = vreinterpretq_u8_s64(a); /* xxxx xxxx HGFE DCBA */
|
||||
uint16x8_t u16x8 = vmovl_u8(vget_low_u8(u8x16)); /* 0H0G 0F0E 0D0C 0B0A */
|
||||
return vreinterpretq_s64_u16(u16x8);
|
||||
}
|
||||
|
||||
inline int64_t _mm_cvtsi128_si64(__m128i a)
|
||||
{
|
||||
return vgetq_lane_s64(a, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
inline __m128i distance_epu8(const __m128i a, __m128i b)
|
||||
{
|
||||
return _mm_or_si128(_mm_subs_epu8(a, b),
|
||||
_mm_subs_epu8(b, a));
|
||||
}
|
||||
|
||||
struct BGRATextureView
|
||||
{
|
||||
const uint32_t* pixels = nullptr;
|
||||
size_t pitch = {};
|
||||
size_t width = {};
|
||||
size_t height = {};
|
||||
|
||||
BGRATextureView() = default;
|
||||
|
||||
BGRATextureView(BGRATextureView&& rhs) = default;
|
||||
|
||||
inline uint32_t GetPixel(const size_t x, const size_t y) const
|
||||
{
|
||||
assert(x < width && x >= 0);
|
||||
assert(y < height && y >= 0);
|
||||
return pixels[x + pitch * y];
|
||||
}
|
||||
|
||||
template<bool perChannel>
|
||||
static inline bool PixelsClose(const uint32_t pixel1, const uint32_t pixel2, uint8_t tolerance)
|
||||
{
|
||||
const __m128i rgba1 = _mm_cvtsi32_si128(pixel1);
|
||||
const __m128i rgba2 = _mm_cvtsi32_si128(pixel2);
|
||||
const __m128i distances = distance_epu8(rgba1, rgba2);
|
||||
|
||||
// Method 1: Test whether each channel distance is not greater than tolerance
|
||||
if constexpr (perChannel)
|
||||
{
|
||||
const __m128i tolerances = _mm_set1_epi16(tolerance);
|
||||
const auto gtResults128 = _mm_cmpgt_epi16(_mm_cvtepu8_epi16(distances), tolerances);
|
||||
return _mm_cvtsi128_si64(gtResults128) == 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Method 2: Test whether sum of all channel differences is smaller than tolerance
|
||||
const int32_t score = _mm_cvtsi128_si32(_mm_sad_epu8(distances, _mm_setzero_si128())) & std::numeric_limits<uint8_t>::max();
|
||||
return score <= tolerance;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(DEBUG_TEXTURE)
|
||||
void SaveAsBitmap(const char* filename) const;
|
||||
#endif
|
||||
};
|
||||
161
src/modules/MeasureTool/MeasureToolCore/BoundsToolOverlayUI.cpp
Normal file
161
src/modules/MeasureTool/MeasureToolCore/BoundsToolOverlayUI.cpp
Normal file
@@ -0,0 +1,161 @@
|
||||
#include "pch.h"
|
||||
#include "BoundsToolOverlayUI.h"
|
||||
#include "CoordinateSystemConversion.h"
|
||||
#include "Clipboard.h"
|
||||
|
||||
#include <common/utils/window.h>
|
||||
|
||||
LRESULT CALLBACK BoundsToolWndProc(HWND window, UINT message, WPARAM wparam, LPARAM lparam) noexcept
|
||||
{
|
||||
switch (message)
|
||||
{
|
||||
case WM_CREATE:
|
||||
{
|
||||
auto toolState = GetWindowCreateParam<BoundsToolState*>(lparam);
|
||||
StoreWindowParam(window, toolState);
|
||||
break;
|
||||
}
|
||||
case WM_ERASEBKGND:
|
||||
return 1;
|
||||
case WM_KEYUP:
|
||||
if (wparam == VK_ESCAPE)
|
||||
{
|
||||
PostMessageW(window, WM_CLOSE, {}, {});
|
||||
}
|
||||
break;
|
||||
case WM_LBUTTONDOWN:
|
||||
{
|
||||
auto toolState = GetWindowParam<BoundsToolState*>(window);
|
||||
if (!toolState)
|
||||
break;
|
||||
const POINT cursorPos = convert::FromSystemToRelativeForDirect2D(window, toolState->commonState->cursorPosSystemSpace);
|
||||
|
||||
D2D_POINT_2F newRegionStart = { .x = static_cast<float>(cursorPos.x), .y = static_cast<float>(cursorPos.y) };
|
||||
toolState->perScreen[window].currentRegionStart = newRegionStart;
|
||||
break;
|
||||
}
|
||||
case WM_CURSOR_LEFT_MONITOR:
|
||||
{
|
||||
auto toolState = GetWindowParam<BoundsToolState*>(window);
|
||||
if (!toolState)
|
||||
break;
|
||||
toolState->perScreen[window].currentRegionStart = std::nullopt;
|
||||
break;
|
||||
}
|
||||
case WM_LBUTTONUP:
|
||||
{
|
||||
auto toolState = GetWindowParam<BoundsToolState*>(window);
|
||||
if (!toolState || !toolState->perScreen[window].currentRegionStart)
|
||||
break;
|
||||
|
||||
toolState->commonState->overlayBoxText.Read([](const OverlayBoxText& text) {
|
||||
SetClipBoardToText(text.buffer);
|
||||
});
|
||||
|
||||
if (const bool shiftPress = GetKeyState(VK_SHIFT) & 0x8000; shiftPress)
|
||||
{
|
||||
const auto cursorPos = convert::FromSystemToRelativeForDirect2D(window, toolState->commonState->cursorPosSystemSpace);
|
||||
|
||||
D2D1_RECT_F rect;
|
||||
std::tie(rect.left, rect.right) = std::minmax(static_cast<float>(cursorPos.x), toolState->perScreen[window].currentRegionStart->x);
|
||||
std::tie(rect.top, rect.bottom) = std::minmax(static_cast<float>(cursorPos.y), toolState->perScreen[window].currentRegionStart->y);
|
||||
toolState->perScreen[window].measurements.push_back(rect);
|
||||
}
|
||||
|
||||
toolState->perScreen[window].currentRegionStart = std::nullopt;
|
||||
break;
|
||||
}
|
||||
case WM_RBUTTONUP:
|
||||
{
|
||||
auto toolState = GetWindowParam<BoundsToolState*>(window);
|
||||
if (!toolState)
|
||||
break;
|
||||
|
||||
if (toolState->perScreen[window].currentRegionStart)
|
||||
toolState->perScreen[window].currentRegionStart = std::nullopt;
|
||||
else
|
||||
{
|
||||
if (toolState->perScreen[window].measurements.empty())
|
||||
PostMessageW(window, WM_CLOSE, {}, {});
|
||||
else
|
||||
toolState->perScreen[window].measurements.clear();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return DefWindowProcW(window, message, wparam, lparam);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
void DrawMeasurement(const D2D1_RECT_F rect,
|
||||
const bool alignTextBoxToCenter,
|
||||
const CommonState& commonState,
|
||||
HWND window,
|
||||
const D2DState& d2dState)
|
||||
{
|
||||
const bool screenQuadrantAware = !alignTextBoxToCenter;
|
||||
const auto prevMode = d2dState.rt->GetAntialiasMode();
|
||||
d2dState.rt->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
|
||||
d2dState.rt->DrawRectangle(rect, d2dState.solidBrushes[Brush::line].get());
|
||||
d2dState.rt->SetAntialiasMode(prevMode);
|
||||
|
||||
OverlayBoxText text;
|
||||
const auto width = std::abs(rect.right - rect.left + 1);
|
||||
const auto height = std::abs(rect.top - rect.bottom + 1);
|
||||
const uint32_t textLen = swprintf_s(text.buffer.data(),
|
||||
text.buffer.size(),
|
||||
L"%.0f × %.0f",
|
||||
width,
|
||||
height);
|
||||
std::optional<size_t> crossSymbolPos = wcschr(text.buffer.data(), L' ') - text.buffer.data() + 1;
|
||||
|
||||
commonState.overlayBoxText.Access([&](OverlayBoxText& v) {
|
||||
v = text;
|
||||
});
|
||||
|
||||
float cornerX = rect.right;
|
||||
float cornerY = rect.bottom;
|
||||
if (alignTextBoxToCenter)
|
||||
{
|
||||
cornerX = rect.left + width / 2;
|
||||
cornerY = rect.top + height / 2;
|
||||
}
|
||||
|
||||
d2dState.DrawTextBox(text.buffer.data(),
|
||||
textLen,
|
||||
crossSymbolPos,
|
||||
cornerX,
|
||||
cornerY,
|
||||
screenQuadrantAware,
|
||||
window);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawBoundsToolTick(const CommonState& commonState,
|
||||
const BoundsToolState& toolState,
|
||||
const HWND window,
|
||||
const D2DState& d2dState)
|
||||
{
|
||||
const auto it = toolState.perScreen.find(window);
|
||||
if (it == end(toolState.perScreen))
|
||||
return;
|
||||
|
||||
d2dState.rt->Clear();
|
||||
|
||||
const auto& perScreen = it->second;
|
||||
for (const auto& measure : perScreen.measurements)
|
||||
DrawMeasurement(measure, true, commonState, window, d2dState);
|
||||
|
||||
if (!perScreen.currentRegionStart.has_value())
|
||||
return;
|
||||
|
||||
const auto cursorPos = convert::FromSystemToRelativeForDirect2D(window, commonState.cursorPosSystemSpace);
|
||||
|
||||
const D2D1_RECT_F rect{ .left = perScreen.currentRegionStart->x,
|
||||
.top = perScreen.currentRegionStart->y,
|
||||
.right = static_cast<float>(cursorPos.x),
|
||||
.bottom = static_cast<float>(cursorPos.y) };
|
||||
DrawMeasurement(rect, false, commonState, window, d2dState);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include "D2DState.h"
|
||||
#include "ToolState.h"
|
||||
|
||||
void DrawBoundsToolTick(const CommonState& commonState,
|
||||
const BoundsToolState& toolState,
|
||||
const HWND overlayWindow,
|
||||
const D2DState& d2dState);
|
||||
|
||||
LRESULT CALLBACK BoundsToolWndProc(HWND window, UINT message, WPARAM wparam, LPARAM lparam) noexcept;
|
||||
28
src/modules/MeasureTool/MeasureToolCore/Clipboard.cpp
Normal file
28
src/modules/MeasureTool/MeasureToolCore/Clipboard.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include "Clipboard.h"
|
||||
|
||||
void SetClipBoardToText(const std::wstring_view text)
|
||||
{
|
||||
if (!OpenClipboard(nullptr))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const wil::unique_hglobal handle{ GlobalAlloc(GMEM_MOVEABLE, static_cast<size_t>((text.length() + 1) * sizeof(wchar_t))) };
|
||||
if (!handle)
|
||||
{
|
||||
CloseClipboard();
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto* bufPtr = static_cast<wchar_t*>(GlobalLock(handle.get())); bufPtr != nullptr)
|
||||
{
|
||||
text.copy(bufPtr, text.length());
|
||||
GlobalUnlock(handle.get());
|
||||
}
|
||||
|
||||
EmptyClipboard();
|
||||
SetClipboardData(CF_UNICODETEXT, handle.get());
|
||||
CloseClipboard();
|
||||
}
|
||||
5
src/modules/MeasureTool/MeasureToolCore/Clipboard.h
Normal file
5
src/modules/MeasureTool/MeasureToolCore/Clipboard.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
|
||||
void SetClipBoardToText(const std::wstring_view text);
|
||||
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
|
||||
namespace convert
|
||||
{
|
||||
// Converts a given point from multi-monitor coordinate system to the one relative to HWND
|
||||
inline POINT FromSystemToRelative(HWND window, POINT p)
|
||||
{
|
||||
ScreenToClient(window, &p);
|
||||
return p;
|
||||
}
|
||||
|
||||
// Converts a given point from multi-monitor coordinate system to the one relative to HWND and also ready
|
||||
// to be used in Direct2D calls with AA mode set to aliased
|
||||
inline POINT FromSystemToRelativeForDirect2D(HWND window, POINT p)
|
||||
{
|
||||
ScreenToClient(window, &p);
|
||||
// Submitting DrawLine calls to Direct2D with thickness == 1.f and AA mode set to aliased causes
|
||||
// them to be drawn offset by [1,1] toward upper-left corner, so we must to compensate for that.
|
||||
++p.x;
|
||||
++p.y;
|
||||
return p;
|
||||
}
|
||||
}
|
||||
170
src/modules/MeasureTool/MeasureToolCore/D2DState.cpp
Normal file
170
src/modules/MeasureTool/MeasureToolCore/D2DState.cpp
Normal file
@@ -0,0 +1,170 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include "constants.h"
|
||||
#include "D2DState.h"
|
||||
|
||||
#include <common/Display/dpi_aware.h>
|
||||
#include <ToolState.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
void DetermineScreenQuadrant(const HWND window, long x, long y, bool& inLeftHalf, bool& inTopHalf)
|
||||
{
|
||||
RECT windowRect{};
|
||||
GetWindowRect(window, &windowRect);
|
||||
const long w = windowRect.right - windowRect.left;
|
||||
const long h = windowRect.bottom - windowRect.top;
|
||||
inLeftHalf = x < w / 2;
|
||||
inTopHalf = y < h / 2;
|
||||
}
|
||||
}
|
||||
|
||||
D2DState::D2DState(const HWND overlayWindow, std::vector<D2D1::ColorF> solidBrushesColors)
|
||||
{
|
||||
std::lock_guard guard{ gpuAccessLock };
|
||||
|
||||
RECT clientRect = {};
|
||||
|
||||
winrt::check_bool(GetClientRect(overlayWindow, &clientRect));
|
||||
winrt::check_hresult(D2D1CreateFactory(D2D1_FACTORY_TYPE_MULTI_THREADED, &d2dFactory));
|
||||
|
||||
winrt::check_hresult(DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), writeFactory.put_unknown()));
|
||||
|
||||
// We should always use DPIAware::DEFAULT_DPI, since it's the correct thing to do in DPI-Aware mode
|
||||
auto renderTargetProperties = D2D1::RenderTargetProperties(
|
||||
D2D1_RENDER_TARGET_TYPE_DEFAULT,
|
||||
D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED),
|
||||
DPIAware::DEFAULT_DPI,
|
||||
DPIAware::DEFAULT_DPI,
|
||||
D2D1_RENDER_TARGET_USAGE_NONE,
|
||||
D2D1_FEATURE_LEVEL_DEFAULT);
|
||||
|
||||
auto renderTargetSize = D2D1::SizeU(clientRect.right - clientRect.left, clientRect.bottom - clientRect.top);
|
||||
auto hwndRenderTargetProperties = D2D1::HwndRenderTargetProperties(overlayWindow, renderTargetSize);
|
||||
|
||||
winrt::check_hresult(d2dFactory->CreateHwndRenderTarget(renderTargetProperties, hwndRenderTargetProperties, &rt));
|
||||
winrt::check_hresult(rt->CreateCompatibleRenderTarget(&bitmapRt));
|
||||
|
||||
unsigned dpi = DPIAware::DEFAULT_DPI;
|
||||
DPIAware::GetScreenDPIForWindow(overlayWindow, dpi);
|
||||
dpiScale = dpi / static_cast<float>(DPIAware::DEFAULT_DPI);
|
||||
|
||||
winrt::check_hresult(writeFactory->CreateTextFormat(L"Segoe UI Variable Text",
|
||||
nullptr,
|
||||
DWRITE_FONT_WEIGHT_NORMAL,
|
||||
DWRITE_FONT_STYLE_NORMAL,
|
||||
DWRITE_FONT_STRETCH_NORMAL,
|
||||
consts::FONT_SIZE * dpiScale,
|
||||
L"en-US",
|
||||
&textFormat));
|
||||
winrt::check_hresult(textFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER));
|
||||
winrt::check_hresult(textFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER));
|
||||
winrt::check_hresult(textFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP));
|
||||
|
||||
solidBrushes.resize(solidBrushesColors.size());
|
||||
for (size_t i = 0; i < solidBrushes.size(); ++i)
|
||||
{
|
||||
winrt::check_hresult(rt->CreateSolidColorBrush(solidBrushesColors[i], &solidBrushes[i]));
|
||||
}
|
||||
|
||||
const auto deviceContext = rt.query<ID2D1DeviceContext>();
|
||||
winrt::check_hresult(deviceContext->CreateEffect(CLSID_D2D1Shadow, &shadowEffect));
|
||||
winrt::check_hresult(shadowEffect->SetValue(D2D1_SHADOW_PROP_BLUR_STANDARD_DEVIATION, consts::SHADOW_RADIUS));
|
||||
winrt::check_hresult(shadowEffect->SetValue(D2D1_SHADOW_PROP_COLOR, D2D1::ColorF(0.f, 0.f, 0.f, consts::SHADOW_OPACITY)));
|
||||
|
||||
winrt::check_hresult(deviceContext->CreateEffect(CLSID_D2D12DAffineTransform, &affineTransformEffect));
|
||||
affineTransformEffect->SetInputEffect(0, shadowEffect.get());
|
||||
|
||||
textRenderer = winrt::make_self<PerGlyphOpacityTextRender>(d2dFactory, rt, solidBrushes[Brush::foreground]);
|
||||
}
|
||||
|
||||
void D2DState::DrawTextBox(const wchar_t* text,
|
||||
const uint32_t textLen,
|
||||
const std::optional<size_t> halfOpaqueSymbolPos,
|
||||
const float centerX,
|
||||
const float centerY,
|
||||
const bool screenQuadrantAware,
|
||||
const HWND window) const
|
||||
{
|
||||
wil::com_ptr<IDWriteTextLayout> textLayout;
|
||||
winrt::check_hresult(writeFactory->CreateTextLayout(text,
|
||||
textLen,
|
||||
textFormat.get(),
|
||||
std::numeric_limits<float>::max(),
|
||||
std::numeric_limits<float>::max(),
|
||||
&textLayout));
|
||||
DWRITE_TEXT_METRICS textMetrics = {};
|
||||
winrt::check_hresult(textLayout->GetMetrics(&textMetrics));
|
||||
textMetrics.width *= consts::TEXT_BOX_MARGIN_COEFF;
|
||||
textMetrics.height *= consts::TEXT_BOX_MARGIN_COEFF;
|
||||
winrt::check_hresult(textLayout->SetMaxWidth(textMetrics.width));
|
||||
winrt::check_hresult(textLayout->SetMaxHeight(textMetrics.height));
|
||||
|
||||
D2D1_RECT_F textRect{ .left = centerX - textMetrics.width / 2.f,
|
||||
.top = centerY - textMetrics.height / 2.f,
|
||||
.right = centerX + textMetrics.width / 2.f,
|
||||
.bottom = centerY + textMetrics.height / 2.f };
|
||||
if (screenQuadrantAware)
|
||||
{
|
||||
bool cursorInLeftScreenHalf = false;
|
||||
bool cursorInTopScreenHalf = false;
|
||||
DetermineScreenQuadrant(window,
|
||||
static_cast<long>(centerX),
|
||||
static_cast<long>(centerY),
|
||||
cursorInLeftScreenHalf,
|
||||
cursorInTopScreenHalf);
|
||||
float textQuadrantOffsetX = textMetrics.width * dpiScale;
|
||||
float textQuadrantOffsetY = textMetrics.height * dpiScale;
|
||||
if (!cursorInLeftScreenHalf)
|
||||
textQuadrantOffsetX *= -1.f;
|
||||
if (!cursorInTopScreenHalf)
|
||||
textQuadrantOffsetY *= -1.f;
|
||||
textRect.left += textQuadrantOffsetX;
|
||||
textRect.right += textQuadrantOffsetX;
|
||||
textRect.top += textQuadrantOffsetY;
|
||||
textRect.bottom += textQuadrantOffsetY;
|
||||
}
|
||||
|
||||
// Draw shadow
|
||||
bitmapRt->BeginDraw();
|
||||
bitmapRt->Clear(D2D1::ColorF(0.f, 0.f, 0.f, 0.f));
|
||||
D2D1_ROUNDED_RECT textBoxRect;
|
||||
textBoxRect.radiusX = textBoxRect.radiusY = consts::TEXT_BOX_CORNER_RADIUS * dpiScale;
|
||||
textBoxRect.rect.bottom = textRect.bottom;
|
||||
textBoxRect.rect.top = textRect.top;
|
||||
textBoxRect.rect.left = textRect.left;
|
||||
textBoxRect.rect.right = textRect.right;
|
||||
bitmapRt->FillRoundedRectangle(textBoxRect, solidBrushes[Brush::border].get());
|
||||
bitmapRt->EndDraw();
|
||||
|
||||
wil::com_ptr<ID2D1Bitmap> rtBitmap;
|
||||
bitmapRt->GetBitmap(&rtBitmap);
|
||||
|
||||
shadowEffect->SetInput(0, rtBitmap.get());
|
||||
const auto shadowMatrix = D2D1::Matrix3x2F::Translation(consts::SHADOW_OFFSET * dpiScale,
|
||||
consts::SHADOW_OFFSET * dpiScale);
|
||||
winrt::check_hresult(affineTransformEffect->SetValue(D2D1_2DAFFINETRANSFORM_PROP_TRANSFORM_MATRIX,
|
||||
shadowMatrix));
|
||||
auto deviceContext = rt.query<ID2D1DeviceContext>();
|
||||
deviceContext->DrawImage(affineTransformEffect.get(), D2D1_INTERPOLATION_MODE_LINEAR);
|
||||
|
||||
// Draw text box border rectangle
|
||||
rt->DrawRoundedRectangle(textBoxRect, solidBrushes[Brush::border].get());
|
||||
const float TEXT_BOX_PADDING = 1.f * dpiScale;
|
||||
textBoxRect.rect.bottom -= TEXT_BOX_PADDING;
|
||||
textBoxRect.rect.top += TEXT_BOX_PADDING;
|
||||
textBoxRect.rect.left += TEXT_BOX_PADDING;
|
||||
textBoxRect.rect.right -= TEXT_BOX_PADDING;
|
||||
|
||||
// Draw text & its box
|
||||
rt->FillRoundedRectangle(textBoxRect, solidBrushes[Brush::background].get());
|
||||
|
||||
if (halfOpaqueSymbolPos.has_value())
|
||||
{
|
||||
DWRITE_TEXT_RANGE textRange = { static_cast<uint32_t>(*halfOpaqueSymbolPos), 2 };
|
||||
auto opacityEffect = winrt::make_self<OpacityEffect>();
|
||||
opacityEffect->alpha = consts::CROSS_OPACITY;
|
||||
winrt::check_hresult(textLayout->SetDrawingEffect(opacityEffect.get(), textRange));
|
||||
}
|
||||
winrt::check_hresult(textLayout->Draw(nullptr, textRenderer.get(), textRect.left, textRect.top));
|
||||
}
|
||||
42
src/modules/MeasureTool/MeasureToolCore/D2DState.h
Normal file
42
src/modules/MeasureTool/MeasureToolCore/D2DState.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
#include <d2d1_3.h>
|
||||
#include <wil/com.h>
|
||||
#include <windef.h>
|
||||
|
||||
#include "PerGlyphOpacityTextRender.h"
|
||||
|
||||
enum Brush : size_t
|
||||
{
|
||||
line,
|
||||
foreground,
|
||||
background,
|
||||
border
|
||||
};
|
||||
|
||||
struct D2DState
|
||||
{
|
||||
wil::com_ptr<ID2D1Factory> d2dFactory;
|
||||
wil::com_ptr<IDWriteFactory> writeFactory;
|
||||
wil::com_ptr<ID2D1HwndRenderTarget> rt;
|
||||
wil::com_ptr<ID2D1BitmapRenderTarget> bitmapRt;
|
||||
wil::com_ptr<IDWriteTextFormat> textFormat;
|
||||
winrt::com_ptr<PerGlyphOpacityTextRender> textRenderer;
|
||||
std::vector<wil::com_ptr<ID2D1SolidColorBrush>> solidBrushes;
|
||||
wil::com_ptr<ID2D1Effect> shadowEffect;
|
||||
wil::com_ptr<ID2D1Effect> affineTransformEffect;
|
||||
|
||||
float dpiScale = 1.f;
|
||||
|
||||
D2DState(const HWND window, std::vector<D2D1::ColorF> solidBrushesColors);
|
||||
void DrawTextBox(const wchar_t* text,
|
||||
const uint32_t textLen,
|
||||
const std::optional<size_t> halfOpaqueSymbolPos,
|
||||
const float centerX,
|
||||
const float centerY,
|
||||
const bool screenQuadrantAware,
|
||||
const HWND window) const;
|
||||
};
|
||||
112
src/modules/MeasureTool/MeasureToolCore/EdgeDetection.cpp
Normal file
112
src/modules/MeasureTool/MeasureToolCore/EdgeDetection.cpp
Normal file
@@ -0,0 +1,112 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include "constants.h"
|
||||
#include "EdgeDetection.h"
|
||||
template<bool PerChannel,
|
||||
bool ContinuousCapture,
|
||||
bool IsX,
|
||||
bool Increment>
|
||||
inline long FindEdge(const BGRATextureView& texture, const POINT centerPoint, const uint8_t tolerance)
|
||||
{
|
||||
using namespace consts;
|
||||
|
||||
long xOffset = 0;
|
||||
long yOffset = 0;
|
||||
|
||||
// For continuous capture, we'll be a bit off center from the cursor so the cross we draw won't interfere with the measurement.
|
||||
if constexpr (ContinuousCapture)
|
||||
{
|
||||
if constexpr (IsX)
|
||||
{
|
||||
xOffset = Increment ? CURSOR_OFFSET_AMOUNT_X : -CURSOR_OFFSET_AMOUNT_X;
|
||||
yOffset = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
xOffset = 1;
|
||||
yOffset = Increment ? CURSOR_OFFSET_AMOUNT_Y : -CURSOR_OFFSET_AMOUNT_Y;
|
||||
}
|
||||
}
|
||||
|
||||
const size_t maxDim = IsX ? texture.width : texture.height;
|
||||
|
||||
long x = std::clamp<long>(centerPoint.x + xOffset, 1, static_cast<long>(texture.width - 2));
|
||||
long y = std::clamp<long>(centerPoint.y + yOffset, 1, static_cast<long>(texture.height - 2));
|
||||
|
||||
const uint32_t startPixel = texture.GetPixel(x, y);
|
||||
while (true)
|
||||
{
|
||||
long oldX = x;
|
||||
long oldY = y;
|
||||
if constexpr (IsX)
|
||||
{
|
||||
if constexpr (Increment)
|
||||
{
|
||||
if (++x == maxDim)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (--x == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if constexpr (Increment)
|
||||
{
|
||||
if (++y == maxDim)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (--y == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const uint32_t nextPixel = texture.GetPixel(x, y);
|
||||
if (!texture.PixelsClose<PerChannel>(startPixel, nextPixel, tolerance))
|
||||
{
|
||||
return IsX ? oldX : oldY;
|
||||
}
|
||||
}
|
||||
|
||||
return Increment ? static_cast<long>(IsX ? texture.width : texture.height) - 1 : 0;
|
||||
}
|
||||
|
||||
template<bool PerChannel, bool ContinuousCapture>
|
||||
inline RECT DetectEdgesInternal(const BGRATextureView& texture,
|
||||
const POINT centerPoint,
|
||||
const uint8_t tolerance)
|
||||
{
|
||||
return RECT{ .left = FindEdge<PerChannel,
|
||||
ContinuousCapture,
|
||||
true,
|
||||
false>(texture, centerPoint, tolerance),
|
||||
.top = FindEdge<PerChannel,
|
||||
ContinuousCapture,
|
||||
false,
|
||||
false>(texture, centerPoint, tolerance),
|
||||
.right = FindEdge<PerChannel,
|
||||
ContinuousCapture,
|
||||
true,
|
||||
true>(texture, centerPoint, tolerance),
|
||||
.bottom = FindEdge<PerChannel,
|
||||
ContinuousCapture,
|
||||
false,
|
||||
true>(texture, centerPoint, tolerance) };
|
||||
}
|
||||
|
||||
RECT DetectEdges(const BGRATextureView& texture,
|
||||
const POINT centerPoint,
|
||||
const bool perChannel,
|
||||
const uint8_t tolerance,
|
||||
const bool continuousCapture)
|
||||
{
|
||||
auto function = perChannel ? &DetectEdgesInternal<true, false> : DetectEdgesInternal<false, false>;
|
||||
if (continuousCapture)
|
||||
function = perChannel ? &DetectEdgesInternal<true, true> : &DetectEdgesInternal<false, true>;
|
||||
|
||||
return function(texture, centerPoint, tolerance);
|
||||
}
|
||||
9
src/modules/MeasureTool/MeasureToolCore/EdgeDetection.h
Normal file
9
src/modules/MeasureTool/MeasureToolCore/EdgeDetection.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "BGRATextureView.h"
|
||||
|
||||
RECT DetectEdges(const BGRATextureView& texture,
|
||||
const POINT centerPoint,
|
||||
const bool perChannel,
|
||||
const uint8_t tolerance,
|
||||
const bool continuousCapture);
|
||||
3
src/modules/MeasureTool/MeasureToolCore/MeasureTool.def
Normal file
3
src/modules/MeasureTool/MeasureToolCore/MeasureTool.def
Normal file
@@ -0,0 +1,3 @@
|
||||
EXPORTS
|
||||
DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE
|
||||
DllGetActivationFactory = WINRT_GetActivationFactory PRIVATE
|
||||
300
src/modules/MeasureTool/MeasureToolCore/MeasureToolOverlayUI.cpp
Normal file
300
src/modules/MeasureTool/MeasureToolCore/MeasureToolOverlayUI.cpp
Normal file
@@ -0,0 +1,300 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include "BGRATextureView.h"
|
||||
#include "Clipboard.h"
|
||||
#include "CoordinateSystemConversion.h"
|
||||
#include "constants.h"
|
||||
#include "MeasureToolOverlayUI.h"
|
||||
|
||||
#include <common/utils/window.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
inline std::pair<D2D_POINT_2F, D2D_POINT_2F> ComputeCrossFeetLine(D2D_POINT_2F center, const bool horizontal)
|
||||
{
|
||||
D2D_POINT_2F start = center, end = center;
|
||||
// Computing in this way to achieve pixel-perfect axial symmetry of aliased D2D lines
|
||||
if (horizontal)
|
||||
{
|
||||
start.x -= consts::FEET_HALF_LENGTH + 1.f;
|
||||
end.x += consts::FEET_HALF_LENGTH;
|
||||
|
||||
start.y += 1.f;
|
||||
end.y += 1.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
start.y -= consts::FEET_HALF_LENGTH + 1.f;
|
||||
end.y += consts::FEET_HALF_LENGTH;
|
||||
|
||||
start.x += 1.f;
|
||||
end.x += 1.f;
|
||||
}
|
||||
|
||||
return { start, end };
|
||||
}
|
||||
}
|
||||
|
||||
winrt::com_ptr<ID2D1Bitmap> ConvertID3D11Texture2DToD2D1Bitmap(wil::com_ptr<ID2D1HwndRenderTarget> rt,
|
||||
winrt::com_ptr<ID3D11Texture2D> texture)
|
||||
{
|
||||
std::lock_guard guard{ gpuAccessLock };
|
||||
|
||||
auto dxgiSurface = texture.try_as<IDXGISurface>();
|
||||
if (!dxgiSurface)
|
||||
return nullptr;
|
||||
|
||||
DXGI_MAPPED_RECT bitmap2Dmap = {};
|
||||
HRESULT hr = dxgiSurface->Map(&bitmap2Dmap, DXGI_MAP_READ);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
D2D1_BITMAP_PROPERTIES props = { .pixelFormat = rt->GetPixelFormat() };
|
||||
rt->GetDpi(&props.dpiX, &props.dpiY);
|
||||
const auto sizeF = rt->GetSize();
|
||||
winrt::com_ptr<ID2D1Bitmap> bitmap;
|
||||
if (FAILED(rt->CreateBitmap(D2D1::SizeU(static_cast<uint32_t>(sizeF.width),
|
||||
static_cast<uint32_t>(sizeF.height)),
|
||||
bitmap2Dmap.pBits,
|
||||
bitmap2Dmap.Pitch,
|
||||
props,
|
||||
bitmap.put())))
|
||||
return nullptr;
|
||||
if (FAILED(dxgiSurface->Unmap()))
|
||||
return nullptr;
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
LRESULT CALLBACK MeasureToolWndProc(HWND window, UINT message, WPARAM wparam, LPARAM lparam) noexcept
|
||||
{
|
||||
switch (message)
|
||||
{
|
||||
case WM_CURSOR_LEFT_MONITOR:
|
||||
{
|
||||
if (auto state = GetWindowParam<Serialized<MeasureToolState>*>(window))
|
||||
{
|
||||
state->Access([&](MeasureToolState& s) {
|
||||
s.perScreen[window].measuredEdges = {};
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WM_NCHITTEST:
|
||||
return HTCLIENT;
|
||||
case WM_CREATE:
|
||||
{
|
||||
auto state = GetWindowCreateParam<Serialized<MeasureToolState>*>(lparam);
|
||||
StoreWindowParam(window, state);
|
||||
|
||||
#if !defined(DEBUG_OVERLAY)
|
||||
for (; ShowCursor(false) > 0;)
|
||||
;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case WM_ERASEBKGND:
|
||||
return 1;
|
||||
case WM_KEYUP:
|
||||
if (wparam == VK_ESCAPE)
|
||||
{
|
||||
PostMessageW(window, WM_CLOSE, {}, {});
|
||||
}
|
||||
break;
|
||||
case WM_RBUTTONUP:
|
||||
PostMessageW(window, WM_CLOSE, {}, {});
|
||||
break;
|
||||
case WM_LBUTTONUP:
|
||||
if (auto state = GetWindowParam<Serialized<MeasureToolState>*>(window))
|
||||
{
|
||||
state->Read([](const MeasureToolState& s) { s.commonState->overlayBoxText.Read([](const OverlayBoxText& text) {
|
||||
SetClipBoardToText(text.buffer);
|
||||
}); });
|
||||
}
|
||||
break;
|
||||
case WM_MOUSEWHEEL:
|
||||
if (auto state = GetWindowParam<Serialized<MeasureToolState>*>(window))
|
||||
{
|
||||
const int8_t step = static_cast<short>(HIWORD(wparam)) < 0 ? -consts::MOUSE_WHEEL_TOLERANCE_STEP : consts::MOUSE_WHEEL_TOLERANCE_STEP;
|
||||
state->Access([step](MeasureToolState& s) {
|
||||
int wideVal = s.global.pixelTolerance;
|
||||
wideVal += step;
|
||||
s.global.pixelTolerance = static_cast<uint8_t>(std::clamp(wideVal, 0, 255));
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return DefWindowProcW(window, message, wparam, lparam);
|
||||
}
|
||||
|
||||
void DrawMeasureToolTick(const CommonState& commonState,
|
||||
Serialized<MeasureToolState>& toolState,
|
||||
HWND window,
|
||||
D2DState& d2dState)
|
||||
{
|
||||
bool continuousCapture = {};
|
||||
bool drawFeetOnCross = {};
|
||||
bool drawHorizontalCrossLine = true;
|
||||
bool drawVerticalCrossLine = true;
|
||||
RECT measuredEdges{};
|
||||
MeasureToolState::Mode mode = {};
|
||||
winrt::com_ptr<ID2D1Bitmap> backgroundBitmap;
|
||||
winrt::com_ptr<ID3D11Texture2D> backgroundTextureToConvert;
|
||||
|
||||
toolState.Read([&](const MeasureToolState& state) {
|
||||
continuousCapture = state.global.continuousCapture;
|
||||
drawFeetOnCross = state.global.drawFeetOnCross;
|
||||
mode = state.global.mode;
|
||||
|
||||
if (auto it = state.perScreen.find(window); it != end(state.perScreen))
|
||||
{
|
||||
const auto& perScreen = it->second;
|
||||
measuredEdges = perScreen.measuredEdges;
|
||||
|
||||
if (continuousCapture)
|
||||
return;
|
||||
|
||||
if (perScreen.capturedScreenBitmap)
|
||||
{
|
||||
backgroundBitmap = perScreen.capturedScreenBitmap;
|
||||
}
|
||||
else if (perScreen.capturedScreenTexture)
|
||||
{
|
||||
backgroundTextureToConvert = perScreen.capturedScreenTexture;
|
||||
}
|
||||
}
|
||||
});
|
||||
switch (mode)
|
||||
{
|
||||
case MeasureToolState::Mode::Cross:
|
||||
drawHorizontalCrossLine = true;
|
||||
drawVerticalCrossLine = true;
|
||||
break;
|
||||
case MeasureToolState::Mode::Vertical:
|
||||
drawHorizontalCrossLine = false;
|
||||
drawVerticalCrossLine = true;
|
||||
break;
|
||||
case MeasureToolState::Mode::Horizontal:
|
||||
drawHorizontalCrossLine = true;
|
||||
drawVerticalCrossLine = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!continuousCapture && !backgroundBitmap && backgroundTextureToConvert)
|
||||
{
|
||||
backgroundBitmap = ConvertID3D11Texture2DToD2D1Bitmap(d2dState.rt, backgroundTextureToConvert);
|
||||
if (backgroundBitmap)
|
||||
{
|
||||
toolState.Access([&](MeasureToolState& state) {
|
||||
state.perScreen[window].capturedScreenTexture = {};
|
||||
state.perScreen[window].capturedScreenBitmap = backgroundBitmap;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (continuousCapture || !backgroundBitmap)
|
||||
d2dState.rt->Clear();
|
||||
|
||||
// Add 1px to each dim, since the range we obtain from measuredEdges is inclusive.
|
||||
const float hMeasure = static_cast<float>(measuredEdges.right - measuredEdges.left + 1);
|
||||
const float vMeasure = static_cast<float>(measuredEdges.bottom - measuredEdges.top + 1);
|
||||
|
||||
// Prevent drawing until we get the first capture
|
||||
const bool hasMeasure = (measuredEdges.right != measuredEdges.left) && (measuredEdges.bottom != measuredEdges.top);
|
||||
if (!hasMeasure)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!continuousCapture && backgroundBitmap)
|
||||
{
|
||||
d2dState.rt->DrawBitmap(backgroundBitmap.get());
|
||||
}
|
||||
|
||||
const auto previousAliasingMode = d2dState.rt->GetAntialiasMode();
|
||||
// Anti-aliasing is creating artifacts. Aliasing is for drawing straight lines.
|
||||
d2dState.rt->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
|
||||
|
||||
const auto cursorPos = convert::FromSystemToRelativeForDirect2D(window, commonState.cursorPosSystemSpace);
|
||||
|
||||
if (drawHorizontalCrossLine)
|
||||
{
|
||||
const D2D_POINT_2F hLineStart{ .x = static_cast<float>(measuredEdges.left), .y = static_cast<float>(cursorPos.y) };
|
||||
D2D_POINT_2F hLineEnd{ .x = hLineStart.x + hMeasure, .y = hLineStart.y };
|
||||
d2dState.rt->DrawLine(hLineStart, hLineEnd, d2dState.solidBrushes[Brush::line].get());
|
||||
|
||||
if (drawFeetOnCross && !continuousCapture)
|
||||
{
|
||||
// To fill all pixels which are close, we call DrawLine with end point one pixel too far, since
|
||||
// it doesn't get filled, i.e. end point of the range is excluded. However, we want to draw cross
|
||||
// feet *on* the last pixel row, so we must subtract 1px from the corresponding axis.
|
||||
hLineEnd.x -= 1.f;
|
||||
auto [left_start, left_end] = ComputeCrossFeetLine(hLineStart, false);
|
||||
auto [right_start, right_end] = ComputeCrossFeetLine(hLineEnd, false);
|
||||
d2dState.rt->DrawLine(left_start, left_end, d2dState.solidBrushes[Brush::line].get());
|
||||
d2dState.rt->DrawLine(right_start, right_end, d2dState.solidBrushes[Brush::line].get());
|
||||
}
|
||||
}
|
||||
|
||||
if (drawVerticalCrossLine)
|
||||
{
|
||||
const D2D_POINT_2F vLineStart{ .x = static_cast<float>(cursorPos.x), .y = static_cast<float>(measuredEdges.top) };
|
||||
D2D_POINT_2F vLineEnd{ .x = vLineStart.x, .y = vLineStart.y + vMeasure };
|
||||
d2dState.rt->DrawLine(vLineStart, vLineEnd, d2dState.solidBrushes[Brush::line].get());
|
||||
|
||||
if (drawFeetOnCross && !continuousCapture)
|
||||
{
|
||||
vLineEnd.y -= 1.f;
|
||||
auto [top_start, top_end] = ComputeCrossFeetLine(vLineStart, true);
|
||||
auto [bottom_start, bottom_end] = ComputeCrossFeetLine(vLineEnd, true);
|
||||
d2dState.rt->DrawLine(top_start, top_end, d2dState.solidBrushes[Brush::line].get());
|
||||
d2dState.rt->DrawLine(bottom_start, bottom_end, d2dState.solidBrushes[Brush::line].get());
|
||||
}
|
||||
}
|
||||
|
||||
// After drawing the lines, restore anti aliasing to draw the measurement tooltip.
|
||||
d2dState.rt->SetAntialiasMode(previousAliasingMode);
|
||||
|
||||
uint32_t measureStringBufLen = 0;
|
||||
|
||||
OverlayBoxText text;
|
||||
std::optional<size_t> crossSymbolPos;
|
||||
switch (mode)
|
||||
{
|
||||
case MeasureToolState::Mode::Cross:
|
||||
measureStringBufLen = swprintf_s(text.buffer.data(),
|
||||
text.buffer.size(),
|
||||
L"%.0f × %.0f",
|
||||
hMeasure,
|
||||
vMeasure);
|
||||
crossSymbolPos = wcschr(text.buffer.data(), L' ') - text.buffer.data() + 1;
|
||||
break;
|
||||
case MeasureToolState::Mode::Vertical:
|
||||
measureStringBufLen = swprintf_s(text.buffer.data(),
|
||||
text.buffer.size(),
|
||||
L"%.0f",
|
||||
vMeasure);
|
||||
break;
|
||||
case MeasureToolState::Mode::Horizontal:
|
||||
measureStringBufLen = swprintf_s(text.buffer.data(),
|
||||
text.buffer.size(),
|
||||
L"%.0f",
|
||||
hMeasure);
|
||||
break;
|
||||
}
|
||||
|
||||
commonState.overlayBoxText.Access([&](OverlayBoxText& v) {
|
||||
v = text;
|
||||
});
|
||||
|
||||
d2dState.DrawTextBox(text.buffer.data(),
|
||||
measureStringBufLen,
|
||||
crossSymbolPos,
|
||||
static_cast<float>(cursorPos.x),
|
||||
static_cast<float>(cursorPos.y),
|
||||
true,
|
||||
window);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
#include "D2DState.h"
|
||||
#include "ToolState.h"
|
||||
|
||||
#include <common/utils/serialized.h>
|
||||
|
||||
void DrawMeasureToolTick(const CommonState& commonState,
|
||||
Serialized<MeasureToolState>& toolState,
|
||||
HWND overlayWindow,
|
||||
D2DState& d2dState);
|
||||
|
||||
LRESULT CALLBACK MeasureToolWndProc(HWND window, UINT message, WPARAM wparam, LPARAM lparam) noexcept;
|
||||
231
src/modules/MeasureTool/MeasureToolCore/OverlayUI.cpp
Normal file
231
src/modules/MeasureTool/MeasureToolCore/OverlayUI.cpp
Normal file
@@ -0,0 +1,231 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include "BoundsToolOverlayUI.h"
|
||||
#include "MeasureToolOverlayUI.h"
|
||||
#include "OverlayUI.h"
|
||||
|
||||
#include <common/Display/dpi_aware.h>
|
||||
#include <common/Display/monitors.h>
|
||||
#include <common/logger/logger.h>
|
||||
#include <common/Themes/windows_colors.h>
|
||||
#include <common/utils/window.h>
|
||||
|
||||
namespace NonLocalizable
|
||||
{
|
||||
const wchar_t MeasureToolOverlayWindowName[] = L"PowerToys.MeasureToolOverlayWindow";
|
||||
const wchar_t BoundsToolOverlayWindowName[] = L"PowerToys.BoundsToolOverlayWindow";
|
||||
}
|
||||
|
||||
void CreateOverlayWindowClasses()
|
||||
{
|
||||
WNDCLASSEXW wcex{ .cbSize = sizeof(WNDCLASSEX), .hInstance = GetModuleHandleW(nullptr) };
|
||||
|
||||
wcex.lpfnWndProc = MeasureToolWndProc;
|
||||
wcex.lpszClassName = NonLocalizable::MeasureToolOverlayWindowName;
|
||||
RegisterClassExW(&wcex);
|
||||
|
||||
wcex.lpfnWndProc = BoundsToolWndProc;
|
||||
wcex.lpszClassName = NonLocalizable::BoundsToolOverlayWindowName;
|
||||
wcex.hCursor = LoadCursorW(nullptr, IDC_CROSS);
|
||||
RegisterClassExW(&wcex);
|
||||
}
|
||||
|
||||
HWND CreateOverlayUIWindow(const CommonState& commonState,
|
||||
const MonitorInfo& monitor,
|
||||
const wchar_t* windowClass,
|
||||
void* extraParam)
|
||||
{
|
||||
static std::once_flag windowClassesCreatedFlag;
|
||||
std::call_once(windowClassesCreatedFlag, CreateOverlayWindowClasses);
|
||||
|
||||
const auto screenArea = monitor.GetScreenSize(true);
|
||||
HWND window{ CreateWindowExW(WS_EX_TOOLWINDOW | WS_EX_TOPMOST,
|
||||
windowClass,
|
||||
L"PowerToys.MeasureToolOverlay",
|
||||
WS_POPUP,
|
||||
screenArea.left(),
|
||||
screenArea.top(),
|
||||
screenArea.width(),
|
||||
screenArea.height(),
|
||||
HWND_DESKTOP,
|
||||
nullptr,
|
||||
GetModuleHandleW(nullptr),
|
||||
extraParam) };
|
||||
winrt::check_bool(window);
|
||||
ShowWindow(window, SW_SHOWNORMAL);
|
||||
#if !defined(DEBUG_OVERLAY)
|
||||
SetWindowPos(window, HWND_TOPMOST, {}, {}, {}, {}, SWP_NOMOVE | SWP_NOSIZE);
|
||||
#else
|
||||
(void)window;
|
||||
#endif
|
||||
|
||||
const int pos = -GetSystemMetrics(SM_CXVIRTUALSCREEN) - 8;
|
||||
if (wil::unique_hrgn hrgn{ CreateRectRgn(pos, 0, (pos + 1), 1) })
|
||||
{
|
||||
DWM_BLURBEHIND bh = { DWM_BB_ENABLE | DWM_BB_BLURREGION, TRUE, hrgn.get(), FALSE };
|
||||
DwmEnableBlurBehindWindow(window, &bh);
|
||||
}
|
||||
|
||||
RECT windowRect = {};
|
||||
// Exclude toolbar from the window's region to be able to use toolbar during tool usage.
|
||||
if (monitor.IsPrimary() && GetWindowRect(window, &windowRect))
|
||||
{
|
||||
// will be freed during SetWindowRgn call
|
||||
const HRGN windowRegion{ CreateRectRgn(windowRect.left, windowRect.top, windowRect.right, windowRect.bottom) };
|
||||
wil::unique_hrgn toolbarRegion{ CreateRectRgn(commonState.toolbarBoundingBox.left(),
|
||||
commonState.toolbarBoundingBox.top(),
|
||||
commonState.toolbarBoundingBox.right(),
|
||||
commonState.toolbarBoundingBox.bottom()) };
|
||||
const auto res = CombineRgn(windowRegion, windowRegion, toolbarRegion.get(), RGN_DIFF);
|
||||
if (res != ERROR)
|
||||
SetWindowRgn(window, windowRegion, true);
|
||||
}
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
std::vector<D2D1::ColorF> AppendCommonOverlayUIColors(const D2D1::ColorF& lineColor)
|
||||
{
|
||||
D2D1::ColorF foreground = D2D1::ColorF::Black;
|
||||
D2D1::ColorF background = D2D1::ColorF(0.96f, 0.96f, 0.96f, 1.0f);
|
||||
D2D1::ColorF border = D2D1::ColorF(0.44f, 0.44f, 0.44f, 0.4f);
|
||||
|
||||
if (WindowsColors::is_dark_mode())
|
||||
{
|
||||
foreground = D2D1::ColorF::White;
|
||||
background = D2D1::ColorF(0.17f, 0.17f, 0.17f, 1.0f);
|
||||
border = D2D1::ColorF(0.44f, 0.44f, 0.44f, 0.4f);
|
||||
}
|
||||
|
||||
return { lineColor, foreground, background, border };
|
||||
}
|
||||
|
||||
void OverlayUIState::RunUILoop()
|
||||
{
|
||||
while (IsWindow(_window) && !_commonState.closeOnOtherMonitors)
|
||||
{
|
||||
const auto cursor = _commonState.cursorPosSystemSpace;
|
||||
const bool cursorOnScreen = _monitorArea.inside(cursor);
|
||||
const bool cursorOverToolbar = _commonState.toolbarBoundingBox.inside(cursor);
|
||||
|
||||
if (cursorOnScreen != _cursorOnScreen)
|
||||
{
|
||||
_cursorOnScreen = cursorOnScreen;
|
||||
if (!cursorOnScreen)
|
||||
{
|
||||
if (_clearOnCursorLeavingScreen)
|
||||
{
|
||||
_d2dState.rt->BeginDraw();
|
||||
_d2dState.rt->Clear();
|
||||
_d2dState.rt->EndDraw();
|
||||
}
|
||||
PostMessageW(_window, WM_CURSOR_LEFT_MONITOR, {}, {});
|
||||
}
|
||||
}
|
||||
if (cursorOnScreen)
|
||||
{
|
||||
_d2dState.rt->BeginDraw();
|
||||
if (!cursorOverToolbar)
|
||||
_tickFunc();
|
||||
else
|
||||
_d2dState.rt->Clear();
|
||||
|
||||
{
|
||||
// TODO: use latch to wait until all threads are created their corresponding d2d textures
|
||||
// in the non-continuous mode
|
||||
// std::lock_guard guard{ gpuAccessLock };
|
||||
_d2dState.rt->EndDraw();
|
||||
}
|
||||
}
|
||||
|
||||
run_message_loop(true, 1);
|
||||
}
|
||||
|
||||
DestroyWindow(_window);
|
||||
}
|
||||
|
||||
template<typename StateT, typename TickFuncT>
|
||||
OverlayUIState::OverlayUIState(StateT& toolState,
|
||||
TickFuncT tickFunc,
|
||||
const CommonState& commonState,
|
||||
HWND window) :
|
||||
_window{ window },
|
||||
_commonState{ commonState },
|
||||
_d2dState{ window, AppendCommonOverlayUIColors(commonState.lineColor) },
|
||||
_tickFunc{ [this, tickFunc, &toolState] {
|
||||
tickFunc(_commonState, toolState, _window, _d2dState);
|
||||
} }
|
||||
{
|
||||
}
|
||||
|
||||
OverlayUIState::~OverlayUIState()
|
||||
{
|
||||
PostMessageW(_window, WM_CLOSE, {}, {});
|
||||
try
|
||||
{
|
||||
if (_uiThread.joinable())
|
||||
_uiThread.join();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
// Returning unique_ptr, since we need to pin ui state in memory
|
||||
template<typename ToolT, typename TickFuncT>
|
||||
inline std::unique_ptr<OverlayUIState> OverlayUIState::CreateInternal(ToolT& toolState,
|
||||
TickFuncT tickFunc,
|
||||
CommonState& commonState,
|
||||
const wchar_t* toolWindowClassName,
|
||||
void* windowParam,
|
||||
const MonitorInfo& monitor,
|
||||
const bool clearOnCursorLeavingScreen)
|
||||
{
|
||||
wil::shared_event uiCreatedEvent(wil::EventOptions::ManualReset);
|
||||
std::unique_ptr<OverlayUIState> uiState;
|
||||
auto threadHandle = SpawnLoggedThread(L"OverlayUI thread", [&] {
|
||||
const HWND window = CreateOverlayUIWindow(commonState, monitor, toolWindowClassName, windowParam);
|
||||
uiState = std::unique_ptr<OverlayUIState>{ new OverlayUIState{ toolState, tickFunc, commonState, window } };
|
||||
uiState->_monitorArea = monitor.GetScreenSize(true);
|
||||
uiState->_clearOnCursorLeavingScreen = clearOnCursorLeavingScreen;
|
||||
// we must create window + d2d state in the same thread, then store thread handle in uiState, thus
|
||||
// lifetime is ok here, since we join the thread in destructor
|
||||
auto* state = uiState.get();
|
||||
uiCreatedEvent.SetEvent();
|
||||
|
||||
state->RunUILoop();
|
||||
|
||||
commonState.closeOnOtherMonitors = true;
|
||||
commonState.sessionCompletedCallback();
|
||||
});
|
||||
|
||||
uiCreatedEvent.wait();
|
||||
uiState->_uiThread = std::move(threadHandle);
|
||||
return uiState;
|
||||
}
|
||||
|
||||
std::unique_ptr<OverlayUIState> OverlayUIState::Create(Serialized<MeasureToolState>& toolState,
|
||||
CommonState& commonState,
|
||||
const MonitorInfo& monitor)
|
||||
{
|
||||
return OverlayUIState::CreateInternal(toolState,
|
||||
DrawMeasureToolTick,
|
||||
commonState,
|
||||
NonLocalizable::MeasureToolOverlayWindowName,
|
||||
&toolState,
|
||||
monitor,
|
||||
true);
|
||||
}
|
||||
|
||||
std::unique_ptr<OverlayUIState> OverlayUIState::Create(BoundsToolState& toolState,
|
||||
CommonState& commonState,
|
||||
const MonitorInfo& monitor)
|
||||
{
|
||||
return OverlayUIState::CreateInternal(toolState,
|
||||
DrawBoundsToolTick,
|
||||
commonState,
|
||||
NonLocalizable::BoundsToolOverlayWindowName,
|
||||
&toolState,
|
||||
monitor,
|
||||
false);
|
||||
}
|
||||
51
src/modules/MeasureTool/MeasureToolCore/OverlayUI.h
Normal file
51
src/modules/MeasureTool/MeasureToolCore/OverlayUI.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
#include "D2DState.h"
|
||||
#include "ToolState.h"
|
||||
|
||||
#include <common/display/monitors.h>
|
||||
#include <common/utils/serialized.h>
|
||||
|
||||
class OverlayUIState final
|
||||
{
|
||||
template<typename StateT, typename TickFuncT>
|
||||
OverlayUIState(StateT& toolState,
|
||||
TickFuncT tickFunc,
|
||||
const CommonState& commonState,
|
||||
HWND window);
|
||||
|
||||
Box _monitorArea;
|
||||
HWND _window = {};
|
||||
const CommonState& _commonState;
|
||||
D2DState _d2dState;
|
||||
std::function<void()> _tickFunc;
|
||||
std::thread _uiThread;
|
||||
bool _cursorOnScreen = true;
|
||||
bool _clearOnCursorLeavingScreen = false;
|
||||
|
||||
template<typename ToolT, typename TickFuncT>
|
||||
static std::unique_ptr<OverlayUIState> CreateInternal(ToolT& toolState,
|
||||
TickFuncT tickFunc,
|
||||
CommonState& commonState,
|
||||
const wchar_t* toolWindowClassName,
|
||||
void* windowParam,
|
||||
const MonitorInfo& monitor,
|
||||
const bool clearOnCursorLeavingScreen);
|
||||
|
||||
public:
|
||||
OverlayUIState(OverlayUIState&&) noexcept = default;
|
||||
~OverlayUIState();
|
||||
|
||||
static std::unique_ptr<OverlayUIState> Create(BoundsToolState& toolState,
|
||||
CommonState& commonState,
|
||||
const MonitorInfo& monitor);
|
||||
static std::unique_ptr<OverlayUIState> Create(Serialized<MeasureToolState>& toolState,
|
||||
CommonState& commonState,
|
||||
const MonitorInfo& monitor);
|
||||
inline HWND overlayWindowHandle() const
|
||||
{
|
||||
return _window;
|
||||
}
|
||||
|
||||
void RunUILoop();
|
||||
};
|
||||
@@ -0,0 +1,141 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include "PerGlyphOpacityTextRender.h"
|
||||
|
||||
PerGlyphOpacityTextRender::PerGlyphOpacityTextRender(
|
||||
wil::com_ptr<ID2D1Factory> pD2DFactory,
|
||||
wil::com_ptr<ID2D1HwndRenderTarget> rt,
|
||||
wil::com_ptr<ID2D1SolidColorBrush> baseBrush) :
|
||||
_pD2DFactory{ pD2DFactory },
|
||||
_rt{ rt },
|
||||
_baseBrush{ baseBrush }
|
||||
{
|
||||
}
|
||||
|
||||
HRESULT __stdcall PerGlyphOpacityTextRender::DrawGlyphRun(void* /*clientDrawingContext*/,
|
||||
FLOAT baselineOriginX,
|
||||
FLOAT baselineOriginY,
|
||||
DWRITE_MEASURING_MODE measuringMode,
|
||||
_In_ const DWRITE_GLYPH_RUN* glyphRun,
|
||||
_In_ const DWRITE_GLYPH_RUN_DESCRIPTION* /*glyphRunDescription*/,
|
||||
IUnknown* clientDrawingEffect) noexcept
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
if (!clientDrawingEffect)
|
||||
{
|
||||
_rt->DrawGlyphRun(D2D1_POINT_2F{ .x = baselineOriginX, .y = baselineOriginY }, glyphRun, _baseBrush.get(), measuringMode);
|
||||
return hr;
|
||||
}
|
||||
// Create the path geometry.
|
||||
wil::com_ptr<ID2D1PathGeometry> pathGeometry;
|
||||
hr = _pD2DFactory->CreatePathGeometry(&pathGeometry);
|
||||
|
||||
// Write to the path geometry using the geometry sink.
|
||||
ID2D1GeometrySink* pSink = nullptr;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = pathGeometry->Open(&pSink);
|
||||
}
|
||||
|
||||
// Get the glyph run outline geometries back from DirectWrite and place them within the
|
||||
// geometry sink.
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = glyphRun->fontFace->GetGlyphRunOutline(
|
||||
glyphRun->fontEmSize,
|
||||
glyphRun->glyphIndices,
|
||||
glyphRun->glyphAdvances,
|
||||
glyphRun->glyphOffsets,
|
||||
glyphRun->glyphCount,
|
||||
glyphRun->isSideways,
|
||||
glyphRun->bidiLevel % 2,
|
||||
pSink);
|
||||
}
|
||||
|
||||
// Close the geometry sink
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = pSink->Close();
|
||||
}
|
||||
|
||||
// Initialize a matrix to translate the origin of the glyph run.
|
||||
D2D1::Matrix3x2F const matrix = D2D1::Matrix3x2F(
|
||||
1.0f, 0.0f, 0.0f, 1.0f, baselineOriginX, baselineOriginY);
|
||||
|
||||
// Create the transformed geometry
|
||||
wil::com_ptr<ID2D1TransformedGeometry> pTransformedGeometry;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = _pD2DFactory->CreateTransformedGeometry(pathGeometry.get(), &matrix, &pTransformedGeometry);
|
||||
}
|
||||
|
||||
float prevOpacity = _baseBrush->GetOpacity();
|
||||
OpacityEffect* opacityEffect = nullptr;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = clientDrawingEffect->QueryInterface(__uuidof(IDrawingEffect), reinterpret_cast<void**>(&opacityEffect));
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
_baseBrush->SetOpacity(opacityEffect->alpha);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
_rt->DrawGeometry(pTransformedGeometry.get(), _baseBrush.get());
|
||||
_rt->FillGeometry(pTransformedGeometry.get(), _baseBrush.get());
|
||||
_baseBrush->SetOpacity(prevOpacity);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT __stdcall PerGlyphOpacityTextRender::DrawUnderline(void* /*clientDrawingContext*/,
|
||||
FLOAT /*baselineOriginX*/,
|
||||
FLOAT /*baselineOriginY*/,
|
||||
_In_ const DWRITE_UNDERLINE* /*underline*/,
|
||||
IUnknown* /*clientDrawingEffect*/) noexcept
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT __stdcall PerGlyphOpacityTextRender::DrawStrikethrough(void* /*clientDrawingContext*/,
|
||||
FLOAT /*baselineOriginX*/,
|
||||
FLOAT /*baselineOriginY*/,
|
||||
_In_ const DWRITE_STRIKETHROUGH* /*strikethrough*/,
|
||||
IUnknown* /*clientDrawingEffect*/) noexcept
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT __stdcall PerGlyphOpacityTextRender::DrawInlineObject(void* /*clientDrawingContext*/,
|
||||
FLOAT /*originX*/,
|
||||
FLOAT /*originY*/,
|
||||
IDWriteInlineObject* /*inlineObject*/,
|
||||
BOOL /*isSideways*/,
|
||||
BOOL /*isRightToLeft*/,
|
||||
IUnknown* /*clientDrawingEffect*/) noexcept
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT __stdcall PerGlyphOpacityTextRender::IsPixelSnappingDisabled(void* /*clientDrawingContext*/, BOOL* isDisabled) noexcept
|
||||
{
|
||||
RETURN_HR_IF_NULL(E_INVALIDARG, isDisabled);
|
||||
|
||||
*isDisabled = false;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT __stdcall PerGlyphOpacityTextRender::GetCurrentTransform(void* /*clientDrawingContext*/, DWRITE_MATRIX* transform) noexcept
|
||||
{
|
||||
_rt->GetTransform(reinterpret_cast<D2D1_MATRIX_3X2_F*>(transform));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT __stdcall PerGlyphOpacityTextRender::GetPixelsPerDip(void* /*clientDrawingContext*/, FLOAT* pixelsPerDip) noexcept
|
||||
{
|
||||
_rt->GetDpi(pixelsPerDip, pixelsPerDip);
|
||||
return S_OK;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
#include <winrt/base.h>
|
||||
#include <wil/resource.h>
|
||||
#include <Windows.h>
|
||||
#include <dwrite.h>
|
||||
|
||||
struct __declspec(uuid("{01557C9F-E3DD-4C28-AE64-E731EAB479CC}")) IDrawingEffect : IUnknown
|
||||
{
|
||||
};
|
||||
|
||||
struct OpacityEffect : winrt::implements<OpacityEffect, IDrawingEffect>
|
||||
{
|
||||
float alpha = 1.f;
|
||||
};
|
||||
|
||||
struct PerGlyphOpacityTextRender : winrt::implements<PerGlyphOpacityTextRender, IDWriteTextRenderer>
|
||||
{
|
||||
wil::com_ptr<ID2D1Factory> _pD2DFactory;
|
||||
wil::com_ptr<ID2D1HwndRenderTarget> _rt;
|
||||
wil::com_ptr<ID2D1SolidColorBrush> _baseBrush;
|
||||
|
||||
PerGlyphOpacityTextRender(
|
||||
wil::com_ptr<ID2D1Factory> pD2DFactory,
|
||||
wil::com_ptr<ID2D1HwndRenderTarget> rt,
|
||||
wil::com_ptr<ID2D1SolidColorBrush> baseBrush);
|
||||
|
||||
HRESULT __stdcall DrawGlyphRun(void* clientDrawingContext,
|
||||
FLOAT baselineOriginX,
|
||||
FLOAT baselineOriginY,
|
||||
DWRITE_MEASURING_MODE measuringMode,
|
||||
_In_ const DWRITE_GLYPH_RUN* glyphRun,
|
||||
_In_ const DWRITE_GLYPH_RUN_DESCRIPTION* glyphRunDescription,
|
||||
IUnknown* clientDrawingEffect) noexcept override;
|
||||
HRESULT __stdcall DrawUnderline(void* clientDrawingContext,
|
||||
FLOAT baselineOriginX,
|
||||
FLOAT baselineOriginY,
|
||||
_In_ const DWRITE_UNDERLINE* underline,
|
||||
IUnknown* clientDrawingEffect) noexcept override;
|
||||
HRESULT __stdcall DrawStrikethrough(void* clientDrawingContext,
|
||||
FLOAT baselineOriginX,
|
||||
FLOAT baselineOriginY,
|
||||
_In_ const DWRITE_STRIKETHROUGH* strikethrough,
|
||||
IUnknown* clientDrawingEffect) noexcept override;
|
||||
HRESULT __stdcall DrawInlineObject(void* clientDrawingContext,
|
||||
FLOAT originX,
|
||||
FLOAT originY,
|
||||
IDWriteInlineObject* inlineObject,
|
||||
BOOL isSideways,
|
||||
BOOL isRightToLeft,
|
||||
IUnknown* clientDrawingEffect) noexcept override;
|
||||
HRESULT __stdcall IsPixelSnappingDisabled(void* clientDrawingContext, BOOL* isDisabled) noexcept override;
|
||||
HRESULT __stdcall GetCurrentTransform(void* clientDrawingContext, DWRITE_MATRIX* transform) noexcept override;
|
||||
HRESULT __stdcall GetPixelsPerDip(void* clientDrawingContext, FLOAT* pixelsPerDip) noexcept override;
|
||||
};
|
||||
@@ -0,0 +1,156 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include <common/display/dpi_aware.h>
|
||||
#include <common/display/monitors.h>
|
||||
#include <common/utils/logger_helper.h>
|
||||
#include <common/logger/logger.h>
|
||||
|
||||
#include "../MeasureToolModuleInterface/trace.h"
|
||||
#include "constants.h"
|
||||
#include "PowerToys.MeasureToolCore.h"
|
||||
#include "Core.g.cpp"
|
||||
#include "OverlayUI.h"
|
||||
#include "ScreenCapturing.h"
|
||||
|
||||
//#define DEBUG_PRIMARY_MONITOR_ONLY
|
||||
|
||||
std::recursive_mutex gpuAccessLock;
|
||||
|
||||
namespace winrt::PowerToys::MeasureToolCore::implementation
|
||||
{
|
||||
void Core::MouseCaptureThread()
|
||||
{
|
||||
while (!_stopMouseCaptureThreadSignal.is_signaled())
|
||||
{
|
||||
static_assert(sizeof(_commonState.cursorPosSystemSpace) == sizeof(LONG64));
|
||||
POINT cursorPos = {};
|
||||
GetCursorPos(&cursorPos);
|
||||
InterlockedExchange64(reinterpret_cast<LONG64*>(&_commonState.cursorPosSystemSpace), std::bit_cast<LONG64>(cursorPos));
|
||||
std::this_thread::sleep_for(consts::TARGET_FRAME_DURATION);
|
||||
}
|
||||
}
|
||||
|
||||
Core::Core() :
|
||||
_mouseCaptureThread{ [this] { MouseCaptureThread(); } },
|
||||
_stopMouseCaptureThreadSignal{ wil::EventOptions::ManualReset }
|
||||
{
|
||||
Trace::RegisterProvider();
|
||||
LoggerHelpers::init_logger(L"Measure Tool", L"Core", "Measure Tool");
|
||||
}
|
||||
|
||||
Core::~Core()
|
||||
{
|
||||
_stopMouseCaptureThreadSignal.SetEvent();
|
||||
_mouseCaptureThread.join();
|
||||
|
||||
ResetState();
|
||||
Trace::UnregisterProvider();
|
||||
}
|
||||
|
||||
void Core::ResetState()
|
||||
{
|
||||
_commonState.closeOnOtherMonitors = true;
|
||||
_overlayUIStates.clear();
|
||||
_boundsToolState = { .commonState = &_commonState };
|
||||
for (auto& thread : _screenCaptureThreads)
|
||||
{
|
||||
if (thread.joinable())
|
||||
{
|
||||
thread.join();
|
||||
}
|
||||
}
|
||||
_screenCaptureThreads.clear();
|
||||
_measureToolState.Reset();
|
||||
_measureToolState.Access([&](MeasureToolState& s) {
|
||||
s.commonState = &_commonState;
|
||||
});
|
||||
|
||||
_settings = Settings::LoadFromFile();
|
||||
|
||||
_commonState.lineColor.r = _settings.lineColor[0] / 255.f;
|
||||
_commonState.lineColor.g = _settings.lineColor[1] / 255.f;
|
||||
_commonState.lineColor.b = _settings.lineColor[2] / 255.f;
|
||||
_commonState.closeOnOtherMonitors = false;
|
||||
}
|
||||
|
||||
void Core::StartBoundsTool()
|
||||
{
|
||||
ResetState();
|
||||
|
||||
#if defined(DEBUG_PRIMARY_MONITOR_ONLY)
|
||||
const auto& monitorInfo = MonitorInfo::GetPrimaryMonitor();
|
||||
#else
|
||||
for (const auto& monitorInfo : MonitorInfo::GetMonitors(true))
|
||||
#endif
|
||||
{
|
||||
auto overlayUI = OverlayUIState::Create(_boundsToolState, _commonState, monitorInfo);
|
||||
#if !defined(DEBUG_PRIMARY_MONITOR_ONLY)
|
||||
if (!overlayUI)
|
||||
continue;
|
||||
#endif
|
||||
_overlayUIStates.push_back(std::move(overlayUI));
|
||||
}
|
||||
Trace::BoundsToolActivated();
|
||||
}
|
||||
|
||||
void Core::StartMeasureTool(const bool horizontal, const bool vertical)
|
||||
{
|
||||
ResetState();
|
||||
|
||||
_measureToolState.Access([horizontal, vertical, this](MeasureToolState& state) {
|
||||
if (horizontal)
|
||||
state.global.mode = vertical ? MeasureToolState::Mode::Cross : MeasureToolState::Mode::Horizontal;
|
||||
else
|
||||
state.global.mode = MeasureToolState::Mode::Vertical;
|
||||
|
||||
state.global.continuousCapture = _settings.continuousCapture;
|
||||
state.global.drawFeetOnCross = _settings.drawFeetOnCross;
|
||||
state.global.pixelTolerance = _settings.pixelTolerance;
|
||||
state.global.perColorChannelEdgeDetection = _settings.perColorChannelEdgeDetection;
|
||||
});
|
||||
|
||||
#if defined(DEBUG_PRIMARY_MONITOR_ONLY)
|
||||
const auto& monitorInfo = MonitorInfo::GetPrimaryMonitor();
|
||||
#else
|
||||
for (const auto& monitorInfo : MonitorInfo::GetMonitors(true))
|
||||
#endif
|
||||
{
|
||||
auto overlayUI = OverlayUIState::Create(_measureToolState, _commonState, monitorInfo);
|
||||
#if !defined(DEBUG_PRIMARY_MONITOR_ONLY)
|
||||
if (!overlayUI)
|
||||
continue;
|
||||
#endif
|
||||
_screenCaptureThreads.emplace_back(StartCapturingThread(_commonState,
|
||||
_measureToolState,
|
||||
overlayUI->overlayWindowHandle(),
|
||||
monitorInfo));
|
||||
_overlayUIStates.push_back(std::move(overlayUI));
|
||||
}
|
||||
Trace::MeasureToolActivated();
|
||||
}
|
||||
|
||||
void MeasureToolCore::implementation::Core::SetToolCompletionEvent(ToolSessionCompleted sessionCompletedTrigger)
|
||||
{
|
||||
_commonState.sessionCompletedCallback = [trigger = std::move(sessionCompletedTrigger)] {
|
||||
trigger();
|
||||
};
|
||||
}
|
||||
|
||||
void MeasureToolCore::implementation::Core::SetToolbarBoundingBox(const uint32_t fromX,
|
||||
const uint32_t fromY,
|
||||
const uint32_t toX,
|
||||
const uint32_t toY)
|
||||
{
|
||||
_commonState.toolbarBoundingBox = Box{ RECT{ .left = static_cast<long>(fromX),
|
||||
.top = static_cast<long>(fromY),
|
||||
.right = static_cast<long>(toX),
|
||||
.bottom = static_cast<long>(toY) } };
|
||||
}
|
||||
|
||||
float MeasureToolCore::implementation::Core::GetDPIScaleForWindow(uint64_t windowHandle)
|
||||
{
|
||||
UINT dpi = DPIAware::DEFAULT_DPI;
|
||||
DPIAware::GetScreenDPIForWindow(std::bit_cast<HWND>(windowHandle), dpi);
|
||||
return static_cast<float>(dpi) / DPIAware::DEFAULT_DPI;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include "Core.g.h"
|
||||
#include "ToolState.h"
|
||||
#include "OverlayUI.h"
|
||||
#include "Settings.h"
|
||||
|
||||
#include <common/utils/serialized.h>
|
||||
|
||||
namespace winrt::PowerToys::MeasureToolCore::implementation
|
||||
{
|
||||
struct Core : CoreT<Core>
|
||||
{
|
||||
Core();
|
||||
~Core();
|
||||
void StartBoundsTool();
|
||||
void StartMeasureTool(const bool horizontal, const bool vertical);
|
||||
void SetToolCompletionEvent(ToolSessionCompleted sessionCompletedTrigger);
|
||||
void SetToolbarBoundingBox(const uint32_t fromX, const uint32_t fromY, const uint32_t toX, const uint32_t toY);
|
||||
void ResetState();
|
||||
float GetDPIScaleForWindow(uint64_t windowHandle);
|
||||
void MouseCaptureThread();
|
||||
|
||||
std::thread _mouseCaptureThread;
|
||||
std::vector<std::thread> _screenCaptureThreads;
|
||||
wil::shared_event _stopMouseCaptureThreadSignal;
|
||||
|
||||
std::vector<std::unique_ptr<OverlayUIState>> _overlayUIStates;
|
||||
Serialized<MeasureToolState> _measureToolState;
|
||||
BoundsToolState _boundsToolState;
|
||||
CommonState _commonState;
|
||||
Settings _settings;
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::PowerToys::MeasureToolCore::factory_implementation
|
||||
{
|
||||
struct Core : CoreT<Core, implementation::Core>
|
||||
{
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
namespace PowerToys
|
||||
{
|
||||
namespace MeasureToolCore
|
||||
{
|
||||
struct Point
|
||||
{
|
||||
Int32 X;
|
||||
Int32 Y;
|
||||
};
|
||||
|
||||
delegate void ToolSessionCompleted();
|
||||
|
||||
[default_interface]
|
||||
runtimeclass Core
|
||||
{
|
||||
Core();
|
||||
void SetToolCompletionEvent(event ToolSessionCompleted completionTrigger);
|
||||
void StartMeasureTool(Boolean horizontal, Boolean vertical);
|
||||
void StartBoundsTool();
|
||||
void ResetState();
|
||||
|
||||
void SetToolbarBoundingBox(Int32 fromX, Int32 fromY, Int32 toX, Int32 toY);
|
||||
Single GetDPIScaleForWindow(Int64 windowHandle);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
#include <windows.h>
|
||||
#include "resource.h"
|
||||
#include "../../../common/version/version.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
#include "winres.h"
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
1 VERSIONINFO
|
||||
FILEVERSION FILE_VERSION
|
||||
PRODUCTVERSION PRODUCT_VERSION
|
||||
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS VS_FF_DEBUG
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS VOS_NT_WINDOWS32
|
||||
FILETYPE VFT_DLL
|
||||
FILESUBTYPE VFT2_UNKNOWN
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0" // US English (0x0409), Unicode (0x04B0) charset
|
||||
BEGIN
|
||||
VALUE "CompanyName", COMPANY_NAME
|
||||
VALUE "FileDescription", FILE_DESCRIPTION
|
||||
VALUE "FileVersion", FILE_VERSION_STRING
|
||||
VALUE "InternalName", INTERNAL_NAME
|
||||
VALUE "LegalCopyright", COPYRIGHT_NOTE
|
||||
VALUE "OriginalFilename", ORIGINAL_FILENAME
|
||||
VALUE "ProductName", PRODUCT_NAME
|
||||
VALUE "ProductVersion", PRODUCT_VERSION_STRING
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200 // US English (0x0409), Unicode (1200) charset
|
||||
END
|
||||
END
|
||||
@@ -0,0 +1,158 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.1.1.4\build\native\Microsoft.WindowsAppSDK.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.1.1.4\build\native\Microsoft.WindowsAppSDK.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22000.197\build\Microsoft.Windows.SDK.BuildTools.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22000.197\build\Microsoft.Windows.SDK.BuildTools.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220418.1\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220418.1\build\native\Microsoft.Windows.CppWinRT.props')" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<CppWinRTOptimized>true</CppWinRTOptimized>
|
||||
<CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge>
|
||||
<MinimalCoreWin>true</MinimalCoreWin>
|
||||
<ProjectGuid>{54a93af7-60c7-4f6c-99d2-fbb1f75f853a}</ProjectGuid>
|
||||
<ProjectName>PowerToys.MeasureToolCore</ProjectName>
|
||||
<RootNamespace>PowerToys.MeasureToolCore</RootNamespace>
|
||||
<!--
|
||||
$(TargetName) should be same as $(RootNamespace) so that the produced binaries (.exe/.pri/etc.)
|
||||
have a name that matches the .winmd
|
||||
-->
|
||||
<TargetName>PowerToys.MeasureToolCore</TargetName>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
<MinimumVisualStudioVersion>16.0</MinimumVisualStudioVersion>
|
||||
<AppContainerApplication>false</AppContainerApplication>
|
||||
<AppxPackage>false</AppxPackage>
|
||||
<ApplicationType>Windows Store</ApplicationType>
|
||||
<ApplicationTypeRevision>10.0</ApplicationTypeRevision>
|
||||
<OverrideWindowsTargetPlatformVersion>true</OverrideWindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion>10.0.20348.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformMinVersion>10.0.19041.0</WindowsTargetPlatformMinVersion>
|
||||
<UseWinUI>true</UseWinUI>
|
||||
<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>
|
||||
<EnablePreviewMsixTooling>true</EnablePreviewMsixTooling>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
<DesktopCompatible>true</DesktopCompatible>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<Import Project="..\..\..\..\deps\spdlog.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\modules\MeasureTool\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<AdditionalOptions>%(AdditionalOptions) /bigobj</AdditionalOptions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)src\;..\..\..\common\Telemetry;..\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateWindowsMetadata>false</GenerateWindowsMetadata>
|
||||
<ModuleDefinitionFile>MeasureTool.def</ModuleDefinitionFile>
|
||||
<AdditionalDependencies>Shell32.lib;Shcore.lib;Dwmapi.lib;Gdi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<Manifest Include="app.manifest" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="MeasureToolCore.def" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\MeasureToolModuleInterface\trace.h" />
|
||||
<ClInclude Include="BoundsToolOverlayUI.h" />
|
||||
<ClInclude Include="Clipboard.h" />
|
||||
<ClInclude Include="constants.h" />
|
||||
<ClInclude Include="D2DState.h" />
|
||||
<ClInclude Include="MeasureToolOverlayUI.h" />
|
||||
<ClInclude Include="PerGlyphOpacityTextRender.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="Settings.h" />
|
||||
<ClInclude Include="PowerToys.MeasureToolCore.h">
|
||||
<DependentUpon>PowerToys.MeasureToolCore.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="BGRATextureView.h" />
|
||||
<ClInclude Include="EdgeDetection.h" />
|
||||
<ClInclude Include="ToolState.h" />
|
||||
<ClInclude Include="OverlayUI.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="ScreenCapturing.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\MeasureToolModuleInterface\trace.cpp" />
|
||||
<ClCompile Include="BGRATextureView.cpp" />
|
||||
<ClCompile Include="BoundsToolOverlayUI.cpp" />
|
||||
<ClCompile Include="Clipboard.cpp" />
|
||||
<ClCompile Include="D2DState.cpp" />
|
||||
<ClCompile Include="EdgeDetection.cpp" />
|
||||
<ClCompile Include="MeasureToolOverlayUI.cpp" />
|
||||
<ClCompile Include="OverlayUI.cpp" />
|
||||
<ClCompile Include="PerGlyphOpacityTextRender.cpp" />
|
||||
<ClCompile Include="PowerToys.MeasureToolCore.cpp">
|
||||
<DependentUpon>PowerToys.MeasureToolCore.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
|
||||
<ClCompile Include="ScreenCapturing.cpp" />
|
||||
<ClCompile Include="Settings.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Midl Include="PowerToys.MeasureToolCore.idl">
|
||||
<WarningLevel>2</WarningLevel>
|
||||
<WarnAsError>true</WarnAsError>
|
||||
</Midl>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\common\Display\Display.vcxproj">
|
||||
<Project>{caba8dfb-823b-4bf2-93ac-3f31984150d9}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\common\logger\logger.vcxproj">
|
||||
<Project>{d9b8fc84-322a-4f9f-bbb9-20915c47ddfd}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\common\SettingsAPI\SettingsAPI.vcxproj">
|
||||
<Project>{6955446d-23f7-4023-9bb3-8657f904af99}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\common\Themes\Themes.vcxproj">
|
||||
<Project>{98537082-0fdb-40de-abd8-0dc5a4269bab}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="PowerToys.MeasureToolCore.rc" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220418.1\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220418.1\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22000.197\build\Microsoft.Windows.SDK.BuildTools.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22000.197\build\Microsoft.Windows.SDK.BuildTools.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.1.1.4\build\native\Microsoft.WindowsAppSDK.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.1.1.4\build\native\Microsoft.WindowsAppSDK.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220418.1\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220418.1\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220418.1\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220418.1\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22000.197\build\Microsoft.Windows.SDK.BuildTools.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22000.197\build\Microsoft.Windows.SDK.BuildTools.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22000.197\build\Microsoft.Windows.SDK.BuildTools.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22000.197\build\Microsoft.Windows.SDK.BuildTools.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.1.1.4\build\native\Microsoft.WindowsAppSDK.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.1.1.4\build\native\Microsoft.WindowsAppSDK.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.1.1.4\build\native\Microsoft.WindowsAppSDK.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.1.1.4\build\native\Microsoft.WindowsAppSDK.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -0,0 +1,53 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Midl Include="PowerToys.MeasureToolCore.idl" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="pch.cpp" />
|
||||
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
|
||||
<ClCompile Include="ScreenCapturing.cpp" />
|
||||
<ClCompile Include="OverlayUI.cpp" />
|
||||
<ClCompile Include="BGRATextureView.cpp" />
|
||||
<ClCompile Include="EdgeDetection.cpp" />
|
||||
<ClCompile Include="Settings.cpp" />
|
||||
<ClCompile Include="D2DState.cpp" />
|
||||
<ClCompile Include="BoundsToolOverlayUI.cpp" />
|
||||
<ClCompile Include="MeasureToolOverlayUI.cpp" />
|
||||
<ClCompile Include="..\MeasureToolModuleInterface\trace.cpp" />
|
||||
<ClCompile Include="Clipboard.cpp" />
|
||||
<ClCompile Include="PerGlyphOpacityTextRender.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="ScreenCapturing.h" />
|
||||
<ClInclude Include="OverlayUI.h" />
|
||||
<ClInclude Include="BGRATextureView.h" />
|
||||
<ClInclude Include="EdgeDetection.h" />
|
||||
<ClInclude Include="ToolState.h" />
|
||||
<ClInclude Include="Settings.h" />
|
||||
<ClInclude Include="BoundsToolOverlayUI.h" />
|
||||
<ClInclude Include="D2DState.h" />
|
||||
<ClInclude Include="MeasureToolOverlayUI.h" />
|
||||
<ClInclude Include="constants.h" />
|
||||
<ClInclude Include="..\MeasureToolModuleInterface\trace.h" />
|
||||
<ClInclude Include="Clipboard.h" />
|
||||
<ClInclude Include="PerGlyphOpacityTextRender.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Assets">
|
||||
<UniqueIdentifier>{e48dc53e-40b1-40cb-970a-f89935452892}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Manifest Include="app.manifest" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
<None Include="MeasureToolCore.def" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="PowerToys.MeasureToolCore.rc" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
443
src/modules/MeasureTool/MeasureToolCore/ScreenCapturing.cpp
Normal file
443
src/modules/MeasureTool/MeasureToolCore/ScreenCapturing.cpp
Normal file
@@ -0,0 +1,443 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include "BGRATextureView.h"
|
||||
#include "constants.h"
|
||||
#include "CoordinateSystemConversion.h"
|
||||
#include "EdgeDetection.h"
|
||||
#include "ScreenCapturing.h"
|
||||
|
||||
#include <common/Display/monitors.h>
|
||||
|
||||
//#define DEBUG_EDGES
|
||||
|
||||
class MappedTextureView
|
||||
{
|
||||
winrt::com_ptr<ID3D11DeviceContext> context;
|
||||
winrt::com_ptr<ID3D11Texture2D> texture;
|
||||
|
||||
public:
|
||||
BGRATextureView view;
|
||||
MappedTextureView(winrt::com_ptr<ID3D11Texture2D> _texture,
|
||||
winrt::com_ptr<ID3D11DeviceContext> _context,
|
||||
const size_t textureWidth,
|
||||
const size_t textureHeight) :
|
||||
texture{ std::move(_texture) }, context{ std::move(_context) }
|
||||
{
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
texture->GetDesc(&desc);
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE resource = {};
|
||||
winrt::check_hresult(context->Map(texture.get(), D3D11CalcSubresource(0, 0, 0), D3D11_MAP_READ, 0, &resource));
|
||||
|
||||
view.pixels = static_cast<const uint32_t*>(resource.pData);
|
||||
view.pitch = resource.RowPitch / 4;
|
||||
view.width = textureWidth;
|
||||
view.height = textureHeight;
|
||||
}
|
||||
|
||||
MappedTextureView(MappedTextureView&&) = default;
|
||||
MappedTextureView& operator=(MappedTextureView&&) = default;
|
||||
|
||||
inline winrt::com_ptr<ID3D11Texture2D> GetTexture() const
|
||||
{
|
||||
return texture;
|
||||
}
|
||||
|
||||
~MappedTextureView()
|
||||
{
|
||||
if (context && texture)
|
||||
context->Unmap(texture.get(), D3D11CalcSubresource(0, 0, 0));
|
||||
}
|
||||
};
|
||||
|
||||
class D3DCaptureState final
|
||||
{
|
||||
winrt::com_ptr<ID3D11Device> d3dDevice;
|
||||
winrt::IDirect3DDevice device;
|
||||
winrt::com_ptr<IDXGISwapChain1> swapChain;
|
||||
winrt::com_ptr<ID3D11DeviceContext> context;
|
||||
winrt::SizeInt32 frameSize;
|
||||
|
||||
winrt::DirectXPixelFormat pixelFormat;
|
||||
winrt::Direct3D11CaptureFramePool framePool;
|
||||
winrt::GraphicsCaptureSession session;
|
||||
|
||||
std::function<void(MappedTextureView)> frameCallback;
|
||||
Box monitorArea;
|
||||
bool captureOutsideOfMonitor = false;
|
||||
|
||||
D3DCaptureState(winrt::com_ptr<ID3D11Device> d3dDevice,
|
||||
winrt::IDirect3DDevice _device,
|
||||
winrt::com_ptr<IDXGISwapChain1> _swapChain,
|
||||
winrt::com_ptr<ID3D11DeviceContext> _context,
|
||||
const winrt::GraphicsCaptureItem& item,
|
||||
winrt::DirectXPixelFormat _pixelFormat,
|
||||
Box monitorArea,
|
||||
const bool captureOutsideOfMonitor);
|
||||
|
||||
winrt::com_ptr<ID3D11Texture2D> CopyFrameToCPU(const winrt::com_ptr<ID3D11Texture2D>& texture);
|
||||
|
||||
void OnFrameArrived(const winrt::Direct3D11CaptureFramePool& sender, const winrt::IInspectable&);
|
||||
|
||||
void StartSessionInPreferredMode();
|
||||
|
||||
std::mutex destructorMutex;
|
||||
|
||||
public:
|
||||
static std::unique_ptr<D3DCaptureState> Create(winrt::GraphicsCaptureItem item,
|
||||
const winrt::DirectXPixelFormat pixelFormat,
|
||||
Box monitorSize,
|
||||
const bool captureOutsideOfMonitor);
|
||||
|
||||
~D3DCaptureState();
|
||||
|
||||
void StartCapture(std::function<void(MappedTextureView)> _frameCallback);
|
||||
MappedTextureView CaptureSingleFrame();
|
||||
|
||||
void StopCapture();
|
||||
};
|
||||
|
||||
D3DCaptureState::D3DCaptureState(winrt::com_ptr<ID3D11Device> _d3dDevice,
|
||||
winrt::IDirect3DDevice _device,
|
||||
winrt::com_ptr<IDXGISwapChain1> _swapChain,
|
||||
winrt::com_ptr<ID3D11DeviceContext> _context,
|
||||
const winrt::GraphicsCaptureItem& item,
|
||||
winrt::DirectXPixelFormat _pixelFormat,
|
||||
Box _monitorArea,
|
||||
const bool _captureOutsideOfMonitor) :
|
||||
d3dDevice{ std::move(_d3dDevice) },
|
||||
device{ std::move(_device) },
|
||||
swapChain{ std::move(_swapChain) },
|
||||
context{ std::move(_context) },
|
||||
frameSize{ item.Size() },
|
||||
pixelFormat{ std::move(_pixelFormat) },
|
||||
framePool{ winrt::Direct3D11CaptureFramePool::CreateFreeThreaded(device, pixelFormat, 2, item.Size()) },
|
||||
session{ framePool.CreateCaptureSession(item) },
|
||||
monitorArea{ _monitorArea },
|
||||
captureOutsideOfMonitor{ _captureOutsideOfMonitor }
|
||||
{
|
||||
framePool.FrameArrived({ this, &D3DCaptureState::OnFrameArrived });
|
||||
}
|
||||
|
||||
winrt::com_ptr<ID3D11Texture2D> D3DCaptureState::CopyFrameToCPU(const winrt::com_ptr<ID3D11Texture2D>& frameTexture)
|
||||
{
|
||||
D3D11_TEXTURE2D_DESC desc = {};
|
||||
frameTexture->GetDesc(&desc);
|
||||
desc.Usage = D3D11_USAGE_STAGING;
|
||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
||||
desc.MiscFlags = 0;
|
||||
desc.BindFlags = 0;
|
||||
|
||||
winrt::com_ptr<ID3D11Texture2D> cpuTexture;
|
||||
winrt::check_hresult(d3dDevice->CreateTexture2D(&desc, nullptr, cpuTexture.put()));
|
||||
context->CopyResource(cpuTexture.get(), frameTexture.get());
|
||||
|
||||
return cpuTexture;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto GetDXGIInterfaceFromObject(winrt::IInspectable const& object)
|
||||
{
|
||||
auto access = object.as<Windows::Graphics::DirectX::Direct3D11::IDirect3DDxgiInterfaceAccess>();
|
||||
winrt::com_ptr<T> result;
|
||||
winrt::check_hresult(access->GetInterface(winrt::guid_of<T>(), result.put_void()));
|
||||
return result;
|
||||
}
|
||||
|
||||
void D3DCaptureState::OnFrameArrived(const winrt::Direct3D11CaptureFramePool& sender, const winrt::IInspectable&)
|
||||
{
|
||||
// Prevent calling a callback on a partially destroyed state
|
||||
std::unique_lock callbackLock{ destructorMutex };
|
||||
|
||||
bool resized = false;
|
||||
POINT cursorPos = {};
|
||||
GetCursorPos(&cursorPos);
|
||||
|
||||
auto frame = sender.TryGetNextFrame();
|
||||
winrt::check_bool(frame);
|
||||
if (monitorArea.inside(cursorPos) || captureOutsideOfMonitor)
|
||||
{
|
||||
winrt::com_ptr<ID3D11Texture2D> texture;
|
||||
{
|
||||
if (auto newFrameSize = frame.ContentSize(); newFrameSize != frameSize)
|
||||
{
|
||||
winrt::check_hresult(swapChain->ResizeBuffers(2,
|
||||
static_cast<uint32_t>(newFrameSize.Height),
|
||||
static_cast<uint32_t>(newFrameSize.Width),
|
||||
static_cast<DXGI_FORMAT>(pixelFormat),
|
||||
0));
|
||||
frameSize = newFrameSize;
|
||||
resized = true;
|
||||
}
|
||||
|
||||
winrt::check_hresult(swapChain->GetBuffer(0, winrt::guid_of<ID3D11Texture2D>(), texture.put_void()));
|
||||
auto gpuTexture = GetDXGIInterfaceFromObject<ID3D11Texture2D>(frame.Surface());
|
||||
texture = CopyFrameToCPU(gpuTexture);
|
||||
MappedTextureView textureView{ texture, context, static_cast<size_t>(frameSize.Width), static_cast<size_t>(frameSize.Height) };
|
||||
|
||||
frameCallback(std::move(textureView));
|
||||
}
|
||||
}
|
||||
|
||||
frame.Close();
|
||||
|
||||
DXGI_PRESENT_PARAMETERS presentParameters = {};
|
||||
swapChain->Present1(1, 0, &presentParameters);
|
||||
|
||||
if (resized)
|
||||
{
|
||||
framePool.Recreate(device, pixelFormat, 2, frameSize);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<D3DCaptureState> D3DCaptureState::Create(winrt::GraphicsCaptureItem item,
|
||||
const winrt::DirectXPixelFormat pixelFormat,
|
||||
Box monitorArea,
|
||||
const bool captureOutsideOfMonitor)
|
||||
{
|
||||
std::lock_guard guard{ gpuAccessLock };
|
||||
|
||||
winrt::com_ptr<ID3D11Device> d3dDevice;
|
||||
UINT flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
|
||||
#ifndef NDEBUG
|
||||
flags |= D3D11_CREATE_DEVICE_DEBUG;
|
||||
#endif
|
||||
HRESULT hr =
|
||||
D3D11CreateDevice(nullptr,
|
||||
D3D_DRIVER_TYPE_HARDWARE,
|
||||
nullptr,
|
||||
flags,
|
||||
nullptr,
|
||||
0,
|
||||
D3D11_SDK_VERSION,
|
||||
d3dDevice.put(),
|
||||
nullptr,
|
||||
nullptr);
|
||||
if (hr == DXGI_ERROR_UNSUPPORTED)
|
||||
{
|
||||
hr = D3D11CreateDevice(nullptr,
|
||||
D3D_DRIVER_TYPE_WARP,
|
||||
nullptr,
|
||||
flags,
|
||||
nullptr,
|
||||
0,
|
||||
D3D11_SDK_VERSION,
|
||||
d3dDevice.put(),
|
||||
nullptr,
|
||||
nullptr);
|
||||
}
|
||||
winrt::check_hresult(hr);
|
||||
|
||||
auto dxgiDevice = d3dDevice.as<IDXGIDevice>();
|
||||
winrt::com_ptr<IInspectable> d3dDeviceInspectable;
|
||||
winrt::check_hresult(CreateDirect3D11DeviceFromDXGIDevice(dxgiDevice.get(), d3dDeviceInspectable.put()));
|
||||
|
||||
const DXGI_SWAP_CHAIN_DESC1 desc = {
|
||||
.Width = static_cast<uint32_t>(item.Size().Width),
|
||||
.Height = static_cast<uint32_t>(item.Size().Height),
|
||||
.Format = static_cast<DXGI_FORMAT>(pixelFormat),
|
||||
.SampleDesc = { .Count = 1, .Quality = 0 },
|
||||
.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT,
|
||||
.BufferCount = 2,
|
||||
.Scaling = DXGI_SCALING_STRETCH,
|
||||
.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL,
|
||||
.AlphaMode = DXGI_ALPHA_MODE_PREMULTIPLIED,
|
||||
};
|
||||
winrt::com_ptr<IDXGIAdapter> adapter;
|
||||
winrt::check_hresult(dxgiDevice->GetParent(winrt::guid_of<IDXGIAdapter>(), adapter.put_void()));
|
||||
winrt::com_ptr<IDXGIFactory2> factory;
|
||||
winrt::check_hresult(adapter->GetParent(winrt::guid_of<IDXGIFactory2>(), factory.put_void()));
|
||||
|
||||
winrt::com_ptr<IDXGISwapChain1> swapChain;
|
||||
winrt::check_hresult(factory->CreateSwapChainForComposition(d3dDevice.get(), &desc, nullptr, swapChain.put()));
|
||||
|
||||
winrt::com_ptr<ID3D11DeviceContext> context;
|
||||
d3dDevice->GetImmediateContext(context.put());
|
||||
winrt::check_bool(context);
|
||||
|
||||
// We must create the object in a heap, since we need to pin it in memory to receive callbacks
|
||||
auto statePtr = new D3DCaptureState{ d3dDevice,
|
||||
d3dDeviceInspectable.as<winrt::IDirect3DDevice>(),
|
||||
std::move(swapChain),
|
||||
std::move(context),
|
||||
item,
|
||||
pixelFormat,
|
||||
monitorArea,
|
||||
captureOutsideOfMonitor };
|
||||
|
||||
return std::unique_ptr<D3DCaptureState>{ statePtr };
|
||||
}
|
||||
|
||||
D3DCaptureState::~D3DCaptureState()
|
||||
{
|
||||
std::unique_lock callbackLock{ destructorMutex };
|
||||
StopCapture();
|
||||
framePool.Close();
|
||||
device.Close();
|
||||
}
|
||||
|
||||
void D3DCaptureState::StartSessionInPreferredMode()
|
||||
{
|
||||
// Try disable border if possible (available on Windows ver >= 20348)
|
||||
if (auto session3 = session.try_as<winrt::IGraphicsCaptureSession3>())
|
||||
{
|
||||
session3.IsBorderRequired(false);
|
||||
}
|
||||
|
||||
session.IsCursorCaptureEnabled(false);
|
||||
session.StartCapture();
|
||||
}
|
||||
|
||||
void D3DCaptureState::StartCapture(std::function<void(MappedTextureView)> _frameCallback)
|
||||
{
|
||||
frameCallback = std::move(_frameCallback);
|
||||
StartSessionInPreferredMode();
|
||||
}
|
||||
|
||||
MappedTextureView D3DCaptureState::CaptureSingleFrame()
|
||||
{
|
||||
std::optional<MappedTextureView> result;
|
||||
wil::shared_event frameArrivedEvent(wil::EventOptions::ManualReset);
|
||||
|
||||
frameCallback = [frameArrivedEvent, &result, this](MappedTextureView tex) {
|
||||
if (result)
|
||||
return;
|
||||
|
||||
StopCapture();
|
||||
result.emplace(std::move(tex));
|
||||
frameArrivedEvent.SetEvent();
|
||||
};
|
||||
std::lock_guard guard{ gpuAccessLock };
|
||||
StartSessionInPreferredMode();
|
||||
|
||||
frameArrivedEvent.wait();
|
||||
|
||||
assert(result.has_value());
|
||||
return std::move(*result);
|
||||
}
|
||||
|
||||
void D3DCaptureState::StopCapture()
|
||||
{
|
||||
session.Close();
|
||||
}
|
||||
|
||||
void UpdateCaptureState(const CommonState& commonState,
|
||||
Serialized<MeasureToolState>& state,
|
||||
HWND window,
|
||||
const MappedTextureView& textureView,
|
||||
const bool continuousCapture)
|
||||
{
|
||||
const auto cursorPos = convert::FromSystemToRelative(window, commonState.cursorPosSystemSpace);
|
||||
const bool cursorInLeftScreenHalf = cursorPos.x < textureView.view.width / 2;
|
||||
const bool cursorInTopScreenHalf = cursorPos.y < textureView.view.height / 2;
|
||||
uint8_t pixelTolerance = {};
|
||||
bool perColorChannelEdgeDetection = {};
|
||||
state.Access([&](MeasureToolState& state) {
|
||||
state.perScreen[window].cursorInLeftScreenHalf = cursorInLeftScreenHalf;
|
||||
state.perScreen[window].cursorInTopScreenHalf = cursorInTopScreenHalf;
|
||||
pixelTolerance = state.global.pixelTolerance;
|
||||
perColorChannelEdgeDetection = state.global.perColorChannelEdgeDetection;
|
||||
});
|
||||
|
||||
// Every one of 4 edges is a coordinate of the last similar pixel in a row
|
||||
// Example: given a 5x5 green square on a blue background with its top-left pixel
|
||||
// at 20x100, bounds should be [20,100]-[24,104]. We don't include [25,105] or
|
||||
// [19,99], since those pixels are blue. Thus, square dims are equal to
|
||||
// [24-20+1,104-100+1]=[5,5].
|
||||
const RECT bounds = DetectEdges(textureView.view,
|
||||
cursorPos,
|
||||
perColorChannelEdgeDetection,
|
||||
pixelTolerance,
|
||||
continuousCapture);
|
||||
|
||||
#if defined(DEBUG_EDGES)
|
||||
char buffer[256];
|
||||
sprintf_s(buffer,
|
||||
"Cursor: [%ld,%ld] Bounds: [%ld,%ld]-[%ld,%ld] Screen size: [%zu, %zu]\n",
|
||||
cursorPos.x,
|
||||
cursorPos.y,
|
||||
bounds.left,
|
||||
bounds.top,
|
||||
bounds.right,
|
||||
bounds.bottom,
|
||||
textureView.view.width,
|
||||
textureView.view.height);
|
||||
OutputDebugStringA(buffer);
|
||||
#endif
|
||||
state.Access([&](MeasureToolState& state) {
|
||||
state.perScreen[window].measuredEdges = bounds;
|
||||
});
|
||||
}
|
||||
|
||||
std::thread StartCapturingThread(const CommonState& commonState,
|
||||
Serialized<MeasureToolState>& state,
|
||||
HWND window,
|
||||
MonitorInfo targetMonitor)
|
||||
{
|
||||
return SpawnLoggedThread(L"Screen Capture thread", [&state, &commonState, targetMonitor, window] {
|
||||
auto captureInterop = winrt::get_activation_factory<
|
||||
winrt::GraphicsCaptureItem,
|
||||
IGraphicsCaptureItemInterop>();
|
||||
|
||||
winrt::GraphicsCaptureItem item = nullptr;
|
||||
|
||||
winrt::check_hresult(captureInterop->CreateForMonitor(
|
||||
targetMonitor.GetHandle(),
|
||||
winrt::guid_of<winrt::GraphicsCaptureItem>(),
|
||||
winrt::put_abi(item)));
|
||||
|
||||
bool continuousCapture = {};
|
||||
state.Read([&](const MeasureToolState& state) {
|
||||
continuousCapture = state.global.continuousCapture;
|
||||
});
|
||||
|
||||
const auto monitorArea = targetMonitor.GetScreenSize(true);
|
||||
auto captureState = D3DCaptureState::Create(item,
|
||||
winrt::DirectXPixelFormat::B8G8R8A8UIntNormalized,
|
||||
monitorArea,
|
||||
!continuousCapture);
|
||||
if (continuousCapture)
|
||||
{
|
||||
captureState->StartCapture([&, window](MappedTextureView textureView) {
|
||||
UpdateCaptureState(commonState, state, window, textureView, continuousCapture);
|
||||
});
|
||||
|
||||
while (IsWindow(window) && !commonState.closeOnOtherMonitors)
|
||||
{
|
||||
std::this_thread::sleep_for(consts::TARGET_FRAME_DURATION);
|
||||
}
|
||||
captureState->StopCapture();
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto textureView = captureState->CaptureSingleFrame();
|
||||
|
||||
state.Access([&](MeasureToolState& s) {
|
||||
s.perScreen[window].capturedScreenTexture = textureView.GetTexture();
|
||||
});
|
||||
|
||||
while (IsWindow(window) && !commonState.closeOnOtherMonitors)
|
||||
{
|
||||
const auto now = std::chrono::high_resolution_clock::now();
|
||||
if (monitorArea.inside(commonState.cursorPosSystemSpace))
|
||||
{
|
||||
#if defined(DEBUG_TEXTURE)
|
||||
SYSTEMTIME lt{};
|
||||
GetLocalTime(<);
|
||||
char buf[256];
|
||||
sprintf_s(buf, "frame-%02d-%02d-Monitor-%zu.bmp", lt.wHour, lt.wMinute, (uint64_t)window);
|
||||
auto path = std::filesystem::temp_directory_path() / buf;
|
||||
textureView.view.SaveAsBitmap(path.string().c_str());
|
||||
#endif
|
||||
UpdateCaptureState(commonState, state, window, textureView, continuousCapture);
|
||||
}
|
||||
|
||||
const auto frameTime = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - now);
|
||||
if (frameTime < consts::TARGET_FRAME_DURATION)
|
||||
{
|
||||
std::this_thread::sleep_for(consts::TARGET_FRAME_DURATION - frameTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
10
src/modules/MeasureTool/MeasureToolCore/ScreenCapturing.h
Normal file
10
src/modules/MeasureTool/MeasureToolCore/ScreenCapturing.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "ToolState.h"
|
||||
|
||||
#include <common/utils/serialized.h>
|
||||
|
||||
std::thread StartCapturingThread(const CommonState& commonState,
|
||||
Serialized<MeasureToolState>& state,
|
||||
HWND targetWindow,
|
||||
MonitorInfo targetMonitor);
|
||||
74
src/modules/MeasureTool/MeasureToolCore/Settings.cpp
Normal file
74
src/modules/MeasureTool/MeasureToolCore/Settings.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include <common/SettingsAPI/settings_helpers.h>
|
||||
#include <common/utils/color.h>
|
||||
|
||||
#include "Settings.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
const wchar_t JSON_KEY_PROPERTIES[] = L"properties";
|
||||
const wchar_t JSON_KEY_VALUE[] = L"value";
|
||||
|
||||
const wchar_t JSON_KEY_CONTINUOUS_CAPTURE[] = L"ContinuousCapture";
|
||||
const wchar_t JSON_KEY_DRAW_FEET_ON_CROSS[] = L"DrawFeetOnCross";
|
||||
const wchar_t JSON_KEY_PIXEL_TOLERANCE[] = L"PixelTolerance";
|
||||
const wchar_t JSON_KEY_PER_COLOR_CHANNEL_EDGE_DETECTION[] = L"PerColorChannelEdgeDetection";
|
||||
const wchar_t JSON_KEY_MEASURE_CROSS_COLOR[] = L"MeasureCrossColor";
|
||||
}
|
||||
|
||||
Settings Settings::LoadFromFile()
|
||||
{
|
||||
Settings result;
|
||||
|
||||
try
|
||||
{
|
||||
auto props = PTSettingsHelper::load_module_settings(L"Measure Tool").GetNamedObject(JSON_KEY_PROPERTIES);
|
||||
|
||||
try
|
||||
{
|
||||
result.continuousCapture = props.GetNamedObject(JSON_KEY_CONTINUOUS_CAPTURE).GetNamedBoolean(JSON_KEY_VALUE);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
result.drawFeetOnCross = props.GetNamedObject(JSON_KEY_DRAW_FEET_ON_CROSS).GetNamedBoolean(JSON_KEY_VALUE);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
result.pixelTolerance = static_cast<uint8_t>(props.GetNamedObject(JSON_KEY_PIXEL_TOLERANCE).GetNamedNumber(JSON_KEY_VALUE));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
const auto colorString = props.GetNamedObject(JSON_KEY_MEASURE_CROSS_COLOR).GetNamedString(JSON_KEY_VALUE);
|
||||
checkValidRGB(colorString, &result.lineColor[0], &result.lineColor[1], &result.lineColor[2]);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
result.perColorChannelEdgeDetection = props.GetNamedObject(JSON_KEY_PER_COLOR_CHANNEL_EDGE_DETECTION).GetNamedBoolean(JSON_KEY_VALUE);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
15
src/modules/MeasureTool/MeasureToolCore/Settings.h
Normal file
15
src/modules/MeasureTool/MeasureToolCore/Settings.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cinttypes>
|
||||
|
||||
struct Settings
|
||||
{
|
||||
uint8_t pixelTolerance = 30;
|
||||
bool continuousCapture = true;
|
||||
bool drawFeetOnCross = true;
|
||||
bool perColorChannelEdgeDetection = false;
|
||||
std::array<uint8_t, 3> lineColor = {255, 69, 0};
|
||||
|
||||
static Settings LoadFromFile();
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user