mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-31 09:27:03 +01:00
Compare commits
61 Commits
yuleng/cmd
...
user/yeela
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
60a0c9134d | ||
|
|
232e1b79bd | ||
|
|
4979d39489 | ||
|
|
8bf342cc46 | ||
|
|
5ec2728dea | ||
|
|
d314fa075e | ||
|
|
90723d5b12 | ||
|
|
f2a5505601 | ||
|
|
311ab88ec3 | ||
|
|
c04400e7df | ||
|
|
05218e8af6 | ||
|
|
6cf73ce839 | ||
|
|
4f9e829155 | ||
|
|
397d5cf655 | ||
|
|
01584f33e1 | ||
|
|
67463abf98 | ||
|
|
e95a570d48 | ||
|
|
cb27874805 | ||
|
|
f65a3fc06f | ||
|
|
c7789abf04 | ||
|
|
e700f86ace | ||
|
|
a16f784011 | ||
|
|
4e0db267dc | ||
|
|
0e98cbd57e | ||
|
|
f15bed5323 | ||
|
|
d3c4e808d0 | ||
|
|
2b5181b4c9 | ||
|
|
60f50d853b | ||
|
|
f1bda8d71f | ||
|
|
21aa49cefb | ||
|
|
293fa262bb | ||
|
|
578d99f3b3 | ||
|
|
badb029bcf | ||
|
|
bec6754aa3 | ||
|
|
d986592737 | ||
|
|
662f04ed34 | ||
|
|
03bc72c436 | ||
|
|
5c8aa67781 | ||
|
|
b32c04fca1 | ||
|
|
4cb72ee126 | ||
|
|
55f8f3a53e | ||
|
|
a7994402fe | ||
|
|
41472a483c | ||
|
|
94e8559796 | ||
|
|
fe53a9c89a | ||
|
|
a708a3afaa | ||
|
|
b7f99e88ef | ||
|
|
6f43aac26a | ||
|
|
d7e826d2ac | ||
|
|
9e8754a592 | ||
|
|
49687251d3 | ||
|
|
f72ccd12fd | ||
|
|
4b44858a48 | ||
|
|
53ae118e72 | ||
|
|
31df702704 | ||
|
|
ea2542b235 | ||
|
|
c6776d0d45 | ||
|
|
d48286a3eb | ||
|
|
7a5b25cd3e | ||
|
|
1eccbc3021 | ||
|
|
ce620e427f |
@@ -6,12 +6,16 @@ properties:
|
||||
directives:
|
||||
description: Enable Developer Mode
|
||||
allowPrerelease: true
|
||||
# Requires elevation for the set operation
|
||||
securityContext: elevated
|
||||
settings:
|
||||
Ensure: Present
|
||||
- resource: Microsoft.WinGet.DSC/WinGetPackage
|
||||
id: vsPackage
|
||||
directives:
|
||||
description: Install Visual Studio 2022 Enterprise (Any edition will work)
|
||||
# Requires elevation for the set operation
|
||||
securityContext: elevated
|
||||
settings:
|
||||
id: Microsoft.VisualStudio.2022.Enterprise
|
||||
source: winget
|
||||
@@ -21,6 +25,8 @@ properties:
|
||||
directives:
|
||||
description: Install required VS workloads
|
||||
allowPrerelease: true
|
||||
# Requires elevation for the get and set operations
|
||||
securityContext: elevated
|
||||
settings:
|
||||
productId: Microsoft.VisualStudio.Product.Enterprise
|
||||
channelId: VisualStudio.17.Release
|
||||
|
||||
@@ -6,12 +6,16 @@ properties:
|
||||
directives:
|
||||
description: Enable Developer Mode
|
||||
allowPrerelease: true
|
||||
# Requires elevation for the set operation
|
||||
securityContext: elevated
|
||||
settings:
|
||||
Ensure: Present
|
||||
- resource: Microsoft.WinGet.DSC/WinGetPackage
|
||||
id: vsPackage
|
||||
directives:
|
||||
description: Install Visual Studio 2022 Professional (Any edition will work)
|
||||
# Requires elevation for the set operation
|
||||
securityContext: elevated
|
||||
settings:
|
||||
id: Microsoft.VisualStudio.2022.Professional
|
||||
source: winget
|
||||
@@ -21,6 +25,8 @@ properties:
|
||||
directives:
|
||||
description: Install required VS workloads
|
||||
allowPrerelease: true
|
||||
# Requires elevation for the get and set operations
|
||||
securityContext: elevated
|
||||
settings:
|
||||
productId: Microsoft.VisualStudio.Product.Professional
|
||||
channelId: VisualStudio.17.Release
|
||||
|
||||
@@ -6,12 +6,16 @@ properties:
|
||||
directives:
|
||||
description: Enable Developer Mode
|
||||
allowPrerelease: true
|
||||
# Requires elevation for the set operation
|
||||
securityContext: elevated
|
||||
settings:
|
||||
Ensure: Present
|
||||
- resource: Microsoft.WinGet.DSC/WinGetPackage
|
||||
id: vsPackage
|
||||
directives:
|
||||
description: Install Visual Studio 2022 Community (Any edition will work)
|
||||
# Requires elevation for the set operation
|
||||
securityContext: elevated
|
||||
settings:
|
||||
id: Microsoft.VisualStudio.2022.Community
|
||||
source: winget
|
||||
@@ -21,6 +25,8 @@ properties:
|
||||
directives:
|
||||
description: Install required VS workloads
|
||||
allowPrerelease: true
|
||||
# Requires elevation for the get and set operations
|
||||
securityContext: elevated
|
||||
settings:
|
||||
productId: Microsoft.VisualStudio.Product.Community
|
||||
channelId: VisualStudio.17.Release
|
||||
|
||||
33
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
33
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -1,6 +1,5 @@
|
||||
name: "🕷️ Bug report"
|
||||
description: Report errors or unexpected behavior
|
||||
type: Bug
|
||||
labels:
|
||||
- Issue-Bug
|
||||
- Needs-Triage
|
||||
@@ -8,15 +7,17 @@ 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
|
||||
- id: version
|
||||
type: input
|
||||
attributes:
|
||||
label: Microsoft PowerToys version
|
||||
placeholder: 0.70.0
|
||||
placeholder: X.XX.X
|
||||
description: Hover over system tray icon or look at Settings
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
- id: installed
|
||||
type: dropdown
|
||||
attributes:
|
||||
label: Installation method
|
||||
description: How / Where was PowerToys installed from?
|
||||
@@ -33,14 +34,6 @@ body:
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Running as admin
|
||||
description: Are you running PowerToys as Admin?
|
||||
options:
|
||||
- "Yes"
|
||||
- "No"
|
||||
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Area(s) with issue?
|
||||
@@ -67,7 +60,7 @@ body:
|
||||
- Keyboard Manager
|
||||
- Mouse Utilities
|
||||
- Mouse Without Borders
|
||||
- New+
|
||||
- New+
|
||||
- Peek
|
||||
- PowerRename
|
||||
- PowerToys Run
|
||||
@@ -106,6 +99,19 @@ body:
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- id: additionalInfo
|
||||
type: textarea
|
||||
attributes:
|
||||
label: Additional Information
|
||||
placeholder: |
|
||||
OS version
|
||||
.Net version
|
||||
System Language
|
||||
User or System Installation
|
||||
Running as admin
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Other Software
|
||||
@@ -116,3 +122,4 @@ body:
|
||||
My Cool Application v0.3 (include a code snippet if it would help!)
|
||||
validations:
|
||||
required: false
|
||||
|
||||
|
||||
3
.github/actions/spell-check/allow/names.txt
vendored
3
.github/actions/spell-check/allow/names.txt
vendored
@@ -110,6 +110,7 @@ Lambson
|
||||
Laute
|
||||
laviusmotileng
|
||||
Leilei
|
||||
Loewen
|
||||
Luecking
|
||||
Mahalingam
|
||||
Markovic
|
||||
@@ -187,6 +188,8 @@ zhaoqpcn
|
||||
Zoltan
|
||||
Zykova
|
||||
Sameerjs
|
||||
ruslanlap
|
||||
vednig
|
||||
|
||||
# OTHERS
|
||||
|
||||
|
||||
71
.github/actions/spell-check/expect.txt
vendored
71
.github/actions/spell-check/expect.txt
vendored
@@ -15,6 +15,7 @@ ACTIVATEAPP
|
||||
activationaction
|
||||
ACVS
|
||||
adaptivecards
|
||||
ADate
|
||||
ADDSTRING
|
||||
ADDUNDORECORD
|
||||
ADifferent
|
||||
@@ -55,12 +56,10 @@ APIIs
|
||||
Apm
|
||||
APPBARDATA
|
||||
APPEXECLINK
|
||||
APPICONREFERENCE
|
||||
APPLICATIONFRAMEHOST
|
||||
appmanifest
|
||||
APPMODEL
|
||||
APPNAME
|
||||
APPPUBLISHER
|
||||
appref
|
||||
appsettings
|
||||
appwindow
|
||||
@@ -172,9 +171,9 @@ CCHFORMNAME
|
||||
CCom
|
||||
CContext
|
||||
CDeclaration
|
||||
cdn
|
||||
CElems
|
||||
CENTERALIGN
|
||||
cer
|
||||
certlm
|
||||
certmgr
|
||||
cfp
|
||||
@@ -199,8 +198,7 @@ CLIPCHILDREN
|
||||
CLIPSIBLINGS
|
||||
closesocket
|
||||
CLSCTX
|
||||
CLSIDs
|
||||
Clsids
|
||||
clsids
|
||||
Clusion
|
||||
cmder
|
||||
CMDNOTFOUNDMODULEINTERFACE
|
||||
@@ -254,8 +252,6 @@ createdump
|
||||
CREATEPROCESS
|
||||
CREATESCHEDULEDTASK
|
||||
CREATESTRUCT
|
||||
CREATETHREAD
|
||||
CREATEWINDOW
|
||||
CREATEWINDOWFAILED
|
||||
CRECT
|
||||
CRH
|
||||
@@ -277,6 +273,7 @@ CURSORINFO
|
||||
cursorpos
|
||||
customaction
|
||||
CUSTOMACTIONTEST
|
||||
CUSTOMFORMATPLACEHOLDER
|
||||
CVal
|
||||
cvd
|
||||
CVirtual
|
||||
@@ -308,11 +305,7 @@ DCOM
|
||||
DComposition
|
||||
DCR
|
||||
ddd
|
||||
DDEAPPLICATION
|
||||
DDECOMMAND
|
||||
DDEIf
|
||||
DDEIFEXEC
|
||||
DDETOPIC
|
||||
DDevice
|
||||
DDxgi
|
||||
Deact
|
||||
@@ -326,16 +319,13 @@ DEFAULTFLAGS
|
||||
DEFAULTICON
|
||||
defaultlib
|
||||
DEFAULTONLY
|
||||
DEFAULTTOFOLDER
|
||||
DEFAULTTONEAREST
|
||||
DEFAULTTONULL
|
||||
DEFAULTTOPRIMARY
|
||||
DEFAULTTOSTAR
|
||||
DEFERERASE
|
||||
DEFPUSHBUTTON
|
||||
deinitialization
|
||||
DELA
|
||||
DELEGATEEXECUTE
|
||||
DELETEDKEYIMAGE
|
||||
DELETESCANS
|
||||
deletethis
|
||||
@@ -355,6 +345,7 @@ DEVMODE
|
||||
DEVMODEW
|
||||
devpal
|
||||
DIALOGEX
|
||||
digicert
|
||||
dimm
|
||||
DISABLEASACTIONKEY
|
||||
DISABLENOSCROLL
|
||||
@@ -389,7 +380,6 @@ dreamsofameaningfullife
|
||||
drivedetectionwarning
|
||||
Droid
|
||||
DROPFILES
|
||||
DROPTARGET
|
||||
DSTINVERT
|
||||
DSurface
|
||||
DTexture
|
||||
@@ -417,6 +407,7 @@ DWORDLONG
|
||||
dworigin
|
||||
dwrite
|
||||
dxgi
|
||||
eab
|
||||
easeofaccess
|
||||
ecount
|
||||
Edid
|
||||
@@ -466,6 +457,7 @@ EXAND
|
||||
EXCLUDEFROMCAPTURE
|
||||
executionpolicy
|
||||
exename
|
||||
exf
|
||||
EXITSIZEMOVE
|
||||
exlist
|
||||
EXPCMDFLAGS
|
||||
@@ -508,12 +500,10 @@ Fira
|
||||
FIXEDFILEINFO
|
||||
FIXEDSYS
|
||||
flac
|
||||
flaticon
|
||||
flyouts
|
||||
FMask
|
||||
fmtid
|
||||
FOF
|
||||
WANTNUKEWARNING
|
||||
FOFX
|
||||
FOLDERID
|
||||
folderpath
|
||||
@@ -523,7 +513,6 @@ FORCEMINIMIZE
|
||||
FORMATDLGORD
|
||||
formatetc
|
||||
FORPARSING
|
||||
fpvm
|
||||
Fqc
|
||||
FRAMECHANGED
|
||||
frm
|
||||
@@ -557,7 +546,6 @@ GETSECKEY
|
||||
GETSTICKYKEYS
|
||||
GETTEXTLENGTH
|
||||
GHND
|
||||
gifv
|
||||
GMEM
|
||||
GNumber
|
||||
gpedit
|
||||
@@ -651,7 +639,6 @@ HROW
|
||||
hsb
|
||||
HSCROLL
|
||||
hsi
|
||||
HSSH
|
||||
HTCLIENT
|
||||
hthumbnail
|
||||
HTOUCHINPUT
|
||||
@@ -689,12 +676,12 @@ iextn
|
||||
IFACEMETHOD
|
||||
IFACEMETHODIMP
|
||||
IFile
|
||||
IGNOREBASECLASS
|
||||
IGNOREUNKNOWN
|
||||
IGo
|
||||
iid
|
||||
Iindex
|
||||
Ijwhost
|
||||
ILD
|
||||
IMAGEHLP
|
||||
IMAGERESIZERCONTEXTMENU
|
||||
IMAGERESIZEREXT
|
||||
@@ -738,8 +725,6 @@ Inste
|
||||
Interlop
|
||||
INTRESOURCE
|
||||
INVALIDARG
|
||||
INVALIDCALL
|
||||
INVALIDINDEX
|
||||
invalidoperatioexception
|
||||
ipcmanager
|
||||
IPREVIEW
|
||||
@@ -801,7 +786,6 @@ LEVELID
|
||||
LExit
|
||||
lhwnd
|
||||
LIBID
|
||||
libraryincludes
|
||||
LIMITSIZE
|
||||
LIMITTEXT
|
||||
lindex
|
||||
@@ -898,11 +882,11 @@ MARKDOWNPREVIEWHANDLERCPP
|
||||
MAXIMIZEBOX
|
||||
MAXSHORTCUTSIZE
|
||||
maxversiontested
|
||||
mber
|
||||
MBM
|
||||
MBR
|
||||
MDICHILD
|
||||
MDL
|
||||
mdpvm
|
||||
mdtext
|
||||
mdtxt
|
||||
mdwn
|
||||
@@ -958,6 +942,7 @@ mpmc
|
||||
MRM
|
||||
MRT
|
||||
mru
|
||||
MSAL
|
||||
msc
|
||||
mscorlib
|
||||
msctls
|
||||
@@ -1021,6 +1006,7 @@ netsh
|
||||
newcolor
|
||||
NEWDIALOGSTYLE
|
||||
NEWFILE
|
||||
NEWFILEHEADER
|
||||
newitem
|
||||
newpath
|
||||
newplus
|
||||
@@ -1050,7 +1036,6 @@ NOCRLF
|
||||
nodeca
|
||||
NODRAWCAPTION
|
||||
NODRAWICON
|
||||
NOFIXUPS
|
||||
NOINHERITLAYOUT
|
||||
NOINTERFACE
|
||||
NOINVERT
|
||||
@@ -1066,13 +1051,11 @@ NONELEVATED
|
||||
NONINFRINGEMENT
|
||||
nonspace
|
||||
nonstd
|
||||
NOOPEN
|
||||
NOOWNERZORDER
|
||||
NOPARENTNOTIFY
|
||||
NOPREFIX
|
||||
NOREDIRECTIONBITMAP
|
||||
NOREDRAW
|
||||
NOREMAPCLSID
|
||||
NOREMOVE
|
||||
norename
|
||||
NOREPEAT
|
||||
@@ -1091,11 +1074,9 @@ NOTIFYICONDATAW
|
||||
NOTIMPL
|
||||
NOTOPMOST
|
||||
NOTRACK
|
||||
NOTRUNCATE
|
||||
NOTSRCCOPY
|
||||
NOTSRCERASE
|
||||
NOTXORPEN
|
||||
NOUSERSETTINGS
|
||||
NOZORDER
|
||||
NPH
|
||||
npmjs
|
||||
@@ -1221,6 +1202,7 @@ Podcasts
|
||||
POINTERID
|
||||
POINTERUPDATE
|
||||
Pokedex
|
||||
Pomodoro
|
||||
Popups
|
||||
POPUPWINDOW
|
||||
POSITIONITEM
|
||||
@@ -1315,11 +1297,11 @@ Quarternary
|
||||
QUERYENDSESSION
|
||||
QUERYOPEN
|
||||
QUEUESYNC
|
||||
QUICKTIP
|
||||
QUNS
|
||||
QXZ
|
||||
RAII
|
||||
RAlt
|
||||
Rappl
|
||||
randi
|
||||
Rasterization
|
||||
Rasterize
|
||||
@@ -1344,7 +1326,6 @@ REFCLSID
|
||||
REFIID
|
||||
REGCLS
|
||||
regfile
|
||||
REGISTERCLASSEX
|
||||
REGISTERCLASSFAILED
|
||||
REGISTRYHEADER
|
||||
registrypath
|
||||
@@ -1356,7 +1337,6 @@ REINSTALLMODE
|
||||
reloadable
|
||||
Relogger
|
||||
remappings
|
||||
REMAPRUNDLL
|
||||
REMAPSUCCESSFUL
|
||||
REMAPUNSUCCESSFUL
|
||||
Remotable
|
||||
@@ -1433,7 +1413,6 @@ SDDL
|
||||
SDKDDK
|
||||
sdns
|
||||
searchterm
|
||||
searchtext
|
||||
SEARCHUI
|
||||
SECONDARYDISPLAY
|
||||
secpol
|
||||
@@ -1482,6 +1461,7 @@ shellex
|
||||
SHELLEXECUTEINFO
|
||||
SHELLEXECUTEINFOW
|
||||
SHELLEXTENSION
|
||||
SHELLICONSIZE
|
||||
SHELLNEWVALUE
|
||||
SHFILEINFO
|
||||
SHFILEOPSTRUCT
|
||||
@@ -1490,9 +1470,9 @@ SHGDNF
|
||||
SHGFI
|
||||
SHGFIICON
|
||||
SHGFILARGEICON
|
||||
SHIL
|
||||
shinfo
|
||||
shlwapi
|
||||
SHNAMEMAPPING
|
||||
shobjidl
|
||||
SHORTCUTATLEAST
|
||||
SHORTCUTMAXONEACTIONKEY
|
||||
@@ -1522,6 +1502,7 @@ SIDs
|
||||
siex
|
||||
sigdn
|
||||
SIGNINGSCENARIO
|
||||
signtool
|
||||
Signtool
|
||||
SINGLEKEY
|
||||
sipolicy
|
||||
@@ -1543,7 +1524,6 @@ SNAPPROCESS
|
||||
snwprintf
|
||||
softline
|
||||
SOURCECLIENTAREAONLY
|
||||
sourced
|
||||
sourcedoc
|
||||
SOURCEHEADER
|
||||
sourcesdirectory
|
||||
@@ -1670,6 +1650,7 @@ telephon
|
||||
templatenamespace
|
||||
testprocess
|
||||
TEXCOORD
|
||||
TEXTBOXNEWLINE
|
||||
TEXTEXTRACTOR
|
||||
TEXTINCLUDE
|
||||
tfopen
|
||||
@@ -1682,7 +1663,6 @@ THotkey
|
||||
throughs
|
||||
TIcon
|
||||
TILEDWINDOW
|
||||
TILEINFO
|
||||
TILLSON
|
||||
timedate
|
||||
timediff
|
||||
@@ -1696,9 +1676,6 @@ TLayout
|
||||
tlb
|
||||
tlbimp
|
||||
tlc
|
||||
TPMLEFTALIGN
|
||||
TPMRETURNCMD
|
||||
TMPVAR
|
||||
TNP
|
||||
Toolhelp
|
||||
toolkitconverters
|
||||
@@ -1706,6 +1683,8 @@ toolwindow
|
||||
TOPDOWNDIB
|
||||
TOUCHEVENTF
|
||||
TOUCHINPUT
|
||||
TPMLEFTALIGN
|
||||
TPMRETURNCMD
|
||||
TRACEHANDLE
|
||||
tracelogging
|
||||
tracerpt
|
||||
@@ -1779,6 +1758,7 @@ USRDLL
|
||||
UType
|
||||
uuidv
|
||||
uwp
|
||||
uxt
|
||||
uxtheme
|
||||
vabdq
|
||||
validmodulename
|
||||
@@ -1804,7 +1784,6 @@ VERTSIZE
|
||||
VFT
|
||||
vget
|
||||
vgetq
|
||||
videourl
|
||||
viewmodel
|
||||
VIRTKEY
|
||||
VIRTUALDESK
|
||||
@@ -1838,7 +1817,7 @@ vstprintf
|
||||
VSTT
|
||||
vswhere
|
||||
Vtbl
|
||||
WANTMAPPINGHANDLE
|
||||
WANTNUKEWARNING
|
||||
WANTPALM
|
||||
wasdk
|
||||
wbem
|
||||
@@ -1859,10 +1838,10 @@ webbrowsers
|
||||
webpage
|
||||
websites
|
||||
wekyb
|
||||
wft
|
||||
wgpocpl
|
||||
WHEREID
|
||||
Wholegrain
|
||||
WIC
|
||||
wic
|
||||
wifi
|
||||
wil
|
||||
@@ -1919,6 +1898,7 @@ WNDCLASSEXW
|
||||
WNDCLASSW
|
||||
WNDPROC
|
||||
wnode
|
||||
wom
|
||||
WORKSPACESEDITOR
|
||||
WORKSPACESLAUNCHER
|
||||
WORKSPACESSNAPSHOTTOOL
|
||||
@@ -1952,7 +1932,6 @@ WUX
|
||||
Wwanpp
|
||||
XAxis
|
||||
xclip
|
||||
xdoc
|
||||
XDocument
|
||||
XElement
|
||||
xfd
|
||||
@@ -1975,13 +1954,13 @@ Yeet
|
||||
YIncrement
|
||||
yinle
|
||||
yinyue
|
||||
youtube
|
||||
YPels
|
||||
YResolution
|
||||
YStr
|
||||
YTM
|
||||
YVIRTUALSCREEN
|
||||
ZEROINIT
|
||||
Zhiwei
|
||||
zonable
|
||||
zoneset
|
||||
Zoneszonabletester
|
||||
@@ -1990,4 +1969,4 @@ zoomit
|
||||
ZOOMITX
|
||||
ZXk
|
||||
ZXNs
|
||||
zzz
|
||||
zzz
|
||||
|
||||
26
.github/workflows/dependency-review.yml
vendored
Normal file
26
.github/workflows/dependency-review.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
# Dependency Review Action
|
||||
#
|
||||
# This Action will scan dependency manifest files that change as part of a Pull Request,
|
||||
# surfacing known-vulnerable versions of the packages declared or updated in the PR.
|
||||
# Once installed, if the workflow run is marked as required,
|
||||
# PRs introducing known-vulnerable packages will be blocked from merging.
|
||||
#
|
||||
# As recommended by Microsoft's security guidelines (https://docs.opensource.microsoft.com/security/tsg/actions/#requirements-for-security-hardening-your-own-github-actions),
|
||||
# 3rd-party actions should be pinned to a specific commit hash to prevent supply chain attacks.
|
||||
# This update aligns with best practices; 1st/2nd-party actions is not required hash pinning.
|
||||
#
|
||||
# Source repository: https://github.com/actions/dependency-review-action
|
||||
name: 'Dependency Review'
|
||||
on: [pull_request]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
dependency-review:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: 'Checkout Repository'
|
||||
uses: actions/checkout@v4
|
||||
- name: 'Dependency Review'
|
||||
uses: actions/dependency-review-action@v4
|
||||
2
.github/workflows/msstore-submissions.yml
vendored
2
.github/workflows/msstore-submissions.yml
vendored
@@ -40,7 +40,7 @@ jobs:
|
||||
echo powerToysInstallerArm64Url=$(jq -n "$powerToysSetup" | jq -r '[.[]|select(.name | contains("arm64"))][0].browser_download_url') >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Setup .NET 9.0
|
||||
uses: actions/setup-dotnet@v3
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: '9.0.x'
|
||||
|
||||
|
||||
8
.github/workflows/spelling2.yml
vendored
8
.github/workflows/spelling2.yml
vendored
@@ -93,7 +93,7 @@ jobs:
|
||||
steps:
|
||||
- name: check-spelling
|
||||
id: spelling
|
||||
uses: check-spelling/check-spelling@v0.0.24
|
||||
uses: check-spelling/check-spelling@67debf50669c7fc76fc8f5d7f996384535a72b77 # v0.0.24
|
||||
with:
|
||||
config: .github/actions/spell-check
|
||||
suppress_push_for_open_pull_request: ${{ github.actor != 'dependabot[bot]' && 1 }}
|
||||
@@ -156,7 +156,7 @@ jobs:
|
||||
if: (success() || failure()) && needs.spelling.outputs.followup && github.event_name == 'push'
|
||||
steps:
|
||||
- name: comment
|
||||
uses: check-spelling/check-spelling@v0.0.24
|
||||
uses: check-spelling/check-spelling@67debf50669c7fc76fc8f5d7f996384535a72b77 # v0.0.24
|
||||
with:
|
||||
config: .github/actions/spell-check
|
||||
checkout: true
|
||||
@@ -175,7 +175,7 @@ jobs:
|
||||
if: (success() || failure()) && needs.spelling.outputs.followup && contains(github.event_name, 'pull_request')
|
||||
steps:
|
||||
- name: comment
|
||||
uses: check-spelling/check-spelling@v0.0.24
|
||||
uses: check-spelling/check-spelling@67debf50669c7fc76fc8f5d7f996384535a72b77 # v0.0.24
|
||||
with:
|
||||
config: .github/actions/spell-check
|
||||
checkout: true
|
||||
@@ -202,7 +202,7 @@ jobs:
|
||||
cancel-in-progress: false
|
||||
steps:
|
||||
- name: apply spelling updates
|
||||
uses: check-spelling/check-spelling@v0.0.24
|
||||
uses: check-spelling/check-spelling@67debf50669c7fc76fc8f5d7f996384535a72b77 # v0.0.24
|
||||
with:
|
||||
experimental_apply_changes_via_bot: ${{ github.repository_owner != 'microsoft' && 1 }}
|
||||
checkout: true
|
||||
|
||||
@@ -220,6 +220,7 @@
|
||||
"WinUI3Apps\\PowerToys.Settings.exe",
|
||||
|
||||
"PowerToys.CmdPalModuleInterface.dll",
|
||||
"CmdPalKeyboardService.dll",
|
||||
"*Microsoft.CmdPal.UI_*.msix"
|
||||
],
|
||||
"SigningInfo": {
|
||||
@@ -330,6 +331,8 @@
|
||||
"TestableIO.System.IO.Abstractions.Wrappers.dll",
|
||||
"WinUI3Apps\\TestableIO.System.IO.Abstractions.Wrappers.dll",
|
||||
"WinUI3Apps\\OpenAI.dll",
|
||||
"Testably.Abstractions.FileSystem.Interface.dll",
|
||||
"WinUI3Apps\\Testably.Abstractions.FileSystem.Interface.dll",
|
||||
"ColorCode.Core.dll",
|
||||
"ColorCode.UWP.dll",
|
||||
"UnitsNet.dll",
|
||||
|
||||
@@ -148,5 +148,7 @@ extends:
|
||||
parameters:
|
||||
versionNumber: ${{ parameters.versionNumber }}
|
||||
includePublicSymbolServer: ${{ parameters.publishSymbolsToPublic }}
|
||||
${{ if ne(parameters.publishSymbolsToPublic, true) }}:
|
||||
symbolExpiryTime: 10 # For private builds, expire symbols within 10 days. The default is 100 years.
|
||||
subscription: $(SymbolPublishingServiceConnection)
|
||||
symbolProject: $(SymbolPublishingProject)
|
||||
|
||||
23
COMMUNITY.md
23
COMMUNITY.md
@@ -16,7 +16,7 @@ Christian contributed New+ utility
|
||||
CleanCodeDeveloper helped do massive amounts of code stability and image resizer work.
|
||||
|
||||
### [@plante-msft](https://github.com/plante-msft) - Connor Plante
|
||||
Connor was the creator of Workspaces and helped create PowerToys Run v2
|
||||
Connor was the creator of Workspaces and helped create Command Palette (PowerToys Run v2)
|
||||
|
||||
### [@damienleroy](https://github.com/damienleroy) - [Damien Leroy](https://www.linkedin.com/in/Damien-Leroy-b2734416a/)
|
||||
Damien has helped out by developing and contributing the Quick Accent utility.
|
||||
@@ -46,7 +46,7 @@ Jeff added in multiple new features into Keyboard manager, such as key chord sup
|
||||
Joe has helped triaging, discussing, issues as well as fixing bugs and building features for Text Extractor.
|
||||
|
||||
### [@joadoumie](https://github.com/joadoumie) - Jordi Adoumie
|
||||
Jordi helped innovate amazing new features into Advanced Paste and helped create PowerToys Run v2
|
||||
Jordi helped innovate amazing new features into Advanced Paste and helped create Command Palette (PowerToys Run v2)
|
||||
|
||||
### [@jsoref](https://github.com/jsoref) - [Josh Soref](https://check-spelling.dev/)
|
||||
Helping keep our spelling correct :)
|
||||
@@ -57,6 +57,9 @@ Color Picker is from Martin.
|
||||
### [@mikeclayton](https://github.com/mikeclayton) - [Michael Clayton](https://michael-clayton.com)
|
||||
Michael contributed the [initial version](https://github.com/microsoft/PowerToys/issues/23216) of the Mouse Jump tool and [a number of updates](https://github.com/microsoft/PowerToys/pulls?q=is%3Apr+author%3Amikeclayton) based on his FancyMouse utility.
|
||||
|
||||
### [@pedrolamas](https://github.com/pedrolamas/) - Pedro Lamas
|
||||
Pedro helped create the thumbnail and File Explorer previewers for 3D files like STL and GCode. If you like 3D printing, these are very helpful.
|
||||
|
||||
### [@PesBandi](https://github.com/PesBandi/) - PesBandi
|
||||
PesBandi has helped do massive amounts of Quick Accent and bug fixes.
|
||||
|
||||
@@ -184,15 +187,11 @@ ZoomIt source code was originally implemented by [Sysinternals](https://sysinter
|
||||
- [@crutkas](https://github.com/crutkas/) - Clint Rutkas - Lead
|
||||
- [@cinnamon-msft](https://github.com/cinnamon-msft) - Kayla Cinnamon - Lead
|
||||
- [@nguyen-dows](https://github.com/nguyen-dows) - Christopher Nguyen - Product Manager
|
||||
- [@jaimecbernardo](https://github.com/jaimecbernardo) - Jaime Bernardo - Dev lead
|
||||
- [@craigloewen-msft](https://github.com/craigloewen-msft) - Craig Loewen - Product Manager
|
||||
- [@zhiwei-ms](https://github.com/zhiwei-ms) - Zhiwei Yu - Product Manager
|
||||
- [@dhowett](https://github.com/dhowett) - Dustin Howett - Dev lead
|
||||
- [@yeelam-gordon](https://github.com/yeelam-gordon) - Gordon Lam - Dev lead
|
||||
- [@jamrobot](https://github.com/jamrobot) - Jerry Xu - Dev lead
|
||||
- [@drawbyperpetual](https://github.com/drawbyperpetual) - Anirudha Shankar - Dev
|
||||
- [@mantaionut](https://github.com/mantaionut) - Ionut Manta - Dev
|
||||
- [@donlaci](https://github.com/donlaci) - Laszlo Nemeth - Dev
|
||||
- [@SeraphimaZykova](https://github.com/SeraphimaZykova) - Seraphima Zykova - Dev
|
||||
- [@stefansjfw](https://github.com/stefansjfw) - Stefan Markovic - Dev
|
||||
- [@lei9444](https://github.com/lei9444) - Leilei Zhang - Dev
|
||||
- [@shuaiyuanxx](https://github.com/shuaiyuanxx) - Shawn Yuan - Dev
|
||||
- [@moooyo](https://github.com/moooyo) - Yu Leng - Dev
|
||||
@@ -206,7 +205,7 @@ ZoomIt source code was originally implemented by [Sysinternals](https://sysinter
|
||||
- [@wang563681252](https://github.com/wang563681252) - Zhaopeng Wang - Dev
|
||||
- [@vanzue](https://github.com/vanzue) - Kai Tao - Dev
|
||||
|
||||
# Former PowerToys core team members
|
||||
## Former PowerToys core team members
|
||||
|
||||
- [@indierawk2k2](https://github.com/indierawk2k2) - Mike Harsh - Product Manager
|
||||
- [@ethanfangg](https://github.com/ethanfangg) - Ethan Fang - Product Manager
|
||||
@@ -219,3 +218,9 @@ ZoomIt source code was originally implemented by [Sysinternals](https://sysinter
|
||||
- [@taras-janea](https://github.com/taras-janea) - Taras Sich - Dev
|
||||
- [@yuyoyuppe](https://github.com/yuyoyuppe) - Andrey Nekrasov - Dev
|
||||
- [@gokcekantarci](https://github.com/gokcekantarci) - Gokce Kantarci - Dev
|
||||
- [@drawbyperpetual](https://github.com/drawbyperpetual) - Anirudha Shankar - Dev
|
||||
- [@mantaionut](https://github.com/mantaionut) - Ionut Manta - Dev
|
||||
- [@donlaci](https://github.com/donlaci) - Laszlo Nemeth - Dev
|
||||
- [@SeraphimaZykova](https://github.com/SeraphimaZykova) - Seraphima Zykova - Dev
|
||||
- [@stefansjfw](https://github.com/stefansjfw) - Stefan Markovic - Dev
|
||||
- [@jaimecbernardo](https://github.com/jaimecbernardo) - Jaime Bernardo - Dev lead
|
||||
|
||||
@@ -10,14 +10,14 @@
|
||||
<PackageVersion Include="Azure.AI.OpenAI" Version="1.0.0-beta.17" />
|
||||
<PackageVersion Include="CommunityToolkit.Common" Version="8.4.0" />
|
||||
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.4.0" />
|
||||
<PackageVersion Include="CommunityToolkit.WinUI.Animations" Version="8.2.250129-preview2" />
|
||||
<PackageVersion Include="CommunityToolkit.WinUI.Collections" Version="8.2.250129-preview2" />
|
||||
<PackageVersion Include="CommunityToolkit.WinUI.Controls.Primitives" Version="8.2.250129-preview2" />
|
||||
<PackageVersion Include="CommunityToolkit.WinUI.Controls.SettingsControls" Version="8.2.250129-preview2" />
|
||||
<PackageVersion Include="CommunityToolkit.WinUI.Controls.Segmented" Version="8.2.250129-preview2" />
|
||||
<PackageVersion Include="CommunityToolkit.WinUI.Controls.Sizers" Version="8.2.250129-preview2" />
|
||||
<PackageVersion Include="CommunityToolkit.WinUI.Converters" Version="8.2.250129-preview2" />
|
||||
<PackageVersion Include="CommunityToolkit.WinUI.Extensions" Version="8.2.250129-preview2" />
|
||||
<PackageVersion Include="CommunityToolkit.WinUI.Animations" Version="8.2.250402" />
|
||||
<PackageVersion Include="CommunityToolkit.WinUI.Collections" Version="8.2.250402" />
|
||||
<PackageVersion Include="CommunityToolkit.WinUI.Controls.Primitives" Version="8.2.250402" />
|
||||
<PackageVersion Include="CommunityToolkit.WinUI.Controls.SettingsControls" Version="8.2.250402" />
|
||||
<PackageVersion Include="CommunityToolkit.WinUI.Controls.Segmented" Version="8.2.250402" />
|
||||
<PackageVersion Include="CommunityToolkit.WinUI.Controls.Sizers" Version="8.2.250402" />
|
||||
<PackageVersion Include="CommunityToolkit.WinUI.Converters" Version="8.2.250402" />
|
||||
<PackageVersion Include="CommunityToolkit.WinUI.Extensions" Version="8.2.250402" />
|
||||
<PackageVersion Include="CommunityToolkit.WinUI.UI.Controls.DataGrid" Version="7.1.2" />
|
||||
<PackageVersion Include="CommunityToolkit.WinUI.UI.Controls.Markdown" Version="7.1.2" />
|
||||
<PackageVersion Include="ControlzEx" Version="6.0.0" />
|
||||
@@ -29,24 +29,24 @@
|
||||
<PackageVersion Include="Mages" Version="3.0.0" />
|
||||
<PackageVersion Include="Markdig.Signed" Version="0.34.0" />
|
||||
<!-- Including MessagePack to force version, since it's used by StreamJsonRpc but contains vulnerabilities. After StreamJsonRpc updates the version of MessagePack, we can upgrade StreamJsonRpc instead. -->
|
||||
<PackageVersion Include="MessagePack" Version="2.5.187" />
|
||||
<PackageVersion Include="MessagePack" Version="3.1.3" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="9.0.0" />
|
||||
<PackageVersion Include="Microsoft.Data.Sqlite" Version="9.0.3" />
|
||||
<PackageVersion Include="Microsoft.Data.Sqlite" Version="9.0.4" />
|
||||
<!-- Including Microsoft.Bcl.AsyncInterfaces to force version, since it's used by Microsoft.SemanticKernel. -->
|
||||
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="9.0.3" />
|
||||
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="9.0.4" />
|
||||
<PackageVersion Include="Microsoft.Diagnostics.Tracing.TraceEvent" Version="3.1.16" />
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="9.0.3" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging" Version="9.0.3" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.3" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="9.0.3" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Hosting.WindowsServices" Version="9.0.3" />
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="9.0.4" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging" Version="9.0.4" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.4" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="9.0.4" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Hosting.WindowsServices" Version="9.0.4" />
|
||||
<PackageVersion Include="Microsoft.SemanticKernel" Version="1.15.0" />
|
||||
<PackageVersion Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.2" />
|
||||
<PackageVersion Include="Microsoft.Web.WebView2" Version="1.0.2903.40" />
|
||||
<!-- Package Microsoft.Win32.SystemEvents added as a hack for being able to exclude the runtime assets so they don't conflict with 8.0.1. This is a dependency of System.Drawing.Common but the 8.0.1 version wasn't published to nuget. -->
|
||||
<PackageVersion Include="Microsoft.Win32.SystemEvents" Version="9.0.3" />
|
||||
<PackageVersion Include="Microsoft.Win32.SystemEvents" Version="9.0.4" />
|
||||
<PackageVersion Include="Microsoft.WindowsPackageManager.ComInterop" Version="1.10.120-preview" />
|
||||
<PackageVersion Include="Microsoft.Windows.Compatibility" Version="9.0.3" />
|
||||
<PackageVersion Include="Microsoft.Windows.Compatibility" Version="9.0.4" />
|
||||
<PackageVersion Include="Microsoft.Windows.CsWin32" Version="0.2.46-beta" />
|
||||
<!-- CsWinRT version needs to be set to have a WinRT.Runtime.dll at the same version contained inside the NET SDK we're currently building on CI. -->
|
||||
<!--
|
||||
@@ -61,7 +61,7 @@
|
||||
<PackageVersion Include="ModernWpfUI" Version="0.9.4" />
|
||||
<!-- Moq to stay below v4.20 due to behavior change. need to be sure fixed -->
|
||||
<PackageVersion Include="Moq" Version="4.18.4" />
|
||||
<PackageVersion Include="MSTest" Version="3.6.3" />
|
||||
<PackageVersion Include="MSTest" Version="3.8.3" />
|
||||
<PackageVersion Include="NLog" Version="5.0.4" />
|
||||
<PackageVersion Include="NLog.Extensions.Logging" Version="5.3.8" />
|
||||
<PackageVersion Include="NLog.Schema" Version="5.2.8" />
|
||||
@@ -69,29 +69,32 @@
|
||||
<PackageVersion Include="ReverseMarkdown" Version="4.1.0" />
|
||||
<PackageVersion Include="ScipBe.Common.Office.OneNote" Version="3.0.1" />
|
||||
<PackageVersion Include="SharpCompress" Version="0.37.2" />
|
||||
<PackageVersion Include="StreamJsonRpc" Version="2.19.27" />
|
||||
<PackageVersion Include="StreamJsonRpc" Version="2.21.69" />
|
||||
<PackageVersion Include="StyleCop.Analyzers" Version="1.2.0-beta.556" />
|
||||
<!-- Package System.CodeDom added as a hack for being able to exclude the runtime assets so they don't conflict with 8.0.1. This is a dependency of System.Management but the 8.0.1 version wasn't published to nuget. -->
|
||||
<PackageVersion Include="System.CodeDom" Version="9.0.3" />
|
||||
<PackageVersion Include="System.CodeDom" Version="9.0.4" />
|
||||
<PackageVersion Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
|
||||
<PackageVersion Include="System.ComponentModel.Composition" Version="9.0.3" />
|
||||
<PackageVersion Include="System.Configuration.ConfigurationManager" Version="9.0.3" />
|
||||
<PackageVersion Include="System.Data.OleDb" Version="9.0.3" />
|
||||
<PackageVersion Include="System.ComponentModel.Composition" Version="9.0.4" />
|
||||
<PackageVersion Include="System.Configuration.ConfigurationManager" Version="9.0.4" />
|
||||
<PackageVersion Include="System.Data.OleDb" Version="9.0.4" />
|
||||
<!-- Package System.Data.SqlClient added to force it as a dependency of Microsoft.Windows.Compatibility to the latest version available at this time. -->
|
||||
<PackageVersion Include="System.Data.SqlClient" Version="4.8.6" />
|
||||
<!-- Package System.Diagnostics.EventLog added as a hack for being able to exclude the runtime assets so they don't conflict with 8.0.1. This is a dependency of System.Data.OleDb but the 8.0.1 version wasn't published to nuget. -->
|
||||
<PackageVersion Include="System.Diagnostics.EventLog" Version="9.0.3" />
|
||||
<PackageVersion Include="System.Diagnostics.EventLog" Version="9.0.4" />
|
||||
<!-- Package System.Diagnostics.PerformanceCounter added as a hack for being able to exclude the runtime assets so they don't conflict with 8.0.11. -->
|
||||
<PackageVersion Include="System.Diagnostics.PerformanceCounter" Version="9.0.3" />
|
||||
<PackageVersion Include="System.Drawing.Common" Version="9.0.3" />
|
||||
<PackageVersion Include="System.IO.Abstractions" Version="21.0.29" />
|
||||
<PackageVersion Include="System.IO.Abstractions.TestingHelpers" Version="21.0.29" />
|
||||
<PackageVersion Include="System.Management" Version="9.0.3" />
|
||||
<PackageVersion Include="System.Diagnostics.PerformanceCounter" Version="9.0.4" />
|
||||
<PackageVersion Include="System.Drawing.Common" Version="9.0.4" />
|
||||
<PackageVersion Include="System.IO.Abstractions" Version="22.0.13" />
|
||||
<PackageVersion Include="System.IO.Abstractions.TestingHelpers" Version="22.0.13" />
|
||||
<PackageVersion Include="System.Management" Version="9.0.4" />
|
||||
<PackageVersion Include="System.Net.Http" Version="4.3.4" />
|
||||
<PackageVersion Include="System.Private.Uri" Version="4.3.2" />
|
||||
<PackageVersion Include="System.Reactive" Version="6.0.1" />
|
||||
<PackageVersion Include="System.Runtime.Caching" Version="9.0.3" />
|
||||
<PackageVersion Include="System.ServiceProcess.ServiceController" Version="9.0.3" />
|
||||
<PackageVersion Include="System.Text.Encoding.CodePages" Version="9.0.3" />
|
||||
<PackageVersion Include="System.Text.Json" Version="9.0.3" />
|
||||
<PackageVersion Include="System.Runtime.Caching" Version="9.0.4" />
|
||||
<PackageVersion Include="System.ServiceProcess.ServiceController" Version="9.0.4" />
|
||||
<PackageVersion Include="System.Text.Encoding.CodePages" Version="9.0.4" />
|
||||
<PackageVersion Include="System.Text.Json" Version="9.0.4" />
|
||||
<PackageVersion Include="System.Text.RegularExpressions" Version="4.3.1" />
|
||||
<PackageVersion Include="UnicodeInformation" Version="2.6.0" />
|
||||
<PackageVersion Include="UnitsNet" Version="5.56.0" />
|
||||
<PackageVersion Include="UTF.Unknown" Version="2.5.1" />
|
||||
|
||||
107
NOTICE.md
107
NOTICE.md
@@ -75,6 +75,40 @@ OTHER DEALINGS IN THE SOFTWARE.
|
||||
For more information, please refer to <http://unlicense.org/>
|
||||
```
|
||||
|
||||
## Utility: Command Palette Built-in Extensions
|
||||
|
||||
### Calculator
|
||||
|
||||
#### Mages
|
||||
|
||||
We use the Mages NuGet package for calculating the result of expression.
|
||||
|
||||
**Source**: [https://github.com/FlorianRappl/Mages](https://github.com/FlorianRappl/Mages)
|
||||
|
||||
```
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 - 2025 Florian Rappl
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
```
|
||||
|
||||
## Utility: File Explorer Add-ins
|
||||
|
||||
### Monaco Editor
|
||||
@@ -1393,7 +1427,6 @@ SOFTWARE.
|
||||
|
||||
## NuGet Packages used by PowerToys
|
||||
|
||||
|
||||
- AdaptiveCards.ObjectModel.WinUI3 2.0.0-beta
|
||||
- AdaptiveCards.Rendering.WinUI3 2.1.0-beta
|
||||
- AdaptiveCards.Templating 2.0.2
|
||||
@@ -1401,14 +1434,14 @@ SOFTWARE.
|
||||
- Azure.AI.OpenAI 1.0.0-beta.17
|
||||
- CommunityToolkit.Common 8.4.0
|
||||
- CommunityToolkit.Mvvm 8.4.0
|
||||
- CommunityToolkit.WinUI.Animations 8.2.250129-preview2
|
||||
- CommunityToolkit.WinUI.Collections 8.2.250129-preview2
|
||||
- CommunityToolkit.WinUI.Controls.Primitives 8.2.250129-preview2
|
||||
- CommunityToolkit.WinUI.Controls.Segmented 8.2.250129-preview2
|
||||
- CommunityToolkit.WinUI.Controls.SettingsControls 8.2.250129-preview2
|
||||
- CommunityToolkit.WinUI.Controls.Sizers 8.2.250129-preview2
|
||||
- CommunityToolkit.WinUI.Converters 8.2.250129-preview2
|
||||
- CommunityToolkit.WinUI.Extensions 8.2.250129-preview2
|
||||
- CommunityToolkit.WinUI.Animations 8.2.250402
|
||||
- CommunityToolkit.WinUI.Collections 8.2.250402
|
||||
- CommunityToolkit.WinUI.Controls.Primitives 8.2.250402
|
||||
- CommunityToolkit.WinUI.Controls.Segmented 8.2.250402
|
||||
- CommunityToolkit.WinUI.Controls.SettingsControls 8.2.250402
|
||||
- CommunityToolkit.WinUI.Controls.Sizers 8.2.250402
|
||||
- CommunityToolkit.WinUI.Converters 8.2.250402
|
||||
- CommunityToolkit.WinUI.Extensions 8.2.250402
|
||||
- CommunityToolkit.WinUI.UI.Controls.DataGrid 7.1.2
|
||||
- CommunityToolkit.WinUI.UI.Controls.Markdown 7.1.2
|
||||
- ControlzEx 6.0.0
|
||||
@@ -1419,23 +1452,23 @@ SOFTWARE.
|
||||
- LazyCache 2.4.0
|
||||
- Mages 3.0.0
|
||||
- Markdig.Signed 0.34.0
|
||||
- MessagePack 2.5.187
|
||||
- Microsoft.Bcl.AsyncInterfaces 9.0.3
|
||||
- MessagePack 3.1.3
|
||||
- Microsoft.Bcl.AsyncInterfaces 9.0.4
|
||||
- Microsoft.CodeAnalysis.NetAnalyzers 9.0.0
|
||||
- Microsoft.Data.Sqlite 9.0.3
|
||||
- Microsoft.Data.Sqlite 9.0.4
|
||||
- Microsoft.Diagnostics.Tracing.TraceEvent 3.1.16
|
||||
- Microsoft.DotNet.ILCompiler (A)
|
||||
- Microsoft.Extensions.DependencyInjection 9.0.3
|
||||
- Microsoft.Extensions.Hosting 9.0.3
|
||||
- Microsoft.Extensions.Hosting.WindowsServices 9.0.3
|
||||
- Microsoft.Extensions.Logging 9.0.3
|
||||
- Microsoft.Extensions.Logging.Abstractions 9.0.3
|
||||
- Microsoft.Extensions.DependencyInjection 9.0.4
|
||||
- Microsoft.Extensions.Hosting 9.0.4
|
||||
- Microsoft.Extensions.Hosting.WindowsServices 9.0.4
|
||||
- Microsoft.Extensions.Logging 9.0.4
|
||||
- Microsoft.Extensions.Logging.Abstractions 9.0.4
|
||||
- Microsoft.NET.ILLink.Tasks (A)
|
||||
- Microsoft.SemanticKernel 1.15.0
|
||||
- Microsoft.Toolkit.Uwp.Notifications 7.1.2
|
||||
- Microsoft.Web.WebView2 1.0.2903.40
|
||||
- Microsoft.Win32.SystemEvents 9.0.3
|
||||
- Microsoft.Windows.Compatibility 9.0.3
|
||||
- Microsoft.Win32.SystemEvents 9.0.4
|
||||
- Microsoft.Windows.Compatibility 9.0.4
|
||||
- Microsoft.Windows.CsWin32 0.2.46-beta
|
||||
- Microsoft.Windows.CsWinRT 2.2.0
|
||||
- Microsoft.Windows.SDK.BuildTools 10.0.22621.2428
|
||||
@@ -1445,35 +1478,39 @@ SOFTWARE.
|
||||
- Microsoft.Xaml.Behaviors.Wpf 1.1.39
|
||||
- ModernWpfUI 0.9.4
|
||||
- Moq 4.18.4
|
||||
- MSTest 3.6.3
|
||||
- MSTest 3.8.3
|
||||
- NLog.Extensions.Logging 5.3.8
|
||||
- NLog.Schema 5.2.8
|
||||
- OpenAI 2.0.0
|
||||
- ReverseMarkdown 4.1.0
|
||||
- ScipBe.Common.Office.OneNote 3.0.1
|
||||
- SharpCompress 0.37.2
|
||||
- StreamJsonRpc 2.19.27
|
||||
- StreamJsonRpc 2.21.69
|
||||
- StyleCop.Analyzers 1.2.0-beta.556
|
||||
- System.CodeDom 9.0.3
|
||||
- System.CodeDom 9.0.4
|
||||
- System.CommandLine 2.0.0-beta4.22272.1
|
||||
- System.ComponentModel.Composition 9.0.3
|
||||
- System.Configuration.ConfigurationManager 9.0.3
|
||||
- System.Data.OleDb 9.0.3
|
||||
- System.ComponentModel.Composition 9.0.4
|
||||
- System.Configuration.ConfigurationManager 9.0.4
|
||||
- System.Data.OleDb 9.0.4
|
||||
- System.Data.SqlClient 4.8.6
|
||||
- System.Diagnostics.EventLog 9.0.3
|
||||
- System.Diagnostics.PerformanceCounter 9.0.3
|
||||
- System.Drawing.Common 9.0.3
|
||||
- System.IO.Abstractions 21.0.29
|
||||
- System.IO.Abstractions.TestingHelpers 21.0.29
|
||||
- System.Management 9.0.3
|
||||
- System.Diagnostics.EventLog 9.0.4
|
||||
- System.Diagnostics.PerformanceCounter 9.0.4
|
||||
- System.Drawing.Common 9.0.4
|
||||
- System.IO.Abstractions 22.0.13
|
||||
- System.IO.Abstractions.TestingHelpers 22.0.13
|
||||
- System.Management 9.0.4
|
||||
- System.Net.Http 4.3.4
|
||||
- System.Private.Uri 4.3.2
|
||||
- System.Reactive 6.0.1
|
||||
- System.Runtime.Caching 9.0.3
|
||||
- System.ServiceProcess.ServiceController 9.0.3
|
||||
- System.Text.Encoding.CodePages 9.0.3
|
||||
- System.Text.Json 9.0.3
|
||||
- System.Runtime.Caching 9.0.4
|
||||
- System.ServiceProcess.ServiceController 9.0.4
|
||||
- System.Text.Encoding.CodePages 9.0.4
|
||||
- System.Text.Json 9.0.4
|
||||
- System.Text.RegularExpressions 4.3.1
|
||||
- UnicodeInformation 2.6.0
|
||||
- UnitsNet 5.56.0
|
||||
- UTF.Unknown 2.5.1
|
||||
- WinUIEx 2.2.0
|
||||
- WPF-UI 3.0.5
|
||||
- WyHash 1.0.5
|
||||
|
||||
|
||||
@@ -624,19 +624,19 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CommandPalette", "CommandPa
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Built-in Extensions", "Built-in Extensions", "{ECB8E0D1-7603-4E5C-AB10-D1E545E6F8E2}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CmdPal.Ext.Apps", "src\modules\cmdpal\Exts\Microsoft.CmdPal.Ext.Apps\Microsoft.CmdPal.Ext.Apps.csproj", "{6CE438DF-C245-4997-A360-0A0939E4BA34}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CmdPal.Ext.Apps", "src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.Apps\Microsoft.CmdPal.Ext.Apps.csproj", "{6CE438DF-C245-4997-A360-0A0939E4BA34}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CmdPal.Ext.Bookmarks", "src\modules\cmdpal\Exts\Microsoft.CmdPal.Ext.Bookmark\Microsoft.CmdPal.Ext.Bookmarks.csproj", "{E09AA983-C755-474F-83D6-A5CDF528C070}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CmdPal.Ext.Bookmarks", "src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.Bookmark\Microsoft.CmdPal.Ext.Bookmarks.csproj", "{E09AA983-C755-474F-83D6-A5CDF528C070}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CmdPal.Ext.Calc", "src\modules\cmdpal\Exts\Microsoft.CmdPal.Ext.Calc\Microsoft.CmdPal.Ext.Calc.csproj", "{6D56B64D-FF1F-488F-AFED-9B9854A5D399}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CmdPal.Ext.Calc", "src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.Calc\Microsoft.CmdPal.Ext.Calc.csproj", "{6D56B64D-FF1F-488F-AFED-9B9854A5D399}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CmdPal.Ext.Registry", "src\modules\cmdpal\Exts\Microsoft.CmdPal.Ext.Registry\Microsoft.CmdPal.Ext.Registry.csproj", "{92EC89E4-9972-453A-8A1A-3A9E230C146A}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CmdPal.Ext.Registry", "src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.Registry\Microsoft.CmdPal.Ext.Registry.csproj", "{92EC89E4-9972-453A-8A1A-3A9E230C146A}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CmdPal.Ext.WindowsServices", "src\modules\cmdpal\Exts\Microsoft.CmdPal.Ext.WindowsServices\Microsoft.CmdPal.Ext.WindowsServices.csproj", "{51939B4F-1F62-4BFF-A6A2-C08646E5BE95}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CmdPal.Ext.WindowsServices", "src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.WindowsServices\Microsoft.CmdPal.Ext.WindowsServices.csproj", "{51939B4F-1F62-4BFF-A6A2-C08646E5BE95}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CmdPal.Ext.WindowsSettings", "src\modules\cmdpal\Exts\Microsoft.CmdPal.Ext.WindowsSettings\Microsoft.CmdPal.Ext.WindowsSettings.csproj", "{D1160404-D3D1-497A-883A-4059C07C2273}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CmdPal.Ext.WindowsSettings", "src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.WindowsSettings\Microsoft.CmdPal.Ext.WindowsSettings.csproj", "{D1160404-D3D1-497A-883A-4059C07C2273}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CmdPal.Ext.WindowsTerminal", "src\modules\cmdpal\Exts\Microsoft.CmdPal.Ext.WindowsTerminal\Microsoft.CmdPal.Ext.WindowsTerminal.csproj", "{40F6D69D-E321-400F-A767-5628C7AE453D}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CmdPal.Ext.WindowsTerminal", "src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.WindowsTerminal\Microsoft.CmdPal.Ext.WindowsTerminal.csproj", "{40F6D69D-E321-400F-A767-5628C7AE453D}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extension SDK", "Extension SDK", "{F3D09629-59A2-4924-A4B9-D6BFAA2C1B49}"
|
||||
EndProject
|
||||
@@ -650,9 +650,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Terminal.UI", "sr
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Sample Extensions", "Sample Extensions", "{071E18A4-A530-46B8-AB7D-B862EE55E24E}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProcessMonitorExtension", "src\modules\cmdpal\Exts\ProcessMonitorExtension\ProcessMonitorExtension.csproj", "{C846F7A7-792A-47D9-B0CB-417C900EE03D}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProcessMonitorExtension", "src\modules\cmdpal\ext\ProcessMonitorExtension\ProcessMonitorExtension.csproj", "{C846F7A7-792A-47D9-B0CB-417C900EE03D}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SamplePagesExtension", "src\modules\cmdpal\Exts\SamplePagesExtension\SamplePagesExtension.csproj", "{C831231F-891C-4572-9694-45062534B42A}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SamplePagesExtension", "src\modules\cmdpal\ext\SamplePagesExtension\SamplePagesExtension.csproj", "{C831231F-891C-4572-9694-45062534B42A}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UI", "UI", "{7520A2FE-00A2-49B8-83ED-DB216E874C04}"
|
||||
EndProject
|
||||
@@ -660,7 +660,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CmdPal.UI", "src\
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CmdPal.UI.ViewModels", "src\modules\cmdpal\Microsoft.CmdPal.UI.ViewModels\Microsoft.CmdPal.UI.ViewModels.csproj", "{C66020D1-CB10-4CF7-8715-84C97FD5E5E2}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CmdPal.Ext.ClipboardHistory", "src\modules\cmdpal\Exts\Microsoft.CmdPal.Ext.ClipboardHistory\Microsoft.CmdPal.Ext.ClipboardHistory.csproj", "{79775343-7A3D-445D-9104-3DD5B2893DF9}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CmdPal.Ext.ClipboardHistory", "src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.ClipboardHistory\Microsoft.CmdPal.Ext.ClipboardHistory.csproj", "{79775343-7A3D-445D-9104-3DD5B2893DF9}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CmdPalModuleInterface", "src\modules\cmdpal\CmdPalModuleInterface\CmdPalModuleInterface.vcxproj", "{0ADEB797-C8C7-4FFA-ACD5-2AF6CAD7ECD8}"
|
||||
EndProject
|
||||
@@ -668,15 +668,15 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkspacesCsharpLibrary", "
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NewPlus.ShellExtension.win10", "src\modules\NewPlus\NewShellExtensionContextMenu.win10\NewPlus.ShellExtension.win10.vcxproj", "{0DB0F63A-D2F8-4DA3-A650-2D0B8724218E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.Indexer", "src\modules\cmdpal\Exts\Microsoft.CmdPal.Ext.Indexer\Microsoft.CmdPal.Ext.Indexer.csproj", "{453CBB73-A3CB-4D0B-8D24-6940B86FE21D}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.Indexer", "src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.Indexer\Microsoft.CmdPal.Ext.Indexer.csproj", "{453CBB73-A3CB-4D0B-8D24-6940B86FE21D}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CmdPal.Ext.Shell", "src\modules\cmdpal\Exts\Microsoft.CmdPal.Ext.Shell\Microsoft.CmdPal.Ext.Shell.csproj", "{C0CE3B5E-16D3-495D-B335-CA791B660162}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CmdPal.Ext.Shell", "src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.Shell\Microsoft.CmdPal.Ext.Shell.csproj", "{C0CE3B5E-16D3-495D-B335-CA791B660162}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CmdPal.Ext.WindowWalker", "src\modules\cmdpal\Exts\Microsoft.CmdPal.Ext.WindowWalker\Microsoft.CmdPal.Ext.WindowWalker.csproj", "{3A9A7297-92C4-4F16-B6F9-8D4AB652C86C}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CmdPal.Ext.WindowWalker", "src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.WindowWalker\Microsoft.CmdPal.Ext.WindowWalker.csproj", "{3A9A7297-92C4-4F16-B6F9-8D4AB652C86C}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.WebSearch", "src\modules\cmdpal\Exts\Microsoft.CmdPal.Ext.WebSearch\Microsoft.CmdPal.Ext.WebSearch.csproj", "{605E914B-7232-4789-AF46-BF5D3DDFC14E}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.WebSearch", "src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.WebSearch\Microsoft.CmdPal.Ext.WebSearch.csproj", "{605E914B-7232-4789-AF46-BF5D3DDFC14E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.WinGet", "src\modules\cmdpal\Exts\Microsoft.CmdPal.Ext.WinGet\Microsoft.CmdPal.Ext.WinGet.csproj", "{E81A7D20-9862-ABDB-0AAE-9BC5B517A9F9}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.WinGet", "src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.WinGet\Microsoft.CmdPal.Ext.WinGet.csproj", "{E81A7D20-9862-ABDB-0AAE-9BC5B517A9F9}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdvancedPaste.UnitTests", "src\modules\AdvancedPaste\AdvancedPaste.UnitTests\AdvancedPaste.UnitTests.csproj", "{D5E5F5EA-1B6C-4A73-88BE-304F36C9E4EE}"
|
||||
EndProject
|
||||
@@ -690,7 +690,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZoomItModuleInterface", "sr
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZoomItSettingsInterop", "src\modules\ZoomIt\ZoomItSettingsInterop\ZoomItSettingsInterop.vcxproj", "{CA7D8106-30B9-4AEC-9D05-B69B31B8C461}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.TimeDate", "src\modules\cmdpal\Exts\Microsoft.CmdPal.Ext.TimeDate\Microsoft.CmdPal.Ext.TimeDate.csproj", "{DCC6BD67-17BB-47AA-B507-FB0FE43A7449}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.TimeDate", "src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.TimeDate\Microsoft.CmdPal.Ext.TimeDate.csproj", "{DCC6BD67-17BB-47AA-B507-FB0FE43A7449}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UITestAutomation", "src\common\UITestAutomation\UITestAutomation.csproj", "{A558C25D-2007-498E-8B6F-43405AFAE9E2}"
|
||||
EndProject
|
||||
@@ -704,7 +704,9 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hosts.UITests", "src\module
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RegistryPreview.FuzzTests", "src\modules\registrypreview\RegistryPreview.FuzzTests\RegistryPreview.FuzzTests.csproj", "{5702B3CC-8575-48D5-83D8-15BB42269CD3}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.System", "src\modules\cmdpal\Exts\Microsoft.CmdPal.Ext.System\Microsoft.CmdPal.Ext.System.csproj", "{64B88F02-CD88-4ED8-9624-989A800230F9}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.System", "src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.System\Microsoft.CmdPal.Ext.System.csproj", "{64B88F02-CD88-4ED8-9624-989A800230F9}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CmdPalKeyboardService", "src\modules\cmdpal\CmdPalKeyboardService\CmdPalKeyboardService.vcxproj", "{5F63C743-F6CE-4DBA-A200-2B3F8A14E8C2}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@@ -2574,14 +2576,18 @@ Global
|
||||
{64B88F02-CD88-4ED8-9624-989A800230F9}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{64B88F02-CD88-4ED8-9624-989A800230F9}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{64B88F02-CD88-4ED8-9624-989A800230F9}.Debug|x64.Build.0 = Debug|x64
|
||||
{64B88F02-CD88-4ED8-9624-989A800230F9}.Debug|x86.ActiveCfg = Debug|x64
|
||||
{64B88F02-CD88-4ED8-9624-989A800230F9}.Debug|x86.Build.0 = Debug|x64
|
||||
{64B88F02-CD88-4ED8-9624-989A800230F9}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{64B88F02-CD88-4ED8-9624-989A800230F9}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{64B88F02-CD88-4ED8-9624-989A800230F9}.Release|x64.ActiveCfg = Release|x64
|
||||
{64B88F02-CD88-4ED8-9624-989A800230F9}.Release|x64.Build.0 = Release|x64
|
||||
{64B88F02-CD88-4ED8-9624-989A800230F9}.Release|x86.ActiveCfg = Release|x64
|
||||
{64B88F02-CD88-4ED8-9624-989A800230F9}.Release|x86.Build.0 = Release|x64
|
||||
{5F63C743-F6CE-4DBA-A200-2B3F8A14E8C2}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{5F63C743-F6CE-4DBA-A200-2B3F8A14E8C2}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{5F63C743-F6CE-4DBA-A200-2B3F8A14E8C2}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{5F63C743-F6CE-4DBA-A200-2B3F8A14E8C2}.Debug|x64.Build.0 = Debug|x64
|
||||
{5F63C743-F6CE-4DBA-A200-2B3F8A14E8C2}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{5F63C743-F6CE-4DBA-A200-2B3F8A14E8C2}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{5F63C743-F6CE-4DBA-A200-2B3F8A14E8C2}.Release|x64.ActiveCfg = Release|x64
|
||||
{5F63C743-F6CE-4DBA-A200-2B3F8A14E8C2}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -2852,6 +2858,7 @@ Global
|
||||
{4E0AE3A4-2EE0-44D7-A2D0-8769977254A0} = {F05E590D-AD46-42BE-9C25-6A63ADD2E3EA}
|
||||
{5702B3CC-8575-48D5-83D8-15BB42269CD3} = {929C1324-22E8-4412-A9A8-80E85F3985A5}
|
||||
{64B88F02-CD88-4ED8-9624-989A800230F9} = {ECB8E0D1-7603-4E5C-AB10-D1E545E6F8E2}
|
||||
{5F63C743-F6CE-4DBA-A200-2B3F8A14E8C2} = {3846508C-77EB-4034-A702-F8BB263C4F79}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0}
|
||||
|
||||
@@ -101,7 +101,7 @@ In this release, we focused on new features, stability, and automation.
|
||||
|
||||

|
||||
|
||||
- New module: Command Palette ("CmdPal") - Created as the evolution of PowerToys Run with extensibility at the forefront, Command Palette is a quick launcher with a richer display and additional capabilities without sacrificing performance, allowing you to start anything with the shortcut **Win+Alt+Space**! Thanks [@zadjii-msft](https://github.com/zadjii-msft), [@niels9001](https://github.com/niels9001), [@joadoumie](https://github.com/joadoumie), [@plante-msft](https://github.com/plante-msft), [@ethanfangg](https://github.com/ethanfangg) and [@krschau](https://github.com/krschau)!
|
||||
- New module: Command Palette ("CmdPal") - Created as the evolution of PowerToys Run with extensibility at the forefront, Command Palette is a quick launcher with a richer display and additional capabilities without sacrificing performance, allowing you to start anything with the shortcut **Win+Alt+Space**! Thanks [@zadjii-msft](https://github.com/zadjii-msft), [@niels9001](https://github.com/niels9001), [@michael-hawker](https://github.com/michael-hawker), [@joadoumie](https://github.com/joadoumie), [@plante-msft](https://github.com/plante-msft), [@ethanfangg](https://github.com/ethanfangg) and [@krschau](https://github.com/krschau)!
|
||||
- Enhanced the Color Picker by switching from WPF UI to .NET WPF, resulting in improved themes and visual consistency across different modes. Thanks [@mantaionut](https://github.com/mantaionut)! Thanks [@Jay-o-Way](https://github.com/Jay-o-Way) and [@niels9001](https://github.com/niels9001) for helping with the review!
|
||||
- Added the ability to delete files directly from Peek, enhancing file management efficiency. Thanks [@daverayment](https://github.com/daverayment) and thanks [@htcfreek](https://github.com/htcfreek) for the review!
|
||||
- Added support for variables in template filenames, enabling dynamic elements like date components and environment variables for enhanced customization in New+. Thanks [@cgaarden](https://github.com/cgaarden)!
|
||||
@@ -112,7 +112,7 @@ In this release, we focused on new features, stability, and automation.
|
||||
|
||||
### Command Palette
|
||||
|
||||
- Introduced the Windows Command Palette ("CmdPal"), the next iteration of PowerToys Run, designed with extensibility at its core. CmdPal includes features such as searching for installed apps, shell commands, files and WinGet package installation. This module aims to provide a more powerful and flexible launcher experience. Thanks [@zadjii-msft](https://github.com/zadjii-msft), [@niels9001](https://github.com/niels9001), [@joadoumie](https://github.com/joadoumie), [@plante-msft](https://github.com/plante-msft), and the whole team!
|
||||
- Introduced the Windows Command Palette ("CmdPal"), the next iteration of PowerToys Run, designed with extensibility at its core. CmdPal includes features such as searching for installed apps, shell commands, files and WinGet package installation. This module aims to provide a more powerful and flexible launcher experience. Thanks [@zadjii-msft](https://github.com/zadjii-msft), [@niels9001](https://github.com/niels9001), [@michael-hawker](https://github.com/michael-hawker), [@joadoumie](https://github.com/joadoumie), [@plante-msft](https://github.com/plante-msft), and the whole team!
|
||||
|
||||
### FancyZones
|
||||
|
||||
|
||||
@@ -88,4 +88,4 @@ namespace UITests_KeyboardManager
|
||||
## Extra tools and information
|
||||
|
||||
**Accessibility Tools**:
|
||||
While working on tests, you may need a tool that helps you to view the element's accessibility data, e.g. for finding the button to click. For this purpose, you could use [AccessibilityInsights](https://accessibilityinsights.io/docs/windows/overview)
|
||||
While working on tests, you may need a tool that helps you to view the element's accessibility data, e.g. for finding the button to click. For this purpose, you could use [AccessibilityInsights](https://accessibilityinsights.io/docs/windows/overview).
|
||||
|
||||
@@ -16,49 +16,70 @@ The 'Time and Date' plugin shows the date and time in different formats. For the
|
||||
### Available formats
|
||||
|
||||
**Remarks**
|
||||
- The following formats requires a prefix in the query:
|
||||
- The following formats requires a prefix in the query when using them as date input:
|
||||
- Unix Timestamp: `u`
|
||||
- Unix Timestamp in milliseconds: `ums`
|
||||
- Windows file time: `ft`
|
||||
- OLE Automation date: `oa`
|
||||
- Excel 1900 date value: `exc`
|
||||
- Excel 1904 date value: `exf`
|
||||
- On invalid number inputs we show a warning that tells the user which prefixes are allowed/required.
|
||||
|
||||
**List of available formats**
|
||||
|
||||
The following formats are currently available:
|
||||
|
||||
| Format | Example (Based on default settings) | As result | As input |
|
||||
| Format | Example (Based on default settings) | As result | As input | Result as custom format only
|
||||
|--------------|-----------|------------|------------|
|
||||
| Time | 5:10 PM | x | x |
|
||||
| Date | 3/5/2022 | x | x |
|
||||
| Now | 3/5/2022 5:10 PM | x | x |
|
||||
| Time UTC | 4:10 PM | x | x |
|
||||
| Now UTC | 3/5/2022 4:10 PM | x | x |
|
||||
| Unix Timestamp | 1646496622 | x | x |
|
||||
| Unix Timestamp in milliseconds | 1646496622500 | x | x |
|
||||
| Hour | 10 | x | |
|
||||
| Minute | 30 | x | |
|
||||
| Second | 45 | x | |
|
||||
| Millisecond | 678 | x | |
|
||||
| Day (Week day) | Saturday | x | |
|
||||
| Day of the week | 6 | x | |
|
||||
| Day of the month | 5 | x | |
|
||||
| Day of the year | 64 | x | |
|
||||
| Week of the month | 1 | x | |
|
||||
| Week of the year (Calendar week, Week number) | 10 | x | |
|
||||
| Month | March | x | |
|
||||
| Month of the year | 3 | x | |
|
||||
| Month and day | March 7 | x | x |
|
||||
| Year | 2022 | x | |
|
||||
| Era | AD | x | |
|
||||
| Era abbreviation | A | x | |
|
||||
| Month and year | March 2022 | x | x |
|
||||
| Windows file time (Int64 number) | 637820976123938199 | x | x |
|
||||
| Universal time format: YYYY-MM-DD hh:mm:ss| 2022-03-05 16:20:12Z | x | x |
|
||||
| ISO 8601 | 2022-03-05T17:23:04 | x | x |
|
||||
| ISO 8601 UTC | 2022-03-05T16:23:04 | x | x |
|
||||
| ISO 8601 with time zone | 2022-03-05T17:23:04+01:00 | x | x |
|
||||
| ISO 8601 UTC with time zone | 2022-03-05T16:23:04Z | x | x |
|
||||
| RFC1123 | Sat, 05 Mar 2022 16:23:04 GMT | x | x |
|
||||
| Time | 5:10 PM | x | x | |
|
||||
| Date | 3/5/2022 | x | x | |
|
||||
| Now | 3/5/2022 5:10 PM | x | x | |
|
||||
| Time UTC | 4:10 PM | x | x | |
|
||||
| Now UTC | 3/5/2022 4:10 PM | x | x | |
|
||||
| Unix Timestamp | 1646496622 | x | x | |
|
||||
| Unix Timestamp in milliseconds | 1646496622500 | x | x | |
|
||||
| Hour | 10 | x | | |
|
||||
| Minute | 30 | x | | |
|
||||
| Second | 45 | x | | |
|
||||
| Millisecond | 678 | x | | |
|
||||
| Day (Week day) | Saturday | x | | |
|
||||
| Day of the week | 6 | x | | |
|
||||
| Day of the month | 5 | x | | |
|
||||
| Day of the year | 64 | x | | |
|
||||
| Week of the month | 1 | x | | |
|
||||
| Week of the year (Calendar week, Week number) | 10 | x | | |
|
||||
| Month | March | x | | |
|
||||
| Month of the year | 3 | x | | |
|
||||
| Month and day | March 7 | x | x | |
|
||||
| Year | 2022 | x | | |
|
||||
| Era | AD | x | | |
|
||||
| Era abbreviation | A | x | | |
|
||||
| Month and year | March 2022 | x | x | |
|
||||
| Windows file time (Int64 number) | 637820976123938199 | x | x | |
|
||||
| Universal time format: YYYY-MM-DD hh:mm:ss| 2022-03-05 16:20:12Z | x | x | |
|
||||
| ISO 8601 | 2022-03-05T17:23:04 | x | x | |
|
||||
| ISO 8601 UTC | 2022-03-05T16:23:04 | x | x | |
|
||||
| ISO 8601 with time zone | 2022-03-05T17:23:04+01:00 | x | x | |
|
||||
| ISO 8601 UTC with time zone | 2022-03-05T16:23:04Z | x | x | |
|
||||
| RFC1123 | Sat, 05 Mar 2022 16:23:04 GMT | x | x | |
|
||||
| OLE Automation date | 45723.44143763889 | | x | x |
|
||||
| Excel's 1900 date value | 45723.44143763889 | | x | x |
|
||||
| Excel's 1904 date value | 44261.44143763889 | | x | x |
|
||||
|
||||
**Custom format definition**
|
||||
The user can create its own formats. One per line in the settings text box. The format of each line is `<name>=<syntax pattern>`.
|
||||
If the syntax pattern starting with `UTC:` then we use the UTC time instead of the local time.
|
||||
As syntax pattern the pattern from `DateTime.ToString()` and the following custom pattern are available:
|
||||
- DOW: Number of the day in the week.
|
||||
- WOM: Number of week in the month.
|
||||
- WOY: Number of the week in the year.
|
||||
- EAB: Era abbreviation.
|
||||
- WFT: Windows file time.
|
||||
- UXT: Unix time stamp.
|
||||
- UMS: Unix time stamp in milliseconds.
|
||||
- OAD: OLE Automation date.
|
||||
- EXC: Excel's 1900 based date value.
|
||||
- EXF: Excel's 1904 based date value.
|
||||
|
||||
### Add new formats
|
||||
- To add a new formats you have to add them to the method `GetList()` of the [`AvailableResultsList`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Components/AvailableResultsList.cs) class.
|
||||
@@ -73,13 +94,13 @@ The following formats are currently available:
|
||||
|
||||
| Key | Type | Default value | Name | Description |
|
||||
|--------------|--------------|-----------|------------|------------|
|
||||
| `CalendarFirstWeekRule` | Combo box | `-1` (Use system settings) | First week of the year | Configure the calendar rule for the first week of the year. |
|
||||
| `FirstDayOfWeek` | Combo box | `-1` (Use system settings) | First day of the week | |
|
||||
| `OnlyDateTimeNowGlobal` | Checkbox | `true` | Show only 'Time', 'Date', and 'Now' result for system time on global queries | Regardless of this setting, for global queries the first word of the query has to be a complete match. |
|
||||
| `TimeWithSeconds` | Checkbox | `false` | Show time with seconds | This setting applies to the 'Time' and 'Now' result. |
|
||||
| `DateWithWeekday` | Checkbox | `false` | Show date with weekday and name of month | This setting applies to the 'Date' and 'Now' result. |
|
||||
| `HideNumberMessageOnGlobalQuery` | Checkbox | `false` | Hide 'Invalid number input' error message on global queries | |
|
||||
|
||||
| `CalendarFirstWeekRule` | Combo box | `-1` (Use system settings) | First week of the year | Configure the calendar rule for the first week of the year. |
|
||||
| `FirstDayOfWeek` | Combo box | `-1` (Use system settings) | First day of the week | |
|
||||
| `CustomFormats` | Multiline text box | `string.Empty` | Custom formats | Use date and time string format syntax and DOW (Day of Week), WOM (Week of Month), WOY (Week of the year), EAB (Era abbreviation), WFT (Windows File Time), UXT (Unix Time), UMS (Unix Time in milliseconds), OAD (OLE Automation date), EXC (Excel's 1900 based date value), EXF (Excel's 1904 based date value). If the format starts with UTC:, then Universal Time (UTC) is used. (Use a backslash to escape format sequences and the backslash character as text.) |
|
||||
|
||||
## Classes
|
||||
|
||||
|
||||
@@ -43,6 +43,9 @@ Contact the developers of a plugin directly for assistance with a specific plugi
|
||||
| [TailwindCSS](https://github.com/skttl/ptrun-tailwindcss) | [skttl](https://github.com/skttl) | Search the documentation of TailwindCSS |
|
||||
| [HttpStatusCodes](https://github.com/grzhan/HttpStatusCodePowerToys) | [grzhan](https://github.com/grzhan) | Search for http status codes |
|
||||
| [SVGL](https://github.com/Sameerjs6/powertoys-svgl) | [SameerJS6](https://github.com/SameerJS6) | Search, Browse and copy SVG logos from SVGL. |
|
||||
| [QuickNotes](https://github.com/ruslanlap/CommunityPowerToysRunPlugin-QuickNotes) | [ruslanlap](https://github.com/ruslanlap) | Create, manage, and search notes directly from PowerToys Run. |
|
||||
| [Weather](https://github.com/ruslanlap/PowerToysRun-Weather) | [ruslanlap](https://github.com/ruslanlap) | Get real-time weather information directly from PowerToys Run. |
|
||||
| [Pomodoro](https://github.com/ruslanlap/PowerToysRun-Pomodoro) | [ruslanlap](https://github.com/ruslanlap) | Manage Pomodoro productivity sessions directly from PowerToys Run. |
|
||||
|
||||
## Extending software plugins
|
||||
|
||||
@@ -65,3 +68,4 @@ Below are community created plugins that target a website or software. They are
|
||||
| [Bilibili](https://github.com/Whuihuan/PowerToysRun-Bilibili) | [Whuihuan](https://github.com/Whuihuan) | Use AVID or BVID to parse and jump to Bilibili |
|
||||
| [YubicoOauthOTP](https://github.com/dlnilsson/Community.PowerToys.Run.Plugin.YubicoOauthOTP) | [dlnilsson](https://github.com/dlnilsson) | Display generated codes from OATH accounts stored on the YubiKey in powerToys Run |
|
||||
| [Firefox Bookmark](https://github.com/8LWXpg/PowerToysRun-FirefoxBookmark) | [8LWXpg](https://github.com/8LWXpg) | Open bookmarks in Firefox based browser |
|
||||
[Linear](https://github.com/vednig/powertoys-linear) | [vednig](https://github.com/vednig) | Create Linear Issues directly from Powertoys Run |
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
<RegistryValue Type="string" Name="Module_CmdPal_Deps" Value="" KeyPath="yes"/>
|
||||
</RegistryKey>
|
||||
<File Source="$(var.CmdPalBuildDir)AppPackages\Microsoft.CmdPal.UI_$(var.CmdPalVersion).0_Test\Dependencies\x64\Microsoft.VCLibs.x64.14.00.Desktop.appx" />
|
||||
<File Source="$(var.CmdPalBuildDir)AppPackages\Microsoft.CmdPal.UI_$(var.CmdPalVersion).0_Test\Dependencies\x64\Microsoft.WindowsAppRuntime.1.6.msix" />
|
||||
</Component>
|
||||
</DirectoryRef>
|
||||
<?else ?>
|
||||
@@ -50,7 +49,6 @@
|
||||
<RegistryValue Type="string" Name="Module_CmdPal_Deps" Value="" KeyPath="yes"/>
|
||||
</RegistryKey>
|
||||
<File Source="$(var.CmdPalBuildDir)AppPackages\Microsoft.CmdPal.UI_$(var.CmdPalVersion).0_Test\Dependencies\arm64\Microsoft.VCLibs.ARM64.14.00.Desktop.appx" />
|
||||
<File Source="$(var.CmdPalBuildDir)AppPackages\Microsoft.CmdPal.UI_$(var.CmdPalVersion).0_Test\Dependencies\arm64\Microsoft.WindowsAppRuntime.1.6.msix" />
|
||||
</Component>
|
||||
</DirectoryRef>
|
||||
<?endif ?>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Some items may be set in Directory.Build.props in root -->
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project=".\Common.Dotnet.PrepareGeneratedFolder.targets" />
|
||||
|
||||
<PropertyGroup>
|
||||
<WindowsSdkPackageVersion>10.0.22621.57</WindowsSdkPackageVersion>
|
||||
<TargetFramework>net9.0-windows10.0.22621.0</TargetFramework>
|
||||
|
||||
16
src/Common.Dotnet.PrepareGeneratedFolder.targets
Normal file
16
src/Common.Dotnet.PrepareGeneratedFolder.targets
Normal file
@@ -0,0 +1,16 @@
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
|
||||
<Target Name="EnsureGeneratedBaseFolder" BeforeTargets="XamlPreCompile">
|
||||
<PropertyGroup>
|
||||
<!-- Only create the base 'generated' folder -->
|
||||
<CompilerGeneratedFilesOutputPath>$(ProjectDir)obj\g</CompilerGeneratedFilesOutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Create 'generated' folder if missing -->
|
||||
<MakeDir Directories="$(CompilerGeneratedFilesOutputPath)" />
|
||||
|
||||
<!-- Optional logging for debugging -->
|
||||
<Message Text="Ensured: $(GeneratedBasePath)" Importance="Low" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.
|
||||
|
||||
@@ -63,8 +63,16 @@ using System.Diagnostics.CodeAnalysis;
|
||||
[assembly: SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "<Dotnet port with style preservation>", Scope = "namespaceanddescendants", Target = "MouseWithoutBorders")]
|
||||
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1649:File name should match first type name", Justification = "<Dotnet port with style preservation>", Scope = "namespaceanddescendants", Target = "MouseWithoutBorders")]
|
||||
|
||||
// AOT
|
||||
// AOT MVVMTK0045
|
||||
[assembly: SuppressMessage("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "MVVMTK0045:Using [ObservableProperty] on fields is not AOT compatible for WinRT", Justification = "Updated MVVM toolkit package introduced this.", Scope = "namespaceanddescendants", Target = "AdvancedPaste.ViewModels")]
|
||||
[assembly: SuppressMessage("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "MVVMTK0045:Using [ObservableProperty] on fields is not AOT compatible for WinRT", Justification = "Updated MVVM toolkit package introduced this.", Scope = "namespaceanddescendants", Target = "HostsUILib")]
|
||||
[assembly: SuppressMessage("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "MVVMTK0045:Using [ObservableProperty] on fields is not AOT compatible for WinRT", Justification = "Updated MVVM toolkit package introduced this.", Scope = "namespaceanddescendants", Target = "EnvironmentVariablesUILib")]
|
||||
[assembly: SuppressMessage("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "MVVMTK0045:Using [ObservableProperty] on fields is not AOT compatible for WinRT", Justification = "Updated MVVM toolkit package introduced this.", Scope = "namespaceanddescendants", Target = "Peek.FilePreviewer")]
|
||||
[assembly: SuppressMessage("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "MVVMTK0045:Using [ObservableProperty] on fields is not AOT compatible for WinRT", Justification = "Updated MVVM toolkit package introduced this.", Scope = "namespaceanddescendants", Target = "Peek.UI")]
|
||||
[assembly: SuppressMessage("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "MVVMTK0045:Using [ObservableProperty] on fields is not AOT compatible for WinRT", Justification = "Updated MVVM toolkit package introduced this.", Scope = "namespaceanddescendants", Target = "Peek.UI.Views")]
|
||||
[assembly: SuppressMessage("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "MVVMTK0045:Using [ObservableProperty] on fields is not AOT compatible for WinRT", Justification = "Updated MVVM toolkit package introduced this.", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib")]
|
||||
|
||||
// AOT MVVMTK0049
|
||||
[assembly: SuppressMessage("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "MVVMTK0049:Using [INotifyPropertyChanged] is not AOT compatible for WinRT", Justification = "Updated MVVM toolkit package introduced this.", Scope = "namespaceanddescendants", Target = "Peek.FilePreviewer")]
|
||||
[assembly: SuppressMessage("CommunityToolkit.Mvvm.SourceGenerators.INotifyPropertyChangedGenerator", "MVVMTK0049:Using [INotifyPropertyChanged] is not AOT compatible for WinRT", Justification = "Updated MVVM toolkit package introduced this.", Scope = "type", Target = "~T:Peek.UI.Views.TitleBar")]
|
||||
[assembly: SuppressMessage("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "MVVMTK0049:Using [INotifyPropertyChanged] is not AOT compatible for WinRT", Justification = "Updated MVVM toolkit package introduced this.", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib")]
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace AllExperiments
|
||||
}
|
||||
|
||||
// Using InvariantCulture since this is used for a log file name
|
||||
var logFilePath = Path.Combine(ApplicationLogPath, "Log_" + DateTime.Now.ToString(@"yyyy-MM-dd", CultureInfo.InvariantCulture) + ".txt");
|
||||
var logFilePath = Path.Combine(ApplicationLogPath, "Log_" + DateTime.Now.ToString(@"yyyy-MM-dd", CultureInfo.InvariantCulture) + ".log");
|
||||
|
||||
Trace.Listeners.Add(new TextWriterTraceListener(logFilePath));
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace ManagedCommon
|
||||
Directory.CreateDirectory(applicationLogPath);
|
||||
}
|
||||
|
||||
var logFilePath = Path.Combine(applicationLogPath, "Log_" + DateTime.Now.ToString(@"yyyy-MM-dd", CultureInfo.InvariantCulture) + ".txt");
|
||||
var logFilePath = Path.Combine(applicationLogPath, "Log_" + DateTime.Now.ToString(@"yyyy-MM-dd", CultureInfo.InvariantCulture) + ".log");
|
||||
|
||||
Trace.Listeners.Add(new TextWriterTraceListener(logFilePath));
|
||||
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
<PackageReference Include="Appium.WebDriver" />
|
||||
<PackageReference Include="MSTest" />
|
||||
<PackageReference Include="System.IO.Abstractions" />
|
||||
<PackageReference Include="System.Net.Http" />
|
||||
<PackageReference Include="System.Private.Uri" />
|
||||
<PackageReference Include="System.Text.RegularExpressions" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -8,49 +8,49 @@ struct LogSettings
|
||||
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::wstring runnerLogPath = L"RunnerLogs\\runner-log.log";
|
||||
inline const static std::string actionRunnerLoggerName = "action-runner";
|
||||
inline const static std::wstring actionRunnerLogPath = L"RunnerLogs\\action-runner-log.txt";
|
||||
inline const static std::wstring actionRunnerLogPath = L"RunnerLogs\\action-runner-log.log";
|
||||
inline const static std::string updateLoggerName = "update";
|
||||
inline const static std::wstring updateLogPath = L"UpdateLogs\\update-log.txt";
|
||||
inline const static std::wstring updateLogPath = L"UpdateLogs\\update-log.log";
|
||||
inline const static std::string fileExplorerLoggerName = "FileExplorer";
|
||||
inline const static std::wstring fileExplorerLogPath = L"Logs\\file-explorer-log.txt";
|
||||
inline const static std::wstring fileExplorerLogPath = L"Logs\\file-explorer-log.log";
|
||||
inline const static std::string gcodePrevLoggerName = "GcodePrevHandler";
|
||||
inline const static std::wstring gcodePrevLogPath = L"logs\\FileExplorer_localLow\\GcodePreviewHandler\\gcode-prev-handler-log.txt";
|
||||
inline const static std::wstring gcodePrevLogPath = L"logs\\FileExplorer_localLow\\GcodePreviewHandler\\gcode-prev-handler-log.log";
|
||||
inline const static std::string gcodeThumbLoggerName = "GcodeThumbnailProvider";
|
||||
inline const static std::wstring gcodeThumbLogPath = L"logs\\FileExplorer_localLow\\GcodeThumbnailProvider\\gcode-thumbnail-provider-log.txt";
|
||||
inline const static std::wstring gcodeThumbLogPath = L"logs\\FileExplorer_localLow\\GcodeThumbnailProvider\\gcode-thumbnail-provider-log.log";
|
||||
inline const static std::string mdPrevLoggerName = "MDPrevHandler";
|
||||
inline const static std::wstring mdPrevLogPath = L"logs\\FileExplorer_localLow\\MDPrevHandler\\md-prev-handler-log.txt";
|
||||
inline const static std::wstring mdPrevLogPath = L"logs\\FileExplorer_localLow\\MDPrevHandler\\md-prev-handler-log.log";
|
||||
inline const static std::string monacoPrevLoggerName = "MonacoPrevHandler";
|
||||
inline const static std::wstring monacoPrevLogPath = L"logs\\FileExplorer_localLow\\MonacoPrevHandler\\monaco-prev-handler-log.txt";
|
||||
inline const static std::wstring monacoPrevLogPath = L"logs\\FileExplorer_localLow\\MonacoPrevHandler\\monaco-prev-handler-log.log";
|
||||
inline const static std::string pdfPrevLoggerName = "PdfPrevHandler";
|
||||
inline const static std::wstring pdfPrevLogPath = L"logs\\FileExplorer_localLow\\PdfPrevHandler\\pdf-prev-handler-log.txt";
|
||||
inline const static std::wstring pdfPrevLogPath = L"logs\\FileExplorer_localLow\\PdfPrevHandler\\pdf-prev-handler-log.log";
|
||||
inline const static std::string pdfThumbLoggerName = "PdfThumbnailProvider";
|
||||
inline const static std::wstring pdfThumbLogPath = L"logs\\FileExplorer_localLow\\PdfThumbnailProvider\\pdf-thumbnail-provider-log.txt";
|
||||
inline const static std::wstring pdfThumbLogPath = L"logs\\FileExplorer_localLow\\PdfThumbnailProvider\\pdf-thumbnail-provider-log.log";
|
||||
inline const static std::string qoiPrevLoggerName = "QoiPrevHandler";
|
||||
inline const static std::wstring qoiPrevLogPath = L"logs\\FileExplorer_localLow\\QoiPreviewHandler\\qoi-prev-handler-log.txt";
|
||||
inline const static std::wstring qoiPrevLogPath = L"logs\\FileExplorer_localLow\\QoiPreviewHandler\\qoi-prev-handler-log.log";
|
||||
inline const static std::string qoiThumbLoggerName = "QoiThumbnailProvider";
|
||||
inline const static std::wstring qoiThumbLogPath = L"logs\\FileExplorer_localLow\\QoiThumbnailProvider\\qoi-thumbnail-provider-log.txt";
|
||||
inline const static std::wstring qoiThumbLogPath = L"logs\\FileExplorer_localLow\\QoiThumbnailProvider\\qoi-thumbnail-provider-log.log";
|
||||
inline const static std::string stlThumbLoggerName = "StlThumbnailProvider";
|
||||
inline const static std::wstring stlThumbLogPath = L"logs\\FileExplorer_localLow\\StlThumbnailProvider\\stl-thumbnail-provider-log.txt";
|
||||
inline const static std::wstring stlThumbLogPath = L"logs\\FileExplorer_localLow\\StlThumbnailProvider\\stl-thumbnail-provider-log.log";
|
||||
inline const static std::string svgPrevLoggerName = "SvgPrevHandler";
|
||||
inline const static std::wstring svgPrevLogPath = L"logs\\FileExplorer_localLow\\SvgPrevHandler\\svg-prev-handler-log.txt";
|
||||
inline const static std::wstring svgPrevLogPath = L"logs\\FileExplorer_localLow\\SvgPrevHandler\\svg-prev-handler-log.log";
|
||||
inline const static std::string svgThumbLoggerName = "SvgThumbnailProvider";
|
||||
inline const static std::wstring svgThumbLogPath = L"logs\\FileExplorer_localLow\\SvgThumbnailProvider\\svg-thumbnail-provider-log.txt";
|
||||
inline const static std::wstring svgThumbLogPath = L"logs\\FileExplorer_localLow\\SvgThumbnailProvider\\svg-thumbnail-provider-log.log";
|
||||
inline const static std::string launcherLoggerName = "launcher";
|
||||
inline const static std::wstring launcherLogPath = L"LogsModuleInterface\\launcher-log.txt";
|
||||
inline const static std::wstring launcherLogPath = L"LogsModuleInterface\\launcher-log.log";
|
||||
inline const static std::string mouseWithoutBordersLoggerName = "mouseWithoutBorders";
|
||||
inline const static std::wstring mouseWithoutBordersLogPath = L"LogsModuleInterface\\mouseWithoutBorders-log.txt";
|
||||
inline const static std::wstring awakeLogPath = L"Logs\\awake-log.txt";
|
||||
inline const static std::wstring powerAccentLogPath = L"quick-accent-log.txt";
|
||||
inline const static std::wstring mouseWithoutBordersLogPath = L"LogsModuleInterface\\mouseWithoutBorders-log.log";
|
||||
inline const static std::wstring awakeLogPath = L"Logs\\awake-log.log";
|
||||
inline const static std::wstring powerAccentLogPath = L"quick-accent-log.log";
|
||||
inline const static std::string fancyZonesLoggerName = "fancyzones";
|
||||
inline const static std::wstring fancyZonesLogPath = L"fancyzones-log.txt";
|
||||
inline const static std::wstring fancyZonesLogPath = L"fancyzones-log.log";
|
||||
inline const static std::wstring fancyZonesOldLogPath = L"FancyZonesLogs\\"; // needed to clean up old logs
|
||||
inline const static std::string shortcutGuideLoggerName = "shortcut-guide";
|
||||
inline const static std::wstring shortcutGuideLogPath = L"ShortcutGuideLogs\\shortcut-guide-log.txt";
|
||||
inline const static std::wstring powerOcrLogPath = L"Logs\\text-extractor-log.txt";
|
||||
inline const static std::wstring shortcutGuideLogPath = L"ShortcutGuideLogs\\shortcut-guide-log.log";
|
||||
inline const static std::wstring powerOcrLogPath = L"Logs\\text-extractor-log.log";
|
||||
inline const static std::string keyboardManagerLoggerName = "keyboard-manager";
|
||||
inline const static std::wstring keyboardManagerLogPath = L"Logs\\keyboard-manager-log.txt";
|
||||
inline const static std::wstring keyboardManagerLogPath = L"Logs\\keyboard-manager-log.log";
|
||||
inline const static std::string findMyMouseLoggerName = "find-my-mouse";
|
||||
inline const static std::string mouseHighlighterLoggerName = "mouse-highlighter";
|
||||
inline const static std::string mouseJumpLoggerName = "mouse-jump";
|
||||
@@ -60,22 +60,22 @@ struct LogSettings
|
||||
inline const static std::string alwaysOnTopLoggerName = "always-on-top";
|
||||
inline const static std::string powerOcrLoggerName = "TextExtractor";
|
||||
inline const static std::string fileLocksmithLoggerName = "FileLocksmith";
|
||||
inline const static std::wstring alwaysOnTopLogPath = L"always-on-top-log.txt";
|
||||
inline const static std::wstring alwaysOnTopLogPath = L"always-on-top-log.log";
|
||||
inline const static std::string hostsLoggerName = "hosts";
|
||||
inline const static std::wstring hostsLogPath = L"Logs\\hosts-log.txt";
|
||||
inline const static std::wstring hostsLogPath = L"Logs\\hosts-log.log";
|
||||
inline const static std::string registryPreviewLoggerName = "registrypreview";
|
||||
inline const static std::string cropAndLockLoggerName = "crop-and-lock";
|
||||
inline const static std::wstring registryPreviewLogPath = L"Logs\\registryPreview-log.txt";
|
||||
inline const static std::wstring registryPreviewLogPath = L"Logs\\registryPreview-log.log";
|
||||
inline const static std::string environmentVariablesLoggerName = "environment-variables";
|
||||
inline const static std::wstring cmdNotFoundLogPath = L"Logs\\cmd-not-found-log.txt";
|
||||
inline const static std::wstring cmdNotFoundLogPath = L"Logs\\cmd-not-found-log.log";
|
||||
inline const static std::string cmdNotFoundLoggerName = "cmd-not-found";
|
||||
inline const static std::string newLoggerName = "NewPlus";
|
||||
inline const static std::string workspacesLauncherLoggerName = "workspaces-launcher";
|
||||
inline const static std::wstring workspacesLauncherLogPath = L"workspaces-launcher-log.txt";
|
||||
inline const static std::wstring workspacesLauncherLogPath = L"workspaces-launcher-log.log";
|
||||
inline const static std::string workspacesWindowArrangerLoggerName = "workspaces-window-arranger";
|
||||
inline const static std::wstring workspacesWindowArrangerLogPath = L"workspaces-window-arranger-log.txt";
|
||||
inline const static std::wstring workspacesWindowArrangerLogPath = L"workspaces-window-arranger-log.log";
|
||||
inline const static std::string workspacesSnapshotToolLoggerName = "workspaces-snapshot-tool";
|
||||
inline const static std::wstring workspacesSnapshotToolLogPath = L"workspaces-snapshot-tool-log.txt";
|
||||
inline const static std::wstring workspacesSnapshotToolLogPath = L"workspaces-snapshot-tool-log.log";
|
||||
inline const static std::string zoomItLoggerName = "zoom-it";
|
||||
inline const static int retention = 30;
|
||||
std::wstring logLevel;
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace LoggerHelpers
|
||||
currentFolder.append(get_product_version());
|
||||
|
||||
auto logsPath = currentFolder;
|
||||
logsPath.append(L"log.txt");
|
||||
logsPath.append(L"log.log");
|
||||
Logger::init(loggerName, logsPath.wstring(), PTSettingsHelper::get_log_settings_file_location());
|
||||
|
||||
delete_other_versions_log_folders(rootFolder.wstring(), currentFolder);
|
||||
|
||||
@@ -2,11 +2,14 @@
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
#include <appxpackaging.h>
|
||||
#include <exception>
|
||||
#include <filesystem>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include <optional>
|
||||
#include <Shlwapi.h>
|
||||
#include <wrl/client.h>
|
||||
|
||||
#include <winrt/Windows.ApplicationModel.h>
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
@@ -15,11 +18,12 @@
|
||||
#include "../logger/logger.h"
|
||||
#include "../version/version.h"
|
||||
|
||||
namespace package {
|
||||
|
||||
namespace package
|
||||
{
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::ApplicationModel;
|
||||
using namespace winrt::Windows::Management::Deployment;
|
||||
using Microsoft::WRL::ComPtr;
|
||||
|
||||
inline BOOL IsWin11OrGreater()
|
||||
{
|
||||
@@ -46,6 +50,118 @@ namespace package {
|
||||
dwlConditionMask);
|
||||
}
|
||||
|
||||
struct PACKAGE_VERSION
|
||||
{
|
||||
UINT16 Major;
|
||||
UINT16 Minor;
|
||||
UINT16 Build;
|
||||
UINT16 Revision;
|
||||
};
|
||||
|
||||
class ComInitializer
|
||||
{
|
||||
public:
|
||||
explicit ComInitializer(DWORD coInitFlags = COINIT_MULTITHREADED) :
|
||||
_initialized(false)
|
||||
{
|
||||
const HRESULT hr = CoInitializeEx(nullptr, coInitFlags);
|
||||
_initialized = SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
~ComInitializer()
|
||||
{
|
||||
if (_initialized)
|
||||
{
|
||||
CoUninitialize();
|
||||
}
|
||||
}
|
||||
|
||||
bool Succeeded() const { return _initialized; }
|
||||
|
||||
private:
|
||||
bool _initialized;
|
||||
};
|
||||
|
||||
inline bool GetPackageNameAndVersionFromAppx(
|
||||
const std::wstring& appxPath,
|
||||
std::wstring& outName,
|
||||
PACKAGE_VERSION& outVersion)
|
||||
{
|
||||
try
|
||||
{
|
||||
ComInitializer comInit;
|
||||
if (!comInit.Succeeded())
|
||||
{
|
||||
Logger::error(L"COM initialization failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
ComPtr<IAppxFactory> factory;
|
||||
ComPtr<IStream> stream;
|
||||
ComPtr<IAppxPackageReader> reader;
|
||||
ComPtr<IAppxManifestReader> manifest;
|
||||
ComPtr<IAppxManifestPackageId> packageId;
|
||||
|
||||
HRESULT hr = CoCreateInstance(__uuidof(AppxFactory), nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&factory));
|
||||
if (FAILED(hr))
|
||||
return false;
|
||||
|
||||
hr = SHCreateStreamOnFileEx(appxPath.c_str(), STGM_READ | STGM_SHARE_DENY_WRITE, FILE_ATTRIBUTE_NORMAL, FALSE, nullptr, &stream);
|
||||
if (FAILED(hr))
|
||||
return false;
|
||||
|
||||
hr = factory->CreatePackageReader(stream.Get(), &reader);
|
||||
if (FAILED(hr))
|
||||
return false;
|
||||
|
||||
hr = reader->GetManifest(&manifest);
|
||||
if (FAILED(hr))
|
||||
return false;
|
||||
|
||||
hr = manifest->GetPackageId(&packageId);
|
||||
if (FAILED(hr))
|
||||
return false;
|
||||
|
||||
LPWSTR name = nullptr;
|
||||
hr = packageId->GetName(&name);
|
||||
if (FAILED(hr))
|
||||
return false;
|
||||
|
||||
UINT64 version = 0;
|
||||
hr = packageId->GetVersion(&version);
|
||||
if (FAILED(hr))
|
||||
return false;
|
||||
|
||||
outName = std::wstring(name);
|
||||
CoTaskMemFree(name);
|
||||
|
||||
outVersion.Major = static_cast<UINT16>((version >> 48) & 0xFFFF);
|
||||
outVersion.Minor = static_cast<UINT16>((version >> 32) & 0xFFFF);
|
||||
outVersion.Build = static_cast<UINT16>((version >> 16) & 0xFFFF);
|
||||
outVersion.Revision = static_cast<UINT16>(version & 0xFFFF);
|
||||
|
||||
Logger::info(L"Package name: {}, version: {}.{}.{}.{}, appxPath: {}",
|
||||
outName,
|
||||
outVersion.Major,
|
||||
outVersion.Minor,
|
||||
outVersion.Build,
|
||||
outVersion.Revision,
|
||||
appxPath);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
Logger::error(L"Standard exception: {}", winrt::to_hstring(ex.what()));
|
||||
return false;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
Logger::error(L"Unknown or non-standard exception occurred.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline std::optional<Package> GetRegisteredPackage(std::wstring packageDisplayName, bool checkVersion)
|
||||
{
|
||||
PackageManager packageManager;
|
||||
@@ -229,6 +345,59 @@ namespace package {
|
||||
return matchedFiles;
|
||||
}
|
||||
|
||||
inline bool IsPackageSatisfied(const std::wstring& appxPath)
|
||||
{
|
||||
std::wstring targetName;
|
||||
PACKAGE_VERSION targetVersion{};
|
||||
|
||||
if (!GetPackageNameAndVersionFromAppx(appxPath, targetName, targetVersion))
|
||||
{
|
||||
Logger::error(L"Failed to get package name and version from appx: " + appxPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
PackageManager pm;
|
||||
|
||||
for (const auto& package : pm.FindPackagesForUser({}))
|
||||
{
|
||||
const auto& id = package.Id();
|
||||
if (std::wstring(id.Name()) == targetName)
|
||||
{
|
||||
const auto& version = id.Version();
|
||||
|
||||
if (version.Major > targetVersion.Major ||
|
||||
(version.Major == targetVersion.Major && version.Minor > targetVersion.Minor) ||
|
||||
(version.Major == targetVersion.Major && version.Minor == targetVersion.Minor && version.Build > targetVersion.Build) ||
|
||||
(version.Major == targetVersion.Major && version.Minor == targetVersion.Minor && version.Build == targetVersion.Build && version.Revision >= targetVersion.Revision))
|
||||
{
|
||||
Logger::info(
|
||||
L"Package {} is already satisfied with version {}.{}.{}.{}; target version {}.{}.{}.{}; appxPath: {}",
|
||||
id.Name(),
|
||||
version.Major,
|
||||
version.Minor,
|
||||
version.Build,
|
||||
version.Revision,
|
||||
targetVersion.Major,
|
||||
targetVersion.Minor,
|
||||
targetVersion.Build,
|
||||
targetVersion.Revision,
|
||||
appxPath);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Logger::info(
|
||||
L"Package {} is not satisfied. Target version: {}.{}.{}.{}; appxPath: {}",
|
||||
targetName,
|
||||
targetVersion.Major,
|
||||
targetVersion.Minor,
|
||||
targetVersion.Build,
|
||||
targetVersion.Revision,
|
||||
appxPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool RegisterPackage(std::wstring pkgPath, std::vector<std::wstring> dependencies)
|
||||
{
|
||||
try
|
||||
@@ -238,7 +407,7 @@ namespace package {
|
||||
PackageManager packageManager;
|
||||
|
||||
// Declare use of an external location
|
||||
DeploymentOptions options = DeploymentOptions::ForceApplicationShutdown;
|
||||
DeploymentOptions options = DeploymentOptions::ForceTargetApplicationShutdown;
|
||||
|
||||
Collections::IVector<Uri> uris = winrt::single_threaded_vector<Uri>();
|
||||
if (!dependencies.empty())
|
||||
@@ -247,7 +416,14 @@ namespace package {
|
||||
{
|
||||
try
|
||||
{
|
||||
uris.Append(Uri(dependency));
|
||||
if (IsPackageSatisfied(dependency))
|
||||
{
|
||||
Logger::info(L"Dependency already satisfied: {}", dependency);
|
||||
}
|
||||
else
|
||||
{
|
||||
uris.Append(Uri(dependency));
|
||||
}
|
||||
}
|
||||
catch (const winrt::hresult_error& ex)
|
||||
{
|
||||
@@ -282,7 +458,6 @@ namespace package {
|
||||
{
|
||||
Logger::debug(L"Register {} package started.", pkgPath);
|
||||
}
|
||||
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
@@ -293,4 +468,4 @@ namespace package {
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
<ProjectPriFileName>PowerToys.EnvironmentVariablesUILib.pri</ProjectPriFileName>
|
||||
<GenerateLibraryLayout>true</GenerateLibraryLayout>
|
||||
<IsPackable>true</IsPackable>
|
||||
<!-- The default generated file path exceeds the length limit 260 on the build agent. Using a shorter path as a workaround. -->
|
||||
<CompilerGeneratedFilesOutputPath>$(ProjectDir)obj\g</CompilerGeneratedFilesOutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
@@ -56,7 +54,4 @@
|
||||
<Manifest Include="$(ApplicationManifest)" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="EnsureCompilerGeneratedFilesOutputPathExists" BeforeTargets="XamlPreCompile">
|
||||
<MakeDir Directories="$(CompilerGeneratedFilesOutputPath)" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MSTest" />
|
||||
<PackageReference Include="System.Net.Http" />
|
||||
<PackageReference Include="System.Private.Uri" />
|
||||
<PackageReference Include="System.Text.RegularExpressions" />
|
||||
<ProjectReference Include="..\..\..\common\UITestAutomation\UITestAutomation.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
EXPORTS
|
||||
DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE
|
||||
DllGetActivationFactory = WINRT_GetActivationFactory PRIVATE
|
||||
@@ -0,0 +1,40 @@
|
||||
#include <windows.h>
|
||||
#include "resource.h"
|
||||
#include "../../../common/version/version.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
#include "winres.h"
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
1 VERSIONINFO
|
||||
FILEVERSION FILE_VERSION
|
||||
PRODUCTVERSION PRODUCT_VERSION
|
||||
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS VS_FF_DEBUG
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS VOS_NT_WINDOWS32
|
||||
FILETYPE VFT_DLL
|
||||
FILESUBTYPE VFT2_UNKNOWN
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0" // US English (0x0409), Unicode (0x04B0) charset
|
||||
BEGIN
|
||||
VALUE "CompanyName", COMPANY_NAME
|
||||
VALUE "FileDescription", FILE_DESCRIPTION
|
||||
VALUE "FileVersion", FILE_VERSION_STRING
|
||||
VALUE "InternalName", INTERNAL_NAME
|
||||
VALUE "LegalCopyright", COPYRIGHT_NOTE
|
||||
VALUE "OriginalFilename", ORIGINAL_FILENAME
|
||||
VALUE "ProductName", PRODUCT_NAME
|
||||
VALUE "ProductVersion", PRODUCT_VERSION_STRING
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200 // US English (0x0409), Unicode (1200) charset
|
||||
END
|
||||
END
|
||||
@@ -0,0 +1,187 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0"
|
||||
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props')" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge>
|
||||
<CppWinRTGenerateWindowsMetadata>true</CppWinRTGenerateWindowsMetadata>
|
||||
<ProjectGuid>{5f63c743-f6ce-4dba-a200-2b3f8a14e8c2}</ProjectGuid>
|
||||
<ProjectName>CmdPalKeyboardService</ProjectName>
|
||||
<RootNamespace>CmdPalKeyboardService</RootNamespace>
|
||||
<AppxPackage>false</AppxPackage>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- BEGIN common.build.pre.props -->
|
||||
<PropertyGroup Label="Configuration">
|
||||
<EnableHybridCRT>true</EnableHybridCRT>
|
||||
<UseCrtSDKReferenceStaticWarning Condition="'$(EnableHybridCRT)'=='true'">false</UseCrtSDKReferenceStaticWarning>
|
||||
</PropertyGroup>
|
||||
<!-- END common.build.pre.props -->
|
||||
<!-- BEGIN cppwinrt.build.pre.props -->
|
||||
<PropertyGroup Label="Globals">
|
||||
<CppWinRTEnabled>true</CppWinRTEnabled>
|
||||
<CppWinRTOptimized>true</CppWinRTOptimized>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
<MinimumVisualStudioVersion>17.0</MinimumVisualStudioVersion>
|
||||
<ApplicationTypeRevision>10.0</ApplicationTypeRevision>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<MinimalCoreWin>true</MinimalCoreWin>
|
||||
<AppContainerApplication>true</AppContainerApplication>
|
||||
<WindowsStoreApp>true</WindowsStoreApp>
|
||||
<ApplicationType>Windows Store</ApplicationType>
|
||||
<UseCrtSDKReference Condition="'$(EnableHybridCRT)'=='true'">false</UseCrtSDKReference> <!-- The SDK reference breaks the Hybrid CRT -->
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<!-- We have to use the Desktop platform for Hybrid CRT to work. -->
|
||||
<_VC_Target_Library_Platform>Desktop</_VC_Target_Library_Platform>
|
||||
<_NoWinAPIFamilyApp>true</_NoWinAPIFamilyApp>
|
||||
</PropertyGroup>
|
||||
<!-- END cppwinrt.build.pre.props -->
|
||||
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="PropertySheet.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<TargetName>CmdPalKeyboardService</TargetName>
|
||||
<OutDir>..\..\..\..\$(Platform)\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<AdditionalOptions>%(AdditionalOptions) /bigobj</AdditionalOptions>
|
||||
<PreprocessorDefinitions>_WINRT_DLL;WINRT_LEAN_AND_MEAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>../../..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateWindowsMetadata>false</GenerateWindowsMetadata>
|
||||
<ModuleDefinitionFile>CmdPalKeyboardService.def</ModuleDefinitionFile>
|
||||
<AdditionalDependencies>Shell32.lib;user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="KeyboardListener.h">
|
||||
<DependentUpon>KeyboardListener.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="KeyboardListener.cpp">
|
||||
<DependentUpon>KeyboardListener.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Midl Include="KeyboardListener.idl" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
<None Include="CmdPalKeyboardService.def" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="PropertySheet.props" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="CmdPalKeyboardService.rc" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<Import Project="..\..\..\..\deps\spdlog.props" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
</Target>
|
||||
|
||||
<!-- BEGIN common.build.post.props -->
|
||||
<!--
|
||||
The Hybrid CRT model statically links the runtime and STL and dynamically
|
||||
links the UCRT instead of the VC++ CRT. The UCRT ships with Windows.
|
||||
WinAppSDK asserts that this is "supported according to the CRT maintainer."
|
||||
|
||||
This must come before Microsoft.Cpp.targets because it manipulates ClCompile.RuntimeLibrary.
|
||||
-->
|
||||
<ItemDefinitionGroup Condition="'$(EnableHybridCRT)'=='true' and '$(Configuration)'=='Debug'">
|
||||
<ClCompile>
|
||||
<!-- We use MultiThreadedDebug, rather than MultiThreadedDebugDLL, to avoid DLL dependencies on VCRUNTIME140d.dll and MSVCP140d.dll. -->
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<!-- Link statically against the runtime and STL, but link dynamically against the CRT by ignoring the static CRT
|
||||
lib and instead linking against the Universal CRT DLL import library. This "hybrid" linking mechanism is
|
||||
supported according to the CRT maintainer. Dynamic linking against the CRT makes the binaries a bit smaller
|
||||
than they would otherwise be if the CRT, runtime, and STL were all statically linked in. -->
|
||||
<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries);libucrtd.lib</IgnoreSpecificDefaultLibraries>
|
||||
<AdditionalOptions>%(AdditionalOptions) /defaultlib:ucrtd.lib</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(EnableHybridCRT)'=='true' and ('$(Configuration)'=='Release' or '$(Configuration)'=='AuditMode')">
|
||||
<ClCompile>
|
||||
<!-- We use MultiThreaded, rather than MultiThreadedDLL, to avoid DLL dependencies on VCRUNTIME140.dll and MSVCP140.dll. -->
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<!-- Link statically against the runtime and STL, but link dynamically against the CRT by ignoring the static CRT
|
||||
lib and instead linking against the Universal CRT DLL import library. This "hybrid" linking mechanism is
|
||||
supported according to the CRT maintainer. Dynamic linking against the CRT makes the binaries a bit smaller
|
||||
than they would otherwise be if the CRT, runtime, and STL were all statically linked in. -->
|
||||
<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries);libucrt.lib</IgnoreSpecificDefaultLibraries>
|
||||
<AdditionalOptions>%(AdditionalOptions) /defaultlib:ucrt.lib</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<!-- END common.build.post.props -->
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0"
|
||||
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Resources">
|
||||
<UniqueIdentifier>accd3aa8-1ba0-4223-9bbe-0c431709210b</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Generated Files">
|
||||
<UniqueIdentifier>{926ab91d-31b4-48c3-b9a4-e681349f27f0}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="pch.cpp" />
|
||||
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Midl Include="KeyboardListener.idl" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="CmdPalKeyboardService.def" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="PropertySheet.props" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="CmdPalKeyboardService.rc">
|
||||
<Filter>Resources</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
165
src/modules/cmdpal/CmdPalKeyboardService/KeyboardListener.cpp
Normal file
165
src/modules/cmdpal/CmdPalKeyboardService/KeyboardListener.cpp
Normal file
@@ -0,0 +1,165 @@
|
||||
#include "pch.h"
|
||||
#include "KeyboardListener.h"
|
||||
#include "KeyboardListener.g.cpp"
|
||||
|
||||
// #include <common/logger/logger.h>
|
||||
// #include <common/utils/logger_helper.h>
|
||||
#include <common/utils/winapi_error.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
}
|
||||
|
||||
namespace winrt::CmdPalKeyboardService::implementation
|
||||
{
|
||||
KeyboardListener::KeyboardListener()
|
||||
{
|
||||
s_instance = this;
|
||||
}
|
||||
|
||||
void KeyboardListener::Start()
|
||||
{
|
||||
#if defined(DISABLE_LOWLEVEL_HOOKS_WHEN_DEBUGGED)
|
||||
const bool hook_disabled = IsDebuggerPresent();
|
||||
#else
|
||||
const bool hook_disabled = false;
|
||||
#endif
|
||||
if (!hook_disabled)
|
||||
{
|
||||
if (!s_llKeyboardHook)
|
||||
{
|
||||
s_llKeyboardHook = SetWindowsHookExW(WH_KEYBOARD_LL, LowLevelKeyboardProc, NULL, NULL);
|
||||
if (!s_llKeyboardHook)
|
||||
{
|
||||
DWORD errorCode = GetLastError();
|
||||
show_last_error_message(L"SetWindowsHookEx", errorCode, L"CmdPalKeyboardService");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KeyboardListener::Stop()
|
||||
{
|
||||
if (s_llKeyboardHook && UnhookWindowsHookEx(s_llKeyboardHook))
|
||||
{
|
||||
s_llKeyboardHook = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void KeyboardListener::SetHotkeyAction(bool win, bool ctrl, bool shift, bool alt, uint8_t key, hstring const& id)
|
||||
{
|
||||
Hotkey hotkey = { .win = win, .ctrl = ctrl, .shift = shift, .alt = alt, .key = key };
|
||||
std::unique_lock lock{ mutex };
|
||||
|
||||
HotkeyDescriptor desc = { .hotkey = hotkey, .id = std::wstring(id) };
|
||||
hotkeyDescriptors.insert(desc);
|
||||
}
|
||||
|
||||
void KeyboardListener::ClearHotkey(hstring const& id)
|
||||
{
|
||||
{
|
||||
std::unique_lock lock{ mutex };
|
||||
auto it = hotkeyDescriptors.begin();
|
||||
while (it != hotkeyDescriptors.end())
|
||||
{
|
||||
if (it->id == id)
|
||||
{
|
||||
it = hotkeyDescriptors.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KeyboardListener::ClearHotkeys()
|
||||
{
|
||||
{
|
||||
std::unique_lock lock{ mutex };
|
||||
auto it = hotkeyDescriptors.begin();
|
||||
while (it != hotkeyDescriptors.end())
|
||||
{
|
||||
it = hotkeyDescriptors.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KeyboardListener::SetProcessCommand(ProcessCommand processCommand)
|
||||
{
|
||||
m_processCommandCb = [trigger = std::move(processCommand)](hstring const& id) {
|
||||
trigger(id);
|
||||
};
|
||||
}
|
||||
|
||||
LRESULT KeyboardListener::DoLowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
const auto& keyPressInfo = *reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam);
|
||||
|
||||
if ((wParam != WM_KEYDOWN) && (wParam != WM_SYSKEYDOWN))
|
||||
{
|
||||
return CallNextHookEx(NULL, nCode, wParam, lParam);
|
||||
}
|
||||
|
||||
Hotkey hotkey{
|
||||
.win = (GetAsyncKeyState(VK_LWIN) & 0x8000) || (GetAsyncKeyState(VK_RWIN) & 0x8000),
|
||||
.ctrl = static_cast<bool>(GetAsyncKeyState(VK_CONTROL) & 0x8000),
|
||||
.shift = static_cast<bool>(GetAsyncKeyState(VK_SHIFT) & 0x8000),
|
||||
.alt = static_cast<bool>(GetAsyncKeyState(VK_MENU) & 0x8000),
|
||||
.key = static_cast<unsigned char>(keyPressInfo.vkCode)
|
||||
};
|
||||
|
||||
if (hotkey == Hotkey{})
|
||||
{
|
||||
return CallNextHookEx(NULL, nCode, wParam, lParam);
|
||||
}
|
||||
|
||||
bool do_action = false;
|
||||
std::wstring actionId{};
|
||||
|
||||
{
|
||||
// Hold the lock for the shortest possible duration
|
||||
std::unique_lock lock{ mutex };
|
||||
HotkeyDescriptor dummy{ .hotkey = hotkey };
|
||||
auto it = hotkeyDescriptors.find(dummy);
|
||||
if (it != hotkeyDescriptors.end())
|
||||
{
|
||||
do_action = true;
|
||||
actionId = it->id;
|
||||
}
|
||||
}
|
||||
|
||||
if (do_action)
|
||||
{
|
||||
m_processCommandCb(hstring{ actionId });
|
||||
|
||||
// After invoking the hotkey send a dummy key to prevent Start Menu from activating
|
||||
INPUT dummyEvent[1] = {};
|
||||
dummyEvent[0].type = INPUT_KEYBOARD;
|
||||
dummyEvent[0].ki.wVk = 0xFF;
|
||||
dummyEvent[0].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
SendInput(1, dummyEvent, sizeof(INPUT));
|
||||
|
||||
// Swallow the key press
|
||||
return 1;
|
||||
}
|
||||
|
||||
return CallNextHookEx(NULL, nCode, wParam, lParam);
|
||||
}
|
||||
|
||||
LRESULT KeyboardListener::LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (s_instance == nullptr)
|
||||
{
|
||||
return CallNextHookEx(NULL, nCode, wParam, lParam);
|
||||
}
|
||||
|
||||
if (nCode < 0)
|
||||
{
|
||||
return CallNextHookEx(NULL, nCode, wParam, lParam);
|
||||
}
|
||||
|
||||
return s_instance->DoLowLevelKeyboardProc(nCode, wParam, lParam);
|
||||
}
|
||||
}
|
||||
67
src/modules/cmdpal/CmdPalKeyboardService/KeyboardListener.h
Normal file
67
src/modules/cmdpal/CmdPalKeyboardService/KeyboardListener.h
Normal file
@@ -0,0 +1,67 @@
|
||||
#pragma once
|
||||
|
||||
#include "KeyboardListener.g.h"
|
||||
#include <mutex>
|
||||
#include <spdlog/stopwatch.h>
|
||||
#include <set>
|
||||
|
||||
namespace winrt::CmdPalKeyboardService::implementation
|
||||
{
|
||||
struct KeyboardListener : KeyboardListenerT<KeyboardListener>
|
||||
{
|
||||
struct Hotkey
|
||||
{
|
||||
bool win = false;
|
||||
bool ctrl = false;
|
||||
bool shift = false;
|
||||
bool alt = false;
|
||||
unsigned char key = 0;
|
||||
|
||||
std::strong_ordering operator<=>(const Hotkey&) const = default;
|
||||
};
|
||||
|
||||
struct HotkeyDescriptor
|
||||
{
|
||||
Hotkey hotkey;
|
||||
std::wstring id;
|
||||
|
||||
bool operator<(const HotkeyDescriptor& other) const
|
||||
{
|
||||
return hotkey < other.hotkey;
|
||||
};
|
||||
};
|
||||
|
||||
KeyboardListener();
|
||||
|
||||
void Start();
|
||||
void Stop();
|
||||
void SetHotkeyAction(bool win, bool ctrl, bool shift, bool alt, uint8_t key, hstring const& id);
|
||||
void ClearHotkey(hstring const& id);
|
||||
void ClearHotkeys();
|
||||
void SetProcessCommand(ProcessCommand processCommand);
|
||||
|
||||
static LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
private:
|
||||
LRESULT CALLBACK DoLowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
static inline KeyboardListener* s_instance;
|
||||
HHOOK s_llKeyboardHook = nullptr;
|
||||
|
||||
// Max DWORD for key code to disable keys.
|
||||
const DWORD VK_DISABLED = 0x100;
|
||||
DWORD vkCodePressed = VK_DISABLED;
|
||||
|
||||
std::multiset<HotkeyDescriptor> hotkeyDescriptors;
|
||||
std::mutex mutex;
|
||||
|
||||
std::function<void(hstring const&)> m_processCommandCb;
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::CmdPalKeyboardService::factory_implementation
|
||||
{
|
||||
struct KeyboardListener : KeyboardListenerT<KeyboardListener, implementation::KeyboardListener>
|
||||
{
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
|
||||
namespace CmdPalKeyboardService
|
||||
{
|
||||
[version(1.0), uuid(78ab07cd-e128-4e73-86aa-e48e6b6d01ff)] delegate void ProcessCommand(String id);
|
||||
|
||||
[default_interface] runtimeclass KeyboardListener {
|
||||
KeyboardListener();
|
||||
void Start();
|
||||
void Stop();
|
||||
|
||||
void SetHotkeyAction(Boolean win, Boolean ctrl, Boolean shift, Boolean alt, UInt8 key, String id);
|
||||
void ClearHotkey(String id);
|
||||
void ClearHotkeys();
|
||||
void SetProcessCommand(ProcessCommand processCommand);
|
||||
}
|
||||
}
|
||||
17
src/modules/cmdpal/CmdPalKeyboardService/PropertySheet.props
Normal file
17
src/modules/cmdpal/CmdPalKeyboardService/PropertySheet.props
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0"
|
||||
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ImportGroup Label="PropertySheets" />
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<!--
|
||||
To customize common C++/WinRT project properties:
|
||||
* right-click the project node
|
||||
* expand the Common Properties item
|
||||
* select the C++/WinRT property page
|
||||
|
||||
For more advanced scenarios, and complete documentation, please see:
|
||||
https://github.com/Microsoft/cppwinrt/tree/master/nuget
|
||||
-->
|
||||
<PropertyGroup />
|
||||
<ItemDefinitionGroup />
|
||||
</Project>
|
||||
4
src/modules/cmdpal/CmdPalKeyboardService/packages.config
Normal file
4
src/modules/cmdpal/CmdPalKeyboardService/packages.config
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.240111.5" targetFramework="native" />
|
||||
</packages>
|
||||
1
src/modules/cmdpal/CmdPalKeyboardService/pch.cpp
Normal file
1
src/modules/cmdpal/CmdPalKeyboardService/pch.cpp
Normal file
@@ -0,0 +1 @@
|
||||
#include "pch.h"
|
||||
4
src/modules/cmdpal/CmdPalKeyboardService/pch.h
Normal file
4
src/modules/cmdpal/CmdPalKeyboardService/pch.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
#include <Unknwn.h>
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
13
src/modules/cmdpal/CmdPalKeyboardService/resource.h
Normal file
13
src/modules/cmdpal/CmdPalKeyboardService/resource.h
Normal file
@@ -0,0 +1,13 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by PowerToys.MeasureToolCore.rc
|
||||
|
||||
//////////////////////////////
|
||||
// Non-localizable
|
||||
|
||||
#define FILE_DESCRIPTION "CmdPalKeyboardService"
|
||||
#define INTERNAL_NAME "CmdPalKeyboardService"
|
||||
#define ORIGINAL_FILENAME "CmdPalKeyboardService.dll"
|
||||
|
||||
// Non-localizable
|
||||
//////////////////////////////
|
||||
@@ -207,12 +207,16 @@ public:
|
||||
|
||||
try
|
||||
{
|
||||
if (!package::GetRegisteredPackage(L"Microsoft.CommandPalette", false).has_value())
|
||||
std::wstring packageName = L"Microsoft.CommandPalette";
|
||||
#ifdef _DEBUG
|
||||
packageName = L"Microsoft.CommandPalette.Dev";
|
||||
#endif
|
||||
if (!package::GetRegisteredPackage(packageName, false).has_value())
|
||||
{
|
||||
Logger::info(L"CmdPal not installed. Installing...");
|
||||
|
||||
std::wstring installationFolder = get_module_folderpath();
|
||||
#if _DEBUG
|
||||
#ifdef _DEBUG
|
||||
std::wstring archSubdir = L"x64";
|
||||
#ifdef _M_ARM64
|
||||
archSubdir = L"ARM64";
|
||||
|
||||
@@ -1,177 +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;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using Microsoft.CmdPal.Ext.Calc.Properties;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using Windows.Foundation;
|
||||
|
||||
namespace Microsoft.CmdPal.Ext.Calc;
|
||||
|
||||
public partial class CalculatorCommandProvider : CommandProvider
|
||||
{
|
||||
private readonly ListItem _listItem = new(new CalculatorListPage()) { Subtitle = Resources.calculator_top_level_subtitle };
|
||||
private readonly FallbackCalculatorItem _fallback = new();
|
||||
|
||||
public CalculatorCommandProvider()
|
||||
{
|
||||
Id = "Calculator";
|
||||
DisplayName = Resources.calculator_display_name;
|
||||
Icon = IconHelpers.FromRelativePath("Assets\\Calculator.svg");
|
||||
}
|
||||
|
||||
public override ICommandItem[] TopLevelCommands() => [_listItem];
|
||||
|
||||
public override IFallbackCommandItem[] FallbackCommands() => [_fallback];
|
||||
}
|
||||
|
||||
// The calculator page is a dynamic list page
|
||||
// * The first command is where we display the results. Title=result, Subtitle=query
|
||||
// - The default command is `SaveCommand`.
|
||||
// - When you save, insert into list at spot 1
|
||||
// - change SearchText to the result
|
||||
// - MoreCommands: a single `CopyCommand` to copy the result to the clipboard
|
||||
// * The rest of the items are previously saved results
|
||||
// - Command is a CopyCommand
|
||||
// - Each item also sets the TextToSuggest to the result
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "This is sample code")]
|
||||
public sealed partial class CalculatorListPage : DynamicListPage
|
||||
{
|
||||
private readonly List<ListItem> _items = [];
|
||||
private readonly SaveCommand _saveCommand = new();
|
||||
private readonly CopyTextCommand _copyContextCommand;
|
||||
private readonly CommandContextItem _copyContextMenuItem;
|
||||
private static readonly CompositeFormat ErrorMessage = System.Text.CompositeFormat.Parse(Properties.Resources.calculator_error);
|
||||
|
||||
public CalculatorListPage()
|
||||
{
|
||||
Icon = IconHelpers.FromRelativePath("Assets\\Calculator.svg");
|
||||
Name = Resources.calculator_title;
|
||||
PlaceholderText = Resources.calculator_placeholder_text;
|
||||
Id = "com.microsoft.cmdpal.calculator";
|
||||
|
||||
_copyContextCommand = new CopyTextCommand(string.Empty);
|
||||
_copyContextMenuItem = new CommandContextItem(_copyContextCommand);
|
||||
|
||||
_items.Add(new(_saveCommand) { Icon = new IconInfo("\uE94E") });
|
||||
|
||||
UpdateSearchText(string.Empty, string.Empty);
|
||||
|
||||
_saveCommand.SaveRequested += HandleSave;
|
||||
}
|
||||
|
||||
private void HandleSave(object sender, object args)
|
||||
{
|
||||
var lastResult = _items[0].Title;
|
||||
if (!string.IsNullOrEmpty(lastResult))
|
||||
{
|
||||
var li = new ListItem(new CopyTextCommand(lastResult))
|
||||
{
|
||||
Title = _items[0].Title,
|
||||
Subtitle = _items[0].Subtitle,
|
||||
TextToSuggest = lastResult,
|
||||
};
|
||||
_items.Insert(1, li);
|
||||
_items[0].Subtitle = string.Empty;
|
||||
SearchText = lastResult;
|
||||
this.RaiseItemsChanged(this._items.Count);
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateSearchText(string oldSearch, string newSearch)
|
||||
{
|
||||
var firstItem = _items[0];
|
||||
if (string.IsNullOrEmpty(newSearch))
|
||||
{
|
||||
firstItem.Title = Resources.calculator_placeholder_text;
|
||||
firstItem.Subtitle = string.Empty;
|
||||
firstItem.MoreCommands = [];
|
||||
}
|
||||
else
|
||||
{
|
||||
_copyContextCommand.Text = ParseQuery(newSearch, out var result) ? result : string.Empty;
|
||||
firstItem.Title = result;
|
||||
firstItem.Subtitle = newSearch;
|
||||
firstItem.MoreCommands = [_copyContextMenuItem];
|
||||
}
|
||||
}
|
||||
|
||||
internal static bool ParseQuery(string equation, out string result)
|
||||
{
|
||||
try
|
||||
{
|
||||
var resultNumber = new DataTable().Compute(equation, null);
|
||||
result = resultNumber.ToString() ?? string.Empty;
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
result = string.Format(CultureInfo.CurrentCulture, ErrorMessage, e.Message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override IListItem[] GetItems() => _items.ToArray();
|
||||
}
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "This is sample code")]
|
||||
public sealed partial class SaveCommand : InvokableCommand
|
||||
{
|
||||
public event TypedEventHandler<object, object> SaveRequested;
|
||||
|
||||
public SaveCommand()
|
||||
{
|
||||
Name = Resources.calculator_save_command_name;
|
||||
}
|
||||
|
||||
public override ICommandResult Invoke()
|
||||
{
|
||||
SaveRequested?.Invoke(this, this);
|
||||
return CommandResult.KeepOpen();
|
||||
}
|
||||
}
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "This is sample code")]
|
||||
internal sealed partial class FallbackCalculatorItem : FallbackCommandItem
|
||||
{
|
||||
private readonly CopyTextCommand _copyCommand = new(string.Empty);
|
||||
private static readonly IconInfo _cachedIcon = IconHelpers.FromRelativePath("Assets\\Calculator.svg");
|
||||
|
||||
public FallbackCalculatorItem()
|
||||
: base(new NoOpCommand(), Resources.calculator_title)
|
||||
{
|
||||
Command = _copyCommand;
|
||||
_copyCommand.Name = string.Empty;
|
||||
Title = string.Empty;
|
||||
Subtitle = Resources.calculator_placeholder_text;
|
||||
Icon = _cachedIcon;
|
||||
}
|
||||
|
||||
public override void UpdateQuery(string query)
|
||||
{
|
||||
if (CalculatorListPage.ParseQuery(query, out var result))
|
||||
{
|
||||
_copyCommand.Text = result;
|
||||
_copyCommand.Name = string.IsNullOrWhiteSpace(query) ? string.Empty : Resources.calculator_copy_command_name;
|
||||
Title = result;
|
||||
|
||||
// we have to make the subtitle the equation,
|
||||
// so that we will still string match the original query
|
||||
// Otherwise, something like 1+2 will have a title of "3" and not match
|
||||
Subtitle = query;
|
||||
}
|
||||
else
|
||||
{
|
||||
_copyCommand.Text = string.Empty;
|
||||
_copyCommand.Name = string.Empty;
|
||||
Title = string.Empty;
|
||||
Subtitle = string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,51 +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.Threading.Tasks;
|
||||
using Microsoft.CmdPal.Ext.System.Helpers;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.Ext.System;
|
||||
|
||||
public sealed partial class SystemCommandsCache
|
||||
{
|
||||
public SystemCommandsCache(SettingsManager manager)
|
||||
{
|
||||
var list = new List<IListItem>();
|
||||
var listLock = new object();
|
||||
|
||||
var a = Task.Run(() =>
|
||||
{
|
||||
var isBootedInUefiMode = Win32Helpers.GetSystemFirmwareType() == FirmwareType.Uefi;
|
||||
|
||||
var separateEmptyRB = manager.HideEmptyRecycleBin;
|
||||
var confirmSystemCommands = manager.ShowDialogToConfirmCommand;
|
||||
var showSuccessOnEmptyRB = manager.ShowSuccessMessageAfterEmptyingRecycleBin;
|
||||
|
||||
// normal system commands are fast and can be returned immediately
|
||||
var systemCommands = Commands.GetSystemCommands(isBootedInUefiMode, separateEmptyRB, confirmSystemCommands, showSuccessOnEmptyRB);
|
||||
lock (listLock)
|
||||
{
|
||||
list.AddRange(systemCommands);
|
||||
}
|
||||
});
|
||||
|
||||
var b = Task.Run(() =>
|
||||
{
|
||||
// Network (ip and mac) results are slow with many network cards and returned delayed.
|
||||
// On global queries the first word/part has to be 'ip', 'mac' or 'address' for network results
|
||||
var networkConnectionResults = Commands.GetNetworkConnectionResults(manager);
|
||||
lock (listLock)
|
||||
{
|
||||
list.AddRange(networkConnectionResults);
|
||||
}
|
||||
});
|
||||
|
||||
Task.WaitAll(a, b);
|
||||
CachedCommands = list.ToArray();
|
||||
}
|
||||
|
||||
public IListItem[] CachedCommands { get; }
|
||||
}
|
||||
@@ -1,189 +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;
|
||||
using System.Globalization;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Microsoft.CmdPal.Ext.TimeDate.Helpers;
|
||||
|
||||
internal static class TimeAndDateHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the format for the time string
|
||||
/// </summary>
|
||||
/// <param name="targetFormat">Type of format</param>
|
||||
/// <param name="timeLong">Show date with weekday and name of month (long format)</param>
|
||||
/// <param name="dateLong">Show time with seconds (long format)</param>
|
||||
/// <returns>String that identifies the time/date format (<see href="https://learn.microsoft.com/dotnet/api/system.datetime.tostring"/>)</returns>
|
||||
internal static string GetStringFormat(FormatStringType targetFormat, bool timeLong, bool dateLong)
|
||||
{
|
||||
switch (targetFormat)
|
||||
{
|
||||
case FormatStringType.Time:
|
||||
return timeLong ? "T" : "t";
|
||||
case FormatStringType.Date:
|
||||
return dateLong ? "D" : "d";
|
||||
case FormatStringType.DateTime:
|
||||
if (timeLong & dateLong)
|
||||
{
|
||||
return "F"; // Friday, October 31, 2008 5:04:32 PM
|
||||
}
|
||||
else if (timeLong & !dateLong)
|
||||
{
|
||||
return "G"; // 10/31/2008 5:04:32 PM
|
||||
}
|
||||
else if (!timeLong & dateLong)
|
||||
{
|
||||
return "f"; // Friday, October 31, 2008 5:04 PM
|
||||
}
|
||||
else
|
||||
{
|
||||
// (!timeLong & !dateLong)
|
||||
return "g"; // 10/31/2008 5:04 PM
|
||||
}
|
||||
|
||||
default:
|
||||
return string.Empty; // Windows default based on current culture settings
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the number week in the month (Used code from 'David Morton' from <see href="https://social.msdn.microsoft.com/Forums/vstudio/bf504bba-85cb-492d-a8f7-4ccabdf882cb/get-week-number-for-month"/>)
|
||||
/// </summary>
|
||||
/// <param name="date">date</param>
|
||||
/// <returns>Number of week in the month</returns>
|
||||
internal static int GetWeekOfMonth(DateTime date, DayOfWeek formatSettingFirstDayOfWeek)
|
||||
{
|
||||
var beginningOfMonth = new DateTime(date.Year, date.Month, 1);
|
||||
var adjustment = 1; // We count from 1 to 7 and not from 0 to 6
|
||||
|
||||
while (date.Date.AddDays(1).DayOfWeek != formatSettingFirstDayOfWeek)
|
||||
{
|
||||
date = date.AddDays(1);
|
||||
}
|
||||
|
||||
return (int)Math.Truncate((double)date.Subtract(beginningOfMonth).TotalDays / 7f) + adjustment;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the number of the day in the week
|
||||
/// </summary>
|
||||
/// <param name="date">Date</param>
|
||||
/// <returns>Number of the day in the week</returns>
|
||||
internal static int GetNumberOfDayInWeek(DateTime date, DayOfWeek formatSettingFirstDayOfWeek)
|
||||
{
|
||||
var daysInWeek = 7;
|
||||
var adjustment = 1; // We count from 1 to 7 and not from 0 to 6
|
||||
|
||||
return ((date.DayOfWeek + daysInWeek - formatSettingFirstDayOfWeek) % daysInWeek) + adjustment;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert input string to a <see cref="DateTime"/> object in local time
|
||||
/// </summary>
|
||||
/// <param name="input">String with date/time</param>
|
||||
/// <param name="timestamp">The new <see cref="DateTime"/> object</param>
|
||||
/// <returns>True on success, otherwise false</returns>
|
||||
internal static bool ParseStringAsDateTime(in string input, out DateTime timestamp)
|
||||
{
|
||||
if (DateTime.TryParse(input, out timestamp))
|
||||
{
|
||||
// Known date/time format
|
||||
return true;
|
||||
}
|
||||
else if (Regex.IsMatch(input, @"^u[\+-]?\d{1,10}$") && long.TryParse(input.TrimStart('u'), out var secondsU))
|
||||
{
|
||||
// Unix time stamp
|
||||
// We use long instead of int, because int is too small after 03:14:07 UTC 2038-01-19
|
||||
timestamp = DateTimeOffset.FromUnixTimeSeconds(secondsU).LocalDateTime;
|
||||
return true;
|
||||
}
|
||||
else if (Regex.IsMatch(input, @"^ums[\+-]?\d{1,13}$") && long.TryParse(input.TrimStart("ums".ToCharArray()), out var millisecondsUms))
|
||||
{
|
||||
// Unix time stamp in milliseconds
|
||||
// We use long instead of int because int is too small after 03:14:07 UTC 2038-01-19
|
||||
timestamp = DateTimeOffset.FromUnixTimeMilliseconds(millisecondsUms).LocalDateTime;
|
||||
return true;
|
||||
}
|
||||
else if (Regex.IsMatch(input, @"^ft\d+$") && long.TryParse(input.TrimStart("ft".ToCharArray()), out var secondsFt))
|
||||
{
|
||||
// Windows file time
|
||||
// DateTime.FromFileTime returns as local time.
|
||||
timestamp = DateTime.FromFileTime(secondsFt);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
timestamp = new DateTime(1, 1, 1, 1, 1, 1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test if input is special parsing for Unix time, Unix time in milliseconds or File time.
|
||||
/// </summary>
|
||||
/// <param name="input">String with date/time</param>
|
||||
/// <returns>True if yes, otherwise false</returns>
|
||||
internal static bool IsSpecialInputParsing(string input)
|
||||
{
|
||||
return Regex.IsMatch(input, @"^.*(u|ums|ft)\d");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a CalendarWeekRule enum value based on the plugin setting.
|
||||
/// </summary>
|
||||
internal static CalendarWeekRule GetCalendarWeekRule(int pluginSetting)
|
||||
{
|
||||
switch (pluginSetting)
|
||||
{
|
||||
case 0:
|
||||
return CalendarWeekRule.FirstDay;
|
||||
case 1:
|
||||
return CalendarWeekRule.FirstFullWeek;
|
||||
case 2:
|
||||
return CalendarWeekRule.FirstFourDayWeek;
|
||||
default:
|
||||
// Wrong json value and system setting (-1).
|
||||
return DateTimeFormatInfo.CurrentInfo.CalendarWeekRule;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a DayOfWeek enum value based on the FirstDayOfWeek plugin setting.
|
||||
/// </summary>
|
||||
internal static DayOfWeek GetFirstDayOfWeek(int pluginSetting)
|
||||
{
|
||||
switch (pluginSetting)
|
||||
{
|
||||
case 0:
|
||||
return DayOfWeek.Sunday;
|
||||
case 1:
|
||||
return DayOfWeek.Monday;
|
||||
case 2:
|
||||
return DayOfWeek.Tuesday;
|
||||
case 3:
|
||||
return DayOfWeek.Wednesday;
|
||||
case 4:
|
||||
return DayOfWeek.Thursday;
|
||||
case 5:
|
||||
return DayOfWeek.Friday;
|
||||
case 6:
|
||||
return DayOfWeek.Saturday;
|
||||
default:
|
||||
// Wrong json value and system setting (-1).
|
||||
return DateTimeFormatInfo.CurrentInfo.FirstDayOfWeek;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Type of time/date format
|
||||
/// </summary>
|
||||
internal enum FormatStringType
|
||||
{
|
||||
Time,
|
||||
Date,
|
||||
DateTime,
|
||||
}
|
||||
@@ -1,97 +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 Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
|
||||
namespace SamplePagesExtension;
|
||||
|
||||
internal sealed partial class SampleListPage : ListPage
|
||||
{
|
||||
public SampleListPage()
|
||||
{
|
||||
Icon = new IconInfo("\uEA37");
|
||||
Name = "Sample List Page";
|
||||
}
|
||||
|
||||
public override IListItem[] GetItems()
|
||||
{
|
||||
var confirmOnceArgs = new ConfirmationArgs
|
||||
{
|
||||
PrimaryCommand = new AnonymousCommand(
|
||||
() =>
|
||||
{
|
||||
var t = new ToastStatusMessage("The dialog was confirmed");
|
||||
t.Show();
|
||||
})
|
||||
{
|
||||
Name = "Confirm",
|
||||
Result = CommandResult.KeepOpen(),
|
||||
},
|
||||
Title = "You can set a title for the dialog",
|
||||
Description = "Are you really sure you want to do the thing?",
|
||||
};
|
||||
var confirmTwiceArgs = new ConfirmationArgs
|
||||
{
|
||||
PrimaryCommand = new AnonymousCommand(() => { })
|
||||
{
|
||||
Name = "How sure are you?",
|
||||
Result = CommandResult.Confirm(confirmOnceArgs),
|
||||
},
|
||||
Title = "You can ask twice too",
|
||||
Description = "You probably don't want to though, that'd be annoying.",
|
||||
};
|
||||
|
||||
return [
|
||||
new ListItem(new NoOpCommand())
|
||||
{
|
||||
Title = "This is a basic item in the list",
|
||||
Subtitle = "I don't do anything though",
|
||||
},
|
||||
new ListItem(new SampleListPageWithDetails())
|
||||
{
|
||||
Title = "This item will take you to another page",
|
||||
Subtitle = "This allows for nested lists of items",
|
||||
},
|
||||
new ListItem(new OpenUrlCommand("https://github.com/microsoft/powertoys"))
|
||||
{
|
||||
Title = "Or you can go to links",
|
||||
Subtitle = "This takes you to the PowerToys repo on GitHub",
|
||||
},
|
||||
new ListItem(new SampleMarkdownPage())
|
||||
{
|
||||
Title = "Items can have tags",
|
||||
Subtitle = "and I'll take you to a page with markdown content",
|
||||
Tags = [new Tag("Sample Tag")],
|
||||
},
|
||||
new ListItem(new SendMessageCommand())
|
||||
{
|
||||
Title = "I send lots of messages",
|
||||
Subtitle = "Status messages can be used to provide feedback to the user in-app",
|
||||
},
|
||||
new SendSingleMessageItem(),
|
||||
new ListItem(new IndeterminateProgressMessageCommand())
|
||||
{
|
||||
Title = "Do a thing with a spinner",
|
||||
Subtitle = "Messages can have progress spinners, to indicate something is happening in the background",
|
||||
},
|
||||
new ListItem(
|
||||
new AnonymousCommand(() => { })
|
||||
{
|
||||
Result = CommandResult.Confirm(confirmOnceArgs),
|
||||
})
|
||||
{
|
||||
Title = "Confirm before doing something",
|
||||
},
|
||||
new ListItem(
|
||||
new AnonymousCommand(() => { })
|
||||
{
|
||||
Result = CommandResult.Confirm(confirmTwiceArgs),
|
||||
})
|
||||
{
|
||||
Title = "Confirm twice before doing something",
|
||||
}
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -7,11 +7,15 @@ using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using Windows.System;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public partial class CommandBarViewModel : ObservableObject,
|
||||
IRecipient<UpdateCommandBarMessage>
|
||||
IRecipient<UpdateCommandBarMessage>,
|
||||
IRecipient<UpdateItemKeybindingsMessage>
|
||||
{
|
||||
public ICommandBarContext? SelectedItem
|
||||
{
|
||||
@@ -49,13 +53,18 @@ public partial class CommandBarViewModel : ObservableObject,
|
||||
[ObservableProperty]
|
||||
public partial ObservableCollection<CommandContextItemViewModel> ContextCommands { get; set; } = [];
|
||||
|
||||
private Dictionary<KeyChord, CommandContextItemViewModel>? _contextKeybindings;
|
||||
|
||||
public CommandBarViewModel()
|
||||
{
|
||||
WeakReferenceMessenger.Default.Register<UpdateCommandBarMessage>(this);
|
||||
WeakReferenceMessenger.Default.Register<UpdateItemKeybindingsMessage>(this);
|
||||
}
|
||||
|
||||
public void Receive(UpdateCommandBarMessage message) => SelectedItem = message.ViewModel;
|
||||
|
||||
public void Receive(UpdateItemKeybindingsMessage message) => _contextKeybindings = message.Keys;
|
||||
|
||||
private void SetSelectedItem(ICommandBarContext? value)
|
||||
{
|
||||
if (value != null)
|
||||
@@ -131,4 +140,22 @@ public partial class CommandBarViewModel : ObservableObject,
|
||||
WeakReferenceMessenger.Default.Send<PerformCommandMessage>(new(SecondaryCommand.Command.Model, SecondaryCommand.Model));
|
||||
}
|
||||
}
|
||||
|
||||
public bool CheckKeybinding(bool ctrl, bool alt, bool shift, bool win, VirtualKey key)
|
||||
{
|
||||
if (_contextKeybindings != null)
|
||||
{
|
||||
// Does the pressed key match any of the keybindings?
|
||||
var pressedKeyChord = KeyChordHelpers.FromModifiers(ctrl, alt, shift, win, key, 0);
|
||||
if (_contextKeybindings.TryGetValue(pressedKeyChord, out var item))
|
||||
{
|
||||
// TODO GH #245: This is a bit of a hack, but we need to make sure that the keybindings are updated before we send the message
|
||||
// so that the correct item is activated.
|
||||
WeakReferenceMessenger.Default.Send<PerformCommandMessage>(new(item));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,12 +9,16 @@ namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public partial class CommandContextItemViewModel(ICommandContextItem contextItem, WeakReference<IPageContext> context) : CommandItemViewModel(new(contextItem), context)
|
||||
{
|
||||
private readonly KeyChord nullKeyChord = new(0, 0, 0);
|
||||
|
||||
public new ExtensionObject<ICommandContextItem> Model { get; } = new(contextItem);
|
||||
|
||||
public bool IsCritical { get; private set; }
|
||||
|
||||
public KeyChord? RequestedShortcut { get; private set; }
|
||||
|
||||
public bool HasRequestedShortcut => RequestedShortcut != null && (RequestedShortcut.Value != nullKeyChord);
|
||||
|
||||
public override void InitializeProperties()
|
||||
{
|
||||
if (IsInitialized)
|
||||
@@ -31,6 +35,9 @@ public partial class CommandContextItemViewModel(ICommandContextItem contextItem
|
||||
}
|
||||
|
||||
IsCritical = contextItem.IsCritical;
|
||||
|
||||
// I actually don't think this will ever actually be null, because
|
||||
// KeyChord is a struct, which isn't nullable in WinRT
|
||||
if (contextItem.RequestedShortcut != null)
|
||||
{
|
||||
RequestedShortcut = new(
|
||||
|
||||
@@ -398,6 +398,23 @@ public partial class CommandItemViewModel : ExtensionObjectViewModel, ICommandBa
|
||||
base.SafeCleanup();
|
||||
Initialized |= InitializedState.CleanedUp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a mapping of key -> command item for this particular item's
|
||||
/// MoreCommands. (This won't include the primary Command, but it will
|
||||
/// include the secondary one). This map can be used to quickly check if a
|
||||
/// shortcut key was pressed
|
||||
/// </summary>
|
||||
/// <returns>a dictionary of KeyChord -> Context commands, for all commands
|
||||
/// that have a shortcut key set.</returns>
|
||||
internal Dictionary<KeyChord, CommandContextItemViewModel> Keybindings()
|
||||
{
|
||||
return MoreCommands
|
||||
.Where(c => c.HasRequestedShortcut)
|
||||
.ToDictionary(
|
||||
c => c.RequestedShortcut ?? new KeyChord(0, 0, 0),
|
||||
c => c);
|
||||
}
|
||||
}
|
||||
|
||||
[Flags]
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.IO.Compression;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
@@ -28,69 +29,69 @@ internal sealed partial class NewExtensionForm : NewExtensionFormBase
|
||||
"body": [
|
||||
{
|
||||
"type": "TextBlock",
|
||||
"text": "{{Properties.Resources.builtin_create_extension_page_title}}",
|
||||
"text": {{FormatJsonString(Properties.Resources.builtin_create_extension_page_title)}},
|
||||
"size": "large"
|
||||
},
|
||||
{
|
||||
"type": "TextBlock",
|
||||
"text": "{{Properties.Resources.builtin_create_extension_page_text}}",
|
||||
"text": {{FormatJsonString(Properties.Resources.builtin_create_extension_page_text)}},
|
||||
"wrap": true
|
||||
},
|
||||
{
|
||||
"type": "TextBlock",
|
||||
"text": "{{Properties.Resources.builtin_create_extension_name_header}}",
|
||||
"text": {{FormatJsonString(Properties.Resources.builtin_create_extension_name_header)}},
|
||||
"weight": "bolder",
|
||||
"size": "default"
|
||||
},
|
||||
{
|
||||
"type": "TextBlock",
|
||||
"text": "{{Properties.Resources.builtin_create_extension_name_description}}",
|
||||
"text": {{FormatJsonString(Properties.Resources.builtin_create_extension_name_description)}},
|
||||
"wrap": true
|
||||
},
|
||||
{
|
||||
"type": "Input.Text",
|
||||
"label": "{{Properties.Resources.builtin_create_extension_name_label}}",
|
||||
"label": {{FormatJsonString(Properties.Resources.builtin_create_extension_name_label)}},
|
||||
"isRequired": true,
|
||||
"errorMessage": "{{Properties.Resources.builtin_create_extension_name_required}}",
|
||||
"errorMessage": {{FormatJsonString(Properties.Resources.builtin_create_extension_name_required)}},
|
||||
"id": "ExtensionName",
|
||||
"placeholder": "ExtensionName",
|
||||
"regex": "^[^\\s]+$"
|
||||
},
|
||||
{
|
||||
"type": "TextBlock",
|
||||
"text": "{{Properties.Resources.builtin_create_extension_display_name_header}}",
|
||||
"text": {{FormatJsonString(Properties.Resources.builtin_create_extension_display_name_header)}},
|
||||
"weight": "bolder",
|
||||
"size": "default"
|
||||
},
|
||||
{
|
||||
"type": "TextBlock",
|
||||
"text": "{{Properties.Resources.builtin_create_extension_display_name_description}}",
|
||||
"text": {{FormatJsonString(Properties.Resources.builtin_create_extension_display_name_description)}},
|
||||
"wrap": true
|
||||
},
|
||||
{
|
||||
"type": "Input.Text",
|
||||
"label": "{{Properties.Resources.builtin_create_extension_display_name_label}}",
|
||||
"label": {{FormatJsonString(Properties.Resources.builtin_create_extension_display_name_label)}},
|
||||
"isRequired": true,
|
||||
"errorMessage": "{{Properties.Resources.builtin_create_extension_display_name_required}}",
|
||||
"errorMessage": {{FormatJsonString(Properties.Resources.builtin_create_extension_display_name_required)}},
|
||||
"id": "DisplayName",
|
||||
"placeholder": "My new extension"
|
||||
},
|
||||
{
|
||||
"type": "TextBlock",
|
||||
"text": "{{Properties.Resources.builtin_create_extension_directory_header}}",
|
||||
"text": {{FormatJsonString(Properties.Resources.builtin_create_extension_directory_header)}},
|
||||
"weight": "bolder",
|
||||
"size": "default"
|
||||
},
|
||||
{
|
||||
"type": "TextBlock",
|
||||
"text": "{{Properties.Resources.builtin_create_extension_directory_description}}",
|
||||
"text": {{FormatJsonString(Properties.Resources.builtin_create_extension_directory_description)}},
|
||||
"wrap": true
|
||||
},
|
||||
{
|
||||
"type": "Input.Text",
|
||||
"label": "{{Properties.Resources.builtin_create_extension_directory_label}}",
|
||||
"label": {{FormatJsonString(Properties.Resources.builtin_create_extension_directory_label)}},
|
||||
"isRequired": true,
|
||||
"errorMessage": "{{Properties.Resources.builtin_create_extension_directory_required}}",
|
||||
"errorMessage": {{FormatJsonString(Properties.Resources.builtin_create_extension_directory_required)}},
|
||||
"id": "OutputPath",
|
||||
"placeholder": "C:\\users\\me\\dev"
|
||||
}
|
||||
@@ -98,7 +99,7 @@ internal sealed partial class NewExtensionForm : NewExtensionFormBase
|
||||
"actions": [
|
||||
{
|
||||
"type": "Action.Submit",
|
||||
"title": "{{Properties.Resources.builtin_create_extension_submit}}",
|
||||
"title": {{FormatJsonString(Properties.Resources.builtin_create_extension_submit)}},
|
||||
"associatedInputs": "auto"
|
||||
}
|
||||
]
|
||||
@@ -192,4 +193,10 @@ internal sealed partial class NewExtensionForm : NewExtensionFormBase
|
||||
// Delete the temp dir
|
||||
Directory.Delete(tempDir, true);
|
||||
}
|
||||
|
||||
private string FormatJsonString(string str)
|
||||
{
|
||||
// Escape the string for JSON
|
||||
return JsonSerializer.Serialize(str);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,8 @@ public partial class ListViewModel : PageViewModel, IDisposable
|
||||
|
||||
public string SearchText { get; private set; } = string.Empty;
|
||||
|
||||
public string InitialSearchText { get; private set; } = string.Empty;
|
||||
|
||||
public CommandItemViewModel EmptyContent { get; private set; }
|
||||
|
||||
private bool _isDynamic;
|
||||
@@ -128,7 +130,7 @@ public partial class ListViewModel : PageViewModel, IDisposable
|
||||
|
||||
try
|
||||
{
|
||||
IListItem[] newItems = _model.Unsafe!.GetItems();
|
||||
var newItems = _model.Unsafe!.GetItems();
|
||||
|
||||
// Collect all the items into new viewmodels
|
||||
Collection<ListItemViewModel> newViewModels = [];
|
||||
@@ -136,7 +138,7 @@ public partial class ListViewModel : PageViewModel, IDisposable
|
||||
// TODO we can probably further optimize this by also keeping a
|
||||
// HashSet of every ExtensionObject we currently have, and only
|
||||
// building new viewmodels for the ones we haven't already built.
|
||||
foreach (IListItem? item in newItems)
|
||||
foreach (var item in newItems)
|
||||
{
|
||||
ListItemViewModel viewModel = new(item, new(this));
|
||||
|
||||
@@ -147,8 +149,8 @@ public partial class ListViewModel : PageViewModel, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerable<ListItemViewModel> firstTwenty = newViewModels.Take(20);
|
||||
foreach (ListItemViewModel? item in firstTwenty)
|
||||
var firstTwenty = newViewModels.Take(20);
|
||||
foreach (var item in firstTwenty)
|
||||
{
|
||||
item?.SafeInitializeProperties();
|
||||
}
|
||||
@@ -233,7 +235,7 @@ public partial class ListViewModel : PageViewModel, IDisposable
|
||||
iterable = Items.ToArray();
|
||||
}
|
||||
|
||||
foreach (ListItemViewModel item in iterable)
|
||||
foreach (var item in iterable)
|
||||
{
|
||||
ct.ThrowIfCancellationRequested();
|
||||
|
||||
@@ -266,8 +268,8 @@ public partial class ListViewModel : PageViewModel, IDisposable
|
||||
return 1;
|
||||
}
|
||||
|
||||
MatchResult nameMatch = StringMatcher.FuzzySearch(query, listItem.Title);
|
||||
MatchResult descriptionMatch = StringMatcher.FuzzySearch(query, listItem.Subtitle);
|
||||
var nameMatch = StringMatcher.FuzzySearch(query, listItem.Title);
|
||||
var descriptionMatch = StringMatcher.FuzzySearch(query, listItem.Subtitle);
|
||||
return new[] { nameMatch.Score, (descriptionMatch.Score - 4) / 2, 0 }.Max();
|
||||
}
|
||||
|
||||
@@ -280,7 +282,7 @@ public partial class ListViewModel : PageViewModel, IDisposable
|
||||
// Similarly stolen from ListHelpers.FilterList
|
||||
public static IEnumerable<ListItemViewModel> FilterList(IEnumerable<ListItemViewModel> items, string query)
|
||||
{
|
||||
IOrderedEnumerable<ScoredListItemViewModel> scores = items
|
||||
var scores = items
|
||||
.Where(i => !i.IsInErrorState)
|
||||
.Select(li => new ScoredListItemViewModel() { ViewModel = li, Score = ScoreListItem(query, li) })
|
||||
.Where(score => score.Score > 0)
|
||||
@@ -342,6 +344,8 @@ public partial class ListViewModel : PageViewModel, IDisposable
|
||||
{
|
||||
WeakReferenceMessenger.Default.Send<UpdateCommandBarMessage>(new(item));
|
||||
|
||||
WeakReferenceMessenger.Default.Send<UpdateItemKeybindingsMessage>(new(item.Keybindings()));
|
||||
|
||||
if (ShowDetails && item.HasDetails)
|
||||
{
|
||||
WeakReferenceMessenger.Default.Send<ShowDetailsMessage>(new(item.Details));
|
||||
@@ -359,7 +363,7 @@ public partial class ListViewModel : PageViewModel, IDisposable
|
||||
{
|
||||
base.InitializeProperties();
|
||||
|
||||
IListPage? model = _model.Unsafe;
|
||||
var model = _model.Unsafe;
|
||||
if (model == null)
|
||||
{
|
||||
return; // throw?
|
||||
@@ -373,8 +377,9 @@ public partial class ListViewModel : PageViewModel, IDisposable
|
||||
_modelPlaceholderText = model.PlaceholderText;
|
||||
UpdateProperty(nameof(PlaceholderText));
|
||||
|
||||
SearchText = model.SearchText;
|
||||
InitialSearchText = SearchText = model.SearchText;
|
||||
UpdateProperty(nameof(SearchText));
|
||||
UpdateProperty(nameof(InitialSearchText));
|
||||
|
||||
EmptyContent = new(new(model.EmptyContent), PageContext);
|
||||
EmptyContent.SlowInitializeProperties();
|
||||
@@ -385,7 +390,7 @@ public partial class ListViewModel : PageViewModel, IDisposable
|
||||
|
||||
public void LoadMoreIfNeeded()
|
||||
{
|
||||
IListPage? model = this._model.Unsafe;
|
||||
var model = this._model.Unsafe;
|
||||
if (model == null)
|
||||
{
|
||||
return;
|
||||
@@ -412,7 +417,7 @@ public partial class ListViewModel : PageViewModel, IDisposable
|
||||
{
|
||||
base.FetchProperty(propertyName);
|
||||
|
||||
IListPage? model = this._model.Unsafe;
|
||||
var model = this._model.Unsafe;
|
||||
if (model == null)
|
||||
{
|
||||
return; // throw?
|
||||
@@ -475,13 +480,13 @@ public partial class ListViewModel : PageViewModel, IDisposable
|
||||
|
||||
lock (_listLock)
|
||||
{
|
||||
foreach (ListItemViewModel item in Items)
|
||||
foreach (var item in Items)
|
||||
{
|
||||
item.SafeCleanup();
|
||||
}
|
||||
|
||||
Items.Clear();
|
||||
foreach (ListItemViewModel item in FilteredItems)
|
||||
foreach (var item in FilteredItems)
|
||||
{
|
||||
item.SafeCleanup();
|
||||
}
|
||||
@@ -489,7 +494,7 @@ public partial class ListViewModel : PageViewModel, IDisposable
|
||||
FilteredItems.Clear();
|
||||
}
|
||||
|
||||
IListPage? model = _model.Unsafe;
|
||||
var model = _model.Unsafe;
|
||||
if (model != null)
|
||||
{
|
||||
model.ItemsChanged -= Model_ItemsChanged;
|
||||
|
||||
@@ -51,6 +51,12 @@ public record PerformCommandMessage
|
||||
Context = context.Unsafe;
|
||||
}
|
||||
|
||||
public PerformCommandMessage(CommandContextItemViewModel contextCommand)
|
||||
{
|
||||
Command = contextCommand.Command.Model;
|
||||
Context = contextCommand.Model.Unsafe;
|
||||
}
|
||||
|
||||
public PerformCommandMessage(ConfirmResultViewModel vm)
|
||||
{
|
||||
Command = vm.PrimaryCommand.Model;
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
// 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 Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
|
||||
public record UpdateItemKeybindingsMessage(Dictionary<KeyChord, CommandContextItemViewModel>? Keys);
|
||||
@@ -31,7 +31,7 @@
|
||||
<ProjectReference Include="..\Microsoft.CmdPal.Common\Microsoft.CmdPal.Common.csproj" />
|
||||
<ProjectReference Include="..\extensionsdk\Microsoft.CommandPalette.Extensions.Toolkit\Microsoft.CommandPalette.Extensions.Toolkit.csproj" />
|
||||
|
||||
<ProjectReference Include="..\Exts\Microsoft.CmdPal.Ext.Apps\Microsoft.CmdPal.Ext.Apps.csproj" />
|
||||
<ProjectReference Include="..\ext\Microsoft.CmdPal.Ext.Apps\Microsoft.CmdPal.Ext.Apps.csproj" />
|
||||
|
||||
<ProjectReference Include="..\..\..\common\ManagedCommon\ManagedCommon.csproj" />
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@ public partial class SettingsModel : ObservableObject
|
||||
|
||||
public HotkeySettings? Hotkey { get; set; } = DefaultActivationShortcut;
|
||||
|
||||
public bool UseLowLevelGlobalHotkey { get; set; }
|
||||
|
||||
public bool ShowAppDetails { get; set; }
|
||||
|
||||
public bool HotkeyGoesHome { get; set; }
|
||||
@@ -36,6 +38,8 @@ public partial class SettingsModel : ObservableObject
|
||||
|
||||
public bool HighlightSearchOnActivate { get; set; } = true;
|
||||
|
||||
public bool ShowSystemTrayIcon { get; set; } = true;
|
||||
|
||||
public Dictionary<string, ProviderSettings> ProviderSettings { get; set; } = [];
|
||||
|
||||
public Dictionary<string, CommandAlias> Aliases { get; set; } = [];
|
||||
|
||||
@@ -27,6 +27,17 @@ public partial class SettingsViewModel : INotifyPropertyChanged
|
||||
}
|
||||
}
|
||||
|
||||
public bool UseLowLevelGlobalHotkey
|
||||
{
|
||||
get => _settings.UseLowLevelGlobalHotkey;
|
||||
set
|
||||
{
|
||||
_settings.UseLowLevelGlobalHotkey = value;
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Hotkey)));
|
||||
Save();
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowAppDetails
|
||||
{
|
||||
get => _settings.ShowAppDetails;
|
||||
@@ -87,6 +98,16 @@ public partial class SettingsViewModel : INotifyPropertyChanged
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowSystemTrayIcon
|
||||
{
|
||||
get => _settings.ShowSystemTrayIcon;
|
||||
set
|
||||
{
|
||||
_settings.ShowSystemTrayIcon = value;
|
||||
Save();
|
||||
}
|
||||
}
|
||||
|
||||
public ObservableCollection<ProviderSettingsViewModel> CommandProviders { get; } = [];
|
||||
|
||||
public SettingsViewModel(SettingsModel settings, IServiceProvider serviceProvider, TaskScheduler scheduler)
|
||||
|
||||
@@ -152,7 +152,7 @@ public sealed partial class TopLevelViewModel : ObservableObject, IListItem
|
||||
{
|
||||
GenerateId();
|
||||
|
||||
UpdateAlias();
|
||||
FetchAliasFromAliasManager();
|
||||
UpdateHotkey();
|
||||
UpdateTags();
|
||||
}
|
||||
@@ -163,24 +163,31 @@ public sealed partial class TopLevelViewModel : ObservableObject, IListItem
|
||||
|
||||
private void HandleChangeAlias()
|
||||
{
|
||||
SetAlias(Alias);
|
||||
SetAlias();
|
||||
Save();
|
||||
}
|
||||
|
||||
public void SetAlias(CommandAlias? newAlias)
|
||||
public void SetAlias()
|
||||
{
|
||||
_serviceProvider.GetService<AliasManager>()!.UpdateAlias(Id, newAlias);
|
||||
UpdateAlias();
|
||||
var commandAlias = Alias is null
|
||||
? null
|
||||
: new CommandAlias(Alias.Alias, Alias.CommandId, Alias.IsDirect);
|
||||
|
||||
_serviceProvider.GetService<AliasManager>()!.UpdateAlias(Id, commandAlias);
|
||||
UpdateTags();
|
||||
}
|
||||
|
||||
private void UpdateAlias()
|
||||
private void FetchAliasFromAliasManager()
|
||||
{
|
||||
// Add tags for the alias, if we have one.
|
||||
var aliases = _serviceProvider.GetService<AliasManager>();
|
||||
if (aliases != null)
|
||||
var am = _serviceProvider.GetService<AliasManager>();
|
||||
if (am != null)
|
||||
{
|
||||
Alias = aliases.AliasFromId(Id);
|
||||
var commandAlias = am.AliasFromId(Id);
|
||||
if (commandAlias is not null)
|
||||
{
|
||||
// Decouple from the alias manager alias object
|
||||
Alias = new CommandAlias(commandAlias.Alias, commandAlias.CommandId, commandAlias.IsDirect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 ManagedCommon;
|
||||
using Microsoft.CmdPal.Common.Helpers;
|
||||
using Microsoft.CmdPal.Common.Services;
|
||||
using Microsoft.CmdPal.Ext.Apps;
|
||||
@@ -78,7 +79,7 @@ public partial class App : Application
|
||||
|
||||
var cmdArgs = Environment.GetCommandLineArgs();
|
||||
|
||||
bool runFromPT = false;
|
||||
var runFromPT = false;
|
||||
foreach (var arg in cmdArgs)
|
||||
{
|
||||
if (arg == "RunFromPT")
|
||||
@@ -107,9 +108,6 @@ public partial class App : Application
|
||||
|
||||
// Built-in Commands. Order matters - this is the order they'll be presented by default.
|
||||
var allApps = new AllAppsCommandProvider();
|
||||
var winget = new WinGetExtensionCommandsProvider();
|
||||
var callback = allApps.LookupApp;
|
||||
winget.SetAllLookup(callback);
|
||||
services.AddSingleton<ICommandProvider>(allApps);
|
||||
services.AddSingleton<ICommandProvider, ShellCommandsProvider>();
|
||||
services.AddSingleton<ICommandProvider, CalculatorCommandProvider>();
|
||||
@@ -120,7 +118,25 @@ public partial class App : Application
|
||||
// services.AddSingleton<ICommandProvider, ClipboardHistoryCommandsProvider>();
|
||||
services.AddSingleton<ICommandProvider, WindowWalkerCommandsProvider>();
|
||||
services.AddSingleton<ICommandProvider, WebSearchCommandsProvider>();
|
||||
services.AddSingleton<ICommandProvider>(winget);
|
||||
|
||||
// GH #38440: Users might not have WinGet installed! Or they might have
|
||||
// a ridiculously old version. Or might be running as admin.
|
||||
// We shouldn't explode in the App ctor if we fail to instantiate an
|
||||
// instance of PackageManager, which will happen in the static ctor
|
||||
// for WinGetStatics
|
||||
try
|
||||
{
|
||||
var winget = new WinGetExtensionCommandsProvider();
|
||||
var callback = allApps.LookupApp;
|
||||
winget.SetAllLookup(callback);
|
||||
services.AddSingleton<ICommandProvider>(winget);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError("Couldn't load winget");
|
||||
Logger.LogError(ex.ToString());
|
||||
}
|
||||
|
||||
services.AddSingleton<ICommandProvider, WindowsTerminalCommandsProvider>();
|
||||
services.AddSingleton<ICommandProvider, WindowsSettingsCommandsProvider>();
|
||||
services.AddSingleton<ICommandProvider, RegistryCommandsProvider>();
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
<!-- Template for actions in the mode actions dropdown button -->
|
||||
<DataTemplate x:Key="ContextMenuViewModelTemplate" x:DataType="viewmodels:CommandContextItemViewModel">
|
||||
<Grid>
|
||||
<Grid AutomationProperties.Name="{x:Bind Title, Mode=OneWay}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="32" />
|
||||
<ColumnDefinition Width="*" />
|
||||
@@ -53,37 +53,16 @@
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Title, Mode=OneWay}" />
|
||||
<!--<TextBlock
|
||||
<TextBlock
|
||||
Grid.Column="2"
|
||||
Margin="16,0,0,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{ThemeResource MenuFlyoutItemKeyboardAcceleratorTextForeground}"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{x:Bind RequestedShortcut, Mode=OneWay, Converter={StaticResource KeyChordToStringConverter}}" />-->
|
||||
Text="{x:Bind RequestedShortcut, Mode=OneWay, Converter={StaticResource KeyChordToStringConverter}}" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
|
||||
<animations:ImplicitAnimationSet x:Name="ShowAnimations">
|
||||
<animations:OpacityAnimation
|
||||
From="0"
|
||||
To="1.0"
|
||||
Duration="0:0:0.340" />
|
||||
<animations:ScaleAnimation
|
||||
From="0.85"
|
||||
To="1"
|
||||
Duration="0:0:0.350" />
|
||||
</animations:ImplicitAnimationSet>
|
||||
<animations:ImplicitAnimationSet x:Name="HideAnimations">
|
||||
<animations:OpacityAnimation
|
||||
From="1.0"
|
||||
To="0"
|
||||
Duration="0:0:0.240" />
|
||||
<animations:ScaleAnimation
|
||||
From="1"
|
||||
To="0.85"
|
||||
Duration="0:0:0.350" />
|
||||
</animations:ImplicitAnimationSet>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
|
||||
@@ -135,9 +114,6 @@
|
||||
<Button
|
||||
x:Name="SettingsIconButton"
|
||||
x:Uid="SettingsButton"
|
||||
animations:Implicit.HideAnimations="{StaticResource HideAnimations}"
|
||||
animations:Implicit.ShowAnimations="{StaticResource ShowAnimations}"
|
||||
ui:VisualExtensions.NormalizedCenterPoint="0.5,0.5"
|
||||
Style="{StaticResource SubtleButtonStyle}"
|
||||
Tapped="SettingsIcon_Tapped"
|
||||
Visibility="{x:Bind CurrentPageViewModel.IsNested, Mode=OneWay, Converter={StaticResource BoolToInvertedVisibilityConverter}}">
|
||||
@@ -167,10 +143,8 @@
|
||||
<Button
|
||||
x:Name="PrimaryButton"
|
||||
Padding="6,4,4,4"
|
||||
animations:Implicit.HideAnimations="{StaticResource HideAnimations}"
|
||||
animations:Implicit.ShowAnimations="{StaticResource ShowAnimations}"
|
||||
ui:VisualExtensions.NormalizedCenterPoint="0.5,0.5"
|
||||
x:Load="{x:Bind IsLoaded, Mode=OneWay}"
|
||||
AutomationProperties.Name="{x:Bind ViewModel.PrimaryCommand.Name, Mode=OneWay}"
|
||||
Background="Transparent"
|
||||
Style="{StaticResource SubtleButtonStyle}"
|
||||
Tapped="PrimaryButton_Tapped"
|
||||
@@ -198,10 +172,8 @@
|
||||
<Button
|
||||
x:Name="SecondaryButton"
|
||||
Padding="6,4,4,4"
|
||||
animations:Implicit.HideAnimations="{StaticResource HideAnimations}"
|
||||
animations:Implicit.ShowAnimations="{StaticResource ShowAnimations}"
|
||||
ui:VisualExtensions.NormalizedCenterPoint="0.5,0.5"
|
||||
x:Load="{x:Bind IsLoaded, Mode=OneWay}"
|
||||
AutomationProperties.Name="{x:Bind ViewModel.SecondaryCommand.Name, Mode=OneWay}"
|
||||
Style="{StaticResource SubtleButtonStyle}"
|
||||
Tapped="SecondaryButton_Tapped"
|
||||
Visibility="{x:Bind ViewModel.HasSecondaryCommand, Mode=OneWay}">
|
||||
@@ -245,13 +217,10 @@
|
||||
x:Name="MoreCommandsButton"
|
||||
x:Uid="MoreCommandsButton"
|
||||
Padding="4"
|
||||
animations:Implicit.HideAnimations="{StaticResource HideAnimations}"
|
||||
animations:Implicit.ShowAnimations="{StaticResource ShowAnimations}"
|
||||
ui:VisualExtensions.NormalizedCenterPoint="0.5,0.5"
|
||||
Content="{ui:FontIcon Glyph=,
|
||||
FontSize=16}"
|
||||
Style="{StaticResource SubtleButtonStyle}"
|
||||
ToolTipService.ToolTip="Ctrl+k"
|
||||
ToolTipService.ToolTip="Ctrl+K"
|
||||
Visibility="{x:Bind ViewModel.ShouldShowContextMenu, Mode=OneWay}">
|
||||
<Button.Flyout>
|
||||
<Flyout Placement="TopEdgeAlignedRight">
|
||||
@@ -263,6 +232,7 @@
|
||||
ItemClick="CommandsDropdown_ItemClick"
|
||||
ItemTemplate="{StaticResource ContextMenuViewModelTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.ContextCommands, Mode=OneWay}"
|
||||
KeyDown="CommandsDropdown_KeyDown"
|
||||
SelectionMode="None">
|
||||
<ListView.ItemContainerStyle>
|
||||
<Style BasedOn="{StaticResource DefaultListViewItemStyle}" TargetType="ListViewItem">
|
||||
|
||||
@@ -6,10 +6,13 @@ using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.CmdPal.UI.ViewModels;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.UI.Views;
|
||||
using Microsoft.UI.Input;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||
using Microsoft.UI.Xaml.Input;
|
||||
using Windows.System;
|
||||
using Windows.UI.Core;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.Controls;
|
||||
|
||||
@@ -89,4 +92,23 @@ public sealed partial class CommandBar : UserControl,
|
||||
MoreCommandsButton.Flyout.Hide();
|
||||
}
|
||||
}
|
||||
|
||||
private void CommandsDropdown_KeyDown(object sender, KeyRoutedEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var ctrlPressed = InputKeyboardSource.GetKeyStateForCurrentThread(VirtualKey.Control).HasFlag(CoreVirtualKeyStates.Down);
|
||||
var altPressed = InputKeyboardSource.GetKeyStateForCurrentThread(VirtualKey.Menu).HasFlag(CoreVirtualKeyStates.Down);
|
||||
var shiftPressed = InputKeyboardSource.GetKeyStateForCurrentThread(VirtualKey.Shift).HasFlag(CoreVirtualKeyStates.Down);
|
||||
var winPressed = InputKeyboardSource.GetKeyStateForCurrentThread(VirtualKey.LeftWindows).HasFlag(CoreVirtualKeyStates.Down) ||
|
||||
InputKeyboardSource.GetKeyStateForCurrentThread(VirtualKey.RightWindows).HasFlag(CoreVirtualKeyStates.Down);
|
||||
|
||||
if (ViewModel?.CheckKeybinding(ctrlPressed, altPressed, shiftPressed, winPressed, e.Key) ?? false)
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ using CommunityToolkit.WinUI;
|
||||
using Microsoft.CmdPal.UI.ViewModels;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.UI.Views;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using Microsoft.UI.Dispatching;
|
||||
using Microsoft.UI.Input;
|
||||
using Microsoft.UI.Xaml;
|
||||
@@ -21,6 +23,7 @@ namespace Microsoft.CmdPal.UI.Controls;
|
||||
public sealed partial class SearchBar : UserControl,
|
||||
IRecipient<GoHomeMessage>,
|
||||
IRecipient<FocusSearchBoxMessage>,
|
||||
IRecipient<UpdateItemKeybindingsMessage>,
|
||||
ICurrentPageAware
|
||||
{
|
||||
private readonly DispatcherQueue _queue = DispatcherQueue.GetForCurrentThread();
|
||||
@@ -31,6 +34,8 @@ public sealed partial class SearchBar : UserControl,
|
||||
private readonly DispatcherQueueTimer _debounceTimer = DispatcherQueue.GetForCurrentThread().CreateTimer();
|
||||
private bool _isBackspaceHeld;
|
||||
|
||||
private Dictionary<KeyChord, CommandContextItemViewModel>? _keyBindings;
|
||||
|
||||
public PageViewModel? CurrentPageViewModel
|
||||
{
|
||||
get => (PageViewModel?)GetValue(CurrentPageViewModelProperty);
|
||||
@@ -69,6 +74,7 @@ public sealed partial class SearchBar : UserControl,
|
||||
this.InitializeComponent();
|
||||
WeakReferenceMessenger.Default.Register<GoHomeMessage>(this);
|
||||
WeakReferenceMessenger.Default.Register<FocusSearchBoxMessage>(this);
|
||||
WeakReferenceMessenger.Default.Register<UpdateItemKeybindingsMessage>(this);
|
||||
}
|
||||
|
||||
public void ClearSearch()
|
||||
@@ -105,19 +111,10 @@ public sealed partial class SearchBar : UserControl,
|
||||
|
||||
var ctrlPressed = InputKeyboardSource.GetKeyStateForCurrentThread(VirtualKey.Control).HasFlag(CoreVirtualKeyStates.Down);
|
||||
var altPressed = InputKeyboardSource.GetKeyStateForCurrentThread(VirtualKey.Menu).HasFlag(CoreVirtualKeyStates.Down);
|
||||
if (e.Key == VirtualKey.Down)
|
||||
{
|
||||
WeakReferenceMessenger.Default.Send<NavigateNextCommand>();
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
else if (e.Key == VirtualKey.Up)
|
||||
{
|
||||
WeakReferenceMessenger.Default.Send<NavigatePreviousCommand>();
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
else if (ctrlPressed && e.Key == VirtualKey.Enter)
|
||||
var shiftPressed = InputKeyboardSource.GetKeyStateForCurrentThread(VirtualKey.Shift).HasFlag(CoreVirtualKeyStates.Down);
|
||||
var winPressed = InputKeyboardSource.GetKeyStateForCurrentThread(VirtualKey.LeftWindows).HasFlag(CoreVirtualKeyStates.Down) ||
|
||||
InputKeyboardSource.GetKeyStateForCurrentThread(VirtualKey.RightWindows).HasFlag(CoreVirtualKeyStates.Down);
|
||||
if (ctrlPressed && e.Key == VirtualKey.Enter)
|
||||
{
|
||||
// ctrl+enter
|
||||
WeakReferenceMessenger.Default.Send<ActivateSecondaryCommandMessage>();
|
||||
@@ -175,6 +172,19 @@ public sealed partial class SearchBar : UserControl,
|
||||
{
|
||||
WeakReferenceMessenger.Default.Send<NavigateBackMessage>(new());
|
||||
}
|
||||
|
||||
if (_keyBindings != null)
|
||||
{
|
||||
// Does the pressed key match any of the keybindings?
|
||||
var pressedKeyChord = KeyChordHelpers.FromModifiers(ctrlPressed, altPressed, shiftPressed, winPressed, (int)e.Key, 0);
|
||||
if (_keyBindings.TryGetValue(pressedKeyChord, out var item))
|
||||
{
|
||||
// TODO GH #245: This is a bit of a hack, but we need to make sure that the keybindings are updated before we send the message
|
||||
// so that the correct item is activated.
|
||||
WeakReferenceMessenger.Default.Send<PerformCommandMessage>(new(item));
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void FilterBox_PreviewKeyDown(object sender, KeyRoutedEventArgs e)
|
||||
@@ -197,6 +207,18 @@ public sealed partial class SearchBar : UserControl,
|
||||
_isBackspaceHeld = true;
|
||||
}
|
||||
}
|
||||
else if (e.Key == VirtualKey.Up)
|
||||
{
|
||||
WeakReferenceMessenger.Default.Send<NavigatePreviousCommand>();
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
else if (e.Key == VirtualKey.Down)
|
||||
{
|
||||
WeakReferenceMessenger.Default.Send<NavigateNextCommand>();
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void FilterBox_PreviewKeyUp(object sender, KeyRoutedEventArgs e)
|
||||
@@ -249,18 +271,31 @@ public sealed partial class SearchBar : UserControl,
|
||||
private void Page_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
{
|
||||
var property = e.PropertyName;
|
||||
if (CurrentPageViewModel is ListViewModel list &&
|
||||
property == nameof(ListViewModel.SearchText))
|
||||
{
|
||||
// Only if the text actually changed...
|
||||
// (sometimes this triggers on a round-trip of the SearchText)
|
||||
if (FilterBox.Text != list.SearchText)
|
||||
{
|
||||
// ... Update our displayed text, and...
|
||||
FilterBox.Text = list.SearchText;
|
||||
|
||||
// ... Move the cursor to the end of the input
|
||||
FilterBox.Select(FilterBox.Text.Length, 0);
|
||||
if (CurrentPageViewModel is ListViewModel list)
|
||||
{
|
||||
if (property == nameof(ListViewModel.SearchText))
|
||||
{
|
||||
// Only if the text actually changed...
|
||||
// (sometimes this triggers on a round-trip of the SearchText)
|
||||
if (FilterBox.Text != list.SearchText)
|
||||
{
|
||||
// ... Update our displayed text, and...
|
||||
FilterBox.Text = list.SearchText;
|
||||
|
||||
// ... Move the cursor to the end of the input
|
||||
FilterBox.Select(FilterBox.Text.Length, 0);
|
||||
}
|
||||
}
|
||||
else if (property == nameof(ListViewModel.InitialSearchText))
|
||||
{
|
||||
// GH #38712:
|
||||
// The ListPage will notify us of the `InitialSearchText` when
|
||||
// we first load the viewmodel. We can use that as an
|
||||
// opportunity to immediately select the search text. That lets
|
||||
// the user start typing a new search without manually
|
||||
// selecting the old one.
|
||||
SelectSearch();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -268,4 +303,9 @@ public sealed partial class SearchBar : UserControl,
|
||||
public void Receive(GoHomeMessage message) => ClearSearch();
|
||||
|
||||
public void Receive(FocusSearchBoxMessage message) => this.Focus(Microsoft.UI.Xaml.FocusState.Programmatic);
|
||||
|
||||
public void Receive(UpdateItemKeybindingsMessage message)
|
||||
{
|
||||
_keyBindings = message.Keys;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
<Setter Property="IsTabStop" Value="False" />
|
||||
<Setter Property="HorizontalAlignment" Value="Center" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="AutomationProperties.AutomationControlType" Value="Custom" />
|
||||
<Setter Property="BackgroundSizing" Value="InnerBorderEdge" />
|
||||
<Setter Property="Padding" Value="{ThemeResource TagPadding}" />
|
||||
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
|
||||
@@ -56,6 +57,7 @@
|
||||
Padding="{TemplateBinding Padding}"
|
||||
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
|
||||
VerticalAlignment="{TemplateBinding VerticalAlignment}"
|
||||
AutomationProperties.Name="{TemplateBinding Text}"
|
||||
Background="{TemplateBinding Background}"
|
||||
BackgroundSizing="{TemplateBinding BackgroundSizing}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
|
||||
@@ -28,21 +28,22 @@
|
||||
NotEmptyValue="Visible" />
|
||||
|
||||
<DataTemplate x:Key="TagTemplate" x:DataType="viewmodels:TagViewModel">
|
||||
<ItemContainer>
|
||||
<cpcontrols:Tag
|
||||
BackgroundColor="{x:Bind Background, Mode=OneWay}"
|
||||
FontSize="12"
|
||||
ForegroundColor="{x:Bind Foreground, Mode=OneWay}"
|
||||
Icon="{x:Bind Icon, Mode=OneWay}"
|
||||
Text="{x:Bind Text, Mode=OneWay}"
|
||||
ToolTipService.ToolTip="{x:Bind ToolTip, Mode=OneWay}" />
|
||||
</ItemContainer>
|
||||
<cpcontrols:Tag
|
||||
AutomationProperties.Name="{x:Bind Text, Mode=OneWay}"
|
||||
BackgroundColor="{x:Bind Background, Mode=OneWay}"
|
||||
FontSize="12"
|
||||
ForegroundColor="{x:Bind Foreground, Mode=OneWay}"
|
||||
Icon="{x:Bind Icon, Mode=OneWay}"
|
||||
Text="{x:Bind Text, Mode=OneWay}"
|
||||
ToolTipService.ToolTip="{x:Bind ToolTip, Mode=OneWay}" />
|
||||
</DataTemplate>
|
||||
|
||||
<!-- https://learn.microsoft.com/windows/apps/design/controls/itemsview#specify-the-look-of-the-items -->
|
||||
<DataTemplate x:Key="ListItemViewModelTemplate" x:DataType="viewmodels:ListItemViewModel">
|
||||
|
||||
<Grid Padding="0,12,0,12" ColumnSpacing="12">
|
||||
<Grid
|
||||
Padding="0,12,0,12"
|
||||
AutomationProperties.Name="{x:Bind Title, Mode=OneWay}"
|
||||
ColumnSpacing="12">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="28" />
|
||||
<ColumnDefinition Width="*" />
|
||||
@@ -55,6 +56,7 @@
|
||||
Width="20"
|
||||
Height="20"
|
||||
Margin="4,0,4,0"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
SourceKey="{x:Bind Icon, Mode=OneWay}"
|
||||
SourceRequested="{x:Bind help:IconCacheProvider.SourceRequested}" />
|
||||
|
||||
@@ -187,6 +187,10 @@ public sealed partial class ListPage : Page,
|
||||
{
|
||||
ItemsList.SelectedIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
ItemsList.SelectedIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void Receive(NavigatePreviousCommand message)
|
||||
@@ -195,6 +199,10 @@ public sealed partial class ListPage : Page,
|
||||
{
|
||||
ItemsList.SelectedIndex--;
|
||||
}
|
||||
else
|
||||
{
|
||||
ItemsList.SelectedIndex = ItemsList.Items.Count - 1;
|
||||
}
|
||||
}
|
||||
|
||||
public void Receive(ActivateSelectedListItemMessage message)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
using CmdPalKeyboardService;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.CmdPal.Common.Helpers;
|
||||
using Microsoft.CmdPal.Common.Messages;
|
||||
@@ -52,9 +53,10 @@ public sealed partial class MainWindow : Window,
|
||||
#pragma warning restore SA1306 // Field names should begin with lower-case letter
|
||||
#pragma warning restore SA1310 // Field names should not contain underscore
|
||||
|
||||
private readonly KeyboardListener _keyboardListener;
|
||||
|
||||
// Notification Area ("Tray") icon data
|
||||
private NOTIFYICONDATAW? _trayIconData;
|
||||
private bool _createdIcon;
|
||||
private DestroyIconSafeHandle? _largeIcon;
|
||||
|
||||
private DesktopAcrylicController? _acrylicController;
|
||||
@@ -67,6 +69,11 @@ public sealed partial class MainWindow : Window,
|
||||
_hwnd = new HWND(WinRT.Interop.WindowNative.GetWindowHandle(this).ToInt32());
|
||||
CommandPaletteHost.SetHostHwnd((ulong)_hwnd.Value);
|
||||
|
||||
_keyboardListener = new KeyboardListener();
|
||||
_keyboardListener.Start();
|
||||
|
||||
_keyboardListener.SetProcessCommand(new CmdPalKeyboardService.ProcessCommand(HandleSummon));
|
||||
|
||||
// TaskbarCreated is the message that's broadcast when explorer.exe
|
||||
// restarts. We need to know when that happens to be able to bring our
|
||||
// notification area icon back
|
||||
@@ -99,7 +106,6 @@ public sealed partial class MainWindow : Window,
|
||||
_hotkeyWndProc = HotKeyPrc;
|
||||
var hotKeyPrcPointer = Marshal.GetFunctionPointerForDelegate(_hotkeyWndProc);
|
||||
_originalWndProc = Marshal.GetDelegateForFunctionPointer<WNDPROC>(PInvoke.SetWindowLongPtr(_hwnd, WINDOW_LONG_PTR_INDEX.GWL_WNDPROC, hotKeyPrcPointer));
|
||||
AddNotificationIcon();
|
||||
|
||||
// Load our settings, and then also wire up a settings changed handler
|
||||
HotReloadSettings();
|
||||
@@ -149,6 +155,7 @@ public sealed partial class MainWindow : Window,
|
||||
var settings = App.Current.Services.GetService<SettingsModel>()!;
|
||||
|
||||
SetupHotkey(settings);
|
||||
SetupTrayIcon(settings.ShowSystemTrayIcon);
|
||||
|
||||
// This will prevent our window from appearing in alt+tab or the taskbar.
|
||||
// You'll _need_ to use the hotkey to summon it.
|
||||
@@ -279,16 +286,12 @@ public sealed partial class MainWindow : Window,
|
||||
ShowHwnd(message.Hwnd, settings.SummonOn);
|
||||
}
|
||||
|
||||
public void Receive(HideWindowMessage message)
|
||||
{
|
||||
PInvoke.ShowWindow(_hwnd, SHOW_WINDOW_CMD.SW_HIDE);
|
||||
}
|
||||
public void Receive(HideWindowMessage message) => PInvoke.ShowWindow(_hwnd, SHOW_WINDOW_CMD.SW_HIDE);
|
||||
|
||||
public void Receive(QuitMessage message) =>
|
||||
|
||||
public void Receive(QuitMessage message)
|
||||
{
|
||||
// This might come in on a background thread
|
||||
DispatcherQueue.TryEnqueue(() => Close());
|
||||
}
|
||||
|
||||
public void Receive(DismissMessage message) =>
|
||||
PInvoke.ShowWindow(_hwnd, SHOW_WINDOW_CMD.SW_HIDE);
|
||||
@@ -299,12 +302,14 @@ public sealed partial class MainWindow : Window,
|
||||
var extensionService = serviceProvider.GetService<IExtensionService>()!;
|
||||
extensionService.SignalStopExtensionsAsync();
|
||||
|
||||
RemoveNotificationIcon();
|
||||
RemoveTrayIcon();
|
||||
|
||||
// WinUI bug is causing a crash on shutdown when FailFastOnErrors is set to true (#51773592).
|
||||
// Workaround by turning it off before shutdown.
|
||||
App.Current.DebugSettings.FailFastOnErrors = false;
|
||||
DisposeAcrylic();
|
||||
|
||||
_keyboardListener.Stop();
|
||||
}
|
||||
|
||||
private void DisposeAcrylic()
|
||||
@@ -369,12 +374,17 @@ public sealed partial class MainWindow : Window,
|
||||
// ... then don't hide the window when it loses focus.
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
PInvoke.ShowWindow(_hwnd, SHOW_WINDOW_CMD.SW_HIDE);
|
||||
|
||||
PowerToysTelemetry.Log.WriteEvent(new CmdPalDismissedOnLostFocus());
|
||||
// Are we disabled? If we are, then we don't want to dismiss on focus lost.
|
||||
// This can happen if an extension wanted to show a modal dialog on top of our
|
||||
// window i.e. in the case of an MSAL auth window.
|
||||
if (PInvoke.IsWindowEnabled(_hwnd) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PInvoke.ShowWindow(_hwnd, SHOW_WINDOW_CMD.SW_HIDE);
|
||||
PowerToysTelemetry.Log.WriteEvent(new CmdPalDismissedOnLostFocus());
|
||||
}
|
||||
|
||||
if (_configurationSource != null)
|
||||
@@ -383,14 +393,13 @@ public sealed partial class MainWindow : Window,
|
||||
}
|
||||
}
|
||||
|
||||
public void Summon(string commandId)
|
||||
{
|
||||
public void Summon(string commandId) =>
|
||||
|
||||
// The actual showing and hiding of the window will be done by the
|
||||
// ShellPage. This is because we don't want to show the window if the
|
||||
// user bound a hotkey to just an invokable command, which we can't
|
||||
// know till the message is being handled.
|
||||
WeakReferenceMessenger.Default.Send<HotkeySummonMessage>(new(commandId, _hwnd));
|
||||
}
|
||||
|
||||
#pragma warning disable SA1310 // Field names should not contain underscore
|
||||
private const uint DOT_KEY = 0xBE;
|
||||
@@ -399,6 +408,8 @@ public sealed partial class MainWindow : Window,
|
||||
|
||||
private void UnregisterHotkeys()
|
||||
{
|
||||
_keyboardListener.ClearHotkeys();
|
||||
|
||||
while (_hotkeys.Count > 0)
|
||||
{
|
||||
PInvoke.UnregisterHotKey(_hwnd, _hotkeys.Count - 1);
|
||||
@@ -413,19 +424,28 @@ public sealed partial class MainWindow : Window,
|
||||
var globalHotkey = settings.Hotkey;
|
||||
if (globalHotkey != null)
|
||||
{
|
||||
var vk = globalHotkey.Code;
|
||||
var modifiers =
|
||||
(globalHotkey.Alt ? HOT_KEY_MODIFIERS.MOD_ALT : 0) |
|
||||
(globalHotkey.Ctrl ? HOT_KEY_MODIFIERS.MOD_CONTROL : 0) |
|
||||
(globalHotkey.Shift ? HOT_KEY_MODIFIERS.MOD_SHIFT : 0) |
|
||||
(globalHotkey.Win ? HOT_KEY_MODIFIERS.MOD_WIN : 0)
|
||||
;
|
||||
|
||||
var success = PInvoke.RegisterHotKey(_hwnd, _hotkeys.Count, modifiers, (uint)vk);
|
||||
if (success)
|
||||
if (settings.UseLowLevelGlobalHotkey)
|
||||
{
|
||||
_keyboardListener.SetHotkeyAction(globalHotkey.Win, globalHotkey.Ctrl, globalHotkey.Shift, globalHotkey.Alt, (byte)globalHotkey.Code, string.Empty);
|
||||
|
||||
_hotkeys.Add(new(globalHotkey, string.Empty));
|
||||
}
|
||||
else
|
||||
{
|
||||
var vk = globalHotkey.Code;
|
||||
var modifiers =
|
||||
(globalHotkey.Alt ? HOT_KEY_MODIFIERS.MOD_ALT : 0) |
|
||||
(globalHotkey.Ctrl ? HOT_KEY_MODIFIERS.MOD_CONTROL : 0) |
|
||||
(globalHotkey.Shift ? HOT_KEY_MODIFIERS.MOD_SHIFT : 0) |
|
||||
(globalHotkey.Win ? HOT_KEY_MODIFIERS.MOD_WIN : 0)
|
||||
;
|
||||
|
||||
var success = PInvoke.RegisterHotKey(_hwnd, _hotkeys.Count, modifiers, (uint)vk);
|
||||
if (success)
|
||||
{
|
||||
_hotkeys.Add(new(globalHotkey, string.Empty));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var commandHotkey in settings.CommandHotkeys)
|
||||
@@ -451,6 +471,26 @@ public sealed partial class MainWindow : Window,
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleSummon(string commandId)
|
||||
{
|
||||
var isRootHotkey = string.IsNullOrEmpty(commandId);
|
||||
PowerToysTelemetry.Log.WriteEvent(new CmdPalHotkeySummoned(isRootHotkey));
|
||||
|
||||
// Note to future us: the wParam will have the index of the hotkey we registered.
|
||||
// We can use that in the future to differentiate the hotkeys we've pressed
|
||||
// so that we can bind hotkeys to individual commands
|
||||
if (!this.Visible || !isRootHotkey)
|
||||
{
|
||||
Activate();
|
||||
|
||||
Summon(commandId);
|
||||
}
|
||||
else if (isRootHotkey)
|
||||
{
|
||||
PInvoke.ShowWindow(_hwnd, SHOW_WINDOW_CMD.SW_HIDE);
|
||||
}
|
||||
}
|
||||
|
||||
private LRESULT HotKeyPrc(
|
||||
HWND hwnd,
|
||||
uint uMsg,
|
||||
@@ -465,22 +505,23 @@ public sealed partial class MainWindow : Window,
|
||||
if (hotkeyIndex < _hotkeys.Count)
|
||||
{
|
||||
var hotkey = _hotkeys[hotkeyIndex];
|
||||
var isRootHotkey = string.IsNullOrEmpty(hotkey.CommandId);
|
||||
PowerToysTelemetry.Log.WriteEvent(new CmdPalHotkeySummoned(isRootHotkey));
|
||||
HandleSummon(hotkey.CommandId);
|
||||
|
||||
// Note to future us: the wParam will have the index of the hotkey we registered.
|
||||
// We can use that in the future to differentiate the hotkeys we've pressed
|
||||
// so that we can bind hotkeys to individual commands
|
||||
if (!this.Visible || !isRootHotkey)
|
||||
{
|
||||
Activate();
|
||||
// var isRootHotkey = string.IsNullOrEmpty(hotkey.CommandId);
|
||||
|
||||
Summon(hotkey.CommandId);
|
||||
}
|
||||
else if (isRootHotkey)
|
||||
{
|
||||
PInvoke.ShowWindow(hwnd, SHOW_WINDOW_CMD.SW_HIDE);
|
||||
}
|
||||
// // Note to future us: the wParam will have the index of the hotkey we registered.
|
||||
// // We can use that in the future to differentiate the hotkeys we've pressed
|
||||
// // so that we can bind hotkeys to individual commands
|
||||
// if (!this.Visible || !isRootHotkey)
|
||||
// {
|
||||
// Activate();
|
||||
|
||||
// Summon(hotkey.CommandId);
|
||||
// }
|
||||
// else if (isRootHotkey)
|
||||
// {
|
||||
// PInvoke.ShowWindow(hwnd, SHOW_WINDOW_CMD.SW_HIDE);
|
||||
// }
|
||||
}
|
||||
|
||||
return (LRESULT)IntPtr.Zero;
|
||||
@@ -491,9 +532,9 @@ public sealed partial class MainWindow : Window,
|
||||
// WM_WINDOWPOSCHANGING which is always received on explorer startup sequence.
|
||||
case PInvoke.WM_WINDOWPOSCHANGING:
|
||||
{
|
||||
if (!_createdIcon)
|
||||
if (_trayIconData == null)
|
||||
{
|
||||
AddNotificationIcon();
|
||||
SetupTrayIcon();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -505,7 +546,7 @@ public sealed partial class MainWindow : Window,
|
||||
{
|
||||
// Handle the case where explorer.exe restarts.
|
||||
// Even if we created it before, do it again
|
||||
AddNotificationIcon();
|
||||
SetupTrayIcon();
|
||||
}
|
||||
else if (uMsg == WM_TRAY_ICON)
|
||||
{
|
||||
@@ -525,55 +566,60 @@ public sealed partial class MainWindow : Window,
|
||||
return PInvoke.CallWindowProc(_originalWndProc, hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
private void AddNotificationIcon()
|
||||
private void SetupTrayIcon(bool? showSystemTrayIcon = null)
|
||||
{
|
||||
// We only need to build the tray data once.
|
||||
if (_trayIconData == null)
|
||||
if (showSystemTrayIcon ?? App.Current.Services.GetService<SettingsModel>()!.ShowSystemTrayIcon)
|
||||
{
|
||||
// We need to stash this handle, so it doesn't clean itself up. If
|
||||
// explorer restarts, we'll come back through here, and we don't
|
||||
// really need to re-load the icon in that case. We can just use
|
||||
// the handle from the first time.
|
||||
_largeIcon = GetAppIconHandle();
|
||||
_trayIconData = new NOTIFYICONDATAW()
|
||||
// We only need to build the tray data once.
|
||||
if (_trayIconData == null)
|
||||
{
|
||||
cbSize = (uint)Marshal.SizeOf(typeof(NOTIFYICONDATAW)),
|
||||
hWnd = _hwnd,
|
||||
uID = MY_NOTIFY_ID,
|
||||
uFlags = NOTIFY_ICON_DATA_FLAGS.NIF_MESSAGE | NOTIFY_ICON_DATA_FLAGS.NIF_ICON | NOTIFY_ICON_DATA_FLAGS.NIF_TIP,
|
||||
uCallbackMessage = WM_TRAY_ICON,
|
||||
hIcon = (HICON)_largeIcon.DangerousGetHandle(),
|
||||
szTip = RS_.GetString("AppStoreName"),
|
||||
};
|
||||
// We need to stash this handle, so it doesn't clean itself up. If
|
||||
// explorer restarts, we'll come back through here, and we don't
|
||||
// really need to re-load the icon in that case. We can just use
|
||||
// the handle from the first time.
|
||||
_largeIcon = GetAppIconHandle();
|
||||
_trayIconData = new NOTIFYICONDATAW()
|
||||
{
|
||||
cbSize = (uint)Marshal.SizeOf(typeof(NOTIFYICONDATAW)),
|
||||
hWnd = _hwnd,
|
||||
uID = MY_NOTIFY_ID,
|
||||
uFlags = NOTIFY_ICON_DATA_FLAGS.NIF_MESSAGE | NOTIFY_ICON_DATA_FLAGS.NIF_ICON | NOTIFY_ICON_DATA_FLAGS.NIF_TIP,
|
||||
uCallbackMessage = WM_TRAY_ICON,
|
||||
hIcon = (HICON)_largeIcon.DangerousGetHandle(),
|
||||
szTip = RS_.GetString("AppStoreName"),
|
||||
};
|
||||
}
|
||||
|
||||
var d = (NOTIFYICONDATAW)_trayIconData;
|
||||
|
||||
// Add the notification icon
|
||||
PInvoke.Shell_NotifyIcon(NOTIFY_ICON_MESSAGE.NIM_ADD, in d);
|
||||
}
|
||||
|
||||
var d = (NOTIFYICONDATAW)_trayIconData;
|
||||
|
||||
// Add the notification icon
|
||||
if (PInvoke.Shell_NotifyIcon(NOTIFY_ICON_MESSAGE.NIM_ADD, in d))
|
||||
else
|
||||
{
|
||||
_createdIcon = true;
|
||||
RemoveTrayIcon();
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveNotificationIcon()
|
||||
private void RemoveTrayIcon()
|
||||
{
|
||||
if (_trayIconData != null && _createdIcon)
|
||||
if (_trayIconData != null)
|
||||
{
|
||||
var d = (NOTIFYICONDATAW)_trayIconData;
|
||||
if (PInvoke.Shell_NotifyIcon(NOTIFY_ICON_MESSAGE.NIM_DELETE, in d))
|
||||
{
|
||||
_createdIcon = false;
|
||||
_trayIconData = null;
|
||||
}
|
||||
}
|
||||
|
||||
_largeIcon?.Close();
|
||||
}
|
||||
|
||||
private DestroyIconSafeHandle GetAppIconHandle()
|
||||
{
|
||||
var exePath = System.Reflection.Assembly.GetExecutingAssembly().Location;
|
||||
DestroyIconSafeHandle largeIcon;
|
||||
DestroyIconSafeHandle smallIcon;
|
||||
PInvoke.ExtractIconEx(exePath, 0, out largeIcon, out smallIcon, 1);
|
||||
PInvoke.ExtractIconEx(exePath, 0, out largeIcon, out _, 1);
|
||||
return largeIcon;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
<EnableMsixTooling>true</EnableMsixTooling>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>
|
||||
|
||||
<Version>$(CmdPalVersion)</Version>
|
||||
|
||||
@@ -22,13 +23,13 @@
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(CIBuild)'=='true'">
|
||||
<PropertyGroup>
|
||||
<GenerateAppxPackageOnBuild>true</GenerateAppxPackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- This lets us actually reference types from Microsoft.Terminal.UI -->
|
||||
<CsWinRTIncludes>Microsoft.Terminal.UI</CsWinRTIncludes>
|
||||
<CsWinRTIncludes>Microsoft.Terminal.UI;CmdPalKeyboardService</CsWinRTIncludes>
|
||||
<CsWinRTGeneratedFilesDir>$(OutDir)</CsWinRTGeneratedFilesDir>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -72,12 +73,17 @@
|
||||
</PackageReference>
|
||||
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" />
|
||||
|
||||
<PackageReference Include="System.Net.Http" />
|
||||
|
||||
<PackageReference Include="System.Private.Uri" />
|
||||
<PackageReference Include="System.Text.Json" />
|
||||
|
||||
<!-- LOAD BEARING: GeneratePathProperty=true on BOTH the AC dependencies. Don't forget the AdaptiveCardsWorkaround below -->
|
||||
<PackageReference Include="AdaptiveCards.ObjectModel.WinUI3" GeneratePathProperty="true" />
|
||||
<PackageReference Include="AdaptiveCards.Rendering.WinUI3" GeneratePathProperty="True" />
|
||||
<PackageReference Include="AdaptiveCards.Templating" />
|
||||
<PackageReference Include="System.Text.RegularExpressions" />
|
||||
</ItemGroup>
|
||||
|
||||
<!--
|
||||
@@ -91,32 +97,38 @@
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\common\ManagedTelemetry\Telemetry\ManagedTelemetry.csproj" />
|
||||
<ProjectReference Include="..\Exts\Microsoft.CmdPal.Ext.System\Microsoft.CmdPal.Ext.System.csproj" />
|
||||
<ProjectReference Include="..\Exts\Microsoft.CmdPal.Ext.WebSearch\Microsoft.CmdPal.Ext.WebSearch.csproj" />
|
||||
<ProjectReference Include="..\Exts\Microsoft.CmdPal.Ext.Indexer\Microsoft.CmdPal.Ext.Indexer.csproj" />
|
||||
<ProjectReference Include="..\ext\Microsoft.CmdPal.Ext.System\Microsoft.CmdPal.Ext.System.csproj" />
|
||||
<ProjectReference Include="..\ext\Microsoft.CmdPal.Ext.WebSearch\Microsoft.CmdPal.Ext.WebSearch.csproj" />
|
||||
<ProjectReference Include="..\ext\Microsoft.CmdPal.Ext.Indexer\Microsoft.CmdPal.Ext.Indexer.csproj" />
|
||||
<ProjectReference Include="..\Microsoft.CmdPal.Common\Microsoft.CmdPal.Common.csproj" />
|
||||
<ProjectReference Include="..\Microsoft.CmdPal.UI.ViewModels\Microsoft.CmdPal.UI.ViewModels.csproj" />
|
||||
|
||||
<ProjectReference Include="..\extensionsdk\Microsoft.CommandPalette.Extensions.Toolkit\Microsoft.CommandPalette.Extensions.Toolkit.csproj" />
|
||||
|
||||
<ProjectReference Include="..\Exts\Microsoft.CmdPal.Ext.Apps\Microsoft.CmdPal.Ext.Apps.csproj" />
|
||||
<ProjectReference Include="..\Exts\Microsoft.CmdPal.Ext.Bookmark\Microsoft.CmdPal.Ext.Bookmarks.csproj" />
|
||||
<ProjectReference Include="..\Exts\Microsoft.CmdPal.Ext.Calc\Microsoft.CmdPal.Ext.Calc.csproj" />
|
||||
<ProjectReference Include="..\Exts\Microsoft.CmdPal.Ext.ClipboardHistory\Microsoft.CmdPal.Ext.ClipboardHistory.csproj" />
|
||||
<ProjectReference Include="..\Exts\Microsoft.CmdPal.Ext.Registry\Microsoft.CmdPal.Ext.Registry.csproj" />
|
||||
<ProjectReference Include="..\Exts\Microsoft.CmdPal.Ext.Shell\Microsoft.CmdPal.Ext.Shell.csproj" />
|
||||
<ProjectReference Include="..\Exts\Microsoft.CmdPal.Ext.TimeDate\Microsoft.CmdPal.Ext.TimeDate.csproj" />
|
||||
<ProjectReference Include="..\Exts\Microsoft.CmdPal.Ext.WindowsServices\Microsoft.CmdPal.Ext.WindowsServices.csproj" />
|
||||
<ProjectReference Include="..\Exts\Microsoft.CmdPal.Ext.WindowsSettings\Microsoft.CmdPal.Ext.WindowsSettings.csproj" />
|
||||
<ProjectReference Include="..\Exts\Microsoft.CmdPal.Ext.WindowsTerminal\Microsoft.CmdPal.Ext.WindowsTerminal.csproj" />
|
||||
<ProjectReference Include="..\Exts\Microsoft.CmdPal.Ext.WindowWalker\Microsoft.CmdPal.Ext.WindowWalker.csproj" />
|
||||
<ProjectReference Include="..\Exts\Microsoft.CmdPal.Ext.WinGet\Microsoft.CmdPal.Ext.WinGet.csproj" />
|
||||
<ProjectReference Include="..\ext\Microsoft.CmdPal.Ext.Apps\Microsoft.CmdPal.Ext.Apps.csproj" />
|
||||
<ProjectReference Include="..\ext\Microsoft.CmdPal.Ext.Bookmark\Microsoft.CmdPal.Ext.Bookmarks.csproj" />
|
||||
<ProjectReference Include="..\ext\Microsoft.CmdPal.Ext.Calc\Microsoft.CmdPal.Ext.Calc.csproj" />
|
||||
<ProjectReference Include="..\ext\Microsoft.CmdPal.Ext.ClipboardHistory\Microsoft.CmdPal.Ext.ClipboardHistory.csproj" />
|
||||
<ProjectReference Include="..\ext\Microsoft.CmdPal.Ext.Registry\Microsoft.CmdPal.Ext.Registry.csproj" />
|
||||
<ProjectReference Include="..\ext\Microsoft.CmdPal.Ext.Shell\Microsoft.CmdPal.Ext.Shell.csproj" />
|
||||
<ProjectReference Include="..\ext\Microsoft.CmdPal.Ext.TimeDate\Microsoft.CmdPal.Ext.TimeDate.csproj" />
|
||||
<ProjectReference Include="..\ext\Microsoft.CmdPal.Ext.WindowsServices\Microsoft.CmdPal.Ext.WindowsServices.csproj" />
|
||||
<ProjectReference Include="..\ext\Microsoft.CmdPal.Ext.WindowsSettings\Microsoft.CmdPal.Ext.WindowsSettings.csproj" />
|
||||
<ProjectReference Include="..\ext\Microsoft.CmdPal.Ext.WindowsTerminal\Microsoft.CmdPal.Ext.WindowsTerminal.csproj" />
|
||||
<ProjectReference Include="..\ext\Microsoft.CmdPal.Ext.WindowWalker\Microsoft.CmdPal.Ext.WindowWalker.csproj" />
|
||||
<ProjectReference Include="..\ext\Microsoft.CmdPal.Ext.WinGet\Microsoft.CmdPal.Ext.WinGet.csproj" />
|
||||
|
||||
<ProjectReference Include="..\Microsoft.Terminal.UI\Microsoft.Terminal.UI.vcxproj">
|
||||
<ReferenceOutputAssembly>True</ReferenceOutputAssembly>
|
||||
<Private>True</Private>
|
||||
<CopyLocalSatelliteAssemblies>True</CopyLocalSatelliteAssemblies>
|
||||
</ProjectReference>
|
||||
|
||||
<ProjectReference Include="..\CmdPalKeyboardService\CmdPalKeyboardService.vcxproj">
|
||||
<ReferenceOutputAssembly>True</ReferenceOutputAssembly>
|
||||
<Private>True</Private>
|
||||
<CopyLocalSatelliteAssemblies>True</CopyLocalSatelliteAssemblies>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -15,10 +15,12 @@ CallWindowProc
|
||||
ShowWindow
|
||||
SetForegroundWindow
|
||||
EnableWindow
|
||||
IsWindowEnabled
|
||||
SetFocus
|
||||
SetActiveWindow
|
||||
MonitorFromWindow
|
||||
GetMonitorInfo
|
||||
GetDpiForMonitor
|
||||
SHCreateStreamOnFileEx
|
||||
CoAllowSetForegroundWindow
|
||||
SHCreateStreamOnFileEx
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
<DataTemplate x:Key="TagTemplate" x:DataType="viewModels:TagViewModel">
|
||||
<cpcontrols:Tag
|
||||
HorizontalAlignment="Left"
|
||||
AutomationProperties.Name="{x:Bind Text, Mode=OneWay}"
|
||||
BackgroundColor="{x:Bind Background, Mode=OneWay}"
|
||||
FontSize="12"
|
||||
ForegroundColor="{x:Bind Foreground, Mode=OneWay}"
|
||||
@@ -147,27 +148,36 @@
|
||||
Visibility="{x:Bind ViewModel.CurrentPage.IsNested, Mode=OneWay, Converter={StaticResource BoolToInvertedVisibilityConverter}}">
|
||||
<animations:Implicit.ShowAnimations>
|
||||
<animations:OpacityAnimation
|
||||
EasingMode="EaseIn"
|
||||
EasingType="Cubic"
|
||||
From="0"
|
||||
To="1.0"
|
||||
Duration="0:0:0.340" />
|
||||
Duration="0:0:0.187" />
|
||||
<animations:ScaleAnimation
|
||||
EasingMode="EaseIn"
|
||||
EasingType="Cubic"
|
||||
From="0.5"
|
||||
To="1"
|
||||
Duration="0:0:0.350" />
|
||||
Duration="0:0:0.187" />
|
||||
</animations:Implicit.ShowAnimations>
|
||||
<animations:Implicit.HideAnimations>
|
||||
<animations:OpacityAnimation
|
||||
EasingMode="EaseOut"
|
||||
EasingType="Cubic"
|
||||
From="1.0"
|
||||
To="0"
|
||||
Duration="0:0:0.240" />
|
||||
Duration="0:0:0.187" />
|
||||
<animations:ScaleAnimation
|
||||
EasingMode="EaseOut"
|
||||
EasingType="Cubic"
|
||||
From="1"
|
||||
To="0.5"
|
||||
Duration="0:0:0.350" />
|
||||
Duration="0:0:0.187" />
|
||||
</animations:Implicit.HideAnimations>
|
||||
</Image>
|
||||
<Button
|
||||
x:Name="BackButton"
|
||||
x:Uid="BackButton"
|
||||
Margin="4,0,4,0"
|
||||
Padding="4"
|
||||
HorizontalAlignment="Center"
|
||||
@@ -178,35 +188,42 @@
|
||||
FontSize="16"
|
||||
Style="{StaticResource SubtleButtonStyle}"
|
||||
Tapped="BackButton_Tapped"
|
||||
ToolTipService.ToolTip="Back"
|
||||
Visibility="{x:Bind ViewModel.CurrentPage.IsNested, Mode=OneWay}">
|
||||
<animations:Implicit.ShowAnimations>
|
||||
<animations:OpacityAnimation
|
||||
EasingMode="EaseIn"
|
||||
EasingType="Cubic"
|
||||
From="0"
|
||||
To="1.0"
|
||||
Duration="0:0:0.340" />
|
||||
Duration="0:0:0.333" />
|
||||
<animations:ScaleAnimation
|
||||
From="0.5"
|
||||
To="1"
|
||||
Duration="0:0:0.350" />
|
||||
Duration="0:0:0.333" />
|
||||
<animations:TranslationAnimation
|
||||
From="16,0,0"
|
||||
To="0,0,0"
|
||||
Duration="0:0:0.350" />
|
||||
Duration="0:0:0.333" />
|
||||
</animations:Implicit.ShowAnimations>
|
||||
<animations:Implicit.HideAnimations>
|
||||
<animations:OpacityAnimation
|
||||
EasingMode="EaseOut"
|
||||
EasingType="Cubic"
|
||||
From="1.0"
|
||||
To="0"
|
||||
Duration="0:0:0.340" />
|
||||
Duration="0:0:0.333" />
|
||||
<animations:ScaleAnimation
|
||||
EasingMode="EaseOut"
|
||||
EasingType="Cubic"
|
||||
From="1"
|
||||
To="0.5"
|
||||
Duration="0:0:0.350" />
|
||||
Duration="0:0:0.333" />
|
||||
<animations:TranslationAnimation
|
||||
EasingMode="EaseOut"
|
||||
EasingType="Cubic"
|
||||
From="0,0,0"
|
||||
To="16,0,0"
|
||||
Duration="0:0:0.350" />
|
||||
Duration="0:0:0.187" />
|
||||
</animations:Implicit.HideAnimations>
|
||||
</Button>
|
||||
<cpcontrols:IconBox
|
||||
@@ -223,29 +240,29 @@
|
||||
<animations:OpacityAnimation
|
||||
From="0"
|
||||
To="1.0"
|
||||
Duration="0:0:0.450" />
|
||||
Duration="0:0:0.333" />
|
||||
<animations:ScaleAnimation
|
||||
From="0.8"
|
||||
To="1"
|
||||
Duration="0:0:0.500" />
|
||||
Duration="0:0:0.333" />
|
||||
<animations:TranslationAnimation
|
||||
From="8,0,0"
|
||||
To="0,0,0"
|
||||
Duration="0:0:0.400" />
|
||||
Duration="0:0:0.187" />
|
||||
</animations:Implicit.ShowAnimations>
|
||||
<animations:Implicit.HideAnimations>
|
||||
<animations:OpacityAnimation
|
||||
From="1.0"
|
||||
To="0"
|
||||
Duration="0:0:0.340" />
|
||||
Duration="0:0:0.333" />
|
||||
<animations:ScaleAnimation
|
||||
From="1"
|
||||
To="0.8"
|
||||
Duration="0:0:0.350" />
|
||||
Duration="0:0:0.333" />
|
||||
<animations:TranslationAnimation
|
||||
From="0,0,0"
|
||||
To="8,0,0"
|
||||
Duration="0:0:0.350" />
|
||||
Duration="0:0:0.187" />
|
||||
</animations:Implicit.HideAnimations>
|
||||
</cpcontrols:IconBox>
|
||||
</StackPanel>
|
||||
@@ -272,13 +289,13 @@
|
||||
<animations:OpacityAnimation
|
||||
From="0"
|
||||
To="1.0"
|
||||
Duration="0:0:0.340" />
|
||||
Duration="0:0:0.333" />
|
||||
</animations:Implicit.ShowAnimations>
|
||||
<animations:Implicit.HideAnimations>
|
||||
<animations:OpacityAnimation
|
||||
From="1.0"
|
||||
To="0"
|
||||
Duration="0:0:0.340" />
|
||||
Duration="0:0:0.333" />
|
||||
</animations:Implicit.HideAnimations>
|
||||
</ProgressBar>
|
||||
|
||||
@@ -313,21 +330,21 @@
|
||||
<animations:OpacityAnimation
|
||||
From="0"
|
||||
To="1.0"
|
||||
Duration="0:0:0.270" />
|
||||
Duration="0:0:0.187" />
|
||||
<animations:TranslationAnimation
|
||||
From="24,0,0"
|
||||
To="0,0,0"
|
||||
Duration="0:0:0.280" />
|
||||
Duration="0:0:0.187" />
|
||||
</animations:Implicit.ShowAnimations>
|
||||
<animations:Implicit.HideAnimations>
|
||||
<animations:OpacityAnimation
|
||||
From="1.0"
|
||||
To="0"
|
||||
Duration="0:0:0.180" />
|
||||
Duration="0:0:0.187" />
|
||||
<animations:TranslationAnimation
|
||||
From="0,0,0"
|
||||
To="24,0,0"
|
||||
Duration="0:0:0.220" />
|
||||
Duration="0:0:0.187" />
|
||||
</animations:Implicit.HideAnimations>
|
||||
<Grid Margin="12">
|
||||
<Grid.RowDefinitions>
|
||||
@@ -343,6 +360,7 @@
|
||||
MinHeight="64"
|
||||
MaxHeight="96"
|
||||
HorizontalAlignment="Center"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
SourceKey="{x:Bind ViewModel.Details.HeroImage, Mode=OneWay}"
|
||||
SourceRequested="{x:Bind help:IconCacheProvider.SourceRequested}"
|
||||
Visibility="{x:Bind HasHeroImage, Mode=OneWay}" />
|
||||
|
||||
@@ -187,6 +187,8 @@ public sealed partial class ShellPage : Microsoft.UI.Xaml.Controls.Page,
|
||||
|
||||
WeakReferenceMessenger.Default.Send<UpdateCommandBarMessage>(new(null));
|
||||
|
||||
WeakReferenceMessenger.Default.Send<UpdateItemKeybindingsMessage>(new(null));
|
||||
|
||||
var isMainPage = command is MainListPage;
|
||||
|
||||
// Construct our ViewModel of the appropriate type and pass it the UI Thread context.
|
||||
@@ -427,8 +429,6 @@ public sealed partial class ShellPage : Microsoft.UI.Xaml.Controls.Page,
|
||||
}
|
||||
|
||||
_settingsWindow.Activate();
|
||||
|
||||
WeakReferenceMessenger.Default.Send<UpdateCommandBarMessage>(new(null));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -36,9 +36,18 @@
|
||||
|
||||
<TextBlock x:Uid="ActivationSettingsHeader" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
|
||||
<controls:SettingsCard x:Uid="Settings_GeneralPage_ActivationKey_SettingsExpander" HeaderIcon="{ui:FontIcon Glyph=}">
|
||||
<controls:SettingsExpander
|
||||
x:Uid="Settings_GeneralPage_ActivationKey_SettingsExpander"
|
||||
HeaderIcon="{ui:FontIcon Glyph=}"
|
||||
IsExpanded="True">
|
||||
<ptControls:ShortcutControl HotkeySettings="{x:Bind viewModel.Hotkey, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="Settings_GeneralPage_LowLevelHook_SettingsCard">
|
||||
<ToggleSwitch IsOn="{x:Bind viewModel.UseLowLevelGlobalHotkey, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
<controls:SettingsCard x:Uid="Settings_GeneralPage_GoHome_SettingsCard" HeaderIcon="{ui:FontIcon Glyph=}">
|
||||
<ToggleSwitch IsOn="{x:Bind viewModel.HotkeyGoesHome, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
@@ -68,6 +77,10 @@
|
||||
<ToggleSwitch IsOn="{x:Bind viewModel.SingleClickActivates, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="Settings_GeneralPage_ShowSystemTrayIcon_SettingsCard" HeaderIcon="{ui:FontIcon Glyph=}">
|
||||
<ToggleSwitch IsOn="{x:Bind viewModel.ShowSystemTrayIcon, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<!-- Example 'About' section -->
|
||||
<TextBlock x:Uid="AboutSettingsHeader" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
|
||||
|
||||
@@ -322,6 +322,12 @@ Right-click to remove the key combination, thereby deactivating the shortcut.</v
|
||||
<data name="Settings_GeneralPage_ActivationKey_SettingsExpander.Description" xml:space="preserve">
|
||||
<value>This key will open the Command Palette.</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_LowLevelHook_SettingsCard.Header" xml:space="preserve">
|
||||
<value>Use low-level keyboard hook</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_LowLevelHook_SettingsCard.Description" xml:space="preserve">
|
||||
<value>Try this if there are issues with the shortcut (Command Palette might not get focus when triggered from an elevated window)</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_GoHome_SettingsCard.Header" xml:space="preserve">
|
||||
<value>Go home when activated</value>
|
||||
</data>
|
||||
@@ -373,9 +379,6 @@ Right-click to remove the key combination, thereby deactivating the shortcut.</v
|
||||
<data name="Settings_GeneralPage_NavigationViewItem_Extensions.Content" xml:space="preserve">
|
||||
<value>Extensions</value>
|
||||
</data>
|
||||
<data name="MoreCommandsButton.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>More commands</value>
|
||||
</data>
|
||||
<data name="SettingsButton.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>Open Command Palette settings</value>
|
||||
</data>
|
||||
@@ -385,4 +388,19 @@ Right-click to remove the key combination, thereby deactivating the shortcut.</v
|
||||
<data name="BehaviorSettingsHeader.Text" xml:space="preserve">
|
||||
<value>Behavior</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_ShowSystemTrayIcon_SettingsCard.Header" xml:space="preserve">
|
||||
<value>Show system tray icon</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_ShowSystemTrayIcon_SettingsCard.Description" xml:space="preserve">
|
||||
<value>Choose if Command Palette is visible in the system tray</value>
|
||||
</data>
|
||||
<data name="BackButton.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>Back</value>
|
||||
</data>
|
||||
<data name="BackButton.[using:Microsoft.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Back</value>
|
||||
</data>
|
||||
<data name="MoreCommandsButton.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>More</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using CommunityToolkit.WinUI;
|
||||
using ManagedCommon;
|
||||
using Microsoft.CmdPal.UI.Helpers;
|
||||
using Microsoft.CmdPal.UI.ViewModels;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
@@ -13,6 +14,8 @@ using Microsoft.UI.Xaml;
|
||||
using Windows.Graphics;
|
||||
using Windows.Win32;
|
||||
using Windows.Win32.Foundation;
|
||||
using Windows.Win32.Graphics.Gdi;
|
||||
using Windows.Win32.UI.HiDpi;
|
||||
using Windows.Win32.UI.WindowsAndMessaging;
|
||||
using RS_ = Microsoft.CmdPal.UI.Helpers.ResourceLoaderInstance;
|
||||
|
||||
@@ -44,6 +47,21 @@ public sealed partial class ToastWindow : Window,
|
||||
WeakReferenceMessenger.Default.Register<QuitMessage>(this);
|
||||
}
|
||||
|
||||
private static double GetScaleFactor(HWND hwnd)
|
||||
{
|
||||
try
|
||||
{
|
||||
var monitor = PInvoke.MonitorFromWindow(hwnd, MONITOR_FROM_FLAGS.MONITOR_DEFAULTTONEAREST);
|
||||
_ = PInvoke.GetDpiForMonitor(monitor, MONITOR_DPI_TYPE.MDT_EFFECTIVE_DPI, out var dpiX, out _);
|
||||
return dpiX / 96.0;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError($"Failed to get scale factor, error: {ex.Message}");
|
||||
return 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
private void PositionCentered()
|
||||
{
|
||||
var intSize = new SizeInt32
|
||||
@@ -51,7 +69,14 @@ public sealed partial class ToastWindow : Window,
|
||||
Width = Convert.ToInt32(ToastText.ActualWidth),
|
||||
Height = Convert.ToInt32(ToastText.ActualHeight),
|
||||
};
|
||||
AppWindow.Resize(intSize);
|
||||
|
||||
var scaleAdjustment = GetScaleFactor(_hwnd);
|
||||
var scaled = new SizeInt32
|
||||
{
|
||||
Width = (int)Math.Round(intSize.Width * scaleAdjustment),
|
||||
Height = (int)Math.Round(intSize.Height * scaleAdjustment),
|
||||
};
|
||||
AppWindow.Resize(scaled);
|
||||
|
||||
var displayArea = DisplayArea.GetFromWindowId(AppWindow.Id, DisplayAreaFallback.Nearest);
|
||||
if (displayArea is not null)
|
||||
|
||||
@@ -40,7 +40,7 @@ Projects of interest are:
|
||||
|
||||
[Initial SDK Spec]: ./doc/initial-sdk-spec/initial-sdk-spec.md
|
||||
[generic samples]: ./Exts/SamplePagesExtension
|
||||
[real samples]: .Exts/ProcessMonitorExtension
|
||||
[real samples]: ./Exts/ProcessMonitorExtension
|
||||
[real extensions that we've "shipped" already]: https://github.com/zadjii/CmdPalExtensions/blob/main/src/extensions
|
||||
|
||||
|
||||
|
||||
@@ -152,7 +152,7 @@ We've made it easy to build a new extension. Just follow these steps:
|
||||
2. Run the following PowerShell script, replacing "MastodonExtension" with the `Name` of your extension and "Mastodon extension for cmdpal" with the `DisplayName` of the [command that will show up in the root view](#root-view) of the Command Palette:
|
||||
|
||||
```powershell
|
||||
.\Exts\NewExtension.ps1 -name MastodonExtension -DisplayName "Mastodon extension for cmdpal"
|
||||
.\ext\NewExtension.ps1 -name MastodonExtension -DisplayName "Mastodon extension for cmdpal"
|
||||
```
|
||||
|
||||
3. Open the solution in Visual Studio.
|
||||
|
||||
@@ -57,7 +57,7 @@ public sealed partial class AllAppsPage : ListPage
|
||||
Stopwatch stopwatch = new();
|
||||
stopwatch.Start();
|
||||
|
||||
List<AppItem> apps = GetPrograms();
|
||||
var apps = GetPrograms();
|
||||
|
||||
this.allAppsSection = apps
|
||||
.Select((app) => new AppListItem(app, true))
|
||||
@@ -73,26 +73,15 @@ public sealed partial class AllAppsPage : ListPage
|
||||
|
||||
internal List<AppItem> GetPrograms()
|
||||
{
|
||||
IEnumerable<AppItem> uwpResults = AppCache.Instance.Value.UWPs
|
||||
var uwpResults = AppCache.Instance.Value.UWPs
|
||||
.Where((application) => application.Enabled)
|
||||
.Select(app =>
|
||||
new AppItem()
|
||||
{
|
||||
Name = app.Name,
|
||||
Subtitle = app.Description,
|
||||
Type = UWPApplication.Type(),
|
||||
IcoPath = app.LogoType != LogoType.Error ? app.LogoPath : string.Empty,
|
||||
DirPath = app.Location,
|
||||
UserModelId = app.UserModelId,
|
||||
IsPackaged = true,
|
||||
Commands = app.GetCommands(),
|
||||
});
|
||||
.Select(UwpToAppItem);
|
||||
|
||||
IEnumerable<AppItem> win32Results = AppCache.Instance.Value.Win32s
|
||||
var win32Results = AppCache.Instance.Value.Win32s
|
||||
.Where((application) => application.Enabled && application.Valid)
|
||||
.Select(app =>
|
||||
{
|
||||
string icoPath = string.IsNullOrEmpty(app.IcoPath) ?
|
||||
var icoPath = string.IsNullOrEmpty(app.IcoPath) ?
|
||||
(app.AppType == Win32Program.ApplicationType.InternetShortcutApplication ?
|
||||
app.IcoPath :
|
||||
app.FullPath) :
|
||||
@@ -116,4 +105,21 @@ public sealed partial class AllAppsPage : ListPage
|
||||
|
||||
return uwpResults.Concat(win32Results).OrderBy(app => app.Name).ToList();
|
||||
}
|
||||
|
||||
private AppItem UwpToAppItem(UWPApplication app)
|
||||
{
|
||||
var iconPath = app.LogoType != LogoType.Error ? app.LogoPath : string.Empty;
|
||||
var item = new AppItem()
|
||||
{
|
||||
Name = app.Name,
|
||||
Subtitle = app.Description,
|
||||
Type = UWPApplication.Type(),
|
||||
IcoPath = iconPath,
|
||||
DirPath = app.Location,
|
||||
UserModelId = app.UserModelId,
|
||||
IsPackaged = true,
|
||||
Commands = app.GetCommands(),
|
||||
};
|
||||
return item;
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,13 @@ internal sealed partial class AppListItem : ListItem
|
||||
Tags = [_appTag];
|
||||
MoreCommands = _app.Commands!.ToArray();
|
||||
|
||||
_details = new Lazy<Details>(() => BuildDetails());
|
||||
_details = new Lazy<Details>(() =>
|
||||
{
|
||||
var t = BuildDetails();
|
||||
t.Wait();
|
||||
return t.Result;
|
||||
});
|
||||
|
||||
_icon = new Lazy<IconInfo>(() =>
|
||||
{
|
||||
var t = FetchIcon(useThumbnails);
|
||||
@@ -41,8 +47,9 @@ internal sealed partial class AppListItem : ListItem
|
||||
});
|
||||
}
|
||||
|
||||
private Details BuildDetails()
|
||||
private async Task<Details> BuildDetails()
|
||||
{
|
||||
// Build metadata, with app type, path, etc.
|
||||
var metadata = new List<DetailsElement>();
|
||||
metadata.Add(new DetailsElement() { Key = "Type", Data = new DetailsTags() { Tags = [new Tag(_app.Type)] } });
|
||||
if (!_app.IsPackaged)
|
||||
@@ -50,10 +57,33 @@ internal sealed partial class AppListItem : ListItem
|
||||
metadata.Add(new DetailsElement() { Key = "Path", Data = new DetailsLink() { Text = _app.ExePath } });
|
||||
}
|
||||
|
||||
// Icon
|
||||
IconInfo? heroImage = null;
|
||||
if (_app.IsPackaged)
|
||||
{
|
||||
heroImage = new IconInfo(_app.IcoPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
var stream = await ThumbnailHelper.GetThumbnail(_app.ExePath, true);
|
||||
if (stream != null)
|
||||
{
|
||||
heroImage = IconInfo.FromStream(stream);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// do nothing if we fail to load an icon.
|
||||
// Logging it would be too NOISY, there's really no need.
|
||||
}
|
||||
}
|
||||
|
||||
return new Details()
|
||||
{
|
||||
Title = this.Title,
|
||||
HeroImage = this.Icon ?? new IconInfo(string.Empty),
|
||||
HeroImage = heroImage ?? this.Icon ?? new IconInfo(string.Empty),
|
||||
Metadata = metadata.ToArray(),
|
||||
};
|
||||
}
|
||||
@@ -64,11 +94,6 @@ internal sealed partial class AppListItem : ListItem
|
||||
if (_app.IsPackaged)
|
||||
{
|
||||
icon = new IconInfo(_app.IcoPath);
|
||||
if (_details.IsValueCreated)
|
||||
{
|
||||
_details.Value.HeroImage = icon;
|
||||
}
|
||||
|
||||
return icon;
|
||||
}
|
||||
|
||||
@@ -94,11 +119,6 @@ internal sealed partial class AppListItem : ListItem
|
||||
icon = new IconInfo(_app.IcoPath);
|
||||
}
|
||||
|
||||
if (_details.IsValueCreated)
|
||||
{
|
||||
_details.Value.HeroImage = icon;
|
||||
}
|
||||
|
||||
return icon;
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user