Compare commits

..

32 Commits

Author SHA1 Message Date
Alekhya
2ba99d14e1 Launcher hot fixes (#4003)
* Add resource only when it is not already present (#3842)

(cherry picked from commit d2dfbff832)

* Take space into consideration while calculating the first matched index (#3874)

(cherry picked from commit a8d67a1c60)

* Fix for File explorer not showing up and multiple notepads (#3969)

* reverted the dedup code, file explorer shows up but so do duplicates

* Fixed file explorer and dedup

* Formatting

* Added tests for all the cases

* Formatting

* Tests

* take name and exe into consideration while calculating hash

* unique primes while calculating hash code

(cherry picked from commit 8cddd595d4)
2020-06-03 09:11:39 -07:00
Enrico Giordani
bbbbf0954d [CDPx] publish symbols (#4016) 2020-06-03 09:11:11 -07:00
Enrico Giordani
f81ccdda3d [runner] Change way of dropping privileges to start PT Run 2020-06-01 20:42:50 +02:00
Enrico Giordani
ef7285fb9a Now working on 0.18.2 (#3542) 2020-06-01 20:42:50 +02:00
Clint Rutkas
e75a74565b Update README.md 2020-05-22 10:21:43 -07:00
vldmr11080
1792849b98 Expose InMoveSize from WindowMoveHandler. (#3525) 2020-05-22 16:42:29 +02:00
ricardosantos9521
c7fb1f6d17 bug fix #3209 (#3457)
Co-authored-by: ricar <ricar@ASUS>
2020-05-21 11:02:03 -07:00
Enrico Giordani
a856263081 [PowerToys Run] run non-elevated when runner is elevated (#3451)
* run Launcher non-elevated

* Implemented acquiring PID of Launcher

Co-authored-by: ivan100sic <ivan100sic@gmail.com>
2020-05-21 19:44:32 +02:00
Ivan Stošić
582d1320a3 [KBM] Fix compilation error 2020-05-21 11:06:50 +02:00
Josh Soref
3789da4305 Use check boxes (#3396) 2020-05-20 22:53:12 -07:00
sakariya
a36f97adfb Dev/saahmedm/fixlabel (#3366)
* Update EditShortcutsWindow.cpp

* Update EditKeyboardWindow.cpp

* Update README.md

* Update EditShortcutsWindow.cpp

* Update EditShortcutsWindow.cpp
2020-05-20 14:52:10 -07:00
Tim De Pauw
2cda53d3af Capitalize GitHub properly (#3356) 2020-05-20 14:28:25 -07:00
Bret
74007ea465 Merge pull request #3360 from microsoft/TheMrJukes-patch-1
Delete README.md
2020-05-20 14:10:37 -07:00
Bret
c88a7dba6b Delete README.md
This is no longer accurate and also talks about internal shares which we shouldn't do publically
2020-05-20 13:17:16 -07:00
Clint Rutkas
66b7863d43 Update README.md 2020-05-20 12:21:37 -07:00
Clint Rutkas
19b318a488 Update README.md (#3355) 2020-05-20 12:15:31 -07:00
ryanbodrug-microsoft
c606e3db43 Disabling IsRightTapEnabled on all UI Elements that steal focus from the text box. (#3349) 2020-05-20 11:38:14 -07:00
wolf99
f89ab74b29 Add 1903 requirement (#3321)
Have not seen this requirement mentioned anywhere until PowerToys is already installed.
For those installing PowerToys specifically to try this, it would be useful to know the requirement in advance, especially given that https://github.com/microsoft/PowerToys/blob/master/README.md mentions only 1803.
2020-05-20 11:20:11 -07:00
Clint Rutkas
4bbdec5044 Update README.md 2020-05-20 11:05:53 -07:00
Arjun Balgovind
56a727cf0d Added check for Type key/shortcut open but not in focus (#3235) 2020-05-20 09:56:00 -07:00
Arjun Balgovind
32f74e41ef Fix publish on local machines (#3270)
* Moved publishing to publish.cmd script

* Moved publish back to pre-build event
2020-05-20 09:55:17 -07:00
Ivan Stošić
e249bc5856 [FancyZones] Fix a regression with Chrome tabs jamming FZ (#3338) 2020-05-20 18:52:48 +02:00
Arjun Balgovind
32b8a344a6 Moved publishing to publish.cmd script (#3259) 2020-05-20 09:35:02 -07:00
Clint Rutkas
61c0c35e92 Fix for 3116, changing uwp to packaged (#3123) 2020-05-20 09:17:46 -07:00
Andrey Nekrasov
2eecaf4570 Revert "[FancyZones] Remove "keep windows pinned to virtual desktop location" settings (#3093)" (#3292)
This reverts commit 8f59247acb.
2020-05-20 11:57:17 +03:00
vldmr11080
8f59247acb [FancyZones] Remove "keep windows pinned to virtual desktop location" settings (#3093)
* Remove keep windows pinned to virtual desktop location FancyZones settings

* Remove virtual desktop switch handling for this scenario.
2020-05-20 10:49:28 +02:00
Clint Rutkas
eb3ec26279 fixing images so they deep link to module overview versus the img in readme (#3240)
* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md
2020-05-19 17:12:35 -07:00
Alekhya
f07d37ce0d [launcher] - Increase the score for Exact matches in the Name of the Application (#3213)
* Increase score for exact matches in the name

* Added tests for exact matching

* Used TestCase

* variable for bonus score

* Removed comment, variable is self explanatory
2020-05-19 16:10:40 -07:00
Alexander Sklar
2e8602eb43 Update win_hook_event_data.h (#3092) 2020-05-19 15:07:06 -07:00
Cloud Han
4277041b0e correct url (#3142) 2020-05-19 10:29:06 -07:00
Enrico Giordani
6801190180 Now working on 0.18.1 (#3141) 2020-05-19 18:20:35 +02:00
Clint Rutkas
067a9cf54d Dev/crutkas/change log0.18 (#3138)
* Update README.md

* Update README.md

* Update README.md

* Update README.md
2020-05-19 08:48:53 -07:00
41 changed files with 742 additions and 282 deletions

View File

@@ -6,11 +6,11 @@
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [] Applies to #xxx
* [] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/PowerToys) and sign the CLA
* [] Tests added/passed
* [] Requires documentation to be updated
* [] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx
* [ ] Applies to #xxx
* [ ] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/PowerToys) and sign the CLA
* [ ] Tests added/passed
* [ ] Requires documentation to be updated
* [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx
<!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments

View File

@@ -1,4 +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
SET IsPipeline=1
call msbuild ../installer/PowerToysSetup.sln /p:Configuration=Release /p:Platform=x64 || exit /b 1

View File

@@ -4,3 +4,5 @@ call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Too
call msbuild ../PowerToys.sln /p:Configuration=Release /p:Platform=x64 || exit /b 1
call msbuild ../src/common/notifications/notifications_dll.vcxproj /p:Configuration=Release /p:Platform=x64 || exit /b 1
call msbuild ../src/common/notifications_winrt/notifications.vcxproj /p:Configuration=Release /p:Platform=x64 || exit /b 1
SET PTRoot=..
call "..\installer\PowerToysSetup\publish.cmd"

View File

@@ -41,6 +41,11 @@ build:
name: 'Build Power Toys'
command: '.pipelines\build.cmd'
artifacts:
- to: 'Symbols'
include:
- 'x64/**/*.pdb'
exclude:
- 'x64/Release/obj/**/*.pdb'
- from: 'x64/Release'
to: 'Build_Output'
include:
@@ -127,20 +132,6 @@ build:
- 'PowerToysSetup-*.msi'
signing_options:
sign_inline: true # This does signing a soon as this command completes
# - !!buildcommand
# name: 'Archive symbols to Symbol Server'
# artifacts:
# - to: 'x64 Symbols'
# include:
# - 'x64/Release/action_runner.pdb'
# - 'x64/Release/Notifications.pdb'
# - 'x64/Release/PowerRenameUWPUI.pdb'
# - 'x64/Release/PowerToys.pdb'
# - 'x64/Release/PowerToysSettings.pdb'
# - 'x64/Release/modules/fancyzones.pdb'
# - 'x64/Release/modules/FancyZonesEditor.pdb'
# - 'x64/Release/modules/PowerRenameExt.pdb'
# - 'x64/Release/modules/shortcut_guide.pdb'
package:
commands:

View File

@@ -14,7 +14,7 @@ Microsoft PowerToys is a set of utilities for power users to tune and streamline
### FancyZones
<img align="left" src="./doc/images/overview/FancyZones_small.png" />[FancyZones](/src/modules/fancyzones/) is a window manager that makes it easy to create complex window layouts and quickly position windows into those layouts.
[<img align="left" src="./doc/images/overview/FancyZones_small.png" />](/src/modules/fancyzones/) [FancyZones](/src/modules/fancyzones/) is a window manager that makes it easy to create complex window layouts and quickly position windows into those layouts.
<br>
<br>
<br>
@@ -23,7 +23,7 @@ Microsoft PowerToys is a set of utilities for power users to tune and streamline
### Shortcut Guide
<img align="left" src="./doc/images/overview/Shortcut guide_small.png" />[Windows key shortcut guide](/src/modules/shortcut_guide) appears when a user holds the Windows key down for more than one second and shows the available shortcuts for the current state of the desktop.
[<img align="left" src="./doc/images/overview/Shortcut guide_small.png" />](/src/modules/shortcut_guide) [Windows key shortcut guide](/src/modules/shortcut_guide) appears when a user holds the Windows key down for more than one second and shows the available shortcuts for the current state of the desktop.
<br>
<br>
<br>
@@ -32,66 +32,67 @@ Microsoft PowerToys is a set of utilities for power users to tune and streamline
### PowerRename
<img align="left" src="./doc/images/overview/PowerRename_small.PNG" />[PowerRename](/src/modules/powerrename) is a Windows Shell Extension for advanced bulk renaming using search and replace or regular expressions. PowerRename allows simple search and replace or more advanced regular expression matching. While you type in the search and replace input fields, the preview area will show what the items will be renamed to. PowerRename then calls into the Windows Explorer file operations engine to perform the rename. This has the benefit of allowing the rename operation to be undone after PowerRename exits. This code is based on [Chris Davis's SmartRename](https://github.com/chrdavis/SmartRename).
[<img align="left" src="./doc/images/overview/PowerRename_small.PNG" />](/src/modules/powerrename) [PowerRename](/src/modules/powerrename) is a Windows Shell Extension for advanced bulk renaming using search and replace or regular expressions. PowerRename allows simple search and replace or more advanced regular expression matching. While you type in the search and replace input fields, the preview area will show what the items will be renamed to. PowerRename then calls into the Windows Explorer file operations engine to perform the rename. This has the benefit of allowing the rename operation to be undone after PowerRename exits. This code is based on [Chris Davis's SmartRename](https://github.com/chrdavis/SmartRename).
<br>
<br>
### File Explorer (Preview Panes)
<img align="left" src="./doc/images/overview/PowerPreview_small.PNG" />[File Explorer](/src/modules/previewpane) add-ons right now are just limited to Preview Pane additions for File Explorer. Preview Pane is an existing feature in the File Explorer. To enable it, you just click the View tab in the ribbon and then click "Preview Pane".
[<img align="left" src="./doc/images/overview/PowerPreview_small.PNG" />](/src/modules/previewpane) [File Explorer](/src/modules/previewpane) add-ons right now are just limited to Preview Pane additions for File Explorer. Preview Pane is an existing feature in the File Explorer. To enable it, you just click the View tab in the ribbon and then click "Preview Pane".
PowerToys will now enable two types of files to be previewed: Markdown (.md) & SVG (.svg)
<br>
<br>
<br>
### Image Resizer
<img align="left" src="./doc/images/overview/ImageResizer_small.png" />[Image Resizer](/src/modules/imageresizer) is a Windows Shell Extension for quickly resizing images. With a simple right click from File Explorer, resize one or many images instantly. This code is based on [Brice Lambson's Image Resizer](https://github.com/bricelam/ImageResizer).
[<img align="left" src="./doc/images/overview/ImageResizer_small.png" />](/src/modules/imageresizer) [Image Resizer](/src/modules/imageresizer) is a Windows Shell Extension for quickly resizing images. With a simple right click from File Explorer, resize one or many images instantly. This code is based on [Brice Lambson's Image Resizer](https://github.com/bricelam/ImageResizer).
<br>
<br>
<br>
<br>
<!---
### Keyboard Manager
<img align="left" src="./doc/images/overview/KBM_small.png" /> [Keyboard Manager](src/modules/keyboardmanager/) allows you to customize the keyboard to be more productive by remapping keys and creating your own keyboard shortcuts.
[<img align="left" src="./doc/images/overview/KBM_small.png" />](src/modules/keyboardmanager/) [Keyboard Manager](src/modules/keyboardmanager/) allows you to customize the keyboard to be more productive by remapping keys and creating your own keyboard shortcuts. This PowerToy requires Windows 10 1903 (build 18362) or later.
<br>
<br>
<br>
<br>
<br>
-->
<!---
### PowerToys Run
<img align="left" src="./doc/images/overview/PowerLauncher_small.png" /> [PowerToys Run](src/modules/launcher/) is a new toy in PowerToys that can help you search and launch your app instantly! It is open source and modular for additional plugins. Window Walker is now inside!
[<img align="left" src="./doc/images/overview/PowerLauncher_small.png" />](src/modules/launcher/) [PowerToys Run](src/modules/launcher/) is a new toy in PowerToys that can help you search and launch your app instantly with a simple alt-space and start typing! It is open source and modular for additional plugins. Window Walker is now inside too! This PowerToy requires Windows 10 1903 (build 18362) or later.
<br>
<br>
<br>
<br>
<br>
<br>
-->
### Version 1.0 plan
Our plan for all the [goals and utilities for v1.0 detailed over here in the wiki][v1].
## Installing and running Microsoft PowerToys
👉 **Note:** Microsoft PowerToys requires Windows 10 1803 (build 17134) or later.
**Requirements:**
- Microsoft PowerToys requires Windows 10 1803 (build 17134) or later.
- Have [.NET Core 3.1 Desktop Runtime](https://dotnet.microsoft.com/download/dotnet-core/thank-you/runtime-desktop-3.1.4-windows-x64-installer). The installer will prompt this but we want to directly make people aware.
### Via Github with MSI [Recommended]
Install from the [Microsoft PowerToys GitHub releases page][github-release-link]. Click on `Assets` to show the files available in the release and then click on `PowerToysSetup-0.17.0-x64.msi` to download the PowerToys installer.
Install from the [Microsoft PowerToys GitHub releases page][github-release-link]. Click on `Assets` to show the files available in the release and then click on `PowerToysSetup-0.18.1-x64.msi` to download the PowerToys installer.
**Note:** After installing, you will have to start PowerToys for the first time. We will improve install experience this moving forward but due to a possible install dependency, we can't start after install currently.
This is our preferred method.
### Via WinGet (Preview)
Download PowerToys from [WinGet](https://github.com/microsoft/winget-cli/releases). To install PowerToys, run the following command from the command line / PowerShell:
```powershell
WinGet install powertoys
```
### Other install methods
#### Via Chocolatey - ⚠ Unofficial
#### Via Chocolatey (Unofficial)
Download and upgrade PowerToys from [Chocolatey](https://chocolatey.org). If you have any issues when installing/upgrading the package please go to the [package page](https://chocolatey.org/packages/powertoys) and follow the [Chocolatey triage process](https://chocolatey.org/docs/package-triage-process)
@@ -117,29 +118,30 @@ We currently support the matrix below.
## What's Happening
### April 2020 Update
### May 2020 Update
Our goals for 0.17 release cycle were updatability and stability.
Our goals for 0.18 release cycle was three big items, PowerToys Run, Keyboard manager, and migrating to the new settings system. This is also the first time we'll test out the auto-updating system.
**Auto-updating:** We just added in the code for doing updating, so the first chance to experience this will be when 0.18 is released. Were also seeing how aggressive everyone wants with this so right now, youll have to click “Install” for it to kick off the installer. This is something wed love feedback on.
Feedback is critical. We know there are areas for improvement on PT Run. We would love feedback so we can improve. We also would love to know if you want us to be more aggressive on auto-upgrading.
Another thing we did was utilized telemetry from PowerToys to prioritize virtual desktop FancyZone work. We knew there was a subset of bugs caused by an underlying issue and seeing how many users it affected helped us reprioritize to do the work sooner.
- We shipped [v0.17][github-release-link]!
- Auto-updating
- FancyZone improvement:
- Virtual desktop support should be much better!
- Better taskbar positioning
- Fixed non-admin install regression.
- We shipped [v0.18][github-release-link]!
- New Utilities
- PowerToys Run, our new application launcher (use alt-space to activate)
- Keyboard manager, a quick easy way to remap your keyboard
- Fixed [#243](https://github.com/microsoft/PowerToys/issues/243)'s setting issue
- Improved performance on FancyZones [#1264](https://github.com/microsoft/PowerToys/issues/1264)
- Lots of bug fixes!
For [0.18](https://github.com/microsoft/PowerToys/issues?q=is%3Aopen+is%3Aissue+project%3Amicrosoft%2FPowerToys%2F4), we are proactively working on:
For [0.19](https://github.com/microsoft/PowerToys/issues?q=is%3Aopen+is%3Aissue+project%3Amicrosoft%2FPowerToys%2F4), we are proactively working on:
- Win+R replacement (Launcher)
- Keyboard remapping
- Enable PT Run to be mapped to Win-Keys
- Stability / tech debt fixes
- Performance improvements with FancyZones
- A testing utility for FancyZones to be sure we can test different window configurations.
- Settings v2 / Fix bug #243
### Version 1.0 plan
Our plan for all the [goals and utilities for v1.0 detailed over here in the wiki][v1].
## Developer Guidance

View File

@@ -69,75 +69,11 @@
</PropertyGroup>
<Error Condition="!Exists('..\packages\WiX.3.11.2\build\wix.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\WiX.3.11.2\build\wix.props'))" />
</Target>
<PropertyGroup>
<PreBuildEvent>setlocal enableDelayedExpansion
rem Publish Settings
SET settingsProfileFolderName=..\..\..\..\src\core\Microsoft.PowerToys.Settings.UI.Runner\Properties\PublishProfiles\
rem Create the publish profile folder if it doesn%27t exist
IF NOT EXIST !settingsProfileFolderName! (mkdir !settingsProfileFolderName!)
SET settingsProfileFileName=SettingsProfile.pubxml
SET settingsPublishProfile=!settingsProfileFolderName!!settingsProfileFileName!
rem Create the publish profile pubxml
echo ^&lt;%3fxml version="1.0" encoding="utf-8"%3f^&gt; &gt; !settingsPublishProfile!
echo ^&lt;^^!-- &gt;&gt; !settingsPublishProfile!
echo https://go.microsoft.com/fwlink/%3fLinkID=208121. &gt;&gt; !settingsPublishProfile!
echo --^&gt; &gt;&gt; !settingsPublishProfile!
echo ^&lt;Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"^&gt; &gt;&gt; !settingsPublishProfile!
echo ^&lt;PropertyGroup^&gt; &gt;&gt; !settingsPublishProfile!
echo ^&lt;PublishProtocol^&gt;FileSystem^&lt;/PublishProtocol^&gt; &gt;&gt; !settingsPublishProfile!
echo ^&lt;Configuration^&gt;$(ConfigurationName)^&lt;/Configuration^&gt; &gt;&gt; !settingsPublishProfile!
echo ^&lt;Platform^&gt;$(PlatformName)^&lt;/Platform^&gt; &gt;&gt; !settingsPublishProfile!
echo ^&lt;TargetFramework^&gt;netcoreapp3.1^&lt;/TargetFramework^&gt; &gt;&gt; !settingsPublishProfile!
echo ^&lt;PublishDir^&gt;..\..\..\$(PlatformName)\$(ConfigurationName)\SettingsUIRunner^&lt;/PublishDir^&gt; &gt;&gt; !settingsPublishProfile!
echo ^&lt;RuntimeIdentifier^&gt;win-x64^&lt;/RuntimeIdentifier^&gt; &gt;&gt; !settingsPublishProfile!
echo ^&lt;SelfContained^&gt;false^&lt;/SelfContained^&gt; &gt;&gt; !settingsPublishProfile!
echo ^&lt;PublishSingleFile^&gt;False^&lt;/PublishSingleFile^&gt; &gt;&gt; !settingsPublishProfile!
echo ^&lt;PublishReadyToRun^&gt;False^&lt;/PublishReadyToRun^&gt; &gt;&gt; !settingsPublishProfile!
echo ^&lt;/PropertyGroup^&gt; &gt;&gt; !settingsPublishProfile!
echo ^&lt;/Project^&gt; &gt;&gt; !settingsPublishProfile!
rem In case of Release we should not use Debug CRT in VCRT forwarders
IF $(ConfigurationName)==Release (
"$(MSBuildBinPath)\msbuild.exe" ..\..\..\..\src\core\Microsoft.PowerToys.Settings.UI.Runner\Microsoft.PowerToys.Settings.UI.Runner.csproj -t:Publish -p:Configuration="$(ConfigurationName)" -p:Platform="$(PlatformName)" -p:AppxBundle=Never -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=!settingsProfileFileName!
) ELSE (
"$(MSBuildBinPath)\msbuild.exe" ..\..\..\..\src\core\Microsoft.PowerToys.Settings.UI.Runner\Microsoft.PowerToys.Settings.UI.Runner.csproj -t:Publish -p:Configuration="$(ConfigurationName)" -p:Platform="$(PlatformName)" -p:AppxBundle=Never -p:PublishProfile=!settingsProfileFileName!
)
rem Publish Launcher
SET launcherProfileFolderName=..\..\..\..\src\modules\launcher\PowerLauncher\Properties\PublishProfiles\
rem Create the publish profile folder if it doesn%27t exist
IF NOT EXIST !launcherProfileFolderName! (mkdir !launcherProfileFolderName!)
SET launcherProfileFileName=LauncherProfile.pubxml
SET launcherPublishProfile=!launcherProfileFolderName!!launcherProfileFileName!
rem Create the publish profile pubxml
echo ^&lt;%3fxml version="1.0" encoding="utf-8"%3f^&gt; &gt; !launcherPublishProfile!
echo ^&lt;^^!-- &gt;&gt; !launcherPublishProfile!
echo https://go.microsoft.com/fwlink/%3fLinkID=208121. &gt;&gt; !launcherPublishProfile!
echo --^&gt; &gt;&gt; !launcherPublishProfile!
echo ^&lt;Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"^&gt; &gt;&gt; !launcherPublishProfile!
echo ^&lt;PropertyGroup^&gt; &gt;&gt; !launcherPublishProfile!
echo ^&lt;PublishProtocol^&gt;FileSystem^&lt;/PublishProtocol^&gt; &gt;&gt; !launcherPublishProfile!
echo ^&lt;Configuration^&gt;$(ConfigurationName)^&lt;/Configuration^&gt; &gt;&gt; !launcherPublishProfile!
echo ^&lt;Platform^&gt;$(PlatformName)^&lt;/Platform^&gt; &gt;&gt; !launcherPublishProfile!
echo ^&lt;TargetFramework^&gt;netcoreapp3.1^&lt;/TargetFramework^&gt; &gt;&gt; !launcherPublishProfile!
echo ^&lt;PublishDir^&gt;..\..\..\..\$(PlatformName)\$(ConfigurationName)\modules\launcher^&lt;/PublishDir^&gt; &gt;&gt; !launcherPublishProfile!
echo ^&lt;RuntimeIdentifier^&gt;win-x64^&lt;/RuntimeIdentifier^&gt; &gt;&gt; !launcherPublishProfile!
echo ^&lt;SelfContained^&gt;false^&lt;/SelfContained^&gt; &gt;&gt; !launcherPublishProfile!
echo ^&lt;PublishSingleFile^&gt;False^&lt;/PublishSingleFile^&gt; &gt;&gt; !launcherPublishProfile!
echo ^&lt;PublishReadyToRun^&gt;False^&lt;/PublishReadyToRun^&gt; &gt;&gt; !launcherPublishProfile!
echo ^&lt;/PropertyGroup^&gt; &gt;&gt; !launcherPublishProfile!
echo ^&lt;/Project^&gt; &gt;&gt; !launcherPublishProfile!
rem In case of Release we should not use Debug CRT in VCRT forwarders
IF $(ConfigurationName)==Release (
"$(MSBuildBinPath)\msbuild.exe" ..\..\..\..\src\modules\launcher\PowerLauncher\PowerLauncher.csproj -t:Publish -p:Configuration="$(ConfigurationName)" -p:Platform="$(PlatformName)" -p:AppxBundle=Never -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=!launcherProfileFileName!
) ELSE (
"$(MSBuildBinPath)\msbuild.exe" ..\..\..\..\src\modules\launcher\PowerLauncher\PowerLauncher.csproj -t:Publish -p:Configuration="$(ConfigurationName)" -p:Platform="$(PlatformName)" -p:AppxBundle=Never -p:PublishProfile=!launcherProfileFileName!
<PreBuildEvent>IF NOT DEFINED IsPipeline (
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64 -winsdk=10.0.18362.0
SET PTRoot=..\..\..\..
call "..\..\publish.cmd"
)</PreBuildEvent>
</PropertyGroup>
<!--

View File

@@ -0,0 +1,63 @@
setlocal enableDelayedExpansion
IF NOT DEFINED PTRoot (SET PTRoot=..\..)
rem Publish Settings
SET settingsProfileFolderName=!PTRoot!\src\core\Microsoft.PowerToys.Settings.UI.Runner\Properties\PublishProfiles\
rem Create the publish profile folder if it doesn't exist
IF NOT EXIST !settingsProfileFolderName! (mkdir !settingsProfileFolderName!)
SET settingsProfileFileName=SettingsProfile.pubxml
SET settingsPublishProfile=!settingsProfileFolderName!!settingsProfileFileName!
rem Create the publish profile pubxml
echo ^<?xml version="1.0" encoding="utf-8"?^> > !settingsPublishProfile!
echo ^<^^!-- >> !settingsPublishProfile!
echo https://go.microsoft.com/fwlink/?LinkID=208121. >> !settingsPublishProfile!
echo --^> >> !settingsPublishProfile!
echo ^<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"^> >> !settingsPublishProfile!
echo ^<PropertyGroup^> >> !settingsPublishProfile!
echo ^<PublishProtocol^>FileSystem^</PublishProtocol^> >> !settingsPublishProfile!
echo ^<Configuration^>Release^</Configuration^> >> !settingsPublishProfile!
echo ^<Platform^>x64^</Platform^> >> !settingsPublishProfile!
echo ^<TargetFramework^>netcoreapp3.1^</TargetFramework^> >> !settingsPublishProfile!
echo ^<PublishDir^>..\..\..\x64\Release\SettingsUIRunner^</PublishDir^> >> !settingsPublishProfile!
echo ^<RuntimeIdentifier^>win-x64^</RuntimeIdentifier^> >> !settingsPublishProfile!
echo ^<SelfContained^>false^</SelfContained^> >> !settingsPublishProfile!
echo ^<PublishSingleFile^>False^</PublishSingleFile^> >> !settingsPublishProfile!
echo ^<PublishReadyToRun^>False^</PublishReadyToRun^> >> !settingsPublishProfile!
echo ^</PropertyGroup^> >> !settingsPublishProfile!
echo ^</Project^> >> !settingsPublishProfile!
rem In case of Release we should not use Debug CRT in VCRT forwarders
msbuild !PTRoot!\src\core\Microsoft.PowerToys.Settings.UI.Runner\Microsoft.PowerToys.Settings.UI.Runner.csproj -t:Publish -p:Configuration="Release" -p:Platform="x64" -p:AppxBundle=Never -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=!settingsProfileFileName!
rem Publish Launcher
SET launcherProfileFolderName=!PTRoot!\src\modules\launcher\PowerLauncher\Properties\PublishProfiles\
rem Create the publish profile folder if it doesn't exist
IF NOT EXIST !launcherProfileFolderName! (mkdir !launcherProfileFolderName!)
SET launcherProfileFileName=LauncherProfile.pubxml
SET launcherPublishProfile=!launcherProfileFolderName!!launcherProfileFileName!
rem Create the publish profile pubxml
echo ^<?xml version="1.0" encoding="utf-8"?^> > !launcherPublishProfile!
echo ^<^^!-- >> !launcherPublishProfile!
echo https://go.microsoft.com/fwlink/?LinkID=208121. >> !launcherPublishProfile!
echo --^> >> !launcherPublishProfile!
echo ^<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"^> >> !launcherPublishProfile!
echo ^<PropertyGroup^> >> !launcherPublishProfile!
echo ^<PublishProtocol^>FileSystem^</PublishProtocol^> >> !launcherPublishProfile!
echo ^<Configuration^>Release^</Configuration^> >> !launcherPublishProfile!
echo ^<Platform^>x64^</Platform^> >> !launcherPublishProfile!
echo ^<TargetFramework^>netcoreapp3.1^</TargetFramework^> >> !launcherPublishProfile!
echo ^<PublishDir^>..\..\..\..\x64\Release\modules\launcher^</PublishDir^> >> !launcherPublishProfile!
echo ^<RuntimeIdentifier^>win-x64^</RuntimeIdentifier^> >> !launcherPublishProfile!
echo ^<SelfContained^>false^</SelfContained^> >> !launcherPublishProfile!
echo ^<PublishSingleFile^>False^</PublishSingleFile^> >> !launcherPublishProfile!
echo ^<PublishReadyToRun^>False^</PublishReadyToRun^> >> !launcherPublishProfile!
echo ^</PropertyGroup^> >> !launcherPublishProfile!
echo ^</Project^> >> !launcherPublishProfile!
rem In case of Release we should not use Debug CRT in VCRT forwarders
msbuild !PTRoot!\src\modules\launcher\PowerLauncher\PowerLauncher.csproj -t:Publish -p:Configuration="Release" -p:Platform="x64" -p:AppxBundle=Never -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=!launcherProfileFileName!

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Version>0.18.0</Version>
<Version>0.18.2</Version>
<DefineConstants>Version=$(Version);</DefineConstants>
</PropertyGroup>
</Project>

View File

@@ -186,7 +186,25 @@ int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
}
std::wstring_view action{ args[1] };
if (action == L"-install_dotnet")
if (action == L"-start_PowerLauncher")
{
HANDLE hMapFile = OpenFileMappingW(FILE_MAP_WRITE, FALSE, POWER_LAUNCHER_PID_SHARED_FILE);
if (hMapFile)
{
PDWORD pidBuffer = reinterpret_cast<PDWORD>(MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(DWORD)));
if (pidBuffer)
{
*pidBuffer = 0;
run_same_elevation(L"modules\\launcher\\PowerLauncher.exe", L"", pidBuffer);
FlushViewOfFile(pidBuffer, sizeof(DWORD));
UnmapViewOfFile(pidBuffer);
}
FlushFileBuffers(hMapFile);
CloseHandle(hMapFile);
}
}
else if (action == L"-install_dotnet")
{
if (dotnet_is_installed())
{

View File

@@ -461,7 +461,7 @@ bool run_elevated(const std::wstring& file, const std::wstring& params)
}
}
bool run_non_elevated(const std::wstring& file, const std::wstring& params)
bool run_non_elevated(const std::wstring& file, const std::wstring& params, DWORD* returnPid)
{
auto executable_args = L"\"" + file + L"\"";
if (!params.empty())
@@ -510,8 +510,8 @@ bool run_non_elevated(const std::wstring& file, const std::wstring& params)
siex.lpAttributeList = pptal;
siex.StartupInfo.cb = sizeof(siex);
PROCESS_INFORMATION process_info = { 0 };
auto succedded = CreateProcessW(file.c_str(),
PROCESS_INFORMATION pi = { 0 };
auto succeeded = CreateProcessW(file.c_str(),
const_cast<LPWSTR>(executable_args.c_str()),
nullptr,
nullptr,
@@ -520,28 +520,38 @@ bool run_non_elevated(const std::wstring& file, const std::wstring& params)
nullptr,
nullptr,
&siex.StartupInfo,
&process_info);
if (process_info.hProcess)
&pi);
if (succeeded)
{
CloseHandle(process_info.hProcess);
if (pi.hProcess)
{
if (returnPid)
{
*returnPid = GetProcessId(pi.hProcess);
}
CloseHandle(pi.hProcess);
}
if (pi.hThread)
{
CloseHandle(pi.hThread);
}
}
if (process_info.hThread)
{
CloseHandle(process_info.hThread);
}
return succedded;
return succeeded;
}
bool run_same_elevation(const std::wstring& file, const std::wstring& params)
bool run_same_elevation(const std::wstring& file, const std::wstring& params, DWORD* returnPid)
{
auto executable_args = L"\"" + file + L"\"";
if (!params.empty())
{
executable_args += L" " + params;
}
STARTUPINFO si = { 0 };
PROCESS_INFORMATION pi = { 0 };
auto succedded = CreateProcessW(file.c_str(),
auto succeeded = CreateProcessW(file.c_str(),
const_cast<LPWSTR>(executable_args.c_str()),
nullptr,
nullptr,
@@ -551,15 +561,26 @@ bool run_same_elevation(const std::wstring& file, const std::wstring& params)
nullptr,
&si,
&pi);
if (pi.hProcess)
if (succeeded)
{
CloseHandle(pi.hProcess);
if (pi.hProcess)
{
if (returnPid)
{
*returnPid = GetProcessId(pi.hProcess);
}
CloseHandle(pi.hProcess);
}
if (pi.hThread)
{
CloseHandle(pi.hThread);
}
}
if (pi.hThread)
{
CloseHandle(pi.hThread);
}
return succedded;
return succeeded;
}
std::wstring get_process_path(HWND window) noexcept

View File

@@ -69,11 +69,11 @@ bool drop_elevated_privileges();
// Run command as elevated user, returns true if succeeded
bool run_elevated(const std::wstring& file, const std::wstring& params);
// Run command as non-elevated user, returns true if succeeded
bool run_non_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
bool run_non_elevated(const std::wstring& file, const std::wstring& params, DWORD* returnPid);
// Run command with the same elevation, returns true if succedded
bool run_same_elevation(const std::wstring& file, const std::wstring& params);
// Run command with the same elevation, returns true if succeeded
bool run_same_elevation(const std::wstring& file, const std::wstring& params, DWORD* returnPid);
// Returns true if the current process is running from administrator account
bool check_user_is_admin();
@@ -136,3 +136,5 @@ struct overloaded : Ts...
};
template<class... Ts>
overloaded(Ts...)->overloaded<Ts...>;
#define POWER_LAUNCHER_PID_SHARED_FILE L"Local\\3cbfbad4-199b-4e2c-9825-942d5d3d3c74"

View File

@@ -14,7 +14,7 @@ namespace Microsoft.PowerLauncher.Telemetry
/// <summary>
/// Gets The version string. TODO: This should be replaced by a P/Invoke call to get_product_version
/// </summary>
public string Version => "v0.18.0";
public string Version => "v0.18.2";
public double BootTimeMs { get; set; }

View File

@@ -14,7 +14,7 @@
<RepositoryUrl>https://github.com/microsoft/PowerToys</RepositoryUrl>
<RepositoryType>Github</RepositoryType>
<PackageTags>PowerToys</PackageTags>
<Version>0.15.2.0</Version>
<Version>0.18.2.0</Version>
<Platforms>x64</Platforms>
<ApplicationIcon>icon.ico</ApplicationIcon>
<Win32Resource />

View File

@@ -9,7 +9,7 @@
<Identity
Name="f4f787a5-f0ae-47a9-be89-5408b1dd2b47"
Publisher="CN=lamotile"
Version="0.15.2.0" />
Version="0.18.2.0" />
<mp:PhoneIdentity PhoneProductId="f4f787a5-f0ae-47a9-be89-5408b1dd2b47" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>

View File

@@ -573,7 +573,7 @@
<value>About Shortcut Guide</value>
</data>
<data name="General_Repository.Text" xml:space="preserve">
<value>Github repository</value>
<value>GitHub repository</value>
</data>
<data name="General_Updates.Text" xml:space="preserve">
<value>Updates</value>

View File

@@ -1,53 +0,0 @@
# Introduction
Super FancyZones! Just like FancyZones except super.
# Getting Started
Grab FancyZones.exe from the bin directory or \\\\wexfs\users\bretan\proto\superfancyzones and run it
## Dragging windows
* While dragging a window around, zones will appear that the window can be dropped in. Dropping the window in a zone will position it in the zone.
* While dragging a window, you can hit number keys to cycle the active zone set. Eg, drag a window around and hit the '3' key will change to a zone set with 3 zones.
## Hotkeys
* Win+~ - opens the zone viewer/editor
* Win+ctrl+number - cycle through layouts with the corresponding number of zones (only if Override snap hotkeys setting is enabled)
* Win+left arrow, Win+right arrow - move foreground window between zones
## Zone Viewer/Editor (Win + ~)
* Hitting a number key cycles through layouts matching the number of zones (eg 3 cycles through layouts with 3 zones)
* R resets the focused monitor back to defaults
* C clears the current layout so you can start fresh
* W opens a dialog to choose wallpaper
* Left click moves the zone to the top
* Right click moves the zone to the bottom
### E enters editor mode (hit E or Escape to exit editor mode)
* Left/Right/Up/Down arrows adjust the grid spacing
* PgUp/PgDn adjust grid margins
* Ctrl+left click splits the clicked zone in half horizontally
* Ctrl+right click splits the clicked zone in half vertically
# Options
### Default Drag Mode
* None - don't do anything when dragging windows around (shift enters normal mode, ctrl enters adjusted mode)
* Normal - show zones when dragging windows around (shift disables, ctrl enters adjusted mode)
* Adjusted - show zones when dragging windows around with an accelerated cursor
### Display change
* Move windows - automatically move windows around when display changes
### Virtual Desktop change
* Move windows - automatically move windows around when virtual desktop changes
* Change wallpaper - use custom wallpaper per-monitor per-desktop
* Flash zones - flash zones on each monitor
### Miscellaneous
* Override snap hotkeys - steal hotkeys normally used by shell (win+left/right, win+ctrl+num)
* Colorful zones - use colored zones in zone viewer
# Known issues
* See open bugs for full list of issues
* Win+left and Win+right don't move between monitors
* If you use Virtual Desktops, make sure to perform at least one virtual desktop switch before launching the fancyzones (it relies on a volatile regkey that explorer writes)
* Sometimes you have to click on a zone viewer window before it gets keyboard focus when opening views with Win+~
* Quickly switching virtual desktops with win+ctrl+arrow hotkeys can crash fancyzones

View File

@@ -55,14 +55,6 @@ public:
IFACEMETHODIMP_(void)
Destroy() noexcept;
// IFancyZonesCallback
IFACEMETHODIMP_(bool)
InMoveSize() noexcept
{
std::shared_lock readLock(m_lock);
return m_windowMoveHandler.InMoveSize();
}
void MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen) noexcept
{
std::unique_lock writeLock(m_lock);
@@ -185,6 +177,13 @@ public:
return m_settings->GetSettings()->makeDraggedWindowTransparent;
}
IFACEMETHODIMP_(bool)
InMoveSize() noexcept
{
std::shared_lock readLock(m_lock);
return m_windowMoveHandler.InMoveSize();
}
LRESULT WndProc(HWND, UINT, WPARAM, LPARAM) noexcept;
void OnDisplayChange(DisplayChangeType changeType) noexcept;
void AddZoneWindow(HMONITOR monitor, PCWSTR deviceId) noexcept;

View File

@@ -81,9 +81,13 @@ interface __declspec(uuid("{5C8D99D6-34B2-4F4A-A8E5-7483F6869775}")) IZoneWindow
*/
IFACEMETHOD_(int, GetZoneHighlightOpacity)() = 0;
/**
* @returns Bool indicating if dragged window should be transparrent
* @returns Boolean indicating if dragged window should be transparrent.
*/
IFACEMETHOD_(bool, isMakeDraggedWindowTransparentActive) () = 0;
/**
* @returns Boolean indicating if move/size operation is currently active.
*/
IFACEMETHOD_(bool, InMoveSize) () = 0;
};
winrt::com_ptr<IFancyZones> MakeFancyZones(HINSTANCE hinstance, const winrt::com_ptr<IFancyZonesSettings>& settings) noexcept;

View File

@@ -522,6 +522,10 @@ ZoneWindow::ShowZoneWindow() noexcept
std::thread{ [=]() {
AnimateWindow(window, m_showAnimationDuration, AW_BLEND);
InvalidateRect(window, nullptr, true);
if (!m_host->InMoveSize())
{
HideZoneWindow();
}
} }.detach();
}

View File

@@ -47,6 +47,11 @@ namespace FancyZonesUnitTests
{
return true;
}
IFACEMETHODIMP_(bool)
InMoveSize() noexcept
{
return true;
}
IZoneWindow* m_zoneWindow;
};

View File

@@ -31,7 +31,7 @@
return 0;
}
Taking to long to process the events has negative impact on the whole system
Taking too long to process the events has negative impact on the whole system
performance. To address this, the events are signaled from a different
thread, not from the event hook callback itself.
*/

View File

@@ -11,7 +11,7 @@ To create mappings with Keyboard Manager, you have the option of launching eithe
## 1.2 Remap Keys
To remap a key to another key, click the <kbd>Remap a Key</kbd> button to launch the Remap Keyboard UI. When first launched, you are met with no predefined mappings and must click the <kbd>+</kbd> button to add a new remap. From there, select the key whose output you want to ***change*** as the “Original Key” and then keys new output as the “New Key”. For example, if you want to press <kbd>A</kbd> and have <kbd>B</kbd> appear, Key <kbd>A</kbd> would be your “Original Key” and Key <kbd>B</kbd> would be your “New Key. If you want to swap keys, add another remapping with Key <kbd>B</kbd> as your Original and Key <kbd>A</kbd> as your New.
To remap a key to another key, click the <kbd>Remap a Key</kbd> button to launch the Remap Keyboard UI. When first launched, you are met with no predefined mappings and must click the <kbd>+</kbd> button to add a new remap. From there, select the key whose output you want to ***change*** as the “Key” and then keys new output as the “Mapped To”. For example, if you want to press <kbd>A</kbd> and have <kbd>B</kbd> appear, Key <kbd>A</kbd> would be your “Key” and Key <kbd>B</kbd> would be your “Mapped To" key. If you want to swap keys, add another remapping with Key <kbd>B</kbd> as your "Key" and Key <kbd>A</kbd> as your "Mapped To".
![alt text][remapkey]
@@ -19,8 +19,8 @@ To remap a key to another key, click the <kbd>Remap a Key</kbd> button to launch
Currently you are only able to remap global level shortcuts (they apply to your whole OS), but **app-specific shortcuts are coming soon!**
To change how you invoke a particular shortcut, click the <kbd>Remap a shortcut</kbd> button to
launch the Remap Shortcuts UI. When first launched, you are met with no predefined mappings and must click the <kbd>+</kbd> button to add a new remap. The Original shortcut is the shortcut you want to change and the New Shortcut is the shortcut you want to change it
to. Ex. If you want <kbd>Ctrl</kbd>+<kbd>C</kbd> to paste, <kbd>Ctrl</kbd>+<kbd>C</kbd> is the Original Shortcut and <kbd>Ctrl</kbd>+<kbd>V</kbd> is the New Shortcut. Here are a few rules to shortcuts as you get started:
launch the Remap Shortcuts UI. When first launched, you are met with no predefined mappings and must click the <kbd>+</kbd> button to add a new remap. The "Shortcut" is the shortcut you want to change and the "Mapped To" is the shortcut you want to change it
to. Ex. If you want <kbd>Ctrl</kbd>+<kbd>C</kbd> to paste, <kbd>Ctrl</kbd>+<kbd>C</kbd> is the "Shortcut" and <kbd>Ctrl</kbd>+<kbd>V</kbd> is the "Mapped To". Here are a few rules to shortcuts as you get started:
- Shortcuts must begin with a modifier key (<kbd>Ctrl</kbd>, <kbd>Shift</kbd>, <kbd>Alt</kbd>, <kbd>![alt text][winlogo]</kbd>)
- Shortcuts must end with an action key (all non-modifier keys)

View File

@@ -38,6 +38,16 @@ bool KeyboardManagerState::CheckUIState(KeyboardManagerUIState state)
return true;
}
}
// If we are checking for EditKeyboardWindowActivated then it's possible the state could be DetectSingleKeyRemapWindowActivated but not in focus
else if (state == KeyboardManagerUIState::EditKeyboardWindowActivated && uiState == KeyboardManagerUIState::DetectSingleKeyRemapWindowActivated)
{
return true;
}
// If we are checking for EditShortcutsWindowActivated then it's possible the state could be DetectShortcutWindowActivated but not in focus
else if (state == KeyboardManagerUIState::EditShortcutsWindowActivated && uiState == KeyboardManagerUIState::DetectShortcutWindowActivated)
{
return true;
}
return false;
}

View File

@@ -232,13 +232,13 @@ void createEditKeyboardWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMan
// Text block for information about remap key section.
TextBlock keyRemapInfoHeader;
keyRemapInfoHeader.Text(L"Select the key you want to change (Original Key) and the key you want it to become (New Key).");
keyRemapInfoHeader.Text(L"Select the key you want to change (Key) and the key you want it to become (Mapped To).");
keyRemapInfoHeader.Margin({ 10, 0, 0, 10 });
keyRemapInfoHeader.FontWeight(Text::FontWeights::SemiBold());
keyRemapInfoHeader.TextWrapping(TextWrapping::Wrap);
TextBlock keyRemapInfoExample;
keyRemapInfoExample.Text(L"For example, if you want to press A and get B, Key A would be your \"Original Key\" and Key B would be your \"New Key\".");
keyRemapInfoExample.Text(L"For example, if you want to press A and get B, Key A would be your \"Key\" and Key B would be your \"Mapped To\".");
keyRemapInfoExample.Margin({ 10, 0, 0, 20 });
keyRemapInfoExample.FontStyle(Text::FontStyle::Italic);
keyRemapInfoExample.TextWrapping(TextWrapping::Wrap);
@@ -265,13 +265,13 @@ void createEditKeyboardWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMan
// First header textblock in the header row of the keys remap table
TextBlock originalKeyRemapHeader;
originalKeyRemapHeader.Text(L"Original Key:");
originalKeyRemapHeader.Text(L"Key:");
originalKeyRemapHeader.FontWeight(Text::FontWeights::Bold());
originalKeyRemapHeader.Margin({ 0, 0, 0, 10 });
// Second header textblock in the header row of the keys remap table
TextBlock newKeyRemapHeader;
newKeyRemapHeader.Text(L"New Key:");
newKeyRemapHeader.Text(L"Mapped To:");
newKeyRemapHeader.FontWeight(Text::FontWeights::Bold());
newKeyRemapHeader.Margin({ 0, 0, 0, 10 });

View File

@@ -144,13 +144,13 @@ void createEditShortcutsWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMa
// Text block for information about remap key section.
TextBlock shortcutRemapInfoHeader;
shortcutRemapInfoHeader.Text(L"Select shortcut you want to change (Original Shortcut) and the shortcut (New Shortcut) you want it to invoke.");
shortcutRemapInfoHeader.Text(L"Select shortcut you want to change (Shortcut) and the shortcut you want it to invoke (Mapped To).");
shortcutRemapInfoHeader.Margin({ 10, 0, 0, 10 });
shortcutRemapInfoHeader.FontWeight(Text::FontWeights::SemiBold());
shortcutRemapInfoHeader.TextWrapping(TextWrapping::Wrap);
TextBlock shortcutRemapInfoExample;
shortcutRemapInfoExample.Text(L"For example, if you want Ctrl+C to paste, Ctrl+C is the Original Shortcut and Ctrl+V is the New Shortcut.");
shortcutRemapInfoExample.Text(L"For example, if you want Ctrl+C to paste, Ctrl+C is the \"Shortcut\" and Ctrl+V would be your \"Mapped To\".");
shortcutRemapInfoExample.Margin({ 10, 0, 0, 20 });
shortcutRemapInfoExample.FontStyle(Text::FontStyle::Italic);
shortcutRemapInfoExample.TextWrapping(TextWrapping::Wrap);
@@ -178,13 +178,13 @@ void createEditShortcutsWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMa
// First header textblock in the header row of the shortcut table
TextBlock originalShortcutHeader;
originalShortcutHeader.Text(L"Original Shortcut:");
originalShortcutHeader.Text(L"Shortcut:");
originalShortcutHeader.FontWeight(Text::FontWeights::Bold());
originalShortcutHeader.Margin({ 0, 0, 0, 10 });
// Second header textblock in the header row of the shortcut table
TextBlock newShortcutHeader;
newShortcutHeader.Text(L"New Shortcut:");
newShortcutHeader.Text(L"Mapped To:");
newShortcutHeader.FontWeight(Text::FontWeights::Bold());
newShortcutHeader.Margin({ 0, 0, 0, 10 });

View File

@@ -3,6 +3,7 @@
#include <interface/lowlevel_keyboard_event_data.h>
#include <interface/win_hook_event_data.h>
#include <common/settings_objects.h>
#include <common/common.h>
#include "trace.h"
#include "resource.h"
@@ -131,13 +132,49 @@ public:
// Enable the powertoy
virtual void enable()
{
SHELLEXECUTEINFO sei{ sizeof(sei) };
sei.fMask = { SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI };
sei.lpFile = L"modules\\launcher\\PowerLauncher.exe";
sei.nShow = SW_SHOWNORMAL;
ShellExecuteEx(&sei);
if (!is_process_elevated(false))
{
SHELLEXECUTEINFOW sei{ sizeof(sei) };
sei.fMask = { SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI };
sei.lpFile = L"modules\\launcher\\PowerLauncher.exe";
sei.nShow = SW_SHOWNORMAL;
ShellExecuteExW(&sei);
m_hProcess = sei.hProcess;
m_hProcess = sei.hProcess;
}
else
{
std::wstring action_runner_path = get_module_folderpath();
action_runner_path += L"\\action_runner.exe";
// Set up the shared file from which to retrieve the PID of PowerLauncher
HANDLE hMapFile = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(DWORD), POWER_LAUNCHER_PID_SHARED_FILE);
if (hMapFile)
{
PDWORD pidBuffer = reinterpret_cast<PDWORD>(MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(DWORD)));
if (pidBuffer)
{
*pidBuffer = 0;
m_hProcess = NULL;
if (run_non_elevated(action_runner_path, L"-start_PowerLauncher", nullptr))
{
const int maxRetries = 20;
for (int retry = 0; retry < maxRetries; ++retry)
{
Sleep(50);
DWORD pid = *pidBuffer;
if (pid)
{
m_hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
break;
}
}
}
}
CloseHandle(hMapFile);
}
}
m_enabled = true;
}

View File

@@ -36,11 +36,12 @@ namespace Microsoft.Plugin.Indexer.SearchHelper
{
while (WDSResults.Read())
{
if(WDSResults.GetValue(0) != DBNull.Value && WDSResults.GetValue(1) != DBNull.Value)
if (WDSResults.GetValue(0) != DBNull.Value && WDSResults.GetValue(1) != DBNull.Value)
{
var uri_path = new Uri(WDSResults.GetString(0));
var result = new SearchResult
{
Path = WDSResults.GetString(0),
Path = uri_path.LocalPath,
Title = WDSResults.GetString(1)
};
_Result.Add(result);
@@ -90,7 +91,7 @@ namespace Microsoft.Plugin.Indexer.SearchHelper
queryHelper.QueryMaxResults = maxCount;
// Set list of columns we want to display, getting the path presently
queryHelper.QuerySelectColumns = "System.ItemPathDisplay, System.FileName";
queryHelper.QuerySelectColumns = "System.ItemUrl, System.FileName";
// Set additional query restriction
queryHelper.QueryWhereRestrictions = "AND scope='file:'";

View File

@@ -279,7 +279,7 @@ namespace Microsoft.Plugin.Program.Programs
var result = new Result
{
SubTitle = "UWP application",
SubTitle = "Packaged application",
Icon = Logo,
Score = score,
ContextData = this,
@@ -449,6 +449,10 @@ namespace Microsoft.Plugin.Program.Programs
{
parsed = prefix + "//" + key;
}
else if (key.Contains("resources", StringComparison.OrdinalIgnoreCase))
{
parsed = prefix + key;
}
else
{
parsed = prefix + "///resources/" + key;

View File

@@ -443,6 +443,46 @@ namespace Microsoft.Plugin.Program.Programs
return entry;
}
public class removeDuplicatesComparer : IEqualityComparer<Win32>
{
public bool Equals(Win32 app1, Win32 app2)
{
if(!string.IsNullOrEmpty(app1.Name) && !string.IsNullOrEmpty(app2.Name)
&& !string.IsNullOrEmpty(app1.ExecutableName) && !string.IsNullOrEmpty(app2.ExecutableName)
&& !string.IsNullOrEmpty(app1.FullPath) && !string.IsNullOrEmpty(app2.FullPath))
{
return app1.Name.Equals(app2.Name, StringComparison.OrdinalIgnoreCase)
&& app1.ExecutableName.Equals(app2.ExecutableName, StringComparison.OrdinalIgnoreCase)
&& app1.FullPath.Equals(app2.FullPath, StringComparison.OrdinalIgnoreCase);
}
return false;
}
// Ref : https://stackoverflow.com/questions/2730865/how-do-i-calculate-a-good-hash-code-for-a-list-of-strings
public int GetHashCode(Win32 obj)
{
int namePrime = 13;
int executablePrime = 17;
int fullPathPrime = 31;
int result = 1;
result = result * namePrime + obj.Name.GetHashCode();
result = result * executablePrime + obj.ExecutableName.GetHashCode();
result = result * fullPathPrime + obj.FullPath.GetHashCode();
return result;
}
}
// Deduplication code
public static Func<ParallelQuery<Win32>, Win32[]> DeduplicatePrograms = (programs) =>
{
var uniqueExePrograms = programs.Where(x => !string.IsNullOrEmpty(x.LnkResolvedPath) || Extension(x.FullPath) != ExeExtension);
var uniquePrograms = uniqueExePrograms.Distinct(new removeDuplicatesComparer());
return uniquePrograms.ToArray();
};
public static Win32[] All(Settings settings)
{
try
@@ -464,15 +504,7 @@ namespace Microsoft.Plugin.Program.Programs
programs = programs.Concat(startMenu);
}
var programsWithoutLnk = programs.Where(x => string.IsNullOrEmpty(x.LnkResolvedPath));
var programsAsList = programs.ToList();
foreach(var app in programsWithoutLnk)
{
programsAsList.RemoveAll(x => (x.FullPath == app.FullPath) && string.IsNullOrEmpty(x.LnkResolvedPath));
}
return programsAsList.ToArray();
return DeduplicatePrograms(programs);
}
#if DEBUG //This is to make developer aware of any unhandled exception and add in handling.
catch (Exception e)

View File

@@ -10,7 +10,7 @@ namespace Microsoft.PowerLauncher.Telemetry
/// <summary>
/// TODO: This should be replaced by a P/Invoke call to get_product_version
/// </summary>
public string Version => "v0.18.0";
public string Version => "v0.18.2";
public double BootTimeMs { get; set; }

View File

@@ -34,6 +34,115 @@
</Setter>
</Style>
<Style x:Key="ListViewItemNoRightTap" TargetType="ListViewItem">
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
<Setter Property="Background" Value="{ThemeResource ListViewItemBackground}" />
<Setter Property="Foreground" Value="{ThemeResource ListViewItemForeground}" />
<Setter Property="TabNavigation" Value="Local" />
<Setter Property="IsHoldingEnabled" Value="True" />
<Setter Property="IsRightTapEnabled" Value="False" />
<Setter Property="Padding" Value="12,0,12,0" />
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="MinWidth" Value="{ThemeResource ListViewItemMinWidth}" />
<Setter Property="MinHeight" Value="{ThemeResource ListViewItemMinHeight}" />
<Setter Property="AllowDrop" Value="False" />
<Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}" />
<Setter Property="FocusVisualMargin" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<ListViewItemPresenter IsRightTapEnabled="False" ContentTransitions="{TemplateBinding ContentTransitions}"
x:Name="Root"
Control.IsTemplateFocusTarget="True"
FocusVisualMargin="{TemplateBinding FocusVisualMargin}"
SelectionCheckMarkVisualEnabled="{ThemeResource ListViewItemSelectionCheckMarkVisualEnabled}"
CheckBrush="{ThemeResource ListViewItemCheckBrush}"
CheckBoxBrush="{ThemeResource ListViewItemCheckBoxBrush}"
DragBackground="{ThemeResource ListViewItemDragBackground}"
DragForeground="{ThemeResource ListViewItemDragForeground}"
FocusBorderBrush="{ThemeResource ListViewItemFocusBorderBrush}"
FocusSecondaryBorderBrush="{ThemeResource ListViewItemFocusSecondaryBorderBrush}"
PlaceholderBackground="{ThemeResource ListViewItemPlaceholderBackground}"
PointerOverBackground="{ThemeResource ListViewItemBackgroundPointerOver}"
PointerOverForeground="{ThemeResource ListViewItemForegroundPointerOver}"
SelectedBackground="{ThemeResource ListViewItemBackgroundSelected}"
SelectedForeground="{ThemeResource ListViewItemForegroundSelected}"
SelectedPointerOverBackground="{ThemeResource ListViewItemBackgroundSelectedPointerOver}"
PressedBackground="{ThemeResource ListViewItemBackgroundPressed}"
SelectedPressedBackground="{ThemeResource ListViewItemBackgroundSelectedPressed}"
DisabledOpacity="{ThemeResource ListViewItemDisabledThemeOpacity}"
DragOpacity="{ThemeResource ListViewItemDragThemeOpacity}"
ReorderHintOffset="{ThemeResource ListViewItemReorderHintThemeOffset}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
ContentMargin="{TemplateBinding Padding}"
CheckMode="{ThemeResource ListViewItemCheckMode}"
RevealBackground="{ThemeResource ListViewItemRevealBackground}"
RevealBorderThickness="{ThemeResource ListViewItemRevealBorderThemeThickness}"
RevealBorderBrush="{ThemeResource ListViewItemRevealBorderBrush}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Selected" />
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Target="Root.(RevealBrush.State)" Value="PointerOver" />
<Setter Target="Root.RevealBorderBrush" Value="{ThemeResource ListViewItemRevealBorderBrushPointerOver}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PointerOverSelected">
<VisualState.Setters>
<Setter Target="Root.(RevealBrush.State)" Value="PointerOver" />
<Setter Target="Root.RevealBorderBrush" Value="{ThemeResource ListViewItemRevealBorderBrushPointerOver}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PointerOverPressed">
<VisualState.Setters>
<Setter Target="Root.(RevealBrush.State)" Value="Pressed" />
<Setter Target="Root.RevealBorderBrush" Value="{ThemeResource ListViewItemRevealBorderBrushPressed}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Pressed">
<VisualState.Setters>
<Setter Target="Root.(RevealBrush.State)" Value="Pressed" />
<Setter Target="Root.RevealBorderBrush" Value="{ThemeResource ListViewItemRevealBorderBrushPressed}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PressedSelected">
<VisualState.Setters>
<Setter Target="Root.(RevealBrush.State)" Value="Pressed" />
<Setter Target="Root.RevealBorderBrush" Value="{ThemeResource ListViewItemRevealBorderBrushPressed}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="DisabledStates">
<VisualState x:Name="Enabled" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Target="Root.RevealBorderThickness" Value="0" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</ListViewItemPresenter>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="IconOnlyButton" TargetType="Button">
<Setter Property="Background" Value="{ThemeResource ButtonRevealBackground}" />
<!--<Setter Property="Foreground" Value="{ThemeResource PrimaryTextColor}" />-->
@@ -50,7 +159,7 @@
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid x:Name="RootGrid" Background="Transparent" CornerRadius="{TemplateBinding CornerRadius}">
<Grid x:Name="RootGrid" IsRightTapEnabled="False" Background="Transparent" CornerRadius="{TemplateBinding CornerRadius}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
@@ -98,7 +207,7 @@
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="ContentPresenter" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0" CornerRadius="{TemplateBinding CornerRadius}" Content="{TemplateBinding Content}" ContentTransitions="{TemplateBinding ContentTransitions}" ContentTemplate="{TemplateBinding ContentTemplate}" Padding="{TemplateBinding Padding}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" AutomationProperties.AccessibilityView="Raw" />
<ContentPresenter x:Name="ContentPresenter" IsRightTapEnabled="False" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0" CornerRadius="{TemplateBinding CornerRadius}" Content="{TemplateBinding Content}" ContentTransitions="{TemplateBinding ContentTransitions}" ContentTemplate="{TemplateBinding ContentTemplate}" Padding="{TemplateBinding Padding}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" AutomationProperties.AccessibilityView="Raw" />
</Grid>

View File

@@ -20,7 +20,7 @@
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GridViewItem">
<ListViewItemPresenter x:Name="Root" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}">
<ListViewItemPresenter x:Name="Root" IsRightTapEnabled="False" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
@@ -46,6 +46,7 @@
<Grid
x:Name="PowerBar"
Background="{ThemeResource BackdropAcrylicBrush}"
IsRightTapEnabled="False"
VerticalAlignment="Top">
<ListView
@@ -55,15 +56,18 @@
MinHeight="{Binding Results.MaxHeight}"
AllowFocusOnInteraction="False"
IsItemClickEnabled="True"
IsRightTapEnabled="False"
RightTapped="SuggestionsList_RightTapped"
Margin="0"
Padding="{ThemeResource AutoSuggestListPadding}"
ItemsSource="{Binding Results.Results, Mode=OneWay}"
SelectionMode="Single"
SelectedIndex="{Binding Results.SelectedIndex, Mode=TwoWay}"
Style="{StaticResource ListViewNoAnimations}">
Style="{StaticResource ListViewNoAnimations}"
ItemContainerStyle="{StaticResource ListViewItemNoRightTap}">
<ListView.ItemTemplate>
<DataTemplate >
<Grid Height="72" Width="642" Background="Transparent" RowSpacing="0">
<Grid IsRightTapEnabled ="False" Height="72" Width="642" Background="Transparent" RowSpacing="0">
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="PointerEntered">
<Core:InvokeCommandAction Command="{Binding ActivateContextButtonsHoverCommand}"/>
@@ -81,9 +85,9 @@
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Image x:Name="AppIcon" Height="36" MaxWidth="56" Grid.RowSpan="2" Margin="-8,0,0,0" HorizontalAlignment="Center" Source="{Binding Image}" />
<TextBlock x:Name="Title" Grid.Column="1" Text="{Binding Result.Title}" FontWeight="SemiBold" FontSize="20" Margin="0,0,0,-2" VerticalAlignment="Bottom"/>
<TextBlock x:Name="Path" Grid.Column="1" Text= "{Binding Result.SubTitle}" Grid.Row="1" Opacity="0.6" Margin="0,2,0,0" VerticalAlignment="Top"/>
<Image x:Name="AppIcon" IsRightTapEnabled ="False" Height="36" MaxWidth="56" Grid.RowSpan="2" Margin="-8,0,0,0" HorizontalAlignment="Center" Source="{Binding Image}" />
<TextBlock x:Name="Title" IsRightTapEnabled ="False" Grid.Column="1" Text="{Binding Result.Title}" FontWeight="SemiBold" FontSize="20" Margin="0,0,0,-2" VerticalAlignment="Bottom"/>
<TextBlock x:Name="Path" IsRightTapEnabled ="False" Grid.Column="1" Text= "{Binding Result.SubTitle}" Grid.Row="1" Opacity="0.6" Margin="0,2,0,0" VerticalAlignment="Top"/>
<GridView
ItemContainerStyle="{StaticResource CommandButtonGridViewItemContainerStyle}"
HorizontalAlignment="Right"
@@ -97,15 +101,17 @@
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ItemsSource="{Binding ContextMenuItems}"
SelectionMode="Single"
SelectedIndex="{Binding ContextMenuSelectedIndex}">
SelectedIndex="{Binding ContextMenuSelectedIndex}"
ContainerContentChanging="GridView_ContainerContentChanging"
IsRightTapEnabled ="False">
<GridView.ItemTemplate>
<DataTemplate>
<Button Command="{Binding Command}" VerticalAlignment="Center" CornerRadius="4" Height="42" Width="42" BorderThickness="1" Style="{ThemeResource IconOnlyButton}" Click="ContextButton_OnClick">
<Button IsRightTapEnabled ="False" Command="{Binding Command}" VerticalAlignment="Center" CornerRadius="4" Height="42" Width="42" BorderThickness="1" Style="{ThemeResource IconOnlyButton}" Click="ContextButton_OnClick">
<ToolTipService.ToolTip>
<TextBlock Text="{Binding Title}"/>
<TextBlock x:Name="ToolTip" Loaded="ToolTip_Loaded" IsRightTapEnabled="False" Text="{Binding Title}"/>
</ToolTipService.ToolTip>
<Button.Content>
<FontIcon FontFamily="{Binding FontFamily}" FontSize="16" Glyph="{Binding Glyph}"/>
<FontIcon x:Name="FontIcon" Loaded="FontIcon_Loaded" IsRightTapEnabled="False" FontFamily="{Binding FontFamily}" FontSize="16" Glyph="{Binding Glyph}"/>
</Button.Content>
<Button.KeyboardAccelerators>
<KeyboardAccelerator

View File

@@ -2,8 +2,10 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
@@ -89,5 +91,74 @@ namespace PowerLauncher.UI
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
private void SuggestionsList_RightTapped(object sender, Windows.UI.Xaml.Input.RightTappedRoutedEventArgs e)
{
Debug.WriteLine($"Right Tap was triggered on {e.OriginalSource}");
}
private void FontIcon_Loaded(object sender, RoutedEventArgs e)
{
DisableRightClick(sender);
}
private void ToolTip_Loaded(object sender, RoutedEventArgs e)
{
DisableRightClick(sender);
}
private void GridView_ContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args)
{
DisableRightClick(sender);
}
private void DisableRightClick(object o)
{
var element = o as UIElement;
if (element != null)
{
DisableRightClick(element, isRecursive: true);
}
}
public void DisableRightClick(UIElement element, bool isRecursive)
{
element.IsRightTapEnabled = false;
if (isRecursive)
{
var children = FindChildren<UIElement>(element);
foreach (var child in children)
{
child.IsRightTapEnabled = false;
}
}
}
private static List<T> FindChildren<T>(DependencyObject startNode, List<T> results = null)
where T : DependencyObject
{
if (results == null)
{
results = new List<T>();
}
int count = VisualTreeHelper.GetChildrenCount(startNode);
for (int i = 0; i < count; i++)
{
DependencyObject current = VisualTreeHelper.GetChild(startNode, i);
if ((current.GetType()).Equals(typeof(T)) || (current.GetType().GetTypeInfo().IsSubclassOf(typeof(T))))
{
T asType = (T)current;
results.Add(asType);
}
FindChildren<T>(current, results);
}
return results;
}
}
}

View File

@@ -6,7 +6,11 @@ modular for additional plugins. Press Alt+Space and start typing!
![](../../../doc/images/Launcher/QuickStart.gif)
# 1\. Get Started
## 1\.1 Features
## 1\.1 Requirements
- Windows 10 version 1903 or higher
## 1\.2 Features
Search for applications, folders, or files
![](../../../doc/images/Launcher/Features.gif)
@@ -27,13 +31,13 @@ Do a simple calculation using calculator
![](../../../doc/images/Launcher/FeaturesCalculator.gif)
## 1\.2 Settings
## 1\.3 Settings
| **Settings** | **Action** |
| --------------- | ------------------------------------------------------------------------------- |
| Maximum number of results | Maximum number of results shown without scrolling on PowerToys Run |
| Open PowerToys Run shortcut | The keyboard shortcut to open/hide PowerToys Run |
## 1\.3 Keyboard Shortcuts
## 1\.4 Keyboard Shortcuts
| **Shortcuts** | **Action** |
| ------------------ | ---------------------------------------------------------------------------------|
| Alt+Space | Open or hide PowerToys Run |
@@ -68,4 +72,4 @@ For a list of all known issues/suggestions, check it out
[Wox](https://github.com/Wox-launcher/Wox/)
[Beta Tadele's Window Walker](https://github.com/Wox-launcher/Wox/)
[Beta Tadele's Window Walker](https://github.com/betsegaw/windowwalker)

View File

@@ -83,9 +83,18 @@ namespace Wox.Infrastructure
bool allSubstringsContainedInCompareString = true;
var indexList = new List<int>();
List<int> spaceIndices = new List<int>();
for (var compareStringIndex = 0; compareStringIndex < fullStringToCompareWithoutCase.Length; compareStringIndex++)
{
// To maintain a list of indices which correspond to spaces in the string to compare
// To populate the list only for the first query substring
if (fullStringToCompareWithoutCase[compareStringIndex].Equals(' ') && currentQuerySubstringIndex == 0)
{
spaceIndices.Add(compareStringIndex);
}
if (fullStringToCompareWithoutCase[compareStringIndex] != currentQuerySubstring[currentQuerySubstringCharacterIndex])
{
matchFoundInPreviousLoop = false;
@@ -147,7 +156,8 @@ namespace Wox.Infrastructure
// proceed to calculate score if every char or substring without whitespaces matched
if (allQuerySubstringsMatched)
{
var score = CalculateSearchScore(query, stringToCompare, firstMatchIndex, lastMatchIndex - firstMatchIndex, allSubstringsContainedInCompareString);
var nearestSpaceIndex = CalculateClosestSpaceIndex(spaceIndices, firstMatchIndex);
var score = CalculateSearchScore(query, stringToCompare, firstMatchIndex - nearestSpaceIndex - 1, lastMatchIndex - firstMatchIndex, allSubstringsContainedInCompareString);
return new MatchResult(true, UserSettingSearchPrecision, indexList, score);
}
@@ -155,6 +165,21 @@ namespace Wox.Infrastructure
return new MatchResult (false, UserSettingSearchPrecision);
}
// To get the index of the closest space which preceeds the first matching index
private int CalculateClosestSpaceIndex(List<int> spaceIndices, int firstMatchIndex)
{
if(spaceIndices.Count == 0)
{
return -1;
}
else
{
int? ind = spaceIndices.OrderBy(item => (firstMatchIndex - item)).Where(item => firstMatchIndex > item).FirstOrDefault();
int closestSpaceIndex = ind ?? -1;
return closestSpaceIndex;
}
}
private static bool AllPreviousCharsMatched(int startIndexToVerify, int currentQuerySubstringCharacterIndex,
string fullStringToCompareWithoutCase, string currentQuerySubstring)
{
@@ -223,6 +248,12 @@ namespace Wox.Infrastructure
}
}
if (String.Equals(query, stringToCompare, StringComparison.CurrentCultureIgnoreCase))
{
var bonusForExactMatch = 10;
score += bonusForExactMatch;
}
return score;
}

View File

@@ -122,21 +122,24 @@ namespace Wox.Test
}
}
[TestCase(Chrome, Chrome, 137)]
[TestCase(Chrome, LastIsChrome, 83)]
[TestCase(Chrome, HelpCureHopeRaiseOnMindEntityChrome, 21)]
[TestCase(Chrome, UninstallOrChangeProgramsOnYourComputer, 15)]
[TestCase(Chrome, CandyCrushSagaFromKing, 0)]
[TestCase("sql", MicrosoftSqlServerManagementStudio, 56)]
[TestCase("sql manag", MicrosoftSqlServerManagementStudio, 79)]//double spacing intended
public void WhenGivenQueryStringThenShouldReturnCurrentScoring(string queryString, string compareString, int expectedScore)
[TestCase("vim", "Vim", "ignoreDescription", "ignore.exe", "Vim Diff", "ignoreDescription", "ignore.exe")]
public void WhenMultipleResults_ExactMatchingResult_ShouldHaveGreatestScore(string queryString, string firstName, string firstDescription, string firstExecutableName, string secondName, string secondDescription, string secondExecutableName)
{
// When, Given
// Act
var matcher = new StringMatcher();
var rawScore = matcher.FuzzyMatch(queryString, compareString).RawScore;
var firstNameMatch = matcher.FuzzyMatch(queryString, firstName).RawScore;
var firstDescriptionMatch = matcher.FuzzyMatch(queryString, firstDescription).RawScore;
var firstExecutableNameMatch = matcher.FuzzyMatch(queryString, firstExecutableName).RawScore;
// Should
Assert.AreEqual(expectedScore, rawScore, $"Expected score for compare string '{compareString}': {expectedScore}, Actual: {rawScore}");
var secondNameMatch = matcher.FuzzyMatch(queryString, secondName).RawScore;
var secondDescriptionMatch = matcher.FuzzyMatch(queryString, secondDescription).RawScore;
var secondExecutableNameMatch = matcher.FuzzyMatch(queryString, secondExecutableName).RawScore;
var firstScore = new[] { firstNameMatch, firstDescriptionMatch, firstExecutableNameMatch }.Max();
var secondScore = new[] { secondNameMatch, secondDescriptionMatch, secondExecutableNameMatch }.Max();
// Assert
Assert.IsTrue(firstScore > secondScore);
}
[TestCase("goo", "Google Chrome", StringMatcher.SearchPrecisionScore.Regular, true)]
@@ -184,8 +187,6 @@ namespace Wox.Test
[TestCase("sql manag", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)]
[TestCase("sql", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)]
[TestCase("sql serv", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)]
[TestCase("sqlserv", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, false)]
[TestCase("sql servman", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, false)]
[TestCase("sql serv man", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)]
[TestCase("sql studio", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)]
[TestCase("mic", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)]
@@ -221,5 +222,20 @@ namespace Wox.Test
$"Raw Score: {matchResult.RawScore}{Environment.NewLine}" +
$"Precision Score: {(int)expectedPrecisionScore}");
}
[TestCase("Windows Terminal", "Windows_Terminal", "term")]
[TestCase("Windows Terminal", "WindowsTerminal", "term")]
public void FuzzyMatchingScore_ShouldBeHigher_WhenPreceedingCharacterIsSpace(string firstCompareStr, string secondCompareStr, string query)
{
// Arrange
var matcher = new StringMatcher();
// Act
var firstScore = matcher.FuzzyMatch(query, firstCompareStr).Score;
var secondScore = matcher.FuzzyMatch(query, secondCompareStr).Score;
// Assert
Assert.IsTrue(firstScore > secondScore);
}
}
}

View File

@@ -0,0 +1,143 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using NUnit.Framework;
using Wox.Infrastructure;
using Wox.Plugin;
using Microsoft.Plugin.Program.Programs;
using Moq;
using System.IO;
namespace Wox.Test.Plugins
{
[TestFixture]
public class ProgramPluginTest
{
Win32 notepad_appdata = new Win32
{
Name = "Notepad",
ExecutableName = "notepad.exe",
FullPath = "c:\\windows\\system32\\notepad.exe",
LnkResolvedPath = "c:\\users\\powertoys\\appdata\\roaming\\microsoft\\windows\\start menu\\programs\\accessories\\notepad.lnk"
};
Win32 notepad_users = new Win32
{
Name = "Notepad",
ExecutableName = "notepad.exe",
FullPath = "c:\\windows\\system32\\notepad.exe",
LnkResolvedPath = "c:\\programdata\\microsoft\\windows\\start menu\\programs\\accessories\\notepad.lnk"
};
Win32 azure_command_prompt = new Win32
{
Name = "Microsoft Azure Command Prompt - v2.9",
ExecutableName = "cmd.exe",
FullPath = "c:\\windows\\system32\\cmd.exe",
LnkResolvedPath = "c:\\programdata\\microsoft\\windows\\start menu\\programs\\microsoft azure\\microsoft azure sdk for .net\\v2.9\\microsoft azure command prompt - v2.9.lnk"
};
Win32 visual_studio_command_prompt = new Win32
{
Name = "x64 Native Tools Command Prompt for VS 2019",
ExecutableName = "cmd.exe",
FullPath = "c:\\windows\\system32\\cmd.exe",
LnkResolvedPath = "c:\\programdata\\microsoft\\windows\\start menu\\programs\\visual studio 2019\\visual studio tools\\vc\\x64 native tools command prompt for vs 2019.lnk"
};
Win32 command_prompt = new Win32
{
Name = "Command Prompt",
ExecutableName = "cmd.exe",
FullPath = "c:\\windows\\system32\\cmd.exe",
LnkResolvedPath ="c:\\users\\powertoys\\appdata\\roaming\\microsoft\\windows\\start menu\\programs\\system tools\\command prompt.lnk"
};
Win32 file_explorer = new Win32
{
Name = "File Explorer",
ExecutableName = "File Explorer.lnk",
FullPath = "c:\\users\\powertoys\\appdata\\roaming\\microsoft\\windows\\start menu\\programs\\system tools\\file explorer.lnk",
LnkResolvedPath = null
};
Win32 wordpad = new Win32
{
Name = "Wordpad",
ExecutableName = "wordpad.exe",
FullPath = "c:\\program files\\windows nt\\accessories\\wordpad.exe",
LnkResolvedPath = "c:\\programdata\\microsoft\\windows\\start menu\\programs\\accessories\\wordpad.lnk"
};
Win32 wordpad_duplicate = new Win32
{
Name = "WORDPAD",
ExecutableName = "WORDPAD.EXE",
FullPath = "c:\\program files\\windows nt\\accessories\\wordpad.exe",
LnkResolvedPath = null
};
[Test]
public void DedupFunction_whenCalled_mustRemoveDuplicateNotepads()
{
// Arrange
List<Win32> prgms = new List<Win32>();
prgms.Add(notepad_appdata);
prgms.Add(notepad_users);
// Act
Win32[] apps = Win32.DeduplicatePrograms(prgms.AsParallel());
// Assert
Assert.AreEqual(apps.Length, 1);
}
[Test]
public void DedupFunction_whenCalled_mustNotRemovelnkWhichdoesNotHaveExe()
{
// Arrange
List<Win32> prgms = new List<Win32>();
prgms.Add(file_explorer);
// Act
Win32[] apps = Win32.DeduplicatePrograms(prgms.AsParallel());
// Assert
Assert.AreEqual(apps.Length, 1);
}
[Test]
public void DedupFunction_mustRemoveDuplicates_forExeExtensionsWithoutLnkResolvedPath()
{
// Arrange
List<Win32> prgms = new List<Win32>();
prgms.Add(wordpad);
prgms.Add(wordpad_duplicate);
// Act
Win32[] apps = Win32.DeduplicatePrograms(prgms.AsParallel());
// Assert
Assert.AreEqual(apps.Length, 1);
Assert.IsTrue(!string.IsNullOrEmpty(apps[0].LnkResolvedPath));
}
[Test]
public void DedupFunction_mustNotRemovePrograms_withSameExeNameAndFullPath()
{
// Arrange
List<Win32> prgms = new List<Win32>();
prgms.Add(azure_command_prompt);
prgms.Add(visual_studio_command_prompt);
prgms.Add(command_prompt);
// Act
Win32[] apps = Win32.DeduplicatePrograms(prgms.AsParallel());
// Assert
Assert.AreEqual(apps.Length, 3);
}
}
}

View File

@@ -40,6 +40,7 @@
<ItemGroup>
<ProjectReference Include="..\Plugins\Microsoft.Plugin.Indexer\Microsoft.Plugin.Indexer.csproj" />
<ProjectReference Include="..\Plugins\Microsoft.Plugin.Program\Microsoft.Plugin.Program.csproj" />
<ProjectReference Include="..\Wox.Core\Wox.Core.csproj" />
<ProjectReference Include="..\Wox.Infrastructure\Wox.Infrastructure.csproj" />
<ProjectReference Include="..\Wox.Plugin\Wox.Plugin.csproj" />

View File

@@ -17,7 +17,7 @@ namespace MarkdownPreviewHandler.Telemetry.Events
/// <summary>
/// Gets The version string. TODO: This should be replaced by a P/Invoke call to get_product_version.
/// </summary>
public string Version => "v0.18.0";
public string Version => "v0.18.2";
/// <inheritdoc/>
public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServiceUsage;

View File

@@ -17,7 +17,7 @@ namespace SvgPreviewHandler.Telemetry.Events
/// <summary>
/// Gets The version string. TODO: This should be replaced by a P/Invoke call to get_product_version.
/// </summary>
public string Version => "v0.18.0";
public string Version => "v0.18.2";
/// <inheritdoc/>
public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServiceUsage;

View File

@@ -36,7 +36,7 @@ bool restart_if_scheduled()
case RestartAsElevated:
return run_elevated(exe_path.get(), {});
case RestartAsNonElevated:
return run_non_elevated(exe_path.get(), L"--dont-elevate");
return run_non_elevated(exe_path.get(), L"--dont-elevate", NULL);
default:
return false;
}
@@ -47,5 +47,5 @@ bool restart_same_elevation()
constexpr DWORD exe_path_size = 0xFFFF;
auto exe_path = std::make_unique<wchar_t[]>(exe_path_size);
GetModuleFileNameW(nullptr, exe_path.get(), exe_path_size);
return run_same_elevation(exe_path.get(), L"--dont-elevate");
return run_same_elevation(exe_path.get(), L"--dont-elevate", nullptr);
}