Compare commits
96 commits
main
...
dev/migrie
Author | SHA1 | Date | |
---|---|---|---|
bfc943aebf | |||
30a3621ec6 | |||
f3c7d9c471 | |||
530903219e | |||
c78c7aefa2 | |||
5936bd13b3 | |||
c95a4297cf | |||
045a8db5e1 | |||
91372ea1f9 | |||
26d5194b0c | |||
c215a97d09 | |||
4eb1d3a8d6 | |||
8370789462 | |||
15a8a9cec0 | |||
2eec961a87 | |||
51617cf6db | |||
f71c948554 | |||
9f9eacb5d9 | |||
305e62708a | |||
1b2e7a7ca1 | |||
717db8130b | |||
4166afaa98 | |||
f892752da7 | |||
71577fcd01 | |||
2a2f5cb9a5 | |||
9d76c62dae | |||
b20222f2c0 | |||
784ec731f8 | |||
1fdb6b1a3c | |||
ac8fef0e39 | |||
7c2a514e50 | |||
25b31ff854 | |||
10779ca310 | |||
5c039eaa1a | |||
eff18d1ec9 | |||
5052d31831 | |||
342d3f2026 | |||
fee6473737 | |||
1dcb4cb777 | |||
848682a27f | |||
91b52d4e6d | |||
3e5d9276f1 | |||
18099d2aa7 | |||
6e7ea615d2 | |||
a41bee653b | |||
18d1a205bb | |||
71f6b581e2 | |||
1c2f8e5d6a | |||
a65f3419e3 | |||
d2a34389a8 | |||
b2db3170dd | |||
f02969b70f | |||
59deca1c2e | |||
689c38519b | |||
5b8ace276b | |||
c34e4ce90f | |||
81c09d9650 | |||
2a7bc94a8f | |||
be74b2ee2d | |||
88ffc6fc0e | |||
bc492f1815 | |||
52b2cb6d3f | |||
3e39ab9e71 | |||
c02f25aba3 | |||
a75da0a104 | |||
65376865b5 | |||
9fc2f0ee3a | |||
0f0df5e8cf | |||
813dbc6671 | |||
bcbef340ba | |||
977db464fa | |||
658db6b568 | |||
00184e7ef6 | |||
921d91582b | |||
0f5c24f661 | |||
fa2df47898 | |||
c08889585b | |||
5939636182 | |||
f978a9c52c | |||
e1402d834f | |||
e101efd11d | |||
d08e65ce03 | |||
b4fe1bffbf | |||
0103331987 | |||
9c6eac4e86 | |||
a3faed6b7d | |||
0579b2417b | |||
590b9ff0c7 | |||
03bfc6e8a9 | |||
5cabcfb452 | |||
9a41647ffe | |||
27ace16652 | |||
36539cfa47 | |||
5a9cdc8b0b | |||
1f52d35833 | |||
3bef7bbb38 |
|
@ -1,3 +1,4 @@
|
||||||
|
<!-- markdownlint-disable MD033 MD041 -->
|
||||||
<details>
|
<details>
|
||||||
<summary>
|
<summary>
|
||||||
:pencil2: Contributor please read this
|
:pencil2: Contributor please read this
|
||||||
|
@ -8,9 +9,10 @@ By default the command suggestion will generate a file named based on your commi
|
||||||
:warning: The command is written for posix shells. You can copy the contents of each `perl` command excluding the outer `'` marks and dropping any `'"`/`"'` quotation mark pairs into a file and then run `perl file.pl` from the root of the repository to run the code. Alternatively, you can manually insert the items...
|
:warning: The command is written for posix shells. You can copy the contents of each `perl` command excluding the outer `'` marks and dropping any `'"`/`"'` quotation mark pairs into a file and then run `perl file.pl` from the root of the repository to run the code. Alternatively, you can manually insert the items...
|
||||||
|
|
||||||
If the listed items are:
|
If the listed items are:
|
||||||
|
|
||||||
* ... **misspelled**, then please *correct* them instead of using the command.
|
* ... **misspelled**, then please *correct* them instead of using the command.
|
||||||
* ... *names*, please add them to `.github/actions/spelling/dictionary/names.txt`.
|
* ... *names*, please add them to `.github/actions/spelling/allow/names.txt`.
|
||||||
* ... APIs, you can add them to a file in `.github/actions/spelling/dictionary/`.
|
* ... APIs, you can add them to a file in `.github/actions/spelling/allow/`.
|
||||||
* ... just things you're using, please add them to an appropriate file in `.github/actions/spelling/expect/`.
|
* ... just things you're using, please add them to an appropriate file in `.github/actions/spelling/expect/`.
|
||||||
* ... tokens you only need in one place and shouldn't *generally be used*, you can add an item in an appropriate file in `.github/actions/spelling/patterns/`.
|
* ... tokens you only need in one place and shouldn't *generally be used*, you can add an item in an appropriate file in `.github/actions/spelling/patterns/`.
|
||||||
|
|
||||||
|
@ -18,10 +20,31 @@ See the `README.md` in each directory for more information.
|
||||||
|
|
||||||
:microscope: You can test your commits **without** *appending* to a PR by creating a new branch with that extra change and pushing it to your fork. The [check-spelling](https://github.com/marketplace/actions/check-spelling) action will run in response to your **push** -- it doesn't require an open pull request. By using such a branch, you can limit the number of typos your peers see you make. :wink:
|
:microscope: You can test your commits **without** *appending* to a PR by creating a new branch with that extra change and pushing it to your fork. The [check-spelling](https://github.com/marketplace/actions/check-spelling) action will run in response to your **push** -- it doesn't require an open pull request. By using such a branch, you can limit the number of typos your peers see you make. :wink:
|
||||||
|
|
||||||
:clamp: If you see a bunch of garbage and it relates to a binary-ish string, please add a file path to the `.github/actions/spelling/excludes.txt` file instead of just accepting the garbage.
|
<details><summary>:clamp: If you see a bunch of garbage</summary>
|
||||||
|
|
||||||
|
If it relates to a ...
|
||||||
|
<details><summary>well-formed pattern</summary>
|
||||||
|
|
||||||
|
See if there's a [pattern](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns) that would match it.
|
||||||
|
|
||||||
|
If not, try writing one and adding it to a `patterns/{file}.txt`.
|
||||||
|
|
||||||
|
Patterns are Perl 5 Regular Expressions - you can [test](
|
||||||
|
https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your lines.
|
||||||
|
|
||||||
|
Note that patterns can't match multiline strings.
|
||||||
|
</details>
|
||||||
|
<details><summary>binary-ish string</summary>
|
||||||
|
|
||||||
|
Please add a file path to the `excludes.txt` file instead of just accepting the garbage.
|
||||||
|
|
||||||
File paths are Perl 5 Regular Expressions - you can [test](
|
File paths are Perl 5 Regular Expressions - you can [test](
|
||||||
https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your files.
|
https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your files.
|
||||||
|
|
||||||
`^` refers to the file's path from the root of the repository, so `^README\.md$` would exclude [README.md](https://github.com/microsoft/terminal/blob/main/README.md) (on whichever branch you're using).
|
`^` refers to the file's path from the root of the repository, so `^README\.md$` would exclude [README.md](
|
||||||
|
../tree/HEAD/README.md) (on whichever branch you're using).
|
||||||
|
</details>
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
</details>
|
</details>
|
|
@ -1,4 +1,4 @@
|
||||||
# Dictionaries are lists of words to accept unconditionally
|
# Allow files are lists of words to accept unconditionally
|
||||||
|
|
||||||
While check spelling will complain about an expected word
|
While check spelling will complain about an expected word
|
||||||
which is no longer present, you can include things here even if
|
which is no longer present, you can include things here even if
|
||||||
|
@ -8,11 +8,11 @@ E.g., you could include a list of system APIs here, or potential
|
||||||
contributors (so that if a future commit includes their name,
|
contributors (so that if a future commit includes their name,
|
||||||
it'll be accepted).
|
it'll be accepted).
|
||||||
|
|
||||||
### Files
|
## Files
|
||||||
|
|
||||||
| File | Description |
|
| File | Description |
|
||||||
| ---- | ----------- |
|
| ---- | ----------- |
|
||||||
| [Dictionary](dictionary.txt) | Primary US English dictionary |
|
| [Allow](allow.txt) | Supplements to the dictionary |
|
||||||
| [Chinese](chinese.txt) | Chinese words |
|
| [Chinese](chinese.txt) | Chinese words |
|
||||||
| [Japanese](japanese.txt) | Japanese words |
|
| [Japanese](japanese.txt) | Japanese words |
|
||||||
| [Microsoft](microsoft.txt) | Microsoft brand items |
|
| [Microsoft](microsoft.txt) | Microsoft brand items |
|
77
.github/actions/spelling/allow/allow.txt
vendored
Normal file
77
.github/actions/spelling/allow/allow.txt
vendored
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
apc
|
||||||
|
calt
|
||||||
|
ccmp
|
||||||
|
changelog
|
||||||
|
cybersecurity
|
||||||
|
Apc
|
||||||
|
clickable
|
||||||
|
clig
|
||||||
|
copyable
|
||||||
|
dalet
|
||||||
|
dcs
|
||||||
|
Dcs
|
||||||
|
dialytika
|
||||||
|
dje
|
||||||
|
downside
|
||||||
|
downsides
|
||||||
|
dze
|
||||||
|
dzhe
|
||||||
|
Enum'd
|
||||||
|
Fitt
|
||||||
|
formattings
|
||||||
|
ftp
|
||||||
|
fvar
|
||||||
|
geeksforgeeks
|
||||||
|
ghe
|
||||||
|
gje
|
||||||
|
hostname
|
||||||
|
hostnames
|
||||||
|
hyperlink
|
||||||
|
hyperlinking
|
||||||
|
hyperlinks
|
||||||
|
img
|
||||||
|
It'd
|
||||||
|
kje
|
||||||
|
liga
|
||||||
|
lje
|
||||||
|
locl
|
||||||
|
lorem
|
||||||
|
Llast
|
||||||
|
Lmid
|
||||||
|
Lorigin
|
||||||
|
maxed
|
||||||
|
mkmk
|
||||||
|
mru
|
||||||
|
noreply
|
||||||
|
nje
|
||||||
|
ogonek
|
||||||
|
ok'd
|
||||||
|
overlined
|
||||||
|
postmodern
|
||||||
|
ptys
|
||||||
|
qof
|
||||||
|
qps
|
||||||
|
rclt
|
||||||
|
reimplementation
|
||||||
|
reserialization
|
||||||
|
reserialize
|
||||||
|
reserializes
|
||||||
|
rlig
|
||||||
|
runtimes
|
||||||
|
shcha
|
||||||
|
slnt
|
||||||
|
Sos
|
||||||
|
timestamped
|
||||||
|
TLDR
|
||||||
|
tokenizes
|
||||||
|
tonos
|
||||||
|
tshe
|
||||||
|
uiatextrange
|
||||||
|
UIs
|
||||||
|
und
|
||||||
|
unregister
|
||||||
|
versioned
|
||||||
|
We'd
|
||||||
|
wildcards
|
||||||
|
yeru
|
||||||
|
zhe
|
|
@ -1,23 +1,35 @@
|
||||||
ACCEPTFILES
|
ACCEPTFILES
|
||||||
ACCESSDENIED
|
ACCESSDENIED
|
||||||
|
alignas
|
||||||
alignof
|
alignof
|
||||||
|
APPLYTOSUBMENUS
|
||||||
bitfield
|
bitfield
|
||||||
bitfields
|
bitfields
|
||||||
|
BUILDBRANCH
|
||||||
|
BUILDMSG
|
||||||
|
BUILDNUMBER
|
||||||
|
BYPOSITION
|
||||||
|
charconv
|
||||||
CLASSNOTAVAILABLE
|
CLASSNOTAVAILABLE
|
||||||
cmdletbinding
|
cmdletbinding
|
||||||
colspan
|
|
||||||
COLORPROPERTY
|
COLORPROPERTY
|
||||||
|
colspan
|
||||||
COMDLG
|
COMDLG
|
||||||
|
comparand
|
||||||
|
cstdint
|
||||||
CXICON
|
CXICON
|
||||||
CYICON
|
CYICON
|
||||||
D2DERR_SHADER_COMPILE_FAILED
|
|
||||||
dataobject
|
dataobject
|
||||||
|
dcomp
|
||||||
DERR
|
DERR
|
||||||
dlldata
|
dlldata
|
||||||
DONTADDTORECENT
|
DONTADDTORECENT
|
||||||
|
DWORDLONG
|
||||||
|
enumset
|
||||||
environstrings
|
environstrings
|
||||||
EXPCMDFLAGS
|
EXPCMDFLAGS
|
||||||
EXPCMDSTATE
|
EXPCMDSTATE
|
||||||
|
filetime
|
||||||
FILTERSPEC
|
FILTERSPEC
|
||||||
FORCEFILESYSTEM
|
FORCEFILESYSTEM
|
||||||
FORCEMINIMIZE
|
FORCEMINIMIZE
|
||||||
|
@ -31,6 +43,7 @@ HIGHCONTRASTON
|
||||||
HIGHCONTRASTW
|
HIGHCONTRASTW
|
||||||
hotkeys
|
hotkeys
|
||||||
href
|
href
|
||||||
|
hrgn
|
||||||
IActivation
|
IActivation
|
||||||
IApp
|
IApp
|
||||||
IAppearance
|
IAppearance
|
||||||
|
@ -39,97 +52,143 @@ IBind
|
||||||
IBox
|
IBox
|
||||||
IClass
|
IClass
|
||||||
IComparable
|
IComparable
|
||||||
|
IComparer
|
||||||
IConnection
|
IConnection
|
||||||
ICustom
|
ICustom
|
||||||
IDialog
|
IDialog
|
||||||
IDirect
|
IDirect
|
||||||
IExplorer
|
IExplorer
|
||||||
|
IFACEMETHOD
|
||||||
IFile
|
IFile
|
||||||
IInheritable
|
IInheritable
|
||||||
IMap
|
IMap
|
||||||
IObject
|
IObject
|
||||||
|
iosfwd
|
||||||
IPackage
|
IPackage
|
||||||
IPeasant
|
IPeasant
|
||||||
|
isspace
|
||||||
|
ISetup
|
||||||
IStorage
|
IStorage
|
||||||
istream
|
istream
|
||||||
IStringable
|
IStringable
|
||||||
ITab
|
ITab
|
||||||
ITaskbar
|
ITaskbar
|
||||||
|
IUri
|
||||||
IVirtual
|
IVirtual
|
||||||
|
KEYSELECT
|
||||||
LCID
|
LCID
|
||||||
llabs
|
llabs
|
||||||
llu
|
llu
|
||||||
localtime
|
localtime
|
||||||
lround
|
lround
|
||||||
LSHIFT
|
LSHIFT
|
||||||
MULTIPLEUSE
|
MENUCOMMAND
|
||||||
|
MENUDATA
|
||||||
|
MENUINFO
|
||||||
|
memicmp
|
||||||
|
mptt
|
||||||
|
mov
|
||||||
msappx
|
msappx
|
||||||
MULTIPLEUSE
|
MULTIPLEUSE
|
||||||
NCHITTEST
|
NCHITTEST
|
||||||
NCLBUTTONDBLCLK
|
NCLBUTTONDBLCLK
|
||||||
NCRBUTTONDBLCLK
|
NCRBUTTONDBLCLK
|
||||||
|
NIF
|
||||||
|
NIN
|
||||||
NOAGGREGATION
|
NOAGGREGATION
|
||||||
NOASYNC
|
NOASYNC
|
||||||
NOCHANGEDIR
|
NOCHANGEDIR
|
||||||
NOPROGRESS
|
NOPROGRESS
|
||||||
NOREDIRECTIONBITMAP
|
NOREDIRECTIONBITMAP
|
||||||
|
NOREPEAT
|
||||||
|
NOTIFYBYPOS
|
||||||
|
NOTIFYICON
|
||||||
|
NOTIFYICONDATA
|
||||||
ntprivapi
|
ntprivapi
|
||||||
oaidl
|
oaidl
|
||||||
ocidl
|
ocidl
|
||||||
|
ODR
|
||||||
|
offsetof
|
||||||
|
osver
|
||||||
|
OSVERSIONINFOEXW
|
||||||
otms
|
otms
|
||||||
OUTLINETEXTMETRICW
|
OUTLINETEXTMETRICW
|
||||||
overridable
|
overridable
|
||||||
PAGESCROLL
|
PAGESCROLL
|
||||||
PICKFOLDERS
|
PICKFOLDERS
|
||||||
pmr
|
pmr
|
||||||
REGCLS
|
rcx
|
||||||
REGCLS
|
REGCLS
|
||||||
RETURNCMD
|
RETURNCMD
|
||||||
rfind
|
rfind
|
||||||
roundf
|
roundf
|
||||||
RSHIFT
|
RSHIFT
|
||||||
rx
|
|
||||||
schandle
|
schandle
|
||||||
semver
|
semver
|
||||||
serializer
|
serializer
|
||||||
|
SETVERSION
|
||||||
|
SHELLEXECUTEINFOW
|
||||||
shobjidl
|
shobjidl
|
||||||
SINGLEUSE
|
|
||||||
SHOWMINIMIZED
|
SHOWMINIMIZED
|
||||||
|
SHOWTIP
|
||||||
|
SINGLEUSE
|
||||||
SIZENS
|
SIZENS
|
||||||
smoothstep
|
smoothstep
|
||||||
GETDESKWALLPAPER
|
|
||||||
SHELLEXECUTEINFOW
|
|
||||||
snprintf
|
snprintf
|
||||||
spsc
|
spsc
|
||||||
sregex
|
sregex
|
||||||
|
SRWLOC
|
||||||
|
SRWLOCK
|
||||||
STDCPP
|
STDCPP
|
||||||
strchr
|
|
||||||
STDMETHOD
|
STDMETHOD
|
||||||
|
strchr
|
||||||
|
strcpy
|
||||||
|
streambuf
|
||||||
|
strtoul
|
||||||
Stubless
|
Stubless
|
||||||
Subheader
|
Subheader
|
||||||
Subpage
|
Subpage
|
||||||
UPDATEINIFILE
|
|
||||||
syscall
|
syscall
|
||||||
|
TASKBARCREATED
|
||||||
TBPF
|
TBPF
|
||||||
THEMECHANGED
|
THEMECHANGED
|
||||||
|
tlg
|
||||||
tmp
|
tmp
|
||||||
tolower
|
tolower
|
||||||
|
toupper
|
||||||
TTask
|
TTask
|
||||||
TVal
|
TVal
|
||||||
tx
|
UChar
|
||||||
UPDATEINIFILE
|
UPDATEINIFILE
|
||||||
userenv
|
userenv
|
||||||
wcsstr
|
wcsstr
|
||||||
wcstoui
|
wcstoui
|
||||||
winmain
|
winmain
|
||||||
|
wmemcmp
|
||||||
wpc
|
wpc
|
||||||
wsregex
|
wsregex
|
||||||
wwinmain
|
wwinmain
|
||||||
|
xchg
|
||||||
XDocument
|
XDocument
|
||||||
XElement
|
XElement
|
||||||
|
xfacet
|
||||||
|
xhash
|
||||||
|
XIcon
|
||||||
|
xiosbase
|
||||||
|
xlocale
|
||||||
|
xlocbuf
|
||||||
|
xlocinfo
|
||||||
xlocmes
|
xlocmes
|
||||||
xlocmon
|
xlocmon
|
||||||
xlocnum
|
xlocnum
|
||||||
xloctime
|
xloctime
|
||||||
|
XMax
|
||||||
|
xmemory
|
||||||
XParse
|
XParse
|
||||||
|
xpath
|
||||||
|
xstddef
|
||||||
xstring
|
xstring
|
||||||
|
xtree
|
||||||
|
xutility
|
||||||
|
YIcon
|
||||||
|
YMax
|
117
.github/actions/spelling/allow/colors.txt
vendored
Normal file
117
.github/actions/spelling/allow/colors.txt
vendored
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
alice
|
||||||
|
aliceblue
|
||||||
|
antiquewhite
|
||||||
|
blanchedalmond
|
||||||
|
blueviolet
|
||||||
|
burlywood
|
||||||
|
cadetblue
|
||||||
|
cornflowerblue
|
||||||
|
cornsilk
|
||||||
|
cyan
|
||||||
|
darkblue
|
||||||
|
darkcyan
|
||||||
|
darkgoldenrod
|
||||||
|
darkgray
|
||||||
|
darkgreen
|
||||||
|
darkgrey
|
||||||
|
darkkhaki
|
||||||
|
darkmagenta
|
||||||
|
darkolivegreen
|
||||||
|
darkorange
|
||||||
|
darkorchid
|
||||||
|
darkred
|
||||||
|
darksalmon
|
||||||
|
darkseagreen
|
||||||
|
darkslateblue
|
||||||
|
darkslategray
|
||||||
|
darkslategrey
|
||||||
|
darkturquoise
|
||||||
|
darkviolet
|
||||||
|
deeppink
|
||||||
|
deepskyblue
|
||||||
|
dimgray
|
||||||
|
dimgrey
|
||||||
|
dodgerblue
|
||||||
|
firebrick
|
||||||
|
floralwhite
|
||||||
|
forestgreen
|
||||||
|
gainsboro
|
||||||
|
ghostwhite
|
||||||
|
greenyellow
|
||||||
|
hotpink
|
||||||
|
indian
|
||||||
|
indianred
|
||||||
|
lavenderblush
|
||||||
|
lawngreen
|
||||||
|
lemonchiffon
|
||||||
|
lightblue
|
||||||
|
lightcoral
|
||||||
|
lightcyan
|
||||||
|
lightgoldenrod
|
||||||
|
lightgoldenrodyellow
|
||||||
|
lightgray
|
||||||
|
lightgreen
|
||||||
|
lightgrey
|
||||||
|
lightpink
|
||||||
|
lightsalmon
|
||||||
|
lightseagreen
|
||||||
|
lightskyblue
|
||||||
|
lightslateblue
|
||||||
|
lightslategray
|
||||||
|
lightslategrey
|
||||||
|
lightsteelblue
|
||||||
|
lightyellow
|
||||||
|
limegreen
|
||||||
|
mediumaquamarine
|
||||||
|
mediumblue
|
||||||
|
mediumorchid
|
||||||
|
mediumpurple
|
||||||
|
mediumseagreen
|
||||||
|
mediumslateblue
|
||||||
|
mediumspringgreen
|
||||||
|
mediumturquoise
|
||||||
|
mediumvioletred
|
||||||
|
midnightblue
|
||||||
|
mintcream
|
||||||
|
mistyrose
|
||||||
|
navajo
|
||||||
|
navajowhite
|
||||||
|
navyblue
|
||||||
|
oldlace
|
||||||
|
olivedrab
|
||||||
|
orangered
|
||||||
|
palegoldenrod
|
||||||
|
palegreen
|
||||||
|
paleturquoise
|
||||||
|
palevioletred
|
||||||
|
papayawhip
|
||||||
|
peachpuff
|
||||||
|
peru
|
||||||
|
powderblue
|
||||||
|
rebecca
|
||||||
|
rebeccapurple
|
||||||
|
rosybrown
|
||||||
|
royalblue
|
||||||
|
saddlebrown
|
||||||
|
sandybrown
|
||||||
|
seagreen
|
||||||
|
sienna
|
||||||
|
skyblue
|
||||||
|
slateblue
|
||||||
|
slategray
|
||||||
|
slategrey
|
||||||
|
springgreen
|
||||||
|
steelblue
|
||||||
|
violetred
|
||||||
|
webgray
|
||||||
|
webgreen
|
||||||
|
webgrey
|
||||||
|
webmaroon
|
||||||
|
webpurple
|
||||||
|
whitesmoke
|
||||||
|
xaroon
|
||||||
|
xray
|
||||||
|
xreen
|
||||||
|
xrey
|
||||||
|
xurple
|
||||||
|
yellowgreen
|
|
@ -7,3 +7,4 @@ Iosevka
|
||||||
MDL
|
MDL
|
||||||
Monofur
|
Monofur
|
||||||
Segoe
|
Segoe
|
||||||
|
wght
|
11
.github/actions/spelling/allow/math.txt
vendored
Normal file
11
.github/actions/spelling/allow/math.txt
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
atan
|
||||||
|
CPrime
|
||||||
|
HBar
|
||||||
|
HPrime
|
||||||
|
isnan
|
||||||
|
LPrime
|
||||||
|
LStep
|
||||||
|
powf
|
||||||
|
RSub
|
||||||
|
sqrtf
|
||||||
|
ULP
|
|
@ -1,15 +1,22 @@
|
||||||
ACLs
|
ACLs
|
||||||
ADMINS
|
ADMINS
|
||||||
|
advapi
|
||||||
altform
|
altform
|
||||||
altforms
|
altforms
|
||||||
appendwttlogging
|
appendwttlogging
|
||||||
|
appx
|
||||||
|
appxbundle
|
||||||
|
appxerror
|
||||||
|
appxmanifest
|
||||||
|
ATL
|
||||||
backplating
|
backplating
|
||||||
bitmaps
|
bitmaps
|
||||||
BOMs
|
BOMs
|
||||||
CPLs
|
CPLs
|
||||||
CPRs
|
|
||||||
cpptools
|
cpptools
|
||||||
cppvsdbg
|
cppvsdbg
|
||||||
|
CPRs
|
||||||
|
cryptbase
|
||||||
DACL
|
DACL
|
||||||
DACLs
|
DACLs
|
||||||
diffs
|
diffs
|
||||||
|
@ -19,14 +26,20 @@ DTDs
|
||||||
DWINRT
|
DWINRT
|
||||||
enablewttlogging
|
enablewttlogging
|
||||||
Intelli
|
Intelli
|
||||||
|
IVisual
|
||||||
LKG
|
LKG
|
||||||
|
LOCKFILE
|
||||||
|
Lxss
|
||||||
mfcribbon
|
mfcribbon
|
||||||
microsoft
|
microsoft
|
||||||
microsoftonline
|
microsoftonline
|
||||||
|
MSAA
|
||||||
msixbundle
|
msixbundle
|
||||||
|
MSVC
|
||||||
muxc
|
muxc
|
||||||
netcore
|
netcore
|
||||||
osgvsowi
|
osgvsowi
|
||||||
|
PFILETIME
|
||||||
pgc
|
pgc
|
||||||
pgo
|
pgo
|
||||||
pgosweep
|
pgosweep
|
||||||
|
@ -34,20 +47,29 @@ powerrename
|
||||||
powershell
|
powershell
|
||||||
propkey
|
propkey
|
||||||
pscustomobject
|
pscustomobject
|
||||||
|
QWORD
|
||||||
|
regedit
|
||||||
robocopy
|
robocopy
|
||||||
SACLs
|
SACLs
|
||||||
|
sdkddkver
|
||||||
Shobjidl
|
Shobjidl
|
||||||
Skype
|
Skype
|
||||||
|
SRW
|
||||||
|
sxs
|
||||||
|
Sysinternals
|
||||||
sysnative
|
sysnative
|
||||||
systemroot
|
systemroot
|
||||||
taskkill
|
taskkill
|
||||||
tasklist
|
tasklist
|
||||||
tdbuildteamid
|
tdbuildteamid
|
||||||
|
unvirtualized
|
||||||
VCRT
|
VCRT
|
||||||
vcruntime
|
vcruntime
|
||||||
|
Virtualization
|
||||||
visualstudio
|
visualstudio
|
||||||
vscode
|
vscode
|
||||||
VSTHRD
|
VSTHRD
|
||||||
|
winsdkver
|
||||||
wlk
|
wlk
|
||||||
wslpath
|
wslpath
|
||||||
wtl
|
wtl
|
|
@ -13,6 +13,7 @@ ethanschoonover
|
||||||
Firefox
|
Firefox
|
||||||
Gatta
|
Gatta
|
||||||
glsl
|
glsl
|
||||||
|
Gravell
|
||||||
Grie
|
Grie
|
||||||
Griese
|
Griese
|
||||||
Hernan
|
Hernan
|
||||||
|
@ -30,6 +31,7 @@ Kourosh
|
||||||
kowalczyk
|
kowalczyk
|
||||||
leonmsft
|
leonmsft
|
||||||
Lepilleur
|
Lepilleur
|
||||||
|
lhecker
|
||||||
lukesampson
|
lukesampson
|
||||||
Manandhar
|
Manandhar
|
||||||
mbadolato
|
mbadolato
|
||||||
|
@ -51,6 +53,7 @@ oldnewthing
|
||||||
opengl
|
opengl
|
||||||
osgwiki
|
osgwiki
|
||||||
pabhojwa
|
pabhojwa
|
||||||
|
panos
|
||||||
paulcam
|
paulcam
|
||||||
pauldotknopf
|
pauldotknopf
|
||||||
PGP
|
PGP
|
||||||
|
@ -65,12 +68,13 @@ sonpham
|
||||||
stakx
|
stakx
|
||||||
thereses
|
thereses
|
||||||
Walisch
|
Walisch
|
||||||
|
Wellons
|
||||||
Wirt
|
Wirt
|
||||||
Wojciech
|
Wojciech
|
||||||
zadjii
|
zadjii
|
||||||
Zamor
|
Zamor
|
||||||
zamora
|
|
||||||
Zamora
|
Zamora
|
||||||
|
zamora
|
||||||
Zoey
|
Zoey
|
||||||
zorio
|
zorio
|
||||||
Zverovich
|
Zverovich
|
782
.github/actions/spelling/dictionary/colors.txt
vendored
782
.github/actions/spelling/dictionary/colors.txt
vendored
|
@ -1,782 +0,0 @@
|
||||||
snow
|
|
||||||
ghost-white
|
|
||||||
ghostwhite
|
|
||||||
white-smoke
|
|
||||||
whitesmoke
|
|
||||||
gainsboro
|
|
||||||
floral-white
|
|
||||||
floralwhite
|
|
||||||
old-lace
|
|
||||||
oldlace
|
|
||||||
linen
|
|
||||||
antique-white
|
|
||||||
antiquewhite
|
|
||||||
papaya-whip
|
|
||||||
papayawhip
|
|
||||||
blanched-almond
|
|
||||||
blanchedalmond
|
|
||||||
bisque
|
|
||||||
peach-puff
|
|
||||||
peachpuff
|
|
||||||
navajo-white
|
|
||||||
navajowhite
|
|
||||||
moccasin
|
|
||||||
cornsilk
|
|
||||||
ivory
|
|
||||||
lemon-chiffon
|
|
||||||
lemonchiffon
|
|
||||||
seashell
|
|
||||||
honeydew
|
|
||||||
mint-cream
|
|
||||||
mintcream
|
|
||||||
azure
|
|
||||||
alice-blue
|
|
||||||
aliceblue
|
|
||||||
lavender
|
|
||||||
lavender-blush
|
|
||||||
lavenderblush
|
|
||||||
misty-rose
|
|
||||||
mistyrose
|
|
||||||
white
|
|
||||||
black
|
|
||||||
dark-slate-gray
|
|
||||||
darkslategray
|
|
||||||
dark-slate-grey
|
|
||||||
darkslategrey
|
|
||||||
dim-gray
|
|
||||||
dimgray
|
|
||||||
dim-grey
|
|
||||||
dimgrey
|
|
||||||
slate-gray
|
|
||||||
slategray
|
|
||||||
slate-grey
|
|
||||||
slategrey
|
|
||||||
light-slate-gray
|
|
||||||
lightslategray
|
|
||||||
light-slate-grey
|
|
||||||
lightslategrey
|
|
||||||
gray
|
|
||||||
grey
|
|
||||||
xray
|
|
||||||
x11gray
|
|
||||||
xrey
|
|
||||||
x11grey
|
|
||||||
web-gray
|
|
||||||
webgray
|
|
||||||
web-grey
|
|
||||||
webgrey
|
|
||||||
light-grey
|
|
||||||
lightgrey
|
|
||||||
light-gray
|
|
||||||
lightgray
|
|
||||||
midnight-blue
|
|
||||||
midnightblue
|
|
||||||
navy
|
|
||||||
navy-blue
|
|
||||||
navyblue
|
|
||||||
cornflower-blue
|
|
||||||
cornflowerblue
|
|
||||||
dark-slate-blue
|
|
||||||
darkslateblue
|
|
||||||
slate-blue
|
|
||||||
slateblue
|
|
||||||
medium-slate-blue
|
|
||||||
mediumslateblue
|
|
||||||
light-slate-blue
|
|
||||||
lightslateblue
|
|
||||||
medium-blue
|
|
||||||
mediumblue
|
|
||||||
royal-blue
|
|
||||||
royalblue
|
|
||||||
blue
|
|
||||||
dodger-blue
|
|
||||||
dodgerblue
|
|
||||||
deep-sky-blue
|
|
||||||
deepskyblue
|
|
||||||
sky-blue
|
|
||||||
skyblue
|
|
||||||
light-sky-blue
|
|
||||||
lightskyblue
|
|
||||||
steel-blue
|
|
||||||
steelblue
|
|
||||||
light-steel-blue
|
|
||||||
lightsteelblue
|
|
||||||
light-blue
|
|
||||||
lightblue
|
|
||||||
powder-blue
|
|
||||||
powderblue
|
|
||||||
pale-turquoise
|
|
||||||
paleturquoise
|
|
||||||
dark-turquoise
|
|
||||||
darkturquoise
|
|
||||||
medium-turquoise
|
|
||||||
mediumturquoise
|
|
||||||
turquoise
|
|
||||||
cyan
|
|
||||||
aqua
|
|
||||||
light-cyan
|
|
||||||
lightcyan
|
|
||||||
cadet-blue
|
|
||||||
cadetblue
|
|
||||||
medium-aquamarine
|
|
||||||
mediumaquamarine
|
|
||||||
aquamarine
|
|
||||||
dark-green
|
|
||||||
darkgreen
|
|
||||||
dark-olive-green
|
|
||||||
darkolivegreen
|
|
||||||
dark-sea-green
|
|
||||||
darkseagreen
|
|
||||||
sea-green
|
|
||||||
seagreen
|
|
||||||
medium-sea-green
|
|
||||||
mediumseagreen
|
|
||||||
light-sea-green
|
|
||||||
lightseagreen
|
|
||||||
pale-green
|
|
||||||
palegreen
|
|
||||||
spring-green
|
|
||||||
springgreen
|
|
||||||
lawn-green
|
|
||||||
lawngreen
|
|
||||||
green
|
|
||||||
lime
|
|
||||||
xreen
|
|
||||||
x11green
|
|
||||||
web-green
|
|
||||||
webgreen
|
|
||||||
chartreuse
|
|
||||||
medium-spring-green
|
|
||||||
mediumspringgreen
|
|
||||||
green-yellow
|
|
||||||
greenyellow
|
|
||||||
lime-green
|
|
||||||
limegreen
|
|
||||||
yellow-green
|
|
||||||
yellowgreen
|
|
||||||
forest-green
|
|
||||||
forestgreen
|
|
||||||
olive-drab
|
|
||||||
olivedrab
|
|
||||||
dark-khaki
|
|
||||||
darkkhaki
|
|
||||||
khaki
|
|
||||||
pale-goldenrod
|
|
||||||
palegoldenrod
|
|
||||||
light-goldenrod-yellow
|
|
||||||
lightgoldenrodyellow
|
|
||||||
light-yellow
|
|
||||||
lightyellow
|
|
||||||
yellow
|
|
||||||
gold
|
|
||||||
light-goldenrod
|
|
||||||
lightgoldenrod
|
|
||||||
goldenrod
|
|
||||||
dark-goldenrod
|
|
||||||
darkgoldenrod
|
|
||||||
rosy-brown
|
|
||||||
rosybrown
|
|
||||||
indian-red
|
|
||||||
indianred
|
|
||||||
saddle-brown
|
|
||||||
saddlebrown
|
|
||||||
sienna
|
|
||||||
peru
|
|
||||||
burlywood
|
|
||||||
beige
|
|
||||||
wheat
|
|
||||||
sandy-brown
|
|
||||||
sandybrown
|
|
||||||
tan
|
|
||||||
chocolate
|
|
||||||
firebrick
|
|
||||||
brown
|
|
||||||
dark-salmon
|
|
||||||
darksalmon
|
|
||||||
salmon
|
|
||||||
light-salmon
|
|
||||||
lightsalmon
|
|
||||||
orange
|
|
||||||
dark-orange
|
|
||||||
darkorange
|
|
||||||
coral
|
|
||||||
light-coral
|
|
||||||
lightcoral
|
|
||||||
tomato
|
|
||||||
orange-red
|
|
||||||
orangered
|
|
||||||
red
|
|
||||||
hot-pink
|
|
||||||
hotpink
|
|
||||||
deep-pink
|
|
||||||
deeppink
|
|
||||||
pink
|
|
||||||
light-pink
|
|
||||||
lightpink
|
|
||||||
pale-violet-red
|
|
||||||
palevioletred
|
|
||||||
maroon
|
|
||||||
xaroon
|
|
||||||
x11maroon
|
|
||||||
web-maroon
|
|
||||||
webmaroon
|
|
||||||
medium-violet-red
|
|
||||||
mediumvioletred
|
|
||||||
violet-red
|
|
||||||
violetred
|
|
||||||
magenta
|
|
||||||
fuchsia
|
|
||||||
violet
|
|
||||||
plum
|
|
||||||
orchid
|
|
||||||
medium-orchid
|
|
||||||
mediumorchid
|
|
||||||
dark-orchid
|
|
||||||
darkorchid
|
|
||||||
dark-violet
|
|
||||||
darkviolet
|
|
||||||
blue-violet
|
|
||||||
blueviolet
|
|
||||||
purple
|
|
||||||
xurple
|
|
||||||
x11purple
|
|
||||||
web-purple
|
|
||||||
webpurple
|
|
||||||
medium-purple
|
|
||||||
mediumpurple
|
|
||||||
thistle
|
|
||||||
snow1
|
|
||||||
snow2
|
|
||||||
snow3
|
|
||||||
snow4
|
|
||||||
seashell1
|
|
||||||
seashell2
|
|
||||||
seashell3
|
|
||||||
seashell4
|
|
||||||
antiquewhite1
|
|
||||||
antiquewhite2
|
|
||||||
antiquewhite3
|
|
||||||
antiquewhite4
|
|
||||||
bisque1
|
|
||||||
bisque2
|
|
||||||
bisque3
|
|
||||||
bisque4
|
|
||||||
peachpuff1
|
|
||||||
peachpuff2
|
|
||||||
peachpuff3
|
|
||||||
peachpuff4
|
|
||||||
navajowhite1
|
|
||||||
navajowhite2
|
|
||||||
navajowhite3
|
|
||||||
navajowhite4
|
|
||||||
lemonchiffon1
|
|
||||||
lemonchiffon2
|
|
||||||
lemonchiffon3
|
|
||||||
lemonchiffon4
|
|
||||||
cornsilk1
|
|
||||||
cornsilk2
|
|
||||||
cornsilk3
|
|
||||||
cornsilk4
|
|
||||||
ivory1
|
|
||||||
ivory2
|
|
||||||
ivory3
|
|
||||||
ivory4
|
|
||||||
honeydew1
|
|
||||||
honeydew2
|
|
||||||
honeydew3
|
|
||||||
honeydew4
|
|
||||||
lavenderblush1
|
|
||||||
lavenderblush2
|
|
||||||
lavenderblush3
|
|
||||||
lavenderblush4
|
|
||||||
mistyrose1
|
|
||||||
mistyrose2
|
|
||||||
mistyrose3
|
|
||||||
mistyrose4
|
|
||||||
azure1
|
|
||||||
azure2
|
|
||||||
azure3
|
|
||||||
azure4
|
|
||||||
slateblue1
|
|
||||||
slateblue2
|
|
||||||
slateblue3
|
|
||||||
slateblue4
|
|
||||||
royalblue1
|
|
||||||
royalblue2
|
|
||||||
royalblue3
|
|
||||||
royalblue4
|
|
||||||
blue1
|
|
||||||
blue2
|
|
||||||
blue3
|
|
||||||
blue4
|
|
||||||
dodgerblue1
|
|
||||||
dodgerblue2
|
|
||||||
dodgerblue3
|
|
||||||
dodgerblue4
|
|
||||||
steelblue1
|
|
||||||
steelblue2
|
|
||||||
steelblue3
|
|
||||||
steelblue4
|
|
||||||
deepskyblue1
|
|
||||||
deepskyblue2
|
|
||||||
deepskyblue3
|
|
||||||
deepskyblue4
|
|
||||||
skyblue1
|
|
||||||
skyblue2
|
|
||||||
skyblue3
|
|
||||||
skyblue4
|
|
||||||
lightskyblue1
|
|
||||||
lightskyblue2
|
|
||||||
lightskyblue3
|
|
||||||
lightskyblue4
|
|
||||||
slategray1
|
|
||||||
slategray2
|
|
||||||
slategray3
|
|
||||||
slategray4
|
|
||||||
lightsteelblue1
|
|
||||||
lightsteelblue2
|
|
||||||
lightsteelblue3
|
|
||||||
lightsteelblue4
|
|
||||||
lightblue1
|
|
||||||
lightblue2
|
|
||||||
lightblue3
|
|
||||||
lightblue4
|
|
||||||
lightcyan1
|
|
||||||
lightcyan2
|
|
||||||
lightcyan3
|
|
||||||
lightcyan4
|
|
||||||
paleturquoise1
|
|
||||||
paleturquoise2
|
|
||||||
paleturquoise3
|
|
||||||
paleturquoise4
|
|
||||||
cadetblue1
|
|
||||||
cadetblue2
|
|
||||||
cadetblue3
|
|
||||||
cadetblue4
|
|
||||||
turquoise1
|
|
||||||
turquoise2
|
|
||||||
turquoise3
|
|
||||||
turquoise4
|
|
||||||
cyan1
|
|
||||||
cyan2
|
|
||||||
cyan3
|
|
||||||
cyan4
|
|
||||||
darkslategray1
|
|
||||||
darkslategray2
|
|
||||||
darkslategray3
|
|
||||||
darkslategray4
|
|
||||||
aquamarine1
|
|
||||||
aquamarine2
|
|
||||||
aquamarine3
|
|
||||||
aquamarine4
|
|
||||||
darkseagreen1
|
|
||||||
darkseagreen2
|
|
||||||
darkseagreen3
|
|
||||||
darkseagreen4
|
|
||||||
seagreen1
|
|
||||||
seagreen2
|
|
||||||
seagreen3
|
|
||||||
seagreen4
|
|
||||||
palegreen1
|
|
||||||
palegreen2
|
|
||||||
palegreen3
|
|
||||||
palegreen4
|
|
||||||
springgreen1
|
|
||||||
springgreen2
|
|
||||||
springgreen3
|
|
||||||
springgreen4
|
|
||||||
green1
|
|
||||||
green2
|
|
||||||
green3
|
|
||||||
green4
|
|
||||||
chartreuse1
|
|
||||||
chartreuse2
|
|
||||||
chartreuse3
|
|
||||||
chartreuse4
|
|
||||||
olivedrab1
|
|
||||||
olivedrab2
|
|
||||||
olivedrab3
|
|
||||||
olivedrab4
|
|
||||||
darkolivegreen1
|
|
||||||
darkolivegreen2
|
|
||||||
darkolivegreen3
|
|
||||||
darkolivegreen4
|
|
||||||
khaki1
|
|
||||||
khaki2
|
|
||||||
khaki3
|
|
||||||
khaki4
|
|
||||||
lightgoldenrod1
|
|
||||||
lightgoldenrod2
|
|
||||||
lightgoldenrod3
|
|
||||||
lightgoldenrod4
|
|
||||||
lightyellow1
|
|
||||||
lightyellow2
|
|
||||||
lightyellow3
|
|
||||||
lightyellow4
|
|
||||||
yellow1
|
|
||||||
yellow2
|
|
||||||
yellow3
|
|
||||||
yellow4
|
|
||||||
gold1
|
|
||||||
gold2
|
|
||||||
gold3
|
|
||||||
gold4
|
|
||||||
goldenrod1
|
|
||||||
goldenrod2
|
|
||||||
goldenrod3
|
|
||||||
goldenrod4
|
|
||||||
darkgoldenrod1
|
|
||||||
darkgoldenrod2
|
|
||||||
darkgoldenrod3
|
|
||||||
darkgoldenrod4
|
|
||||||
rosybrown1
|
|
||||||
rosybrown2
|
|
||||||
rosybrown3
|
|
||||||
rosybrown4
|
|
||||||
indianred1
|
|
||||||
indianred2
|
|
||||||
indianred3
|
|
||||||
indianred4
|
|
||||||
sienna1
|
|
||||||
sienna2
|
|
||||||
sienna3
|
|
||||||
sienna4
|
|
||||||
burlywood1
|
|
||||||
burlywood2
|
|
||||||
burlywood3
|
|
||||||
burlywood4
|
|
||||||
wheat1
|
|
||||||
wheat2
|
|
||||||
wheat3
|
|
||||||
wheat4
|
|
||||||
tan1
|
|
||||||
tan2
|
|
||||||
tan3
|
|
||||||
tan4
|
|
||||||
chocolate1
|
|
||||||
chocolate2
|
|
||||||
chocolate3
|
|
||||||
chocolate4
|
|
||||||
firebrick1
|
|
||||||
firebrick2
|
|
||||||
firebrick3
|
|
||||||
firebrick4
|
|
||||||
brown1
|
|
||||||
brown2
|
|
||||||
brown3
|
|
||||||
brown4
|
|
||||||
salmon1
|
|
||||||
salmon2
|
|
||||||
salmon3
|
|
||||||
salmon4
|
|
||||||
lightsalmon1
|
|
||||||
lightsalmon2
|
|
||||||
lightsalmon3
|
|
||||||
lightsalmon4
|
|
||||||
orange1
|
|
||||||
orange2
|
|
||||||
orange3
|
|
||||||
orange4
|
|
||||||
darkorange1
|
|
||||||
darkorange2
|
|
||||||
darkorange3
|
|
||||||
darkorange4
|
|
||||||
coral1
|
|
||||||
coral2
|
|
||||||
coral3
|
|
||||||
coral4
|
|
||||||
tomato1
|
|
||||||
tomato2
|
|
||||||
tomato3
|
|
||||||
tomato4
|
|
||||||
orangered1
|
|
||||||
orangered2
|
|
||||||
orangered3
|
|
||||||
orangered4
|
|
||||||
red1
|
|
||||||
red2
|
|
||||||
red3
|
|
||||||
red4
|
|
||||||
deeppink1
|
|
||||||
deeppink2
|
|
||||||
deeppink3
|
|
||||||
deeppink4
|
|
||||||
hotpink1
|
|
||||||
hotpink2
|
|
||||||
hotpink3
|
|
||||||
hotpink4
|
|
||||||
pink1
|
|
||||||
pink2
|
|
||||||
pink3
|
|
||||||
pink4
|
|
||||||
lightpink1
|
|
||||||
lightpink2
|
|
||||||
lightpink3
|
|
||||||
lightpink4
|
|
||||||
palevioletred1
|
|
||||||
palevioletred2
|
|
||||||
palevioletred3
|
|
||||||
palevioletred4
|
|
||||||
maroon1
|
|
||||||
maroon2
|
|
||||||
maroon3
|
|
||||||
maroon4
|
|
||||||
violetred1
|
|
||||||
violetred2
|
|
||||||
violetred3
|
|
||||||
violetred4
|
|
||||||
magenta1
|
|
||||||
magenta2
|
|
||||||
magenta3
|
|
||||||
magenta4
|
|
||||||
orchid1
|
|
||||||
orchid2
|
|
||||||
orchid3
|
|
||||||
orchid4
|
|
||||||
plum1
|
|
||||||
plum2
|
|
||||||
plum3
|
|
||||||
plum4
|
|
||||||
mediumorchid1
|
|
||||||
mediumorchid2
|
|
||||||
mediumorchid3
|
|
||||||
mediumorchid4
|
|
||||||
darkorchid1
|
|
||||||
darkorchid2
|
|
||||||
darkorchid3
|
|
||||||
darkorchid4
|
|
||||||
purple1
|
|
||||||
purple2
|
|
||||||
purple3
|
|
||||||
purple4
|
|
||||||
mediumpurple1
|
|
||||||
mediumpurple2
|
|
||||||
mediumpurple3
|
|
||||||
mediumpurple4
|
|
||||||
thistle1
|
|
||||||
thistle2
|
|
||||||
thistle3
|
|
||||||
thistle4
|
|
||||||
gray0
|
|
||||||
grey0
|
|
||||||
gray1
|
|
||||||
grey1
|
|
||||||
gray2
|
|
||||||
grey2
|
|
||||||
gray3
|
|
||||||
grey3
|
|
||||||
gray4
|
|
||||||
grey4
|
|
||||||
gray5
|
|
||||||
grey5
|
|
||||||
gray6
|
|
||||||
grey6
|
|
||||||
gray7
|
|
||||||
grey7
|
|
||||||
gray8
|
|
||||||
grey8
|
|
||||||
gray9
|
|
||||||
grey9
|
|
||||||
gray10
|
|
||||||
grey10
|
|
||||||
gray11
|
|
||||||
grey11
|
|
||||||
gray12
|
|
||||||
grey12
|
|
||||||
gray13
|
|
||||||
grey13
|
|
||||||
gray14
|
|
||||||
grey14
|
|
||||||
gray15
|
|
||||||
grey15
|
|
||||||
gray16
|
|
||||||
grey16
|
|
||||||
gray17
|
|
||||||
grey17
|
|
||||||
gray18
|
|
||||||
grey18
|
|
||||||
gray19
|
|
||||||
grey19
|
|
||||||
gray20
|
|
||||||
grey20
|
|
||||||
gray21
|
|
||||||
grey21
|
|
||||||
gray22
|
|
||||||
grey22
|
|
||||||
gray23
|
|
||||||
grey23
|
|
||||||
gray24
|
|
||||||
grey24
|
|
||||||
gray25
|
|
||||||
grey25
|
|
||||||
gray26
|
|
||||||
grey26
|
|
||||||
gray27
|
|
||||||
grey27
|
|
||||||
gray28
|
|
||||||
grey28
|
|
||||||
gray29
|
|
||||||
grey29
|
|
||||||
gray30
|
|
||||||
grey30
|
|
||||||
gray31
|
|
||||||
grey31
|
|
||||||
gray32
|
|
||||||
grey32
|
|
||||||
gray33
|
|
||||||
grey33
|
|
||||||
gray34
|
|
||||||
grey34
|
|
||||||
gray35
|
|
||||||
grey35
|
|
||||||
gray36
|
|
||||||
grey36
|
|
||||||
gray37
|
|
||||||
grey37
|
|
||||||
gray38
|
|
||||||
grey38
|
|
||||||
gray39
|
|
||||||
grey39
|
|
||||||
gray40
|
|
||||||
grey40
|
|
||||||
gray41
|
|
||||||
grey41
|
|
||||||
gray42
|
|
||||||
grey42
|
|
||||||
gray43
|
|
||||||
grey43
|
|
||||||
gray44
|
|
||||||
grey44
|
|
||||||
gray45
|
|
||||||
grey45
|
|
||||||
gray46
|
|
||||||
grey46
|
|
||||||
gray47
|
|
||||||
grey47
|
|
||||||
gray48
|
|
||||||
grey48
|
|
||||||
gray49
|
|
||||||
grey49
|
|
||||||
gray50
|
|
||||||
grey50
|
|
||||||
gray51
|
|
||||||
grey51
|
|
||||||
gray52
|
|
||||||
grey52
|
|
||||||
gray53
|
|
||||||
grey53
|
|
||||||
gray54
|
|
||||||
grey54
|
|
||||||
gray55
|
|
||||||
grey55
|
|
||||||
gray56
|
|
||||||
grey56
|
|
||||||
gray57
|
|
||||||
grey57
|
|
||||||
gray58
|
|
||||||
grey58
|
|
||||||
gray59
|
|
||||||
grey59
|
|
||||||
gray60
|
|
||||||
grey60
|
|
||||||
gray61
|
|
||||||
grey61
|
|
||||||
gray62
|
|
||||||
grey62
|
|
||||||
gray63
|
|
||||||
grey63
|
|
||||||
gray64
|
|
||||||
grey64
|
|
||||||
gray65
|
|
||||||
grey65
|
|
||||||
gray66
|
|
||||||
grey66
|
|
||||||
gray67
|
|
||||||
grey67
|
|
||||||
gray68
|
|
||||||
grey68
|
|
||||||
gray69
|
|
||||||
grey69
|
|
||||||
gray70
|
|
||||||
grey70
|
|
||||||
gray71
|
|
||||||
grey71
|
|
||||||
gray72
|
|
||||||
grey72
|
|
||||||
gray73
|
|
||||||
grey73
|
|
||||||
gray74
|
|
||||||
grey74
|
|
||||||
gray75
|
|
||||||
grey75
|
|
||||||
gray76
|
|
||||||
grey76
|
|
||||||
gray77
|
|
||||||
grey77
|
|
||||||
gray78
|
|
||||||
grey78
|
|
||||||
gray79
|
|
||||||
grey79
|
|
||||||
gray80
|
|
||||||
grey80
|
|
||||||
gray81
|
|
||||||
grey81
|
|
||||||
gray82
|
|
||||||
grey82
|
|
||||||
gray83
|
|
||||||
grey83
|
|
||||||
gray84
|
|
||||||
grey84
|
|
||||||
gray85
|
|
||||||
grey85
|
|
||||||
gray86
|
|
||||||
grey86
|
|
||||||
gray87
|
|
||||||
grey87
|
|
||||||
gray88
|
|
||||||
grey88
|
|
||||||
gray89
|
|
||||||
grey89
|
|
||||||
gray90
|
|
||||||
grey90
|
|
||||||
gray91
|
|
||||||
grey91
|
|
||||||
gray92
|
|
||||||
grey92
|
|
||||||
gray93
|
|
||||||
grey93
|
|
||||||
gray94
|
|
||||||
grey94
|
|
||||||
gray95
|
|
||||||
grey95
|
|
||||||
gray96
|
|
||||||
grey96
|
|
||||||
gray97
|
|
||||||
grey97
|
|
||||||
gray98
|
|
||||||
grey98
|
|
||||||
gray99
|
|
||||||
grey99
|
|
||||||
gray100
|
|
||||||
grey100
|
|
||||||
dark-grey
|
|
||||||
darkgrey
|
|
||||||
dark-gray
|
|
||||||
darkgray
|
|
||||||
dark-blue
|
|
||||||
darkblue
|
|
||||||
dark-cyan
|
|
||||||
darkcyan
|
|
||||||
dark-magenta
|
|
||||||
darkmagenta
|
|
||||||
dark-red
|
|
||||||
darkred
|
|
||||||
light-green
|
|
||||||
lightgreen
|
|
||||||
crimson
|
|
||||||
indigo
|
|
||||||
olive
|
|
||||||
rebecca-purple
|
|
||||||
rebeccapurple
|
|
||||||
silver
|
|
||||||
teal
|
|
479851
.github/actions/spelling/dictionary/dictionary.txt
vendored
479851
.github/actions/spelling/dictionary/dictionary.txt
vendored
File diff suppressed because it is too large
Load diff
3
.github/actions/spelling/dictionary/math.txt
vendored
3
.github/actions/spelling/dictionary/math.txt
vendored
|
@ -1,3 +0,0 @@
|
||||||
powf
|
|
||||||
sqrtf
|
|
||||||
isnan
|
|
20
.github/actions/spelling/excludes.txt
vendored
20
.github/actions/spelling/excludes.txt
vendored
|
@ -1,3 +1,4 @@
|
||||||
|
(?:(?i)\.png$)
|
||||||
(?:^|/)dirs$
|
(?:^|/)dirs$
|
||||||
(?:^|/)go\.mod$
|
(?:^|/)go\.mod$
|
||||||
(?:^|/)go\.sum$
|
(?:^|/)go\.sum$
|
||||||
|
@ -35,7 +36,6 @@ SUMS$
|
||||||
\.pbxproj$
|
\.pbxproj$
|
||||||
\.pdf$
|
\.pdf$
|
||||||
\.pem$
|
\.pem$
|
||||||
(?:(?i)\.png$)
|
|
||||||
\.psd$
|
\.psd$
|
||||||
\.runsettings$
|
\.runsettings$
|
||||||
\.sig$
|
\.sig$
|
||||||
|
@ -54,14 +54,26 @@ SUMS$
|
||||||
\.zip$
|
\.zip$
|
||||||
^consolegit2gitfilters\.json$
|
^consolegit2gitfilters\.json$
|
||||||
^dep/
|
^dep/
|
||||||
^oss/
|
^doc/reference/master-sequence-list.csv$
|
||||||
^doc/reference/UTF8-torture-test\.txt$
|
^doc/reference/UTF8-torture-test\.txt$
|
||||||
|
^oss/
|
||||||
|
^src/host/ft_uia/run\.bat$
|
||||||
|
^src/host/runft\.bat$
|
||||||
|
^src/host/runut\.bat$
|
||||||
^src/interactivity/onecore/BgfxEngine\.
|
^src/interactivity/onecore/BgfxEngine\.
|
||||||
^src/renderer/wddmcon/WddmConRenderer\.
|
^src/renderer/wddmcon/WddmConRenderer\.
|
||||||
|
^src/terminal/adapter/ut_adapter/run\.bat$
|
||||||
|
^src/terminal/parser/delfuzzpayload\.bat$
|
||||||
|
^src/terminal/parser/ft_fuzzer/run\.bat$
|
||||||
^src/terminal/parser/ft_fuzzer/VTCommandFuzzer\.cpp$
|
^src/terminal/parser/ft_fuzzer/VTCommandFuzzer\.cpp$
|
||||||
^src/types/ut_types/UtilsTests.cpp$
|
^src/terminal/parser/ft_fuzzwrapper/run\.bat$
|
||||||
|
^src/terminal/parser/ut_parser/run\.bat$
|
||||||
|
^src/tools/integrity/packageuwp/ConsoleUWP\.appxSources$
|
||||||
|
^src/tools/lnkd/lnkd\.bat$
|
||||||
|
^src/tools/pixels/pixels\.bat$
|
||||||
|
^src/tools/texttests/fira\.txt$
|
||||||
^src/tools/U8U16Test/(?:fr|ru|zh)\.txt$
|
^src/tools/U8U16Test/(?:fr|ru|zh)\.txt$
|
||||||
|
^src/types/ut_types/UtilsTests.cpp$
|
||||||
^\.github/actions/spelling/
|
^\.github/actions/spelling/
|
||||||
^\.gitignore$
|
^\.gitignore$
|
||||||
^doc/reference/master-sequence-list.csv$
|
|
||||||
^\XamlStyler.json$
|
^\XamlStyler.json$
|
||||||
|
|
16
.github/actions/spelling/expect/alphabet.txt
vendored
16
.github/actions/spelling/expect/alphabet.txt
vendored
|
@ -1,4 +1,9 @@
|
||||||
AAAa
|
AAAa
|
||||||
|
AAAAA
|
||||||
|
AAAAAAAAAAAAA
|
||||||
|
AAAAAABBBBBBCCC
|
||||||
|
AAAAABBBBBBCCC
|
||||||
|
abcd
|
||||||
abcd
|
abcd
|
||||||
abcde
|
abcde
|
||||||
abcdef
|
abcdef
|
||||||
|
@ -6,12 +11,20 @@ ABCDEFG
|
||||||
ABCDEFGH
|
ABCDEFGH
|
||||||
ABCDEFGHIJ
|
ABCDEFGHIJ
|
||||||
abcdefghijk
|
abcdefghijk
|
||||||
|
ABCDEFGHIJKLMNO
|
||||||
abcdefghijklmnop
|
abcdefghijklmnop
|
||||||
ABCDEFGHIJKLMNOPQRST
|
ABCDEFGHIJKLMNOPQRST
|
||||||
abcdefghijklmnopqrstuvwxyz
|
abcdefghijklmnopqrstuvwxyz
|
||||||
|
ABCG
|
||||||
ABE
|
ABE
|
||||||
BBGGRR
|
abf
|
||||||
|
BBBBB
|
||||||
|
BBBBBBBB
|
||||||
BBBBBBBBBBBBBBDDDD
|
BBBBBBBBBBBBBBDDDD
|
||||||
|
BBBBBCCC
|
||||||
|
BBBBCCCCC
|
||||||
|
BBGGRR
|
||||||
|
CCE
|
||||||
EFG
|
EFG
|
||||||
EFGh
|
EFGh
|
||||||
QQQQQQQQQQABCDEFGHIJ
|
QQQQQQQQQQABCDEFGHIJ
|
||||||
|
@ -32,3 +45,4 @@ ZYXWVUT
|
||||||
ZZBBZ
|
ZZBBZ
|
||||||
ZZZBB
|
ZZZBB
|
||||||
ZZZBZ
|
ZZZBZ
|
||||||
|
ZZZZZ
|
||||||
|
|
244
.github/actions/spelling/expect/expect.txt
vendored
244
.github/actions/spelling/expect/expect.txt
vendored
File diff suppressed because it is too large
Load diff
6
.github/actions/spelling/expect/web.txt
vendored
6
.github/actions/spelling/expect/web.txt
vendored
|
@ -1,6 +1,7 @@
|
||||||
http
|
http
|
||||||
td
|
|
||||||
www
|
www
|
||||||
|
easyrgb
|
||||||
|
php
|
||||||
ecma
|
ecma
|
||||||
rapidtables
|
rapidtables
|
||||||
WCAG
|
WCAG
|
||||||
|
@ -10,10 +11,9 @@ robertelder
|
||||||
kovidgoyal
|
kovidgoyal
|
||||||
leonerd
|
leonerd
|
||||||
fixterms
|
fixterms
|
||||||
uk
|
|
||||||
winui
|
winui
|
||||||
appshellintegration
|
appshellintegration
|
||||||
|
mdtauk
|
||||||
cppreference
|
cppreference
|
||||||
gfycat
|
gfycat
|
||||||
what3words
|
|
||||||
Guake
|
Guake
|
||||||
|
|
|
@ -22,3 +22,6 @@ Base64::s_(?:En|De)code\(L"[^"]+"
|
||||||
VERIFY_ARE_EQUAL\(L"[^"]+"
|
VERIFY_ARE_EQUAL\(L"[^"]+"
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\+/"
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\+/"
|
||||||
std::memory_order_[\w]+
|
std::memory_order_[\w]+
|
||||||
|
D2DERR_SHADER_COMPILE_FAILED
|
||||||
|
TIL_FEATURE_[0-9A-Z_]+
|
||||||
|
vcvars\w*
|
||||||
|
|
22
.github/actions/spelling/reject.txt
vendored
Normal file
22
.github/actions/spelling/reject.txt
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
^attache$
|
||||||
|
^attacher$
|
||||||
|
^attachers$
|
||||||
|
^spae$
|
||||||
|
^spaebook$
|
||||||
|
^spaecraft$
|
||||||
|
^spaed$
|
||||||
|
^spaedom$
|
||||||
|
^spaeing$
|
||||||
|
^spaeings$
|
||||||
|
^spae-man$
|
||||||
|
^spaeman$
|
||||||
|
^spaer$
|
||||||
|
^Spaerobee$
|
||||||
|
^spaes$
|
||||||
|
^spaewife$
|
||||||
|
^spaewoman$
|
||||||
|
^spaework$
|
||||||
|
^spaewright$
|
||||||
|
^wether$
|
||||||
|
^wethers$
|
||||||
|
^wetherteg$
|
15
.github/workflows/spelling.yml
vendored
15
.github/workflows/spelling.yml
vendored
|
@ -1,15 +0,0 @@
|
||||||
name: Spell checking
|
|
||||||
on:
|
|
||||||
pull_request_target:
|
|
||||||
push:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
name: Spell checking
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2.0.0
|
|
||||||
with:
|
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
|
||||||
fetch-depth: 5
|
|
||||||
- uses: check-spelling/check-spelling@0.0.17-alpha
|
|
20
.github/workflows/spelling2.yml
vendored
Normal file
20
.github/workflows/spelling2.yml
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# spelling.yml is blocked per https://github.com/check-spelling/check-spelling/security/advisories/GHSA-g86g-chm8-7r2p
|
||||||
|
name: Spell checking
|
||||||
|
on:
|
||||||
|
pull_request_target:
|
||||||
|
push:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
spelling:
|
||||||
|
name: Spell checking
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: checkout-merge
|
||||||
|
if: "contains(github.event_name, 'pull_request')"
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
ref: refs/pull/${{github.event.pull_request.number}}/merge
|
||||||
|
- name: checkout
|
||||||
|
if: "!contains(github.event_name, 'pull_request')"
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- uses: check-spelling/check-spelling@v0.0.19
|
30
NOTICE.md
30
NOTICE.md
|
@ -251,3 +251,33 @@ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
DEALINGS IN THE SOFTWARE.
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## `VirtualDesktopUtils`
|
||||||
|
|
||||||
|
**Source**: [https://github.com/microsoft/PowerToys](https://github.com/microsoft/PowerToys)
|
||||||
|
|
||||||
|
### License
|
||||||
|
|
||||||
|
```
|
||||||
|
The MIT License
|
||||||
|
|
||||||
|
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
|
||||||
|
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.
|
||||||
|
```
|
||||||
|
|
|
@ -25,6 +25,12 @@
|
||||||
<ClInclude Include="ProposeCommandlineResult.h">
|
<ClInclude Include="ProposeCommandlineResult.h">
|
||||||
<DependentUpon>Monarch.idl</DependentUpon>
|
<DependentUpon>Monarch.idl</DependentUpon>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="SummonWindowSelectionArgs.h">
|
||||||
|
<DependentUpon>Monarch.idl</DependentUpon>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="SummonWindowBehavior.h">
|
||||||
|
<DependentUpon>Peasant.idl</DependentUpon>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="RenameRequestArgs.h">
|
<ClInclude Include="RenameRequestArgs.h">
|
||||||
<DependentUpon>Peasant.idl</DependentUpon>
|
<DependentUpon>Peasant.idl</DependentUpon>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
@ -54,6 +60,12 @@
|
||||||
<ClCompile Include="ProposeCommandlineResult.cpp">
|
<ClCompile Include="ProposeCommandlineResult.cpp">
|
||||||
<DependentUpon>Monarch.idl</DependentUpon>
|
<DependentUpon>Monarch.idl</DependentUpon>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="SummonWindowSelectionArgs.cpp">
|
||||||
|
<DependentUpon>Monarch.idl</DependentUpon>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="SummonWindowBehavior.cpp">
|
||||||
|
<DependentUpon>Peasant.idl</DependentUpon>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="RenameRequestArgs.cpp">
|
<ClCompile Include="RenameRequestArgs.cpp">
|
||||||
<DependentUpon>Peasant.idl</DependentUpon>
|
<DependentUpon>Peasant.idl</DependentUpon>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|
|
@ -680,4 +680,54 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
||||||
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE));
|
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Method Description:
|
||||||
|
// - Attempt to summon a window. `args` contains information about which
|
||||||
|
// window we should try to summon:
|
||||||
|
// * if a WindowName is provided, we'll try to find a window with exactly
|
||||||
|
// that name, and fail if there isn't one.
|
||||||
|
// - Calls Peasant::Summon on the matching peasant (which might be an RPC call)
|
||||||
|
// - This should only ever be called by the WindowManager in the monarch
|
||||||
|
// process itself. The monarch is the one registering for global hotkeys,
|
||||||
|
// so it's the one calling this method.
|
||||||
|
// Arguments:
|
||||||
|
// - args: contains information about the window that should be summoned.
|
||||||
|
// Return Value:
|
||||||
|
// - <none>
|
||||||
|
// - Sets args.FoundMatch when a window matching args is found successfully.
|
||||||
|
void Monarch::SummonWindow(const Remoting::SummonWindowSelectionArgs& args)
|
||||||
|
{
|
||||||
|
const auto searchedForName{ args.WindowName() };
|
||||||
|
try
|
||||||
|
{
|
||||||
|
args.FoundMatch(false);
|
||||||
|
uint64_t windowId = 0;
|
||||||
|
// If no name was provided, then just summon the MRU window.
|
||||||
|
if (searchedForName.empty())
|
||||||
|
{
|
||||||
|
// Use the value of the `desktop` arg to determine if we should
|
||||||
|
// limit to the current desktop (desktop:onCurrent) or not
|
||||||
|
// (desktop:any or desktop:toCurrent)
|
||||||
|
windowId = _getMostRecentPeasantID(args.OnCurrentDesktop());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Try to find a peasant that currently has this name
|
||||||
|
windowId = _lookupPeasantIdForName(searchedForName);
|
||||||
|
}
|
||||||
|
if (auto targetPeasant{ _getPeasant(windowId) })
|
||||||
|
{
|
||||||
|
targetPeasant.Summon(args.SummonBehavior());
|
||||||
|
args.FoundMatch(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
LOG_CAUGHT_EXCEPTION();
|
||||||
|
TraceLoggingWrite(g_hRemotingProvider,
|
||||||
|
"Monarch_SummonWindow_Failed",
|
||||||
|
TraceLoggingWideString(searchedForName.c_str(), "searchedForName", "The name of the window we tried to summon"),
|
||||||
|
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
||||||
|
|
||||||
winrt::Microsoft::Terminal::Remoting::ProposeCommandlineResult ProposeCommandline(const winrt::Microsoft::Terminal::Remoting::CommandlineArgs& args);
|
winrt::Microsoft::Terminal::Remoting::ProposeCommandlineResult ProposeCommandline(const winrt::Microsoft::Terminal::Remoting::CommandlineArgs& args);
|
||||||
void HandleActivatePeasant(const winrt::Microsoft::Terminal::Remoting::WindowActivatedArgs& args);
|
void HandleActivatePeasant(const winrt::Microsoft::Terminal::Remoting::WindowActivatedArgs& args);
|
||||||
|
void SummonWindow(const Remoting::SummonWindowSelectionArgs& args);
|
||||||
|
|
||||||
TYPED_EVENT(FindTargetWindowRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::FindTargetWindowArgs);
|
TYPED_EVENT(FindTargetWindowRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::FindTargetWindowArgs);
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,19 @@ namespace Microsoft.Terminal.Remoting
|
||||||
Boolean ShouldCreateWindow { get; }; // If you name this `CreateWindow`, the compiler will explode
|
Boolean ShouldCreateWindow { get; }; // If you name this `CreateWindow`, the compiler will explode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[default_interface] runtimeclass SummonWindowSelectionArgs {
|
||||||
|
SummonWindowSelectionArgs();
|
||||||
|
SummonWindowSelectionArgs(String windowName);
|
||||||
|
String WindowName;
|
||||||
|
Boolean OnCurrentDesktop;
|
||||||
|
// TODO GH#8888 Other options:
|
||||||
|
// * CurrentMonitor
|
||||||
|
|
||||||
|
Boolean FoundMatch;
|
||||||
|
SummonWindowBehavior SummonBehavior;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[default_interface] runtimeclass Monarch {
|
[default_interface] runtimeclass Monarch {
|
||||||
Monarch();
|
Monarch();
|
||||||
|
|
||||||
|
@ -25,6 +38,7 @@ namespace Microsoft.Terminal.Remoting
|
||||||
UInt64 AddPeasant(IPeasant peasant);
|
UInt64 AddPeasant(IPeasant peasant);
|
||||||
ProposeCommandlineResult ProposeCommandline(CommandlineArgs args);
|
ProposeCommandlineResult ProposeCommandline(CommandlineArgs args);
|
||||||
void HandleActivatePeasant(WindowActivatedArgs args);
|
void HandleActivatePeasant(WindowActivatedArgs args);
|
||||||
|
void SummonWindow(SummonWindowSelectionArgs args);
|
||||||
|
|
||||||
event Windows.Foundation.TypedEventHandler<Object, FindTargetWindowArgs> FindTargetWindowRequested;
|
event Windows.Foundation.TypedEventHandler<Object, FindTargetWindowArgs> FindTargetWindowRequested;
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "Peasant.h"
|
#include "Peasant.h"
|
||||||
#include "CommandlineArgs.h"
|
#include "CommandlineArgs.h"
|
||||||
|
#include "SummonWindowBehavior.h"
|
||||||
#include "Peasant.g.cpp"
|
#include "Peasant.g.cpp"
|
||||||
#include "../../types/inc/utils.hpp"
|
#include "../../types/inc/utils.hpp"
|
||||||
|
|
||||||
|
@ -117,6 +118,28 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
||||||
return _lastActivatedArgs;
|
return _lastActivatedArgs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Method Description:
|
||||||
|
// - Summon this peasant to become the active window. Currently, it just
|
||||||
|
// causes the peasant to become the active window wherever the window
|
||||||
|
// already was.
|
||||||
|
// - Will raise a SummonRequested event to ask the hosting window to handle for us.
|
||||||
|
// Arguments:
|
||||||
|
// - <none>
|
||||||
|
// Return Value:
|
||||||
|
// - <none>
|
||||||
|
void Peasant::Summon(const Remoting::SummonWindowBehavior& summonBehavior)
|
||||||
|
{
|
||||||
|
auto localCopy = winrt::make_self<implementation::SummonWindowBehavior>(summonBehavior);
|
||||||
|
|
||||||
|
TraceLoggingWrite(g_hRemotingProvider,
|
||||||
|
"Peasant_Summon",
|
||||||
|
TraceLoggingUInt64(GetID(), "peasantID", "Our ID"),
|
||||||
|
TraceLoggingUInt64(localCopy->MoveToCurrentDesktop(), "MoveToCurrentDesktop", "true if we should move to the current desktop"),
|
||||||
|
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE));
|
||||||
|
|
||||||
|
_SummonRequestedHandlers(*this, *localCopy);
|
||||||
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - Tell this window to display it's window ID. We'll raise a
|
// - Tell this window to display it's window ID. We'll raise a
|
||||||
// DisplayWindowIdRequested event, which will get handled in the AppHost,
|
// DisplayWindowIdRequested event, which will get handled in the AppHost,
|
||||||
|
|
|
@ -23,6 +23,8 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
||||||
|
|
||||||
bool ExecuteCommandline(const winrt::Microsoft::Terminal::Remoting::CommandlineArgs& args);
|
bool ExecuteCommandline(const winrt::Microsoft::Terminal::Remoting::CommandlineArgs& args);
|
||||||
void ActivateWindow(const winrt::Microsoft::Terminal::Remoting::WindowActivatedArgs& args);
|
void ActivateWindow(const winrt::Microsoft::Terminal::Remoting::WindowActivatedArgs& args);
|
||||||
|
|
||||||
|
void Summon(const Remoting::SummonWindowBehavior& summonBehavior);
|
||||||
void RequestIdentifyWindows();
|
void RequestIdentifyWindows();
|
||||||
void DisplayWindowId();
|
void DisplayWindowId();
|
||||||
void RequestRename(const winrt::Microsoft::Terminal::Remoting::RenameRequestArgs& args);
|
void RequestRename(const winrt::Microsoft::Terminal::Remoting::RenameRequestArgs& args);
|
||||||
|
@ -37,6 +39,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
||||||
TYPED_EVENT(IdentifyWindowsRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
|
TYPED_EVENT(IdentifyWindowsRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
|
||||||
TYPED_EVENT(DisplayWindowIdRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
|
TYPED_EVENT(DisplayWindowIdRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
|
||||||
TYPED_EVENT(RenameRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::RenameRequestArgs);
|
TYPED_EVENT(RenameRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::RenameRequestArgs);
|
||||||
|
TYPED_EVENT(SummonRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::SummonWindowBehavior);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Peasant(const uint64_t testPID);
|
Peasant(const uint64_t testPID);
|
||||||
|
|
|
@ -30,6 +30,13 @@ namespace Microsoft.Terminal.Remoting
|
||||||
Windows.Foundation.DateTime ActivatedTime { get; };
|
Windows.Foundation.DateTime ActivatedTime { get; };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
[default_interface] runtimeclass SummonWindowBehavior {
|
||||||
|
SummonWindowBehavior();
|
||||||
|
Boolean MoveToCurrentDesktop;
|
||||||
|
// Other options:
|
||||||
|
// * CurrentMonitor
|
||||||
|
}
|
||||||
|
|
||||||
interface IPeasant
|
interface IPeasant
|
||||||
{
|
{
|
||||||
CommandlineArgs InitialArgs { get; };
|
CommandlineArgs InitialArgs { get; };
|
||||||
|
@ -40,17 +47,20 @@ namespace Microsoft.Terminal.Remoting
|
||||||
Boolean ExecuteCommandline(CommandlineArgs args);
|
Boolean ExecuteCommandline(CommandlineArgs args);
|
||||||
void ActivateWindow(WindowActivatedArgs args);
|
void ActivateWindow(WindowActivatedArgs args);
|
||||||
WindowActivatedArgs GetLastActivatedArgs();
|
WindowActivatedArgs GetLastActivatedArgs();
|
||||||
String WindowName { get; };
|
|
||||||
void RequestIdentifyWindows(); // Tells us to raise a IdentifyWindowsRequested
|
|
||||||
void DisplayWindowId(); // Tells us to display its own ID (which causes a DisplayWindowIdRequested to be raised)
|
void DisplayWindowId(); // Tells us to display its own ID (which causes a DisplayWindowIdRequested to be raised)
|
||||||
|
|
||||||
|
String WindowName { get; };
|
||||||
|
void RequestIdentifyWindows(); // Tells us to raise a IdentifyWindowsRequested
|
||||||
void RequestRename(RenameRequestArgs args); // Tells us to raise a RenameRequested
|
void RequestRename(RenameRequestArgs args); // Tells us to raise a RenameRequested
|
||||||
|
void Summon(SummonWindowBehavior behavior);
|
||||||
|
|
||||||
event Windows.Foundation.TypedEventHandler<Object, WindowActivatedArgs> WindowActivated;
|
event Windows.Foundation.TypedEventHandler<Object, WindowActivatedArgs> WindowActivated;
|
||||||
event Windows.Foundation.TypedEventHandler<Object, CommandlineArgs> ExecuteCommandlineRequested;
|
event Windows.Foundation.TypedEventHandler<Object, CommandlineArgs> ExecuteCommandlineRequested;
|
||||||
event Windows.Foundation.TypedEventHandler<Object, Object> IdentifyWindowsRequested;
|
event Windows.Foundation.TypedEventHandler<Object, Object> IdentifyWindowsRequested;
|
||||||
event Windows.Foundation.TypedEventHandler<Object, Object> DisplayWindowIdRequested;
|
event Windows.Foundation.TypedEventHandler<Object, Object> DisplayWindowIdRequested;
|
||||||
event Windows.Foundation.TypedEventHandler<Object, RenameRequestArgs> RenameRequested;
|
event Windows.Foundation.TypedEventHandler<Object, RenameRequestArgs> RenameRequested;
|
||||||
|
event Windows.Foundation.TypedEventHandler<Object, SummonWindowBehavior> SummonRequested;
|
||||||
};
|
};
|
||||||
|
|
||||||
[default_interface] runtimeclass Peasant : IPeasant
|
[default_interface] runtimeclass Peasant : IPeasant
|
||||||
|
|
5
src/cascadia/Remoting/SummonWindowBehavior.cpp
Normal file
5
src/cascadia/Remoting/SummonWindowBehavior.cpp
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
// Copyright (c) Microsoft Corporation.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
#include "pch.h"
|
||||||
|
#include "SummonWindowBehavior.h"
|
||||||
|
#include "SummonWindowBehavior.g.cpp"
|
39
src/cascadia/Remoting/SummonWindowBehavior.h
Normal file
39
src/cascadia/Remoting/SummonWindowBehavior.h
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
/*++
|
||||||
|
Copyright (c) Microsoft Corporation
|
||||||
|
Licensed under the MIT license.
|
||||||
|
|
||||||
|
Class Name:
|
||||||
|
- SummonWindowBehavior.h
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
- A helper class for encapsulating the various properties that control _how_ a
|
||||||
|
window should be summoned, when it is summoned. This will be created from the
|
||||||
|
properties in a GlobalSummonArgs, and passed into a SummonWindowSelectionArgs.
|
||||||
|
When the window is summoned, the Monarch will use these args in the
|
||||||
|
SummonWindowSelectionArgs to tell the peasant how to be summoned.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "SummonWindowBehavior.g.h"
|
||||||
|
#include "../cascadia/inc/cppwinrt_utils.h"
|
||||||
|
|
||||||
|
namespace winrt::Microsoft::Terminal::Remoting::implementation
|
||||||
|
{
|
||||||
|
struct SummonWindowBehavior : public SummonWindowBehaviorT<SummonWindowBehavior>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SummonWindowBehavior() = default;
|
||||||
|
WINRT_PROPERTY(bool, MoveToCurrentDesktop, true);
|
||||||
|
|
||||||
|
public:
|
||||||
|
SummonWindowBehavior(const Remoting::SummonWindowBehavior& other) :
|
||||||
|
_MoveToCurrentDesktop{ other.MoveToCurrentDesktop() } {};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace winrt::Microsoft::Terminal::Remoting::factory_implementation
|
||||||
|
{
|
||||||
|
BASIC_FACTORY(SummonWindowBehavior);
|
||||||
|
}
|
5
src/cascadia/Remoting/SummonWindowSelectionArgs.cpp
Normal file
5
src/cascadia/Remoting/SummonWindowSelectionArgs.cpp
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
// Copyright (c) Microsoft Corporation.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
#include "pch.h"
|
||||||
|
#include "SummonWindowSelectionArgs.h"
|
||||||
|
#include "SummonWindowSelectionArgs.g.cpp"
|
43
src/cascadia/Remoting/SummonWindowSelectionArgs.h
Normal file
43
src/cascadia/Remoting/SummonWindowSelectionArgs.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/*++
|
||||||
|
Copyright (c) Microsoft Corporation
|
||||||
|
Licensed under the MIT license.
|
||||||
|
|
||||||
|
Class Name:
|
||||||
|
- SummonWindowSelectionArgs.h
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
- This is a helper class for determining which window a should be summoned when
|
||||||
|
a global hotkey is pressed. Parameters from a GlobalSummon action will be
|
||||||
|
filled in here. The Monarch will use these to find the window that matches
|
||||||
|
these args, and Summon() that Peasant.
|
||||||
|
- When the monarch finds a match, it will set FoundMatch to true. If it doesn't,
|
||||||
|
then the Monarch window might need to create a new window matching these args
|
||||||
|
instead.
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "SummonWindowSelectionArgs.g.h"
|
||||||
|
#include "../cascadia/inc/cppwinrt_utils.h"
|
||||||
|
|
||||||
|
namespace winrt::Microsoft::Terminal::Remoting::implementation
|
||||||
|
{
|
||||||
|
struct SummonWindowSelectionArgs : public SummonWindowSelectionArgsT<SummonWindowSelectionArgs>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SummonWindowSelectionArgs() = default;
|
||||||
|
SummonWindowSelectionArgs(winrt::hstring name) :
|
||||||
|
_WindowName{ name } {};
|
||||||
|
|
||||||
|
WINRT_PROPERTY(winrt::hstring, WindowName);
|
||||||
|
|
||||||
|
WINRT_PROPERTY(bool, FoundMatch, false);
|
||||||
|
WINRT_PROPERTY(bool, OnCurrentDesktop, false);
|
||||||
|
WINRT_PROPERTY(SummonWindowBehavior, SummonBehavior);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace winrt::Microsoft::Terminal::Remoting::factory_implementation
|
||||||
|
{
|
||||||
|
BASIC_FACTORY(SummonWindowSelectionArgs);
|
||||||
|
}
|
|
@ -247,6 +247,8 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
||||||
// window, and when the current monarch dies.
|
// window, and when the current monarch dies.
|
||||||
|
|
||||||
_monarch.FindTargetWindowRequested({ this, &WindowManager::_raiseFindTargetWindowRequested });
|
_monarch.FindTargetWindowRequested({ this, &WindowManager::_raiseFindTargetWindowRequested });
|
||||||
|
|
||||||
|
_BecameMonarchHandlers(*this, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WindowManager::_areWeTheKing()
|
bool WindowManager::_areWeTheKing()
|
||||||
|
@ -478,4 +480,18 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
||||||
{
|
{
|
||||||
_FindTargetWindowRequestedHandlers(sender, args);
|
_FindTargetWindowRequestedHandlers(sender, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WindowManager::IsMonarch()
|
||||||
|
{
|
||||||
|
return _isKing;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowManager::SummonWindow(const Remoting::SummonWindowSelectionArgs& args)
|
||||||
|
{
|
||||||
|
// We should only ever get called when we are the monarch, because only
|
||||||
|
// the monarch ever registers for the global hotkey. So the monarch is
|
||||||
|
// the only window that will be calling this.
|
||||||
|
_monarch.SummonWindow(args);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,8 +37,11 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
||||||
bool ShouldCreateWindow();
|
bool ShouldCreateWindow();
|
||||||
|
|
||||||
winrt::Microsoft::Terminal::Remoting::Peasant CurrentWindow();
|
winrt::Microsoft::Terminal::Remoting::Peasant CurrentWindow();
|
||||||
|
bool IsMonarch();
|
||||||
|
void SummonWindow(const Remoting::SummonWindowSelectionArgs& args);
|
||||||
|
|
||||||
TYPED_EVENT(FindTargetWindowRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::FindTargetWindowArgs);
|
TYPED_EVENT(FindTargetWindowRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::FindTargetWindowArgs);
|
||||||
|
TYPED_EVENT(BecameMonarch, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _shouldCreateWindow{ false };
|
bool _shouldCreateWindow{ false };
|
||||||
|
|
|
@ -10,6 +10,9 @@ namespace Microsoft.Terminal.Remoting
|
||||||
void ProposeCommandline(CommandlineArgs args);
|
void ProposeCommandline(CommandlineArgs args);
|
||||||
Boolean ShouldCreateWindow { get; };
|
Boolean ShouldCreateWindow { get; };
|
||||||
IPeasant CurrentWindow();
|
IPeasant CurrentWindow();
|
||||||
|
Boolean IsMonarch { get; };
|
||||||
|
void SummonWindow(SummonWindowSelectionArgs args);
|
||||||
event Windows.Foundation.TypedEventHandler<Object, FindTargetWindowArgs> FindTargetWindowRequested;
|
event Windows.Foundation.TypedEventHandler<Object, FindTargetWindowArgs> FindTargetWindowRequested;
|
||||||
|
event Windows.Foundation.TypedEventHandler<Object, Object> BecameMonarch;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -771,4 +771,23 @@ namespace winrt::TerminalApp::implementation
|
||||||
|
|
||||||
args.Handled(true);
|
args.Handled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TerminalPage::_HandleGlobalSummon(const IInspectable& /*sender*/,
|
||||||
|
const ActionEventArgs& args)
|
||||||
|
{
|
||||||
|
// Manually return false. These shouldn't ever get here, except for when
|
||||||
|
// we fail to register for the global hotkey. In that case, returning
|
||||||
|
// false here will let the underlying terminal still process the key, as
|
||||||
|
// if it wasn't bound at all.
|
||||||
|
args.Handled(false);
|
||||||
|
}
|
||||||
|
void TerminalPage::_HandleQuakeMode(const IInspectable& /*sender*/,
|
||||||
|
const ActionEventArgs& args)
|
||||||
|
{
|
||||||
|
// Manually return false. These shouldn't ever get here, except for when
|
||||||
|
// we fail to register for the global hotkey. In that case, returning
|
||||||
|
// false here will let the underlying terminal still process the key, as
|
||||||
|
// if it wasn't bound at all.
|
||||||
|
args.Handled(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -988,7 +988,7 @@ namespace winrt::TerminalApp::implementation
|
||||||
CATCH_LOG();
|
CATCH_LOG();
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - Reloads the settings from the profile.json.
|
// - Reloads the settings from the settings.json file.
|
||||||
void AppLogic::_ReloadSettings()
|
void AppLogic::_ReloadSettings()
|
||||||
{
|
{
|
||||||
// Attempt to load our settings.
|
// Attempt to load our settings.
|
||||||
|
@ -1018,6 +1018,8 @@ namespace winrt::TerminalApp::implementation
|
||||||
_ApplyStartupTaskStateChange();
|
_ApplyStartupTaskStateChange();
|
||||||
|
|
||||||
Jumplist::UpdateJumplist(_settings);
|
Jumplist::UpdateJumplist(_settings);
|
||||||
|
|
||||||
|
_SettingsChangedHandlers(*this, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
|
@ -1400,6 +1402,11 @@ namespace winrt::TerminalApp::implementation
|
||||||
return _root ? _root->AlwaysOnTop() : false;
|
return _root ? _root->AlwaysOnTop() : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Windows::Foundation::Collections::IMap<Microsoft::Terminal::Control::KeyChord, Microsoft::Terminal::Settings::Model::ActionAndArgs> AppLogic::GlobalHotkeys()
|
||||||
|
{
|
||||||
|
return _settings.GlobalSettings().KeyMap().FetchGlobalHotkeys();
|
||||||
|
}
|
||||||
|
|
||||||
void AppLogic::IdentifyWindow()
|
void AppLogic::IdentifyWindow()
|
||||||
{
|
{
|
||||||
if (_root)
|
if (_root)
|
||||||
|
|
|
@ -89,8 +89,11 @@ namespace winrt::TerminalApp::implementation
|
||||||
|
|
||||||
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> ShowDialog(winrt::Windows::UI::Xaml::Controls::ContentDialog dialog);
|
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> ShowDialog(winrt::Windows::UI::Xaml::Controls::ContentDialog dialog);
|
||||||
|
|
||||||
|
Windows::Foundation::Collections::IMap<Microsoft::Terminal::Control::KeyChord, Microsoft::Terminal::Settings::Model::ActionAndArgs> GlobalHotkeys();
|
||||||
|
|
||||||
// -------------------------------- WinRT Events ---------------------------------
|
// -------------------------------- WinRT Events ---------------------------------
|
||||||
TYPED_EVENT(RequestedThemeChanged, winrt::Windows::Foundation::IInspectable, winrt::Windows::UI::Xaml::ElementTheme);
|
TYPED_EVENT(RequestedThemeChanged, winrt::Windows::Foundation::IInspectable, winrt::Windows::UI::Xaml::ElementTheme);
|
||||||
|
TYPED_EVENT(SettingsChanged, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _isUwp{ false };
|
bool _isUwp{ false };
|
||||||
|
|
|
@ -70,6 +70,8 @@ namespace TerminalApp
|
||||||
|
|
||||||
FindTargetWindowResult FindTargetWindow(String[] args);
|
FindTargetWindowResult FindTargetWindow(String[] args);
|
||||||
|
|
||||||
|
Windows.Foundation.Collections.IMap<Microsoft.Terminal.Control.KeyChord, Microsoft.Terminal.Settings.Model.ActionAndArgs> GlobalHotkeys();
|
||||||
|
|
||||||
// See IDialogPresenter and TerminalPage's DialogPresenter for more
|
// See IDialogPresenter and TerminalPage's DialogPresenter for more
|
||||||
// information.
|
// information.
|
||||||
Windows.Foundation.IAsyncOperation<Windows.UI.Xaml.Controls.ContentDialogResult> ShowDialog(Windows.UI.Xaml.Controls.ContentDialog dialog);
|
Windows.Foundation.IAsyncOperation<Windows.UI.Xaml.Controls.ContentDialogResult> ShowDialog(Windows.UI.Xaml.Controls.ContentDialog dialog);
|
||||||
|
@ -85,5 +87,6 @@ namespace TerminalApp
|
||||||
event Windows.Foundation.TypedEventHandler<Object, Object> SetTaskbarProgress;
|
event Windows.Foundation.TypedEventHandler<Object, Object> SetTaskbarProgress;
|
||||||
event Windows.Foundation.TypedEventHandler<Object, Object> IdentifyWindowsRequested;
|
event Windows.Foundation.TypedEventHandler<Object, Object> IdentifyWindowsRequested;
|
||||||
event Windows.Foundation.TypedEventHandler<Object, RenameWindowRequestedArgs> RenameWindowRequested;
|
event Windows.Foundation.TypedEventHandler<Object, RenameWindowRequestedArgs> RenameWindowRequested;
|
||||||
|
event Windows.Foundation.TypedEventHandler<Object, Object> SettingsChanged;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,8 @@ static constexpr std::string_view IdentifyWindowKey{ "identifyWindow" };
|
||||||
static constexpr std::string_view IdentifyWindowsKey{ "identifyWindows" };
|
static constexpr std::string_view IdentifyWindowsKey{ "identifyWindows" };
|
||||||
static constexpr std::string_view RenameWindowKey{ "renameWindow" };
|
static constexpr std::string_view RenameWindowKey{ "renameWindow" };
|
||||||
static constexpr std::string_view OpenWindowRenamerKey{ "openWindowRenamer" };
|
static constexpr std::string_view OpenWindowRenamerKey{ "openWindowRenamer" };
|
||||||
|
static constexpr std::string_view GlobalSummonKey{ "globalSummon" };
|
||||||
|
static constexpr std::string_view QuakeModeKey{ "quakeMode" };
|
||||||
|
|
||||||
static constexpr std::string_view ActionKey{ "action" };
|
static constexpr std::string_view ActionKey{ "action" };
|
||||||
|
|
||||||
|
@ -127,6 +129,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||||
{ IdentifyWindowsKey, ShortcutAction::IdentifyWindows },
|
{ IdentifyWindowsKey, ShortcutAction::IdentifyWindows },
|
||||||
{ RenameWindowKey, ShortcutAction::RenameWindow },
|
{ RenameWindowKey, ShortcutAction::RenameWindow },
|
||||||
{ OpenWindowRenamerKey, ShortcutAction::OpenWindowRenamer },
|
{ OpenWindowRenamerKey, ShortcutAction::OpenWindowRenamer },
|
||||||
|
{ GlobalSummonKey, ShortcutAction::GlobalSummon },
|
||||||
|
{ QuakeModeKey, ShortcutAction::QuakeMode },
|
||||||
};
|
};
|
||||||
|
|
||||||
using ParseResult = std::tuple<IActionArgs, std::vector<SettingsLoadWarnings>>;
|
using ParseResult = std::tuple<IActionArgs, std::vector<SettingsLoadWarnings>>;
|
||||||
|
@ -162,6 +166,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||||
{ ShortcutAction::PrevTab, PrevTabArgs::FromJson },
|
{ ShortcutAction::PrevTab, PrevTabArgs::FromJson },
|
||||||
{ ShortcutAction::NextTab, NextTabArgs::FromJson },
|
{ ShortcutAction::NextTab, NextTabArgs::FromJson },
|
||||||
{ ShortcutAction::RenameWindow, RenameWindowArgs::FromJson },
|
{ ShortcutAction::RenameWindow, RenameWindowArgs::FromJson },
|
||||||
|
{ ShortcutAction::GlobalSummon, GlobalSummonArgs::FromJson },
|
||||||
|
|
||||||
{ ShortcutAction::Invalid, nullptr },
|
{ ShortcutAction::Invalid, nullptr },
|
||||||
};
|
};
|
||||||
|
@ -337,6 +342,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||||
{ ShortcutAction::IdentifyWindows, RS_(L"IdentifyWindowsCommandKey") },
|
{ ShortcutAction::IdentifyWindows, RS_(L"IdentifyWindowsCommandKey") },
|
||||||
{ ShortcutAction::RenameWindow, RS_(L"ResetWindowNameCommandKey") },
|
{ ShortcutAction::RenameWindow, RS_(L"ResetWindowNameCommandKey") },
|
||||||
{ ShortcutAction::OpenWindowRenamer, RS_(L"OpenWindowRenamerCommandKey") },
|
{ ShortcutAction::OpenWindowRenamer, RS_(L"OpenWindowRenamerCommandKey") },
|
||||||
|
{ ShortcutAction::GlobalSummon, L"" }, // Intentionally omitted, must be generated by GenerateName
|
||||||
|
{ ShortcutAction::QuakeMode, RS_(L"QuakeModeCommandKey") },
|
||||||
};
|
};
|
||||||
}();
|
}();
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "PrevTabArgs.g.cpp"
|
#include "PrevTabArgs.g.cpp"
|
||||||
#include "NextTabArgs.g.cpp"
|
#include "NextTabArgs.g.cpp"
|
||||||
#include "RenameWindowArgs.g.cpp"
|
#include "RenameWindowArgs.g.cpp"
|
||||||
|
#include "GlobalSummonArgs.g.cpp"
|
||||||
|
|
||||||
#include <LibraryResources.h>
|
#include <LibraryResources.h>
|
||||||
|
|
||||||
|
@ -582,4 +583,19 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||||
}
|
}
|
||||||
return RS_(L"ResetWindowNameCommandKey");
|
return RS_(L"ResetWindowNameCommandKey");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
winrt::hstring GlobalSummonArgs::GenerateName() const
|
||||||
|
{
|
||||||
|
std::wstringstream ss;
|
||||||
|
ss << std::wstring_view(RS_(L"GlobalSummonCommandKey"));
|
||||||
|
|
||||||
|
// "Summon the Terminal window"
|
||||||
|
// "Summon the Terminal window, name:\"{_Name}\""
|
||||||
|
if (!_Name.empty())
|
||||||
|
{
|
||||||
|
ss << L", name: ";
|
||||||
|
ss << std::wstring_view(_Name);
|
||||||
|
}
|
||||||
|
return winrt::hstring{ ss.str() };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "PrevTabArgs.g.h"
|
#include "PrevTabArgs.g.h"
|
||||||
#include "NextTabArgs.g.h"
|
#include "NextTabArgs.g.h"
|
||||||
#include "RenameWindowArgs.g.h"
|
#include "RenameWindowArgs.g.h"
|
||||||
|
#include "GlobalSummonArgs.g.h"
|
||||||
|
|
||||||
#include "../../cascadia/inc/cppwinrt_utils.h"
|
#include "../../cascadia/inc/cppwinrt_utils.h"
|
||||||
#include "JsonUtils.h"
|
#include "JsonUtils.h"
|
||||||
|
@ -1037,6 +1038,45 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||||
return *copy;
|
return *copy;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct GlobalSummonArgs : public GlobalSummonArgsT<GlobalSummonArgs>
|
||||||
|
{
|
||||||
|
GlobalSummonArgs() = default;
|
||||||
|
WINRT_PROPERTY(winrt::hstring, Name, L"");
|
||||||
|
WINRT_PROPERTY(Model::DesktopBehavior, Desktop, Model::DesktopBehavior::ToCurrent);
|
||||||
|
|
||||||
|
static constexpr std::string_view NameKey{ "name" };
|
||||||
|
static constexpr std::string_view DesktopKey{ "desktop" };
|
||||||
|
|
||||||
|
public:
|
||||||
|
hstring GenerateName() const;
|
||||||
|
|
||||||
|
bool Equals(const IActionArgs& other)
|
||||||
|
{
|
||||||
|
if (auto otherAsUs = other.try_as<GlobalSummonArgs>())
|
||||||
|
{
|
||||||
|
return otherAsUs->_Name == _Name &&
|
||||||
|
otherAsUs->_Desktop == _Desktop;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
static FromJsonResult FromJson(const Json::Value& json)
|
||||||
|
{
|
||||||
|
// LOAD BEARING: Not using make_self here _will_ break you in the future!
|
||||||
|
auto args = winrt::make_self<GlobalSummonArgs>();
|
||||||
|
JsonUtils::GetValueForKey(json, NameKey, args->_Name);
|
||||||
|
JsonUtils::GetValueForKey(json, DesktopKey, args->_Desktop);
|
||||||
|
return { *args, {} };
|
||||||
|
}
|
||||||
|
IActionArgs Copy() const
|
||||||
|
{
|
||||||
|
auto copy{ winrt::make_self<GlobalSummonArgs>() };
|
||||||
|
copy->_Name = _Name;
|
||||||
|
copy->_Desktop = _Desktop;
|
||||||
|
return *copy;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace winrt::Microsoft::Terminal::Settings::Model::factory_implementation
|
namespace winrt::Microsoft::Terminal::Settings::Model::factory_implementation
|
||||||
|
|
|
@ -84,6 +84,13 @@ namespace Microsoft.Terminal.Settings.Model
|
||||||
Disabled,
|
Disabled,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum DesktopBehavior
|
||||||
|
{
|
||||||
|
Any,
|
||||||
|
ToCurrent,
|
||||||
|
OnCurrent,
|
||||||
|
};
|
||||||
|
|
||||||
[default_interface] runtimeclass NewTerminalArgs {
|
[default_interface] runtimeclass NewTerminalArgs {
|
||||||
NewTerminalArgs();
|
NewTerminalArgs();
|
||||||
NewTerminalArgs(Int32 profileIndex);
|
NewTerminalArgs(Int32 profileIndex);
|
||||||
|
@ -252,4 +259,10 @@ namespace Microsoft.Terminal.Settings.Model
|
||||||
{
|
{
|
||||||
String Name { get; };
|
String Name { get; };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
[default_interface] runtimeclass GlobalSummonArgs : IActionArgs
|
||||||
|
{
|
||||||
|
String Name { get; };
|
||||||
|
DesktopBehavior Desktop { get; };
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,4 +72,6 @@
|
||||||
ON_ALL_ACTIONS(IdentifyWindow) \
|
ON_ALL_ACTIONS(IdentifyWindow) \
|
||||||
ON_ALL_ACTIONS(IdentifyWindows) \
|
ON_ALL_ACTIONS(IdentifyWindows) \
|
||||||
ON_ALL_ACTIONS(RenameWindow) \
|
ON_ALL_ACTIONS(RenameWindow) \
|
||||||
ON_ALL_ACTIONS(OpenWindowRenamer)
|
ON_ALL_ACTIONS(OpenWindowRenamer) \
|
||||||
|
ON_ALL_ACTIONS(GlobalSummon) \
|
||||||
|
ON_ALL_ACTIONS(QuakeMode)
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "../../inc/DefaultSettings.h"
|
#include "../../inc/DefaultSettings.h"
|
||||||
#include "JsonUtils.h"
|
#include "JsonUtils.h"
|
||||||
#include "TerminalSettingsSerializationHelpers.h"
|
#include "TerminalSettingsSerializationHelpers.h"
|
||||||
|
#include "KeyChordSerialization.h"
|
||||||
|
|
||||||
#include "GlobalAppSettings.g.cpp"
|
#include "GlobalAppSettings.g.cpp"
|
||||||
|
|
||||||
|
|
|
@ -141,4 +141,44 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||||
|
|
||||||
return keyModifiers;
|
return keyModifiers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Method Description:
|
||||||
|
// - Build a map of all the globalSummon actions.
|
||||||
|
// - quakeMode actions are included in this, but expanded to the equivalent
|
||||||
|
// set of GlobalSummonArgs
|
||||||
|
// - This is only ever called in two scenarios:
|
||||||
|
// - on becoming the monarch (which only happens once per window)
|
||||||
|
// - when the settings reload (and the cache would inevitably be dirty)
|
||||||
|
// So it's perfectly reasonable to not cache these results.
|
||||||
|
// Arguments:
|
||||||
|
// - <none>
|
||||||
|
// Return Value:
|
||||||
|
// - a map of KeyChord -> ActionAndArgs containing all globally bindable actions.
|
||||||
|
Windows::Foundation::Collections::IMap<Control::KeyChord, Model::ActionAndArgs> KeyMapping::FetchGlobalHotkeys()
|
||||||
|
{
|
||||||
|
std::unordered_map<Control::KeyChord, Model::ActionAndArgs, KeyChordHash, KeyChordEquality> justGlobals;
|
||||||
|
|
||||||
|
for (const auto& [k, v] : _keyShortcuts)
|
||||||
|
{
|
||||||
|
if (v.Action() == ShortcutAction::GlobalSummon)
|
||||||
|
{
|
||||||
|
justGlobals[k] = v;
|
||||||
|
}
|
||||||
|
else if (v.Action() == ShortcutAction::QuakeMode)
|
||||||
|
{
|
||||||
|
// Manually replace the QuakeMode action with a globalSummon
|
||||||
|
// that has the appropriate action args.
|
||||||
|
auto args = winrt::make_self<GlobalSummonArgs>();
|
||||||
|
|
||||||
|
// We want to summon the window with the name "_quake" specifically.
|
||||||
|
args->Name(L"_quake");
|
||||||
|
|
||||||
|
Model::ActionAndArgs actionAndArgs{ ShortcutAction::GlobalSummon, *args };
|
||||||
|
justGlobals[k] = actionAndArgs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return winrt::single_threaded_map<Control::KeyChord, Model::ActionAndArgs>(std::move(justGlobals));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||||
std::vector<Model::SettingsLoadWarnings> LayerJson(const Json::Value& json);
|
std::vector<Model::SettingsLoadWarnings> LayerJson(const Json::Value& json);
|
||||||
Json::Value ToJson();
|
Json::Value ToJson();
|
||||||
|
|
||||||
|
Windows::Foundation::Collections::IMap<Control::KeyChord, Model::ActionAndArgs> FetchGlobalHotkeys();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unordered_map<Control::KeyChord, Model::ActionAndArgs, KeyChordHash, KeyChordEquality> _keyShortcuts;
|
std::unordered_map<Control::KeyChord, Model::ActionAndArgs, KeyChordHash, KeyChordEquality> _keyShortcuts;
|
||||||
std::vector<std::pair<Control::KeyChord, Model::ActionAndArgs>> _keyShortcutsByInsertionOrder;
|
std::vector<std::pair<Control::KeyChord, Model::ActionAndArgs>> _keyShortcutsByInsertionOrder;
|
||||||
|
|
|
@ -35,5 +35,7 @@ namespace Microsoft.Terminal.Settings.Model
|
||||||
|
|
||||||
Microsoft.Terminal.Control.KeyChord GetKeyBindingForAction(ShortcutAction action);
|
Microsoft.Terminal.Control.KeyChord GetKeyBindingForAction(ShortcutAction action);
|
||||||
Microsoft.Terminal.Control.KeyChord GetKeyBindingForActionWithArgs(ActionAndArgs actionAndArgs);
|
Microsoft.Terminal.Control.KeyChord GetKeyBindingForActionWithArgs(ActionAndArgs actionAndArgs);
|
||||||
|
|
||||||
|
Windows.Foundation.Collections.IMap<Microsoft.Terminal.Control.KeyChord, ActionAndArgs> FetchGlobalHotkeys();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -391,4 +391,10 @@
|
||||||
<data name="OpenWindowRenamerCommandKey" xml:space="preserve">
|
<data name="OpenWindowRenamerCommandKey" xml:space="preserve">
|
||||||
<value>Rename window...</value>
|
<value>Rename window...</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="GlobalSummonCommandKey" xml:space="preserve">
|
||||||
|
<value>Summon the Terminal window</value>
|
||||||
|
</data>
|
||||||
|
<data name="QuakeModeCommandKey" xml:space="preserve">
|
||||||
|
<value>Summon Quake window</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|
|
@ -448,3 +448,12 @@ JSON_ENUM_MAPPER(::winrt::Microsoft::Terminal::Settings::Model::WindowingMode)
|
||||||
pair_type{ "useExisting", ValueType::UseExisting },
|
pair_type{ "useExisting", ValueType::UseExisting },
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
JSON_ENUM_MAPPER(::winrt::Microsoft::Terminal::Settings::Model::DesktopBehavior)
|
||||||
|
{
|
||||||
|
JSON_MAPPINGS(3) = {
|
||||||
|
pair_type{ "any", ValueType::Any },
|
||||||
|
pair_type{ "toCurrent", ValueType::ToCurrent },
|
||||||
|
pair_type{ "onCurrent", ValueType::OnCurrent },
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
|
@ -36,6 +36,31 @@ using namespace winrt::Microsoft::Terminal;
|
||||||
|
|
||||||
namespace RemotingUnitTests
|
namespace RemotingUnitTests
|
||||||
{
|
{
|
||||||
|
struct MockDesktopManager : implements<MockDesktopManager, IVirtualDesktopManager>
|
||||||
|
{
|
||||||
|
HRESULT GetWindowDesktopId(HWND /*topLevelWindow*/, GUID* /*desktopId*/)
|
||||||
|
{
|
||||||
|
VERIFY_IS_TRUE(false, L"We shouldn't need GetWindowDesktopId in the tests.");
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
HRESULT MoveWindowToDesktop(HWND /*topLevelWindow*/, REFGUID /*desktopId*/)
|
||||||
|
{
|
||||||
|
VERIFY_IS_TRUE(false, L"We shouldn't need GetWindowDesktopId in the tests.");
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
HRESULT IsWindowOnCurrentVirtualDesktop(HWND topLevelWindow, BOOL* onCurrentDesktop)
|
||||||
|
{
|
||||||
|
if (pfnIsWindowOnCurrentVirtualDesktop)
|
||||||
|
{
|
||||||
|
return pfnIsWindowOnCurrentVirtualDesktop(topLevelWindow, onCurrentDesktop);
|
||||||
|
}
|
||||||
|
VERIFY_IS_TRUE(false, L"You didn't set up the pfnIsWindowOnCurrentVirtualDesktop for this test!");
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::function<HRESULT(HWND, BOOL*)> pfnIsWindowOnCurrentVirtualDesktop;
|
||||||
|
};
|
||||||
|
|
||||||
// This is a silly helper struct.
|
// This is a silly helper struct.
|
||||||
// It will always throw an hresult_error on any of its methods.
|
// It will always throw an hresult_error on any of its methods.
|
||||||
//
|
//
|
||||||
|
@ -60,11 +85,13 @@ namespace RemotingUnitTests
|
||||||
Remoting::CommandlineArgs InitialArgs() { throw winrt::hresult_error{}; }
|
Remoting::CommandlineArgs InitialArgs() { throw winrt::hresult_error{}; }
|
||||||
Remoting::WindowActivatedArgs GetLastActivatedArgs() { throw winrt::hresult_error{}; }
|
Remoting::WindowActivatedArgs GetLastActivatedArgs() { throw winrt::hresult_error{}; }
|
||||||
void RequestRename(const Remoting::RenameRequestArgs& /*args*/) { throw winrt::hresult_error{}; }
|
void RequestRename(const Remoting::RenameRequestArgs& /*args*/) { throw winrt::hresult_error{}; }
|
||||||
|
void Summon(const Remoting::SummonWindowBehavior& /*args*/) { throw winrt::hresult_error{}; };
|
||||||
TYPED_EVENT(WindowActivated, winrt::Windows::Foundation::IInspectable, Remoting::WindowActivatedArgs);
|
TYPED_EVENT(WindowActivated, winrt::Windows::Foundation::IInspectable, Remoting::WindowActivatedArgs);
|
||||||
TYPED_EVENT(ExecuteCommandlineRequested, winrt::Windows::Foundation::IInspectable, Remoting::CommandlineArgs);
|
TYPED_EVENT(ExecuteCommandlineRequested, winrt::Windows::Foundation::IInspectable, Remoting::CommandlineArgs);
|
||||||
TYPED_EVENT(IdentifyWindowsRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
|
TYPED_EVENT(IdentifyWindowsRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
|
||||||
TYPED_EVENT(DisplayWindowIdRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
|
TYPED_EVENT(DisplayWindowIdRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
|
||||||
TYPED_EVENT(RenameRequested, winrt::Windows::Foundation::IInspectable, Remoting::RenameRequestArgs);
|
TYPED_EVENT(RenameRequested, winrt::Windows::Foundation::IInspectable, Remoting::RenameRequestArgs);
|
||||||
|
TYPED_EVENT(SummonRequested, winrt::Windows::Foundation::IInspectable, Remoting::SummonWindowBehavior);
|
||||||
};
|
};
|
||||||
|
|
||||||
class RemotingTests
|
class RemotingTests
|
||||||
|
@ -105,6 +132,15 @@ namespace RemotingUnitTests
|
||||||
TEST_METHOD(TestRenameSameNameAsAnother);
|
TEST_METHOD(TestRenameSameNameAsAnother);
|
||||||
TEST_METHOD(TestRenameSameNameAsADeadPeasant);
|
TEST_METHOD(TestRenameSameNameAsADeadPeasant);
|
||||||
|
|
||||||
|
TEST_METHOD(TestSummonMostRecentWindow);
|
||||||
|
TEST_METHOD(TestSummonNamedWindow);
|
||||||
|
TEST_METHOD(TestSummonNamedDeadWindow);
|
||||||
|
TEST_METHOD(TestSummonMostRecentDeadWindow);
|
||||||
|
|
||||||
|
TEST_METHOD(TestSummonOnCurrent);
|
||||||
|
TEST_METHOD(TestSummonOnCurrentWithName);
|
||||||
|
TEST_METHOD(TestSummonOnCurrentDeadWindow);
|
||||||
|
|
||||||
TEST_CLASS_SETUP(ClassSetup)
|
TEST_CLASS_SETUP(ClassSetup)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
@ -466,7 +502,6 @@ namespace RemotingUnitTests
|
||||||
VERIFY_ARE_EQUAL(false, (bool)result.Id());
|
VERIFY_ARE_EQUAL(false, (bool)result.Id());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemotingTests::ProposeCommandlineCurrentWindow()
|
void RemotingTests::ProposeCommandlineCurrentWindow()
|
||||||
{
|
{
|
||||||
Log::Comment(L"Test proposing a commandline for the current window (ID=0)");
|
Log::Comment(L"Test proposing a commandline for the current window (ID=0)");
|
||||||
|
@ -547,7 +582,6 @@ namespace RemotingUnitTests
|
||||||
VERIFY_ARE_EQUAL(false, (bool)result.Id());
|
VERIFY_ARE_EQUAL(false, (bool)result.Id());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemotingTests::ProposeCommandlineNonExistentWindow()
|
void RemotingTests::ProposeCommandlineNonExistentWindow()
|
||||||
{
|
{
|
||||||
Log::Comment(L"Test proposing a commandline for an ID that doesn't have a current peasant");
|
Log::Comment(L"Test proposing a commandline for an ID that doesn't have a current peasant");
|
||||||
|
@ -1506,4 +1540,884 @@ namespace RemotingUnitTests
|
||||||
VERIFY_ARE_EQUAL(p1->GetID(), m0->_lookupPeasantIdForName(L"two"));
|
VERIFY_ARE_EQUAL(p1->GetID(), m0->_lookupPeasantIdForName(L"two"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RemotingTests::TestSummonMostRecentWindow()
|
||||||
|
{
|
||||||
|
Log::Comment(L"Attempt to summon the most recent window");
|
||||||
|
|
||||||
|
const winrt::guid guid1{ Utils::GuidFromString(L"{11111111-1111-1111-1111-111111111111}") };
|
||||||
|
|
||||||
|
const auto monarch0PID = 12345u;
|
||||||
|
const auto peasant1PID = 23456u;
|
||||||
|
const auto peasant2PID = 34567u;
|
||||||
|
|
||||||
|
com_ptr<Remoting::implementation::Monarch> m0;
|
||||||
|
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||||
|
|
||||||
|
com_ptr<Remoting::implementation::Peasant> p1;
|
||||||
|
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||||
|
|
||||||
|
com_ptr<Remoting::implementation::Peasant> p2;
|
||||||
|
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||||
|
|
||||||
|
VERIFY_IS_NOT_NULL(m0);
|
||||||
|
VERIFY_IS_NOT_NULL(p1);
|
||||||
|
VERIFY_IS_NOT_NULL(p2);
|
||||||
|
p1->WindowName(L"one");
|
||||||
|
p2->WindowName(L"two");
|
||||||
|
|
||||||
|
VERIFY_ARE_EQUAL(0, p1->GetID());
|
||||||
|
VERIFY_ARE_EQUAL(0, p2->GetID());
|
||||||
|
|
||||||
|
m0->AddPeasant(*p1);
|
||||||
|
m0->AddPeasant(*p2);
|
||||||
|
|
||||||
|
VERIFY_ARE_EQUAL(1, p1->GetID());
|
||||||
|
VERIFY_ARE_EQUAL(2, p2->GetID());
|
||||||
|
|
||||||
|
VERIFY_ARE_EQUAL(2u, m0->_peasants.size());
|
||||||
|
|
||||||
|
bool p1ExpectedToBeSummoned = false;
|
||||||
|
bool p2ExpectedToBeSummoned = false;
|
||||||
|
|
||||||
|
p1->SummonRequested([&](auto&&, auto&&) {
|
||||||
|
Log::Comment(L"p1 summoned");
|
||||||
|
VERIFY_IS_TRUE(p1ExpectedToBeSummoned);
|
||||||
|
});
|
||||||
|
p2->SummonRequested([&](auto&&, auto&&) {
|
||||||
|
Log::Comment(L"p2 summoned");
|
||||||
|
VERIFY_IS_TRUE(p2ExpectedToBeSummoned);
|
||||||
|
});
|
||||||
|
|
||||||
|
{
|
||||||
|
Log::Comment(L"Activate the first peasant, first desktop");
|
||||||
|
Remoting::WindowActivatedArgs activatedArgs{ p1->GetID(),
|
||||||
|
guid1,
|
||||||
|
winrt::clock().now() };
|
||||||
|
p1->ActivateWindow(activatedArgs);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Log::Comment(L"Activate the second peasant, first desktop");
|
||||||
|
Remoting::WindowActivatedArgs activatedArgs{ p2->GetID(),
|
||||||
|
guid1,
|
||||||
|
winrt::clock().now() };
|
||||||
|
p2->ActivateWindow(activatedArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
p2ExpectedToBeSummoned = true;
|
||||||
|
Remoting::SummonWindowSelectionArgs args;
|
||||||
|
// Without setting the WindowName, SummonWindowSelectionArgs defaults to
|
||||||
|
// the MRU window
|
||||||
|
Log::Comment(L"Summon the MRU window, which is window two");
|
||||||
|
m0->SummonWindow(args);
|
||||||
|
VERIFY_IS_TRUE(args.FoundMatch());
|
||||||
|
|
||||||
|
{
|
||||||
|
Log::Comment(L"Activate the first peasant, first desktop");
|
||||||
|
Remoting::WindowActivatedArgs activatedArgs{ p1->GetID(),
|
||||||
|
guid1,
|
||||||
|
winrt::clock().now() };
|
||||||
|
p1->ActivateWindow(activatedArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::Comment(L"Now that one is the MRU, summon it");
|
||||||
|
p2ExpectedToBeSummoned = false;
|
||||||
|
p1ExpectedToBeSummoned = true;
|
||||||
|
args.FoundMatch(false);
|
||||||
|
m0->SummonWindow(args);
|
||||||
|
VERIFY_IS_TRUE(args.FoundMatch());
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemotingTests::TestSummonNamedWindow()
|
||||||
|
{
|
||||||
|
Log::Comment(L"Attempt to summon a window by name. When there isn't a "
|
||||||
|
L"window with that name, set FoundMatch to false, so the "
|
||||||
|
L"caller can handle that case.");
|
||||||
|
|
||||||
|
const auto monarch0PID = 12345u;
|
||||||
|
const auto peasant1PID = 23456u;
|
||||||
|
const auto peasant2PID = 34567u;
|
||||||
|
|
||||||
|
com_ptr<Remoting::implementation::Monarch> m0;
|
||||||
|
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||||
|
|
||||||
|
com_ptr<Remoting::implementation::Peasant> p1;
|
||||||
|
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||||
|
|
||||||
|
com_ptr<Remoting::implementation::Peasant> p2;
|
||||||
|
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||||
|
|
||||||
|
VERIFY_IS_NOT_NULL(m0);
|
||||||
|
VERIFY_IS_NOT_NULL(p1);
|
||||||
|
VERIFY_IS_NOT_NULL(p2);
|
||||||
|
p1->WindowName(L"one");
|
||||||
|
p2->WindowName(L"two");
|
||||||
|
|
||||||
|
VERIFY_ARE_EQUAL(0, p1->GetID());
|
||||||
|
VERIFY_ARE_EQUAL(0, p2->GetID());
|
||||||
|
|
||||||
|
m0->AddPeasant(*p1);
|
||||||
|
m0->AddPeasant(*p2);
|
||||||
|
|
||||||
|
VERIFY_ARE_EQUAL(1, p1->GetID());
|
||||||
|
VERIFY_ARE_EQUAL(2, p2->GetID());
|
||||||
|
|
||||||
|
VERIFY_ARE_EQUAL(2u, m0->_peasants.size());
|
||||||
|
|
||||||
|
bool p1ExpectedToBeSummoned = false;
|
||||||
|
bool p2ExpectedToBeSummoned = false;
|
||||||
|
|
||||||
|
p1->SummonRequested([&](auto&&, auto&&) {
|
||||||
|
Log::Comment(L"p1 summoned");
|
||||||
|
VERIFY_IS_TRUE(p1ExpectedToBeSummoned);
|
||||||
|
});
|
||||||
|
p2->SummonRequested([&](auto&&, auto&&) {
|
||||||
|
Log::Comment(L"p2 summoned");
|
||||||
|
VERIFY_IS_TRUE(p2ExpectedToBeSummoned);
|
||||||
|
});
|
||||||
|
|
||||||
|
Remoting::SummonWindowSelectionArgs args;
|
||||||
|
|
||||||
|
Log::Comment(L"Summon window two by name");
|
||||||
|
p2ExpectedToBeSummoned = true;
|
||||||
|
args.WindowName(L"two");
|
||||||
|
m0->SummonWindow(args);
|
||||||
|
VERIFY_IS_TRUE(args.FoundMatch());
|
||||||
|
|
||||||
|
Log::Comment(L"Summon window one by name");
|
||||||
|
p2ExpectedToBeSummoned = false;
|
||||||
|
p1ExpectedToBeSummoned = true;
|
||||||
|
args.FoundMatch(false);
|
||||||
|
args.WindowName(L"one");
|
||||||
|
m0->SummonWindow(args);
|
||||||
|
VERIFY_IS_TRUE(args.FoundMatch());
|
||||||
|
|
||||||
|
Log::Comment(L"Fail to summon window three by name");
|
||||||
|
p1ExpectedToBeSummoned = false;
|
||||||
|
args.FoundMatch(false);
|
||||||
|
args.WindowName(L"three");
|
||||||
|
m0->SummonWindow(args);
|
||||||
|
VERIFY_IS_FALSE(args.FoundMatch());
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemotingTests::TestSummonNamedDeadWindow()
|
||||||
|
{
|
||||||
|
Log::Comment(L"Attempt to summon a dead window by name. This will fail, but not crash.");
|
||||||
|
|
||||||
|
const auto monarch0PID = 12345u;
|
||||||
|
const auto peasant1PID = 23456u;
|
||||||
|
const auto peasant2PID = 34567u;
|
||||||
|
|
||||||
|
com_ptr<Remoting::implementation::Monarch> m0;
|
||||||
|
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||||
|
|
||||||
|
com_ptr<Remoting::implementation::Peasant> p1;
|
||||||
|
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||||
|
|
||||||
|
com_ptr<Remoting::implementation::Peasant> p2;
|
||||||
|
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||||
|
|
||||||
|
VERIFY_IS_NOT_NULL(m0);
|
||||||
|
VERIFY_IS_NOT_NULL(p1);
|
||||||
|
VERIFY_IS_NOT_NULL(p2);
|
||||||
|
p1->WindowName(L"one");
|
||||||
|
p2->WindowName(L"two");
|
||||||
|
|
||||||
|
VERIFY_ARE_EQUAL(0, p1->GetID());
|
||||||
|
VERIFY_ARE_EQUAL(0, p2->GetID());
|
||||||
|
|
||||||
|
m0->AddPeasant(*p1);
|
||||||
|
m0->AddPeasant(*p2);
|
||||||
|
|
||||||
|
VERIFY_ARE_EQUAL(1, p1->GetID());
|
||||||
|
VERIFY_ARE_EQUAL(2, p2->GetID());
|
||||||
|
|
||||||
|
VERIFY_ARE_EQUAL(2u, m0->_peasants.size());
|
||||||
|
|
||||||
|
bool p1ExpectedToBeSummoned = false;
|
||||||
|
bool p2ExpectedToBeSummoned = false;
|
||||||
|
|
||||||
|
p1->SummonRequested([&](auto&&, auto&&) {
|
||||||
|
Log::Comment(L"p1 summoned");
|
||||||
|
VERIFY_IS_TRUE(p1ExpectedToBeSummoned);
|
||||||
|
});
|
||||||
|
p2->SummonRequested([&](auto&&, auto&&) {
|
||||||
|
Log::Comment(L"p2 summoned");
|
||||||
|
VERIFY_IS_TRUE(p2ExpectedToBeSummoned);
|
||||||
|
});
|
||||||
|
|
||||||
|
Remoting::SummonWindowSelectionArgs args;
|
||||||
|
|
||||||
|
Log::Comment(L"Summon window two by name");
|
||||||
|
p2ExpectedToBeSummoned = true;
|
||||||
|
args.WindowName(L"two");
|
||||||
|
m0->SummonWindow(args);
|
||||||
|
VERIFY_IS_TRUE(args.FoundMatch());
|
||||||
|
|
||||||
|
Log::Comment(L"Summon window one by name");
|
||||||
|
p2ExpectedToBeSummoned = false;
|
||||||
|
p1ExpectedToBeSummoned = true;
|
||||||
|
args.FoundMatch(false);
|
||||||
|
args.WindowName(L"one");
|
||||||
|
m0->SummonWindow(args);
|
||||||
|
VERIFY_IS_TRUE(args.FoundMatch());
|
||||||
|
|
||||||
|
Log::Comment(L"Kill peasant one.");
|
||||||
|
RemotingTests::_killPeasant(m0, p1->GetID());
|
||||||
|
|
||||||
|
Log::Comment(L"Fail to summon window one by name");
|
||||||
|
p1ExpectedToBeSummoned = false;
|
||||||
|
args.FoundMatch(false);
|
||||||
|
args.WindowName(L"one");
|
||||||
|
m0->SummonWindow(args);
|
||||||
|
VERIFY_IS_FALSE(args.FoundMatch());
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemotingTests::TestSummonMostRecentDeadWindow()
|
||||||
|
{
|
||||||
|
Log::Comment(L"Attempt to summon the MRU window, when the MRU window "
|
||||||
|
L"has died. This will fall back to the next MRU window.");
|
||||||
|
|
||||||
|
const winrt::guid guid1{ Utils::GuidFromString(L"{11111111-1111-1111-1111-111111111111}") };
|
||||||
|
|
||||||
|
const auto monarch0PID = 12345u;
|
||||||
|
const auto peasant1PID = 23456u;
|
||||||
|
const auto peasant2PID = 34567u;
|
||||||
|
|
||||||
|
com_ptr<Remoting::implementation::Monarch> m0;
|
||||||
|
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||||
|
|
||||||
|
com_ptr<Remoting::implementation::Peasant> p1;
|
||||||
|
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||||
|
|
||||||
|
com_ptr<Remoting::implementation::Peasant> p2;
|
||||||
|
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||||
|
|
||||||
|
VERIFY_IS_NOT_NULL(m0);
|
||||||
|
VERIFY_IS_NOT_NULL(p1);
|
||||||
|
VERIFY_IS_NOT_NULL(p2);
|
||||||
|
p1->WindowName(L"one");
|
||||||
|
p2->WindowName(L"two");
|
||||||
|
|
||||||
|
VERIFY_ARE_EQUAL(0, p1->GetID());
|
||||||
|
VERIFY_ARE_EQUAL(0, p2->GetID());
|
||||||
|
|
||||||
|
m0->AddPeasant(*p1);
|
||||||
|
m0->AddPeasant(*p2);
|
||||||
|
|
||||||
|
VERIFY_ARE_EQUAL(1, p1->GetID());
|
||||||
|
VERIFY_ARE_EQUAL(2, p2->GetID());
|
||||||
|
|
||||||
|
VERIFY_ARE_EQUAL(2u, m0->_peasants.size());
|
||||||
|
|
||||||
|
bool p1ExpectedToBeSummoned = false;
|
||||||
|
bool p2ExpectedToBeSummoned = false;
|
||||||
|
|
||||||
|
p1->SummonRequested([&](auto&&, auto&&) {
|
||||||
|
Log::Comment(L"p1 summoned");
|
||||||
|
VERIFY_IS_TRUE(p1ExpectedToBeSummoned);
|
||||||
|
});
|
||||||
|
p2->SummonRequested([&](auto&&, auto&&) {
|
||||||
|
Log::Comment(L"p2 summoned");
|
||||||
|
VERIFY_IS_TRUE(p2ExpectedToBeSummoned);
|
||||||
|
});
|
||||||
|
|
||||||
|
{
|
||||||
|
Log::Comment(L"Activate the first peasant, first desktop");
|
||||||
|
Remoting::WindowActivatedArgs activatedArgs{ p1->GetID(),
|
||||||
|
guid1,
|
||||||
|
winrt::clock().now() };
|
||||||
|
p1->ActivateWindow(activatedArgs);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Log::Comment(L"Activate the second peasant, first desktop");
|
||||||
|
Remoting::WindowActivatedArgs activatedArgs{ p2->GetID(),
|
||||||
|
guid1,
|
||||||
|
winrt::clock().now() };
|
||||||
|
p2->ActivateWindow(activatedArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
p2ExpectedToBeSummoned = true;
|
||||||
|
Remoting::SummonWindowSelectionArgs args;
|
||||||
|
// Without setting the WindowName, SummonWindowSelectionArgs defaults to
|
||||||
|
// the MRU window
|
||||||
|
Log::Comment(L"Summon the MRU window, which is window two");
|
||||||
|
m0->SummonWindow(args);
|
||||||
|
VERIFY_IS_TRUE(args.FoundMatch());
|
||||||
|
|
||||||
|
{
|
||||||
|
Log::Comment(L"Activate the first peasant, first desktop");
|
||||||
|
Remoting::WindowActivatedArgs activatedArgs{ p1->GetID(),
|
||||||
|
guid1,
|
||||||
|
winrt::clock().now() };
|
||||||
|
p1->ActivateWindow(activatedArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::Comment(L"Now that one is the MRU, summon it");
|
||||||
|
p2ExpectedToBeSummoned = false;
|
||||||
|
p1ExpectedToBeSummoned = true;
|
||||||
|
args.FoundMatch(false);
|
||||||
|
m0->SummonWindow(args);
|
||||||
|
VERIFY_IS_TRUE(args.FoundMatch());
|
||||||
|
|
||||||
|
Log::Comment(L"Kill peasant one.");
|
||||||
|
RemotingTests::_killPeasant(m0, p1->GetID());
|
||||||
|
|
||||||
|
Log::Comment(L"We now expect to summon two, since the MRU peasant (one) is actually dead.");
|
||||||
|
p2ExpectedToBeSummoned = true;
|
||||||
|
p1ExpectedToBeSummoned = false;
|
||||||
|
args.FoundMatch(false);
|
||||||
|
m0->SummonWindow(args);
|
||||||
|
VERIFY_IS_TRUE(args.FoundMatch());
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemotingTests::TestSummonOnCurrent()
|
||||||
|
{
|
||||||
|
Log::Comment(L"Tests summoning a window, using OnCurrentDesktop to only"
|
||||||
|
L"select windows on the current desktop.");
|
||||||
|
|
||||||
|
const winrt::guid guid1{ Utils::GuidFromString(L"{11111111-1111-1111-1111-111111111111}") };
|
||||||
|
const winrt::guid guid2{ Utils::GuidFromString(L"{22222222-2222-2222-2222-222222222222}") };
|
||||||
|
|
||||||
|
constexpr auto monarch0PID = 12345u;
|
||||||
|
constexpr auto peasant1PID = 23456u;
|
||||||
|
constexpr auto peasant2PID = 34567u;
|
||||||
|
constexpr auto peasant3PID = 45678u;
|
||||||
|
|
||||||
|
com_ptr<Remoting::implementation::Monarch> m0;
|
||||||
|
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||||
|
|
||||||
|
com_ptr<Remoting::implementation::Peasant> p1;
|
||||||
|
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||||
|
|
||||||
|
com_ptr<Remoting::implementation::Peasant> p2;
|
||||||
|
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||||
|
|
||||||
|
com_ptr<Remoting::implementation::Peasant> p3;
|
||||||
|
p3.attach(new Remoting::implementation::Peasant(peasant3PID));
|
||||||
|
|
||||||
|
VERIFY_IS_NOT_NULL(m0);
|
||||||
|
VERIFY_IS_NOT_NULL(p1);
|
||||||
|
VERIFY_IS_NOT_NULL(p2);
|
||||||
|
VERIFY_IS_NOT_NULL(p3);
|
||||||
|
p1->WindowName(L"one");
|
||||||
|
p2->WindowName(L"two");
|
||||||
|
p3->WindowName(L"three");
|
||||||
|
|
||||||
|
VERIFY_ARE_EQUAL(0, p1->GetID());
|
||||||
|
VERIFY_ARE_EQUAL(0, p2->GetID());
|
||||||
|
VERIFY_ARE_EQUAL(0, p3->GetID());
|
||||||
|
|
||||||
|
m0->AddPeasant(*p1);
|
||||||
|
m0->AddPeasant(*p2);
|
||||||
|
m0->AddPeasant(*p3);
|
||||||
|
|
||||||
|
VERIFY_ARE_EQUAL(1, p1->GetID());
|
||||||
|
VERIFY_ARE_EQUAL(2, p2->GetID());
|
||||||
|
VERIFY_ARE_EQUAL(3, p3->GetID());
|
||||||
|
|
||||||
|
VERIFY_ARE_EQUAL(3u, m0->_peasants.size());
|
||||||
|
|
||||||
|
bool p1ExpectedToBeSummoned = false;
|
||||||
|
bool p2ExpectedToBeSummoned = false;
|
||||||
|
bool p3ExpectedToBeSummoned = false;
|
||||||
|
|
||||||
|
p1->SummonRequested([&](auto&&, auto&&) {
|
||||||
|
Log::Comment(L"p1 summoned");
|
||||||
|
VERIFY_IS_TRUE(p1ExpectedToBeSummoned);
|
||||||
|
});
|
||||||
|
p2->SummonRequested([&](auto&&, auto&&) {
|
||||||
|
Log::Comment(L"p2 summoned");
|
||||||
|
VERIFY_IS_TRUE(p2ExpectedToBeSummoned);
|
||||||
|
});
|
||||||
|
p3->SummonRequested([&](auto&&, auto&&) {
|
||||||
|
Log::Comment(L"p3 summoned");
|
||||||
|
VERIFY_IS_TRUE(p3ExpectedToBeSummoned);
|
||||||
|
});
|
||||||
|
|
||||||
|
{
|
||||||
|
Log::Comment(L"Activate the first peasant, first desktop");
|
||||||
|
Remoting::WindowActivatedArgs activatedArgs{ p1->GetID(),
|
||||||
|
p1->GetPID(), // USE PID as HWND, because these values don't _really_ matter
|
||||||
|
guid1,
|
||||||
|
winrt::clock().now() };
|
||||||
|
p1->ActivateWindow(activatedArgs);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Log::Comment(L"Activate the second peasant, second desktop");
|
||||||
|
Remoting::WindowActivatedArgs activatedArgs{ p2->GetID(),
|
||||||
|
p2->GetPID(), // USE PID as HWND, because these values don't _really_ matter
|
||||||
|
guid2,
|
||||||
|
winrt::clock().now() };
|
||||||
|
p2->ActivateWindow(activatedArgs);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Log::Comment(L"Activate the third peasant, first desktop");
|
||||||
|
Remoting::WindowActivatedArgs activatedArgs{ p3->GetID(),
|
||||||
|
p3->GetPID(), // USE PID as HWND, because these values don't _really_ matter
|
||||||
|
guid1,
|
||||||
|
winrt::clock().now() };
|
||||||
|
p3->ActivateWindow(activatedArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::Comment(L"Create a mock IVirtualDesktopManager to handle checking if a window is on a given desktop");
|
||||||
|
winrt::com_ptr<MockDesktopManager> manager;
|
||||||
|
manager.attach(new MockDesktopManager());
|
||||||
|
m0->_desktopManager = manager.try_as<IVirtualDesktopManager>();
|
||||||
|
|
||||||
|
auto firstCallback = [&](HWND h, BOOL* result) -> HRESULT {
|
||||||
|
Log::Comment(L"firstCallback: Checking if window is on desktop 1");
|
||||||
|
|
||||||
|
const uint64_t hwnd = reinterpret_cast<uint64_t>(h);
|
||||||
|
if (hwnd == peasant1PID || hwnd == peasant3PID)
|
||||||
|
{
|
||||||
|
*result = true;
|
||||||
|
}
|
||||||
|
else if (hwnd == peasant2PID)
|
||||||
|
{
|
||||||
|
*result = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VERIFY_IS_TRUE(false, L"IsWindowOnCurrentVirtualDesktop called with unexpected value");
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
};
|
||||||
|
manager->pfnIsWindowOnCurrentVirtualDesktop = firstCallback;
|
||||||
|
|
||||||
|
Remoting::SummonWindowSelectionArgs args;
|
||||||
|
|
||||||
|
Log::Comment(L"Summon window three - it is the MRU on desktop 1");
|
||||||
|
p3ExpectedToBeSummoned = true;
|
||||||
|
args.OnCurrentDesktop(true);
|
||||||
|
m0->SummonWindow(args);
|
||||||
|
VERIFY_IS_TRUE(args.FoundMatch());
|
||||||
|
|
||||||
|
{
|
||||||
|
Log::Comment(L"Activate the first peasant, first desktop");
|
||||||
|
Remoting::WindowActivatedArgs activatedArgs{ p1->GetID(),
|
||||||
|
p1->GetPID(), // USE PID as HWND, because these values don't _really_ matter
|
||||||
|
guid1,
|
||||||
|
winrt::clock().now() };
|
||||||
|
p1->ActivateWindow(activatedArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::Comment(L"Summon window one - it is the MRU on desktop 1");
|
||||||
|
p1ExpectedToBeSummoned = true;
|
||||||
|
p2ExpectedToBeSummoned = false;
|
||||||
|
p3ExpectedToBeSummoned = false;
|
||||||
|
args.FoundMatch(false);
|
||||||
|
args.OnCurrentDesktop(true);
|
||||||
|
m0->SummonWindow(args);
|
||||||
|
VERIFY_IS_TRUE(args.FoundMatch());
|
||||||
|
|
||||||
|
Log::Comment(L"Now we'll pretend we switched to desktop 2");
|
||||||
|
|
||||||
|
auto secondCallback = [&](HWND h, BOOL* result) -> HRESULT {
|
||||||
|
Log::Comment(L"secondCallback: Checking if window is on desktop 2");
|
||||||
|
const uint64_t hwnd = reinterpret_cast<uint64_t>(h);
|
||||||
|
if (hwnd == peasant1PID || hwnd == peasant3PID)
|
||||||
|
{
|
||||||
|
*result = false;
|
||||||
|
}
|
||||||
|
else if (hwnd == peasant2PID)
|
||||||
|
{
|
||||||
|
*result = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VERIFY_IS_TRUE(false, L"IsWindowOnCurrentVirtualDesktop called with unexpected value");
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
};
|
||||||
|
manager->pfnIsWindowOnCurrentVirtualDesktop = secondCallback;
|
||||||
|
|
||||||
|
Log::Comment(L"Summon window one - it is the MRU on desktop 2");
|
||||||
|
p1ExpectedToBeSummoned = false;
|
||||||
|
p2ExpectedToBeSummoned = true;
|
||||||
|
p3ExpectedToBeSummoned = false;
|
||||||
|
args.FoundMatch(false);
|
||||||
|
args.OnCurrentDesktop(true);
|
||||||
|
m0->SummonWindow(args);
|
||||||
|
VERIFY_IS_TRUE(args.FoundMatch());
|
||||||
|
|
||||||
|
{
|
||||||
|
Log::Comment(L"Activate the third peasant, second desktop");
|
||||||
|
Remoting::WindowActivatedArgs activatedArgs{ p3->GetID(),
|
||||||
|
p3->GetPID(), // USE PID as HWND, because these values don't _really_ matter
|
||||||
|
guid2,
|
||||||
|
winrt::clock().now() };
|
||||||
|
p3->ActivateWindow(activatedArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto thirdCallback = [&](HWND h, BOOL* result) -> HRESULT {
|
||||||
|
Log::Comment(L"thirdCallback: Checking if window is on desktop 2. (windows 2 and 3 are)");
|
||||||
|
const uint64_t hwnd = reinterpret_cast<uint64_t>(h);
|
||||||
|
if (hwnd == peasant1PID)
|
||||||
|
{
|
||||||
|
*result = false;
|
||||||
|
}
|
||||||
|
else if (hwnd == peasant2PID || hwnd == peasant3PID)
|
||||||
|
{
|
||||||
|
*result = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VERIFY_IS_TRUE(false, L"IsWindowOnCurrentVirtualDesktop called with unexpected value");
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
};
|
||||||
|
manager->pfnIsWindowOnCurrentVirtualDesktop = thirdCallback;
|
||||||
|
|
||||||
|
Log::Comment(L"Summon window three - it is the MRU on desktop 2");
|
||||||
|
p1ExpectedToBeSummoned = false;
|
||||||
|
p2ExpectedToBeSummoned = false;
|
||||||
|
p3ExpectedToBeSummoned = true;
|
||||||
|
args.FoundMatch(false);
|
||||||
|
args.OnCurrentDesktop(true);
|
||||||
|
m0->SummonWindow(args);
|
||||||
|
VERIFY_IS_TRUE(args.FoundMatch());
|
||||||
|
|
||||||
|
Log::Comment(L"Now we'll pretend we switched to desktop 1");
|
||||||
|
|
||||||
|
auto fourthCallback = [&](HWND h, BOOL* result) -> HRESULT {
|
||||||
|
Log::Comment(L"fourthCallback: Checking if window is on desktop 1. (window 1 is)");
|
||||||
|
const uint64_t hwnd = reinterpret_cast<uint64_t>(h);
|
||||||
|
if (hwnd == peasant1PID)
|
||||||
|
{
|
||||||
|
*result = true;
|
||||||
|
}
|
||||||
|
else if (hwnd == peasant2PID || hwnd == peasant3PID)
|
||||||
|
{
|
||||||
|
*result = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VERIFY_IS_TRUE(false, L"IsWindowOnCurrentVirtualDesktop called with unexpected value");
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
};
|
||||||
|
manager->pfnIsWindowOnCurrentVirtualDesktop = fourthCallback;
|
||||||
|
|
||||||
|
Log::Comment(L"Summon window one - it is the only window on desktop 1");
|
||||||
|
p1ExpectedToBeSummoned = true;
|
||||||
|
p2ExpectedToBeSummoned = false;
|
||||||
|
p3ExpectedToBeSummoned = false;
|
||||||
|
args.FoundMatch(false);
|
||||||
|
args.OnCurrentDesktop(true);
|
||||||
|
m0->SummonWindow(args);
|
||||||
|
VERIFY_IS_TRUE(args.FoundMatch());
|
||||||
|
|
||||||
|
Log::Comment(L"Now we'll pretend we switched to desktop 3");
|
||||||
|
|
||||||
|
auto fifthCallback = [&](HWND h, BOOL* result) -> HRESULT {
|
||||||
|
Log::Comment(L"fifthCallback: Checking if window is on desktop 3. (none are)");
|
||||||
|
const uint64_t hwnd = reinterpret_cast<uint64_t>(h);
|
||||||
|
if (hwnd == peasant1PID || hwnd == peasant2PID || hwnd == peasant3PID)
|
||||||
|
{
|
||||||
|
*result = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VERIFY_IS_TRUE(false, L"IsWindowOnCurrentVirtualDesktop called with unexpected value");
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
};
|
||||||
|
manager->pfnIsWindowOnCurrentVirtualDesktop = fifthCallback;
|
||||||
|
|
||||||
|
Log::Comment(L"This summon won't find a window.");
|
||||||
|
p1ExpectedToBeSummoned = false;
|
||||||
|
p2ExpectedToBeSummoned = false;
|
||||||
|
p3ExpectedToBeSummoned = false;
|
||||||
|
args.FoundMatch(false);
|
||||||
|
args.OnCurrentDesktop(true);
|
||||||
|
m0->SummonWindow(args);
|
||||||
|
VERIFY_IS_FALSE(args.FoundMatch());
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemotingTests::TestSummonOnCurrentWithName()
|
||||||
|
{
|
||||||
|
Log::Comment(L"Test that specifying a WindowName forces us to ignore OnCurrentDesktop");
|
||||||
|
|
||||||
|
const winrt::guid guid1{ Utils::GuidFromString(L"{11111111-1111-1111-1111-111111111111}") };
|
||||||
|
const winrt::guid guid2{ Utils::GuidFromString(L"{22222222-2222-2222-2222-222222222222}") };
|
||||||
|
|
||||||
|
constexpr auto monarch0PID = 12345u;
|
||||||
|
constexpr auto peasant1PID = 23456u;
|
||||||
|
constexpr auto peasant2PID = 34567u;
|
||||||
|
constexpr auto peasant3PID = 45678u;
|
||||||
|
|
||||||
|
com_ptr<Remoting::implementation::Monarch> m0;
|
||||||
|
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||||
|
|
||||||
|
com_ptr<Remoting::implementation::Peasant> p1;
|
||||||
|
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||||
|
|
||||||
|
com_ptr<Remoting::implementation::Peasant> p2;
|
||||||
|
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||||
|
|
||||||
|
com_ptr<Remoting::implementation::Peasant> p3;
|
||||||
|
p3.attach(new Remoting::implementation::Peasant(peasant3PID));
|
||||||
|
|
||||||
|
VERIFY_IS_NOT_NULL(m0);
|
||||||
|
VERIFY_IS_NOT_NULL(p1);
|
||||||
|
VERIFY_IS_NOT_NULL(p2);
|
||||||
|
VERIFY_IS_NOT_NULL(p3);
|
||||||
|
p1->WindowName(L"one");
|
||||||
|
p2->WindowName(L"two");
|
||||||
|
p3->WindowName(L"three");
|
||||||
|
|
||||||
|
VERIFY_ARE_EQUAL(0, p1->GetID());
|
||||||
|
VERIFY_ARE_EQUAL(0, p2->GetID());
|
||||||
|
VERIFY_ARE_EQUAL(0, p3->GetID());
|
||||||
|
|
||||||
|
m0->AddPeasant(*p1);
|
||||||
|
m0->AddPeasant(*p2);
|
||||||
|
m0->AddPeasant(*p3);
|
||||||
|
|
||||||
|
VERIFY_ARE_EQUAL(1, p1->GetID());
|
||||||
|
VERIFY_ARE_EQUAL(2, p2->GetID());
|
||||||
|
VERIFY_ARE_EQUAL(3, p3->GetID());
|
||||||
|
|
||||||
|
VERIFY_ARE_EQUAL(3u, m0->_peasants.size());
|
||||||
|
|
||||||
|
bool p1ExpectedToBeSummoned = false;
|
||||||
|
bool p2ExpectedToBeSummoned = false;
|
||||||
|
bool p3ExpectedToBeSummoned = false;
|
||||||
|
|
||||||
|
p1->SummonRequested([&](auto&&, auto&&) {
|
||||||
|
Log::Comment(L"p1 summoned");
|
||||||
|
VERIFY_IS_TRUE(p1ExpectedToBeSummoned);
|
||||||
|
});
|
||||||
|
p2->SummonRequested([&](auto&&, auto&&) {
|
||||||
|
Log::Comment(L"p2 summoned");
|
||||||
|
VERIFY_IS_TRUE(p2ExpectedToBeSummoned);
|
||||||
|
});
|
||||||
|
p3->SummonRequested([&](auto&&, auto&&) {
|
||||||
|
Log::Comment(L"p3 summoned");
|
||||||
|
VERIFY_IS_TRUE(p3ExpectedToBeSummoned);
|
||||||
|
});
|
||||||
|
|
||||||
|
{
|
||||||
|
Log::Comment(L"Activate the first peasant, first desktop");
|
||||||
|
Remoting::WindowActivatedArgs activatedArgs{ p1->GetID(),
|
||||||
|
p1->GetPID(), // USE PID as HWND, because these values don't _really_ matter
|
||||||
|
guid1,
|
||||||
|
winrt::clock().now() };
|
||||||
|
p1->ActivateWindow(activatedArgs);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Log::Comment(L"Activate the second peasant, second desktop");
|
||||||
|
Remoting::WindowActivatedArgs activatedArgs{ p2->GetID(),
|
||||||
|
p2->GetPID(), // USE PID as HWND, because these values don't _really_ matter
|
||||||
|
guid2,
|
||||||
|
winrt::clock().now() };
|
||||||
|
p2->ActivateWindow(activatedArgs);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Log::Comment(L"Activate the third peasant, first desktop");
|
||||||
|
Remoting::WindowActivatedArgs activatedArgs{ p3->GetID(),
|
||||||
|
p3->GetPID(), // USE PID as HWND, because these values don't _really_ matter
|
||||||
|
guid1,
|
||||||
|
winrt::clock().now() };
|
||||||
|
p3->ActivateWindow(activatedArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::Comment(L"Create a mock IVirtualDesktopManager to handle checking if a window is on a given desktop");
|
||||||
|
winrt::com_ptr<MockDesktopManager> manager;
|
||||||
|
manager.attach(new MockDesktopManager());
|
||||||
|
m0->_desktopManager = manager.try_as<IVirtualDesktopManager>();
|
||||||
|
|
||||||
|
auto firstCallback = [&](HWND h, BOOL* result) -> HRESULT {
|
||||||
|
Log::Comment(L"firstCallback: Checking if window is on desktop 1");
|
||||||
|
|
||||||
|
const uint64_t hwnd = reinterpret_cast<uint64_t>(h);
|
||||||
|
if (hwnd == peasant1PID || hwnd == peasant3PID)
|
||||||
|
{
|
||||||
|
*result = true;
|
||||||
|
}
|
||||||
|
else if (hwnd == peasant2PID)
|
||||||
|
{
|
||||||
|
*result = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VERIFY_IS_TRUE(false, L"IsWindowOnCurrentVirtualDesktop called with unexpected value");
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
};
|
||||||
|
manager->pfnIsWindowOnCurrentVirtualDesktop = firstCallback;
|
||||||
|
|
||||||
|
Remoting::SummonWindowSelectionArgs args;
|
||||||
|
|
||||||
|
Log::Comment(L"Summon window three - it is the MRU on desktop 1");
|
||||||
|
p3ExpectedToBeSummoned = true;
|
||||||
|
args.OnCurrentDesktop(true);
|
||||||
|
m0->SummonWindow(args);
|
||||||
|
VERIFY_IS_TRUE(args.FoundMatch());
|
||||||
|
|
||||||
|
Log::Comment(L"Look for window 1 by name. When given a name, we don't care about OnCurrentDesktop.");
|
||||||
|
p1ExpectedToBeSummoned = true;
|
||||||
|
p2ExpectedToBeSummoned = false;
|
||||||
|
p3ExpectedToBeSummoned = false;
|
||||||
|
args.FoundMatch(false);
|
||||||
|
args.WindowName(L"one");
|
||||||
|
args.OnCurrentDesktop(true);
|
||||||
|
m0->SummonWindow(args);
|
||||||
|
VERIFY_IS_TRUE(args.FoundMatch());
|
||||||
|
|
||||||
|
Log::Comment(L"Look for window 2 by name. When given a name, we don't care about OnCurrentDesktop.");
|
||||||
|
p1ExpectedToBeSummoned = false;
|
||||||
|
p2ExpectedToBeSummoned = true;
|
||||||
|
p3ExpectedToBeSummoned = false;
|
||||||
|
args.FoundMatch(false);
|
||||||
|
args.WindowName(L"two");
|
||||||
|
args.OnCurrentDesktop(true);
|
||||||
|
m0->SummonWindow(args);
|
||||||
|
VERIFY_IS_TRUE(args.FoundMatch());
|
||||||
|
|
||||||
|
Log::Comment(L"Look for window 3 by name. When given a name, we don't care about OnCurrentDesktop.");
|
||||||
|
p1ExpectedToBeSummoned = false;
|
||||||
|
p2ExpectedToBeSummoned = false;
|
||||||
|
p3ExpectedToBeSummoned = true;
|
||||||
|
args.FoundMatch(false);
|
||||||
|
args.WindowName(L"three");
|
||||||
|
args.OnCurrentDesktop(true);
|
||||||
|
m0->SummonWindow(args);
|
||||||
|
VERIFY_IS_TRUE(args.FoundMatch());
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemotingTests::TestSummonOnCurrentDeadWindow()
|
||||||
|
{
|
||||||
|
Log::Comment(L"Test that we can summon a window on the current desktop,"
|
||||||
|
L" when the MRU window on that desktop dies.");
|
||||||
|
|
||||||
|
const winrt::guid guid1{ Utils::GuidFromString(L"{11111111-1111-1111-1111-111111111111}") };
|
||||||
|
const winrt::guid guid2{ Utils::GuidFromString(L"{22222222-2222-2222-2222-222222222222}") };
|
||||||
|
|
||||||
|
constexpr auto monarch0PID = 12345u;
|
||||||
|
constexpr auto peasant1PID = 23456u;
|
||||||
|
constexpr auto peasant2PID = 34567u;
|
||||||
|
constexpr auto peasant3PID = 45678u;
|
||||||
|
|
||||||
|
com_ptr<Remoting::implementation::Monarch> m0;
|
||||||
|
m0.attach(new Remoting::implementation::Monarch(monarch0PID));
|
||||||
|
|
||||||
|
com_ptr<Remoting::implementation::Peasant> p1;
|
||||||
|
p1.attach(new Remoting::implementation::Peasant(peasant1PID));
|
||||||
|
|
||||||
|
com_ptr<Remoting::implementation::Peasant> p2;
|
||||||
|
p2.attach(new Remoting::implementation::Peasant(peasant2PID));
|
||||||
|
|
||||||
|
com_ptr<Remoting::implementation::Peasant> p3;
|
||||||
|
p3.attach(new Remoting::implementation::Peasant(peasant3PID));
|
||||||
|
|
||||||
|
VERIFY_IS_NOT_NULL(m0);
|
||||||
|
VERIFY_IS_NOT_NULL(p1);
|
||||||
|
VERIFY_IS_NOT_NULL(p2);
|
||||||
|
VERIFY_IS_NOT_NULL(p3);
|
||||||
|
p1->WindowName(L"one");
|
||||||
|
p2->WindowName(L"two");
|
||||||
|
p3->WindowName(L"three");
|
||||||
|
|
||||||
|
VERIFY_ARE_EQUAL(0, p1->GetID());
|
||||||
|
VERIFY_ARE_EQUAL(0, p2->GetID());
|
||||||
|
VERIFY_ARE_EQUAL(0, p3->GetID());
|
||||||
|
|
||||||
|
m0->AddPeasant(*p1);
|
||||||
|
m0->AddPeasant(*p2);
|
||||||
|
m0->AddPeasant(*p3);
|
||||||
|
|
||||||
|
VERIFY_ARE_EQUAL(1, p1->GetID());
|
||||||
|
VERIFY_ARE_EQUAL(2, p2->GetID());
|
||||||
|
VERIFY_ARE_EQUAL(3, p3->GetID());
|
||||||
|
|
||||||
|
VERIFY_ARE_EQUAL(3u, m0->_peasants.size());
|
||||||
|
|
||||||
|
bool p1ExpectedToBeSummoned = false;
|
||||||
|
bool p2ExpectedToBeSummoned = false;
|
||||||
|
bool p3ExpectedToBeSummoned = false;
|
||||||
|
|
||||||
|
p1->SummonRequested([&](auto&&, auto&&) {
|
||||||
|
Log::Comment(L"p1 summoned");
|
||||||
|
VERIFY_IS_TRUE(p1ExpectedToBeSummoned);
|
||||||
|
});
|
||||||
|
p2->SummonRequested([&](auto&&, auto&&) {
|
||||||
|
Log::Comment(L"p2 summoned");
|
||||||
|
VERIFY_IS_TRUE(p2ExpectedToBeSummoned);
|
||||||
|
});
|
||||||
|
p3->SummonRequested([&](auto&&, auto&&) {
|
||||||
|
Log::Comment(L"p3 summoned");
|
||||||
|
VERIFY_IS_TRUE(p3ExpectedToBeSummoned);
|
||||||
|
});
|
||||||
|
|
||||||
|
{
|
||||||
|
Log::Comment(L"Activate the first peasant, first desktop");
|
||||||
|
Remoting::WindowActivatedArgs activatedArgs{ p1->GetID(),
|
||||||
|
p1->GetPID(), // USE PID as HWND, because these values don't _really_ matter
|
||||||
|
guid1,
|
||||||
|
winrt::clock().now() };
|
||||||
|
p1->ActivateWindow(activatedArgs);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Log::Comment(L"Activate the second peasant, second desktop");
|
||||||
|
Remoting::WindowActivatedArgs activatedArgs{ p2->GetID(),
|
||||||
|
p2->GetPID(), // USE PID as HWND, because these values don't _really_ matter
|
||||||
|
guid2,
|
||||||
|
winrt::clock().now() };
|
||||||
|
p2->ActivateWindow(activatedArgs);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Log::Comment(L"Activate the third peasant, first desktop");
|
||||||
|
Remoting::WindowActivatedArgs activatedArgs{ p3->GetID(),
|
||||||
|
p3->GetPID(), // USE PID as HWND, because these values don't _really_ matter
|
||||||
|
guid1,
|
||||||
|
winrt::clock().now() };
|
||||||
|
p3->ActivateWindow(activatedArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::Comment(L"Create a mock IVirtualDesktopManager to handle checking if a window is on a given desktop");
|
||||||
|
winrt::com_ptr<MockDesktopManager> manager;
|
||||||
|
manager.attach(new MockDesktopManager());
|
||||||
|
m0->_desktopManager = manager.try_as<IVirtualDesktopManager>();
|
||||||
|
|
||||||
|
auto firstCallback = [&](HWND h, BOOL* result) -> HRESULT {
|
||||||
|
Log::Comment(L"firstCallback: Checking if window is on desktop 1");
|
||||||
|
|
||||||
|
const uint64_t hwnd = reinterpret_cast<uint64_t>(h);
|
||||||
|
if (hwnd == peasant1PID || hwnd == peasant3PID)
|
||||||
|
{
|
||||||
|
*result = true;
|
||||||
|
}
|
||||||
|
else if (hwnd == peasant2PID)
|
||||||
|
{
|
||||||
|
*result = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VERIFY_IS_TRUE(false, L"IsWindowOnCurrentVirtualDesktop called with unexpected value");
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
};
|
||||||
|
manager->pfnIsWindowOnCurrentVirtualDesktop = firstCallback;
|
||||||
|
|
||||||
|
Remoting::SummonWindowSelectionArgs args;
|
||||||
|
|
||||||
|
Log::Comment(L"Summon window three - it is the MRU on desktop 1");
|
||||||
|
p3ExpectedToBeSummoned = true;
|
||||||
|
args.OnCurrentDesktop(true);
|
||||||
|
m0->SummonWindow(args);
|
||||||
|
VERIFY_IS_TRUE(args.FoundMatch());
|
||||||
|
|
||||||
|
Log::Comment(L"Kill window 3. Window 1 is now the MRU on desktop 1.");
|
||||||
|
RemotingTests::_killPeasant(m0, p3->GetID());
|
||||||
|
|
||||||
|
Log::Comment(L"Summon window three - it is the MRU on desktop 1");
|
||||||
|
p1ExpectedToBeSummoned = true;
|
||||||
|
p2ExpectedToBeSummoned = false;
|
||||||
|
p3ExpectedToBeSummoned = false;
|
||||||
|
args.FoundMatch(false);
|
||||||
|
args.OnCurrentDesktop(true);
|
||||||
|
m0->SummonWindow(args);
|
||||||
|
VERIFY_IS_TRUE(args.FoundMatch());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,9 @@
|
||||||
#include "../types/inc/Viewport.hpp"
|
#include "../types/inc/Viewport.hpp"
|
||||||
#include "../types/inc/utils.hpp"
|
#include "../types/inc/utils.hpp"
|
||||||
#include "../types/inc/User32Utils.hpp"
|
#include "../types/inc/User32Utils.hpp"
|
||||||
|
#include "../WinRTUtils/inc/WtExeUtils.h"
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
|
#include "VirtualDesktopUtils.h"
|
||||||
|
|
||||||
using namespace winrt::Windows::UI;
|
using namespace winrt::Windows::UI;
|
||||||
using namespace winrt::Windows::UI::Composition;
|
using namespace winrt::Windows::UI::Composition;
|
||||||
|
@ -22,6 +24,8 @@ using namespace ::Microsoft::Console::Types;
|
||||||
// "If the high-order bit is 1, the key is down; otherwise, it is up."
|
// "If the high-order bit is 1, the key is down; otherwise, it is up."
|
||||||
static constexpr short KeyPressed{ gsl::narrow_cast<short>(0x8000) };
|
static constexpr short KeyPressed{ gsl::narrow_cast<short>(0x8000) };
|
||||||
|
|
||||||
|
static const wchar_t* const PSEUDO_WINDOW_CLASS = L"PseudoWindow";
|
||||||
|
|
||||||
AppHost::AppHost() noexcept :
|
AppHost::AppHost() noexcept :
|
||||||
_app{},
|
_app{},
|
||||||
_windowManager{},
|
_windowManager{},
|
||||||
|
@ -71,8 +75,15 @@ AppHost::AppHost() noexcept :
|
||||||
std::placeholders::_2));
|
std::placeholders::_2));
|
||||||
_window->MouseScrolled({ this, &AppHost::_WindowMouseWheeled });
|
_window->MouseScrolled({ this, &AppHost::_WindowMouseWheeled });
|
||||||
_window->WindowActivated({ this, &AppHost::_WindowActivated });
|
_window->WindowActivated({ this, &AppHost::_WindowActivated });
|
||||||
|
_window->HotkeyPressed({ this, &AppHost::_GlobalHotkeyPressed });
|
||||||
_window->SetAlwaysOnTop(_logic.GetInitialAlwaysOnTop());
|
_window->SetAlwaysOnTop(_logic.GetInitialAlwaysOnTop());
|
||||||
_window->MakeWindow();
|
_window->MakeWindow();
|
||||||
|
|
||||||
|
_windowManager.BecameMonarch({ this, &AppHost::_BecomeMonarch });
|
||||||
|
if (_windowManager.IsMonarch())
|
||||||
|
{
|
||||||
|
_BecomeMonarch(nullptr, nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AppHost::~AppHost()
|
AppHost::~AppHost()
|
||||||
|
@ -194,6 +205,7 @@ void AppHost::_HandleCommandlineArgs()
|
||||||
// commandline (in the future), it'll trigger this callback, that we'll
|
// commandline (in the future), it'll trigger this callback, that we'll
|
||||||
// use to send the actions to the app.
|
// use to send the actions to the app.
|
||||||
peasant.ExecuteCommandlineRequested({ this, &AppHost::_DispatchCommandline });
|
peasant.ExecuteCommandlineRequested({ this, &AppHost::_DispatchCommandline });
|
||||||
|
peasant.SummonRequested({ this, &AppHost::_HandleSummon });
|
||||||
|
|
||||||
peasant.DisplayWindowIdRequested({ this, &AppHost::_DisplayWindowId });
|
peasant.DisplayWindowIdRequested({ this, &AppHost::_DisplayWindowId });
|
||||||
|
|
||||||
|
@ -251,6 +263,7 @@ void AppHost::Initialize()
|
||||||
_logic.SetTaskbarProgress({ this, &AppHost::SetTaskbarProgress });
|
_logic.SetTaskbarProgress({ this, &AppHost::SetTaskbarProgress });
|
||||||
_logic.IdentifyWindowsRequested({ this, &AppHost::_IdentifyWindowsRequested });
|
_logic.IdentifyWindowsRequested({ this, &AppHost::_IdentifyWindowsRequested });
|
||||||
_logic.RenameWindowRequested({ this, &AppHost::_RenameWindowRequested });
|
_logic.RenameWindowRequested({ this, &AppHost::_RenameWindowRequested });
|
||||||
|
_logic.SettingsChanged({ this, &AppHost::_HandleSettingsChanged });
|
||||||
|
|
||||||
_window->UpdateTitle(_logic.Title());
|
_window->UpdateTitle(_logic.Title());
|
||||||
|
|
||||||
|
@ -555,6 +568,8 @@ bool AppHost::HasWindow()
|
||||||
void AppHost::_DispatchCommandline(winrt::Windows::Foundation::IInspectable /*sender*/,
|
void AppHost::_DispatchCommandline(winrt::Windows::Foundation::IInspectable /*sender*/,
|
||||||
Remoting::CommandlineArgs args)
|
Remoting::CommandlineArgs args)
|
||||||
{
|
{
|
||||||
|
// Summon the window whenever we dispatch a commandline to it. This will
|
||||||
|
// make it obvious when a new tab/pane is created in a window.
|
||||||
_window->SummonWindow();
|
_window->SummonWindow();
|
||||||
_logic.ExecuteCommandline(args.Commandline(), args.CurrentDirectory());
|
_logic.ExecuteCommandline(args.Commandline(), args.CurrentDirectory());
|
||||||
}
|
}
|
||||||
|
@ -596,18 +611,271 @@ winrt::fire_and_forget AppHost::_WindowActivated()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AppHost::_BecomeMonarch(const winrt::Windows::Foundation::IInspectable& /*sender*/,
|
||||||
|
const winrt::Windows::Foundation::IInspectable& /*args*/)
|
||||||
|
{
|
||||||
|
_setupGlobalHotkeys();
|
||||||
|
}
|
||||||
|
|
||||||
|
winrt::fire_and_forget AppHost::_setupGlobalHotkeys()
|
||||||
|
{
|
||||||
|
// The hotkey MUST be registered on the main thread. It will fail otherwise!
|
||||||
|
co_await winrt::resume_foreground(_logic.GetRoot().Dispatcher(),
|
||||||
|
winrt::Windows::UI::Core::CoreDispatcherPriority::Normal);
|
||||||
|
|
||||||
|
// Remove all the already registered hotkeys before setting up the new ones.
|
||||||
|
_window->UnsetHotkeys(_hotkeys);
|
||||||
|
|
||||||
|
_hotkeyActions = _logic.GlobalHotkeys();
|
||||||
|
_hotkeys.clear();
|
||||||
|
for (const auto& [k, v] : _hotkeyActions)
|
||||||
|
{
|
||||||
|
if (k != nullptr)
|
||||||
|
{
|
||||||
|
_hotkeys.push_back(k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_window->SetGlobalHotkeys(_hotkeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method Description:
|
||||||
|
// - Called whenever a registered hotkey is pressed. We'll look up the
|
||||||
|
// GlobalSummonArgs for the specified hotkey, then dispatch a call to the
|
||||||
|
// Monarch with the selection information.
|
||||||
|
// - If the monarch finds a match for the window name (or no name was provided),
|
||||||
|
// it'll set FoundMatch=true.
|
||||||
|
// - If FoundMatch is false, and a name was provided, then we should create a
|
||||||
|
// new window with the given name.
|
||||||
|
// Arguments:
|
||||||
|
// - hotkeyIndex: the index of the entry in _hotkeys that was pressed.
|
||||||
|
// Return Value:
|
||||||
|
// - <none>
|
||||||
|
void AppHost::_GlobalHotkeyPressed(const long hotkeyIndex)
|
||||||
|
{
|
||||||
|
if (hotkeyIndex < 0 || static_cast<size_t>(hotkeyIndex) > _hotkeys.size())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Lookup the matching keychord
|
||||||
|
Control::KeyChord kc = _hotkeys.at(hotkeyIndex);
|
||||||
|
// Get the stored ActionAndArgs for that chord
|
||||||
|
if (const auto& actionAndArgs{ _hotkeyActions.Lookup(kc) })
|
||||||
|
{
|
||||||
|
if (const auto& summonArgs{ actionAndArgs.Args().try_as<Settings::Model::GlobalSummonArgs>() })
|
||||||
|
{
|
||||||
|
Remoting::SummonWindowSelectionArgs args{ summonArgs.Name() };
|
||||||
|
|
||||||
|
// desktop:any - MoveToCurrentDesktop=false, OnCurrentDesktop=false
|
||||||
|
// desktop:toCurrent - MoveToCurrentDesktop=true, OnCurrentDesktop=false
|
||||||
|
// desktop:onCurrent - MoveToCurrentDesktop=false, OnCurrentDesktop=true
|
||||||
|
args.OnCurrentDesktop(summonArgs.Desktop() == Settings::Model::DesktopBehavior::OnCurrent);
|
||||||
|
args.SummonBehavior().MoveToCurrentDesktop(summonArgs.Desktop() == Settings::Model::DesktopBehavior::ToCurrent);
|
||||||
|
|
||||||
|
_windowManager.SummonWindow(args);
|
||||||
|
if (args.FoundMatch())
|
||||||
|
{
|
||||||
|
// Excellent, the window was found. We have nothing else to do here.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We should make the window ourselves.
|
||||||
|
_createNewTerminalWindow(summonArgs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method Description:
|
||||||
|
// - Called when the monarch failed to summon a window for a given set of
|
||||||
|
// SummonWindowSelectionArgs. In this case, we should create the specified
|
||||||
|
// window ourselves.
|
||||||
|
// - This is to support the scenario like `globalSummon(Name="_quake")` being
|
||||||
|
// used to summon the window if it already exists, or create it if it doesn't.
|
||||||
|
// Arguments:
|
||||||
|
// - args: Contains information on how we should name the window
|
||||||
|
// Return Value:
|
||||||
|
// - <none>
|
||||||
|
winrt::fire_and_forget AppHost::_createNewTerminalWindow(Settings::Model::GlobalSummonArgs args)
|
||||||
|
{
|
||||||
|
// Hop to the BG thread
|
||||||
|
co_await winrt::resume_background();
|
||||||
|
|
||||||
|
// This will get us the correct exe for dev/preview/release. If you
|
||||||
|
// don't stick this in a local, it'll get mangled by ShellExecute. I
|
||||||
|
// have no idea why.
|
||||||
|
const auto exePath{ GetWtExePath() };
|
||||||
|
|
||||||
|
// If we weren't given a name, then just use new to force the window to be
|
||||||
|
// unnamed.
|
||||||
|
winrt::hstring cmdline{
|
||||||
|
fmt::format(L"-w {}",
|
||||||
|
args.Name().empty() ? L"new" :
|
||||||
|
args.Name())
|
||||||
|
};
|
||||||
|
// Build the args to ShellExecuteEx. We need to use ShellExecuteEx so we
|
||||||
|
// can pass the SEE_MASK_NOASYNC flag. That flag allows us to safely
|
||||||
|
// call this on the background thread, and have ShellExecute _not_ call
|
||||||
|
// back to us on the main thread. Without this, if you close the
|
||||||
|
// Terminal quickly after the UAC prompt, the elevated WT will never
|
||||||
|
// actually spawn.
|
||||||
|
SHELLEXECUTEINFOW seInfo{ 0 };
|
||||||
|
seInfo.cbSize = sizeof(seInfo);
|
||||||
|
seInfo.fMask = SEE_MASK_NOASYNC;
|
||||||
|
seInfo.lpVerb = L"open";
|
||||||
|
seInfo.lpFile = exePath.c_str();
|
||||||
|
seInfo.lpParameters = cmdline.c_str();
|
||||||
|
seInfo.nShow = SW_SHOWNORMAL;
|
||||||
|
LOG_IF_WIN32_BOOL_FALSE(ShellExecuteExW(&seInfo));
|
||||||
|
|
||||||
|
co_return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method Description:
|
||||||
|
// - Helper to initialize our instance of IVirtualDesktopManager. If we already
|
||||||
|
// got one, then this will just return true. Otherwise, we'll try and init a
|
||||||
|
// new instance of one, and store that.
|
||||||
|
// - This will return false if we weren't able to initialize one, which I'm not
|
||||||
|
// sure is actually possible.
|
||||||
|
// Arguments:
|
||||||
|
// - <none>
|
||||||
|
// Return Value:
|
||||||
|
// - true iff _desktopManager points to a non-null instance of IVirtualDesktopManager
|
||||||
|
bool AppHost::_LazyLoadDesktopManager()
|
||||||
|
{
|
||||||
|
if (_desktopManager == nullptr)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_desktopManager = winrt::create_instance<IVirtualDesktopManager>(__uuidof(VirtualDesktopManager));
|
||||||
|
}
|
||||||
|
CATCH_LOG();
|
||||||
|
}
|
||||||
|
|
||||||
|
return _desktopManager != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static wil::unique_event windowCreated;
|
||||||
|
GUID AppHost::_fakeGetCurrentDesktop()
|
||||||
|
{
|
||||||
|
GUID currentlyActiveDesktop;
|
||||||
|
|
||||||
|
static bool createEvent{ []() {
|
||||||
|
windowCreated.create();
|
||||||
|
return true;
|
||||||
|
}() };
|
||||||
|
static auto fakeWndProc = [](HWND const window, UINT const message, WPARAM const wparam, LPARAM const lparam) -> LRESULT {
|
||||||
|
switch (message)
|
||||||
|
{
|
||||||
|
case WM_SHOWWINDOW:
|
||||||
|
{
|
||||||
|
OutputDebugString(L"WM_SHOWWINDOW\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WM_ACTIVATE:
|
||||||
|
{
|
||||||
|
OutputDebugString(L"WM_ACTIVATE\n");
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WM_CREATE:
|
||||||
|
{
|
||||||
|
OutputDebugString(L"WM_CREATE\n");
|
||||||
|
// PostMessage(window, WM_USER + 100, 0, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WM_USER + 100:
|
||||||
|
{
|
||||||
|
OutputDebugString(L"WM_USER + 100\n");
|
||||||
|
windowCreated.SetEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (message == WM_ACTIVATE)
|
||||||
|
// {
|
||||||
|
// windowCreated.SetEvent();
|
||||||
|
// }
|
||||||
|
return DefWindowProc(window, message, wparam, lparam);
|
||||||
|
};
|
||||||
|
|
||||||
|
// *** magic static ***
|
||||||
|
// Only initialize the psuedo class once over the lifetime of the process
|
||||||
|
static ATOM pseudoClassAtom{ []() {
|
||||||
|
WNDCLASS pseudoClass{ 0 };
|
||||||
|
pseudoClass.lpszClassName = PSEUDO_WINDOW_CLASS;
|
||||||
|
// pseudoClass.lpfnWndProc = DefWindowProc;
|
||||||
|
pseudoClass.lpfnWndProc = fakeWndProc;
|
||||||
|
return RegisterClass(&pseudoClass);
|
||||||
|
}() };
|
||||||
|
|
||||||
|
wil::unique_hwnd hwnd{ CreateWindowExW(0,
|
||||||
|
PSEUDO_WINDOW_CLASS,
|
||||||
|
nullptr,
|
||||||
|
WS_POPUP, //WS_TILED, // WS_CHILD,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
HWND_DESKTOP,
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
nullptr) };
|
||||||
|
|
||||||
|
{
|
||||||
|
// // Attempt 1:
|
||||||
|
// ShowWindow(hwnd.get(), SW_SHOWNORMAL);
|
||||||
|
// Sleep(1); // !! LOAD BEARING !!
|
||||||
|
}
|
||||||
|
|
||||||
|
OutputDebugString(L"after CreateWindowExW");
|
||||||
|
windowCreated.ResetEvent();
|
||||||
|
OutputDebugString(L"after ResetEvent");
|
||||||
|
ShowWindow(hwnd.get(), SW_SHOWNORMAL);
|
||||||
|
// PostMessage(hwnd.get(), WM_USER + 100, 0, 0);
|
||||||
|
WaitForSingleObject(windowCreated.get(), INFINITE);
|
||||||
|
OutputDebugString(L"after WaitForSingleObject");
|
||||||
|
|
||||||
|
{
|
||||||
|
// // Attempt 3
|
||||||
|
// BOOL onCurrent = false;
|
||||||
|
// while (!onCurrent)
|
||||||
|
// {
|
||||||
|
// ShowWindow(hwnd.get(), SW_HIDE);
|
||||||
|
// ShowWindow(hwnd.get(), SW_RESTORE);
|
||||||
|
// _desktopManager->IsWindowOnCurrentVirtualDesktop(hwnd.get(), &onCurrent);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_IF_FAILED(_desktopManager->GetWindowDesktopId(hwnd.get(), ¤tlyActiveDesktop));
|
||||||
|
|
||||||
|
return currentlyActiveDesktop;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppHost::_HandleSummon(const winrt::Windows::Foundation::IInspectable& /*sender*/,
|
||||||
|
const Remoting::SummonWindowBehavior& args)
|
||||||
|
{
|
||||||
|
_window->SummonWindow();
|
||||||
|
|
||||||
|
if (args != nullptr && args.MoveToCurrentDesktop())
|
||||||
|
{
|
||||||
|
if (_LazyLoadDesktopManager())
|
||||||
|
{
|
||||||
|
// GUID currentlyActiveDesktop;
|
||||||
|
// VirtualDesktopUtils::GetCurrentVirtualDesktopId(¤tlyActiveDesktop);
|
||||||
|
auto currentlyActiveDesktop = _fakeGetCurrentDesktop();
|
||||||
|
LOG_IF_FAILED(_desktopManager->MoveWindowToDesktop(_window->GetHandle(), currentlyActiveDesktop));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GUID AppHost::_CurrentDesktopGuid()
|
GUID AppHost::_CurrentDesktopGuid()
|
||||||
{
|
{
|
||||||
GUID currentDesktopGuid{ 0 };
|
GUID currentDesktopGuid{ 0 };
|
||||||
try
|
const auto manager = winrt::create_instance<IVirtualDesktopManager>(__uuidof(VirtualDesktopManager));
|
||||||
|
if (_LazyLoadDesktopManager())
|
||||||
{
|
{
|
||||||
const auto manager = winrt::create_instance<IVirtualDesktopManager>(__uuidof(VirtualDesktopManager));
|
LOG_IF_FAILED(_desktopManager->GetWindowDesktopId(_window->GetHandle(), ¤tDesktopGuid));
|
||||||
if (manager)
|
|
||||||
{
|
|
||||||
LOG_IF_FAILED(manager->GetWindowDesktopId(_window->GetHandle(), ¤tDesktopGuid));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
CATCH_LOG();
|
|
||||||
return currentDesktopGuid;
|
return currentDesktopGuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -674,3 +942,9 @@ winrt::fire_and_forget AppHost::_RenameWindowRequested(const winrt::Windows::Fou
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AppHost::_HandleSettingsChanged(const winrt::Windows::Foundation::IInspectable& /*sender*/,
|
||||||
|
const winrt::Windows::Foundation::IInspectable& /*args*/)
|
||||||
|
{
|
||||||
|
_setupGlobalHotkeys();
|
||||||
|
}
|
||||||
|
|
|
@ -28,6 +28,11 @@ private:
|
||||||
bool _shouldCreateWindow{ false };
|
bool _shouldCreateWindow{ false };
|
||||||
winrt::Microsoft::Terminal::Remoting::WindowManager _windowManager{ nullptr };
|
winrt::Microsoft::Terminal::Remoting::WindowManager _windowManager{ nullptr };
|
||||||
|
|
||||||
|
std::vector<winrt::Microsoft::Terminal::Control::KeyChord> _hotkeys{};
|
||||||
|
winrt::Windows::Foundation::Collections::IMap<winrt::Microsoft::Terminal::Control::KeyChord, winrt::Microsoft::Terminal::Settings::Model::ActionAndArgs> _hotkeyActions{ nullptr };
|
||||||
|
|
||||||
|
winrt::com_ptr<IVirtualDesktopManager> _desktopManager{ nullptr };
|
||||||
|
|
||||||
void _HandleCommandlineArgs();
|
void _HandleCommandlineArgs();
|
||||||
|
|
||||||
void _HandleCreateWindow(const HWND hwnd, RECT proposedRect, winrt::Microsoft::Terminal::Settings::Model::LaunchMode& launchMode);
|
void _HandleCreateWindow(const HWND hwnd, RECT proposedRect, winrt::Microsoft::Terminal::Settings::Model::LaunchMode& launchMode);
|
||||||
|
@ -51,6 +56,13 @@ private:
|
||||||
|
|
||||||
void _FindTargetWindow(const winrt::Windows::Foundation::IInspectable& sender,
|
void _FindTargetWindow(const winrt::Windows::Foundation::IInspectable& sender,
|
||||||
const winrt::Microsoft::Terminal::Remoting::FindTargetWindowArgs& args);
|
const winrt::Microsoft::Terminal::Remoting::FindTargetWindowArgs& args);
|
||||||
|
|
||||||
|
void _BecomeMonarch(const winrt::Windows::Foundation::IInspectable& sender,
|
||||||
|
const winrt::Windows::Foundation::IInspectable& args);
|
||||||
|
void _GlobalHotkeyPressed(const long hotkeyIndex);
|
||||||
|
void _HandleSummon(const winrt::Windows::Foundation::IInspectable& sender,
|
||||||
|
const winrt::Microsoft::Terminal::Remoting::SummonWindowBehavior& args);
|
||||||
|
|
||||||
winrt::fire_and_forget _IdentifyWindowsRequested(const winrt::Windows::Foundation::IInspectable sender,
|
winrt::fire_and_forget _IdentifyWindowsRequested(const winrt::Windows::Foundation::IInspectable sender,
|
||||||
const winrt::Windows::Foundation::IInspectable args);
|
const winrt::Windows::Foundation::IInspectable args);
|
||||||
void _DisplayWindowId(const winrt::Windows::Foundation::IInspectable& sender,
|
void _DisplayWindowId(const winrt::Windows::Foundation::IInspectable& sender,
|
||||||
|
@ -59,4 +71,11 @@ private:
|
||||||
const winrt::TerminalApp::RenameWindowRequestedArgs args);
|
const winrt::TerminalApp::RenameWindowRequestedArgs args);
|
||||||
|
|
||||||
GUID _CurrentDesktopGuid();
|
GUID _CurrentDesktopGuid();
|
||||||
|
bool _LazyLoadDesktopManager();
|
||||||
|
GUID _fakeGetCurrentDesktop();
|
||||||
|
|
||||||
|
winrt::fire_and_forget _setupGlobalHotkeys();
|
||||||
|
winrt::fire_and_forget _createNewTerminalWindow(winrt::Microsoft::Terminal::Settings::Model::GlobalSummonArgs args);
|
||||||
|
void _HandleSettingsChanged(const winrt::Windows::Foundation::IInspectable& sender,
|
||||||
|
const winrt::Windows::Foundation::IInspectable& args);
|
||||||
};
|
};
|
||||||
|
|
|
@ -15,6 +15,7 @@ using namespace winrt::Windows::UI::Xaml;
|
||||||
using namespace winrt::Windows::UI::Xaml::Hosting;
|
using namespace winrt::Windows::UI::Xaml::Hosting;
|
||||||
using namespace winrt::Windows::Foundation::Numerics;
|
using namespace winrt::Windows::Foundation::Numerics;
|
||||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||||
|
using namespace winrt::Microsoft::Terminal::Control;
|
||||||
using namespace ::Microsoft::Console::Types;
|
using namespace ::Microsoft::Console::Types;
|
||||||
|
|
||||||
#define XAML_HOSTING_WINDOW_CLASS_NAME L"CASCADIA_HOSTING_WINDOW_CLASS"
|
#define XAML_HOSTING_WINDOW_CLASS_NAME L"CASCADIA_HOSTING_WINDOW_CLASS"
|
||||||
|
@ -351,6 +352,11 @@ long IslandWindow::_calculateTotalSize(const bool isWidth, const long clientSize
|
||||||
{
|
{
|
||||||
switch (message)
|
switch (message)
|
||||||
{
|
{
|
||||||
|
case WM_HOTKEY:
|
||||||
|
{
|
||||||
|
_HotkeyPressedHandlers(static_cast<long>(wparam));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case WM_GETMINMAXINFO:
|
case WM_GETMINMAXINFO:
|
||||||
{
|
{
|
||||||
_OnGetMinMaxInfo(wparam, lparam);
|
_OnGetMinMaxInfo(wparam, lparam);
|
||||||
|
@ -367,8 +373,9 @@ long IslandWindow::_calculateTotalSize(const bool isWidth, const long clientSize
|
||||||
{
|
{
|
||||||
// send focus to the child window
|
// send focus to the child window
|
||||||
SetFocus(_interopWindowHandle);
|
SetFocus(_interopWindowHandle);
|
||||||
return 0; // eat the message
|
return 0;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case WM_ACTIVATE:
|
case WM_ACTIVATE:
|
||||||
{
|
{
|
||||||
|
@ -895,6 +902,63 @@ void IslandWindow::_SetIsFullscreen(const bool fullscreenEnabled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Method Description:
|
||||||
|
// - Call UnregisterHotKey once for each entry in hotkeyList, to unset all the bound global hotkeys.
|
||||||
|
// Arguments:
|
||||||
|
// - hotkeyList: a list of hotkeys to unbind
|
||||||
|
// Return Value:
|
||||||
|
// - <none>
|
||||||
|
void IslandWindow::UnsetHotkeys(const std::vector<winrt::Microsoft::Terminal::Control::KeyChord>& hotkeyList)
|
||||||
|
{
|
||||||
|
TraceLoggingWrite(g_hWindowsTerminalProvider,
|
||||||
|
"UnsetHotkeys",
|
||||||
|
TraceLoggingDescription("Emitted when clearing previously set hotkeys"),
|
||||||
|
TraceLoggingInt64(hotkeyList.size(), "numHotkeys", "The number of hotkeys to unset"),
|
||||||
|
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE));
|
||||||
|
|
||||||
|
for (int i = 0; i < ::base::saturated_cast<int>(hotkeyList.size()); i++)
|
||||||
|
{
|
||||||
|
LOG_IF_WIN32_BOOL_FALSE(UnregisterHotKey(_window.get(), static_cast<int>(i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method Description:
|
||||||
|
// - Call RegisterHotKey once for each entry in hotkeyList, to attempt to
|
||||||
|
// register that keybinding as a global hotkey.
|
||||||
|
// - When these keys are pressed, we'll get a WM_HOTKEY message with the payload
|
||||||
|
// containing the index we registered here.
|
||||||
|
// Arguments:
|
||||||
|
// - hotkeyList: a list of hotkeys to bind
|
||||||
|
// Return Value:
|
||||||
|
// - <none>
|
||||||
|
void IslandWindow::SetGlobalHotkeys(const std::vector<winrt::Microsoft::Terminal::Control::KeyChord>& hotkeyList)
|
||||||
|
{
|
||||||
|
TraceLoggingWrite(g_hWindowsTerminalProvider,
|
||||||
|
"SetGlobalHotkeys",
|
||||||
|
TraceLoggingDescription("Emitted when setting hotkeys"),
|
||||||
|
TraceLoggingInt64(hotkeyList.size(), "numHotkeys", "The number of hotkeys to set"),
|
||||||
|
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE));
|
||||||
|
int index = 0;
|
||||||
|
for (const auto& hotkey : hotkeyList)
|
||||||
|
{
|
||||||
|
const auto modifiers = hotkey.Modifiers();
|
||||||
|
const auto hotkeyFlags = MOD_NOREPEAT |
|
||||||
|
(WI_IsFlagSet(modifiers, KeyModifiers::Windows) ? MOD_WIN : 0) |
|
||||||
|
(WI_IsFlagSet(modifiers, KeyModifiers::Alt) ? MOD_ALT : 0) |
|
||||||
|
(WI_IsFlagSet(modifiers, KeyModifiers::Ctrl) ? MOD_CONTROL : 0) |
|
||||||
|
(WI_IsFlagSet(modifiers, KeyModifiers::Shift) ? MOD_SHIFT : 0);
|
||||||
|
|
||||||
|
// TODO GH#8888: We should display a warning of some kind if this fails.
|
||||||
|
// This can fail if something else already bound this hotkey.
|
||||||
|
LOG_IF_WIN32_BOOL_FALSE(RegisterHotKey(_window.get(),
|
||||||
|
index,
|
||||||
|
hotkeyFlags,
|
||||||
|
hotkey.Vkey()));
|
||||||
|
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - Force activate this window. This method will bring us to the foreground and
|
// - Force activate this window. This method will bring us to the foreground and
|
||||||
// activate us. If the window is minimized, it will restore the window. If the
|
// activate us. If the window is minimized, it will restore the window. If the
|
||||||
|
@ -929,6 +993,10 @@ winrt::fire_and_forget IslandWindow::SummonWindow()
|
||||||
});
|
});
|
||||||
LOG_IF_WIN32_BOOL_FALSE(BringWindowToTop(_window.get()));
|
LOG_IF_WIN32_BOOL_FALSE(BringWindowToTop(_window.get()));
|
||||||
LOG_IF_WIN32_BOOL_FALSE(ShowWindow(_window.get(), SW_SHOW));
|
LOG_IF_WIN32_BOOL_FALSE(ShowWindow(_window.get(), SW_SHOW));
|
||||||
|
|
||||||
|
// Activate the window too. This will force us to the virtual desktop this
|
||||||
|
// window is on, if it's on another virtual desktop.
|
||||||
|
LOG_LAST_ERROR_IF_NULL(SetActiveWindow(_window.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_EVENT(IslandWindow, DragRegionClicked, _DragRegionClickedHandlers, winrt::delegate<>);
|
DEFINE_EVENT(IslandWindow, DragRegionClicked, _DragRegionClickedHandlers, winrt::delegate<>);
|
||||||
|
|
|
@ -38,6 +38,9 @@ public:
|
||||||
void FlashTaskbar();
|
void FlashTaskbar();
|
||||||
void SetTaskbarProgress(const size_t state, const size_t progress);
|
void SetTaskbarProgress(const size_t state, const size_t progress);
|
||||||
|
|
||||||
|
void UnsetHotkeys(const std::vector<winrt::Microsoft::Terminal::Control::KeyChord>& hotkeyList);
|
||||||
|
void SetGlobalHotkeys(const std::vector<winrt::Microsoft::Terminal::Control::KeyChord>& hotkeyList);
|
||||||
|
|
||||||
winrt::fire_and_forget SummonWindow();
|
winrt::fire_and_forget SummonWindow();
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
@ -46,6 +49,7 @@ public:
|
||||||
DECLARE_EVENT(WindowCloseButtonClicked, _windowCloseButtonClickedHandler, winrt::delegate<>);
|
DECLARE_EVENT(WindowCloseButtonClicked, _windowCloseButtonClickedHandler, winrt::delegate<>);
|
||||||
WINRT_CALLBACK(MouseScrolled, winrt::delegate<void(til::point, int32_t)>);
|
WINRT_CALLBACK(MouseScrolled, winrt::delegate<void(til::point, int32_t)>);
|
||||||
WINRT_CALLBACK(WindowActivated, winrt::delegate<void()>);
|
WINRT_CALLBACK(WindowActivated, winrt::delegate<void()>);
|
||||||
|
WINRT_CALLBACK(HotkeyPressed, winrt::delegate<void(long)>);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void ForceResize()
|
void ForceResize()
|
||||||
|
|
145
src/cascadia/WindowsTerminal/VirtualDesktopUtils.cpp
Normal file
145
src/cascadia/WindowsTerminal/VirtualDesktopUtils.cpp
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
// Copyright (c) Microsoft Corporation.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
//
|
||||||
|
// Shamelessly copied from microsoft/PowerToys, at
|
||||||
|
// https://github.com/microsoft/PowerToys/blob/master/src/modules/fancyzones/lib/VirtualDesktopUtils.cpp
|
||||||
|
//
|
||||||
|
// The code style is left untouched, as to make contributions from/to the
|
||||||
|
// upstream source easier.
|
||||||
|
|
||||||
|
#include "pch.h"
|
||||||
|
|
||||||
|
#include "VirtualDesktopUtils.h"
|
||||||
|
|
||||||
|
// Non-Localizable strings
|
||||||
|
namespace NonLocalizable
|
||||||
|
{
|
||||||
|
const wchar_t RegCurrentVirtualDesktop[] = L"CurrentVirtualDesktop";
|
||||||
|
const wchar_t RegVirtualDesktopIds[] = L"VirtualDesktopIDs";
|
||||||
|
const wchar_t RegKeyVirtualDesktops[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\VirtualDesktops";
|
||||||
|
const wchar_t RegKeyVirtualDesktopsFromSession[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\SessionInfo\\%d\\VirtualDesktops";
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace VirtualDesktopUtils
|
||||||
|
{
|
||||||
|
bool GetDesktopIdFromCurrentSession(GUID* desktopId)
|
||||||
|
{
|
||||||
|
DWORD sessionId;
|
||||||
|
if (!ProcessIdToSessionId(GetCurrentProcessId(), &sessionId))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
wchar_t sessionKeyPath[256]{};
|
||||||
|
if (FAILED(StringCchPrintfW(sessionKeyPath, ARRAYSIZE(sessionKeyPath), NonLocalizable::RegKeyVirtualDesktopsFromSession, sessionId)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
wil::unique_hkey key{};
|
||||||
|
if (RegOpenKeyExW(HKEY_CURRENT_USER, sessionKeyPath, 0, KEY_ALL_ACCESS, &key) == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
GUID value{};
|
||||||
|
DWORD size = sizeof(GUID);
|
||||||
|
if (RegQueryValueExW(key.get(), NonLocalizable::RegCurrentVirtualDesktop, 0, nullptr, reinterpret_cast<BYTE*>(&value), &size) == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
*desktopId = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetVirtualDesktopIds(HKEY hKey, std::vector<GUID>& ids)
|
||||||
|
{
|
||||||
|
if (!hKey)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
DWORD bufferCapacity;
|
||||||
|
// request regkey binary buffer capacity only
|
||||||
|
if (RegQueryValueExW(hKey, NonLocalizable::RegVirtualDesktopIds, 0, nullptr, nullptr, &bufferCapacity) != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::unique_ptr<BYTE[]> buffer = std::make_unique<BYTE[]>(bufferCapacity);
|
||||||
|
// request regkey binary content
|
||||||
|
if (RegQueryValueExW(hKey, NonLocalizable::RegVirtualDesktopIds, 0, nullptr, buffer.get(), &bufferCapacity) != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const size_t guidSize = sizeof(GUID);
|
||||||
|
std::vector<GUID> temp;
|
||||||
|
temp.reserve(bufferCapacity / guidSize);
|
||||||
|
for (size_t i = 0; i < bufferCapacity; i += guidSize)
|
||||||
|
{
|
||||||
|
GUID* guid = reinterpret_cast<GUID*>(buffer.get() + i);
|
||||||
|
temp.push_back(*guid);
|
||||||
|
}
|
||||||
|
ids = std::move(temp);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
HKEY OpenVirtualDesktopsRegKey()
|
||||||
|
{
|
||||||
|
HKEY hKey{ nullptr };
|
||||||
|
if (RegOpenKeyEx(HKEY_CURRENT_USER, NonLocalizable::RegKeyVirtualDesktops, 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
return hKey;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
HKEY GetVirtualDesktopsRegKey()
|
||||||
|
{
|
||||||
|
static wil::unique_hkey virtualDesktopsKey{ OpenVirtualDesktopsRegKey() };
|
||||||
|
return virtualDesktopsKey.get();
|
||||||
|
}
|
||||||
|
bool GetVirtualDesktopIds(std::vector<GUID>& ids)
|
||||||
|
{
|
||||||
|
return GetVirtualDesktopIds(GetVirtualDesktopsRegKey(), ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetVirtualDesktopIds(std::vector<std::wstring>& ids)
|
||||||
|
{
|
||||||
|
std::vector<GUID> guids{};
|
||||||
|
if (GetVirtualDesktopIds(guids))
|
||||||
|
{
|
||||||
|
for (auto& guid : guids)
|
||||||
|
{
|
||||||
|
wil::unique_cotaskmem_string guidString;
|
||||||
|
if (SUCCEEDED(StringFromCLSID(guid, &guidString)))
|
||||||
|
{
|
||||||
|
ids.push_back(guidString.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetCurrentVirtualDesktopId(GUID* desktopId)
|
||||||
|
{
|
||||||
|
// Explorer persists current virtual desktop identifier to registry on a per session basis, but only
|
||||||
|
// after first virtual desktop switch happens. If the user hasn't switched virtual desktops in this
|
||||||
|
// session, value in registry will be empty.
|
||||||
|
if (GetDesktopIdFromCurrentSession(desktopId))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Fallback scenario is to get array of virtual desktops stored in registry, but not kept per session.
|
||||||
|
// Note that we are taking first element from virtual desktop array, which is primary desktop.
|
||||||
|
// If user has more than one virtual desktop, previous function should return correct value, as desktop
|
||||||
|
// switch occurred in current session.
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::vector<GUID> ids{};
|
||||||
|
if (GetVirtualDesktopIds(ids) && ids.size() > 0)
|
||||||
|
{
|
||||||
|
*desktopId = ids[0];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
11
src/cascadia/WindowsTerminal/VirtualDesktopUtils.h
Normal file
11
src/cascadia/WindowsTerminal/VirtualDesktopUtils.h
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
// Copyright (c) Microsoft Corporation.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
//
|
||||||
|
// A helper function for determining the GUID of the current Virtual Desktop.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace VirtualDesktopUtils
|
||||||
|
{
|
||||||
|
bool GetCurrentVirtualDesktopId(GUID* desktopId);
|
||||||
|
}
|
|
@ -48,6 +48,7 @@
|
||||||
<ClInclude Include="BaseWindow.h" />
|
<ClInclude Include="BaseWindow.h" />
|
||||||
<ClInclude Include="IslandWindow.h" />
|
<ClInclude Include="IslandWindow.h" />
|
||||||
<ClInclude Include="NonClientIslandWindow.h" />
|
<ClInclude Include="NonClientIslandWindow.h" />
|
||||||
|
<ClInclude Include="VirtualDesktopUtils.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="pch.cpp">
|
<ClCompile Include="pch.cpp">
|
||||||
|
@ -57,6 +58,7 @@
|
||||||
<ClCompile Include="AppHost.cpp" />
|
<ClCompile Include="AppHost.cpp" />
|
||||||
<ClCompile Include="IslandWindow.cpp" />
|
<ClCompile Include="IslandWindow.cpp" />
|
||||||
<ClCompile Include="NonClientIslandWindow.cpp" />
|
<ClCompile Include="NonClientIslandWindow.cpp" />
|
||||||
|
<ClCompile Include="VirtualDesktopUtils.cpp" />
|
||||||
<ClCompile Include="icon.cpp" />
|
<ClCompile Include="icon.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -56,12 +56,14 @@ Abstract:
|
||||||
#include <windows.ui.xaml.hosting.desktopwindowxamlsource.h>
|
#include <windows.ui.xaml.hosting.desktopwindowxamlsource.h>
|
||||||
|
|
||||||
// Additional headers for various xaml features. We need:
|
// Additional headers for various xaml features. We need:
|
||||||
// * Core so we can resume_foreground
|
// * Core so we can resume_foreground with CoreDispatcher
|
||||||
// * Controls for grid
|
// * Controls for grid
|
||||||
// * Media for ScaleTransform
|
// * Media for ScaleTransform
|
||||||
|
// * ApplicationModel for finding the path to wt.exe
|
||||||
#include <winrt/Windows.UI.Core.h>
|
#include <winrt/Windows.UI.Core.h>
|
||||||
#include <winrt/Windows.UI.Xaml.Controls.h>
|
#include <winrt/Windows.UI.Xaml.Controls.h>
|
||||||
#include <winrt/Windows.ui.xaml.media.h>
|
#include <winrt/Windows.ui.xaml.media.h>
|
||||||
|
#include <winrt/Windows.ApplicationModel.h>
|
||||||
|
|
||||||
#include <winrt/TerminalApp.h>
|
#include <winrt/TerminalApp.h>
|
||||||
#include <winrt/Microsoft.Terminal.Settings.Model.h>
|
#include <winrt/Microsoft.Terminal.Settings.Model.h>
|
||||||
|
|
Loading…
Reference in a new issue