Compare commits

..

78 Commits

Author SHA1 Message Date
Enrico Giordani
d2ec89a0ca [OOBE] New FZ Editor hotkey (#10988) 2021-04-28 13:09:08 +02:00
Enrico Giordani
4279d6c067 [KBM] supress warning (#10983) 2021-04-27 20:13:30 +02:00
Enrico Giordani
2c2cd3fde2 [msi] missing dlls (#10982) 2021-04-27 19:58:35 +02:00
Mykhailo Pylyp
5426e7bc30 [KBM Engine] Remove global usings (#10976) 2021-04-27 17:56:59 +02:00
Mykhailo Pylyp
4c6191d7c0 [KBM] fix for build error C2872 (#10970) 2021-04-27 15:19:18 +02:00
Enrico Giordani
0aee35df0c [KBM] fix build error C2079 (#10959)
* [KBM] fix build error C2079

* [KBM] one more <sstream> fix
2021-04-27 09:37:44 +02:00
Enrico Giordani
aa51f81bb8 [KBM] move interop methods to dedicated class (#10958) 2021-04-27 01:14:59 +02:00
Mykhailo Pylyp
a8c99e9513 [KBM] Migrate Engine and Editor into separate processes (#10774)
* Move KBM engine into separate process (#10672)

* [KBM] Migrate KBM UI out of the runner (#10709)

* Clean up keyboard hook handles (#10817)

* [C++ common] Unhandled exception handler (#10821)

* [KBM] Use icon in the KeyboardManagerEditor (#10845)

* [KBM] Move resources from the Common project to the Editor. (#10844)

* KBM Editor tests (#10858)

* Rename engine executable (#10868)

* clean up (#10870)

* [KBM] Changed Editor and libraries output folders (#10871)

* [KBM] New logs structure (#10872)

* Add unhandled exception handling to the editor (#10874)

* [KBM] Trace for edit keyboard window

* Logging for XamlBridge message loop

* [KBM] Added Editor and Engine to the installer (#10876)

* Fix spelling

* Interprocess communication logs, remove unnecessary windows message logs

* [KBM] Separated telemetry for the engine and editor. (#10889)

* [KBM] Editor test project (#10891)

* Versions for the engine and the editor (#10897)

* Add the editor's and the engine's executables to signing process (#10900)

* [KBM editor] Run only one instance, exit when parent process exits (#10890)

* [KBM] Force kill editor process to avoid XAML crash (#10907)

* [KBM] Force kill editor process to avoid XAML crash

* Fix event releasing

Co-authored-by: mykhailopylyp <17161067+mykhailopylyp@users.noreply.github.com>

* Make the editor dpi aware (#10908)

* [KBM] KeyboardManagerCommon refactoring (#10909)

* Do not start the process if it is already started (#10910)

* logs

* Update src/modules/keyboardmanager/KeyboardManagerEditorLibrary/EditKeyboardWindow.cpp

* Update src/modules/keyboardmanager/KeyboardManagerEditorLibrary/EditKeyboardWindow.cpp

* [KBM] Rename InitUnhandledExceptionHandler
to make it explicit that is for x64 only.
We will fix it properly when adding support for ARM64 and add a header with
the proper conditional building.

* [KBM] rename file/class/variables using camel case

* [KBM] Rename "event_locker" -> "EventLocker"

* [KBM] rename process_waiter
Add a TODO comment

* [KBM] rename methods
Add TODO comment

* [KBM] use uppercase for function names

* [KBM] use uppercase for methos, lowercase for properties

* [KBM] rename method, make methods private, formatting

* [KBM] rename private variables

* [KBM] use uppercase for function names

* [KBM] Added support to run the editor stand-alone when built in debug mode

* Update src/modules/keyboardmanager/KeyboardManagerEditor/KeyboardManagerEditor.cpp

* Check success of event creation, comment (#10947)

* [KBM] code formatting (#10951)

* [KBM] code formatting

* Update src/modules/keyboardmanager/KeyboardManagerEditorLibrary/BufferValidationHelpers.cpp

* [KBM] tracing

* [KBM] Remappings not showing fix. (#10954)

* removed mutex

* retry loop for reading

* retry on reading config once

* log error

Co-authored-by: Enrico Giordani <enricogior@users.noreply.github.com>

Co-authored-by: Enrico Giordani <enricogior@users.noreply.github.com>

Co-authored-by: Seraphima Zykova <zykovas91@gmail.com>
Co-authored-by: Enrico Giordani <enricogior@users.noreply.github.com>
Co-authored-by: Enrico Giordani <enrico.giordani@gmail.com>
2021-04-26 21:01:38 +02:00
Seraphima Zykova
e9a0b58796 [FancyZones Editor] Fix FZ Editor crash on opening custom layout for editing (#10911) 2021-04-26 14:32:18 +01:00
csigs
b2f47b9073 LEGO: check in for master to temporary branch. (#10949) 2021-04-26 14:27:29 +02:00
Clint Rutkas
6729da3a1b https://grammarist.com/usage/up-to-date/ correcting verbage (#10914) 2021-04-23 11:49:00 -07:00
Clint Rutkas
e098581688 change in user string (#10912) 2021-04-23 10:22:50 -07:00
Clint Rutkas
3f3494a3c3 Update feature_request.yml 2021-04-21 17:21:13 -07:00
Clint Rutkas
f561b25d9d Delete feature_request.md 2021-04-21 17:20:06 -07:00
Clint Rutkas
61739453c2 Update feature_request.yml 2021-04-21 17:19:40 -07:00
Clint Rutkas
75d8443e3e Update feature_request.yml 2021-04-21 17:18:44 -07:00
Clint Rutkas
94c2115bf4 Create feature_request.yml 2021-04-21 17:18:05 -07:00
Enrico Giordani
150ffe6013 [File Explorer Add-ons] remove old settings support (#10857) 2021-04-21 12:16:01 +02:00
Enrico Giordani
6ec30e2186 [Image Resizer] remove old in app settings (#10837)
* [Image Resizer] Remove old settings

* [Image Resizer] Removed unused code

* [common interop] remove "ShouldNewSettingsBeUsed()"
2021-04-20 15:11:59 +02:00
Niels Laute
0e64071051 [FZ Editor] Edit dialog UX fixes (#10734)
* Updates to UI

* Handle enter key

* Focus visual fix

* Fix

Co-authored-by: Niels Laute <niels9001@hotmail.com>
2021-04-20 14:56:18 +02:00
Andrey Nekrasov
9b8970fd9c [Setup] Introduce a flag to always start PowerToys after install (#10838) 2021-04-20 14:47:59 +03:00
Clint Rutkas
78943dc19b Delete documentation-issue.md 2021-04-19 20:21:27 -07:00
Clint Rutkas
7aad6d8f95 Update and rename documentation-issue1.md to documentation-issue.md 2021-04-19 20:21:00 -07:00
Clint Rutkas
7bf2114ece Rename documentation-issue.md to documentation-issue1.md 2021-04-19 20:20:42 -07:00
Clint Rutkas
3dd1487a13 Create documentation-issue.yml 2021-04-19 20:19:51 -07:00
Clint Rutkas
04e9635f66 Update bug_report.yml 2021-04-19 20:15:54 -07:00
Clint Rutkas
10b3011757 Update translation_issue.yml 2021-04-19 20:15:12 -07:00
Clint Rutkas
ac3b2bb14d Update translation_issue.yml 2021-04-19 20:14:05 -07:00
Clint Rutkas
9adbfdf270 Update translation_issue.yml 2021-04-19 20:09:14 -07:00
Clint Rutkas
bf05f97cfe Update bug_report.yml 2021-04-19 15:27:53 -07:00
Clint Rutkas
05c083bb54 Update bug_report.yml 2021-04-19 15:26:35 -07:00
Clint Rutkas
5a37991d44 Update bug_report.yml 2021-04-19 15:25:45 -07:00
csigs
34f371aeae LEGO: check in for master to temporary branch. (#10819) 2021-04-19 13:07:20 -07:00
Niels Laute
21d68c7998 [OOBE] Accessibility fixes (#10799)
* Narrator support for all Settings buttons

* Shortened welcome title

* Fixes

* Removed unused string

* Update src/settings-ui/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw

Co-authored-by: Niels Laute <niels9001@hotmail.com>
Co-authored-by: Enrico Giordani <enricogior@users.noreply.github.com>
2021-04-19 12:42:36 +02:00
Mykhailo Pylyp
a92c18f80c Log a warning if a plugin search takes more than 50 milliseconds (#10772) 2021-04-19 11:43:24 +03:00
Mykhailo Pylyp
6e65f9cbd5 Make delete_other_versions_log_folders more reliable (#10760) 2021-04-16 15:21:21 +03:00
Niels Laute
71cf94b330 [Image Resizer] Visual updates + NumberBox (#10596)
* Input page visual updates + NumberBox

* Update UI

* Update to NumberBoxes

* Update src/modules/imageresizer/ui/Views/InputPage.xaml

* Update src/modules/imageresizer/ui/Views/InputPage.xaml

* Formatting

Co-authored-by: Niels Laute <niels9001@hotmail.com>
Co-authored-by: Enrico Giordani <enricogior@users.noreply.github.com>
Co-authored-by: Enrico Giordani <enrico.giordani@gmail.com>
2021-04-16 10:15:50 +02:00
Clint Rutkas
43a73065af Update README.md 2021-04-15 18:32:12 -07:00
Clint Rutkas
e762859d1b Update README.md 2021-04-15 12:56:56 -07:00
Clint Rutkas
501d3b9a35 Update README.md 2021-04-15 12:13:59 -07:00
Clint Rutkas
9ff63b486e updating system.text.json (#10762) 2021-04-15 11:41:11 -07:00
yuyoyuppe
d4e5418f07 [Auto-update] Remove special case logic for autoupdate disabling 2021-04-15 16:17:43 +03:00
yuyoyuppe
3c3859e840 [Setup] Update WIX to require at least build 18362 2021-04-15 16:16:50 +03:00
yuyoyuppe
f3915043dd [VCM] do not cleanup settings during installation 2021-04-15 16:16:28 +03:00
Clint Rutkas
e9ce9ab87a Changing default key for FanzyZones (#10751)
* Changing default key

* Update Settings.h
2021-04-15 11:11:08 +02:00
Niels Laute
b585aef166 [OOBE] Updated GIFs (#10745)
* Updated GIFs

* Updated PowerRename image

* Update PowerRename image

* Updated imageresizer

Co-authored-by: Niels Laute <niels9001@hotmail.com>
2021-04-14 11:11:55 -07:00
Clint Rutkas
b13388a138 Delete preview-monaco.md
moved to wiki
2021-04-14 10:40:24 -07:00
Aaron Junker
2f5458ab5f monaco preview specification (#10136)
* Create preview-monaco.md

* Update preview-monaco.md

* Update preview-monaco.md

* Update preview-monaco.md

* Update expect.txt

* Update preview-monaco.md

* Update preview-monaco.md

added a bit more information up front. Added in new requirement at the bottom that i think we should discuss.

* Update preview-monaco.md

Co-authored-by: Clint Rutkas <clint@rutkas.com>
2021-04-14 10:32:41 -07:00
Mykhailo Pylyp
0f89acea96 [docs] New plugin checklist (#10511)
* new plugin checklist

* Fix paths

* spellings, paths

* fix pattern

* make checklist items more specific

* Make check boxes, enforce existence of .NET 5 dependency
2021-04-14 09:12:38 -07:00
DoctorNefario
28e9f168d4 Disable forwarding the Escape event (#10697) 2021-04-13 11:16:48 +02:00
Mykhailo Pylyp
04101d23e7 Added missed dlls (#10706) 2021-04-12 19:24:42 +03:00
Clare DuVal
0a6de4561f [PowerRename] Add option for Capitalization (#10213)
* Add camelcase instances + helper translation

* Add camel case testing

* Update Helpers.cpp

* Update PowerRenameUI.cpp

* Update src/modules/powerrename/ui/PowerRenameUI.cpp

Co-authored-by: Enrico Giordani <enricogior@users.noreply.github.com>

* Change camel case to capitalized, move ui

* Update PowerRenameManagerTests.cpp

* Update PowerRenameUI.base.rc

* Update PowerRenameUI.base.rc

Co-authored-by: Enrico Giordani <enricogior@users.noreply.github.com>
2021-04-09 14:24:06 +02:00
Ivan Stošić
c08be14919 Use local mutexes (#10651)
* Update file config mutex code in KeyboardManager

* Update runner instance mutex names and logic

* Update Launcher mutex

* Update a mutex in the Runner

* Restored a mutex used in the installer

* Update src/modules/launcher/PowerLauncher/App.xaml.cs

Co-authored-by: Enrico Giordani <enricogior@users.noreply.github.com>
2021-04-08 19:42:46 +02:00
Enrico Giordani
aa5ff65b54 [runner, color picker, run] remove os dection (#10648) 2021-04-08 16:10:05 +02:00
Mykhailo Pylyp
97fdf10cea Divide load and initialize of plugins into two stages (#10650) 2021-04-08 16:07:26 +03:00
Seraphima Zykova
55a851e5f2 [FancyZones] Place log files in subfolders with the version number. (#10549) 2021-04-07 14:43:35 +01:00
Ivan Stošić
675ae91c29 [ColorPicker] Ensure that the hotkey always works (#10542)
* Fix multiple instances running

* Make ColorPicker invokable from the runner

* Use a local mutex

* Enable running ColorPicker as standalone as well as a in PT

* Add some logging

* Remove newline

This will happen sooner or later and is not needed in the PR

* Update mutex name

* Update names

* Add logging
2021-04-07 11:59:41 +02:00
Clint Rutkas
353ca842ad Shift to detect nullable (#10627) 2021-04-07 02:54:15 -07:00
Clint Rutkas
304ba8c6bb file explorer comments (#10628) 2021-04-07 02:53:45 -07:00
Ivan Stošić
bb5d4dfbf0 Fixed an issue with zone sizes (#10609) 2021-04-07 09:30:35 +02:00
Aaron Junker
29ed73ba92 Dev/aaron junker/localisation GitHub template (#10443)
* Create translation_issue.yml

* Update translation_issue.yml

* Update translation_issue.yml

* Update translation_issue.yml

* Update translation_issue.yml

* Update translation_issue.yml

* Update translation_issue.yml

* Update translation_issue.yml

* Update translation_issue.yml

* Update translation_issue.yml

* Update translation_issue.yml

* Update translation_issue.yml

* Update translation_issue.yml

* Update translation_issue.yml

* Create test.yml

* Update test.yml

* Update test.yml

* Update test.yml

* Update test.yml

* Delete test.yml

* Delete translation_issue.md

* Update translation_issue.yml

* Update translation_issue.yml

* Update translation_issue.yml

Co-authored-by: Clint Rutkas <clint@rutkas.com>
2021-04-05 16:36:11 -07:00
Clint Rutkas
e36f08db3a More targetted links (#10604) 2021-04-05 12:48:02 -07:00
Clint Rutkas
fc2189fe0a Update bug_report.yml 2021-04-05 10:47:28 -07:00
Clint Rutkas
bb5deffdd4 Update bug_report.yml 2021-04-05 10:45:54 -07:00
Clint Rutkas
68e00ed208 Tweaking bug report template (#10558)
* Tweaking bug report template

Tracking #10450

* Update bug_report.yml

* Update bug_report.yml
2021-04-05 10:44:16 -07:00
Mykhailo Pylyp
1c8b7a5ae5 Do not load plugin when it is disabled (#10515) 2021-04-05 17:57:22 +03:00
Niels Laute
ed21dba8f0 Removed manual cleartype (#10568)
Co-authored-by: Niels Laute <niels9001@hotmail.com>
2021-04-05 16:26:24 +02:00
csigs
8e78892712 LEGO: check in for master to temporary branch. (#10588) 2021-04-05 15:23:18 +02:00
Niels Laute
38bc0bab3d [FZ Editor] Added resolution to monitor (#10567)
* Added resolution

* Added resolution

* Fontsize fix

Co-authored-by: Niels Laute <niels9001@hotmail.com>
2021-04-05 11:35:33 +02:00
Enrico Giordani
927e947385 [old settings] deprecate old settings (#10548)
* [old settings] deprecate old settings

* removed old settings from the pipeline signing process
2021-04-05 11:32:48 +02:00
Niels Laute
b0465bb500 [OOBE] UX fixes (#10583)
* Updated OOBE

* String fix

Co-authored-by: Niels Laute <niels9001@hotmail.com>
2021-04-05 11:15:08 +02:00
Niels Laute
0ee034a084 [OOBE] Bolded shortcuts / instructions (#10574)
* Colorpicker keys

* Key visuals added

* Added highlighted text

* Undo comment

Co-authored-by: Niels Laute <niels9001@hotmail.com>
2021-04-05 10:52:44 +02:00
Enrico Giordani
fa92f2e581 [msi] remove old settings from installer (#10546) 2021-04-02 16:44:12 +02:00
Davide Giacometti
bc28a3f5e3 disable apps for shortcut guide (#10123) 2021-04-02 16:29:48 +02:00
Enrico Giordani
6561290bde [spell checker] Add expected terms (#10544) 2021-04-02 15:58:43 +02:00
ricardosantos9521
2b9ecf75b6 fix workspaces not showing in vscode plugin #10530 (#10533) 2021-04-02 15:06:14 +02:00
Chris Davis
d128939227 Show progress dialog during startup (#9255)
* Show progress dialog during startup for selection enumeration that can take a long time.

* Updated with better code organization and a timer to ensure the progress dialog does not appear in most cases.

* Update based on PR feedback

* Change progress dialog delay from 1500ms to 2500ms

* Move progress dialog invocation off the main UI thread

Co-authored-by: Chris Davis (EDGE) <chrdavis@microsoft.com>
2021-04-02 12:07:12 +02:00
Clint Rutkas
6613522e53 Readme 0.35 (#10504)
* Update README.md

* Update README.md

shifting to WinGet

* Update expect.txt

* Update README.md

* Update README.md

* Update README.md

* Update expect.txt

* Update README.md

* Update README.md

* Update expect.txt

addrum

* Update README.md

* Update README.md

* Update README.md

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

* Update README.md

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

* Update README.md

Co-authored-by: Deondre Davis <dedavis@microsoft.com>
Co-authored-by: htcfreek <61519853+htcfreek@users.noreply.github.com>
2021-04-01 09:52:13 -07:00
417 changed files with 10442 additions and 18345 deletions

View File

@@ -1,18 +1,13 @@
name: "Bug report 🐛"
name: "🐛 Bug report"
description: Report errors or unexpected behavior
title: ''
labels:
- Issue-Bug
- Triage-Needed
assignees: ''
issue_body: true
body:
- type: markdown
attributes:
value: |
Please make sure to [search for existing issues](https://github.com/microsoft/PowerToys/issues) before filing a new one!
We highly suggest including a screenshots and a bug report log (System tray->Report bug). To include, paste them into the markdown editor below the form or follow up with a separate comment.
- type: input
attributes:
label: Microsoft PowerToys version
@@ -23,15 +18,12 @@ body:
validations:
required: true
- type: dropdown
- type: checkboxes
attributes:
label: Running as admin
description: Are you running PowerToys as Admin?
options:
- 'No'
- 'Yes'
validations:
required: true
- label: "Yes"
- type: dropdown
attributes:
@@ -51,26 +43,17 @@ body:
- Shortcut Guide
- SVG Preview
- SVG Thumbnail
- Installer
- Settings
- Welcome / PowerToys Tour window
- System tray interaction
- Settings window
- Installer
validations:
required: true
- type: textarea
attributes:
label: Other Software
description: If you're reporting a bug about our interaction with other software, what software? What versions?
placeholder: |
vim 8.2 (inside WSL)
OpenSSH_for_Windows_8.1p1
My Cool Application v0.3 (include a code snippet if it would help!)
validations:
required: false
- type: textarea
attributes:
label: Steps to reproduce
description: We highly suggest including a screenshots and a bug report log (System tray->Report bug).
placeholder: Tell us the steps required to trigger your bug.
validations:
required: true
@@ -88,3 +71,14 @@ body:
placeholder: What happened instead?
validations:
required: true
- type: textarea
attributes:
label: Other Software
description: If you're reporting a bug about our interaction with other software, what software? What versions?
placeholder: |
vim 8.2 (inside WSL)
OpenSSH_for_Windows_8.1p1
My Cool Application v0.3 (include a code snippet if it would help!)
validations:
required: false

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,17 @@
name: "⭐ Feature / enhancement request"
description: Propose something new.
labels:
- Triage-Needed
body:
- type: textarea
attributes:
label: Provide a description of the new feature / enhancement
placeholder: |
What is the expected behavior of the proposed feature?
What is the scenario this would be used?
validations:
required: true
- type: markdown
attributes:
value: |
Please limit one request per issue.

View File

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

View File

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

View File

@@ -5,6 +5,7 @@ abcdef
abcdefgh
abgr
ABlocked
ABOUTBOX
Abug
accctrl
Acceleratorkeys
@@ -22,6 +23,7 @@ activatable
ACTIVATEAPP
Addavirtualdesktop
Addins
addrum
ADDUNDORECORD
ADifferent
ADMINS
@@ -117,6 +119,7 @@ atlstr
attr
Attribs
aumid
Aut
AUTHN
AUTOAPPEND
autocomplete
@@ -191,6 +194,7 @@ buildtransitive
BValue
bytearray
callbackptr
capitalized
CANRENAME
Captureascreenshot
CAPTURECHANGED
@@ -216,6 +220,7 @@ charset
chdir
checkbox
checkboxes
CHECKCANCELED
Checkedin
checknetisolation
Chicklet
@@ -393,6 +398,7 @@ davidegiacometti
Dayof
dbdfc
Dbg
Dbghelp
DBLCLKS
DBLEPSILON
DCOM
@@ -1036,6 +1042,7 @@ ipreviewhandlertranslateaccelerator
ipreviewhandlervisualssetfont
IPrincipal
IProgram
IProgress
IProperty
IPublic
IQuery
@@ -1055,6 +1062,7 @@ isetting
isfinite
IShell
ISingle
ISmart
ismethod
isocpp
IStorage
@@ -1096,6 +1104,7 @@ jp
jpe
jpeg
jpg
jsoref
JPN
json
jsonval
@@ -1111,6 +1120,7 @@ KEYBDINPUT
keyboardeventhandlers
keyboardmanager
keyboardmanagercommon
KEYBOARDMANAGEREDITOR
keyboardmanagerstate
keyboardmanagerui
keycode
@@ -1263,6 +1273,7 @@ MAPPEDTOSAMEKEY
MAPTOSAMESHORTCUT
MAPVK
Markdig
MARQUEEPROGRESS
martinchrzan
martinmoene
MATCHALLOCCURENCES
@@ -1270,6 +1281,7 @@ MATCHMODE
MAXIMIZEBOX
MAXSHORTCUTSIZE
maxversiontested
mayitbeegh
MBUTTON
MBUTTONDBLCLK
MBUTTONDOWN
@@ -1502,6 +1514,7 @@ oldnewthing
oldpath
oldtheme
oleaut
OleAut
OLECHAR
OLEDB
OLIVEGREEN
@@ -1578,6 +1591,8 @@ pguid
phbm
phbmp
Phishing
php
phptest
phwnd
pici
pid
@@ -1653,6 +1668,7 @@ Printfax
prm
PROCESSKEY
PRODUCTVERSION
PROGDLG
Progman
programdata
PROGRAMFILES
@@ -1661,6 +1677,7 @@ Proj
projectname
propkey
propvarutil
prpui
Prt
prui
prvpane
@@ -1691,6 +1708,7 @@ pwcs
PWSTR
pwtd
px
py
Qand
QI
qianlifeng
@@ -1724,6 +1742,7 @@ readme
READMODE
readonly
READWRITE
REALTIME
RECTDESTINATION
RECTL
rectp
@@ -1816,6 +1835,7 @@ runsettings
runtimeclass
runtimeconfig
runtimes
rutkas
rv
rvalue
rvm
@@ -1952,6 +1972,8 @@ spesi
spinbuttonref
splitwstring
spoprod
sppd
sppre
spsi
spsia
spsrif
@@ -1992,6 +2014,7 @@ stdcall
stdcpp
stdcpplatest
stdexcept
stdio
stdin
stdlib
STDMETHODCALLTYPE
@@ -2011,6 +2034,7 @@ Strikethrough
Stringified
stringify
STRINGIZE
stringstream
stringtable
stringval
Strmiids
@@ -2109,6 +2133,7 @@ thre
tif
TILEDWINDOW
Timeline
TIMERID
timeunion
timeutil
titlecase
@@ -2162,6 +2187,7 @@ Tz
UAC
UAL
uap
UCHAR
udit
UIA
Uid
@@ -2278,6 +2304,7 @@ VREDRAW
VSC
VSCBD
vscode
vsconfig
VSCROLL
vse
vsonline
@@ -2405,6 +2432,7 @@ wstr
wstring
wstringstream
wsz
wtoi
WTS
WTSAT
wu
@@ -2451,6 +2479,7 @@ yinwang
YLogo
yml
YOffset
YourUserName
YStr
YUY
YUYV

2
.gitignore vendored
View File

@@ -342,3 +342,5 @@ src/common/Telemetry/*.etl
!**/MergeModules/Release/
!**/MergeModules/Debug/
/src/modules/previewpane/SvgThumbnailProvider/$(SolutionDir)$(Platform)/$(Configuration)/modules/FileExplorerPreview/SvgThumbnailProvider.xml
/src/modules/powerrename/ui/RCa24464
/src/modules/powerrename/ui/RCb24464

View File

@@ -163,7 +163,8 @@ steps:
configuration: '$(BuildConfiguration)'
testSelector: 'testAssemblies'
testAssemblyVer2: |
**\KeyboardManagerTest.dll
**\KeyboardManagerEngineTest.dll
**\KeyboardManagerEditorTest.dll
**\UnitTests-CommonLib.dll
**\PowerRenameUnitTests.dll
**\powerpreviewTest.dll

View File

@@ -98,6 +98,8 @@ build:
- 'modules\ImageResizer\ManagedTelemetry.dll'
- 'modules\ImageResizer\Microsoft.PowerToys.Common.UI.dll'
- 'modules\KeyboardManager\KeyboardManager.dll'
- 'modules\KeyboardManager\KeyboardManagerEditor\PowerToys.KeyboardManagerEditor.exe'
- 'modules\KeyboardManager\KeyboardManagerEngine\PowerToys.KeyboardManagerEngine.exe'
- 'modules\launcher\Microsoft.PowerToys.Settings.UI.Lib.dll'
- 'modules\launcher\ManagedCommon.dll'
- 'modules\launcher\Microsoft.PowerToys.Common.UI.dll'
@@ -150,7 +152,6 @@ build:
- 'os-detection.dll'
- 'PowerToys.exe'
- 'PowerToysInterop.dll'
- 'PowerToysSettings.exe'
- 'Settings\Microsoft.PowerToys.Settings.UI.exe'
- 'Settings\Microsoft.PowerToys.Settings.UI.Lib.dll'
- 'Settings\PowerToys.Settings.dll'

View File

@@ -103,8 +103,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ImageResizerExt", "src\modu
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ImageResizerUITest", "src\modules\imageresizer\tests\ImageResizerUITest.csproj", "{E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeyboardManagerUI", "src\modules\keyboardmanager\ui\KeyboardManagerUI.vcxproj", "{EAF23649-EF6E-478B-980E-81FAD96CCA2A}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "action_runner", "src\action_runner\action_runner.vcxproj", "{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}"
ProjectSection(ProjectDependencies) = postProject
{17DA04DF-E393-4397-9CF0-84DABE11032E} = {17DA04DF-E393-4397-9CF0-84DABE11032E}
@@ -210,8 +208,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PowerLauncher.Telemetry", "
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ManagedTelemetry", "src\common\ManagedTelemetry\Telemetry\ManagedTelemetry.csproj", "{5D00D290-4016-4CFE-9E41-1E7C724509BA}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeyboardManagerTest", "src\modules\keyboardmanager\test\KeyboardManagerTest.vcxproj", "{62173D9A-6724-4C00-A1C8-FB646480A9EC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ManagedCommon", "src\common\ManagedCommon\ManagedCommon.csproj", "{4AED67B6-55FD-486F-B917-E543DEE2CB3C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Plugin.Program.UnitTests", "src\modules\launcher\Plugins\Microsoft.Plugin.Program.UnitTests\Microsoft.Plugin.Program.UnitTests.csproj", "{42851751-CBC8-45A6-97F5-7A0753F7B4D1}"
@@ -221,6 +217,9 @@ EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SvgThumbnailProvider", "src\modules\previewpane\SvgThumbnailProvider\SvgThumbnailProvider.csproj", "{8FFE09DA-FA4F-4EE1-B3A2-AD5497FBD1AD}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ColorPicker", "src\modules\colorPicker\ColorPicker\ColorPicker.vcxproj", "{655C9AF2-18D3-4DA6-80E4-85504A7722BA}"
ProjectSection(ProjectDependencies) = postProject
{D9B8FC84-322A-4F9F-BBB9-20915C47DDFD} = {D9B8FC84-322A-4F9F-BBB9-20915C47DDFD}
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ColorPickerUI", "src\modules\colorPicker\ColorPickerUI\ColorPickerUI.csproj", "{BA58206B-1493-4C75-BFEA-A85768A1E156}"
EndProject
@@ -282,19 +281,22 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "utils", "utils", "{B39DC643
src\common\utils\appMutex.h = src\common\utils\appMutex.h
src\common\utils\com_object_factory.h = src\common\utils\com_object_factory.h
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\exec.h = src\common\utils\exec.h
src\common\utils\json.h = src\common\utils\json.h
src\common\utils\logger_helper.h = src\common\utils\logger_helper.h
src\common\utils\os-detect.h = src\common\utils\os-detect.h
src\common\utils\process_path.h = src\common\utils\process_path.h
src\common\utils\ProcessWaiter.h = src\common\utils\ProcessWaiter.h
src\common\utils\resources.h = src\common\utils\resources.h
src\common\utils\string_utils.h = src\common\utils\string_utils.h
src\common\utils\timeutil.h = src\common\utils\timeutil.h
src\common\utils\UnhandledExceptionHandler_x64.h = src\common\utils\UnhandledExceptionHandler_x64.h
src\common\utils\winapi_error.h = src\common\utils\winapi_error.h
src\common\utils\window.h = src\common\utils\window.h
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "old-settings-ui", "src\settings\old-settings-ui.vcxproj", "{07C389E3-6BC8-41CF-923E-307B1265FA2D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Telemetry", "Telemetry", "{8F62026A-294B-41C6-8839-87463613F216}"
ProjectSection(SolutionItems) = preProject
src\common\Telemetry\ProjectTelemetry.h = src\common\Telemetry\ProjectTelemetry.h
@@ -310,6 +312,18 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerToys.Run.Plu
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PowerToys.Settings", "src\settings-ui\PowerToys.Settings\PowerToys.Settings.csproj", "{6ED2F4FC-E122-4CEE-90F1-97E4CCC8BC7A}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeyboardManagerEngine", "src\modules\keyboardmanager\KeyboardManagerEngine\KeyboardManagerEngine.vcxproj", "{BA661F5B-1D5A-4FFC-9BF1-FC39DF280BDD}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeyboardManagerEngineLibrary", "src\modules\keyboardmanager\KeyboardManagerEngineLibrary\KeyboardManagerEngineLibrary.vcxproj", "{E496B7FC-1E99-4BAB-849B-0E8367040B02}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeyboardManagerEngineTest", "src\modules\keyboardmanager\KeyboardManagerEngineTest\KeyboardManagerEngineTest.vcxproj", "{7F4B3A60-BC27-45A7-8000-68B0B6EA7466}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeyboardManagerEditor", "src\modules\keyboardmanager\KeyboardManagerEditor\KeyboardManagerEditor.vcxproj", "{8DF78B53-200E-451F-9328-01EB907193AE}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeyboardManagerEditorLibrary", "src\modules\keyboardmanager\KeyboardManagerEditorLibrary\KeyboardManagerEditorLibrary.vcxproj", "{23D2070D-E4AD-4ADD-85A7-083D9C76AD49}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeyboardManagerEditorTest", "src\modules\keyboardmanager\KeyboardManagerEditorTest\KeyboardManagerEditorTest.vcxproj", "{62173D9A-6724-4C00-A1C8-FB646480A9EC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@@ -388,10 +402,6 @@ Global
{E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8}.Debug|x64.Build.0 = Debug|x64
{E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8}.Release|x64.ActiveCfg = Release|x64
{E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8}.Release|x64.Build.0 = Release|x64
{EAF23649-EF6E-478B-980E-81FAD96CCA2A}.Debug|x64.ActiveCfg = Debug|x64
{EAF23649-EF6E-478B-980E-81FAD96CCA2A}.Debug|x64.Build.0 = Debug|x64
{EAF23649-EF6E-478B-980E-81FAD96CCA2A}.Release|x64.ActiveCfg = Release|x64
{EAF23649-EF6E-478B-980E-81FAD96CCA2A}.Release|x64.Build.0 = Release|x64
{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}.Debug|x64.ActiveCfg = Debug|x64
{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}.Debug|x64.Build.0 = Debug|x64
{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}.Release|x64.ActiveCfg = Release|x64
@@ -504,10 +514,6 @@ Global
{5D00D290-4016-4CFE-9E41-1E7C724509BA}.Debug|x64.Build.0 = Debug|x64
{5D00D290-4016-4CFE-9E41-1E7C724509BA}.Release|x64.ActiveCfg = Release|x64
{5D00D290-4016-4CFE-9E41-1E7C724509BA}.Release|x64.Build.0 = Release|x64
{62173D9A-6724-4C00-A1C8-FB646480A9EC}.Debug|x64.ActiveCfg = Debug|x64
{62173D9A-6724-4C00-A1C8-FB646480A9EC}.Debug|x64.Build.0 = Debug|x64
{62173D9A-6724-4C00-A1C8-FB646480A9EC}.Release|x64.ActiveCfg = Release|x64
{62173D9A-6724-4C00-A1C8-FB646480A9EC}.Release|x64.Build.0 = Release|x64
{4AED67B6-55FD-486F-B917-E543DEE2CB3C}.Debug|x64.ActiveCfg = Debug|x64
{4AED67B6-55FD-486F-B917-E543DEE2CB3C}.Debug|x64.Build.0 = Debug|x64
{4AED67B6-55FD-486F-B917-E543DEE2CB3C}.Release|x64.ActiveCfg = Release|x64
@@ -616,10 +622,6 @@ Global
{98537082-0FDB-40DE-ABD8-0DC5A4269BAB}.Debug|x64.Build.0 = Debug|x64
{98537082-0FDB-40DE-ABD8-0DC5A4269BAB}.Release|x64.ActiveCfg = Release|x64
{98537082-0FDB-40DE-ABD8-0DC5A4269BAB}.Release|x64.Build.0 = Release|x64
{07C389E3-6BC8-41CF-923E-307B1265FA2D}.Debug|x64.ActiveCfg = Debug|x64
{07C389E3-6BC8-41CF-923E-307B1265FA2D}.Debug|x64.Build.0 = Debug|x64
{07C389E3-6BC8-41CF-923E-307B1265FA2D}.Release|x64.ActiveCfg = Release|x64
{07C389E3-6BC8-41CF-923E-307B1265FA2D}.Release|x64.Build.0 = Release|x64
{C3A17DCA-217B-462C-BB0C-BE086AF80081}.Debug|x64.ActiveCfg = Debug|x64
{C3A17DCA-217B-462C-BB0C-BE086AF80081}.Debug|x64.Build.0 = Debug|x64
{C3A17DCA-217B-462C-BB0C-BE086AF80081}.Release|x64.ActiveCfg = Release|x64
@@ -636,6 +638,30 @@ Global
{6ED2F4FC-E122-4CEE-90F1-97E4CCC8BC7A}.Debug|x64.Build.0 = Debug|x64
{6ED2F4FC-E122-4CEE-90F1-97E4CCC8BC7A}.Release|x64.ActiveCfg = Release|x64
{6ED2F4FC-E122-4CEE-90F1-97E4CCC8BC7A}.Release|x64.Build.0 = Release|x64
{BA661F5B-1D5A-4FFC-9BF1-FC39DF280BDD}.Debug|x64.ActiveCfg = Debug|x64
{BA661F5B-1D5A-4FFC-9BF1-FC39DF280BDD}.Debug|x64.Build.0 = Debug|x64
{BA661F5B-1D5A-4FFC-9BF1-FC39DF280BDD}.Release|x64.ActiveCfg = Release|x64
{BA661F5B-1D5A-4FFC-9BF1-FC39DF280BDD}.Release|x64.Build.0 = Release|x64
{E496B7FC-1E99-4BAB-849B-0E8367040B02}.Debug|x64.ActiveCfg = Debug|x64
{E496B7FC-1E99-4BAB-849B-0E8367040B02}.Debug|x64.Build.0 = Debug|x64
{E496B7FC-1E99-4BAB-849B-0E8367040B02}.Release|x64.ActiveCfg = Release|x64
{E496B7FC-1E99-4BAB-849B-0E8367040B02}.Release|x64.Build.0 = Release|x64
{7F4B3A60-BC27-45A7-8000-68B0B6EA7466}.Debug|x64.ActiveCfg = Debug|x64
{7F4B3A60-BC27-45A7-8000-68B0B6EA7466}.Debug|x64.Build.0 = Debug|x64
{7F4B3A60-BC27-45A7-8000-68B0B6EA7466}.Release|x64.ActiveCfg = Release|x64
{7F4B3A60-BC27-45A7-8000-68B0B6EA7466}.Release|x64.Build.0 = Release|x64
{8DF78B53-200E-451F-9328-01EB907193AE}.Debug|x64.ActiveCfg = Debug|x64
{8DF78B53-200E-451F-9328-01EB907193AE}.Debug|x64.Build.0 = Debug|x64
{8DF78B53-200E-451F-9328-01EB907193AE}.Release|x64.ActiveCfg = Release|x64
{8DF78B53-200E-451F-9328-01EB907193AE}.Release|x64.Build.0 = Release|x64
{23D2070D-E4AD-4ADD-85A7-083D9C76AD49}.Debug|x64.ActiveCfg = Debug|x64
{23D2070D-E4AD-4ADD-85A7-083D9C76AD49}.Debug|x64.Build.0 = Debug|x64
{23D2070D-E4AD-4ADD-85A7-083D9C76AD49}.Release|x64.ActiveCfg = Release|x64
{23D2070D-E4AD-4ADD-85A7-083D9C76AD49}.Release|x64.Build.0 = Release|x64
{62173D9A-6724-4C00-A1C8-FB646480A9EC}.Debug|x64.ActiveCfg = Debug|x64
{62173D9A-6724-4C00-A1C8-FB646480A9EC}.Debug|x64.Build.0 = Debug|x64
{62173D9A-6724-4C00-A1C8-FB646480A9EC}.Release|x64.ActiveCfg = Release|x64
{62173D9A-6724-4C00-A1C8-FB646480A9EC}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -661,7 +687,6 @@ Global
{2BE46397-4DFA-414C-9BD4-41E4BBF8CB34} = {6C7F47CC-2151-44A3-A546-41C70025132C}
{0B43679E-EDFA-4DA0-AD30-F4628B308B1B} = {6C7F47CC-2151-44A3-A546-41C70025132C}
{E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8} = {6C7F47CC-2151-44A3-A546-41C70025132C}
{EAF23649-EF6E-478B-980E-81FAD96CCA2A} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
{17DA04DF-E393-4397-9CF0-84DABE11032E} = {1AFB6476-670D-4E80-A464-657E01DFF482}
{38BDB927-829B-4C65-9CD9-93FB05D66D65} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{8AFFA899-0B73-49EC-8C50-0FADDA57B2FC} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
@@ -693,7 +718,6 @@ Global
{787B8AA6-CA93-4C84-96FE-DF31110AD1C4} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{08C8C05F-0362-41BC-818C-724572DF8B06} = {C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68}
{5D00D290-4016-4CFE-9E41-1E7C724509BA} = {1AFB6476-670D-4E80-A464-657E01DFF482}
{62173D9A-6724-4C00-A1C8-FB646480A9EC} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
{4AED67B6-55FD-486F-B917-E543DEE2CB3C} = {1AFB6476-670D-4E80-A464-657E01DFF482}
{42851751-CBC8-45A6-97F5-7A0753F7B4D1} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{1EF1EEF0-10F0-4F2E-8550-39B6D8044D3E} = {2F305555-C296-497E-AC20-5FA1B237996A}
@@ -731,6 +755,12 @@ Global
{4BABF3FE-3451-42FD-873F-3C332E18DCEF} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{0648DF05-5DDA-4BE1-B5F2-584926EBDB65} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{6ED2F4FC-E122-4CEE-90F1-97E4CCC8BC7A} = {C3081D9A-1586-441A-B5F4-ED815B3719C1}
{BA661F5B-1D5A-4FFC-9BF1-FC39DF280BDD} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
{E496B7FC-1E99-4BAB-849B-0E8367040B02} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
{7F4B3A60-BC27-45A7-8000-68B0B6EA7466} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
{8DF78B53-200E-451F-9328-01EB907193AE} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
{23D2070D-E4AD-4ADD-85A7-083D9C76AD49} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
{62173D9A-6724-4C00-A1C8-FB646480A9EC} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0}

View File

@@ -24,24 +24,23 @@ Microsoft PowerToys is a set of utilities for power users to tune and streamline
### Requirements
- Windows 10 v1903 (build 18362) or better preferred, Windows 10 v1803 (build 17134) minimum.
- Have [.NET Core 3.1 Desktop Runtime](https://dotnet.microsoft.com/download/dotnet-core/thank-you/runtime-desktop-3.1.11-windows-x64-installer). The installer should handle this but we want to directly make people aware.
- Windows 10 v1903 (build 18362) or newer preferred, Windows 10 v1803 (build 17134) minimum.
- ⚠️ PowerToys minimum version of Windows 10 will be increased to v1903 starting with the 0.37 release
- Have [.NET Core 3.1.13 Desktop Runtime](https://dotnet.microsoft.com/download/dotnet-core/thank-you/runtime-desktop-3.1.13-windows-x64-installer). The installer should handle this but we want to directly make people aware.
### Via GitHub with EXE [Recommended]
#### Stable version
Install from the [Microsoft PowerToys GitHub releases page][github-release-link]. Click on `Assets` to show the files available in the release and then click on `PowerToysSetup-0.33.1-x64.exe` 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.35.0-x64.exe` to download the PowerToys installer.
This is our preferred method.
#### Experimental version
To install the Video Conference mute, please use the [v0.28 pre-release experimental version of PowerToys][github-prerelease-link] to try out this version. It includes all improvements from v0.27 in addition to the Video conference utility. Click on `Assets` to show the files available in the release and then download the .exe installer.
We hope to have an updated version in February 2021 with the new DirectShow driver.
To install the Video Conference mute, please use the [v0.36 experimental version of PowerToys][github-prerelease-link] to try out this version. It includes all improvements from v0.35 in addition to the Video conference utility. Click on `Assets` to show the files available in the release and then download the .exe installer.
### Via WinGet (Preview)
Download PowerToys from [WinGet](https://github.com/microsoft/winget-cli/releases). To install PowerToys, run the following command from the command line / PowerShell:
Download PowerToys from [WinGet](https://github.com/microsoft/winget-cli#installing-the-client). To install PowerToys, run the following command from the command line / PowerShell:
```powershell
WinGet install powertoys
@@ -75,65 +74,73 @@ 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.33 - February 2021 Update
### 0.35 - March 2021 Update
Our goals for [v0.33 release cycle][github-release-link] was to add in some critical new functionality into the new user experience as well as a plug-in manager for PowerToys Run. In addition, we feel we are near ready to add in Video Conference mute into the stable release pending feedback from the pending 0.34 experimental release. The 0.34 experimental release will happen week of March 8th toward the end of the week pending testing.
Our goals for the [v0.35 release cycle][github-release-link] were to add in new functionality to support quick swapping layouts for FancyZones, wrap up work for the DirectShow migration for Video Conference Mute so we can migrate into the main dev branch as well as fixing bugs.
Our [prioritized roadmap][roadmap] of features and utilities that the core team is focusing on for the near future. We fixed a lot of localization issues from our initial release but we may not still be perfect. If you find an issue, please file a [localization bug][loc-bug].
The 0.36 experimental release was released as well which includes Video Conference Mute.
#### Highlights from v0.33 Stable/0.34 Experimental
Our [prioritized roadmap][roadmap] of features and utilities will dictate what the core team is focusing on for the near future.
#### Highlights from v0.35 Stable/0.36 Experimental
**General**
- Updated overview links to be language agnostic to the docs site.
- 'First time load' experience. The hope is a quick, light way to learn about basic functionality. We have some more work to do and want to also use the same framework for teaching about updates as well.
- PowerToys will start requiring Windows 10 v1903 or greater after 0.35.x release. The v1 settings, which supports older Windows versions, will be removed in 0.37.
- Note: We may be able to bring back support when we migrate to WinUI3 but as of now, we will be increasing the minimum version of Windows to 1903 or greater.
- Localization corrections
- Improved GitHub report bug template.
- Increased .NET Core to 3.1.13
- Fixed installer 'run as user' regression
**Color Picker**
- UX adjustments to editor. Thanks [@niels9001](https://github.com/niels9001)!
- `Esc` can now be used to exit the editor. Thanks [@BenConstable9](https://github.com/BenConstable9)!
**FancyZones**
- Adjusted editor UX based on feedback. Thanks [@niels9001](https://github.com/niels9001)!
- New options to change zone activation algorithm.
**File Explorer**
- Improved how SVG images are previewed in the preview pane, thanks[@Drakula44](https://github.com/Drakula44)!
- [@Aaron-Junker](Aaron-Junker) has created a proof of concept for using [Monaco editor](https://github.com/microsoft/monaco-editor) for previewing dev files. This will enable over 125+ file types.
- Added hotkeys and quick swap functionality for custom layouts! Users can now assign a hotkey in the editor and use it to quickly set a desktop's zones with `Ctrl + Win + Alt + NUMBER` key binding, or by pressing the hotkey while dragging a window.
- UX updates. Thanks [@niels9001](https://github.com/niels9001)!
- Fixed zone placement algorithm for when the Taskbar is vertical
- Bug fixes
**PowerToys Run**
- Plugin Manager now is in settings. You can directly turn on / off, include items in general search, and change the action key! Thanks [@htcfreek](https://github.com/htcfreek) for the great feedback!
- Improved support for additional window managers by abstracting out shell process calls. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
- Fix for PT Run registering the hotkey on non-supported OS versions.
- `~` will now act as the user home directory in Folder plugin. Thanks [@davidegiacometti](https://github.com/davidegiacometti)
- Service plugin has adjusted status messages
- Users can specify where to show the launcher window. Thanks [@addrum](https://github.com/addrum)!
- New plugin added to support opening previously used Visual Studio Code workspaces, remote machines (SSH or Codespaces), and containers! When enabled, use `{` to query for available workspaces. Thanks [@ricardosantos9521](https://github.com/ricardosantos9521)! Please note, this plugin is off by default.
- Shell history now saves the raw command instead of the resolved command. A command like `%appdata%` would now save in the Shell history as is instead of `C:\Users\YourUserName\AppData\Roaming`. Thanks [@mayitbeegh](https://github.com/mayitbeegh)!
- Better logging to try to track down some bugs
- Bug fixes
**Video Conference Mute (Experimental)**
- Adjust video muting to leverage DirectShow.
- Goal is to have 0.34 experimental release week of March 8th.
- Tracking work remaining at issue [#7944](https://github.com/microsoft/PowerToys/issues/7944)
- Goal is to have 0.36 experimental release week of April 5th (Yes, we've stated this before, we know)
**Settings**
- When restarting as admin, the settings now will reopen. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
**ARM64 Progress**
- Investigation on how we'll accomplish Settings with the XAML Island and WPF app.
**Contributor workflow**
- Main project now has a vsconfig which will prompt you to install needed items versus having to use a script. This will aid in keeping you up-to-date when something changes.
- Updated spell checker. Thanks [@jsoref](https://github.com/jsoref)!
#### Community contributions
We'd like to directly mention (in alphabetical order) for their continued community support this month and helping directly make PowerToys a better piece of software.
[@Aaron-Junker](https://github.com/Aaron-Junker),
[@davidegiacometti](https://github.com/davidegiacometti),
[@Drakula44](https://github.com/Drakula44),
[@htcfreek](https://github.com/htcfreek),
[@Jay-o-Way](https://github.com/Jay-o-Way),
[@addrum](https://github.com/addrum),
[@BenConstable9](https://github.com/BenConstable9),
[@htcfreek](https://github.com/htcfreek),
[@Jay-o-Way](https://github.com/Jay-o-Way),
[@jsoref](https://github.com/jsoref),
[@mayitbeegh](https://github.com/mayitbeegh),
[@niels9001](https://github.com/niels9001),
and
[@notDevagya](https://github.com/notDevagya)
[@pc-v2](https://github.com/pc-v2),
and
[@ricardosantos9521](https://github.com/ricardosantos9521)
#### What is being planned for v0.35 - March 2021
#### What is being planned for v0.37 - April 2021
For [v0.35][github-next-release-work], we are planning to work on:
For [v0.37][github-next-release-work], we are planning to work on:
- Stability and bug fixes
- FZ Editor hotkey layout swap support
- Integrating VCM in main release
- Start process for removal support for old settings system and migrating our minimum OS version to Windows 10 1903.
- Adding VCM to the stable release
- Removing v1 Settings / PT minimum version will become Windows 10 v1903
- Post-update guidance prompt work
## PowerToys Community
@@ -158,5 +165,5 @@ The application logs basic telemetry. Our Telemetry Data page (Coming Soon) has
[usingPowerToys-docs-link]: https://docs.microsoft.com/windows/powertoys/
<!-- items that need to be updated release to release -->
[github-next-release-work]: https://github.com/microsoft/PowerToys/issues?q=is%3Aopen+is%3Aissue+project%3Amicrosoft%2FPowerToys%2F18
[github-prerelease-link]: https://github.com/microsoft/PowerToys/releases/tag/v0.28.0
[github-next-release-work]: https://github.com/microsoft/PowerToys/issues?q=is%3Aopen+is%3Aissue+project%3Amicrosoft%2FPowerToys%2F19
[github-prerelease-link]: https://github.com/microsoft/PowerToys/releases/tag/v0.36.0

View File

@@ -0,0 +1,30 @@
# New plugin checklist
- [ ] The plugin is a project under `modules\launcher\Plugins`
- [ ] Microsoft plugin project name pattern: `Microsoft.PowerToys.Run.Plugin.{PluginName}`
- [ ] Community plugin project name pattern: `Community.PowerToys.Run.Plugin.{PluginName}`
- [ ] [`GlobalSuppressions.cs`](/src/codeAnalysis/GlobalSuppressions.cs) and [`StyleCop.json`](/src/codeAnalysis/StyleCop.json) have to be included in the plugin project so it follows PowerToys code guidelines
- [ ] The plugin has to have `{PowerToys version}.0` version
- [ ] Make sure `*.csproj` specify only x64 platform target
- [ ] The plugin has to contain a `plugin.json` file of the following format in its root folder
```
{
"ID": string, // GUID string
"ActionKeyword": string, // Direct activation phrase
"IsGlobal": boolean,
"Name": string, // Has to be unique, same as 'PluginName' in the project name pattern
"Author": string,
"Version": "1.0.0", // For future compatibility
"Language": "csharp", // So far we support only csharp
"Website": "https://aka.ms/powertoys",
"ExecuteFileName": string, // Should be {Type}.PowerToys.Run.Plugin.{PluginName}.dll
"IcoPathDark": string, // Path to dark theme icon. The path is relative to the root plugin folder
"IcoPathLight": string // Path to light theme icon. The path is relative to the root plugin folder
}
```
- [ ] Do not use plugin name or PowerToys as prefixes for entities inside of the plugin project
- [ ] The plugin has to have Unit tests. Use MSTest framework
- [ ] To enable localization add `LocProject.json` file to the plugin root folder. For details see [`localization.md`](/doc/devdocs/localization.md#enabling-localization-on-a-new-project)
- [ ] Plugin's output code and assets have to be included in the installer [`Product.wxs`](/installer/PowerToysSetup/Product.wxs)
- [ ] Test the plugin with a local build. Build the installer, install, check that the plugin works as expected
- [ ] All plugin's binaries have to be included in the signed build [`pipeline.user.windows.yml`](/.pipelines/pipeline.user.windows.yml)
- [ ] The plugin target framework has to be .NET Core 3.1. All dependencies have to have .NET 5 version

View File

@@ -136,8 +136,9 @@ int Bootstrapper(HINSTANCE hInstance)
options.add_options()
("h,help", "Show help")
("no_full_ui", "Use reduced UI for MSI")
("s,silent", "Suppress MSI UI and notifications")
("s,silent", "Suppress all UI, notifications and does not start PowerToys")
("no_start_pt", "Do not launch PowerToys after the installation is complete")
("start_pt", "Always launch PowerToys after the installation is complete")
("skip_dotnet_install", "Skip dotnet 3.X installation even if it's not detected")
("log_level", "Log level. Possible values: off|debug|error", cxxopts::value<std::string>()->default_value("off"))
("log_dir", "Log directory", cxxopts::value<std::string>()->default_value("."))
@@ -169,10 +170,11 @@ int Bootstrapper(HINSTANCE hInstance)
const bool noFullUI = cmdArgs["no_full_ui"].as<bool>();
const bool skipDotnetInstall = cmdArgs["skip_dotnet_install"].as<bool>();
const bool noStartPT = cmdArgs["no_start_pt"].as<bool>();
const bool startPT = cmdArgs["start_pt"].as<bool>();
const auto logLevel = cmdArgs["log_level"].as<std::string>();
const auto logDirArg = cmdArgs["log_dir"].as<std::string>();
const auto installDirArg = cmdArgs["install_dir"].as<std::string>();
const bool extract_msi_only = cmdArgs["extract_msi"].as<bool>();
const bool extractMsiOnly = cmdArgs["extract_msi"].as<bool>();
std::wstring installFolderProp;
if (!installDirArg.empty())
@@ -216,7 +218,7 @@ int Bootstrapper(HINSTANCE hInstance)
}
SetupLogger(logDir, severity);
spdlog::debug("PowerToys Bootstrapper is launched\nnoFullUI: {}\nsilent: {}\nno_start_pt: {}\nskip_dotnet_install: {}\nlog_level: {}\ninstall_dir: {}\nextract_msi: {}\n", noFullUI, g_Silent, noStartPT, skipDotnetInstall, logLevel, installDirArg, extract_msi_only);
spdlog::debug("PowerToys Bootstrapper is launched\nnoFullUI: {}\nsilent: {}\nno_start_pt: {}\nskip_dotnet_install: {}\nlog_level: {}\ninstall_dir: {}\nextract_msi: {}\n", noFullUI, g_Silent, noStartPT, skipDotnetInstall, logLevel, installDirArg, extractMsiOnly);
const VersionHelper myVersion(VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION);
@@ -229,7 +231,7 @@ int Bootstrapper(HINSTANCE hInstance)
}
// If a user requested an MSI -> extract it and exit
if (extract_msi_only)
if (extractMsiOnly)
{
if (const auto installerPath = ExtractEmbeddedInstaller(fs::current_path()))
{
@@ -402,8 +404,6 @@ int Bootstrapper(HINSTANCE hInstance)
ShowMessageBoxError(IDS_DOTNET_INSTALL_ERROR);
}
CleanupSettingsFromOlderVersions();
// At this point, there's no reason to show progress bar window, since MSI installers have their own
CloseProgressBarDialog();
@@ -418,7 +418,7 @@ int Bootstrapper(HINSTANCE hInstance)
spdlog::debug("Installation completed");
if (!noStartPT && !g_Silent)
if ((!noStartPT && !g_Silent) || startPT)
{
spdlog::debug("Starting the newly installed PowerToys.exe");
auto newPTPath = updating::get_msi_package_installed_path();

View File

@@ -283,6 +283,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";OLD_WINDOWS_ERROR" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[PowerToys requires Windows 10 version 1903 (May 2019 Update) or newer to run.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[PowerToys 需要 Windows 10 版本 1903 (2019 年 5 月更新)或更高版本才能运行。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";SNOOZE_BUTTON" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Snooze]]></Val>

View File

@@ -35,8 +35,8 @@
<Property Id="WINDOWSBUILDNUMBER" Secure="yes">
<RegistrySearch Id="BuildNumberSearch" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion" Name="CurrentBuildNumber" Type="raw" />
</Property>
<Condition Message="This application is only supported on Windows 10 version 1803 (build 17134) or higher.">
<![CDATA[(WINDOWSBUILDNUMBER >= 17134)]]>
<Condition Message="This application is only supported on Windows 10 version 1903 (build 18362) or higher.">
<![CDATA[(WINDOWSBUILDNUMBER >= 18362)]]>
</Condition>
<Icon Id="powertoys.exe" SourceFile="$(var.BinX64Dir)svgs\icon.ico"/>
@@ -212,7 +212,10 @@
<Directory Id="ShortcutGuideInstallFolder" Name="$(var.ShortcutGuideProjectName)"/>
<Directory Id="FileExplorerPreviewInstallFolder" Name="FileExplorerPreview" />
<Directory Id="FancyZonesInstallFolder" Name="$(var.FancyZonesProjectName)" />
<Directory Id="KeyboardManagerInstallFolder" Name="$(var.KeyboardManagerProjectName)" />
<Directory Id="KeyboardManagerInstallFolder" Name="$(var.KeyboardManagerProjectName)">
<Directory Id="KeyboardManagerEditorInstallFolder" Name="KeyboardManagerEditor" />
<Directory Id="KeyboardManagerEngineInstallFolder" Name="KeyboardManagerEngine" />
</Directory>
<Directory Id="ColorPickerInstallFolder" Name="$(var.ColorPickerProjectName)">
<Directory Id="ColorPickerResourcesFolder" Name="Resources"/>
</Directory>
@@ -281,9 +284,6 @@
<Directory Id="SettingsV2XamlAssetsInstallFolder" Name="Assets" />
</Directory>
</Directory>
<Directory Id="SettingsHtmlInstallFolder" Name="settings-html">
<Directory Id="SettingsHtmlDistInstallFolder" Name="dist"/>
</Directory>
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder">
@@ -315,9 +315,6 @@
</RegistryKey>
</RegistryKey>
</Component>
<Component Id="settings_exe" Guid="A5A461A9-7097-4CBA-9D39-3DBBB6B7B80C" Win64="yes">
<File Id="PowerToysSettings.exe" KeyPath="yes" Checksum="yes" />
</Component>
<Component Id="BackgroundActivator_dll" Guid="23B25EE4-BCA2-45DF-BBCD-82FBDF01C5AB" Win64="yes">
<File Id="BackgroundActivatorDLL.dll" KeyPath="yes" Checksum="yes" />
</Component>
@@ -391,6 +388,8 @@
<File Id="FancyZones_Microsoft.PowerToys.Common.UI" Source="$(var.BinX64Dir)modules\$(var.FancyZonesProjectName)\Microsoft.PowerToys.Common.UI.dll" />
<File Id="FancyZones_Telemetry.dll" Source="$(var.BinX64Dir)modules\$(var.FancyZonesProjectName)\ManagedTelemetry.dll" />
<File Id="FancyZone_System.IO.Abstractions.dll" Source="$(var.BinX64Dir)modules\$(var.FancyZonesProjectName)\System.IO.Abstractions.dll" />
<File Id="FancyZones_System.Runtime.CompilerServices.Unsafe.dll" Source="$(var.BinX64Dir)modules\$(var.FancyZonesProjectName)\System.Runtime.CompilerServices.Unsafe.dll" />
<File Id="FancyZones_System.Text.Encodings.Web.dll" Source="$(var.BinX64Dir)modules\$(var.FancyZonesProjectName)\System.Text.Encodings.Web.dll" />
</Component>
</DirectoryRef>
@@ -595,9 +594,21 @@
</Component>
</DirectoryRef>
<DirectoryRef Id="KeyboardManagerEditorInstallFolder" FileSource="$(var.BinX64Dir)modules\$(var.KeyboardManagerProjectName)\KeyboardManagerEditor">
<Component Id="Module_KeyboardManager_Editor" Guid="1240F1B8-17FE-4D68-B9AF-91882B0B1933" Win64="yes">
<File Source="$(var.BinX64Dir)modules\$(var.KeyboardManagerProjectName)\KeyboardManagerEditor\PowerToys.KeyboardManagerEditor.exe" />
</Component>
</DirectoryRef>
<DirectoryRef Id="KeyboardManagerEngineInstallFolder" FileSource="$(var.BinX64Dir)modules\$(var.KeyboardManagerProjectName)\KeyboardManagerEngine">
<Component Id="Module_KeyboardManager_Engine" Guid="14DBAA38-B98D-431F-9439-8EDE1C0670DB" Win64="yes">
<File Source="$(var.BinX64Dir)modules\$(var.KeyboardManagerProjectName)\KeyboardManagerEngine\PowerToys.KeyboardManagerEngine.exe" />
</Component>
</DirectoryRef>
<DirectoryRef Id="ColorPickerInstallFolder" FileSource="$(var.BinX64Dir)modules\$(var.ColorPickerProjectName)">
<Component Id="Module_ColorPicker" Guid="8A52A69E-37B2-4BEA-9D73-77763066052F" Win64="yes">
<?foreach File in ColorPicker.dll;System.IO.Abstractions.dll;ColorPickerUI.exe;ColorPickerUI.dll;ColorPickerUI.deps.json;ColorPickerUI.runtimeconfig.json;Microsoft.PowerToys.Settings.UI.Lib.dll;PowerToysInterop.dll;System.Text.Json.dll;ManagedTelemetry.dll;ManagedCommon.dll;ControlzEx.dll;Microsoft.Xaml.Behaviors.dll;ModernWpf.Controls.dll;ModernWpf.dll;System.ComponentModel.Composition.dll;Microsoft.PowerToys.Common.UI.dll?>
<?foreach File in ColorPicker.dll;System.IO.Abstractions.dll;ColorPickerUI.exe;ColorPickerUI.dll;ColorPickerUI.deps.json;ColorPickerUI.runtimeconfig.json;Microsoft.PowerToys.Settings.UI.Lib.dll;PowerToysInterop.dll;System.Text.Json.dll;ManagedTelemetry.dll;ManagedCommon.dll;ControlzEx.dll;Microsoft.Xaml.Behaviors.dll;ModernWpf.Controls.dll;ModernWpf.dll;System.ComponentModel.Composition.dll;Microsoft.PowerToys.Common.UI.dll;System.Runtime.CompilerServices.Unsafe.dll;System.Text.Encodings.Web.dll?>
<File Id="ColorPickerFile_$(var.File)" Source="$(var.BinX64Dir)modules\$(var.ColorPickerProjectName)\$(var.File)" />
<?endforeach?>
</Component>
@@ -648,7 +659,7 @@
<File Source="$(var.BinX64Dir)Settings\PowerToys.Settings.exe"/>
<File Source="$(var.BinX64Dir)Settings\Microsoft.PowerToys.Settings.UI.exe"/>
<!-- dll -->
<?foreach File in concrt140_app.dll;Microsoft.Bcl.AsyncInterfaces.dll;System.IO.Abstractions.dll;Microsoft.PowerToys.Settings.UI.Lib.dll;PowerToys.Settings.dll;Microsoft.Toolkit.dll;Microsoft.Toolkit.Uwp.dll;Microsoft.Toolkit.Uwp.UI.dll;Microsoft.Toolkit.Win32.UI.XamlHost.dll;Microsoft.Toolkit.Win32.UI.XamlHost.Managed.dll;Microsoft.Toolkit.Wpf.UI.Controls.dll;Microsoft.Toolkit.Wpf.UI.XamlHost.dll;Microsoft.UI.Xaml.dll;Microsoft.Xaml.Interactions.dll;Microsoft.Xaml.Interactivity.dll;msvcp140_1_app.dll;msvcp140_2_app.dll;msvcp140_app.dll;Newtonsoft.Json.dll;PowerToysInterop.dll;System.Runtime.CompilerServices.Unsafe.dll;System.Text.Encodings.Web.dll;System.Text.Json.dll;vcamp140_app.dll;vccorlib140_app.dll;vcomp140_app.dll;vcruntime140_1_app.dll;vcruntime140_app.dll;ManagedTelemetry.dll;ManagedCommon.dll?>
<?foreach File in concrt140_app.dll;Microsoft.Bcl.AsyncInterfaces.dll;System.IO.Abstractions.dll;Microsoft.PowerToys.Settings.UI.Lib.dll;PowerToys.Settings.dll;Microsoft.Toolkit.dll;Microsoft.Toolkit.Uwp.dll;Microsoft.Toolkit.Uwp.UI.dll;Microsoft.Toolkit.Win32.UI.XamlHost.dll;Microsoft.Toolkit.Win32.UI.XamlHost.Managed.dll;Microsoft.Toolkit.Wpf.UI.Controls.dll;Microsoft.Toolkit.Wpf.UI.XamlHost.dll;Microsoft.UI.Xaml.dll;Microsoft.Xaml.Interactions.dll;Microsoft.Xaml.Interactivity.dll;msvcp140_1_app.dll;msvcp140_2_app.dll;msvcp140_app.dll;Newtonsoft.Json.dll;PowerToysInterop.dll;System.Runtime.CompilerServices.Unsafe.dll;System.Text.Encodings.Web.dll;System.Text.Json.dll;vcamp140_app.dll;vccorlib140_app.dll;vcomp140_app.dll;vcruntime140_1_app.dll;vcruntime140_app.dll;ManagedTelemetry.dll;ManagedCommon.dll;ColorCode.Core.dll;ColorCode.UWP.dll;Microsoft.Graphics.Canvas.winmd;Microsoft.Toolkit.Parsers.dll;Microsoft.Toolkit.Uwp.UI.Animations.dll;Microsoft.Toolkit.Uwp.UI.Controls.dll?>
<File Id="SettingsV2_$(var.File)" Source="$(var.BinX64Dir)Settings\$(var.File)" />
<?endforeach?>
<!-- json -->
@@ -743,23 +754,6 @@
</Component>
</DirectoryRef>
<DirectoryRef Id="SettingsHtmlInstallFolder" FileSource="$(var.RepoDir)\settings\settings-html\">
<Component Id="settings_html" Guid="87881A99-E917-4B0D-B1D8-5C6EB9709F96" Win64="yes">
<File Source="$(var.RepoDir)\src\settings\settings-html\index.html" KeyPath="yes" />
</Component>
<Component Id="settings_dark_html" Guid="855866C7-2F13-4B08-B5C1-B507354C2760" Win64="yes">
<File Source="$(var.RepoDir)\src\settings\settings-html\index-dark.html" KeyPath="yes" />
</Component>
</DirectoryRef>
<DirectoryRef Id="SettingsHtmlDistInstallFolder" FileSource="$(var.RepoDir)\settings\settings-html\dist\">
<Component Id="settings_js_bundle" Guid="9EF539C1-2F50-421E-B074-C58ED3A9785C" Win64="yes">
<File Source="$(var.RepoDir)\src\settings\settings-html\dist\bundle.js" KeyPath="yes" />
</Component>
<Component Id="settings_css" Guid="9B8EBF56-A7A7-4D83-B53C-75A692E2F95A" Win64="yes">
<File Source="$(var.RepoDir)\src\settings\settings-html\dist\layout.css" KeyPath="yes" />
</Component>
</DirectoryRef>
<DirectoryRef Id="DesktopFolder">
<Component Id="DesktopShortcut" Guid="87321F2B-CC48-4326-881E-9C62CC260DC8">
<Condition>INSTALLDESKTOPSHORTCUT</Condition>
@@ -802,6 +796,8 @@
<ComponentRef Id="Module_PowerPreview" />
<ComponentRef Id="Module_PowerPreview_PerUserRegistry" />
<ComponentRef Id="Module_KeyboardManager" />
<ComponentRef Id="Module_KeyboardManager_Editor" />
<ComponentRef Id="Module_KeyboardManager_Engine" />
<ComponentRef Id="Module_ColorPicker" />
<ComponentRef Id="Module_ColorPicker_Resources"/>
<ComponentRef Id="SettingsV2" />
@@ -814,11 +810,6 @@
<ComponentRef Id="SettingsV2Styles" />
<ComponentRef Id="SettingsV2Views" />
<ComponentRef Id="SettingsV2XamlAssets" />
<ComponentRef Id="settings_exe" />
<ComponentRef Id="settings_html" />
<ComponentRef Id="settings_dark_html" />
<ComponentRef Id="settings_js_bundle" />
<ComponentRef Id="settings_css" />
</ComponentGroup>
<ComponentGroup Id="ToolComponents" Directory="ToolsFolder">
<ComponentRef Id="BugReportTool_exe" />
@@ -936,7 +927,7 @@
<Component Id="launcherInstallComponent" Directory="LauncherInstallFolder" Guid="5E688DB4-C522-4268-BA54-ED1CDFFE9DB6">
<File Source="$(var.BinX64Dir)modules\Launcher\Microsoft.Launcher.dll" />
<?foreach File in concrt140_app.dll;ICSharpCode.SharpZipLib.dll;JetBrains.Annotations.dll;Mages.Core.dll;Microsoft.Search.Interop.dll;Mono.Cecil.dll;Mono.Cecil.Mdb.dll;Mono.Cecil.Pdb.dll;Mono.Cecil.Rocks.dll;msvcp140_1_app.dll;msvcp140_2_app.dll;msvcp140_app.dll;Newtonsoft.Json.dll;NLog.dll;NLog.Extensions.Logging.dll;PowerLauncher.deps.json;PowerLauncher.dll;PowerLauncher.exe;Microsoft.Xaml.Behaviors.dll;System.Text.Json.dll;PowerLauncher.runtimeconfig.json;System.Data.OleDb.dll;vcamp140_app.dll;vccorlib140_app.dll;vcomp140_app.dll;vcruntime140_1_app.dll;vcruntime140_app.dll;Wox.Infrastructure.dll;Wox.Plugin.dll;PowerToysInterop.dll;ManagedTelemetry.dll;PowerLauncher.Telemetry.dll;Microsoft.Extensions.Configuration.Abstractions.dll;Microsoft.Extensions.Configuration.Binder.dll;Microsoft.Extensions.Configuration.dll;Microsoft.Extensions.DependencyInjection.Abstractions.dll;Microsoft.Extensions.DependencyInjection.dll;Microsoft.Extensions.Logging.Abstractions.dll;Microsoft.Extensions.Logging.dll;Microsoft.Extensions.Options.dll;Microsoft.Extensions.Primitives.dll;ControlzEx.dll;ManagedCommon.dll;System.IO.Abstractions.dll;Microsoft.PowerToys.Common.UI.dll;System.ServiceProcess.ServiceController.dll;Microsoft.Toolkit.Uwp.Notifications.dll;ModernWpf.Controls.dll;ModernWpf.dll?>
<?foreach File in concrt140_app.dll;ICSharpCode.SharpZipLib.dll;JetBrains.Annotations.dll;Mages.Core.dll;Microsoft.Search.Interop.dll;Mono.Cecil.dll;Mono.Cecil.Mdb.dll;Mono.Cecil.Pdb.dll;Mono.Cecil.Rocks.dll;msvcp140_1_app.dll;msvcp140_2_app.dll;msvcp140_app.dll;Newtonsoft.Json.dll;NLog.dll;NLog.Extensions.Logging.dll;PowerLauncher.deps.json;PowerLauncher.dll;PowerLauncher.exe;Microsoft.Xaml.Behaviors.dll;System.Text.Json.dll;PowerLauncher.runtimeconfig.json;System.Data.OleDb.dll;vcamp140_app.dll;vccorlib140_app.dll;vcomp140_app.dll;vcruntime140_1_app.dll;vcruntime140_app.dll;Wox.Infrastructure.dll;Wox.Plugin.dll;PowerToysInterop.dll;ManagedTelemetry.dll;PowerLauncher.Telemetry.dll;Microsoft.Extensions.Configuration.Abstractions.dll;Microsoft.Extensions.Configuration.Binder.dll;Microsoft.Extensions.Configuration.dll;Microsoft.Extensions.DependencyInjection.Abstractions.dll;Microsoft.Extensions.DependencyInjection.dll;Microsoft.Extensions.Logging.Abstractions.dll;Microsoft.Extensions.Logging.dll;Microsoft.Extensions.Options.dll;Microsoft.Extensions.Primitives.dll;ControlzEx.dll;ManagedCommon.dll;System.IO.Abstractions.dll;Microsoft.PowerToys.Common.UI.dll;System.ServiceProcess.ServiceController.dll;Microsoft.Toolkit.Uwp.Notifications.dll;ModernWpf.Controls.dll;ModernWpf.dll;System.Runtime.CompilerServices.Unsafe.dll;System.Text.Encodings.Web.dll?>
<File Id="File_$(var.File)" Source="$(var.BinX64Dir)modules\launcher\$(var.File)" />
<?endforeach?>
<File Source="$(var.BinX64Dir)Settings\Microsoft.PowerToys.Settings.UI.Lib.dll" />

View File

@@ -87,6 +87,7 @@
<ClInclude Include="KeyboardHook.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="shared_constants.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="Generated Files\AssemblyInfo.cpp" />

View File

@@ -27,6 +27,9 @@
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="shared_constants.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="interop.cpp">

View File

@@ -22,9 +22,6 @@ namespace Microsoft.Interop.Tests
[TestInitialize]
public void Initialize()
{
// Make sure we don't crash
Assert.IsTrue(CommonManaged.ShouldNewSettingsBeUsed() == CommonManaged.ShouldNewSettingsBeUsed());
ClientPipe = new TwoWayPipeMessageIPCManaged(ClientSidePipe, ServerSidePipe, null);
}

View File

@@ -122,11 +122,6 @@ public
static String ^ GetProductVersion() {
return gcnew String(get_product_version().c_str());
}
static bool ShouldNewSettingsBeUsed()
{
return UseNewSettings();
}
};
public

View File

@@ -27,4 +27,4 @@ namespace CommonSharedConstants
// Max DWORD for key code to disable keys.
const int VK_DISABLED = 0x100;
}
}

View File

@@ -55,4 +55,9 @@ public:
{
logger->critical(fmt, args...);
}
static void flush()
{
logger->flush();
}
};

View File

@@ -7,13 +7,15 @@ struct LogSettings
inline const static std::wstring defaultLogLevel = L"trace";
inline const static std::wstring logLevelOption = L"logLevel";
inline const static std::string runnerLoggerName = "runner";
inline const static std::wstring logPath = L"Logs\\";
inline const static std::wstring runnerLogPath = L"RunnerLogs\\runner-log.txt";
inline const static std::string actionRunnerLoggerName = "action-runner";
inline const static std::wstring actionRunnerLogPath = L"RunnerLogs\\action-runner-log.txt";
inline const static std::string launcherLoggerName = "launcher";
inline const static std::wstring launcherLogPath = L"LogsModuleInterface\\launcher-log.txt";
inline const static std::string fancyZonesLoggerName = "fancyzones";
inline const static std::wstring fancyZonesLogPath = L"FancyZonesLogs\\fancyzones-log.txt";
inline const static std::wstring fancyZonesLogPath = L"fancyzones-log.txt";
inline const static std::wstring fancyZonesOldLogPath = L"FancyZonesLogs\\"; // needed to clean up old logs
inline const static std::string shortcutGuideLoggerName = "shortcut-guide";
inline const static std::wstring shortcutGuideLogPath = L"ShortcutGuideLogs\\shortcut-guide-log.txt";
inline const static std::string keyboardManagerLoggerName = "keyboard-manager";

View File

@@ -10,7 +10,6 @@
#include <common/notifications/notifications.h>
#include <common/SettingsAPI/settings_helpers.h>
#include <common/utils/json.h>
#include <common/utils/os-detect.h>
namespace // Strings in this namespace should not be localized
{
@@ -77,9 +76,6 @@ namespace updating
const VersionHelper current_version(VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION);
VersionHelper github_version = current_version;
// On a <1903 system, block updates to 0.36+
const bool blockNonPatchReleases = current_version.major == 0 && current_version.minor == 35 && !Is19H1OrHigher();
if (prerelease)
{
const auto body = co_await client.request(Uri{ ALL_RELEASES_ENDPOINT });
@@ -108,11 +104,6 @@ namespace updating
}
}
if (blockNonPatchReleases && github_version >= VersionHelper{ 0, 36, 0 })
{
co_return version_up_to_date{};
}
if (github_version <= current_version)
{
co_return version_up_to_date{};

View File

@@ -0,0 +1,61 @@
#include <windows.h>
#include <string>
class EventLocker
{
public:
EventLocker(HANDLE h)
{
eventHandle = h;
SetEvent(eventHandle);
}
static std::optional<EventLocker> Get(std::wstring eventName)
{
EventLocker locker(eventName);
if (!locker.eventHandle)
{
return {};
}
return locker;
}
EventLocker(EventLocker& e) = delete;
EventLocker& operator=(EventLocker& e) = delete;
EventLocker(EventLocker&& e) noexcept
{
this->eventHandle = e.eventHandle;
e.eventHandle = nullptr;
}
EventLocker& operator=(EventLocker&& e) noexcept
{
this->eventHandle = e.eventHandle;
e.eventHandle = nullptr;
}
~EventLocker()
{
if (eventHandle)
{
ResetEvent(eventHandle);
CloseHandle(eventHandle);
eventHandle = nullptr;
}
}
private:
EventLocker(std::wstring eventName)
{
eventHandle = CreateEvent(nullptr, true, false, eventName.c_str());
if (!eventHandle)
{
return;
}
SetEvent(eventHandle);
}
HANDLE eventHandle;
};

View File

@@ -0,0 +1,78 @@
#include <functional>
#include <thread>
#include <string>
#include <windows.h>
class EventWaiter
{
public:
EventWaiter() {}
EventWaiter(const std::wstring& name, std::function<void(DWORD)> callback)
{
// Create localExitThreadEvent and localWaitingEvent for capturing. We can not capture 'this' as we implement move constructor.
auto localExitThreadEvent = exitThreadEvent = CreateEvent(nullptr, false, false, nullptr);
HANDLE localWaitingEvent = waitingEvent = CreateEvent(nullptr, false, false, name.c_str());
std::thread([=]() {
HANDLE events[2] = { localWaitingEvent, localExitThreadEvent };
while (true)
{
auto waitResult = WaitForMultipleObjects(2, events, false, INFINITE);
if (waitResult == WAIT_OBJECT_0 + 1)
{
break;
}
if (waitResult == WAIT_FAILED)
{
callback(GetLastError());
continue;
}
if (waitResult == WAIT_OBJECT_0)
{
callback(ERROR_SUCCESS);
}
}
}).detach();
}
EventWaiter(EventWaiter&) = delete;
EventWaiter& operator=(EventWaiter&) = delete;
EventWaiter(EventWaiter&& a) noexcept
{
this->exitThreadEvent = a.exitThreadEvent;
this->waitingEvent = a.waitingEvent;
a.exitThreadEvent = nullptr;
a.waitingEvent = nullptr;
}
EventWaiter& operator=(EventWaiter&& a) noexcept
{
this->exitThreadEvent = a.exitThreadEvent;
this->waitingEvent = a.waitingEvent;
a.exitThreadEvent = nullptr;
a.waitingEvent = nullptr;
return *this;
}
~EventWaiter()
{
if (exitThreadEvent)
{
SetEvent(exitThreadEvent);
CloseHandle(exitThreadEvent);
}
if (waitingEvent)
{
CloseHandle(waitingEvent);
}
}
private:
HANDLE exitThreadEvent = nullptr;
HANDLE waitingEvent = nullptr;
};

View File

@@ -0,0 +1,32 @@
#include <functional>
#include <string>
#include <Windows.h>
#include <thread>
namespace ProcessWaiter
{
void OnProcessTerminate(std::wstring parent_pid, std::function<void(DWORD)> callback)
{
DWORD pid = std::stol(parent_pid);
std::thread([=]() {
HANDLE process = OpenProcess(SYNCHRONIZE, FALSE, pid);
if (process != nullptr)
{
if (WaitForSingleObject(process, INFINITE) == WAIT_OBJECT_0)
{
CloseHandle(process);
callback(ERROR_SUCCESS);
}
else
{
CloseHandle(process);
callback(GetLastError());
}
}
else
{
callback(GetLastError());
}
}).detach();
}
}

View File

@@ -0,0 +1,239 @@
#include <Windows.h>
#include <DbgHelp.h>
#include <signal.h>
#include <sstream>
#include <stdio.h>
#include "../logger/logger.h"
static IMAGEHLP_SYMBOL64* pSymbol = (IMAGEHLP_SYMBOL64*)malloc(sizeof(IMAGEHLP_SYMBOL64) + MAX_PATH * sizeof(TCHAR));
static IMAGEHLP_LINE64 line;
static BOOLEAN processingException = FALSE;
static CHAR modulePath[MAX_PATH];
static inline const char* exceptionDescription(const DWORD& code)
{
switch (code)
{
case EXCEPTION_ACCESS_VIOLATION:
return "EXCEPTION_ACCESS_VIOLATION";
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
return "EXCEPTION_ARRAY_BOUNDS_EXCEEDED";
case EXCEPTION_BREAKPOINT:
return "EXCEPTION_BREAKPOINT";
case EXCEPTION_DATATYPE_MISALIGNMENT:
return "EXCEPTION_DATATYPE_MISALIGNMENT";
case EXCEPTION_FLT_DENORMAL_OPERAND:
return "EXCEPTION_FLT_DENORMAL_OPERAND";
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
return "EXCEPTION_FLT_DIVIDE_BY_ZERO";
case EXCEPTION_FLT_INEXACT_RESULT:
return "EXCEPTION_FLT_INEXACT_RESULT";
case EXCEPTION_FLT_INVALID_OPERATION:
return "EXCEPTION_FLT_INVALID_OPERATION";
case EXCEPTION_FLT_OVERFLOW:
return "EXCEPTION_FLT_OVERFLOW";
case EXCEPTION_FLT_STACK_CHECK:
return "EXCEPTION_FLT_STACK_CHECK";
case EXCEPTION_FLT_UNDERFLOW:
return "EXCEPTION_FLT_UNDERFLOW";
case EXCEPTION_ILLEGAL_INSTRUCTION:
return "EXCEPTION_ILLEGAL_INSTRUCTION";
case EXCEPTION_IN_PAGE_ERROR:
return "EXCEPTION_IN_PAGE_ERROR";
case EXCEPTION_INT_DIVIDE_BY_ZERO:
return "EXCEPTION_INT_DIVIDE_BY_ZERO";
case EXCEPTION_INT_OVERFLOW:
return "EXCEPTION_INT_OVERFLOW";
case EXCEPTION_INVALID_DISPOSITION:
return "EXCEPTION_INVALID_DISPOSITION";
case EXCEPTION_NONCONTINUABLE_EXCEPTION:
return "EXCEPTION_NONCONTINUABLE_EXCEPTION";
case EXCEPTION_PRIV_INSTRUCTION:
return "EXCEPTION_PRIV_INSTRUCTION";
case EXCEPTION_SINGLE_STEP:
return "EXCEPTION_SINGLE_STEP";
case EXCEPTION_STACK_OVERFLOW:
return "EXCEPTION_STACK_OVERFLOW";
default:
return "UNKNOWN EXCEPTION";
}
}
/* Returns the index of the last backslash in the file path */
inline int GetFilenameStart(CHAR* path)
{
int pos = 0;
int found = 0;
if (path != NULL)
{
while (path[pos] != '\0' && pos < MAX_PATH)
{
if (path[pos] == '\\')
{
found = pos + 1;
}
++pos;
}
}
return found;
}
inline void LogStackTrace()
{
BOOL result;
HANDLE thread;
HANDLE process;
CONTEXT context;
STACKFRAME64 stack;
ULONG frame;
DWORD64 dw64Displacement;
DWORD dwDisplacement;
memset(&stack, 0, sizeof(STACKFRAME64));
memset(pSymbol, '\0', sizeof(*pSymbol) + MAX_PATH);
memset(&modulePath[0], '\0', sizeof(modulePath));
line.LineNumber = 0;
try
{
RtlCaptureContext(&context);
}
catch (...)
{
Logger::error(L"Failed to capture context. {}", get_last_error_or_default(GetLastError()));
return;
}
process = GetCurrentProcess();
thread = GetCurrentThread();
dw64Displacement = 0;
stack.AddrPC.Offset = context.Rip;
stack.AddrPC.Mode = AddrModeFlat;
stack.AddrStack.Offset = context.Rsp;
stack.AddrStack.Mode = AddrModeFlat;
stack.AddrFrame.Offset = context.Rbp;
stack.AddrFrame.Mode = AddrModeFlat;
std::stringstream ss;
for (frame = 0;; frame++)
{
result = StackWalk64(
IMAGE_FILE_MACHINE_AMD64,
process,
thread,
&stack,
&context,
NULL,
SymFunctionTableAccess64,
SymGetModuleBase64,
NULL);
if (!result)
{
break;
}
pSymbol->MaxNameLength = MAX_PATH;
pSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
if (!SymGetSymFromAddr64(process, stack.AddrPC.Offset, &dw64Displacement, pSymbol))
{
Logger::error(L"Failed to get a symbol. {}", get_last_error_or_default(GetLastError()));
}
line.LineNumber = 0;
SymGetLineFromAddr64(process, stack.AddrPC.Offset, &dwDisplacement, &line);
DWORD64 moduleBase = SymGetModuleBase64(process, stack.AddrPC.Offset);
if (moduleBase)
{
if (!GetModuleFileNameA((HINSTANCE)moduleBase, modulePath, MAX_PATH))
{
Logger::error(L"Failed to get a module path. {}", get_last_error_or_default(GetLastError()));
}
}
else
{
Logger::error(L"Failed to get a module. {}", get_last_error_or_default(GetLastError()));
}
ss << std::string(modulePath).substr(GetFilenameStart(modulePath)) << "!" << pSymbol->Name << "(" << line.FileName << ":" << line.LineNumber << std::endl;
}
Logger::error("STACK TRACE\r\n{}", ss.str());
Logger::flush();
}
inline LONG WINAPI UnhandledExceptionHandler(PEXCEPTION_POINTERS info)
{
if (!processingException)
{
bool headerLogged = false;
try
{
const char* exDescription = "Exception code not available";
processingException = true;
if (info != NULL && info->ExceptionRecord != NULL && info->ExceptionRecord->ExceptionCode != NULL)
{
exDescription = exceptionDescription(info->ExceptionRecord->ExceptionCode);
}
headerLogged = true;
Logger::error(exDescription);
LogStackTrace();
}
catch (...)
{
Logger::error("Failed to log stack trace");
Logger::flush();
}
processingException = false;
}
return EXCEPTION_CONTINUE_SEARCH;
}
/* Handler to trap abort() calls */
inline void AbortHandler(int signal_number)
{
Logger::error("--- ABORT");
try
{
LogStackTrace();
}
catch(...)
{
Logger::error("Failed to log stack trace on abort");
Logger::flush();
}
}
inline void InitSymbols()
{
// Preload symbols so they will be available in case of out-of-memory exception
SymSetOptions(SYMOPT_LOAD_LINES | SYMOPT_UNDNAME);
line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
HANDLE process = GetCurrentProcess();
if (!SymInitialize(process, NULL, TRUE))
{
Logger::error(L"Failed to initialize symbol handler. {}", get_last_error_or_default(GetLastError()));
}
}
inline void InitUnhandledExceptionHandler_x64(void)
{
try
{
InitSymbols();
// Global handler for unhandled exceptions
SetUnhandledExceptionFilter(UnhandledExceptionHandler);
// Handler for abort()
signal(SIGABRT, &AbortHandler);
}
catch(...)
{
Logger::error("Failed to init global unhandled exception handler");
}
}

View File

@@ -10,17 +10,13 @@
namespace
{
constexpr inline wchar_t POWERTOYS_MSI_MUTEX_NAME[] = L"Local\\PowerToyRunMutex";
constexpr inline wchar_t POWERTOYS_MSIX_MUTEX_NAME[] = L"Local\\PowerToyMSIXRunMutex";
constexpr inline wchar_t POWERTOYS_BOOTSTRAPPER_MUTEX_NAME[] = L"PowerToysBootstrapperMutex";
constexpr inline wchar_t POWERTOYS_MSI_MUTEX_NAME[] = L"Local\\PowerToys_Runner_MSI_InstanceMutex";
constexpr inline wchar_t POWERTOYS_MSIX_MUTEX_NAME[] = L"Local\\PowerToys_Runner_MSIX_InstanceMutex";
constexpr inline wchar_t POWERTOYS_BOOTSTRAPPER_MUTEX_NAME[] = L"Local\\PowerToys_Bootstrapper_InstanceMutex";
}
inline wil::unique_mutex_nothrow createAppMutex(std::wstring mutexName)
inline wil::unique_mutex_nothrow createAppMutex(const std::wstring& mutexName)
{
wchar_t username[UNLEN + 1];
DWORD username_length = UNLEN + 1;
GetUserNameW(username, &username_length);
mutexName += username;
wil::unique_mutex_nothrow result{ CreateMutexW(nullptr, TRUE, mutexName.c_str()) };
return GetLastError() == ERROR_ALREADY_EXISTS ? wil::unique_mutex_nothrow{} : std::move(result);

View File

@@ -0,0 +1,99 @@
#pragma once
#include <filesystem>
#include <common/version/version.h>
#include <common/SettingsAPI/settings_helpers.h>
namespace LoggerHelpers
{
inline std::filesystem::path get_log_folder_path(std::wstring_view appPath)
{
std::filesystem::path logFolderPath(appPath);
logFolderPath.append(LogSettings::logPath);
logFolderPath.append(get_product_version());
return logFolderPath;
}
inline bool delete_old_log_folder(const std::filesystem::path& logFolderPath)
{
try
{
std::filesystem::remove_all(logFolderPath);
return true;
}
catch (std::filesystem::filesystem_error& e)
{
Logger::error("Failed to delete old log folder: {}", e.what());
}
return false;
}
inline bool dir_exists(std::filesystem::path dir)
{
std::error_code err;
auto entry = std::filesystem::directory_entry(dir, err);
if (err.value())
{
Logger::error("Failed to create directory entry. {}", err.message());
return false;
}
return entry.exists();
}
inline bool delete_other_versions_log_folders(std::wstring_view appPath, const std::filesystem::path& currentVersionLogFolder)
{
bool result = true;
std::filesystem::path logFolderPath(appPath);
logFolderPath.append(LogSettings::logPath);
if (!dir_exists(logFolderPath))
{
Logger::trace("Directory {} does not exist", logFolderPath.string());
return true;
}
std::error_code err;
auto folders = std::filesystem::directory_iterator(logFolderPath, err);
if (err.value())
{
Logger::error("Failed to create directory iterator for {}. {}", logFolderPath.string(), err.message());
return false;
}
for (const auto& dir : folders)
{
if (dir != currentVersionLogFolder)
{
try
{
std::filesystem::remove_all(dir);
}
catch (std::filesystem::filesystem_error& e)
{
Logger::error("Failed to delete previous version log folder: {}", e.what());
result = false;
}
}
}
return result;
}
inline void init_logger(std::wstring moduleName, std::wstring internalPath, std::string loggerName)
{
std::filesystem::path rootFolder(PTSettingsHelper::get_module_save_folder_location(moduleName));
rootFolder.append(internalPath);
auto currentFolder = rootFolder;
currentFolder.append(LogSettings::logPath);
currentFolder.append(get_product_version());
auto logsPath = currentFolder;
logsPath.append(L"log.txt");
Logger::init(loggerName, logsPath.wstring(), PTSettingsHelper::get_log_settings_file_location());
delete_other_versions_log_folders(rootFolder.wstring(), currentFolder);
}
}

View File

@@ -22,10 +22,3 @@ inline bool Is19H1OrHigher()
{
return IsAPIContractV8Available();
}
// This function returns true if the build is 19h1 or higher, so that we deploy the new settings.
// It returns false otherwise.
inline bool UseNewSettings()
{
return Is19H1OrHigher();
}

View File

@@ -22,6 +22,12 @@ inline std::optional<std::wstring> get_last_error_message(const DWORD dw)
return message;
}
inline std::wstring get_last_error_or_default(const DWORD dw)
{
auto message = get_last_error_message(dw);
return message.has_value() ? message.value() : L"";
}
inline void show_last_error_message(const wchar_t* functionName, DWORD dw, const wchar_t* errorTitle)
{
const auto system_message = get_last_error_message(dw);

View File

@@ -54,6 +54,9 @@
<ClCompile Include="trace.cpp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\common\logger\logger.vcxproj">
<Project>{d9b8fc84-322a-4f9f-bbb9-20915c47ddfd}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\common\SettingsAPI\SetttingsAPI.vcxproj">
<Project>{6955446d-23f7-4023-9bb3-8657f904af99}</Project>
</ProjectReference>
@@ -69,6 +72,7 @@
<None Include="Resources.resx" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<Import Project="..\..\..\..\deps\spdlog.props" />
<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')" />
</ImportGroup>

View File

@@ -4,8 +4,8 @@
#include <interface/powertoy_module_interface.h>
#include "trace.h"
#include "Generated Files/resource.h"
#include <common/logger/logger.h>
#include <common/SettingsAPI/settings_objects.h>
#include <common/utils/os-detect.h>
#include <common/utils/resources.h>
#include <colorPicker/ColorPicker/ColorPickerConstants.h>
@@ -29,6 +29,17 @@ BOOL APIENTRY DllMain(HMODULE hModule,
return TRUE;
}
namespace
{
const wchar_t JSON_KEY_PROPERTIES[] = L"properties";
const wchar_t JSON_KEY_WIN[] = L"win";
const wchar_t JSON_KEY_ALT[] = L"alt";
const wchar_t JSON_KEY_CTRL[] = L"ctrl";
const wchar_t JSON_KEY_SHIFT[] = L"shift";
const wchar_t JSON_KEY_CODE[] = L"code";
const wchar_t JSON_KEY_ACTIVATION_SHORTCUT[] = L"ActivationShortcut";
}
struct ModuleSettings
{
} g_settings;
@@ -50,12 +61,101 @@ private:
HANDLE send_telemetry_event;
Hotkey m_hotkey;
// Handle to event used to invoke ColorPicker
HANDLE m_hInvokeEvent;
void parse_hotkey(PowerToysSettings::PowerToyValues& settings)
{
auto settingsObject = settings.get_raw_json();
if (settingsObject.GetView().Size())
{
try
{
auto jsonHotkeyObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_ACTIVATION_SHORTCUT);
m_hotkey.win = jsonHotkeyObject.GetNamedBoolean(JSON_KEY_WIN);
m_hotkey.alt = jsonHotkeyObject.GetNamedBoolean(JSON_KEY_ALT);
m_hotkey.shift = jsonHotkeyObject.GetNamedBoolean(JSON_KEY_SHIFT);
m_hotkey.ctrl = jsonHotkeyObject.GetNamedBoolean(JSON_KEY_CTRL);
m_hotkey.key = static_cast<unsigned char>(jsonHotkeyObject.GetNamedNumber(JSON_KEY_CODE));
}
catch (...)
{
Logger::error("Failed to initialize ColorPicker start shortcut");
}
}
else
{
Logger::info("ColorPicker settings are empty");
}
if (!m_hotkey.key)
{
Logger::info("ColorPicker is going to use default shortcut");
m_hotkey.win = true;
m_hotkey.alt = false;
m_hotkey.shift = true;
m_hotkey.ctrl = false;
m_hotkey.key = 'C';
}
}
bool is_process_running()
{
return WaitForSingleObject(m_hProcess, 0) == WAIT_TIMEOUT;
}
void launch_process()
{
Logger::trace(L"Launching ColorPicker process");
unsigned long powertoys_pid = GetCurrentProcessId();
std::wstring executable_args = L"";
executable_args.append(std::to_wstring(powertoys_pid));
SHELLEXECUTEINFOW sei{ sizeof(sei) };
sei.fMask = { SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI };
sei.lpFile = L"modules\\ColorPicker\\ColorPickerUI.exe";
sei.nShow = SW_SHOWNORMAL;
sei.lpParameters = executable_args.data();
if (!ShellExecuteExW(&sei))
{
DWORD error = GetLastError();
std::wstring message = L"ColorPicker failed to start with error = ";
message += std::to_wstring(error);
Logger::error(message);
}
m_hProcess = sei.hProcess;
}
// Load the settings file.
void init_settings()
{
try
{
// Load and parse the settings file for this PowerToy.
PowerToysSettings::PowerToyValues settings =
PowerToysSettings::PowerToyValues::load_from_settings_file(get_key());
parse_hotkey(settings);
}
catch (std::exception ex)
{
Logger::warn(L"An exception occurred while loading the settings file");
// Error while loading from the settings file. Let default values stay as they are.
}
}
public:
ColorPicker()
{
app_name = GET_RESOURCE_STRING(IDS_COLORPICKER_NAME);
app_key = ColorPickerConstants::ModuleKey;
send_telemetry_event = CreateDefaultEvent(CommonSharedConstants::COLOR_PICKER_SEND_SETTINGS_TELEMETRY_EVENT);
m_hInvokeEvent = CreateDefaultEvent(CommonSharedConstants::SHOW_COLOR_PICKER_SHARED_EVENT);
init_settings();
}
~ColorPicker()
@@ -109,6 +209,7 @@ public:
PowerToysSettings::PowerToyValues values =
PowerToysSettings::PowerToyValues::from_json_string(config, get_key());
parse_hotkey(values);
// If you don't need to do any custom processing of the settings, proceed
// to persists the values calling:
values.save_to_settings_file();
@@ -124,25 +225,9 @@ public:
virtual void enable()
{
ResetEvent(send_telemetry_event);
// use only with new settings?
if (UseNewSettings())
{
unsigned long powertoys_pid = GetCurrentProcessId();
std::wstring executable_args = L"";
executable_args.append(std::to_wstring(powertoys_pid));
SHELLEXECUTEINFOW sei{ sizeof(sei) };
sei.fMask = { SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI };
sei.lpFile = L"modules\\ColorPicker\\ColorPickerUI.exe";
sei.nShow = SW_SHOWNORMAL;
sei.lpParameters = executable_args.data();
ShellExecuteExW(&sei);
m_hProcess = sei.hProcess;
m_enabled = true;
}
ResetEvent(m_hInvokeEvent);
launch_process();
m_enabled = true;
};
virtual void disable()
@@ -150,12 +235,47 @@ public:
if (m_enabled)
{
ResetEvent(send_telemetry_event);
ResetEvent(m_hInvokeEvent);
TerminateProcess(m_hProcess, 1);
}
m_enabled = false;
}
virtual bool on_hotkey(size_t hotkeyId) override
{
if (m_enabled)
{
Logger::trace(L"ColorPicker hotkey pressed");
if (!is_process_running())
{
launch_process();
}
SetEvent(m_hInvokeEvent);
return true;
}
return false;
}
virtual size_t get_hotkeys(Hotkey* hotkeys, size_t buffer_size) override
{
if (m_hotkey.key)
{
if (hotkeys && buffer_size >= 1)
{
hotkeys[0] = m_hotkey;
}
return 1;
}
else
{
return 0;
}
}
virtual bool is_enabled() override
{
return m_enabled;

View File

@@ -18,7 +18,7 @@ namespace ColorPickerUI
{
private Mutex _instanceMutex;
private static string[] _args;
private int _powerToysPid;
private int _powerToysRunnerPid;
private bool disposedValue;
private ThemeManager _themeManager;
@@ -27,23 +27,27 @@ namespace ColorPickerUI
_args = e?.Args;
// allow only one instance of color picker
_instanceMutex = new Mutex(true, @"Global\ColorPicker", out bool createdNew);
_instanceMutex = new Mutex(true, @"Local\PowerToys_ColorPicker_InstanceMutex", out bool createdNew);
if (!createdNew)
{
_instanceMutex = null;
Application.Current.Shutdown();
Environment.Exit(0);
return;
}
if (_args?.Length > 0)
{
_ = int.TryParse(_args[0], out _powerToysPid);
}
_ = int.TryParse(_args[0], out _powerToysRunnerPid);
RunnerHelper.WaitForPowerToysRunner(_powerToysPid, () =>
RunnerHelper.WaitForPowerToysRunner(_powerToysRunnerPid, () =>
{
Environment.Exit(0);
});
}
else
{
Environment.Exit(0);
});
_powerToysRunnerPid = -1;
}
_themeManager = new ThemeManager(this);
base.OnStartup(e);
@@ -83,5 +87,10 @@ namespace ColorPickerUI
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
public bool IsRunningDetachedFromPowerToys()
{
return _powerToysRunnerPid == -1;
}
}
}

View File

@@ -54,7 +54,7 @@ namespace ColorPicker.Helpers
}
}
public void EndUserSession()
public bool EndUserSession()
{
lock (_colorPickerVisibilityLock)
{
@@ -70,7 +70,11 @@ namespace ColorPicker.Helpers
}
SessionEventHelper.End();
return true;
}
return false;
}
}

View File

@@ -72,40 +72,44 @@ namespace ColorPicker.Keyboard
// ESC pressed
if (virtualCode == KeyInterop.VirtualKeyFromKey(Key.Escape))
{
_appStateHandler.EndUserSession();
e.Handled = _appStateHandler.EndUserSession();
return;
}
var name = Helper.GetKeyName((uint)virtualCode);
// If the last key pressed is a modifier key, then currentlyPressedKeys cannot possibly match with _activationKeys
// because _activationKeys contains exactly 1 non-modifier key. Hence, there's no need to check if `name` is a
// modifier key or to do any additional processing on it.
if (e.KeyboardState == GlobalKeyboardHook.KeyboardState.KeyDown || e.KeyboardState == GlobalKeyboardHook.KeyboardState.SysKeyDown)
if ((System.Windows.Application.Current as ColorPickerUI.App).IsRunningDetachedFromPowerToys())
{
// Check pressed modifier keys.
AddModifierKeys(currentlyPressedKeys);
var name = Helper.GetKeyName((uint)virtualCode);
currentlyPressedKeys.Add(name);
}
currentlyPressedKeys.Sort();
if (currentlyPressedKeys.Count == 0 && _previouslyPressedKeys.Count != 0)
{
// no keys pressed, we can enable activation shortcut again
_activationShortcutPressed = false;
}
_previouslyPressedKeys = currentlyPressedKeys;
if (ArraysAreSame(currentlyPressedKeys, _activationKeys))
{
// avoid triggering this action multiple times as this will be called nonstop while keys are pressed
if (!_activationShortcutPressed)
// If the last key pressed is a modifier key, then currentlyPressedKeys cannot possibly match with _activationKeys
// because _activationKeys contains exactly 1 non-modifier key. Hence, there's no need to check if `name` is a
// modifier key or to do any additional processing on it.
if (e.KeyboardState == GlobalKeyboardHook.KeyboardState.KeyDown || e.KeyboardState == GlobalKeyboardHook.KeyboardState.SysKeyDown)
{
_activationShortcutPressed = true;
_appStateHandler.StartUserSession();
// Check pressed modifier keys.
AddModifierKeys(currentlyPressedKeys);
currentlyPressedKeys.Add(name);
}
currentlyPressedKeys.Sort();
if (currentlyPressedKeys.Count == 0 && _previouslyPressedKeys.Count != 0)
{
// no keys pressed, we can enable activation shortcut again
_activationShortcutPressed = false;
}
_previouslyPressedKeys = currentlyPressedKeys;
if (ArraysAreSame(currentlyPressedKeys, _activationKeys))
{
// avoid triggering this action multiple times as this will be called nonstop while keys are pressed
if (!_activationShortcutPressed)
{
_activationShortcutPressed = true;
_appStateHandler.StartUserSession();
}
}
}
}

View File

@@ -14,6 +14,7 @@
#include <lib/FancyZonesWinHookEventIDs.h>
#include <lib/FancyZonesData.cpp>
#include <common/logger/logger.h>
#include <common/utils/logger_helper.h>
#include <common/utils/resources.h>
#include <common/utils/winapi_error.h>
#include <common/utils/window.h>
@@ -156,9 +157,19 @@ public:
{
app_name = GET_RESOURCE_STRING(IDS_FANCYZONES);
app_key = NonLocalizable::FancyZonesStr;
std::filesystem::path logFilePath(PTSettingsHelper::get_module_save_folder_location(app_key));
const auto appFolder = PTSettingsHelper::get_module_save_folder_location(app_key);
const std::filesystem::path logFolder = LoggerHelpers::get_log_folder_path(appFolder);
std::filesystem::path logFilePath(logFolder);
logFilePath.append(LogSettings::fancyZonesLogPath);
Logger::init(LogSettings::fancyZonesLoggerName, logFilePath.wstring(), PTSettingsHelper::get_log_settings_file_location());
std::filesystem::path oldLogFolder(appFolder);
oldLogFolder.append(LogSettings::fancyZonesOldLogPath);
LoggerHelpers::delete_old_log_folder(oldLogFolder);
LoggerHelpers::delete_other_versions_log_folders(appFolder, logFolder);
m_settings = MakeFancyZonesSettings(reinterpret_cast<HINSTANCE>(&__ImageBase), FancyZonesModule::get_name(), FancyZonesModule::get_key());
FancyZonesDataInstance().LoadFancyZonesData();
s_instance = this;

View File

@@ -65,13 +65,13 @@
</AdditionalFiles>
</ItemGroup>
<ItemGroup>
<PackageReference Include="ModernWpfUI" Version="0.9.3" />
<PackageReference Include="ModernWpfUI" Version="0.9.4" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="System.IO.Abstractions" Version="12.2.5" />
<PackageReference Include="System.Text.Json" Version="5.0.1" />
<PackageReference Include="System.Text.Json" Version="5.0.2" />
</ItemGroup>
<ItemGroup>
<Resource Include="images\FancyZonesEditor.ico" />

View File

@@ -5,7 +5,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using FancyZonesEditor.Models;
@@ -121,7 +120,7 @@ namespace FancyZonesEditor
if (zoneCount > rows * cols)
{
throw new ArgumentException("Invalid index found in model.CellChildMap");
return;
}
var indexCount = Enumerable.Repeat(0, zoneCount).ToList();
@@ -147,33 +146,18 @@ namespace FancyZonesEditor
{
if (indexCount[index] == 0)
{
throw new ArgumentException("Indices in model.CellChildMap are not contiguous");
return;
}
if (indexCount[index] != (indexRowHigh[index] - indexRowLow[index] + 1) * (indexColHigh[index] - indexColLow[index] + 1))
{
throw new ArgumentException("One or more indices in model.CellChildMap don't form a rectangle");
return;
}
}
if (model.RowPercents.Count != rows)
if (model.RowPercents.Count != model.Rows || model.ColumnPercents.Count != model.Columns || model.RowPercents.Exists((x) => (x < 1)) || model.ColumnPercents.Exists((x) => (x < 1)))
{
throw new ArgumentException("model.RowPercents has invalid size");
}
if (model.ColumnPercents.Count != cols)
{
throw new ArgumentException("model.ColumnPercents has invalid size");
}
if (model.RowPercents.Exists((x) => (x < 1)))
{
throw new ArgumentException("Invalid value in model.RowPercents");
}
if (model.ColumnPercents.Exists((x) => (x < 1)))
{
throw new ArgumentException("Invalid value in model.ColumnPercents");
return;
}
var rowPrefixSum = PrefixSum(model.RowPercents);
@@ -181,7 +165,7 @@ namespace FancyZonesEditor
if (rowPrefixSum[rows] != Multiplier || colPrefixSum[cols] != Multiplier)
{
throw new ArgumentException();
return;
}
_zones = new List<Zone>(zoneCount);

View File

@@ -97,7 +97,7 @@ namespace FancyZonesEditor
{
Size actualSize = WorkAreaSize();
if (actualSize.Width < 1 || _data == null || Model == null)
if (actualSize.Width < 1 || _data == null || _data.Zones == null || Model == null)
{
return;
}

View File

@@ -2,16 +2,16 @@
x:Name="MainWindow1"
AutomationProperties.Name="{x:Static props:Resources.Fancy_Zones_Main_Editor}"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ui="http://schemas.modernwpf.com/2019"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:FancyZonesEditor"
xmlns:Converters="clr-namespace:FancyZonesEditor.Converters"
xmlns:props="clr-namespace:FancyZonesEditor.Properties"
xmlns:local1="clr-namespace:FancyZonesEditor.ViewModels"
xmlns:ui="http://schemas.modernwpf.com/2019"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:controls="clr-namespace:ModernWpf.Controls;assembly=ModernWpf"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Title="FancyZones Editor"
ui:WindowHelper.UseModernWindowStyle="True"
@@ -84,15 +84,28 @@
</StackPanel>
</ToolTip>
</Border.ToolTip>
<TextBlock Name="IndexText"
TextTrimming="CharacterEllipsis"
Text="{Binding Index}"
FontSize="26"
Grid.Row="0"
FontWeight="SemiBold"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{DynamicResource PrimaryForegroundBrush}" />
<StackPanel Orientation="Vertical"
VerticalAlignment="Center">
<TextBlock Name="IndexText"
TextTrimming="CharacterEllipsis"
Text="{Binding Index}"
FontSize="26"
Grid.Row="0"
FontWeight="SemiBold"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{DynamicResource PrimaryForegroundBrush}" />
<TextBlock Name="ResolutionText"
TextTrimming="CharacterEllipsis"
Text="{Binding Dimensions}"
Grid.Row="0"
Margin="0,0,0,0"
FontSize="11"
FontWeight="SemiBold"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{DynamicResource SecondaryForegroundBrush}" />
</StackPanel>
</Border>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Selected}"
@@ -100,6 +113,10 @@
<Setter TargetName="IndexText"
Property="Foreground"
Value="{DynamicResource SystemControlBackgroundAccentBrush}" />
<Setter TargetName="ResolutionText"
Property="Foreground"
Value="{DynamicResource SystemControlBackgroundAccentBrush}" />
<Setter TargetName="MonitorItem"
Property="BorderBrush"
Value="{DynamicResource SystemControlBackgroundAccentBrush}" />
@@ -107,6 +124,9 @@
</DataTemplate.Triggers>
</DataTemplate>
<DataTemplate x:Key="LayoutItemTemplate">
<Grid Background="Transparent"
Width="216"
@@ -186,7 +206,7 @@
<Setter TargetName="LayoutItem"
Property="BorderBrush"
Value="{DynamicResource LayoutItemBorderPointerOverBrush}" />
<Setter TargetName="EditLayoutButton"
Property="Foreground"
Value="{DynamicResource SystemControlBackgroundAccentBrush}" />
@@ -214,6 +234,7 @@
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Text="{x:Static props:Resources.Templates}"
x:Name="TemplatesHeaderBlock"
FontWeight="SemiBold"
@@ -284,7 +305,7 @@
</Grid>
</ScrollViewer>
<Button x:Name="NewLayoutButton"
Click="NewLayoutButton_Click"
HorizontalAlignment="Right"
@@ -329,7 +350,6 @@
<local1:MonitorViewModel x:Name="monitorViewModel" />
</ScrollViewer.DataContext>
<Grid>
<ItemsControl x:Name="MainWindowItemControl"
TabIndex="0"
ItemTemplate="{StaticResource MonitorItemTemplate}"
@@ -342,7 +362,6 @@
Margin="8, 0, 8, 16" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Grid>
</ScrollViewer>
@@ -360,7 +379,7 @@
Opened="Dialog_Opened"
Closed="Dialog_Closed">
<Grid DataContext="{Binding SelectedModel}"
MinWidth="320" Margin="0,0,0,32">
MinWidth="320" Margin="4,4,4,32">
<StackPanel Margin="0,-37,0,0"
HorizontalAlignment="Right"
@@ -396,120 +415,192 @@
</StackPanel>
<StackPanel>
<local:LayoutPreview Width="216"
Height="132"
Margin="0,16,0,16" />
<Button Click="EditZones_Click"
x:Name="editZoneLayoutButton"
HorizontalAlignment="Stretch"
AutomationProperties.Name="{x:Static props:Resources.Edit_zones}"
HorizontalContentAlignment="Center"
Foreground="{DynamicResource SystemControlBackgroundAccentBrush}"
Style="{StaticResource IconOnlyButtonStyle}"
Visibility="{Binding Path=Type, Converter={StaticResource LayoutTypeCustomToVisibilityConverter}}">
<Button.Content>
<StackPanel Orientation="Horizontal">
<TextBlock Text="&#xE104;"
Margin="0,2,8,0"
FontFamily="Segoe MDL2 Assets" />
<TextBlock Text="{x:Static props:Resources.Edit_zones}" />
</StackPanel>
</Button.Content>
</Button>
<StackPanel Orientation="Horizontal"
Margin="0,24,0,0"
HorizontalAlignment="Stretch"
Visibility="{Binding IsCustom, Converter={StaticResource BooleanToVisibilityConverter}}">
<TextBlock FontFamily="Segoe MDL2 Assets"
ToolTip="{x:Static props:Resources.Name}"
FontSize="16"
VerticalAlignment="Bottom" Margin="0,0,0,8"
Text="&#xE932;" />
<TextBox Text="{Binding Name}"
ui:ControlHelper.PlaceholderText="{x:Static props:Resources.Name}"
AutomationProperties.Name="{x:Static props:Resources.Name}"
Margin="12,0,0,0"
ui:ControlHelper.Header="{x:Static props:Resources.Name}"
MinWidth="286"
HorizontalAlignment="Stretch" />
</StackPanel>
<!-- Shortcut panel -->
<StackPanel Orientation="Vertical"
Visibility="{Binding IsCustom, Converter={StaticResource BooleanToVisibilityConverter}}"
Margin="0,12,0,36">
<StackPanel Margin="28,0,0,4"
Orientation="Horizontal">
<TextBlock x:Name="QuickKeyTitle"
Text="{x:Static props:Resources.QuickKey_Title}" />
<TextBlock FontFamily="Segoe MDL2 Assets"
Margin="8,4,0,0"
Foreground="{DynamicResource SystemControlBackgroundAccentBrush}"
Text="&#xE946;"
ToolTip="{x:Static props:Resources.QuickKey_Description}" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock FontFamily="Segoe MDL2 Assets"
VerticalAlignment="Center"
FontSize="16"
ToolTip="{x:Static props:Resources.QuickKey_Title}"
Text="&#xEDA7;" />
<ComboBox x:Name="quickKeySelectionComboBox"
Margin="12,0,0,0"
Width="286"
AutomationProperties.LabeledBy="{Binding ElementName=QuickKeyTitle}"
AutomationProperties.HelpText="{x:Static props:Resources.QuickKey_Description}"
AutomationProperties.Name="{x:Static props:Resources.QuickKey_Title}"
ItemsSource="{Binding QuickKeysAvailable}"
SelectedItem="{Binding QuickKey}" />
</StackPanel>
</StackPanel>
<Grid Width="218"
Height="124"
HorizontalAlignment="Left"
Margin="24,12,0,24">
<local:LayoutPreview />
<Button Content="&#xE104;"
x:Name="editZoneLayoutButton"
FontFamily="Segoe MDL2 Assets"
FontSize="14"
HorizontalAlignment="Center"
Visibility="{Binding Path=Type, Converter={StaticResource LayoutTypeTemplateToVisibilityConverter}}">
<Button x:Name="decrementZones"
Width="40"
Height="40"
AutomationProperties.Name="{x:Static props:Resources.Zone_Count_Decrement}"
ToolTip="{x:Static props:Resources.Zone_Count_Decrement}"
Foreground="{DynamicResource SystemControlBackgroundAccentBrush}"
Style="{StaticResource IconOnlyButtonStyle}"
Click="DecrementZones_Click">
<Button.Content>
<TextBlock Text="&#xE108;"
FontFamily="Segoe MDL2 Assets" />
</Button.Content>
</Button>
<TextBlock x:Name="zoneCount"
Text="{Binding TemplateZoneCount}"
FontWeight="SemiBold"
FontSize="18"
Width="32"
HorizontalAlignment="Center"
TextAlignment="Center"
Margin="0,-4,0,0"
ToolTip="Number of zones"
VerticalAlignment="Center" />
<Button x:Name="incrementZones"
Width="40"
Height="40"
AutomationProperties.Name="{x:Static props:Resources.Zone_Count_Increment}"
ToolTip="{x:Static props:Resources.Zone_Count_Increment}"
Foreground="{DynamicResource SystemControlBackgroundAccentBrush}"
Style="{StaticResource IconOnlyButtonStyle}"
Click="IncrementZones_Click">
<Button.Content>
<TextBlock Text="&#xE109;"
FontFamily="Segoe MDL2 Assets" />
</Button.Content>
</Button>
</StackPanel>
<TextBox Text="{Binding Name}"
ui:ControlHelper.Header="{x:Static props:Resources.Name}"
Margin="0,16,2,0"
Visibility="{Binding IsCustom, Converter={StaticResource BooleanToVisibilityConverter}}"
HorizontalAlignment="Stretch" />
<CheckBox x:Name="spaceAroundSetting"
Content="{x:Static props:Resources.Show_Space_Zones}"
IsChecked="{Binding ShowSpacing}"
Margin="0,16,12,0"
Visibility="{Binding Converter={StaticResource LayoutModelTypeToVisibilityConverter}}" />
VerticalAlignment="Center"
Height="36"
Width="36"
Padding="0"
BorderBrush="Transparent"
Click="EditZones_Click"
Visibility="{Binding Path=Type, Converter={StaticResource LayoutTypeCustomToVisibilityConverter}}"
ToolTip="{x:Static props:Resources.Edit_zones}"
AutomationProperties.Name="{x:Static props:Resources.Edit_zones}"
Style="{StaticResource AccentButtonStyle}"
ui:ControlHelper.CornerRadius="36">
</Button>
<ui:NumberBox Margin="0,6,0,0"
IsEnabled="{Binding ShowSpacing}"
Text="{Binding Spacing}"
Width="106"
Minimum="-20"
Maximum="1000"
SpinButtonPlacementMode="Compact"
HorizontalAlignment="Left"
AutomationProperties.LabeledBy="{Binding ElementName=spaceAroundSetting}"
Visibility="{Binding Converter={StaticResource LayoutModelTypeToVisibilityConverter}}" />
</Grid>
<TextBlock Text="{x:Static props:Resources.Distance_adjacent_zones}"
IsEnabled="{Binding ShowSpacing}"
Margin="0,16,12,0"
TextWrapping="Wrap"
Foreground="{DynamicResource PrimaryForegroundBrush}"
x:Name="sensitivityRadiusValue" />
<ui:NumberBox Margin="0,6,0,0"
Text="{Binding SensitivityRadius}"
Width="106"
Minimum="0"
Maximum="1000"
SpinButtonPlacementMode="Compact"
HorizontalAlignment="Left"
AutomationProperties.LabeledBy="{Binding ElementName=sensitivityRadiusValue}" />
<TextBlock Text="{x:Static props:Resources.QuickKey_Select}"
Margin="0,16,12,0"
Foreground="{DynamicResource PrimaryForegroundBrush}"
TextWrapping="Wrap"
Visibility="{Binding Path=Type, Converter={StaticResource LayoutTypeCustomToVisibilityConverter}}"/>
<ComboBox x:Name="quickKeySelectionComboBox"
Margin="0,6,0,0"
ItemsSource="{Binding QuickKeysAvailable}"
SelectedItem="{Binding QuickKey}"
Width="106"
Visibility="{Binding Path=Type, Converter={StaticResource LayoutTypeCustomToVisibilityConverter}}"/>
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Left"
Margin="0,16,0,0"
Visibility="{Binding Path=Type, Converter={StaticResource LayoutTypeTemplateToVisibilityConverter}}">
<TextBlock FontFamily="Segoe MDL2 Assets"
VerticalAlignment="Center"
FontSize="16"
Margin="0,16,0,0"
ToolTip="{x:Static props:Resources.Number_of_zones}"
Text="&#xECA5;" />
<ui:NumberBox Minimum="1"
Maximum="40"
Width="216"
KeyDown="EditDialogNumberBox_KeyDown"
Margin="12,0,0,0"
Header="{x:Static props:Resources.Number_of_zones}"
SpinButtonPlacementMode="Compact"
Text="{Binding TemplateZoneCount}" />
</StackPanel>
<StackPanel Margin="0, 12, 0, 0"
Visibility="{Binding Converter={StaticResource LayoutModelTypeToVisibilityConverter}}">
<TextBlock Text="{x:Static props:Resources.Space_Around_Zones}"
x:Name="spacingTitle"
Margin="28,0,0,4"
TextWrapping="Wrap" />
<StackPanel Orientation="Horizontal">
<TextBlock FontFamily="Segoe MDL2 Assets"
VerticalAlignment="Center"
FontSize="16"
ToolTip="{x:Static props:Resources.Space_Around_Zones}"
Text="&#xE91B;" />
<ui:NumberBox Margin="12,0,0,0"
IsEnabled="{Binding ShowSpacing}"
Text="{Binding Spacing}"
Width="216"
Minimum="-20"
Maximum="1000"
KeyDown="EditDialogNumberBox_KeyDown"
SpinButtonPlacementMode="Compact"
HorizontalAlignment="Left"
VerticalAlignment="Center"
AutomationProperties.Name="{x:Static props:Resources.Space_Around_Zones}"
AutomationProperties.LabeledBy="{Binding ElementName=spacingTitle}" />
<TextBlock Text="{x:Static props:Resources.Pixels}"
Margin="6,-4,0,0"
FontSize="12"
Foreground="{DynamicResource SecondaryForegroundBrush}"
TextWrapping="Wrap"
VerticalAlignment="Center" />
<ui:ToggleSwitch x:Name="spaceAroundSetting"
IsOn="{Binding ShowSpacing}"
Margin="12,0,0,0"
OffContent=""
OnContent=""
ui:FocusVisualHelper.FocusVisualMargin="-3,-3,8,-3"
VerticalAlignment="Center"
AutomationProperties.Name="{x:Static props:Resources.Show_Space_Zones}">
<ui:ToggleSwitch.Resources>
<sys:Double x:Key="ToggleSwitchThemeMinWidth">0</sys:Double>
</ui:ToggleSwitch.Resources>
</ui:ToggleSwitch>
</StackPanel>
</StackPanel>
<StackPanel Margin="0, 12, 0, 0">
<TextBlock Text="{x:Static props:Resources.Distance_adjacent_zones}"
x:Name="distanceTitle"
Margin="28,0,0,4"
TextWrapping="Wrap" />
<StackPanel Orientation="Horizontal">
<TextBlock FontFamily="Segoe MDL2 Assets"
VerticalAlignment="Center"
FontSize="16"
ToolTip="{x:Static props:Resources.Distance_adjacent_zones}"
Text="&#xF617;" />
<ui:NumberBox Text="{Binding SensitivityRadius}"
Width="216"
Minimum="0"
Maximum="1000"
KeyDown="EditDialogNumberBox_KeyDown"
Margin="12,0,0,0"
AutomationProperties.Name="{x:Static props:Resources.Distance_adjacent_zones}"
AutomationProperties.LabeledBy="{Binding ElementName=distanceTitle}"
SpinButtonPlacementMode="Compact"
HorizontalAlignment="Left" />
<TextBlock Text="{x:Static props:Resources.Pixels}"
Margin="6,-4,0,0"
FontSize="12"
Foreground="{DynamicResource SecondaryForegroundBrush}"
TextWrapping="Wrap"
VerticalAlignment="Center" />
</StackPanel>
</StackPanel>
</StackPanel>
</Grid>
</ui:ContentDialog>

View File

@@ -421,5 +421,14 @@ namespace FancyZonesEditor
{
_openedDialog = null;
}
private void EditDialogNumberBox_KeyDown(object sender, KeyEventArgs e)
{
// Making sure that pressing Enter when changing values in a NumberBox will not close the edit dialog.
if (e.Key == Key.Enter)
{
e.Handled = true;
}
}
}
}

View File

@@ -2,6 +2,7 @@
// 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 FancyZonesEditor.Models
@@ -173,6 +174,53 @@ namespace FancyZonesEditor.Models
}
}
public bool IsModelValid()
{
// Check if rows and columns are valid
if (Rows <= 0 || Columns <= 0)
{
return false;
}
// Check if percentage is valid.
if (RowPercents.Count != Rows || ColumnPercents.Count != Columns || RowPercents.Exists((x) => (x < 1)) || ColumnPercents.Exists((x) => (x < 1)))
{
return false;
}
// Check if cells map is valid
if (CellChildMap.Length != Rows * Columns)
{
return false;
}
int zoneCount = 0;
for (int row = 0; row < Rows; row++)
{
for (int col = 0; col < Columns; col++)
{
zoneCount = Math.Max(zoneCount, CellChildMap[row, col]);
}
}
zoneCount++;
if (zoneCount > Rows * Columns)
{
return false;
}
var rowPrefixSum = GridData.PrefixSum(RowPercents);
var colPrefixSum = GridData.PrefixSum(ColumnPercents);
if (rowPrefixSum[Rows] != GridData.Multiplier || colPrefixSum[Columns] != GridData.Multiplier)
{
return false;
}
return true;
}
public void UpdatePreview()
{
FirePropertyChanged();

View File

@@ -250,7 +250,7 @@ namespace FancyZonesEditor.Properties {
}
/// <summary>
/// Looks up a localized string similar to Distance to highlight adjacent zones.
/// Looks up a localized string similar to Highlight distance.
/// </summary>
public static string Distance_adjacent_zones {
get {
@@ -537,6 +537,15 @@ namespace FancyZonesEditor.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Number of zones.
/// </summary>
public static string Number_of_zones {
get {
return ResourceManager.GetString("Number_of_zones", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Number of zones.
/// </summary>
@@ -546,6 +555,15 @@ namespace FancyZonesEditor.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to px.
/// </summary>
public static string Pixels {
get {
return ResourceManager.GetString("Pixels", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to None.
/// </summary>
@@ -556,11 +574,20 @@ namespace FancyZonesEditor.Properties {
}
/// <summary>
/// Looks up a localized string similar to Select a key to quickly apply the layout (Win + Ctrl + Alt + key).
/// Looks up a localized string similar to Press Win + Ctrl + Alt + selected key to apply this layout.
/// </summary>
public static string QuickKey_Select {
public static string QuickKey_Description {
get {
return ResourceManager.GetString("QuickKey_Select", resourceCulture);
return ResourceManager.GetString("QuickKey_Description", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Layout shortcut.
/// </summary>
public static string QuickKey_Title {
get {
return ResourceManager.GetString("QuickKey_Title", resourceCulture);
}
}

View File

@@ -145,7 +145,8 @@
<value>Custom layout creator</value>
</data>
<data name="Distance_adjacent_zones" xml:space="preserve">
<value>Distance to highlight adjacent zones</value>
<value>Highlight distance</value>
<comment>Distance of when an adjacent zone should light up when the window is close to it</comment>
</data>
<data name="Edit_Layout" xml:space="preserve">
<value>Edit layout</value>
@@ -343,10 +344,20 @@
<value>Splitter:</value>
<comment>Title for concept: A segmenter visual for splitting one item into two. This would be the vertical line</comment>
</data>
<data name="QuickKey_Select" xml:space="preserve">
<value>Select a key to quickly apply the layout (Win + Ctrl + Alt + key)</value>
<data name="QuickKey_Description" xml:space="preserve">
<value>Press Win + Ctrl + Alt + selected key to apply this layout</value>
</data>
<data name="Quick_Key_None" xml:space="preserve">
<value>None</value>
</data>
<data name="Number_of_zones" xml:space="preserve">
<value>Number of zones</value>
</data>
<data name="Pixels" xml:space="preserve">
<value>px</value>
<comment>Abbreviation of pixels</comment>
</data>
<data name="QuickKey_Title" xml:space="preserve">
<value>Layout shortcut</value>
</data>
</root>

View File

@@ -16,7 +16,7 @@
<Setter Property="VerticalContentAlignment" Value="Top" />
<Setter Property="FontFamily" Value="{DynamicResource ContentControlThemeFontFamily}" />
<Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" />
<Setter Property="MinWidth" Value="120" />
<Setter Property="MinWidth" Value="0" />
<Setter Property="FocusVisualStyle" Value="{DynamicResource {x:Static SystemParameters.FocusVisualStyleKey}}" />
<Setter Property="ui:FocusVisualHelper.UseSystemFocusVisuals" Value="{DynamicResource UseSystemFocusVisuals}" />
<Setter Property="ui:FocusVisualHelper.FocusVisualMargin" Value="0" />

View File

@@ -916,17 +916,19 @@ namespace FancyZonesEditor.Utils
}
// Check if percentage is valid. Otherwise, Editor could crash on layout rendering.
foreach (int percent in info.RowsPercentage)
if (info.RowsPercentage.Exists((x) => (x < 1)) || info.ColumnsPercentage.Exists((x) => (x < 1)))
{
if (percent < 0)
{
return null;
}
return null;
}
foreach (int percent in info.ColumnsPercentage)
if (info.CellChildMap.Length != info.Rows)
{
if (percent < 0)
return null;
}
foreach (var col in info.CellChildMap)
{
if (col.Length != info.Columns)
{
return null;
}
@@ -942,6 +944,11 @@ namespace FancyZonesEditor.Utils
}
var layout = new GridLayoutModel(wrapper.Uuid, wrapper.Name, LayoutType.Custom, info.Rows, info.Columns, info.RowsPercentage, info.ColumnsPercentage, cells);
if (!layout.IsModelValid())
{
return null;
}
layout.SensitivityRadius = info.SensitivityRadius;
layout.ShowSpacing = info.ShowSpacing;
layout.Spacing = info.Spacing;

View File

@@ -48,7 +48,7 @@ namespace FancyZonesEditor.ViewModels
double maxMultiplier = MaxPreviewDisplaySize / maxDimension;
double minMultiplier = MinPreviewDisplaySize / minDimension;
DesktopPreviewMultiplier = (minMultiplier + maxMultiplier) / 3.5;
DesktopPreviewMultiplier = (minMultiplier + maxMultiplier) / 2.5;
}
private void RaisePropertyChanged(string propertyName)

View File

@@ -334,11 +334,11 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Parsing_Zones_Settings_Malformed_Data" ItemType="0;.resx" PsrId="211" Leaf="true">
<Item ItemId=";Error_Parsing_Zones_Settings_Message" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['zones-settings.json' contains malformed data.]]></Val>
<Val><![CDATA[A layout that contained invalid data has been removed.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Soubor zones-settings.json obsahuje chybná data.]]></Val>
<Val><![CDATA[Rozložení, které obsahovalo neplatná data, se odebralo.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
@@ -352,15 +352,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Parsing_Zones_Settings_User_Choice" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Would you like to continue? Malformed data will be lost.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Chcete pokračovat? Chybná data se ztratí.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Persisting_Custom_Layout" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Error persisting custom layout]]></Val>

View File

@@ -334,11 +334,11 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Parsing_Zones_Settings_Malformed_Data" ItemType="0;.resx" PsrId="211" Leaf="true">
<Item ItemId=";Error_Parsing_Zones_Settings_Message" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['zones-settings.json' contains malformed data.]]></Val>
<Val><![CDATA[A layout that contained invalid data has been removed.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA["zones-settings.json" enthält nicht wohlgeformte Daten.]]></Val>
<Val><![CDATA[Ein Layout, das ungültige Daten enthielt, wurde entfernt.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
@@ -352,15 +352,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Parsing_Zones_Settings_User_Choice" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Would you like to continue? Malformed data will be lost.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Möchten Sie den Vorgang fortsetzen? Nicht wohlgeformte Daten gehen verloren.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Persisting_Custom_Layout" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Error persisting custom layout]]></Val>

View File

@@ -334,11 +334,11 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Parsing_Zones_Settings_Malformed_Data" ItemType="0;.resx" PsrId="211" Leaf="true">
<Item ItemId=";Error_Parsing_Zones_Settings_Message" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['zones-settings.json' contains malformed data.]]></Val>
<Val><![CDATA[A layout that contained invalid data has been removed.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA["zones-settings.json" contiene datos con un formato incorrecto.]]></Val>
<Val><![CDATA[Se quitó un diseño que contenía datos que no son válidos.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
@@ -352,15 +352,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Parsing_Zones_Settings_User_Choice" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Would you like to continue? Malformed data will be lost.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[¿Quiere continuar? Se perderán los datos con un formato incorrecto.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Persisting_Custom_Layout" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Error persisting custom layout]]></Val>

View File

@@ -334,11 +334,11 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Parsing_Zones_Settings_Malformed_Data" ItemType="0;.resx" PsrId="211" Leaf="true">
<Item ItemId=";Error_Parsing_Zones_Settings_Message" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['zones-settings.json' contains malformed data.]]></Val>
<Val><![CDATA[A layout that contained invalid data has been removed.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[« zones-settings.json » contient des données malformées.]]></Val>
<Val><![CDATA[Une disposition qui contenait des données non valides a été supprimée.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
@@ -352,15 +352,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Parsing_Zones_Settings_User_Choice" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Would you like to continue? Malformed data will be lost.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Voulez-vous continuer ? Les données malformées seront perdues.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Persisting_Custom_Layout" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Error persisting custom layout]]></Val>
@@ -517,6 +508,9 @@
<Item ItemId=";QuickKey_Select" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Select a key to quickly apply the layout (Win + Ctrl + Alt + key)]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Sélectionner une touche pour appliquer rapidement la disposition (Win + Ctrl + Alt + touche)]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>

View File

@@ -334,11 +334,11 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Parsing_Zones_Settings_Malformed_Data" ItemType="0;.resx" PsrId="211" Leaf="true">
<Item ItemId=";Error_Parsing_Zones_Settings_Message" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['zones-settings.json' contains malformed data.]]></Val>
<Val><![CDATA[A layout that contained invalid data has been removed.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[A zones-settings.json szabálytalan adatokat tartalmaz.]]></Val>
<Val><![CDATA[A rendszer eltávolított egy érvénytelen adatot tartalmazó elrendezést.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
@@ -352,15 +352,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Parsing_Zones_Settings_User_Choice" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Would you like to continue? Malformed data will be lost.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Folytatja? A szabálytalan adatok el fognak veszni.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Persisting_Custom_Layout" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Error persisting custom layout]]></Val>
@@ -517,6 +508,9 @@
<Item ItemId=";QuickKey_Select" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Select a key to quickly apply the layout (Win + Ctrl + Alt + key)]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Válasszon egy billentyűt az elrendezés gyors alkalmazásához (Win + Ctrl + Alt + billentyű)]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>

View File

@@ -334,11 +334,11 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Parsing_Zones_Settings_Malformed_Data" ItemType="0;.resx" PsrId="211" Leaf="true">
<Item ItemId=";Error_Parsing_Zones_Settings_Message" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['zones-settings.json' contains malformed data.]]></Val>
<Val><![CDATA[A layout that contained invalid data has been removed.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA['zones-settings.json' contiene dati non validi.]]></Val>
<Val><![CDATA[Un layout contenente dati non validi è stato rimosso.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
@@ -352,15 +352,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Parsing_Zones_Settings_User_Choice" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Would you like to continue? Malformed data will be lost.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Continuare? I dati con formato non valido andranno persi.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Persisting_Custom_Layout" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Error persisting custom layout]]></Val>

View File

@@ -334,11 +334,11 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Parsing_Zones_Settings_Malformed_Data" ItemType="0;.resx" PsrId="211" Leaf="true">
<Item ItemId=";Error_Parsing_Zones_Settings_Message" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['zones-settings.json' contains malformed data.]]></Val>
<Val><![CDATA[A layout that contained invalid data has been removed.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA['zones-settings.json' に誤った形式のデータが含まれています。]]></Val>
<Val><![CDATA[無効なデータを含むレイアウトが削除されました。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
@@ -352,15 +352,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Parsing_Zones_Settings_User_Choice" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Would you like to continue? Malformed data will be lost.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[続行しますか? 誤った形式のデータは失われます。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Persisting_Custom_Layout" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Error persisting custom layout]]></Val>

View File

@@ -334,11 +334,11 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Parsing_Zones_Settings_Malformed_Data" ItemType="0;.resx" PsrId="211" Leaf="true">
<Item ItemId=";Error_Parsing_Zones_Settings_Message" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['zones-settings.json' contains malformed data.]]></Val>
<Val><![CDATA[A layout that contained invalid data has been removed.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA['zones-settings.json'에 잘못된 형식의 데이터가 있습니다.]]></Val>
<Val><![CDATA[잘못된 데이터가 포함된 레이아웃이 제거되었습니다.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
@@ -352,15 +352,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Parsing_Zones_Settings_User_Choice" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Would you like to continue? Malformed data will be lost.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[계속하시겠습니까? 잘못된 형식의 데이터가 손실됩니다.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Persisting_Custom_Layout" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Error persisting custom layout]]></Val>

View File

@@ -334,11 +334,11 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Parsing_Zones_Settings_Malformed_Data" ItemType="0;.resx" PsrId="211" Leaf="true">
<Item ItemId=";Error_Parsing_Zones_Settings_Message" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['zones-settings.json' contains malformed data.]]></Val>
<Val><![CDATA[A layout that contained invalid data has been removed.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[zones-settings.json' bevat gegevens met ongeldige indeling.]]></Val>
<Val><![CDATA[Een indeling die ongeldige gegevens bevat, is verwijderd.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
@@ -352,15 +352,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Parsing_Zones_Settings_User_Choice" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Would you like to continue? Malformed data will be lost.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Wilt u doorgaan? Gegevens met een ongeldige indeling gaan verloren.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Persisting_Custom_Layout" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Error persisting custom layout]]></Val>

View File

@@ -334,11 +334,11 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Parsing_Zones_Settings_Malformed_Data" ItemType="0;.resx" PsrId="211" Leaf="true">
<Item ItemId=";Error_Parsing_Zones_Settings_Message" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['zones-settings.json' contains malformed data.]]></Val>
<Val><![CDATA[A layout that contained invalid data has been removed.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Plik „zones-settings.json” zawiera źle sformułowane dane.]]></Val>
<Val><![CDATA[Układ, który zawierał nieprawidłowe dane, został usunięty.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
@@ -352,15 +352,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Parsing_Zones_Settings_User_Choice" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Would you like to continue? Malformed data will be lost.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Chcesz kontynuować? Uszkodzone dane zostaną utracone.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Persisting_Custom_Layout" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Error persisting custom layout]]></Val>

View File

@@ -334,11 +334,11 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Parsing_Zones_Settings_Malformed_Data" ItemType="0;.resx" PsrId="211" Leaf="true">
<Item ItemId=";Error_Parsing_Zones_Settings_Message" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['zones-settings.json' contains malformed data.]]></Val>
<Val><![CDATA[A layout that contained invalid data has been removed.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA['zones-settings.json' contém dados malformados.]]></Val>
<Val><![CDATA[Um layout que continha dados inválidos foi removido.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
@@ -352,15 +352,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Parsing_Zones_Settings_User_Choice" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Would you like to continue? Malformed data will be lost.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Deseja continuar? Os dados malformados serão perdidos.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Persisting_Custom_Layout" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Error persisting custom layout]]></Val>
@@ -517,6 +508,9 @@
<Item ItemId=";QuickKey_Select" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Select a key to quickly apply the layout (Win + Ctrl + Alt + key)]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Selecione uma tecla para aplicar o layout rapidamente (Win + Ctrl + Alt + tecla)]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -524,7 +518,7 @@
<Str Cat="Text">
<Val><![CDATA[None]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Nenhum]]></Val>
<Val><![CDATA[Nenhuma]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />

View File

@@ -334,11 +334,11 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Parsing_Zones_Settings_Malformed_Data" ItemType="0;.resx" PsrId="211" Leaf="true">
<Item ItemId=";Error_Parsing_Zones_Settings_Message" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['zones-settings.json' contains malformed data.]]></Val>
<Val><![CDATA[A layout that contained invalid data has been removed.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA["zones-settings.json" contém dados malformados.]]></Val>
<Val><![CDATA[Foi removido um esquema que continha dados inválidos.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
@@ -352,15 +352,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Parsing_Zones_Settings_User_Choice" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Would you like to continue? Malformed data will be lost.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Pretende continuar? Os dados malformados serão perdidos.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Persisting_Custom_Layout" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Error persisting custom layout]]></Val>

View File

@@ -334,11 +334,11 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Parsing_Zones_Settings_Malformed_Data" ItemType="0;.resx" PsrId="211" Leaf="true">
<Item ItemId=";Error_Parsing_Zones_Settings_Message" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['zones-settings.json' contains malformed data.]]></Val>
<Val><![CDATA[A layout that contained invalid data has been removed.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA["zones-settings.json" содержит неправильно сформированные данные.]]></Val>
<Val><![CDATA[Макет, содержащий недопустимые данные, удален.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
@@ -352,15 +352,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Parsing_Zones_Settings_User_Choice" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Would you like to continue? Malformed data will be lost.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Вы хотите продолжить? Неправильно сформированные данные будут утеряны.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Persisting_Custom_Layout" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Error persisting custom layout]]></Val>

View File

@@ -334,11 +334,11 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Parsing_Zones_Settings_Malformed_Data" ItemType="0;.resx" PsrId="211" Leaf="true">
<Item ItemId=";Error_Parsing_Zones_Settings_Message" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['zones-settings.json' contains malformed data.]]></Val>
<Val><![CDATA[A layout that contained invalid data has been removed.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[zones-settings.json innehåller felaktigt utformade data.]]></Val>
<Val><![CDATA[En layout som innehöll ogiltiga data har tagits bort.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
@@ -352,15 +352,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Parsing_Zones_Settings_User_Choice" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Would you like to continue? Malformed data will be lost.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Vill du fortsätta? Felaktigt utformade data kommer att gå förlorade.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Persisting_Custom_Layout" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Error persisting custom layout]]></Val>
@@ -517,6 +508,9 @@
<Item ItemId=";QuickKey_Select" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Select a key to quickly apply the layout (Win + Ctrl + Alt + key)]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Välj en tangent för att snabbt tillämpa layouten (Win + Ctrl + Alt + tangent)]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -524,7 +518,7 @@
<Str Cat="Text">
<Val><![CDATA[None]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Inget]]></Val>
<Val><![CDATA[Ingen]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />

View File

@@ -334,11 +334,11 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Parsing_Zones_Settings_Malformed_Data" ItemType="0;.resx" PsrId="211" Leaf="true">
<Item ItemId=";Error_Parsing_Zones_Settings_Message" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['zones-settings.json' contains malformed data.]]></Val>
<Val><![CDATA[A layout that contained invalid data has been removed.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA['zones-settings.json' hatalı biçimlendirilmiş veriler içeriyor.]]></Val>
<Val><![CDATA[Geçersiz veri içeren düzen kaldırıldı.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
@@ -352,15 +352,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Parsing_Zones_Settings_User_Choice" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Would you like to continue? Malformed data will be lost.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Devam etmek istiyor musunuz? Hatalı biçimlendirilmiş veriler kaybolacak.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Persisting_Custom_Layout" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Error persisting custom layout]]></Val>
@@ -517,6 +508,9 @@
<Item ItemId=";QuickKey_Select" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Select a key to quickly apply the layout (Win + Ctrl + Alt + key)]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Düzeni hızlıca uygulamak için bir tuş seçin (Win + Ctrl + Alt + tuş)]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>

View File

@@ -334,11 +334,11 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Parsing_Zones_Settings_Malformed_Data" ItemType="0;.resx" PsrId="211" Leaf="true">
<Item ItemId=";Error_Parsing_Zones_Settings_Message" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['zones-settings.json' contains malformed data.]]></Val>
<Val><![CDATA[A layout that contained invalid data has been removed.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA["zones-settings.json" 包含格式错误的数据。]]></Val>
<Val><![CDATA[包含了无效数据的布局已被删除。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
@@ -352,15 +352,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Parsing_Zones_Settings_User_Choice" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Would you like to continue? Malformed data will be lost.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[是否要继续操作? 格式错误的数据将丢失。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Persisting_Custom_Layout" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Error persisting custom layout]]></Val>
@@ -454,12 +445,18 @@
<Item ItemId=";MergeDescription" ItemType="0;.resx" PsrId="211" InstFlg="true" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Click and drag across zones.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[单击并跨区域拖动。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";MergeName" ItemType="0;.resx" PsrId="211" InstFlg="true" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Merge/Delete:]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[合并/删除:]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -511,6 +508,9 @@
<Item ItemId=";QuickKey_Select" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Select a key to quickly apply the layout (Win + Ctrl + Alt + key)]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[选择一个键来快速应用布局(Windows 键 + Ctrl + Alt + 你选择的键)]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -583,12 +583,18 @@
<Item ItemId=";SplitterDescription" ItemType="0;.resx" PsrId="211" InstFlg="true" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Hold Shift key for vertical split.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[按住 Shift 键进行垂直拆分。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";SplitterName" ItemType="0;.resx" PsrId="211" InstFlg="true" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Splitter:]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[拆分器:]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>

View File

@@ -334,11 +334,11 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Parsing_Zones_Settings_Malformed_Data" ItemType="0;.resx" PsrId="211" Leaf="true">
<Item ItemId=";Error_Parsing_Zones_Settings_Message" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['zones-settings.json' contains malformed data.]]></Val>
<Val><![CDATA[A layout that contained invalid data has been removed.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA['zones-settings.json' 包含格式錯誤的資料。]]></Val>
<Val><![CDATA[已移除包含無效資料的配置。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
@@ -352,15 +352,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Parsing_Zones_Settings_User_Choice" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Would you like to continue? Malformed data will be lost.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[您要繼續嗎? 格式錯誤的資料將會遺失。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_Persisting_Custom_Layout" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Error persisting custom layout]]></Val>

View File

@@ -209,7 +209,8 @@
<comment>FancyZone is a product name, keep as is.</comment>
</data>
<data name="Cant_Drag_Elevated" xml:space="preserve">
<value>We've detected an application running with administrator privileges. This blocks some functionality in PowerToys. Visit our wiki page to learn more.</value>
<value>We've detected an application running with administrator privileges. This will prevent certain interactions with these applications.</value>
<comment>administrator is context of user account.</comment>
</data>
<data name="Cant_Drag_Elevated_Learn_More" xml:space="preserve">
<value>Learn more</value>

View File

@@ -12,6 +12,7 @@ namespace ZonedWindowProperties
const wchar_t MultiMonitorDeviceID[] = L"FancyZones#MultiMonitorDevice";
}
// in reality, this file needs to be kept in sync currently with src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/FZConfigProperties.cs
struct Settings
{
enum struct OverlappingZonesAlgorithm : int
@@ -45,7 +46,7 @@ struct Settings
std::wstring zoneHighlightColor = L"#008CFF";
int zoneHighlightOpacity = 50;
OverlappingZonesAlgorithm overlappingZonesAlgorithm = OverlappingZonesAlgorithm::Smallest;
PowerToysSettings::HotkeyObject editorHotkey = PowerToysSettings::HotkeyObject::from_settings(true, false, false, false, VK_OEM_3);
PowerToysSettings::HotkeyObject editorHotkey = PowerToysSettings::HotkeyObject::from_settings(true, false, false, true, VK_OEM_3);
std::wstring excludedApps = L"";
std::vector<std::wstring> excludedAppsArray;
};

View File

@@ -882,9 +882,9 @@ bool ZoneSet::CalculateGridZones(Rect workArea, FancyZonesDataTypes::GridLayoutI
long bottom = rowInfo[maxRow].End;
top += row == 0 ? spacing : spacing / 2;
bottom -= row == gridLayoutInfo.rows() - 1 ? spacing : spacing / 2;
bottom -= maxRow == gridLayoutInfo.rows() - 1 ? spacing : spacing / 2;
left += col == 0 ? spacing : spacing / 2;
right -= col == gridLayoutInfo.columns() - 1 ? spacing : spacing / 2;
right -= maxCol == gridLayoutInfo.columns() - 1 ? spacing : spacing / 2;
auto zone = MakeZone(RECT{ left, top, right, bottom }, i);
if (zone)

View File

@@ -127,6 +127,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Setting_Description_FlashZonesOnQuickSwitch" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Flash zones when switching layout]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Flasher les zones pendant le changement de disposition]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Setting_Description_Make_Dragged_Window_Transparent" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Make dragged window transparent]]></Val>
@@ -181,6 +190,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Setting_Description_QuickLayoutSwitch" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Enable quick layout switch]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Activer le changement de disposition rapide]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Setting_Description_RestoreSize" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Restore the original size of windows when unsnapping]]></Val>

View File

@@ -127,6 +127,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Setting_Description_FlashZonesOnQuickSwitch" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Flash zones when switching layout]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Zónák villogtatása az elrendezés váltásakor]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Setting_Description_Make_Dragged_Window_Transparent" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Make dragged window transparent]]></Val>
@@ -181,6 +190,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Setting_Description_QuickLayoutSwitch" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Enable quick layout switch]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Gyors elrendezésváltás engedélyezése]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Setting_Description_RestoreSize" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Restore the original size of windows when unsnapping]]></Val>

View File

@@ -127,6 +127,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Setting_Description_FlashZonesOnQuickSwitch" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Flash zones when switching layout]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Piscar as zonas ao mudar de layout]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Setting_Description_Make_Dragged_Window_Transparent" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Make dragged window transparent]]></Val>
@@ -181,6 +190,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Setting_Description_QuickLayoutSwitch" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Enable quick layout switch]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Habilitar opção de mudança rápida de layout]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Setting_Description_RestoreSize" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Restore the original size of windows when unsnapping]]></Val>

View File

@@ -127,6 +127,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Setting_Description_FlashZonesOnQuickSwitch" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Flash zones when switching layout]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Blinka zoner vid layoutväxling]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Setting_Description_Make_Dragged_Window_Transparent" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Make dragged window transparent]]></Val>
@@ -181,6 +190,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Setting_Description_QuickLayoutSwitch" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Enable quick layout switch]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Aktivera snabb layoutväxling]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Setting_Description_RestoreSize" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Restore the original size of windows when unsnapping]]></Val>

View File

@@ -127,6 +127,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Setting_Description_FlashZonesOnQuickSwitch" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Flash zones when switching layout]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Düzen değiştirilirken bölgeleri parlamayla gösterin]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Setting_Description_Make_Dragged_Window_Transparent" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Make dragged window transparent]]></Val>
@@ -181,6 +190,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Setting_Description_QuickLayoutSwitch" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Enable quick layout switch]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Hızlı düzen anahtarını etkinleştirin]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Setting_Description_RestoreSize" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Restore the original size of windows when unsnapping]]></Val>

View File

@@ -127,6 +127,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Setting_Description_FlashZonesOnQuickSwitch" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Flash zones when switching layout]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[切换布局时刷写区域]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Setting_Description_Make_Dragged_Window_Transparent" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Make dragged window transparent]]></Val>
@@ -181,6 +190,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Setting_Description_QuickLayoutSwitch" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Enable quick layout switch]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[启用快速布局切换]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Setting_Description_RestoreSize" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Restore the original size of windows when unsnapping]]></Val>

View File

@@ -1,12 +0,0 @@
// This class sets the visibility property of Advanced settings based on the OS Version
namespace ImageResizer.Models
{
public static class AdvancedSettings
{
public static bool UseNewSettings()
{
return interop.CommonManaged.ShouldNewSettingsBeUsed();
}
}
}

View File

@@ -59,232 +59,7 @@ namespace ImageResizer.Properties {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to About.
/// </summary>
public static string Advanced_About {
get {
return ResourceManager.GetString("Advanced_About", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Create a new size.
/// </summary>
public static string Advanced_CreateSize {
get {
return ResourceManager.GetString("Advanced_CreateSize", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Delete.
/// </summary>
public static string Advanced_DeleteSize {
get {
return ResourceManager.GetString("Advanced_DeleteSize", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Encoding.
/// </summary>
public static string Advanced_Encoding {
get {
return ResourceManager.GetString("Advanced_Encoding", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to _Fallback encoder:.
/// </summary>
public static string Advanced_FallbackEncoder {
get {
return ResourceManager.GetString("Advanced_FallbackEncoder", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Fallback encoder.
/// </summary>
public static string Advanced_FallbackEncoder_Name {
get {
return ResourceManager.GetString("Advanced_FallbackEncoder_Name", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to File.
/// </summary>
public static string Advanced_File {
get {
return ResourceManager.GetString("Advanced_File", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to _Filename:.
/// </summary>
public static string Advanced_FileName {
get {
return ResourceManager.GetString("Advanced_FileName", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Filename.
/// </summary>
public static string Advanced_FileName_Name {
get {
return ResourceManager.GetString("Advanced_FileName_Name", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Original filename.
/// </summary>
public static string Advanced_FileNameToken1 {
get {
return ResourceManager.GetString("Advanced_FileNameToken1", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Size name.
/// </summary>
public static string Advanced_FileNameToken2 {
get {
return ResourceManager.GetString("Advanced_FileNameToken2", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Selected width.
/// </summary>
public static string Advanced_FileNameToken3 {
get {
return ResourceManager.GetString("Advanced_FileNameToken3", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Selected height.
/// </summary>
public static string Advanced_FileNameToken4 {
get {
return ResourceManager.GetString("Advanced_FileNameToken4", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Actual width (pixels).
/// </summary>
public static string Advanced_FileNameToken5 {
get {
return ResourceManager.GetString("Advanced_FileNameToken5", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Actual height (pixels).
/// </summary>
public static string Advanced_FileNameToken6 {
get {
return ResourceManager.GetString("Advanced_FileNameToken6", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The following parameters can be used..
/// </summary>
public static string Advanced_FileNameTokens {
get {
return ResourceManager.GetString("Advanced_FileNameTokens", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to _JPEG quality level:.
/// </summary>
public static string Advanced_JpegQualityLevel {
get {
return ResourceManager.GetString("Advanced_JpegQualityLevel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to JPEG quality level.
/// </summary>
public static string Advanced_JpegQualityLevel_Name {
get {
return ResourceManager.GetString("Advanced_JpegQualityLevel_Name", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to _Use original date modified.
/// </summary>
public static string Advanced_KeepDateModified {
get {
return ResourceManager.GetString("Advanced_KeepDateModified", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to _PNG interlacing:.
/// </summary>
public static string Advanced_PngInterlaceOption {
get {
return ResourceManager.GetString("Advanced_PngInterlaceOption", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to PNG interlacing.
/// </summary>
public static string Advanced_PngInterlaceOption_Name {
get {
return ResourceManager.GetString("Advanced_PngInterlaceOption_Name", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Sizes.
/// </summary>
public static string Advanced_Sizes {
get {
return ResourceManager.GetString("Advanced_Sizes", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to _TIFF compression:.
/// </summary>
public static string Advanced_TiffCompressOption {
get {
return ResourceManager.GetString("Advanced_TiffCompressOption", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to TIFF compression.
/// </summary>
public static string Advanced_TiffCompressOption_Name {
get {
return ResourceManager.GetString("Advanced_TiffCompressOption_Name", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Settings.
/// </summary>
public static string Advanced_Title {
get {
return ResourceManager.GetString("Advanced_Title", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to All Files.
/// </summary>
@@ -302,16 +77,7 @@ namespace ImageResizer.Properties {
return ResourceManager.GetString("Cancel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to © 2020 Brice Lambson. All rights reserved..
/// </summary>
public static string Copyright {
get {
return ResourceManager.GetString("Copyright", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Height.
/// </summary>
@@ -384,15 +150,6 @@ namespace ImageResizer.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Settings.
/// </summary>
public static string Input_ShowAdvanced {
get {
return ResourceManager.GetString("Input_ShowAdvanced", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to _Make pictures smaller but not larger.
/// </summary>
@@ -726,69 +483,6 @@ namespace ImageResizer.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to CCITT3.
/// </summary>
public static string TiffCompressOption_Ccitt3 {
get {
return ResourceManager.GetString("TiffCompressOption_Ccitt3", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to CCITT4.
/// </summary>
public static string TiffCompressOption_Ccitt4 {
get {
return ResourceManager.GetString("TiffCompressOption_Ccitt4", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to (Default).
/// </summary>
public static string TiffCompressOption_Default {
get {
return ResourceManager.GetString("TiffCompressOption_Default", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to LZW.
/// </summary>
public static string TiffCompressOption_Lzw {
get {
return ResourceManager.GetString("TiffCompressOption_Lzw", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to None.
/// </summary>
public static string TiffCompressOption_None {
get {
return ResourceManager.GetString("TiffCompressOption_None", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to RLE.
/// </summary>
public static string TiffCompressOption_Rle {
get {
return ResourceManager.GetString("TiffCompressOption_Rle", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to ZIP.
/// </summary>
public static string TiffCompressOption_Zip {
get {
return ResourceManager.GetString("TiffCompressOption_Zip", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Times Symbol.
/// </summary>

View File

@@ -117,93 +117,12 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Advanced_About" xml:space="preserve">
<value>About</value>
</data>
<data name="Advanced_CreateSize" xml:space="preserve">
<value>Create a new size</value>
</data>
<data name="Advanced_DeleteSize" xml:space="preserve">
<value>Delete</value>
<comment>remove a file</comment>
</data>
<data name="Advanced_Encoding" xml:space="preserve">
<value>Encoding</value>
<comment>encoding a file to a different format</comment>
</data>
<data name="Advanced_FallbackEncoder" xml:space="preserve">
<value>_Fallback encoder:</value>
</data>
<data name="Advanced_FallbackEncoder_Name" xml:space="preserve">
<value>Fallback encoder</value>
</data>
<data name="Advanced_File" xml:space="preserve">
<value>File</value>
<comment>as in file name</comment>
</data>
<data name="Advanced_FileName" xml:space="preserve">
<value>_Filename:</value>
</data>
<data name="Advanced_FileNameToken1" xml:space="preserve">
<value>Original filename</value>
</data>
<data name="Advanced_FileNameToken2" xml:space="preserve">
<value>Size name</value>
</data>
<data name="Advanced_FileNameToken3" xml:space="preserve">
<value>Selected width</value>
</data>
<data name="Advanced_FileNameToken4" xml:space="preserve">
<value>Selected height</value>
</data>
<data name="Advanced_FileNameToken5" xml:space="preserve">
<value>Actual width (pixels)</value>
</data>
<data name="Advanced_FileNameToken6" xml:space="preserve">
<value>Actual height (pixels)</value>
</data>
<data name="Advanced_FileNameTokens" xml:space="preserve">
<value>The following parameters can be used.</value>
</data>
<data name="Advanced_FileName_Name" xml:space="preserve">
<value>Filename</value>
</data>
<data name="Advanced_JpegQualityLevel" xml:space="preserve">
<value>_JPEG quality level:</value>
</data>
<data name="Advanced_JpegQualityLevel_Name" xml:space="preserve">
<value>JPEG quality level</value>
</data>
<data name="Advanced_KeepDateModified" xml:space="preserve">
<value>_Use original date modified</value>
</data>
<data name="Advanced_PngInterlaceOption" xml:space="preserve">
<value>_PNG interlacing:</value>
</data>
<data name="Advanced_PngInterlaceOption_Name" xml:space="preserve">
<value>PNG interlacing</value>
</data>
<data name="Advanced_Sizes" xml:space="preserve">
<value>Sizes</value>
</data>
<data name="Advanced_TiffCompressOption" xml:space="preserve">
<value>_TIFF compression:</value>
</data>
<data name="Advanced_TiffCompressOption_Name" xml:space="preserve">
<value>TIFF compression</value>
</data>
<data name="Advanced_Title" xml:space="preserve">
<value>Settings</value>
</data>
<data name="AllFilesFilter" xml:space="preserve">
<value>All Files</value>
</data>
<data name="Cancel" xml:space="preserve">
<value>Cancel</value>
</data>
<data name="Copyright" xml:space="preserve">
<value>© 2020 Brice Lambson. All rights reserved.</value>
</data>
<data name="Height" xml:space="preserve">
<value>Height</value>
</data>
@@ -229,9 +148,6 @@
<data name="Input_Resize" xml:space="preserve">
<value>Resize</value>
</data>
<data name="Input_ShowAdvanced" xml:space="preserve">
<value>Settings</value>
</data>
<data name="Input_ShrinkOnly" xml:space="preserve">
<value>_Make pictures smaller but not larger</value>
</data>
@@ -343,32 +259,6 @@
<data name="Small" xml:space="preserve">
<value>Small</value>
</data>
<data name="TiffCompressOption_Ccitt3" xml:space="preserve">
<value>CCITT3</value>
<comment>Do not loc</comment>
</data>
<data name="TiffCompressOption_Ccitt4" xml:space="preserve">
<value>CCITT4</value>
<comment>Do not loc</comment>
</data>
<data name="TiffCompressOption_Default" xml:space="preserve">
<value>(Default)</value>
</data>
<data name="TiffCompressOption_Lzw" xml:space="preserve">
<value>LZW</value>
<comment>Do not loc</comment>
</data>
<data name="TiffCompressOption_None" xml:space="preserve">
<value>None</value>
</data>
<data name="TiffCompressOption_Rle" xml:space="preserve">
<value>RLE</value>
<comment>Do not loc</comment>
</data>
<data name="TiffCompressOption_Zip" xml:space="preserve">
<value>ZIP</value>
<comment>Do not loc</comment>
</data>
<data name="Times_Symbol" xml:space="preserve">
<value>Times Symbol</value>
</data>

View File

@@ -1,7 +1,6 @@
// Copyright (c) Brice Lambson
// The Brice Lambson licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/
// ShowAdvancedCommand = new RelayCommand(ShowAdvanced);
using System.Windows.Input;
using ImageResizer.Helpers;
@@ -35,21 +34,14 @@ namespace ImageResizer.ViewModels
ResizeCommand = new RelayCommand(Resize);
CancelCommand = new RelayCommand(Cancel);
ShowAdvancedCommand = new RelayCommand(ShowAdvanced);
ShowAdvancedSettings = !AdvancedSettings.UseNewSettings();
}
public bool ShowAdvancedSettings { get; }
public Settings Settings { get; }
public ICommand ResizeCommand { get; }
public ICommand CancelCommand { get; }
public ICommand ShowAdvancedCommand { get; }
public void Resize()
{
Settings.Save();
@@ -58,8 +50,5 @@ namespace ImageResizer.ViewModels
public void Cancel()
=> _mainView.Close();
public void ShowAdvanced()
=> _mainView.ShowAdvanced(new AdvancedViewModel(Settings));
}
}

View File

@@ -1,24 +0,0 @@
// 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.Collections.Generic;
using System.Windows;
using System.Windows.Automation.Peers;
using System.Windows.Documents;
namespace ImageResizer.Views
{
public class AccessibleHyperlink : Hyperlink
{
public AutomationControlType ControlType { get; set; }
protected override AutomationPeer OnCreateAutomationPeer()
{
var peer = new CustomizableHyperlinkAutomationPeer(this);
peer.ControlType = ControlType;
return peer;
}
}
}

View File

@@ -1,312 +0,0 @@
<Window x:Class="ImageResizer.Views.AdvancedWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ImageResizer.Views"
xmlns:m="clr-namespace:ImageResizer.Models"
xmlns:p="clr-namespace:ImageResizer.Properties"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:ui="http://schemas.modernwpf.com/2019"
ContentRendered="WindowContentRendered"
MinWidth="560"
MinHeight="340"
ui:WindowHelper.UseModernWindowStyle="True"
ui:TitleBar.IsIconVisible="True"
Background="{DynamicResource PrimaryBackgroundBrush}"
Name="_this"
ResizeMode="NoResize"
SizeToContent="WidthAndHeight"
Title="{x:Static p:Resources.Advanced_Title}"
WindowStyle="ToolWindow"
WindowStartupLocation="CenterScreen">
<Window.Resources>
<ObjectDataProvider x:Key="PngInterlaceOptionValues"
MethodName="GetValues"
ObjectType="{x:Type sys:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="PngInterlaceOption"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<ObjectDataProvider x:Key="TiffCompressOptionValues"
MethodName="GetValues"
ObjectType="{x:Type sys:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="TiffCompressOption"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<local:ContainerFormatConverter x:Key="ContainerFormatConverter"/>
</Window.Resources>
<Grid Margin="0">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TabControl Style="{StaticResource TabControlPivotStyle}">
<TabItem Header="{x:Static p:Resources.Advanced_Sizes}">
<StackPanel Margin="0,12,0,12">
<!-- TODO: Allow these to be drag-and-drop reordered (issue #15) -->
<ItemsControl Grid.IsSharedSizeScope="True" TabIndex="0" ItemsSource="{Binding Settings.Sizes}">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="m:ResizeSize">
<Grid Margin="0,0,0,8">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="0"/>
<ColumnDefinition SharedSizeGroup="1"/>
<ColumnDefinition SharedSizeGroup="2"/>
<ColumnDefinition SharedSizeGroup="3"/>
<ColumnDefinition SharedSizeGroup="4"/>
<ColumnDefinition SharedSizeGroup="5"/>
<ColumnDefinition SharedSizeGroup="6"/>
</Grid.ColumnDefinitions>
<TextBox Width="96"
MaxWidth="96"
TextWrapping="Wrap"
AutomationProperties.Name="{Binding Name}"
Text="{Binding Name}"/>
<ComboBox Grid.Column="1"
Margin="8,0,0,0"
Width="90"
ItemsSource="{Binding Source={StaticResource ResizeFitValues}}"
AutomationProperties.Name="{x:Static p:Resources.Resize_Type}"
SelectedItem="{Binding Fit}">
<ComboBox.ItemTemplate>
<DataTemplate DataType="{x:Type m:ResizeFit}">
<ContentPresenter Content="{Binding Converter={StaticResource EnumValueConverter}}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<TextBox Grid.Column="2"
Width="56"
MaxWidth="56"
TextWrapping="Wrap"
AutomationProperties.Name="{x:Static p:Resources.Width}"
Margin="8,0,0,0">
<TextBox.Text>
<Binding Converter="{StaticResource AutoDoubleConverter}"
Path="Width"
UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<local:AutoDoubleValidationRule/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<TextBlock Grid.Column="3"
Foreground="{DynamicResource PrimaryForegroundBrush}"
Name="Times_Symbol"
AutomationProperties.Name="{x:Static p:Resources.Times_Symbol}"
VerticalAlignment="Center"
Text="&#xE711;"
FontFamily="Segoe MDL2 Assets"
Width="25"
TextAlignment="Center"
Visibility="{Binding ShowHeight,Converter={StaticResource BoolValueConverter}}"/>
<TextBox Grid.Column="4"
Width="56"
MaxWidth="56"
TextWrapping="Wrap"
AutomationProperties.Name="{x:Static p:Resources.Height}"
Visibility="{Binding ShowHeight,Converter={StaticResource BoolValueConverter}}">
<TextBox.Text>
<Binding Converter="{StaticResource AutoDoubleConverter}"
Path="Height"
UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<local:AutoDoubleValidationRule/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<ComboBox Grid.Column="5"
Margin="8,0,0,0"
MinWidth="120"
ItemsSource="{Binding Source={StaticResource ResizeUnitValues}}"
AutomationProperties.Name="{x:Static p:Resources.Unit}"
SelectedItem="{Binding Unit}">
<ComboBox.ItemTemplate>
<DataTemplate DataType="{x:Type m:ResizeUnit}">
<ContentPresenter Content="{Binding Converter={StaticResource EnumValueConverter}}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<Button Content="&#xE107;"
FontFamily="Segoe MDL2 Assets"
Background="Transparent"
Grid.Column="6"
Margin="8,0,0,0"
VerticalAlignment="Center"
AutomationProperties.Name="{x:Static p:Resources.Advanced_DeleteSize}"
ToolTip="{x:Static p:Resources.Advanced_DeleteSize}"
Command="{Binding DataContext.RemoveSizeCommand,ElementName=_this}"
CommandParameter="{Binding}" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Button Margin="0,12,0,0"
Command="{Binding AddSizeCommand}"
Content="{x:Static p:Resources.Advanced_CreateSize}"/>
</StackPanel>
</TabItem>
<TabItem Header="{x:Static p:Resources.Advanced_Encoding}">
<Grid Margin="0,12,0,12" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Content="{x:Static p:Resources.Advanced_FallbackEncoder}"
Padding="0,8,8,0"
Target="{Binding ElementName=_fallbackEncoderComboBox}"/>
<ComboBox Grid.Column="1"
HorizontalAlignment="Left"
MinWidth="148"
ItemsSource="{Binding Encoders}"
AutomationProperties.Name="{x:Static p:Resources.Advanced_FallbackEncoder_Name}"
Name="_fallbackEncoderComboBox"
SelectedItem="{Binding Settings.FallbackEncoder}">
<ComboBox.ItemTemplate>
<DataTemplate DataType="{x:Type sys:Guid}">
<ContentPresenter Content="{Binding Converter={StaticResource ContainerFormatConverter}}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<Label Grid.Row="1"
Margin="0,8,0,0"
Content="{x:Static p:Resources.Advanced_JpegQualityLevel}"
Padding="0,8,8,0"
Target="{Binding ElementName=_jpegQualityLevelTextBox}"/>
<TextBox Grid.Row="1"
Grid.Column="1"
Width="56"
MinWidth="148"
TextWrapping="Wrap"
AutomationProperties.Name="{x:Static p:Resources.Advanced_JpegQualityLevel_Name}"
Margin="0,8,0,0"
HorizontalAlignment="Left"
Name="_jpegQualityLevelTextBox"
Text="{Binding Settings.JpegQualityLevel,ValidatesOnExceptions=True,ValidatesOnDataErrors=True}"/>
<Label Grid.Row="2"
Margin="0,8,0,0"
Content="{x:Static p:Resources.Advanced_PngInterlaceOption}"
Padding="0,8,8,0"
Target="{Binding ElementName=_pngInterlaceComboBox}"/>
<ComboBox Grid.Row="2"
Grid.Column="1"
Margin="0,8,0,0"
MinWidth="148"
HorizontalAlignment="Left"
AutomationProperties.Name="{x:Static p:Resources.Advanced_PngInterlaceOption_Name}"
ItemsSource="{Binding Source={StaticResource PngInterlaceOptionValues}}"
Name="_pngInterlaceComboBox"
SelectedItem="{Binding Settings.PngInterlaceOption}">
<ComboBox.ItemTemplate>
<DataTemplate DataType="{x:Type PngInterlaceOption}">
<ContentPresenter Content="{Binding Converter={StaticResource EnumValueConverter}}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<Label Grid.Row="3"
Margin="0,8,0,0"
Content="{x:Static p:Resources.Advanced_TiffCompressOption}"
Padding="0,8,8,0"
Target="{Binding ElementName=_tiffCompressComboBox}"/>
<ComboBox Grid.Row="3"
Grid.Column="1"
MinWidth="148"
Margin="0,8,0,0"
HorizontalAlignment="Left"
AutomationProperties.Name="{x:Static p:Resources.Advanced_TiffCompressOption_Name}"
ItemsSource="{Binding Source={StaticResource TiffCompressOptionValues}}"
Name="_tiffCompressComboBox"
SelectedItem="{Binding Settings.TiffCompressOption}">
<ComboBox.ItemTemplate>
<DataTemplate DataType="{x:Type TiffCompressOption}">
<ContentPresenter Content="{Binding Converter={StaticResource EnumValueConverter}}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</Grid>
</TabItem>
<TabItem Header="{x:Static p:Resources.Advanced_File}">
<StackPanel Margin="0,12,0,12">
<TextBlock Text="{x:Static p:Resources.Advanced_FileNameTokens}"/>
<TextBlock Margin="0,8,0,0">
<Run Text="%1 -"/>
<Run Text="{x:Static p:Resources.Advanced_FileNameToken1}"/>
<LineBreak/>
<Run>%2 -</Run>
<Run Text="{x:Static p:Resources.Advanced_FileNameToken2}"/>
<LineBreak/>
<Run>%3 -</Run>
<Run Text="{x:Static p:Resources.Advanced_FileNameToken3}"/>
<LineBreak/>
<Run>%4 -</Run>
<Run Text="{x:Static p:Resources.Advanced_FileNameToken4}"/>
<LineBreak/>
<Run>%5 -</Run>
<Run Text="{x:Static p:Resources.Advanced_FileNameToken5}"/>
<LineBreak/>
<Run>%6 -</Run>
<Run Text="{x:Static p:Resources.Advanced_FileNameToken6}"/>
</TextBlock>
<Grid Margin="0,8,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Label HorizontalAlignment="Left"
x:Name="fileNameTextBoxLabel"
Content="{x:Static p:Resources.Advanced_FileName}"
Padding="0,4,4,0"
Target="{Binding ElementName=fileNameTextBox}"/>
<TextBox Grid.Column="1"
Height="23"
MinWidth="240"
TabIndex="0"
HorizontalAlignment="Left"
TextWrapping="Wrap"
Name="fileNameTextBox"
AutomationProperties.Name="{x:Static p:Resources.Advanced_FileName_Name}"
Text="{Binding Settings.FileName}"/>
</Grid>
<Separator Margin="0,12,0,0"/>
<CheckBox Margin="0,12,0,0"
Content="{x:Static p:Resources.Advanced_KeepDateModified}"
IsChecked="{Binding Settings.KeepDateModified}"/>
</StackPanel>
</TabItem>
</TabControl>
<Border Grid.Row="1"
Margin="0,24,0,0"
BorderBrush="{DynamicResource PrimaryBorderBrush}"
BorderThickness="0,1,0,0"
Background="{DynamicResource SecondaryBackgroundBrush}"
Padding="12">
<StackPanel
HorizontalAlignment="Right"
Orientation="Horizontal">
<Button MinWidth="76"
TabIndex="100"
Click="HandleAcceptClick"
Style="{StaticResource AccentButtonStyle}"
Content="{x:Static p:Resources.OK}"
AutomationProperties.Name="{x:Static p:Resources.OK_Tooltip}"
IsDefault="True"/>
<Button MinWidth="76"
Margin="8,0,0,0"
TabIndex="101"
Content="{x:Static p:Resources.Cancel}"
IsCancel="True"/>
</StackPanel>
</Border>
</Grid>
</Window>

View File

@@ -1,35 +0,0 @@
// Copyright (c) Brice Lambson
// The Brice Lambson licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/
using System.Diagnostics;
using System.Windows;
using System.Windows.Navigation;
using ImageResizer.ViewModels;
namespace ImageResizer.Views
{
public partial class AdvancedWindow : Window
{
public AdvancedWindow(AdvancedViewModel viewModel)
{
DataContext = viewModel;
InitializeComponent();
}
private void HandleAcceptClick(object sender, RoutedEventArgs e)
=> DialogResult = true;
private void HandleRequestNavigate(object sender, RequestNavigateEventArgs e)
{
Process.Start(e.Uri.ToString());
e.Handled = true;
}
// Fix for black outline WPF bug when a window uses custom chrome. More info here https://stackoverflow.com/questions/29207331/wpf-window-with-custom-chrome-has-unwanted-outline-on-right-and-bottom
private void WindowContentRendered(object sender, System.EventArgs e)
{
InvalidateVisual();
}
}
}

View File

@@ -1,22 +0,0 @@
// Copyright (c) Brice Lambson
// The Brice Lambson licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/
using System.Globalization;
using System.Windows.Controls;
namespace ImageResizer.Views
{
internal class AutoDoubleValidationRule : ValidationRule
{
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
var text = (string)value;
return new ValidationResult(
string.IsNullOrEmpty(text)
|| double.TryParse(text, NumberStyles.AllowThousands | NumberStyles.Float, cultureInfo, out var _),
null);
}
}
}

View File

@@ -1,23 +0,0 @@
// Copyright (c) Brice Lambson
// The Brice Lambson licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/
using System;
using System.Globalization;
using System.Windows.Data;
using ImageResizer.ViewModels;
namespace ImageResizer.Views
{
[ValueConversion(typeof(Guid), typeof(string))]
public class ContainerFormatConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
=> AdvancedViewModel.EncoderMap.TryGetValue((Guid)value, out var result)
? result
: value?.ToString();
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
=> throw new NotImplementedException();
}
}

View File

@@ -1,24 +0,0 @@
// 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.Windows.Automation.Peers;
using System.Windows.Documents;
namespace ImageResizer.Views
{
public class CustomizableHyperlinkAutomationPeer : HyperlinkAutomationPeer
{
public CustomizableHyperlinkAutomationPeer(Hyperlink owner)
: base(owner)
{
}
public AutomationControlType ControlType { get; set; }
protected override AutomationControlType GetAutomationControlTypeCore()
{
return ControlType;
}
}
}

View File

@@ -1,7 +1,6 @@
// Copyright (c) Brice Lambson
// The Brice Lambson licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/
// void ShowAdvanced(AdvancedViewModel viewModel);
using System.Collections.Generic;
using ImageResizer.ViewModels;
@@ -12,8 +11,6 @@ namespace ImageResizer.Views
{
void Close();
void ShowAdvanced(AdvancedViewModel viewModel);
IEnumerable<string> OpenPictureFiles();
}
}

View File

@@ -17,7 +17,9 @@
</DataTrigger>
</Style.Triggers>
</Style>
<Style x:Key="DisabledWhenUnselectedTextBoxStyle" TargetType="TextBox" BasedOn="{StaticResource DefaultTextBoxStyle}">
<Style x:Key="DisabledWhenUnselectedTextBoxStyle"
TargetType="ui:NumberBox"
>
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=ListBoxItem}}" Value="True">
<Setter Property="IsEnabled" Value="True"/>
@@ -67,25 +69,49 @@
<ListBox.Resources>
<DataTemplate DataType="{x:Type m:ResizeSize}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" FontWeight="SemiBold" Foreground="{DynamicResource PrimaryForegroundBrush}"/>
<TextBlock Text="(" Margin="4,0,0,0" Foreground="{DynamicResource SecondaryForegroundBrush}"/>
<TextBlock Text="{Binding Fit,Converter={StaticResource EnumValueConverter},ConverterParameter=ThirdPersonSingular}" Foreground="{DynamicResource SecondaryForegroundBrush}"/>
<Grid Margin="0,0,0,4">
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition Height="24" />
</Grid.RowDefinitions>
<TextBlock Text="{Binding Name}"
FontWeight="SemiBold"
FontSize="16"
Margin="0,-2,0,0"
VerticalAlignment="Top"
Foreground="{DynamicResource PrimaryForegroundBrush}" />
<StackPanel Orientation="Horizontal"
Grid.Row="1"
VerticalAlignment="Top">
<TextBlock Text="{Binding Fit,Converter={StaticResource EnumValueConverter},ConverterParameter=ThirdPersonSingular}" Foreground="{DynamicResource SecondaryForegroundBrush}"/>
<TextBlock Text="{Binding Width,Converter={StaticResource AutoDoubleConverter},ConverterParameter=Auto}" Margin="4,0,0,0" Foreground="{DynamicResource SecondaryForegroundBrush}"/>
<TextBlock Text="&#xE711;" FontSize="11" FontFamily="Segoe MDL2 Assets" Visibility="{Binding ShowHeight,Converter={StaticResource BoolValueConverter}}" Margin="4,5,0,0" Foreground="{DynamicResource SecondaryForegroundBrush}"/>
<TextBlock Text="{Binding Height,Converter={StaticResource AutoDoubleConverter},ConverterParameter=Auto}" Visibility="{Binding ShowHeight,Converter={StaticResource BoolValueConverter}}" Margin="4,0,0,0" Foreground="{DynamicResource SecondaryForegroundBrush}"/>
<TextBlock Text="{Binding Unit,Converter={StaticResource EnumValueConverter},ConverterParameter=ToLower}" Margin="4,0,0,0" Foreground="{DynamicResource SecondaryForegroundBrush}"/>
<TextBlock Text=")" Foreground="{DynamicResource SecondaryForegroundBrush}"/>
</StackPanel>
<TextBlock Text="{Binding Unit,Converter={StaticResource EnumValueConverter},ConverterParameter=ToLower}"
Margin="4,0,0,0"
Foreground="{DynamicResource SecondaryForegroundBrush}" />
</StackPanel>
</Grid>
</DataTemplate>
<DataTemplate DataType="{x:Type m:CustomSize}">
<StackPanel Orientation="Horizontal" Margin="0,-8,0,0">
<TextBlock VerticalAlignment="Center"
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="32" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock VerticalAlignment="Top"
Text="{Binding Name}"
FontSize="16"
Margin="0,-2,0,0"
Foreground="{DynamicResource PrimaryForegroundBrush}"
FontWeight="SemiBold"/>
<ComboBox Margin="8,0,0,0"
FontWeight="SemiBold" />
<StackPanel Orientation="Horizontal" Grid.Row="1" Margin="0,-8,0,0">
<ComboBox Margin="0,0,0,0"
ItemsSource="{Binding Source={StaticResource ResizeFitValues}}"
Style="{StaticResource DisabledWhenUnselectedComboBoxStyle}"
AutomationProperties.Name="{x:Static p:Resources.Resize_Type}"
@@ -96,22 +122,19 @@
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<TextBox Width="56"
TextWrapping="Wrap"
Style="{StaticResource DisabledWhenUnselectedTextBoxStyle}"
AutomationProperties.Name="{x:Static p:Resources.Width}"
Margin="8,0,0,0">
<TextBox.Text>
<Binding Converter="{StaticResource AutoDoubleConverter}"
Path="Width"
UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<local:AutoDoubleValidationRule/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<TextBlock VerticalAlignment="Center"
<ui:NumberBox SpinButtonPlacementMode="Compact"
Minimum="1"
Width="102"
Style="{StaticResource DisabledWhenUnselectedTextBoxStyle}"
AutomationProperties.Name="{x:Static p:Resources.Width}"
Margin="8,0,0,0">
<ui:NumberBox.Value>
<Binding Path="Width"
UpdateSourceTrigger="PropertyChanged">
</Binding>
</ui:NumberBox.Value>
</ui:NumberBox>
<TextBlock VerticalAlignment="Center"
Text="&#xE711;"
FontFamily="Segoe MDL2 Assets"
Width="25"
@@ -121,22 +144,19 @@
TextAlignment="Center"
Visibility="{Binding ShowHeight,Converter={StaticResource BoolValueConverter}}"/>
<TextBox Width="56"
Style="{StaticResource DisabledWhenUnselectedTextBoxStyle}"
TextWrapping="Wrap"
AutomationProperties.Name="{x:Static p:Resources.Height}"
Visibility="{Binding ShowHeight,Converter={StaticResource BoolValueConverter}}">
<TextBox.Text>
<Binding Converter="{StaticResource AutoDoubleConverter}"
Path="Height"
UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<local:AutoDoubleValidationRule/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<ComboBox Margin="8,0,0,0"
<ui:NumberBox Style="{StaticResource DisabledWhenUnselectedTextBoxStyle}"
SpinButtonPlacementMode="Compact"
Minimum="1"
Width="102"
AutomationProperties.Name="{x:Static p:Resources.Height}"
Visibility="{Binding ShowHeight,Converter={StaticResource BoolValueConverter}}">
<ui:NumberBox.Value>
<Binding Path="Height"
UpdateSourceTrigger="PropertyChanged">
</Binding>
</ui:NumberBox.Value>
</ui:NumberBox>
<ComboBox Margin="8,0,0,0"
ItemsSource="{Binding Source={StaticResource ResizeUnitValues}}"
Style="{StaticResource DisabledWhenUnselectedComboBoxStyle}"
AutomationProperties.Name="{x:Static p:Resources.Unit}"
@@ -148,6 +168,7 @@
</ComboBox.ItemTemplate>
</ComboBox>
</StackPanel>
</Grid>
</DataTemplate>
</ListBox.Resources>
</ListBox>
@@ -177,17 +198,6 @@
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Button Content="&#xE115;"
FontFamily="Segoe MDL2 Assets"
Style="{StaticResource DefaultButtonStyle}"
FontSize="16"
Margin="-6,0,0,0"
AutomationProperties.Name="{x:Static p:Resources.Input_ShowAdvanced}"
ToolTip="{x:Static p:Resources.Input_ShowAdvanced}"
Background="Transparent"
Command="{Binding ShowAdvancedCommand}"
Visibility="{Binding ShowAdvancedSettings, Converter={StaticResource BoolValueConverter}}"/>
<Button Grid.Column="1"
Style="{StaticResource AccentButtonStyle}"
MinWidth="76"

View File

@@ -39,8 +39,6 @@ namespace ImageResizer.Views
return openFileDialog.FileNames;
}
public void ShowAdvanced(AdvancedViewModel viewModel) => viewModel?.Close(new AdvancedWindow(viewModel).ShowDialog() == true);
void IMainView.Close()
=> Dispatcher.Invoke((Action)Close);
}

View File

Before

Width:  |  Height:  |  Size: 113 KiB

After

Width:  |  Height:  |  Size: 113 KiB

View File

@@ -0,0 +1,110 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#include "../../../../common/version/version.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#ifndef APSTUDIO_INVOKED
#include "targetver.h"
#endif
#define APSTUDIO_HIDDEN_SYMBOLS
#include "windows.h"
#undef APSTUDIO_HIDDEN_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION FILE_VERSION
PRODUCTVERSION PRODUCT_VERSION
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
#ifdef _DEBUG
FILEFLAGS VS_FF_DEBUG
#else
FILEFLAGS 0x0L
#endif
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE VFT2_UNKNOWN
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", COMPANY_NAME
VALUE "FileDescription", "PowerToys Keyboard Manager Editor"
VALUE "FileVersion", FILE_VERSION_STRING
VALUE "InternalName", "PowerToys.KeyboardManagerEditor.exe"
VALUE "LegalCopyright", COPYRIGHT_NOTE
VALUE "OriginalFilename", "PowerToys.KeyboardManagerEditor.exe"
VALUE "ProductName", PRODUCT_NAME
VALUE "ProductVersion", PRODUCT_VERSION_STRING
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
/////////////////////////////////////////////////////////////////////////////
// English (United States) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#ifndef APSTUDIO_INVOKED\r\n"
"#include ""targetver.h""\r\n"
"#endif\r\n"
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
"#include ""windows.h""\r\n"
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#endif // English (United States) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
IDS_KEYBOARDMANAGER_ICON ICON L"../Keyboard.ico"

View File

@@ -0,0 +1,217 @@
// KeyboardManagerEditor.cpp : Defines the entry point for the application.
//
#include "pch.h"
#include "KeyboardManagerEditor.h"
#include <common/utils/winapi_error.h>
#include <common/utils/logger_helper.h>
#include <common/utils/UnhandledExceptionHandler_x64.h>
#include <trace.h>
#include <KeyboardEventHandlers.h>
#include <KeyboardManagerState.h>
#include <SettingsHelper.h>
#include <EditKeyboardWindow.h>
#include <EditShortcutsWindow.h>
#include <common/utils/ProcessWaiter.h>
std::unique_ptr<KeyboardManagerEditor> editor = nullptr;
const std::wstring instanceMutexName = L"Local\\PowerToys_KBMEditor_InstanceMutex";
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
LoggerHelpers::init_logger(KeyboardManagerConstants::ModuleName, L"Editor", LogSettings::keyboardManagerLoggerName);
InitUnhandledExceptionHandler_x64();
Trace::RegisterProvider();
auto mutex = CreateMutex(nullptr, true, instanceMutexName.c_str());
if (mutex == nullptr)
{
Logger::error(L"Failed to create mutex. {}", get_last_error_or_default(GetLastError()));
}
else
{
Logger::trace(L"Created/Opened {} mutex", instanceMutexName);
}
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
Logger::info(L"KBM editor instance is already running");
return 0;
}
int numArgs;
LPWSTR* cmdArgs = CommandLineToArgvW(GetCommandLineW(), &numArgs);
KeyboardManagerEditorType type = KeyboardManagerEditorType::KeyEditor;
if (!IsDebuggerPresent())
{
if (cmdArgs == nullptr)
{
Logger::error(L"Keyboard Manager Editor cannot start as a standalone application");
return -1;
}
if (numArgs < 2)
{
Logger::error(L"Invalid arguments on Keyboard Manager Editor start");
return -1;
}
}
if (numArgs > 1)
{
type = static_cast<KeyboardManagerEditorType>(_wtoi(cmdArgs[1]));
}
if (numArgs == 3)
{
std::wstring pid = std::wstring(cmdArgs[2]);
Logger::trace(L"Editor started from the settings with pid {}", pid);
if (!pid.empty())
{
auto mainThreadId = GetCurrentThreadId();
ProcessWaiter::OnProcessTerminate(pid, [mainThreadId](int err) {
if (err != ERROR_SUCCESS)
{
Logger::error(L"Failed to wait for parent process exit. {}", get_last_error_or_default(err));
}
Logger::trace(L"Parent process exited. Exiting KeyboardManager editor");
PostThreadMessage(mainThreadId, WM_QUIT, 0, 0);
});
}
}
editor = std::make_unique<KeyboardManagerEditor>(hInstance);
if (!editor->StartLowLevelKeyboardHook())
{
DWORD errorCode = GetLastError();
show_last_error_message(L"SetWindowsHookEx", errorCode, L"PowerToys - Keyboard Manager Editor");
auto errorMessage = get_last_error_message(errorCode);
Logger::error(L"Unable to start keyboard hook: {}", errorMessage.has_value() ? errorMessage.value() : L"");
Trace::Error(errorCode, errorMessage.has_value() ? errorMessage.value() : L"", L"start_lowlevel_keyboard_hook.SetWindowsHookEx");
return -1;
}
editor->OpenEditorWindow(type);
editor = nullptr;
Trace::UnregisterProvider();
return 0;
}
KeyboardManagerEditor::KeyboardManagerEditor(HINSTANCE hInst) :
hInstance(hInst)
{
bool loadedSuccessful = SettingsHelper::LoadSettings(keyboardManagerState);
if (!loadedSuccessful)
{
std::this_thread::sleep_for(std::chrono::milliseconds(500));
// retry once
SettingsHelper::LoadSettings(keyboardManagerState);
}
StartLowLevelKeyboardHook();
}
KeyboardManagerEditor::~KeyboardManagerEditor()
{
UnhookWindowsHookEx(hook);
}
bool KeyboardManagerEditor::StartLowLevelKeyboardHook()
{
#if defined(DISABLE_LOWLEVEL_HOOKS_WHEN_DEBUGGED)
if (IsDebuggerPresent())
{
return true;
}
#endif
hook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyHookProc, GetModuleHandle(NULL), NULL);
return (hook != nullptr);
}
void KeyboardManagerEditor::OpenEditorWindow(KeyboardManagerEditorType type)
{
switch (type)
{
case KeyboardManagerEditorType::KeyEditor:
CreateEditKeyboardWindow(hInstance, keyboardManagerState);
break;
case KeyboardManagerEditorType::ShortcutEditor:
CreateEditShortcutsWindow(hInstance, keyboardManagerState);
}
}
intptr_t KeyboardManagerEditor::HandleKeyboardHookEvent(LowlevelKeyboardEvent* data) noexcept
{
// If the Detect Key Window is currently activated, then suppress the keyboard event
KeyboardManagerHelper::KeyboardHookDecision singleKeyRemapUIDetected = keyboardManagerState.DetectSingleRemapKeyUIBackend(data);
if (singleKeyRemapUIDetected == KeyboardManagerHelper::KeyboardHookDecision::Suppress)
{
return 1;
}
else if (singleKeyRemapUIDetected == KeyboardManagerHelper::KeyboardHookDecision::SkipHook)
{
return 0;
}
// If the Detect Shortcut Window from Remap Keys is currently activated, then suppress the keyboard event
KeyboardManagerHelper::KeyboardHookDecision remapKeyShortcutUIDetected = keyboardManagerState.DetectShortcutUIBackend(data, true);
if (remapKeyShortcutUIDetected == KeyboardManagerHelper::KeyboardHookDecision::Suppress)
{
return 1;
}
else if (remapKeyShortcutUIDetected == KeyboardManagerHelper::KeyboardHookDecision::SkipHook)
{
return 0;
}
// If the Detect Shortcut Window is currently activated, then suppress the keyboard event
KeyboardManagerHelper::KeyboardHookDecision shortcutUIDetected = keyboardManagerState.DetectShortcutUIBackend(data, false);
if (shortcutUIDetected == KeyboardManagerHelper::KeyboardHookDecision::Suppress)
{
return 1;
}
else if (shortcutUIDetected == KeyboardManagerHelper::KeyboardHookDecision::SkipHook)
{
return 0;
}
return 0;
}
// Hook procedure definition
LRESULT KeyboardManagerEditor::KeyHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
LowlevelKeyboardEvent event;
if (nCode == HC_ACTION)
{
event.lParam = reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam);
event.wParam = wParam;
if (editor->HandleKeyboardHookEvent(&event) == 1)
{
// Reset Num Lock whenever a NumLock key down event is suppressed since Num Lock key state change occurs before it is intercepted by low level hooks
if (event.lParam->vkCode == VK_NUMLOCK && (event.wParam == WM_KEYDOWN || event.wParam == WM_SYSKEYDOWN) && event.lParam->dwExtraInfo != KeyboardManagerConstants::KEYBOARDMANAGER_SUPPRESS_FLAG)
{
KeyboardEventHandlers::SetNumLockToPreviousState(editor->GetInputHandler());
}
return 1;
}
}
return CallNextHookEx(hook, nCode, wParam, lParam);
}

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
</windowsSettings>
</application>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Required for C++ XAML Islands. More details at https://docs.microsoft.com/en-us/windows/apps/desktop/modernize/host-standard-control-with-xaml-islands-cpp#create-a-desktop-application-project -->
<maxversiontested Id="10.0.18362.0"/>
</application>
</compatibility>
</assembly>

View File

@@ -0,0 +1,39 @@
#pragma once
#include <KeyboardManagerState.h>
#include <Input.h>
enum class KeyboardManagerEditorType
{
KeyEditor = 0,
ShortcutEditor,
};
class KeyboardManagerEditor
{
public:
KeyboardManagerEditor(HINSTANCE hInstance);
~KeyboardManagerEditor();
KeyboardManagerInput::Input& GetInputHandler() noexcept
{
return inputHandler;
}
bool StartLowLevelKeyboardHook();
void OpenEditorWindow(KeyboardManagerEditorType type);
// Function called by the hook procedure to handle the events. This is the starting point function for remapping
intptr_t HandleKeyboardHookEvent(LowlevelKeyboardEvent* data) noexcept;
private:
static LRESULT CALLBACK KeyHookProc(int nCode, WPARAM wParam, LPARAM lParam);
inline static HHOOK hook;
HINSTANCE hInstance;
KeyboardManagerState keyboardManagerState;
// Object of class which implements InputInterface. Required for calling library functions while enabling testing
KeyboardManagerInput::Input inputHandler;
};

View File

@@ -0,0 +1,192 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" />
<!-- Project configurations -->
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<!-- Props that should be disabled while building on CI server -->
<ItemDefinitionGroup Condition="'$(CIBuild)'!='true'">
<ClCompile>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<PrecompiledHeader>Use</PrecompiledHeader>
</ClCompile>
</ItemDefinitionGroup>
<!-- C++ source compile-specific things for all configurations -->
<ItemDefinitionGroup>
<ClCompile>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<WarningLevel>Level3</WarningLevel>
<ConformanceMode>false</ConformanceMode>
<TreatWarningAsError>true</TreatWarningAsError>
<LanguageStandard>stdcpplatest</LanguageStandard>
<AdditionalOptions>/await %(AdditionalOptions)</AdditionalOptions>
<PreprocessorDefinitions>_UNICODE;UNICODE;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
</Link>
<Lib>
<TreatLibWarningAsErrors>true</TreatLibWarningAsErrors>
</Lib>
</ItemDefinitionGroup>
<!-- C++ source compile-specific things for Debug/Release configurations -->
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Optimization>MaxSpeed</Optimization>
<SDLCheck>false</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<!-- Global props -->
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{8df78b53-200e-451f-9328-01eb907193ae}</ProjectGuid>
<RootNamespace>KeyboardManagerEditor</RootNamespace>
<OverrideWindowsTargetPlatformVersion>true</OverrideWindowsTargetPlatformVersion>
<TargetPlatformVersion>10.0.18362.0</TargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<!-- Props that are constant for both Debug and Release configurations -->
<PropertyGroup Label="Configuration">
<PlatformToolset>v142</PlatformToolset>
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)\obj\$(ProjectName)\</IntDir>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\modules\KeyboardManager\$(MSBuildProjectName)\</OutDir>
<CharacterSet>Unicode</CharacterSet>
<SpectreMitigation>Spectre</SpectreMitigation>
<ConfigurationType>Application</ConfigurationType>
<TargetName>PowerToys.$(MSBuildProjectName)</TargetName>
</PropertyGroup>
<!-- Debug/Release props -->
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<AdditionalIncludeDirectories>./;$(SolutionDir)src\modules\;$(SolutionDir)src\modules\KeyboardManager\KeyboardManagerEditorLibrary\;$(SolutionDir)src\common\Display;$(SolutionDir)src\common\inc;$(SolutionDir)src\common\Telemetry;$(SolutionDir)src;./../common;./../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>Display.lib;shcore.lib;Dbghelp.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)$(Platform)\$(ConfigurationName);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<AdditionalIncludeDirectories>./;$(SolutionDir)src\modules\;$(SolutionDir)src\modules\KeyboardManager\KeyboardManagerEditorLibrary\;$(SolutionDir)src\common\Display;$(SolutionDir)src\common\inc;$(SolutionDir)src\common\Telemetry;$(SolutionDir)src;./../common;./../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>Display.lib;shcore.lib;Dbghelp.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)$(Platform)\$(ConfigurationName);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="Generated Files\resource.h" />
<ClInclude Include="KeyboardManagerEditor.h" />
<ClInclude Include="pch.h" />
<None Include="resource.base.h" />
<ClInclude Include="targetver.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="KeyboardManagerEditor.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Generated Files\KeyboardManagerEditor.rc" />
<None Include="KeyboardManagerEditor.base.rc" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\common\Display\Display.vcxproj">
<Project>{caba8dfb-823b-4bf2-93ac-3f31984150d9}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\common\logger\logger.vcxproj">
<Project>{d9b8fc84-322a-4f9f-bbb9-20915c47ddfd}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\common\Themes\Themes.vcxproj">
<Project>{98537082-0fdb-40de-abd8-0dc5a4269bab}</Project>
</ProjectReference>
<ProjectReference Include="..\common\KeyboardManagerCommon.vcxproj">
<Project>{8affa899-0b73-49ec-8c50-0fadda57b2fc}</Project>
</ProjectReference>
<ProjectReference Include="..\KeyboardManagerEditorLibrary\KeyboardManagerEditorLibrary.vcxproj">
<Project>{23d2070d-e4ad-4add-85a7-083d9c76ad49}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Manifest Include="KeyboardManagerEditor.exe.manifest" />
</ItemGroup>
<ItemGroup>
<None Include="Resources.resx" />
</ItemGroup>
<ItemGroup>
<Image Include="Keyboard.ico" />
</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')" />
</ImportGroup>
<Import Project="..\..\..\..\deps\spdlog.props" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props'))" />
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets'))" />
</Target>
<Target Name="GenerateResourceFiles" BeforeTargets="PrepareForBuild">
<Exec Command="powershell -NonInteractive -executionpolicy Unrestricted $(SolutionDir)tools\build\convert-resx-to-rc.ps1 $(MSBuildThisFileDirectory) resource.base.h resource.h KeyboardManagerEditor.base.rc KeyboardManagerEditor.rc" />
</Target>
</Project>

View File

@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="GeneratedFiles">
<UniqueIdentifier>{904807de-a4f6-4c65-9399-a9c244580ca4}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="targetver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="KeyboardManagerEditor.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="pch.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Generated Files\resource.h">
<Filter>GeneratedFiles</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="KeyboardManagerEditor.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="pch.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Generated Files\KeyboardManagerEditor.rc">
<Filter>GeneratedFiles</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<None Include="Resources.resx">
<Filter>Resource Files</Filter>
</None>
<None Include="resource.base.h">
<Filter>Header Files</Filter>
</None>
<None Include="KeyboardManagerEditor.base.rc">
<Filter>Resource Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<Manifest Include="KeyboardManagerEditor.exe.manifest" />
</ItemGroup>
<ItemGroup>
<Image Include="Keyboard.ico">
<Filter>Resource Files</Filter>
</Image>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,14 @@
{
"Projects": [
{
"LanguageSet": "Azure_Languages",
"LocItems": [
{
"SourceFile": "src\\modules\\keyboardmanager\\KeyboardManagerEditor\\Resources.resx",
"CopyOption": "LangIDOnName",
"OutputPath": "src\\modules\\keyboardmanager\\KeyboardManagerEditor"
}
]
}
]
}

View File

@@ -0,0 +1,24 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by KeyboardManagerEditor.base.rc
//
#define IDC_MYICON 2
#define IDD_KEYBOARDMANAGEREDITOR_DIALOG 102
#define IDS_APP_TITLE 103
#define IDM_ABOUT 104
#define IDM_EXIT 105
#define IDC_KEYBOARDMANAGEREDITOR 109
#define IDR_MAINFRAME 128
#define IDC_STATIC -1
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NO_MFC 1
#define _APS_NEXT_RESOURCE_VALUE 129
#define _APS_NEXT_COMMAND_VALUE 32771
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 110
#endif
#endif

View File

@@ -0,0 +1,367 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Settings_Description" xml:space="preserve">
<value>This feature requires Windows 10 version 1903 or higher</value>
</data>
<data name="KeyboardManager" xml:space="preserve">
<value>Keyboard Manager</value>
</data>
<data name="CreateWindowFailed_ErrorMessage" xml:space="preserve">
<value>Call to CreateWindow failed!</value>
</data>
<data name="CreateWindowFailed_ErrorTitle" xml:space="preserve">
<value>Error</value>
</data>
<data name="RegisterClassFailed_ErrorMessage" xml:space="preserve">
<value>Windows registration failed!</value>
<comment>This refers to an application window</comment>
</data>
<data name="RegisterClassFailed_ErrorTitle" xml:space="preserve">
<value>Error</value>
</data>
<data name="EditKeyboard_WindowName" xml:space="preserve">
<value>Remap keys</value>
</data>
<data name="EditShortcuts_WindowName" xml:space="preserve">
<value>Remap shortcuts</value>
</data>
<data name="Ok_Button" xml:space="preserve">
<value>OK</value>
</data>
<data name="Cancel_Button" xml:space="preserve">
<value>Cancel</value>
</data>
<data name="Continue_Button" xml:space="preserve">
<value>Continue Anyway</value>
</data>
<data name="EditKeyboard_SourceHeader" xml:space="preserve">
<value>Key:</value>
<comment>Key on a keyboard</comment>
</data>
<data name="EditKeyboard_TargetHeader" xml:space="preserve">
<value>Mapped To:</value>
</data>
<data name="EditShortcuts_SourceHeader" xml:space="preserve">
<value>Shortcut:</value>
</data>
<data name="EditShortcuts_TargetHeader" xml:space="preserve">
<value>Mapped To:</value>
</data>
<data name="EditShortcuts_TargetAppHeader" xml:space="preserve">
<value>Target App:</value>
</data>
<data name="EditKeyboard_OrphanedDialogTitle" xml:space="preserve">
<value>The following keys have been reassigned and you won't be able to use them for their original assignment:</value>
</data>
<data name="EditKeyboard_PartialConfirmationDialogTitle" xml:space="preserve">
<value>Some of the keys could not be remapped. Do you want to continue anyway?</value>
</data>
<data name="EditShortcuts_PartialConfirmationDialogTitle" xml:space="preserve">
<value>Some of the shortcuts could not be remapped. Do you want to continue anyway?</value>
</data>
<data name="EditKeyboard_Info" xml:space="preserve">
<value>Select the key you want to change (Key) and then the key or shortcut you want it to become (Mapped To).</value>
</data>
<data name="EditKeyboard_InfoExample" xml:space="preserve">
<value>For example, if you want to press A and get "Ctrl+C", key "A" would be your "Key" column and the shortcut "Ctrl+C" would be your "Mapped To" column.</value>
</data>
<data name="EditShortcuts_Info" xml:space="preserve">
<value>Select the shortcut you want to change (Shortcut) and then the key or shortcut you want it to invoke (Mapped To).</value>
</data>
<data name="EditShortcuts_InfoExample" xml:space="preserve">
<value>For example, if you want to press "Ctrl+C" and get "Alt" only on Microsoft Edge, "Ctrl+C" would be your "Shortcut" column, the key "Alt" would be your "Mapped To" column, and "MSEdge" would be your "Target App" column. If no target app is entered, it will apply globally. The name must be the process name and not the app name.</value>
</data>
<data name="ErrorMessage_RemapSuccessful" xml:space="preserve">
<value>Remapping successful</value>
</data>
<data name="ErrorMessage_RemapUnsuccessful" xml:space="preserve">
<value>Some remappings were not applied</value>
</data>
<data name="ErrorMessage_SameKeyPreviouslyMapped" xml:space="preserve">
<value>Cannot remap a key more than once</value>
<comment>Key on a keyboard</comment>
</data>
<data name="ErrorMessage_MappedToSameKey" xml:space="preserve">
<value>Cannot remap a key to itself</value>
<comment>Key on a keyboard</comment>
</data>
<data name="ErrorMessage_ConflictingModifierKey" xml:space="preserve">
<value>Cannot remap this key as it conflicts with another remapped key</value>
<comment>Key on a keyboard</comment>
</data>
<data name="ErrorMessage_SameShortcutPreviouslyMapped" xml:space="preserve">
<value>Cannot remap a shortcut more than once for the same target app</value>
</data>
<data name="ErrorMessage_MapToSameShortcut" xml:space="preserve">
<value>Cannot remap a shortcut to itself</value>
</data>
<data name="ErrorMessage_ConflictingModifierShortcut" xml:space="preserve">
<value>Cannot remap this shortcut as it conflicts with another remapped shortcut</value>
</data>
<data name="ErrorMessage_WinL" xml:space="preserve">
<value>Cannot remap from/to Win L</value>
<comment>Win refers to Windows as in the OS</comment>
</data>
<data name="ErrorMessage_CtrlAltDel" xml:space="preserve">
<value>Cannot remap from/to Ctrl Alt Del</value>
</data>
<data name="ErrorMessage_SaveFailed" xml:space="preserve">
<value>Failed to save the remappings</value>
</data>
<data name="ErrorMessage_ShortcutStartWithModifier" xml:space="preserve">
<value>Shortcut must start with a modifier key</value>
<comment>Key on a keyboard</comment>
</data>
<data name="ErrorMessage_ShortcutNoRepeatedModifier" xml:space="preserve">
<value>Shortcut cannot contain a repeated modifier</value>
</data>
<data name="ErrorMessage_ShortcutAtleast2Keys" xml:space="preserve">
<value>Shortcut must have atleast 2 keys</value>
<comment>Key on a keyboard</comment>
</data>
<data name="ErrorMessage_ShortcutOneActionKey" xml:space="preserve">
<value>Shortcut must contain an action key</value>
<comment>Key on a keyboard</comment>
</data>
<data name="ErrorMessage_ShortcutMaxOneActionKey" xml:space="preserve">
<value>Shortcut cannot have more than one action key</value>
<comment>Key on a keyboard</comment>
</data>
<data name="ErrorMessage_MaxShortcutSize" xml:space="preserve">
<value>Shortcuts can only have up to 2 modifier keys</value>
<comment>Key on a keyboard</comment>
</data>
<data name="ErrorMessage_Default" xml:space="preserve">
<value>Unexpected error</value>
</data>
<data name="Type_Button" xml:space="preserve">
<value>Type</value>
<comment>As in type a key</comment>
</data>
<data name="TypeKey_Title" xml:space="preserve">
<value>Press a key on selected keyboard:</value>
<comment>Key on a keyboard</comment>
</data>
<data name="TypeShortcut_Title" xml:space="preserve">
<value>Press the keys in shortcut:</value>
<comment>Key on a keyboard</comment>
</data>
<data name="TypeKey_Header" xml:space="preserve">
<value>Key Pressed:</value>
<comment>Key on a keyboard</comment>
</data>
<data name="TypeShortcut_Header" xml:space="preserve">
<value>Keys Pressed:</value>
<comment>Key on a keyboard</comment>
</data>
<data name="Type_HoldEnter" xml:space="preserve">
<value>Hold Enter to continue</value>
</data>
<data name="Type_HoldEsc" xml:space="preserve">
<value>Hold Esc to discard</value>
</data>
<data name="EditShortcuts_AllApps" xml:space="preserve">
<value>All Apps</value>
</data>
<data name="ErrorMessage_RemapSuccessful" xml:space="preserve">
<value>Remapping successful</value>
</data>
<data name="ErrorMessage_RemapUnsuccessful" xml:space="preserve">
<value>Some remappings were not applied</value>
</data>
<data name="ErrorMessage_SameKeyPreviouslyMapped" xml:space="preserve">
<value>Cannot remap a key more than once</value>
<comment>Key on a keyboard</comment>
</data>
<data name="ErrorMessage_MappedToSameKey" xml:space="preserve">
<value>Cannot remap a key to itself</value>
<comment>Key on a keyboard</comment>
</data>
<data name="ErrorMessage_ConflictingModifierKey" xml:space="preserve">
<value>Cannot remap this key as it conflicts with another remapped key</value>
<comment>Key on a keyboard</comment>
</data>
<data name="ErrorMessage_SameShortcutPreviouslyMapped" xml:space="preserve">
<value>Cannot remap a shortcut more than once for the same target app</value>
</data>
<data name="ErrorMessage_MapToSameShortcut" xml:space="preserve">
<value>Cannot remap a shortcut to itself</value>
</data>
<data name="ErrorMessage_ConflictingModifierShortcut" xml:space="preserve">
<value>Cannot remap this shortcut as it conflicts with another remapped shortcut</value>
</data>
<data name="ErrorMessage_WinL" xml:space="preserve">
<value>Cannot remap from/to Win L</value>
<comment>Win refers to Windows as in the OS</comment>
</data>
<data name="ErrorMessage_CtrlAltDel" xml:space="preserve">
<value>Cannot remap from/to Ctrl Alt Del</value>
</data>
<data name="ErrorMessage_SaveFailed" xml:space="preserve">
<value>Failed to save the remappings</value>
</data>
<data name="ErrorMessage_ShortcutStartWithModifier" xml:space="preserve">
<value>Shortcut must start with a modifier key</value>
<comment>Key on a keyboard</comment>
</data>
<data name="ErrorMessage_ShortcutNoRepeatedModifier" xml:space="preserve">
<value>Shortcut cannot contain a repeated modifier</value>
</data>
<data name="ErrorMessage_ShortcutAtleast2Keys" xml:space="preserve">
<value>Shortcut must have atleast 2 keys</value>
<comment>Key on a keyboard</comment>
</data>
<data name="ErrorMessage_ShortcutOneActionKey" xml:space="preserve">
<value>Shortcut must contain an action key</value>
<comment>Key on a keyboard</comment>
</data>
<data name="ErrorMessage_ShortcutMaxOneActionKey" xml:space="preserve">
<value>Shortcut cannot have more than one action key</value>
<comment>Key on a keyboard</comment>
</data>
<data name="ErrorMessage_MaxShortcutSize" xml:space="preserve">
<value>Shortcuts can only have up to 2 modifier keys</value>
<comment>Key on a keyboard</comment>
</data>
<data name="ErrorMessage_Default" xml:space="preserve">
<value>Unexpected error</value>
</data>
<data name="Key_DropDown_Combobox" xml:space="preserve">
<value>Key</value>
<comment>Key on a keyboard</comment>
</data>
<data name="Add_Key_Remap_Button" xml:space="preserve">
<value>Add Key Remap</value>
<comment>Key on a keyboard</comment>
</data>
<data name="Add_Shortcut_Button" xml:space="preserve">
<value>Add Shortcut Remapping</value>
</data>
<data name="Delete_Remapping_Button" xml:space="preserve">
<value>Delete Remapping</value>
</data>
<data name="AutomationProperties_Row" xml:space="preserve">
<value>Row </value>
</data>
<data name="ERRORMESSAGE_DISABLEASACTIONKEY" xml:space="preserve">
<value>Disable can not be an action or a modifier key</value>
<comment>Key on a keyboard</comment>
</data>
</root>

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