Compare commits

...

181 Commits

Author SHA1 Message Date
Davide Giacometti
bd5af79237 [PTRun][Terminal] additional logging (#17570) 2022-04-07 11:25:31 +01:00
Seraphima Zykova
75e966ce19 [FancyZones] Restore window size fix (#17553) 2022-04-06 17:33:02 +01:00
Jaime Bernardo
a09d8bf14b [FancyZones]Fix rounded corners optimized bug (#17560)
* [FancyZones]Fix rounded corners optimized bug

* Use proper flags

* Use WideChar version of functions
2022-04-06 15:54:11 +01:00
Jaime Bernardo
d5a5f858c0 [DevFilesPreview]Fix not created settings crash (#17541) 2022-04-05 16:47:41 +01:00
Jaime Bernardo
2cf354ff28 [Installer]Upgrade .net framework to 3.1.23 (#17537) 2022-04-05 15:03:10 +01:00
Jaime Bernardo
3ea0a10c73 [FZEditor] Improve narrator support on Grid Editor (#17532)
* [FZEditor]Add narrator info to thumb buttons

* [FZEditor]Narrator information about the zones

* [FZEditor]Allow text to be focused for narrator

* Address PR feedback
2022-04-05 13:22:17 +01:00
Jaime Bernardo
6f50a38e5f [PTRun][Program]List special empty shortcuts (#17517) 2022-04-05 11:17:48 +01:00
Dustin L. Howett
1fc7a59b7c Make sure the final WiX bundle contains a *signed* MSI (#17446)
* Make sure the *signed* MSI makes it into the bundle

* And don't let Bootstrapper force-build MSI

* Revert "And don't let Bootstrapper force-build MSI"

This reverts commit 77cea11008.

* try this wacky hacky sacky thing

* Revert "Revert "And don't let Bootstrapper force-build MSI""

This reverts commit 7d25009932.

* Revert "try this wacky hacky sacky thing"

This reverts commit 0fea6df635.

* ah the things i hate
2022-04-05 09:58:03 +01:00
Seraphima Zykova
c7e0850b7b [FancyZones]Remove check if window already snapped (#17512) 2022-04-04 16:24:52 +01:00
Heiko
fd01ee391b [PTRun][System]Fix delay on many net interfaces (#17490)
* code changes

* small text fixes

* update docs

* comment improvements

* update tests

* fix typo

* change

* fix typo

* fix error msg

* fix bug

* second fix
2022-04-04 12:47:58 +01:00
ricardosantos9521
44165621f0 [PTRun][VSCode] Workspaces not showing up after update or first installation (#17279) 2022-04-04 12:06:45 +01:00
Heiko
686a48a29b [PTRun][WindowWalker]fix handle not existing registry path (#17471) 2022-04-04 10:40:04 +01:00
Heiko
e444881320 [PT Run] Run as user feature (#17283)
* run as different user

* fix tests

* Update src/modules/launcher/Plugins/Microsoft.Plugin.Shell/Main.cs

* fix typo
2022-04-04 10:37:08 +01:00
Jaime Bernardo
12282a8dc7 [Updater]Use sensible default time between checks (#17318) 2022-04-01 17:44:49 +01:00
Seraphima Zykova
95dcbb1891 [FancyZones] Restore original corners and setting(#17425)
* fix corners

* save corner preference

* added fz setting

* add option to settings

* return original preference despite the setting

* removed reset to default corner preference
2022-04-01 17:28:19 +01:00
Jaime Bernardo
04588bc7e0 [PTRun][Settings][Program] Fix 100% CPU load issue (#17414)
* [PTRun][Program]Don't reload on settings change

* [PTRun][Settings] Don't trigger saves on visual property changes

* [PTRun][Settings] Fix manipulation of searched plugins

* [PTRun][Settings] Don't reload settings if we wrote recently

* fix PR comments nit
2022-04-01 14:50:16 +01:00
Seraphima Zykova
172c63f1e2 [AOT] Fix for topmost resetting (#17392) 2022-04-01 13:15:47 +01:00
Jaime Bernardo
b5622cd07a 0.57 changelog (#17342)
* 0.57 changelog

* fix spellchecker

* fix spellchecker

* fix new line

* Update README.md

Co-authored-by: Heiko <61519853+htcfreek@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Heiko <61519853+htcfreek@users.noreply.github.com>

* Address review comments

* Add mention to docs update

* Address PR comments

* Update README.md

Co-authored-by: Heiko <61519853+htcfreek@users.noreply.github.com>

* Update README.md

Co-authored-by: Franky Chen <franky@frankychen.net>

* Update README.md

Co-authored-by: Franky Chen <franky@frankychen.net>

* Update README.md

Co-authored-by: Franky Chen <franky@frankychen.net>

* Update README.md

Co-authored-by: Jay <65828559+Jay-o-Way@users.noreply.github.com>

* Update README.md

Co-authored-by: Jay <65828559+Jay-o-Way@users.noreply.github.com>

* Update README.md

Co-authored-by: Jay <65828559+Jay-o-Way@users.noreply.github.com>

* Update README.md

Co-authored-by: Jay <65828559+Jay-o-Way@users.noreply.github.com>

* Update README.md

Co-authored-by: Jay <65828559+Jay-o-Way@users.noreply.github.com>

* Update README.md

Co-authored-by: Jay <65828559+Jay-o-Way@users.noreply.github.com>

* Address feedback.

Co-authored-by: Heiko <61519853+htcfreek@users.noreply.github.com>
Co-authored-by: Franky Chen <franky@frankychen.net>
Co-authored-by: Jay <65828559+Jay-o-Way@users.noreply.github.com>
2022-03-30 10:56:41 -07:00
Jaime Bernardo
ba73bc7d50 [Installer]Don't enable pdf preview by default (#17274)
* [Installer]Don't enable pdf preview by default

* Change settings UI when there's no settings as well

* clear analyzer errors
2022-03-25 21:01:09 +00:00
Jaime Bernardo
bdbf0b8c14 [FileExplorer]Add warnings for incompatibilities (#17273) 2022-03-25 20:16:11 +00:00
Aaron Junker
79227b9db6 [Dev file preview]Add wrap text setting (#16486)
* Push (not working)

* Add Context menu

* push

* Adress feedback

* Update installer

* Fix build

* Fix warnings
2022-03-25 17:29:33 +00:00
Seraphima Zykova
4aadaf9bf1 [FancyZones] Fix canvas layout with scaling reset issue (#17186)
* canvas scaling

* predef layout check

* return false on custom layout error

* clean up

* update unit tests

* spelling

* floating point convert

* fix build
2022-03-25 16:09:59 +00:00
Jaime Bernardo
403969587e [PTRun][Program]Add logs on launch failure (#17270) 2022-03-25 15:30:06 +00:00
Jaime Bernardo
1be880438a [ColorPicker]Use Hotkey when started from runner (#17265)
* [ColorPicker]Use Hotkey when started from runner

* fix spellchecker
2022-03-25 13:40:33 +00:00
Jaime Bernardo
80e9fc0c43 [PTRun][Program]Fix bug when renaming url shortcut (#17184)
* [PTRun][Program]Fix bug when renaming url shortcut

* Try to use the old full path for old app removal

* Guard against links to nowhere

* Fix test to have link point to existing location

* Update src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/Win32Program.cs

Co-authored-by: Heiko <61519853+htcfreek@users.noreply.github.com>

* Fix nit.

Co-authored-by: Heiko <61519853+htcfreek@users.noreply.github.com>
2022-03-25 10:08:10 +00:00
Jaime Bernardo
559a0442d8 [SvgThumbnail]Register as a picture kind (#17080) 2022-03-25 10:05:37 +00:00
Andrey Nekrasov
724620a24e [Runner]Fix elevation issues due to syncing settings with scheduler state (#17254) 2022-03-25 10:04:29 +00:00
Jaime Bernardo
75f2be1891 [PTRun][Calculator]Fix trailing zeroes on hexadecimal numbers (#17248)
* [PTRun][Calculator]Fix hexadecimal trailing 0s

* Add tests
2022-03-24 16:59:27 +00:00
Jaime Bernardo
aba4e462a8 [Updater]Pass flag to not restart automatically (#17255) 2022-03-24 16:53:31 +00:00
CleanCodeDeveloper
58aa274b21 [Launcher Plugins] Move shared keys into central props file (#17214)
* [Launcher Plugins] Move shared keys into central props file

* fixes

* TreatWarningsAsErrors is set to true now. This caused a few errors to pop up
2022-03-23 16:35:52 +00:00
CleanCodeDeveloper
d9c054b1f5 [Settings] Move shared keys into central props file (#17188) 2022-03-23 16:32:34 +00:00
CleanCodeDeveloper
53a92215fc [preview pane] Move shared keys into central props file (#17212)
* [preview pane] Move shared keys into central props file

* left overs
2022-03-23 16:31:51 +00:00
Den Delimarsky
d7617a47d3 [Awake] Context menu bug fixes (#16903)
* Fix the path to the icon

* Need the reverse when not working in isolation

* Updating some tray behaviors

* Making sure we have constants separately, and a filter

* Update tray logic

* Remove unnecessary menus

* Cleaning up how exit is done.

* Adding handling for tray commands

* Update with settings for dynamic times

* Proper reaction to timed keep-awake from the tray

* Proper handling for timed keep-awake from the tray

* Making sure that code analysis works correctly

* Making sure that errors are set in native calls

* Making sure the right icon path is used after testing

* Proper disposal of the context menu

* Fix tray designation

* Update with latest information on changes to the builds

* Update with guidance on files

* Update changelog doc

* Fix project file

* Remove `VTABLE`
2022-03-23 14:46:37 +00:00
CleanCodeDeveloper
ada3a9ad88 [Wox] Move shared keys into central props file (#17193) 2022-03-22 16:31:40 +00:00
CleanCodeDeveloper
c22a3fbcb7 [Awake] Move shared keys into central props file (#17189) 2022-03-22 16:31:07 +00:00
CleanCodeDeveloper
9c9b5d9dca [Color picker] Move shared keys into central props file (#17190) 2022-03-22 16:30:45 +00:00
CleanCodeDeveloper
dd03d1ee63 [Fancy zones] Move shared keys into central props file (#17191) 2022-03-22 16:30:07 +00:00
CleanCodeDeveloper
ae196fd592 [PowerLauncher] Move shared keys into central props file (#17192) 2022-03-22 16:29:42 +00:00
Heiko
b3a0bf7919 [PTRun][Settings] Additional settings (#17170) 2022-03-22 12:12:21 +00:00
Heiko
58b219f671 [PTRun][Settings]explain ip/mac setting in description(#17195) 2022-03-22 11:40:23 +00:00
Heiko
889bc1e514 [PT Run] Folder plugin: Improvements for the results (#16867)
* Improvements

* fix spelling

* text improvement

* fix build

* update tipp text
2022-03-22 11:07:09 +00:00
Jaime Bernardo
fcc1d46b63 [PTRun]Fix focus glitch on first time run (#17128) 2022-03-21 16:18:45 +00:00
CleanCodeDeveloper
1d15070698 [Common] Move shared keys into central props file (#17131)
* [Common] Move shared keys into central props file

* Add PackageTags prop
2022-03-21 12:48:52 +00:00
Heiko
380add882c [Settings] Run Plugin additional options: description (#17108)
* last changes

* update ww settings

* feedbvack and TimeDate plugin

* Add property description
2022-03-21 12:47:09 +00:00
Heiko
4c067bb728 [PT Run] System plugin: Add IP and MAC (#17023)
* first test and changes

* last changes

* last changes

* last changes

* improve exception

* fix spellings

* spell fixes

* search improvements, installer, tests, code cleanup

* remove left-over

* update dev docs

* fix spelling

* update namings

* improve scoring

* spell checker

* dev docs

* update images

* update expect.txt for this pr
2022-03-21 12:37:51 +00:00
Star Brilliant
42ba008323 [ColorPicker] Increase precision of CIEXYZ format (#17041)
* Increase precision of CIEXYZ conversion matrix

The output has 4 decimal places, so the conversion matrix should be more than 6 digits to avoid round-off errors.

* Match unit tests and docs with new CIEXYZ conversion matrix

* Remove negative sign from zeros

I generated the unit test results from other color-management systems.
It seems that they sometimes output negative zeros for very small values.
Let's just remove the negative signs for aesthetic.

* Fix spelling mistakes in ColorConverterTest.cs

* Explain how to obtain CIEXYZ unit test reference values

* Explain the CIELAB output is D65 adapted version

* Add words related to CIEXYZ conversion to spellcheck bypass list
2022-03-21 12:15:48 +00:00
Jaime Bernardo
b7d528b6e8 [MouseCrosshairs]Fix odd thickness offset (#17091) 2022-03-21 11:37:24 +00:00
Andrey Nekrasov
176f2c2870 [VCM] Track newly added microphones (#16199)
* [VCM] Track newly added microphones when [All] is selected in the settings

* [VCM] handle case when no mics are left

* fixup: fix crashes onNotify

* fixup: fix build
2022-03-21 09:48:11 +00:00
CleanCodeDeveloper
2e3a2b3f96 [meta]common csproj/vcxproj settings to Directory.Build.props (#17067)
* Add common csproj/vcxproj settings to Directory.Build.props

* Set TreatWarningsAsErrors to true for all c# projects

* Minor fixes in unit test projects where Analyzers where not enabled before

* Clean up Directory.Build.props

* Remove properties from ImageResizer csprojs files
2022-03-18 16:47:18 +00:00
Stefan Markovic
f4f8a1bd69 Fix Checking for Updates - running indefinitely (#17084) 2022-03-18 10:26:29 +01:00
Heiko
34e4e7e5bd [PT Run] TimeDate plugin (#16662)
* create plugin

* Update plugin code

* fix deps

* last changes

* unix

* new results and small changes

* Update settings name

* make spellcheck happy

* new time/date formats

* add comment

* code cleanup, installer, signing pipeline

* fix unix result

* UnitTests

* spell fix

* Update tests, Timestamp query feature

* new formats

* last changes

* last changes

* unit tests and fixes

* cjhanges and fixes

* fix installer

* fix settings class init

* context menu

* fix tests

* add settings tests

* update/fix DateTimeResult tests

* small improvements

* update pipeline

* enable analyzer

* fixes and improvements

* spell fix

* dev docs

* doc fixes

* spell fix

* last changes

* changes and fixes

* fixes and test updates

* improvements

* last changes

* try to fix tests

* remove obsolete code

* add info to test log

* fix search

* tag fix

* tests

* change tests

* update dev docs

* fix spelling

* fix culture for ui strings

* improvements based on feedback

* improve global search

* improve text

* docs improvement

* add settings note

* fix and update tests

* fix spelling
2022-03-17 19:33:05 +00:00
Jaime Bernardo
5914fc1ffd [MouseUtils]Workaround taskbar transparency glitch (#17085) 2022-03-17 17:25:15 +00:00
Josh Soref
bad435bb26 [spellcheck]Spelling cleanup (#17099)
Co-authored-by: Josh Soref <jsoref@users.noreply.github.com>
2022-03-17 17:19:16 +00:00
Andrey Nekrasov
41f4d971dd [Setup] Use custom prefix for WiX bootstrapper logs and collect them via BugReportTool (#17062) 2022-03-16 11:39:00 +00:00
Stefan Markovic
79d4782b23 [runner]Open settings only on tray icon double click (#17061) 2022-03-16 11:36:30 +00:00
Jaime Bernardo
cfdaea4363 [Installer]Upgrade .net framework to 6.0.3 (#17051)
* Revert "[PTRun]Workaround fix tooltip crash on .net 6 (#16629)"

This reverts commit b4250c1235.

* Upgrade .net framework to 6.0.3
2022-03-16 10:54:01 +00:00
CleanCodeDeveloper
d66fac3c3c [Run.Plugin.UnitConverter] Enable analyzer and fix warnings (#17002)
* [Run.Plugin.UnitConverter] Enable analyzer and fix warnings
2022-03-14 17:08:23 +00:00
CleanCodeDeveloper
66619ca059 [Plugin.Program] Enable analyzer and fix warnings (#17000) 2022-03-14 15:46:34 +00:00
CleanCodeDeveloper
79b2cdca7b [Run.Plugin.Calculator] Enable analyzer and fix warnings (#16998) 2022-03-14 15:46:08 +00:00
CleanCodeDeveloper
3e9c7f83c8 [Plugin.Folder] Enable analyzer and fix warnings (#16997) 2022-03-14 15:45:40 +00:00
CleanCodeDeveloper
561882c2f1 [Wox.Infrastructure] Enable analyzer and fix warnings (#16996) 2022-03-14 15:44:17 +00:00
CleanCodeDeveloper
7365ba14d0 [PreviewPane] Enable analyzer and fix warnings (#16995) 2022-03-14 15:42:32 +00:00
Heiko
bf3e427017 [PTRun][WindowWalker] Fixes and small improvements (#16959)
* fixes and changes

* fix spelling

* add os version check

* Improve speed of virtual desktop helper

* speed improvement two
2022-03-14 15:40:27 +00:00
lncubus
50169f9271 #16693 Unit Converter should recognize metre (#16984) 2022-03-14 10:17:09 +00:00
Jaime Bernardo
1f64c1cf83 [PTRun][Calculator]Always accept decimal point (#16980) 2022-03-11 17:26:29 +00:00
Franky Chen
6648402ddb [AOT] Change sound (#16865)
Co-authored-by: Hsuan-Li, Chen <franky@workspace.frankychen.net>
2022-03-11 16:45:44 +00:00
Seraphima Zykova
0816714782 [FancyZones]Additional logs (#16927) 2022-03-10 17:59:31 +00:00
Andrey Nekrasov
a8fb9e0804 [Settings] Do not try to apply profile settings if there was a timeout (#16933) 2022-03-10 17:31:16 +00:00
Jaime Bernardo
309a0661c3 [Installer]Enable Unit Converter plugin loc (#16960) 2022-03-10 17:23:01 +00:00
CleanCodeDeveloper
0d3aa3a187 [PTRun][WindowsSettings] Enable analyzer and fix warnings (#16942) 2022-03-10 16:00:28 +00:00
CleanCodeDeveloper
94391775c8 [PTRun][Registry] Enable analyzer and fix warnings (#16941) 2022-03-10 15:59:04 +00:00
Jaime Bernardo
b1b1f1ba21 [installer]Enable Web Search plugin localization (#16894) 2022-03-10 11:15:59 +00:00
CleanCodeDeveloper
ba525f068b [PTRun][VSCodeWorkspaces] Enable analyzer and fix warning (#16897)
* [Community.PowerToys.Run.Plugin.VSCodeWorkspaces] Enable analyzer and fix warnings

* fix CA1824: Mark assemblies with NeutralResourcesLanguageAttribute
2022-03-10 10:37:14 +00:00
CleanCodeDeveloper
ffdb5d44d7 [PTRun][WebSearch] Enable analyzer and fix warnings (#16938) 2022-03-10 10:35:49 +00:00
CleanCodeDeveloper
3b04cfd267 [PTRun][Uri] Enable analyzer and fix warnings (#16940) 2022-03-10 10:35:13 +00:00
Yifan Kang
462b48edae [PTRun][UnitConverter]Fix "feet" and "gal" (#16618)
* Update InputInterpreter.cs

* Update InputInterpreter.cs
2022-03-10 10:21:08 +00:00
skycommand
05d5649c9c [MonacoPreviewHandler][Settings] Resolve preview handler race (#16180)
* Register .markdown with the correct handler

* Fix spelling

* Move file name extensions from "expect.txt" to "excludes.txt"

* Revert "Move file name extensions from "expect.txt" to "excludes.txt""

This reverts commit 710d5a4968.
I must have misunderstood the instructions.

* Revert "Register .markdown with the correct handler"

This reverts commit 5c37b009f3.

* Work in progress

* Code ready for testing

* Update excludes.txt

* Update excludes.txt

* Update modulesRegistry.h

* Update modulesRegistry.h

For the want of an exclamation mark, a kingdom is lost!

* Update modulesRegistry.h

* Work on modulesRegistry.h per code review in 16180

Removed all previous exclusions from Monaco preview handler. Added a new exclusion: SVGZ. It's a binary file that Monaco cannot, in any meaningful way, read.

* Update expect.txt

* Update accessory files

* Disable machine-wide checks for performance reasons
2022-03-09 14:06:00 +00:00
Josh Soref
b415e79ef5 [spellcheck]Ignore .pipelines/ESRPSigning_core.json (#16907)
Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

Co-authored-by: Josh Soref <jsoref@users.noreply.github.com>
2022-03-09 12:52:53 +00:00
Josh Soref
477041a884 [spellcheck]Add Hash to patterns (#16906)
Co-authored-by: Josh Soref <jsoref@users.noreply.github.com>
2022-03-09 12:34:07 +00:00
CleanCodeDeveloper
425346b1f2 [Awake] Enable analyzer and fix warnings (#16899)
* [Awake] Enable analyzer and fix warnings

* Suppress "CA1051:Do not declare visible instance fields" for structs

* Revert "Suppress "CA1051:Do not declare visible instance fields" for structs"

This reverts commit bea215bffa.

* Suppress "CA1051:Do not declare visible instance fields" for structs

* spellchecker
2022-03-09 12:09:17 +00:00
CleanCodeDeveloper
46684966a1 [PowerLauncher] Enable analyzer and fix warnings (#16900) 2022-03-09 12:08:12 +00:00
Jaime Bernardo
eb961ee052 [PTRun][WindowWalker]Fix analyzer errors (#16887) 2022-03-08 18:23:45 +00:00
CleanCodeDeveloper
0a5bdf6734 [Microsoft.Plugin.WindowWalker] Enable analyzer and fix warnings (#16555) 2022-03-08 16:47:10 +00:00
CleanCodeDeveloper
ec3ea5c4ae [Wox.Plugin] Enable analyzer and fix warnings (#16547) 2022-03-08 16:46:36 +00:00
Niels Laute
9cf39654d9 [OOBE] Refactor UI code, minor UI tweaks (#16578)
* Move content to dedicated XAML

* Select modules enum

* Remove redundant code, UI fixes

* Markdown rendering tweaks

* Address feedback
2022-03-08 15:27:17 +00:00
Clint Rutkas
139c6c2c8d Update README.md 2022-03-07 10:16:43 -08:00
Tore Lervik
b20e991a35 [FancyZones] Set correct corner preference when snapping windows on Windows 11 (#16542)
* [FancyZones] Set correct corner preference when snapping windows on Windows 11

* Changed magic numbers to use enum values.

* Added missing words to spell check list.

* Changed note: to todo: for future visibility

* Changed note: to todo: for future visibility
2022-03-07 11:50:37 +00:00
mshtang
81f61630cb [Color Picker] remove and export multiple colors from history (#16475)
* Allow to export and delete multiple colors

* Allow to export and delete multiple colors
2022-03-07 11:47:42 +00:00
Heiko
e8363a3be1 [PT Run] VirtualDesktopHelper & WindowWalker improvements (#16325)
* Import vdh from poc

* last changes

* push changes

* small change

* add error handling to vdh

* last changes

* make spellchecker happy

* last changes

* last changes

* spell check

* fix settings defaults

* Improve WindowWalkerSettings class

* add comment

* New settings and improvements

* new features

* subtitle and tool tip

* spell fixes

* small fixes

* fixes

* Explorer info

* spell fixes

* fixes and CloseWindow feature

* last changes

* first part of implementing KillProcess

* killProcess Part 2 & Fixes

* text fix and installer

* update access modifiers

* some fixes

* update dev docs

* fix dev docs

* dev doc change

* dev docs: add missed infos

* dev docs: add link

* Update src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/WindowWalkerSettings.cs

* fix build

* resolve feedback

* fix settings

* add tests
2022-03-07 11:45:29 +00:00
Jaime Bernardo
27611593bd [ci]fix windows terminal loc build (#16788) 2022-03-04 20:24:20 +00:00
Jaime Bernardo
6b6ba2205c [Installer]Include PTRun WindowsTerminal loc (#16777)
* [Installer]Include PTRun WindowsTerminal loc

* Add languages folder reference
2022-03-04 16:56:11 +00:00
CleanCodeDeveloper
aa2c9390ef [ColorPicker] Enable analyzer and fix warnings (#16543)
* ColorPicker: Enable analyzer and fix warnings

* Suppress CA1711:Identifiers should not have incorrect suffix

Renaming everything would be a lot of work. It does not do any harm if an EventHandler delegate ends with the suffix EventHandler.
Besides this, the Rule causes some false postives

* CA1838:Avoid 'StringBuilder' parameters for P/Invokes

We are not concerned about the performance impact of marshaling a StringBuilder

* resolve pr comments
2022-03-04 15:06:51 +00:00
Jaime Bernardo
45f121b8bc [FindMyMouse]setting for minimum shake distance (#16756)
* [FindMyMouse]setting for minimum shake distance

* Group inside Activation method
2022-03-04 12:28:11 +00:00
Jaime Bernardo
400cd7ea45 [build]Fix PowerRename flaky build errors (#16728) 2022-03-04 12:17:05 +00:00
Aaron Junker
62c2f9479b Fixed file in use issue (#16748) 2022-03-04 10:16:43 +01:00
Seraphima Zykova
3a8218be44 [FancyZones] Template layout settings reset fix (#16628) 2022-03-04 08:12:25 +03:00
Franky Chen
5881469855 [Installer]Install dotnet with /norestart (#16691)
* Add norestart for dotnet

* Add norestart to spell-check

* Add quite back for dotnet
2022-03-03 10:09:47 +00:00
CleanCodeDeveloper
4e662f61c3 [Telemetry] fix analyzer warnings (#16545) 2022-03-02 19:24:04 +00:00
CleanCodeDeveloper
efd14d8611 [Microsoft.Plugin.Indexer] Enable analyzer and fix warnings (#16544) 2022-03-02 19:19:49 +00:00
Clint Rutkas
57bc924d8d Update ci.yml 2022-03-02 10:47:05 -08:00
Clint Rutkas
3715b0c378 Update ci.yml 2022-03-02 10:37:35 -08:00
Clint Rutkas
2783342f33 Update ci.yml 2022-03-02 10:31:49 -08:00
Clint Rutkas
1920a1f3de Update ci.yml 2022-03-02 10:28:31 -08:00
Clint Rutkas
29a25454d8 removing nowarn's (#16590) 2022-03-01 06:33:27 -08:00
Clint Rutkas
47920f50f3 supressing warning (#16594) 2022-03-01 06:32:23 -08:00
Clint Rutkas
cc8d8074bb 0.56 change log. (#16591)
* activate to shake

* updating requirement / download exe name

* spellings oops

* Update names.txt

* Update names.txt

* adjusting word for spelling

* adjusting langauge to match highlight

* properly casing nVidia

* adjusting spelling files

* Apply suggestions from code review

Co-authored-by: Jay <65828559+Jay-o-Way@users.noreply.github.com>

* Create README.md

* Update README.md

* Update README.md

Co-authored-by: Aaron Junker <aaron.junker@outlook.com>

* Update README.md

Co-authored-by: Aaron Junker <aaron.junker@outlook.com>

* Update README.md

Co-authored-by: Aaron Junker <aaron.junker@outlook.com>

* Update README.md

* Update README.md

* Update README.md

* Update README.md

Co-authored-by: Jay <65828559+Jay-o-Way@users.noreply.github.com>
Co-authored-by: Aaron Junker <aaron.junker@outlook.com>
2022-02-28 11:50:28 -08: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
574 changed files with 29835 additions and 7772 deletions

2
.gitattributes vendored
View File

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

View File

@@ -0,0 +1,11 @@
bdoserror
crutkas
edwinzap
hallatore
mshtang
nVidia
robmen
skycommand
snickler
Vidia
yifan

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$
@@ -45,6 +46,10 @@ ignore$
^src/modules/previewpane/PreviewPaneUnitTests/HelperFiles/MarkdownWithHTMLImageTag\.txt$
^src/modules/previewpane/UnitTests-MarkdownPreviewHandler/HelperFiles/MarkdownWithHTMLImageTag.txt$
^tools/CleanUp_tool/CleanUp_tool\.vcxproj\.filters$
^tools/Verification scripts/Check preview handler registration\.ps1$
^\.github/
^\.github/actions/spell-check/
^\.gitmodules$
(?:^|/)WindowsSettings\.json$
(?:^|/)timezones\.json$
^\Q.pipelines/ESRPSigning_core.json\E$

File diff suppressed because it is too large Load Diff

View File

@@ -12,6 +12,10 @@ https?://(?:(?:www\.|)youtube\.com|youtu.be)/[-a-zA-Z0-9?&=]*
# msdn
\b(?:download\.visualstudio|docs|msdn)\.microsoft\.com/[-_a-zA-Z0-9()=./]*
# medium
link\.medium\.com/[a-zA-Z0-9]+
\bmedium\.com/\@[^/]+/[-\w]+
publicKeyToken=(['"]|)[0-9a-f]+\g{-1}
\@sha256:[0-9a-f]{64}\b
@@ -19,15 +23,21 @@ publicKeyToken=(['"]|)[0-9a-f]+\g{-1}
(['"])data:.*?\g{-1}
data:[-a-zA-Z=;:/0-9+]*,\S*
# uuid:
L?(["']|[-<({>]|\b)[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}(?:\g{-1}|[<})>])
# uuid: (or CompGUIDPrefix)
L?(["']|[-<({>]|\b)[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{10,12}(?:\g{-1}|[<})>])
# c99 hex digits (not the full format, just one I've seen)
0x[0-9a-fA-F](?:\.[0-9a-fA-F]*|)[pP]
# URL escaped characters
\%[0-9A-F]{2}
# wregex
std::wregex\(L"[^"]*"\)
# hash
Hash="[0-9A-F]{40}"
# hex digits including css/html color classes:
(?:[\\0][xX]|\\u|[uU]\+|#x?|\%23|L")[0-9a-fA-FgGrR_]{2,}(?:[uU]?[lL]{0,2}|u\d+)\b
@@ -42,12 +52,18 @@ TestCase\("[^"]+"
\[DataRow\("[0-9A-F]{6}", \d{3}.\d{1}, \d{3}.\d{1}, \d{3}.\d{1}\)\]
\[DataRow\("[0-9A-F]{6}", "[BCGMRY]\d\d?", \d{3}, \d{3}\)\]
# version suffix <word>v#
[Vv]\d+(?:\b|(?=[a-zA-Z_]))
# Windows paths
\\native
\\netcoreapp
\\netstandard
\\network
\\notifications
\\recyclebin
\\Registry
\\registry
\\reinstall
\\Resize
\\resource
@@ -75,8 +91,14 @@ TestCase\("[^"]+"
# TestCase strings intentionally have non dictionary items
\[TestCase\(new string.*\]
# D2D
D2D
# marker for ignoring a comment to the end of the line
^.*/\* #no-spell-check-line \*/.*$
// #no-spell-check.*$
http://tes/
# tar arguments
\b(?:\\n|)tar(?:\s+-[a-zA-Z]+|\s[a-z]+)+

View File

@@ -94,6 +94,8 @@
"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\\TimeDate\\Microsoft.PowerToys.Run.Plugin.TimeDate.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 +160,6 @@
},
{
"MatchedPath": [
"Microsoft.Search.Interop.dll",
"ModernWpf.dll",
"ModernWpf.Controls.dll",
"System.IO.Abstractions.dll",
@@ -173,7 +174,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 }}
@@ -84,13 +92,24 @@ steps:
restoreDirectory: '$(Build.SourcesDirectory)\installer\packages'
- task: VSBuild@1
displayName: 'Build PowerToysSetup.sln'
displayName: 'Build PowerToys MSI'
inputs:
solution: '**\installer\PowerToysSetup.sln'
vsVersion: 16.0
vsVersion: 17.0
platform: '$(BuildPlatform)'
configuration: '$(BuildConfiguration)'
msbuildArgs: ${{ parameters.additionalBuildArguments }}
msbuildArgs: /t:PowerToysInstaller ${{ parameters.additionalBuildArguments }}
maximumCpuCount: true
- task: VSBuild@1
displayName: 'Build PowerToys Bootstrapper'
inputs:
solution: '**\installer\PowerToysSetup.sln'
vsVersion: 17.0
platform: '$(BuildPlatform)'
configuration: '$(BuildConfiguration)'
msbuildArgs: /t:PowerToysBootstrapper ${{ parameters.additionalBuildArguments }}
clean: false
maximumCpuCount: true
# directly not doing WinAppDriver testing
@@ -122,8 +141,10 @@ steps:
**\Microsoft.PowerToys.Run.Plugin.Calculator.UnitTest.dll
**\Microsoft.Plugin.Uri.UnitTests.dll
**\Wox.Test.dll
**\Microsoft.PowerToys.Run.Plugin.System.UnitTests.dll
**\Microsoft.PowerToys.Run.Plugin.WindowsTerminal.UnitTests.dll
**\Microsoft.PowerToys.Run.Plugin.System.UnitTests.dll
**\Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests.dll
**\Microsoft.Plugin.WindowsTerminal.UnitTests.dll
**\Microsoft.Plugin.WindowWalker.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,11 +262,11 @@ jobs:
displayName: Build Bootstrapper
inputs:
solution: '**/installer/PowerToysSetup.sln'
vsVersion: 16.0
msbuildArgs: /p:CIBuild=true /bl:$(Build.SourcesDirectory)\msbuild.binlog
vsVersion: 17.0
msbuildArgs: /p:CIBuild=true /bl:$(Build.SourcesDirectory)\msbuild.binlog /t:PowerToysBootstrapper
platform: $(BuildPlatform)
configuration: $(BuildConfiguration)
clean: true
clean: false # don't undo our hard work above by deleting the MSI
maximumCpuCount: true
- task: CmdLine@2
@@ -296,7 +312,7 @@ jobs:
script: '.\installer\packages\WiX.3.11.2\tools\insignia.exe -ab installer\engine.exe installer\PowerToysSetup\$(BuildPlatform)\$(BuildConfiguration)\PowerToysSetup-${{ parameters.versionNumber }}-$(BuildPlatform).exe -o installer\PowerToysSetup\$(BuildPlatform)\$(BuildConfiguration)\PowerToysSetup-${{ parameters.versionNumber }}-$(BuildPlatform).exe'
- task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1
displayName: Sign Boostrapper
displayName: Sign Bootstrapper
inputs:
ConnectedServiceName: 'Terminal/Console/WinAppDriver Team Code Signing Connection'
FolderPath: 'installer/PowerToysSetup/$(BuildPlatform)\$(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,8 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project>
<PropertyGroup>
<Copyright>Copyright (C) 2022 Microsoft Corporation</Copyright>
<AssemblyCompany>Microsoft Corp.</AssemblyCompany>
<AssemblyCopyright>Copyright (C) 2022 Microsoft Corporation</AssemblyCopyright>
<AssemblyProduct>PowerToys</AssemblyProduct>
<Company>Microsoft Corporation</Company>
<NeutralLanguage>en-US</NeutralLanguage>
<Platforms>x64</Platforms>
<PackageTags>PowerToys</PackageTags>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<AnalysisMode>Recommended</AnalysisMode>
</PropertyGroup>
<PropertyGroup Condition="'$(MSBuildProjectExtension)' == '.csproj'">
<RepositoryUrl>https://github.com/microsoft/PowerToys</RepositoryUrl>
<RepositoryType>Github</RepositoryType>
</PropertyGroup>
<PropertyGroup Condition="'$(MSBuildProjectExtension)' == '.csproj'">
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<PropertyGroup>
<_PropertySheetDisplayName>PowerToys.Root.Props</_PropertySheetDisplayName>
<ForceImportBeforeCppProps>$(MsbuildThisFileDirectory)\Cpp.Build.props</ForceImportBeforeCppProps>
</PropertyGroup>
</Project>

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
@@ -136,6 +136,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PowerLauncher", "src\module
{C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0} = {C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0}
{0351ADA4-0C32-4652-9BA0-41F7B602372B} = {0351ADA4-0C32-4652-9BA0-41F7B602372B}
{787B8AA6-CA93-4C84-96FE-DF31110AD1C4} = {787B8AA6-CA93-4C84-96FE-DF31110AD1C4}
{F44934A8-36F3-49B0-9465-3831BE041CDE} = {F44934A8-36F3-49B0-9465-3831BE041CDE}
{5BDBD6C9-A31F-4CEB-871A-5E9E709197EF} = {5BDBD6C9-A31F-4CEB-871A-5E9E709197EF}
{5043CECE-E6A7-4867-9CBE-02D27D83747A} = {5043CECE-E6A7-4867-9CBE-02D27D83747A}
{F8B870EB-D5F5-45BA-9CF7-A5C459818820} = {F8B870EB-D5F5-45BA-9CF7-A5C459818820}
{74F1B9ED-F59C-4FE7-B473-7B453E30837E} = {74F1B9ED-F59C-4FE7-B473-7B453E30837E}
@@ -174,7 +176,8 @@ 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
Directory.Build.props = Directory.Build.props
Solution.props = Solution.props
EndProjectSection
EndProject
@@ -265,6 +268,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 +361,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 +400,13 @@ 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
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerToys.Run.Plugin.TimeDate", "src\modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.TimeDate\Microsoft.PowerToys.Run.Plugin.TimeDate.csproj", "{5BDBD6C9-A31F-4CEB-871A-5E9E709197EF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests", "src\modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests\Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests.csproj", "{FD464B4C-2F68-4D06-91E7-4208146C41F5}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Plugin.WindowWalker.UnitTests", "src\modules\launcher\Plugins\Microsoft.Plugin.WindowWalker.UnitTests\Microsoft.Plugin.WindowWalker.UnitTests.csproj", "{8FE5A5EE-1B59-401C-9FB3-B04ECD3E29C1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@@ -985,8 +996,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 +1084,42 @@ 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|Any CPU
{04B193D7-3E21-46B8-A958-89B63A8A69DE}.Release|x86.Build.0 = 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}.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
{5BDBD6C9-A31F-4CEB-871A-5E9E709197EF}.Debug|x64.ActiveCfg = Debug|x64
{5BDBD6C9-A31F-4CEB-871A-5E9E709197EF}.Debug|x64.Build.0 = Debug|x64
{5BDBD6C9-A31F-4CEB-871A-5E9E709197EF}.Debug|x86.ActiveCfg = Debug|x64
{5BDBD6C9-A31F-4CEB-871A-5E9E709197EF}.Release|x64.ActiveCfg = Release|x64
{5BDBD6C9-A31F-4CEB-871A-5E9E709197EF}.Release|x64.Build.0 = Release|x64
{5BDBD6C9-A31F-4CEB-871A-5E9E709197EF}.Release|x86.ActiveCfg = Release|x64
{5BDBD6C9-A31F-4CEB-871A-5E9E709197EF}.Release|x86.Build.0 = Release|x64
{FD464B4C-2F68-4D06-91E7-4208146C41F5}.Debug|x64.ActiveCfg = Debug|x64
{FD464B4C-2F68-4D06-91E7-4208146C41F5}.Debug|x64.Build.0 = Debug|x64
{FD464B4C-2F68-4D06-91E7-4208146C41F5}.Debug|x86.ActiveCfg = Debug|x64
{FD464B4C-2F68-4D06-91E7-4208146C41F5}.Debug|x86.Build.0 = Debug|x64
{FD464B4C-2F68-4D06-91E7-4208146C41F5}.Release|x64.ActiveCfg = Release|x64
{FD464B4C-2F68-4D06-91E7-4208146C41F5}.Release|x64.Build.0 = Release|x64
{FD464B4C-2F68-4D06-91E7-4208146C41F5}.Release|x86.ActiveCfg = Release|x64
{FD464B4C-2F68-4D06-91E7-4208146C41F5}.Release|x86.Build.0 = Release|x64
{8FE5A5EE-1B59-401C-9FB3-B04ECD3E29C1}.Debug|x64.ActiveCfg = Debug|x64
{8FE5A5EE-1B59-401C-9FB3-B04ECD3E29C1}.Debug|x64.Build.0 = Debug|x64
{8FE5A5EE-1B59-401C-9FB3-B04ECD3E29C1}.Debug|x86.ActiveCfg = Debug|x64
{8FE5A5EE-1B59-401C-9FB3-B04ECD3E29C1}.Debug|x86.Build.0 = Debug|x64
{8FE5A5EE-1B59-401C-9FB3-B04ECD3E29C1}.Release|x64.ActiveCfg = Release|x64
{8FE5A5EE-1B59-401C-9FB3-B04ECD3E29C1}.Release|x64.Build.0 = Release|x64
{8FE5A5EE-1B59-401C-9FB3-B04ECD3E29C1}.Release|x86.ActiveCfg = Release|x64
{8FE5A5EE-1B59-401C-9FB3-B04ECD3E29C1}.Release|x86.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1208,6 +1251,10 @@ 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}
{5BDBD6C9-A31F-4CEB-871A-5E9E709197EF} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{FD464B4C-2F68-4D06-91E7-4208146C41F5} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{8FE5A5EE-1B59-401C-9FB3-B04ECD3E29C1} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0}

168
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.23 Desktop Runtime](https://dotnet.microsoft.com/download/dotnet/thank-you/runtime-desktop-3.1.23-windows-x64-installer) or a newer 3.1.x runtime. This is needed currently for the Settings application.
- [.NET 6.0.3 Desktop Runtime](https://dotnet.microsoft.com/download/dotnet/thank-you/runtime-desktop-6.0.3-windows-x64-installer) or a newer 6.0.x runtime.
- [Microsoft Edge WebView2 Runtime](https://go.microsoft.com/fwlink/p/?LinkId=2124703) bootstrapper. This will install the latest version.
### 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.57.0-x64.exe` to download the PowerToys installer.
This is our preferred method.
@@ -66,98 +69,117 @@ 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.57 - March 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 focused heavily on stability and improvements. Below are some of the highlights!
[@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.
**Highlights**
#### 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.
- PowerToys Run quality pass. Old standing issues were re-evaluated and fixed.
- Additional features and improvements were added to existing PowerToys Run plugins.
- New plugin for time and date values/information in PowerToys Run. Thanks [@htcfreek](https://github.com/htcfreek)!
- The [PowerToys Run documentation](https://aka.ms/PowerToysOverview_PowerToysRun) is also receiving a required update. Thanks [@htcfreek](https://github.com/htcfreek)!
- PowerToys will register SVGs as a picture kind when SVG Thumbnails are enabled so they appear when searching for pictures in File Explorer.
- We've disabled PDF preview by default, given its incompatibilities with Outlook and that Edge is now being registered for previewing PDF files on Windows 10 too.
- From a coding quality point of view, every project now has code analyzer active. Thanks [@CleanCodeDeveloper](https://github.com/CleanCodeDeveloper)!
- A double click on the tray icon is needed instead of single click to open settings.
#### 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.
### Always on Top
#### 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
- New sound for Always on Top activation. Thanks [@franky920920](https://github.com/franky920920)!
#### 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
### Awake
- Fixes for the system tray icon. Thanks [@dend](https://github.com/dend)!
- Temporary duration presets are now configurable. Thanks [@dend](https://github.com/dend)!
- Fix for an issue causing Awake to not be closed properly. Thanks [@dend](https://github.com/dend)!
#### File Explorer
- Added G-code support for thumbnails and preview pane. Thanks @pedrolamas
### ColorPicker
#### Image Resizer
- Fixed regression from Metadata tag removal of ColorSpace. Thanks @CleanCodeDeveloper
- It's now possible to delete multiple colors from the history, or to export a list of colors to a file. Thanks [@mshtang](https://github.com/mshtang)!
- The CIEXYZ format has increased precision. Thanks [@m13253](https://github.com/m13253)!
- Performance improved by reducing the use of low level keyboard hooks.
#### PowerRename
- Row highlighting + preview support now implemented. Thanks @niels9001
- Fixed AltGR input issue
- Improved folder renaming support
- Opens on active monitor
### FancyZones
#### 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.
- Fixed a bug where the same layout applied with different configurations to different screens would reset to a single configuration. (This was a hotfix for 0.56)
- When snapping windows with rounded corners on Windows 11, set the correct corner preferences to avoid gaps between zones. Thanks [@hallatore](https://github.com/hallatore)!
- Fix for canvas layout resetting due to resolution changes.
#### 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
### File explorer
#### Settings
- Multiple accessibility, layout, image, string and icons fixes. Thanks @niels9001
- Additional markdown file extensions added for Markdown Preview. Thanks [@skycommand](https://github.com/skycommand)!
- SVG files are now registered as a picture kind on Windows.
- Added a text wrapping setting and copy context menu to dev file preview. Thanks [@Aaron-Junker](https://github.com/Aaron-Junker)!
- PDF file preview and thumbnails are now disabled by default, due to incompatibility with Outlook and an appropriate warning is shown in Settings.
#### Runner
- Improved mutex support to prevent multiple PT Run instances from running
### Mouse utility
#### 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
- Find my mouse has a new setting to specify a minimum moving distance for activation. (This was a hotfix for 0.56)
- Fix for the bug causing the task bar to be hidden behind other windows when a mouse utility was active.
- Fix for the bug causing shortcuts set on icons to not activate when a mouse utility was active.
- Fixed a slight offset in Mouse Pointer Crosshairs when it's configured with an odd thickness.
#### ARM64 support
- Setting WinUI3 proof-of-concept and validate we do need at least one more feature, elevation support from WinUI 3 unpackaged applications.
### PowerToys Run
#### 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
- New plugin for time and date values/information. Thanks [@htcfreek](https://github.com/htcfreek)!
- WindowWalker now has a tooltip, additional features like killing the process and closing the window, additional settings and improvements. Thanks [@htcfreek](https://github.com/htcfreek)!
- Unit converter now accepts alternative syntax for feet and gallon. It interprets as either imperial or US gallons depending on current culture. Thanks [@yifan-k](https://github.com/yifan-k)!
- Unit converter now accepts "metre" and "meter".
- Localization for Web Search and Unit Converter (not including units) has been enabled.
- Localization for Windows Terminal has been enabled. (This was a hotfix for 0.56)
- Calculator now tries to always interpret the dot (.) symbol as a decimal separator, despite configured culture, to meet expectations.
- Calculator now handles trailing zeroes on hexadecimal numbers correctly.
- System commands plugin can now show the local ip and mac addresses. Thanks [@htcfreek](https://github.com/htcfreek)!
- Folder plugin has improved results, with improved tooltips. Thanks [@htcfreek](https://github.com/htcfreek)!
- Windows settings plugin has added entries for Screen Saver and Connect Wiring Display Panel. Thanks [@htcfreek](https://github.com/htcfreek)!
- Plugins can now show descriptions for their configurations in settings. Thanks [@htcfreek](https://github.com/htcfreek)!
- Fix for the focus issue when calling PowerToys Run for the first time after login and after returning from some windows.
- Fix for a bug on Program when creating a shortcut.
- Validated that upgrading to .NET framework 6 fixed the error appearing when shutting down the system with PowerToys Run running.
### Video conference mute
- Newly added microphones are now updated and tracked by VCM.
### Settings
- _What's new_ button in the bottom with a new look, with a few more UI tweaks. Thanks [@niels9001](https://github.com/niels9001)!
- Fixed a bug causing Settings not to open when a racing condition caused Keyboard Manager settings to not be read correctly.
- To open settings from the tray icon a double click is needed instead of a single click.
- Fix for a bug which would cause checking for updates to run indefinitely.
- When auto-updating, pass a flag to avoid rebooting the computer without being prompted.
### Installer
- Dependencies installers are now executed with /norestart to avoid unprompted reboots. (This was a hotfix for 0.56). Thanks [@franky920920](https://github.com/franky920920)!
- Upgraded .NET framework dependency to 6.0.3.
- Installer logs are now saved where they can be collected and sent by the bug report tool.
- Reverted changes to start with proper elevation and when installed under a different user since those changes ended up causing more issues where PowerToys would start running with the wrong user.
### Development
- OOBE code refactor to have all module information in XAML, like in Settings. Thanks [@niels9001](https://github.com/niels9001)!
- Every project now has analyzers turned on and warnings fixed. Thanks [@CleanCodeDeveloper](https://github.com/CleanCodeDeveloper)!
- New patterns added for code spell-checking and stale entries removed. Thanks [@jsoref](https://github.com/jsoref)
- Additional logging has been added to Fancy Zones and PowerToys Run.
- A new CI release build will not be triggered if all that was changed was just documentation.
- Fixed a racing condition causing flaky build errors when building PowerRename.
- Centralization of common csproj/vcxproj settings underway. Thanks [@CleanCodeDeveloper](https://github.com/CleanCodeDeveloper)!
#### 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.
We'd like to directly mention certain contributors (in alphabetical order) for their continued community support this month and helping directly make PowerToys a better piece of software.
[@Aaron-Junker](https://github.com/Aaron-Junker), [@CleanCodeDeveloper](https://github.com/CleanCodeDeveloper), [@dend](https://github.com/dend), [@franky920920](https://github.com/franky920920), [@htcfreek](https://github.com/htcfreek), [@jay-o-way](https://github.com/jay-o-way), [@jsoref](https://github.com/jsoref), [@niels9001](https://github.com/niels9001), [@snickler](https://github.com/snickler).
[@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.58
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.58][github-next-release-work], we'll start work on below:
- 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
- Environment Variables Editor PowerToy
- Continue work on another new PowerToy
- Stability / bug fixes
- Adding new file types to dev file preview
## PowerToys Community
@@ -184,5 +206,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%2F31
[github-current-release-work]: https://github.com/microsoft/PowerToys/issues?q=is%3Aopen+is%3Aissue+project%3Amicrosoft%2FPowerToys%2F30

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,84 @@
# 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.)
* IP / MAC / Address => Show informations about network connections.
## 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 |
| `ReduceNetworkResultScore` | `true` | Reduce the priority of 'IP' and 'MAC' results to improve the order in the global results |
* 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.
### [`Commands.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Components/Commands.cs)
- The [`Commands`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Components/Commands.cs) class contains the definition of all available commands/results.
### [`ResultHelper.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Components/ResultHelper.cs)
- The [`ResultHelper`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Components/ResultHelper.cs) class contains methods for working with the results and some of the result features (tool tip, copy to clipboard, execute command).
### [`NetworkConnectionProperties.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Components/NetworkConnectionProperties.cs)
- The [`NetworkConnectionProperties`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Components/NetworkConnectionProperties.cs) class contains methods to get the properties of a network interface/connection.
- An instance of this class collects/provides all required informations about one connection/adapter.
### [`SystemPluginContext.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Components/SystemPluginContext.cs)
- An instance of the class [`SystemPluginContext`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Components/SystemPluginContext.cs) contains/defines the context data of a system plugin result. We select the context menu based on the defined properties.
- It is used for the `ContextData` property of the [`Wox.Plugin.Result`](/src/modules/launcher/Wox.Plugin/Result.cs).
### 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`.
## Search
### 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.
* For network results (IP address and MAC address) the score is reduced by 25 percent.
### Network results on global queries
- The network results (IP and MAC address) are only shown on global queries, if the search term starts with either IP, MAC or Address. (We compare case-insensitive.)
### Returning results
We return the results in two steps:
1. All results which we can create very fast like shutdown or logoff via [`Main.Query(Query query)`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Main.cs).
2. All results which need some time to create like the network results (IP, MAC) via [`Main.Query(Query query, bool delayedExecution)`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Main.cs).
## [Unit Tests](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System.UnitTests)
We have a [Unit Test project](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System.UnitTests) that executes various test to ensure that the plugin works as expected.
### [`ImageTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System.UnitTests/ImageTests.cs)
- The [`ImageTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System.UnitTests/ImageTests.cs) class contains tests to validate that each result shows the expected and correct image.
### [`QueryTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System.UnitTests/QueryTests.cs)
- The [`QueryTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System.UnitTests/QueryTests.cs) class contains tests to validate that the user gets the correct results when searching.

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

@@ -0,0 +1,148 @@
# 'Time and Date' plugin
The 'Time and Date' plugin shows the date and time in different formats. For the date and time formats the plugin uses the culture setting in Windows, if the format is not commonly defined. The user can search for the system date/time or a custom date/time. The value of each result can be copied to clipboard.
**Query examples:**
- Format: `time`
- Date/time: `10:30 AM`
- Format and date/time: `Week number::10/10/2022`
!['Time and Date' plugin](/doc/images/launcher/plugins/timedate.png)
![Search for a date in a specified format](/doc/images/launcher/plugins/timedate2.png)
## Formats
### Available formats
**Remarks**
- The following formats requires a prefix in the query:
- Unix Timestamp: `u`
- Windows file time: `ft`
- On invalid number inputs we show a warning that tells the user which prefixes are allowed/required.
**List of available formats**
The following formats are currently available:
| Format | Example (Based on default settings) | As result | As input |
|--------------|-----------|------------|------------|
| Time | 5:10 PM | x | x |
| Date | 3/5/2022 | x | x |
| Now | 3/5/2022 5:10 PM | x | x |
| Time UTC | 4:10 PM | x | x |
| Now UTC | 3/5/2022 4:10 PM | x | x |
| Unix Timestamp | 1646496622 | x | x |
| Hour | 10 | x | |
| Minute | 30 | x | |
| Second | 45 | x | |
| Millisecond | 678 | x | |
| Day (Week day) | Saturday | x | |
| Day of the week | 6 | x | |
| Day of the month | 5 | x | |
| Day of the year | 64 | x | |
| Week of the month | 1 | x | |
| Week of the year (Calendar week, Week number) | 10 | x | |
| Month | March | x | |
| Month of the year | 3 | x | |
| Month and day | March 7 | x | x |
| Year | 2022 | x | |
| Era | AD | x | |
| Era abbreviation | A | x | |
| Month and year | March 2022 | x | x |
| Windows file time (Int64 number) | 637820976123938199 | x | x |
| Universal time format: YYYY-MM-DD hh:mm:ss| 2022-03-05 16:20:12Z | x | x |
| ISO 8601 | 2022-03-05T17:23:04 | x | x |
| ISO 8601 UTC | 2022-03-05T16:23:04 | x | x |
| ISO 8601 with time zone | 2022-03-05T17:23:04+01:00 | x | x |
| ISO 8601 UTC with time zone | 2022-03-05T16:23:04Z | x | x |
| RFC1123 | Sat, 05 Mar 2022 16:23:04 GMT | x | x |
### Add new formats
- To add a new formats you have to add them to the method `GetList()` of the [`AvailableResultsList`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Components/AvailableResultsList.cs) class.
- Please add the new formats in the second range. The first one is reserved for the three main formats (Time, Date, Now).
- After adding the new formats you have to update the Unit Tests!
## Optional plugin settings
- 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 [`TimeDateSettings`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Components/TimeDateSettings.cs) class of the plugin. The settings can be accessed everywhere in the plugin code via the static class instance `TimeDateSettings.Instance`.
- We have the following settings that the user can configure to change the behavior of the plugin:
| Key | Default value | Name/Description |
|--------------|-----------|------------|
| `OnlyDateTimeNowGlobal` | `true` | Show only 'Time', 'Date', and 'Now' result on global queries |
| `TimeWithSeconds` | `false` | Show time with seconds (Applies to 'Time' and 'Now' result) |
| `DateWithWeekday` | `false` | Show date with weekday and name of month (Applies to 'Date' and 'Now' result) |
| `HideNumberMessageOnGlobalQuery` | `false` | Hide 'Invalid number input' error message on global queries |
## Classes
### [`AvailableResult.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Components/AvailableResult.cs)
- Each instance of the [`AvailableResult`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Components/AvailableResult.cs) class represents a time/date result/format that the user can search for.
- The results/formats are defined in the `AvailableResultsList` class.
### [`AvailableResultsList.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Components/AvailableResultsList.cs)
- The [`AvailableResultsList`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Components/AvailableResultsList.cs) class contains the list of available formats/results in its method `GetList()`.
### [`ResultHelper.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Components/ResultHelper.cs)
- The [`ResultHelper`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Components/ResultHelper.cs) class contains methods for some of the result features (tool tip, copy to clipboard) and the error result on incorrect number input.
- And it contains the `SelectStringFromResources()` method for getting the resource strings based on the user input.
- The method has a parameter for the `stringId` which is the name of the string in the resource file. By default the word `Now` is automatically added at the end to get the string for a system time/date search.
- If a different/custom string is needed for a system time/date search the parameter `stringIdNow` can be used to override the default behavior of the method.
- If only a string for the system time/date search is required, you can set `stringId` to `string.Empty` and only `stringIdNow` to a valid string id.
### [`TimeAndDateHelper.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Components/TimeAndDateHelper.cs)
- The [`TimeAndDateHelper`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Components/TimeAndDateHelper.cs) class contains methods to format/convert date and time formats/strings.
### [`TimeDateSettings.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Components/TimeDateSettings.cs)
- The [`TimeDateSettings`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Components/TimeDateSettings.cs) class provides access to all optional plugin settings.
- The class has a static property called `Instance` that holds an instance of the class itself. This allows us to access the settings from everywhere in the plugin code without having additional parameters in our methods.
### [`SearchController.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Components/SearchController.cs)
- The [`SearchController`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Components/SearchController.cs) encapsulates the methods needed to search and find matches.
## Search
### Tags
- We compare the user input with the label of each results. If it doesn't match we search the tags of the result too.
- For each result two tag strings are defined. One for a search with system time/date and one for a search with a custom time/date. Most of the results (except the era results) are using one of the generic tag lists: Date, Time or Format
- The selection of the tag (for "system time/date" or "custom time/date") is happening at search time in the `AvailableResultsList.cs` class.
- The different tags in a list are split by the `;` character.
### Score
- The plugin uses `FuzzyMatching` to get the matching formats, if the user searches for a specific format. The score is set based on the `FuzzySearch` result.
- To achieve a better balance between sub title matches and tag matches the score of tag matches is divided by two.
### Match requirements for global queries
On global queries the high score returned by `FuzzySearch` has negative impacts on the user experience and the search results priority/order of other plugins. To mitigate this we defined some matching requirements:
- If the query is a word of the following conjunction list, we don't return any results: for, and, nor, but, or, so
- We don't have 'yet' (synonym of 'now') on the list, because this could block results in some languages.
- The first word of the query has to be a full match with a word in the label or tag list.
- For both requirements we compare case-insensitive.
## [Unit Tests](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests)
We have a [Unit Test project](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests) that executes various test to ensure that the plugin works as expected.
### [`TimeDateResultTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/TimeDateResultTests.cs)
- The [`TimeDateResultTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/TimeDateResultTests.cs) class contains tests to validate that the time and date values are correctly formatted/calculated.
- That we can execute the tests at any time on any machine, we use a specified date/time value and set the thread culture always to `en-us` while executing the tests.
- Some tests contain checks that calculate the expected result at runtime instead of using an expected value written fix in the code. This is done to get valid results on every machine at any time.
### [`ImageTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/ImageTests.cs)
- The [`ImageTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/ImageTests.cs) class contains tests to validate that each result shows the expected and correct image.
- That we can execute the tests at any time on any machine, we set the thread culture always to `en-us` while executing the tests.
### [`PluginSettingsTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/PluginSettingsTests.cs)
- The [`PluginSettingsTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/PluginSettingsTests.cs) class contains tests to validate that all settings exist and that they have the correct default values.
### [`QueryTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/QueryTests.cs)
- The [`QueryTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/QueryTests.cs) class contains tests to validate that the user gets the correct results when searching.,
- That we can execute the tests at any time on any machine, we set the thread culture always to `en-us` while executing the tests.
### [`StringParserTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/StringParserTests.cs)
- The [`StringParserTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/StringParserTests.cs) class contains tests to validate that the typed string gets converted correctly into a `DateTime` object.
- That we can execute the tests at any time on any machine, we set the thread culture always to `en-us` while executing the tests.

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

@@ -1,8 +1,49 @@
# Window Walker plugin
The window walker plugin matches the user entered query with the open windows on the system.
The user can switch to the found windows, close them or kill their process.
![Image of Window Walker plugin](/doc/images/launcher/plugins/windowwalker.png)
## Remarks
### UWP Apps
- The process of an UWP app can't be detected correctly for windows that are minimized while searching. At this time they are assigned to the generic process `ApplicationFrameHost.exe`. If the user searches for such an window while it is not minimized, then the process gets assigned correctly/updated.
### Killing processes
- Killing the Explorer process is only allowed, if each folder window is running in its own process. (See section `File Explorer setting` below.)
- You can only kill elevated processes, if you have admin permissions (UAC).
- If you kill the process of an UWP app window, you kill all instances of the app. All windows are assigned to the same process.
- Windows of UWP apps don't know their process, until they are searched in non-minimized state.
### File Explorer setting
- To kill the Process of an Explorer window, each window has to run in a separate process. Otherwise the process is the same one as the shell process and killing the shell process will crash the shell (Windows ui).
- To enable this behavior the setting `Launch folder windows in a separate process` under `Folder Options > View` has to be enabled.
- From PowerToys Run you can open the `Folder options` dialog by clicking the information message in the search results. The information message is only shown when searching with action keyword for explorer windows and can be hidden in the plugin settings.
- Note: The folder option/process is evaluated in real time. After changing the setting it is enough to search again for the windows.
![Folder options for Window Walker](/doc/images/launcher/plugins/windowwalker_folder_options.png)
## Optional plugin settings
- 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 [`WindowWalkerSettings`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/WindowWalkerSettings.cs) class of the plugin. The settings can be accessed everywhere in the plugin code via the static class instance `WindowWalkerSettings.Instance`.
- We have the following settings that the user can configure to change the behavior of the plugin:
| Key | Default value | Name/Description |
|--------------|-----------|------------|
| `ResultsFromVisibleDesktopOnly` | `false` | Show only results from visible desktop |
| `SubtitleShowPid` | `false` | Show process id in subtitle |
| `SubtitleShowDesktopName` | `true` | Show desktop name in subtitle (If two or more desktops exist) |
| `ConfirmKillProcess` | `true` | Request confirmation when killing a process |
| `KillProcessTree` | `false` | Kill process and it's child processes |
| `OpenAfterKillAndClose` | `false` | Stay open after closing windows and killing processes (Not working with kill process confirmation) |
| `HideKillProcessOnElevatedProcesses` | `false` | Hide "kill process" button if additional permissions required |
| `HideExplorerSettingInfo` | `false` | Hide Explorer process information |
## Technical details
### [`OpenWindows.cs`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/OpenWindows.cs)
- The window walker plugin uses the `EnumWindows` function to enumerate all the open windows in the [`OpenWindows.cs`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/OpenWindows.cs) class.
@@ -11,11 +52,33 @@ The window walker plugin matches the user entered query with the open windows on
- It is responsible for updating the search text and performing a fuzzy search on all the open windows.
### [`Window.cs`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/Window.cs)
- The [`Window`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/Window.cs) class represents a specific window and has functions to get the name of the window, the state of the window (whether it is visible or not), and the `SwitchTowindow` function which switches the desktop focus to the selected window. This action is performed when the user clicks on a window walker plugin result.
- The [`Window`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/Window.cs) class represents a specific window and has functions to get the name of the window, the state of the window (whether it is visible or not), the `SwitchTowindow` function which switches the desktop focus to the selected window and the `CloseThisWindow` function which closes the window. The `SwitchTowindow` action is performed when the user clicks on a window walker plugin result.
- The `Window` class holds a static cache with the process information of all windows we know so far and each window instance has a property which holds its process information (name, file, ...). The process data in the cache and the window property are of the type `WindowProcess`.
- To get the desktop information for a window, we use the common [`VirtualDesktopHelper`](/src/modules/launcher/Wox.Plugin/Common/VirtualDesktop/VirtualDesktopHelper.cs) in `Wox.Plugin` project. The instance of `VirtualDesktopHelper` is cached in the [`Main`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Main.cs) class of the plugin at runtime. The desktop information is stored in a property of the type [`VDesktop`](/src/modules/launcher/Wox.Plugin/Common/VirtualDesktop/VDesktop.cs).
### [`WindowProcess.cs`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/WindowProcess.cs)
- The [`WindowProcess`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/WindowProcess.cs) class represents a specific process for a window. It contains static methods to query process information from the system. And it contains instance methods and properties to hold/retrieve the process information we want to know about a window's process.
- The [`WindowProcess`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/WindowProcess.cs) class represents a specific process for a window.
- It contains static methods to query process information from the system and instance methods/properties to hold/retrieve the process information we want to know about a window's process.
- Additionally, it contains the method `KillThisProcess` to kill the process. (If the user has not enough permissions to kill a process they are requested via UAC.)
### [`ResultHelper.cs`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/ResultHelper.cs)
- The [`ResultHelper`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/ResultHelper.cs) class contains the code to create the list with all results for PT Run based on the data returned from `SearchController` class.
- There is a special result that is added if the folder windows doesn't run in separate processes and the user searches for Explorer windows using the action keyword.
- This result informs the user that there is a setting that must be enabled to be able to kill Explorer processes.
- The result can be disabled in plugin options. When it is clicked it opens the folder options.
### [`ContextMenuHelper.cs`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/ContextMenuHelper.cs)
- The [`ContextMenuHelper`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/ContextMenuHelper.cs) class provides the code for the context menu items.
### [`WindowWalkerSettings.cs`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/WindowWalkerSettings.cs)
- The [`WindowWalkerSettings`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/WindowWalkerSettings.cs) class provides access to all optional plugin settings.
- The class has a static property called `Instance` that holds an instance of the class itself. This allows us to access the settings from everywhere in the plugin code without having additional parameters in our methods.
### Score
The window walker plugin uses [`FuzzyMatching`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/FuzzyMatching.cs) to get the matching indices and calculates the score by creating a 2 dimensional array of the window and the query text.
## [Unit Tests](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker.UnitTests)
We have a [Unit Test project](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker.UnitTests) that executes various test to ensure that the plugin works as expected.
### [`PluginSettingsTests.cs`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker.UnitTests/PluginSettingsTests.cs)
- The [`PluginSettingsTests.cs`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker.UnitTests/PluginSettingsTests.cs) class contains tests to validate that all settings exist and that they have the correct default values.

View File

@@ -11,7 +11,8 @@
- [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)
- [Time and Date](/doc/devdocs/modules/launcher/plugins/timedate.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

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

38
doc/planning/awake.md Normal file
View File

@@ -0,0 +1,38 @@
---
last-update: 3-20-2022
---
# PowerToys Awake Changelog
## Builds
The build ID can be found in [`NLog.config`](https://github.com/microsoft/PowerToys/blob/2e3a2b3f96f67c7dfc72963e5135662d3230b5fe/src/modules/awake/Awake/NLog.config#L5) - it is a unique identifier for the current builds that allows better diagnostics (we can look up the build ID from the logs) and offers a way to triage Awake-specific issues faster independent of the PowerToys version. The build ID does not carry any significance beyond that within the PowerToys code base.
| Build ID | Build Date |
|:----------------------------------------------------------|:-----------------|
| [`LIBRARIAN_03202022`](#librarian_03202022-march-20-2022) | March 20, 2022 |
| `ARBITER_01312022` | January 31, 2022 |
### `LIBRARIAN_03202022` (March 20, 2022)
- Changed the tray context menu to be following OS conventions instead of the style offered by Windows Forms. This introduces better support for DPI scaling and theming in the future.
- Custom times in the tray can now be configured in the `settings.json` file for awake, through the `tray_times` property. The property values are representative of a `Dictionary<string, int>` and can be in the form of `"YOUR_NAME": LENGTH_IN_SECONDS`:
```json
{
"properties": {
"awake_keep_display_on": true,
"awake_mode": 2,
"awake_hours": 0,
"awake_minutes": 3,
"tray_times": {
"Custom length": 1800,
"Another custom length": 3600
}
},
"name": "Awake",
"version": "1.0"
}
```
- Proper Awake background window closure was implemented to ensure that the process collects the correct handle instead of the empty one that was previously done through `System.Diagnostics.Process.GetCurrentProcess().CloseMainWindow()`. This likely can help with the Awake process that is left hanging after PowerToys itself closes.

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

@@ -12,9 +12,6 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "logger", "..\src\common\logger\logger.vcxproj", "{D9B8FC84-322A-4F9F-BBB9-20915C47DDFD}"
EndProject
Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "PowerToysBootstrapper", "PowerToysSetup\PowerToysBootstrapper.wixproj", "{31D72625-43C1-41B1-B784-BCE4A8DC5543}"
ProjectSection(ProjectDependencies) = postProject
{022A9D30-7C4F-416D-A9DF-5FF2661CC0AD} = {022A9D30-7C4F-416D-A9DF-5FF2661CC0AD}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution

View File

@@ -20,13 +20,15 @@
SuppressRepair="yes" />
</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="HasDotnet3123" Path="[ProgramFiles64Folder]dotnet\shared\Microsoft.WindowsDesktop.App\3.1.23\System.Xaml.dll" Result="exists" />
<util:FileSearch Variable="HasDotnet603" Path="[ProgramFiles64Folder]dotnet\shared\Microsoft.WindowsDesktop.App\6.0.3\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" />
<Variable Name="InstallFolder" Type="string" Value="[ProgramFiles64Folder]PowerToys" bal:Overridable="yes"/>
<Variable Name="MsiLogFolder" Type="string" Value="[LocalAppDataFolder]\Microsoft\PowerToys\" />
<Log Disable="no" Prefix='powertoys-bootstrapper-msi-$(var.Version)' Extension=".log" />
<!-- Only install/upgrade if the version is greater or equal than the currently installed version of PowerToys, to handle the case in which PowerToys was installed from old MSI (before WiX bootstrapper was used) -->
<!-- If the previous installation is a bundle installation, just let WiX run its logic. -->
@@ -41,40 +43,42 @@
<Chain>
<ExePackage
Name="windowsdesktop-runtime-3.1.22-win-x64.exe"
Name="windowsdesktop-runtime-3.1.23-win-x64.exe"
Compressed="no"
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"
DetectCondition="HasDotnet3123"
DownloadUrl="https://download.visualstudio.microsoft.com/download/pr/0bc6a80a-3f07-411d-8ce3-17aaeb7388ac/ed1000a04fc9c8dca5af35b53263d9ae/windowsdesktop-runtime-3.1.23-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 - 3.1.22 (x64)"
ProductName="Microsoft Windows Desktop Runtime - 3.1.22 (x64)"
Size="54342024"
Version="3.1.22.30721"
Hash="08EF2F6CFDB33946061884B1CE13FA867EFBD576" />
Description="Microsoft Windows Desktop Runtime - 3.1.23 (x64)"
ProductName="Microsoft Windows Desktop Runtime - 3.1.23 (x64)"
Size="54413248"
Version="3.1.23.31022"
Hash="460D8CD07672A7B686867B0E6CF85A745005AA43" />
</ExePackage>
<ExePackage
Name="windowsdesktop-runtime-5.0.13-win-x64.exe"
Name="windowsdesktop-runtime-6.0.3-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="HasDotnet603"
DownloadUrl="https://download.visualstudio.microsoft.com/download/pr/7f3a766e-9516-4579-aaf2-2b150caa465c/d57665f880cdcce816b278a944092965/windowsdesktop-runtime-6.0.3-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.3 (x64)"
ProductName="Microsoft Windows Desktop Runtime - 6.0.3 (x64)"
Size="57153808"
Version="6.0.3.31024"
Hash="85EB71B760EBA108348824A4928ED2BA9775BE76" />
</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

@@ -75,7 +75,7 @@ UINT __stdcall ApplyModulesRegistryChangeSetsCA(MSIHANDLE hInstall)
hr = getInstallFolder(hInstall, installationFolder);
ExitOnFailure(hr, "Failed to get installFolder.");
for (const auto& changeSet : getAllModulesChangeSets(installationFolder))
for (const auto& changeSet : getAllOnByDefaultModulesChangeSets(installationFolder))
{
if (!changeSet.apply())
{

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

@@ -5,3 +5,6 @@ dotnet_diagnostic.SA1201.severity = none
# CA1303: Do not pass literals as localized parameters
dotnet_diagnostic.CA1303.severity = suggestion
# CA1051: Do not declare visible instance fields
dotnet_code_quality.ca1051.exclude_structs = true

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

@@ -153,7 +153,7 @@ bool InstallNewVersionStage2(std::wstring installer_path, std::wstring_view inst
sei.fMask = { SEE_MASK_FLAG_NO_UI | SEE_MASK_NOASYNC | SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NO_CONSOLE };
sei.lpFile = installer_path.c_str();
sei.nShow = SW_SHOWNORMAL;
std::wstring parameters = L"/passive";
std::wstring parameters = L"/passive /norestart";
sei.lpParameters = parameters.c_str();
success = ShellExecuteExW(&sei) == TRUE;

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,10 @@ 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")]
[assembly: SuppressMessage("Naming", "CA1711:Identifiers should not have incorrect suffix", Justification = "Renaming everything would be a lot of work. It does not do any harm if an EventHandler delegate ends with the suffix EventHandler. Besides this, the Rule causes some false positives.")]
[assembly: SuppressMessage("Performance", "CA1838:Avoid 'StringBuilder' parameters for P/Invokes", Justification = "We are not concerned about the performance impact of marshaling a StringBuilder")]
// 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")]
@@ -45,6 +49,10 @@ using System.Diagnostics.CodeAnalysis;
[assembly: SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Microsoft.Templates.Core.Locations.JunctionNativeMethods.ThrowLastWin32Error(System.String)", Scope = "member", Target = "Microsoft.Templates.Core.Locations.JunctionNativeMethods.#InternalGetTarget(Microsoft.Win32.SafeHandles.SafeFileHandle)", Justification = "Only used for local generation")]
[assembly: SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Microsoft.Templates.Core.Locations.JunctionNativeMethods.ThrowLastWin32Error(System.String)", Scope = "member", Target = "Microsoft.Templates.Core.Locations.JunctionNativeMethods.#OpenReparsePoint(System.String,Microsoft.Templates.Core.Locations.JunctionNativeMethods+EFileAccess)", Justification = "Only used for local generation")]
[assembly: SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Windows.Documents.InlineCollection.Add(System.String)", Scope = "member", Target = "Microsoft.Templates.UI.Extensions.TextBlockExtensions.#OnSequentialFlowStepChanged(System.Windows.DependencyObject,System.Windows.DependencyPropertyChangedEventArgs)", Justification = "No text here")]
[assembly: SuppressMessage("Globalization", "CA1309:Use ordinal string comparison", Justification = "The user's search term should be compared with culture based rules.", Scope = "type", Target = "~T:Microsoft.PowerToys.Run.Plugin.TimeDate.Components.SearchController")]
// FxCop warning suppression for uninstantiated TestFixture classes
[assembly: SuppressMessage("Microsoft.Performance", "CA1812: Avoid uninstantiated internal classes", Scope = "module", Justification = "CA1812 will be thrown for every file in the test project. This is mentioned here: dotnet/roslyn-analyzers#1830")]
// Code quality
[assembly: SuppressMessage("CodeQuality", "IDE0076:Invalid global 'SuppressMessageAttribute'", Justification = "Affect predefined supressions.")]

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

@@ -44,7 +44,7 @@ namespace DPIAware
return GetScreenDPIForMonitor(targetMonitor, dpi);
}
void Convert(HMONITOR monitor_handle, int& width, int& height)
void Convert(HMONITOR monitor_handle, float& width, float& height)
{
if (monitor_handle == NULL)
{
@@ -55,12 +55,12 @@ namespace DPIAware
UINT dpi_x, dpi_y;
if (GetDpiForMonitor(monitor_handle, MDT_EFFECTIVE_DPI, &dpi_x, &dpi_y) == S_OK)
{
width = width * static_cast<int>(dpi_x) / DEFAULT_DPI;
height = height * static_cast<int>(dpi_y) / DEFAULT_DPI;
width = width * dpi_x / DEFAULT_DPI;
height = height * dpi_y / DEFAULT_DPI;
}
}
void ConvertByCursorPosition(int& width, int& height)
void ConvertByCursorPosition(float& width, float& height)
{
HMONITOR targetMonitor = nullptr;
POINT currentCursorPos{ 0 };
@@ -73,7 +73,7 @@ namespace DPIAware
Convert(targetMonitor, width, height);
}
void InverseConvert(HMONITOR monitor_handle, int& width, int& height)
void InverseConvert(HMONITOR monitor_handle, float& width, float& height)
{
if (monitor_handle == NULL)
{
@@ -84,8 +84,8 @@ namespace DPIAware
UINT dpi_x, dpi_y;
if (GetDpiForMonitor(monitor_handle, MDT_EFFECTIVE_DPI, &dpi_x, &dpi_y) == S_OK)
{
width = width * DEFAULT_DPI / static_cast<int>(dpi_x);
height = height * DEFAULT_DPI / static_cast<int>(dpi_y);
width = width * DEFAULT_DPI / dpi_x;
height = height * DEFAULT_DPI / dpi_y;
}
}

View File

@@ -11,9 +11,9 @@ namespace DPIAware
HRESULT GetScreenDPIForWindow(HWND hwnd, UINT& dpi);
HRESULT GetScreenDPIForPoint(POINT p, UINT& dpi);
HRESULT GetScreenDPIForCursor(UINT& dpi);
void Convert(HMONITOR monitor_handle, int& width, int& height);
void ConvertByCursorPosition(int& width, int& height);
void InverseConvert(HMONITOR monitor_handle, int& width, int& height);
void Convert(HMONITOR monitor_handle, float& width, float& height);
void ConvertByCursorPosition(float& width, float& height);
void InverseConvert(HMONITOR monitor_handle, float& width, float& height);
void EnableDPIAwarenessForThisProcess();
enum AwarenessLevel

View File

@@ -1,33 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\Version.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<Platforms>x64</Platforms>
<PlatformTarget>x64</PlatformTarget>
<TargetFramework>netstandard2.0</TargetFramework>
<Version>$(Version).0</Version>
<Authors>Microsoft Corporation</Authors>
<Product>PowerToys</Product>
<Description>PowerToys ManagedCommon</Description>
<Copyright>Copyright (C) 2020 Microsoft Corporation</Copyright>
<RepositoryUrl>https://github.com/microsoft/PowerToys</RepositoryUrl>
<RepositoryType>Github</RepositoryType>
<PackageTags>PowerToys</PackageTags>
<NeutralLanguage>en-US</NeutralLanguage>
<AssemblyName>PowerToys.ManagedCommon</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</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

@@ -2,37 +2,38 @@
<Import Project="..\..\..\Version.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<Platforms>x64</Platforms>
<PlatformTarget>x64</PlatformTarget>
<TargetFramework>netstandard2.0</TargetFramework>
<Version>$(Version).0</Version>
<Authors>Microsoft Corporation</Authors>
<Product>PowerToys</Product>
<Description>PowerToys Telemetry</Description>
<Copyright>Copyright (C) 2020 Microsoft Corporation</Copyright>
<RepositoryUrl>https://github.com/microsoft/PowerToys</RepositoryUrl>
<RepositoryType>Github</RepositoryType>
<PackageTags>PowerToys</PackageTags>
<NeutralLanguage>en-US</NeutralLanguage>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<AssemblyName>PowerToys.ManagedTelemetry</AssemblyName>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\..\Telemetry\TelemetryBase.cs" Link="TelemetryBase.cs" />
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="..\..\..\codeAnalysis\StyleCop.json">
<Link>StyleCop.json</Link>
</AdditionalFiles>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="StyleCop.Analyzers">
<Version>1.1.118</Version>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\..\codeAnalysis\GlobalSuppressions.cs">
<Link>GlobalSuppressions.cs</Link>

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

@@ -17,10 +17,10 @@ namespace Microsoft.PowerToys.Telemetry
None = 0,
/// <nodoc/>
ProductAndServicePerformance = 0x0u,
ProductAndServicePerformance = 1,
/// <nodoc/>
ProductAndServiceUsage = 0x0u,
ProductAndServiceUsage = 2,
}
/// <summary>

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,87 +2,67 @@
<Import Project="..\..\..\Version.props" />
<PropertyGroup>
<TargetFramework>net5.0-windows</TargetFramework>
<TargetFramework>net6.0-windows</TargetFramework>
<IsPackable>false</IsPackable>
<RuntimeIdentifiers>win-x64</RuntimeIdentifiers>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<RuntimeIdentifiers>win-x64</RuntimeIdentifiers>
<Platforms>x64</Platforms>
<AssemblyTitle>interop-tests</AssemblyTitle>
<Company>Microsoft Corp.</Company>
<Copyright>Copyright (C) 2020 Microsoft Corp.</Copyright>
</PropertyGroup>
<PropertyGroup>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<RuntimeIdentifiers>win-x64</RuntimeIdentifiers>
<OutputType>Library</OutputType>
<RootNamespace>Microsoft.Interop.Tests</RootNamespace>
<AssemblyName>Microsoft.Interop.Tests</AssemblyName>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<RuntimeIdentifiers>win-x64</RuntimeIdentifiers>
<Platforms>x64</Platforms>
<AssemblyTitle>interop-tests</AssemblyTitle>
</PropertyGroup>
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<OutputType>Library</OutputType>
<RootNamespace>Microsoft.Interop.Tests</RootNamespace>
<AssemblyName>Microsoft.Interop.Tests</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<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">
<ItemGroup>
<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="StyleCop.Analyzers">
<Version>1.1.118</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>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\..\codeAnalysis\GlobalSuppressions.cs">
<Link>GlobalSuppressions.cs</Link>
</Compile>
</Compile>
<AdditionalFiles Include="..\..\..\codeAnalysis\StyleCop.json">
<Link>StyleCop.json</Link>
</AdditionalFiles>
<Link>StyleCop.json</Link>
</AdditionalFiles>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\PowerToys.Interop.vcxproj" />
</ItemGroup>

View File

@@ -132,7 +132,7 @@ public
auto names = gcnew List<String ^>();
for (const auto& device : MicrophoneDevice::getAllActive())
{
names->Add(gcnew String(device.name().data()));
names->Add(gcnew String(device->name().data()));
}
return names;
}

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,11 +10,17 @@ 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";
const static wchar_t* SVGExtension = L".svg";
const static std::vector<std::wstring> ExtSVG = { L".svg" };
const static std::vector<std::wstring> ExtMarkdown = { L".md", L".markdown", L".mdown", L".mkdn", L".mkd", L".mdwn", L".mdtxt", L".mdtext" };
const static std::vector<std::wstring> ExtPDF = { L".pdf" };
const static std::vector<std::wstring> ExtGCode = { L".gcode" };
const static std::vector<std::wstring> ExtSTL = { L".stl" };
const static std::vector<std::wstring> ExtNoNoNo = {
L".svgz" //Monaco cannot handle this file type at all; it's a binary file.
};
}
inline registry::ChangeSet getSvgPreviewHandlerChangeSet(const std::wstring installationDir, const bool perUser)
@@ -30,7 +36,7 @@ inline registry::ChangeSet getSvgPreviewHandlerChangeSet(const std::wstring inst
registry::DOTNET_COMPONENT_CATEGORY_CLSID,
L"Microsoft.PowerToys.PreviewHandler.Svg.SvgPreviewHandler",
L"Svg Preview Handler",
{ L".svg" });
NonLocalizable::ExtSVG);
}
inline registry::ChangeSet getMdPreviewHandlerChangeSet(const std::wstring installationDir, const bool perUser)
@@ -44,14 +50,23 @@ inline registry::ChangeSet getMdPreviewHandlerChangeSet(const std::wstring insta
registry::DOTNET_COMPONENT_CATEGORY_CLSID,
L"Microsoft.PowerToys.PreviewHandler.Markdown.MarkdownPreviewHandler",
L"Markdown Preview Handler",
{ L".md" });
NonLocalizable::ExtMarkdown);
}
inline registry::ChangeSet getMonacoPreviewHandlerChangeSet(const std::wstring installationDir, const bool perUser)
{
using namespace registry::shellex;
// Set up a list of extensions for the preview handler to take over
std::vector<std::wstring> extensions;
// Set up a list of extensions that Monaco support but the preview handler shouldn't take over
std::vector<std::wstring> ExtExclusions;
ExtExclusions.insert(ExtExclusions.end(), NonLocalizable::ExtMarkdown.begin(), NonLocalizable::ExtMarkdown.end());
ExtExclusions.insert(ExtExclusions.end(), NonLocalizable::ExtSVG.begin(), NonLocalizable::ExtSVG.end());
ExtExclusions.insert(ExtExclusions.end(), NonLocalizable::ExtNoNoNo.begin(), NonLocalizable::ExtNoNoNo.end());
bool IsExcluded = false;
std::wstring languagesFilePath = fs::path{ installationDir } / NonLocalizable::MONACO_LANGUAGES_FILE_NAME;
auto json = json::from_file(languagesFilePath);
@@ -68,13 +83,19 @@ inline registry::ChangeSet getMonacoPreviewHandlerChangeSet(const std::wstring i
for (uint32_t j = 0; j < extensionsList.Size(); ++j)
{
auto extension = extensionsList.GetStringAt(j);
// Ignore extensions we already have dedicated handlers for
if (std::wstring{ extension } == std::wstring{ NonLocalizable::MDExtension } ||
std::wstring{ extension } == std::wstring{ NonLocalizable::SVGExtension })
// Ignore extensions in the exclusion list
IsExcluded = false;
for (std::wstring k : ExtExclusions)
{
continue;
if (std::wstring{ extension } == k)
{
IsExcluded = true;
break;
}
}
if (IsExcluded) { continue; }
extensions.push_back(std::wstring{ extension });
}
}
@@ -106,7 +127,7 @@ inline registry::ChangeSet getPdfPreviewHandlerChangeSet(const std::wstring inst
registry::DOTNET_COMPONENT_CATEGORY_CLSID,
L"Microsoft.PowerToys.PreviewHandler.Pdf.PdfPreviewHandler",
L"Pdf Preview Handler",
{ L".pdf" });
NonLocalizable::ExtPDF);
}
inline registry::ChangeSet getGcodePreviewHandlerChangeSet(const std::wstring installationDir, const bool perUser)
@@ -120,7 +141,7 @@ inline registry::ChangeSet getGcodePreviewHandlerChangeSet(const std::wstring in
registry::DOTNET_COMPONENT_CATEGORY_CLSID,
L"Microsoft.PowerToys.PreviewHandler.Gcode.GcodePreviewHandler",
L"G-code Preview Handler",
{ L".gcode" });
NonLocalizable::ExtGCode);
}
inline registry::ChangeSet getSvgThumbnailHandlerChangeSet(const std::wstring installationDir, const bool perUser)
@@ -134,7 +155,8 @@ inline registry::ChangeSet getSvgThumbnailHandlerChangeSet(const std::wstring in
registry::DOTNET_COMPONENT_CATEGORY_CLSID,
L"Microsoft.PowerToys.ThumbnailHandler.Svg.SvgThumbnailProvider",
L"Svg Thumbnail Provider",
{ L".svg" });
NonLocalizable::ExtSVG,
L"Picture");
}
inline registry::ChangeSet getPdfThumbnailHandlerChangeSet(const std::wstring installationDir, const bool perUser)
@@ -148,7 +170,7 @@ inline registry::ChangeSet getPdfThumbnailHandlerChangeSet(const std::wstring in
registry::DOTNET_COMPONENT_CATEGORY_CLSID,
L"Microsoft.PowerToys.ThumbnailHandler.Pdf.PdfThumbnailProvider",
L"Pdf Thumbnail Provider",
{ L".pdf" });
NonLocalizable::ExtPDF);
}
inline registry::ChangeSet getGcodeThumbnailHandlerChangeSet(const std::wstring installationDir, const bool perUser)
@@ -162,7 +184,7 @@ inline registry::ChangeSet getGcodeThumbnailHandlerChangeSet(const std::wstring
registry::DOTNET_COMPONENT_CATEGORY_CLSID,
L"Microsoft.PowerToys.ThumbnailHandler.Gcode.GcodeThumbnailProvider",
L"G-code Thumbnail Provider",
{ L".gcode" });
NonLocalizable::ExtGCode);
}
inline registry::ChangeSet getStlThumbnailHandlerChangeSet(const std::wstring installationDir, const bool perUser)
@@ -176,7 +198,19 @@ inline registry::ChangeSet getStlThumbnailHandlerChangeSet(const std::wstring in
registry::DOTNET_COMPONENT_CATEGORY_CLSID,
L"Microsoft.PowerToys.ThumbnailHandler.Stl.StlThumbnailProvider",
L"Stl Thumbnail Provider",
{ L".stl" });
NonLocalizable::ExtSTL);
}
inline std::vector<registry::ChangeSet> getAllOnByDefaultModulesChangeSets(const std::wstring installationDir)
{
constexpr bool PER_USER = true;
return { getSvgPreviewHandlerChangeSet(installationDir, PER_USER),
getMdPreviewHandlerChangeSet(installationDir, PER_USER),
getMonacoPreviewHandlerChangeSet(installationDir, PER_USER),
getGcodePreviewHandlerChangeSet(installationDir, PER_USER),
getSvgThumbnailHandlerChangeSet(installationDir, PER_USER),
getGcodeThumbnailHandlerChangeSet(installationDir, PER_USER),
getStlThumbnailHandlerChangeSet(installationDir, PER_USER) };
}
inline std::vector<registry::ChangeSet> getAllModulesChangeSets(const std::wstring installationDir)
@@ -191,4 +225,4 @@ inline std::vector<registry::ChangeSet> getAllModulesChangeSets(const std::wstri
getPdfThumbnailHandlerChangeSet(installationDir, PER_USER),
getGcodeThumbnailHandlerChangeSet(installationDir, PER_USER),
getStlThumbnailHandlerChangeSet(installationDir, PER_USER) };
}
}

View File

@@ -69,9 +69,10 @@ namespace registry
std::wstring path;
std::optional<std::wstring> name; // none == default
value_t value;
bool required = true;
ValueChange(const HKEY scope, std::wstring path, std::optional<std::wstring> name, value_t value) :
scope{ scope }, path{ std::move(path) }, name{ std::move(name) }, value{ std::move(value) }
ValueChange(const HKEY scope, std::wstring path, std::optional<std::wstring> name, value_t value, bool required = true) :
scope{ scope }, path{ std::move(path) }, name{ std::move(name) }, value{ std::move(value) }, required{ required }
{
}
@@ -268,7 +269,7 @@ namespace registry
{
for (const auto& c : changes)
{
if (!c.isApplied())
if (c.required && !c.isApplied())
{
return false;
}
@@ -281,7 +282,7 @@ namespace registry
bool ok = true;
for (const auto& c : changes)
{
ok = c.apply() && ok;
ok = (c.apply()||!c.required) && ok;
}
return ok;
}
@@ -291,7 +292,7 @@ namespace registry
bool ok = true;
for (const auto& c : changes)
{
ok = c.unApply() && ok;
ok = (c.unApply()||!c.required) && ok;
}
return ok;
}
@@ -317,7 +318,8 @@ namespace registry
std::wstring handlerCategory,
std::wstring className,
std::wstring displayName,
std::vector<std::wstring> fileTypes)
std::vector<std::wstring> fileTypes,
std::wstring fileKindType = L"" )
{
const HKEY scope = perUser ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE;
@@ -369,6 +371,13 @@ namespace registry
fileAssociationPath += L"\\shellex\\";
fileAssociationPath += handlerType == PreviewHandlerType::preview ? IPREVIEW_HANDLER_CLSID : ITHUMBNAIL_PROVIDER_CLSID;
changes.push_back({ scope, fileAssociationPath, std::nullopt, handlerClsid });
if (!fileKindType.empty())
{
// Registering a file type as a kind needs to be done at the HKEY_LOCAL_MACHINE level.
// Make it optional as well so that we don't fail registering the handler if we can't write to HKEY_LOCAL_MACHINE.
std::wstring kindMapPath = L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\KindMap";
changes.push_back({ HKEY_LOCAL_MACHINE, kindMapPath, fileType, fileKindType, false});
}
}
if (handlerType == PreviewHandlerType::preview)

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,10 +483,22 @@ 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.
SetWindowPos(m_hwnd, HWND_TOPMOST, GetSystemMetrics(SM_XVIRTUALSCREEN), GetSystemMetrics(SM_YVIRTUALSCREEN), GetSystemMetrics(SM_CXVIRTUALSCREEN), GetSystemMetrics(SM_CYVIRTUALSCREEN), 0);
// HACK: Draw with 1 pixel off. Otherwise Windows glitches the task bar transparency when a transparent window fill the whole screen.
SetWindowPos(m_hwnd, HWND_TOPMOST, GetSystemMetrics(SM_XVIRTUALSCREEN), GetSystemMetrics(SM_YVIRTUALSCREEN), GetSystemMetrics(SM_CXVIRTUALSCREEN), GetSystemMetrics(SM_CYVIRTUALSCREEN)-1, 0);
m_sonarPos = ptNowhere;
OnMouseTimer();
UpdateMouseSnooping();
@@ -393,7 +521,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 +561,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 +582,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 +737,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 +764,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

@@ -150,8 +150,9 @@ void Highlighter::AddDrawingPoint(MouseButton button)
// Perhaps add a task to the Dispatcher every X circles to clean up.
// Get back on top in case other Window is now the topmost.
// HACK: Draw with 1 pixel off. Otherwise Windows glitches the task bar transparency when a transparent window fill the whole screen.
SetWindowPos(m_hwnd, HWND_TOPMOST, GetSystemMetrics(SM_XVIRTUALSCREEN), GetSystemMetrics(SM_YVIRTUALSCREEN),
GetSystemMetrics(SM_CXVIRTUALSCREEN), GetSystemMetrics(SM_CYVIRTUALSCREEN), 0);
GetSystemMetrics(SM_CXVIRTUALSCREEN), GetSystemMetrics(SM_CYVIRTUALSCREEN)-1, 0);
}
void Highlighter::UpdateDrawingPointPosition(MouseButton button)
@@ -259,8 +260,10 @@ void Highlighter::StartDrawing()
Logger::info("Starting draw mode.");
Trace::StartHighlightingSession();
m_visible = true;
// HACK: Draw with 1 pixel off. Otherwise Windows glitches the task bar transparency when a transparent window fill the whole screen.
SetWindowPos(m_hwnd, HWND_TOPMOST, GetSystemMetrics(SM_XVIRTUALSCREEN), GetSystemMetrics(SM_YVIRTUALSCREEN),
GetSystemMetrics(SM_CXVIRTUALSCREEN), GetSystemMetrics(SM_CYVIRTUALSCREEN), 0);
GetSystemMetrics(SM_CXVIRTUALSCREEN), GetSystemMetrics(SM_CYVIRTUALSCREEN)-1, 0);
ClearDrawing();
ShowWindow(m_hwnd, SW_SHOWNOACTIVATE);
m_mouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProc, m_hinstance, 0);

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 + halfPixelAdjustment * 2, (float)ptCursor.y + halfPixelAdjustment, .0f });
m_left_crosshairs_border.Size({ (float)ptCursor.x - (float)ptMonitorUpperLeft.x - m_crosshairs_radius + m_crosshairs_border_size + halfPixelAdjustment * 2, (float)m_crosshairs_thickness + m_crosshairs_border_size * 2 });
m_left_crosshairs.Offset({ (float)ptCursor.x - m_crosshairs_radius + halfPixelAdjustment * 2, (float)ptCursor.y + halfPixelAdjustment, .0f });
m_left_crosshairs.Size({ (float)ptCursor.x - (float)ptMonitorUpperLeft.x - m_crosshairs_radius + halfPixelAdjustment * 2, (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 + halfPixelAdjustment * 2, .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 + halfPixelAdjustment * 2 });
m_top_crosshairs.Offset({ (float)ptCursor.x + halfPixelAdjustment, (float)ptCursor.y - m_crosshairs_radius + halfPixelAdjustment * 2, .0f });
m_top_crosshairs.Size({ (float)m_crosshairs_thickness, (float)ptCursor.y - (float)ptMonitorUpperLeft.y - m_crosshairs_radius + halfPixelAdjustment * 2 });
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,12 @@ 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);
// HACK: Draw with 1 pixel off. Otherwise Windows glitches the task bar transparency when a transparent window fill the whole screen.
SetWindowPos(m_hwnd, HWND_TOPMOST, GetSystemMetrics(SM_XVIRTUALSCREEN), GetSystemMetrics(SM_YVIRTUALSCREEN), GetSystemMetrics(SM_CXVIRTUALSCREEN), GetSystemMetrics(SM_CYVIRTUALSCREEN)-1, 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 +271,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

@@ -31,7 +31,7 @@ protected:
virtual void init() = 0;
// resize - when called, window_width and window_height will have current window size
virtual void resize() = 0;
// render - called on WM_PAIT, BeginPaint/EndPaint is handled by D2DWindow
// render - called on WM_PAINT, BeginPaint/EndPaint is handled by D2DWindow
virtual void render(ID2D1DeviceContext5* d2d_dc) = 0;
// on_show, on_hide - called when the window is about to be shown or about to be hidden
virtual void on_show() = 0;

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:
@@ -379,6 +394,8 @@ void AlwaysOnTop::HandleWinHookEvent(WinHookEvent* data) noexcept
auto iter = m_topmostWindows.find(data->hwnd);
if (iter != m_topmostWindows.end())
{
// pin border again, in some cases topmost flag stops working: https://github.com/microsoft/PowerToys/issues/17332
PinTopmostWindow(data->hwnd);
AssignBorder(data->hwnd);
}
}
@@ -396,15 +413,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

@@ -27,7 +27,7 @@ public:
success = PlaySound(TEXT("Media\\Speech On.wav"), NULL, SND_FILENAME | SND_ASYNC);
break;
case Type::Off:
success = PlaySound(TEXT("Media\\Speech Off.wav"), NULL, SND_FILENAME | SND_ASYNC);
success = PlaySound(TEXT("Media\\Speech Sleep.wav"), NULL, SND_FILENAME | SND_ASYNC);
break;
default:
break;

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-windows10.0.18362.0</TargetFramework>
<OutputPath>$(SolutionDir)$(Platform)\$(Configuration)\modules\Awake</OutputPath>
<Nullable>enable</Nullable>
<Platforms>x64</Platforms>
@@ -12,9 +12,13 @@
<!--Per documentation: https://docs.microsoft.com/dotnet/core/compatibility/windows-forms/5.0/automatically-infer-winexe-output-type#outputtype-set-to-winexe-for-wpf-and-winforms-apps -->
<DisableWinExeOutputInference>true</DisableWinExeOutputInference>
<AssemblyName>PowerToys.Awake</AssemblyName>
<Company>Microsoft Corporation</Company>
<Version>$(Version).0</Version>
<ApplicationIcon>Images\Awake.ico</ApplicationIcon>
<SupportedOSPlatformVersion>10.0.18362.0</SupportedOSPlatformVersion>
<PackageProjectUrl>https://awake.den.dev</PackageProjectUrl>
<RepositoryUrl>https://github.com/microsoft/powertoys</RepositoryUrl>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<AnalysisMode>Recommended</AnalysisMode>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -22,10 +26,8 @@
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<WarningLevel>4</WarningLevel>
<Optimize>false</Optimize>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -34,17 +36,23 @@
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<None Remove="Images\Awake.ico" />
</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="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>
@@ -71,6 +79,11 @@
<Link>StyleCop.json</Link>
</AdditionalFiles>
</ItemGroup>
<ItemGroup>
<Content Include="Images\Awake.ico">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="StyleCop.Analyzers">
<Version>1.1.118</Version>
@@ -78,9 +91,4 @@
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<None Update="Images\Awake.ico">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@@ -3,34 +3,19 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
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 +70,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
{
@@ -117,9 +102,16 @@ namespace Awake.Core
_tokenSource = new CancellationTokenSource();
_threadToken = _tokenSource.Token;
_runnerThread = Task.Run(() => RunIndefiniteLoop(keepDisplayOn), _threadToken)
.ContinueWith((result) => callback(result.Result), TaskContinuationOptions.OnlyOnRanToCompletion)
.ContinueWith((result) => failureCallback, TaskContinuationOptions.NotOnRanToCompletion);
try
{
_runnerThread = Task.Run(() => RunIndefiniteLoop(keepDisplayOn), _threadToken)
.ContinueWith((result) => callback(result.Result), TaskContinuationOptions.OnlyOnRanToCompletion)
.ContinueWith((result) => failureCallback, TaskContinuationOptions.NotOnRanToCompletion);
}
catch (Exception ex)
{
_log.Error(ex.Message);
}
}
public static void SetNoKeepAwake()
@@ -168,11 +160,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
@@ -199,6 +191,26 @@ namespace Awake.Core
}
}
internal static void CompleteExit(int exitCode, bool force = false)
{
APIHelper.SetNoKeepAwake();
TrayHelper.ClearTray();
// Because we are running a message loop for the tray, we can't just use Environment.Exit,
// but have to make sure that we properly send the termination message.
IntPtr windowHandle = APIHelper.GetHiddenWindow();
if (windowHandle != IntPtr.Zero)
{
NativeMethods.SendMessage(windowHandle, NativeConstants.WM_CLOSE, 0, string.Empty);
}
if (force)
{
Environment.Exit(exitCode);
}
}
private static bool RunTimedLoop(uint seconds, bool keepDisplayOn = true)
{
bool success = false;
@@ -209,11 +221,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)
@@ -280,5 +292,54 @@ namespace Awake.Core
return string.Empty;
}
}
[SuppressMessage("Performance", "CA1806:Do not ignore method results", Justification = "Function returns DWORD value that identifies the current thread, but we do not need it.")]
public static IEnumerable<IntPtr> EnumerateWindowsForProcess(int processId)
{
var handles = new List<IntPtr>();
IntPtr hCurrentWnd = IntPtr.Zero;
do
{
hCurrentWnd = NativeMethods.FindWindowEx(IntPtr.Zero, hCurrentWnd, null, null);
NativeMethods.GetWindowThreadProcessId(hCurrentWnd, out uint targetProcessId);
if (targetProcessId == processId)
{
handles.Add(hCurrentWnd);
}
}
while (hCurrentWnd != IntPtr.Zero);
return handles;
}
[SuppressMessage("Globalization", "CA1305:Specify IFormatProvider", Justification = "In this context, the string is only converted to a hex value.")]
public static IntPtr GetHiddenWindow()
{
IEnumerable<IntPtr> windowHandles = EnumerateWindowsForProcess(Environment.ProcessId);
var domain = AppDomain.CurrentDomain.GetHashCode().ToString("x");
string targetClass = $"{InternalConstants.TrayWindowId}{domain}";
foreach (var handle in windowHandles)
{
StringBuilder className = new (256);
int classQueryResult = NativeMethods.GetClassName(handle, className, className.Capacity);
if (classQueryResult != 0 && className.ToString().StartsWith(targetClass, StringComparison.InvariantCultureIgnoreCase))
{
return handle;
}
}
return IntPtr.Zero;
}
public static Dictionary<string, int> GetDefaultTrayOptions()
{
Dictionary<string, int> optionsList = new Dictionary<string, int>();
optionsList.Add("30 minutes", 1800);
optionsList.Add("1 hour", 3600);
optionsList.Add("2 hours", 7200);
return optionsList;
}
}
}

View File

@@ -0,0 +1,30 @@
// 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;
using System.Collections.Generic;
namespace Awake.Core
{
internal static class ExtensionMethods
{
public static void AddRange<T>(this ICollection<T> target, IEnumerable<T> source)
{
if (target == null)
{
throw new ArgumentNullException(nameof(target));
}
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
foreach (var element in source)
{
target.Add(element);
}
}
}
}

View File

@@ -8,5 +8,6 @@ namespace Awake.Core
{
internal const string AppName = "Awake";
internal const string FullAppName = "PowerToys " + AppName;
internal const string TrayWindowId = "WindowsForms10.Window.0.app.0.";
}
}

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,
}
}

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