Compare commits

...

81 Commits

Author SHA1 Message Date
Jaime Bernardo
4b9cbc2c32 [ci]fix windows terminal loc build (#16788) 2022-03-04 20:28:59 +00:00
Jaime Bernardo
47fc7be669 [Installer]Include PTRun WindowsTerminal loc (#16777)
* [Installer]Include PTRun WindowsTerminal loc

* Add languages folder reference
2022-03-04 20:28:46 +00:00
Jaime Bernardo
b968e5733b [FindMyMouse]setting for minimum shake distance (#16756)
* [FindMyMouse]setting for minimum shake distance

* Group inside Activation method
2022-03-04 20:28:12 +00:00
Aaron Junker
7d2c8db43a Fixed file in use issue (#16748) 2022-03-04 20:27:46 +00:00
Seraphima Zykova
4edb4dee10 [FancyZones] Template layout settings reset fix (#16628) 2022-03-04 20:27:36 +00:00
Franky Chen
a0bb3dedc1 [Installer]Install dotnet with /norestart (#16691)
* Add norestart for dotnet

* Add norestart to spell-check

* Add quite back for dotnet
2022-03-04 20:27:15 +00:00
Jaime Bernardo
b4250c1235 [PTRun]Workaround fix tooltip crash on .net 6 (#16629) 2022-02-28 15:24:24 +00:00
Clint Rutkas
c428f0787d Add symbols back in (#16572)
* Update release.yml

* Update release.yml

* Update release.yml

* Update release.yml

* Update release.yml

* Update release.yml

* Update release.yml

* Update release.yml

* Update release.yml

* Update release.yml

* Update release.yml

* Update release.yml

* Update release.yml

* Update release.yml

* trying different approach by flattening

* Update release.yml

* Update release.yml

* Update release.yml

* Update release.yml

* Update release.yml

* Update release.yml

* Update release.yml

* Update expect.txt

* Update expect.txt

* Update release.yml

* Update release.yml

* Update release.yml
2022-02-25 08:42:39 -08:00
Jaime Bernardo
c3b378101c [OOBE]Fix welcome page after install (#16561) 2022-02-24 14:42:29 +00:00
Jaime Bernardo
489335e4d0 [MouseCrosshairs] Fix wrong initial position (#16559) 2022-02-24 13:39:47 +00:00
Jaime Bernardo
ddc075d24c [MouseCrosshairs]Fix odd thickness anti-aliasing (#16533) 2022-02-23 15:54:54 +00:00
Jaime Bernardo
50a73965d9 [Oobe]Fix close button style (#16530) 2022-02-23 15:17:44 +00:00
Jaime Bernardo
d5fc4547a2 [oobe] fix scoobe page threading issues (#16532) 2022-02-23 15:01:49 +00:00
Tobias Sekan
84e142631e [PT Run][New Plugin] Time zone plugin (#11431)
* Initial commit - simple idea for a time zone plugin

* Translations, better search results, copy to clipboard, cleanup

* fix typo

* Add shortcut search and prepare JSON for later usage

* Fix typo

* Use timezone Data only from JSON

* Exclude json file from spell checker

* fix wrong dst

* Improved results (title, subtitle, tooltip) and fix namespace/class problem

* Always show full offset (-##:## and +##:##)

* Add and show timezone names (first pass)

* Fix typos

* fix build

* JSON: fix wrong minus sign and put extra country info the end

* Improved Subtitle for many matched countries and allow full offset search (+ and -)

* Allow more than one names for time zones and remove leftover

* Add military time zone names, and fix name result

* Only use one JSON entry for one time zone

* Use TimeSpan for offset, use build-in calculation for time in time zone

* add descriptions for JSON schema

* Fix typos

* Split out names in separate properties

* Add many time names, time zone names and shortcuts

* Add additional options and most code documentation

* Fix unreadable TimeSpans in JSON and rename helper class

* Fix not allowed commas in JSON file

* Cut to long time and time zone names in title

* Fix missing results for names and offsets

* Better result and show only one result when offset are identical (respect daylight saving time)

* Show generic name fot time zones without names

* Typo fixes

* Fix not working serach by shortcuts

* Fix german resx file -> english resx file

* Translate all names and countires

* Fix not working context menu

* Typo fixes, fix wrong shortcut in names, comments, few better variable names

* New symbols - thx to niels9001

* Search by shortcuts for time names

* update schema

* Add more time zone names and shortcuts (second pass), make spell checker happy

* Reduce matching checks

* Show shortcuts in tool-tips, avoid string converting

* Show only names that match the query

* Make all translatable (Part 1)

* Make all translatable (part 2 of 2)

* XML Doc

* Fix plugin name (type)

* Fix Typos

* Add TimeZone Plugint to WXS

* Add TimeZone plugin to sign pipeline

* Add Documentation

* Remove double spell entries

* Remove TODO leftovers

* Fix for results with no countries

* Fix typos

* fix typos

* Fix broken siolution after rebase

* Update target framework to make build happy

* fix wrong guid count in WXS

* fix wrong output folder (setup wasn’t found files)

* Address feedback from @jsoref - fix spell check

* typo fix - one leftover in expect.txt

* Switch to .NET6 and update dokumentation

* Address feedbacks, and fix search bug

* fix installer build error

* fix spellchecker

* Address feedback from @htcfreek

Co-authored-by: Sekan, Tobias <tobias.sekan@axp-consulting.de>
2022-02-23 14:26:48 +00:00
Seraphima Zykova
8edfb8fe80 [FancyZones] Child windows support (#16507) 2022-02-23 17:25:28 +03:00
Jaime Bernardo
d9c98bbc29 [Oobe]Update file explorer add-ons description (#16510) 2022-02-23 09:53:43 +00:00
Seraphima Zykova
4ff7e4150f [AlwaysOnTop] Added error description to logs (#16514) 2022-02-23 10:20:21 +03:00
CleanCodeDeveloper
f4044ffd51 [Settings] Enable analyzer and fix warnings (#16515) 2022-02-22 22:02:45 +00:00
CleanCodeDeveloper
2b747d02d3 [ImageResizer] Enable analyzer and fix warnings (#16512) 2022-02-22 22:01:48 +00:00
CleanCodeDeveloper
6a722e2961 Fix analyzer warning (#16442) 2022-02-22 22:52:34 +03:00
Stefan Markovic
230c199ee5 [runner] Add logging (#16503) 2022-02-22 12:50:20 +01:00
Jaime Bernardo
87bb89ab15 [OOBE]Add What's New page - SCOOBE (#16478)
* [Oobe]Add a What's New page

* Show What's New when version changes

* Add link to GitHub

* Use generic icon for now

* Get only the latest 5 releases

* fix spellchecker

* rename last_version_run.json

* Remove UserControl_Loaded

* Remove installer hash from the release notes

* constexpr some strings

* Add check your internet connection message
2022-02-22 11:02:08 +00:00
Stefan Markovic
e9dccf82ab [ColorPicker] Unify HEX color to lower case (#16492) 2022-02-22 09:28:05 +01:00
Aaron Junker
4cc74602c1 [Developer Preview] Bug fixes (#16108)
* Renamed languages.json to monaco_languages.json

* Update excludes.txt

* Fixed encoding issue

* Reverted accidently removed file

* push

* push

* push

* Fixing path to monaco_languages.json

* Removing unused file

* Fixing NullReferenceException bug

* Minor fixes

Co-authored-by: Stefan Markovic <stefan@janeasystems.com>
2022-02-21 16:10:55 +01:00
Jaime Bernardo
6b2cde7eb0 [installer]update installed .net to 6.0.2 (#16472) 2022-02-21 14:44:49 +00:00
Jaime Bernardo
af65d79573 [ci]fix vcm proxy filter build (#16471) 2022-02-21 14:44:35 +00:00
Andrey Nekrasov
dabf657761 [Setup] Update wix Guids (#16425)
* [Setup] Update wix Guids

* Update expect.txt

* add documentation links

* fix spellchecker
2022-02-18 15:11:31 +00:00
CleanCodeDeveloper
4572f62ce5 [meta]Update nuget packages (#16379)
* Update nuget packages

* try to fix build (Microsoft.UI.Xaml)

* Removed dlls because there are not needed anymore

* Add binaries System.Text.Json.dll (5x) to wxs file

* Downgrade System.IO.Abstractions.* due to breaking changes

* Update Microsoft.NET.Test.Sdk

* Revert MSTest.* to 2.2.3
2022-02-18 14:19:40 +00:00
makeProjectGreatAgain
f2093ec423 [PTRun][VSCode]Support for VSCodium (#16380) 2022-02-18 14:17:21 +00:00
Andrey Nekrasov
51aba915f0 [VCM] add details for the proxy filter .dlls (#16427) 2022-02-18 13:33:12 +03:00
Michael Panitz (at Cascadia College)
9fff2b535f Fix broken link (#16382) 2022-02-17 11:43:47 -08:00
Aaron Junker
3ede2a6467 [meta]Change copyright date to 2022 (#16279) 2022-02-17 18:41:30 +00:00
Jeremy Sinclair
35bfb0f83e [PT Run] Replace tblimp-Microsoft.Search.Interop package with source implementation (#16363)
* Removed Search Interop tlb package. Added minimal Search API Com implementation

* Added CSearchManagerImp

* Updated Main with proper reference to CSearchManagerImp. Switched WindowsIndexerTest to use Indexer.Interop classes

* Updated with proper SearchAPI Interop implementation

* Deleted initial CSearchManager file that didn't work

* Updated namespaces to match folder structure

* Removed the interfaces and classes not being used from SearchAPI. Added suppressions

* Updated spell check. Renamed CSearch call back to original

* Fix spell check

* Switched back to original class name for Search Manager in tests

* Removed Microsoft.Search.Interop.dll from setup

* Removed Microsoft.Search.Interop package from PowerLauncher and signing scripts
2022-02-16 16:06:10 +00:00
CleanCodeDeveloper
832f580aa8 [meta]Remove 10.0.17134 platform SDK from vsconfig file (#16290)
* remove unnecessary sdk

* add .vsconfig to sln, remove dead link

* spell check

* Update WindowsTargetPlatformMinVersion to 18362 (Minimum required version in README.md)
2022-02-16 15:22:33 +00:00
Seraphima Zykova
03b7cb4690 [AlwaysOnTop] fix remaining border after window closing (#16268) 2022-02-16 17:00:05 +03:00
Clint Rutkas
d744ca33b6 Remove build server warning (#16284)
* Update BugReportTool.sln

* Update release.yml
2022-02-14 11:41:10 -08:00
Jaime Bernardo
05728a6dc2 [FindMyMouse] Add setting for excluded apps (#16308)
* refactor find_app_name_in_path

* Add a setting for excluded apps

* Restore game_mode.h
2022-02-14 18:22:05 +00:00
Jaime Bernardo
10a5629fe8 [spellchecker]Fix Awake spellchecker errors (#16356) 2022-02-14 18:20:41 +00:00
CleanCodeDeveloper
38e401007a Add Microsoft.CodeAnalysis.NetAnalyzers were it was missing (#16285) 2022-02-14 09:53:15 -08:00
Stefan Markovic
3508301f06 Add fallback resource search path (#16265) 2022-02-14 09:59:08 +01:00
Den Delimarsky
3df2c5fe6a PowerToys Awake - Improved Logging/Minor Bug Fixes (#15875)
* Some code cleanup

* Making sure that the native wrapper lives in Awake.Core

* Adding power state logging, as well as termination entries.

* Better logging.

* Typos and logging improvements

* Remove dependency
2022-02-12 10:42:14 -08:00
infinitepower18
dc15a6cecc Correct typo (#16291) 2022-02-11 23:24:13 -08:00
Jaime Bernardo
f6a292d47f [FindMyMouse] Add setting to activate by shaking mouse (#16244)
* [FindMyMouse]Initial shaking activation implementation

* Add setting to change activation method

* Update Mouse Snooping on settings change

* fix spellchecker

* Place activation method setting outside the expander

* Address PR Comments
2022-02-11 22:52:57 +00:00
CleanCodeDeveloper
f0d084c59c [meta]replace FxCopAnalyzers by Microsoft.CodeAnalysis.NetAnalyzers (#16210)
* Replace Microsoft.CodeAnalysis.FxCopAnalyzers by Microsoft.CodeAnalysis.NetAnalyzers

* fix error CA2101: Specify marshaling for P/Invoke string arguments

Microsoft.CodeAnalysis.NetAnalyzers treats CA2101 as an error

* Removed obsolete Analyzer Microsoft.NetCore.Analyzers

* Removed obsolete Analyzer Microsoft.NetFramework.Analyzers

* Removed obsolete Analyzer Microsoft.CodeQuality.Analyzers

* Removed obsolete Analyzer Microsoft.CodeAnalysis.VersionCheckAnalyzer

* fix error CA2101: Specify marshaling for P/Invoke string arguments

Microsoft.CodeAnalysis.NetAnalyzers treats CA2101 as an error
2022-02-11 16:42:17 +00:00
Clint Rutkas
9fc3727709 removing anycpu (#16184) 2022-02-11 07:57:20 -08:00
Andrey Nekrasov
218e9cfcb9 [VCM] Do not unmute mics on disabling the module (#16196) 2022-02-11 17:30:52 +03:00
Andrey Nekrasov
9e029c0867 [VCM] Fix crash with NVIDIA broadcaster (#16202) 2022-02-11 17:29:13 +03:00
Clint Rutkas
01a3106450 Remove qps test lang (#16213)
* commenting out qps

* Update release.yml
2022-02-10 13:52:28 -08:00
cyberrex5
416419ffde [PT Run] Refactoring: combined all NativeMethods.cs files for plugins… (#15807)
* [PT Run] Refactoring: combined all NativeMethods.cs files for plugins into Wox.Plugin/Common/Win32/

* Fixed spell check

* [PT Run] Changed NativeMethods.Helpers to Win32Helpers (seperate class) to not conflict with Microsoft.PowerToys.Settings.UI.Library.Helpers

* [PT Run] Renamed Constants.cs to ConstantsAndStructs.cs and moved all of them from NativeMethods.cs

* [PT Run] Merged ConstantsAndStructs.cs into NativeMethods.cs and renamed Constants to Win32Constants to avoid conflicting

* [PT Run] Added missing summaries + fixed missed refactored method

* [PT Run] Use using directive instead of alias + updated method call for .Net 6

* [PT Run] Fixed missed using alias + spell check
2022-02-10 13:44:19 -08:00
Clint Rutkas
57a8d505c0 reducing verbosity on string (#16214) 2022-02-10 11:48:32 -08:00
Seraphima Zykova
ddcb065b22 [AlwaysOnTop] Inaccurate border position fix (#16206) 2022-02-10 20:24:29 +03:00
Andrey Nekrasov
8c64a0b6f8 [Setup] Ignore exit code 1638 (#16228) 2022-02-10 16:18:05 +00:00
Clint Rutkas
cc68133ddc correcting verbage (#16185) 2022-02-09 08:06:27 -08:00
Davide Giacometti
692817e382 updated .NET nugets to 6.x (#16154) 2022-02-08 16:18:05 -08:00
Clint Rutkas
651e823c30 adding in hybrid shutdown for fast startup (#16151)
https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/shutdown
2022-02-08 08:20:01 -08:00
Stefan Markovic
11bb7ccf60 Fallback to run as admin after install, if running PT as user not possible (#16089)
* Fallback to run as admin, if running PT as user not possible

* Update condition - address PR comment

Co-authored-by: Andrey Nekrasov <yuyoyuppe@users.noreply.github.com>

* Update condition #2 - address PR comment

Co-authored-by: Andrey Nekrasov <yuyoyuppe@users.noreply.github.com>

* Update condition #3 - address PR comment

Co-authored-by: Andrey Nekrasov <yuyoyuppe@users.noreply.github.com>

* Revert method name & unify var namings

Co-authored-by: Andrey Nekrasov <yuyoyuppe@users.noreply.github.com>
2022-02-08 11:18:12 +01:00
Stefan Markovic
c3dda238e9 [PowerRename] Fix . instead of \. regex info (#16145)
* [PowerRename] Fix . instead of \. regex info

* Several -> One or more
2022-02-08 11:16:55 +01:00
Clint Rutkas
ff95257e5f adding in attribution in settings (#16044)
* adding in attribution stuff for pedro and aaron

* Update PowerPreviewPage.xaml

* Update AwakePage.xaml
2022-02-07 15:36:11 -08:00
Davide Giacometti
e284b07da7 [Common]fix fancy zones exclusion (#16041)
replace WS_POPUP with WS_EX_TOOLWINDOW
2022-02-07 19:16:36 +00:00
Seraphima Zykova
49a2218358 [AlwaysOnTop] Non-selectable border (#16085) 2022-02-07 17:28:26 +03:00
Clint Rutkas
c46ccce373 [build]Update to .net 6 framework and VS 2022 (#15741)
* Update release.yml

* Update ColorPickerUI.csproj

* Update release.yml

adding in .net6 sdk and moving stuff sooner

* Update release.yml

* Update release.yml

* fixing test

* Forcing vs17 and adding in .net 6 sdk

* forcing pool

* fixing issues in each pipeline

* moving release .net up

* fixing diff on agent version for nuget installer

* Removing system.text.json.dll as included now

* getting unit tests it looks like to work

* updating everythign to .net 6 minus wxs for runtime

* unit test still have

* getting 6.0 stuff up and going.  Terminal Unit tests have file max length issue ....

* found i think the last .net 5 issue

* looks like i wasn't aggressive enough with the 6.0 upgrade

* Getting stuff .net 6 buildable again

* tweaking with new stuff for installer

* Update newly added merged projects to .net 6

* Fix HeatDirectory bug on VS 2022

* Settings still needs JSON dependency

* Revert "getting 6.0 stuff up and going.  Terminal Unit tests have file max length issue ...."

This reverts commit b9cb4586dc.

* Update sln version

* supress obsolete warning, since this is not a new development

* Partially Revert "Getting stuff .net 6 buildable again"

This reverts commit 42b4201c6b.

* supress another obsolete warning, since this is not a new development

* Reduce the unit test project name to avoid MAX PATH in CI

* Upgrade project's toolset in the main solution

* Some TODOs to review HttpClient usage

* Upgrade project toolsets from other solutions

* Install .net 6 instead of .net 5

* Fix issue when disabling PowerToys Run on .net framework 6

* Update docs for Visual Studio 2022

* PR comments: manually upgrade missing VS 2019 references

* Discard no discard values to solve compiler warnings

Co-authored-by: Jaime Bernardo <jaime@janeasystems.com>
2022-02-07 14:08:30 +00:00
Tyler
2cdf6f9cc0 Fix typo in README (#16111) 2022-02-05 13:35:27 -08:00
CleanCodeDeveloper
8bb0772ae5 [ImageResizer] Fix bug "Operation caused an invalid state" (#15852)
* Add metadata check to ensure valid metadata

* Thank you Mister Spellbot
2022-02-04 16:59:33 +00:00
Heiko
2a34cf740b [PowerToys Run] Windows Terminal plugin: Improve query speed (#15836)
* Change code to query aumid

* update comment

* update aumid on package update

* fix tetx position

* Write AUMID as static values in code

* code style
2022-02-04 16:57:37 +00:00
Heiko
314425e32e [PT Run] System commands plugin: Update dev docs and UnitTests (#15832)
* update UnitTests

* dev docs

* fix plugin name

* fix spelling

* fix path

* improvement

* fix table
2022-02-04 16:56:31 +00:00
Stefan Markovic
26e3eb9350 [MouseCrosshairs] Update initial cursor position before drawing (#16077) 2022-02-04 16:28:25 +01:00
Seraphima Zykova
a3dbb55404 [FancyZones] Increase the number of zones limit to 128 (#15976) 2022-02-04 15:09:11 +00:00
Chanakya
f62dd6933c ignore .gcode files for github linguist (#16029) 2022-02-03 09:32:34 -08:00
Andrey Nekrasov
3e7b04891d [AlwaysOnTop] Improve performance and power consumption (#15993) 2022-02-03 20:30:05 +03:00
Stefan Markovic
ddf96e28b8 [PowerRename] Set RegEx engine default flags to 0 (#15865) 2022-02-02 17:46:22 +01:00
Jaime Bernardo
567cc50fb7 [Runner]remove hotkeyEx when disabling a module (#15944) 2022-02-02 12:17:37 +00:00
Heiko
79c13aec6e [PTRun]WindowWalker: remove IsCloaked check (#15943) 2022-02-02 11:07:43 +00:00
Jaime Bernardo
26f01431ff [MouseUtils]check queue dispatcher initialization (#15948) 2022-02-02 11:06:32 +00:00
Jaime Bernardo
55e3a94da3 [PTRun]Remove Wox plugin install dead code/deps (#15869) 2022-02-02 10:58:13 +00:00
Stefan Markovic
0fc69ca222 If process elevated and --dont-elevate arg - run non elevated (#15920) 2022-02-02 11:23:40 +01:00
Stefan Markovic
51a43d58de [runner] Save settings on closing only when PT was actually running (#15926)
i.e. Don't save if PT was only scheduling a restart
2022-02-02 10:54:03 +01:00
Niels Laute
b27a7261be Custom AutoSuggestBox style (#15847) 2022-02-01 14:50:33 +01:00
Niels Laute
8144f5cedd [Settings] UX bugfixes (#15848)
* Update AlwaysOnTopPage.xaml

* Update VideoConference.xaml
2022-02-01 14:48:48 +01:00
Clint Rutkas
f67ae38aba Update README.md 2022-01-31 16:48:04 -08:00
Clint Rutkas
6b5fd308cb Preview pane support is already in Windows.
Pedro dropped a knowledge bomb on me.
2022-01-31 16:46:07 -08:00
Clint Rutkas
fb4ab87fdd Update README.md for .55 release (#15825)
update for .055 readme.
2022-01-31 11:04:11 -08:00
358 changed files with 19677 additions and 4758 deletions

2
.gitattributes vendored
View File

@@ -13,3 +13,5 @@
# entries below.
###############################################################################
*.rc diff
*.gcode linguist-detectable=false

View File

@@ -0,0 +1,3 @@
bdoserror
crutkas
edwinzap

View File

@@ -1,6 +1,6 @@
# See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-excludes
(?:^|/)monacoSRC/
(?:^|/)MonacoPreviewHandler/languages.json
(?:^|/)MonacoPreviewHandler/monaco_languages.json
(?:^|/)MonacoPreviewHandler/index.html
(?:^|/)MonacoPreviewHandler/generateLanguagesJson.html
(?:^|/)(?i)COPYRIGHT
@@ -34,6 +34,7 @@ ignore$
\.woff$
\.zip$
^doc/devdocs/akaLinks\.md$
^installer/PowerToysSetup/WebView2/MicrosoftEdgeWebview2Setup.exe$
^src/common/logger/logger\.vcxproj\.filters$
^src/common/notifications/BackgroundActivatorDLL/BackgroundActivator\.vcxproj\.filters$
^src/common/notifications/BackgroundActivatorDLL/cpp\.hint$
@@ -48,3 +49,5 @@ ignore$
^\.github/
^\.github/actions/spell-check/
^\.gitmodules$
(?:^|/)WindowsSettings\.json$
(?:^|/)timezones\.json$

View File

@@ -34,6 +34,8 @@ AFX
AGGREGATABLE
AHybrid
Aissue
Akrotiri
Aktobe
ALarger
alekhyareddy
alignas
@@ -45,10 +47,12 @@ Altdown
altform
alwaysontop
amd
AMF
Amicrosoft
AModifier
AMPROPERTY
AMPROPSETID
Andreanof
anges
angularsen
ansicolor
@@ -61,6 +65,7 @@ APeriod
api
APIENTRY
APIIs
Apm
APPBARDATA
appcontainer
appdata
@@ -71,6 +76,7 @@ APPLASTZONE
applets
Applicationcan
applicationframehost
applog
appmanifest
appref
apps
@@ -80,6 +86,7 @@ appx
appxmanifest
APSTUDIO
AQS
Aqtobe
arcosh
ARemapped
argb
@@ -95,6 +102,7 @@ ARRAYSIZE
arsinh
artanh
Artboard
Artsakh
asdf
AShortcut
ASingle
@@ -103,6 +111,7 @@ aspnet
ASSOCCHANGED
ASYNCWINDOWPLACEMENT
ASYNCWINDOWPOS
Atikokan
atl
atlbase
atlcom
@@ -112,6 +121,7 @@ atlstr
atop
Attribs
attrs
Atyrau
aumid
Aut
Authenticode
@@ -124,6 +134,7 @@ AUTOMATIONPROPERTIES
Autorun
AUTOUPDATE
AValid
Avanc
Awaitable
awakeness
awakeversion
@@ -133,13 +144,17 @@ AZCLI
azurecr
backend
backtracer
BADD
BAEC
BAF
bak
Bashkortostan
Bayan
bbwe
bck
Bcl
BEEE
Belarus
betadele
betsegaw
BFB
@@ -198,8 +213,11 @@ BUILDARCH
buildcommand
buildtools
buildtransitive
Burkina
Buryatia
BValue
bytearray
Caiguna
CALG
callbackptr
cameligo
@@ -232,12 +250,14 @@ ChaseKnowlden
chdir
CHILDACTIVATE
CHILDWINDOW
Choibalsan
chrdavis
chromaticities
chrono
Chrzan
chrzan
CHT
Chukotka
Chuuk
cielab
ciexyz
CImage
@@ -255,13 +275,14 @@ CLIENTEDGE
CLIENTPULL
clientside
CLIPCHILDREN
Clipperton
CLIPSIBLINGS
cljs
clrcall
Cls
cls
CLSCTX
clsid
Clusion
cmder
Cmdlet
cmdline
@@ -274,9 +295,11 @@ CMONITORS
cmp
cmyk
cnt
Cocklebiddy
coclass
codebase
codecvt
CODENAME
codeofconduct
codereview
Codespaces
@@ -297,6 +320,7 @@ comhost
cominterop
commandline
commctrl
Comoros
companding
Compat
COMPOSITIONFULL
@@ -364,6 +388,7 @@ CTRLALTDEL
Ctrls
Ctx
CUI
Cunha
currentculture
CURSORINFO
cursorpos
@@ -383,6 +408,7 @@ czf
cziplib
Dac
dacl
Danmarkshavn
DARKPURPLE
DARKTEAL
DARKYELLOW
@@ -393,7 +419,7 @@ davidegiacometti
Dayof
DBCD
DBDA
dbg
Dbg
Dbghelp
DBLCLKS
DBLEPSILON
@@ -488,6 +514,7 @@ DQTYPE
DRAWFRAME
drawingcolor
dreamsofameaningfullife
DRect
drivedetectionwarning
dshow
dst
@@ -566,9 +593,11 @@ ESettings
esize
esrp
estdir
Eswatini
etcore
etl
etw
Eucla
EUQ
eventlog
everytime
@@ -603,6 +632,7 @@ fancyzones
FANCYZONESDRAWLAYOUTTEST
FANCYZONESEDITOR
Farbraum
Faroe
FARPROC
FBF
FCCD
@@ -632,13 +662,13 @@ findfast
findstr
Firefox
FIXEDFILEINFO
FIXME
FLASHZONES
FLASHZONESONQUICKSWITCH
flt
flyout
fmtlib
FOF
fof
FOFX
FOLDERID
folderpath
@@ -657,6 +687,7 @@ fstream
FTYPE
func
Functiondiscoverykeys
Futuna
fwlink
fwrite
fxcop
@@ -726,6 +757,7 @@ hdrop
HEB
Heiko
helptext
Heure
HEVC
hfile
hglobal
@@ -733,6 +765,8 @@ hhk
HHmmss
HHOOK
hhx
Hiber
Hiberboot
HICON
HIDEWINDOW
highlighter
@@ -766,6 +800,7 @@ hotkeycontrol
hotkeys
hotlight
hotspot
Hovd
HPAINTBUFFER
HRAWINPUT
hread
@@ -994,6 +1029,7 @@ ith
IThrottled
ithumbnail
ITrigger
Ittoqqortoormiit
IUI
IUnknown
IUri
@@ -1052,14 +1088,23 @@ keystokes
Keystool
Keytool
keyup
Khakassia
Khanty
Khovd
KILLFOCUS
Kitts
Knowlden
Knownfolders
kotlin
Krai
KSPROPERTY
ktm
kts
Kwango
Kwilu
Kybd
Kyrgyzstan
Kyzylorda
LAlt
Lambson
lamotile
@@ -1067,7 +1112,6 @@ langword
Lastdevice
LASTEXITCODE
Laute
laute
laviusmotileng
LAYOUTRTL
LBUTTON
@@ -1083,14 +1127,17 @@ Ldone
ldx
LEFTSCROLLBAR
lego
lemy
len
LEQ
LError
Lessthan
LEVELID
LExit
lgii
lhs
lhwnd
lia
LIBID
LIGHTORANGE
LIGHTTURQUOISE
@@ -1125,6 +1172,7 @@ logon
LOGPIXELSX
LOn
longdate
LONGLONG
lookbehind
lowlevel
LOWORD
@@ -1159,10 +1207,14 @@ lstrcmpi
lstrlen
LTRB
LTRREADING
Luhansk
LWA
lwin
LZero
lzw
Maarten
Macquarie
Magadan
MAINICON
Mainwindow
majortype
@@ -1173,13 +1225,18 @@ MAKEINTRESOURCEW
MAKELPARAM
makepri
malloc
Mangere
Mangystau
manifestdependency
Mansi
MAPPEDTOSAMEKEY
MAPTOSAMESHORTCUT
MAPVK
Markdig
Marquesas
martinchrzan
martinmoene
Mato
MAXIMIZEBOX
MAXSHORTCUTSIZE
maxversiontested
@@ -1188,12 +1245,15 @@ MBUTTON
MBUTTONDBLCLK
MBUTTONDOWN
MBUTTONUP
MCDT
MCST
MDICHILD
MDL
mdpreviewhandler
MEDIASUBTYPE
mediatype
Melman
memcmp
memcpy
memset
MENUITEMINFO
@@ -1226,9 +1286,11 @@ miniz
minlevel
Miracast
mirophone
Mishkeegogamang
mjpg
mkdir
mlcfg
MMDDYYYY
mmdeviceapi
mmi
mmsys
@@ -1238,6 +1300,8 @@ MODECHANGE
moderncop
modernwpf
modulekey
Moldova
Mongala
MONITORINFO
MONITORINFOEX
MONITORINFOEXW
@@ -1291,23 +1355,27 @@ MULTIPLEUSE
Multiselect
multiset
multizone
Mundrabilla
mutex
mutexes
muxc
mvvm
myfile
MYICON
MYTZ
NAMECHANGE
nameof
namespace
namings
NATIVEFNTCTL
Navassa
NCACTIVATE
ncc
NCCALCSIZE
NCCREATE
NCDESTROY
NCHITTEST
ncipe
NCLBUTTONDBLCLK
NCLBUTTONDOWN
NCLBUTTONUP
@@ -1322,6 +1390,7 @@ NCRBUTTONDBLCLK
NCRBUTTONDOWN
NCRBUTTONUP
NDEBUG
Ndombe
ndp
NEEDDISPATCH
neq
@@ -1342,6 +1411,7 @@ newitem
newpath
newrow
Newtonsoft
nia
niels
nielslaute
NIF
@@ -1376,8 +1446,10 @@ NOREMOVE
norename
NOREPEAT
NOREPOSITION
norestart
NORMALDISPLAY
NORMALUSER
Noronha
NOSEARCH
NOSENDCHANGING
NOSIZE
@@ -1406,6 +1478,8 @@ nullptr
numberbox
NUMLOCK
NUMPAD
Nunavut
Nusa
Nvidia
nwc
NWSE
@@ -1458,6 +1532,7 @@ Overridable
Oversampling
OWNDC
PACL
pagos
PAINTSTRUCT
PAIT
PALEBLUE
@@ -1479,7 +1554,7 @@ pcb
pch
PCIDLIST
PCWSTR
Pdb
pdb
pdbonly
pdfpreviewhandler
@@ -1494,6 +1569,7 @@ pesi
PEXCEPTION
pfn
pfo
pft
pgp
pguid
phbm
@@ -1510,6 +1586,7 @@ pinfo
pinvoke
Pipelinhttps
pipename
Pitcairn
PKBDLLHOOKSTRUCT
PKEY
plib
@@ -1521,6 +1598,7 @@ plugin
pluginsmodel
plx
PMSIHANDLE
Pohnpei
policheck
popd
popup
@@ -1567,6 +1645,7 @@ PREVIOUSVERSIONSINSTALLED
prevpane
prgms
pri
Primorsky
PRINTCLIENT
printf
prm
@@ -1621,6 +1700,7 @@ qit
QITAB
QITABENT
qps
quateur
Queryable
QUERYENDSESSION
QUERYOPEN
@@ -1660,8 +1740,9 @@ RECTDESTINATION
RECTL
rectp
rects
Recyclebin
recyclebin
redirectedfrom
Redist
reencode
reencoded
refactor
@@ -1729,9 +1810,11 @@ RKey
RMENU
RNumber
roadmap
robmensching
robocopy
Roboto
roslyn
Rothera
royvou
Rpc
RRF
@@ -1766,7 +1849,7 @@ scancode
scanled
schedtasks
scm
SCOOBE
scoobe
SCOPEID
screenshot
scrollable
@@ -1859,6 +1942,7 @@ signtool
SINGLEKEY
singlekeyremapcontrol
singletones
Sint
sipolicy
SIZEBOX
sizeg
@@ -1902,7 +1986,9 @@ spsrm
spsv
sqlite
SRCCOPY
Srch
sre
Srednekolymsk
sregex
SResize
SRGB
@@ -1940,7 +2026,7 @@ STDMETHODIMP
stdout
stefan
STEPIT
stgm
STGM
STGMEDIUM
sticpl
stl
@@ -1972,7 +2058,9 @@ subkey
SUBLANG
subquery
substr
Sul
Superbar
Suri
sut
SVE
SVGIn
@@ -2005,10 +2093,11 @@ SYSLIB
syslog
SYSMENU
systemd
SYSTEMAPPS
SYSTEMTIME
systemverilog
Tadele
tadele
Tajikistan
talynone
TApp
TApplication
@@ -2035,6 +2124,7 @@ telem
tellg
Templated
templatenamespace
Tenggara
testcase
testhost
testprocess
@@ -2053,6 +2143,8 @@ timediff
Timeline
timeunion
timeutil
timezone
timezones
Titlecase
TLayout
tlb
@@ -2065,7 +2157,6 @@ Toolchain
toolkitcontrols
toolkitconverters
Toolset
toolset
toolstrip
toolwindow
TOPDOWNDIB
@@ -2079,14 +2170,18 @@ tracelogging
trackpad
traies
transcoded
Transnistria
transparrent
TRAYMOUSEMESSAGE
triaging
TRK
trl
trunc
Tshuapa
tspan
TStr
Tuva
TValue
TYMED
typedef
TYPEKEY
@@ -2096,13 +2191,16 @@ TYPEMOUSE
typename
typeof
typeparam
typeparamref
TYPESHORTCUT
UAC
UAL
uap
udit
Udmurtia
Udp
uefi
UHash
UIA
Uid
uint
@@ -2110,6 +2208,7 @@ uintptr
UIPI
UIs
UITo
Ulaanbaatar
ULARGE
ULLONG
ulong
@@ -2132,6 +2231,7 @@ Uniq
uniquifier
Uniquifies
unitconverter
unittest
unittests
unk
unknwn
@@ -2151,6 +2251,7 @@ Uptool
upvote
uri
URLs
Urville
Usb
USEDEFAULT
USEFILEATTRIBUTES
@@ -2166,6 +2267,7 @@ Utc
utf
utils
uuidof
Uvs
uwp
UWPUI
uxtheme
@@ -2215,6 +2317,7 @@ VSC
VSCBD
vscdb
vscode
vsconfig
VSCROLL
vse
vsix
@@ -2222,6 +2325,7 @@ vsonline
vstemplate
VSTHRD
VSTT
vtable
VTABLE
Vtbl
WBounds
@@ -2314,6 +2418,7 @@ wixproj
wixtoolset
WIXUI
WKSG
Wlkr
wmain
WMKEYDOWN
WMKEYUP
@@ -2341,6 +2446,7 @@ wprp
wregex
WResize
writefile
Wrk
wsf
wsh
wsl
@@ -2380,6 +2486,7 @@ XResource
xsi
XStr
XVIRTUALSCREEN
Yamalia
YIncrement
yinwang
YOffset
@@ -2390,6 +2497,7 @@ YUYV
YVIRTUALSCREEN
YVU
YVYU
Zabaykalsky
ZEROINIT
ZIndex
zonable
@@ -2398,4 +2506,5 @@ ZONEHIGHLIGHTCOLOR
zoneset
ZONESETCHANGE
Zoneszonabletester
zzz
Zonev
zzz

View File

@@ -94,6 +94,7 @@
"modules\\launcher\\Plugins\\VSCodeWorkspaces\\Community.PowerToys.Run.Plugin.VSCodeWorkspaces.dll",
"modules\\launcher\\Plugins\\Service\\Microsoft.PowerToys.Run.Plugin.Service.dll",
"modules\\launcher\\Plugins\\System\\Microsoft.PowerToys.Run.Plugin.System.dll",
"modules\\launcher\\Plugins\\TimeZone\\Microsoft.PowerToys.Run.Plugin.TimeZone.dll",
"modules\\launcher\\Plugins\\WebSearch\\Community.PowerToys.Run.Plugin.WebSearch.dll",
"modules\\launcher\\Plugins\\WindowsTerminal\\Microsoft.PowerToys.Run.Plugin.WindowsTerminal.dll",
@@ -158,7 +159,6 @@
},
{
"MatchedPath": [
"Microsoft.Search.Interop.dll",
"ModernWpf.dll",
"ModernWpf.Controls.dll",
"System.IO.Abstractions.dll",
@@ -173,7 +173,6 @@
"HelixToolkit.Core.Wpf.dll",
"Mages.Core.dll",
"JetBrains.Annotations.dll",
"ICSharpCode.SharpZipLib.dll",
"NLog.Extensions.Logging.dll",
"concrt140_app.dll",
"msvcp140_1_app.dll",

View File

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

View File

@@ -10,6 +10,7 @@ jobs:
BuildConfiguration: ${{ parameters.configuration }}
BuildPlatform: ${{ parameters.platform }}
pool:
demands: ImageOverride -equals WinDevVS17-latest
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
name: WinDevPoolOSS-L
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:

View File

@@ -7,12 +7,20 @@ steps:
submodules: true
clean: true
- task: NuGetToolInstaller@0
displayName: Ensure NuGet 5.8.0
- task: UseDotNet@2
displayName: 'Use .NET 3.1 for unit test SDK'
inputs:
versionSpec: 5.8.0
packageType: sdk
version: '3.1.x'
#- template: .\..\..\..\restore-dependencies.yml
- task: UseDotNet@2
displayName: 'Use .NET 6 SDK'
inputs:
packageType: sdk
version: '6.x'
- task: NuGetToolInstaller@1
displayName: Ensure NuGet Installer
- task: VisualStudioTestPlatformInstaller@1
displayName: Ensure VSTest Platform
@@ -30,7 +38,7 @@ steps:
displayName: 'Build PowerToys.sln'
inputs:
solution: '**\PowerToys.sln'
vsVersion: 16.0
vsVersion: 17.0
platform: '$(BuildPlatform)'
configuration: '$(BuildConfiguration)'
msbuildArgs: ${{ parameters.additionalBuildArguments }}
@@ -49,7 +57,7 @@ steps:
displayName: 'Build BugReportTool.sln'
inputs:
solution: '**\BugReportTool.sln'
vsVersion: 16.0
vsVersion: 17.0
platform: '$(BuildPlatform)'
configuration: '$(BuildConfiguration)'
msbuildArgs: ${{ parameters.additionalBuildArguments }}
@@ -68,7 +76,7 @@ steps:
displayName: 'Build WebcamReportTool.sln'
inputs:
solution: '**\WebcamReportTool.sln'
vsVersion: 16.0
vsVersion: 17.0
platform: '$(BuildPlatform)'
configuration: '$(BuildConfiguration)'
msbuildArgs: ${{ parameters.additionalBuildArguments }}
@@ -87,7 +95,7 @@ steps:
displayName: 'Build PowerToysSetup.sln'
inputs:
solution: '**\installer\PowerToysSetup.sln'
vsVersion: 16.0
vsVersion: 17.0
platform: '$(BuildPlatform)'
configuration: '$(BuildConfiguration)'
msbuildArgs: ${{ parameters.additionalBuildArguments }}
@@ -123,7 +131,7 @@ steps:
**\Microsoft.Plugin.Uri.UnitTests.dll
**\Wox.Test.dll
**\Microsoft.PowerToys.Run.Plugin.System.UnitTests.dll
**\Microsoft.PowerToys.Run.Plugin.WindowsTerminal.UnitTests.dll
**\Microsoft.Plugin.WindowsTerminal.UnitTests.dll
!**\obj\**
!**\ref\**

View File

@@ -4,7 +4,7 @@ pr: none
pool:
name: WinDevPool-L
demands: ImageOverride -equals WinDevVS16-latest
demands: ImageOverride -equals WinDevVS17-latest
parameters:
- name: buildConfigurations
@@ -53,37 +53,26 @@ jobs:
scriptName: .pipelines/versionSetting.ps1
arguments: -versionNumber '${{ parameters.versionNumber }}' -DevEnvironment ''
- task: MicrosoftTDBuild.tdbuild-task.tdbuild-task.TouchdownBuildTask@1
displayName: 'Download Localization Files -- PowerToys 37400'
# Guardian tool needs 'Microsoft.NETCore.App', version '2.1.0' (x64)
- task: UseDotNet@2
displayName: 'Use .NET Core 2.1 SDK'
inputs:
teamId: 37400
authId: '$(TouchdownApplicationID)'
authKey: '$(TouchdownApplicationKey)'
resourceFilePath: |
**\Resources.resx
**\Resource.resx
**\Resources.resw
appendRelativeDir: true
localizationTarget: false
pseudoSetting: Included
- task: PowerShell@2
displayName: Move Loc files into correct locations
packageType: sdk
version: '2.1.x'
- task: UseDotNet@2
displayName: 'Use .NET 6 SDK'
inputs:
targetType: inline
script: >-
$VerbosePreference = "Continue"
packageType: sdk
version: '6.x'
./tools/build/move-and-rename-resx.ps1
./tools/build/move-uwp-resw.ps1
pwsh: true
- task: NuGetAuthenticate@0
inputs:
nuGetServiceConnections: PowerToysCDPxFeed
- task: NuGetToolInstaller@1
displayName: Use NuGet 5.10
inputs:
versionSpec: 5.10
displayName: Use NuGet Installer latest
# this will restore the following nugets:
# - main solution
# - Bug report tool
@@ -98,6 +87,32 @@ jobs:
selectOrConfig: config
nugetConfigPath: .pipelines/release-nuget.config
- task: MicrosoftTDBuild.tdbuild-task.tdbuild-task.TouchdownBuildTask@1
displayName: 'Download Localization Files -- PowerToys 37400'
inputs:
teamId: 37400
authId: '$(TouchdownApplicationID)'
authKey: '$(TouchdownApplicationKey)'
resourceFilePath: |
**\Resources.resx
**\Resource.resx
**\Resources.resw
appendRelativeDir: true
localizationTarget: false
# pseudoSetting: Included
- task: PowerShell@2
displayName: Move Loc files into correct locations
inputs:
targetType: inline
script: >-
$VerbosePreference = "Continue"
./tools/build/move-and-rename-resx.ps1
./tools/build/move-uwp-resw.ps1
pwsh: true
- task: CmdLine@2
displayName: Moving telem files
inputs:
@@ -111,7 +126,7 @@ jobs:
displayName: Build PowerToys main project
inputs:
solution: '**\PowerToys.sln'
vsVersion: 16.0
vsVersion: 17.0
msbuildArgs: /p:CIBuild=true /bl:$(Build.SourcesDirectory)\msbuild.binlog
platform: $(BuildPlatform)
configuration: $(BuildConfiguration)
@@ -122,7 +137,7 @@ jobs:
displayName: Build BugReportTool
inputs:
solution: '**/tools/BugReportTool/BugReportTool.sln'
vsVersion: 16.0
vsVersion: 17.0
msbuildArgs: /p:CIBuild=true /bl:$(Build.SourcesDirectory)\msbuild.binlog
platform: $(BuildPlatform)
configuration: $(BuildConfiguration)
@@ -133,7 +148,7 @@ jobs:
displayName: Build WebcamReportTool
inputs:
solution: '**/tools/WebcamReportTool/WebcamReportTool.sln'
vsVersion: 16.0
vsVersion: 17.0
msbuildArgs: /p:CIBuild=true /bl:$(Build.SourcesDirectory)\msbuild.binlog
platform: $(BuildPlatform)
configuration: $(BuildConfiguration)
@@ -144,7 +159,7 @@ jobs:
displayName: Build PowerToysSetupCustomActions
inputs:
solution: '**/installer/PowerToysSetup.sln'
vsVersion: 16.0
vsVersion: 17.0
msbuildArgs: /target:PowerToysSetupCustomActions /p:CIBuild=true /bl:$(Build.SourcesDirectory)\msbuild.binlog
platform: $(BuildPlatform)
configuration: $(BuildConfiguration)
@@ -155,7 +170,7 @@ jobs:
displayName: Publish Settings for Packaging
inputs:
solution: 'src/settings-ui/PowerToys.Settings/PowerToys.Settings.csproj'
vsVersion: 16.0
vsVersion: 17.0
msbuildArgs: >-
/target:Publish
/p:Configuration=$(BuildConfiguration);Platform=$(BuildPlatform);AppxBundle=Never
@@ -170,7 +185,7 @@ jobs:
displayName: Publish Launcher for Packaging
inputs:
solution: 'src/modules/launcher/PowerLauncher/PowerLauncher.csproj'
vsVersion: 16.0
vsVersion: 17.0
# The arguments should be the same as the ones for Settings; make sure they are.
msbuildArgs: >-
/target:Publish
@@ -185,6 +200,7 @@ jobs:
#### MAIN SIGNING AREA
# reference https://dev.azure.com/microsoft/Dart/_git/AppDriver?path=/ESRPSigning.json&version=GBarm64-netcore&_a=contents for winappdriver
# https://dev.azure.com/microsoft/Dart/_git/AppDriver?path=/CIPolicy.xml&version=GBarm64-netcore&_a=contents
- task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1
displayName: Sign Core PT
inputs:
@@ -210,7 +226,7 @@ jobs:
displayName: Build MSI
inputs:
solution: '**/installer/PowerToysSetup.sln'
vsVersion: 16.0
vsVersion: 17.0
msbuildArgs: /p:CIBuild=true /target:PowerToysInstaller /bl:$(Build.SourcesDirectory)\msbuild.binlog
platform: $(BuildPlatform)
configuration: $(BuildConfiguration)
@@ -246,7 +262,7 @@ jobs:
displayName: Build Bootstrapper
inputs:
solution: '**/installer/PowerToysSetup.sln'
vsVersion: 16.0
vsVersion: 17.0
msbuildArgs: /p:CIBuild=true /bl:$(Build.SourcesDirectory)\msbuild.binlog
platform: $(BuildPlatform)
configuration: $(BuildConfiguration)
@@ -318,14 +334,54 @@ jobs:
displayName: Component Detection
- task: CopyFiles@2
displayName: Copying files for symbols
inputs:
contents: >-
**/*.pdb
flattenFolders: True
targetFolder: $(Build.ArtifactStagingDirectory)/Symbols/
- task: PowerShell@2
displayName: 'Remove unneeded files from ArtifactStagingDirectory'
inputs:
targetType: 'inline'
script: |
cd $(Build.ArtifactStagingDirectory)/Symbols/
Remove-Item vc143.pdb
Remove-Item *test*
- task: PublishSymbols@2
displayName: Publish symbols path
continueOnError: True
inputs:
SearchPattern: |
$(Build.ArtifactStagingDirectory)/Symbols/**/*.*
IndexSources: false
SymbolServerType: TeamServices
- task: PublishBuildArtifacts@1
displayName: 'Publish Artifact: Symbols'
inputs:
PathtoPublish: $(System.ArtifactsDirectory)/Symbols/
ArtifactName: Symbols
- task: DeleteFiles@1
displayName: 'Remove symbols from ArtifactStagingDirectory'
inputs:
Contents: '*'
SourceFolder: $(Build.ArtifactStagingDirectory)/Symbols/
RemoveSourceFolder: True
- task: CopyFiles@2
displayName: Copying setup file over
inputs:
contents: '**/PowerToysSetup-*.exe'
flattenFolders: True
targetFolder: $(Build.ArtifactStagingDirectory)
- task: PublishBuildArtifacts@1
displayName: 'Publish Artifact: PowerToySetup'
inputs:
PathtoPublish: $(System.ArtifactsDirectory)
ArtifactName: BuildArtifacts
ArtifactName: setup-$(BuildPlatform)
...

View File

@@ -28,11 +28,8 @@ if($items.Count -eq 0)
$items | ForEach-Object {
if($_.VersionInfo.FileVersion -eq "1.0.0.0" )
{
if(-not $_.Name.EndsWith("Microsoft.Search.Interop.dll"))
{
Write-Host "Version not set: " + $_.FullName
$totalFailure++;
}
Write-Host "Version not set: " + $_.FullName
$totalFailure++;
}
}

View File

@@ -6,7 +6,6 @@
"Microsoft.VisualStudio.Workload.NativeDesktop",
"Microsoft.VisualStudio.Workload.ManagedDesktop",
"Microsoft.VisualStudio.Workload.Universal",
"Microsoft.VisualStudio.Component.Windows10SDK.17134",
"Microsoft.VisualStudio.Component.Windows10SDK.18362",
"Microsoft.VisualStudio.ComponentGroup.UWP.VC",
"Microsoft.VisualStudio.Component.VC.Runtimes.x86.x64.Spectre",

View File

@@ -81,7 +81,7 @@
<!-- Props that are constant for both Debug and Release configurations -->
<PropertyGroup Label="Configuration">
<PlatformToolset Condition="'$(OverridePlatformToolset)'!='True'">v142</PlatformToolset>
<PlatformToolset Condition="'$(OverridePlatformToolset)'!='True'">v143</PlatformToolset>
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)\obj\$(ProjectName)\</IntDir>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>

View File

@@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28803.452
# Visual Studio Version 17
VisualStudioVersion = 17.0.32014.148
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "runner", "src\runner\runner.vcxproj", "{9412D5C6-2CF2-4FC2-A601-B55508EA9B27}"
ProjectSection(ProjectDependencies) = postProject
@@ -174,7 +174,7 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4981CCD1-4CD9-4A49-B240-00AA46493FF8}"
ProjectSection(SolutionItems) = preProject
src\.editorconfig = src\.editorconfig
src\tests\win-app-driver\packages.config = src\tests\win-app-driver\packages.config
.vsconfig = .vsconfig
Solution.props = Solution.props
EndProjectSection
EndProject
@@ -265,6 +265,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "utils", "utils", "{B39DC643
src\common\utils\elevation.h = src\common\utils\elevation.h
src\common\utils\EventLocker.h = src\common\utils\EventLocker.h
src\common\utils\EventWaiter.h = src\common\utils\EventWaiter.h
src\common\utils\excluded_apps.h = src\common\utils\excluded_apps.h
src\common\utils\exec.h = src\common\utils\exec.h
src\common\utils\game_mode.h = src\common\utils\game_mode.h
src\common\utils\HDropIterator.h = src\common\utils\HDropIterator.h
@@ -357,7 +358,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests-PdfThumbnailProvi
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerToys.Run.Plugin.WindowsTerminal", "src\modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.WindowsTerminal\Microsoft.PowerToys.Run.Plugin.WindowsTerminal.csproj", "{A2D583F0-B70C-4462-B1F0-8E81AFB7BA85}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerToys.Run.Plugin.WindowsTerminal.UnitTests", "src\modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.WindowsTerminal.UnitTests\Microsoft.PowerToys.Run.Plugin.WindowsTerminal.UnitTests.csproj", "{4ED320BC-BA04-4D42-8D15-CBE62151F08B}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Plugin.WindowsTerminal.UnitTests", "src\modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.WindowsTerminal.UnitTests\Microsoft.Plugin.WindowsTerminal.UnitTests.csproj", "{4ED320BC-BA04-4D42-8D15-CBE62151F08B}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerRenameUIHost", "src\modules\powerrename\PowerRenameUIHost\PowerRenameUIHost.vcxproj", "{F7EC4E6C-19CA-4FBD-9918-B8AC5FEF4F63}"
ProjectSection(ProjectDependencies) = postProject
@@ -396,6 +397,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests-StlThumbnailProvi
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonacoPreviewHandler", "src\modules\previewpane\MonacoPreviewHandler\MonacoPreviewHandler.csproj", "{04B193D7-3E21-46B8-A958-89B63A8A69DE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerToys.Run.Plugin.TimeZone", "src\modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.TimeZone\Microsoft.PowerToys.Run.Plugin.TimeZone.csproj", "{F44934A8-36F3-49B0-9465-3831BE041CDE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@@ -985,8 +988,8 @@ Global
{4ED320BC-BA04-4D42-8D15-CBE62151F08B}.Debug|x86.ActiveCfg = Debug|x64
{4ED320BC-BA04-4D42-8D15-CBE62151F08B}.Release|x64.ActiveCfg = Release|x64
{4ED320BC-BA04-4D42-8D15-CBE62151F08B}.Release|x64.Build.0 = Release|x64
{4ED320BC-BA04-4D42-8D15-CBE62151F08B}.Release|x86.ActiveCfg = Release|Any CPU
{4ED320BC-BA04-4D42-8D15-CBE62151F08B}.Release|x86.Build.0 = Release|Any CPU
{4ED320BC-BA04-4D42-8D15-CBE62151F08B}.Release|x86.ActiveCfg = Release|x64
{4ED320BC-BA04-4D42-8D15-CBE62151F08B}.Release|x86.Build.0 = Release|x64
{F7EC4E6C-19CA-4FBD-9918-B8AC5FEF4F63}.Debug|x64.ActiveCfg = Debug|x64
{F7EC4E6C-19CA-4FBD-9918-B8AC5FEF4F63}.Debug|x64.Build.0 = Debug|x64
{F7EC4E6C-19CA-4FBD-9918-B8AC5FEF4F63}.Debug|x86.ActiveCfg = Debug|x64
@@ -1073,10 +1076,21 @@ Global
{F1F6B6B6-9F18-4A17-8B5C-97DF552C53DC}.Release|x86.ActiveCfg = Release|x64
{04B193D7-3E21-46B8-A958-89B63A8A69DE}.Debug|x64.ActiveCfg = Debug|x64
{04B193D7-3E21-46B8-A958-89B63A8A69DE}.Debug|x64.Build.0 = Debug|x64
{04B193D7-3E21-46B8-A958-89B63A8A69DE}.Debug|x86.ActiveCfg = Debug|Any CPU
{04B193D7-3E21-46B8-A958-89B63A8A69DE}.Debug|x86.ActiveCfg = Debug|x64
{04B193D7-3E21-46B8-A958-89B63A8A69DE}.Debug|x86.Build.0 = Debug|x64
{04B193D7-3E21-46B8-A958-89B63A8A69DE}.Release|x64.ActiveCfg = Release|x64
{04B193D7-3E21-46B8-A958-89B63A8A69DE}.Release|x64.Build.0 = Release|x64
{04B193D7-3E21-46B8-A958-89B63A8A69DE}.Release|x86.ActiveCfg = Release|x64
{04B193D7-3E21-46B8-A958-89B63A8A69DE}.Release|x86.Build.0 = Release|x64
{04B193D7-3E21-46B8-A958-89B63A8A69DE}.Release|x86.ActiveCfg = Release|Any CPU
{F44934A8-36F3-49B0-9465-3831BE041CDE}.Debug|x64.ActiveCfg = Debug|x64
{F44934A8-36F3-49B0-9465-3831BE041CDE}.Debug|x64.Build.0 = Debug|x64
{F44934A8-36F3-49B0-9465-3831BE041CDE}.Debug|x86.ActiveCfg = Debug|x64
{F44934A8-36F3-49B0-9465-3831BE041CDE}.Debug|x86.Build.0 = Debug|x64
{F44934A8-36F3-49B0-9465-3831BE041CDE}.Release|x64.ActiveCfg = Release|x64
{F44934A8-36F3-49B0-9465-3831BE041CDE}.Release|x64.Build.0 = Release|x64
{F44934A8-36F3-49B0-9465-3831BE041CDE}.Release|x86.ActiveCfg = Release|x64
{F44934A8-36F3-49B0-9465-3831BE041CDE}.Release|x86.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1208,6 +1222,7 @@ Global
{F7C8C0F1-5431-4347-89D0-8E5354F93CF2} = {2F305555-C296-497E-AC20-5FA1B237996A}
{F1F6B6B6-9F18-4A17-8B5C-97DF552C53DC} = {2F305555-C296-497E-AC20-5FA1B237996A}
{04B193D7-3E21-46B8-A958-89B63A8A69DE} = {2F305555-C296-497E-AC20-5FA1B237996A}
{F44934A8-36F3-49B0-9465-3831BE041CDE} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0}

130
README.md
View File

@@ -27,11 +27,14 @@ Microsoft PowerToys is a set of utilities for power users to tune and streamline
### Requirements
- Windows 11 or Windows 10 v1903 (18362) or newer.
- [.NET Core 3.1.22 Desktop Runtime](https://dotnet.microsoft.com/download/dotnet/thank-you/runtime-desktop-3.1.22-windows-x64-installer) or a newer 3.1.x runtime. The installer will handle this if not present.
- Our installer will install the following items:
- [.NET Core 3.1.22 Desktop Runtime](https://dotnet.microsoft.com/download/dotnet/thank-you/runtime-desktop-3.1.22-windows-x64-installer) or a newer 3.1.x runtime. This is needed currently for the Settings application.
- [.NET 5.0.13 Desktop Runtime](https://dotnet.microsoft.com/download/dotnet/thank-you/runtime-desktop-5.0.13-windows-x64-installer) or a newer 5.0.x runtime.
- [Microsoft Edge WebView2 Runtime](https://go.microsoft.com/fwlink/p/?LinkId=2124703) bootstrapper. This will install the latest version.
### Via GitHub with EXE [Recommended]
[Microsoft PowerToys GitHub releases page][github-release-link], click on `Assets` at the bottom to show the files available in the release and then click on `PowerToysSetup-0.53.3-x64.exe` to download the PowerToys installer.
[Microsoft PowerToys GitHub releases page][github-release-link], click on `Assets` at the bottom to show the files available in the release and then click on `PowerToysSetup-0.55.0-x64.exe` to download the PowerToys installer.
This is our preferred method.
@@ -66,98 +69,83 @@ For guidance on developing for PowerToys, please read the [developer docs](/doc/
Our [prioritized roadmap][roadmap] of features and utilities that the core team is focusing on.
#### 0.53 - December 2021 Update
### 0.55 - January 2022 Update
We hope everyone has had a wonderful December 2021. The PowerToys community has been busy with a bunch of improvements. We're still working on improving the installer but this should drastically improve things. 3 things you will want to check out are G-code support in file explorer preview pane and thumbnails, the new web search plugin from PowerToys Run via <kbd>??</kbd> action phrase, and the new Always on Top utility via <kbd>Win</kbd>+<kbd>Ctrl</kbd>+<kbd>T</kbd>.
In this release, we are continuing our progress toward getting PowerToys ARM64 ready, fix some top issues and new utilities. Work from last month enabled us to upgrade the code base to .NET 5 and next month onward to .NET 6. This will provide stability and speed improvements.
[@Aaron-Junker](https://github.com/Aaron-Junker) also has done some great progress on [implementing developer file preview pane](https://github.com/microsoft/PowerToys/issues/1527) via the Monaco engine from Visual Studio Code.
We're also extremely excited to bring on 3 new PowerToy utilities.
#### Things to be aware of
- The new installer currently has a visual quirk when upgrade if you have a custom install path. It will show the default install path but it will actually overwrite the current location. We are investigating how to fix this.
- File Explorer add-on: Developer files for preview pane. This should add about 150 file extensions total. We are using the [Monaco Editor](https://github.com/Microsoft/monaco-editor) to power this experience. Thanks [@aaron-junker](https://github.com/aaron-junker)!
- File Explorer add-on: STL file format thumbnail generation! Since STL is a common 3D file format, this allows a quick visual check. Thanks [@pedrolamas](https://github.com/pedrolamas)! Preview pane support is already in Windows.
- Mouse Utility: Crosshair over pointer via <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>P</kbd>. This feature was co-developed with the accessibility team at Microsoft. When the team told us about the idea and described trying to find your cursor by looking through a straw, we knew we could leverage code from the other mouse utilities to quickly enable this feature. Below is a quote from one of the testers with a rough validation build:
> "This will change my life and allow me to use any PC without constantly losing the pointer. This is huge! I will be able to work at my normal speed again. It is a total game changer for people with visual field impairments!" Joanna A.
#### Community
- We would love to directly say THANK YOU. Filing issues and feature requests takes time and we greatly appreciate it. You help us quickly diagnose, spot trends, and prioritize. We love when people fix bugs and develop new PowerToys every little bit does really help.
- [@edwinzap](https://github.com/edwinzap) really helped us validate translation issues when our localization system was in transition.
- [@bdoserror](https://github.com/bdoserror) quickly pointed out a release note error
#### General
- .NET runtime is now on 5, our next release will be upgraded to .NET 6. Moving to .NET 5 and then 6 helped reduce our moving parts in a single release so we went this route. Why this is important is this is one of the major work items needed for ARM64 support. In addition, this should help provide a speed boosts once we are on .NET 6.
- [@jsoref's](https://github.com/jsoref) spelling plugin help
#### Always on Top
- Welcome to the family! With a quick <kbd>Win</kbd>+<kbd>Ctrl</kbd>+<kbd>T</kbd>, the window in focus is toggled to be on top. Toggle again, and it reverts back to normal.
- Fixed one of two borders showing incorrectly bugs.
- Border defaults to OS accent color now. Thanks [@davidegiacometti](https://github.com/davidegiacometti)
- Reduced CPU / GPU activity. Not done improving, we know we can do better.
#### ColorPicker
- HEX input improvements for adjust color menu including support for hex code without hashtag and short hex code like #CF0. Thanks @htcfreek!
- Better bottom right screen detection for overlay
#### FancyZones
- Bug fixed to not lose zones after update
- Fixed editor margin issue for Chinese language. Thanks [@niels9001](https://github.com/niels9001)
#### FancyZones
- Increased negative space margin
- Fix for not snapping child windows
- Fix for clearing keyboard focus on editor launch
- Fix to improve overlays to reduce brightness and hide numbers. Thanks @davidegiacometti
#### File Explorer
- Added G-code support for thumbnails and preview pane. Thanks @pedrolamas
#### File explorer add-ons
- GCode thumbnails now have transparency. Thanks [@pedrolamas](https://github.com/pedrolamas)
- New Utility - Developer files for File Explorer preview pane. This should add about 150 file extensions total. We are using the [Monaco Editor](https://github.com/Microsoft/monaco-editor) to power this experience. Thanks [@aaron-junker](https://github.com/aaron-junker)!
- New Utility - STL thumbnails added! Preview pane support is already in Windows. Thanks [@pedrolamas](https://github.com/pedrolamas)!
#### Image Resizer
- Fixed regression from Metadata tag removal of ColorSpace. Thanks @CleanCodeDeveloper
- Fixed bug with too much meta data. Thanks [@CleanCodeDeveloper](https://github.com/CleanCodeDeveloper)
- Fixed bug resizing bug for constant height while maintaining aspect ratio. Thanks [@CleanCodeDeveloper](https://github.com/CleanCodeDeveloper)
#### Mouse utilities
- New Utility - Crosshair over pointer via <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>P</kbd>. This feature was co-developed with the accessibility team at Microsoft. Thanks [@niels9001](https://github.com/niels9001) for helping with the icon!
#### PowerRename
- Row highlighting + preview support now implemented. Thanks @niels9001
- Fixed AltGR input issue
- Improved folder renaming support
- Opens on active monitor
- Files are sorted now how File Explorer sorts.
#### PowerToys Run
- Web searching has been added! `?? What is the answer to life` will go to your favorite search engine via your browser. You can change the default action key too! Thanks @cyberrex5 for primary implementation and @franky920920 and @htcfreek for supporting
- VS Code workspace improvements. Thanks @ricardosantos9521
- Binary and Hex number support. Thanks @gsuberland
- Ability to use factorials in calculations
- PT Run will not show in Window Walker results anymore. Thanks @davidegiacometti
- Fix log / ln calculations
- Fix to make previous results clear
- Fix to detect symlinks and prevent recursive loops
- Fix for trackpad scrolling being too fast
- Removed unneeded nuget package. Thanks @ChaseKnowlden
- Better detection for if a packaged app can be elevated
- Improve crash resiliency for Program plugin. Thanks @davidegiacometti
- Improved Windows setting results. Thanks @htcfreek
- Fixed a bug where some similar activation phrases aren't working as expected. Thanks @htcfreek and @cyberrex5.
#### Video conference mute
- Disabled by default as this requires elevation to register the virtual camera.
- Changed (default) hotkey for mute camera & microphone from <kbd>Win</kbd>+<kbd>N</kbd> to <kbd>Win</kbd>+<kbd>Shift</kbd>+<kbd>Q</kbd> to not conflict with a Windows 11 keyboard shortcut
- Improved speed and fixed bugs with Window walker plugin. Thanks [@htcfreek](https://github.com/htcfreek)
- Window Walker will now show path of elevated apps. Thanks [@davidegiacometti](https://github.com/davidegiacometti)
- Added UEFI command to system commands. Thanks [@htcfreek](https://github.com/htcfreek)
- Fixed crashing bug in EnvironmentHelper class. Thanks [@htcfreek](https://github.com/htcfreek)
- Fix URI plugin bug with `^:`. Thanks [@franky920920](https://github.com/franky920920)
- VS Code plugin not showing workspaces with latest Code version was corrected. Thanks [@ricardosantos9521](https://github.com/ricardosantos9521)
- Fixed bug that caused plugins to not load. Thanks [@davidegiacometti](https://github.com/davidegiacometti)
- Fixed crash in Uri plugin and Web search plugin. Thanks [@cyberrex5](https://github.com/cyberrex5)!
#### Settings
- Multiple accessibility, layout, image, string and icons fixes. Thanks @niels9001
- Fixed a regression with settings being reset when moving from admin to non-admin
#### Runner
- Improved mutex support to prevent multiple PT Run instances from running
#### Installer
- **NOTE:** The new installer currently has a visual quirk when upgrade if you have a custom install path. It will show the default install path but it will actually overwrite the current location. We are investigating how to fix this.
- Large progress toward user based installing vs machine wide. Upgrade scenario still needs additional work.
- Removed custom bootstrapper and now are using a WiX bundle.
- Removed unused image assets that were still being shipped. Thanks @niels9001
#### ARM64 support
- Setting WinUI3 proof-of-concept and validate we do need at least one more feature, elevation support from WinUI 3 unpackaged applications.
#### Dev improvements
- New YAML based pipeline for building our signed installer. This will allow us to consolidate our CI to use same file. This was critical for us to unblock ARM64 and .NET 6 migration.
- Our submodules will no longer auto fetch to prevent locking issues. If you want a refresher on how to do this, head to [our dev docs](https://github.com/microsoft/PowerToys/tree/main/doc/devdocs#get-submodules-to-compile)
- Localization system shifted to Touchdown from CDPx. This should remove many of the loc issues.
- Consolidated a lot of the naming of EXEs and DLLs along with projects
- Update to spell checker. Thanks @jsoref
- /dup response has been added
- /reportbug /bugreport will ask for a "report bug" zip
#### Video Conference Mute
- Fixed crashing bug with Zoom and other clients. We found someone we could remotely debug with and identify the actual crashing part.
- Change of behavior: When leaving a meeting, VCM will now leave your microphone in the state it was. This mimics behavior of applications if VCM was not present.
- Change of behavior: When you exit PowerToys, your current microphone state will remain.
#### Community contributions
We'd like to directly mention certain contributors (in alphabetical order) for their continued community support this month and helping directly make PowerToys a better piece of software.
[@Aaron-Junker](https://github.com/Aaron-Junker), [@bdoserror](https://github.com/bdoserror), [@CleanCodeDeveloper](https://github.com/CleanCodeDeveloper), [@cyberrex5](https://github.com/cyberrex5), [@davidegiacometti](https://github.com/davidegiacometti), [@edwinzap](https://github.com/edwinzap), [@franky920920](https://github.com/franky920920), [@jay-o-way](https://github.com/jay-o-way), [@jsoref](https://github.com/jsoref), [@niels9001](https://github.com/niels9001), and [@ricardosantos9521](https://github.com/ricardosantos9521)
[@Aaron-Junker](https://github.com/Aaron-Junker), [@ChaseKnowlden](https://github.com/ChaseKnowlden), [@CleanCodeDeveloper](https://github.com/CleanCodeDeveloper), [@cyberrex5](https://github.com/cyberrex5), [@davidegiacometti](https://github.com/davidegiacometti), [@franky920920](https://github.com/franky920920), [@gsuberland](https://github.com/gsuberland), [@jay-o-way](https://github.com/jay-o-way), [@jsoref](https://github.com/jsoref), [@niels9001](https://github.com/niels9001), and [@ricardosantos9521](https://github.com/ricardosantos9521)
#### What is being planned for v0.55
#### What is being planned for v0.56
For [v0.55][github-next-release-work], we'll work on adding more stability in with VCM and getting dev file preview pane added in so we get 150 file types :)
For [v0.56][github-next-release-work], we plan on finishing up the .NET upgrade path to 6. This will require development to migrate to Visual Studio 2022. We are also shifting back to a continuous version number system versus Odd for main and Even for experimental releases.
- We are working to heavily reduce / remove the UAC prompt over the next few releases on install. This is a big shift so it is spanning multiple releases so we can isolate issues if they do occur. Work is tracked in [#10126](https://github.com/microsoft/PowerToys/issues/10126)
- Getting the dev file preview pane work integrated. (Monaco Editor)
- .NET 6 upgrade to all available surfaces
- Find my mouse feature, accessibility cross-hair
- A Dialog on update making you aware of what has changed.
- 'Shake to activate' find my mouse
- PowerToy Run plugin improvements
## PowerToys Community
@@ -184,5 +172,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%2F28
[github-current-release-work]: https://github.com/microsoft/PowerToys/issues?q=is%3Aopen+is%3Aissue+project%3Amicrosoft%2FPowerToys%2F27
[github-next-release-work]: https://github.com/microsoft/PowerToys/issues?q=is%3Aopen+is%3Aissue+project%3Amicrosoft%2FPowerToys%2F29
[github-current-release-work]: https://github.com/microsoft/PowerToys/issues?q=is%3Aopen+is%3Aissue+project%3Amicrosoft%2FPowerToys%2F28

View File

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

View File

@@ -1,23 +0,0 @@
# Sys Plugin
As the name suggests, the Sys Plugin is used to directly run Windows system commands that have been entered by the user as a query. This is done by parsing the entry and validating the command, followed by executing it.
* Shutdown
* Restart
* Sign Out
* Lock
* Sleep
* Hibernate
* Empty Recycle Bin
![Image of Sys plugin](/doc/images/launcher/plugins/sys.gif)
## [`Sys`](/src/modules/launcher/Plugins/Microsoft.Plugin.Sys/Main.cs)
* Tries to parse the user input and returns a specific Windows system command by using a [`Result`](/src/modules/launcher/Wox.Plugin/Result.cs) list.
* While parsing, the Sys plugin uses [`FuzzyMatch`](/src/modules/launcher/Wox.Infrastructure/StringMatcher.cs) to get characters matching a result in the list.
### Score
* [`CalculateSearchScore`](/src/modules/launcher/Wox.Infrastructure/StringMatcher.cs) A match found near the beginning of a string is scored more than a match found near the end. A match is scored more if the characters in the patterns are closer to each other, while the score is lower if they are more spread out.

View File

@@ -0,0 +1,46 @@
# Windows System Commands Plugin
As the name suggests, the Windows System Commands Plugin is used to directly run Windows system commands that have been entered by the user as a query. This is done by parsing the entry and validating the command, followed by executing it.
The user can change the behavior of the plugin (language, confirmation dialog, ...) with optional plugin settings.
![Image of System Commands plugin](/doc/images/launcher/plugins/sys.gif)
Available commands:
* Shutdown
* Restart
* Sign Out
* Lock
* Sleep
* Hibernate
* Empty Recycle Bin
* UEFI Firmware Settings (Only available on systems, that boot in UEFI mode.)
## Optional plugin settings
* We have the following settings that the user can configure to change the behavior of the plugin:
| Key | Default value | Name/Description |
|--------------|-----------|------------|
| `ConfirmSystemCommands` | `false` | Show a dialog to confirm system commands |
| `LocalizeSystemCommands` | `true` | Use localized system commands instead of English ones |
* The optional plugin settings are implemented via the [`ISettingProvider`](/src/modules/launcher/Wox.Plugin/ISettingProvider.cs) interface from `Wox.Plugin` project. All available settings for the plugin are defined in the [`Main`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Main.cs) class of the plugin.
## Technical details
### [`Main`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Main.cs)
* Tries to parse the user input and returns a specific Windows system command by using a [`Result`](/src/modules/launcher/Wox.Plugin/Result.cs) list.
* While parsing, the plugin uses [`FuzzyMatch`](/src/modules/launcher/Wox.Infrastructure/StringMatcher.cs) to get characters matching a result in the list.
### UEFI command
* The UEFI command is only available on systems, that boot in UEFI mode.
* This is validated by checking the result of the method [`GetSystemFirmwareType`](/src/modules/launcher/Wox.Plugin/Common/Win32/Win32Helpers.cs), which uses the native method [`GetFirmwareType`](/src/modules/launcher/Wox.Plugin/Common/Win32/NativeMethods.cs) in `kernel32.dll`.
### Score
* [`CalculateSearchScore`](/src/modules/launcher/Wox.Infrastructure/StringMatcher.cs) A match found near the beginning of a string is scored more than a match found near the end. A match is scored more if the characters in the patterns are closer to each other, while the score is lower if they are more spread out.

View File

@@ -0,0 +1,150 @@
# Time Zone Plugin
The Time Zone plugin allows users to search a time zone.
## Special functions (differ from the regular functions)
* Search for a country, like Kamchatka, Prince Edward Island, France
* Search for a shortcuts, like WEST, UTC, PST
* Search for a offset, like -12:00, -7, 5, 9:30
* Search for a military time zone name (must activate in plugin settings)
## How to add a new time zone or change one
All time zones are located in `TimeZone.json` in root folder of the project.
The `TimeZone.json` use a JSON schema file that make it easier to edit it.
| Key | Optional | Value type |
| ------------------- | -------- | ----------------- |
| `Offset` | **No** | String |
| `Name` | Yes | String |
| `MilitaryName` | Yes | String |
| `Shortcut` | Yes | String |
| `TimeNamesStandard` | Yes | List with strings |
| `TimeNamesDaylight` | Yes | List with strings |
| `ShortcutsStandard` | Yes | List with strings |
| `ShortcutsDaylight` | Yes | List with strings |
| `CountriesStandard` | Yes | List with strings |
| `CountriesDaylight` | Yes | List with strings |
A minimum entry for the `TimeZone.json` looks like:
```json
{
"Offset": "11:55",
"Name": "My crazy time zone",
}
```
A full entry for the `TimeZone.json` looks like:
```json
{
"Offset": "11:55",
"Name": "My crazy time zone",
"Shortcut" : "MYTZ",
"MilitaryName" : "Order Time Zone",
"TimeNamesStandard": [
"My crazy standard time"
],
"ShortcutsStandard": [
"MCST"
],
"TimeNamesDaylight": [
"My crazy daylight time"
],
"ShortcutsDaylight": [
"MCDT"
],
"CountriesStandard": [
"Crazy Land East"
],
"CountriesDaylight": [
"Crazy Land West"
]
}
```
### Remarks
* At minimum one of the optional value should be filled.
## Scores
* Scores are not used
## Important for developers
### General
* The assembly name is cached into `_assemblyName` (to avoid to many calls of `Assembly.GetExecutingAssembly()`)
## Microsoft.PowerToys.Run.Plugin.TimeZone project
### Important plugin values (meta-data)
| Name | Value |
| --------------- | ---------------------------------------------------- |
| ActionKeyword | `&` |
| ExecuteFileName | `Microsoft.PowerToys.Run.Plugin.TimeZone.dll` |
| ID | `BADD1B06EF0A4B61AD95395F24241D69` |
### Interfaces used by this plugin
The plugin use only these interfaces (all inside the `Main.cs`):
* `Wox.Plugin.IPlugin`
* `Wox.Plugin.IContextMenu`
* `Wox.Plugin.IPluginI18n`
* `Wox.Plugin.ISettingProvider`
* `IDisposable`
### Program files
| File | Content |
| -------------------------------------- | ----------------------------------------------------------------------- |
| `Classes\TimeZoneProperties.cs` | A class that represent one time zone |
| `Classes\TimeZones.cs` | A wrapper class that only contains a list with time zones (see 1) |
| `Classes\TimeZoneSettings.cs` | A class that contains all settings for the Time Zone plugin |
| `Extensions\StringBuilderExtension.cs` | Extension methods for `StringBuilder` Objects |
| `Helper\ContextMenuHelper.cs` | All functions to build the context menu (for each result entry) |
| `Helper\JsonHelper.cs` | All functions to load the time zones from a JSON file |
| `Helper\ResultHelper.cs` | All functions to convert internal results into WOX results |
| `Helper\TranslationHelper.cs` | All functions to translate the result in the surface language |
| `Images\timeZone.dark.png` | Symbol for the results for the dark theme |
| `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.
### Important project values (*.csproj)
| Name | Value |
| --------------- | ------------------------------------------------------------- |
| TargetFramework | `net6.0-windows` |
| Platforms | `x64` |
| Output | `..\..\..\..\..\x64\Debug\modules\launcher\Plugins\TimeZone\` |
| RootNamespace | `Microsoft.PowerToys.Run.Plugin.TimeZone` |
| AssemblyName | `Microsoft.PowerToys.Run.Plugin.TimeZone` |
### Project dependencies
#### Packages
| Package | Version |
| ------------------------------------------------------------------------------------- | ------- |
| [`StyleCop.Analyzers`](https://github.com/DotNetAnalyzers/StyleCopAnalyzers) | 1.1.118 |
#### Projects
* `Wox.Infrastructure`
* `Wox.Plugin`

View File

@@ -141,7 +141,7 @@ Because the JSON file must have a object as root type, instead of a array.
| Name | Value |
| --------------- | --------------------------------------------------------------------------------------------------- |
| TargetFramework | `net5.0-windows` (.NET 5) or `net5.0-windows10.0.18362.0` (OS version specific) |
| TargetFramework | `net6.0-windows` (.NET 5) or `net6.0-windows10.0.18362.0` (OS version specific) |
| Platforms | `x64` |
| Output | `..\..\..\..\..\x64\Debug\modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.WindowsSettings\` |
| RootNamespace | `Microsoft.PowerToys.Run.Plugin.WindowsSettings` |

View File

@@ -11,7 +11,7 @@
- [Program](/doc/devdocs/modules/launcher/plugins/program.md)
- [Registry](/doc/devdocs/modules/launcher/plugins/registry.md)
- [Shell](/doc/devdocs/modules/launcher/plugins/shell.md)
- [Sys](/doc/devdocs/modules/launcher/plugins/sys.md)
- [Windows System Commands](/doc/devdocs/modules/launcher/plugins/system.md)
- [Uri](/doc/devdocs/modules/launcher/plugins/uri.md)
- [Window Walker](/doc/devdocs/modules/launcher/plugins/windowwalker.md)
- [Web Search](/doc/devdocs/modules/launcher/plugins/WebSearch.md)

View File

@@ -9,13 +9,13 @@ Developer preview is based on [Microsofts Monaco Editor](https://microsoft.githu
3. Copy the `min` folder inside the [`monacoSRC`](/src/modules/previewpane/MonacoPreviewHandler/monacoSRC) folder.
4. Generate the JSON file (see section below)
## languages.json
## monaco_languages.json
[`languages.json`](/src/modules/previewpane/MonacoPreviewHandler/languages.json) contains all extensions and Id's for the supported languages of Monaco. The [`FileHandler`](/src/modules/previewpane/MonacoPreviewHandler/FileHandler.cs) class and the installer are using this file.
[`monaco_languages.json`](/src/modules/previewpane/MonacoPreviewHandler/monaco_languages.json) contains all extensions and Id's for the supported languages of Monaco. The [`FileHandler`](/src/modules/previewpane/MonacoPreviewHandler/FileHandler.cs) class and the installer are using this file.
### Generate languages.json file
### Generate monaco_languages.json file
After you updated monaco editor or adding a new language you should update the [`languages.json`](/src/modules/previewpane/MonacoPreviewHandler/languages.json) file.
After you updated monaco editor or adding a new language you should update the [`monaco_languages.json`](/src/modules/previewpane/MonacoPreviewHandler/monaco_languages.json) file.
1. Build monaco in debug mode.
2. Open [generateLanguagesJson.html](/src/modules/previewpane/MonacoPreviewHandler/generateLanguagesJson.html) in a browser.

View File

@@ -38,7 +38,7 @@ Once you've discussed your proposed feature/fix/etc. with a team member, and you
### Prerequisites for Compiling PowerToys
1. Windows 10 April 2018 Update (version 1803) or newer
2. Visual Studio Community/Professional/Enterprise 2019
2. Visual Studio Community/Professional/Enterprise 2022
3. Once you've cloned and started the `PowerToys.sln`, in the solution explorer, if you see a dialog that says `install extra components`, click `install`
### Get Submodules to compile
@@ -69,7 +69,7 @@ The installer can only be compiled in `Release` mode, step 1 and 2 must be done
### Prerequisites for building the MSI installer
1. Install the [WiX Toolset Visual Studio 2019 Extension](https://marketplace.visualstudio.com/items?itemName=WixToolset.WixToolsetVisualStudio2019Extension).
1. Install the [WiX Toolset Visual Studio 2022 Extension](https://marketplace.visualstudio.com/items?itemName=WixToolset.WixToolsetVisualStudio2022Extension).
2. Install the [WiX Toolset build tools](https://wixtoolset.org/releases/).
### Locally compiling the Bug reporting tool

View File

@@ -1,6 +1,6 @@
cd /D "%~dp0"
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64 -winsdk=10.0.18362.0
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64 -winsdk=10.0.18362.0
powershell -file update_appxmanifest_version.ps1 || exit /b 1

View File

@@ -21,7 +21,7 @@
</BootstrapperApplicationRef>
<util:FileSearch Variable="HasDotnet3122" Path="[ProgramFiles64Folder]dotnet\shared\Microsoft.WindowsDesktop.App\3.1.22\System.Xaml.dll" Result="exists" />
<util:FileSearch Variable="HasDotnet5013" Path="[ProgramFiles64Folder]dotnet\shared\Microsoft.WindowsDesktop.App\5.0.13\System.Xaml.dll" Result="exists" />
<util:FileSearch Variable="HasDotnet602" Path="[ProgramFiles64Folder]dotnet\shared\Microsoft.WindowsDesktop.App\6.0.2\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" />
@@ -46,11 +46,12 @@
Id="DotnetRuntime"
DetectCondition="HasDotnet3122"
DownloadUrl="https://download.visualstudio.microsoft.com/download/pr/1c14e24b-7f31-42dc-ba3c-83295a2d6f7e/41b93591162dfe556cc160ae44fbe75e/windowsdesktop-runtime-3.1.22-win-x64.exe"
InstallCommand="/install /quiet"
RepairCommand="/repair /passive"
InstallCommand="/install /quiet /norestart"
RepairCommand="/repair /passive /norestart"
Permanent="yes"
PerMachine="yes"
UninstallCommand="/uninstall /quiet">
UninstallCommand="/uninstall /quiet /norestart">
<ExitCode Value="1638" Behavior="success"/>
<RemotePayload
Description="Microsoft Windows Desktop Runtime - 3.1.22 (x64)"
ProductName="Microsoft Windows Desktop Runtime - 3.1.22 (x64)"
@@ -59,22 +60,23 @@
Hash="08EF2F6CFDB33946061884B1CE13FA867EFBD576" />
</ExePackage>
<ExePackage
Name="windowsdesktop-runtime-5.0.13-win-x64.exe"
Name="windowsdesktop-runtime-6.0.2-win-x64.exe"
Compressed="no"
Id="DotnetRuntime5"
DetectCondition="HasDotnet5013"
DownloadUrl="https://download.visualstudio.microsoft.com/download/pr/2bfb80f2-b8f2-44b0-90c1-d3c8c1c8eac8/409dd3d3367feeeda048f4ff34b32e82/windowsdesktop-runtime-5.0.13-win-x64.exe"
InstallCommand="/install /quiet"
RepairCommand="/repair /passive"
Id="DotnetRuntime6"
DetectCondition="HasDotnet602"
DownloadUrl="https://download.visualstudio.microsoft.com/download/pr/efa32b7a-6eec-4d97-9cdc-c7336a29a749/3df4296170397cf60884dae1be3d103b/windowsdesktop-runtime-6.0.2-win-x64.exe"
InstallCommand="/install /quiet /norestart"
RepairCommand="/repair /passive /norestart"
Permanent="yes"
PerMachine="yes"
UninstallCommand="/uninstall /quiet">
UninstallCommand="/uninstall /quiet /norestart">
<ExitCode Value="1638" Behavior="success"/>
<RemotePayload
Description="Microsoft Windows Desktop Runtime - 5.0.13 (x64)"
ProductName="Microsoft Windows Desktop Runtime - 5.0.13 (x64)"
Size="54456248"
Version="5.0.13.30717"
Hash="EB5506CEBB3DD1CEC78F7F8131F87A2C5F665B40" />
Description="Microsoft Windows Desktop Runtime - 6.0.2 (x64)"
ProductName="Microsoft Windows Desktop Runtime - 6.0.2 (x64)"
Size="57296456"
Version="6.0.2.30914"
Hash="EA8DB9D01555D0EA2A3D3CD41D56A28199A064F5" />
</ExePackage>
<ExePackage
Name="MicrosoftEdgeWebview2Setup.exe"

View File

@@ -98,15 +98,16 @@ call "..\..\publish.cmd"
</Target>
-->
<Target Name="BeforeBuild">
<HeatDirectory Directory="..\..\src\modules\previewpane\MonacoPreviewHandler\monacoSRC"
PreprocessorVariable="var.MonacoSRCHarvestPath"
OutputFile="MonacoSRC.wxs"
ComponentGroupName="MonacoSRCHeatGenerated"
DirectoryRefId="MonacoPreviewHandlerMonacoSRCFolder"
AutogenerateGuids="true"
ToolPath="$(WixToolPath)"
SuppressFragments="true"
SuppressRegistry="true"
SuppressRootDirectory="true" />
<HeatDirectory Directory="..\..\src\modules\previewpane\MonacoPreviewHandler\monacoSRC"
PreprocessorVariable="var.MonacoSRCHarvestPath"
OutputFile="MonacoSRC.wxs"
ComponentGroupName="MonacoSRCHeatGenerated"
DirectoryRefId="MonacoPreviewHandlerMonacoSRCFolder"
AutogenerateGuids="true"
ToolPath="$(WixToolPath)"
RunAsSeparateProcess="true"
SuppressFragments="true"
SuppressRegistry="true"
SuppressRootDirectory="true" />
</Target>
</Project>

File diff suppressed because it is too large Load Diff

View File

@@ -22,13 +22,13 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<Import Project="..\..\deps\spdlog.props" />

View File

@@ -11,6 +11,12 @@
<ProjectName>PowerToys.ActionRunner</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<Import Project="..\..\deps\expected.props" />
<PropertyGroup>
<ConfigurationType>Application</ConfigurationType>

View File

@@ -3,6 +3,6 @@
## Code organization
The PowerToys are split into DLLs for each PowerToy module ([`modules`](/src/modules) folder), and an executable ([`runner`](/src/runner) folder) that loads and manages those DLLs.
The settings window is a separate executable, contained in [`settings`](/src/settings) folder. It utilizes a WebView to display an HTML-based settings window (contained in [`settings-web`](/src/settings-web) folder).
The settings window is a separate executable, contained in [`settings-ui`](/src/settings-ui) folder. It utilizes a WebView to display an HTML-based settings window.
The [`common`](/src/common) contains code for a static library with helper functions, used by both the runner and the PowerToys modules.

View File

@@ -11,6 +11,12 @@
<ProjectName>PowerToys.Update</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<Import Project="..\..\deps\expected.props" />
<PropertyGroup>
<ConfigurationType>Application</ConfigurationType>

View File

@@ -31,6 +31,8 @@ using System.Diagnostics.CodeAnalysis;
[assembly: SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Justification = "We need to have the names of these keys in lowercase to be able to compare with the keys becoming form the template json. ContainsKey does not allow StringComparer specification to IgnoreCase", Scope = "member", Target = "Microsoft.Templates.Core.ITemplateInfoExtensions.#GetQueryableProperties(Microsoft.TemplateEngine.Abstractions.ITemplateInfo)")]
[assembly: SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Justification = "We need to have the names of these keys in lowercase to be able to compare with the keys becoming form the template json. ContainsKey does not allow StringComparer specification to IgnoreCase", Scope = "member", Target = "Microsoft.Templates.Core.Composition.CompositionQuery.#Match(System.Collections.Generic.IEnumerable`1<Microsoft.Templates.Core.Composition.QueryNode>,Microsoft.Templates.Core.Composition.QueryablePropertyDictionary)")]
[assembly: SuppressMessage("Usage", "VSTHRD103:Call async methods when in an async method", Justification = "Resource DictionaryWriter does not implement flush async", Scope = "member", Target = "~M:Microsoft.Templates.Core.PostActions.Catalog.Merge.MergeResourceDictionaryPostAction.ExecuteInternalAsync~System.Threading.Tasks.Task")]
[assembly: SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification = "Used in a lot of places for meaningful method names")]
[assembly: SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Static methods may improve performance but decrease maintainability")]
// Threading suppressions
[assembly: SuppressMessage("Microsoft.VisualStudio.Threading.Analyzers", "VSTHRD100:Avoid async void methods", Justification = "Event handlers needs async void", Scope = "member", Target = "~M:Microsoft.Templates.UI.Controls.Notification.OnClose")]

View File

@@ -11,6 +11,12 @@
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>

View File

@@ -2,7 +2,7 @@
<Import Project="..\..\Version.props" />
<PropertyGroup>
<TargetFramework>net5.0-windows</TargetFramework>
<TargetFramework>net6.0-windows</TargetFramework>
<UseWPF>true</UseWPF>
<Platforms>x64</Platforms>
<PlatformTarget>x64</PlatformTarget>
@@ -10,11 +10,11 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ControlzEx" Version="4.4.0" />
<PackageReference Include="ControlzEx" Version="5.0.1" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.3.0">
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View File

@@ -11,6 +11,12 @@
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
@@ -25,7 +31,7 @@
<PropertyGroup Label="UserMacros" />
<ItemDefinitionGroup>
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<AdditionalIncludeDirectories>..\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeader>NotUsing</PrecompiledHeader>

View File

@@ -10,7 +10,7 @@
<Authors>Microsoft Corporation</Authors>
<Product>PowerToys</Product>
<Description>PowerToys ManagedCommon</Description>
<Copyright>Copyright (C) 2020 Microsoft Corporation</Copyright>
<Copyright>Copyright (C) 2022 Microsoft Corporation</Copyright>
<RepositoryUrl>https://github.com/microsoft/PowerToys</RepositoryUrl>
<RepositoryType>Github</RepositoryType>
<PackageTags>PowerToys</PackageTags>
@@ -27,7 +27,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.3.0">
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View File

@@ -9,7 +9,7 @@
<Authors>Microsoft Corporation</Authors>
<Product>PowerToys</Product>
<Description>PowerToys Telemetry</Description>
<Copyright>Copyright (C) 2020 Microsoft Corporation</Copyright>
<Copyright>Copyright (C) 2022 Microsoft Corporation</Copyright>
<RepositoryUrl>https://github.com/microsoft/PowerToys</RepositoryUrl>
<RepositoryType>Github</RepositoryType>
<PackageTags>PowerToys</PackageTags>
@@ -27,6 +27,10 @@
</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>

View File

@@ -12,6 +12,12 @@
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
@@ -40,7 +46,7 @@
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" />

View File

@@ -5,6 +5,9 @@ namespace PTSettingsHelper
{
constexpr inline const wchar_t* settings_filename = L"\\settings.json";
constexpr inline const wchar_t* oobe_filename = L"oobe_settings.json";
constexpr inline const wchar_t* last_version_run_filename = L"last_version_run.json";
constexpr inline const wchar_t* opened_at_first_launch_json_field_name = L"openedAtFirstLaunch";
constexpr inline const wchar_t* last_version_json_field_name = L"last_version";
std::wstring get_root_save_folder_location()
{
@@ -90,7 +93,7 @@ namespace PTSettingsHelper
return false;
}
bool opened = saved_settings->GetNamedBoolean(L"openedAtFirstLaunch", false);
bool opened = saved_settings->GetNamedBoolean(opened_at_first_launch_json_field_name, false);
return opened;
}
@@ -103,8 +106,39 @@ namespace PTSettingsHelper
oobePath = oobePath.append(oobe_filename);
json::JsonObject obj;
obj.SetNamedValue(L"openedAtFirstLaunch", json::value(true));
obj.SetNamedValue(opened_at_first_launch_json_field_name, json::value(true));
json::to_file(oobePath.c_str(), obj);
}
std::wstring get_last_version_run()
{
std::filesystem::path lastVersionRunPath(PTSettingsHelper::get_root_save_folder_location());
lastVersionRunPath = lastVersionRunPath.append(last_version_run_filename);
if (std::filesystem::exists(lastVersionRunPath))
{
auto saved_settings = json::from_file(lastVersionRunPath.c_str());
if (!saved_settings.has_value())
{
return L"";
}
std::wstring last_version = saved_settings->GetNamedString(last_version_json_field_name, L"").c_str();
return last_version;
}
return L"";
}
void save_last_version_run(const std::wstring& version)
{
std::filesystem::path lastVersionRunPath(PTSettingsHelper::get_root_save_folder_location());
lastVersionRunPath = lastVersionRunPath.append(last_version_run_filename);
json::JsonObject obj;
obj.SetNamedValue(last_version_json_field_name, json::value(version));
json::to_file(lastVersionRunPath.c_str(), obj);
}
}

View File

@@ -21,4 +21,6 @@ namespace PTSettingsHelper
bool get_oobe_opened_state();
void save_oobe_opened_state();
std::wstring get_last_version_run();
void save_last_version_run(const std::wstring& version);
}

View File

@@ -12,6 +12,12 @@
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>

View File

@@ -13,6 +13,12 @@
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>

View File

@@ -4,7 +4,7 @@
<PropertyGroup>
<AssemblyTitle>PowerToys.Interop</AssemblyTitle>
<AssemblyCompany>Microsoft Corp.</AssemblyCompany>
<AssemblyCopyright>Copyright (C) 2019 Microsoft Corp.</AssemblyCopyright>
<AssemblyCopyright>Copyright (C) 2022 Microsoft Corp.</AssemblyCopyright>
</PropertyGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
@@ -19,6 +19,12 @@
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CLRSupport>true</CLRSupport>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>

View File

@@ -2,7 +2,7 @@
<Import Project="..\..\..\Version.props" />
<PropertyGroup>
<TargetFramework>net5.0-windows</TargetFramework>
<TargetFramework>net6.0-windows</TargetFramework>
<IsPackable>false</IsPackable>
<RuntimeIdentifiers>win-x64</RuntimeIdentifiers>
@@ -12,7 +12,7 @@
<Platforms>x64</Platforms>
<AssemblyTitle>interop-tests</AssemblyTitle>
<Company>Microsoft Corp.</Company>
<Copyright>Copyright (C) 2020 Microsoft Corp.</Copyright>
<Copyright>Copyright (C) 2022 Microsoft Corp.</Copyright>
</PropertyGroup>
<PropertyGroup>
@@ -52,21 +52,20 @@
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.5" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.5" />
<PackageReference Include="coverlet.collector" Version="3.0.3">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.3" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.3" />
<PackageReference Include="coverlet.collector" Version="3.1.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers">
<Version>3.3.0</Version>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<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>

View File

@@ -11,6 +11,12 @@
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<Import Project="..\..\..\deps\spdlog.props" />
<ImportGroup Label="ExtensionSettings">

View File

@@ -18,7 +18,7 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>

View File

@@ -11,6 +11,12 @@
<PropertyGroup Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>

View File

@@ -12,6 +12,12 @@
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>

View File

@@ -13,6 +13,12 @@
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>

View File

@@ -189,6 +189,7 @@ inline bool drop_elevated_privileges()
// Run command as elevated user, returns true if succeeded
inline HANDLE run_elevated(const std::wstring& file, const std::wstring& params)
{
Logger::info(L"run_elevated with params={}", params);
SHELLEXECUTEINFOW exec_info = { 0 };
exec_info.cbSize = sizeof(SHELLEXECUTEINFOW);
exec_info.lpVerb = L"runas";
@@ -206,6 +207,7 @@ inline HANDLE run_elevated(const std::wstring& file, const std::wstring& params)
// Run command as non-elevated user, returns true if succeeded, puts the process id into returnPid if returnPid != NULL
inline bool run_non_elevated(const std::wstring& file, const std::wstring& params, DWORD* returnPid)
{
Logger::info(L"run_non_elevated with params={}", params);
auto executable_args = L"\"" + file + L"\"";
if (!params.empty())
{

View File

@@ -0,0 +1,32 @@
#pragma once
#include <vector>
#include <string>
// Checks if a process path is included in a list of strings.
inline bool find_app_name_in_path(const std::wstring& where, const std::vector<std::wstring>& what)
{
for (const auto& row : what)
{
const auto pos = where.rfind(row);
const auto last_slash = where.rfind('\\');
//Check that row occurs in where, and its last occurrence contains in itself the first character after the last backslash.
if (pos != std::wstring::npos && pos <= last_slash + 1 && pos + row.length() > last_slash)
{
return true;
}
}
return false;
}
inline bool find_folder_in_path(const std::wstring& where, const std::vector<std::wstring>& what)
{
for (const auto& row : what)
{
const auto pos = where.rfind(row);
if (pos != std::wstring::npos)
{
return true;
}
}
return false;
}

View File

@@ -10,7 +10,7 @@ namespace fs = std::filesystem;
namespace NonLocalizable
{
const static wchar_t* MONACO_LANGUAGES_FILE_NAME = L"modules\\FileExplorerPreview\\languages.json";
const static wchar_t* MONACO_LANGUAGES_FILE_NAME = L"modules\\FileExplorerPreview\\monaco_languages.json";
const static wchar_t* ListID = L"list";
const static wchar_t* ExtensionsID = L"extensions";
const static wchar_t* MDExtension = L".md";

View File

@@ -13,7 +13,7 @@
#define PRODUCT_VERSION_STRING FILE_VERSION_STRING
#define COMPANY_NAME "Microsoft Corporation"
#define COPYRIGHT_NOTE "Copyright (C) 2020 Microsoft Corporation"
#define COPYRIGHT_NOTE "Copyright (C) 2022 Microsoft Corporation"
#define PRODUCT_NAME "PowerToys"
#include <string>

View File

@@ -21,6 +21,12 @@
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>

View File

@@ -14,6 +14,12 @@
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>

View File

@@ -4,6 +4,9 @@
#include "FindMyMouse.h"
#include "trace.h"
#include "common/utils/game_mode.h"
#include "common/utils/process_path.h"
#include "common/utils/excluded_apps.h"
#include <vector>
#ifdef COMPOSITION
namespace winrt
@@ -43,6 +46,8 @@ protected:
void BeforeMoveSonar() {}
void AfterMoveSonar() {}
void SetSonarVisibility(bool visible) = delete;
void UpdateMouseSnooping();
bool IsForegroundAppExcluded();
protected:
// Base class members you can access.
@@ -57,22 +62,49 @@ protected:
static const int MIN_DOUBLE_CLICK_TIME = 100;
bool m_destroyed = false;
bool m_doNotActivateOnGameMode = true;
FindMyMouseActivationMethod m_activationMethod = FIND_MY_MOUSE_DEFAULT_ACTIVATION_METHOD;
bool m_doNotActivateOnGameMode = FIND_MY_MOUSE_DEFAULT_DO_NOT_ACTIVATE_ON_GAME_MODE;
int m_sonarRadius = FIND_MY_MOUSE_DEFAULT_SPOTLIGHT_RADIUS;
int m_sonarZoomFactor = FIND_MY_MOUSE_DEFAULT_SPOTLIGHT_INITIAL_ZOOM;
DWORD m_fadeDuration = FIND_MY_MOUSE_DEFAULT_ANIMATION_DURATION_MS;
int m_finalAlphaNumerator = FIND_MY_MOUSE_DEFAULT_OVERLAY_OPACITY;
std::vector<std::wstring> m_excludedApps;
int m_shakeMinimumDistance = FIND_MY_MOUSE_DEFAULT_SHAKE_MINIMUM_DISTANCE;
static constexpr int FinalAlphaDenominator = 100;
winrt::DispatcherQueueController m_dispatcherQueueController{ nullptr };
private:
// Save the mouse movement that occurred in any direction.
struct PointerRecentMovement
{
POINT diff;
ULONGLONG tick;
};
std::vector<PointerRecentMovement> m_movementHistory;
// Raw Input may give relative or absolute values. Need to take each case into account.
bool m_seenAnAbsoluteMousePosition = false;
POINT m_lastAbsolutePosition = { 0, 0 };
// Don't consider movements started past these milliseconds to detect shaking.
static constexpr LONG ShakeIntervalMs = 1000;
// By which factor must travelled distance be than the diagonal of the rectangle containing the movements.
static constexpr float ShakeFactor = 4.0f;
static inline byte GetSign(LONG const& num)
{
if (num > 0)
return 1;
if (num < 0)
return -1;
return 0;
}
static bool IsEqual(POINT const& p1, POINT const& p2)
{
return p1.x == p2.x && p1.y == p2.y;
}
static constexpr POINT ptNowhere = { -1, -1 };
static constexpr DWORD TIMER_ID_TRACK = 100;
static constexpr DWORD IdlePeriod = 1000;
@@ -89,11 +121,11 @@ private:
HWND m_hwndOwner;
SonarState m_sonarState = SonarState::Idle;
POINT m_lastKeyPos{};
DWORD m_lastKeyTime{};
ULONGLONG m_lastKeyTime{};
static constexpr DWORD NoSonar = 0;
static constexpr DWORD SonarWaitingForMouseMove = 1;
DWORD m_sonarStart = NoSonar;
ULONGLONG m_sonarStart = NoSonar;
bool m_isSnoopingMouse = false;
private:
@@ -110,10 +142,10 @@ private:
void OnSonarMouseInput(RAWINPUT const& input);
void OnMouseTimer();
void DetectShake();
void StartSonar();
void StopSonar();
void UpdateMouseSnooping();
};
template<typename D>
@@ -189,7 +221,9 @@ LRESULT SuperSonar<D>::BaseWndProc(UINT message, WPARAM wParam, LPARAM lParam) n
switch (message)
{
case WM_CREATE:
return OnSonarCreate() ? 0 : -1;
if(!OnSonarCreate()) return -1;
UpdateMouseSnooping();
return 0;
case WM_DESTROY:
OnSonarDestroy();
@@ -257,13 +291,7 @@ void SuperSonar<D>::OnSonarInput(WPARAM flags, HRAWINPUT hInput)
template<typename D>
void SuperSonar<D>::OnSonarKeyboardInput(RAWINPUT const& input)
{
// Don't activate if game mode is on.
if (m_doNotActivateOnGameMode && detect_game_mode())
{
return;
}
if (input.data.keyboard.VKey != VK_CONTROL)
if ( m_activationMethod != FindMyMouseActivationMethod::DoubleControlKey || input.data.keyboard.VKey != VK_CONTROL)
{
StopSonar();
return;
@@ -293,7 +321,7 @@ void SuperSonar<D>::OnSonarKeyboardInput(RAWINPUT const& input)
if (pressed)
{
m_sonarState = SonarState::ControlDown1;
m_lastKeyTime = GetTickCount();
m_lastKeyTime = GetTickCount64();
m_lastKeyPos = {};
GetCursorPos(&m_lastKeyPos);
UpdateMouseSnooping();
@@ -310,7 +338,7 @@ void SuperSonar<D>::OnSonarKeyboardInput(RAWINPUT const& input)
case SonarState::ControlUp1:
if (pressed)
{
auto now = GetTickCount();
auto now = GetTickCount64();
auto doubleClickInterval = now - m_lastKeyTime;
POINT ptCursor{};
auto doubleClickTimeSetting = GetDoubleClickTime();
@@ -325,7 +353,7 @@ void SuperSonar<D>::OnSonarKeyboardInput(RAWINPUT const& input)
else
{
m_sonarState = SonarState::ControlDown1;
m_lastKeyTime = GetTickCount();
m_lastKeyTime = GetTickCount64();
m_lastKeyPos = {};
GetCursorPos(&m_lastKeyPos);
UpdateMouseSnooping();
@@ -351,9 +379,97 @@ void SuperSonar<D>::OnSonarKeyboardInput(RAWINPUT const& input)
}
}
// Shaking detection algorithm is: Has distance travelled been much greater than the diagonal of the rectangle containing the movement?
template<typename D>
void SuperSonar<D>::DetectShake()
{
ULONGLONG shakeStartTick = GetTickCount64() - ShakeIntervalMs;
// Prune the story of movements for those movements that started too long ago.
std::erase_if(m_movementHistory, [shakeStartTick](const PointerRecentMovement& movement) { return movement.tick < shakeStartTick; });
double distanceTravelled = 0;
LONGLONG currentX=0, minX=0, maxX=0;
LONGLONG currentY=0, minY=0, maxY=0;
for (const PointerRecentMovement& movement : m_movementHistory)
{
currentX += movement.diff.x;
currentY += movement.diff.y;
distanceTravelled += sqrt((double)movement.diff.x * movement.diff.x + (double)movement.diff.y * movement.diff.y); // Pythagorean theorem
minX = min(currentX, minX);
maxX = max(currentX, maxX);
minY = min(currentY, minY);
maxY = max(currentY, maxY);
}
if (distanceTravelled < m_shakeMinimumDistance)
{
return;
}
// Size of the rectangle the pointer moved in.
double rectangleWidth = (double)maxX - minX;
double rectangleHeight = (double)maxY - minY;
double diagonal = sqrt(rectangleWidth * rectangleWidth + rectangleHeight * rectangleHeight);
if (diagonal > 0 && distanceTravelled / diagonal > ShakeFactor)
{
m_movementHistory.clear();
StartSonar();
}
}
template<typename D>
void SuperSonar<D>::OnSonarMouseInput(RAWINPUT const& input)
{
if (m_activationMethod == FindMyMouseActivationMethod::ShakeMouse)
{
LONG relativeX = 0;
LONG relativeY = 0;
if ((input.data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE) == MOUSE_MOVE_ABSOLUTE && (input.data.mouse.lLastX!=0 || input.data.mouse.lLastY!=0))
{
// Getting absolute mouse coordinates. Likely inside a VM / RDP session.
if (m_seenAnAbsoluteMousePosition)
{
relativeX = input.data.mouse.lLastX - m_lastAbsolutePosition.x;
relativeY = input.data.mouse.lLastY - m_lastAbsolutePosition.y;
m_lastAbsolutePosition.x = input.data.mouse.lLastX;
m_lastAbsolutePosition.y = input.data.mouse.lLastY;
}
m_seenAnAbsoluteMousePosition = true;
}
else
{
relativeX = input.data.mouse.lLastX;
relativeY = input.data.mouse.lLastY;
}
if (m_movementHistory.size() > 0)
{
PointerRecentMovement& lastMovement = m_movementHistory.back();
// If the pointer is still moving in the same direction, just add to that movement instead of adding a new movement.
// This helps in keeping the list of movements smaller even in cases where a high number of messages is sent.
if (GetSign(lastMovement.diff.x) == GetSign(relativeX) && GetSign(lastMovement.diff.y) == GetSign(relativeY))
{
lastMovement.diff.x += relativeX;
lastMovement.diff.y += relativeY;
}
else
{
m_movementHistory.push_back({ .diff = { .x=relativeX, .y=relativeY }, .tick = GetTickCount64() });
// Mouse movement changed directions. Take the opportunity do detect shake.
DetectShake();
}
}
else
{
m_movementHistory.push_back({ .diff = { .x = relativeX, .y = relativeY }, .tick = GetTickCount64() });
}
}
if (input.data.mouse.usButtonFlags)
{
StopSonar();
@@ -367,6 +483,17 @@ void SuperSonar<D>::OnSonarMouseInput(RAWINPUT const& input)
template<typename D>
void SuperSonar<D>::StartSonar()
{
// Don't activate if game mode is on.
if (m_doNotActivateOnGameMode && detect_game_mode())
{
return;
}
if (IsForegroundAppExcluded())
{
return;
}
Logger::info("Focusing the sonar on the mouse cursor.");
Trace::MousePointerFocused();
// Cover the entire virtual screen.
@@ -393,7 +520,7 @@ void SuperSonar<D>::StopSonar()
template<typename D>
void SuperSonar<D>::OnMouseTimer()
{
auto now = GetTickCount();
auto now = GetTickCount64();
// If mouse has moved, then reset the sonar timer.
POINT ptCursor{};
@@ -433,7 +560,7 @@ void SuperSonar<D>::OnMouseTimer()
template<typename D>
void SuperSonar<D>::UpdateMouseSnooping()
{
bool wantSnoopingMouse = m_sonarStart != NoSonar || m_sonarState != SonarState::Idle;
bool wantSnoopingMouse = m_sonarStart != NoSonar || m_sonarState != SonarState::Idle || m_activationMethod == FindMyMouseActivationMethod::ShakeMouse;
if (m_isSnoopingMouse != wantSnoopingMouse)
{
m_isSnoopingMouse = wantSnoopingMouse;
@@ -454,6 +581,25 @@ void SuperSonar<D>::UpdateMouseSnooping()
}
}
template<typename D>
bool SuperSonar<D>::IsForegroundAppExcluded()
{
if (m_excludedApps.size() < 1)
{
return false;
}
if (HWND foregroundApp{ GetForegroundWindow() })
{
auto processPath = get_process_path(foregroundApp);
CharUpperBuffW(processPath.data(), (DWORD)processPath.length());
return find_app_name_in_path(processPath, m_excludedApps);
}
else
{
return false;
}
}
struct CompositionSpotlight : SuperSonar<CompositionSpotlight>
{
static constexpr UINT WM_OPACITY_ANIMATION_COMPLETED = WM_APP;
@@ -590,14 +736,23 @@ public:
m_sonarRadiusFloat = static_cast<float>(m_sonarRadius);
m_backgroundColor = settings.backgroundColor;
m_spotlightColor = settings.spotlightColor;
m_activationMethod = settings.activationMethod;
m_doNotActivateOnGameMode = settings.doNotActivateOnGameMode;
m_fadeDuration = settings.animationDurationMs > 0 ? settings.animationDurationMs : 1;
m_finalAlphaNumerator = settings.overlayOpacity;
m_sonarZoomFactor = settings.spotlightInitialZoom;
m_excludedApps = settings.excludedApps;
m_shakeMinimumDistance = settings.shakeMinimumDistance;
}
else
{
// Runtime objects already created. Should update in the owner thread.
if (m_dispatcherQueueController == nullptr)
{
Logger::warn("Tried accessing the dispatch queue controller before it was initialized.");
// No dispatcher Queue Controller? Means initialization still hasn't run, so settings will be applied then.
return;
}
auto dispatcherQueue = m_dispatcherQueueController.DispatcherQueue();
FindMyMouseSettings localSettings = settings;
bool enqueueSucceeded = dispatcherQueue.TryEnqueue([=]() {
@@ -608,11 +763,15 @@ public:
m_sonarRadiusFloat = static_cast<float>(m_sonarRadius);
m_backgroundColor = localSettings.backgroundColor;
m_spotlightColor = localSettings.spotlightColor;
m_activationMethod = localSettings.activationMethod;
m_doNotActivateOnGameMode = localSettings.doNotActivateOnGameMode;
m_fadeDuration = localSettings.animationDurationMs > 0 ? localSettings.animationDurationMs : 1;
m_finalAlphaNumerator = localSettings.overlayOpacity;
m_sonarZoomFactor = localSettings.spotlightInitialZoom;
m_excludedApps = localSettings.excludedApps;
m_shakeMinimumDistance = localSettings.shakeMinimumDistance;
UpdateMouseSnooping(); // For the shake mouse activation method
// Apply new settings to runtime composition objects.
m_backdrop.Brush().as<winrt::CompositionColorBrush>().Color(m_backgroundColor);
m_circleShape.FillBrush().as<winrt::CompositionColorBrush>().Color(m_spotlightColor);

View File

@@ -1,6 +1,13 @@
#pragma once
#include "pch.h"
enum struct FindMyMouseActivationMethod : int
{
DoubleControlKey = 0,
ShakeMouse = 1,
EnumElements = 2, // number of elements in the enum, not counting this
};
constexpr bool FIND_MY_MOUSE_DEFAULT_DO_NOT_ACTIVATE_ON_GAME_MODE = true;
const winrt::Windows::UI::Color FIND_MY_MOUSE_DEFAULT_BACKGROUND_COLOR = winrt::Windows::UI::ColorHelper::FromArgb(255, 0, 0, 0);
const winrt::Windows::UI::Color FIND_MY_MOUSE_DEFAULT_SPOTLIGHT_COLOR = winrt::Windows::UI::ColorHelper::FromArgb(255, 255, 255, 255);
@@ -8,9 +15,12 @@ constexpr int FIND_MY_MOUSE_DEFAULT_OVERLAY_OPACITY = 50;
constexpr int FIND_MY_MOUSE_DEFAULT_SPOTLIGHT_RADIUS = 100;
constexpr int FIND_MY_MOUSE_DEFAULT_ANIMATION_DURATION_MS = 500;
constexpr int FIND_MY_MOUSE_DEFAULT_SPOTLIGHT_INITIAL_ZOOM = 9;
constexpr FindMyMouseActivationMethod FIND_MY_MOUSE_DEFAULT_ACTIVATION_METHOD = FindMyMouseActivationMethod::DoubleControlKey;
constexpr int FIND_MY_MOUSE_DEFAULT_SHAKE_MINIMUM_DISTANCE = 1000;
struct FindMyMouseSettings
{
FindMyMouseActivationMethod activationMethod = FIND_MY_MOUSE_DEFAULT_ACTIVATION_METHOD;
bool doNotActivateOnGameMode = FIND_MY_MOUSE_DEFAULT_DO_NOT_ACTIVATE_ON_GAME_MODE;
winrt::Windows::UI::Color backgroundColor = FIND_MY_MOUSE_DEFAULT_BACKGROUND_COLOR;
winrt::Windows::UI::Color spotlightColor = FIND_MY_MOUSE_DEFAULT_SPOTLIGHT_COLOR;
@@ -18,6 +28,8 @@ struct FindMyMouseSettings
int spotlightRadius = FIND_MY_MOUSE_DEFAULT_SPOTLIGHT_RADIUS;
int animationDurationMs = FIND_MY_MOUSE_DEFAULT_ANIMATION_DURATION_MS;
int spotlightInitialZoom = FIND_MY_MOUSE_DEFAULT_SPOTLIGHT_INITIAL_ZOOM;
int shakeMinimumDistance = FIND_MY_MOUSE_DEFAULT_SHAKE_MINIMUM_DISTANCE;
std::vector<std::wstring> excludedApps;
};
int FindMyMouseMain(HINSTANCE hinst, const FindMyMouseSettings& settings);

View File

@@ -24,13 +24,13 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>

View File

@@ -6,11 +6,13 @@
#include <thread>
#include <common/utils/logger_helper.h>
#include <common/utils/color.h>
#include <common/utils/string_utils.h>
namespace
{
const wchar_t JSON_KEY_PROPERTIES[] = L"properties";
const wchar_t JSON_KEY_VALUE[] = L"value";
const wchar_t JSON_KEY_ACTIVATION_METHOD[] = L"activation_method";
const wchar_t JSON_KEY_DO_NOT_ACTIVATE_ON_GAME_MODE[] = L"do_not_activate_on_game_mode";
const wchar_t JSON_KEY_BACKGROUND_COLOR[] = L"background_color";
const wchar_t JSON_KEY_SPOTLIGHT_COLOR[] = L"spotlight_color";
@@ -18,6 +20,8 @@ namespace
const wchar_t JSON_KEY_SPOTLIGHT_RADIUS[] = L"spotlight_radius";
const wchar_t JSON_KEY_ANIMATION_DURATION_MS[] = L"animation_duration_ms";
const wchar_t JSON_KEY_SPOTLIGHT_INITIAL_ZOOM[] = L"spotlight_initial_zoom";
const wchar_t JSON_KEY_EXCLUDED_APPS[] = L"excluded_apps";
const wchar_t JSON_KEY_SHAKING_MINIMUM_DISTANCE[] = L"shaking_minimum_distance";
}
extern "C" IMAGE_DOS_HEADER __ImageBase;
@@ -171,6 +175,20 @@ void FindMyMouse::parse_settings(PowerToysSettings::PowerToyValues& settings)
FindMyMouseSettings findMyMouseSettings;
if (settingsObject.GetView().Size())
{
try
{
// Parse Activation Method
auto jsonPropertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_ACTIVATION_METHOD);
UINT value = (UINT)jsonPropertiesObject.GetNamedNumber(JSON_KEY_VALUE);
if (value < (int)FindMyMouseActivationMethod::EnumElements)
{
findMyMouseSettings.activationMethod = (FindMyMouseActivationMethod)value;
}
}
catch (...)
{
Logger::warn("Failed to initialize Activation Method from settings. Will use default value");
}
try
{
auto jsonPropertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_DO_NOT_ACTIVATE_ON_GAME_MODE);
@@ -258,6 +276,41 @@ void FindMyMouse::parse_settings(PowerToysSettings::PowerToyValues& settings)
{
Logger::warn("Failed to initialize Spotlight Initial Zoom from settings. Will use default value");
}
try
{
// Parse Excluded Apps
auto jsonPropertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_EXCLUDED_APPS);
std::wstring apps = jsonPropertiesObject.GetNamedString(JSON_KEY_VALUE).c_str();
std::vector<std::wstring> excludedApps;
auto excludedUppercase = apps;
CharUpperBuffW(excludedUppercase.data(), (DWORD)excludedUppercase.length());
std::wstring_view view(excludedUppercase);
view = left_trim<wchar_t>(trim<wchar_t>(view));
while (!view.empty())
{
auto pos = (std::min)(view.find_first_of(L"\r\n"), view.length());
excludedApps.emplace_back(view.substr(0, pos));
view.remove_prefix(pos);
view = left_trim<wchar_t>(trim<wchar_t>(view));
}
findMyMouseSettings.excludedApps = excludedApps;
}
catch (...)
{
Logger::warn("Failed to initialize Excluded Apps from settings. Will use default value");
}
try
{
// Parse Shaking Minimum Distance
auto jsonPropertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_SHAKING_MINIMUM_DISTANCE);
findMyMouseSettings.shakeMinimumDistance = (UINT)jsonPropertiesObject.GetNamedNumber(JSON_KEY_VALUE);
}
catch (...)
{
Logger::warn("Failed to initialize Shaking Minimum Distance from settings. Will use default value");
}
}
else
{

View File

@@ -23,13 +23,13 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>

View File

@@ -71,9 +71,9 @@ private:
// Configurable Settings
winrt::Windows::UI::Color m_crosshairs_border_color = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_BORDER_COLOR;
winrt::Windows::UI::Color m_crosshairs_color = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_COLOR;
float m_crosshairs_radius = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_RADIUS;
float m_crosshairs_thickness = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_THICKNESS;
float m_crosshairs_border_size = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_BORDER_SIZE;
int m_crosshairs_radius = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_RADIUS;
int m_crosshairs_thickness = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_THICKNESS;
int m_crosshairs_border_size = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_BORDER_SIZE;
float m_crosshairs_opacity = max(0.f, min(1.f, (float)INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_OPACITY / 100.0f));
};
@@ -205,26 +205,29 @@ void InclusiveCrosshairs::UpdateCrosshairsPosition()
ScreenToClient(m_hwnd, &ptMonitorUpperLeft);
ScreenToClient(m_hwnd, &ptMonitorBottomRight);
// Crosshair position should receive a minor adjustment for odd values to prevent anti-aliasing due to half pixels, while still looking like it's centered around the mouse pointer.
float halfPixelAdjustment = m_crosshairs_thickness % 2 == 1 ? 0.5f : 0.0f;
// Position crosshairs components around the mouse pointer.
m_left_crosshairs_border.Offset({ (float)ptCursor.x - m_crosshairs_radius + m_crosshairs_border_size, (float)ptCursor.y, .0f });
m_left_crosshairs_border.Size({ (float)ptCursor.x - (float)ptMonitorUpperLeft.x - m_crosshairs_radius + m_crosshairs_border_size, m_crosshairs_thickness + m_crosshairs_border_size * 2 });
m_left_crosshairs.Offset({ (float)ptCursor.x - m_crosshairs_radius, (float)ptCursor.y, .0f });
m_left_crosshairs.Size({ (float)ptCursor.x - (float)ptMonitorUpperLeft.x - m_crosshairs_radius, m_crosshairs_thickness });
m_left_crosshairs_border.Offset({ (float)ptCursor.x - m_crosshairs_radius + m_crosshairs_border_size, (float)ptCursor.y - halfPixelAdjustment, .0f });
m_left_crosshairs_border.Size({ (float)ptCursor.x - (float)ptMonitorUpperLeft.x - m_crosshairs_radius + m_crosshairs_border_size, (float)m_crosshairs_thickness + m_crosshairs_border_size * 2 });
m_left_crosshairs.Offset({ (float)ptCursor.x - m_crosshairs_radius, (float)ptCursor.y - halfPixelAdjustment, .0f });
m_left_crosshairs.Size({ (float)ptCursor.x - (float)ptMonitorUpperLeft.x - m_crosshairs_radius, (float)m_crosshairs_thickness });
m_right_crosshairs_border.Offset({ (float)ptCursor.x + m_crosshairs_radius - m_crosshairs_border_size, (float)ptCursor.y, .0f });
m_right_crosshairs_border.Size({ (float)ptMonitorBottomRight.x - (float)ptCursor.x - m_crosshairs_radius + m_crosshairs_border_size, m_crosshairs_thickness + m_crosshairs_border_size * 2 });
m_right_crosshairs.Offset({ (float)ptCursor.x + m_crosshairs_radius, (float)ptCursor.y, .0f });
m_right_crosshairs.Size({ (float)ptMonitorBottomRight.x - (float)ptCursor.x - m_crosshairs_radius, m_crosshairs_thickness });
m_right_crosshairs_border.Offset({ (float)ptCursor.x + m_crosshairs_radius - m_crosshairs_border_size, (float)ptCursor.y - halfPixelAdjustment, .0f });
m_right_crosshairs_border.Size({ (float)ptMonitorBottomRight.x - (float)ptCursor.x - m_crosshairs_radius + m_crosshairs_border_size, (float)m_crosshairs_thickness + m_crosshairs_border_size * 2 });
m_right_crosshairs.Offset({ (float)ptCursor.x + m_crosshairs_radius, (float)ptCursor.y - halfPixelAdjustment, .0f });
m_right_crosshairs.Size({ (float)ptMonitorBottomRight.x - (float)ptCursor.x - m_crosshairs_radius, (float)m_crosshairs_thickness });
m_top_crosshairs_border.Offset({ (float)ptCursor.x, (float)ptCursor.y - m_crosshairs_radius + m_crosshairs_border_size, .0f });
m_top_crosshairs_border.Size({ m_crosshairs_thickness + m_crosshairs_border_size * 2, (float)ptCursor.y - (float)ptMonitorUpperLeft.y - m_crosshairs_radius + m_crosshairs_border_size });
m_top_crosshairs.Offset({ (float)ptCursor.x, (float)ptCursor.y - m_crosshairs_radius, .0f });
m_top_crosshairs.Size({ m_crosshairs_thickness, (float)ptCursor.y - (float)ptMonitorUpperLeft.y - m_crosshairs_radius });
m_top_crosshairs_border.Offset({ (float)ptCursor.x - halfPixelAdjustment, (float)ptCursor.y - m_crosshairs_radius + m_crosshairs_border_size, .0f });
m_top_crosshairs_border.Size({ (float)m_crosshairs_thickness + m_crosshairs_border_size * 2, (float)ptCursor.y - (float)ptMonitorUpperLeft.y - m_crosshairs_radius + m_crosshairs_border_size });
m_top_crosshairs.Offset({ (float)ptCursor.x - halfPixelAdjustment, (float)ptCursor.y - m_crosshairs_radius, .0f });
m_top_crosshairs.Size({ (float)m_crosshairs_thickness, (float)ptCursor.y - (float)ptMonitorUpperLeft.y - m_crosshairs_radius });
m_bottom_crosshairs_border.Offset({ (float)ptCursor.x, (float)ptCursor.y + m_crosshairs_radius - m_crosshairs_border_size, .0f });
m_bottom_crosshairs_border.Size({ m_crosshairs_thickness + m_crosshairs_border_size * 2, (float)ptMonitorBottomRight.y - (float)ptCursor.y - m_crosshairs_radius + m_crosshairs_border_size });
m_bottom_crosshairs.Offset({ (float)ptCursor.x, (float)ptCursor.y + m_crosshairs_radius, .0f });
m_bottom_crosshairs.Size({ m_crosshairs_thickness, (float)ptMonitorBottomRight.y - (float)ptCursor.y - m_crosshairs_radius });
m_bottom_crosshairs_border.Offset({ (float)ptCursor.x - halfPixelAdjustment, (float)ptCursor.y + m_crosshairs_radius - m_crosshairs_border_size, .0f });
m_bottom_crosshairs_border.Size({ (float)m_crosshairs_thickness + m_crosshairs_border_size * 2, (float)ptMonitorBottomRight.y - (float)ptCursor.y - m_crosshairs_radius + m_crosshairs_border_size });
m_bottom_crosshairs.Offset({ (float)ptCursor.x - halfPixelAdjustment, (float)ptCursor.y + m_crosshairs_radius, .0f });
m_bottom_crosshairs.Size({ (float)m_crosshairs_thickness, (float)ptMonitorBottomRight.y - (float)ptCursor.y - m_crosshairs_radius });
}
@@ -244,11 +247,11 @@ void InclusiveCrosshairs::StartDrawing()
{
Logger::info("Start drawing crosshairs.");
Trace::StartDrawingCrosshairs();
m_visible = true;
SetWindowPos(m_hwnd, HWND_TOPMOST, GetSystemMetrics(SM_XVIRTUALSCREEN), GetSystemMetrics(SM_YVIRTUALSCREEN), GetSystemMetrics(SM_CXVIRTUALSCREEN), GetSystemMetrics(SM_CYVIRTUALSCREEN), 0);
ShowWindow(m_hwnd, SW_SHOWNOACTIVATE);
m_mouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProc, m_hinstance, 0);
UpdateCrosshairsPosition();
ShowWindow(m_hwnd, SW_SHOWNOACTIVATE);
m_visible = true;
m_mouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProc, m_hinstance, 0);
}
void InclusiveCrosshairs::StopDrawing()
@@ -267,16 +270,22 @@ void InclusiveCrosshairs::SwitchActivationMode()
void InclusiveCrosshairs::ApplySettings(InclusiveCrosshairsSettings& settings, bool applyToRunTimeObjects)
{
m_crosshairs_radius = (float)settings.crosshairsRadius;
m_crosshairs_thickness = (float)settings.crosshairsThickness;
m_crosshairs_radius = settings.crosshairsRadius;
m_crosshairs_thickness = settings.crosshairsThickness;
m_crosshairs_color = settings.crosshairsColor;
m_crosshairs_opacity = max(0.f, min(1.f, (float)settings.crosshairsOpacity / 100.0f));
m_crosshairs_border_color = settings.crosshairsBorderColor;
m_crosshairs_border_size = (float)settings.crosshairsBorderSize;
m_crosshairs_border_size = settings.crosshairsBorderSize;
if (applyToRunTimeObjects)
{
// Runtime objects already created. Should update in the owner thread.
if (m_dispatcherQueueController == nullptr)
{
Logger::warn("Tried accessing the dispatch queue controller before it was initialized.");
// No dispatcher Queue Controller? Means initialization still hasn't run, so settings will be applied then.
return;
}
auto dispatcherQueue = m_dispatcherQueueController.DispatcherQueue();
InclusiveCrosshairsSettings localSettings = settings;
bool enqueueSucceeded = dispatcherQueue.TryEnqueue([=]() {

View File

@@ -24,13 +24,13 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>

View File

@@ -13,12 +13,12 @@
<ProjectGuid>{2edb3eb4-fa92-4bff-b2d8-566584837231}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>ShortcutGuide</RootNamespace>
<WindowsTargetPlatformMinVersion>10.0.17134.0</WindowsTargetPlatformMinVersion>
<WindowsTargetPlatformMinVersion>10.0.18362.0</WindowsTargetPlatformMinVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '15.0'">v141</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '16.0'">v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>

View File

@@ -19,21 +19,21 @@
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{2d604c07-51fc-46bb-9eb7-75aecc7f5e81}</ProjectGuid>
<RootNamespace>ShortcutGuideModuleInterface</RootNamespace>
<WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>
<ProjectName>ShortcutGuideModuleInterface</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<SpectreMitigation>Spectre</SpectreMitigation>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<SpectreMitigation>Spectre</SpectreMitigation>

View File

@@ -3,6 +3,7 @@
#include <common/display/dpi_aware.h>
#include <common/utils/game_mode.h>
#include <common/utils/excluded_apps.h>
#include <common/utils/resources.h>
#include <common/utils/winapi_error.h>
#include <common/utils/process_path.h>
@@ -15,22 +16,6 @@ namespace NonLocalizable
const static wchar_t* WINDOW_IS_PINNED_PROP = L"AlwaysOnTop_Pinned";
}
// TODO: move to common utils
bool find_app_name_in_path(const std::wstring& where, const std::vector<std::wstring>& what)
{
for (const auto& row : what)
{
const auto pos = where.rfind(row);
const auto last_slash = where.rfind('\\');
//Check that row occurs in where, and its last occurrence contains in itself the first character after the last backslash.
if (pos != std::wstring::npos && pos <= last_slash + 1 && pos + row.length() > last_slash)
{
return true;
}
}
return false;
}
bool isExcluded(HWND window)
{
auto processPath = get_process_path(window);
@@ -262,12 +247,11 @@ void AlwaysOnTop::RegisterHotkey() const
void AlwaysOnTop::SubscribeToEvents()
{
// subscribe to windows events
std::array<DWORD, 6> events_to_subscribe = {
std::array<DWORD, 5> events_to_subscribe = {
EVENT_OBJECT_LOCATIONCHANGE,
EVENT_SYSTEM_MINIMIZESTART,
EVENT_SYSTEM_MINIMIZEEND,
EVENT_SYSTEM_MOVESIZEEND,
EVENT_OBJECT_DESTROY,
EVENT_OBJECT_NAMECHANGE
};
@@ -326,15 +310,28 @@ bool AlwaysOnTop::PinTopmostWindow(HWND window) const noexcept
{
if (!SetProp(window, NonLocalizable::WINDOW_IS_PINNED_PROP, (HANDLE)1))
{
Logger::error(L"SetProp failed");
Logger::error(L"SetProp failed, {}", get_last_error_or_default(GetLastError()));
}
return SetWindowPos(window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
auto res = SetWindowPos(window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
if (!res)
{
Logger::error(L"Failed to pin window, {}", get_last_error_or_default(GetLastError()));
}
return res;
}
bool AlwaysOnTop::UnpinTopmostWindow(HWND window) const noexcept
{
RemoveProp(window, NonLocalizable::WINDOW_IS_PINNED_PROP);
return SetWindowPos(window, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
auto res = SetWindowPos(window, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
if (!res)
{
Logger::error(L"Failed to unpin window, {}", get_last_error_or_default(GetLastError()));
}
return res;
}
bool AlwaysOnTop::IsTracked(HWND window) const noexcept
@@ -345,11 +342,29 @@ bool AlwaysOnTop::IsTracked(HWND window) const noexcept
void AlwaysOnTop::HandleWinHookEvent(WinHookEvent* data) noexcept
{
if (!AlwaysOnTopSettings::settings().enableFrame)
if (!AlwaysOnTopSettings::settings().enableFrame || !data->hwnd)
{
return;
}
// fix for the https://github.com/microsoft/PowerToys/issues/15300
// check if the window was closed, since for some EVENT_OBJECT_DESTROY doesn't work
std::vector<HWND> toErase{};
for (const auto& [window, border] : m_topmostWindows)
{
bool visible = IsWindowVisible(window);
if (!visible)
{
UnpinTopmostWindow(window);
toErase.push_back(window);
}
}
for (const auto window : toErase)
{
m_topmostWindows.erase(window);
}
switch (data->event)
{
case EVENT_OBJECT_LOCATIONCHANGE:
@@ -396,15 +411,6 @@ void AlwaysOnTop::HandleWinHookEvent(WinHookEvent* data) noexcept
}
}
break;
case EVENT_OBJECT_DESTROY:
{
auto iter = m_topmostWindows.find(data->hwnd);
if (iter != m_topmostWindows.end())
{
m_topmostWindows.erase(iter);
}
}
break;
case EVENT_OBJECT_NAMECHANGE:
{
// The accessibility name of the desktop window changes whenever the user

View File

@@ -66,7 +66,7 @@
</ItemDefinitionGroup>
<!-- Global props -->
<PropertyGroup Label="Globals" Condition="'$(OverrideWindowsTargetPlatformVersion)'!='True'">
<WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{1DC3BE92-CE89-43FB-8110-9C043A2FE7A2}</ProjectGuid>
@@ -75,7 +75,7 @@
<!-- Props that are constant for both Debug and Release configurations -->
<PropertyGroup Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)\obj\$(ProjectName)\</IntDir>
<CharacterSet>Unicode</CharacterSet>
<SpectreMitigation>Spectre</SpectreMitigation>

View File

@@ -1,6 +1,19 @@
#include "pch.h"
#include "FrameDrawer.h"
#include <dwmapi.h>
namespace
{
size_t D2DRectUHash(D2D1_SIZE_U rect)
{
using pod_repr_t = uint64_t;
static_assert(sizeof(D2D1_SIZE_U) == sizeof(pod_repr_t));
std::hash<pod_repr_t> hasher{};
return hasher(*reinterpret_cast<const pod_repr_t*>(&rect));
}
}
std::unique_ptr<FrameDrawer> FrameDrawer::Create(HWND window)
{
auto self = std::make_unique<FrameDrawer>(window);
@@ -12,63 +25,54 @@ std::unique_ptr<FrameDrawer> FrameDrawer::Create(HWND window)
return nullptr;
}
FrameDrawer::FrameDrawer(FrameDrawer&& other) :
m_window(other.m_window),
m_renderTarget(std::move(other.m_renderTarget)),
m_sceneRect(std::move(other.m_sceneRect)),
m_renderThread(std::move(m_renderThread))
{
}
FrameDrawer::FrameDrawer(HWND window) :
m_window(window), m_renderTarget(nullptr)
m_window(window)
{
}
FrameDrawer::~FrameDrawer()
bool FrameDrawer::CreateRenderTargets(const RECT& clientRect)
{
m_abortThread = true;
m_renderThread.join();
HRESULT hr;
if (m_renderTarget)
constexpr float DPI = 96.f; // Always using the default in DPI-aware mode
const auto renderTargetProperties = D2D1::RenderTargetProperties(
D2D1_RENDER_TARGET_TYPE_DEFAULT,
D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED),
DPI,
DPI);
const auto renderTargetSize = D2D1::SizeU(clientRect.right - clientRect.left, clientRect.bottom - clientRect.top);
const auto rectHash = D2DRectUHash(renderTargetSize);
if (m_renderTarget && rectHash == m_renderTargetSizeHash)
{
m_renderTarget->Release();
// Already at the desired size -> do nothing
return true;
}
m_renderTarget = nullptr;
const auto hwndRenderTargetProperties = D2D1::HwndRenderTargetProperties(m_window, renderTargetSize, D2D1_PRESENT_OPTIONS_NONE);
hr = GetD2DFactory()->CreateHwndRenderTarget(renderTargetProperties, hwndRenderTargetProperties, m_renderTarget.put());
if (!SUCCEEDED(hr) || !m_renderTarget)
{
return false;
}
m_renderTargetSizeHash = rectHash;
return true;
}
bool FrameDrawer::Init()
{
RECT clientRect;
// Obtain the size of the drawing area.
if (!GetClientRect(m_window, &clientRect))
if (!SUCCEEDED(DwmGetWindowAttribute(m_window, DWMWA_EXTENDED_FRAME_BOUNDS, &clientRect, sizeof(clientRect))))
{
return false;
}
HRESULT hr;
// Create a Direct2D render target
// We should always use the DPI value of 96 since we're running in DPI aware mode
auto renderTargetProperties = D2D1::RenderTargetProperties(
D2D1_RENDER_TARGET_TYPE_DEFAULT,
D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED),
96.f,
96.f);
auto renderTargetSize = D2D1::SizeU(clientRect.right - clientRect.left, clientRect.bottom - clientRect.top);
auto hwndRenderTargetProperties = D2D1::HwndRenderTargetProperties(m_window, renderTargetSize);
hr = GetD2DFactory()->CreateHwndRenderTarget(renderTargetProperties, hwndRenderTargetProperties, &m_renderTarget);
if (!SUCCEEDED(hr))
{
return false;
}
m_renderThread = std::thread([this]() { RenderLoop(); });
return true;
return CreateRenderTargets(clientRect);
}
void FrameDrawer::Hide()
@@ -79,19 +83,63 @@ void FrameDrawer::Hide()
void FrameDrawer::Show()
{
ShowWindow(m_window, SW_SHOWNA);
Render();
}
void FrameDrawer::SetBorderRect(RECT windowRect, COLORREF color, float thickness)
void FrameDrawer::SetBorderRect(RECT windowRect, COLORREF color, int thickness)
{
std::unique_lock lock(m_mutex);
auto borderColor = ConvertColor(color);
m_sceneRect = DrawableRect{
const auto newSceneRect = DrawableRect{
.rect = ConvertRect(windowRect),
.borderColor = borderColor,
.borderColor = ConvertColor(color),
.thickness = thickness
};
const bool colorUpdated = std::memcmp(&m_sceneRect.borderColor, &newSceneRect.borderColor, sizeof(newSceneRect.borderColor));
const bool thicknessUpdated = m_sceneRect.thickness != newSceneRect.thickness;
const bool needsRedraw = colorUpdated || thicknessUpdated;
RECT clientRect;
if (!SUCCEEDED(DwmGetWindowAttribute(m_window, DWMWA_EXTENDED_FRAME_BOUNDS, &clientRect, sizeof(clientRect))))
{
return;
}
m_sceneRect = newSceneRect;
const auto renderTargetSize = D2D1::SizeU(clientRect.right - clientRect.left, clientRect.bottom - clientRect.top);
const auto rectHash = D2DRectUHash(renderTargetSize);
const bool atTheDesiredSize = (rectHash == m_renderTargetSizeHash) && m_renderTarget;
if (!atTheDesiredSize)
{
const bool resizeOk = m_renderTarget && SUCCEEDED(m_renderTarget->Resize(renderTargetSize));
if (!resizeOk)
{
if (!CreateRenderTargets(clientRect))
{
Logger::error(L"Failed to create render targets");
}
}
else
{
m_renderTargetSizeHash = rectHash;
}
}
if (colorUpdated)
{
m_borderBrush = nullptr;
if (m_renderTarget)
{
m_renderTarget->CreateSolidColorBrush(m_sceneRect.borderColor, m_borderBrush.put());
}
}
if (!atTheDesiredSize || needsRedraw)
{
Render();
}
}
ID2D1Factory* FrameDrawer::GetD2DFactory()
@@ -127,46 +175,19 @@ D2D1_RECT_F FrameDrawer::ConvertRect(RECT rect)
return D2D1::RectF((float)rect.left, (float)rect.top, (float)rect.right, (float)rect.bottom);
}
FrameDrawer::RenderResult FrameDrawer::Render()
void FrameDrawer::Render()
{
std::unique_lock lock(m_mutex);
if (!m_renderTarget)
{
return RenderResult::Failed;
}
return;
m_renderTarget->BeginDraw();
// Draw backdrop
m_renderTarget->Clear(D2D1::ColorF(0.f, 0.f, 0.f, 0.f));
ID2D1SolidColorBrush* borderBrush = nullptr;
m_renderTarget->CreateSolidColorBrush(m_sceneRect.borderColor, &borderBrush);
if (borderBrush)
if (m_borderBrush)
{
m_renderTarget->DrawRectangle(m_sceneRect.rect, borderBrush, m_sceneRect.thickness);
borderBrush->Release();
// The border stroke is centered on the line.
m_renderTarget->DrawRectangle(m_sceneRect.rect, m_borderBrush.get(), static_cast<float>(m_sceneRect.thickness * 2));
}
// The lock must be released here, as EndDraw() will wait for vertical sync
lock.unlock();
m_renderTarget->EndDraw();
return RenderResult::Ok;
}
void FrameDrawer::RenderLoop()
{
while (!m_abortThread)
{
auto result = Render();
if (result == RenderResult::Failed)
{
Logger::error("Render failed");
Hide();
m_abortThread = true;
}
}
}
}

View File

@@ -1,7 +1,9 @@
#pragma once
#include <mutex>
#include <d2d1.h>
#include <winrt/base.h>
#include <dwrite.h>
class FrameDrawer
@@ -10,42 +12,33 @@ public:
static std::unique_ptr<FrameDrawer> Create(HWND window);
FrameDrawer(HWND window);
FrameDrawer(FrameDrawer&& other);
~FrameDrawer();
FrameDrawer(FrameDrawer&& other) = default;
bool Init();
void Show();
void Hide();
void SetBorderRect(RECT windowRect, COLORREF color, float thickness);
void SetBorderRect(RECT windowRect, COLORREF color, int thickness);
private:
bool CreateRenderTargets(const RECT& clientRect);
struct DrawableRect
{
D2D1_RECT_F rect;
D2D1_COLOR_F borderColor;
float thickness;
};
enum struct RenderResult
{
Ok,
Failed,
int thickness;
};
static ID2D1Factory* GetD2DFactory();
static IDWriteFactory* GetWriteFactory();
static D2D1_COLOR_F ConvertColor(COLORREF color);
static D2D1_RECT_F ConvertRect(RECT rect);
RenderResult Render();
void RenderLoop();
void Render();
HWND m_window = nullptr;
ID2D1HwndRenderTarget* m_renderTarget = nullptr;
std::mutex m_mutex;
DrawableRect m_sceneRect;
std::atomic<bool> m_abortThread = false;
std::thread m_renderThread;
size_t m_renderTargetSizeHash = {};
winrt::com_ptr<ID2D1HwndRenderTarget> m_renderTarget;
winrt::com_ptr<ID2D1SolidColorBrush> m_borderBrush;
DrawableRect m_sceneRect = {};
};

View File

@@ -118,7 +118,7 @@ void AlwaysOnTopSettings::LoadSettings()
auto val = *jsonVal;
if (m_settings.frameThickness != val)
{
m_settings.frameThickness = static_cast<float>(val);
m_settings.frameThickness = val;
NotifyObservers(SettingId::FrameThickness);
}
}

View File

@@ -19,7 +19,7 @@ struct Settings
bool enableSound = true;
bool blockInGameMode = true;
bool frameAccentColor = true;
float frameThickness = 15.0f;
int frameThickness = 15;
COLORREF frameColor = RGB(0, 173, 239);
std::vector<std::wstring> excludedApps{};
};

View File

@@ -2,10 +2,10 @@
#include "WindowBorder.h"
#include <dwmapi.h>
#include "winrt/Windows.Foundation.h"
#include <FrameDrawer.h>
#include <Settings.h>
#include "winrt/Windows.Foundation.h"
// Non-Localizable strings
namespace NonLocalizable
@@ -21,7 +21,7 @@ std::optional<RECT> GetFrameRect(HWND window)
return std::nullopt;
}
int border = static_cast<int>(AlwaysOnTopSettings::settings().frameThickness / 2);
int border = AlwaysOnTopSettings::settings().frameThickness;
rect.top -= border;
rect.left -= border;
rect.right += border;
@@ -31,18 +31,10 @@ std::optional<RECT> GetFrameRect(HWND window)
}
WindowBorder::WindowBorder(HWND window) :
SettingsObserver({SettingId::FrameColor, SettingId::FrameThickness, SettingId::FrameAccentColor }),
m_window(nullptr),
m_trackingWindow(window),
m_frameDrawer(nullptr)
{
}
WindowBorder::WindowBorder(WindowBorder&& other) :
SettingsObserver({ SettingId::FrameColor, SettingId::FrameThickness, SettingId::FrameAccentColor }),
m_window(other.m_window),
m_trackingWindow(other.m_trackingWindow),
m_frameDrawer(std::move(other.m_frameDrawer))
m_window(nullptr),
m_trackingWindow(window),
m_frameDrawer(nullptr)
{
}
@@ -72,6 +64,12 @@ std::unique_ptr<WindowBorder> WindowBorder::Create(HWND window, HINSTANCE hinsta
return nullptr;
}
namespace
{
constexpr uint32_t REFRESH_BORDER_TIMER_ID = 123;
constexpr uint32_t REFRESH_BORDER_INTERVAL = 100;
}
bool WindowBorder::Init(HINSTANCE hinstance)
{
if (!m_trackingWindow)
@@ -98,7 +96,7 @@ bool WindowBorder::Init(HINSTANCE hinstance)
m_window = CreateWindowExW(WS_EX_LAYERED | WS_EX_TOPMOST | WS_EX_TOOLWINDOW
, NonLocalizable::ToolWindowClassName
, L""
, WS_POPUP
, WS_POPUP | WS_DISABLED
, windowRect.left
, windowRect.top
, windowRect.right - windowRect.left
@@ -124,8 +122,8 @@ bool WindowBorder::Init(HINSTANCE hinstance)
, m_window
, windowRect.left
, windowRect.top
, windowRect.right - windowRect.left - static_cast<int>(AlwaysOnTopSettings::settings().frameThickness)
, windowRect.bottom - windowRect.top - static_cast<int>(AlwaysOnTopSettings::settings().frameThickness)
, windowRect.right - windowRect.left
, windowRect.bottom - windowRect.top
, SWP_NOMOVE | SWP_NOSIZE);
m_frameDrawer = FrameDrawer::Create(m_window);
@@ -136,6 +134,8 @@ bool WindowBorder::Init(HINSTANCE hinstance)
UpdateBorderProperties();
m_frameDrawer->Show();
m_timer_id = SetTimer(m_window, REFRESH_BORDER_TIMER_ID, REFRESH_BORDER_INTERVAL, nullptr);
return true;
}
@@ -154,7 +154,7 @@ void WindowBorder::UpdateBorderPosition() const
}
RECT rect = rectOpt.value();
SetWindowPos(m_window, m_trackingWindow, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOREDRAW);
SetWindowPos(m_window, m_trackingWindow, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOREDRAW | SWP_NOACTIVATE);
}
void WindowBorder::UpdateBorderProperties() const
@@ -170,7 +170,9 @@ void WindowBorder::UpdateBorderProperties() const
return;
}
RECT windowRect = windowRectOpt.value();
const RECT windowRect = windowRectOpt.value();
SetWindowPos(m_window, m_trackingWindow, windowRect.left, windowRect.top, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, SWP_NOREDRAW | SWP_NOACTIVATE);
RECT frameRect{ 0, 0, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top };
COLORREF color;
@@ -192,8 +194,22 @@ LRESULT WindowBorder::WndProc(UINT message, WPARAM wparam, LPARAM lparam) noexce
{
switch (message)
{
case WM_TIMER:
{
switch (wparam)
{
case REFRESH_BORDER_TIMER_ID:
KillTimer(m_window, m_timer_id);
m_timer_id = SetTimer(m_window, REFRESH_BORDER_TIMER_ID, REFRESH_BORDER_INTERVAL, nullptr);
UpdateBorderPosition();
UpdateBorderProperties();
break;
}
break;
}
case WM_NCDESTROY:
{
KillTimer(m_window, m_timer_id);
::DefWindowProc(m_window, message, wparam, lparam);
SetWindowLongPtr(m_window, GWLP_USERDATA, 0);
}
@@ -202,6 +218,10 @@ LRESULT WindowBorder::WndProc(UINT message, WPARAM wparam, LPARAM lparam) noexce
case WM_ERASEBKGND:
return TRUE;
// prevent from beeping if the border was clicked
case WM_SETCURSOR:
return TRUE;
default:
{
return DefWindowProc(m_window, message, wparam, lparam);
@@ -231,7 +251,7 @@ void WindowBorder::SettingsUpdate(SettingId id)
UpdateBorderProperties();
}
break;
case SettingId::FrameColor:
{
UpdateBorderProperties();
@@ -246,5 +266,4 @@ void WindowBorder::SettingsUpdate(SettingId id)
default:
break;
}
}

View File

@@ -7,8 +7,8 @@ class FrameDrawer;
class WindowBorder : public SettingsObserver
{
WindowBorder(HWND window);
WindowBorder(WindowBorder&& other);
WindowBorder(WindowBorder&& other) = default;
public:
static std::unique_ptr<WindowBorder> Create(HWND window, HINSTANCE hinstance);
~WindowBorder();
@@ -32,8 +32,9 @@ protected:
}
private:
HWND m_window;
HWND m_trackingWindow;
UINT_PTR m_timer_id = {};
HWND m_window = {};
HWND m_trackingWindow = {};
std::unique_ptr<FrameDrawer> m_frameDrawer;
LRESULT WndProc(UINT message, WPARAM wparam, LPARAM lparam) noexcept;

View File

@@ -4,4 +4,7 @@
#include <winrt/base.h>
#include <wil/resource.h>
#include <ProjectTelemetry.h>
#include <common/logger/logger.h>
#include <common/logger/logger.h>
#include <functional>
#include <array>

View File

@@ -12,6 +12,12 @@
<PropertyGroup Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>

View File

@@ -2,7 +2,7 @@
<Import Project="..\..\..\Version.props" />
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net5.0-windows</TargetFramework>
<TargetFramework>net6.0-windows</TargetFramework>
<OutputPath>$(SolutionDir)$(Platform)\$(Configuration)\modules\Awake</OutputPath>
<Nullable>enable</Nullable>
<Platforms>x64</Platforms>
@@ -40,11 +40,15 @@
</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="NLog" Version="4.7.9" />
<PackageReference Include="NLog" Version="4.7.13" />
<PackageReference Include="System.CommandLine" Version="2.0.0-beta1.20071.2" />
<PackageReference Include="System.Reactive" Version="5.0.0" />
<PackageReference Include="System.Runtime.Caching" Version="6.0.0-preview.1.21102.12" />
<PackageReference Include="System.Runtime.Caching" Version="6.0.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -7,30 +7,12 @@ using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Awake.Core.Models;
using Microsoft.Win32;
using NLog;
namespace Awake.Core
{
[Flags]
public enum EXECUTION_STATE : uint
{
ES_AWAYMODE_REQUIRED = 0x00000040,
ES_CONTINUOUS = 0x80000000,
ES_DISPLAY_REQUIRED = 0x00000002,
ES_SYSTEM_REQUIRED = 0x00000001,
}
// See: https://docs.microsoft.com/windows/console/handlerroutine
public enum ControlType
{
CTRL_C_EVENT = 0,
CTRL_BREAK_EVENT = 1,
CTRL_CLOSE_EVENT = 2,
CTRL_LOGOFF_EVENT = 5,
CTRL_SHUTDOWN_EVENT = 6,
}
public delegate bool ConsoleEventHandler(ControlType ctrlType);
/// <summary>
@@ -85,7 +67,7 @@ namespace Awake.Core
/// </summary>
/// <param name="state">Single or multiple EXECUTION_STATE entries.</param>
/// <returns>true if successful, false if failed</returns>
private static bool SetAwakeState(EXECUTION_STATE state)
private static bool SetAwakeState(ExecutionState state)
{
try
{
@@ -168,11 +150,11 @@ namespace Awake.Core
bool success;
if (keepDisplayOn)
{
success = SetAwakeState(EXECUTION_STATE.ES_SYSTEM_REQUIRED | EXECUTION_STATE.ES_DISPLAY_REQUIRED | EXECUTION_STATE.ES_CONTINUOUS);
success = SetAwakeState(ExecutionState.ES_SYSTEM_REQUIRED | ExecutionState.ES_DISPLAY_REQUIRED | ExecutionState.ES_CONTINUOUS);
}
else
{
success = SetAwakeState(EXECUTION_STATE.ES_SYSTEM_REQUIRED | EXECUTION_STATE.ES_CONTINUOUS);
success = SetAwakeState(ExecutionState.ES_SYSTEM_REQUIRED | ExecutionState.ES_CONTINUOUS);
}
try
@@ -209,11 +191,11 @@ namespace Awake.Core
{
if (keepDisplayOn)
{
success = SetAwakeState(EXECUTION_STATE.ES_SYSTEM_REQUIRED | EXECUTION_STATE.ES_DISPLAY_REQUIRED | EXECUTION_STATE.ES_CONTINUOUS);
success = SetAwakeState(ExecutionState.ES_SYSTEM_REQUIRED | ExecutionState.ES_DISPLAY_REQUIRED | ExecutionState.ES_CONTINUOUS);
}
else
{
success = SetAwakeState(EXECUTION_STATE.ES_SYSTEM_REQUIRED | EXECUTION_STATE.ES_CONTINUOUS);
success = SetAwakeState(ExecutionState.ES_SYSTEM_REQUIRED | ExecutionState.ES_CONTINUOUS);
}
if (success)

View File

@@ -0,0 +1,12 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Awake.Core.Models
{
public struct BatteryReportingScale
{
public uint Granularity;
public uint Capacity;
}
}

View File

@@ -0,0 +1,16 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Awake.Core.Models
{
// See: https://docs.microsoft.com/windows/console/handlerroutine
public enum ControlType
{
CTRL_C_EVENT = 0,
CTRL_BREAK_EVENT = 1,
CTRL_CLOSE_EVENT = 2,
CTRL_LOGOFF_EVENT = 5,
CTRL_SHUTDOWN_EVENT = 6,
}
}

View File

@@ -0,0 +1,17 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
namespace Awake.Core.Models
{
[Flags]
public enum ExecutionState : uint
{
ES_AWAYMODE_REQUIRED = 0x00000040,
ES_CONTINUOUS = 0x80000000,
ES_DISPLAY_REQUIRED = 0x00000002,
ES_SYSTEM_REQUIRED = 0x00000001,
}
}

View File

@@ -0,0 +1,70 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Runtime.InteropServices;
namespace Awake.Core.Models
{
public struct SystemPowerCapabilities
{
[MarshalAs(UnmanagedType.U1)]
public bool PowerButtonPresent;
[MarshalAs(UnmanagedType.U1)]
public bool SleepButtonPresent;
[MarshalAs(UnmanagedType.U1)]
public bool LidPresent;
[MarshalAs(UnmanagedType.U1)]
public bool SystemS1;
[MarshalAs(UnmanagedType.U1)]
public bool SystemS2;
[MarshalAs(UnmanagedType.U1)]
public bool SystemS3;
[MarshalAs(UnmanagedType.U1)]
public bool SystemS4;
[MarshalAs(UnmanagedType.U1)]
public bool SystemS5;
[MarshalAs(UnmanagedType.U1)]
public bool HiberFilePresent;
[MarshalAs(UnmanagedType.U1)]
public bool FullWake;
[MarshalAs(UnmanagedType.U1)]
public bool VideoDimPresent;
[MarshalAs(UnmanagedType.U1)]
public bool ApmPresent;
[MarshalAs(UnmanagedType.U1)]
public bool UpsPresent;
[MarshalAs(UnmanagedType.U1)]
public bool ThermalControl;
[MarshalAs(UnmanagedType.U1)]
public bool ProcessorThrottle;
public byte ProcessorMinThrottle;
public byte ProcessorMaxThrottle;
[MarshalAs(UnmanagedType.U1)]
public bool FastSystemS4;
[MarshalAs(UnmanagedType.U1)]
public bool Hiberboot;
[MarshalAs(UnmanagedType.U1)]
public bool WakeAlarmPresent;
[MarshalAs(UnmanagedType.U1)]
public bool AoAc;
[MarshalAs(UnmanagedType.U1)]
public bool DiskSpinDown;
public byte HiberFileType;
[MarshalAs(UnmanagedType.U1)]
public bool AoAcConnectivitySupported;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
private readonly byte[] spare3;
[MarshalAs(UnmanagedType.U1)]
public bool SystemBatteriesPresent;
[MarshalAs(UnmanagedType.U1)]
public bool BatteriesAreShortTerm;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public BatteryReportingScale[] BatteryScale;
public SystemPowerState AcOnLineWake;
public SystemPowerState SoftLidWake;
public SystemPowerState RtcWake;
public SystemPowerState MinDeviceWakeState;
public SystemPowerState DefaultLowLatencyWake;
}
}

View File

@@ -0,0 +1,20 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Awake.Core.Models
{
// Maps to the OS power state.
// See documentation: https://docs.microsoft.com/windows/win32/power/system-power-states
public enum SystemPowerState
{
PowerSystemUnspecified = 0,
PowerSystemWorking = 1,
PowerSystemSleeping1 = 2,
PowerSystemSleeping2 = 3,
PowerSystemSleeping3 = 4,
PowerSystemHibernate = 5,
PowerSystemShutdown = 6,
PowerSystemMaximum = 7,
}
}

View File

@@ -5,16 +5,20 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
using Awake.Core.Models;
namespace Awake.Core
{
internal static class NativeMethods
{
[DllImport("Powrprof.dll", SetLastError = true)]
internal static extern bool GetPwrCapabilities(out SystemPowerCapabilities lpSystemPowerCapabilities);
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern bool SetConsoleCtrlHandler(ConsoleEventHandler handler, bool add);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags);
internal static extern ExecutionState SetThreadExecutionState(ExecutionState esFlags);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]

View File

@@ -2,12 +2,12 @@
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<variable name="awakeversion" value="0.0.1" />
<variable name="buildId" value="ARBITER_01312022" />
<targets async="true">
<target name="logfile"
xsi:type="File"
fileName="${specialfolder:folder=LocalApplicationData}/Microsoft/PowerToys/Awake/Logs/${var:awakeversion}/log_${date:format=yyyy-MM-dd_HH}_DBG.txt"
fileName="${specialfolder:folder=LocalApplicationData}/Microsoft/PowerToys/Awake/Logs/${var:awakeversion}/applog_${date:format=yyyy-MM-dd_HH}_${var:buildId}.txt"
layout="[${longdate} ${level:uppercase=true} ${logger}] ${message}"
archiveEvery="Day"
archiveNumbering="Rolling"

View File

@@ -12,9 +12,10 @@ using System.Linq;
using System.Reactive.Concurrency;
using System.Reactive.Linq;
using System.Reflection;
using System.Text.Json;
using System.Threading;
using System.Windows;
using Awake.Core;
using Awake.Core.Models;
using interop;
using ManagedCommon;
using Microsoft.PowerToys.Settings.UI.Library;
@@ -27,6 +28,14 @@ namespace Awake
{
internal class Program
{
// PowerToys Awake build code name. Used for exact logging
// that does not map to PowerToys broad version schema to pinpoint
// internal issues easier.
// Format of the build ID is: CODENAME_MMDDYYYY, where MMDDYYYY
// is representative of the date when the last change was made before
// the pull request is issued.
private static readonly string BuildId = "ARBITER_01312022";
private static Mutex? _mutex = null;
private static FileSystemWatcher? _watcher = null;
private static SettingsUtils? _settingsUtils = null;
@@ -37,6 +46,7 @@ namespace Awake
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
private static ConsoleEventHandler _handler;
private static SystemPowerCapabilities _powerCapabilities;
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
private static ManualResetEvent _exitSignal = new ManualResetEvent(false);
@@ -56,17 +66,23 @@ namespace Awake
_settingsUtils = new SettingsUtils();
_log.Info("Launching PowerToys Awake...");
_log.Info($"Launching {InternalConstants.AppName}...");
_log.Info(FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion);
_log.Info($"Build: {BuildId}");
_log.Info($"OS: {Environment.OSVersion}");
_log.Info($"OS Build: {APIHelper.GetOperatingSystemBuild()}");
// To make it easier to diagnose future issues, let's get the
// system power capabilities and aggregate them in the log.
NativeMethods.GetPwrCapabilities(out _powerCapabilities);
_log.Info(JsonSerializer.Serialize(_powerCapabilities));
_log.Info("Parsing parameters...");
Option<bool>? configOption = new Option<bool>(
Option<bool>? configOption = new (
aliases: new[] { "--use-pt-config", "-c" },
getDefaultValue: () => false,
description: "Specifies whether PowerToys Awake will be using the PowerToys configuration file for managing the state.")
description: $"Specifies whether {InternalConstants.AppName} will be using the PowerToys configuration file for managing the state.")
{
Argument = new Argument<bool>(() => false)
{
@@ -76,7 +92,7 @@ namespace Awake
configOption.Required = false;
Option<bool>? displayOption = new Option<bool>(
Option<bool>? displayOption = new (
aliases: new[] { "--display-on", "-d" },
getDefaultValue: () => true,
description: "Determines whether the display should be kept awake.")
@@ -89,7 +105,7 @@ namespace Awake
displayOption.Required = false;
Option<uint>? timeOption = new Option<uint>(
Option<uint>? timeOption = new (
aliases: new[] { "--time-limit", "-t" },
getDefaultValue: () => 0,
description: "Determines the interval, in seconds, during which the computer is kept awake.")
@@ -102,10 +118,10 @@ namespace Awake
timeOption.Required = false;
Option<int>? pidOption = new Option<int>(
Option<int>? pidOption = new (
aliases: new[] { "--pid", "-p" },
getDefaultValue: () => 0,
description: "Bind the execution of PowerToys Awake to another process.")
description: $"Bind the execution of {InternalConstants.AppName} to another process.")
{
Argument = new Argument<int>(() => 0)
{
@@ -135,9 +151,7 @@ namespace Awake
private static bool ExitHandler(ControlType ctrlType)
{
_log.Info($"Exited through handler with control type: {ctrlType}");
Exit("Exiting from the internal termination handler.", Environment.ExitCode);
return false;
}
@@ -251,7 +265,8 @@ namespace Awake
{
RunnerHelper.WaitForPowerToysRunner(pid, () =>
{
Exit("Terminating from PowerToys binding hook.", 0, true);
_log.Info($"Triggered PID-based exit handler for PID {pid}.");
Exit("Terminating from process binding hook.", 0, true);
});
}

View File

@@ -17,12 +17,18 @@
<Keyword>Win32Proj</Keyword>
<RootNamespace>Awake</RootNamespace>
<ProjectName>AwakeModuleInterface</ProjectName>
<WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>

View File

@@ -15,6 +15,12 @@
<PropertyGroup Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>

View File

@@ -31,7 +31,7 @@ namespace ColorPicker
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
NativeMethods.SetPopupStyle(this);
NativeMethods.SetToolWindowStyle(this);
}
}
}

View File

@@ -5,7 +5,7 @@
<Company>Microsoft Corporation</Company>
<AssemblyDescription>PowerToys ColorPicker</AssemblyDescription>
<AssemblyCompany>Microsoft Corp.</AssemblyCompany>
<AssemblyCopyright>Copyright (C) 2020 Microsoft Corporation</AssemblyCopyright>
<AssemblyCopyright>Copyright (C) 2022 Microsoft Corporation</AssemblyCopyright>
<AssemblyProduct>PowerToys</AssemblyProduct>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<OutputPath>$(SolutionDir)$(Platform)\$(Configuration)\modules\ColorPicker</OutputPath>
@@ -21,7 +21,7 @@
<OutputType>WinExe</OutputType>
<RootNamespace>ColorPicker</RootNamespace>
<AssemblyName>PowerToys.ColorPickerUI</AssemblyName>
<TargetFramework>net5.0-windows10.0.18362.0</TargetFramework>
<TargetFramework>net6.0-windows10.0.18362.0</TargetFramework>
<LangVersion>8.0</LangVersion>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
</PropertyGroup>
@@ -50,17 +50,17 @@
<Resource Include="Shaders\GridShader.cso" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.3.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="ModernWpfUI" Version="0.9.4" />
<PackageReference Include="System.ComponentModel.Composition" Version="5.0.0" />
<PackageReference Include="System.ComponentModel.Composition" Version="6.0.0" />
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
<PackageReference Include="System.IO.Abstractions" Version="12.2.5" />
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.19" />
<PackageReference Include="System.Drawing.Common" Version="4.7.0" />
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.39" />
<PackageReference Include="System.Drawing.Common" Version="6.0.0" />
</ItemGroup>
<ItemGroup>
<None Update="Properties\Settings.settings">
@@ -107,4 +107,4 @@
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>
</Project>
</Project>

View File

@@ -79,9 +79,9 @@ namespace ColorPicker.Helpers
/// <param name="color">The see cref="Color"/> for the hexadecimal presentation</param>
/// <returns>A hexadecimal <see cref="string"/> representation of a RGB color</returns>
private static string ColorToHex(Color color)
=> $"{color.R.ToString("X2", CultureInfo.InvariantCulture)}"
+ $"{color.G.ToString("X2", CultureInfo.InvariantCulture)}"
+ $"{color.B.ToString("X2", CultureInfo.InvariantCulture)}";
=> $"{color.R.ToString("x2", CultureInfo.InvariantCulture)}"
+ $"{color.G.ToString("x2", CultureInfo.InvariantCulture)}"
+ $"{color.B.ToString("x2", CultureInfo.InvariantCulture)}";
/// <summary>
/// Return a <see cref="string"/> representation of a HSB color

View File

@@ -15,8 +15,8 @@ namespace ColorPicker
// will have to rename
public static class NativeMethods
{
private const int GWL_STYLE = -16;
private const int WS_POPUP = 1 << 31; // 0x80000000
private const int GWL_EX_STYLE = -20;
private const int WS_EX_TOOLWINDOW = 0x00000080;
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Interop")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification = "Interop")]
@@ -180,10 +180,10 @@ namespace ColorPicker
[DllImport("user32.dll")]
internal static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
internal static void SetPopupStyle(Window win)
internal static void SetToolWindowStyle(Window win)
{
var hwnd = new WindowInteropHelper(win).Handle;
_ = SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) | WS_POPUP);
_ = SetWindowLong(hwnd, GWL_EX_STYLE, GetWindowLong(hwnd, GWL_EX_STYLE) | WS_EX_TOOLWINDOW);
}
}
}

View File

@@ -2,7 +2,7 @@
<Import Project="..\..\..\Version.props" />
<PropertyGroup>
<TargetFramework>net5.0-windows10.0.18362.0</TargetFramework>
<TargetFramework>net6.0-windows10.0.18362.0</TargetFramework>
<ProjectGuid>{090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1}</ProjectGuid>
<RootNamespace>Microsoft.ColorPicker.UnitTests</RootNamespace>
<IsPackable>false</IsPackable>
@@ -26,12 +26,12 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.3.0">
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
<PackageReference Include="coverlet.collector" Version="3.0.3">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
<PackageReference Include="coverlet.collector" Version="3.1.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>

View File

@@ -66,7 +66,7 @@
</ItemDefinitionGroup>
<!-- Global props -->
<PropertyGroup Label="Globals" Condition="'$(OverrideWindowsTargetPlatformVersion)'!='True'">
<WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{ff1d7936-842a-4bbb-8bea-e9fe796de700}</ProjectGuid>
@@ -75,7 +75,7 @@
<!-- Props that are constant for both Debug and Release configurations -->
<PropertyGroup Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)\obj\$(ProjectName)\</IntDir>
<CharacterSet>Unicode</CharacterSet>
<SpectreMitigation>Spectre</SpectreMitigation>

View File

@@ -16,11 +16,9 @@
FancyZonesApp::FancyZonesApp(const std::wstring& appName, const std::wstring& appKey)
{
DPIAware::EnableDPIAwarenessForThisProcess();
m_settings = MakeFancyZonesSettings(reinterpret_cast<HINSTANCE>(&__ImageBase), appName.c_str(), appKey.c_str());
InitializeWinhookEventIds();
m_app = MakeFancyZones(reinterpret_cast<HINSTANCE>(&__ImageBase), m_settings, std::bind(&FancyZonesApp::DisableModule, this));
m_app = MakeFancyZones(reinterpret_cast<HINSTANCE>(&__ImageBase), std::bind(&FancyZonesApp::DisableModule, this));
InitHooks();

View File

@@ -19,7 +19,6 @@ private:
winrt::com_ptr<IFancyZones> m_app;
HWINEVENTHOOK m_objectLocationWinEventHook = nullptr;
std::vector<HWINEVENTHOOK> m_staticWinEventHooks;
winrt::com_ptr<IFancyZonesSettings> m_settings;
void DisableModule() noexcept;

View File

@@ -0,0 +1,59 @@
#include "pch.h"
#include "Colors.h"
#include <winrt/Windows.UI.ViewManagement.h>
#include <FancyZonesLib/Settings.h>
#include <FancyZonesLib/util.h>
namespace Colors
{
COLORREF currentAccentColor;
COLORREF currentBackgroundColor;
bool GetSystemTheme() noexcept
{
winrt::Windows::UI::ViewManagement::UISettings settings;
auto accentValue = settings.GetColorValue(winrt::Windows::UI::ViewManagement::UIColorType::Accent);
auto accentColor = RGB(accentValue.R, accentValue.G, accentValue.B);
auto backgroundValue = settings.GetColorValue(winrt::Windows::UI::ViewManagement::UIColorType::Background);
auto backgroundColor = RGB(backgroundValue.R, backgroundValue.G, backgroundValue.B);
if (currentAccentColor != accentColor || currentBackgroundColor != backgroundColor)
{
currentAccentColor = accentColor;
currentBackgroundColor = backgroundColor;
return true;
}
return false;
}
ZoneColors GetZoneColors() noexcept
{
if (FancyZonesSettings::settings().systemTheme)
{
GetSystemTheme();
auto numberColor = currentBackgroundColor == RGB(0, 0, 0) ? RGB(255, 255, 255) : RGB(0, 0, 0);
return ZoneColors{
.primaryColor = currentBackgroundColor,
.borderColor = currentAccentColor,
.highlightColor = currentAccentColor,
.numberColor = numberColor,
.highlightOpacity = FancyZonesSettings::settings().zoneHighlightOpacity
};
}
else
{
return ZoneColors{
.primaryColor = FancyZonesUtils::HexToRGB(FancyZonesSettings::settings().zoneColor),
.borderColor = FancyZonesUtils::HexToRGB(FancyZonesSettings::settings().zoneBorderColor),
.highlightColor = FancyZonesUtils::HexToRGB(FancyZonesSettings::settings().zoneHighlightColor),
.numberColor = FancyZonesUtils::HexToRGB(FancyZonesSettings::settings().zoneNumberColor),
.highlightOpacity = FancyZonesSettings::settings().zoneHighlightOpacity
};
}
}
}

View File

@@ -0,0 +1,17 @@
#pragma once
#include <windef.h>
namespace Colors
{
struct ZoneColors
{
COLORREF primaryColor;
COLORREF borderColor;
COLORREF highlightColor;
COLORREF numberColor;
int highlightOpacity;
};
ZoneColors GetZoneColors() noexcept;
}

View File

@@ -21,9 +21,11 @@
#include <FancyZonesLib/FancyZonesWinHookEventIDs.h>
#include <FancyZonesLib/MonitorUtils.h>
#include <FancyZonesLib/Settings.h>
#include <FancyZonesLib/SettingsObserver.h>
#include <FancyZonesLib/ZoneSet.h>
#include <FancyZonesLib/WorkArea.h>
#include <FancyZonesLib/WindowMoveHandler.h>
#include <FancyZonesLib/WindowUtils.h>
#include <FancyZonesLib/util.h>
#include "on_thread_executor.h"
@@ -33,7 +35,6 @@
#include "util.h"
#include <FancyZonesLib/SecondaryMouseButtonsHook.h>
#include <winrt/Windows.UI.ViewManagement.h>
enum class DisplayChangeType
{
@@ -50,18 +51,15 @@ namespace NonLocalizable
const wchar_t FZEditorExecutablePath[] = L"modules\\FancyZones\\PowerToys.FancyZonesEditor.exe";
}
struct FancyZones : public winrt::implements<FancyZones, IFancyZones, IFancyZonesCallback>
struct FancyZones : public winrt::implements<FancyZones, IFancyZones, IFancyZonesCallback>, public SettingsObserver
{
public:
FancyZones(HINSTANCE hinstance, const winrt::com_ptr<IFancyZonesSettings>& settings, std::function<void()> disableModuleCallback) noexcept :
FancyZones(HINSTANCE hinstance, std::function<void()> disableModuleCallback) noexcept :
SettingsObserver({ SettingId::EditorHotkey, SettingId::PrevTabHotkey, SettingId::NextTabHotkey, SettingId::SpanZonesAcrossMonitors }),
m_hinstance(hinstance),
m_settings(settings),
m_windowMoveHandler(settings, [this]() {
m_windowMoveHandler([this]() {
PostMessageW(m_window, WM_PRIV_LOCATIONCHANGE, NULL, NULL);
}),
m_settingsFileWatcher(FancyZonesDataInstance().GetSettingsFileName(), [this]() {
PostMessageW(m_window, WM_PRIV_SETTINGS_CHANGED, NULL, NULL);
}),
m_virtualDesktop([this]() {
PostMessage(m_window, WM_PRIV_VD_INIT, 0, 0);
},
@@ -71,6 +69,8 @@ public:
{
this->disableModuleCallback = std::move(disableModuleCallback);
FancyZonesSettings::instance().LoadSettings();
FancyZonesDataInstance().ReplaceZoneSettingsFileFromOlderVersions();
LayoutTemplates::instance().LoadData();
CustomLayouts::instance().LoadData();
@@ -87,23 +87,17 @@ public:
void MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen) noexcept
{
if (m_settings->GetSettings()->spanZonesAcrossMonitors)
if (FancyZonesSettings::settings().spanZonesAcrossMonitors)
{
monitor = NULL;
}
// If accent color or theme is changed need to update colors for zones
if (m_settings->GetSettings()->systemTheme && GetSystemTheme())
{
m_workAreaHandler.UpdateZoneColors(GetZoneColors());
}
m_windowMoveHandler.MoveSizeStart(window, monitor, ptScreen, m_workAreaHandler.GetWorkAreasByDesktopId(m_currentDesktopId));
}
void MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen) noexcept
{
if (m_settings->GetSettings()->spanZonesAcrossMonitors)
if (FancyZonesSettings::settings().spanZonesAcrossMonitors)
{
monitor = NULL;
}
@@ -174,8 +168,7 @@ private:
void RegisterVirtualDesktopUpdates() noexcept;
void UpdateHotkey(int hotkeyId, const PowerToysSettings::HotkeyObject& hotkeyObject, bool enable) noexcept;
void OnSettingsChanged() noexcept;
std::pair<winrt::com_ptr<IWorkArea>, ZoneIndexSet> GetAppZoneHistoryInfo(HWND window, HMONITOR monitor, const std::unordered_map<HMONITOR, winrt::com_ptr<IWorkArea>>& workAreaMap) noexcept;
void MoveWindowIntoZone(HWND window, winrt::com_ptr<IWorkArea> workArea, const ZoneIndexSet& zoneIndexSet) noexcept;
bool MoveToAppLastZone(HWND window, HMONITOR active, HMONITOR primary) noexcept;
@@ -190,8 +183,7 @@ private:
std::vector<HMONITOR> GetMonitorsSorted() noexcept;
HMONITOR WorkAreaKeyFromWindow(HWND window) noexcept;
bool GetSystemTheme() const noexcept;
ZoneColors GetZoneColors() const noexcept;
virtual void SettingsUpdate(SettingId type) override;
const HINSTANCE m_hinstance{};
@@ -200,9 +192,6 @@ private:
MonitorWorkAreaHandler m_workAreaHandler;
VirtualDesktop m_virtualDesktop;
FileWatcher m_settingsFileWatcher;
winrt::com_ptr<IFancyZonesSettings> m_settings{};
GUID m_previousDesktopId{}; // UUID of previously active virtual desktop.
GUID m_currentDesktopId{}; // UUID of the current virtual desktop.
wil::unique_handle m_terminateEditorEvent; // Handle of FancyZonesEditor.exe we launch and wait on
@@ -231,8 +220,6 @@ private:
};
std::function<void()> FancyZones::disableModuleCallback = {};
COLORREF currentAccentColor;
COLORREF currentBackgroundColor;
// IFancyZones
IFACEMETHODIMP_(void)
@@ -253,11 +240,22 @@ FancyZones::Run() noexcept
return;
}
RegisterHotKey(m_window, static_cast<int>(HotkeyId::Editor), m_settings->GetSettings()->editorHotkey.get_modifiers(), m_settings->GetSettings()->editorHotkey.get_code());
if (m_settings->GetSettings()->windowSwitching)
if (!RegisterHotKey(m_window, static_cast<int>(HotkeyId::Editor), FancyZonesSettings::settings().editorHotkey.get_modifiers(), FancyZonesSettings::settings().editorHotkey.get_code()))
{
RegisterHotKey(m_window, static_cast<int>(HotkeyId::NextTab), m_settings->GetSettings()->nextTabHotkey.get_modifiers(), m_settings->GetSettings()->nextTabHotkey.get_code());
RegisterHotKey(m_window, static_cast<int>(HotkeyId::PrevTab), m_settings->GetSettings()->prevTabHotkey.get_modifiers(), m_settings->GetSettings()->prevTabHotkey.get_code());
Logger::error(L"Failed to register hotkey: {}", get_last_error_or_default(GetLastError()));
}
if (FancyZonesSettings::settings().windowSwitching)
{
if (!RegisterHotKey(m_window, static_cast<int>(HotkeyId::NextTab), FancyZonesSettings::settings().nextTabHotkey.get_modifiers(), FancyZonesSettings::settings().nextTabHotkey.get_code()))
{
Logger::error(L"Failed to register hotkey: {}", get_last_error_or_default(GetLastError()));
}
if (!RegisterHotKey(m_window, static_cast<int>(HotkeyId::PrevTab), FancyZonesSettings::settings().prevTabHotkey.get_modifiers(), FancyZonesSettings::settings().prevTabHotkey.get_code()))
{
Logger::error(L"Failed to register hotkey: {}", get_last_error_or_default(GetLastError()));
}
}
m_virtualDesktop.Init();
@@ -389,8 +387,8 @@ bool FancyZones::MoveToAppLastZone(HWND window, HMONITOR active, HMONITOR primar
void FancyZones::WindowCreated(HWND window) noexcept
{
const bool moveToAppLastZone = m_settings->GetSettings()->appLastZone_moveWindows;
const bool openOnActiveMonitor = m_settings->GetSettings()->openWindowOnActiveMonitor;
const bool moveToAppLastZone = FancyZonesSettings::settings().appLastZone_moveWindows;
const bool openOnActiveMonitor = FancyZonesSettings::settings().openWindowOnActiveMonitor;
if (!moveToAppLastZone && !openOnActiveMonitor)
{
// Nothing to do here then.
@@ -407,7 +405,7 @@ void FancyZones::WindowCreated(HWND window) noexcept
// Avoid processing splash screens, already stamped (zoned) windows, or those windows
// that belong to excluded applications list.
const bool isSplashScreen = FancyZonesUtils::IsSplashScreen(window);
const bool isSplashScreen = FancyZonesWindowUtils::IsSplashScreen(window);
if (isSplashScreen)
{
return;
@@ -419,13 +417,13 @@ void FancyZones::WindowCreated(HWND window) noexcept
return;
}
const bool isZoned = reinterpret_cast<ZoneIndex>(::GetProp(window, ZonedWindowProperties::PropertyMultipleZoneID)) != 0;
const bool isZoned = !FancyZonesWindowProperties::RetrieveZoneIndexProperty(window).empty();
if (isZoned)
{
return;
}
const bool isCandidateForLastKnownZone = FancyZonesUtils::IsCandidateForZoning(window, m_settings->GetSettings()->excludedAppsArray);
const bool isCandidateForLastKnownZone = FancyZonesWindowUtils::IsCandidateForZoning(window);
if (!isCandidateForLastKnownZone)
{
return;
@@ -477,7 +475,7 @@ FancyZones::OnKeyDown(PKBDLLHOOKSTRUCT info) noexcept
}
}
if (m_settings->GetSettings()->quickLayoutSwitch)
if (FancyZonesSettings::settings().quickLayoutSwitch)
{
int digitPressed = -1;
if ('0' <= info->vkCode && info->vkCode <= '9')
@@ -526,7 +524,7 @@ void FancyZones::ToggleEditor() noexcept
HMONITOR targetMonitor{};
const bool use_cursorpos_editor_startupscreen = m_settings->GetSettings()->use_cursorpos_editor_startupscreen;
const bool use_cursorpos_editor_startupscreen = FancyZonesSettings::settings().use_cursorpos_editor_startupscreen;
if (use_cursorpos_editor_startupscreen)
{
POINT currentCursorPos{};
@@ -569,7 +567,7 @@ void FancyZones::ToggleEditor() noexcept
std::wstring params;
const std::wstring divider = L"/";
params += std::to_wstring(GetCurrentProcessId()) + divider; /* Process id */
const bool spanZonesAcrossMonitors = m_settings->GetSettings()->spanZonesAcrossMonitors;
const bool spanZonesAcrossMonitors = FancyZonesSettings::settings().spanZonesAcrossMonitors;
params += std::to_wstring(spanZonesAcrossMonitors) + divider; /* Span zones */
std::vector<std::pair<HMONITOR, MONITORINFOEX>> allMonitors;
@@ -794,7 +792,7 @@ LRESULT FancyZones::WndProc(HWND window, UINT message, WPARAM wparam, LPARAM lpa
}
else if (message == WM_PRIV_SETTINGS_CHANGED)
{
OnSettingsChanged();
FancyZonesSettings::instance().LoadSettings();
}
else
{
@@ -845,7 +843,7 @@ void FancyZones::OnDisplayChange(DisplayChangeType changeType) noexcept
if ((changeType == DisplayChangeType::WorkArea) || (changeType == DisplayChangeType::DisplayChange))
{
if (m_settings->GetSettings()->displayChange_moveWindows)
if (FancyZonesSettings::settings().displayChange_moveWindows)
{
UpdateWindowsPositions();
}
@@ -895,7 +893,7 @@ void FancyZones::AddWorkArea(HMONITOR monitor, const std::wstring& deviceId) noe
parentId = parentArea->UniqueId();
}
auto workArea = MakeWorkArea(m_hinstance, monitor, uniqueId, parentId, GetZoneColors(), m_settings->GetSettings()->overlappingZonesAlgorithm, m_settings->GetSettings()->showZoneNumber);
auto workArea = MakeWorkArea(m_hinstance, monitor, uniqueId, parentId);
if (workArea)
{
m_workAreaHandler.AddWorkArea(m_currentDesktopId, monitor, workArea);
@@ -920,7 +918,7 @@ LRESULT CALLBACK FancyZones::s_WndProc(HWND window, UINT message, WPARAM wparam,
void FancyZones::UpdateWorkAreas() noexcept
{
if (m_settings->GetSettings()->spanZonesAcrossMonitors)
if (FancyZonesSettings::settings().spanZonesAcrossMonitors)
{
AddWorkArea(nullptr, {});
}
@@ -957,7 +955,7 @@ void FancyZones::UpdateWindowsPositions(bool suppressMove) noexcept
{
for (const auto [window, desktopId] : m_virtualDesktop.GetWindowsRelatedToDesktops())
{
auto zoneIndexSet = GetZoneIndexSet(window);
auto zoneIndexSet = FancyZonesWindowProperties::RetrieveZoneIndexProperty(window);
auto workArea = m_workAreaHandler.GetWorkArea(window, desktopId);
if (workArea)
{
@@ -984,7 +982,7 @@ bool FancyZones::OnSnapHotkeyBasedOnZoneNumber(HWND window, DWORD vkCode) noexce
HMONITOR current = WorkAreaKeyFromWindow(window);
std::vector<HMONITOR> monitorInfo = GetMonitorsSorted();
if (current && monitorInfo.size() > 1 && m_settings->GetSettings()->moveWindowAcrossMonitors)
if (current && monitorInfo.size() > 1 && FancyZonesSettings::settings().moveWindowAcrossMonitors)
{
// Multi monitor environment.
auto currMonitorInfo = std::find(std::begin(monitorInfo), std::end(monitorInfo), current);
@@ -1019,13 +1017,13 @@ bool FancyZones::OnSnapHotkeyBasedOnZoneNumber(HWND window, DWORD vkCode) noexce
{
auto workArea = m_workAreaHandler.GetWorkArea(m_currentDesktopId, current);
// Single monitor environment, or combined multi-monitor environment.
if (m_settings->GetSettings()->restoreSize)
if (FancyZonesSettings::settings().restoreSize)
{
bool moved = m_windowMoveHandler.MoveWindowIntoZoneByDirectionAndIndex(window, vkCode, false /* cycle through zones */, workArea);
if (!moved)
{
FancyZonesUtils::RestoreWindowOrigin(window);
FancyZonesUtils::RestoreWindowSize(window);
FancyZonesWindowUtils::RestoreWindowOrigin(window);
FancyZonesWindowUtils::RestoreWindowSize(window);
}
else
{
@@ -1053,7 +1051,7 @@ bool FancyZones::OnSnapHotkeyBasedOnPosition(HWND window, DWORD vkCode) noexcept
auto allMonitors = FancyZonesUtils::GetAllMonitorRects<&MONITORINFOEX::rcWork>();
if (current && allMonitors.size() > 1 && m_settings->GetSettings()->moveWindowAcrossMonitors)
if (current && allMonitors.size() > 1 && FancyZonesSettings::settings().moveWindowAcrossMonitors)
{
// Multi monitor environment.
// First, try to stay on the same monitor
@@ -1179,7 +1177,7 @@ bool FancyZones::OnSnapHotkey(DWORD vkCode) noexcept
{
// We already checked in ShouldProcessSnapHotkey whether the foreground window is a candidate for zoning
auto window = GetForegroundWindow();
if (m_settings->GetSettings()->moveWindowsBasedOnPosition)
if (FancyZonesSettings::settings().moveWindowsBasedOnPosition)
{
return OnSnapHotkeyBasedOnPosition(window, vkCode);
}
@@ -1231,6 +1229,11 @@ void FancyZones::RegisterVirtualDesktopUpdates() noexcept
void FancyZones::UpdateHotkey(int hotkeyId, const PowerToysSettings::HotkeyObject& hotkeyObject, bool enable) noexcept
{
if (!m_window)
{
return;
}
UnregisterHotKey(m_window, hotkeyId);
if (!enable)
@@ -1248,28 +1251,34 @@ void FancyZones::UpdateHotkey(int hotkeyId, const PowerToysSettings::HotkeyObjec
}
}
void FancyZones::OnSettingsChanged() noexcept
void FancyZones::SettingsUpdate(SettingId id)
{
_TRACER_;
m_settings->ReloadSettings();
// Update the hotkeys
UpdateHotkey(static_cast<int>(HotkeyId::Editor), m_settings->GetSettings()->editorHotkey, true);
auto windowSwitching = m_settings->GetSettings()->windowSwitching;
UpdateHotkey(static_cast<int>(HotkeyId::NextTab), m_settings->GetSettings()->nextTabHotkey, windowSwitching);
UpdateHotkey(static_cast<int>(HotkeyId::PrevTab), m_settings->GetSettings()->prevTabHotkey, windowSwitching);
// Needed if we toggled spanZonesAcrossMonitors
m_workAreaHandler.Clear();
// update zone colors
m_workAreaHandler.UpdateZoneColors(GetZoneColors());
// update overlapping algorithm
m_workAreaHandler.UpdateOverlappingAlgorithm(m_settings->GetSettings()->overlappingZonesAlgorithm);
PostMessageW(m_window, WM_PRIV_VD_INIT, NULL, NULL);
switch (id)
{
case SettingId::EditorHotkey:
{
UpdateHotkey(static_cast<int>(HotkeyId::Editor), FancyZonesSettings::settings().editorHotkey, true);
}
break;
case SettingId::PrevTabHotkey:
{
UpdateHotkey(static_cast<int>(HotkeyId::PrevTab), FancyZonesSettings::settings().prevTabHotkey, FancyZonesSettings::settings().windowSwitching);
}
break;
case SettingId::NextTabHotkey:
{
UpdateHotkey(static_cast<int>(HotkeyId::NextTab), FancyZonesSettings::settings().nextTabHotkey, FancyZonesSettings::settings().windowSwitching);
}
break;
case SettingId::SpanZonesAcrossMonitors:
{
m_workAreaHandler.Clear();
PostMessageW(m_window, WM_PRIV_VD_INIT, NULL, NULL);
}
break;
default:
break;
}
}
void FancyZones::OnEditorExitEvent() noexcept
@@ -1287,14 +1296,14 @@ void FancyZones::UpdateZoneSets() noexcept
workArea->UpdateActiveZoneSet();
}
auto moveWindows = m_settings->GetSettings()->zoneSetChange_moveWindows;
auto moveWindows = FancyZonesSettings::settings().zoneSetChange_moveWindows;
UpdateWindowsPositions(!moveWindows);
}
bool FancyZones::ShouldProcessSnapHotkey(DWORD vkCode) noexcept
{
auto window = GetForegroundWindow();
if (m_settings->GetSettings()->overrideSnapHotkeys && FancyZonesUtils::IsCandidateForZoning(window, m_settings->GetSettings()->excludedAppsArray))
if (FancyZonesSettings::settings().overrideSnapHotkeys && FancyZonesWindowUtils::IsCandidateForZoning(window))
{
HMONITOR monitor = WorkAreaKeyFromWindow(window);
@@ -1303,7 +1312,7 @@ bool FancyZones::ShouldProcessSnapHotkey(DWORD vkCode) noexcept
{
if (vkCode == VK_UP || vkCode == VK_DOWN)
{
return m_settings->GetSettings()->moveWindowsBasedOnPosition;
return FancyZonesSettings::settings().moveWindowsBasedOnPosition;
}
else
{
@@ -1329,16 +1338,8 @@ void FancyZones::ApplyQuickLayout(int key) noexcept
return;
}
auto uuidStr = FancyZonesUtils::GuidToString(layoutId.value());
if (!uuidStr)
{
return;
}
FancyZonesDataTypes::ZoneSetData data{ .uuid = uuidStr.value(), .type = FancyZonesDataTypes::ZoneSetLayoutType::Custom };
auto workArea = m_workAreaHandler.GetWorkAreaFromCursor(m_currentDesktopId);
AppliedLayouts::instance().ApplyLayout(workArea->UniqueId(), data);
AppliedLayouts::instance().ApplyLayout(workArea->UniqueId(), layout.value());
AppliedLayouts::instance().SaveData();
UpdateZoneSets();
FlashZones();
@@ -1346,7 +1347,7 @@ void FancyZones::ApplyQuickLayout(int key) noexcept
void FancyZones::FlashZones() noexcept
{
if (m_settings->GetSettings()->flashZonesOnQuickSwitch && !m_windowMoveHandler.IsDragEnabled())
if (FancyZonesSettings::settings().flashZonesOnQuickSwitch && !m_windowMoveHandler.IsDragEnabled())
{
for (auto [monitor, workArea] : m_workAreaHandler.GetWorkAreasByDesktopId(m_currentDesktopId))
{
@@ -1385,7 +1386,7 @@ std::vector<std::pair<HMONITOR, RECT>> FancyZones::GetRawMonitorData() noexcept
HMONITOR FancyZones::WorkAreaKeyFromWindow(HWND window) noexcept
{
if (m_settings->GetSettings()->spanZonesAcrossMonitors)
if (FancyZonesSettings::settings().spanZonesAcrossMonitors)
{
return NULL;
}
@@ -1395,61 +1396,7 @@ HMONITOR FancyZones::WorkAreaKeyFromWindow(HWND window) noexcept
}
}
bool FancyZones::GetSystemTheme() const noexcept
winrt::com_ptr<IFancyZones> MakeFancyZones(HINSTANCE hinstance, std::function<void()> disableCallback) noexcept
{
winrt::Windows::UI::ViewManagement::UISettings settings;
auto accentValue = settings.GetColorValue(winrt::Windows::UI::ViewManagement::UIColorType::Accent);
auto accentColor = RGB(accentValue.R, accentValue.G, accentValue.B);
auto backgroundValue = settings.GetColorValue(winrt::Windows::UI::ViewManagement::UIColorType::Background);
auto backgroundColor = RGB(backgroundValue.R, backgroundValue.G, backgroundValue.B);
if (currentAccentColor != accentColor || currentBackgroundColor != backgroundColor)
{
currentAccentColor = accentColor;
currentBackgroundColor = backgroundColor;
return true;
}
return false;
}
ZoneColors FancyZones::GetZoneColors() const noexcept
{
if (m_settings->GetSettings()->systemTheme)
{
GetSystemTheme();
auto numberColor = currentBackgroundColor == RGB(0, 0, 0) ? RGB(255, 255, 255) : RGB(0, 0, 0);
return ZoneColors{
.primaryColor = currentBackgroundColor,
.borderColor = currentAccentColor,
.highlightColor = currentAccentColor,
.numberColor = numberColor,
.highlightOpacity = m_settings->GetSettings()->zoneHighlightOpacity
};
}
else
{
return ZoneColors{
.primaryColor = FancyZonesUtils::HexToRGB(m_settings->GetSettings()->zoneColor),
.borderColor = FancyZonesUtils::HexToRGB(m_settings->GetSettings()->zoneBorderColor),
.highlightColor = FancyZonesUtils::HexToRGB(m_settings->GetSettings()->zoneHighlightColor),
.numberColor = FancyZonesUtils::HexToRGB(m_settings->GetSettings()->zoneNumberColor),
.highlightOpacity = m_settings->GetSettings()->zoneHighlightOpacity
};
}
}
winrt::com_ptr<IFancyZones> MakeFancyZones(HINSTANCE hinstance,
const winrt::com_ptr<IFancyZonesSettings>& settings,
std::function<void()> disableCallback) noexcept
{
if (!settings)
{
return nullptr;
}
return winrt::make_self<FancyZones>(hinstance, settings, disableCallback);
return winrt::make_self<FancyZones>(hinstance, disableCallback);
}

View File

@@ -52,4 +52,4 @@ interface __declspec(uuid("{2CB37E8F-87E6-4AEC-B4B2-E0FDC873343F}")) IFancyZones
(PKBDLLHOOKSTRUCT info) = 0;
};
winrt::com_ptr<IFancyZones> MakeFancyZones(HINSTANCE hinstance, const winrt::com_ptr<IFancyZonesSettings>& settings, std::function<void()> disableCallback) noexcept;
winrt::com_ptr<IFancyZones> MakeFancyZones(HINSTANCE hinstance, std::function<void()> disableCallback) noexcept;

View File

@@ -164,11 +164,11 @@ bool AppZoneHistory::RemoveAppLastZone(HWND window, const FancyZonesDataTypes::D
}
// if there is another instance of same application placed in the same zone don't erase history
ZoneIndex windowZoneStamp = reinterpret_cast<ZoneIndex>(::GetProp(window, ZonedWindowProperties::PropertyMultipleZoneID));
auto windowZoneStamps = FancyZonesWindowProperties::RetrieveZoneIndexProperty(window);
for (auto placedWindow : data->processIdToHandleMap)
{
ZoneIndex placedWindowZoneStamp = reinterpret_cast<ZoneIndex>(::GetProp(placedWindow.second, ZonedWindowProperties::PropertyMultipleZoneID));
if (IsWindow(placedWindow.second) && (windowZoneStamp == placedWindowZoneStamp))
auto placedWindowZoneStamps = FancyZonesWindowProperties::RetrieveZoneIndexProperty(placedWindow.second);
if (IsWindow(placedWindow.second) && (windowZoneStamps == placedWindowZoneStamps))
{
return false;
}

View File

@@ -7,7 +7,6 @@
#include <FancyZonesLib/GuidUtils.h>
#include <FancyZonesLib/FancyZonesData/CustomLayouts.h>
#include <FancyZonesLib/FancyZonesData/LayoutDefaults.h>
#include <FancyZonesLib/FancyZonesData/LayoutTemplates.h>
#include <FancyZonesLib/FancyZonesWinHookEventIDs.h>
#include <FancyZonesLib/JsonHelpers.h>
#include <FancyZonesLib/util.h>
@@ -320,59 +319,9 @@ bool AppliedLayouts::IsLayoutApplied(const FancyZonesDataTypes::DeviceIdData& id
return iter != m_layouts.end();
}
bool AppliedLayouts::ApplyLayout(const FancyZonesDataTypes::DeviceIdData& deviceId, const FancyZonesDataTypes::ZoneSetData& layout)
bool AppliedLayouts::ApplyLayout(const FancyZonesDataTypes::DeviceIdData& deviceId, Layout layout)
{
auto uuid = FancyZonesUtils::GuidFromString(layout.uuid);
if (!uuid)
{
return false;
}
Layout layoutToApply {
.uuid = uuid.value(),
.type = layout.type,
.showSpacing = DefaultValues::ShowSpacing,
.spacing = DefaultValues::Spacing,
.zoneCount = DefaultValues::ZoneCount,
.sensitivityRadius = DefaultValues::SensitivityRadius,
};
// copy layouts properties to the applied-layout
auto customLayout = CustomLayouts::instance().GetLayout(layoutToApply.uuid);
if (customLayout)
{
if (customLayout.value().type == FancyZonesDataTypes::CustomLayoutType::Grid)
{
auto layoutInfo = std::get<FancyZonesDataTypes::GridLayoutInfo>(customLayout.value().info);
layoutToApply.sensitivityRadius = layoutInfo.sensitivityRadius();
layoutToApply.showSpacing = layoutInfo.showSpacing();
layoutToApply.spacing = layoutInfo.spacing();
layoutToApply.zoneCount = layoutInfo.zoneCount();
}
else if (customLayout.value().type == FancyZonesDataTypes::CustomLayoutType::Canvas)
{
auto layoutInfo = std::get<FancyZonesDataTypes::CanvasLayoutInfo>(customLayout.value().info);
layoutToApply.sensitivityRadius = layoutInfo.sensitivityRadius;
layoutToApply.zoneCount = (int)layoutInfo.zones.size();
}
}
else
{
// check templates only if it wasn't a custom layout, since templates don't have ids yet
auto templateLayout = LayoutTemplates::instance().GetLayout(layout.type);
if (templateLayout)
{
auto layoutInfo = templateLayout.value();
layoutToApply.sensitivityRadius = layoutInfo.sensitivityRadius;
layoutToApply.showSpacing = layoutInfo.showSpacing;
layoutToApply.spacing = layoutInfo.spacing;
layoutToApply.zoneCount = layoutInfo.zoneCount;
}
}
m_layouts[deviceId] = std::move(layoutToApply);
m_layouts[deviceId] = std::move(layout);
return true;
}

View File

@@ -54,7 +54,7 @@ public:
bool IsLayoutApplied(const FancyZonesDataTypes::DeviceIdData& id) const noexcept;
bool ApplyLayout(const FancyZonesDataTypes::DeviceIdData& deviceId, const FancyZonesDataTypes::ZoneSetData& layout);
bool ApplyLayout(const FancyZonesDataTypes::DeviceIdData& deviceId, Layout layout);
bool ApplyDefaultLayout(const FancyZonesDataTypes::DeviceIdData& deviceId);
bool CloneLayout(const FancyZonesDataTypes::DeviceIdData& srcId, const FancyZonesDataTypes::DeviceIdData& dstId);

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