mirror of
https://github.com/microsoft/terminal.git
synced 2026-05-20 05:54:23 +00:00
Compare commits
30 Commits
v1.25.1241
...
dev/migrie
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a0589db4a3 | ||
|
|
81a5a736fe | ||
|
|
dbee7e6d67 | ||
|
|
36fb572308 | ||
|
|
6b6ca8fe60 | ||
|
|
015e3211fc | ||
|
|
5c17603a94 | ||
|
|
354e4b00a3 | ||
|
|
8707c03715 | ||
|
|
31b2763be5 | ||
|
|
a000d81fa9 | ||
|
|
d36a08186c | ||
|
|
3b1bb455d8 | ||
|
|
901bc78966 | ||
|
|
4150609b42 | ||
|
|
d5920a8c69 | ||
|
|
fd364db727 | ||
|
|
3a0fbd9f59 | ||
|
|
64533c838a | ||
|
|
aa6b08118f | ||
|
|
b0b44410c6 | ||
|
|
b541179333 | ||
|
|
56f1223dc5 | ||
|
|
88d974280d | ||
|
|
d84a31801a | ||
|
|
6910677a11 | ||
|
|
9331cc8e59 | ||
|
|
2f64db2765 | ||
|
|
4cc3d39de9 | ||
|
|
d8dcb6f570 |
15
.github/actions/spelling/README.md
vendored
Normal file
15
.github/actions/spelling/README.md
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# check-spelling/check-spelling configuration
|
||||||
|
|
||||||
|
File | Purpose | Format | Info
|
||||||
|
-|-|-|-
|
||||||
|
[allow/*.txt](allow/) | Add words to the dictionary | one word per line (only letters and `'`s allowed) | [allow](https://github.com/check-spelling/check-spelling/wiki/Configuration#allow)
|
||||||
|
[reject.txt](reject.txt) | Remove words from the dictionary (after allow) | grep pattern matching whole dictionary words | [reject](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-reject)
|
||||||
|
[excludes.txt](excludes.txt) | Files to ignore entirely | perl regular expression | [excludes](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-excludes)
|
||||||
|
[patterns/*.txt](patterns/) | Patterns to ignore from checked lines | perl regular expression (order matters, first match wins) | [patterns](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-patterns)
|
||||||
|
[candidate.patterns](candidate.patterns) | Patterns that might be worth adding to [patterns.txt](patterns.txt) | perl regular expression with optional comment block introductions (all matches will be suggested) | [candidates](https://github.com/check-spelling/check-spelling/wiki/Feature:-Suggest-patterns)
|
||||||
|
[line_forbidden.patterns](line_forbidden.patterns) | Patterns to flag in checked lines | perl regular expression (order matters, first match wins) | [patterns](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-patterns)
|
||||||
|
[expect/*.txt](expect.txt) | Expected words that aren't in the dictionary | one word per line (sorted, alphabetically) | [expect](https://github.com/check-spelling/check-spelling/wiki/Configuration#expect)
|
||||||
|
[advice.md](advice.md) | Supplement for GitHub comment when unrecognized words are found | GitHub Markdown | [advice](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-advice)
|
||||||
|
|
||||||
|
Note: you can replace any of these files with a directory by the same name (minus the suffix)
|
||||||
|
and then include multiple files inside that directory (with that suffix) to merge multiple files together.
|
||||||
38
.github/actions/spelling/advice.md
vendored
38
.github/actions/spelling/advice.md
vendored
@@ -1,4 +1,4 @@
|
|||||||
<!-- markdownlint-disable MD033 MD041 -->
|
<!-- See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-advice --> <!-- markdownlint-disable MD033 MD041 -->
|
||||||
<details>
|
<details>
|
||||||
<summary>
|
<summary>
|
||||||
:pencil2: Contributor please read this
|
:pencil2: Contributor please read this
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
By default the command suggestion will generate a file named based on your commit. That's generally ok as long as you add the file to your commit. Someone can reorganize it later.
|
By default the command suggestion will generate a file named based on your commit. That's generally ok as long as you add the file to your commit. Someone can reorganize it later.
|
||||||
|
|
||||||
: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. If it doesn't work for you, you can manually _add_ (one word per line) / _remove_ items to `expect.txt` and the `excludes.txt` files.
|
||||||
|
|
||||||
If the listed items are:
|
If the listed items are:
|
||||||
|
|
||||||
@@ -20,31 +20,29 @@ 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:
|
||||||
|
|
||||||
<details><summary>:clamp: If you see a bunch of garbage</summary>
|
|
||||||
|
|
||||||
If it relates to a ...
|
<details><summary>If the flagged items are :exploding_head: false positives</summary>
|
||||||
<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 items relate to a ...
|
||||||
|
* binary file (or some other file you wouldn't want to check at all).
|
||||||
|
|
||||||
If not, try writing one and adding it to a `patterns/{file}.txt`.
|
Please add a file path to the `excludes.txt` file matching the containing file.
|
||||||
|
|
||||||
Patterns 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 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](
|
|
||||||
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](
|
`^` 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).
|
../tree/HEAD/README.md) (on whichever branch you're using).
|
||||||
</details>
|
|
||||||
|
* well-formed pattern.
|
||||||
|
|
||||||
|
If you can write a [pattern](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns) that would match it,
|
||||||
|
try adding it to the `patterns.txt` file.
|
||||||
|
|
||||||
|
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>
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|||||||
41
.github/actions/spelling/allow/allow.txt
vendored
41
.github/actions/spelling/allow/allow.txt
vendored
@@ -1,46 +1,75 @@
|
|||||||
|
admins
|
||||||
|
allcolors
|
||||||
|
Apc
|
||||||
apc
|
apc
|
||||||
|
breadcrumb
|
||||||
|
breadcrumbs
|
||||||
|
bsd
|
||||||
calt
|
calt
|
||||||
ccmp
|
ccmp
|
||||||
Apc
|
changelog
|
||||||
clickable
|
clickable
|
||||||
clig
|
clig
|
||||||
|
CMMI
|
||||||
copyable
|
copyable
|
||||||
|
cybersecurity
|
||||||
dalet
|
dalet
|
||||||
dcs
|
|
||||||
Dcs
|
Dcs
|
||||||
|
dcs
|
||||||
dialytika
|
dialytika
|
||||||
dje
|
dje
|
||||||
downside
|
downside
|
||||||
downsides
|
downsides
|
||||||
dze
|
dze
|
||||||
dzhe
|
dzhe
|
||||||
|
EDDB
|
||||||
|
EDDC
|
||||||
Enum'd
|
Enum'd
|
||||||
Fitt
|
Fitt
|
||||||
formattings
|
formattings
|
||||||
|
FTCS
|
||||||
ftp
|
ftp
|
||||||
fvar
|
fvar
|
||||||
|
gantt
|
||||||
|
gcc
|
||||||
geeksforgeeks
|
geeksforgeeks
|
||||||
ghe
|
ghe
|
||||||
|
github
|
||||||
gje
|
gje
|
||||||
|
godbolt
|
||||||
hostname
|
hostname
|
||||||
hostnames
|
hostnames
|
||||||
|
https
|
||||||
hyperlink
|
hyperlink
|
||||||
hyperlinking
|
hyperlinking
|
||||||
hyperlinks
|
hyperlinks
|
||||||
|
iconify
|
||||||
img
|
img
|
||||||
|
inlined
|
||||||
It'd
|
It'd
|
||||||
kje
|
kje
|
||||||
|
libfuzzer
|
||||||
|
libuv
|
||||||
liga
|
liga
|
||||||
lje
|
lje
|
||||||
|
Llast
|
||||||
|
llvm
|
||||||
|
Lmid
|
||||||
locl
|
locl
|
||||||
|
lol
|
||||||
lorem
|
lorem
|
||||||
|
Lorigin
|
||||||
maxed
|
maxed
|
||||||
|
minimalistic
|
||||||
mkmk
|
mkmk
|
||||||
|
mnt
|
||||||
mru
|
mru
|
||||||
nje
|
nje
|
||||||
|
noreply
|
||||||
ogonek
|
ogonek
|
||||||
ok'd
|
ok'd
|
||||||
overlined
|
overlined
|
||||||
|
pipeline
|
||||||
postmodern
|
postmodern
|
||||||
ptys
|
ptys
|
||||||
qof
|
qof
|
||||||
@@ -55,17 +84,25 @@ runtimes
|
|||||||
shcha
|
shcha
|
||||||
slnt
|
slnt
|
||||||
Sos
|
Sos
|
||||||
|
ssh
|
||||||
|
timeline
|
||||||
|
timelines
|
||||||
timestamped
|
timestamped
|
||||||
TLDR
|
TLDR
|
||||||
tokenizes
|
tokenizes
|
||||||
tonos
|
tonos
|
||||||
|
toolset
|
||||||
tshe
|
tshe
|
||||||
|
ubuntu
|
||||||
uiatextrange
|
uiatextrange
|
||||||
UIs
|
UIs
|
||||||
und
|
und
|
||||||
unregister
|
unregister
|
||||||
versioned
|
versioned
|
||||||
|
vsdevcmd
|
||||||
We'd
|
We'd
|
||||||
wildcards
|
wildcards
|
||||||
|
XBox
|
||||||
|
YBox
|
||||||
yeru
|
yeru
|
||||||
zhe
|
zhe
|
||||||
|
|||||||
62
.github/actions/spelling/allow/apis.txt
vendored
62
.github/actions/spelling/allow/apis.txt
vendored
@@ -1,30 +1,44 @@
|
|||||||
ACCEPTFILES
|
ACCEPTFILES
|
||||||
ACCESSDENIED
|
ACCESSDENIED
|
||||||
|
acl
|
||||||
|
aclapi
|
||||||
alignas
|
alignas
|
||||||
alignof
|
alignof
|
||||||
APPLYTOSUBMENUS
|
APPLYTOSUBMENUS
|
||||||
|
appxrecipe
|
||||||
bitfield
|
bitfield
|
||||||
bitfields
|
bitfields
|
||||||
BUILDBRANCH
|
BUILDBRANCH
|
||||||
BUILDMSG
|
BUILDMSG
|
||||||
BUILDNUMBER
|
BUILDNUMBER
|
||||||
|
BYCOMMAND
|
||||||
BYPOSITION
|
BYPOSITION
|
||||||
charconv
|
charconv
|
||||||
CLASSNOTAVAILABLE
|
CLASSNOTAVAILABLE
|
||||||
|
CLOSEAPP
|
||||||
cmdletbinding
|
cmdletbinding
|
||||||
COLORPROPERTY
|
COLORPROPERTY
|
||||||
colspan
|
colspan
|
||||||
COMDLG
|
COMDLG
|
||||||
|
commandlinetoargv
|
||||||
comparand
|
comparand
|
||||||
cstdint
|
cstdint
|
||||||
CXICON
|
CXICON
|
||||||
CYICON
|
CYICON
|
||||||
|
Dacl
|
||||||
dataobject
|
dataobject
|
||||||
dcomp
|
dcomp
|
||||||
DERR
|
DERR
|
||||||
dlldata
|
dlldata
|
||||||
|
DNE
|
||||||
DONTADDTORECENT
|
DONTADDTORECENT
|
||||||
|
DWMSBT
|
||||||
|
DWMWA
|
||||||
|
DWMWA
|
||||||
DWORDLONG
|
DWORDLONG
|
||||||
|
endfor
|
||||||
|
ENDSESSION
|
||||||
|
enumset
|
||||||
environstrings
|
environstrings
|
||||||
EXPCMDFLAGS
|
EXPCMDFLAGS
|
||||||
EXPCMDSTATE
|
EXPCMDSTATE
|
||||||
@@ -37,12 +51,16 @@ fullkbd
|
|||||||
futex
|
futex
|
||||||
GETDESKWALLPAPER
|
GETDESKWALLPAPER
|
||||||
GETHIGHCONTRAST
|
GETHIGHCONTRAST
|
||||||
|
GETMOUSEHOVERTIME
|
||||||
Hashtable
|
Hashtable
|
||||||
HIGHCONTRASTON
|
HIGHCONTRASTON
|
||||||
HIGHCONTRASTW
|
HIGHCONTRASTW
|
||||||
hotkeys
|
hotkeys
|
||||||
href
|
href
|
||||||
hrgn
|
hrgn
|
||||||
|
HTCLOSE
|
||||||
|
hwinsta
|
||||||
|
HWINSTA
|
||||||
IActivation
|
IActivation
|
||||||
IApp
|
IApp
|
||||||
IAppearance
|
IAppearance
|
||||||
@@ -59,18 +77,22 @@ IDirect
|
|||||||
IExplorer
|
IExplorer
|
||||||
IFACEMETHOD
|
IFACEMETHOD
|
||||||
IFile
|
IFile
|
||||||
|
IGraphics
|
||||||
IInheritable
|
IInheritable
|
||||||
IMap
|
IMap
|
||||||
|
IMonarch
|
||||||
IObject
|
IObject
|
||||||
iosfwd
|
iosfwd
|
||||||
IPackage
|
IPackage
|
||||||
IPeasant
|
IPeasant
|
||||||
|
ISetup
|
||||||
isspace
|
isspace
|
||||||
IStorage
|
IStorage
|
||||||
istream
|
istream
|
||||||
IStringable
|
IStringable
|
||||||
ITab
|
ITab
|
||||||
ITaskbar
|
ITaskbar
|
||||||
|
itow
|
||||||
IUri
|
IUri
|
||||||
IVirtual
|
IVirtual
|
||||||
KEYSELECT
|
KEYSELECT
|
||||||
@@ -79,17 +101,27 @@ llabs
|
|||||||
llu
|
llu
|
||||||
localtime
|
localtime
|
||||||
lround
|
lround
|
||||||
|
Lsa
|
||||||
|
lsass
|
||||||
LSHIFT
|
LSHIFT
|
||||||
|
LTGRAY
|
||||||
|
MAINWINDOW
|
||||||
|
memchr
|
||||||
|
memicmp
|
||||||
MENUCOMMAND
|
MENUCOMMAND
|
||||||
MENUDATA
|
MENUDATA
|
||||||
MENUINFO
|
MENUINFO
|
||||||
memicmp
|
MENUITEMINFOW
|
||||||
mptt
|
mmeapi
|
||||||
|
MOUSELEAVE
|
||||||
mov
|
mov
|
||||||
|
mptt
|
||||||
msappx
|
msappx
|
||||||
MULTIPLEUSE
|
MULTIPLEUSE
|
||||||
NCHITTEST
|
NCHITTEST
|
||||||
NCLBUTTONDBLCLK
|
NCLBUTTONDBLCLK
|
||||||
|
NCMOUSELEAVE
|
||||||
|
NCMOUSEMOVE
|
||||||
NCRBUTTONDBLCLK
|
NCRBUTTONDBLCLK
|
||||||
NIF
|
NIF
|
||||||
NIN
|
NIN
|
||||||
@@ -107,26 +139,36 @@ oaidl
|
|||||||
ocidl
|
ocidl
|
||||||
ODR
|
ODR
|
||||||
offsetof
|
offsetof
|
||||||
|
ofstream
|
||||||
|
onefuzz
|
||||||
osver
|
osver
|
||||||
OSVERSIONINFOEXW
|
OSVERSIONINFOEXW
|
||||||
otms
|
otms
|
||||||
OUTLINETEXTMETRICW
|
OUTLINETEXTMETRICW
|
||||||
overridable
|
overridable
|
||||||
|
PACL
|
||||||
PAGESCROLL
|
PAGESCROLL
|
||||||
|
PATINVERT
|
||||||
|
PEXPLICIT
|
||||||
PICKFOLDERS
|
PICKFOLDERS
|
||||||
pmr
|
pmr
|
||||||
|
ptstr
|
||||||
|
QUERYENDSESSION
|
||||||
rcx
|
rcx
|
||||||
REGCLS
|
REGCLS
|
||||||
RETURNCMD
|
RETURNCMD
|
||||||
rfind
|
rfind
|
||||||
|
ROOTOWNER
|
||||||
roundf
|
roundf
|
||||||
RSHIFT
|
RSHIFT
|
||||||
|
SACL
|
||||||
schandle
|
schandle
|
||||||
semver
|
semver
|
||||||
serializer
|
serializer
|
||||||
SETVERSION
|
SETVERSION
|
||||||
SHELLEXECUTEINFOW
|
SHELLEXECUTEINFOW
|
||||||
shobjidl
|
shobjidl
|
||||||
|
SHOWHIDE
|
||||||
SHOWMINIMIZED
|
SHOWMINIMIZED
|
||||||
SHOWTIP
|
SHOWTIP
|
||||||
SINGLEUSE
|
SINGLEUSE
|
||||||
@@ -147,23 +189,37 @@ Stubless
|
|||||||
Subheader
|
Subheader
|
||||||
Subpage
|
Subpage
|
||||||
syscall
|
syscall
|
||||||
|
SYSTEMBACKDROP
|
||||||
|
TABROW
|
||||||
TASKBARCREATED
|
TASKBARCREATED
|
||||||
TBPF
|
TBPF
|
||||||
THEMECHANGED
|
THEMECHANGED
|
||||||
tlg
|
tlg
|
||||||
|
TME
|
||||||
tmp
|
tmp
|
||||||
|
tmpdir
|
||||||
tolower
|
tolower
|
||||||
toupper
|
toupper
|
||||||
|
TRACKMOUSEEVENT
|
||||||
TTask
|
TTask
|
||||||
TVal
|
TVal
|
||||||
UChar
|
UChar
|
||||||
|
UFIELD
|
||||||
|
ULARGE
|
||||||
|
UOI
|
||||||
UPDATEINIFILE
|
UPDATEINIFILE
|
||||||
userenv
|
userenv
|
||||||
|
USEROBJECTFLAGS
|
||||||
|
Viewbox
|
||||||
|
virtualalloc
|
||||||
wcsstr
|
wcsstr
|
||||||
wcstoui
|
wcstoui
|
||||||
winmain
|
winmain
|
||||||
|
winsta
|
||||||
|
winstamin
|
||||||
wmemcmp
|
wmemcmp
|
||||||
wpc
|
wpc
|
||||||
|
WSF
|
||||||
wsregex
|
wsregex
|
||||||
wwinmain
|
wwinmain
|
||||||
xchg
|
xchg
|
||||||
@@ -180,6 +236,7 @@ xlocmes
|
|||||||
xlocmon
|
xlocmon
|
||||||
xlocnum
|
xlocnum
|
||||||
xloctime
|
xloctime
|
||||||
|
XMax
|
||||||
xmemory
|
xmemory
|
||||||
XParse
|
XParse
|
||||||
xpath
|
xpath
|
||||||
@@ -188,3 +245,4 @@ xstring
|
|||||||
xtree
|
xtree
|
||||||
xutility
|
xutility
|
||||||
YIcon
|
YIcon
|
||||||
|
YMax
|
||||||
|
|||||||
8
.github/actions/spelling/allow/math.txt
vendored
8
.github/actions/spelling/allow/math.txt
vendored
@@ -1,3 +1,11 @@
|
|||||||
|
atan
|
||||||
|
CPrime
|
||||||
|
HBar
|
||||||
|
HPrime
|
||||||
isnan
|
isnan
|
||||||
|
LPrime
|
||||||
|
LStep
|
||||||
powf
|
powf
|
||||||
|
RSub
|
||||||
sqrtf
|
sqrtf
|
||||||
|
ULP
|
||||||
|
|||||||
13
.github/actions/spelling/allow/microsoft.txt
vendored
13
.github/actions/spelling/allow/microsoft.txt
vendored
@@ -1,5 +1,6 @@
|
|||||||
ACLs
|
ACLs
|
||||||
ADMINS
|
ADMINS
|
||||||
|
advapi
|
||||||
altform
|
altform
|
||||||
altforms
|
altforms
|
||||||
appendwttlogging
|
appendwttlogging
|
||||||
@@ -15,8 +16,10 @@ CPLs
|
|||||||
cpptools
|
cpptools
|
||||||
cppvsdbg
|
cppvsdbg
|
||||||
CPRs
|
CPRs
|
||||||
|
cryptbase
|
||||||
DACL
|
DACL
|
||||||
DACLs
|
DACLs
|
||||||
|
defaultlib
|
||||||
diffs
|
diffs
|
||||||
disposables
|
disposables
|
||||||
dotnetfeed
|
dotnetfeed
|
||||||
@@ -24,15 +27,22 @@ DTDs
|
|||||||
DWINRT
|
DWINRT
|
||||||
enablewttlogging
|
enablewttlogging
|
||||||
Intelli
|
Intelli
|
||||||
|
IVisual
|
||||||
|
libucrt
|
||||||
|
libucrtd
|
||||||
LKG
|
LKG
|
||||||
|
LOCKFILE
|
||||||
|
Lxss
|
||||||
mfcribbon
|
mfcribbon
|
||||||
microsoft
|
microsoft
|
||||||
microsoftonline
|
microsoftonline
|
||||||
MSAA
|
MSAA
|
||||||
msixbundle
|
msixbundle
|
||||||
MSVC
|
MSVC
|
||||||
|
MSVCP
|
||||||
muxc
|
muxc
|
||||||
netcore
|
netcore
|
||||||
|
Onefuzz
|
||||||
osgvsowi
|
osgvsowi
|
||||||
PFILETIME
|
PFILETIME
|
||||||
pgc
|
pgc
|
||||||
@@ -43,6 +53,7 @@ powershell
|
|||||||
propkey
|
propkey
|
||||||
pscustomobject
|
pscustomobject
|
||||||
QWORD
|
QWORD
|
||||||
|
regedit
|
||||||
robocopy
|
robocopy
|
||||||
SACLs
|
SACLs
|
||||||
sdkddkver
|
sdkddkver
|
||||||
@@ -56,6 +67,8 @@ systemroot
|
|||||||
taskkill
|
taskkill
|
||||||
tasklist
|
tasklist
|
||||||
tdbuildteamid
|
tdbuildteamid
|
||||||
|
ucrt
|
||||||
|
ucrtd
|
||||||
unvirtualized
|
unvirtualized
|
||||||
VCRT
|
VCRT
|
||||||
vcruntime
|
vcruntime
|
||||||
|
|||||||
12
.github/actions/spelling/allow/names.txt
vendored
12
.github/actions/spelling/allow/names.txt
vendored
@@ -1,14 +1,18 @@
|
|||||||
Anup
|
Anup
|
||||||
austdi
|
austdi
|
||||||
|
arkthur
|
||||||
Ballmer
|
Ballmer
|
||||||
bhoj
|
bhoj
|
||||||
Bhojwani
|
Bhojwani
|
||||||
|
Bluloco
|
||||||
carlos
|
carlos
|
||||||
dhowett
|
dhowett
|
||||||
Diviness
|
Diviness
|
||||||
dsafa
|
dsafa
|
||||||
duhowett
|
duhowett
|
||||||
|
DXP
|
||||||
ekg
|
ekg
|
||||||
|
eryksun
|
||||||
ethanschoonover
|
ethanschoonover
|
||||||
Firefox
|
Firefox
|
||||||
Gatta
|
Gatta
|
||||||
@@ -20,6 +24,7 @@ Hernan
|
|||||||
Howett
|
Howett
|
||||||
Illhardt
|
Illhardt
|
||||||
iquilezles
|
iquilezles
|
||||||
|
italo
|
||||||
jantari
|
jantari
|
||||||
jerrysh
|
jerrysh
|
||||||
Kaiyu
|
Kaiyu
|
||||||
@@ -33,7 +38,9 @@ leonmsft
|
|||||||
Lepilleur
|
Lepilleur
|
||||||
lhecker
|
lhecker
|
||||||
lukesampson
|
lukesampson
|
||||||
|
Macbook
|
||||||
Manandhar
|
Manandhar
|
||||||
|
masserano
|
||||||
mbadolato
|
mbadolato
|
||||||
Mehrain
|
Mehrain
|
||||||
menger
|
menger
|
||||||
@@ -53,6 +60,7 @@ oldnewthing
|
|||||||
opengl
|
opengl
|
||||||
osgwiki
|
osgwiki
|
||||||
pabhojwa
|
pabhojwa
|
||||||
|
panos
|
||||||
paulcam
|
paulcam
|
||||||
pauldotknopf
|
pauldotknopf
|
||||||
PGP
|
PGP
|
||||||
@@ -61,12 +69,16 @@ Rincewind
|
|||||||
rprichard
|
rprichard
|
||||||
Schoonover
|
Schoonover
|
||||||
shadertoy
|
shadertoy
|
||||||
|
Shomnipotence
|
||||||
|
simioni
|
||||||
Somuah
|
Somuah
|
||||||
sonph
|
sonph
|
||||||
sonpham
|
sonpham
|
||||||
stakx
|
stakx
|
||||||
|
talo
|
||||||
thereses
|
thereses
|
||||||
Walisch
|
Walisch
|
||||||
|
WDX
|
||||||
Wellons
|
Wellons
|
||||||
Wirt
|
Wirt
|
||||||
Wojciech
|
Wojciech
|
||||||
|
|||||||
523
.github/actions/spelling/candidate.patterns
vendored
Normal file
523
.github/actions/spelling/candidate.patterns
vendored
Normal file
@@ -0,0 +1,523 @@
|
|||||||
|
# marker to ignore all code on line
|
||||||
|
^.*/\* #no-spell-check-line \*/.*$
|
||||||
|
# marker for ignoring a comment to the end of the line
|
||||||
|
// #no-spell-check.*$
|
||||||
|
|
||||||
|
# patch hunk comments
|
||||||
|
^\@\@ -\d+(?:,\d+|) \+\d+(?:,\d+|) \@\@ .*
|
||||||
|
# git index header
|
||||||
|
index [0-9a-z]{7,40}\.\.[0-9a-z]{7,40}
|
||||||
|
|
||||||
|
# cid urls
|
||||||
|
(['"])cid:.*?\g{-1}
|
||||||
|
|
||||||
|
# data url in parens
|
||||||
|
\(data:[^)]*?(?:[A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,})[^)]*\)
|
||||||
|
# data url in quotes
|
||||||
|
([`'"])data:.*?(?:[A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,}).*\g{-1}
|
||||||
|
# data url
|
||||||
|
data:[-a-zA-Z=;:/0-9+]*,\S*
|
||||||
|
|
||||||
|
# mailto urls
|
||||||
|
mailto:[-a-zA-Z=;:/?%&0-9+@.]{3,}
|
||||||
|
|
||||||
|
# magnet urls
|
||||||
|
magnet:[?=:\w]+
|
||||||
|
|
||||||
|
# magnet urls
|
||||||
|
"magnet:[^"]+"
|
||||||
|
|
||||||
|
# obs:
|
||||||
|
"obs:[^"]*"
|
||||||
|
|
||||||
|
# The `\b` here means a break, it's the fancy way to handle urls, but it makes things harder to read
|
||||||
|
# In this examples content, I'm using a number of different ways to match things to show various approaches
|
||||||
|
# asciinema
|
||||||
|
\basciinema\.org/a/[0-9a-zA-Z]+
|
||||||
|
|
||||||
|
# apple
|
||||||
|
\bdeveloper\.apple\.com/[-\w?=/]+
|
||||||
|
# Apple music
|
||||||
|
\bembed\.music\.apple\.com/fr/playlist/usr-share/[-\w.]+
|
||||||
|
|
||||||
|
# appveyor api
|
||||||
|
\bci\.appveyor\.com/api/projects/status/[0-9a-z]+
|
||||||
|
# appveyor project
|
||||||
|
\bci\.appveyor\.com/project/(?:[^/\s"]*/){2}builds?/\d+/job/[0-9a-z]+
|
||||||
|
|
||||||
|
# Amazon
|
||||||
|
|
||||||
|
# Amazon
|
||||||
|
\bamazon\.com/[-\w]+/(?:dp/[0-9A-Z]+|)
|
||||||
|
# AWS S3
|
||||||
|
\b\w*\.s3[^.]*\.amazonaws\.com/[-\w/&#%_?:=]*
|
||||||
|
# AWS execute-api
|
||||||
|
\b[0-9a-z]{10}\.execute-api\.[-0-9a-z]+\.amazonaws\.com\b
|
||||||
|
# AWS ELB
|
||||||
|
\b\w+\.[-0-9a-z]+\.elb\.amazonaws\.com\b
|
||||||
|
# AWS SNS
|
||||||
|
\bsns\.[-0-9a-z]+.amazonaws\.com/[-\w/&#%_?:=]*
|
||||||
|
# AWS VPC
|
||||||
|
vpc-\w+
|
||||||
|
|
||||||
|
# While you could try to match `http://` and `https://` by using `s?` in `https?://`, sometimes there
|
||||||
|
# YouTube url
|
||||||
|
\b(?:(?:www\.|)youtube\.com|youtu.be)/(?:channel/|embed/|user/|playlist\?list=|watch\?v=|v/|)[-a-zA-Z0-9?&=_%]*
|
||||||
|
# YouTube music
|
||||||
|
\bmusic\.youtube\.com/youtubei/v1/browse(?:[?&]\w+=[-a-zA-Z0-9?&=_]*)
|
||||||
|
# YouTube tag
|
||||||
|
<\s*youtube\s+id=['"][-a-zA-Z0-9?_]*['"]
|
||||||
|
# YouTube image
|
||||||
|
\bimg\.youtube\.com/vi/[-a-zA-Z0-9?&=_]*
|
||||||
|
# Google Accounts
|
||||||
|
\baccounts.google.com/[-_/?=.:;+%&0-9a-zA-Z]*
|
||||||
|
# Google Analytics
|
||||||
|
\bgoogle-analytics\.com/collect.[-0-9a-zA-Z?%=&_.~]*
|
||||||
|
# Google APIs
|
||||||
|
\bgoogleapis\.(?:com|dev)/[a-z]+/(?:v\d+/|)[a-z]+/[-@:./?=\w+|&]+
|
||||||
|
# Google Storage
|
||||||
|
\b[-a-zA-Z0-9.]*\bstorage\d*\.googleapis\.com(?:/\S*|)
|
||||||
|
# Google Calendar
|
||||||
|
\bcalendar\.google\.com/calendar(?:/u/\d+|)/embed\?src=[@./?=\w&%]+
|
||||||
|
\w+\@group\.calendar\.google\.com\b
|
||||||
|
# Google DataStudio
|
||||||
|
\bdatastudio\.google\.com/(?:(?:c/|)u/\d+/|)(?:embed/|)(?:open|reporting|datasources|s)/[-0-9a-zA-Z]+(?:/page/[-0-9a-zA-Z]+|)
|
||||||
|
# The leading `/` here is as opposed to the `\b` above
|
||||||
|
# ... a short way to match `https://` or `http://` since most urls have one of those prefixes
|
||||||
|
# Google Docs
|
||||||
|
/docs\.google\.com/[a-z]+/(?:ccc\?key=\w+|(?:u/\d+|d/(?:e/|)[0-9a-zA-Z_-]+/)?(?:edit\?[-\w=#.]*|/\?[\w=&]*|))
|
||||||
|
# Google Drive
|
||||||
|
\bdrive\.google\.com/(?:file/d/|open)[-0-9a-zA-Z_?=]*
|
||||||
|
# Google Groups
|
||||||
|
\bgroups\.google\.com/(?:(?:forum/#!|d/)(?:msg|topics?|searchin)|a)/[^/\s"]+/[-a-zA-Z0-9$]+(?:/[-a-zA-Z0-9]+)*
|
||||||
|
# Google Maps
|
||||||
|
\bmaps\.google\.com/maps\?[\w&;=]*
|
||||||
|
# Google themes
|
||||||
|
themes\.googleusercontent\.com/static/fonts/[^/\s"]+/v\d+/[^.]+.
|
||||||
|
# Google CDN
|
||||||
|
\bclients2\.google(?:usercontent|)\.com[-0-9a-zA-Z/.]*
|
||||||
|
# Goo.gl
|
||||||
|
/goo\.gl/[a-zA-Z0-9]+
|
||||||
|
# Google Chrome Store
|
||||||
|
\bchrome\.google\.com/webstore/detail/[-\w]*(?:/\w*|)
|
||||||
|
# Google Books
|
||||||
|
\bgoogle\.(?:\w{2,4})/books(?:/\w+)*\?[-\w\d=&#.]*
|
||||||
|
# Google Fonts
|
||||||
|
\bfonts\.(?:googleapis|gstatic)\.com/[-/?=:;+&0-9a-zA-Z]*
|
||||||
|
# Google Forms
|
||||||
|
\bforms\.gle/\w+
|
||||||
|
# Google Scholar
|
||||||
|
\bscholar\.google\.com/citations\?user=[A-Za-z0-9_]+
|
||||||
|
# Google Colab Research Drive
|
||||||
|
\bcolab\.research\.google\.com/drive/[-0-9a-zA-Z_?=]*
|
||||||
|
|
||||||
|
# GitHub SHAs (api)
|
||||||
|
\bapi.github\.com/repos(?:/[^/\s"]+){3}/[0-9a-f]+\b
|
||||||
|
# GitHub SHAs (markdown)
|
||||||
|
(?:\[`?[0-9a-f]+`?\]\(https:/|)/(?:www\.|)github\.com(?:/[^/\s"]+){2,}(?:/[^/\s")]+)(?:[0-9a-f]+(?:[-0-9a-zA-Z/#.]*|)\b|)
|
||||||
|
# GitHub SHAs
|
||||||
|
\bgithub\.com(?:/[^/\s"]+){2}[@#][0-9a-f]+\b
|
||||||
|
# GitHub wiki
|
||||||
|
\bgithub\.com/(?:[^/]+/){2}wiki/(?:(?:[^/]+/|)_history|[^/]+(?:/_compare|)/[0-9a-f.]{40,})\b
|
||||||
|
# githubusercontent
|
||||||
|
/[-a-z0-9]+\.githubusercontent\.com/[-a-zA-Z0-9?&=_\/.]*
|
||||||
|
# githubassets
|
||||||
|
\bgithubassets.com/[0-9a-f]+(?:[-/\w.]+)
|
||||||
|
# gist github
|
||||||
|
\bgist\.github\.com/[^/\s"]+/[0-9a-f]+
|
||||||
|
# git.io
|
||||||
|
\bgit\.io/[0-9a-zA-Z]+
|
||||||
|
# GitHub JSON
|
||||||
|
"node_id": "[-a-zA-Z=;:/0-9+]*"
|
||||||
|
# Contributor
|
||||||
|
\[[^\]]+\]\(https://github\.com/[^/\s"]+\)
|
||||||
|
# GHSA
|
||||||
|
GHSA(?:-[0-9a-z]{4}){3}
|
||||||
|
|
||||||
|
# GitLab commit
|
||||||
|
\bgitlab\.[^/\s"]*/\S+/\S+/commit/[0-9a-f]{7,16}#[0-9a-f]{40}\b
|
||||||
|
# GitLab merge requests
|
||||||
|
\bgitlab\.[^/\s"]*/\S+/\S+/-/merge_requests/\d+/diffs#[0-9a-f]{40}\b
|
||||||
|
# GitLab uploads
|
||||||
|
\bgitlab\.[^/\s"]*/uploads/[-a-zA-Z=;:/0-9+]*
|
||||||
|
# GitLab commits
|
||||||
|
\bgitlab\.[^/\s"]*/(?:[^/\s"]+/){2}commits?/[0-9a-f]+\b
|
||||||
|
|
||||||
|
# binanace
|
||||||
|
accounts.binance.com/[a-z/]*oauth/authorize\?[-0-9a-zA-Z&%]*
|
||||||
|
|
||||||
|
# bitbucket diff
|
||||||
|
\bapi\.bitbucket\.org/\d+\.\d+/repositories/(?:[^/\s"]+/){2}diff(?:stat|)(?:/[^/\s"]+){2}:[0-9a-f]+
|
||||||
|
# bitbucket repositories commits
|
||||||
|
\bapi\.bitbucket\.org/\d+\.\d+/repositories/(?:[^/\s"]+/){2}commits?/[0-9a-f]+
|
||||||
|
# bitbucket commits
|
||||||
|
\bbitbucket\.org/(?:[^/\s"]+/){2}commits?/[0-9a-f]+
|
||||||
|
|
||||||
|
# bit.ly
|
||||||
|
\bbit\.ly/\w+
|
||||||
|
|
||||||
|
# bitrise
|
||||||
|
\bapp\.bitrise\.io/app/[0-9a-f]*/[\w.?=&]*
|
||||||
|
|
||||||
|
# bootstrapcdn.com
|
||||||
|
\bbootstrapcdn\.com/[-./\w]+
|
||||||
|
|
||||||
|
# cdn.cloudflare.com
|
||||||
|
\bcdnjs\.cloudflare\.com/[./\w]+
|
||||||
|
|
||||||
|
# circleci
|
||||||
|
\bcircleci\.com/gh(?:/[^/\s"]+){1,5}.[a-z]+\?[-0-9a-zA-Z=&]+
|
||||||
|
|
||||||
|
# gitter
|
||||||
|
\bgitter\.im(?:/[^/\s"]+){2}\?at=[0-9a-f]+
|
||||||
|
|
||||||
|
# gravatar
|
||||||
|
\bgravatar\.com/avatar/[0-9a-f]+
|
||||||
|
|
||||||
|
# ibm
|
||||||
|
[a-z.]*ibm\.com/[-_#=:%!?~.\\/\d\w]*
|
||||||
|
|
||||||
|
# imgur
|
||||||
|
\bimgur\.com/[^.]+
|
||||||
|
|
||||||
|
# Internet Archive
|
||||||
|
\barchive\.org/web/\d+/(?:[-\w.?,'/\\+&%$#_:]*)
|
||||||
|
|
||||||
|
# discord
|
||||||
|
/discord(?:app\.com|\.gg)/(?:invite/)?[a-zA-Z0-9]{7,}
|
||||||
|
|
||||||
|
# Disqus
|
||||||
|
\bdisqus\.com/[-\w/%.()!?&=_]*
|
||||||
|
|
||||||
|
# medium link
|
||||||
|
\blink\.medium\.com/[a-zA-Z0-9]+
|
||||||
|
# medium
|
||||||
|
\bmedium\.com/\@?[^/\s"]+/[-\w]+
|
||||||
|
|
||||||
|
# microsoft
|
||||||
|
\b(?:https?://|)(?:(?:download\.visualstudio|docs|msdn2?|research)\.microsoft|blogs\.msdn)\.com/[-_a-zA-Z0-9()=./%]*
|
||||||
|
# powerbi
|
||||||
|
\bapp\.powerbi\.com/reportEmbed/[^"' ]*
|
||||||
|
# vs devops
|
||||||
|
\bvisualstudio.com(?::443|)/[-\w/?=%&.]*
|
||||||
|
# microsoft store
|
||||||
|
\bmicrosoft\.com/store/apps/\w+
|
||||||
|
|
||||||
|
# mvnrepository.com
|
||||||
|
\bmvnrepository\.com/[-0-9a-z./]+
|
||||||
|
|
||||||
|
# now.sh
|
||||||
|
/[0-9a-z-.]+\.now\.sh\b
|
||||||
|
|
||||||
|
# oracle
|
||||||
|
\bdocs\.oracle\.com/[-0-9a-zA-Z./_?#&=]*
|
||||||
|
|
||||||
|
# chromatic.com
|
||||||
|
/\S+.chromatic.com\S*[")]
|
||||||
|
|
||||||
|
# codacy
|
||||||
|
\bapi\.codacy\.com/project/badge/Grade/[0-9a-f]+
|
||||||
|
|
||||||
|
# compai
|
||||||
|
\bcompai\.pub/v1/png/[0-9a-f]+
|
||||||
|
|
||||||
|
# mailgun api
|
||||||
|
\.api\.mailgun\.net/v3/domains/[0-9a-z]+\.mailgun.org/messages/[0-9a-zA-Z=@]*
|
||||||
|
# mailgun
|
||||||
|
\b[0-9a-z]+.mailgun.org
|
||||||
|
|
||||||
|
# /message-id/
|
||||||
|
/message-id/[-\w@./%]+
|
||||||
|
|
||||||
|
# Reddit
|
||||||
|
\breddit\.com/r/[/\w_]*
|
||||||
|
|
||||||
|
# requestb.in
|
||||||
|
\brequestb\.in/[0-9a-z]+
|
||||||
|
|
||||||
|
# sched
|
||||||
|
\b[a-z0-9]+\.sched\.com\b
|
||||||
|
|
||||||
|
# Slack url
|
||||||
|
slack://[a-zA-Z0-9?&=]+
|
||||||
|
# Slack
|
||||||
|
\bslack\.com/[-0-9a-zA-Z/_~?&=.]*
|
||||||
|
# Slack edge
|
||||||
|
\bslack-edge\.com/[-a-zA-Z0-9?&=%./]+
|
||||||
|
# Slack images
|
||||||
|
\bslack-imgs\.com/[-a-zA-Z0-9?&=%.]+
|
||||||
|
|
||||||
|
# shields.io
|
||||||
|
\bshields\.io/[-\w/%?=&.:+;,]*
|
||||||
|
|
||||||
|
# stackexchange -- https://stackexchange.com/feeds/sites
|
||||||
|
\b(?:askubuntu|serverfault|stack(?:exchange|overflow)|superuser).com/(?:questions/\w+/[-\w]+|a/)
|
||||||
|
|
||||||
|
# Sentry
|
||||||
|
[0-9a-f]{32}\@o\d+\.ingest\.sentry\.io\b
|
||||||
|
|
||||||
|
# Twitter markdown
|
||||||
|
\[\@[^[/\]:]*?\]\(https://twitter.com/[^/\s"')]*(?:/status/\d+(?:\?[-_0-9a-zA-Z&=]*|)|)\)
|
||||||
|
# Twitter hashtag
|
||||||
|
\btwitter\.com/hashtag/[\w?_=&]*
|
||||||
|
# Twitter status
|
||||||
|
\btwitter\.com/[^/\s"')]*(?:/status/\d+(?:\?[-_0-9a-zA-Z&=]*|)|)
|
||||||
|
# Twitter profile images
|
||||||
|
\btwimg\.com/profile_images/[_\w./]*
|
||||||
|
# Twitter media
|
||||||
|
\btwimg\.com/media/[-_\w./?=]*
|
||||||
|
# Twitter link shortened
|
||||||
|
\bt\.co/\w+
|
||||||
|
|
||||||
|
# facebook
|
||||||
|
\bfburl\.com/[0-9a-z_]+
|
||||||
|
# facebook CDN
|
||||||
|
\bfbcdn\.net/[\w/.,]*
|
||||||
|
# facebook watch
|
||||||
|
\bfb\.watch/[0-9A-Za-z]+
|
||||||
|
|
||||||
|
# dropbox
|
||||||
|
\bdropbox\.com/sh?/[^/\s"]+/[-0-9A-Za-z_.%?=&;]+
|
||||||
|
|
||||||
|
# ipfs protocol
|
||||||
|
ipfs://[0-9a-z]*
|
||||||
|
# ipfs url
|
||||||
|
/ipfs/[0-9a-z]*
|
||||||
|
|
||||||
|
# w3
|
||||||
|
\bw3\.org/[-0-9a-zA-Z/#.]+
|
||||||
|
|
||||||
|
# loom
|
||||||
|
\bloom\.com/embed/[0-9a-f]+
|
||||||
|
|
||||||
|
# regex101
|
||||||
|
\bregex101\.com/r/[^/\s"]+/\d+
|
||||||
|
|
||||||
|
# figma
|
||||||
|
\bfigma\.com/file(?:/[0-9a-zA-Z]+/)+
|
||||||
|
|
||||||
|
# freecodecamp.org
|
||||||
|
\bfreecodecamp\.org/[-\w/.]+
|
||||||
|
|
||||||
|
# image.tmdb.org
|
||||||
|
\bimage\.tmdb\.org/[/\w.]+
|
||||||
|
|
||||||
|
# mermaid
|
||||||
|
\bmermaid\.ink/img/[-\w]+|\bmermaid-js\.github\.io/mermaid-live-editor/#/edit/[-\w]+
|
||||||
|
|
||||||
|
# Wikipedia
|
||||||
|
\ben\.wikipedia\.org/wiki/[-\w%.#]+
|
||||||
|
|
||||||
|
# gitweb
|
||||||
|
[^"\s]+/gitweb/\S+;h=[0-9a-f]+
|
||||||
|
|
||||||
|
# HyperKitty lists
|
||||||
|
/archives/list/[^@/]+\@[^/\s"]*/message/[^/\s"]*/
|
||||||
|
|
||||||
|
# lists
|
||||||
|
/thread\.html/[^"\s]+
|
||||||
|
|
||||||
|
# list-management
|
||||||
|
\blist-manage\.com/subscribe(?:[?&](?:u|id)=[0-9a-f]+)+
|
||||||
|
|
||||||
|
# kubectl.kubernetes.io/last-applied-configuration
|
||||||
|
"kubectl.kubernetes.io/last-applied-configuration": ".*"
|
||||||
|
|
||||||
|
# pgp
|
||||||
|
\bgnupg\.net/pks/lookup[?&=0-9a-zA-Z]*
|
||||||
|
|
||||||
|
# Spotify
|
||||||
|
\bopen\.spotify\.com/embed/playlist/\w+
|
||||||
|
|
||||||
|
# Mastodon
|
||||||
|
\bmastodon\.[-a-z.]*/(?:media/|\@)[?&=0-9a-zA-Z_]*
|
||||||
|
|
||||||
|
# scastie
|
||||||
|
\bscastie\.scala-lang\.org/[^/]+/\w+
|
||||||
|
|
||||||
|
# images.unsplash.com
|
||||||
|
\bimages\.unsplash\.com/(?:(?:flagged|reserve)/|)[-\w./%?=%&.;]+
|
||||||
|
|
||||||
|
# pastebin
|
||||||
|
\bpastebin\.com/[\w/]+
|
||||||
|
|
||||||
|
# heroku
|
||||||
|
\b\w+\.heroku\.com/source/archive/\w+
|
||||||
|
|
||||||
|
# quip
|
||||||
|
\b\w+\.quip\.com/\w+(?:(?:#|/issues/)\w+)?
|
||||||
|
|
||||||
|
# badgen.net
|
||||||
|
\bbadgen\.net/badge/[^")\]'\s]+
|
||||||
|
|
||||||
|
# statuspage.io
|
||||||
|
\w+\.statuspage\.io\b
|
||||||
|
|
||||||
|
# media.giphy.com
|
||||||
|
\bmedia\.giphy\.com/media/[^/]+/[\w.?&=]+
|
||||||
|
|
||||||
|
# tinyurl
|
||||||
|
\btinyurl\.com/\w+
|
||||||
|
|
||||||
|
# getopts
|
||||||
|
\bgetopts\s+(?:"[^"]+"|'[^']+')
|
||||||
|
|
||||||
|
# ANSI color codes
|
||||||
|
(?:\\(?:u00|x)1b|\x1b)\[\d+(?:;\d+|)m
|
||||||
|
|
||||||
|
# URL escaped characters
|
||||||
|
\%[0-9A-F][A-F]
|
||||||
|
# IPv6
|
||||||
|
\b(?:[0-9a-fA-F]{0,4}:){3,7}[0-9a-fA-F]{0,4}\b
|
||||||
|
# c99 hex digits (not the full format, just one I've seen)
|
||||||
|
0x[0-9a-fA-F](?:\.[0-9a-fA-F]*|)[pP]
|
||||||
|
# Punycode
|
||||||
|
\bxn--[-0-9a-z]+
|
||||||
|
# sha
|
||||||
|
sha\d+:[0-9]*[a-f]{3,}[0-9a-f]*
|
||||||
|
# sha-... -- uses a fancy capture
|
||||||
|
(['"]|")[0-9a-f]{40,}\g{-1}
|
||||||
|
# hex runs
|
||||||
|
\b[0-9a-fA-F]{16,}\b
|
||||||
|
# hex in url queries
|
||||||
|
=[0-9a-fA-F]*?(?:[A-F]{3,}|[a-f]{3,})[0-9a-fA-F]*?&
|
||||||
|
# ssh
|
||||||
|
(?:ssh-\S+|-nistp256) [-a-zA-Z=;:/0-9+]{12,}
|
||||||
|
|
||||||
|
# PGP
|
||||||
|
\b(?:[0-9A-F]{4} ){9}[0-9A-F]{4}\b
|
||||||
|
# GPG keys
|
||||||
|
\b(?:[0-9A-F]{4} ){5}(?: [0-9A-F]{4}){5}\b
|
||||||
|
# Well known gpg keys
|
||||||
|
.well-known/openpgpkey/[\w./]+
|
||||||
|
|
||||||
|
# uuid:
|
||||||
|
\b[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}\b
|
||||||
|
# hex digits including css/html color classes:
|
||||||
|
(?:[\\0][xX]|\\u|[uU]\+|#x?|\%23)[0-9_a-fA-FgGrR]*?[a-fA-FgGrR]{2,}[0-9_a-fA-FgGrR]*(?:[uUlL]{0,3}|u\d+)\b
|
||||||
|
# integrity
|
||||||
|
integrity="sha\d+-[-a-zA-Z=;:/0-9+]{40,}"
|
||||||
|
|
||||||
|
# https://www.gnu.org/software/groff/manual/groff.html
|
||||||
|
# man troff content
|
||||||
|
\\f[BCIPR]
|
||||||
|
# '
|
||||||
|
\\\(aq
|
||||||
|
|
||||||
|
# .desktop mime types
|
||||||
|
^MimeTypes?=.*$
|
||||||
|
# .desktop localized entries
|
||||||
|
^[A-Z][a-z]+\[[a-z]+\]=.*$
|
||||||
|
# Localized .desktop content
|
||||||
|
Name\[[^\]]+\]=.*
|
||||||
|
|
||||||
|
# IServiceProvider
|
||||||
|
\bI(?=(?:[A-Z][a-z]{2,})+\b)
|
||||||
|
|
||||||
|
# crypt
|
||||||
|
"\$2[ayb]\$.{56}"
|
||||||
|
|
||||||
|
# scrypt / argon
|
||||||
|
\$(?:scrypt|argon\d+[di]*)\$\S+
|
||||||
|
|
||||||
|
# Input to GitHub JSON
|
||||||
|
content: "[-a-zA-Z=;:/0-9+]*="
|
||||||
|
|
||||||
|
# Python stringprefix / binaryprefix
|
||||||
|
# Note that there's a high false positive rate, remove the `?=` and search for the regex to see if the matches seem like reasonable strings
|
||||||
|
(?<!')\b(?:B|BR|Br|F|FR|Fr|R|RB|RF|Rb|Rf|U|UR|Ur|b|bR|br|f|fR|fr|r|rB|rF|rb|rf|u|uR|ur)'(?:[A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,})
|
||||||
|
|
||||||
|
# Regular expressions for (P|p)assword
|
||||||
|
\([A-Z]\|[a-z]\)[a-z]+
|
||||||
|
|
||||||
|
# JavaScript regular expressions
|
||||||
|
# javascript test regex
|
||||||
|
/.*/[gim]*\.test\(
|
||||||
|
# javascript match regex
|
||||||
|
\.match\(/[^/\s"]*/[gim]*\s*
|
||||||
|
# javascript match regex
|
||||||
|
\.match\(/\\[b].*?/[gim]*\s*\)(?:;|$)
|
||||||
|
# javascript regex
|
||||||
|
^\s*/\\[b].*/[gim]*\s*(?:\)(?:;|$)|,$)
|
||||||
|
# javascript replace regex
|
||||||
|
\.replace\(/[^/\s"]*/[gim]*\s*,
|
||||||
|
|
||||||
|
# Go regular expressions
|
||||||
|
regexp?\.MustCompile\(`[^`]*`\)
|
||||||
|
|
||||||
|
# sed regular expressions
|
||||||
|
sed 's/(?:[^/]*?[a-zA-Z]{3,}[^/]*?/){2}
|
||||||
|
|
||||||
|
# go install
|
||||||
|
go install(?:\s+[a-z]+\.[-@\w/.]+)+
|
||||||
|
|
||||||
|
# kubernetes pod status lists
|
||||||
|
# https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase
|
||||||
|
\w+(?:-\w+)+\s+\d+/\d+\s+(?:Running|Pending|Succeeded|Failed|Unknown)\s+
|
||||||
|
|
||||||
|
# kubectl - pods in CrashLoopBackOff
|
||||||
|
\w+-[0-9a-f]+-\w+\s+\d+/\d+\s+CrashLoopBackOff\s+
|
||||||
|
|
||||||
|
# kubernetes object suffix
|
||||||
|
-[0-9a-f]{10}-\w{5}\s
|
||||||
|
|
||||||
|
# posthog secrets
|
||||||
|
posthog\.init\((['"])phc_[^"',]+\g{-1},
|
||||||
|
|
||||||
|
# xcode
|
||||||
|
|
||||||
|
# xcodeproject scenes
|
||||||
|
(?:Controller|ID|id)="\w{3}-\w{2}-\w{3}"
|
||||||
|
|
||||||
|
# xcode api botches
|
||||||
|
customObjectInstantitationMethod
|
||||||
|
|
||||||
|
# font awesome classes
|
||||||
|
\.fa-[-a-z0-9]+
|
||||||
|
|
||||||
|
# Update Lorem based on your content (requires `ge` and `w` from https://github.com/jsoref/spelling; and `review` from https://github.com/check-spelling/check-spelling/wiki/Looking-for-items-locally )
|
||||||
|
# grep '^[^#].*lorem' .github/actions/spelling/patterns.txt|perl -pne 's/.*i..\?://;s/\).*//' |tr '|' "\n"|sort -f |xargs -n1 ge|perl -pne 's/^[^:]*://'|sort -u|w|sed -e 's/ .*//'|w|review -
|
||||||
|
# Warning, while `(?i)` is very neat and fancy, if you have some binary files that aren't proper unicode, you might run into:
|
||||||
|
## Operation "substitution (s///)" returns its argument for non-Unicode code point 0x1C19AE (the code point will vary).
|
||||||
|
## You could manually change `(?i)X...` to use `[Xx]...`
|
||||||
|
## or you could add the files to your `excludes` file (a version after 0.0.19 should identify the file path)
|
||||||
|
# Lorem
|
||||||
|
(?:\w|\s|[,.])*\b(?i)(?:amet|consectetur|cursus|dolor|eros|ipsum|lacus|libero|ligula|lorem|magna|neque|nulla|suscipit|tempus)\b(?:\w|\s|[,.])*
|
||||||
|
|
||||||
|
# Non-English
|
||||||
|
[a-zA-Z]*[ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź][a-zA-Z]{3}[a-zA-ZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź]*
|
||||||
|
|
||||||
|
# French
|
||||||
|
# This corpus only had capital letters, but you probably want lowercase ones as well.
|
||||||
|
\b[LN]'+[a-z]{2,}\b
|
||||||
|
|
||||||
|
# latex
|
||||||
|
\\(?:n(?:ew|ormal|osub)|r(?:enew)|t(?:able(?:of|)|he|itle))(?=[a-z]+)
|
||||||
|
|
||||||
|
# the negative lookahead here is to allow catching 'templatesz' as a misspelling
|
||||||
|
# but to otherwise recognize a Windows path with \templates\foo.template or similar:
|
||||||
|
\\(?:necessary|r(?:eport|esolve[dr]?|esult)|t(?:arget|emplates?))(?![a-z])
|
||||||
|
# ignore long runs of a single character:
|
||||||
|
\b([A-Za-z])\g{-1}{3,}\b
|
||||||
|
# Note that the next example is no longer necessary if you are using
|
||||||
|
# to match a string starting with a `#`, use a character-class:
|
||||||
|
[#]backwards
|
||||||
|
# version suffix <word>v#
|
||||||
|
(?:(?<=[A-Z]{2})V|(?<=[a-z]{2}|[A-Z]{2})v)\d+(?:\b|(?=[a-zA-Z_]))
|
||||||
|
# Compiler flags (Scala)
|
||||||
|
(?:^|[\t ,>"'`=(])-J-[DPWXY](?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,})
|
||||||
|
# Compiler flags
|
||||||
|
#(?:^|[\t ,"'`=(])-[DPWXYLlf](?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,})
|
||||||
|
|
||||||
|
# Compiler flags (linker)
|
||||||
|
,-B
|
||||||
|
# curl arguments
|
||||||
|
\b(?:\\n|)curl(?:\s+-[a-zA-Z]{1,2}\b)*(?:\s+-[a-zA-Z]{3,})(?:\s+-[a-zA-Z]+)*
|
||||||
|
# set arguments
|
||||||
|
\bset(?:\s+-[abefimouxE]{1,2})*\s+-[abefimouxE]{3,}(?:\s+-[abefimouxE]+)*
|
||||||
|
# tar arguments
|
||||||
|
\b(?:\\n|)g?tar(?:\.exe|)(?:(?:\s+--[-a-zA-Z]+|\s+-[a-zA-Z]+|\s[ABGJMOPRSUWZacdfh-pr-xz]+\b)(?:=[^ ]*|))+
|
||||||
|
# tput arguments -- https://man7.org/linux/man-pages/man5/terminfo.5.html -- technically they can be more than 5 chars long...
|
||||||
|
\btput\s+(?:(?:-[SV]|-T\s*\w+)\s+)*\w{3,5}\b
|
||||||
|
# macOS temp folders
|
||||||
|
/var/folders/\w\w/[+\w]+/(?:T|-Caches-)/
|
||||||
48
.github/actions/spelling/excludes.txt
vendored
48
.github/actions/spelling/excludes.txt
vendored
@@ -1,28 +1,39 @@
|
|||||||
|
# See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-excludes
|
||||||
(?:(?i)\.png$)
|
(?:(?i)\.png$)
|
||||||
|
(?:^|/)(?i)COPYRIGHT
|
||||||
|
(?:^|/)(?i)LICEN[CS]E
|
||||||
|
(?:^|/)3rdparty/
|
||||||
(?:^|/)dirs$
|
(?:^|/)dirs$
|
||||||
(?:^|/)go\.mod$
|
(?:^|/)go\.mod$
|
||||||
(?:^|/)go\.sum$
|
(?:^|/)go\.sum$
|
||||||
(?:^|/)package-lock\.json$
|
(?:^|/)package(?:-lock|)\.json$
|
||||||
(?:^|/)sources(?:|\.dep)$
|
(?:^|/)sources(?:|\.dep)$
|
||||||
SUMS$
|
(?:^|/)vendor/
|
||||||
|
\.a$
|
||||||
\.ai$
|
\.ai$
|
||||||
|
\.avi$
|
||||||
\.bmp$
|
\.bmp$
|
||||||
|
\.bz2$
|
||||||
\.cer$
|
\.cer$
|
||||||
\.class$
|
\.class$
|
||||||
\.crl$
|
\.crl$
|
||||||
\.crt$
|
\.crt$
|
||||||
\.csr$
|
\.csr$
|
||||||
\.dll$
|
\.dll$
|
||||||
|
\.docx?$
|
||||||
|
\.drawio$
|
||||||
\.DS_Store$
|
\.DS_Store$
|
||||||
\.eot$
|
\.eot$
|
||||||
\.eps$
|
\.eps$
|
||||||
\.exe$
|
\.exe$
|
||||||
\.gif$
|
\.gif$
|
||||||
|
\.gitattributes$
|
||||||
\.graffle$
|
\.graffle$
|
||||||
\.gz$
|
\.gz$
|
||||||
\.icns$
|
\.icns$
|
||||||
\.ico$
|
\.ico$
|
||||||
\.jar$
|
\.jar$
|
||||||
|
\.jks$
|
||||||
\.jpeg$
|
\.jpeg$
|
||||||
\.jpg$
|
\.jpg$
|
||||||
\.key$
|
\.key$
|
||||||
@@ -30,28 +41,53 @@ SUMS$
|
|||||||
\.lock$
|
\.lock$
|
||||||
\.map$
|
\.map$
|
||||||
\.min\..
|
\.min\..
|
||||||
|
\.mod$
|
||||||
\.mp3$
|
\.mp3$
|
||||||
\.mp4$
|
\.mp4$
|
||||||
|
\.o$
|
||||||
|
\.ocf$
|
||||||
\.otf$
|
\.otf$
|
||||||
\.pbxproj$
|
\.pbxproj$
|
||||||
\.pdf$
|
\.pdf$
|
||||||
\.pem$
|
\.pem$
|
||||||
|
\.png$
|
||||||
\.psd$
|
\.psd$
|
||||||
|
\.pyc$
|
||||||
\.runsettings$
|
\.runsettings$
|
||||||
|
\.s$
|
||||||
\.sig$
|
\.sig$
|
||||||
\.so$
|
\.so$
|
||||||
\.svg$
|
\.svg$
|
||||||
\.svgz$
|
\.svgz$
|
||||||
|
\.svgz?$
|
||||||
\.tar$
|
\.tar$
|
||||||
\.tgz$
|
\.tgz$
|
||||||
|
\.tiff?$
|
||||||
\.ttf$
|
\.ttf$
|
||||||
\.vsdx$
|
\.vsdx$
|
||||||
|
\.wav$
|
||||||
|
\.webm$
|
||||||
|
\.webp$
|
||||||
\.woff
|
\.woff
|
||||||
|
\.woff2?$
|
||||||
\.xcf$
|
\.xcf$
|
||||||
\.xls
|
\.xls
|
||||||
|
\.xlsx?$
|
||||||
\.xpm$
|
\.xpm$
|
||||||
\.yml$
|
\.yml$
|
||||||
\.zip$
|
\.zip$
|
||||||
|
^\.github/actions/spelling/
|
||||||
|
^\.github/fabricbot.json$
|
||||||
|
^\.gitignore$
|
||||||
|
^\Q.git-blame-ignore-revs\E$
|
||||||
|
^\Q.github/workflows/spelling.yml\E$
|
||||||
|
^\Qdoc/reference/windows-terminal-logo.ans\E$
|
||||||
|
^\Qsamples/ConPTY/EchoCon/EchoCon/EchoCon.vcxproj.filters\E$
|
||||||
|
^\Qsrc/host/exe/Host.EXE.vcxproj.filters\E$
|
||||||
|
^\Qsrc/host/ft_host/chafa.txt\E$
|
||||||
|
^\Qsrc/tools/closetest/CloseTest.vcxproj.filters\E$
|
||||||
|
^\XamlStyler.json$
|
||||||
|
^build/config/
|
||||||
^consolegit2gitfilters\.json$
|
^consolegit2gitfilters\.json$
|
||||||
^dep/
|
^dep/
|
||||||
^doc/reference/master-sequence-list.csv$
|
^doc/reference/master-sequence-list.csv$
|
||||||
@@ -61,12 +97,14 @@ SUMS$
|
|||||||
^src/host/runft\.bat$
|
^src/host/runft\.bat$
|
||||||
^src/host/runut\.bat$
|
^src/host/runut\.bat$
|
||||||
^src/interactivity/onecore/BgfxEngine\.
|
^src/interactivity/onecore/BgfxEngine\.
|
||||||
|
^src/renderer/atlas/
|
||||||
^src/renderer/wddmcon/WddmConRenderer\.
|
^src/renderer/wddmcon/WddmConRenderer\.
|
||||||
^src/terminal/adapter/ut_adapter/run\.bat$
|
^src/terminal/adapter/ut_adapter/run\.bat$
|
||||||
^src/terminal/parser/delfuzzpayload\.bat$
|
^src/terminal/parser/delfuzzpayload\.bat$
|
||||||
^src/terminal/parser/ft_fuzzer/run\.bat$
|
^src/terminal/parser/ft_fuzzer/run\.bat$
|
||||||
^src/terminal/parser/ft_fuzzer/VTCommandFuzzer\.cpp$
|
^src/terminal/parser/ft_fuzzer/VTCommandFuzzer\.cpp$
|
||||||
^src/terminal/parser/ft_fuzzwrapper/run\.bat$
|
^src/terminal/parser/ft_fuzzwrapper/run\.bat$
|
||||||
|
^src/terminal/parser/ut_parser/Base64Test.cpp$
|
||||||
^src/terminal/parser/ut_parser/run\.bat$
|
^src/terminal/parser/ut_parser/run\.bat$
|
||||||
^src/tools/integrity/packageuwp/ConsoleUWP\.appxSources$
|
^src/tools/integrity/packageuwp/ConsoleUWP\.appxSources$
|
||||||
^src/tools/lnkd/lnkd\.bat$
|
^src/tools/lnkd/lnkd\.bat$
|
||||||
@@ -74,6 +112,6 @@ SUMS$
|
|||||||
^src/tools/texttests/fira\.txt$
|
^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$
|
^src/types/ut_types/UtilsTests.cpp$
|
||||||
^\.github/actions/spelling/
|
^tools/ReleaseEngineering/ServicingPipeline.ps1$
|
||||||
^\.gitignore$
|
ignore$
|
||||||
^\XamlStyler.json$
|
SUMS$
|
||||||
|
|||||||
8
.github/actions/spelling/expect/alphabet.txt
vendored
8
.github/actions/spelling/expect/alphabet.txt
vendored
@@ -5,26 +5,19 @@ AAAAAABBBBBBCCC
|
|||||||
AAAAABBBBBBCCC
|
AAAAABBBBBBCCC
|
||||||
abcd
|
abcd
|
||||||
abcd
|
abcd
|
||||||
abcde
|
|
||||||
abcdef
|
|
||||||
ABCDEFG
|
|
||||||
ABCDEFGH
|
|
||||||
ABCDEFGHIJ
|
ABCDEFGHIJ
|
||||||
abcdefghijk
|
abcdefghijk
|
||||||
ABCDEFGHIJKLMNO
|
ABCDEFGHIJKLMNO
|
||||||
abcdefghijklmnop
|
abcdefghijklmnop
|
||||||
ABCDEFGHIJKLMNOPQRST
|
ABCDEFGHIJKLMNOPQRST
|
||||||
abcdefghijklmnopqrstuvwxyz
|
|
||||||
ABCG
|
ABCG
|
||||||
ABE
|
ABE
|
||||||
abf
|
abf
|
||||||
BBBBB
|
BBBBB
|
||||||
BBBBBBBB
|
BBBBBBBB
|
||||||
BBBBBBBBBBBBBBDDDD
|
|
||||||
BBBBBCCC
|
BBBBBCCC
|
||||||
BBBBCCCCC
|
BBBBCCCCC
|
||||||
BBGGRR
|
BBGGRR
|
||||||
CCE
|
|
||||||
EFG
|
EFG
|
||||||
EFGh
|
EFGh
|
||||||
QQQQQQQQQQABCDEFGHIJ
|
QQQQQQQQQQABCDEFGHIJ
|
||||||
@@ -33,7 +26,6 @@ QQQQQQQQQQABCDEFGHIJKLMNOPQRSTQQQQQQQQQQ
|
|||||||
QQQQQQQQQQABCDEFGHIJPQRSTQQQQQQQQQQ
|
QQQQQQQQQQABCDEFGHIJPQRSTQQQQQQQQQQ
|
||||||
qrstuvwxyz
|
qrstuvwxyz
|
||||||
qwerty
|
qwerty
|
||||||
QWERTYUIOP
|
|
||||||
qwertyuiopasdfg
|
qwertyuiopasdfg
|
||||||
YYYYYYYDDDDDDDDDDD
|
YYYYYYYDDDDDDDDDDD
|
||||||
ZAAZZ
|
ZAAZZ
|
||||||
|
|||||||
918
.github/actions/spelling/expect/expect.txt
vendored
918
.github/actions/spelling/expect/expect.txt
vendored
File diff suppressed because it is too large
Load Diff
12
.github/actions/spelling/expect/web.txt
vendored
12
.github/actions/spelling/expect/web.txt
vendored
@@ -1,16 +1,6 @@
|
|||||||
http
|
|
||||||
www
|
|
||||||
ecma
|
|
||||||
rapidtables
|
|
||||||
WCAG
|
WCAG
|
||||||
freedesktop
|
|
||||||
ycombinator
|
|
||||||
robertelder
|
|
||||||
kovidgoyal
|
|
||||||
leonerd
|
|
||||||
fixterms
|
|
||||||
winui
|
winui
|
||||||
appshellintegration
|
appshellintegration
|
||||||
cppreference
|
mdtauk
|
||||||
gfycat
|
gfycat
|
||||||
Guake
|
Guake
|
||||||
|
|||||||
62
.github/actions/spelling/line_forbidden.patterns
vendored
Normal file
62
.github/actions/spelling/line_forbidden.patterns
vendored
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
# reject `m_data` as there's a certain OS which has evil defines that break things if it's used elsewhere
|
||||||
|
# \bm_data\b
|
||||||
|
|
||||||
|
# If you have a framework that uses `it()` for testing and `fit()` for debugging a specific test,
|
||||||
|
# you might not want to check in code where you were debugging w/ `fit()`, in which case, you might want
|
||||||
|
# to use this:
|
||||||
|
#\bfit\(
|
||||||
|
|
||||||
|
# s.b. GitHub
|
||||||
|
\bGithub\b
|
||||||
|
|
||||||
|
# s.b. GitLab
|
||||||
|
\bGitlab\b
|
||||||
|
|
||||||
|
# s.b. JavaScript
|
||||||
|
\bJavascript\b
|
||||||
|
|
||||||
|
# s.b. Microsoft
|
||||||
|
\bMicroSoft\b
|
||||||
|
|
||||||
|
# s.b. another
|
||||||
|
\ban[- ]other\b
|
||||||
|
|
||||||
|
# s.b. greater than
|
||||||
|
\bgreater then\b
|
||||||
|
|
||||||
|
# s.b. into
|
||||||
|
#\sin to\s
|
||||||
|
|
||||||
|
# s.b. opt-in
|
||||||
|
\sopt in\s
|
||||||
|
|
||||||
|
# s.b. less than
|
||||||
|
\bless then\b
|
||||||
|
|
||||||
|
# s.b. otherwise
|
||||||
|
\bother[- ]wise\b
|
||||||
|
|
||||||
|
# s.b. nonexistent
|
||||||
|
\bnon existing\b
|
||||||
|
\b[Nn]o[nt][- ]existent\b
|
||||||
|
|
||||||
|
# s.b. preexisting
|
||||||
|
[Pp]re[- ]existing
|
||||||
|
|
||||||
|
# s.b. preempt
|
||||||
|
[Pp]re[- ]empt\b
|
||||||
|
|
||||||
|
# s.b. preemptively
|
||||||
|
[Pp]re[- ]emptively
|
||||||
|
|
||||||
|
# s.b. reentrancy
|
||||||
|
[Rr]e[- ]entrancy
|
||||||
|
|
||||||
|
# s.b. reentrant
|
||||||
|
[Rr]e[- ]entrant
|
||||||
|
|
||||||
|
# s.b. workaround(s)
|
||||||
|
#\bwork[- ]arounds?\b
|
||||||
|
|
||||||
|
# Reject duplicate words
|
||||||
|
\s([A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,})\s\g{-1}\s
|
||||||
86
.github/actions/spelling/patterns/patterns.txt
vendored
86
.github/actions/spelling/patterns/patterns.txt
vendored
@@ -1,11 +1,6 @@
|
|||||||
https://(?:(?:[-a-zA-Z0-9?&=]*\.|)microsoft\.com)/[-a-zA-Z0-9?&=_#\/.]*
|
# See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns
|
||||||
https://aka\.ms/[-a-zA-Z0-9?&=\/_]*
|
|
||||||
https://www\.itscj\.ipsj\.or\.jp/iso-ir/[-0-9]+\.pdf
|
https?://\S+
|
||||||
https://www\.vt100\.net/docs/[-a-zA-Z0-9#_\/.]*
|
|
||||||
https://www.w3.org/[-a-zA-Z0-9?&=\/_#]*
|
|
||||||
https://(?:(?:www\.|)youtube\.com|youtu.be)/[-a-zA-Z0-9?&=]*
|
|
||||||
https://(?:[a-z-]+\.|)github(?:usercontent|)\.com/[-a-zA-Z0-9?%&=_\/.]*
|
|
||||||
https://www.xfree86.org/[-a-zA-Z0-9?&=\/_#]*
|
|
||||||
[Pp]ublicKeyToken="?[0-9a-fA-F]{16}"?
|
[Pp]ublicKeyToken="?[0-9a-fA-F]{16}"?
|
||||||
(?:[{"]|UniqueIdentifier>)[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}(?:[}"]|</UniqueIdentifier)
|
(?:[{"]|UniqueIdentifier>)[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}(?:[}"]|</UniqueIdentifier)
|
||||||
(?:0[Xx]|\\x|U\+|#)[a-f0-9A-FGgRr]{2,}[Uu]?[Ll]{0,2}\b
|
(?:0[Xx]|\\x|U\+|#)[a-f0-9A-FGgRr]{2,}[Uu]?[Ll]{0,2}\b
|
||||||
@@ -24,3 +19,78 @@ VERIFY_ARE_EQUAL\(L"[^"]+"
|
|||||||
std::memory_order_[\w]+
|
std::memory_order_[\w]+
|
||||||
D2DERR_SHADER_COMPILE_FAILED
|
D2DERR_SHADER_COMPILE_FAILED
|
||||||
TIL_FEATURE_[0-9A-Z_]+
|
TIL_FEATURE_[0-9A-Z_]+
|
||||||
|
vcvars\w*
|
||||||
|
ROY\sG\.\sBIV
|
||||||
|
!(?:(?i)ESC)!\[
|
||||||
|
!(?:(?i)CSI)!(?:\d+(?:;\d+|)m|[ABCDF])
|
||||||
|
|
||||||
|
# Python stringprefix / binaryprefix
|
||||||
|
\b(?:B|BR|Br|F|FR|Fr|R|RB|RF|Rb|Rf|U|UR|Ur|b|bR|br|f|fR|fr|r|rB|rF|rb|rf|u|uR|ur)'
|
||||||
|
|
||||||
|
# Automatically suggested patterns
|
||||||
|
# hit-count: 3831 file-count: 582
|
||||||
|
# IServiceProvider
|
||||||
|
\bI(?=(?:[A-Z][a-z]{2,})+\b)
|
||||||
|
|
||||||
|
# hit-count: 71 file-count: 35
|
||||||
|
# Compiler flags
|
||||||
|
(?:^|[\t ,"'`=(])-[D](?=[A-Z]{2,}|[A-Z][a-z])
|
||||||
|
(?:^|[\t ,"'`=(])-[X](?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,})
|
||||||
|
|
||||||
|
# hit-count: 41 file-count: 28
|
||||||
|
# version suffix <word>v#
|
||||||
|
(?:(?<=[A-Z]{2})V|(?<=[a-z]{2}|[A-Z]{2})v)\d+(?:\b|(?=[a-zA-Z_]))
|
||||||
|
|
||||||
|
# hit-count: 20 file-count: 9
|
||||||
|
# hex runs
|
||||||
|
\b[0-9a-fA-F]{16,}\b
|
||||||
|
|
||||||
|
# hit-count: 10 file-count: 7
|
||||||
|
# uuid:
|
||||||
|
\b[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}\b
|
||||||
|
|
||||||
|
# hit-count: 4 file-count: 4
|
||||||
|
# mailto urls
|
||||||
|
mailto:[-a-zA-Z=;:/?%&0-9+@.]{3,}
|
||||||
|
|
||||||
|
# hit-count: 4 file-count: 1
|
||||||
|
# ANSI color codes
|
||||||
|
(?:\\(?:u00|x)1b|\x1b)\[\d+(?:;\d+|)m
|
||||||
|
|
||||||
|
# hit-count: 2 file-count: 1
|
||||||
|
# latex
|
||||||
|
\\(?:n(?:ew|ormal|osub)|r(?:enew)|t(?:able(?:of|)|he|itle))(?=[a-z]+)
|
||||||
|
|
||||||
|
# hit-count: 1 file-count: 1
|
||||||
|
# hex digits including css/html color classes:
|
||||||
|
(?:[\\0][xX]|\\u|[uU]\+|#x?|\%23)[0-9_a-fA-FgGrR]*?[a-fA-FgGrR]{2,}[0-9_a-fA-FgGrR]*(?:[uUlL]{0,3}|u\d+)\b
|
||||||
|
|
||||||
|
# hit-count: 1 file-count: 1
|
||||||
|
# Non-English
|
||||||
|
[a-zA-Z]*[ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź][a-zA-Z]{3}[a-zA-ZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź]*
|
||||||
|
|
||||||
|
# hit-count: 1 file-count: 1
|
||||||
|
# French
|
||||||
|
# This corpus only had capital letters, but you probably want lowercase ones as well.
|
||||||
|
\b[LN]'+[a-z]{2,}\b
|
||||||
|
|
||||||
|
# acceptable duplicates
|
||||||
|
# ls directory listings
|
||||||
|
[-bcdlpsw](?:[-r][-w][-sx]){3}\s+\d+\s+(\S+)\s+\g{-1}\s+\d+\s+
|
||||||
|
# C/idl types + English ...
|
||||||
|
\s(Guid|long|LONG|that) \g{-1}\s
|
||||||
|
|
||||||
|
# javadoc / .net
|
||||||
|
(?:[\\@](?:groupname|param)|(?:public|private)(?:\s+static|\s+readonly)*)\s+(\w+)\s+\g{-1}\s
|
||||||
|
|
||||||
|
# Commit message -- Signed-off-by and friends
|
||||||
|
^\s*(?:(?:Based-on-patch|Co-authored|Helped|Mentored|Reported|Reviewed|Signed-off)-by|Thanks-to): (?:[^<]*<[^>]*>|[^<]*)\s*$
|
||||||
|
|
||||||
|
# Autogenerated revert commit message
|
||||||
|
^This reverts commit [0-9a-f]{40}\.$
|
||||||
|
|
||||||
|
# vtmode
|
||||||
|
--vtmode\s+(\w+)\s+\g{-1}\s
|
||||||
|
|
||||||
|
# ignore long runs of a single character:
|
||||||
|
\b([A-Za-z])\g{-1}{3,}\b
|
||||||
|
|||||||
28
.github/actions/spelling/reject.txt
vendored
28
.github/actions/spelling/reject.txt
vendored
@@ -1,22 +1,12 @@
|
|||||||
^attache$
|
^attache$
|
||||||
^attacher$
|
^attacher$
|
||||||
^attachers$
|
^attachers$
|
||||||
^spae$
|
benefitting
|
||||||
^spaebook$
|
occurences?
|
||||||
^spaecraft$
|
^dependan.*
|
||||||
^spaed$
|
^oer$
|
||||||
^spaedom$
|
Sorce
|
||||||
^spaeing$
|
^[Ss]pae.*
|
||||||
^spaeings$
|
^untill$
|
||||||
^spae-man$
|
^untilling$
|
||||||
^spaeman$
|
^wether.*
|
||||||
^spaer$
|
|
||||||
^Spaerobee$
|
|
||||||
^spaes$
|
|
||||||
^spaewife$
|
|
||||||
^spaewoman$
|
|
||||||
^spaework$
|
|
||||||
^spaewright$
|
|
||||||
^wether$
|
|
||||||
^wethers$
|
|
||||||
^wetherteg$
|
|
||||||
|
|||||||
132
.github/workflows/spelling2.yml
vendored
132
.github/workflows/spelling2.yml
vendored
@@ -1,20 +1,134 @@
|
|||||||
# spelling.yml is blocked per https://github.com/check-spelling/check-spelling/security/advisories/GHSA-g86g-chm8-7r2p
|
# spelling.yml is blocked per https://github.com/check-spelling/check-spelling/security/advisories/GHSA-g86g-chm8-7r2p
|
||||||
name: Spell checking
|
name: Spell checking
|
||||||
|
|
||||||
|
# Comment management is handled through a secondary job, for details see:
|
||||||
|
# https://github.com/check-spelling/check-spelling/wiki/Feature%3A-Restricted-Permissions
|
||||||
|
#
|
||||||
|
# `jobs.comment-push` runs when a push is made to a repository and the `jobs.spelling` job needs to make a comment
|
||||||
|
# (in odd cases, it might actually run just to collapse a commment, but that's fairly rare)
|
||||||
|
# it needs `contents: write` in order to add a comment.
|
||||||
|
#
|
||||||
|
# `jobs.comment-pr` runs when a pull_request is made to a repository and the `jobs.spelling` job needs to make a comment
|
||||||
|
# or collapse a comment (in the case where it had previously made a comment and now no longer needs to show a comment)
|
||||||
|
# it needs `pull-requests: write` in order to manipulate those comments.
|
||||||
|
|
||||||
|
# Updating pull request branches is managed via comment handling.
|
||||||
|
# For details, see: https://github.com/check-spelling/check-spelling/wiki/Feature:-Update-expect-list
|
||||||
|
#
|
||||||
|
# These elements work together to make it happen:
|
||||||
|
#
|
||||||
|
# `on.issue_comment`
|
||||||
|
# This event listens to comments by users asking to update the metadata.
|
||||||
|
#
|
||||||
|
# `jobs.update`
|
||||||
|
# This job runs in response to an issue_comment and will push a new commit
|
||||||
|
# to update the spelling metadata.
|
||||||
|
#
|
||||||
|
# `with.experimental_apply_changes_via_bot`
|
||||||
|
# Tells the action to support and generate messages that enable it
|
||||||
|
# to make a commit to update the spelling metadata.
|
||||||
|
#
|
||||||
|
# `with.ssh_key`
|
||||||
|
# In order to trigger workflows when the commit is made, you can provide a
|
||||||
|
# secret (typically, a write-enabled github deploy key).
|
||||||
|
#
|
||||||
|
# For background, see: https://github.com/check-spelling/check-spelling/wiki/Feature:-Update-with-deploy-key
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request_target:
|
|
||||||
push:
|
push:
|
||||||
|
branches:
|
||||||
|
- "**"
|
||||||
|
tags-ignore:
|
||||||
|
- "**"
|
||||||
|
pull_request_target:
|
||||||
|
branches:
|
||||||
|
- "**"
|
||||||
|
tags-ignore:
|
||||||
|
- "**"
|
||||||
|
types:
|
||||||
|
- 'opened'
|
||||||
|
- 'reopened'
|
||||||
|
- 'synchronize'
|
||||||
|
issue_comment:
|
||||||
|
types:
|
||||||
|
- 'created'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
spelling:
|
spelling:
|
||||||
name: Spell checking
|
name: Spell checking
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pull-requests: read
|
||||||
|
actions: read
|
||||||
|
outputs:
|
||||||
|
followup: ${{ steps.spelling.outputs.followup }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
if: "contains(github.event_name, 'pull_request') || github.event_name == 'push'"
|
||||||
|
concurrency:
|
||||||
|
group: spelling-${{ github.event.pull_request.number || github.ref }}
|
||||||
|
# note: If you use only_check_changed_files, you do not want cancel-in-progress
|
||||||
|
cancel-in-progress: true
|
||||||
steps:
|
steps:
|
||||||
- name: checkout-merge
|
- name: check-spelling
|
||||||
if: "contains(github.event_name, 'pull_request')"
|
id: spelling
|
||||||
uses: actions/checkout@v2
|
uses: check-spelling/check-spelling@v0.0.21
|
||||||
with:
|
with:
|
||||||
ref: refs/pull/${{github.event.pull_request.number}}/merge
|
suppress_push_for_open_pull_request: 1
|
||||||
- name: checkout
|
checkout: true
|
||||||
if: "!contains(github.event_name, 'pull_request')"
|
check_file_names: 1
|
||||||
uses: actions/checkout@v2
|
spell_check_this: check-spelling/spell-check-this@prerelease
|
||||||
- uses: check-spelling/check-spelling@v0.0.19
|
post_comment: 0
|
||||||
|
use_magic_file: 1
|
||||||
|
extra_dictionary_limit: 10
|
||||||
|
extra_dictionaries:
|
||||||
|
cspell:software-terms/src/software-terms.txt
|
||||||
|
cspell:python/src/python/python-lib.txt
|
||||||
|
cspell:node/node.txt
|
||||||
|
cspell:cpp/src/stdlib-c.txt
|
||||||
|
cspell:cpp/src/stdlib-cpp.txt
|
||||||
|
cspell:fullstack/fullstack.txt
|
||||||
|
cspell:filetypes/filetypes.txt
|
||||||
|
cspell:html/html.txt
|
||||||
|
cspell:cpp/src/compiler-msvc.txt
|
||||||
|
cspell:python/src/common/extra.txt
|
||||||
|
cspell:powershell/powershell.txt
|
||||||
|
cspell:aws/aws.txt
|
||||||
|
cspell:cpp/src/lang-keywords.txt
|
||||||
|
cspell:npm/npm.txt
|
||||||
|
cspell:dotnet/dotnet.txt
|
||||||
|
cspell:python/src/python/python.txt
|
||||||
|
cspell:css/css.txt
|
||||||
|
cspell:cpp/src/stdlib-cmath.txt
|
||||||
|
check_extra_dictionaries: ''
|
||||||
|
|
||||||
|
comment-push:
|
||||||
|
name: Report (Push)
|
||||||
|
# If your workflow isn't running on push, you can remove this job
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: spelling
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
if: (success() || failure()) && needs.spelling.outputs.followup && github.event_name == 'push'
|
||||||
|
steps:
|
||||||
|
- name: comment
|
||||||
|
uses: check-spelling/check-spelling@v0.0.21
|
||||||
|
with:
|
||||||
|
checkout: true
|
||||||
|
spell_check_this: check-spelling/spell-check-this@prerelease
|
||||||
|
task: ${{ needs.spelling.outputs.followup }}
|
||||||
|
|
||||||
|
comment-pr:
|
||||||
|
name: Report (PR)
|
||||||
|
# If you workflow isn't running on pull_request*, you can remove this job
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: spelling
|
||||||
|
permissions:
|
||||||
|
pull-requests: write
|
||||||
|
if: (success() || failure()) && needs.spelling.outputs.followup && contains(github.event_name, 'pull_request')
|
||||||
|
steps:
|
||||||
|
- name: comment
|
||||||
|
uses: check-spelling/check-spelling@v0.0.21
|
||||||
|
with:
|
||||||
|
checkout: true
|
||||||
|
spell_check_this: check-spelling/spell-check-this@prerelease
|
||||||
|
task: ${{ needs.spelling.outputs.followup }}
|
||||||
|
|||||||
@@ -3,9 +3,11 @@
|
|||||||
|
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "MyPage.h"
|
#include "MyPage.h"
|
||||||
|
#include "MySettings.h"
|
||||||
#include <LibraryResources.h>
|
#include <LibraryResources.h>
|
||||||
#include "MyPage.g.cpp"
|
#include "MyPage.g.cpp"
|
||||||
#include "MySettings.h"
|
#include "..\..\..\src\cascadia\UnitTests_Control\MockControlSettings.h"
|
||||||
|
#include "..\..\..\src\types\inc\utils.hpp"
|
||||||
|
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
using namespace winrt::Microsoft::Terminal;
|
using namespace winrt::Microsoft::Terminal;
|
||||||
@@ -26,7 +28,7 @@ namespace winrt::SampleApp::implementation
|
|||||||
|
|
||||||
void MyPage::Create()
|
void MyPage::Create()
|
||||||
{
|
{
|
||||||
auto settings = winrt::make_self<implementation::MySettings>();
|
auto settings = winrt::make_self<MySettings>();
|
||||||
|
|
||||||
auto connectionSettings{ TerminalConnection::ConptyConnection::CreateSettings(L"cmd.exe /k echo This TermControl is hosted in-proc...",
|
auto connectionSettings{ TerminalConnection::ConptyConnection::CreateSettings(L"cmd.exe /k echo This TermControl is hosted in-proc...",
|
||||||
winrt::hstring{},
|
winrt::hstring{},
|
||||||
@@ -44,6 +46,212 @@ namespace winrt::SampleApp::implementation
|
|||||||
Control::TermControl control{ *settings, conn };
|
Control::TermControl control{ *settings, conn };
|
||||||
|
|
||||||
InProcContent().Children().Append(control);
|
InProcContent().Children().Append(control);
|
||||||
|
|
||||||
|
// Once the control loads (and not before that), write some text for debugging:
|
||||||
|
control.Initialized([conn](auto&&, auto&&) {
|
||||||
|
conn.WriteInput(L"This TermControl is hosted in-proc...");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static wil::unique_process_information _createHostClassProcess(const winrt::guid& g)
|
||||||
|
{
|
||||||
|
auto guidStr{ ::Microsoft::Console::Utils::GuidToString(g) };
|
||||||
|
|
||||||
|
// Create an event that the content process will use to signal it is
|
||||||
|
// ready to go. We won't need the event after this function, so the
|
||||||
|
// unique_event will clean up our handle when we leave this scope. The
|
||||||
|
// ContentProcess is responsible for cleaning up its own handle.
|
||||||
|
wil::unique_event ev{ CreateEvent(nullptr, true, false, L"contentProcessStarted") };
|
||||||
|
// Make sure to mark this handle as inheritable! Even with
|
||||||
|
// bInheritHandles=true, this is only inherited when it's explicitly
|
||||||
|
// allowed to be.
|
||||||
|
SetHandleInformation(ev.get(), HANDLE_FLAG_INHERIT, 1);
|
||||||
|
|
||||||
|
// god bless, fmt::format will format a HANDLE like `0xa80`
|
||||||
|
std::wstring commandline{
|
||||||
|
fmt::format(L"windowsterminal.exe --content {} --signal {}", guidStr, ev.get())
|
||||||
|
};
|
||||||
|
|
||||||
|
STARTUPINFO siOne{ 0 };
|
||||||
|
siOne.cb = sizeof(STARTUPINFOW);
|
||||||
|
wil::unique_process_information piOne;
|
||||||
|
auto succeeded = CreateProcessW(
|
||||||
|
nullptr,
|
||||||
|
commandline.data(),
|
||||||
|
nullptr, // lpProcessAttributes
|
||||||
|
nullptr, // lpThreadAttributes
|
||||||
|
true, // bInheritHandles
|
||||||
|
CREATE_UNICODE_ENVIRONMENT, // dwCreationFlags
|
||||||
|
nullptr, // lpEnvironment
|
||||||
|
nullptr, // startingDirectory
|
||||||
|
&siOne, // lpStartupInfo
|
||||||
|
&piOne // lpProcessInformation
|
||||||
|
);
|
||||||
|
THROW_IF_WIN32_BOOL_FALSE(succeeded);
|
||||||
|
|
||||||
|
// Wait for the child process to signal that they're ready.
|
||||||
|
WaitForSingleObject(ev.get(), INFINITE);
|
||||||
|
|
||||||
|
return std::move(piOne);
|
||||||
|
}
|
||||||
|
|
||||||
|
winrt::fire_and_forget MyPage::_writeToLog(std::wstring_view str)
|
||||||
|
{
|
||||||
|
winrt::hstring copy{ str };
|
||||||
|
// Switch back to the UI thread.
|
||||||
|
co_await resume_foreground(Dispatcher());
|
||||||
|
winrt::WUX::Controls::TextBlock block;
|
||||||
|
block.Text(copy);
|
||||||
|
Log().Children().Append(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
winrt::fire_and_forget MyPage::CreateClicked(const IInspectable& sender,
|
||||||
|
const WUX::Input::TappedRoutedEventArgs& eventArgs)
|
||||||
|
{
|
||||||
|
auto guidString = GuidInput().Text();
|
||||||
|
|
||||||
|
// Capture calling context.
|
||||||
|
winrt::apartment_context ui_thread;
|
||||||
|
|
||||||
|
auto canConvert = guidString.size() == 38 &&
|
||||||
|
guidString.front() == '{' &&
|
||||||
|
guidString.back() == '}';
|
||||||
|
bool tryingToAttach = false;
|
||||||
|
winrt::guid contentGuid{ ::Microsoft::Console::Utils::CreateGuid() };
|
||||||
|
|
||||||
|
if (canConvert)
|
||||||
|
{
|
||||||
|
GUID result{};
|
||||||
|
if (SUCCEEDED(IIDFromString(guidString.c_str(), &result)))
|
||||||
|
{
|
||||||
|
contentGuid = result;
|
||||||
|
tryingToAttach = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_writeToLog(tryingToAttach ? L"Attaching to existing content process" : L"Creating new content process");
|
||||||
|
|
||||||
|
co_await winrt::resume_background();
|
||||||
|
if (!tryingToAttach)
|
||||||
|
{
|
||||||
|
// Spawn a wt.exe, with the guid on the commandline
|
||||||
|
piContentProcess = std::move(_createHostClassProcess(contentGuid));
|
||||||
|
}
|
||||||
|
|
||||||
|
// THIS MUST TAKE PLACE AFTER _createHostClassProcess.
|
||||||
|
// * If we're creating a new OOP control, _createHostClassProcess will
|
||||||
|
// spawn the process that will actually host the ContentProcess
|
||||||
|
// object.
|
||||||
|
// * If we're attaching, then that process already exists.
|
||||||
|
Control::ContentProcess content{nullptr};
|
||||||
|
try
|
||||||
|
{
|
||||||
|
content = create_instance<Control::ContentProcess>(contentGuid, CLSCTX_LOCAL_SERVER);
|
||||||
|
}
|
||||||
|
catch (winrt::hresult_error hr)
|
||||||
|
{
|
||||||
|
_writeToLog(L"CreateInstance the ContentProces object");
|
||||||
|
_writeToLog(fmt::format(L" HR ({}): {}", hr.code(), hr.message().c_str()));
|
||||||
|
co_return; // be sure to co_return or we'll fall through to the part where we clear the log
|
||||||
|
}
|
||||||
|
|
||||||
|
if (content == nullptr)
|
||||||
|
{
|
||||||
|
_writeToLog(L"Failed to connect to the ContentProces object. It may not have been started fast enough.");
|
||||||
|
co_return; // be sure to co_return or we'll fall through to the part where we clear the log
|
||||||
|
}
|
||||||
|
|
||||||
|
TerminalConnection::ConnectionInformation connectInfo{ nullptr };
|
||||||
|
Control::IControlSettings settings{ *winrt::make_self<implementation::MySettings>() };
|
||||||
|
|
||||||
|
// When creating a terminal for the first time, pass it a connection
|
||||||
|
// info
|
||||||
|
//
|
||||||
|
// otherwise, when attaching to an existing one, just pass null, because
|
||||||
|
// we don't need the connection info.
|
||||||
|
if (!tryingToAttach)
|
||||||
|
{
|
||||||
|
auto connectionSettings{ TerminalConnection::ConptyConnection::CreateSettings(L"cmd.exe /k echo This TermControl is hosted out-of-proc...",
|
||||||
|
winrt::hstring{},
|
||||||
|
L"",
|
||||||
|
nullptr,
|
||||||
|
32,
|
||||||
|
80,
|
||||||
|
winrt::guid()) };
|
||||||
|
|
||||||
|
// "Microsoft.Terminal.TerminalConnection.ConptyConnection"
|
||||||
|
winrt::hstring myClass{ winrt::name_of<TerminalConnection::ConptyConnection>() };
|
||||||
|
connectInfo = TerminalConnection::ConnectionInformation(myClass, connectionSettings);
|
||||||
|
|
||||||
|
if (!content.Initialize(settings, connectInfo))
|
||||||
|
{
|
||||||
|
_writeToLog(L"Failed to Initialize the ContentProces object.");
|
||||||
|
co_return; // be sure to co_return or we'll fall through to the part where we clear the log
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If we're attaching, we don't really need to do anything special.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Switch back to the UI thread.
|
||||||
|
co_await ui_thread;
|
||||||
|
|
||||||
|
// Create the XAML control that will be attached to the content process.
|
||||||
|
// We're not passing in a connection, because the contentGuid will be used instead.
|
||||||
|
Control::TermControl control{ contentGuid, settings, nullptr };
|
||||||
|
control.RaiseNotice([this](auto&&, auto& args) {
|
||||||
|
_writeToLog(L"Content process died, probably.");
|
||||||
|
_writeToLog(args.Message());
|
||||||
|
OutOfProcContent().Children().Clear();
|
||||||
|
GuidInput().Text(L"");
|
||||||
|
if (piContentProcess.hProcess)
|
||||||
|
{
|
||||||
|
piContentProcess.reset();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
control.ConnectionStateChanged([this, control](auto&&, auto&) {
|
||||||
|
const auto newConnectionState = control.ConnectionState();
|
||||||
|
if (newConnectionState == TerminalConnection::ConnectionState::Closed)
|
||||||
|
{
|
||||||
|
_writeToLog(L"Connection was closed");
|
||||||
|
OutOfProcContent().Children().Clear();
|
||||||
|
GuidInput().Text(L"");
|
||||||
|
if (piContentProcess.hProcess)
|
||||||
|
{
|
||||||
|
piContentProcess.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Log().Children().Clear();
|
||||||
|
OutOfProcContent().Children().Append(control);
|
||||||
|
|
||||||
|
if (!tryingToAttach)
|
||||||
|
{
|
||||||
|
auto guidStr{ ::Microsoft::Console::Utils::GuidToString(contentGuid) };
|
||||||
|
GuidInput().Text(guidStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyPage::CloseClicked(const IInspectable& /*sender*/,
|
||||||
|
const WUX::Input::TappedRoutedEventArgs& /*eventArgs*/)
|
||||||
|
{
|
||||||
|
OutOfProcContent().Children().Clear();
|
||||||
|
GuidInput().Text(L"");
|
||||||
|
if (piContentProcess.hProcess)
|
||||||
|
{
|
||||||
|
piContentProcess.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyPage::KillClicked(const IInspectable& /*sender*/,
|
||||||
|
const WUX::Input::TappedRoutedEventArgs& /*eventArgs*/)
|
||||||
|
{
|
||||||
|
if (piContentProcess.hProcess)
|
||||||
|
{
|
||||||
|
TerminateProcess(piContentProcess.hProcess, (UINT)-1);
|
||||||
|
piContentProcess.reset();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
|
|||||||
@@ -14,11 +14,18 @@ namespace winrt::SampleApp::implementation
|
|||||||
MyPage();
|
MyPage();
|
||||||
|
|
||||||
void Create();
|
void Create();
|
||||||
|
|
||||||
hstring Title();
|
hstring Title();
|
||||||
|
|
||||||
|
winrt::fire_and_forget CreateClicked(const IInspectable& sender, const Windows::UI::Xaml::Input::TappedRoutedEventArgs& eventArgs);
|
||||||
|
void CloseClicked(const IInspectable& sender, const Windows::UI::Xaml::Input::TappedRoutedEventArgs& eventArgs);
|
||||||
|
void KillClicked(const IInspectable& sender, const Windows::UI::Xaml::Input::TappedRoutedEventArgs& eventArgs);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend struct MyPageT<MyPage>; // for Xaml to bind events
|
friend struct MyPageT<MyPage>; // for Xaml to bind events
|
||||||
|
|
||||||
|
wil::unique_process_information piContentProcess;
|
||||||
|
|
||||||
|
winrt::fire_and_forget _writeToLog(std::wstring_view str);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,9 +23,23 @@
|
|||||||
<TextBox x:Name="GuidInput"
|
<TextBox x:Name="GuidInput"
|
||||||
Width="400"
|
Width="400"
|
||||||
PlaceholderText="{}{guid here}" />
|
PlaceholderText="{}{guid here}" />
|
||||||
<Button Grid.Row="0">
|
<Button x:Name="CreateOopControl"
|
||||||
|
Grid.Row="0"
|
||||||
|
Tapped="CreateClicked">
|
||||||
Create
|
Create
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button x:Name="CloseOopControl"
|
||||||
|
Grid.Row="0"
|
||||||
|
Margin="4,0,0,0"
|
||||||
|
Tapped="CloseClicked">
|
||||||
|
Close
|
||||||
|
</Button>
|
||||||
|
<Button x:Name="KillOopControl"
|
||||||
|
Grid.Row="0"
|
||||||
|
Margin="4,0,0,0"
|
||||||
|
Tapped="KillClicked">
|
||||||
|
Kill
|
||||||
|
</Button>
|
||||||
|
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
@@ -46,14 +60,26 @@
|
|||||||
VerticalAlignment="Stretch"
|
VerticalAlignment="Stretch"
|
||||||
Background="#ff0000" />
|
Background="#ff0000" />
|
||||||
|
|
||||||
<Grid x:Name="OutOfProcContent"
|
<Grid Grid.Column="1"
|
||||||
Grid.Column="1"
|
|
||||||
Padding="16"
|
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
VerticalAlignment="Stretch"
|
VerticalAlignment="Stretch">
|
||||||
Background="#0000ff" />
|
|
||||||
|
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<StackPanel x:Name="Log"
|
||||||
|
Grid.Row="0"
|
||||||
|
Orientation="Vertical" />
|
||||||
|
|
||||||
|
<Grid x:Name="OutOfProcContent"
|
||||||
|
Grid.Row="1"
|
||||||
|
Padding="16"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Stretch"
|
||||||
|
Background="#0000ff" />
|
||||||
|
</Grid>
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ Licensed under the MIT license.
|
|||||||
#include <conattrs.hpp>
|
#include <conattrs.hpp>
|
||||||
#include "MySettings.g.h"
|
#include "MySettings.g.h"
|
||||||
|
|
||||||
|
using IFontFeatureMap = winrt::Windows::Foundation::Collections::IMap<winrt::hstring, uint32_t>;
|
||||||
|
using IFontAxesMap = winrt::Windows::Foundation::Collections::IMap<winrt::hstring, float>;
|
||||||
|
|
||||||
namespace winrt::SampleApp::implementation
|
namespace winrt::SampleApp::implementation
|
||||||
{
|
{
|
||||||
struct MySettings : MySettingsT<MySettings>
|
struct MySettings : MySettingsT<MySettings>
|
||||||
@@ -41,6 +44,8 @@ namespace winrt::SampleApp::implementation
|
|||||||
winrt::Microsoft::Terminal::Core::ICoreAppearance UnfocusedAppearance() { return {}; };
|
winrt::Microsoft::Terminal::Core::ICoreAppearance UnfocusedAppearance() { return {}; };
|
||||||
|
|
||||||
WINRT_PROPERTY(bool, TrimBlockSelection, false);
|
WINRT_PROPERTY(bool, TrimBlockSelection, false);
|
||||||
|
WINRT_PROPERTY(bool, DetectURLs, true);
|
||||||
|
WINRT_PROPERTY(bool, IntenseIsBright, true);
|
||||||
// ------------------------ End of Core Settings -----------------------
|
// ------------------------ End of Core Settings -----------------------
|
||||||
|
|
||||||
WINRT_PROPERTY(winrt::hstring, ProfileName);
|
WINRT_PROPERTY(winrt::hstring, ProfileName);
|
||||||
@@ -78,7 +83,10 @@ namespace winrt::SampleApp::implementation
|
|||||||
|
|
||||||
WINRT_PROPERTY(winrt::hstring, PixelShaderPath);
|
WINRT_PROPERTY(winrt::hstring, PixelShaderPath);
|
||||||
|
|
||||||
WINRT_PROPERTY(bool, DetectURLs, true);
|
WINRT_PROPERTY(IFontFeatureMap, FontFeatures);
|
||||||
|
WINRT_PROPERTY(IFontAxesMap, FontAxes);
|
||||||
|
|
||||||
|
WINRT_PROPERTY(bool, IntenseIsBold, true);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::array<winrt::Microsoft::Terminal::Core::Color, COLOR_TABLE_SIZE> _ColorTable;
|
std::array<winrt::Microsoft::Terminal::Core::Color, COLOR_TABLE_SIZE> _ColorTable;
|
||||||
|
|||||||
@@ -56,39 +56,42 @@ namespace winrt::TerminalApp::implementation
|
|||||||
// - existingConnection: An optional connection that is already established to a PTY
|
// - existingConnection: An optional connection that is already established to a PTY
|
||||||
// for this tab to host instead of creating one.
|
// for this tab to host instead of creating one.
|
||||||
// If not defined, the tab will create the connection.
|
// If not defined, the tab will create the connection.
|
||||||
HRESULT TerminalPage::_OpenNewTab(const NewTerminalArgs& newTerminalArgs, winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection existingConnection)
|
HRESULT TerminalPage::_OpenNewTab(const NewTerminalArgs& newTerminalArgs,
|
||||||
|
TerminalConnection::ITerminalConnection /*existingConnection*/)
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const auto profile{ _settings.GetProfileForArgs(newTerminalArgs) };
|
const auto profile{ _settings.GetProfileForArgs(newTerminalArgs) };
|
||||||
const auto settings{ TerminalSettings::CreateWithNewTerminalArgs(_settings, newTerminalArgs, *_bindings) };
|
const auto settings{ TerminalSettings::CreateWithNewTerminalArgs(_settings, newTerminalArgs, *_bindings) };
|
||||||
|
|
||||||
_CreateNewTabWithProfileAndSettings(profile, settings, existingConnection);
|
// TODO! Handle defterm connections here (and above)
|
||||||
|
// _CreateNewTabWithProfileAndSettings(profile, settings, existingConnection);
|
||||||
|
_CreateTabWithContent(profile, settings, nullptr);
|
||||||
|
|
||||||
const uint32_t tabCount = _tabs.Size();
|
// const uint32_t tabCount = _tabs.Size();
|
||||||
const bool usedManualProfile = (newTerminalArgs != nullptr) &&
|
// const bool usedManualProfile = (newTerminalArgs != nullptr) &&
|
||||||
(newTerminalArgs.ProfileIndex() != nullptr ||
|
// (newTerminalArgs.ProfileIndex() != nullptr ||
|
||||||
newTerminalArgs.Profile().empty());
|
// newTerminalArgs.Profile().empty());
|
||||||
|
|
||||||
// Lookup the name of the color scheme used by this profile.
|
// // Lookup the name of the color scheme used by this profile.
|
||||||
const auto scheme = _settings.GetColorSchemeForProfile(profile);
|
// const auto scheme = _settings.GetColorSchemeForProfile(profile);
|
||||||
// If they explicitly specified `null` as the scheme (indicating _no_ scheme), log
|
// // If they explicitly specified `null` as the scheme (indicating _no_ scheme), log
|
||||||
// that as the empty string.
|
// // that as the empty string.
|
||||||
const auto schemeName = scheme ? scheme.Name() : L"\0";
|
// const auto schemeName = scheme ? scheme.Name() : L"\0";
|
||||||
|
|
||||||
TraceLoggingWrite(
|
// TraceLoggingWrite(
|
||||||
g_hTerminalAppProvider, // handle to TerminalApp tracelogging provider
|
// g_hTerminalAppProvider, // handle to TerminalApp tracelogging provider
|
||||||
"TabInformation",
|
// "TabInformation",
|
||||||
TraceLoggingDescription("Event emitted upon new tab creation in TerminalApp"),
|
// TraceLoggingDescription("Event emitted upon new tab creation in TerminalApp"),
|
||||||
TraceLoggingUInt32(1u, "EventVer", "Version of this event"),
|
// TraceLoggingUInt32(1u, "EventVer", "Version of this event"),
|
||||||
TraceLoggingUInt32(tabCount, "TabCount", "Count of tabs currently opened in TerminalApp"),
|
// TraceLoggingUInt32(tabCount, "TabCount", "Count of tabs currently opened in TerminalApp"),
|
||||||
TraceLoggingBool(usedManualProfile, "ProfileSpecified", "Whether the new tab specified a profile explicitly"),
|
// TraceLoggingBool(usedManualProfile, "ProfileSpecified", "Whether the new tab specified a profile explicitly"),
|
||||||
TraceLoggingGuid(profile.Guid(), "ProfileGuid", "The GUID of the profile spawned in the new tab"),
|
// TraceLoggingGuid(profile.Guid(), "ProfileGuid", "The GUID of the profile spawned in the new tab"),
|
||||||
TraceLoggingBool(settings.DefaultSettings().UseAcrylic(), "UseAcrylic", "The acrylic preference from the settings"),
|
// TraceLoggingBool(settings.DefaultSettings().UseAcrylic(), "UseAcrylic", "The acrylic preference from the settings"),
|
||||||
TraceLoggingFloat64(settings.DefaultSettings().TintOpacity(), "TintOpacity", "Opacity preference from the settings"),
|
// TraceLoggingFloat64(settings.DefaultSettings().TintOpacity(), "TintOpacity", "Opacity preference from the settings"),
|
||||||
TraceLoggingWideString(settings.DefaultSettings().FontFace().c_str(), "FontFace", "Font face chosen in the settings"),
|
// TraceLoggingWideString(settings.DefaultSettings().FontFace().c_str(), "FontFace", "Font face chosen in the settings"),
|
||||||
TraceLoggingWideString(schemeName.data(), "SchemeName", "Color scheme set in the settings"),
|
// TraceLoggingWideString(schemeName.data(), "SchemeName", "Color scheme set in the settings"),
|
||||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
// TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||||
TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance));
|
// TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance));
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
@@ -228,6 +231,129 @@ namespace winrt::TerminalApp::implementation
|
|||||||
_InitializeTab(newTabImpl);
|
_InitializeTab(newTabImpl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static wil::unique_process_information _createHostClassProcess(const winrt::guid& g)
|
||||||
|
{
|
||||||
|
auto guidStr{ ::Microsoft::Console::Utils::GuidToString(g) };
|
||||||
|
|
||||||
|
// Create an event that the content process will use to signal it is
|
||||||
|
// ready to go. We won't need the event after this function, so the
|
||||||
|
// unique_event will clean up our handle when we leave this scope. The
|
||||||
|
// ContentProcess is responsible for cleaning up its own handle.
|
||||||
|
wil::unique_event ev{ CreateEvent(nullptr, true, false, nullptr /*L"contentProcessStarted"*/) };
|
||||||
|
// Make sure to mark this handle as inheritable! Even with
|
||||||
|
// bInheritHandles=true, this is only inherited when it's explicitly
|
||||||
|
// allowed to be.
|
||||||
|
SetHandleInformation(ev.get(), HANDLE_FLAG_INHERIT, 1);
|
||||||
|
|
||||||
|
// god bless, fmt::format will format a HANDLE like `0xa80`
|
||||||
|
std::wstring commandline{
|
||||||
|
fmt::format(L"windowsterminal.exe --content {} --signal {}", guidStr, ev.get())
|
||||||
|
};
|
||||||
|
|
||||||
|
STARTUPINFO siOne{ 0 };
|
||||||
|
siOne.cb = sizeof(STARTUPINFOW);
|
||||||
|
wil::unique_process_information piOne;
|
||||||
|
auto succeeded = CreateProcessW(
|
||||||
|
nullptr,
|
||||||
|
commandline.data(),
|
||||||
|
nullptr, // lpProcessAttributes
|
||||||
|
nullptr, // lpThreadAttributes
|
||||||
|
true, // bInheritHandles
|
||||||
|
CREATE_UNICODE_ENVIRONMENT, // dwCreationFlags
|
||||||
|
nullptr, // lpEnvironment
|
||||||
|
nullptr, // startingDirectory
|
||||||
|
&siOne, // lpStartupInfo
|
||||||
|
&piOne // lpProcessInformation
|
||||||
|
);
|
||||||
|
THROW_IF_WIN32_BOOL_FALSE(succeeded);
|
||||||
|
|
||||||
|
// Wait for the child process to signal that they're ready.
|
||||||
|
WaitForSingleObject(ev.get(), INFINITE);
|
||||||
|
|
||||||
|
return std::move(piOne);
|
||||||
|
}
|
||||||
|
|
||||||
|
Windows::Foundation::IAsyncOperation<ContentProcess> TerminalPage::_CreateNewContentProcess(Profile profile,
|
||||||
|
TerminalSettingsCreateResult settings)
|
||||||
|
{
|
||||||
|
co_await winrt::resume_background();
|
||||||
|
winrt::guid contentGuid{ ::Microsoft::Console::Utils::CreateGuid() };
|
||||||
|
// Spawn a wt.exe, with the guid on the commandline
|
||||||
|
auto piContentProcess{ _createHostClassProcess(contentGuid) };
|
||||||
|
// THIS MUST TAKE PLACE AFTER _createHostClassProcess.
|
||||||
|
// * If we're creating a new OOP control, _createHostClassProcess will
|
||||||
|
// spawn the process that will actually host the ContentProcess
|
||||||
|
// object.
|
||||||
|
// * If we're attaching, then that process already exists.
|
||||||
|
ContentProcess content{ nullptr };
|
||||||
|
try
|
||||||
|
{
|
||||||
|
content = create_instance<ContentProcess>(contentGuid, CLSCTX_LOCAL_SERVER);
|
||||||
|
}
|
||||||
|
catch (winrt::hresult_error hr)
|
||||||
|
{
|
||||||
|
// _writeToLog(L"CreateInstance the ContentProces object");
|
||||||
|
// _writeToLog(fmt::format(L" HR ({}): {}", hr.code(), hr.message().c_str()));
|
||||||
|
co_return nullptr; // be sure to co_return or we'll fall through to the part where we clear the log
|
||||||
|
}
|
||||||
|
|
||||||
|
if (content == nullptr)
|
||||||
|
{
|
||||||
|
// _writeToLog(L"Failed to connect to the ContentProces object. It may not have been started fast enough.");
|
||||||
|
co_return nullptr; // be sure to co_return or we'll fall through to the part where we clear the log
|
||||||
|
}
|
||||||
|
|
||||||
|
TerminalConnection::ConnectionInformation connectInfo{ _CreateConnectionInfoFromSettings(profile, settings.DefaultSettings()) };
|
||||||
|
// TODO! how do we init the content proc with the focused/unfocused pair correctly?
|
||||||
|
if (!content.Initialize(settings.DefaultSettings(), connectInfo))
|
||||||
|
{
|
||||||
|
// _writeToLog(L"Failed to Initialize the ContentProces object.");
|
||||||
|
co_return nullptr; // be sure to co_return or we'll fall through to the part where we clear the log
|
||||||
|
}
|
||||||
|
|
||||||
|
co_return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
ContentProcess TerminalPage::_AttachToContentProcess(const winrt::guid contentGuid)
|
||||||
|
{
|
||||||
|
ContentProcess content{ nullptr };
|
||||||
|
try
|
||||||
|
{
|
||||||
|
content = create_instance<ContentProcess>(contentGuid, CLSCTX_LOCAL_SERVER);
|
||||||
|
}
|
||||||
|
catch (winrt::hresult_error hr)
|
||||||
|
{
|
||||||
|
// _writeToLog(L"CreateInstance the ContentProces object");
|
||||||
|
// _writeToLog(fmt::format(L" HR ({}): {}", hr.code(), hr.message().c_str()));
|
||||||
|
// return nullptr; // be sure to co_return or we'll fall through to the part where we clear the log
|
||||||
|
}
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
winrt::fire_and_forget TerminalPage::_CreateTabWithContent(Profile profile,
|
||||||
|
TerminalSettingsCreateResult settings,
|
||||||
|
ContentProcess existingContentProc)
|
||||||
|
{
|
||||||
|
// Capture calling context.
|
||||||
|
winrt::apartment_context ui_thread;
|
||||||
|
co_await winrt::resume_background();
|
||||||
|
auto content = existingContentProc ? existingContentProc : _CreateNewContentProcess(profile, settings).get();
|
||||||
|
if (!content)
|
||||||
|
{
|
||||||
|
co_return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Switch back to the UI thread.
|
||||||
|
co_await ui_thread;
|
||||||
|
// Create the XAML control that will be attached to the content process.
|
||||||
|
// We're not passing in a connection, because the contentGuid will be used instead.
|
||||||
|
auto term = _InitControl(settings, content.Guid());
|
||||||
|
auto newTabImpl = winrt::make_self<TerminalTab>(profile, term);
|
||||||
|
_RegisterTerminalEvents(term);
|
||||||
|
_InitializeTab(newTabImpl);
|
||||||
|
co_return;
|
||||||
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - Creates a new tab with the given settings. If the tab bar is not being
|
// - Creates a new tab with the given settings. If the tab bar is not being
|
||||||
// currently displayed, it will be shown.
|
// currently displayed, it will be shown.
|
||||||
@@ -235,7 +361,9 @@ namespace winrt::TerminalApp::implementation
|
|||||||
// - profile: profile settings for this connection
|
// - profile: profile settings for this connection
|
||||||
// - settings: the TerminalSettings object to use to create the TerminalControl with.
|
// - settings: the TerminalSettings object to use to create the TerminalControl with.
|
||||||
// - existingConnection: optionally receives a connection from the outside world instead of attempting to create one
|
// - existingConnection: optionally receives a connection from the outside world instead of attempting to create one
|
||||||
void TerminalPage::_CreateNewTabWithProfileAndSettings(const Profile& profile, const TerminalSettingsCreateResult& settings, TerminalConnection::ITerminalConnection existingConnection)
|
void TerminalPage::_CreateNewTabWithProfileAndSettings(const Profile& profile,
|
||||||
|
const TerminalSettingsCreateResult& settings,
|
||||||
|
TerminalConnection::ITerminalConnection existingConnection)
|
||||||
{
|
{
|
||||||
// Initialize the new tab
|
// Initialize the new tab
|
||||||
// Create a connection based on the values in our settings object if we weren't given one.
|
// Create a connection based on the values in our settings object if we weren't given one.
|
||||||
@@ -360,16 +488,20 @@ namespace winrt::TerminalApp::implementation
|
|||||||
settingsCreateResult.DefaultSettings().StartingDirectory(workingDirectory);
|
settingsCreateResult.DefaultSettings().StartingDirectory(workingDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
_CreateNewTabWithProfileAndSettings(profile, settingsCreateResult);
|
_CreateTabWithContent(profile, settingsCreateResult, nullptr);
|
||||||
|
|
||||||
const auto runtimeTabText{ tab.GetTabText() };
|
// TODO! duplicating a tab should dup the tab title over, but
|
||||||
if (!runtimeTabText.empty())
|
// _CreateTabWithContent will return before the tab actually
|
||||||
{
|
// exists.
|
||||||
if (auto newTab{ _GetFocusedTabImpl() })
|
//
|
||||||
{
|
// const auto runtimeTabText{ tab.GetTabText() };
|
||||||
newTab->SetTabText(runtimeTabText);
|
// if (!runtimeTabText.empty())
|
||||||
}
|
// {
|
||||||
}
|
// if (auto newTab{ _GetFocusedTabImpl() })
|
||||||
|
// {
|
||||||
|
// newTab->SetTabText(runtimeTabText);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CATCH_LOG();
|
CATCH_LOG();
|
||||||
|
|||||||
@@ -461,7 +461,12 @@ namespace winrt::TerminalApp::implementation
|
|||||||
// GH#6586: now that we're done processing all startup commands,
|
// GH#6586: now that we're done processing all startup commands,
|
||||||
// focus the active control. This will work as expected for both
|
// focus the active control. This will work as expected for both
|
||||||
// commandline invocations and for `wt` action invocations.
|
// commandline invocations and for `wt` action invocations.
|
||||||
_GetActiveControl().Focus(FocusState::Programmatic);
|
if (auto activeControl{ _GetActiveControl() })
|
||||||
|
{
|
||||||
|
// TODO! this doesn't work during startup anymore now that
|
||||||
|
// tabs are made on a BG thread
|
||||||
|
activeControl.Focus(FocusState::Programmatic);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (initial)
|
if (initial)
|
||||||
{
|
{
|
||||||
@@ -898,6 +903,103 @@ namespace winrt::TerminalApp::implementation
|
|||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Method Description:
|
||||||
|
// - Creates a new connection based on the profile settings
|
||||||
|
// Arguments:
|
||||||
|
// - the profile we want the settings from
|
||||||
|
// - the terminal settings
|
||||||
|
// Return value:
|
||||||
|
// - the desired connection
|
||||||
|
TerminalConnection::ConnectionInformation TerminalPage::_CreateConnectionInfoFromSettings(Profile profile,
|
||||||
|
const TerminalSettings& settings)
|
||||||
|
{
|
||||||
|
if (!profile)
|
||||||
|
{
|
||||||
|
// Use the default profile if we didn't get one as an argument.
|
||||||
|
profile = _settings.FindProfile(_settings.GlobalSettings().DefaultProfile());
|
||||||
|
}
|
||||||
|
|
||||||
|
winrt::guid connectionType = profile.ConnectionType();
|
||||||
|
winrt::guid sessionGuid{};
|
||||||
|
|
||||||
|
Windows::Foundation::Collections::ValueSet connectionSettings{ nullptr };
|
||||||
|
winrt::hstring className;
|
||||||
|
|
||||||
|
if (connectionType == TerminalConnection::AzureConnection::ConnectionType() &&
|
||||||
|
TerminalConnection::AzureConnection::IsAzureConnectionAvailable())
|
||||||
|
{
|
||||||
|
// TODO GH#4661: Replace this with directly using the AzCon when our VT is better
|
||||||
|
std::filesystem::path azBridgePath{ wil::GetModuleFileNameW<std::wstring>(nullptr) };
|
||||||
|
azBridgePath.replace_filename(L"TerminalAzBridge.exe");
|
||||||
|
className = winrt::name_of<TerminalConnection::ConptyConnection>();
|
||||||
|
connectionSettings = TerminalConnection::ConptyConnection::CreateSettings(azBridgePath.wstring(),
|
||||||
|
L".",
|
||||||
|
L"Azure",
|
||||||
|
nullptr,
|
||||||
|
::base::saturated_cast<uint32_t>(settings.InitialRows()),
|
||||||
|
::base::saturated_cast<uint32_t>(settings.InitialCols()),
|
||||||
|
winrt::guid());
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// profile is guaranteed to exist here
|
||||||
|
std::wstring guidWString = Utils::GuidToString(profile.Guid());
|
||||||
|
|
||||||
|
StringMap envMap{};
|
||||||
|
envMap.Insert(L"WT_PROFILE_ID", guidWString);
|
||||||
|
envMap.Insert(L"WSLENV", L"WT_PROFILE_ID");
|
||||||
|
|
||||||
|
// Update the path to be relative to whatever our CWD is.
|
||||||
|
//
|
||||||
|
// Refer to the examples in
|
||||||
|
// https://en.cppreference.com/w/cpp/filesystem/path/append
|
||||||
|
//
|
||||||
|
// We need to do this here, to ensure we tell the ConptyConnection
|
||||||
|
// the correct starting path. If we're being invoked from another
|
||||||
|
// terminal instance (e.g. wt -w 0 -d .), then we have switched our
|
||||||
|
// CWD to the provided path. We should treat the StartingDirectory
|
||||||
|
// as relative to the current CWD.
|
||||||
|
//
|
||||||
|
// The connection must be informed of the current CWD on
|
||||||
|
// construction, because the connection might not spawn the child
|
||||||
|
// process until later, on another thread, after we've already
|
||||||
|
// restored the CWD to it's original value.
|
||||||
|
winrt::hstring newWorkingDirectory{ settings.StartingDirectory() };
|
||||||
|
if (newWorkingDirectory.size() <= 1 ||
|
||||||
|
!(newWorkingDirectory[0] == L'~' || newWorkingDirectory[0] == L'/'))
|
||||||
|
{ // We only want to resolve the new WD against the CWD if it doesn't look like a Linux path (see GH#592)
|
||||||
|
std::wstring cwdString{ wil::GetCurrentDirectoryW<std::wstring>() };
|
||||||
|
std::filesystem::path cwd{ cwdString };
|
||||||
|
cwd /= settings.StartingDirectory().c_str();
|
||||||
|
newWorkingDirectory = winrt::hstring{ cwd.wstring() };
|
||||||
|
}
|
||||||
|
|
||||||
|
className = winrt::name_of<TerminalConnection::ConptyConnection>();
|
||||||
|
connectionSettings = TerminalConnection::ConptyConnection::CreateSettings(settings.Commandline(),
|
||||||
|
newWorkingDirectory,
|
||||||
|
settings.StartingTitle(),
|
||||||
|
envMap.GetView(),
|
||||||
|
::base::saturated_cast<uint32_t>(settings.InitialRows()),
|
||||||
|
::base::saturated_cast<uint32_t>(settings.InitialCols()),
|
||||||
|
winrt::guid());
|
||||||
|
|
||||||
|
// sessionGuid = conhostConn.Guid();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TraceLoggingWrite(
|
||||||
|
// g_hTerminalAppProvider,
|
||||||
|
// "ConnectionCreated",
|
||||||
|
// TraceLoggingDescription("Event emitted upon the creation of a connection"),
|
||||||
|
// TraceLoggingGuid(connectionType, "ConnectionTypeGuid", "The type of the connection"),
|
||||||
|
// TraceLoggingGuid(profile.Guid(), "ProfileGuid", "The profile's GUID"),
|
||||||
|
// TraceLoggingGuid(sessionGuid, "SessionGuid", "The WT_SESSION's GUID"),
|
||||||
|
// TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||||
|
// TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance));
|
||||||
|
|
||||||
|
return TerminalConnection::ConnectionInformation(className, connectionSettings);
|
||||||
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - Called when the settings button is clicked. Launches a background
|
// - Called when the settings button is clicked. Launches a background
|
||||||
// thread to open the settings file in the default JSON editor.
|
// thread to open the settings file in the default JSON editor.
|
||||||
@@ -1344,11 +1446,11 @@ namespace winrt::TerminalApp::implementation
|
|||||||
// - newTerminalArgs: An object that may contain a blob of parameters to
|
// - newTerminalArgs: An object that may contain a blob of parameters to
|
||||||
// control which profile is created and with possible other
|
// control which profile is created and with possible other
|
||||||
// configurations. See CascadiaSettings::BuildSettings for more details.
|
// configurations. See CascadiaSettings::BuildSettings for more details.
|
||||||
void TerminalPage::_SplitPane(TerminalTab& tab,
|
winrt::fire_and_forget TerminalPage::_SplitPane(TerminalTab& tab,
|
||||||
const SplitState splitType,
|
const SplitState splitType,
|
||||||
const SplitType splitMode,
|
const SplitType splitMode,
|
||||||
const float splitSize,
|
const float splitSize,
|
||||||
const NewTerminalArgs& newTerminalArgs)
|
const NewTerminalArgs& newTerminalArgs)
|
||||||
{
|
{
|
||||||
// Do nothing if we're requesting no split.
|
// Do nothing if we're requesting no split.
|
||||||
if (splitType == SplitState::None)
|
if (splitType == SplitState::None)
|
||||||
@@ -1393,7 +1495,9 @@ namespace winrt::TerminalApp::implementation
|
|||||||
controlSettings = TerminalSettings::CreateWithNewTerminalArgs(_settings, newTerminalArgs, *_bindings);
|
controlSettings = TerminalSettings::CreateWithNewTerminalArgs(_settings, newTerminalArgs, *_bindings);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto controlConnection = _CreateConnectionFromSettings(profile, controlSettings.DefaultSettings());
|
co_await winrt::resume_background();
|
||||||
|
const auto contentProc = _CreateNewContentProcess(profile, controlSettings).get();
|
||||||
|
co_await winrt::resume_foreground(Dispatcher());
|
||||||
|
|
||||||
const float contentWidth = ::base::saturated_cast<float>(_tabContent.ActualWidth());
|
const float contentWidth = ::base::saturated_cast<float>(_tabContent.ActualWidth());
|
||||||
const float contentHeight = ::base::saturated_cast<float>(_tabContent.ActualHeight());
|
const float contentHeight = ::base::saturated_cast<float>(_tabContent.ActualHeight());
|
||||||
@@ -1408,10 +1512,10 @@ namespace winrt::TerminalApp::implementation
|
|||||||
const auto canSplit = tab.PreCalculateCanSplit(realSplitType, splitSize, availableSpace);
|
const auto canSplit = tab.PreCalculateCanSplit(realSplitType, splitSize, availableSpace);
|
||||||
if (!canSplit)
|
if (!canSplit)
|
||||||
{
|
{
|
||||||
return;
|
co_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto newControl = _InitControl(controlSettings, controlConnection);
|
auto newControl = _InitControl(controlSettings, contentProc.Guid());
|
||||||
|
|
||||||
// Hookup our event handlers to the new terminal
|
// Hookup our event handlers to the new terminal
|
||||||
_RegisterTerminalEvents(newControl);
|
_RegisterTerminalEvents(newControl);
|
||||||
@@ -1996,6 +2100,17 @@ namespace winrt::TerminalApp::implementation
|
|||||||
|
|
||||||
return term;
|
return term;
|
||||||
}
|
}
|
||||||
|
TermControl TerminalPage::_InitControl(const TerminalSettingsCreateResult& settings, const winrt::guid& contentGuid)
|
||||||
|
{
|
||||||
|
// Give term control a child of the settings so that any overrides go in the child
|
||||||
|
// This way, when we do a settings reload we just update the parent and the overrides remain
|
||||||
|
const auto child = TerminalSettings::CreateWithParent(settings);
|
||||||
|
TermControl term{ contentGuid, child.DefaultSettings(), nullptr };
|
||||||
|
|
||||||
|
term.UnfocusedAppearance(child.UnfocusedSettings()); // It is okay for the unfocused settings to be null
|
||||||
|
|
||||||
|
return term;
|
||||||
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - Hook up keybindings, and refresh the UI of the terminal.
|
// - Hook up keybindings, and refresh the UI of the terminal.
|
||||||
|
|||||||
@@ -190,7 +190,13 @@ namespace winrt::TerminalApp::implementation
|
|||||||
HRESULT _OpenNewTab(const Microsoft::Terminal::Settings::Model::NewTerminalArgs& newTerminalArgs, winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection existingConnection = nullptr);
|
HRESULT _OpenNewTab(const Microsoft::Terminal::Settings::Model::NewTerminalArgs& newTerminalArgs, winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection existingConnection = nullptr);
|
||||||
void _CreateNewTabFromPane(std::shared_ptr<Pane> pane);
|
void _CreateNewTabFromPane(std::shared_ptr<Pane> pane);
|
||||||
void _CreateNewTabWithProfileAndSettings(const Microsoft::Terminal::Settings::Model::Profile& profile, const Microsoft::Terminal::Settings::Model::TerminalSettingsCreateResult& settings, winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection existingConnection = nullptr);
|
void _CreateNewTabWithProfileAndSettings(const Microsoft::Terminal::Settings::Model::Profile& profile, const Microsoft::Terminal::Settings::Model::TerminalSettingsCreateResult& settings, winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection existingConnection = nullptr);
|
||||||
|
winrt::Windows::Foundation::IAsyncOperation<Microsoft::Terminal::Control::ContentProcess> _CreateNewContentProcess(Microsoft::Terminal::Settings::Model::Profile profile,
|
||||||
|
Microsoft::Terminal::Settings::Model::TerminalSettingsCreateResult settings);
|
||||||
|
Microsoft::Terminal::Control::ContentProcess _AttachToContentProcess(const winrt::guid contentGuid);
|
||||||
|
|
||||||
|
winrt::fire_and_forget _CreateTabWithContent(Microsoft::Terminal::Settings::Model::Profile profile, Microsoft::Terminal::Settings::Model::TerminalSettingsCreateResult settings, Microsoft::Terminal::Control::ContentProcess existingContentProc);
|
||||||
winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection _CreateConnectionFromSettings(Microsoft::Terminal::Settings::Model::Profile profile, Microsoft::Terminal::Settings::Model::TerminalSettings settings);
|
winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection _CreateConnectionFromSettings(Microsoft::Terminal::Settings::Model::Profile profile, Microsoft::Terminal::Settings::Model::TerminalSettings settings);
|
||||||
|
winrt::Microsoft::Terminal::TerminalConnection::ConnectionInformation _CreateConnectionInfoFromSettings(Microsoft::Terminal::Settings::Model::Profile profile, const Microsoft::Terminal::Settings::Model::TerminalSettings& settings);
|
||||||
|
|
||||||
winrt::fire_and_forget _OpenNewWindow(const bool elevate, const Microsoft::Terminal::Settings::Model::NewTerminalArgs newTerminalArgs);
|
winrt::fire_and_forget _OpenNewWindow(const bool elevate, const Microsoft::Terminal::Settings::Model::NewTerminalArgs newTerminalArgs);
|
||||||
|
|
||||||
@@ -259,11 +265,11 @@ namespace winrt::TerminalApp::implementation
|
|||||||
const Microsoft::Terminal::Settings::Model::SplitType splitMode = Microsoft::Terminal::Settings::Model::SplitType::Manual,
|
const Microsoft::Terminal::Settings::Model::SplitType splitMode = Microsoft::Terminal::Settings::Model::SplitType::Manual,
|
||||||
const float splitSize = 0.5f,
|
const float splitSize = 0.5f,
|
||||||
const Microsoft::Terminal::Settings::Model::NewTerminalArgs& newTerminalArgs = nullptr);
|
const Microsoft::Terminal::Settings::Model::NewTerminalArgs& newTerminalArgs = nullptr);
|
||||||
void _SplitPane(TerminalTab& tab,
|
winrt::fire_and_forget _SplitPane(TerminalTab& tab,
|
||||||
const Microsoft::Terminal::Settings::Model::SplitState splitType,
|
const Microsoft::Terminal::Settings::Model::SplitState splitType,
|
||||||
const Microsoft::Terminal::Settings::Model::SplitType splitMode = Microsoft::Terminal::Settings::Model::SplitType::Manual,
|
const Microsoft::Terminal::Settings::Model::SplitType splitMode = Microsoft::Terminal::Settings::Model::SplitType::Manual,
|
||||||
const float splitSize = 0.5f,
|
const float splitSize = 0.5f,
|
||||||
const Microsoft::Terminal::Settings::Model::NewTerminalArgs& newTerminalArgs = nullptr);
|
const Microsoft::Terminal::Settings::Model::NewTerminalArgs& newTerminalArgs = nullptr);
|
||||||
void _ResizePane(const Microsoft::Terminal::Settings::Model::ResizeDirection& direction);
|
void _ResizePane(const Microsoft::Terminal::Settings::Model::ResizeDirection& direction);
|
||||||
void _ToggleSplitOrientation();
|
void _ToggleSplitOrientation();
|
||||||
|
|
||||||
@@ -310,6 +316,9 @@ namespace winrt::TerminalApp::implementation
|
|||||||
winrt::Microsoft::Terminal::Control::TermControl _InitControl(const winrt::Microsoft::Terminal::Settings::Model::TerminalSettingsCreateResult& settings,
|
winrt::Microsoft::Terminal::Control::TermControl _InitControl(const winrt::Microsoft::Terminal::Settings::Model::TerminalSettingsCreateResult& settings,
|
||||||
const winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection& connection);
|
const winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection& connection);
|
||||||
|
|
||||||
|
winrt::Microsoft::Terminal::Control::TermControl _InitControl(const winrt::Microsoft::Terminal::Settings::Model::TerminalSettingsCreateResult& settings,
|
||||||
|
const winrt::guid& contentGuid);
|
||||||
|
|
||||||
void _RefreshUIForSettingsReload();
|
void _RefreshUIForSettingsReload();
|
||||||
|
|
||||||
void _SetNonClientAreaColors(const Windows::UI::Color& selectedTabColor);
|
void _SetNonClientAreaColors(const Windows::UI::Color& selectedTabColor);
|
||||||
|
|||||||
@@ -36,21 +36,59 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
|||||||
::IInspectable** raw = reinterpret_cast<::IInspectable**>(pointer);
|
::IInspectable** raw = reinterpret_cast<::IInspectable**>(pointer);
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
|
|
||||||
// RoActivateInstance() will try to create an instance of the object,
|
TerminalConnection::ITerminalConnection connection{ nullptr };
|
||||||
// who's fully qualified name is the string in Name().
|
|
||||||
|
// A couple short-circuits, for connections that _we_ implement.
|
||||||
|
// Sometimes, RoActivateInstance is weird and fails with errors like the
|
||||||
|
// following
|
||||||
//
|
//
|
||||||
// The class has to be activatable. For the Terminal, this is easy
|
|
||||||
// enough - we're not hosting anything that's not already in our
|
|
||||||
// manifest, or living as a .dll & .winmd SxS.
|
|
||||||
//
|
//
|
||||||
// When we get to extensions (GH#4000), we may want to revisit.
|
/*
|
||||||
if (LOG_IF_FAILED(RoActivateInstance(name, raw)))
|
onecore\com\combase\inc\RegistryKey.hpp(527)\combase.dll!00007FFF75E1F855:
|
||||||
|
(caller: 00007FFF75D3BC29) LogHr(2) tid(83a8) 800700A1 The specified
|
||||||
|
path is invalid.
|
||||||
|
Msg:[StaticNtOpen failed with
|
||||||
|
path:\REGISTRY\A\{A41685A4-AD85-4C4C-BA5D-A849ADBF3C40}\ActivatableClassId
|
||||||
|
\REGISTRY\MACHINE\Software\Classes\ActivatableClasses]
|
||||||
|
...\src\cascadia\TerminalConnection\ConnectionInformation.cpp(47)\TerminalConnection.dll!00007FFEC1381FC5:
|
||||||
|
(caller: 00007FFEC13810A5) LogHr(1) tid(83a8) 800700A1 The specified
|
||||||
|
path is invalid.
|
||||||
|
[...TerminalConnection::implementation::ConnectionInformation::CreateConnection(RoActivateInstance(name,
|
||||||
|
raw))]
|
||||||
|
*/
|
||||||
|
//
|
||||||
|
// So to avoid those, we'll manually instantiate these
|
||||||
|
if (info.ClassName() == winrt::name_of<TerminalConnection::ConptyConnection>())
|
||||||
{
|
{
|
||||||
return nullptr;
|
connection = TerminalConnection::ConptyConnection();
|
||||||
|
}
|
||||||
|
else if (info.ClassName() == winrt::name_of<TerminalConnection::AzureConnection>())
|
||||||
|
{
|
||||||
|
connection = TerminalConnection::AzureConnection();
|
||||||
|
}
|
||||||
|
else if (info.ClassName() == winrt::name_of<TerminalConnection::EchoConnection>())
|
||||||
|
{
|
||||||
|
connection = TerminalConnection::EchoConnection();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// RoActivateInstance() will try to create an instance of the object,
|
||||||
|
// who's fully qualified name is the string in Name().
|
||||||
|
//
|
||||||
|
// The class has to be activatable. For the Terminal, this is easy
|
||||||
|
// enough - we're not hosting anything that's not already in our
|
||||||
|
// manifest, or living as a .dll & .winmd SxS.
|
||||||
|
//
|
||||||
|
// When we get to extensions (GH#4000), we may want to revisit.
|
||||||
|
if (LOG_IF_FAILED(RoActivateInstance(name, raw)))
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
connection = inspectable.try_as<TerminalConnection::ITerminalConnection>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now that thing we made, make sure it's actually a ITerminalConnection
|
// Now that thing we made, make sure it's actually a ITerminalConnection
|
||||||
if (const auto connection{ inspectable.try_as<TerminalConnection::ITerminalConnection>() })
|
if (connection)
|
||||||
{
|
{
|
||||||
// Initialize it, and return it.
|
// Initialize it, and return it.
|
||||||
connection.Initialize(info.Settings());
|
connection.Initialize(info.Settings());
|
||||||
|
|||||||
105
src/cascadia/TerminalControl/ContentProcess.cpp
Normal file
105
src/cascadia/TerminalControl/ContentProcess.cpp
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
#include "pch.h"
|
||||||
|
#include "ContentProcess.h"
|
||||||
|
#include "ContentProcess.g.cpp"
|
||||||
|
|
||||||
|
namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
|
{
|
||||||
|
ContentProcess::ContentProcess(winrt::guid g) :
|
||||||
|
_ourPID{ GetCurrentProcessId() }, _guid{ g } {}
|
||||||
|
|
||||||
|
bool ContentProcess::Initialize(Control::IControlSettings settings,
|
||||||
|
TerminalConnection::ConnectionInformation connectionInfo)
|
||||||
|
{
|
||||||
|
auto conn{ TerminalConnection::ConnectionInformation::CreateConnection(connectionInfo) };
|
||||||
|
if (conn == nullptr)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_interactivity = winrt::make<implementation::ControlInteractivity>(settings, conn);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ContentProcess::~ContentProcess()
|
||||||
|
{
|
||||||
|
// DANGER - We're straight up going to EXIT THE ENTIRE PROCESS when we
|
||||||
|
// get destructed. This eliminates the need to do any sort of
|
||||||
|
// refcounting weirdness. This entire process exists to host one
|
||||||
|
// singular ContentProcess instance. When we're destructed, it's because
|
||||||
|
// every other window process was done with us. We can die now, knowing
|
||||||
|
// that our job is complete.
|
||||||
|
ExitProcess(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Control::ControlInteractivity ContentProcess::GetInteractivity()
|
||||||
|
{
|
||||||
|
return _interactivity;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t ContentProcess::GetPID()
|
||||||
|
{
|
||||||
|
return _ourPID;
|
||||||
|
}
|
||||||
|
winrt::guid ContentProcess::Guid()
|
||||||
|
{
|
||||||
|
return _guid;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method Description:
|
||||||
|
// - Duplicate the swap chain handle to the provided process.
|
||||||
|
// - If the provided PID is our pid, then great - we don't need to do anything.
|
||||||
|
// Arguments:
|
||||||
|
// - callersPid: the PID of the process calling this method.
|
||||||
|
// Return Value:
|
||||||
|
// - The value of the swapchain handle in the callers process
|
||||||
|
// Notes:
|
||||||
|
// - This is BODGY! We're basically asking to marshal a HANDLE here. WinRT
|
||||||
|
// has no good mechanism for doing this, so we're doing it by casting the
|
||||||
|
// value to a uint64_t. In all reality, we _should_ be using a COM
|
||||||
|
// interface for this, because it can set up the security on these handles
|
||||||
|
// more appropriately. Fortunately, all we're dealing with is swapchains,
|
||||||
|
// so the security doesn't matter all that much.
|
||||||
|
uint64_t ContentProcess::RequestSwapChainHandle(const uint64_t callersPid)
|
||||||
|
{
|
||||||
|
auto ourPid = GetCurrentProcessId();
|
||||||
|
HANDLE ourHandle = reinterpret_cast<HANDLE>(_interactivity.Core().SwapChainHandle());
|
||||||
|
if (callersPid == ourPid)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<uint64_t>(ourHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
wil::unique_handle hWindowProcess{ OpenProcess(PROCESS_ALL_ACCESS,
|
||||||
|
FALSE,
|
||||||
|
static_cast<DWORD>(callersPid)) };
|
||||||
|
if (hWindowProcess.get() == nullptr)
|
||||||
|
{
|
||||||
|
const auto gle = GetLastError();
|
||||||
|
gle;
|
||||||
|
// TODO! tracelog an error here
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
HANDLE theirHandle{ nullptr };
|
||||||
|
BOOL success = DuplicateHandle(GetCurrentProcess(),
|
||||||
|
ourHandle,
|
||||||
|
hWindowProcess.get(),
|
||||||
|
&theirHandle,
|
||||||
|
0,
|
||||||
|
FALSE,
|
||||||
|
DUPLICATE_SAME_ACCESS);
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
const auto gle = GetLastError();
|
||||||
|
gle;
|
||||||
|
// TODO! tracelog an error here
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// At this point, the handle is now in their process space, with value
|
||||||
|
// theirHandle
|
||||||
|
return reinterpret_cast<uint64_t>(theirHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
33
src/cascadia/TerminalControl/ContentProcess.h
Normal file
33
src/cascadia/TerminalControl/ContentProcess.h
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ContentProcess.g.h"
|
||||||
|
#include "ControlInteractivity.h"
|
||||||
|
|
||||||
|
namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
|
{
|
||||||
|
struct ContentProcess : ContentProcessT<ContentProcess>
|
||||||
|
{
|
||||||
|
ContentProcess(winrt::guid g);
|
||||||
|
~ContentProcess();
|
||||||
|
bool Initialize(Control::IControlSettings settings,
|
||||||
|
TerminalConnection::ConnectionInformation connectionInfo);
|
||||||
|
Control::ControlInteractivity GetInteractivity();
|
||||||
|
|
||||||
|
uint64_t GetPID();
|
||||||
|
winrt::guid Guid();
|
||||||
|
uint64_t RequestSwapChainHandle(const uint64_t pid);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Control::ControlInteractivity _interactivity{ nullptr };
|
||||||
|
uint64_t _ourPID;
|
||||||
|
winrt::guid _guid;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace winrt::Microsoft::Terminal::Control::factory_implementation
|
||||||
|
{
|
||||||
|
BASIC_FACTORY(ContentProcess);
|
||||||
|
}
|
||||||
22
src/cascadia/TerminalControl/ContentProcess.idl
Normal file
22
src/cascadia/TerminalControl/ContentProcess.idl
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
import "ControlInteractivity.idl";
|
||||||
|
|
||||||
|
namespace Microsoft.Terminal.Control
|
||||||
|
{
|
||||||
|
runtimeclass ContentProcess {
|
||||||
|
|
||||||
|
ContentProcess(Guid g);
|
||||||
|
|
||||||
|
Boolean Initialize(IControlSettings settings,
|
||||||
|
Microsoft.Terminal.TerminalConnection.ConnectionInformation connectionInfo);
|
||||||
|
|
||||||
|
ControlInteractivity GetInteractivity();
|
||||||
|
|
||||||
|
UInt64 GetPID();
|
||||||
|
Guid Guid { get; };
|
||||||
|
|
||||||
|
UInt64 RequestSwapChainHandle(UInt64 pid);
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -595,7 +595,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
_desiredFont = { _actualFont };
|
_desiredFont = { _actualFont };
|
||||||
|
|
||||||
// Update the terminal core with its new Core settings
|
// Update the terminal core with its new Core settings
|
||||||
_terminal->UpdateSettings(_settings);
|
// Are you seeing a crash specifically on this line?
|
||||||
|
Core::ICoreSettings coreSettings{ _settings };
|
||||||
|
// Then you might not have Microsoft.Terminal.Core.winmd in the package
|
||||||
|
// or SxS with windowsterminal.exe!
|
||||||
|
_terminal->UpdateSettings(coreSettings);
|
||||||
|
|
||||||
if (!_initializedTerminal)
|
if (!_initializedTerminal)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -247,14 +247,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
inline bool _IsClosing() const noexcept
|
inline bool _IsClosing() const noexcept
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
if (_dispatcher)
|
// // TODO! This may not be strictly true if the core is running out of
|
||||||
{
|
// // proc with XAML. I keep hitting this assertion every time it
|
||||||
// _closing isn't atomic and may only be accessed from the main thread.
|
// // exits, so we might need a better solution.
|
||||||
//
|
// if (_dispatcher)
|
||||||
// Though, the unit tests don't actually run in TAEF's main
|
// {
|
||||||
// thread, so we don't care when we're running in tests.
|
// // _closing isn't atomic and may only be accessed from the main thread.
|
||||||
assert(_inUnitTests || _dispatcher.HasThreadAccess());
|
// //
|
||||||
}
|
// // Though, the unit tests don't actually run in TAEF's main
|
||||||
|
// // thread, so we don't care when we're running in tests.
|
||||||
|
// assert(_inUnitTests || _dispatcher.HasThreadAccess());
|
||||||
|
// }
|
||||||
#endif
|
#endif
|
||||||
return _closing;
|
return _closing;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
_controlPadding = padding;
|
_controlPadding = padding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InteractivityAutomationPeer::SetParentProvider(Windows::UI::Xaml::Automation::Provider::IRawElementProviderSimple parentProvider)
|
||||||
|
{
|
||||||
|
_parentProvider = parentProvider;
|
||||||
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - Signals the ui automation client that the terminal's selection has
|
// - Signals the ui automation client that the terminal's selection has
|
||||||
// changed and should be updated
|
// changed and should be updated
|
||||||
@@ -111,7 +116,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
THROW_IF_FAILED(_uiaProvider->RangeFromChild(/* IRawElementProviderSimple */ nullptr,
|
THROW_IF_FAILED(_uiaProvider->RangeFromChild(/* IRawElementProviderSimple */ nullptr,
|
||||||
&returnVal));
|
&returnVal));
|
||||||
|
|
||||||
const auto parentProvider = this->ProviderFromPeer(*this);
|
// const auto parentProvider = this->ProviderFromPeer(*this);
|
||||||
|
const auto parentProvider = _parentProvider;
|
||||||
const auto xutr = winrt::make_self<XamlUiaTextRange>(returnVal, parentProvider);
|
const auto xutr = winrt::make_self<XamlUiaTextRange>(returnVal, parentProvider);
|
||||||
return xutr.as<XamlAutomation::ITextRangeProvider>();
|
return xutr.as<XamlAutomation::ITextRangeProvider>();
|
||||||
}
|
}
|
||||||
@@ -121,7 +127,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
UIA::ITextRangeProvider* returnVal;
|
UIA::ITextRangeProvider* returnVal;
|
||||||
THROW_IF_FAILED(_uiaProvider->RangeFromPoint({ screenLocation.X, screenLocation.Y }, &returnVal));
|
THROW_IF_FAILED(_uiaProvider->RangeFromPoint({ screenLocation.X, screenLocation.Y }, &returnVal));
|
||||||
|
|
||||||
const auto parentProvider = this->ProviderFromPeer(*this);
|
// const auto parentProvider = this->ProviderFromPeer(*this);
|
||||||
|
const auto parentProvider = _parentProvider;
|
||||||
const auto xutr = winrt::make_self<XamlUiaTextRange>(returnVal, parentProvider);
|
const auto xutr = winrt::make_self<XamlUiaTextRange>(returnVal, parentProvider);
|
||||||
return xutr.as<XamlAutomation::ITextRangeProvider>();
|
return xutr.as<XamlAutomation::ITextRangeProvider>();
|
||||||
}
|
}
|
||||||
@@ -131,7 +138,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
UIA::ITextRangeProvider* returnVal;
|
UIA::ITextRangeProvider* returnVal;
|
||||||
THROW_IF_FAILED(_uiaProvider->get_DocumentRange(&returnVal));
|
THROW_IF_FAILED(_uiaProvider->get_DocumentRange(&returnVal));
|
||||||
|
|
||||||
const auto parentProvider = this->ProviderFromPeer(*this);
|
// const auto parentProvider = this->ProviderFromPeer(*this);
|
||||||
|
const auto parentProvider = _parentProvider;
|
||||||
const auto xutr = winrt::make_self<XamlUiaTextRange>(returnVal, parentProvider);
|
const auto xutr = winrt::make_self<XamlUiaTextRange>(returnVal, parentProvider);
|
||||||
return xutr.as<XamlAutomation::ITextRangeProvider>();
|
return xutr.as<XamlAutomation::ITextRangeProvider>();
|
||||||
}
|
}
|
||||||
@@ -194,7 +202,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
|
|
||||||
std::vector<XamlAutomation::ITextRangeProvider> vec;
|
std::vector<XamlAutomation::ITextRangeProvider> vec;
|
||||||
vec.reserve(count);
|
vec.reserve(count);
|
||||||
auto parentProvider = this->ProviderFromPeer(*this);
|
// auto parentProvider = this->ProviderFromPeer(*this);
|
||||||
|
const auto parentProvider = _parentProvider;
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
auto xutr = make_self<XamlUiaTextRange>(providers[i].detach(), parentProvider);
|
auto xutr = make_self<XamlUiaTextRange>(providers[i].detach(), parentProvider);
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
|
|
||||||
void SetControlBounds(const Windows::Foundation::Rect bounds);
|
void SetControlBounds(const Windows::Foundation::Rect bounds);
|
||||||
void SetControlPadding(const Core::Padding padding);
|
void SetControlPadding(const Core::Padding padding);
|
||||||
|
void SetParentProvider(Windows::UI::Xaml::Automation::Provider::IRawElementProviderSimple parentProvider);
|
||||||
|
|
||||||
#pragma region IUiaEventDispatcher
|
#pragma region IUiaEventDispatcher
|
||||||
void SignalSelectionChanged() override;
|
void SignalSelectionChanged() override;
|
||||||
@@ -76,6 +77,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
private:
|
private:
|
||||||
::Microsoft::WRL::ComPtr<::Microsoft::Terminal::TermControlUiaProvider> _uiaProvider;
|
::Microsoft::WRL::ComPtr<::Microsoft::Terminal::TermControlUiaProvider> _uiaProvider;
|
||||||
winrt::Microsoft::Terminal::Control::implementation::ControlInteractivity* _interactivity;
|
winrt::Microsoft::Terminal::Control::implementation::ControlInteractivity* _interactivity;
|
||||||
|
winrt::Windows::UI::Xaml::Automation::Provider::IRawElementProviderSimple _parentProvider{ nullptr };
|
||||||
|
|
||||||
til::rectangle _controlBounds{};
|
til::rectangle _controlBounds{};
|
||||||
til::rectangle _controlPadding{};
|
til::rectangle _controlPadding{};
|
||||||
|
|||||||
@@ -3,13 +3,21 @@
|
|||||||
|
|
||||||
namespace Microsoft.Terminal.Control
|
namespace Microsoft.Terminal.Control
|
||||||
{
|
{
|
||||||
[default_interface] runtimeclass InteractivityAutomationPeer :
|
[default_interface] runtimeclass InteractivityAutomationPeer/* :
|
||||||
Windows.UI.Xaml.Automation.Peers.AutomationPeer,
|
Windows.UI.Xaml.Automation.Peers.AutomationPeer,
|
||||||
Windows.UI.Xaml.Automation.Provider.ITextProvider
|
Windows.UI.Xaml.Automation.Provider.ITextProvider*/
|
||||||
{
|
{
|
||||||
|
|
||||||
|
Windows.UI.Xaml.Automation.Provider.ITextRangeProvider[] GetSelection();
|
||||||
|
Windows.UI.Xaml.Automation.Provider.ITextRangeProvider[] GetVisibleRanges();
|
||||||
|
Windows.UI.Xaml.Automation.Provider.ITextRangeProvider RangeFromChild(Windows.UI.Xaml.Automation.Provider.IRawElementProviderSimple childElement);
|
||||||
|
Windows.UI.Xaml.Automation.Provider.ITextRangeProvider RangeFromPoint(Windows.Foundation.Point screenLocation);
|
||||||
|
Windows.UI.Xaml.Automation.Provider.ITextRangeProvider DocumentRange();
|
||||||
|
Windows.UI.Xaml.Automation.SupportedTextSelection SupportedTextSelection();
|
||||||
|
|
||||||
void SetControlBounds(Windows.Foundation.Rect bounds);
|
void SetControlBounds(Windows.Foundation.Rect bounds);
|
||||||
void SetControlPadding(Microsoft.Terminal.Core.Padding padding);
|
void SetControlPadding(Microsoft.Terminal.Core.Padding padding);
|
||||||
|
void SetParentProvider(Windows.UI.Xaml.Automation.Provider.IRawElementProviderSimple provider);
|
||||||
|
|
||||||
event Windows.Foundation.TypedEventHandler<Object, Object> SelectionChanged;
|
event Windows.Foundation.TypedEventHandler<Object, Object> SelectionChanged;
|
||||||
event Windows.Foundation.TypedEventHandler<Object, Object> TextChanged;
|
event Windows.Foundation.TypedEventHandler<Object, Object> TextChanged;
|
||||||
|
|||||||
@@ -200,4 +200,10 @@ Please either install the missing font or choose another one.</value>
|
|||||||
<data name="TermControlReadOnly" xml:space="preserve">
|
<data name="TermControlReadOnly" xml:space="preserve">
|
||||||
<value>Read-only mode is enabled.</value>
|
<value>Read-only mode is enabled.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="TermControl_ContentDiedTextBlock.Text" xml:space="preserve">
|
||||||
|
<value>The content of this terminal was closed unexpectedly.</value>
|
||||||
|
</data>
|
||||||
|
<data name="TermControl_ContentDiedButton.Content" xml:space="preserve">
|
||||||
|
<value>Close</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
// Copyright (c) Microsoft Corporation.
|
// Copyright (c) Microsoft Corporation.
|
||||||
// Licensed under the MIT license.
|
// Licensed under the MIT license.
|
||||||
|
//
|
||||||
|
// The functions for handling content processes in the TermControl are largely
|
||||||
|
// in TermControlContentManageent.cpp
|
||||||
|
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "TermControl.h"
|
#include "TermControl.h"
|
||||||
@@ -32,8 +35,10 @@ using namespace winrt::Windows::ApplicationModel::DataTransfer;
|
|||||||
// The updates are throttled to limit power usage.
|
// The updates are throttled to limit power usage.
|
||||||
constexpr const auto ScrollBarUpdateInterval = std::chrono::milliseconds(8);
|
constexpr const auto ScrollBarUpdateInterval = std::chrono::milliseconds(8);
|
||||||
|
|
||||||
// The minimum delay between updating the TSF input control.
|
// The minimum delay between updating the TSF input control. This is already
|
||||||
// This is already throttled primarily in the ControlCore, with a timeout of 100ms. We're adding another smaller one here, as the (potentially x-proc) call will come in off the UI thread
|
// throttled primarily in the ControlCore, with a timeout of 100ms. We're adding
|
||||||
|
// another smaller one here, as the (potentially x-proc) call will come in off
|
||||||
|
// the UI thread
|
||||||
constexpr const auto TsfRedrawInterval = std::chrono::milliseconds(8);
|
constexpr const auto TsfRedrawInterval = std::chrono::milliseconds(8);
|
||||||
|
|
||||||
// The minimum delay between updating the locations of regex patterns
|
// The minimum delay between updating the locations of regex patterns
|
||||||
@@ -50,7 +55,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
{
|
{
|
||||||
TermControl::TermControl(IControlSettings settings,
|
TermControl::TermControl(IControlSettings settings,
|
||||||
TerminalConnection::ITerminalConnection connection) :
|
TerminalConnection::ITerminalConnection connection) :
|
||||||
|
TermControl(winrt::guid{}, settings, connection) {}
|
||||||
|
|
||||||
|
TermControl::TermControl(winrt::guid contentGuid,
|
||||||
|
IControlSettings settings,
|
||||||
|
TerminalConnection::ITerminalConnection connection) :
|
||||||
|
_initializedTerminal{ false },
|
||||||
_settings{ settings },
|
_settings{ settings },
|
||||||
|
_closing{ false },
|
||||||
_isInternalScrollBarUpdate{ false },
|
_isInternalScrollBarUpdate{ false },
|
||||||
_autoScrollVelocity{ 0 },
|
_autoScrollVelocity{ 0 },
|
||||||
_autoScrollingPointerPoint{ std::nullopt },
|
_autoScrollingPointerPoint{ std::nullopt },
|
||||||
@@ -62,7 +74,21 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
_interactivity = winrt::make<implementation::ControlInteractivity>(settings, connection);
|
if (contentGuid != winrt::guid{})
|
||||||
|
{
|
||||||
|
_contentProc = create_instance<Control::ContentProcess>(contentGuid, CLSCTX_LOCAL_SERVER);
|
||||||
|
if (_contentProc != nullptr)
|
||||||
|
{
|
||||||
|
_interactivity = _contentProc.GetInteractivity();
|
||||||
|
_contentWaitInterrupt.create();
|
||||||
|
_createContentWaitThread();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_interactivity == nullptr)
|
||||||
|
{
|
||||||
|
_interactivity = winrt::make<implementation::ControlInteractivity>(settings, connection);
|
||||||
|
}
|
||||||
_core = _interactivity.Core();
|
_core = _interactivity.Core();
|
||||||
|
|
||||||
// These events might all be triggered by the connection, but that
|
// These events might all be triggered by the connection, but that
|
||||||
@@ -75,6 +101,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
// This event is specifically triggered by the renderer thread, a BG thread. Use a weak ref here.
|
// This event is specifically triggered by the renderer thread, a BG thread. Use a weak ref here.
|
||||||
_core.RendererEnteredErrorState({ get_weak(), &TermControl::_RendererEnteredErrorState });
|
_core.RendererEnteredErrorState({ get_weak(), &TermControl::_RendererEnteredErrorState });
|
||||||
|
|
||||||
|
_core.ConnectionStateChanged({ get_weak(), &TermControl::_coreConnectionStateChanged });
|
||||||
|
|
||||||
// These callbacks can only really be triggered by UI interactions. So
|
// These callbacks can only really be triggered by UI interactions. So
|
||||||
// they don't need weak refs - they can't be triggered unless we're
|
// they don't need weak refs - they can't be triggered unless we're
|
||||||
// alive.
|
// alive.
|
||||||
@@ -500,6 +528,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
|
|
||||||
TermControl::~TermControl()
|
TermControl::~TermControl()
|
||||||
{
|
{
|
||||||
|
if (_contentIsOutOfProc())
|
||||||
|
{
|
||||||
|
_contentWaitInterrupt.SetEvent();
|
||||||
|
_contentWaitThread.join();
|
||||||
|
}
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -526,6 +559,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
margins.Right,
|
margins.Right,
|
||||||
margins.Bottom };
|
margins.Bottom };
|
||||||
_automationPeer = winrt::make<implementation::TermControlAutomationPeer>(this, padding, interactivityAutoPeer);
|
_automationPeer = winrt::make<implementation::TermControlAutomationPeer>(this, padding, interactivityAutoPeer);
|
||||||
|
interactivityAutoPeer.SetParentProvider(_automationPeer.GetParentProvider());
|
||||||
return _automationPeer;
|
return _automationPeer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -546,7 +580,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
|
|
||||||
TerminalConnection::ConnectionState TermControl::ConnectionState() const
|
TerminalConnection::ConnectionState TermControl::ConnectionState() const
|
||||||
{
|
{
|
||||||
return _core.ConnectionState();
|
try
|
||||||
|
{
|
||||||
|
return _core.ConnectionState();
|
||||||
|
}
|
||||||
|
CATCH_LOG();
|
||||||
|
return TerminalConnection::ConnectionState::Closed;
|
||||||
}
|
}
|
||||||
|
|
||||||
winrt::fire_and_forget TermControl::RenderEngineSwapChainChanged(IInspectable /*sender*/, IInspectable /*args*/)
|
winrt::fire_and_forget TermControl::RenderEngineSwapChainChanged(IInspectable /*sender*/, IInspectable /*args*/)
|
||||||
@@ -560,7 +599,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
|
|
||||||
if (auto control{ weakThis.get() })
|
if (auto control{ weakThis.get() })
|
||||||
{
|
{
|
||||||
const HANDLE chainHandle = reinterpret_cast<HANDLE>(control->_core.SwapChainHandle());
|
// TODO! very good chance we leak this handle
|
||||||
|
const HANDLE chainHandle = reinterpret_cast<HANDLE>(control->_contentIsOutOfProc() ?
|
||||||
|
control->_contentProc.RequestSwapChainHandle(GetCurrentProcessId()) :
|
||||||
|
control->_core.SwapChainHandle());
|
||||||
_AttachDxgiSwapChainToXaml(chainHandle);
|
_AttachDxgiSwapChainToXaml(chainHandle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -648,7 +690,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
}
|
}
|
||||||
_interactivity.Initialize();
|
_interactivity.Initialize();
|
||||||
|
|
||||||
_AttachDxgiSwapChainToXaml(reinterpret_cast<HANDLE>(_core.SwapChainHandle()));
|
// TODO! very good chance we leak this handle
|
||||||
|
const HANDLE chainHandle = reinterpret_cast<HANDLE>(_contentIsOutOfProc() ?
|
||||||
|
_contentProc.RequestSwapChainHandle(GetCurrentProcessId()) :
|
||||||
|
_core.SwapChainHandle());
|
||||||
|
_AttachDxgiSwapChainToXaml(chainHandle);
|
||||||
|
|
||||||
// Tell the DX Engine to notify us when the swap chain changes. We do
|
// Tell the DX Engine to notify us when the swap chain changes. We do
|
||||||
// this after we initially set the swapchain so as to avoid unnecessary
|
// this after we initially set the swapchain so as to avoid unnecessary
|
||||||
@@ -1734,8 +1780,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
// Disconnect the TSF input control so it doesn't receive EditContext events.
|
// Disconnect the TSF input control so it doesn't receive EditContext events.
|
||||||
TSFInputControl().Close();
|
TSFInputControl().Close();
|
||||||
_autoScrollTimer.Stop();
|
_autoScrollTimer.Stop();
|
||||||
|
if (!_contentIsOutOfProc())
|
||||||
_core.Close();
|
{
|
||||||
|
_core.Close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2568,4 +2616,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
{
|
{
|
||||||
_playWarningBell->Run();
|
_playWarningBell->Run();
|
||||||
}
|
}
|
||||||
|
void TermControl::_coreConnectionStateChanged(const IInspectable& /*sender*/, const IInspectable& /*args*/)
|
||||||
|
{
|
||||||
|
_ConnectionStateChangedHandlers(*this, nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
{
|
{
|
||||||
struct TermControl : TermControlT<TermControl>
|
struct TermControl : TermControlT<TermControl>
|
||||||
{
|
{
|
||||||
|
TermControl(winrt::guid contentGuid, IControlSettings settings, TerminalConnection::ITerminalConnection connection);
|
||||||
TermControl(IControlSettings settings, TerminalConnection::ITerminalConnection connection);
|
TermControl(IControlSettings settings, TerminalConnection::ITerminalConnection connection);
|
||||||
|
|
||||||
winrt::fire_and_forget UpdateSettings();
|
winrt::fire_and_forget UpdateSettings();
|
||||||
@@ -70,6 +71,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
winrt::fire_and_forget _RendererEnteredErrorState(IInspectable sender, IInspectable args);
|
winrt::fire_and_forget _RendererEnteredErrorState(IInspectable sender, IInspectable args);
|
||||||
|
|
||||||
void _RenderRetryButton_Click(IInspectable const& button, IInspectable const& args);
|
void _RenderRetryButton_Click(IInspectable const& button, IInspectable const& args);
|
||||||
|
void _ContentDiedCloseButton_Click(IInspectable const& button, IInspectable const& args);
|
||||||
winrt::fire_and_forget _RendererWarning(IInspectable sender,
|
winrt::fire_and_forget _RendererWarning(IInspectable sender,
|
||||||
Control::RendererWarningArgs args);
|
Control::RendererWarningArgs args);
|
||||||
|
|
||||||
@@ -115,7 +117,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
PROJECTED_FORWARDED_TYPED_EVENT(TitleChanged, IInspectable, Control::TitleChangedEventArgs, _core, TitleChanged);
|
PROJECTED_FORWARDED_TYPED_EVENT(TitleChanged, IInspectable, Control::TitleChangedEventArgs, _core, TitleChanged);
|
||||||
PROJECTED_FORWARDED_TYPED_EVENT(TabColorChanged, IInspectable, IInspectable, _core, TabColorChanged);
|
PROJECTED_FORWARDED_TYPED_EVENT(TabColorChanged, IInspectable, IInspectable, _core, TabColorChanged);
|
||||||
PROJECTED_FORWARDED_TYPED_EVENT(SetTaskbarProgress, IInspectable, IInspectable, _core, TaskbarProgressChanged);
|
PROJECTED_FORWARDED_TYPED_EVENT(SetTaskbarProgress, IInspectable, IInspectable, _core, TaskbarProgressChanged);
|
||||||
PROJECTED_FORWARDED_TYPED_EVENT(ConnectionStateChanged, IInspectable, IInspectable, _core, ConnectionStateChanged);
|
TYPED_EVENT(ConnectionStateChanged, IInspectable, IInspectable);
|
||||||
|
|
||||||
PROJECTED_FORWARDED_TYPED_EVENT(PasteFromClipboard, IInspectable, Control::PasteFromClipboardEventArgs, _interactivity, PasteFromClipboard);
|
PROJECTED_FORWARDED_TYPED_EVENT(PasteFromClipboard, IInspectable, Control::PasteFromClipboardEventArgs, _interactivity, PasteFromClipboard);
|
||||||
|
|
||||||
@@ -145,6 +147,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
Control::TermControlAutomationPeer _automationPeer{ nullptr };
|
Control::TermControlAutomationPeer _automationPeer{ nullptr };
|
||||||
Control::ControlInteractivity _interactivity{ nullptr };
|
Control::ControlInteractivity _interactivity{ nullptr };
|
||||||
Control::ControlCore _core{ nullptr };
|
Control::ControlCore _core{ nullptr };
|
||||||
|
Control::ContentProcess _contentProc{ nullptr };
|
||||||
|
|
||||||
winrt::com_ptr<SearchBoxControl> _searchBox;
|
winrt::com_ptr<SearchBoxControl> _searchBox;
|
||||||
|
|
||||||
@@ -183,6 +186,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
|
|
||||||
winrt::Windows::UI::Xaml::Controls::SwapChainPanel::LayoutUpdated_revoker _layoutUpdatedRevoker;
|
winrt::Windows::UI::Xaml::Controls::SwapChainPanel::LayoutUpdated_revoker _layoutUpdatedRevoker;
|
||||||
|
|
||||||
|
wil::unique_event _contentWaitInterrupt;
|
||||||
|
std::thread _contentWaitThread;
|
||||||
|
void _createContentWaitThread();
|
||||||
|
bool _contentIsOutOfProc() const;
|
||||||
|
|
||||||
inline bool _IsClosing() const noexcept
|
inline bool _IsClosing() const noexcept
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
@@ -270,6 +278,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
winrt::fire_and_forget _coreTransparencyChanged(IInspectable sender, Control::TransparencyChangedEventArgs args);
|
winrt::fire_and_forget _coreTransparencyChanged(IInspectable sender, Control::TransparencyChangedEventArgs args);
|
||||||
void _coreRaisedNotice(const IInspectable& s, const Control::NoticeEventArgs& args);
|
void _coreRaisedNotice(const IInspectable& s, const Control::NoticeEventArgs& args);
|
||||||
void _coreWarningBell(const IInspectable& sender, const IInspectable& args);
|
void _coreWarningBell(const IInspectable& sender, const IInspectable& args);
|
||||||
|
winrt::fire_and_forget _raiseContentDied();
|
||||||
|
void _coreConnectionStateChanged(const IInspectable& sender, const IInspectable& args);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,10 @@ namespace Microsoft.Terminal.Control
|
|||||||
IMouseWheelListener,
|
IMouseWheelListener,
|
||||||
ICoreState
|
ICoreState
|
||||||
{
|
{
|
||||||
|
TermControl(Guid contentGuid,
|
||||||
|
IControlSettings settings,
|
||||||
|
Microsoft.Terminal.TerminalConnection.ITerminalConnection connection);
|
||||||
|
|
||||||
TermControl(IControlSettings settings,
|
TermControl(IControlSettings settings,
|
||||||
Microsoft.Terminal.TerminalConnection.ITerminalConnection connection);
|
Microsoft.Terminal.TerminalConnection.ITerminalConnection connection);
|
||||||
|
|
||||||
|
|||||||
@@ -130,6 +130,27 @@
|
|||||||
</Border>
|
</Border>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
<Grid x:Name="ContentDiedNotice"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
x:Load="False">
|
||||||
|
<Border Margin="8,8,8,8"
|
||||||
|
Padding="8,8,8,8"
|
||||||
|
Background="{ThemeResource SystemControlBackgroundAltHighBrush}"
|
||||||
|
BorderBrush="{ThemeResource SystemAccentColor}"
|
||||||
|
BorderThickness="2,2,2,2"
|
||||||
|
CornerRadius="{ThemeResource OverlayCornerRadius}">
|
||||||
|
<StackPanel>
|
||||||
|
<TextBlock x:Uid="TermControl_ContentDiedTextBlock"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
TextWrapping="WrapWholeWords" />
|
||||||
|
<Button x:Uid="TermControl_ContentDiedButton"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
Click="_ContentDiedCloseButton_Click" />
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|||||||
@@ -67,6 +67,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
_contentAutomationPeer.SetControlPadding(padding);
|
_contentAutomationPeer.SetControlPadding(padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XamlAutomation::IRawElementProviderSimple TermControlAutomationPeer::GetParentProvider()
|
||||||
|
{
|
||||||
|
const auto parentProvider = this->ProviderFromPeer(*this);
|
||||||
|
return parentProvider;
|
||||||
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - Signals the ui automation client that the terminal's selection has changed and should be updated
|
// - Signals the ui automation client that the terminal's selection has changed and should be updated
|
||||||
// Arguments:
|
// Arguments:
|
||||||
@@ -153,7 +159,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
|
|
||||||
hstring TermControlAutomationPeer::GetLocalizedControlTypeCore() const
|
hstring TermControlAutomationPeer::GetLocalizedControlTypeCore() const
|
||||||
{
|
{
|
||||||
return RS_(L"TerminalControl_ControlType");
|
// return RS_(L"TerminalControl_ControlType");
|
||||||
|
return L"foo";
|
||||||
}
|
}
|
||||||
|
|
||||||
Windows::Foundation::IInspectable TermControlAutomationPeer::GetPatternCore(PatternInterface patternInterface) const
|
Windows::Foundation::IInspectable TermControlAutomationPeer::GetPatternCore(PatternInterface patternInterface) const
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
|
|
||||||
void UpdateControlBounds();
|
void UpdateControlBounds();
|
||||||
void SetControlPadding(const Core::Padding padding);
|
void SetControlPadding(const Core::Padding padding);
|
||||||
|
Windows::UI::Xaml::Automation::Provider::IRawElementProviderSimple GetParentProvider();
|
||||||
|
|
||||||
#pragma region FrameworkElementAutomationPeer
|
#pragma region FrameworkElementAutomationPeer
|
||||||
hstring GetClassNameCore() const;
|
hstring GetClassNameCore() const;
|
||||||
|
|||||||
@@ -12,5 +12,6 @@ namespace Microsoft.Terminal.Control
|
|||||||
|
|
||||||
void UpdateControlBounds();
|
void UpdateControlBounds();
|
||||||
void SetControlPadding(Microsoft.Terminal.Core.Padding padding);
|
void SetControlPadding(Microsoft.Terminal.Core.Padding padding);
|
||||||
|
Windows.UI.Xaml.Automation.Provider.IRawElementProviderSimple GetParentProvider();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
154
src/cascadia/TerminalControl/TermControlContentManagement.cpp
Normal file
154
src/cascadia/TerminalControl/TermControlContentManagement.cpp
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
//
|
||||||
|
// The functions in this class are specific to the handling of out-of-proc
|
||||||
|
// content processes by the TermControl. Putting them all in one file keeps
|
||||||
|
// TermControl.cpp a little less cluttered.
|
||||||
|
|
||||||
|
#include "pch.h"
|
||||||
|
#include "TermControl.h"
|
||||||
|
|
||||||
|
using namespace ::Microsoft::Console::Types;
|
||||||
|
using namespace winrt::Windows::UI::Xaml;
|
||||||
|
using namespace winrt::Windows::UI::Core;
|
||||||
|
using namespace winrt::Windows::System;
|
||||||
|
|
||||||
|
namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
|
{
|
||||||
|
bool TermControl::_contentIsOutOfProc() const
|
||||||
|
{
|
||||||
|
return _contentProc != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool s_waitOnContentProcess(uint64_t contentPid, HANDLE contentWaitInterrupt)
|
||||||
|
{
|
||||||
|
// This is the array of HANDLEs that we're going to wait on in
|
||||||
|
// WaitForMultipleObjects below.
|
||||||
|
// * waits[0] will be the handle to the content process. It gets
|
||||||
|
// signalled when the process exits / dies.
|
||||||
|
// * waits[1] is the handle to our _contentWaitInterrupt event. Another
|
||||||
|
// thread can use that to manually break this loop. We'll do that when
|
||||||
|
// we're getting torn down.
|
||||||
|
HANDLE waits[2];
|
||||||
|
waits[1] = contentWaitInterrupt;
|
||||||
|
bool displayError = true;
|
||||||
|
|
||||||
|
// At any point in all this, the content process might die. If it does,
|
||||||
|
// we want to raise an error message, to inform that this control is now
|
||||||
|
// dead.
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// This might fail to even ask the content for it's PID.
|
||||||
|
wil::unique_handle hContent{ OpenProcess(PROCESS_ALL_ACCESS,
|
||||||
|
FALSE,
|
||||||
|
static_cast<DWORD>(contentPid)) };
|
||||||
|
|
||||||
|
// If we fail to open the content, then they don't exist
|
||||||
|
// anymore! We'll need to immediately raise the notification that the content has died.
|
||||||
|
if (hContent.get() == nullptr)
|
||||||
|
{
|
||||||
|
const auto gle = GetLastError();
|
||||||
|
TraceLoggingWrite(g_hTerminalControlProvider,
|
||||||
|
"TermControl_FailedToOpenContent",
|
||||||
|
TraceLoggingUInt64(gle, "lastError", "The result of GetLastError"),
|
||||||
|
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE),
|
||||||
|
TraceLoggingKeyword(TIL_KEYWORD_TRACE));
|
||||||
|
return displayError;
|
||||||
|
}
|
||||||
|
|
||||||
|
waits[0] = hContent.get();
|
||||||
|
|
||||||
|
switch (WaitForMultipleObjects(2, waits, FALSE, INFINITE))
|
||||||
|
{
|
||||||
|
case WAIT_OBJECT_0 + 0: // waits[0] was signaled, the handle to the content process
|
||||||
|
|
||||||
|
TraceLoggingWrite(g_hTerminalControlProvider,
|
||||||
|
"TermControl_ContentDied",
|
||||||
|
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE),
|
||||||
|
TraceLoggingKeyword(TIL_KEYWORD_TRACE));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WAIT_OBJECT_0 + 1: // waits[1] was signaled, our manual interrupt
|
||||||
|
|
||||||
|
TraceLoggingWrite(g_hTerminalControlProvider,
|
||||||
|
"TermControl_ContentWaitInterrupted",
|
||||||
|
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE),
|
||||||
|
TraceLoggingKeyword(TIL_KEYWORD_TRACE));
|
||||||
|
displayError = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WAIT_TIMEOUT:
|
||||||
|
// This should be impossible.
|
||||||
|
TraceLoggingWrite(g_hTerminalControlProvider,
|
||||||
|
"TermControl_ContentWaitTimeout",
|
||||||
|
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE),
|
||||||
|
TraceLoggingKeyword(TIL_KEYWORD_TRACE));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
// Returning any other value is invalid. Just die.
|
||||||
|
const auto gle = GetLastError();
|
||||||
|
TraceLoggingWrite(g_hTerminalControlProvider,
|
||||||
|
"TermControl_WaitFailed",
|
||||||
|
TraceLoggingUInt64(gle, "lastError", "The result of GetLastError"),
|
||||||
|
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE),
|
||||||
|
TraceLoggingKeyword(TIL_KEYWORD_TRACE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
// Theoretically, if window[1] dies when we're trying to get
|
||||||
|
// it's PID we'll get here. We can probably just exit here.
|
||||||
|
|
||||||
|
TraceLoggingWrite(g_hTerminalControlProvider,
|
||||||
|
"TermControl_ExceptionInWaitThread",
|
||||||
|
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE),
|
||||||
|
TraceLoggingKeyword(TIL_KEYWORD_TRACE));
|
||||||
|
}
|
||||||
|
return displayError;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TermControl::_createContentWaitThread()
|
||||||
|
{
|
||||||
|
_contentWaitThread = std::thread([weakThis = get_weak(), contentPid = _contentProc.GetPID(), contentWaitInterrupt = _contentWaitInterrupt.get()] {
|
||||||
|
if (s_waitOnContentProcess(contentPid, contentWaitInterrupt))
|
||||||
|
{
|
||||||
|
// When s_waitOnContentProcess returns, if it returned true, we
|
||||||
|
// should display a dialog in our bounds to indicate that we
|
||||||
|
// were closed unexpectedly. If we closed in an expected way,
|
||||||
|
// then s_waitOnContentProcess will return false.
|
||||||
|
if (auto control{ weakThis.get() })
|
||||||
|
{
|
||||||
|
control->_raiseContentDied();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
winrt::fire_and_forget TermControl::_raiseContentDied()
|
||||||
|
{
|
||||||
|
auto weakThis{ get_weak() };
|
||||||
|
co_await winrt::resume_foreground(Dispatcher());
|
||||||
|
|
||||||
|
if (auto control{ weakThis.get() })
|
||||||
|
{
|
||||||
|
if (auto loadedUiElement{ FindName(L"ContentDiedNotice") })
|
||||||
|
{
|
||||||
|
if (auto uiElement{ loadedUiElement.try_as<::winrt::Windows::UI::Xaml::UIElement>() })
|
||||||
|
{
|
||||||
|
uiElement.Visibility(Visibility::Visible);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Method Description:
|
||||||
|
// - Handler for when the "Content Died" dialog's button is clicked.
|
||||||
|
void TermControl::_ContentDiedCloseButton_Click(IInspectable const& /*sender*/, IInspectable const& /*args*/)
|
||||||
|
{
|
||||||
|
// Alert whoever's hosting us that the connection was closed.
|
||||||
|
// When they come asking what the new connection state is, we'll reply with Closed
|
||||||
|
_ConnectionStateChangedHandlers(*this, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,6 +28,9 @@
|
|||||||
<!-- ========================= Headers ======================== -->
|
<!-- ========================= Headers ======================== -->
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="pch.h" />
|
<ClInclude Include="pch.h" />
|
||||||
|
<ClInclude Include="ContentProcess.h">
|
||||||
|
<DependentUpon>ContentProcess.idl</DependentUpon>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="ControlCore.h">
|
<ClInclude Include="ControlCore.h">
|
||||||
<DependentUpon>ControlCore.idl</DependentUpon>
|
<DependentUpon>ControlCore.idl</DependentUpon>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@@ -58,13 +61,18 @@
|
|||||||
<ClInclude Include="TSFInputControl.h">
|
<ClInclude Include="TSFInputControl.h">
|
||||||
<DependentUpon>TSFInputControl.xaml</DependentUpon>
|
<DependentUpon>TSFInputControl.xaml</DependentUpon>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="XamlUiaTextRange.h" />
|
<ClInclude Include="XamlUiaTextRange.h" >
|
||||||
|
<DependentUpon>XamlUiaTextRange.idl</DependentUpon>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<!-- ========================= Cpp Files ======================== -->
|
<!-- ========================= Cpp Files ======================== -->
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="pch.cpp">
|
<ClCompile Include="pch.cpp">
|
||||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="ContentProcess.cpp">
|
||||||
|
<DependentUpon>ContentProcess.idl</DependentUpon>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="ControlCore.cpp">
|
<ClCompile Include="ControlCore.cpp">
|
||||||
<DependentUpon>ControlCore.idl</DependentUpon>
|
<DependentUpon>ControlCore.idl</DependentUpon>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@@ -87,6 +95,9 @@
|
|||||||
<ClCompile Include="TermControl.cpp">
|
<ClCompile Include="TermControl.cpp">
|
||||||
<DependentUpon>TermControl.xaml</DependentUpon>
|
<DependentUpon>TermControl.xaml</DependentUpon>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="TermControlContentManagement.cpp">
|
||||||
|
<DependentUpon>TermControl.xaml</DependentUpon>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="TSFInputControl.cpp">
|
<ClCompile Include="TSFInputControl.cpp">
|
||||||
<DependentUpon>TSFInputControl.xaml</DependentUpon>
|
<DependentUpon>TSFInputControl.xaml</DependentUpon>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@@ -97,10 +108,13 @@
|
|||||||
<ClCompile Include="InteractivityAutomationPeer.cpp">
|
<ClCompile Include="InteractivityAutomationPeer.cpp">
|
||||||
<DependentUpon>InteractivityAutomationPeer.idl</DependentUpon>
|
<DependentUpon>InteractivityAutomationPeer.idl</DependentUpon>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="XamlUiaTextRange.cpp" />
|
<ClCompile Include="XamlUiaTextRange.cpp" >
|
||||||
|
<DependentUpon>XamlUiaTextRange.idl</DependentUpon>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<!-- ========================= idl Files ======================== -->
|
<!-- ========================= idl Files ======================== -->
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Midl Include="ContentProcess.idl" />
|
||||||
<Midl Include="ControlCore.idl" />
|
<Midl Include="ControlCore.idl" />
|
||||||
<Midl Include="ControlInteractivity.idl" />
|
<Midl Include="ControlInteractivity.idl" />
|
||||||
<Midl Include="ICoreState.idl" />
|
<Midl Include="ICoreState.idl" />
|
||||||
@@ -123,6 +137,7 @@
|
|||||||
<Midl Include="TSFInputControl.idl">
|
<Midl Include="TSFInputControl.idl">
|
||||||
<DependentUpon>TSFInputControl.xaml</DependentUpon>
|
<DependentUpon>TSFInputControl.xaml</DependentUpon>
|
||||||
</Midl>
|
</Midl>
|
||||||
|
<Midl Include="XamlUiaTextRange.idl" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<!-- ========================= XAML Files ======================== -->
|
<!-- ========================= XAML Files ======================== -->
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -21,13 +21,13 @@ Author(s):
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "TermControlAutomationPeer.h"
|
#include "TermControlAutomationPeer.h"
|
||||||
|
#include "XamlUiaTextRange.g.h"
|
||||||
#include <UIAutomationCore.h>
|
#include <UIAutomationCore.h>
|
||||||
#include "../types/TermControlUiaTextRange.hpp"
|
#include "../types/TermControlUiaTextRange.hpp"
|
||||||
|
|
||||||
namespace winrt::Microsoft::Terminal::Control::implementation
|
namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
{
|
{
|
||||||
class XamlUiaTextRange :
|
class XamlUiaTextRange : public XamlUiaTextRangeT<XamlUiaTextRange>
|
||||||
public winrt::implements<XamlUiaTextRange, Windows::UI::Xaml::Automation::Provider::ITextRangeProvider>
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
XamlUiaTextRange(::ITextRangeProvider* uiaProvider, Windows::UI::Xaml::Automation::Provider::IRawElementProviderSimple parentProvider) :
|
XamlUiaTextRange(::ITextRangeProvider* uiaProvider, Windows::UI::Xaml::Automation::Provider::IRawElementProviderSimple parentProvider) :
|
||||||
|
|||||||
10
src/cascadia/TerminalControl/XamlUiaTextRange.idl
Normal file
10
src/cascadia/TerminalControl/XamlUiaTextRange.idl
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
namespace Microsoft.Terminal.Control
|
||||||
|
{
|
||||||
|
[default_interface] runtimeclass XamlUiaTextRange :
|
||||||
|
Windows.UI.Xaml.Automation.Provider.ITextRangeProvider
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,7 +22,9 @@ namespace Microsoft.Terminal.Settings.Model
|
|||||||
// and pass along the Core properties to the terminal core.
|
// and pass along the Core properties to the terminal core.
|
||||||
[default_interface]
|
[default_interface]
|
||||||
runtimeclass TerminalSettings : Microsoft.Terminal.Core.ICoreSettings,
|
runtimeclass TerminalSettings : Microsoft.Terminal.Core.ICoreSettings,
|
||||||
Microsoft.Terminal.Control.IControlSettings
|
Microsoft.Terminal.Control.IControlSettings,
|
||||||
|
Microsoft.Terminal.Core.ICoreAppearance,
|
||||||
|
Microsoft.Terminal.Control.IControlAppearance
|
||||||
{
|
{
|
||||||
TerminalSettings();
|
TerminalSettings();
|
||||||
|
|
||||||
|
|||||||
150
src/cascadia/WindowsTerminal/ContentProcessMain.cpp
Normal file
150
src/cascadia/WindowsTerminal/ContentProcessMain.cpp
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
#include "pch.h"
|
||||||
|
#include "AppHost.h"
|
||||||
|
#include "resource.h"
|
||||||
|
#include "../types/inc/User32Utils.hpp"
|
||||||
|
#include <WilErrorReporting.h>
|
||||||
|
|
||||||
|
using namespace winrt;
|
||||||
|
using namespace winrt::Windows::UI;
|
||||||
|
using namespace winrt::Windows::UI::Composition;
|
||||||
|
using namespace winrt::Windows::UI::Xaml::Hosting;
|
||||||
|
using namespace winrt::Windows::Foundation::Numerics;
|
||||||
|
|
||||||
|
// We keep a weak ref to our ContentProcess singleton here.
|
||||||
|
// Why?
|
||||||
|
//
|
||||||
|
// We need to always return the _same_ ContentProcess when someone comes to
|
||||||
|
// instantiate this class. So we want to track the single instance we make. We
|
||||||
|
// also want to track when the last outstanding reference to this object is
|
||||||
|
// removed. If we're keeping a strong ref, then the ref count will always be > 1
|
||||||
|
|
||||||
|
winrt::weak_ref<winrt::Microsoft::Terminal::Control::ContentProcess> g_weak{ nullptr };
|
||||||
|
wil::unique_event g_canExitThread;
|
||||||
|
|
||||||
|
struct ContentProcessFactory : implements<ContentProcessFactory, IClassFactory>
|
||||||
|
{
|
||||||
|
ContentProcessFactory(winrt::guid g) :
|
||||||
|
_guid{ g } {};
|
||||||
|
|
||||||
|
HRESULT __stdcall CreateInstance(IUnknown* outer, GUID const& iid, void** result) noexcept final
|
||||||
|
{
|
||||||
|
*result = nullptr;
|
||||||
|
if (outer)
|
||||||
|
{
|
||||||
|
return CLASS_E_NOAGGREGATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!g_weak)
|
||||||
|
{
|
||||||
|
// Instantiate the ContentProcess here
|
||||||
|
winrt::Microsoft::Terminal::Control::ContentProcess strong{ _guid };
|
||||||
|
|
||||||
|
// Now, create a weak ref to that ContentProcess object.
|
||||||
|
winrt::weak_ref<winrt::Microsoft::Terminal::Control::ContentProcess> weak{ strong };
|
||||||
|
|
||||||
|
// Stash away that weak ref for future callers.
|
||||||
|
g_weak = weak;
|
||||||
|
return strong.as(iid, result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto strong = g_weak.get();
|
||||||
|
// !! LOAD BEARING !! If you set this event in the _first_ branch
|
||||||
|
// here, when we first create the object, then there will be _no_
|
||||||
|
// referernces to the ContentProcess object for a small slice. We'll
|
||||||
|
// stash the ContentProcess in the weak_ptr, and return it, and at
|
||||||
|
// that moment, there will be 0 outstanding references, it'll dtor,
|
||||||
|
// and wei'll ExitProcess.
|
||||||
|
//
|
||||||
|
// Instead, set the event here, once there's already a reference
|
||||||
|
// outside of just the weak one we keep. Experimentation showed this
|
||||||
|
// waw always hit when creating the ContentProcess at least once.
|
||||||
|
g_canExitThread.SetEvent();
|
||||||
|
return strong.as(iid, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT __stdcall LockServer(BOOL) noexcept final
|
||||||
|
{
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
winrt::guid _guid;
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool checkIfContentProcess(winrt::guid& contentProcessGuid, HANDLE& eventHandle)
|
||||||
|
{
|
||||||
|
std::vector<std::wstring> args;
|
||||||
|
|
||||||
|
if (auto commandline{ GetCommandLineW() })
|
||||||
|
{
|
||||||
|
int argc = 0;
|
||||||
|
|
||||||
|
// Get the argv, and turn them into a hstring array to pass to the app.
|
||||||
|
wil::unique_any<LPWSTR*, decltype(&::LocalFree), ::LocalFree> argv{ CommandLineToArgvW(commandline, &argc) };
|
||||||
|
if (argv)
|
||||||
|
{
|
||||||
|
for (auto& elem : wil::make_range(argv.get(), argc))
|
||||||
|
{
|
||||||
|
args.emplace_back(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (args.size() == 5 &&
|
||||||
|
args.at(1) == L"--content" &&
|
||||||
|
args.at(3) == L"--signal")
|
||||||
|
{
|
||||||
|
auto& guidString{ args.at(2) };
|
||||||
|
auto canConvert = guidString.length() == 38 && guidString.front() == '{' && guidString.back() == '}';
|
||||||
|
if (canConvert)
|
||||||
|
{
|
||||||
|
GUID result{};
|
||||||
|
THROW_IF_FAILED(IIDFromString(guidString.c_str(), &result));
|
||||||
|
contentProcessGuid = result;
|
||||||
|
|
||||||
|
eventHandle = reinterpret_cast<HANDLE>(wcstoul(args.at(4).c_str(),
|
||||||
|
nullptr /*endptr*/,
|
||||||
|
16 /*base*/));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void doContentProcessThing(const winrt::guid& contentProcessGuid, const HANDLE& eventHandle)
|
||||||
|
{
|
||||||
|
// !! LOAD BEARING !! - important to be a MTA for these COM calls.
|
||||||
|
winrt::init_apartment();
|
||||||
|
DWORD registrationHostClass{};
|
||||||
|
check_hresult(CoRegisterClassObject(contentProcessGuid,
|
||||||
|
make<ContentProcessFactory>(contentProcessGuid).get(),
|
||||||
|
CLSCTX_LOCAL_SERVER,
|
||||||
|
REGCLS_MULTIPLEUSE,
|
||||||
|
®istrationHostClass));
|
||||||
|
|
||||||
|
// Signal the event handle that was passed to us that we're now set up and
|
||||||
|
// ready to go.
|
||||||
|
SetEvent(eventHandle);
|
||||||
|
CloseHandle(eventHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TryRunAsContentProcess()
|
||||||
|
{
|
||||||
|
winrt::guid contentProcessGuid{};
|
||||||
|
HANDLE eventHandle{ INVALID_HANDLE_VALUE };
|
||||||
|
if (checkIfContentProcess(contentProcessGuid, eventHandle))
|
||||||
|
{
|
||||||
|
g_canExitThread = wil::unique_event{ CreateEvent(nullptr, true, false, nullptr /*L"ContentProcessReady"*/) };
|
||||||
|
|
||||||
|
doContentProcessThing(contentProcessGuid, eventHandle);
|
||||||
|
|
||||||
|
WaitForSingleObject(g_canExitThread.get(), INFINITE);
|
||||||
|
// This is the conhost thing - if we ExitThread the main thread, the
|
||||||
|
// other threads can keep running till one calls ExitProcess.
|
||||||
|
ExitThread(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -55,6 +55,7 @@
|
|||||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="main.cpp" />
|
<ClCompile Include="main.cpp" />
|
||||||
|
<ClCompile Include="ContentProcessMain.cpp" />
|
||||||
<ClCompile Include="AppHost.cpp" />
|
<ClCompile Include="AppHost.cpp" />
|
||||||
<ClCompile Include="IslandWindow.cpp" />
|
<ClCompile Include="IslandWindow.cpp" />
|
||||||
<ClCompile Include="NonClientIslandWindow.cpp" />
|
<ClCompile Include="NonClientIslandWindow.cpp" />
|
||||||
@@ -99,8 +100,8 @@
|
|||||||
<Reference Include="Microsoft.Terminal.Core">
|
<Reference Include="Microsoft.Terminal.Core">
|
||||||
<HintPath>$(OpenConsoleCommonOutDir)TerminalCore\Microsoft.Terminal.Core.winmd</HintPath>
|
<HintPath>$(OpenConsoleCommonOutDir)TerminalCore\Microsoft.Terminal.Core.winmd</HintPath>
|
||||||
<IsWinMDFile>true</IsWinMDFile>
|
<IsWinMDFile>true</IsWinMDFile>
|
||||||
<Private>false</Private>
|
<Private>true</Private>
|
||||||
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
|
<CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
|
||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<!--
|
<!--
|
||||||
@@ -177,4 +178,4 @@
|
|||||||
</Target>
|
</Target>
|
||||||
<Import Project="$(OpenConsoleDir)\build\rules\GenerateSxsManifestsFromWinmds.targets" />
|
<Import Project="$(OpenConsoleDir)\build\rules\GenerateSxsManifestsFromWinmds.targets" />
|
||||||
<Import Project="..\..\..\packages\Microsoft.Internal.Windows.Terminal.ThemeHelpers.0.3.210521003\build\native\Microsoft.Internal.Windows.Terminal.ThemeHelpers.targets" Condition="Exists('..\..\..\packages\Microsoft.Internal.Windows.Terminal.ThemeHelpers.0.3.210521003\build\native\Microsoft.Internal.Windows.Terminal.ThemeHelpers.targets')" />
|
<Import Project="..\..\..\packages\Microsoft.Internal.Windows.Terminal.ThemeHelpers.0.3.210521003\build\native\Microsoft.Internal.Windows.Terminal.ThemeHelpers.targets" Condition="Exists('..\..\..\packages\Microsoft.Internal.Windows.Terminal.ThemeHelpers.0.3.210521003\build\native\Microsoft.Internal.Windows.Terminal.ThemeHelpers.targets')" />
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ TRACELOGGING_DEFINE_PROVIDER(
|
|||||||
#include <LibraryResources.h>
|
#include <LibraryResources.h>
|
||||||
UTILS_DEFINE_LIBRARY_RESOURCE_SCOPE(L"TerminalApp/Resources");
|
UTILS_DEFINE_LIBRARY_RESOURCE_SCOPE(L"TerminalApp/Resources");
|
||||||
|
|
||||||
|
void TryRunAsContentProcess();
|
||||||
|
|
||||||
// Routine Description:
|
// Routine Description:
|
||||||
// - Takes an image architecture and locates a string resource that maps to that architecture.
|
// - Takes an image architecture and locates a string resource that maps to that architecture.
|
||||||
// Arguments:
|
// Arguments:
|
||||||
@@ -119,6 +121,13 @@ int __stdcall wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int)
|
|||||||
// should choose and install the correct one from the bundle.
|
// should choose and install the correct one from the bundle.
|
||||||
EnsureNativeArchitecture();
|
EnsureNativeArchitecture();
|
||||||
|
|
||||||
|
// If we _are_ a content process, then this function will call ExitThread(),
|
||||||
|
// after spawning some COM threads to deal with inbound COM requests to the
|
||||||
|
// ContentProcess object.
|
||||||
|
TryRunAsContentProcess();
|
||||||
|
// If we weren't a content process, then we'll just move on, and do the
|
||||||
|
// normal WindowsTerminal thing.
|
||||||
|
|
||||||
// Make sure to call this so we get WM_POINTER messages.
|
// Make sure to call this so we get WM_POINTER messages.
|
||||||
EnableMouseInPointer(true);
|
EnableMouseInPointer(true);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user