mirror of
https://github.com/microsoft/terminal.git
synced 2026-05-21 22:37:19 +00:00
Compare commits
59 Commits
dev/migrie
...
release-1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ca815287b | ||
|
|
24a69689c2 | ||
|
|
a512dddc08 | ||
|
|
c2bc927e50 | ||
|
|
689be38372 | ||
|
|
744631a293 | ||
|
|
89191f8211 | ||
|
|
fce00ff8f6 | ||
|
|
d1b26085e1 | ||
|
|
da26894434 | ||
|
|
5bfbebe3ac | ||
|
|
82534cf8e0 | ||
|
|
6cc7dfaf85 | ||
|
|
72ac061a8e | ||
|
|
2fcf5d7903 | ||
|
|
952f5b11ef | ||
|
|
489329bf41 | ||
|
|
3098fba203 | ||
|
|
1aa3909fea | ||
|
|
f4d6756b68 | ||
|
|
eecf76478b | ||
|
|
4ede37767a | ||
|
|
830c79be93 | ||
|
|
596597bca3 | ||
|
|
136db72b8a | ||
|
|
1607804dfc | ||
|
|
b2c521a372 | ||
|
|
7ca3e35b94 | ||
|
|
fe4f0f38cb | ||
|
|
bb5549a98d | ||
|
|
8a758f7f85 | ||
|
|
a0a70cc801 | ||
|
|
888b6e95b9 | ||
|
|
9f5967527c | ||
|
|
72bedcc159 | ||
|
|
d9c95ca31c | ||
|
|
74678ff2b0 | ||
|
|
67e205746c | ||
|
|
e3edf180a8 | ||
|
|
b78ceacd84 | ||
|
|
fd1afae214 | ||
|
|
ef5198e231 | ||
|
|
62d22c2a57 | ||
|
|
1279c63819 | ||
|
|
cf25fd0e7f | ||
|
|
afe5860ead | ||
|
|
c66f8feffb | ||
|
|
c529789bb3 | ||
|
|
57ca2ec8a4 | ||
|
|
2592cc41fe | ||
|
|
cf81d8c3c5 | ||
|
|
b49fa5ec59 | ||
|
|
ca0dc3d9fd | ||
|
|
825039ea17 | ||
|
|
21ab0a841d | ||
|
|
6ad0bb9232 | ||
|
|
a5b29b6abf | ||
|
|
a7a7d506d3 | ||
|
|
0e4ffd6f58 |
25
.github/actions/spell-check/advice.txt
vendored
25
.github/actions/spell-check/advice.txt
vendored
@@ -1,25 +0,0 @@
|
|||||||
<details>
|
|
||||||
<summary>
|
|
||||||
:pencil2: Contributor please read this
|
|
||||||
</summary>
|
|
||||||
|
|
||||||
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...
|
|
||||||
|
|
||||||
If the listed items are:
|
|
||||||
* ... **misspelled**, then please *correct* them instead of using the command.
|
|
||||||
* ... *names*, please add them to `.github/actions/spell-check/dictionary/names.txt`.
|
|
||||||
* ... APIs, you can add them to a file in `.github/actions/spell-check/dictionary/`.
|
|
||||||
* ... just things you're using, please add them to an appropriate file in `.github/actions/spell-check/expect/`.
|
|
||||||
* ... tokens you only need in one place and shouldn't *generally be used*, you can add an item in an appropriate file in `.github/actions/spell-check/patterns/`.
|
|
||||||
|
|
||||||
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:
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
#### :warning: Reviewers
|
|
||||||
At present, the action that triggered this message will not show its :x: in this PR unless the branch is within this repository.
|
|
||||||
Thus, you **should** make sure that this comment has been addressed before encouraging the merge bot to merge this PR.
|
|
||||||
55
.github/actions/spell-check/dictionary/apis.txt
vendored
55
.github/actions/spell-check/dictionary/apis.txt
vendored
@@ -1,55 +0,0 @@
|
|||||||
ACCEPTFILES
|
|
||||||
ACCESSDENIED
|
|
||||||
alignof
|
|
||||||
bitfield
|
|
||||||
bitfields
|
|
||||||
CLASSNOTAVAILABLE
|
|
||||||
environstrings
|
|
||||||
EXPCMDFLAGS
|
|
||||||
EXPCMDSTATE
|
|
||||||
fullkbd
|
|
||||||
futex
|
|
||||||
Hashtable
|
|
||||||
href
|
|
||||||
IAsync
|
|
||||||
IBind
|
|
||||||
IBox
|
|
||||||
IClass
|
|
||||||
IComparable
|
|
||||||
ICustom
|
|
||||||
IDialog
|
|
||||||
IDirect
|
|
||||||
IExplorer
|
|
||||||
IMap
|
|
||||||
IObject
|
|
||||||
IStorage
|
|
||||||
llabs
|
|
||||||
LCID
|
|
||||||
lround
|
|
||||||
LSHIFT
|
|
||||||
NCHITTEST
|
|
||||||
NCLBUTTONDBLCLK
|
|
||||||
NCRBUTTONDBLCLK
|
|
||||||
NOAGGREGATION
|
|
||||||
NOREDIRECTIONBITMAP
|
|
||||||
oaidl
|
|
||||||
ocidl
|
|
||||||
otms
|
|
||||||
OUTLINETEXTMETRICW
|
|
||||||
PAGESCROLL
|
|
||||||
RETURNCMD
|
|
||||||
rfind
|
|
||||||
roundf
|
|
||||||
RSHIFT
|
|
||||||
rx
|
|
||||||
serializer
|
|
||||||
SIZENS
|
|
||||||
spsc
|
|
||||||
STDCPP
|
|
||||||
syscall
|
|
||||||
tmp
|
|
||||||
tx
|
|
||||||
userenv
|
|
||||||
wcstoui
|
|
||||||
XDocument
|
|
||||||
XElement
|
|
||||||
479835
.github/actions/spell-check/dictionary/dictionary.txt
vendored
479835
.github/actions/spell-check/dictionary/dictionary.txt
vendored
File diff suppressed because it is too large
Load Diff
@@ -1,3 +0,0 @@
|
|||||||
powf
|
|
||||||
sqrtf
|
|
||||||
isnan
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
ACLs
|
|
||||||
altform
|
|
||||||
appendwttlogging
|
|
||||||
backplating
|
|
||||||
CPRs
|
|
||||||
DACL
|
|
||||||
DACLs
|
|
||||||
dotnetfeed
|
|
||||||
DWINRT
|
|
||||||
enablewttlogging
|
|
||||||
LKG
|
|
||||||
mfcribbon
|
|
||||||
microsoft
|
|
||||||
microsoftonline
|
|
||||||
netcore
|
|
||||||
osgvsowi
|
|
||||||
pgc
|
|
||||||
pgo
|
|
||||||
pgosweep
|
|
||||||
powerrename
|
|
||||||
powershell
|
|
||||||
propkey
|
|
||||||
pscustomobject
|
|
||||||
robocopy
|
|
||||||
SACLs
|
|
||||||
Shobjidl
|
|
||||||
Skype
|
|
||||||
sysnative
|
|
||||||
systemroot
|
|
||||||
taskkill
|
|
||||||
tasklist
|
|
||||||
tdbuildteamid
|
|
||||||
vcruntime
|
|
||||||
visualstudio
|
|
||||||
wlk
|
|
||||||
wslpath
|
|
||||||
wtl
|
|
||||||
wtt
|
|
||||||
wttlog
|
|
||||||
63
.github/actions/spell-check/excludes.txt
vendored
63
.github/actions/spell-check/excludes.txt
vendored
@@ -1,63 +0,0 @@
|
|||||||
(?:^|/)dirs$
|
|
||||||
(?:^|/)go\.mod$
|
|
||||||
(?:^|/)go\.sum$
|
|
||||||
(?:^|/)package-lock\.json$
|
|
||||||
(?:^|/)sources(?:|\.dep)$
|
|
||||||
SUMS$
|
|
||||||
\.ai$
|
|
||||||
\.bmp$
|
|
||||||
\.cer$
|
|
||||||
\.class$
|
|
||||||
\.crl$
|
|
||||||
\.crt$
|
|
||||||
\.csr$
|
|
||||||
\.dll$
|
|
||||||
\.DS_Store$
|
|
||||||
\.eot$
|
|
||||||
\.eps$
|
|
||||||
\.exe$
|
|
||||||
\.gif$
|
|
||||||
\.graffle$
|
|
||||||
\.gz$
|
|
||||||
\.icns$
|
|
||||||
\.ico$
|
|
||||||
\.jar$
|
|
||||||
\.jpeg$
|
|
||||||
\.jpg$
|
|
||||||
\.key$
|
|
||||||
\.lib$
|
|
||||||
\.lock$
|
|
||||||
\.map$
|
|
||||||
\.min\..
|
|
||||||
\.mp3$
|
|
||||||
\.mp4$
|
|
||||||
\.otf$
|
|
||||||
\.pbxproj$
|
|
||||||
\.pdf$
|
|
||||||
\.pem$
|
|
||||||
\.png$
|
|
||||||
\.psd$
|
|
||||||
\.runsettings$
|
|
||||||
\.sig$
|
|
||||||
\.so$
|
|
||||||
\.svg$
|
|
||||||
\.svgz$
|
|
||||||
\.tar$
|
|
||||||
\.tgz$
|
|
||||||
\.ttf$
|
|
||||||
\.woff
|
|
||||||
\.xcf$
|
|
||||||
\.xls
|
|
||||||
\.xpm$
|
|
||||||
\.yml$
|
|
||||||
\.zip$
|
|
||||||
^consolegit2gitfilters\.json$
|
|
||||||
^dep/
|
|
||||||
^oss/
|
|
||||||
^doc/reference/UTF8-torture-test\.txt$
|
|
||||||
^src/interactivity/onecore/BgfxEngine\.
|
|
||||||
^src/renderer/wddmcon/WddmConRenderer\.
|
|
||||||
^src/terminal/parser/ft_fuzzer/VTCommandFuzzer\.cpp$
|
|
||||||
^src/tools/U8U16Test/(?:fr|ru|zh)\.txt$
|
|
||||||
^\.github/actions/spell-check/
|
|
||||||
^\.gitignore$
|
|
||||||
15
.github/actions/spell-check/expect/web.txt
vendored
15
.github/actions/spell-check/expect/web.txt
vendored
@@ -1,15 +0,0 @@
|
|||||||
http
|
|
||||||
td
|
|
||||||
www
|
|
||||||
ecma
|
|
||||||
rapidtables
|
|
||||||
WCAG
|
|
||||||
freedesktop
|
|
||||||
ycombinator
|
|
||||||
robertelder
|
|
||||||
kovidgoyal
|
|
||||||
leonerd
|
|
||||||
fixterms
|
|
||||||
uk
|
|
||||||
winui
|
|
||||||
appshellintegration
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
https://(?:(?:[-a-zA-Z0-9?&=]*\.|)microsoft\.com)/[-a-zA-Z0-9?&=_#\/.]*
|
|
||||||
https://aka\.ms/[-a-zA-Z0-9?&=\/_]*
|
|
||||||
https://www\.itscj\.ipsj\.or\.jp/iso-ir/[-0-9]+\.pdf
|
|
||||||
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-]+\.githubusercontent\.com/[-a-zA-Z0-9?&=_\/.]*
|
|
||||||
[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)
|
|
||||||
(?:0[Xx]|\\x|U\+|#)[a-f0-9A-FGgRr]{2,}[Uu]?[Ll]{0,2}\b
|
|
||||||
microsoft/cascadia-code\@[0-9a-fA-F]{40}
|
|
||||||
\d+x\d+Logo
|
|
||||||
Scro\&ll
|
|
||||||
# selectionInput.cpp
|
|
||||||
:\\windows\\syste\b
|
|
||||||
TestUtils::VerifyExpectedString\(tb, L"[^"]+"
|
|
||||||
(?:hostSm|mach)\.ProcessString\(L"[^"]+"
|
|
||||||
\b([A-Za-z])\1{3,}\b
|
|
||||||
Base64::s_(?:En|De)code\(L"[^"]+"
|
|
||||||
VERIFY_ARE_EQUAL\(L"[^"]+"
|
|
||||||
L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\+/"
|
|
||||||
std::memory_order_[\w]+
|
|
||||||
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.
|
||||||
48
.github/actions/spelling/advice.md
vendored
Normal file
48
.github/actions/spelling/advice.md
vendored
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<!-- See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-advice --> <!-- markdownlint-disable MD033 MD041 -->
|
||||||
|
<details>
|
||||||
|
<summary>
|
||||||
|
:pencil2: Contributor please read this
|
||||||
|
</summary>
|
||||||
|
|
||||||
|
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. 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:
|
||||||
|
|
||||||
|
* ... **misspelled**, then please *correct* them instead of using the command.
|
||||||
|
* ... *names*, please add them to `.github/actions/spelling/allow/names.txt`.
|
||||||
|
* ... APIs, you can add them to a file in `.github/actions/spelling/allow/`.
|
||||||
|
* ... just things you're using, please add them to an appropriate file in `.github/actions/spelling/expect/`.
|
||||||
|
* ... tokens you only need in one place and shouldn't *generally be used*, you can add an item in an appropriate file in `.github/actions/spelling/patterns/`.
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
|
||||||
|
<details><summary>If the flagged items are :exploding_head: false positives</summary>
|
||||||
|
|
||||||
|
If items relate to a ...
|
||||||
|
* binary file (or some other file you wouldn't want to check at all).
|
||||||
|
|
||||||
|
Please add a file path to the `excludes.txt` file matching the containing file.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
`^` 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).
|
||||||
|
|
||||||
|
* 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>
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
# Dictionaries are lists of words to accept unconditionally
|
# Allow files are lists of words to accept unconditionally
|
||||||
|
|
||||||
While check spelling will complain about a whitelisted word
|
While check spelling will complain about an expected word
|
||||||
which is no longer present, you can include things here even if
|
which is no longer present, you can include things here even if
|
||||||
they are not otherwise present in the repository.
|
they are not otherwise present in the repository.
|
||||||
|
|
||||||
@@ -8,13 +8,14 @@ E.g., you could include a list of system APIs here, or potential
|
|||||||
contributors (so that if a future commit includes their name,
|
contributors (so that if a future commit includes their name,
|
||||||
it'll be accepted).
|
it'll be accepted).
|
||||||
|
|
||||||
### Files
|
## Files
|
||||||
|
|
||||||
| File | Description |
|
| File | Description |
|
||||||
| ---- | ----------- |
|
| ---- | ----------- |
|
||||||
| [Dictionary](dictionary.txt) | Primary US English dictionary |
|
| [Allow](allow.txt) | Supplements to the dictionary |
|
||||||
| [Chinese](chinese.txt) | Chinese words |
|
| [Chinese](chinese.txt) | Chinese words |
|
||||||
| [Japanese](japanese.txt) | Japanese words |
|
| [Japanese](japanese.txt) | Japanese words |
|
||||||
| [Microsoft](microsoft.txt) | Microsoft brand items |
|
| [Microsoft](microsoft.txt) | Microsoft brand items |
|
||||||
| [Fonts](fonts.txt) | Font names |
|
| [Fonts](fonts.txt) | Font names |
|
||||||
| [Names](names.txt) | Names of people |
|
| [Names](names.txt) | Names of people |
|
||||||
|
| [Colors](colors.txt) | Names of color |
|
||||||
108
.github/actions/spelling/allow/allow.txt
vendored
Normal file
108
.github/actions/spelling/allow/allow.txt
vendored
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
admins
|
||||||
|
allcolors
|
||||||
|
Apc
|
||||||
|
apc
|
||||||
|
breadcrumb
|
||||||
|
breadcrumbs
|
||||||
|
bsd
|
||||||
|
calt
|
||||||
|
ccmp
|
||||||
|
changelog
|
||||||
|
clickable
|
||||||
|
clig
|
||||||
|
CMMI
|
||||||
|
copyable
|
||||||
|
cybersecurity
|
||||||
|
dalet
|
||||||
|
Dcs
|
||||||
|
dcs
|
||||||
|
dialytika
|
||||||
|
dje
|
||||||
|
downside
|
||||||
|
downsides
|
||||||
|
dze
|
||||||
|
dzhe
|
||||||
|
EDDB
|
||||||
|
EDDC
|
||||||
|
Enum'd
|
||||||
|
Fitt
|
||||||
|
formattings
|
||||||
|
FTCS
|
||||||
|
ftp
|
||||||
|
fvar
|
||||||
|
gantt
|
||||||
|
gcc
|
||||||
|
geeksforgeeks
|
||||||
|
ghe
|
||||||
|
github
|
||||||
|
gje
|
||||||
|
godbolt
|
||||||
|
hostname
|
||||||
|
hostnames
|
||||||
|
https
|
||||||
|
hyperlink
|
||||||
|
hyperlinking
|
||||||
|
hyperlinks
|
||||||
|
iconify
|
||||||
|
img
|
||||||
|
inlined
|
||||||
|
It'd
|
||||||
|
kje
|
||||||
|
libfuzzer
|
||||||
|
libuv
|
||||||
|
liga
|
||||||
|
lje
|
||||||
|
Llast
|
||||||
|
llvm
|
||||||
|
Lmid
|
||||||
|
locl
|
||||||
|
lol
|
||||||
|
lorem
|
||||||
|
Lorigin
|
||||||
|
maxed
|
||||||
|
minimalistic
|
||||||
|
mkmk
|
||||||
|
mnt
|
||||||
|
mru
|
||||||
|
nje
|
||||||
|
noreply
|
||||||
|
ogonek
|
||||||
|
ok'd
|
||||||
|
overlined
|
||||||
|
pipeline
|
||||||
|
postmodern
|
||||||
|
ptys
|
||||||
|
qof
|
||||||
|
qps
|
||||||
|
rclt
|
||||||
|
reimplementation
|
||||||
|
reserialization
|
||||||
|
reserialize
|
||||||
|
reserializes
|
||||||
|
rlig
|
||||||
|
runtimes
|
||||||
|
shcha
|
||||||
|
slnt
|
||||||
|
Sos
|
||||||
|
ssh
|
||||||
|
timeline
|
||||||
|
timelines
|
||||||
|
timestamped
|
||||||
|
TLDR
|
||||||
|
tokenizes
|
||||||
|
tonos
|
||||||
|
toolset
|
||||||
|
tshe
|
||||||
|
ubuntu
|
||||||
|
uiatextrange
|
||||||
|
UIs
|
||||||
|
und
|
||||||
|
unregister
|
||||||
|
versioned
|
||||||
|
vsdevcmd
|
||||||
|
We'd
|
||||||
|
wildcards
|
||||||
|
XBox
|
||||||
|
YBox
|
||||||
|
yeru
|
||||||
|
zhe
|
||||||
248
.github/actions/spelling/allow/apis.txt
vendored
Normal file
248
.github/actions/spelling/allow/apis.txt
vendored
Normal file
@@ -0,0 +1,248 @@
|
|||||||
|
ACCEPTFILES
|
||||||
|
ACCESSDENIED
|
||||||
|
acl
|
||||||
|
aclapi
|
||||||
|
alignas
|
||||||
|
alignof
|
||||||
|
APPLYTOSUBMENUS
|
||||||
|
appxrecipe
|
||||||
|
bitfield
|
||||||
|
bitfields
|
||||||
|
BUILDBRANCH
|
||||||
|
BUILDMSG
|
||||||
|
BUILDNUMBER
|
||||||
|
BYCOMMAND
|
||||||
|
BYPOSITION
|
||||||
|
charconv
|
||||||
|
CLASSNOTAVAILABLE
|
||||||
|
CLOSEAPP
|
||||||
|
cmdletbinding
|
||||||
|
COLORPROPERTY
|
||||||
|
colspan
|
||||||
|
COMDLG
|
||||||
|
commandlinetoargv
|
||||||
|
comparand
|
||||||
|
cstdint
|
||||||
|
CXICON
|
||||||
|
CYICON
|
||||||
|
Dacl
|
||||||
|
dataobject
|
||||||
|
dcomp
|
||||||
|
DERR
|
||||||
|
dlldata
|
||||||
|
DNE
|
||||||
|
DONTADDTORECENT
|
||||||
|
DWMSBT
|
||||||
|
DWMWA
|
||||||
|
DWMWA
|
||||||
|
DWORDLONG
|
||||||
|
endfor
|
||||||
|
ENDSESSION
|
||||||
|
enumset
|
||||||
|
environstrings
|
||||||
|
EXPCMDFLAGS
|
||||||
|
EXPCMDSTATE
|
||||||
|
filetime
|
||||||
|
FILTERSPEC
|
||||||
|
FORCEFILESYSTEM
|
||||||
|
FORCEMINIMIZE
|
||||||
|
frac
|
||||||
|
fullkbd
|
||||||
|
futex
|
||||||
|
GETDESKWALLPAPER
|
||||||
|
GETHIGHCONTRAST
|
||||||
|
GETMOUSEHOVERTIME
|
||||||
|
Hashtable
|
||||||
|
HIGHCONTRASTON
|
||||||
|
HIGHCONTRASTW
|
||||||
|
hotkeys
|
||||||
|
href
|
||||||
|
hrgn
|
||||||
|
HTCLOSE
|
||||||
|
hwinsta
|
||||||
|
HWINSTA
|
||||||
|
IActivation
|
||||||
|
IApp
|
||||||
|
IAppearance
|
||||||
|
IAsync
|
||||||
|
IBind
|
||||||
|
IBox
|
||||||
|
IClass
|
||||||
|
IComparable
|
||||||
|
IComparer
|
||||||
|
IConnection
|
||||||
|
ICustom
|
||||||
|
IDialog
|
||||||
|
IDirect
|
||||||
|
IExplorer
|
||||||
|
IFACEMETHOD
|
||||||
|
IFile
|
||||||
|
IGraphics
|
||||||
|
IInheritable
|
||||||
|
IMap
|
||||||
|
IMonarch
|
||||||
|
IObject
|
||||||
|
iosfwd
|
||||||
|
IPackage
|
||||||
|
IPeasant
|
||||||
|
ISetup
|
||||||
|
isspace
|
||||||
|
IStorage
|
||||||
|
istream
|
||||||
|
IStringable
|
||||||
|
ITab
|
||||||
|
ITaskbar
|
||||||
|
itow
|
||||||
|
IUri
|
||||||
|
IVirtual
|
||||||
|
KEYSELECT
|
||||||
|
LCID
|
||||||
|
llabs
|
||||||
|
llu
|
||||||
|
localtime
|
||||||
|
lround
|
||||||
|
Lsa
|
||||||
|
lsass
|
||||||
|
LSHIFT
|
||||||
|
LTGRAY
|
||||||
|
MAINWINDOW
|
||||||
|
memchr
|
||||||
|
memicmp
|
||||||
|
MENUCOMMAND
|
||||||
|
MENUDATA
|
||||||
|
MENUINFO
|
||||||
|
MENUITEMINFOW
|
||||||
|
mmeapi
|
||||||
|
MOUSELEAVE
|
||||||
|
mov
|
||||||
|
mptt
|
||||||
|
msappx
|
||||||
|
MULTIPLEUSE
|
||||||
|
NCHITTEST
|
||||||
|
NCLBUTTONDBLCLK
|
||||||
|
NCMOUSELEAVE
|
||||||
|
NCMOUSEMOVE
|
||||||
|
NCRBUTTONDBLCLK
|
||||||
|
NIF
|
||||||
|
NIN
|
||||||
|
NOAGGREGATION
|
||||||
|
NOASYNC
|
||||||
|
NOCHANGEDIR
|
||||||
|
NOPROGRESS
|
||||||
|
NOREDIRECTIONBITMAP
|
||||||
|
NOREPEAT
|
||||||
|
NOTIFYBYPOS
|
||||||
|
NOTIFYICON
|
||||||
|
NOTIFYICONDATA
|
||||||
|
ntprivapi
|
||||||
|
oaidl
|
||||||
|
ocidl
|
||||||
|
ODR
|
||||||
|
offsetof
|
||||||
|
ofstream
|
||||||
|
onefuzz
|
||||||
|
osver
|
||||||
|
OSVERSIONINFOEXW
|
||||||
|
otms
|
||||||
|
OUTLINETEXTMETRICW
|
||||||
|
overridable
|
||||||
|
PACL
|
||||||
|
PAGESCROLL
|
||||||
|
PATINVERT
|
||||||
|
PEXPLICIT
|
||||||
|
PICKFOLDERS
|
||||||
|
pmr
|
||||||
|
ptstr
|
||||||
|
QUERYENDSESSION
|
||||||
|
rcx
|
||||||
|
REGCLS
|
||||||
|
RETURNCMD
|
||||||
|
rfind
|
||||||
|
ROOTOWNER
|
||||||
|
roundf
|
||||||
|
RSHIFT
|
||||||
|
SACL
|
||||||
|
schandle
|
||||||
|
semver
|
||||||
|
serializer
|
||||||
|
SETVERSION
|
||||||
|
SHELLEXECUTEINFOW
|
||||||
|
shobjidl
|
||||||
|
SHOWHIDE
|
||||||
|
SHOWMINIMIZED
|
||||||
|
SHOWTIP
|
||||||
|
SINGLEUSE
|
||||||
|
SIZENS
|
||||||
|
smoothstep
|
||||||
|
snprintf
|
||||||
|
spsc
|
||||||
|
sregex
|
||||||
|
SRWLOC
|
||||||
|
SRWLOCK
|
||||||
|
STDCPP
|
||||||
|
STDMETHOD
|
||||||
|
strchr
|
||||||
|
strcpy
|
||||||
|
streambuf
|
||||||
|
strtoul
|
||||||
|
Stubless
|
||||||
|
Subheader
|
||||||
|
Subpage
|
||||||
|
syscall
|
||||||
|
SYSTEMBACKDROP
|
||||||
|
TABROW
|
||||||
|
TASKBARCREATED
|
||||||
|
TBPF
|
||||||
|
THEMECHANGED
|
||||||
|
tlg
|
||||||
|
TME
|
||||||
|
tmp
|
||||||
|
tmpdir
|
||||||
|
tolower
|
||||||
|
toupper
|
||||||
|
TRACKMOUSEEVENT
|
||||||
|
TTask
|
||||||
|
TVal
|
||||||
|
UChar
|
||||||
|
UFIELD
|
||||||
|
ULARGE
|
||||||
|
UOI
|
||||||
|
UPDATEINIFILE
|
||||||
|
userenv
|
||||||
|
USEROBJECTFLAGS
|
||||||
|
Viewbox
|
||||||
|
virtualalloc
|
||||||
|
wcsstr
|
||||||
|
wcstoui
|
||||||
|
winmain
|
||||||
|
winsta
|
||||||
|
winstamin
|
||||||
|
wmemcmp
|
||||||
|
wpc
|
||||||
|
WSF
|
||||||
|
wsregex
|
||||||
|
wwinmain
|
||||||
|
xchg
|
||||||
|
XDocument
|
||||||
|
XElement
|
||||||
|
xfacet
|
||||||
|
xhash
|
||||||
|
XIcon
|
||||||
|
xiosbase
|
||||||
|
xlocale
|
||||||
|
xlocbuf
|
||||||
|
xlocinfo
|
||||||
|
xlocmes
|
||||||
|
xlocmon
|
||||||
|
xlocnum
|
||||||
|
xloctime
|
||||||
|
XMax
|
||||||
|
xmemory
|
||||||
|
XParse
|
||||||
|
xpath
|
||||||
|
xstddef
|
||||||
|
xstring
|
||||||
|
xtree
|
||||||
|
xutility
|
||||||
|
YIcon
|
||||||
|
YMax
|
||||||
117
.github/actions/spelling/allow/colors.txt
vendored
Normal file
117
.github/actions/spelling/allow/colors.txt
vendored
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
alice
|
||||||
|
aliceblue
|
||||||
|
antiquewhite
|
||||||
|
blanchedalmond
|
||||||
|
blueviolet
|
||||||
|
burlywood
|
||||||
|
cadetblue
|
||||||
|
cornflowerblue
|
||||||
|
cornsilk
|
||||||
|
cyan
|
||||||
|
darkblue
|
||||||
|
darkcyan
|
||||||
|
darkgoldenrod
|
||||||
|
darkgray
|
||||||
|
darkgreen
|
||||||
|
darkgrey
|
||||||
|
darkkhaki
|
||||||
|
darkmagenta
|
||||||
|
darkolivegreen
|
||||||
|
darkorange
|
||||||
|
darkorchid
|
||||||
|
darkred
|
||||||
|
darksalmon
|
||||||
|
darkseagreen
|
||||||
|
darkslateblue
|
||||||
|
darkslategray
|
||||||
|
darkslategrey
|
||||||
|
darkturquoise
|
||||||
|
darkviolet
|
||||||
|
deeppink
|
||||||
|
deepskyblue
|
||||||
|
dimgray
|
||||||
|
dimgrey
|
||||||
|
dodgerblue
|
||||||
|
firebrick
|
||||||
|
floralwhite
|
||||||
|
forestgreen
|
||||||
|
gainsboro
|
||||||
|
ghostwhite
|
||||||
|
greenyellow
|
||||||
|
hotpink
|
||||||
|
indian
|
||||||
|
indianred
|
||||||
|
lavenderblush
|
||||||
|
lawngreen
|
||||||
|
lemonchiffon
|
||||||
|
lightblue
|
||||||
|
lightcoral
|
||||||
|
lightcyan
|
||||||
|
lightgoldenrod
|
||||||
|
lightgoldenrodyellow
|
||||||
|
lightgray
|
||||||
|
lightgreen
|
||||||
|
lightgrey
|
||||||
|
lightpink
|
||||||
|
lightsalmon
|
||||||
|
lightseagreen
|
||||||
|
lightskyblue
|
||||||
|
lightslateblue
|
||||||
|
lightslategray
|
||||||
|
lightslategrey
|
||||||
|
lightsteelblue
|
||||||
|
lightyellow
|
||||||
|
limegreen
|
||||||
|
mediumaquamarine
|
||||||
|
mediumblue
|
||||||
|
mediumorchid
|
||||||
|
mediumpurple
|
||||||
|
mediumseagreen
|
||||||
|
mediumslateblue
|
||||||
|
mediumspringgreen
|
||||||
|
mediumturquoise
|
||||||
|
mediumvioletred
|
||||||
|
midnightblue
|
||||||
|
mintcream
|
||||||
|
mistyrose
|
||||||
|
navajo
|
||||||
|
navajowhite
|
||||||
|
navyblue
|
||||||
|
oldlace
|
||||||
|
olivedrab
|
||||||
|
orangered
|
||||||
|
palegoldenrod
|
||||||
|
palegreen
|
||||||
|
paleturquoise
|
||||||
|
palevioletred
|
||||||
|
papayawhip
|
||||||
|
peachpuff
|
||||||
|
peru
|
||||||
|
powderblue
|
||||||
|
rebecca
|
||||||
|
rebeccapurple
|
||||||
|
rosybrown
|
||||||
|
royalblue
|
||||||
|
saddlebrown
|
||||||
|
sandybrown
|
||||||
|
seagreen
|
||||||
|
sienna
|
||||||
|
skyblue
|
||||||
|
slateblue
|
||||||
|
slategray
|
||||||
|
slategrey
|
||||||
|
springgreen
|
||||||
|
steelblue
|
||||||
|
violetred
|
||||||
|
webgray
|
||||||
|
webgreen
|
||||||
|
webgrey
|
||||||
|
webmaroon
|
||||||
|
webpurple
|
||||||
|
whitesmoke
|
||||||
|
xaroon
|
||||||
|
xray
|
||||||
|
xreen
|
||||||
|
xrey
|
||||||
|
xurple
|
||||||
|
yellowgreen
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
Consolas
|
Consolas
|
||||||
emoji
|
emoji
|
||||||
|
emojis
|
||||||
Extralight
|
Extralight
|
||||||
Gabriola
|
Gabriola
|
||||||
Iosevka
|
Iosevka
|
||||||
MDL
|
MDL
|
||||||
Monofur
|
Monofur
|
||||||
Segoe
|
Segoe
|
||||||
|
wght
|
||||||
11
.github/actions/spelling/allow/math.txt
vendored
Normal file
11
.github/actions/spelling/allow/math.txt
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
atan
|
||||||
|
CPrime
|
||||||
|
HBar
|
||||||
|
HPrime
|
||||||
|
isnan
|
||||||
|
LPrime
|
||||||
|
LStep
|
||||||
|
powf
|
||||||
|
RSub
|
||||||
|
sqrtf
|
||||||
|
ULP
|
||||||
85
.github/actions/spelling/allow/microsoft.txt
vendored
Normal file
85
.github/actions/spelling/allow/microsoft.txt
vendored
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
ACLs
|
||||||
|
ADMINS
|
||||||
|
advapi
|
||||||
|
altform
|
||||||
|
altforms
|
||||||
|
appendwttlogging
|
||||||
|
appx
|
||||||
|
appxbundle
|
||||||
|
appxerror
|
||||||
|
appxmanifest
|
||||||
|
ATL
|
||||||
|
backplating
|
||||||
|
bitmaps
|
||||||
|
BOMs
|
||||||
|
CPLs
|
||||||
|
cpptools
|
||||||
|
cppvsdbg
|
||||||
|
CPRs
|
||||||
|
cryptbase
|
||||||
|
DACL
|
||||||
|
DACLs
|
||||||
|
defaultlib
|
||||||
|
diffs
|
||||||
|
disposables
|
||||||
|
dotnetfeed
|
||||||
|
DTDs
|
||||||
|
DWINRT
|
||||||
|
enablewttlogging
|
||||||
|
Intelli
|
||||||
|
IVisual
|
||||||
|
libucrt
|
||||||
|
libucrtd
|
||||||
|
LKG
|
||||||
|
LOCKFILE
|
||||||
|
Lxss
|
||||||
|
mfcribbon
|
||||||
|
microsoft
|
||||||
|
microsoftonline
|
||||||
|
MSAA
|
||||||
|
msixbundle
|
||||||
|
MSVC
|
||||||
|
MSVCP
|
||||||
|
muxc
|
||||||
|
netcore
|
||||||
|
Onefuzz
|
||||||
|
osgvsowi
|
||||||
|
PFILETIME
|
||||||
|
pgc
|
||||||
|
pgo
|
||||||
|
pgosweep
|
||||||
|
powerrename
|
||||||
|
powershell
|
||||||
|
propkey
|
||||||
|
pscustomobject
|
||||||
|
QWORD
|
||||||
|
regedit
|
||||||
|
robocopy
|
||||||
|
SACLs
|
||||||
|
sdkddkver
|
||||||
|
Shobjidl
|
||||||
|
Skype
|
||||||
|
SRW
|
||||||
|
sxs
|
||||||
|
Sysinternals
|
||||||
|
sysnative
|
||||||
|
systemroot
|
||||||
|
taskkill
|
||||||
|
tasklist
|
||||||
|
tdbuildteamid
|
||||||
|
ucrt
|
||||||
|
ucrtd
|
||||||
|
unvirtualized
|
||||||
|
VCRT
|
||||||
|
vcruntime
|
||||||
|
Virtualization
|
||||||
|
visualstudio
|
||||||
|
vscode
|
||||||
|
VSTHRD
|
||||||
|
winsdkver
|
||||||
|
wlk
|
||||||
|
wslpath
|
||||||
|
wtl
|
||||||
|
wtt
|
||||||
|
wttlog
|
||||||
|
Xamarin
|
||||||
@@ -1,44 +1,66 @@
|
|||||||
Anup
|
Anup
|
||||||
austdi
|
austdi
|
||||||
|
arkthur
|
||||||
Ballmer
|
Ballmer
|
||||||
bhoj
|
bhoj
|
||||||
Bhojwani
|
Bhojwani
|
||||||
|
Bluloco
|
||||||
carlos
|
carlos
|
||||||
dhowett
|
dhowett
|
||||||
Diviness
|
Diviness
|
||||||
dsafa
|
dsafa
|
||||||
duhowett
|
duhowett
|
||||||
|
DXP
|
||||||
|
ekg
|
||||||
|
eryksun
|
||||||
ethanschoonover
|
ethanschoonover
|
||||||
Firefox
|
Firefox
|
||||||
Gatta
|
Gatta
|
||||||
|
glsl
|
||||||
|
Gravell
|
||||||
Grie
|
Grie
|
||||||
Griese
|
Griese
|
||||||
Hernan
|
Hernan
|
||||||
Howett
|
Howett
|
||||||
Illhardt
|
Illhardt
|
||||||
|
iquilezles
|
||||||
|
italo
|
||||||
jantari
|
jantari
|
||||||
jerrysh
|
jerrysh
|
||||||
Kaiyu
|
Kaiyu
|
||||||
kimwalisch
|
kimwalisch
|
||||||
KMehrain
|
KMehrain
|
||||||
|
KODELIFE
|
||||||
|
Kodelife
|
||||||
Kourosh
|
Kourosh
|
||||||
kowalczyk
|
kowalczyk
|
||||||
leonmsft
|
leonmsft
|
||||||
Lepilleur
|
Lepilleur
|
||||||
|
lhecker
|
||||||
lukesampson
|
lukesampson
|
||||||
|
Macbook
|
||||||
Manandhar
|
Manandhar
|
||||||
|
masserano
|
||||||
mbadolato
|
mbadolato
|
||||||
Mehrain
|
Mehrain
|
||||||
|
menger
|
||||||
mgravell
|
mgravell
|
||||||
michaelniksa
|
michaelniksa
|
||||||
|
michkap
|
||||||
migrie
|
migrie
|
||||||
mikegr
|
mikegr
|
||||||
mikemaccana
|
mikemaccana
|
||||||
|
miloush
|
||||||
miniksa
|
miniksa
|
||||||
niksa
|
niksa
|
||||||
|
nvaccess
|
||||||
|
nvda
|
||||||
oising
|
oising
|
||||||
oldnewthing
|
oldnewthing
|
||||||
|
opengl
|
||||||
osgwiki
|
osgwiki
|
||||||
|
pabhojwa
|
||||||
|
panos
|
||||||
paulcam
|
paulcam
|
||||||
pauldotknopf
|
pauldotknopf
|
||||||
PGP
|
PGP
|
||||||
@@ -46,11 +68,18 @@ Pham
|
|||||||
Rincewind
|
Rincewind
|
||||||
rprichard
|
rprichard
|
||||||
Schoonover
|
Schoonover
|
||||||
|
shadertoy
|
||||||
|
Shomnipotence
|
||||||
|
simioni
|
||||||
Somuah
|
Somuah
|
||||||
sonph
|
sonph
|
||||||
sonpham
|
sonpham
|
||||||
stakx
|
stakx
|
||||||
|
talo
|
||||||
|
thereses
|
||||||
Walisch
|
Walisch
|
||||||
|
WDX
|
||||||
|
Wellons
|
||||||
Wirt
|
Wirt
|
||||||
Wojciech
|
Wojciech
|
||||||
zadjii
|
zadjii
|
||||||
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-)/
|
||||||
117
.github/actions/spelling/excludes.txt
vendored
Normal file
117
.github/actions/spelling/excludes.txt
vendored
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
# See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-excludes
|
||||||
|
(?:(?i)\.png$)
|
||||||
|
(?:^|/)(?i)COPYRIGHT
|
||||||
|
(?:^|/)(?i)LICEN[CS]E
|
||||||
|
(?:^|/)3rdparty/
|
||||||
|
(?:^|/)dirs$
|
||||||
|
(?:^|/)go\.mod$
|
||||||
|
(?:^|/)go\.sum$
|
||||||
|
(?:^|/)package(?:-lock|)\.json$
|
||||||
|
(?:^|/)sources(?:|\.dep)$
|
||||||
|
(?:^|/)vendor/
|
||||||
|
\.a$
|
||||||
|
\.ai$
|
||||||
|
\.avi$
|
||||||
|
\.bmp$
|
||||||
|
\.bz2$
|
||||||
|
\.cer$
|
||||||
|
\.class$
|
||||||
|
\.crl$
|
||||||
|
\.crt$
|
||||||
|
\.csr$
|
||||||
|
\.dll$
|
||||||
|
\.docx?$
|
||||||
|
\.drawio$
|
||||||
|
\.DS_Store$
|
||||||
|
\.eot$
|
||||||
|
\.eps$
|
||||||
|
\.exe$
|
||||||
|
\.gif$
|
||||||
|
\.gitattributes$
|
||||||
|
\.graffle$
|
||||||
|
\.gz$
|
||||||
|
\.icns$
|
||||||
|
\.ico$
|
||||||
|
\.jar$
|
||||||
|
\.jks$
|
||||||
|
\.jpeg$
|
||||||
|
\.jpg$
|
||||||
|
\.key$
|
||||||
|
\.lib$
|
||||||
|
\.lock$
|
||||||
|
\.map$
|
||||||
|
\.min\..
|
||||||
|
\.mod$
|
||||||
|
\.mp3$
|
||||||
|
\.mp4$
|
||||||
|
\.o$
|
||||||
|
\.ocf$
|
||||||
|
\.otf$
|
||||||
|
\.pbxproj$
|
||||||
|
\.pdf$
|
||||||
|
\.pem$
|
||||||
|
\.png$
|
||||||
|
\.psd$
|
||||||
|
\.pyc$
|
||||||
|
\.runsettings$
|
||||||
|
\.s$
|
||||||
|
\.sig$
|
||||||
|
\.so$
|
||||||
|
\.svg$
|
||||||
|
\.svgz$
|
||||||
|
\.svgz?$
|
||||||
|
\.tar$
|
||||||
|
\.tgz$
|
||||||
|
\.tiff?$
|
||||||
|
\.ttf$
|
||||||
|
\.vsdx$
|
||||||
|
\.wav$
|
||||||
|
\.webm$
|
||||||
|
\.webp$
|
||||||
|
\.woff
|
||||||
|
\.woff2?$
|
||||||
|
\.xcf$
|
||||||
|
\.xls
|
||||||
|
\.xlsx?$
|
||||||
|
\.xpm$
|
||||||
|
\.yml$
|
||||||
|
\.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$
|
||||||
|
^dep/
|
||||||
|
^doc/reference/master-sequence-list.csv$
|
||||||
|
^doc/reference/UTF8-torture-test\.txt$
|
||||||
|
^oss/
|
||||||
|
^src/host/ft_uia/run\.bat$
|
||||||
|
^src/host/runft\.bat$
|
||||||
|
^src/host/runut\.bat$
|
||||||
|
^src/interactivity/onecore/BgfxEngine\.
|
||||||
|
^src/renderer/atlas/
|
||||||
|
^src/renderer/wddmcon/WddmConRenderer\.
|
||||||
|
^src/terminal/adapter/ut_adapter/run\.bat$
|
||||||
|
^src/terminal/parser/delfuzzpayload\.bat$
|
||||||
|
^src/terminal/parser/ft_fuzzer/run\.bat$
|
||||||
|
^src/terminal/parser/ft_fuzzer/VTCommandFuzzer\.cpp$
|
||||||
|
^src/terminal/parser/ft_fuzzwrapper/run\.bat$
|
||||||
|
^src/terminal/parser/ut_parser/Base64Test.cpp$
|
||||||
|
^src/terminal/parser/ut_parser/run\.bat$
|
||||||
|
^src/tools/integrity/packageuwp/ConsoleUWP\.appxSources$
|
||||||
|
^src/tools/lnkd/lnkd\.bat$
|
||||||
|
^src/tools/pixels/pixels\.bat$
|
||||||
|
^src/tools/texttests/fira\.txt$
|
||||||
|
^src/tools/U8U16Test/(?:fr|ru|zh)\.txt$
|
||||||
|
^src/types/ut_types/UtilsTests.cpp$
|
||||||
|
^tools/ReleaseEngineering/ServicingPipeline.ps1$
|
||||||
|
ignore$
|
||||||
|
SUMS$
|
||||||
@@ -1,16 +1,23 @@
|
|||||||
|
AAAa
|
||||||
|
AAAAA
|
||||||
|
AAAAAAAAAAAAA
|
||||||
|
AAAAAABBBBBBCCC
|
||||||
|
AAAAABBBBBBCCC
|
||||||
|
abcd
|
||||||
abcd
|
abcd
|
||||||
abcde
|
|
||||||
abcdef
|
|
||||||
ABCDEFG
|
|
||||||
ABCDEFGH
|
|
||||||
ABCDEFGHIJ
|
ABCDEFGHIJ
|
||||||
abcdefghijk
|
abcdefghijk
|
||||||
|
ABCDEFGHIJKLMNO
|
||||||
abcdefghijklmnop
|
abcdefghijklmnop
|
||||||
ABCDEFGHIJKLMNOPQRST
|
ABCDEFGHIJKLMNOPQRST
|
||||||
abcdefghijklmnopqrstuvwxyz
|
ABCG
|
||||||
ABE
|
ABE
|
||||||
|
abf
|
||||||
|
BBBBB
|
||||||
|
BBBBBBBB
|
||||||
|
BBBBBCCC
|
||||||
|
BBBBCCCCC
|
||||||
BBGGRR
|
BBGGRR
|
||||||
BBBBBBBBBBBBBBDDDD
|
|
||||||
EFG
|
EFG
|
||||||
EFGh
|
EFGh
|
||||||
QQQQQQQQQQABCDEFGHIJ
|
QQQQQQQQQQABCDEFGHIJ
|
||||||
@@ -19,7 +26,6 @@ QQQQQQQQQQABCDEFGHIJKLMNOPQRSTQQQQQQQQQQ
|
|||||||
QQQQQQQQQQABCDEFGHIJPQRSTQQQQQQQQQQ
|
QQQQQQQQQQABCDEFGHIJPQRSTQQQQQQQQQQ
|
||||||
qrstuvwxyz
|
qrstuvwxyz
|
||||||
qwerty
|
qwerty
|
||||||
QWERTYUIOP
|
|
||||||
qwertyuiopasdfg
|
qwertyuiopasdfg
|
||||||
YYYYYYYDDDDDDDDDDD
|
YYYYYYYDDDDDDDDDDD
|
||||||
ZAAZZ
|
ZAAZZ
|
||||||
@@ -31,3 +37,4 @@ ZYXWVUT
|
|||||||
ZZBBZ
|
ZZBBZ
|
||||||
ZZZBB
|
ZZZBB
|
||||||
ZZZBZ
|
ZZZBZ
|
||||||
|
ZZZZZ
|
||||||
File diff suppressed because it is too large
Load Diff
6
.github/actions/spelling/expect/web.txt
vendored
Normal file
6
.github/actions/spelling/expect/web.txt
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
WCAG
|
||||||
|
winui
|
||||||
|
appshellintegration
|
||||||
|
mdtauk
|
||||||
|
gfycat
|
||||||
|
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
|
||||||
96
.github/actions/spelling/patterns/patterns.txt
vendored
Normal file
96
.github/actions/spelling/patterns/patterns.txt
vendored
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
# See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns
|
||||||
|
|
||||||
|
https?://\S+
|
||||||
|
[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)
|
||||||
|
(?:0[Xx]|\\x|U\+|#)[a-f0-9A-FGgRr]{2,}[Uu]?[Ll]{0,2}\b
|
||||||
|
microsoft/cascadia-code\@[0-9a-fA-F]{40}
|
||||||
|
\d+x\d+Logo
|
||||||
|
Scro\&ll
|
||||||
|
# selectionInput.cpp
|
||||||
|
:\\windows\\syste\b
|
||||||
|
TestUtils::VerifyExpectedString\(tb, L"[^"]+"
|
||||||
|
(?:hostSm|mach)\.ProcessString\(L"[^"]+"
|
||||||
|
\b([A-Za-z])\g{-1}{3,}\b
|
||||||
|
0x[0-9A-Za-z]+
|
||||||
|
Base64::s_(?:En|De)code\(L"[^"]+"
|
||||||
|
VERIFY_ARE_EQUAL\(L"[^"]+"
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\+/"
|
||||||
|
std::memory_order_[\w]+
|
||||||
|
D2DERR_SHADER_COMPILE_FAILED
|
||||||
|
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
|
||||||
12
.github/actions/spelling/reject.txt
vendored
Normal file
12
.github/actions/spelling/reject.txt
vendored
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
^attache$
|
||||||
|
^attacher$
|
||||||
|
^attachers$
|
||||||
|
benefitting
|
||||||
|
occurences?
|
||||||
|
^dependan.*
|
||||||
|
^oer$
|
||||||
|
Sorce
|
||||||
|
^[Ss]pae.*
|
||||||
|
^untill$
|
||||||
|
^untilling$
|
||||||
|
^wether.*
|
||||||
20
.github/workflows/spelling.yml
vendored
20
.github/workflows/spelling.yml
vendored
@@ -1,20 +0,0 @@
|
|||||||
name: Spell checking
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
schedule:
|
|
||||||
# * is a special character in YAML so you have to quote this string
|
|
||||||
- cron: '15 * * * *'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
name: Spell checking
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2.0.0
|
|
||||||
with:
|
|
||||||
fetch-depth: 5
|
|
||||||
- uses: check-spelling/check-spelling@0.0.16-alpha
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
bucket: .github/actions
|
|
||||||
project: spell-check
|
|
||||||
134
.github/workflows/spelling2.yml
vendored
Normal file
134
.github/workflows/spelling2.yml
vendored
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
# spelling.yml is blocked per https://github.com/check-spelling/check-spelling/security/advisories/GHSA-g86g-chm8-7r2p
|
||||||
|
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:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- "**"
|
||||||
|
tags-ignore:
|
||||||
|
- "**"
|
||||||
|
pull_request_target:
|
||||||
|
branches:
|
||||||
|
- "**"
|
||||||
|
tags-ignore:
|
||||||
|
- "**"
|
||||||
|
types:
|
||||||
|
- 'opened'
|
||||||
|
- 'reopened'
|
||||||
|
- 'synchronize'
|
||||||
|
issue_comment:
|
||||||
|
types:
|
||||||
|
- 'created'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
spelling:
|
||||||
|
name: Spell checking
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pull-requests: read
|
||||||
|
actions: read
|
||||||
|
outputs:
|
||||||
|
followup: ${{ steps.spelling.outputs.followup }}
|
||||||
|
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:
|
||||||
|
- name: check-spelling
|
||||||
|
id: spelling
|
||||||
|
uses: check-spelling/check-spelling@v0.0.21
|
||||||
|
with:
|
||||||
|
suppress_push_for_open_pull_request: 1
|
||||||
|
checkout: true
|
||||||
|
check_file_names: 1
|
||||||
|
spell_check_this: check-spelling/spell-check-this@prerelease
|
||||||
|
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 }}
|
||||||
30
NOTICE.md
30
NOTICE.md
@@ -48,36 +48,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
```
|
```
|
||||||
|
|
||||||
## telnetpp
|
|
||||||
|
|
||||||
**Source**: https://github.com/KazDragon/telnetpp
|
|
||||||
|
|
||||||
### License
|
|
||||||
|
|
||||||
```
|
|
||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2015-2017 Matthew Chaplain a.k.a KazDragon
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
```
|
|
||||||
|
|
||||||
## chromium/base/numerics
|
## chromium/base/numerics
|
||||||
|
|
||||||
**Source**: https://github.com/chromium/chromium/tree/master/base/numerics
|
**Source**: https://github.com/chromium/chromium/tree/master/base/numerics
|
||||||
|
|||||||
@@ -620,7 +620,7 @@
|
|||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
"useTabSwitcher": {
|
"useTabSwitcher": {
|
||||||
"default": true,
|
"default": false,
|
||||||
"description": "When set to \"true\", the \"nextTab\" and \"prevTab\" commands will use the tab switcher UI.",
|
"description": "When set to \"true\", the \"nextTab\" and \"prevTab\" commands will use the tab switcher UI.",
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
res/Cascadia.ttf
BIN
res/Cascadia.ttf
Binary file not shown.
Binary file not shown.
@@ -17,5 +17,5 @@ Please consult the [license](https://raw.githubusercontent.com/microsoft/cascadi
|
|||||||
|
|
||||||
### Fonts Included
|
### Fonts Included
|
||||||
|
|
||||||
* Cascadia Code, Cascadia Mono (2008.25)
|
* Cascadia Code, Cascadia Mono (2009.21)
|
||||||
* from microsoft/cascadia-code@678eea921b0c8b921b9fb009bb16d3d2ca5b8112
|
* from microsoft/cascadia-code@32f84124db1970fa5d032f0fe9019e6922961beb
|
||||||
|
|||||||
@@ -88,16 +88,18 @@ bool TextAttribute::IsLegacy() const noexcept
|
|||||||
// - defaultFgColor: the default foreground color rgb value.
|
// - defaultFgColor: the default foreground color rgb value.
|
||||||
// - defaultBgColor: the default background color rgb value.
|
// - defaultBgColor: the default background color rgb value.
|
||||||
// - reverseScreenMode: true if the screen mode is reversed.
|
// - reverseScreenMode: true if the screen mode is reversed.
|
||||||
|
// - blinkingIsFaint: true if blinking should be interpreted as faint.
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - the foreground and background colors that should be displayed.
|
// - the foreground and background colors that should be displayed.
|
||||||
std::pair<COLORREF, COLORREF> TextAttribute::CalculateRgbColors(const gsl::span<const COLORREF> colorTable,
|
std::pair<COLORREF, COLORREF> TextAttribute::CalculateRgbColors(const gsl::span<const COLORREF> colorTable,
|
||||||
const COLORREF defaultFgColor,
|
const COLORREF defaultFgColor,
|
||||||
const COLORREF defaultBgColor,
|
const COLORREF defaultBgColor,
|
||||||
const bool reverseScreenMode) const noexcept
|
const bool reverseScreenMode,
|
||||||
|
const bool blinkingIsFaint) const noexcept
|
||||||
{
|
{
|
||||||
auto fg = _foreground.GetColor(colorTable, defaultFgColor, IsBold());
|
auto fg = _foreground.GetColor(colorTable, defaultFgColor, IsBold());
|
||||||
auto bg = _background.GetColor(colorTable, defaultBgColor);
|
auto bg = _background.GetColor(colorTable, defaultBgColor);
|
||||||
if (IsFaint())
|
if (IsFaint() || (IsBlinking() && blinkingIsFaint))
|
||||||
{
|
{
|
||||||
fg = (fg >> 1) & 0x7F7F7F; // Divide foreground color components by two.
|
fg = (fg >> 1) & 0x7F7F7F; // Divide foreground color components by two.
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,7 +69,8 @@ public:
|
|||||||
std::pair<COLORREF, COLORREF> CalculateRgbColors(const gsl::span<const COLORREF> colorTable,
|
std::pair<COLORREF, COLORREF> CalculateRgbColors(const gsl::span<const COLORREF> colorTable,
|
||||||
const COLORREF defaultFgColor,
|
const COLORREF defaultFgColor,
|
||||||
const COLORREF defaultBgColor,
|
const COLORREF defaultBgColor,
|
||||||
const bool reverseScreenMode = false) const noexcept;
|
const bool reverseScreenMode = false,
|
||||||
|
const bool blinkingIsFaint = false) const noexcept;
|
||||||
|
|
||||||
bool IsLeadingByte() const noexcept;
|
bool IsLeadingByte() const noexcept;
|
||||||
bool IsTrailingByte() const noexcept;
|
bool IsTrailingByte() const noexcept;
|
||||||
@@ -151,6 +152,8 @@ public:
|
|||||||
return !IsAnyGridLineEnabled() && // grid lines have a visual representation
|
return !IsAnyGridLineEnabled() && // grid lines have a visual representation
|
||||||
// crossed out, doubly and singly underlined have a visual representation
|
// crossed out, doubly and singly underlined have a visual representation
|
||||||
WI_AreAllFlagsClear(_extendedAttrs, ExtendedAttributes::CrossedOut | ExtendedAttributes::DoublyUnderlined | ExtendedAttributes::Underlined) &&
|
WI_AreAllFlagsClear(_extendedAttrs, ExtendedAttributes::CrossedOut | ExtendedAttributes::DoublyUnderlined | ExtendedAttributes::Underlined) &&
|
||||||
|
// hyperlinks have a visual representation
|
||||||
|
!IsHyperlink() &&
|
||||||
// all other attributes do not have a visual representation
|
// all other attributes do not have a visual representation
|
||||||
(_wAttrLegacy & META_ATTRS) == (other._wAttrLegacy & META_ATTRS) &&
|
(_wAttrLegacy & META_ATTRS) == (other._wAttrLegacy & META_ATTRS) &&
|
||||||
((checkForeground && _foreground == other._foreground) ||
|
((checkForeground && _foreground == other._foreground) ||
|
||||||
|
|||||||
@@ -996,19 +996,29 @@ const COORD TextBuffer::GetWordStart(const COORD target, const std::wstring_view
|
|||||||
// so the words in the example include ["word ", "other "]
|
// so the words in the example include ["word ", "other "]
|
||||||
// NOTE: the start anchor (this one) is inclusive, whereas the end anchor (GetWordEnd) is exclusive
|
// NOTE: the start anchor (this one) is inclusive, whereas the end anchor (GetWordEnd) is exclusive
|
||||||
|
|
||||||
// can't expand left
|
#pragma warning(suppress : 26496)
|
||||||
if (target.X == GetSize().Left())
|
// GH#7664: Treat EndExclusive as EndInclusive so
|
||||||
|
// that it actually points to a space in the buffer
|
||||||
|
auto copy{ target };
|
||||||
|
const auto bufferSize{ GetSize() };
|
||||||
|
if (target == bufferSize.Origin())
|
||||||
{
|
{
|
||||||
|
// can't expand left
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
else if (target == bufferSize.EndExclusive())
|
||||||
|
{
|
||||||
|
// treat EndExclusive as EndInclusive
|
||||||
|
copy = { bufferSize.RightInclusive(), bufferSize.BottomInclusive() };
|
||||||
|
}
|
||||||
|
|
||||||
if (accessibilityMode)
|
if (accessibilityMode)
|
||||||
{
|
{
|
||||||
return _GetWordStartForAccessibility(target, wordDelimiters);
|
return _GetWordStartForAccessibility(copy, wordDelimiters);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return _GetWordStartForSelection(target, wordDelimiters);
|
return _GetWordStartForSelection(copy, wordDelimiters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1108,9 +1118,16 @@ const COORD TextBuffer::GetWordEnd(const COORD target, const std::wstring_view w
|
|||||||
// so the words in the example include ["word ", "other "]
|
// so the words in the example include ["word ", "other "]
|
||||||
// NOTE: the end anchor (this one) is exclusive, whereas the start anchor (GetWordStart) is inclusive
|
// NOTE: the end anchor (this one) is exclusive, whereas the start anchor (GetWordStart) is inclusive
|
||||||
|
|
||||||
|
// Already at the end. Can't move forward.
|
||||||
|
if (target == GetSize().EndExclusive())
|
||||||
|
{
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
if (accessibilityMode)
|
if (accessibilityMode)
|
||||||
{
|
{
|
||||||
return _GetWordEndForAccessibility(target, wordDelimiters);
|
const auto lastCharPos{ GetLastNonSpaceCharacter() };
|
||||||
|
return _GetWordEndForAccessibility(target, wordDelimiters, lastCharPos);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1123,13 +1140,20 @@ const COORD TextBuffer::GetWordEnd(const COORD target, const std::wstring_view w
|
|||||||
// Arguments:
|
// Arguments:
|
||||||
// - target - a COORD on the word you are currently on
|
// - target - a COORD on the word you are currently on
|
||||||
// - wordDelimiters - what characters are we considering for the separation of words
|
// - wordDelimiters - what characters are we considering for the separation of words
|
||||||
|
// - lastCharPos - the position of the last nonspace character in the text buffer (to improve performance)
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - The COORD for the first character of the next readable "word". If no next word, return one past the end of the buffer
|
// - The COORD for the first character of the next readable "word". If no next word, return one past the end of the buffer
|
||||||
const COORD TextBuffer::_GetWordEndForAccessibility(const COORD target, const std::wstring_view wordDelimiters) const
|
const COORD TextBuffer::_GetWordEndForAccessibility(const COORD target, const std::wstring_view wordDelimiters, const COORD lastCharPos) const
|
||||||
{
|
{
|
||||||
const auto bufferSize = GetSize();
|
const auto bufferSize = GetSize();
|
||||||
COORD result = target;
|
COORD result = target;
|
||||||
|
|
||||||
|
// Check if we're already on/past the last RegularChar
|
||||||
|
if (bufferSize.CompareInBounds(result, lastCharPos, true) >= 0)
|
||||||
|
{
|
||||||
|
return bufferSize.EndExclusive();
|
||||||
|
}
|
||||||
|
|
||||||
// ignore right boundary. Continue through readable text found
|
// ignore right boundary. Continue through readable text found
|
||||||
while (_GetDelimiterClassAt(result, wordDelimiters) == DelimiterClass::RegularChar)
|
while (_GetDelimiterClassAt(result, wordDelimiters) == DelimiterClass::RegularChar)
|
||||||
{
|
{
|
||||||
@@ -1139,6 +1163,12 @@ const COORD TextBuffer::_GetWordEndForAccessibility(const COORD target, const st
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we are already on/past the last RegularChar
|
||||||
|
if (bufferSize.CompareInBounds(result, lastCharPos, true) >= 0)
|
||||||
|
{
|
||||||
|
return bufferSize.EndExclusive();
|
||||||
|
}
|
||||||
|
|
||||||
// make sure we expand to the beginning of the NEXT word
|
// make sure we expand to the beginning of the NEXT word
|
||||||
while (_GetDelimiterClassAt(result, wordDelimiters) != DelimiterClass::RegularChar)
|
while (_GetDelimiterClassAt(result, wordDelimiters) != DelimiterClass::RegularChar)
|
||||||
{
|
{
|
||||||
@@ -1240,38 +1270,16 @@ void TextBuffer::_PruneHyperlinks()
|
|||||||
// - pos - The COORD for the first character on the "word" (inclusive)
|
// - pos - The COORD for the first character on the "word" (inclusive)
|
||||||
bool TextBuffer::MoveToNextWord(COORD& pos, const std::wstring_view wordDelimiters, COORD lastCharPos) const
|
bool TextBuffer::MoveToNextWord(COORD& pos, const std::wstring_view wordDelimiters, COORD lastCharPos) const
|
||||||
{
|
{
|
||||||
auto copy = pos;
|
// move to the beginning of the next word
|
||||||
const auto bufferSize = GetSize();
|
// NOTE: _GetWordEnd...() returns the exclusive position of the "end of the word"
|
||||||
|
// This is also the inclusive start of the next word.
|
||||||
|
auto copy{ _GetWordEndForAccessibility(pos, wordDelimiters, lastCharPos) };
|
||||||
|
|
||||||
// started on a word, continue until the end of the word
|
if (copy == GetSize().EndExclusive())
|
||||||
while (_GetDelimiterClassAt(copy, wordDelimiters) == DelimiterClass::RegularChar)
|
|
||||||
{
|
|
||||||
if (!bufferSize.IncrementInBounds(copy))
|
|
||||||
{
|
|
||||||
// last char in buffer is a RegularChar
|
|
||||||
// thus there is no next word
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// we are already on/past the last RegularChar
|
|
||||||
if (bufferSize.CompareInBounds(copy, lastCharPos) >= 0)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// on whitespace, continue until the beginning of the next word
|
|
||||||
while (_GetDelimiterClassAt(copy, wordDelimiters) != DelimiterClass::RegularChar)
|
|
||||||
{
|
|
||||||
if (!bufferSize.IncrementInBounds(copy))
|
|
||||||
{
|
|
||||||
// last char in buffer is a DelimiterChar or ControlChar
|
|
||||||
// there is no next word
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// successful move, copy result out
|
|
||||||
pos = copy;
|
pos = copy;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1286,33 +1294,17 @@ bool TextBuffer::MoveToNextWord(COORD& pos, const std::wstring_view wordDelimite
|
|||||||
// - pos - The COORD for the first character on the "word" (inclusive)
|
// - pos - The COORD for the first character on the "word" (inclusive)
|
||||||
bool TextBuffer::MoveToPreviousWord(COORD& pos, std::wstring_view wordDelimiters) const
|
bool TextBuffer::MoveToPreviousWord(COORD& pos, std::wstring_view wordDelimiters) const
|
||||||
{
|
{
|
||||||
auto copy = pos;
|
// move to the beginning of the current word
|
||||||
auto bufferSize = GetSize();
|
auto copy{ GetWordStart(pos, wordDelimiters, true) };
|
||||||
|
|
||||||
// started on whitespace/delimiter, continue until the end of the previous word
|
if (!GetSize().DecrementInBounds(copy, true))
|
||||||
while (_GetDelimiterClassAt(copy, wordDelimiters) != DelimiterClass::RegularChar)
|
|
||||||
{
|
{
|
||||||
if (!bufferSize.DecrementInBounds(copy))
|
// can't move behind current word
|
||||||
{
|
return false;
|
||||||
// first char in buffer is a DelimiterChar or ControlChar
|
|
||||||
// there is no previous word
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// on a word, continue until the beginning of the word
|
// move to the beginning of the previous word
|
||||||
while (_GetDelimiterClassAt(copy, wordDelimiters) == DelimiterClass::RegularChar)
|
pos = GetWordStart(copy, wordDelimiters, true);
|
||||||
{
|
|
||||||
if (!bufferSize.DecrementInBounds(copy))
|
|
||||||
{
|
|
||||||
// first char in buffer is a RegularChar
|
|
||||||
// there is no previous word
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// successful move, copy result out
|
|
||||||
pos = copy;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1325,8 +1317,13 @@ bool TextBuffer::MoveToPreviousWord(COORD& pos, std::wstring_view wordDelimiters
|
|||||||
const til::point TextBuffer::GetGlyphStart(const til::point pos) const
|
const til::point TextBuffer::GetGlyphStart(const til::point pos) const
|
||||||
{
|
{
|
||||||
COORD resultPos = pos;
|
COORD resultPos = pos;
|
||||||
|
|
||||||
const auto bufferSize = GetSize();
|
const auto bufferSize = GetSize();
|
||||||
|
|
||||||
|
if (resultPos == bufferSize.EndExclusive())
|
||||||
|
{
|
||||||
|
bufferSize.DecrementInBounds(resultPos, true);
|
||||||
|
}
|
||||||
|
|
||||||
if (resultPos != bufferSize.EndExclusive() && GetCellDataAt(resultPos)->DbcsAttr().IsTrailing())
|
if (resultPos != bufferSize.EndExclusive() && GetCellDataAt(resultPos)->DbcsAttr().IsTrailing())
|
||||||
{
|
{
|
||||||
bufferSize.DecrementInBounds(resultPos, true);
|
bufferSize.DecrementInBounds(resultPos, true);
|
||||||
@@ -1367,9 +1364,15 @@ const til::point TextBuffer::GetGlyphEnd(const til::point pos) const
|
|||||||
bool TextBuffer::MoveToNextGlyph(til::point& pos, bool allowBottomExclusive) const
|
bool TextBuffer::MoveToNextGlyph(til::point& pos, bool allowBottomExclusive) const
|
||||||
{
|
{
|
||||||
COORD resultPos = pos;
|
COORD resultPos = pos;
|
||||||
|
const auto bufferSize = GetSize();
|
||||||
|
|
||||||
|
if (resultPos == GetSize().EndExclusive())
|
||||||
|
{
|
||||||
|
// we're already at the end
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// try to move. If we can't, we're done.
|
// try to move. If we can't, we're done.
|
||||||
const auto bufferSize = GetSize();
|
|
||||||
const bool success = bufferSize.IncrementInBounds(resultPos, allowBottomExclusive);
|
const bool success = bufferSize.IncrementInBounds(resultPos, allowBottomExclusive);
|
||||||
if (resultPos != bufferSize.EndExclusive() && GetCellDataAt(resultPos)->DbcsAttr().IsTrailing())
|
if (resultPos != bufferSize.EndExclusive() && GetCellDataAt(resultPos)->DbcsAttr().IsTrailing())
|
||||||
{
|
{
|
||||||
@@ -1384,20 +1387,19 @@ bool TextBuffer::MoveToNextGlyph(til::point& pos, bool allowBottomExclusive) con
|
|||||||
// - Update pos to be the beginning of the previous glyph/character. This is used for accessibility
|
// - Update pos to be the beginning of the previous glyph/character. This is used for accessibility
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// - pos - a COORD on the word you are currently on
|
// - pos - a COORD on the word you are currently on
|
||||||
// - allowBottomExclusive - allow the nonexistent end-of-buffer cell to be encountered
|
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - true, if successfully updated pos. False, if we are unable to move (usually due to a buffer boundary)
|
// - true, if successfully updated pos. False, if we are unable to move (usually due to a buffer boundary)
|
||||||
// - pos - The COORD for the first cell of the previous glyph (inclusive)
|
// - pos - The COORD for the first cell of the previous glyph (inclusive)
|
||||||
bool TextBuffer::MoveToPreviousGlyph(til::point& pos, bool allowBottomExclusive) const
|
bool TextBuffer::MoveToPreviousGlyph(til::point& pos) const
|
||||||
{
|
{
|
||||||
COORD resultPos = pos;
|
COORD resultPos = pos;
|
||||||
|
|
||||||
// try to move. If we can't, we're done.
|
// try to move. If we can't, we're done.
|
||||||
const auto bufferSize = GetSize();
|
const auto bufferSize = GetSize();
|
||||||
const bool success = bufferSize.DecrementInBounds(resultPos, allowBottomExclusive);
|
const bool success = bufferSize.DecrementInBounds(resultPos, true);
|
||||||
if (resultPos != bufferSize.EndExclusive() && GetCellDataAt(resultPos)->DbcsAttr().IsLeading())
|
if (resultPos != bufferSize.EndExclusive() && GetCellDataAt(resultPos)->DbcsAttr().IsLeading())
|
||||||
{
|
{
|
||||||
bufferSize.DecrementInBounds(resultPos, allowBottomExclusive);
|
bufferSize.DecrementInBounds(resultPos, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = resultPos;
|
pos = resultPos;
|
||||||
@@ -2279,32 +2281,35 @@ std::wstring TextBuffer::GetHyperlinkUriFromId(uint16_t id) const
|
|||||||
// - The user-defined id
|
// - The user-defined id
|
||||||
// Return value:
|
// Return value:
|
||||||
// - The internal hyperlink ID
|
// - The internal hyperlink ID
|
||||||
uint16_t TextBuffer::GetHyperlinkId(std::wstring_view params)
|
uint16_t TextBuffer::GetHyperlinkId(std::wstring_view uri, std::wstring_view id)
|
||||||
{
|
{
|
||||||
uint16_t id = 0;
|
uint16_t numericId = 0;
|
||||||
if (params.empty())
|
if (id.empty())
|
||||||
{
|
{
|
||||||
// no custom id specified, return our internal count
|
// no custom id specified, return our internal count
|
||||||
id = _currentHyperlinkId;
|
numericId = _currentHyperlinkId;
|
||||||
++_currentHyperlinkId;
|
++_currentHyperlinkId;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// assign _currentHyperlinkId if the custom id does not already exist
|
// assign _currentHyperlinkId if the custom id does not already exist
|
||||||
const auto result = _hyperlinkCustomIdMap.emplace(params, _currentHyperlinkId);
|
std::wstring newId{ id };
|
||||||
|
// hash the URL and add it to the custom ID - GH#7698
|
||||||
|
newId += L"%" + std::to_wstring(std::hash<std::wstring_view>{}(uri));
|
||||||
|
const auto result = _hyperlinkCustomIdMap.emplace(newId, _currentHyperlinkId);
|
||||||
if (result.second)
|
if (result.second)
|
||||||
{
|
{
|
||||||
// the custom id did not already exist
|
// the custom id did not already exist
|
||||||
++_currentHyperlinkId;
|
++_currentHyperlinkId;
|
||||||
}
|
}
|
||||||
id = (*(result.first)).second;
|
numericId = (*(result.first)).second;
|
||||||
}
|
}
|
||||||
// _currentHyperlinkId could overflow, make sure its not 0
|
// _currentHyperlinkId could overflow, make sure its not 0
|
||||||
if (_currentHyperlinkId == 0)
|
if (_currentHyperlinkId == 0)
|
||||||
{
|
{
|
||||||
++_currentHyperlinkId;
|
++_currentHyperlinkId;
|
||||||
}
|
}
|
||||||
return id;
|
return numericId;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
@@ -2345,11 +2350,13 @@ std::wstring TextBuffer::GetCustomIdFromId(uint16_t id) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - Copies the hyperlink/customID maps of the old buffer into this one
|
// - Copies the hyperlink/customID maps of the old buffer into this one,
|
||||||
|
// also copies currentHyperlinkId
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// - The other buffer
|
// - The other buffer
|
||||||
void TextBuffer::CopyHyperlinkMaps(const TextBuffer& other)
|
void TextBuffer::CopyHyperlinkMaps(const TextBuffer& other)
|
||||||
{
|
{
|
||||||
_hyperlinkMap = other._hyperlinkMap;
|
_hyperlinkMap = other._hyperlinkMap;
|
||||||
_hyperlinkCustomIdMap = other._hyperlinkCustomIdMap;
|
_hyperlinkCustomIdMap = other._hyperlinkCustomIdMap;
|
||||||
|
_currentHyperlinkId = other._currentHyperlinkId;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -137,13 +137,13 @@ public:
|
|||||||
const til::point GetGlyphStart(const til::point pos) const;
|
const til::point GetGlyphStart(const til::point pos) const;
|
||||||
const til::point GetGlyphEnd(const til::point pos) const;
|
const til::point GetGlyphEnd(const til::point pos) const;
|
||||||
bool MoveToNextGlyph(til::point& pos, bool allowBottomExclusive = false) const;
|
bool MoveToNextGlyph(til::point& pos, bool allowBottomExclusive = false) const;
|
||||||
bool MoveToPreviousGlyph(til::point& pos, bool allowBottomExclusive = false) const;
|
bool MoveToPreviousGlyph(til::point& pos) const;
|
||||||
|
|
||||||
const std::vector<SMALL_RECT> GetTextRects(COORD start, COORD end, bool blockSelection = false) const;
|
const std::vector<SMALL_RECT> GetTextRects(COORD start, COORD end, bool blockSelection = false) const;
|
||||||
|
|
||||||
void AddHyperlinkToMap(std::wstring_view uri, uint16_t id);
|
void AddHyperlinkToMap(std::wstring_view uri, uint16_t id);
|
||||||
std::wstring GetHyperlinkUriFromId(uint16_t id) const;
|
std::wstring GetHyperlinkUriFromId(uint16_t id) const;
|
||||||
uint16_t GetHyperlinkId(std::wstring_view params);
|
uint16_t GetHyperlinkId(std::wstring_view uri, std::wstring_view id);
|
||||||
void RemoveHyperlinkFromMap(uint16_t id);
|
void RemoveHyperlinkFromMap(uint16_t id);
|
||||||
std::wstring GetCustomIdFromId(uint16_t id) const;
|
std::wstring GetCustomIdFromId(uint16_t id) const;
|
||||||
void CopyHyperlinkMaps(const TextBuffer& OtherBuffer);
|
void CopyHyperlinkMaps(const TextBuffer& OtherBuffer);
|
||||||
@@ -224,7 +224,7 @@ private:
|
|||||||
const DelimiterClass _GetDelimiterClassAt(const COORD pos, const std::wstring_view wordDelimiters) const;
|
const DelimiterClass _GetDelimiterClassAt(const COORD pos, const std::wstring_view wordDelimiters) const;
|
||||||
const COORD _GetWordStartForAccessibility(const COORD target, const std::wstring_view wordDelimiters) const;
|
const COORD _GetWordStartForAccessibility(const COORD target, const std::wstring_view wordDelimiters) const;
|
||||||
const COORD _GetWordStartForSelection(const COORD target, const std::wstring_view wordDelimiters) const;
|
const COORD _GetWordStartForSelection(const COORD target, const std::wstring_view wordDelimiters) const;
|
||||||
const COORD _GetWordEndForAccessibility(const COORD target, const std::wstring_view wordDelimiters) const;
|
const COORD _GetWordEndForAccessibility(const COORD target, const std::wstring_view wordDelimiters, const COORD lastCharPos) const;
|
||||||
const COORD _GetWordEndForSelection(const COORD target, const std::wstring_view wordDelimiters) const;
|
const COORD _GetWordEndForSelection(const COORD target, const std::wstring_view wordDelimiters) const;
|
||||||
|
|
||||||
void _PruneHyperlinks();
|
void _PruneHyperlinks();
|
||||||
|
|||||||
@@ -62,6 +62,10 @@ namespace TerminalAppLocalTests
|
|||||||
TEST_METHOD(TryDuplicateBadTab);
|
TEST_METHOD(TryDuplicateBadTab);
|
||||||
TEST_METHOD(TryDuplicateBadPane);
|
TEST_METHOD(TryDuplicateBadPane);
|
||||||
|
|
||||||
|
TEST_METHOD(TryZoomPane);
|
||||||
|
TEST_METHOD(MoveFocusFromZoomedPane);
|
||||||
|
TEST_METHOD(CloseZoomedPane);
|
||||||
|
|
||||||
TEST_CLASS_SETUP(ClassSetup)
|
TEST_CLASS_SETUP(ClassSetup)
|
||||||
{
|
{
|
||||||
InitializeJsonReader();
|
InitializeJsonReader();
|
||||||
@@ -76,6 +80,7 @@ namespace TerminalAppLocalTests
|
|||||||
private:
|
private:
|
||||||
void _initializeTerminalPage(winrt::com_ptr<winrt::TerminalApp::implementation::TerminalPage>& page,
|
void _initializeTerminalPage(winrt::com_ptr<winrt::TerminalApp::implementation::TerminalPage>& page,
|
||||||
winrt::com_ptr<winrt::TerminalApp::implementation::CascadiaSettings>& initialSettings);
|
winrt::com_ptr<winrt::TerminalApp::implementation::CascadiaSettings>& initialSettings);
|
||||||
|
winrt::com_ptr<winrt::TerminalApp::implementation::TerminalPage> _commonSetup();
|
||||||
};
|
};
|
||||||
|
|
||||||
void TabTests::EnsureTestsActivate()
|
void TabTests::EnsureTestsActivate()
|
||||||
@@ -517,4 +522,192 @@ namespace TerminalAppLocalTests
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Method Description:
|
||||||
|
// - This is a helper method for setting up a TerminalPage with some common
|
||||||
|
// settings, and creating the first tab.
|
||||||
|
// Arguments:
|
||||||
|
// - <none>
|
||||||
|
// Return Value:
|
||||||
|
// - The initialized TerminalPage, ready to use.
|
||||||
|
winrt::com_ptr<winrt::TerminalApp::implementation::TerminalPage> TabTests::_commonSetup()
|
||||||
|
{
|
||||||
|
const std::string settingsJson0{ R"(
|
||||||
|
{
|
||||||
|
"defaultProfile": "{6239a42c-1111-49a3-80bd-e8fdd045185c}",
|
||||||
|
"profiles": [
|
||||||
|
{
|
||||||
|
"name" : "profile0",
|
||||||
|
"guid": "{6239a42c-1111-49a3-80bd-e8fdd045185c}",
|
||||||
|
"historySize": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name" : "profile1",
|
||||||
|
"guid": "{6239a42c-2222-49a3-80bd-e8fdd045185c}",
|
||||||
|
"historySize": 2
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})" };
|
||||||
|
|
||||||
|
CascadiaSettings settings0{ til::u8u16(settingsJson0) };
|
||||||
|
VERIFY_IS_NOT_NULL(settings0);
|
||||||
|
|
||||||
|
const auto guid1 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}");
|
||||||
|
const auto guid2 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-2222-49a3-80bd-e8fdd045185c}");
|
||||||
|
|
||||||
|
// This is super wacky, but we can't just initialize the
|
||||||
|
// com_ptr<impl::TerminalPage> in the lambda and assign it back out of
|
||||||
|
// the lambda. We'll crash trying to get a weak_ref to the TerminalPage
|
||||||
|
// during TerminalPage::Create() below.
|
||||||
|
//
|
||||||
|
// Instead, create the winrt object, then get a com_ptr to the
|
||||||
|
// implementation _from_ the winrt object. This seems to work, even if
|
||||||
|
// it's weird.
|
||||||
|
winrt::com_ptr<winrt::TerminalApp::implementation::TerminalPage> page{ nullptr };
|
||||||
|
_initializeTerminalPage(page, settings0);
|
||||||
|
|
||||||
|
auto result = RunOnUIThread([&page]() {
|
||||||
|
VERIFY_ARE_EQUAL(1u, page->_tabs.Size());
|
||||||
|
});
|
||||||
|
VERIFY_SUCCEEDED(result);
|
||||||
|
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabTests::TryZoomPane()
|
||||||
|
{
|
||||||
|
auto page = _commonSetup();
|
||||||
|
|
||||||
|
Log::Comment(L"Create a second pane");
|
||||||
|
auto result = RunOnUIThread([&page]() {
|
||||||
|
SplitPaneArgs args{ SplitType::Duplicate };
|
||||||
|
ActionEventArgs eventArgs{ args };
|
||||||
|
// eventArgs.Args(args);
|
||||||
|
page->_HandleSplitPane(nullptr, eventArgs);
|
||||||
|
auto firstTab = page->_GetStrongTabImpl(0);
|
||||||
|
|
||||||
|
VERIFY_ARE_EQUAL(2, firstTab->GetLeafPaneCount());
|
||||||
|
VERIFY_IS_FALSE(firstTab->IsZoomed());
|
||||||
|
});
|
||||||
|
VERIFY_SUCCEEDED(result);
|
||||||
|
|
||||||
|
Log::Comment(L"Zoom in on the pane");
|
||||||
|
result = RunOnUIThread([&page]() {
|
||||||
|
ActionEventArgs eventArgs{};
|
||||||
|
page->_HandleTogglePaneZoom(nullptr, eventArgs);
|
||||||
|
auto firstTab = page->_GetStrongTabImpl(0);
|
||||||
|
VERIFY_ARE_EQUAL(2, firstTab->GetLeafPaneCount());
|
||||||
|
VERIFY_IS_TRUE(firstTab->IsZoomed());
|
||||||
|
});
|
||||||
|
VERIFY_SUCCEEDED(result);
|
||||||
|
|
||||||
|
Log::Comment(L"Zoom out of the pane");
|
||||||
|
result = RunOnUIThread([&page]() {
|
||||||
|
ActionEventArgs eventArgs{};
|
||||||
|
page->_HandleTogglePaneZoom(nullptr, eventArgs);
|
||||||
|
auto firstTab = page->_GetStrongTabImpl(0);
|
||||||
|
VERIFY_ARE_EQUAL(2, firstTab->GetLeafPaneCount());
|
||||||
|
VERIFY_IS_FALSE(firstTab->IsZoomed());
|
||||||
|
});
|
||||||
|
VERIFY_SUCCEEDED(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabTests::MoveFocusFromZoomedPane()
|
||||||
|
{
|
||||||
|
auto page = _commonSetup();
|
||||||
|
|
||||||
|
Log::Comment(L"Create a second pane");
|
||||||
|
auto result = RunOnUIThread([&page]() {
|
||||||
|
// Set up action
|
||||||
|
SplitPaneArgs args{ SplitType::Duplicate };
|
||||||
|
ActionEventArgs eventArgs{ args };
|
||||||
|
page->_HandleSplitPane(nullptr, eventArgs);
|
||||||
|
auto firstTab = page->_GetStrongTabImpl(0);
|
||||||
|
|
||||||
|
VERIFY_ARE_EQUAL(2, firstTab->GetLeafPaneCount());
|
||||||
|
VERIFY_IS_FALSE(firstTab->IsZoomed());
|
||||||
|
});
|
||||||
|
VERIFY_SUCCEEDED(result);
|
||||||
|
|
||||||
|
Log::Comment(L"Zoom in on the pane");
|
||||||
|
result = RunOnUIThread([&page]() {
|
||||||
|
// Set up action
|
||||||
|
ActionEventArgs eventArgs{};
|
||||||
|
|
||||||
|
page->_HandleTogglePaneZoom(nullptr, eventArgs);
|
||||||
|
|
||||||
|
auto firstTab = page->_GetStrongTabImpl(0);
|
||||||
|
VERIFY_ARE_EQUAL(2, firstTab->GetLeafPaneCount());
|
||||||
|
VERIFY_IS_TRUE(firstTab->IsZoomed());
|
||||||
|
});
|
||||||
|
VERIFY_SUCCEEDED(result);
|
||||||
|
|
||||||
|
Log::Comment(L"Move focus. This will cause us to un-zoom.");
|
||||||
|
result = RunOnUIThread([&page]() {
|
||||||
|
// Set up action
|
||||||
|
MoveFocusArgs args{ Direction::Left };
|
||||||
|
ActionEventArgs eventArgs{ args };
|
||||||
|
|
||||||
|
page->_HandleMoveFocus(nullptr, eventArgs);
|
||||||
|
|
||||||
|
auto firstTab = page->_GetStrongTabImpl(0);
|
||||||
|
VERIFY_ARE_EQUAL(2, firstTab->GetLeafPaneCount());
|
||||||
|
VERIFY_IS_FALSE(firstTab->IsZoomed());
|
||||||
|
});
|
||||||
|
VERIFY_SUCCEEDED(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabTests::CloseZoomedPane()
|
||||||
|
{
|
||||||
|
auto page = _commonSetup();
|
||||||
|
|
||||||
|
Log::Comment(L"Create a second pane");
|
||||||
|
auto result = RunOnUIThread([&page]() {
|
||||||
|
// Set up action
|
||||||
|
SplitPaneArgs args{ SplitType::Duplicate };
|
||||||
|
ActionEventArgs eventArgs{ args };
|
||||||
|
page->_HandleSplitPane(nullptr, eventArgs);
|
||||||
|
auto firstTab = page->_GetStrongTabImpl(0);
|
||||||
|
|
||||||
|
VERIFY_ARE_EQUAL(2, firstTab->GetLeafPaneCount());
|
||||||
|
VERIFY_IS_FALSE(firstTab->IsZoomed());
|
||||||
|
});
|
||||||
|
VERIFY_SUCCEEDED(result);
|
||||||
|
|
||||||
|
Log::Comment(L"Zoom in on the pane");
|
||||||
|
result = RunOnUIThread([&page]() {
|
||||||
|
// Set up action
|
||||||
|
ActionEventArgs eventArgs{};
|
||||||
|
|
||||||
|
page->_HandleTogglePaneZoom(nullptr, eventArgs);
|
||||||
|
|
||||||
|
auto firstTab = page->_GetStrongTabImpl(0);
|
||||||
|
VERIFY_ARE_EQUAL(2, firstTab->GetLeafPaneCount());
|
||||||
|
VERIFY_IS_TRUE(firstTab->IsZoomed());
|
||||||
|
});
|
||||||
|
VERIFY_SUCCEEDED(result);
|
||||||
|
|
||||||
|
Log::Comment(L"Close Pane. This should cause us to un-zoom, and remove the second pane from the tree");
|
||||||
|
result = RunOnUIThread([&page]() {
|
||||||
|
// Set up action
|
||||||
|
ActionEventArgs eventArgs{};
|
||||||
|
|
||||||
|
page->_HandleClosePane(nullptr, eventArgs);
|
||||||
|
|
||||||
|
auto firstTab = page->_GetStrongTabImpl(0);
|
||||||
|
VERIFY_IS_FALSE(firstTab->IsZoomed());
|
||||||
|
});
|
||||||
|
VERIFY_SUCCEEDED(result);
|
||||||
|
|
||||||
|
// Introduce a slight delay to let the events finish propagating
|
||||||
|
Sleep(250);
|
||||||
|
|
||||||
|
Log::Comment(L"Check to ensure there's only one pane left.");
|
||||||
|
|
||||||
|
result = RunOnUIThread([&page]() {
|
||||||
|
auto firstTab = page->_GetStrongTabImpl(0);
|
||||||
|
VERIFY_ARE_EQUAL(1, firstTab->GetLeafPaneCount());
|
||||||
|
VERIFY_IS_FALSE(firstTab->IsZoomed());
|
||||||
|
});
|
||||||
|
VERIFY_SUCCEEDED(result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -433,7 +433,15 @@ void _stdcall TerminalSendOutput(void* terminal, LPCWSTR data)
|
|||||||
publicTerminal->SendOutput(data);
|
publicTerminal->SendOutput(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT _stdcall TerminalTriggerResize(void* terminal, double width, double height, _Out_ COORD* dimensions)
|
/// <summary>
|
||||||
|
/// Triggers a terminal resize using the new width and height in pixel.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="terminal">Terminal pointer.</param>
|
||||||
|
/// <param name="width">New width of the terminal in pixels.</param>
|
||||||
|
/// <param name="height">New height of the terminal in pixels</param>
|
||||||
|
/// <param name="dimensions">Out parameter containing the columns and rows that fit the new size.</param>
|
||||||
|
/// <returns>HRESULT of the attempted resize.</returns>
|
||||||
|
HRESULT _stdcall TerminalTriggerResize(_In_ void* terminal, _In_ short width, _In_ short height, _Out_ COORD* dimensions)
|
||||||
{
|
{
|
||||||
const auto publicTerminal = static_cast<HwndTerminal*>(terminal);
|
const auto publicTerminal = static_cast<HwndTerminal*>(terminal);
|
||||||
|
|
||||||
@@ -446,10 +454,55 @@ HRESULT _stdcall TerminalTriggerResize(void* terminal, double width, double heig
|
|||||||
static_cast<int>(height),
|
static_cast<int>(height),
|
||||||
0));
|
0));
|
||||||
|
|
||||||
const SIZE windowSize{ static_cast<short>(width), static_cast<short>(height) };
|
const SIZE windowSize{ width, height };
|
||||||
return publicTerminal->Refresh(windowSize, dimensions);
|
return publicTerminal->Refresh(windowSize, dimensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Helper method for resizing the terminal using character column and row counts
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="terminal">Pointer to the terminal object.</param>
|
||||||
|
/// <param name="dimensionsInCharacters">New terminal size in row and column count.</param>
|
||||||
|
/// <param name="dimensionsInPixels">Out parameter with the new size of the renderer.</param>
|
||||||
|
/// <returns>HRESULT of the attempted resize.</returns>
|
||||||
|
HRESULT _stdcall TerminalTriggerResizeWithDimension(_In_ void* terminal, _In_ COORD dimensionsInCharacters, _Out_ SIZE* dimensionsInPixels)
|
||||||
|
{
|
||||||
|
RETURN_HR_IF_NULL(E_INVALIDARG, dimensionsInPixels);
|
||||||
|
|
||||||
|
const auto publicTerminal = static_cast<const HwndTerminal*>(terminal);
|
||||||
|
|
||||||
|
const auto viewInCharacters = Viewport::FromDimensions({ 0, 0 }, { (dimensionsInCharacters.X), (dimensionsInCharacters.Y) });
|
||||||
|
const auto viewInPixels = publicTerminal->_renderEngine->GetViewportInPixels(viewInCharacters);
|
||||||
|
|
||||||
|
dimensionsInPixels->cx = viewInPixels.Width();
|
||||||
|
dimensionsInPixels->cy = viewInPixels.Height();
|
||||||
|
|
||||||
|
COORD unused{ 0, 0 };
|
||||||
|
|
||||||
|
return TerminalTriggerResize(terminal, viewInPixels.Width(), viewInPixels.Height(), &unused);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculates the amount of rows and columns that fit in the provided width and height.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="terminal">Terminal pointer</param>
|
||||||
|
/// <param name="width">Width of the terminal area to calculate.</param>
|
||||||
|
/// <param name="height">Height of the terminal area to calculate.</param>
|
||||||
|
/// <param name="dimensions">Out parameter containing the columns and rows that fit the new size.</param>
|
||||||
|
/// <returns>HRESULT of the calculation.</returns>
|
||||||
|
HRESULT _stdcall TerminalCalculateResize(_In_ void* terminal, _In_ short width, _In_ short height, _Out_ COORD* dimensions)
|
||||||
|
{
|
||||||
|
const auto publicTerminal = static_cast<const HwndTerminal*>(terminal);
|
||||||
|
|
||||||
|
const auto viewInPixels = Viewport::FromDimensions({ 0, 0 }, { width, height });
|
||||||
|
const auto viewInCharacters = publicTerminal->_renderEngine->GetViewportInCharacters(viewInPixels);
|
||||||
|
|
||||||
|
dimensions->X = viewInCharacters.Width();
|
||||||
|
dimensions->Y = viewInCharacters.Height();
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
void _stdcall TerminalDpiChanged(void* terminal, int newDpi)
|
void _stdcall TerminalDpiChanged(void* terminal, int newDpi)
|
||||||
{
|
{
|
||||||
const auto publicTerminal = static_cast<HwndTerminal*>(terminal);
|
const auto publicTerminal = static_cast<HwndTerminal*>(terminal);
|
||||||
@@ -760,18 +813,6 @@ void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR font
|
|||||||
publicTerminal->Refresh(windowSize, &dimensions);
|
publicTerminal->Refresh(windowSize, &dimensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resizes the terminal to the specified rows and columns.
|
|
||||||
HRESULT _stdcall TerminalResize(void* terminal, COORD dimensions)
|
|
||||||
{
|
|
||||||
const auto publicTerminal = static_cast<const HwndTerminal*>(terminal);
|
|
||||||
|
|
||||||
auto lock = publicTerminal->_terminal->LockForWriting();
|
|
||||||
publicTerminal->_terminal->ClearSelection();
|
|
||||||
publicTerminal->_renderer->TriggerRedrawAll();
|
|
||||||
|
|
||||||
return publicTerminal->_terminal->UserResize(dimensions);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _stdcall TerminalBlinkCursor(void* terminal)
|
void _stdcall TerminalBlinkCursor(void* terminal)
|
||||||
{
|
{
|
||||||
const auto publicTerminal = static_cast<const HwndTerminal*>(terminal);
|
const auto publicTerminal = static_cast<const HwndTerminal*>(terminal);
|
||||||
|
|||||||
@@ -27,8 +27,9 @@ extern "C" {
|
|||||||
__declspec(dllexport) HRESULT _stdcall CreateTerminal(HWND parentHwnd, _Out_ void** hwnd, _Out_ void** terminal);
|
__declspec(dllexport) HRESULT _stdcall CreateTerminal(HWND parentHwnd, _Out_ void** hwnd, _Out_ void** terminal);
|
||||||
__declspec(dllexport) void _stdcall TerminalSendOutput(void* terminal, LPCWSTR data);
|
__declspec(dllexport) void _stdcall TerminalSendOutput(void* terminal, LPCWSTR data);
|
||||||
__declspec(dllexport) void _stdcall TerminalRegisterScrollCallback(void* terminal, void __stdcall callback(int, int, int));
|
__declspec(dllexport) void _stdcall TerminalRegisterScrollCallback(void* terminal, void __stdcall callback(int, int, int));
|
||||||
__declspec(dllexport) HRESULT _stdcall TerminalTriggerResize(void* terminal, double width, double height, _Out_ COORD* dimensions);
|
__declspec(dllexport) HRESULT _stdcall TerminalTriggerResize(_In_ void* terminal, _In_ short width, _In_ short height, _Out_ COORD* dimensions);
|
||||||
__declspec(dllexport) HRESULT _stdcall TerminalResize(void* terminal, COORD dimensions);
|
__declspec(dllexport) HRESULT _stdcall TerminalTriggerResizeWithDimension(_In_ void* terminal, _In_ COORD dimensions, _Out_ SIZE* dimensionsInPixels);
|
||||||
|
__declspec(dllexport) HRESULT _stdcall TerminalCalculateResize(_In_ void* terminal, _In_ short width, _In_ short height, _Out_ COORD* dimensions);
|
||||||
__declspec(dllexport) void _stdcall TerminalDpiChanged(void* terminal, int newDpi);
|
__declspec(dllexport) void _stdcall TerminalDpiChanged(void* terminal, int newDpi);
|
||||||
__declspec(dllexport) void _stdcall TerminalUserScroll(void* terminal, int viewTop);
|
__declspec(dllexport) void _stdcall TerminalUserScroll(void* terminal, int viewTop);
|
||||||
__declspec(dllexport) void _stdcall TerminalClearSelection(void* terminal);
|
__declspec(dllexport) void _stdcall TerminalClearSelection(void* terminal);
|
||||||
@@ -90,7 +91,9 @@ private:
|
|||||||
std::optional<til::point> _singleClickTouchdownPos;
|
std::optional<til::point> _singleClickTouchdownPos;
|
||||||
|
|
||||||
friend HRESULT _stdcall CreateTerminal(HWND parentHwnd, _Out_ void** hwnd, _Out_ void** terminal);
|
friend HRESULT _stdcall CreateTerminal(HWND parentHwnd, _Out_ void** hwnd, _Out_ void** terminal);
|
||||||
friend HRESULT _stdcall TerminalResize(void* terminal, COORD dimensions);
|
friend HRESULT _stdcall TerminalTriggerResize(_In_ void* terminal, _In_ short width, _In_ short height, _Out_ COORD* dimensions);
|
||||||
|
friend HRESULT _stdcall TerminalTriggerResizeWithDimension(_In_ void* terminal, _In_ COORD dimensions, _Out_ SIZE* dimensionsInPixels);
|
||||||
|
friend HRESULT _stdcall TerminalCalculateResize(_In_ void* terminal, _In_ short width, _In_ short height, _Out_ COORD* dimensions);
|
||||||
friend void _stdcall TerminalDpiChanged(void* terminal, int newDpi);
|
friend void _stdcall TerminalDpiChanged(void* terminal, int newDpi);
|
||||||
friend void _stdcall TerminalUserScroll(void* terminal, int viewTop);
|
friend void _stdcall TerminalUserScroll(void* terminal, int viewTop);
|
||||||
friend void _stdcall TerminalClearSelection(void* terminal);
|
friend void _stdcall TerminalClearSelection(void* terminal);
|
||||||
|
|||||||
@@ -185,12 +185,17 @@ HRESULT OpenTerminalHere::GetState(IShellItemArray* /*psiItemArray*/,
|
|||||||
|
|
||||||
HRESULT OpenTerminalHere::GetIcon(IShellItemArray* /*psiItemArray*/,
|
HRESULT OpenTerminalHere::GetIcon(IShellItemArray* /*psiItemArray*/,
|
||||||
LPWSTR* ppszIcon)
|
LPWSTR* ppszIcon)
|
||||||
|
try
|
||||||
{
|
{
|
||||||
// the icon ref ("dll,-<resid>") is provided here, in this case none is provided
|
std::filesystem::path modulePath{ wil::GetModuleFileNameW<std::wstring>(wil::GetModuleInstanceHandle()) };
|
||||||
*ppszIcon = nullptr;
|
modulePath.replace_filename(WindowsTerminalExe);
|
||||||
// TODO GH#6111: Return the Terminal icon here
|
// WindowsTerminal.exe,-101 will be the first icon group in WT
|
||||||
return E_NOTIMPL;
|
// We're using WindowsTerminal here explicitly, and not wt (from _getExePath), because
|
||||||
|
// WindowsTerminal is the only one built with the right icons.
|
||||||
|
const auto resource{ modulePath.wstring() + L",-101" };
|
||||||
|
return SHStrDupW(resource.c_str(), ppszIcon);
|
||||||
}
|
}
|
||||||
|
CATCH_RETURN();
|
||||||
|
|
||||||
HRESULT OpenTerminalHere::GetFlags(EXPCMDFLAGS* pFlags)
|
HRESULT OpenTerminalHere::GetFlags(EXPCMDFLAGS* pFlags)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -214,6 +214,9 @@ namespace winrt::TerminalApp::implementation
|
|||||||
struct MoveFocusArgs : public MoveFocusArgsT<MoveFocusArgs>
|
struct MoveFocusArgs : public MoveFocusArgsT<MoveFocusArgs>
|
||||||
{
|
{
|
||||||
MoveFocusArgs() = default;
|
MoveFocusArgs() = default;
|
||||||
|
MoveFocusArgs(TerminalApp::Direction direction) :
|
||||||
|
_Direction{ direction } {};
|
||||||
|
|
||||||
GETSET_PROPERTY(TerminalApp::Direction, Direction, TerminalApp::Direction::None);
|
GETSET_PROPERTY(TerminalApp::Direction, Direction, TerminalApp::Direction::None);
|
||||||
|
|
||||||
static constexpr std::string_view DirectionKey{ "direction" };
|
static constexpr std::string_view DirectionKey{ "direction" };
|
||||||
@@ -308,6 +311,11 @@ namespace winrt::TerminalApp::implementation
|
|||||||
struct SplitPaneArgs : public SplitPaneArgsT<SplitPaneArgs>
|
struct SplitPaneArgs : public SplitPaneArgsT<SplitPaneArgs>
|
||||||
{
|
{
|
||||||
SplitPaneArgs() = default;
|
SplitPaneArgs() = default;
|
||||||
|
SplitPaneArgs(winrt::TerminalApp::SplitState style, const winrt::TerminalApp::NewTerminalArgs& terminalArgs) :
|
||||||
|
_SplitStyle{ style },
|
||||||
|
_TerminalArgs{ terminalArgs } {};
|
||||||
|
SplitPaneArgs(SplitType splitMode) :
|
||||||
|
_SplitMode{ splitMode } {};
|
||||||
GETSET_PROPERTY(winrt::TerminalApp::SplitState, SplitStyle, winrt::TerminalApp::SplitState::Automatic);
|
GETSET_PROPERTY(winrt::TerminalApp::SplitState, SplitStyle, winrt::TerminalApp::SplitState::Automatic);
|
||||||
GETSET_PROPERTY(winrt::TerminalApp::NewTerminalArgs, TerminalArgs, nullptr);
|
GETSET_PROPERTY(winrt::TerminalApp::NewTerminalArgs, TerminalArgs, nullptr);
|
||||||
GETSET_PROPERTY(winrt::TerminalApp::SplitType, SplitMode, winrt::TerminalApp::SplitType::Manual);
|
GETSET_PROPERTY(winrt::TerminalApp::SplitType, SplitMode, winrt::TerminalApp::SplitType::Manual);
|
||||||
@@ -553,4 +561,6 @@ namespace winrt::TerminalApp::factory_implementation
|
|||||||
{
|
{
|
||||||
BASIC_FACTORY(ActionEventArgs);
|
BASIC_FACTORY(ActionEventArgs);
|
||||||
BASIC_FACTORY(NewTerminalArgs);
|
BASIC_FACTORY(NewTerminalArgs);
|
||||||
|
BASIC_FACTORY(MoveFocusArgs);
|
||||||
|
BASIC_FACTORY(SplitPaneArgs);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ namespace TerminalApp
|
|||||||
|
|
||||||
[default_interface] runtimeclass MoveFocusArgs : IActionArgs
|
[default_interface] runtimeclass MoveFocusArgs : IActionArgs
|
||||||
{
|
{
|
||||||
|
MoveFocusArgs(Direction direction);
|
||||||
Direction Direction { get; };
|
Direction Direction { get; };
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -102,6 +103,9 @@ namespace TerminalApp
|
|||||||
|
|
||||||
[default_interface] runtimeclass SplitPaneArgs : IActionArgs
|
[default_interface] runtimeclass SplitPaneArgs : IActionArgs
|
||||||
{
|
{
|
||||||
|
SplitPaneArgs(SplitState split, NewTerminalArgs terminalArgs);
|
||||||
|
SplitPaneArgs(SplitType splitMode);
|
||||||
|
|
||||||
SplitState SplitStyle { get; };
|
SplitState SplitStyle { get; };
|
||||||
NewTerminalArgs TerminalArgs { get; };
|
NewTerminalArgs TerminalArgs { get; };
|
||||||
SplitType SplitMode { get; };
|
SplitType SplitMode { get; };
|
||||||
|
|||||||
@@ -132,10 +132,9 @@ namespace winrt::TerminalApp::implementation
|
|||||||
// be removed before it's re-added in Pane::Restore
|
// be removed before it's re-added in Pane::Restore
|
||||||
_tabContent.Children().Clear();
|
_tabContent.Children().Clear();
|
||||||
|
|
||||||
|
// Togging the zoom on the tab will cause the tab to inform us of
|
||||||
|
// the new root Content for this tab.
|
||||||
activeTab->ToggleZoom();
|
activeTab->ToggleZoom();
|
||||||
|
|
||||||
// Update the selected tab, to trigger us to re-add the tab's GetRootElement to the UI tree
|
|
||||||
_UpdatedSelectedTab(_tabView.SelectedIndex());
|
|
||||||
}
|
}
|
||||||
args.Handled(true);
|
args.Handled(true);
|
||||||
}
|
}
|
||||||
@@ -488,6 +487,14 @@ namespace winrt::TerminalApp::implementation
|
|||||||
void TerminalPage::_HandleOpenTabSearch(const IInspectable& /*sender*/,
|
void TerminalPage::_HandleOpenTabSearch(const IInspectable& /*sender*/,
|
||||||
const TerminalApp::ActionEventArgs& args)
|
const TerminalApp::ActionEventArgs& args)
|
||||||
{
|
{
|
||||||
|
// Tab search is always in-order.
|
||||||
|
auto tabCommands = winrt::single_threaded_vector<TerminalApp::Command>();
|
||||||
|
for (const auto& tab : _tabs)
|
||||||
|
{
|
||||||
|
tabCommands.Append(tab.SwitchToTabCommand());
|
||||||
|
}
|
||||||
|
CommandPalette().SetTabActions(tabCommands);
|
||||||
|
|
||||||
auto opt = _GetFocusedTabIndex();
|
auto opt = _GetFocusedTabIndex();
|
||||||
uint32_t startIdx = opt.value_or(0);
|
uint32_t startIdx = opt.value_or(0);
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,8 @@ static const std::array<std::wstring_view, static_cast<uint32_t>(winrt::Terminal
|
|||||||
USES_RESOURCE(L"TooManyKeysForChord"),
|
USES_RESOURCE(L"TooManyKeysForChord"),
|
||||||
USES_RESOURCE(L"MissingRequiredParameter"),
|
USES_RESOURCE(L"MissingRequiredParameter"),
|
||||||
USES_RESOURCE(L"LegacyGlobalsProperty"),
|
USES_RESOURCE(L"LegacyGlobalsProperty"),
|
||||||
USES_RESOURCE(L"FailedToParseCommandJson")
|
USES_RESOURCE(L"FailedToParseCommandJson"),
|
||||||
|
USES_RESOURCE(L"FailedToWriteToSettings")
|
||||||
};
|
};
|
||||||
static const std::array<std::wstring_view, static_cast<uint32_t>(winrt::TerminalApp::SettingsLoadErrors::ERRORS_SIZE)> settingsLoadErrorsLabels {
|
static const std::array<std::wstring_view, static_cast<uint32_t>(winrt::TerminalApp::SettingsLoadErrors::ERRORS_SIZE)> settingsLoadErrorsLabels {
|
||||||
USES_RESOURCE(L"NoProfilesText"),
|
USES_RESOURCE(L"NoProfilesText"),
|
||||||
@@ -464,6 +465,11 @@ namespace winrt::TerminalApp::implementation
|
|||||||
void AppLogic::_OnLoaded(const IInspectable& /*sender*/,
|
void AppLogic::_OnLoaded(const IInspectable& /*sender*/,
|
||||||
const RoutedEventArgs& /*eventArgs*/)
|
const RoutedEventArgs& /*eventArgs*/)
|
||||||
{
|
{
|
||||||
|
const auto keyboardServiceIsDisabled = !_IsKeyboardServiceEnabled();
|
||||||
|
if (keyboardServiceIsDisabled)
|
||||||
|
{
|
||||||
|
_root->ShowKeyboardServiceWarning();
|
||||||
|
}
|
||||||
if (FAILED(_settingsLoadedResult))
|
if (FAILED(_settingsLoadedResult))
|
||||||
{
|
{
|
||||||
const winrt::hstring titleKey = USES_RESOURCE(L"InitialJsonParseErrorTitle");
|
const winrt::hstring titleKey = USES_RESOURCE(L"InitialJsonParseErrorTitle");
|
||||||
@@ -476,6 +482,51 @@ namespace winrt::TerminalApp::implementation
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Method Description:
|
||||||
|
// - Helper for determining if the "Touch Keyboard and Handwriting Panel
|
||||||
|
// Service" is enabled. If it isn't, we want to be able to display a
|
||||||
|
// warning to the user, because they won't be able to type in the
|
||||||
|
// Terminal.
|
||||||
|
// Return Value:
|
||||||
|
// - true if the service is enabled, or if we fail to query the service. We
|
||||||
|
// return true in that case, to be less noisy (though, that is unexpected)
|
||||||
|
bool AppLogic::_IsKeyboardServiceEnabled()
|
||||||
|
{
|
||||||
|
if (IsUwp())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If at any point we fail to open the service manager, the service,
|
||||||
|
// etc, then just quick return true to disable the dialog. We'd rather
|
||||||
|
// not be noisy with this dialog if we failed for some reason.
|
||||||
|
|
||||||
|
// Open the service manager. This will return 0 if it failed.
|
||||||
|
wil::unique_schandle hManager{ OpenSCManager(nullptr, nullptr, 0) };
|
||||||
|
|
||||||
|
if (LOG_LAST_ERROR_IF(!hManager.is_valid()))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a handle to the keyboard service
|
||||||
|
wil::unique_schandle hService{ OpenService(hManager.get(), TabletInputServiceKey.data(), SERVICE_QUERY_STATUS) };
|
||||||
|
if (LOG_LAST_ERROR_IF(!hService.is_valid()))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the current state of the service
|
||||||
|
SERVICE_STATUS status{ 0 };
|
||||||
|
if (!LOG_IF_WIN32_BOOL_FALSE(QueryServiceStatus(hService.get(), &status)))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto state = status.dwCurrentState;
|
||||||
|
return (state == SERVICE_RUNNING || state == SERVICE_START_PENDING);
|
||||||
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - Get the size in pixels of the client area we'll need to launch this
|
// - Get the size in pixels of the client area we'll need to launch this
|
||||||
// terminal app. This method will use the default profile's settings to do
|
// terminal app. This method will use the default profile's settings to do
|
||||||
@@ -609,6 +660,17 @@ namespace winrt::TerminalApp::implementation
|
|||||||
return _settings.GlobalSettings().ShowTabsInTitlebar();
|
return _settings.GlobalSettings().ShowTabsInTitlebar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AppLogic::GetInitialAlwaysOnTop()
|
||||||
|
{
|
||||||
|
if (!_loadedInitialSettings)
|
||||||
|
{
|
||||||
|
// Load settings if we haven't already
|
||||||
|
LoadSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
return _settings.GlobalSettings().AlwaysOnTop();
|
||||||
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - See Pane::CalcSnappedDimension
|
// - See Pane::CalcSnappedDimension
|
||||||
float AppLogic::CalcSnappedDimension(const bool widthOrHeight, const float dimension) const
|
float AppLogic::CalcSnappedDimension(const bool widthOrHeight, const float dimension) const
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ namespace winrt::TerminalApp::implementation
|
|||||||
winrt::Windows::UI::Xaml::ElementTheme GetRequestedTheme();
|
winrt::Windows::UI::Xaml::ElementTheme GetRequestedTheme();
|
||||||
LaunchMode GetLaunchMode();
|
LaunchMode GetLaunchMode();
|
||||||
bool GetShowTabsInTitlebar();
|
bool GetShowTabsInTitlebar();
|
||||||
|
bool GetInitialAlwaysOnTop();
|
||||||
float CalcSnappedDimension(const bool widthOrHeight, const float dimension) const;
|
float CalcSnappedDimension(const bool widthOrHeight, const float dimension) const;
|
||||||
|
|
||||||
Windows::UI::Xaml::UIElement GetRoot() noexcept;
|
Windows::UI::Xaml::UIElement GetRoot() noexcept;
|
||||||
@@ -88,6 +89,8 @@ namespace winrt::TerminalApp::implementation
|
|||||||
|
|
||||||
void _ShowLoadErrorsDialog(const winrt::hstring& titleKey, const winrt::hstring& contentKey, HRESULT settingsLoadedResult);
|
void _ShowLoadErrorsDialog(const winrt::hstring& titleKey, const winrt::hstring& contentKey, HRESULT settingsLoadedResult);
|
||||||
void _ShowLoadWarningsDialog();
|
void _ShowLoadWarningsDialog();
|
||||||
|
bool _IsKeyboardServiceEnabled();
|
||||||
|
void _ShowKeyboardServiceDisabledDialog();
|
||||||
|
|
||||||
fire_and_forget _LoadErrorsDialogRoutine();
|
fire_and_forget _LoadErrorsDialogRoutine();
|
||||||
fire_and_forget _ShowLoadWarningsDialogRoutine();
|
fire_and_forget _ShowLoadWarningsDialogRoutine();
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ namespace TerminalApp
|
|||||||
Windows.UI.Xaml.ElementTheme GetRequestedTheme();
|
Windows.UI.Xaml.ElementTheme GetRequestedTheme();
|
||||||
LaunchMode GetLaunchMode();
|
LaunchMode GetLaunchMode();
|
||||||
Boolean GetShowTabsInTitlebar();
|
Boolean GetShowTabsInTitlebar();
|
||||||
|
Boolean GetInitialAlwaysOnTop();
|
||||||
Single CalcSnappedDimension(Boolean widthOrHeight, Single dimension);
|
Single CalcSnappedDimension(Boolean widthOrHeight, Single dimension);
|
||||||
void TitlebarClicked();
|
void TitlebarClicked();
|
||||||
void WindowCloseButtonClicked();
|
void WindowCloseButtonClicked();
|
||||||
|
|||||||
@@ -126,6 +126,16 @@ IVectorView<winrt::TerminalApp::SettingsLoadWarnings> CascadiaSettings::Warnings
|
|||||||
return _warnings.GetView();
|
return _warnings.GetView();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CascadiaSettings::ClearWarnings()
|
||||||
|
{
|
||||||
|
_warnings.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CascadiaSettings::AppendWarning(SettingsLoadWarnings warning)
|
||||||
|
{
|
||||||
|
_warnings.Append(warning);
|
||||||
|
}
|
||||||
|
|
||||||
winrt::Windows::Foundation::IReference<winrt::TerminalApp::SettingsLoadErrors> CascadiaSettings::GetLoadingError()
|
winrt::Windows::Foundation::IReference<winrt::TerminalApp::SettingsLoadErrors> CascadiaSettings::GetLoadingError()
|
||||||
{
|
{
|
||||||
return _loadError;
|
return _loadError;
|
||||||
@@ -148,8 +158,6 @@ winrt::hstring CascadiaSettings::GetSerializationErrorMessage()
|
|||||||
// - <none>
|
// - <none>
|
||||||
void CascadiaSettings::_ValidateSettings()
|
void CascadiaSettings::_ValidateSettings()
|
||||||
{
|
{
|
||||||
_warnings.Clear();
|
|
||||||
|
|
||||||
// Make sure to check that profiles exists at all first and foremost:
|
// Make sure to check that profiles exists at all first and foremost:
|
||||||
_ValidateProfilesExist();
|
_ValidateProfilesExist();
|
||||||
|
|
||||||
|
|||||||
@@ -82,6 +82,8 @@ namespace winrt::TerminalApp::implementation
|
|||||||
TerminalApp::ColorScheme GetColorSchemeForProfile(const guid profileGuid) const;
|
TerminalApp::ColorScheme GetColorSchemeForProfile(const guid profileGuid) const;
|
||||||
|
|
||||||
Windows::Foundation::Collections::IVectorView<SettingsLoadWarnings> Warnings();
|
Windows::Foundation::Collections::IVectorView<SettingsLoadWarnings> Warnings();
|
||||||
|
void ClearWarnings();
|
||||||
|
void AppendWarning(SettingsLoadWarnings warning);
|
||||||
Windows::Foundation::IReference<SettingsLoadErrors> GetLoadingError();
|
Windows::Foundation::IReference<SettingsLoadErrors> GetLoadingError();
|
||||||
hstring GetSerializationErrorMessage();
|
hstring GetSerializationErrorMessage();
|
||||||
|
|
||||||
|
|||||||
@@ -106,6 +106,7 @@ winrt::TerminalApp::CascadiaSettings CascadiaSettings::LoadAll()
|
|||||||
{
|
{
|
||||||
auto settings = LoadDefaults();
|
auto settings = LoadDefaults();
|
||||||
auto resultPtr = winrt::get_self<CascadiaSettings>(settings);
|
auto resultPtr = winrt::get_self<CascadiaSettings>(settings);
|
||||||
|
resultPtr->ClearWarnings();
|
||||||
|
|
||||||
// GH 3588, we need this below to know if the user chose something that wasn't our default.
|
// GH 3588, we need this below to know if the user chose something that wasn't our default.
|
||||||
// Collect it up here in case it gets modified by any of the other layers between now and when
|
// Collect it up here in case it gets modified by any of the other layers between now and when
|
||||||
@@ -185,7 +186,14 @@ winrt::TerminalApp::CascadiaSettings CascadiaSettings::LoadAll()
|
|||||||
// We should re-parse, but not re-layer
|
// We should re-parse, but not re-layer
|
||||||
resultPtr->_ParseJsonString(resultPtr->_userSettingsString, false);
|
resultPtr->_ParseJsonString(resultPtr->_userSettingsString, false);
|
||||||
|
|
||||||
_WriteSettings(resultPtr->_userSettingsString);
|
try
|
||||||
|
{
|
||||||
|
_WriteSettings(resultPtr->_userSettingsString);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
resultPtr->AppendWarning(SettingsLoadWarnings::FailedToWriteToSettings);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this throws, the app will catch it and use the default settings
|
// If this throws, the app will catch it and use the default settings
|
||||||
|
|||||||
@@ -129,7 +129,7 @@
|
|||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<ColorPicker x:Name="customColorPicker"
|
<ColorPicker x:Name="customColorPicker"
|
||||||
IsMoreButtonVisible="True"
|
IsMoreButtonVisible="True"
|
||||||
IsColorSliderVisible="False"
|
IsColorSliderVisible="True"
|
||||||
IsColorChannelTextInputVisible="True"
|
IsColorChannelTextInputVisible="True"
|
||||||
IsHexInputVisible="True"
|
IsHexInputVisible="True"
|
||||||
IsAlphaEnabled="False"
|
IsAlphaEnabled="False"
|
||||||
|
|||||||
@@ -95,6 +95,8 @@ namespace winrt::TerminalApp::implementation
|
|||||||
}
|
}
|
||||||
_sizeChangedRevoker.revoke();
|
_sizeChangedRevoker.revoke();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
_filteredActionsView().SelectionChanged({ this, &CommandPalette::_selectedCommandChanged });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
@@ -117,6 +119,113 @@ namespace winrt::TerminalApp::implementation
|
|||||||
_filteredActionsView().ScrollIntoView(_filteredActionsView().SelectedItem());
|
_filteredActionsView().ScrollIntoView(_filteredActionsView().SelectedItem());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Method Description:
|
||||||
|
// - Scroll the command palette to the specified index
|
||||||
|
// Arguments:
|
||||||
|
// - index within a list view of commands
|
||||||
|
// Return Value:
|
||||||
|
// - <none>
|
||||||
|
void CommandPalette::_scrollToIndex(uint32_t index)
|
||||||
|
{
|
||||||
|
auto numItems = _filteredActionsView().Items().Size();
|
||||||
|
|
||||||
|
if (numItems == 0)
|
||||||
|
{
|
||||||
|
// if the list is empty no need to scroll
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto clampedIndex = std::clamp<int32_t>(index, 0, numItems - 1);
|
||||||
|
_filteredActionsView().SelectedIndex(clampedIndex);
|
||||||
|
_filteredActionsView().ScrollIntoView(_filteredActionsView().SelectedItem());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method Description:
|
||||||
|
// - Computes the number of visible commands
|
||||||
|
// Arguments:
|
||||||
|
// - <none>
|
||||||
|
// Return Value:
|
||||||
|
// - the approximate number of items visible in the list (in other words the size of the page)
|
||||||
|
uint32_t CommandPalette::_getNumVisibleItems()
|
||||||
|
{
|
||||||
|
const auto container = _filteredActionsView().ContainerFromIndex(0);
|
||||||
|
const auto item = container.try_as<winrt::Windows::UI::Xaml::Controls::ListViewItem>();
|
||||||
|
const auto itemHeight = ::base::saturated_cast<int>(item.ActualHeight());
|
||||||
|
const auto listHeight = ::base::saturated_cast<int>(_filteredActionsView().ActualHeight());
|
||||||
|
return listHeight / itemHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method Description:
|
||||||
|
// - Scrolls the focus one page up the list of commands.
|
||||||
|
// Arguments:
|
||||||
|
// - <none>
|
||||||
|
// Return Value:
|
||||||
|
// - <none>
|
||||||
|
void CommandPalette::ScrollPageUp()
|
||||||
|
{
|
||||||
|
auto selected = _filteredActionsView().SelectedIndex();
|
||||||
|
auto numVisibleItems = _getNumVisibleItems();
|
||||||
|
_scrollToIndex(selected - numVisibleItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method Description:
|
||||||
|
// - Scrolls the focus one page down the list of commands.
|
||||||
|
// Arguments:
|
||||||
|
// - <none>
|
||||||
|
// Return Value:
|
||||||
|
// - <none>
|
||||||
|
void CommandPalette::ScrollPageDown()
|
||||||
|
{
|
||||||
|
auto selected = _filteredActionsView().SelectedIndex();
|
||||||
|
auto numVisibleItems = _getNumVisibleItems();
|
||||||
|
_scrollToIndex(selected + numVisibleItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method Description:
|
||||||
|
// - Moves the focus to the top item in the list of commands.
|
||||||
|
// Arguments:
|
||||||
|
// - <none>
|
||||||
|
// Return Value:
|
||||||
|
// - <none>
|
||||||
|
void CommandPalette::ScrollToTop()
|
||||||
|
{
|
||||||
|
_scrollToIndex(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method Description:
|
||||||
|
// - Moves the focus to the bottom item in the list of commands.
|
||||||
|
// Arguments:
|
||||||
|
// - <none>
|
||||||
|
// Return Value:
|
||||||
|
// - <none>
|
||||||
|
void CommandPalette::ScrollToBottom()
|
||||||
|
{
|
||||||
|
_scrollToIndex(_filteredActionsView().Items().Size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method Description:
|
||||||
|
// - Called when the command selection changes. We'll use this in the tab
|
||||||
|
// switcher to "preview" tabs as the user navigates the list of tabs. To
|
||||||
|
// do that, we'll dispatch the switch to tab command for this tab, but not
|
||||||
|
// dismiss the switcher.
|
||||||
|
// Arguments:
|
||||||
|
// - <unused>
|
||||||
|
// Return Value:
|
||||||
|
// - <none>
|
||||||
|
void CommandPalette::_selectedCommandChanged(const IInspectable& /*sender*/,
|
||||||
|
const Windows::UI::Xaml::RoutedEventArgs& /*args*/)
|
||||||
|
{
|
||||||
|
if (_currentMode == CommandPaletteMode::TabSwitchMode)
|
||||||
|
{
|
||||||
|
const auto& selectedCommand = _filteredActionsView().SelectedItem();
|
||||||
|
if (const auto& command = selectedCommand.try_as<TerminalApp::Command>())
|
||||||
|
{
|
||||||
|
const auto& actionAndArgs = command.Action();
|
||||||
|
_dispatch.DoAction(actionAndArgs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CommandPalette::_previewKeyDownHandler(IInspectable const& /*sender*/,
|
void CommandPalette::_previewKeyDownHandler(IInspectable const& /*sender*/,
|
||||||
Windows::UI::Xaml::Input::KeyRoutedEventArgs const& e)
|
Windows::UI::Xaml::Input::KeyRoutedEventArgs const& e)
|
||||||
{
|
{
|
||||||
@@ -170,6 +279,30 @@ namespace winrt::TerminalApp::implementation
|
|||||||
SelectNextItem(true);
|
SelectNextItem(true);
|
||||||
e.Handled(true);
|
e.Handled(true);
|
||||||
}
|
}
|
||||||
|
else if (key == VirtualKey::PageUp)
|
||||||
|
{
|
||||||
|
// Action Mode: Move focus to the first visible item in the list.
|
||||||
|
ScrollPageUp();
|
||||||
|
e.Handled(true);
|
||||||
|
}
|
||||||
|
else if (key == VirtualKey::PageDown)
|
||||||
|
{
|
||||||
|
// Action Mode: Move focus to the last visible item in the list.
|
||||||
|
ScrollPageDown();
|
||||||
|
e.Handled(true);
|
||||||
|
}
|
||||||
|
else if (key == VirtualKey::Home)
|
||||||
|
{
|
||||||
|
// Action Mode: Move focus to the first item in the list.
|
||||||
|
ScrollToTop();
|
||||||
|
e.Handled(true);
|
||||||
|
}
|
||||||
|
else if (key == VirtualKey::End)
|
||||||
|
{
|
||||||
|
// Action Mode: Move focus to the last item in the list.
|
||||||
|
ScrollToBottom();
|
||||||
|
e.Handled(true);
|
||||||
|
}
|
||||||
else if (key == VirtualKey::Enter)
|
else if (key == VirtualKey::Enter)
|
||||||
{
|
{
|
||||||
// Action, TabSwitch or TabSearchMode Mode: Dispatch the action of the selected command.
|
// Action, TabSwitch or TabSearchMode Mode: Dispatch the action of the selected command.
|
||||||
@@ -600,6 +733,12 @@ namespace winrt::TerminalApp::implementation
|
|||||||
_updateFilteredActions();
|
_updateFilteredActions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CommandPalette::SetTabActions(Collections::IVector<TerminalApp::Command> const& tabs)
|
||||||
|
{
|
||||||
|
_allTabActions = tabs;
|
||||||
|
_updateFilteredActions();
|
||||||
|
}
|
||||||
|
|
||||||
void CommandPalette::EnableCommandPaletteMode()
|
void CommandPalette::EnableCommandPaletteMode()
|
||||||
{
|
{
|
||||||
_switchToMode(CommandPaletteMode::ActionMode);
|
_switchToMode(CommandPaletteMode::ActionMode);
|
||||||
@@ -955,135 +1094,6 @@ namespace winrt::TerminalApp::implementation
|
|||||||
_currentNestedCommands.Clear();
|
_currentNestedCommands.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
|
||||||
// - Listens for changes to TerminalPage's _tabs vector. Updates our vector of
|
|
||||||
// tab switching commands accordingly.
|
|
||||||
// Arguments:
|
|
||||||
// - s: The vector being listened to.
|
|
||||||
// - e: The vector changed args that tells us whether a change, insert, or removal was performed
|
|
||||||
// on the listened-to vector.
|
|
||||||
// Return Value:
|
|
||||||
// - <none>
|
|
||||||
void CommandPalette::OnTabsChanged(const IInspectable& s, const IVectorChangedEventArgs& e)
|
|
||||||
{
|
|
||||||
if (auto tabList = s.try_as<IObservableVector<TerminalApp::Tab>>())
|
|
||||||
{
|
|
||||||
auto idx = e.Index();
|
|
||||||
auto changedEvent = e.CollectionChange();
|
|
||||||
|
|
||||||
switch (changedEvent)
|
|
||||||
{
|
|
||||||
case CollectionChange::ItemChanged:
|
|
||||||
{
|
|
||||||
winrt::com_ptr<Command> item;
|
|
||||||
item.copy_from(winrt::get_self<Command>(_allTabActions.GetAt(idx)));
|
|
||||||
item->propertyChangedRevoker.revoke();
|
|
||||||
|
|
||||||
auto tab = tabList.GetAt(idx);
|
|
||||||
GenerateCommandForTab(idx, false, tab);
|
|
||||||
UpdateTabIndices(idx);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CollectionChange::ItemInserted:
|
|
||||||
{
|
|
||||||
auto tab = tabList.GetAt(idx);
|
|
||||||
GenerateCommandForTab(idx, true, tab);
|
|
||||||
UpdateTabIndices(idx);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CollectionChange::ItemRemoved:
|
|
||||||
{
|
|
||||||
winrt::com_ptr<Command> item;
|
|
||||||
item.copy_from(winrt::get_self<Command>(_allTabActions.GetAt(idx)));
|
|
||||||
item->propertyChangedRevoker.revoke();
|
|
||||||
|
|
||||||
_allTabActions.RemoveAt(idx);
|
|
||||||
UpdateTabIndices(idx);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_updateFilteredActions();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method Description:
|
|
||||||
// - In the case where a tab is removed or reordered, the given indices of
|
|
||||||
// the tab switch commands following the removed/reordered tab will get out of sync by 1
|
|
||||||
// (e.g. if tab 1 is removed, tabs 2,3,4,... need to become tabs 1,2,3,...)
|
|
||||||
// This function just loops through the tabs following startIdx and adjusts their given indices.
|
|
||||||
// Arguments:
|
|
||||||
// - startIdx: The index to start the update loop at.
|
|
||||||
// Return Value:
|
|
||||||
// - <none>
|
|
||||||
void CommandPalette::UpdateTabIndices(const uint32_t startIdx)
|
|
||||||
{
|
|
||||||
for (auto i = startIdx; i < _allTabActions.Size(); ++i)
|
|
||||||
{
|
|
||||||
auto command = _allTabActions.GetAt(i);
|
|
||||||
|
|
||||||
command.Action().Args().as<implementation::SwitchToTabArgs>()->TabIndex(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method Description:
|
|
||||||
// - Create a tab switching command based on the given tab object and insert/update the command
|
|
||||||
// at the given index. The command will call a SwitchToTab action on the given idx.
|
|
||||||
// Arguments:
|
|
||||||
// - idx: The index to insert or update the tab switch command.
|
|
||||||
// - tab: The tab object to refer to when creating the tab switch command.
|
|
||||||
// Return Value:
|
|
||||||
// - <none>
|
|
||||||
void CommandPalette::GenerateCommandForTab(const uint32_t idx, bool inserted, TerminalApp::Tab& tab)
|
|
||||||
{
|
|
||||||
auto focusTabAction = winrt::make_self<implementation::ActionAndArgs>();
|
|
||||||
auto args = winrt::make_self<implementation::SwitchToTabArgs>();
|
|
||||||
args->TabIndex(idx);
|
|
||||||
|
|
||||||
focusTabAction->Action(ShortcutAction::SwitchToTab);
|
|
||||||
focusTabAction->Args(*args);
|
|
||||||
|
|
||||||
auto command = winrt::make_self<implementation::Command>();
|
|
||||||
command->Action(*focusTabAction);
|
|
||||||
command->Name(tab.Title());
|
|
||||||
command->IconSource(tab.IconSource());
|
|
||||||
|
|
||||||
// Listen for changes to the Tab so we can update this Command's attributes accordingly.
|
|
||||||
auto weakThis{ get_weak() };
|
|
||||||
auto weakCommand{ command->get_weak() };
|
|
||||||
command->propertyChangedRevoker = tab.PropertyChanged(winrt::auto_revoke, [weakThis, weakCommand, tab](auto&&, const Windows::UI::Xaml::Data::PropertyChangedEventArgs& args) {
|
|
||||||
auto palette{ weakThis.get() };
|
|
||||||
auto command{ weakCommand.get() };
|
|
||||||
|
|
||||||
if (palette && command)
|
|
||||||
{
|
|
||||||
if (args.PropertyName() == L"Title")
|
|
||||||
{
|
|
||||||
if (command->Name() != tab.Title())
|
|
||||||
{
|
|
||||||
command->Name(tab.Title());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (args.PropertyName() == L"IconSource")
|
|
||||||
{
|
|
||||||
if (command->IconSource() != tab.IconSource())
|
|
||||||
{
|
|
||||||
command->IconSource(tab.IconSource());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (inserted)
|
|
||||||
{
|
|
||||||
_allTabActions.InsertAt(idx, *command);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_allTabActions.SetAt(idx, *command);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CommandPalette::EnableTabSwitcherMode(const bool searchMode, const uint32_t startIdx)
|
void CommandPalette::EnableTabSwitcherMode(const bool searchMode, const uint32_t startIdx)
|
||||||
{
|
{
|
||||||
_switcherStartIdx = startIdx;
|
_switcherStartIdx = startIdx;
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ namespace winrt::TerminalApp::implementation
|
|||||||
Windows::Foundation::Collections::IObservableVector<TerminalApp::Command> FilteredActions();
|
Windows::Foundation::Collections::IObservableVector<TerminalApp::Command> FilteredActions();
|
||||||
|
|
||||||
void SetCommands(Windows::Foundation::Collections::IVector<TerminalApp::Command> const& actions);
|
void SetCommands(Windows::Foundation::Collections::IVector<TerminalApp::Command> const& actions);
|
||||||
|
void SetTabActions(Windows::Foundation::Collections::IVector<TerminalApp::Command> const& tabs);
|
||||||
void SetKeyBindings(Microsoft::Terminal::TerminalControl::IKeyBindings bindings);
|
void SetKeyBindings(Microsoft::Terminal::TerminalControl::IKeyBindings bindings);
|
||||||
|
|
||||||
void EnableCommandPaletteMode();
|
void EnableCommandPaletteMode();
|
||||||
@@ -33,9 +34,13 @@ namespace winrt::TerminalApp::implementation
|
|||||||
|
|
||||||
void SelectNextItem(const bool moveDown);
|
void SelectNextItem(const bool moveDown);
|
||||||
|
|
||||||
|
void ScrollPageUp();
|
||||||
|
void ScrollPageDown();
|
||||||
|
void ScrollToTop();
|
||||||
|
void ScrollToBottom();
|
||||||
|
|
||||||
// Tab Switcher
|
// Tab Switcher
|
||||||
void EnableTabSwitcherMode(const bool searchMode, const uint32_t startIdx);
|
void EnableTabSwitcherMode(const bool searchMode, const uint32_t startIdx);
|
||||||
void OnTabsChanged(const Windows::Foundation::IInspectable& s, const Windows::Foundation::Collections::IVectorChangedEventArgs& e);
|
|
||||||
|
|
||||||
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
|
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
|
||||||
OBSERVABLE_GETSET_PROPERTY(winrt::hstring, NoMatchesText, _PropertyChangedHandlers);
|
OBSERVABLE_GETSET_PROPERTY(winrt::hstring, NoMatchesText, _PropertyChangedHandlers);
|
||||||
@@ -64,6 +69,9 @@ namespace winrt::TerminalApp::implementation
|
|||||||
void _keyUpHandler(Windows::Foundation::IInspectable const& sender,
|
void _keyUpHandler(Windows::Foundation::IInspectable const& sender,
|
||||||
Windows::UI::Xaml::Input::KeyRoutedEventArgs const& e);
|
Windows::UI::Xaml::Input::KeyRoutedEventArgs const& e);
|
||||||
|
|
||||||
|
void _selectedCommandChanged(Windows::Foundation::IInspectable const& sender,
|
||||||
|
Windows::UI::Xaml::RoutedEventArgs const& args);
|
||||||
|
|
||||||
void _updateUIForStackChange();
|
void _updateUIForStackChange();
|
||||||
|
|
||||||
void _rootPointerPressed(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs const& e);
|
void _rootPointerPressed(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs const& e);
|
||||||
@@ -87,8 +95,6 @@ namespace winrt::TerminalApp::implementation
|
|||||||
Microsoft::Terminal::TerminalControl::IKeyBindings _bindings;
|
Microsoft::Terminal::TerminalControl::IKeyBindings _bindings;
|
||||||
|
|
||||||
// Tab Switcher
|
// Tab Switcher
|
||||||
void GenerateCommandForTab(const uint32_t idx, bool inserted, winrt::TerminalApp::Tab& tab);
|
|
||||||
void UpdateTabIndices(const uint32_t startIdx);
|
|
||||||
Windows::Foundation::Collections::IVector<TerminalApp::Command> _allTabActions{ nullptr };
|
Windows::Foundation::Collections::IVector<TerminalApp::Command> _allTabActions{ nullptr };
|
||||||
uint32_t _switcherStartIdx;
|
uint32_t _switcherStartIdx;
|
||||||
void _anchorKeyUpHandler();
|
void _anchorKeyUpHandler();
|
||||||
@@ -98,6 +104,9 @@ namespace winrt::TerminalApp::implementation
|
|||||||
void _dispatchCommand(const TerminalApp::Command& command);
|
void _dispatchCommand(const TerminalApp::Command& command);
|
||||||
void _dispatchCommandline();
|
void _dispatchCommandline();
|
||||||
void _dismissPalette();
|
void _dismissPalette();
|
||||||
|
|
||||||
|
void _scrollToIndex(uint32_t index);
|
||||||
|
uint32_t _getNumVisibleItems();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ namespace TerminalApp
|
|||||||
Windows.Foundation.Collections.IObservableVector<Command> FilteredActions { get; };
|
Windows.Foundation.Collections.IObservableVector<Command> FilteredActions { get; };
|
||||||
|
|
||||||
void SetCommands(Windows.Foundation.Collections.IVector<Command> actions);
|
void SetCommands(Windows.Foundation.Collections.IVector<Command> actions);
|
||||||
|
void SetTabActions(Windows.Foundation.Collections.IVector<Command> tabs);
|
||||||
void SetKeyBindings(Microsoft.Terminal.TerminalControl.IKeyBindings bindings);
|
void SetKeyBindings(Microsoft.Terminal.TerminalControl.IKeyBindings bindings);
|
||||||
void EnableCommandPaletteMode();
|
void EnableCommandPaletteMode();
|
||||||
|
|
||||||
@@ -26,6 +27,5 @@ namespace TerminalApp
|
|||||||
void SetDispatch(ShortcutActionDispatch dispatch);
|
void SetDispatch(ShortcutActionDispatch dispatch);
|
||||||
|
|
||||||
void EnableTabSwitcherMode(Boolean searchMode, UInt32 startIdx);
|
void EnableTabSwitcherMode(Boolean searchMode, UInt32 startIdx);
|
||||||
void OnTabsChanged(IInspectable s, Windows.Foundation.Collections.IVectorChangedEventArgs e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ the MIT License. See LICENSE in the project root for license information. -->
|
|||||||
<Style x:Key="KeyChordBorderStyle" TargetType="Border">
|
<Style x:Key="KeyChordBorderStyle" TargetType="Border">
|
||||||
<Setter Property="BorderThickness" Value="1" />
|
<Setter Property="BorderThickness" Value="1" />
|
||||||
<Setter Property="CornerRadius" Value="1" />
|
<Setter Property="CornerRadius" Value="1" />
|
||||||
<Setter Property="Background" Value="{ThemeResource SystemControlBackgroundBaseLowBrush}" />
|
<Setter Property="Background" Value="{ThemeResource SystemAltMediumLowColor}" />
|
||||||
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||||
</Style>
|
</Style>
|
||||||
<Style x:Key="KeyChordTextBlockStyle" TargetType="TextBlock">
|
<Style x:Key="KeyChordTextBlockStyle" TargetType="TextBlock">
|
||||||
@@ -89,7 +89,7 @@ the MIT License. See LICENSE in the project root for license information. -->
|
|||||||
<Style x:Key="KeyChordBorderStyle" TargetType="Border">
|
<Style x:Key="KeyChordBorderStyle" TargetType="Border">
|
||||||
<Setter Property="BorderThickness" Value="1" />
|
<Setter Property="BorderThickness" Value="1" />
|
||||||
<Setter Property="CornerRadius" Value="1" />
|
<Setter Property="CornerRadius" Value="1" />
|
||||||
<Setter Property="Background" Value="{ThemeResource SystemControlBackgroundBaseLowBrush}" />
|
<Setter Property="Background" Value="{ThemeResource SystemAltMediumLowColor}" />
|
||||||
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||||
</Style>
|
</Style>
|
||||||
<Style x:Key="KeyChordTextBlockStyle" TargetType="TextBlock">
|
<Style x:Key="KeyChordTextBlockStyle" TargetType="TextBlock">
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ namespace winrt::TerminalApp::implementation
|
|||||||
GETSET_PROPERTY(bool, DebugFeaturesEnabled); // default value set in constructor
|
GETSET_PROPERTY(bool, DebugFeaturesEnabled); // default value set in constructor
|
||||||
GETSET_PROPERTY(bool, StartOnUserLogin, false);
|
GETSET_PROPERTY(bool, StartOnUserLogin, false);
|
||||||
GETSET_PROPERTY(bool, AlwaysOnTop, false);
|
GETSET_PROPERTY(bool, AlwaysOnTop, false);
|
||||||
GETSET_PROPERTY(bool, UseTabSwitcher, true);
|
GETSET_PROPERTY(bool, UseTabSwitcher, false);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
hstring _unparsedDefaultProfile;
|
hstring _unparsedDefaultProfile;
|
||||||
|
|||||||
@@ -17,6 +17,40 @@ DEFINE_PROPERTYKEY(PKEY_AppUserModel_DestListLogoUri, 0x9F4C2855, 0x9F79, 0x4B39
|
|||||||
{ 0x9F4C2855, 0x9F79, 0x4B39, 0xA8, 0xD0, 0xE1, 0xD4, 0x2D, 0xE1, 0xD5, 0xF3 }, 29 \
|
{ 0x9F4C2855, 0x9F79, 0x4B39, 0xA8, 0xD0, 0xE1, 0xD4, 0x2D, 0xE1, 0xD5, 0xF3 }, 29 \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Function Description:
|
||||||
|
// - This function guesses whether a string is a file path.
|
||||||
|
static constexpr bool _isProbableFilePath(std::wstring_view path)
|
||||||
|
{
|
||||||
|
// "C:X", "C:\X", "\\?", "\\."
|
||||||
|
// _this function rejects \??\ as a path_
|
||||||
|
if (path.size() >= 3)
|
||||||
|
{
|
||||||
|
const auto firstColon{ path.find(L':') };
|
||||||
|
if (firstColon == 1)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto prefix{ path.substr(0, 2) };
|
||||||
|
return prefix == LR"(//)" || prefix == LR"(\\)";
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function Description:
|
||||||
|
// - DestListLogoUri cannot take paths that are separated by / unless they're URLs.
|
||||||
|
// This function uses std::filesystem to normalize strings that appear to be file
|
||||||
|
// paths to have the "correct" slash direction.
|
||||||
|
static std::wstring _normalizeIconPath(std::wstring_view path)
|
||||||
|
{
|
||||||
|
if (_isProbableFilePath(path))
|
||||||
|
{
|
||||||
|
std::filesystem::path asPath{ path };
|
||||||
|
return asPath.make_preferred().wstring();
|
||||||
|
}
|
||||||
|
return std::wstring{ path };
|
||||||
|
}
|
||||||
|
|
||||||
// Function Description:
|
// Function Description:
|
||||||
// - Helper function for getting the path to the appropriate executable to use
|
// - Helper function for getting the path to the appropriate executable to use
|
||||||
// for this instance of the jumplist. For the dev build, it should be `wtd.exe`,
|
// for this instance of the jumplist. For the dev build, it should be `wtd.exe`,
|
||||||
@@ -83,8 +117,13 @@ static std::wstring_view _getExePath()
|
|||||||
// - settings - The settings object to update the jumplist with.
|
// - settings - The settings object to update the jumplist with.
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - <none>
|
// - <none>
|
||||||
HRESULT Jumplist::UpdateJumplist(const CascadiaSettings& settings) noexcept
|
winrt::fire_and_forget Jumplist::UpdateJumplist(const CascadiaSettings& settings) noexcept
|
||||||
{
|
{
|
||||||
|
// make sure to capture the settings _before_ the co_await
|
||||||
|
const auto strongSettings = settings;
|
||||||
|
|
||||||
|
co_await winrt::resume_background();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
auto jumplistInstance = winrt::create_instance<ICustomDestinationList>(CLSID_DestinationList, CLSCTX_ALL);
|
auto jumplistInstance = winrt::create_instance<ICustomDestinationList>(CLSID_DestinationList, CLSCTX_ALL);
|
||||||
@@ -96,10 +135,10 @@ HRESULT Jumplist::UpdateJumplist(const CascadiaSettings& settings) noexcept
|
|||||||
|
|
||||||
// It's easier to clear the list and re-add everything. The settings aren't
|
// It's easier to clear the list and re-add everything. The settings aren't
|
||||||
// updated often, and there likely isn't a huge amount of items to add.
|
// updated often, and there likely isn't a huge amount of items to add.
|
||||||
RETURN_IF_FAILED(jumplistItems->Clear());
|
THROW_IF_FAILED(jumplistItems->Clear());
|
||||||
|
|
||||||
// Update the list of profiles.
|
// Update the list of profiles.
|
||||||
RETURN_IF_FAILED(_updateProfiles(jumplistItems.get(), settings.Profiles().GetView()));
|
THROW_IF_FAILED(_updateProfiles(jumplistItems.get(), strongSettings.Profiles().GetView()));
|
||||||
|
|
||||||
// TODO GH#1571: Add items from the future customizable new tab dropdown as well.
|
// TODO GH#1571: Add items from the future customizable new tab dropdown as well.
|
||||||
// This could either replace the default profiles, or be added alongside them.
|
// This could either replace the default profiles, or be added alongside them.
|
||||||
@@ -107,13 +146,11 @@ HRESULT Jumplist::UpdateJumplist(const CascadiaSettings& settings) noexcept
|
|||||||
// Add the items to the jumplist Task section.
|
// Add the items to the jumplist Task section.
|
||||||
// The Tasks section is immutable by the user, unlike the destinations
|
// The Tasks section is immutable by the user, unlike the destinations
|
||||||
// section that can have its items pinned and removed.
|
// section that can have its items pinned and removed.
|
||||||
RETURN_IF_FAILED(jumplistInstance->AddUserTasks(jumplistItems.get()));
|
THROW_IF_FAILED(jumplistInstance->AddUserTasks(jumplistItems.get()));
|
||||||
|
|
||||||
RETURN_IF_FAILED(jumplistInstance->CommitList());
|
THROW_IF_FAILED(jumplistInstance->CommitList());
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
}
|
||||||
CATCH_RETURN();
|
CATCH_LOG();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
@@ -134,7 +171,8 @@ HRESULT Jumplist::UpdateJumplist(const CascadiaSettings& settings) noexcept
|
|||||||
|
|
||||||
// Create the shell link object for the profile
|
// Create the shell link object for the profile
|
||||||
winrt::com_ptr<IShellLinkW> shLink;
|
winrt::com_ptr<IShellLinkW> shLink;
|
||||||
RETURN_IF_FAILED(_createShellLink(profile.Name(), profile.ExpandedIconPath(), args, shLink.put()));
|
const auto normalizedIconPath{ _normalizeIconPath(profile.ExpandedIconPath()) };
|
||||||
|
RETURN_IF_FAILED(_createShellLink(profile.Name(), normalizedIconPath, args, shLink.put()));
|
||||||
|
|
||||||
RETURN_IF_FAILED(jumplistItems->AddObject(shLink.get()));
|
RETURN_IF_FAILED(jumplistItems->AddObject(shLink.get()));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ struct IShellLinkW;
|
|||||||
class Jumplist
|
class Jumplist
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static HRESULT UpdateJumplist(const winrt::TerminalApp::CascadiaSettings& settings) noexcept;
|
static winrt::fire_and_forget UpdateJumplist(const winrt::TerminalApp::CascadiaSettings& settings) noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
[[nodiscard]] static HRESULT _updateProfiles(IObjectCollection* jumplistItems, winrt::Windows::Foundation::Collections::IVectorView<winrt::TerminalApp::Profile> profiles) noexcept;
|
[[nodiscard]] static HRESULT _updateProfiles(IObjectCollection* jumplistItems, winrt::Windows::Foundation::Collections::IVectorView<winrt::TerminalApp::Profile> profiles) noexcept;
|
||||||
|
|||||||
@@ -18,5 +18,4 @@ Author(s):
|
|||||||
|
|
||||||
static constexpr std::wstring_view WslGeneratorNamespace{ L"Windows.Terminal.Wsl" };
|
static constexpr std::wstring_view WslGeneratorNamespace{ L"Windows.Terminal.Wsl" };
|
||||||
static constexpr std::wstring_view AzureGeneratorNamespace{ L"Windows.Terminal.Azure" };
|
static constexpr std::wstring_view AzureGeneratorNamespace{ L"Windows.Terminal.Azure" };
|
||||||
static constexpr std::wstring_view TelnetGeneratorNamespace{ L"Windows.Terminal.Telnet" };
|
|
||||||
static constexpr std::wstring_view PowershellCoreGeneratorNamespace{ L"Windows.Terminal.PowershellCore" };
|
static constexpr std::wstring_view PowershellCoreGeneratorNamespace{ L"Windows.Terminal.PowershellCore" };
|
||||||
|
|||||||
@@ -657,6 +657,16 @@ void Pane::_CloseChild(const bool closeFirst)
|
|||||||
if (_lastActive)
|
if (_lastActive)
|
||||||
{
|
{
|
||||||
_control.Focus(FocusState::Programmatic);
|
_control.Focus(FocusState::Programmatic);
|
||||||
|
|
||||||
|
// See GH#7252
|
||||||
|
// Manually fire off the GotFocus event. Typically, this is done
|
||||||
|
// automatically when the control gets focused. However, if we're
|
||||||
|
// `exit`ing a zoomed pane, then the other sibling isn't in the UI
|
||||||
|
// tree currently. So the above call to Focus won't actually focus
|
||||||
|
// the control. Because Tab is relying on GotFocus to know who the
|
||||||
|
// active pane in the tree is, without this call, _no one_ will be
|
||||||
|
// the active pane any longer.
|
||||||
|
_GotFocusHandlers(shared_from_this());
|
||||||
}
|
}
|
||||||
|
|
||||||
_UpdateBorders();
|
_UpdateBorders();
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ namespace winrt::TerminalApp::implementation
|
|||||||
|
|
||||||
GETSET_PROPERTY(hstring, BackgroundImagePath);
|
GETSET_PROPERTY(hstring, BackgroundImagePath);
|
||||||
GETSET_PROPERTY(double, BackgroundImageOpacity, 1.0);
|
GETSET_PROPERTY(double, BackgroundImageOpacity, 1.0);
|
||||||
GETSET_PROPERTY(Windows::UI::Xaml::Media::Stretch, BackgroundImageStretchMode, Windows::UI::Xaml::Media::Stretch::Fill);
|
GETSET_PROPERTY(Windows::UI::Xaml::Media::Stretch, BackgroundImageStretchMode, Windows::UI::Xaml::Media::Stretch::UniformToFill);
|
||||||
|
|
||||||
GETSET_PROPERTY(Microsoft::Terminal::TerminalControl::TextAntialiasingMode, AntialiasingMode, Microsoft::Terminal::TerminalControl::TextAntialiasingMode::Grayscale);
|
GETSET_PROPERTY(Microsoft::Terminal::TerminalControl::TextAntialiasingMode, AntialiasingMode, Microsoft::Terminal::TerminalControl::TextAntialiasingMode::Grayscale);
|
||||||
GETSET_PROPERTY(bool, RetroTerminalEffect, false);
|
GETSET_PROPERTY(bool, RetroTerminalEffect, false);
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<root>
|
<root>
|
||||||
<!--
|
<!--
|
||||||
Microsoft ResX Schema
|
Microsoft ResX Schema
|
||||||
|
|
||||||
Version 2.0
|
Version 2.0
|
||||||
|
|
||||||
The primary goals of this format is to allow a simple XML format
|
The primary goals of this format is to allow a simple XML format
|
||||||
that is mostly human readable. The generation and parsing of the
|
that is mostly human readable. The generation and parsing of the
|
||||||
various data types are done through the TypeConverter classes
|
various data types are done through the TypeConverter classes
|
||||||
associated with the data types.
|
associated with the data types.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
... ado.net/XML headers & schema ...
|
... ado.net/XML headers & schema ...
|
||||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
<resheader name="version">2.0</resheader>
|
<resheader name="version">2.0</resheader>
|
||||||
@@ -26,36 +26,36 @@
|
|||||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
<comment>This is a comment</comment>
|
<comment>This is a comment</comment>
|
||||||
</data>
|
</data>
|
||||||
|
|
||||||
There are any number of "resheader" rows that contain simple
|
There are any number of "resheader" rows that contain simple
|
||||||
name/value pairs.
|
name/value pairs.
|
||||||
|
|
||||||
Each data row contains a name, and value. The row also contains a
|
Each data row contains a name, and value. The row also contains a
|
||||||
type or mimetype. Type corresponds to a .NET class that support
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
text/value conversion through the TypeConverter architecture.
|
text/value conversion through the TypeConverter architecture.
|
||||||
Classes that don't support this are serialized and stored with the
|
Classes that don't support this are serialized and stored with the
|
||||||
mimetype set.
|
mimetype set.
|
||||||
|
|
||||||
The mimetype is used for serialized objects, and tells the
|
The mimetype is used for serialized objects, and tells the
|
||||||
ResXResourceReader how to depersist the object. This is currently not
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
extensible. For a given mimetype the value must be set accordingly:
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
that the ResXResourceWriter will generate, however the reader can
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
read any of the formats listed below.
|
read any of the formats listed below.
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.binary.base64
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
value : The object must be serialized with
|
value : The object must be serialized with
|
||||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
: and then encoded with base64 encoding.
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.soap.base64
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
value : The object must be serialized with
|
value : The object must be serialized with
|
||||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
: and then encoded with base64 encoding.
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
value : The object must be serialized into a byte array
|
value : The object must be serialized into a byte array
|
||||||
: using a System.ComponentModel.TypeConverter
|
: using a System.ComponentModel.TypeConverter
|
||||||
: and then encoded with base64 encoding.
|
: and then encoded with base64 encoding.
|
||||||
-->
|
-->
|
||||||
@@ -149,6 +149,16 @@
|
|||||||
<data name="SettingsValidateErrorTitle" xml:space="preserve">
|
<data name="SettingsValidateErrorTitle" xml:space="preserve">
|
||||||
<value>Encountered errors while loading user settings</value>
|
<value>Encountered errors while loading user settings</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="KeyboardServiceDisabledDialog.PrimaryButtonText" xml:space="preserve">
|
||||||
|
<value>OK</value>
|
||||||
|
</data>
|
||||||
|
<data name="KeyboardServiceDisabledDialog.Title" xml:space="preserve">
|
||||||
|
<value>Warning:</value>
|
||||||
|
</data>
|
||||||
|
<data name="KeyboardServiceWarningText" xml:space="preserve">
|
||||||
|
<value>The "{0}" isn't running on your machine. This can prevent the Terminal from receiving keyboard input.</value>
|
||||||
|
<comment>{0} will be replaced with the OS-localized name of the TabletInputService</comment>
|
||||||
|
</data>
|
||||||
<data name="Ok" xml:space="preserve">
|
<data name="Ok" xml:space="preserve">
|
||||||
<value>OK</value>
|
<value>OK</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -291,8 +301,11 @@
|
|||||||
<data name="NewTabSplitButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
<data name="NewTabSplitButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||||
<value>New Tab</value>
|
<value>New Tab</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="NewTabSplitButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
<data name="NewTabRun.Text" xml:space="preserve">
|
||||||
<value>New Tab</value>
|
<value>Open a new tab</value>
|
||||||
|
</data>
|
||||||
|
<data name="NewPaneRun.Text" xml:space="preserve">
|
||||||
|
<value>Alt+Click to split the current window</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="WindowCloseButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
<data name="WindowCloseButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||||
<value>Close</value>
|
<value>Close</value>
|
||||||
@@ -661,4 +674,7 @@
|
|||||||
<data name="CouldNotOpenUriDialog.PrimaryButtonText" xml:space="preserve">
|
<data name="CouldNotOpenUriDialog.PrimaryButtonText" xml:space="preserve">
|
||||||
<value>Cancel</value>
|
<value>Cancel</value>
|
||||||
</data>
|
</data>
|
||||||
</root>
|
<data name="FailedToWriteToSettings" xml:space="preserve">
|
||||||
|
<value>We could not write to your settings file. Check the permissions on that file to ensure that the read-only flag is not set and that write access is granted.</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
#include "Tab.g.cpp"
|
#include "Tab.g.cpp"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
#include "ColorHelper.h"
|
#include "ColorHelper.h"
|
||||||
|
#include "ActionAndArgs.h"
|
||||||
|
#include "ActionArgs.h"
|
||||||
|
|
||||||
using namespace winrt;
|
using namespace winrt;
|
||||||
using namespace winrt::Windows::UI::Xaml;
|
using namespace winrt::Windows::UI::Xaml;
|
||||||
@@ -32,8 +34,10 @@ namespace winrt::TerminalApp::implementation
|
|||||||
});
|
});
|
||||||
|
|
||||||
_activePane = _rootPane;
|
_activePane = _rootPane;
|
||||||
|
Content(_rootPane->GetRootElement());
|
||||||
|
|
||||||
_MakeTabViewItem();
|
_MakeTabViewItem();
|
||||||
|
_MakeSwitchToTabCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
@@ -58,24 +62,6 @@ namespace winrt::TerminalApp::implementation
|
|||||||
_RecalculateAndApplyTabColor();
|
_RecalculateAndApplyTabColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
|
||||||
// - Get the root UIElement of this Tab's root pane.
|
|
||||||
// Arguments:
|
|
||||||
// - <none>
|
|
||||||
// Return Value:
|
|
||||||
// - The UIElement acting as root of the Tab's root pane.
|
|
||||||
UIElement Tab::GetRootElement()
|
|
||||||
{
|
|
||||||
if (_zoomedPane)
|
|
||||||
{
|
|
||||||
return _zoomedPane->GetRootElement();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return _rootPane->GetRootElement();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - Returns nullptr if no children of this tab were the last control to be
|
// - Returns nullptr if no children of this tab were the last control to be
|
||||||
// focused, or the TermControl that _was_ the last control to be focused (if
|
// focused, or the TermControl that _was_ the last control to be focused (if
|
||||||
@@ -229,6 +215,9 @@ namespace winrt::TerminalApp::implementation
|
|||||||
// The TabViewItem Icon needs MUX while the IconSourceElement in the CommandPalette needs WUX...
|
// The TabViewItem Icon needs MUX while the IconSourceElement in the CommandPalette needs WUX...
|
||||||
IconSource(GetColoredIcon<winrt::WUX::Controls::IconSource>(_lastIconPath));
|
IconSource(GetColoredIcon<winrt::WUX::Controls::IconSource>(_lastIconPath));
|
||||||
_tabViewItem.IconSource(GetColoredIcon<winrt::MUX::Controls::IconSource>(_lastIconPath));
|
_tabViewItem.IconSource(GetColoredIcon<winrt::MUX::Controls::IconSource>(_lastIconPath));
|
||||||
|
|
||||||
|
// Update SwitchToTab command's icon
|
||||||
|
SwitchToTabCommand().IconSource(IconSource());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,6 +255,9 @@ namespace winrt::TerminalApp::implementation
|
|||||||
// Bubble our current tab text to anyone who's listening for changes.
|
// Bubble our current tab text to anyone who's listening for changes.
|
||||||
Title(GetActiveTitle());
|
Title(GetActiveTitle());
|
||||||
|
|
||||||
|
// Update SwitchToTab command's name
|
||||||
|
SwitchToTabCommand().Name(Title());
|
||||||
|
|
||||||
// Update the UI to reflect the changed
|
// Update the UI to reflect the changed
|
||||||
_UpdateTabHeader();
|
_UpdateTabHeader();
|
||||||
}
|
}
|
||||||
@@ -502,6 +494,22 @@ namespace winrt::TerminalApp::implementation
|
|||||||
tab->_RecalculateAndApplyTabColor();
|
tab->_RecalculateAndApplyTabColor();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Add a Closed event handler to the Pane. If the pane closes out from
|
||||||
|
// underneath us, and it's zoomed, we want to be able to make sure to
|
||||||
|
// update our state accordingly to un-zoom that pane. See GH#7252.
|
||||||
|
pane->Closed([weakThis](auto&& /*s*/, auto && /*e*/) -> winrt::fire_and_forget {
|
||||||
|
if (auto tab{ weakThis.get() })
|
||||||
|
{
|
||||||
|
if (tab->_zoomedPane)
|
||||||
|
{
|
||||||
|
co_await winrt::resume_foreground(tab->Content().Dispatcher());
|
||||||
|
|
||||||
|
tab->Content(tab->_rootPane->GetRootElement());
|
||||||
|
tab->ExitZoom();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
@@ -1012,6 +1020,7 @@ namespace winrt::TerminalApp::implementation
|
|||||||
_rootPane->Maximize(_zoomedPane);
|
_rootPane->Maximize(_zoomedPane);
|
||||||
// Update the tab header to show the magnifying glass
|
// Update the tab header to show the magnifying glass
|
||||||
_UpdateTabHeader();
|
_UpdateTabHeader();
|
||||||
|
Content(_zoomedPane->GetRootElement());
|
||||||
}
|
}
|
||||||
void Tab::ExitZoom()
|
void Tab::ExitZoom()
|
||||||
{
|
{
|
||||||
@@ -1019,6 +1028,7 @@ namespace winrt::TerminalApp::implementation
|
|||||||
_zoomedPane = nullptr;
|
_zoomedPane = nullptr;
|
||||||
// Update the tab header to hide the magnifying glass
|
// Update the tab header to hide the magnifying glass
|
||||||
_UpdateTabHeader();
|
_UpdateTabHeader();
|
||||||
|
Content(_rootPane->GetRootElement());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Tab::IsZoomed()
|
bool Tab::IsZoomed()
|
||||||
@@ -1026,6 +1036,35 @@ namespace winrt::TerminalApp::implementation
|
|||||||
return _zoomedPane != nullptr;
|
return _zoomedPane != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Method Description:
|
||||||
|
// - Initializes a SwitchToTab command object for this Tab instance.
|
||||||
|
// Arguments:
|
||||||
|
// - <none>
|
||||||
|
// Return Value:
|
||||||
|
// - <none>
|
||||||
|
void Tab::_MakeSwitchToTabCommand()
|
||||||
|
{
|
||||||
|
auto focusTabAction = winrt::make_self<implementation::ActionAndArgs>();
|
||||||
|
auto args = winrt::make_self<implementation::SwitchToTabArgs>();
|
||||||
|
args->TabIndex(_TabViewIndex);
|
||||||
|
|
||||||
|
focusTabAction->Action(ShortcutAction::SwitchToTab);
|
||||||
|
focusTabAction->Args(*args);
|
||||||
|
|
||||||
|
winrt::TerminalApp::Command command;
|
||||||
|
command.Action(*focusTabAction);
|
||||||
|
command.Name(Title());
|
||||||
|
command.IconSource(IconSource());
|
||||||
|
|
||||||
|
SwitchToTabCommand(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tab::UpdateTabViewIndex(const uint32_t idx)
|
||||||
|
{
|
||||||
|
TabViewIndex(idx);
|
||||||
|
SwitchToTabCommand().Action().Args().as<implementation::SwitchToTabArgs>()->TabIndex(idx);
|
||||||
|
}
|
||||||
|
|
||||||
DEFINE_EVENT(Tab, ActivePaneChanged, _ActivePaneChangedHandlers, winrt::delegate<>);
|
DEFINE_EVENT(Tab, ActivePaneChanged, _ActivePaneChangedHandlers, winrt::delegate<>);
|
||||||
DEFINE_EVENT(Tab, ColorSelected, _colorSelected, winrt::delegate<winrt::Windows::UI::Color>);
|
DEFINE_EVENT(Tab, ColorSelected, _colorSelected, winrt::delegate<winrt::Windows::UI::Color>);
|
||||||
DEFINE_EVENT(Tab, ColorCleared, _colorCleared, winrt::delegate<>);
|
DEFINE_EVENT(Tab, ColorCleared, _colorCleared, winrt::delegate<>);
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ namespace winrt::TerminalApp::implementation
|
|||||||
void Initialize(const winrt::Microsoft::Terminal::TerminalControl::TermControl& control);
|
void Initialize(const winrt::Microsoft::Terminal::TerminalControl::TermControl& control);
|
||||||
|
|
||||||
winrt::Microsoft::UI::Xaml::Controls::TabViewItem GetTabViewItem();
|
winrt::Microsoft::UI::Xaml::Controls::TabViewItem GetTabViewItem();
|
||||||
winrt::Windows::UI::Xaml::UIElement GetRootElement();
|
|
||||||
winrt::Microsoft::Terminal::TerminalControl::TermControl GetActiveTerminalControl() const;
|
winrt::Microsoft::Terminal::TerminalControl::TermControl GetActiveTerminalControl() const;
|
||||||
std::optional<GUID> GetFocusedProfile() const noexcept;
|
std::optional<GUID> GetFocusedProfile() const noexcept;
|
||||||
|
|
||||||
@@ -68,6 +67,8 @@ namespace winrt::TerminalApp::implementation
|
|||||||
|
|
||||||
int GetLeafPaneCount() const noexcept;
|
int GetLeafPaneCount() const noexcept;
|
||||||
|
|
||||||
|
void UpdateTabViewIndex(const uint32_t idx);
|
||||||
|
|
||||||
WINRT_CALLBACK(Closed, winrt::Windows::Foundation::EventHandler<winrt::Windows::Foundation::IInspectable>);
|
WINRT_CALLBACK(Closed, winrt::Windows::Foundation::EventHandler<winrt::Windows::Foundation::IInspectable>);
|
||||||
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
|
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
|
||||||
DECLARE_EVENT(ActivePaneChanged, _ActivePaneChangedHandlers, winrt::delegate<>);
|
DECLARE_EVENT(ActivePaneChanged, _ActivePaneChangedHandlers, winrt::delegate<>);
|
||||||
@@ -76,6 +77,13 @@ namespace winrt::TerminalApp::implementation
|
|||||||
|
|
||||||
OBSERVABLE_GETSET_PROPERTY(winrt::hstring, Title, _PropertyChangedHandlers);
|
OBSERVABLE_GETSET_PROPERTY(winrt::hstring, Title, _PropertyChangedHandlers);
|
||||||
OBSERVABLE_GETSET_PROPERTY(winrt::Windows::UI::Xaml::Controls::IconSource, IconSource, _PropertyChangedHandlers, nullptr);
|
OBSERVABLE_GETSET_PROPERTY(winrt::Windows::UI::Xaml::Controls::IconSource, IconSource, _PropertyChangedHandlers, nullptr);
|
||||||
|
OBSERVABLE_GETSET_PROPERTY(winrt::TerminalApp::Command, SwitchToTabCommand, _PropertyChangedHandlers, nullptr);
|
||||||
|
|
||||||
|
// The TabViewIndex is the index this Tab object resides in TerminalPage's _tabs vector.
|
||||||
|
// This is needed since Tab is going to be managing its own SwitchToTab command.
|
||||||
|
OBSERVABLE_GETSET_PROPERTY(uint32_t, TabViewIndex, _PropertyChangedHandlers, 0);
|
||||||
|
|
||||||
|
OBSERVABLE_GETSET_PROPERTY(winrt::Windows::UI::Xaml::UIElement, Content, _PropertyChangedHandlers, nullptr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<Pane> _rootPane{ nullptr };
|
std::shared_ptr<Pane> _rootPane{ nullptr };
|
||||||
@@ -114,6 +122,8 @@ namespace winrt::TerminalApp::implementation
|
|||||||
void _ApplyTabColor(const winrt::Windows::UI::Color& color);
|
void _ApplyTabColor(const winrt::Windows::UI::Color& color);
|
||||||
void _ClearTabBackgroundColor();
|
void _ClearTabBackgroundColor();
|
||||||
|
|
||||||
|
void _MakeSwitchToTabCommand();
|
||||||
|
|
||||||
friend class ::TerminalAppLocalTests::TabTests;
|
friend class ::TerminalAppLocalTests::TabTests;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
// Copyright (c) Microsoft Corporation.
|
// Copyright (c) Microsoft Corporation.
|
||||||
// Licensed under the MIT license.
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
import "Command.idl";
|
||||||
|
|
||||||
namespace TerminalApp
|
namespace TerminalApp
|
||||||
{
|
{
|
||||||
[default_interface] runtimeclass Tab : Windows.UI.Xaml.Data.INotifyPropertyChanged
|
[default_interface] runtimeclass Tab : Windows.UI.Xaml.Data.INotifyPropertyChanged
|
||||||
{
|
{
|
||||||
String Title { get; };
|
String Title { get; };
|
||||||
Windows.UI.Xaml.Controls.IconSource IconSource { get; };
|
Windows.UI.Xaml.Controls.IconSource IconSource { get; };
|
||||||
|
Windows.UI.Xaml.UIElement Content { get; };
|
||||||
|
Command SwitchToTabCommand { get; };
|
||||||
|
UInt32 TabViewIndex { get; };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,16 @@ the MIT License. See LICENSE in the project root for license information. -->
|
|||||||
BorderThickness="0"
|
BorderThickness="0"
|
||||||
CornerRadius="{Binding Source={ThemeResource OverlayCornerRadius}, Converter={StaticResource TopCornerRadiusFilterConverter}}"
|
CornerRadius="{Binding Source={ThemeResource OverlayCornerRadius}, Converter={StaticResource TopCornerRadiusFilterConverter}}"
|
||||||
AutomationProperties.AccessibilityView="Control">
|
AutomationProperties.AccessibilityView="Control">
|
||||||
|
<ToolTipService.ToolTip>
|
||||||
|
<ToolTip Placement="Mouse">
|
||||||
|
<TextBlock IsTextSelectionEnabled="False">
|
||||||
|
<Run x:Uid="NewTabRun"/> <LineBreak />
|
||||||
|
<Run x:Uid="NewPaneRun"
|
||||||
|
FontStyle="Italic">
|
||||||
|
</Run>
|
||||||
|
</TextBlock>
|
||||||
|
</ToolTip>
|
||||||
|
</ToolTipService.ToolTip>
|
||||||
<!-- U+E710 is the fancy plus icon. -->
|
<!-- U+E710 is the fancy plus icon. -->
|
||||||
<mux:SplitButton.Resources>
|
<mux:SplitButton.Resources>
|
||||||
<!-- Override the SplitButton* resources to match the tab view's button's styles. -->
|
<!-- Override the SplitButton* resources to match the tab view's button's styles. -->
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
/*++
|
|
||||||
Copyright (c) Microsoft Corporation
|
|
||||||
Licensed under the MIT license.
|
|
||||||
|
|
||||||
Module Name:
|
|
||||||
- TelnetGenerator
|
|
||||||
|
|
||||||
Abstract:
|
|
||||||
- Information needed to detect a Telnet connection type.
|
|
||||||
|
|
||||||
Author(s):
|
|
||||||
- Michael Niksa - 2019-12-05
|
|
||||||
|
|
||||||
--*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
// {311153fb-d3f0-4ac6-b920-038de7cf5289}
|
|
||||||
static constexpr winrt::guid TelnetConnectionType = { 0x311153fb, 0xd3f0, 0x4ac6, { 0xb9, 0x20, 0x03, 0x8d, 0xe7, 0xcf, 0x52, 0x89 } };
|
|
||||||
@@ -129,7 +129,6 @@
|
|||||||
<ClInclude Include="PowershellCoreProfileGenerator.h" />
|
<ClInclude Include="PowershellCoreProfileGenerator.h" />
|
||||||
<ClInclude Include="WslDistroGenerator.h" />
|
<ClInclude Include="WslDistroGenerator.h" />
|
||||||
<ClInclude Include="AzureCloudShellGenerator.h" />
|
<ClInclude Include="AzureCloudShellGenerator.h" />
|
||||||
<ClInclude Include="TelnetGenerator.h" />
|
|
||||||
<ClInclude Include="ColorHelper.h" />
|
<ClInclude Include="ColorHelper.h" />
|
||||||
<ClInclude Include="TerminalSettings.h">
|
<ClInclude Include="TerminalSettings.h">
|
||||||
<DependentUpon>TerminalSettings.idl</DependentUpon>
|
<DependentUpon>TerminalSettings.idl</DependentUpon>
|
||||||
|
|||||||
@@ -117,9 +117,6 @@
|
|||||||
<ClInclude Include="Commandline.h" />
|
<ClInclude Include="Commandline.h" />
|
||||||
<ClInclude Include="DebugTapConnection.h" />
|
<ClInclude Include="DebugTapConnection.h" />
|
||||||
<ClInclude Include="ColorHelper.h" />
|
<ClInclude Include="ColorHelper.h" />
|
||||||
<ClInclude Include="TelnetGenerator.h">
|
|
||||||
<Filter>profileGeneration</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="TerminalSettings.h">
|
<ClInclude Include="TerminalSettings.h">
|
||||||
<Filter>settings</Filter>
|
<Filter>settings</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
#include "KeyChordSerialization.h"
|
#include "KeyChordSerialization.h"
|
||||||
#include "AzureCloudShellGenerator.h" // For AzureConnectionType
|
#include "AzureCloudShellGenerator.h" // For AzureConnectionType
|
||||||
#include "TelnetGenerator.h" // For TelnetConnectionType
|
|
||||||
#include "TabRowControl.h"
|
#include "TabRowControl.h"
|
||||||
#include "ColorHelper.h"
|
#include "ColorHelper.h"
|
||||||
#include "DebugTapConnection.h"
|
#include "DebugTapConnection.h"
|
||||||
@@ -46,6 +45,7 @@ namespace winrt::TerminalApp::implementation
|
|||||||
{
|
{
|
||||||
TerminalPage::TerminalPage() :
|
TerminalPage::TerminalPage() :
|
||||||
_tabs{ winrt::single_threaded_observable_vector<TerminalApp::Tab>() },
|
_tabs{ winrt::single_threaded_observable_vector<TerminalApp::Tab>() },
|
||||||
|
_mruTabActions{ winrt::single_threaded_vector<winrt::TerminalApp::Command>() },
|
||||||
_startupActions{ winrt::single_threaded_vector<winrt::TerminalApp::ActionAndArgs>() }
|
_startupActions{ winrt::single_threaded_vector<winrt::TerminalApp::ActionAndArgs>() }
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
@@ -166,6 +166,7 @@ namespace winrt::TerminalApp::implementation
|
|||||||
auto tab = tabs.GetAt(from.value());
|
auto tab = tabs.GetAt(from.value());
|
||||||
tabs.RemoveAt(from.value());
|
tabs.RemoveAt(from.value());
|
||||||
tabs.InsertAt(to.value(), tab);
|
tabs.InsertAt(to.value(), tab);
|
||||||
|
page->_UpdateTabIndices();
|
||||||
}
|
}
|
||||||
|
|
||||||
page->_rearranging = false;
|
page->_rearranging = false;
|
||||||
@@ -243,19 +244,14 @@ namespace winrt::TerminalApp::implementation
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
_tabs.VectorChanged([weakThis{ get_weak() }](auto&& s, auto&& e) {
|
|
||||||
if (auto page{ weakThis.get() })
|
|
||||||
{
|
|
||||||
page->CommandPalette().OnTabsChanged(s, e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Once the page is actually laid out on the screen, trigger all our
|
// Once the page is actually laid out on the screen, trigger all our
|
||||||
// startup actions. Things like Panes need to know at least how big the
|
// startup actions. Things like Panes need to know at least how big the
|
||||||
// window will be, so they can subdivide that space.
|
// window will be, so they can subdivide that space.
|
||||||
//
|
//
|
||||||
// _OnFirstLayout will remove this handler so it doesn't get called more than once.
|
// _OnFirstLayout will remove this handler so it doesn't get called more than once.
|
||||||
_layoutUpdatedRevoker = _tabContent.LayoutUpdated(winrt::auto_revoke, { this, &TerminalPage::_OnFirstLayout });
|
_layoutUpdatedRevoker = _tabContent.LayoutUpdated(winrt::auto_revoke, { this, &TerminalPage::_OnFirstLayout });
|
||||||
|
|
||||||
|
_isAlwaysOnTop = _settings.GlobalSettings().AlwaysOnTop();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
@@ -497,6 +493,21 @@ namespace winrt::TerminalApp::implementation
|
|||||||
profileMenuItem.FontWeight(FontWeights::Bold());
|
profileMenuItem.FontWeight(FontWeights::Bold());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto newTabRun = WUX::Documents::Run();
|
||||||
|
newTabRun.Text(RS_(L"NewTabRun/Text"));
|
||||||
|
auto newPaneRun = WUX::Documents::Run();
|
||||||
|
newPaneRun.Text(RS_(L"NewPaneRun/Text"));
|
||||||
|
newPaneRun.FontStyle(FontStyle::Italic);
|
||||||
|
|
||||||
|
auto textBlock = WUX::Controls::TextBlock{};
|
||||||
|
textBlock.Inlines().Append(newTabRun);
|
||||||
|
textBlock.Inlines().Append(WUX::Documents::LineBreak{});
|
||||||
|
textBlock.Inlines().Append(newPaneRun);
|
||||||
|
|
||||||
|
auto toolTip = WUX::Controls::ToolTip{};
|
||||||
|
toolTip.Content(textBlock);
|
||||||
|
WUX::Controls::ToolTipService::SetToolTip(profileMenuItem, toolTip);
|
||||||
|
|
||||||
profileMenuItem.Click([profileIndex, weakThis{ get_weak() }](auto&&, auto&&) {
|
profileMenuItem.Click([profileIndex, weakThis{ get_weak() }](auto&&, auto&&) {
|
||||||
if (auto page{ weakThis.get() })
|
if (auto page{ weakThis.get() })
|
||||||
{
|
{
|
||||||
@@ -686,6 +697,10 @@ namespace winrt::TerminalApp::implementation
|
|||||||
// Add the new tab to the list of our tabs.
|
// Add the new tab to the list of our tabs.
|
||||||
auto newTabImpl = winrt::make_self<Tab>(profileGuid, term);
|
auto newTabImpl = winrt::make_self<Tab>(profileGuid, term);
|
||||||
_tabs.Append(*newTabImpl);
|
_tabs.Append(*newTabImpl);
|
||||||
|
_mruTabActions.Append(newTabImpl->SwitchToTabCommand());
|
||||||
|
|
||||||
|
// Give the tab its index in the _tabs vector so it can manage its own SwitchToTab command.
|
||||||
|
newTabImpl->UpdateTabViewIndex(_tabs.Size() - 1);
|
||||||
|
|
||||||
// Hookup our event handlers to the new terminal
|
// Hookup our event handlers to the new terminal
|
||||||
_RegisterTerminalEvents(term, *newTabImpl);
|
_RegisterTerminalEvents(term, *newTabImpl);
|
||||||
@@ -792,12 +807,6 @@ namespace winrt::TerminalApp::implementation
|
|||||||
winrt::guid());
|
winrt::guid());
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (hasConnectionType &&
|
|
||||||
connectionType == TelnetConnectionType)
|
|
||||||
{
|
|
||||||
connection = TerminalConnection::TelnetConnection(settings.Commandline());
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::wstring guidWString = Utils::GuidToString(profileGuid);
|
std::wstring guidWString = Utils::GuidToString(profileGuid);
|
||||||
@@ -1064,8 +1073,16 @@ namespace winrt::TerminalApp::implementation
|
|||||||
auto tab{ _GetStrongTabImpl(tabIndex) };
|
auto tab{ _GetStrongTabImpl(tabIndex) };
|
||||||
tab->Shutdown();
|
tab->Shutdown();
|
||||||
|
|
||||||
|
uint32_t mruIndex;
|
||||||
|
if (_mruTabActions.IndexOf(_tabs.GetAt(tabIndex).SwitchToTabCommand(), mruIndex))
|
||||||
|
{
|
||||||
|
_mruTabActions.RemoveAt(mruIndex);
|
||||||
|
CommandPalette().SetTabActions(_mruTabActions);
|
||||||
|
}
|
||||||
|
|
||||||
_tabs.RemoveAt(tabIndex);
|
_tabs.RemoveAt(tabIndex);
|
||||||
_tabView.TabItems().RemoveAt(tabIndex);
|
_tabView.TabItems().RemoveAt(tabIndex);
|
||||||
|
_UpdateTabIndices();
|
||||||
|
|
||||||
// To close the window here, we need to close the hosting window.
|
// To close the window here, we need to close the hosting window.
|
||||||
if (_tabs.Size() == 0)
|
if (_tabs.Size() == 0)
|
||||||
@@ -1155,6 +1172,16 @@ namespace winrt::TerminalApp::implementation
|
|||||||
{
|
{
|
||||||
page->_UpdateTitle(*tab);
|
page->_UpdateTitle(*tab);
|
||||||
}
|
}
|
||||||
|
else if (args.PropertyName() == L"Content")
|
||||||
|
{
|
||||||
|
if (tab == page->_GetFocusedTab())
|
||||||
|
{
|
||||||
|
page->_tabContent.Children().Clear();
|
||||||
|
page->_tabContent.Children().Append(tab->Content());
|
||||||
|
|
||||||
|
tab->SetFocused(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1191,28 +1218,36 @@ namespace winrt::TerminalApp::implementation
|
|||||||
// - Sets focus to the tab to the right or left the currently selected tab.
|
// - Sets focus to the tab to the right or left the currently selected tab.
|
||||||
void TerminalPage::_SelectNextTab(const bool bMoveRight)
|
void TerminalPage::_SelectNextTab(const bool bMoveRight)
|
||||||
{
|
{
|
||||||
if (auto index{ _GetFocusedTabIndex() })
|
if (CommandPalette().Visibility() == Visibility::Visible)
|
||||||
|
{
|
||||||
|
// If the tab switcher is currently open, don't change its mode.
|
||||||
|
// Just select the new tab.
|
||||||
|
CommandPalette().SelectNextItem(bMoveRight);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_settings.GlobalSettings().UseTabSwitcher())
|
||||||
|
{
|
||||||
|
CommandPalette().SetTabActions(_mruTabActions);
|
||||||
|
|
||||||
|
// Since ATS is always MRU, our focused tab index is always 0.
|
||||||
|
// So, going next should go to index 1, and going prev should wrap to the end.
|
||||||
|
uint32_t tabCount = _mruTabActions.Size();
|
||||||
|
auto newTabIndex = ((tabCount + (bMoveRight ? 1 : -1)) % tabCount);
|
||||||
|
|
||||||
|
// Otherwise, set up the tab switcher in the selected mode, with
|
||||||
|
// the given ordering, and make it visible.
|
||||||
|
CommandPalette().EnableTabSwitcherMode(false, newTabIndex);
|
||||||
|
CommandPalette().Visibility(Visibility::Visible);
|
||||||
|
}
|
||||||
|
else if (auto index{ _GetFocusedTabIndex() })
|
||||||
{
|
{
|
||||||
uint32_t tabCount = _tabs.Size();
|
uint32_t tabCount = _tabs.Size();
|
||||||
// Wraparound math. By adding tabCount and then calculating modulo tabCount,
|
// Wraparound math. By adding tabCount and then calculating modulo tabCount,
|
||||||
// we clamp the values to the range [0, tabCount) while still supporting moving
|
// we clamp the values to the range [0, tabCount) while still supporting moving
|
||||||
// leftward from 0 to tabCount - 1.
|
// leftward from 0 to tabCount - 1.
|
||||||
const auto newTabIndex = ((tabCount + *index + (bMoveRight ? 1 : -1)) % tabCount);
|
auto newTabIndex = ((tabCount + *index + (bMoveRight ? 1 : -1)) % tabCount);
|
||||||
|
_SelectTab(newTabIndex);
|
||||||
if (_settings.GlobalSettings().UseTabSwitcher())
|
|
||||||
{
|
|
||||||
if (CommandPalette().Visibility() == Visibility::Visible)
|
|
||||||
{
|
|
||||||
CommandPalette().SelectNextItem(bMoveRight);
|
|
||||||
}
|
|
||||||
|
|
||||||
CommandPalette().EnableTabSwitcherMode(false, newTabIndex);
|
|
||||||
CommandPalette().Visibility(Visibility::Visible);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_SelectTab(newTabIndex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1267,9 +1302,10 @@ namespace winrt::TerminalApp::implementation
|
|||||||
// Remove the content from the tab first, so Pane::UnZoom can
|
// Remove the content from the tab first, so Pane::UnZoom can
|
||||||
// re-attach the content to the tree w/in the pane
|
// re-attach the content to the tree w/in the pane
|
||||||
_tabContent.Children().Clear();
|
_tabContent.Children().Clear();
|
||||||
|
// In ExitZoom, we'll change the Tab's Content(), triggering the
|
||||||
|
// content changed event, which will re-attach the tab's new content
|
||||||
|
// root to the tree.
|
||||||
activeTab->ExitZoom();
|
activeTab->ExitZoom();
|
||||||
// Re-attach the tab's content to the UI tree.
|
|
||||||
_tabContent.Children().Append(activeTab->GetRootElement());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1387,8 +1423,9 @@ namespace winrt::TerminalApp::implementation
|
|||||||
// than one tab opened, show a warning dialog.
|
// than one tab opened, show a warning dialog.
|
||||||
void TerminalPage::CloseWindow()
|
void TerminalPage::CloseWindow()
|
||||||
{
|
{
|
||||||
if (_tabs.Size() > 1 && _settings.GlobalSettings().ConfirmCloseAllTabs())
|
if (_tabs.Size() > 1 && _settings.GlobalSettings().ConfirmCloseAllTabs() && !_displayingCloseDialog)
|
||||||
{
|
{
|
||||||
|
_displayingCloseDialog = true;
|
||||||
_ShowCloseWarningDialog();
|
_ShowCloseWarningDialog();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1918,10 +1955,6 @@ namespace winrt::TerminalApp::implementation
|
|||||||
_rearrangeTo = eventArgs.Index();
|
_rearrangeTo = eventArgs.Index();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
_UpdateCommandsForPalette();
|
|
||||||
}
|
|
||||||
|
|
||||||
_UpdateTabView();
|
_UpdateTabView();
|
||||||
}
|
}
|
||||||
@@ -1960,9 +1993,23 @@ namespace winrt::TerminalApp::implementation
|
|||||||
auto tab{ _GetStrongTabImpl(index) };
|
auto tab{ _GetStrongTabImpl(index) };
|
||||||
|
|
||||||
_tabContent.Children().Clear();
|
_tabContent.Children().Clear();
|
||||||
_tabContent.Children().Append(tab->GetRootElement());
|
_tabContent.Children().Append(tab->Content());
|
||||||
|
|
||||||
tab->SetFocused(true);
|
// GH#7409: If the tab switcher is open, then we _don't_ want to
|
||||||
|
// automatically focus the new tab here. The tab switcher wants
|
||||||
|
// to be able to "preview" the selected tab as the user tabs
|
||||||
|
// through the menu, but if we toss the focus to the control
|
||||||
|
// here, then the user won't be able to navigate the ATS any
|
||||||
|
// longer.
|
||||||
|
//
|
||||||
|
// When the tab swither is eventually dismissed, the focus will
|
||||||
|
// get tossed back to the focused terminal control, so we don't
|
||||||
|
// need to worry about focus getting lost.
|
||||||
|
if (CommandPalette().Visibility() != Visibility::Visible)
|
||||||
|
{
|
||||||
|
tab->SetFocused(true);
|
||||||
|
_UpdateMRUTab(index);
|
||||||
|
}
|
||||||
|
|
||||||
// Raise an event that our title changed
|
// Raise an event that our title changed
|
||||||
_titleChangeHandlers(*this, tab->GetActiveTitle());
|
_titleChangeHandlers(*this, tab->GetActiveTitle());
|
||||||
@@ -2033,6 +2080,20 @@ namespace winrt::TerminalApp::implementation
|
|||||||
_CloseAllTabs();
|
_CloseAllTabs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Method Description:
|
||||||
|
// - Called when the close button of the content dialog is clicked.
|
||||||
|
// This resets the flag _displayingCloseDialog, which was set before
|
||||||
|
// opening the dialog. Otherwise, the Terminal app would be closed
|
||||||
|
// on the next close request without showing the warning dialog.
|
||||||
|
// Arguments:
|
||||||
|
// - sender: unused
|
||||||
|
// - ContentDialogButtonClickEventArgs: unused
|
||||||
|
void TerminalPage::_CloseWarningCloseButtonOnClick(WUX::Controls::ContentDialog /* sender */,
|
||||||
|
WUX::Controls::ContentDialogButtonClickEventArgs /* eventArgs*/)
|
||||||
|
{
|
||||||
|
_displayingCloseDialog = false;
|
||||||
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - Hook up keybindings, and refresh the UI of the terminal.
|
// - Hook up keybindings, and refresh the UI of the terminal.
|
||||||
// This includes update the settings of all the tabs according
|
// This includes update the settings of all the tabs according
|
||||||
@@ -2209,6 +2270,15 @@ namespace winrt::TerminalApp::implementation
|
|||||||
{
|
{
|
||||||
_newTabButton.Flyout().Hide();
|
_newTabButton.Flyout().Hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const auto& tab : _tabs)
|
||||||
|
{
|
||||||
|
auto tabImpl{ _GetStrongTabImpl(tab) };
|
||||||
|
if (tabImpl->GetTabViewItem().ContextFlyout())
|
||||||
|
{
|
||||||
|
tabImpl->GetTabViewItem().ContextFlyout().Hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
@@ -2493,6 +2563,7 @@ namespace winrt::TerminalApp::implementation
|
|||||||
if (auto index{ _GetFocusedTabIndex() })
|
if (auto index{ _GetFocusedTabIndex() })
|
||||||
{
|
{
|
||||||
_GetStrongTabImpl(index.value())->SetFocused(true);
|
_GetStrongTabImpl(index.value())->SetFocused(true);
|
||||||
|
_UpdateMRUTab(index.value());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2519,6 +2590,109 @@ namespace winrt::TerminalApp::implementation
|
|||||||
return _isAlwaysOnTop;
|
return _isAlwaysOnTop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Method Description:
|
||||||
|
// - Updates all tabs with their current index in _tabs.
|
||||||
|
// Arguments:
|
||||||
|
// - <none>
|
||||||
|
// Return Value:
|
||||||
|
// - <none>
|
||||||
|
void TerminalPage::_UpdateTabIndices()
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < _tabs.Size(); ++i)
|
||||||
|
{
|
||||||
|
_GetStrongTabImpl(i)->UpdateTabViewIndex(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method Description:
|
||||||
|
// - Bumps the tab in its in-order index up to the top of the mru list.
|
||||||
|
// Arguments:
|
||||||
|
// - index: the in-order index of the tab to bump.
|
||||||
|
// Return Value:
|
||||||
|
// - <none>
|
||||||
|
void TerminalPage::_UpdateMRUTab(const uint32_t index)
|
||||||
|
{
|
||||||
|
uint32_t mruIndex;
|
||||||
|
auto command = _tabs.GetAt(index).SwitchToTabCommand();
|
||||||
|
if (_mruTabActions.IndexOf(command, mruIndex))
|
||||||
|
{
|
||||||
|
if (mruIndex > 0)
|
||||||
|
{
|
||||||
|
_mruTabActions.RemoveAt(mruIndex);
|
||||||
|
_mruTabActions.InsertAt(0, command);
|
||||||
|
CommandPalette().SetTabActions(_mruTabActions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method Description:
|
||||||
|
// - Displays a dialog stating the "Touch Keyboard and Handwriting Panel
|
||||||
|
// Service" is disabled.
|
||||||
|
void TerminalPage::ShowKeyboardServiceWarning()
|
||||||
|
{
|
||||||
|
if (auto presenter{ _dialogPresenter.get() })
|
||||||
|
{
|
||||||
|
presenter.ShowDialog(FindName(L"KeyboardServiceDisabledDialog").try_as<WUX::Controls::ContentDialog>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function Description:
|
||||||
|
// - Helper function to get the OS-localized name for the "Touch Keyboard
|
||||||
|
// and Handwriting Panel Service". If we can't open up the service for any
|
||||||
|
// reason, then we'll just return the service's key, "TabletInputService".
|
||||||
|
// Return Value:
|
||||||
|
// - The OS-localized name for the TabletInputService
|
||||||
|
winrt::hstring _getTabletServiceName()
|
||||||
|
{
|
||||||
|
auto isUwp = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
isUwp = ::winrt::Windows::UI::Xaml::Application::Current().as<::winrt::TerminalApp::App>().Logic().IsUwp();
|
||||||
|
}
|
||||||
|
CATCH_LOG();
|
||||||
|
|
||||||
|
if (isUwp)
|
||||||
|
{
|
||||||
|
return winrt::hstring{ TabletInputServiceKey };
|
||||||
|
}
|
||||||
|
|
||||||
|
wil::unique_schandle hManager{ OpenSCManager(nullptr, nullptr, 0) };
|
||||||
|
|
||||||
|
if (LOG_LAST_ERROR_IF(!hManager.is_valid()))
|
||||||
|
{
|
||||||
|
return winrt::hstring{ TabletInputServiceKey };
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD cchBuffer = 0;
|
||||||
|
GetServiceDisplayName(hManager.get(), TabletInputServiceKey.data(), nullptr, &cchBuffer);
|
||||||
|
std::wstring buffer;
|
||||||
|
cchBuffer += 1; // Add space for a null
|
||||||
|
buffer.resize(cchBuffer);
|
||||||
|
|
||||||
|
if (LOG_LAST_ERROR_IF(!GetServiceDisplayName(hManager.get(),
|
||||||
|
TabletInputServiceKey.data(),
|
||||||
|
buffer.data(),
|
||||||
|
&cchBuffer)))
|
||||||
|
{
|
||||||
|
return winrt::hstring{ TabletInputServiceKey };
|
||||||
|
}
|
||||||
|
return winrt::hstring{ buffer };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method Description:
|
||||||
|
// - Return the fully-formed warning message for the
|
||||||
|
// "KeyboardServiceDisabled" dialog. This dialog is used to warn the user
|
||||||
|
// if the keyboard service is disabled, and uses the OS localization for
|
||||||
|
// the service's actual name. It's bound to the dialog in XAML.
|
||||||
|
// Return Value:
|
||||||
|
// - The warning message, including the OS-localized service name.
|
||||||
|
winrt::hstring TerminalPage::KeyboardServiceDisabledText()
|
||||||
|
{
|
||||||
|
const winrt::hstring serviceName{ _getTabletServiceName() };
|
||||||
|
const winrt::hstring text{ fmt::format(std::wstring_view(RS_(L"KeyboardServiceWarningText")), serviceName) };
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
// -------------------------------- WinRT Events ---------------------------------
|
// -------------------------------- WinRT Events ---------------------------------
|
||||||
// Winrt events need a method for adding a callback to the event and removing the callback.
|
// Winrt events need a method for adding a callback to the event and removing the callback.
|
||||||
// These macros will define them both for you.
|
// These macros will define them both for you.
|
||||||
|
|||||||
@@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
#include "AppCommandlineArgs.h"
|
#include "AppCommandlineArgs.h"
|
||||||
|
|
||||||
|
static constexpr std::wstring_view TabletInputServiceKey{ L"TabletInputService" };
|
||||||
|
|
||||||
// fwdecl unittest classes
|
// fwdecl unittest classes
|
||||||
namespace TerminalAppLocalTests
|
namespace TerminalAppLocalTests
|
||||||
{
|
{
|
||||||
@@ -65,6 +67,9 @@ namespace winrt::TerminalApp::implementation
|
|||||||
winrt::TerminalApp::IDialogPresenter DialogPresenter() const;
|
winrt::TerminalApp::IDialogPresenter DialogPresenter() const;
|
||||||
void DialogPresenter(winrt::TerminalApp::IDialogPresenter dialogPresenter);
|
void DialogPresenter(winrt::TerminalApp::IDialogPresenter dialogPresenter);
|
||||||
|
|
||||||
|
void ShowKeyboardServiceWarning();
|
||||||
|
winrt::hstring KeyboardServiceDisabledText();
|
||||||
|
|
||||||
// -------------------------------- WinRT Events ---------------------------------
|
// -------------------------------- WinRT Events ---------------------------------
|
||||||
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(TitleChanged, _titleChangeHandlers, winrt::Windows::Foundation::IInspectable, winrt::hstring);
|
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(TitleChanged, _titleChangeHandlers, winrt::Windows::Foundation::IInspectable, winrt::hstring);
|
||||||
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(LastTabClosed, _lastTabClosedHandlers, winrt::Windows::Foundation::IInspectable, winrt::TerminalApp::LastTabClosedEventArgs);
|
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(LastTabClosed, _lastTabClosedHandlers, winrt::Windows::Foundation::IInspectable, winrt::TerminalApp::LastTabClosedEventArgs);
|
||||||
@@ -91,8 +96,10 @@ namespace winrt::TerminalApp::implementation
|
|||||||
TerminalApp::CascadiaSettings _settings{ nullptr };
|
TerminalApp::CascadiaSettings _settings{ nullptr };
|
||||||
|
|
||||||
Windows::Foundation::Collections::IObservableVector<TerminalApp::Tab> _tabs;
|
Windows::Foundation::Collections::IObservableVector<TerminalApp::Tab> _tabs;
|
||||||
|
Windows::Foundation::Collections::IVector<TerminalApp::Command> _mruTabActions;
|
||||||
winrt::com_ptr<Tab> _GetStrongTabImpl(const uint32_t index) const;
|
winrt::com_ptr<Tab> _GetStrongTabImpl(const uint32_t index) const;
|
||||||
winrt::com_ptr<Tab> _GetStrongTabImpl(const ::winrt::TerminalApp::Tab& tab) const;
|
winrt::com_ptr<Tab> _GetStrongTabImpl(const ::winrt::TerminalApp::Tab& tab) const;
|
||||||
|
void _UpdateTabIndices();
|
||||||
|
|
||||||
bool _isInFocusMode{ false };
|
bool _isInFocusMode{ false };
|
||||||
bool _isFullscreen{ false };
|
bool _isFullscreen{ false };
|
||||||
@@ -125,10 +132,12 @@ namespace winrt::TerminalApp::implementation
|
|||||||
void _CreateNewTabFromSettings(GUID profileGuid, TerminalApp::TerminalSettings settings);
|
void _CreateNewTabFromSettings(GUID profileGuid, TerminalApp::TerminalSettings settings);
|
||||||
winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection _CreateConnectionFromSettings(GUID profileGuid, TerminalApp::TerminalSettings settings);
|
winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection _CreateConnectionFromSettings(GUID profileGuid, TerminalApp::TerminalSettings settings);
|
||||||
|
|
||||||
|
bool _displayingCloseDialog{ false };
|
||||||
void _SettingsButtonOnClick(const IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& eventArgs);
|
void _SettingsButtonOnClick(const IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& eventArgs);
|
||||||
void _FeedbackButtonOnClick(const IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& eventArgs);
|
void _FeedbackButtonOnClick(const IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& eventArgs);
|
||||||
void _AboutButtonOnClick(const IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& eventArgs);
|
void _AboutButtonOnClick(const IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& eventArgs);
|
||||||
void _CloseWarningPrimaryButtonOnClick(Windows::UI::Xaml::Controls::ContentDialog sender, Windows::UI::Xaml::Controls::ContentDialogButtonClickEventArgs eventArgs);
|
void _CloseWarningPrimaryButtonOnClick(Windows::UI::Xaml::Controls::ContentDialog sender, Windows::UI::Xaml::Controls::ContentDialogButtonClickEventArgs eventArgs);
|
||||||
|
void _CloseWarningCloseButtonOnClick(Windows::UI::Xaml::Controls::ContentDialog sender, Windows::UI::Xaml::Controls::ContentDialogButtonClickEventArgs eventArgs);
|
||||||
void _ThirdPartyNoticesOnClick(const IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& eventArgs);
|
void _ThirdPartyNoticesOnClick(const IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& eventArgs);
|
||||||
|
|
||||||
void _HookupKeyBindings(const TerminalApp::KeyMapping& keymap) noexcept;
|
void _HookupKeyBindings(const TerminalApp::KeyMapping& keymap) noexcept;
|
||||||
@@ -206,6 +215,9 @@ namespace winrt::TerminalApp::implementation
|
|||||||
|
|
||||||
void _UnZoomIfNeeded();
|
void _UnZoomIfNeeded();
|
||||||
|
|
||||||
|
void _UpdateTabSwitcherCommands(const bool mru);
|
||||||
|
void _UpdateMRUTab(const uint32_t index);
|
||||||
|
|
||||||
#pragma region ActionHandlers
|
#pragma region ActionHandlers
|
||||||
// These are all defined in AppActionHandlers.cpp
|
// These are all defined in AppActionHandlers.cpp
|
||||||
void _HandleOpenNewTabDropdown(const IInspectable& sender, const TerminalApp::ActionEventArgs& args);
|
void _HandleOpenNewTabDropdown(const IInspectable& sender, const TerminalApp::ActionEventArgs& args);
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ namespace TerminalApp
|
|||||||
// that there's only one application-global dialog visible at a time,
|
// that there's only one application-global dialog visible at a time,
|
||||||
// and because of GH#5224.
|
// and because of GH#5224.
|
||||||
IDialogPresenter DialogPresenter;
|
IDialogPresenter DialogPresenter;
|
||||||
|
void ShowKeyboardServiceWarning();
|
||||||
|
String KeyboardServiceDisabledText { get; };
|
||||||
|
|
||||||
event Windows.Foundation.TypedEventHandler<Object, String> TitleChanged;
|
event Windows.Foundation.TypedEventHandler<Object, String> TitleChanged;
|
||||||
event Windows.Foundation.TypedEventHandler<Object, LastTabClosedEventArgs> LastTabClosed;
|
event Windows.Foundation.TypedEventHandler<Object, LastTabClosedEventArgs> LastTabClosed;
|
||||||
|
|||||||
@@ -51,7 +51,8 @@ the MIT License. See LICENSE in the project root for license information. -->
|
|||||||
x:Name="CloseAllDialog"
|
x:Name="CloseAllDialog"
|
||||||
x:Uid="CloseAllDialog"
|
x:Uid="CloseAllDialog"
|
||||||
DefaultButton="Primary"
|
DefaultButton="Primary"
|
||||||
PrimaryButtonClick="_CloseWarningPrimaryButtonOnClick">
|
PrimaryButtonClick="_CloseWarningPrimaryButtonOnClick"
|
||||||
|
CloseButtonClick="_CloseWarningCloseButtonOnClick">
|
||||||
</ContentDialog>
|
</ContentDialog>
|
||||||
|
|
||||||
<ContentDialog
|
<ContentDialog
|
||||||
@@ -73,7 +74,7 @@ the MIT License. See LICENSE in the project root for license information. -->
|
|||||||
x:Name="CouldNotOpenUriDialog"
|
x:Name="CouldNotOpenUriDialog"
|
||||||
x:Uid="CouldNotOpenUriDialog"
|
x:Uid="CouldNotOpenUriDialog"
|
||||||
DefaultButton="Primary">
|
DefaultButton="Primary">
|
||||||
<TextBlock IsTextSelectionEnabled="True">
|
<TextBlock IsTextSelectionEnabled="True" TextWrapping="WrapWholeWords">
|
||||||
<Run x:Name="CouldNotOpenUriReason" /> <LineBreak />
|
<Run x:Name="CouldNotOpenUriReason" /> <LineBreak />
|
||||||
<Run
|
<Run
|
||||||
x:Name="UnopenedUri"
|
x:Name="UnopenedUri"
|
||||||
@@ -82,6 +83,20 @@ the MIT License. See LICENSE in the project root for license information. -->
|
|||||||
</TextBlock>
|
</TextBlock>
|
||||||
</ContentDialog>
|
</ContentDialog>
|
||||||
|
|
||||||
|
|
||||||
|
<ContentDialog
|
||||||
|
x:Load="False"
|
||||||
|
x:Name="KeyboardServiceDisabledDialog"
|
||||||
|
x:Uid="KeyboardServiceDisabledDialog"
|
||||||
|
DefaultButton="Primary">
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Foreground="{ThemeResource ErrorTextBrush}"
|
||||||
|
IsTextSelectionEnabled="True"
|
||||||
|
TextWrapping="WrapWholeWords"
|
||||||
|
Text="{x:Bind KeyboardServiceDisabledText, Mode=OneWay}" />
|
||||||
|
</ContentDialog>
|
||||||
|
|
||||||
<local:CommandPalette
|
<local:CommandPalette
|
||||||
x:Name="CommandPalette"
|
x:Name="CommandPalette"
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ namespace TerminalApp
|
|||||||
MissingRequiredParameter = 7,
|
MissingRequiredParameter = 7,
|
||||||
LegacyGlobalsProperty = 8,
|
LegacyGlobalsProperty = 8,
|
||||||
FailedToParseCommandJson = 9,
|
FailedToParseCommandJson = 9,
|
||||||
|
FailedToWriteToSettings = 10,
|
||||||
WARNINGS_SIZE // IMPORTANT: This MUST be the last value in this enum. It's an unused placeholder.
|
WARNINGS_SIZE // IMPORTANT: This MUST be the last value in this enum. It's an unused placeholder.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
// THIS IS AN AUTO-GENERATED FILE! Changes to this file will be ignored.
|
// THIS IS AN AUTO-GENERATED FILE! Changes to this file will be ignored.
|
||||||
{
|
{
|
||||||
"defaultProfile": "{550ce7b8-d500-50ad-8a1a-c400c3262db3}",
|
"defaultProfile": "{70bfecf4-bcbb-443b-a8fa-d7ac4f7ad201}",
|
||||||
|
|
||||||
// Launch Settings
|
// Launch Settings
|
||||||
"initialCols": 120,
|
"initialCols": 120,
|
||||||
"initialRows": 30,
|
"initialRows": 30,
|
||||||
"launchMode": "default",
|
"launchMode": "default",
|
||||||
|
"alwaysOnTop": false,
|
||||||
|
|
||||||
// Selection
|
// Selection
|
||||||
"copyOnSelect": false,
|
"copyOnSelect": false,
|
||||||
"copyFormatting": false,
|
"copyFormatting": true,
|
||||||
"wordDelimiters": " /\\()\"'-.,:;<>~!@#$%^&*|+=[]{}~?\u2502",
|
"wordDelimiters": " /\\()\"'-.,:;<>~!@#$%^&*|+=[]{}~?\u2502",
|
||||||
|
|
||||||
// Tab UI
|
// Tab UI
|
||||||
@@ -17,30 +18,56 @@
|
|||||||
"showTabsInTitlebar": true,
|
"showTabsInTitlebar": true,
|
||||||
"showTerminalTitleInTitlebar": true,
|
"showTerminalTitleInTitlebar": true,
|
||||||
"tabWidthMode": "equal",
|
"tabWidthMode": "equal",
|
||||||
|
"useTabSwitcher": true,
|
||||||
|
|
||||||
// Miscellaneous
|
// Miscellaneous
|
||||||
"confirmCloseAllTabs": true,
|
"confirmCloseAllTabs": true,
|
||||||
|
"startOnUserLogin": false,
|
||||||
"theme": "system",
|
"theme": "system",
|
||||||
"snapToGridOnResize": true,
|
"snapToGridOnResize": true,
|
||||||
|
|
||||||
"profiles":
|
"profiles":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"guid": "{550ce7b8-d500-50ad-8a1a-c400c3262db3}",
|
"guid": "{70bfecf4-bcbb-443b-a8fa-d7ac4f7ad201}",
|
||||||
"name": "Telnet Loopback",
|
"name": "PowerShell",
|
||||||
"commandline": "ms-telnet-loop://127.0.0.1:23",
|
"commandline": "pwsh.exe",
|
||||||
"connectionType" : "{311153fb-d3f0-4ac6-b920-038de7cf5289}",
|
"icon": "ms-appx:///ProfileIcons/pwsh.png",
|
||||||
"hidden": false,
|
"colorScheme": "Campbell",
|
||||||
"startingDirectory": "%USERPROFILE%",
|
"antialiasingMode": "grayscale",
|
||||||
"closeOnExit": "graceful",
|
"closeOnExit": "graceful",
|
||||||
"colorScheme": "Vintage",
|
|
||||||
"cursorColor": "#FFFFFF",
|
|
||||||
"cursorShape": "bar",
|
"cursorShape": "bar",
|
||||||
"fontFace": "Cascadia Mono",
|
"fontFace": "Cascadia Mono",
|
||||||
"icon": "ms-appx:///ProfileIcons/{550ce7b8-d500-50ad-8a1a-c400c3262db3}.png",
|
"fontSize": 12,
|
||||||
|
"hidden": false,
|
||||||
|
"historySize": 9001,
|
||||||
"padding": "8, 8, 8, 8",
|
"padding": "8, 8, 8, 8",
|
||||||
"snapOnInput": true,
|
"snapOnInput": true,
|
||||||
"altGrAliasing": true,
|
"altGrAliasing": true,
|
||||||
|
"startingDirectory": "%SystemRoot%",
|
||||||
|
"useAcrylic": false,
|
||||||
|
"backgroundImage": "ms-appx:///internal-background.png",
|
||||||
|
"backgroundImageAlignment": "bottomRight",
|
||||||
|
"backgroundImageOpacity": 0.4,
|
||||||
|
"backgroundImageStretchMode": "none"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}",
|
||||||
|
"name": "Command Prompt",
|
||||||
|
"commandline": "%SystemRoot%\\System32\\cmd.exe",
|
||||||
|
"icon": "ms-appx:///ProfileIcons/{0caa0dad-35be-5f56-a8ff-afceeeaa6101}.png",
|
||||||
|
"colorScheme": "Campbell",
|
||||||
|
"antialiasingMode": "grayscale",
|
||||||
|
"closeOnExit": "graceful",
|
||||||
|
"cursorShape": "bar",
|
||||||
|
"fontFace": "Cascadia Mono",
|
||||||
|
"fontSize": 12,
|
||||||
|
"hidden": false,
|
||||||
|
"historySize": 9001,
|
||||||
|
"padding": "8, 8, 8, 8",
|
||||||
|
"snapOnInput": true,
|
||||||
|
"altGrAliasing": true,
|
||||||
|
"startingDirectory": "%SystemRoot%",
|
||||||
"useAcrylic": false,
|
"useAcrylic": false,
|
||||||
"backgroundImage": "ms-appx:///internal-background.png",
|
"backgroundImage": "ms-appx:///internal-background.png",
|
||||||
"backgroundImageAlignment": "bottomRight",
|
"backgroundImageAlignment": "bottomRight",
|
||||||
@@ -51,25 +78,26 @@
|
|||||||
"schemes":
|
"schemes":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"name": "Vintage",
|
"name": "Campbell",
|
||||||
"foreground": "#C0C0C0",
|
"foreground": "#CCCCCC",
|
||||||
"background": "#000000",
|
"background": "#0C0C0C",
|
||||||
"black": "#000000",
|
"cursorColor": "#FFFFFF",
|
||||||
"red": "#800000",
|
"black": "#0C0C0C",
|
||||||
"green": "#008000",
|
"red": "#C50F1F",
|
||||||
"yellow": "#808000",
|
"green": "#13A10E",
|
||||||
"blue": "#000080",
|
"yellow": "#C19C00",
|
||||||
"purple": "#800080",
|
"blue": "#0037DA",
|
||||||
"cyan": "#008080",
|
"purple": "#881798",
|
||||||
"white": "#C0C0C0",
|
"cyan": "#3A96DD",
|
||||||
"brightBlack": "#808080",
|
"white": "#CCCCCC",
|
||||||
"brightRed": "#FF0000",
|
"brightBlack": "#767676",
|
||||||
"brightGreen": "#00FF00",
|
"brightRed": "#E74856",
|
||||||
"brightYellow": "#FFFF00",
|
"brightGreen": "#16C60C",
|
||||||
"brightBlue": "#0000FF",
|
"brightYellow": "#F9F1A5",
|
||||||
"brightPurple": "#FF00FF",
|
"brightBlue": "#3B78FF",
|
||||||
"brightCyan": "#00FFFF",
|
"brightPurple": "#B4009E",
|
||||||
"brightWhite": "#FFFFFF"
|
"brightCyan": "#61D6D6",
|
||||||
|
"brightWhite": "#F2F2F2"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"actions":
|
"actions":
|
||||||
@@ -78,14 +106,21 @@
|
|||||||
{ "command": "closeWindow", "keys": "alt+f4" },
|
{ "command": "closeWindow", "keys": "alt+f4" },
|
||||||
{ "command": "toggleFullscreen", "keys": "alt+enter" },
|
{ "command": "toggleFullscreen", "keys": "alt+enter" },
|
||||||
{ "command": "toggleFullscreen", "keys": "f11" },
|
{ "command": "toggleFullscreen", "keys": "f11" },
|
||||||
|
{ "command": "toggleFocusMode" },
|
||||||
|
{ "command": "toggleAlwaysOnTop" },
|
||||||
{ "command": "openNewTabDropdown", "keys": "ctrl+shift+space" },
|
{ "command": "openNewTabDropdown", "keys": "ctrl+shift+space" },
|
||||||
{ "command": "openSettings", "keys": "ctrl+," },
|
{ "command": "openSettings", "keys": "ctrl+," },
|
||||||
|
{ "command": { "action": "openSettings", "target": "defaultsFile" }, "keys": "ctrl+alt+," },
|
||||||
{ "command": "find", "keys": "ctrl+shift+f" },
|
{ "command": "find", "keys": "ctrl+shift+f" },
|
||||||
|
{ "command": "toggleRetroEffect" },
|
||||||
|
{ "command": "openTabColorPicker" },
|
||||||
{ "command": "commandPalette", "keys":"ctrl+shift+p" },
|
{ "command": "commandPalette", "keys":"ctrl+shift+p" },
|
||||||
|
|
||||||
// Tab Management
|
// Tab Management
|
||||||
// "command": "closeTab" is unbound by default.
|
// "command": "closeTab" is unbound by default.
|
||||||
// The closeTab command closes a tab without confirmation, even if it has multiple panes.
|
// The closeTab command closes a tab without confirmation, even if it has multiple panes.
|
||||||
|
{ "command": "closeOtherTabs" },
|
||||||
|
{ "command": "closeTabsAfter" },
|
||||||
{ "command": "newTab", "keys": "ctrl+shift+t" },
|
{ "command": "newTab", "keys": "ctrl+shift+t" },
|
||||||
{ "command": { "action": "newTab", "index": 0 }, "keys": "ctrl+shift+1" },
|
{ "command": { "action": "newTab", "index": 0 }, "keys": "ctrl+shift+1" },
|
||||||
{ "command": { "action": "newTab", "index": 1 }, "keys": "ctrl+shift+2" },
|
{ "command": { "action": "newTab", "index": 1 }, "keys": "ctrl+shift+2" },
|
||||||
@@ -121,6 +156,7 @@
|
|||||||
{ "command": { "action": "moveFocus", "direction": "left" }, "keys": "alt+left" },
|
{ "command": { "action": "moveFocus", "direction": "left" }, "keys": "alt+left" },
|
||||||
{ "command": { "action": "moveFocus", "direction": "right" }, "keys": "alt+right" },
|
{ "command": { "action": "moveFocus", "direction": "right" }, "keys": "alt+right" },
|
||||||
{ "command": { "action": "moveFocus", "direction": "up" }, "keys": "alt+up" },
|
{ "command": { "action": "moveFocus", "direction": "up" }, "keys": "alt+up" },
|
||||||
|
{ "command": "togglePaneZoom" },
|
||||||
|
|
||||||
// Clipboard Integration
|
// Clipboard Integration
|
||||||
{ "command": { "action": "copy", "singleLine": false }, "keys": "ctrl+shift+c" },
|
{ "command": { "action": "copy", "singleLine": false }, "keys": "ctrl+shift+c" },
|
||||||
@@ -137,6 +173,53 @@
|
|||||||
// Visual Adjustments
|
// Visual Adjustments
|
||||||
{ "command": { "action": "adjustFontSize", "delta": 1 }, "keys": "ctrl+=" },
|
{ "command": { "action": "adjustFontSize", "delta": 1 }, "keys": "ctrl+=" },
|
||||||
{ "command": { "action": "adjustFontSize", "delta": -1 }, "keys": "ctrl+-" },
|
{ "command": { "action": "adjustFontSize", "delta": -1 }, "keys": "ctrl+-" },
|
||||||
{ "command": "resetFontSize", "keys": "ctrl+0" }
|
{ "command": "resetFontSize", "keys": "ctrl+0" },
|
||||||
|
|
||||||
|
// Other commands
|
||||||
|
{
|
||||||
|
// Select color scheme...
|
||||||
|
"name": { "key": "SetColorSchemeParentCommandName" },
|
||||||
|
"commands": [
|
||||||
|
{
|
||||||
|
"iterateOn": "schemes",
|
||||||
|
"name": "${scheme.name}",
|
||||||
|
"command": { "action": "setColorScheme", "colorScheme": "${scheme.name}" }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// New tab...
|
||||||
|
"name": { "key": "NewTabParentCommandName" },
|
||||||
|
"commands": [
|
||||||
|
{
|
||||||
|
"iterateOn": "profiles",
|
||||||
|
"icon": "${profile.icon}",
|
||||||
|
"name": "${profile.name}",
|
||||||
|
"command": { "action": "newTab", "profile": "${profile.name}" }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Split pane...
|
||||||
|
"name": { "key": "SplitPaneParentCommandName" },
|
||||||
|
"commands": [
|
||||||
|
{
|
||||||
|
"iterateOn": "profiles",
|
||||||
|
"icon": "${profile.icon}",
|
||||||
|
"name": "${profile.name}...",
|
||||||
|
"commands": [
|
||||||
|
{
|
||||||
|
"command": { "action": "splitPane", "profile": "${profile.name}", "split": "auto" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": { "action": "splitPane", "profile": "${profile.name}", "split": "vertical" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": { "action": "splitPane", "profile": "${profile.name}", "split": "horizontal" }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
"showTabsInTitlebar": true,
|
"showTabsInTitlebar": true,
|
||||||
"showTerminalTitleInTitlebar": true,
|
"showTerminalTitleInTitlebar": true,
|
||||||
"tabWidthMode": "equal",
|
"tabWidthMode": "equal",
|
||||||
"useTabSwitcher": true,
|
"useTabSwitcher": false,
|
||||||
|
|
||||||
// Miscellaneous
|
// Miscellaneous
|
||||||
"confirmCloseAllTabs": true,
|
"confirmCloseAllTabs": true,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include <LibraryResources.h>
|
#include <LibraryResources.h>
|
||||||
|
#include <WilErrorReporting.h>
|
||||||
|
|
||||||
// Note: Generate GUID using TlgGuid.exe tool
|
// Note: Generate GUID using TlgGuid.exe tool
|
||||||
TRACELOGGING_DEFINE_PROVIDER(
|
TRACELOGGING_DEFINE_PROVIDER(
|
||||||
@@ -19,6 +20,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD reason, LPVOID /*reserved*/)
|
|||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
DisableThreadLibraryCalls(hInstDll);
|
DisableThreadLibraryCalls(hInstDll);
|
||||||
TraceLoggingRegister(g_hTerminalAppProvider);
|
TraceLoggingRegister(g_hTerminalAppProvider);
|
||||||
|
Microsoft::Console::ErrorReporting::EnableFallbackFailureReporting(g_hTerminalAppProvider);
|
||||||
break;
|
break;
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
if (g_hTerminalAppProvider)
|
if (g_hTerminalAppProvider)
|
||||||
|
|||||||
@@ -52,10 +52,10 @@
|
|||||||
// To learn more about color schemes, visit https://aka.ms/terminal-color-schemes
|
// To learn more about color schemes, visit https://aka.ms/terminal-color-schemes
|
||||||
"schemes": [],
|
"schemes": [],
|
||||||
|
|
||||||
// Add custom keybindings to this array.
|
// Add custom actions and keybindings to this array.
|
||||||
// To unbind a key combination from your defaults.json, set the command to "unbound".
|
// To unbind a key combination from your defaults.json, set the command to "unbound".
|
||||||
// To learn more about keybindings, visit https://aka.ms/terminal-keybindings
|
// To learn more about actions and keybindings, visit https://aka.ms/terminal-keybindings
|
||||||
"keybindings":
|
"actions":
|
||||||
[
|
[
|
||||||
// Copy and paste are bound to Ctrl+Shift+C and Ctrl+Shift+V in your defaults.json.
|
// Copy and paste are bound to Ctrl+Shift+C and Ctrl+Shift+V in your defaults.json.
|
||||||
// These two lines additionally bind them to Ctrl+C and Ctrl+V.
|
// These two lines additionally bind them to Ctrl+C and Ctrl+V.
|
||||||
|
|||||||
@@ -3,10 +3,6 @@
|
|||||||
|
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
|
|
||||||
// We have to define GSL here, not PCH
|
|
||||||
// because TelnetConnection has a conflicting GSL implementation.
|
|
||||||
#include <gsl/gsl>
|
|
||||||
|
|
||||||
#include "AzureConnection.h"
|
#include "AzureConnection.h"
|
||||||
#include "AzureClientID.h"
|
#include "AzureClientID.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|||||||
@@ -3,14 +3,9 @@
|
|||||||
|
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
|
|
||||||
// We have to define GSL here, not PCH
|
|
||||||
// because TelnetConnection has a conflicting GSL implementation.
|
|
||||||
#include <gsl/gsl>
|
|
||||||
|
|
||||||
#include "ConptyConnection.h"
|
#include "ConptyConnection.h"
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <userenv.h>
|
|
||||||
|
|
||||||
#include "ConptyConnection.g.cpp"
|
#include "ConptyConnection.g.cpp"
|
||||||
|
|
||||||
@@ -98,11 +93,8 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
|||||||
environment.clear();
|
environment.clear();
|
||||||
});
|
});
|
||||||
|
|
||||||
{
|
// Populate the environment map with the current environment.
|
||||||
const auto newEnvironmentBlock{ Utils::CreateEnvironmentBlock() };
|
RETURN_IF_FAILED(Utils::UpdateEnvironmentMapW(environment));
|
||||||
// Populate the environment map with the current environment.
|
|
||||||
RETURN_IF_FAILED(Utils::UpdateEnvironmentMapW(environment, newEnvironmentBlock.get()));
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
// Convert connection Guid to string and ignore the enclosing '{}'.
|
// Convert connection Guid to string and ignore the enclosing '{}'.
|
||||||
|
|||||||
@@ -5,10 +5,6 @@
|
|||||||
#include "EchoConnection.h"
|
#include "EchoConnection.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
// We have to define GSL here, not PCH
|
|
||||||
// because TelnetConnection has a conflicting GSL implementation.
|
|
||||||
#include <gsl/gsl>
|
|
||||||
|
|
||||||
#include "EchoConnection.g.cpp"
|
#include "EchoConnection.g.cpp"
|
||||||
|
|
||||||
namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||||
|
|||||||
@@ -212,7 +212,4 @@
|
|||||||
<comment>The first argument {0...} is the hexadecimal error code. The second argument {1} is the user-specified path to a program.
|
<comment>The first argument {0...} is the hexadecimal error code. The second argument {1} is the user-specified path to a program.
|
||||||
If this string is broken to multiple lines, it will not be displayed properly.</comment>
|
If this string is broken to multiple lines, it will not be displayed properly.</comment>
|
||||||
</data>
|
</data>
|
||||||
<data name="TelnetInternetOrServerIssue" xml:space="preserve">
|
|
||||||
<value>Could not connect to telnet server.</value>
|
|
||||||
</data>
|
|
||||||
</root>
|
</root>
|
||||||
|
|||||||
@@ -1,333 +0,0 @@
|
|||||||
// Copyright (c) Microsoft Corporation.
|
|
||||||
// Licensed under the MIT license.
|
|
||||||
|
|
||||||
#include "pch.h"
|
|
||||||
#include "TelnetConnection.h"
|
|
||||||
#include <LibraryResources.h>
|
|
||||||
|
|
||||||
#include "TelnetConnection.g.cpp"
|
|
||||||
|
|
||||||
#include "../../types/inc/Utils.hpp"
|
|
||||||
|
|
||||||
using namespace ::Microsoft::Console;
|
|
||||||
|
|
||||||
constexpr std::wstring_view telnetScheme = L"telnet";
|
|
||||||
constexpr std::wstring_view msTelnetLoopbackScheme = L"ms-telnet-loop";
|
|
||||||
|
|
||||||
namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
|
||||||
{
|
|
||||||
TelnetConnection::TelnetConnection(const hstring& uri) :
|
|
||||||
_reader{ nullptr },
|
|
||||||
_writer{ nullptr },
|
|
||||||
_uri{ uri },
|
|
||||||
_receiveBuffer{}
|
|
||||||
{
|
|
||||||
_session.install(_nawsServer);
|
|
||||||
_nawsServer.activate([](auto&&) {});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method description:
|
|
||||||
// - ascribes to the ITerminalConnection interface
|
|
||||||
// - creates the output thread
|
|
||||||
void TelnetConnection::Start()
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Create our own output handling thread
|
|
||||||
// Each connection needs to make sure to drain the output from its backing host.
|
|
||||||
_hOutputThread.reset(CreateThread(
|
|
||||||
nullptr,
|
|
||||||
0,
|
|
||||||
[](LPVOID lpParameter) {
|
|
||||||
auto pInstance = static_cast<TelnetConnection*>(lpParameter);
|
|
||||||
if (pInstance)
|
|
||||||
{
|
|
||||||
return pInstance->_outputThread();
|
|
||||||
}
|
|
||||||
return gsl::narrow_cast<DWORD>(ERROR_BAD_ARGUMENTS);
|
|
||||||
},
|
|
||||||
this,
|
|
||||||
0,
|
|
||||||
nullptr));
|
|
||||||
|
|
||||||
THROW_LAST_ERROR_IF_NULL(_hOutputThread);
|
|
||||||
|
|
||||||
_transitionToState(ConnectionState::Connecting);
|
|
||||||
|
|
||||||
// Set initial window title.
|
|
||||||
_TerminalOutputHandlers(L"\x1b]0;Telnet\x7");
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
LOG_CAUGHT_EXCEPTION();
|
|
||||||
_transitionToState(ConnectionState::Failed);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method description:
|
|
||||||
// - ascribes to the ITerminalConnection interface
|
|
||||||
// - handles the different possible inputs in the different states
|
|
||||||
// Arguments:
|
|
||||||
// the user's input
|
|
||||||
void TelnetConnection::WriteInput(hstring const& data)
|
|
||||||
{
|
|
||||||
if (!_isStateOneOf(ConnectionState::Connected, ConnectionState::Connecting))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto str = winrt::to_string(data);
|
|
||||||
if (str.size() == 1 && str.at(0) == L'\r')
|
|
||||||
{
|
|
||||||
str = "\r\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma warning(suppress : 26490) // Using something that isn't reinterpret_cast to forward stream bytes is more clumsy than just using it.
|
|
||||||
telnetpp::bytes bytes(reinterpret_cast<const uint8_t*>(str.data()), str.size());
|
|
||||||
_session.send(bytes, [=](telnetpp::bytes data) {
|
|
||||||
_socketSend(data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method description:
|
|
||||||
// - ascribes to the ITerminalConnection interface
|
|
||||||
// - resizes the terminal
|
|
||||||
// Arguments:
|
|
||||||
// - the new rows/cols values
|
|
||||||
void TelnetConnection::Resize(uint32_t rows, uint32_t columns)
|
|
||||||
{
|
|
||||||
if (_prevResize.has_value() && _prevResize.value().first == rows && _prevResize.value().second == columns)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_prevResize.emplace(std::pair{ rows, columns });
|
|
||||||
|
|
||||||
_nawsServer.set_window_size(gsl::narrow<uint16_t>(columns),
|
|
||||||
gsl::narrow<uint16_t>(rows),
|
|
||||||
[=](telnetpp::subnegotiation sub) {
|
|
||||||
_session.send(sub,
|
|
||||||
[=](telnetpp::bytes data) {
|
|
||||||
_socketBufferedSend(data);
|
|
||||||
});
|
|
||||||
_socketFlushBuffer();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method description:
|
|
||||||
// - ascribes to the ITerminalConnection interface
|
|
||||||
// - closes the socket connection and the output thread
|
|
||||||
void TelnetConnection::Close()
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (_transitionToState(ConnectionState::Closing))
|
|
||||||
{
|
|
||||||
_socket.Close();
|
|
||||||
if (_hOutputThread)
|
|
||||||
{
|
|
||||||
// Tear down our output thread
|
|
||||||
WaitForSingleObject(_hOutputThread.get(), INFINITE);
|
|
||||||
_hOutputThread.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
_transitionToState(ConnectionState::Closed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
LOG_CAUGHT_EXCEPTION();
|
|
||||||
_transitionToState(ConnectionState::Failed);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method description:
|
|
||||||
// - this is the output thread, where we initiate the connection to the remote host
|
|
||||||
// and establish a socket connection
|
|
||||||
// Return value:
|
|
||||||
// - return status
|
|
||||||
DWORD TelnetConnection::_outputThread()
|
|
||||||
try
|
|
||||||
{
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
if (_isStateOneOf(ConnectionState::Failed))
|
|
||||||
{
|
|
||||||
_TerminalOutputHandlers(RS_(L"TelnetInternetOrServerIssue") + L"\r\n");
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
|
||||||
else if (_isStateAtOrBeyond(ConnectionState::Closing))
|
|
||||||
{
|
|
||||||
return S_FALSE;
|
|
||||||
}
|
|
||||||
else if (_isStateOneOf(ConnectionState::Connecting))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
const auto uri = Windows::Foundation::Uri(_uri);
|
|
||||||
const auto host = Windows::Networking::HostName(uri.Host());
|
|
||||||
|
|
||||||
bool autoLogin = false;
|
|
||||||
// If we specified the special ms loopback scheme, then set autologin and proceed below.
|
|
||||||
if (msTelnetLoopbackScheme == uri.SchemeName())
|
|
||||||
{
|
|
||||||
autoLogin = true;
|
|
||||||
}
|
|
||||||
// Otherwise, make sure we said telnet://, anything else is not supported here.
|
|
||||||
else if (telnetScheme != uri.SchemeName())
|
|
||||||
{
|
|
||||||
THROW_HR(E_INVALIDARG);
|
|
||||||
}
|
|
||||||
|
|
||||||
_socket.ConnectAsync(host, winrt::to_hstring(uri.Port())).get();
|
|
||||||
_writer = Windows::Storage::Streams::DataWriter(_socket.OutputStream());
|
|
||||||
_reader = Windows::Storage::Streams::DataReader(_socket.InputStream());
|
|
||||||
_reader.InputStreamOptions(Windows::Storage::Streams::InputStreamOptions::Partial); // returns when 1 or more bytes ready.
|
|
||||||
_transitionToState(ConnectionState::Connected);
|
|
||||||
|
|
||||||
if (autoLogin)
|
|
||||||
{
|
|
||||||
// Send newline to bypass User Name prompt.
|
|
||||||
const auto newline = winrt::to_hstring("\r\n");
|
|
||||||
WriteInput(newline);
|
|
||||||
|
|
||||||
// Wait for login.
|
|
||||||
Sleep(1000);
|
|
||||||
|
|
||||||
// Send "cls" enter to clear the thing and just look like a prompt.
|
|
||||||
const auto clearScreen = winrt::to_hstring("cls\r\n");
|
|
||||||
WriteInput(clearScreen);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
LOG_CAUGHT_EXCEPTION();
|
|
||||||
_transitionToState(ConnectionState::Failed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_isStateOneOf(ConnectionState::Connected))
|
|
||||||
{
|
|
||||||
// Read from socket
|
|
||||||
const auto amountReceived = _socketReceive(_receiveBuffer);
|
|
||||||
|
|
||||||
_session.receive(
|
|
||||||
telnetpp::bytes{ _receiveBuffer.data(), amountReceived },
|
|
||||||
[=](telnetpp::bytes data,
|
|
||||||
std::function<void(telnetpp::bytes)> const& send) {
|
|
||||||
_applicationReceive(data, send);
|
|
||||||
},
|
|
||||||
[=](telnetpp::bytes data) {
|
|
||||||
_socketSend(data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
// If the exception was thrown while we were already supposed to be closing, fine. We're closed.
|
|
||||||
// This is because the socket got mad things were being torn down.
|
|
||||||
if (_isStateAtOrBeyond(ConnectionState::Closing))
|
|
||||||
{
|
|
||||||
_transitionToState(ConnectionState::Closed);
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG_CAUGHT_EXCEPTION();
|
|
||||||
_transitionToState(ConnectionState::Failed);
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Routine Description:
|
|
||||||
// - Call to buffer up bytes to send to the remote device.
|
|
||||||
// - You must flush before they'll go out.
|
|
||||||
// Arguments:
|
|
||||||
// - data - View of bytes to be sent
|
|
||||||
// Return Value:
|
|
||||||
// - <none>
|
|
||||||
void TelnetConnection::_socketBufferedSend(telnetpp::bytes data)
|
|
||||||
{
|
|
||||||
// winrt::array_view should take data/size but it doesn't.
|
|
||||||
// We contacted the WinRT owners and they said, more or less, that it's not worth fixing
|
|
||||||
// with std::span on the horizon instead of this. So we're suppressing the warning
|
|
||||||
// and hoping for a std::span future that will eliminate winrt::array_view<T>
|
|
||||||
#pragma warning(push)
|
|
||||||
#pragma warning(disable : 26481)
|
|
||||||
const uint8_t* first = data.data();
|
|
||||||
const uint8_t* last = data.data() + data.size();
|
|
||||||
#pragma warning(pop)
|
|
||||||
|
|
||||||
const winrt::array_view<const uint8_t> arrayView(first, last);
|
|
||||||
_writer.WriteBytes(arrayView);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Routine Description:
|
|
||||||
// - Flushes any buffered bytes to the underlying socket
|
|
||||||
// Arguments:
|
|
||||||
// - <none>
|
|
||||||
// Return Value:
|
|
||||||
// - <none>
|
|
||||||
fire_and_forget TelnetConnection::_socketFlushBuffer()
|
|
||||||
{
|
|
||||||
co_await _writer.StoreAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Routine Description:
|
|
||||||
// - Used to send bytes into the socket to the remote device
|
|
||||||
// Arguments:
|
|
||||||
// - data - View of bytes to be sent
|
|
||||||
// Return Value:
|
|
||||||
// - <none>
|
|
||||||
void TelnetConnection::_socketSend(telnetpp::bytes data)
|
|
||||||
{
|
|
||||||
_socketBufferedSend(data);
|
|
||||||
_socketFlushBuffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Routine Description:
|
|
||||||
// - Reads bytes from the socket into the given array.
|
|
||||||
// Arguments:
|
|
||||||
// - buffer - The array of bytes to use for storage
|
|
||||||
// Return Value:
|
|
||||||
// - The number of bytes actually read (less than or equal to input array size)
|
|
||||||
size_t TelnetConnection::_socketReceive(gsl::span<telnetpp::byte> buffer)
|
|
||||||
{
|
|
||||||
const auto bytesLoaded = _reader.LoadAsync(gsl::narrow<uint32_t>(buffer.size())).get();
|
|
||||||
|
|
||||||
// winrt::array_view, despite having a pointer and size constructor
|
|
||||||
// hides it as protected.
|
|
||||||
// So we have to get first/last (even though cppcorechecks will be
|
|
||||||
// mad at us for it) to use a public array_view constructor.
|
|
||||||
// The WinRT team isn't fixing this because std::span is coming
|
|
||||||
// soon and that will do it.
|
|
||||||
#pragma warning(push)
|
|
||||||
#pragma warning(disable : 26481)
|
|
||||||
const auto first = buffer.data();
|
|
||||||
const auto last = first + bytesLoaded;
|
|
||||||
#pragma warning(pop)
|
|
||||||
|
|
||||||
const winrt::array_view<uint8_t> arrayView(first, last);
|
|
||||||
_reader.ReadBytes(arrayView);
|
|
||||||
return bytesLoaded;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Routine Description:
|
|
||||||
// - Called by telnetpp framework when application data is received on the channel
|
|
||||||
// In contrast, telnet metadata payload is consumed by telnetpp and not forwarded to us.
|
|
||||||
// Arguments:
|
|
||||||
// - data - The relevant application-level payload received
|
|
||||||
// - send - A function where we can send a reply to given data immediately
|
|
||||||
// in reaction to the received message.
|
|
||||||
// Return Value:
|
|
||||||
// - <none>
|
|
||||||
void TelnetConnection::_applicationReceive(telnetpp::bytes data,
|
|
||||||
std::function<void(telnetpp::bytes)> const& /*send*/)
|
|
||||||
{
|
|
||||||
// Convert telnetpp bytes to standard string_view
|
|
||||||
#pragma warning(suppress : 26490) // Using something that isn't reinterpret_cast to forward stream bytes is more clumsy than just using it.
|
|
||||||
const auto stringView = std::string_view{ reinterpret_cast<const char*>(data.data()), gsl::narrow<size_t>(data.size()) };
|
|
||||||
|
|
||||||
// Convert to hstring
|
|
||||||
const auto hstr = winrt::to_hstring(stringView);
|
|
||||||
|
|
||||||
// Pass the output to our registered event handlers
|
|
||||||
_TerminalOutputHandlers(hstr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
// Copyright (c) Microsoft Corporation.
|
|
||||||
// Licensed under the MIT license.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "TelnetConnection.g.h"
|
|
||||||
|
|
||||||
#include <mutex>
|
|
||||||
#include <condition_variable>
|
|
||||||
|
|
||||||
#pragma warning(push)
|
|
||||||
#pragma warning(disable : 4100)
|
|
||||||
#pragma warning(disable : 4251)
|
|
||||||
#include <telnetpp/core.hpp>
|
|
||||||
#include <telnetpp/session.hpp>
|
|
||||||
#include <telnetpp/options/naws/server.hpp>
|
|
||||||
#pragma warning(pop)
|
|
||||||
|
|
||||||
#include "winrt/Windows.Networking.Sockets.h"
|
|
||||||
#include "winrt/Windows.Storage.Streams.h"
|
|
||||||
|
|
||||||
#include "../cascadia/inc/cppwinrt_utils.h"
|
|
||||||
#include "ConnectionStateHolder.h"
|
|
||||||
|
|
||||||
namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
|
||||||
{
|
|
||||||
struct TelnetConnection : TelnetConnectionT<TelnetConnection>, ConnectionStateHolder<TelnetConnection>
|
|
||||||
{
|
|
||||||
TelnetConnection(const hstring& uri);
|
|
||||||
|
|
||||||
void Start();
|
|
||||||
void WriteInput(hstring const& data);
|
|
||||||
void Resize(uint32_t rows, uint32_t columns);
|
|
||||||
void Close();
|
|
||||||
|
|
||||||
WINRT_CALLBACK(TerminalOutput, TerminalOutputHandler);
|
|
||||||
|
|
||||||
private:
|
|
||||||
hstring _uri;
|
|
||||||
|
|
||||||
void _applicationReceive(telnetpp::bytes data,
|
|
||||||
std::function<void(telnetpp::bytes)> const& send);
|
|
||||||
|
|
||||||
void _socketBufferedSend(telnetpp::bytes data);
|
|
||||||
fire_and_forget _socketFlushBuffer();
|
|
||||||
void _socketSend(telnetpp::bytes data);
|
|
||||||
size_t _socketReceive(gsl::span<telnetpp::byte> buffer);
|
|
||||||
|
|
||||||
telnetpp::session _session;
|
|
||||||
// NAWS = Negotiation About Window Size
|
|
||||||
telnetpp::options::naws::server _nawsServer;
|
|
||||||
Windows::Networking::Sockets::StreamSocket _socket;
|
|
||||||
Windows::Storage::Streams::DataWriter _writer;
|
|
||||||
Windows::Storage::Streams::DataReader _reader;
|
|
||||||
|
|
||||||
std::optional<std::pair<uint32_t, uint32_t>> _prevResize;
|
|
||||||
|
|
||||||
static constexpr size_t _receiveBufferSize = 1024;
|
|
||||||
std::array<telnetpp::byte, _receiveBufferSize> _receiveBuffer;
|
|
||||||
|
|
||||||
wil::unique_handle _hOutputThread;
|
|
||||||
|
|
||||||
DWORD _outputThread();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace winrt::Microsoft::Terminal::TerminalConnection::factory_implementation
|
|
||||||
{
|
|
||||||
struct TelnetConnection : TelnetConnectionT<TelnetConnection, implementation::TelnetConnection>
|
|
||||||
{
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
// Copyright (c) Microsoft Corporation.
|
|
||||||
// Licensed under the MIT license.
|
|
||||||
|
|
||||||
import "ITerminalConnection.idl";
|
|
||||||
|
|
||||||
namespace Microsoft.Terminal.TerminalConnection
|
|
||||||
{
|
|
||||||
[default_interface]
|
|
||||||
runtimeclass TelnetConnection : ITerminalConnection
|
|
||||||
{
|
|
||||||
TelnetConnection(String uri);
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -28,9 +28,6 @@
|
|||||||
<ClInclude Include="EchoConnection.h">
|
<ClInclude Include="EchoConnection.h">
|
||||||
<DependentUpon>EchoConnection.idl</DependentUpon>
|
<DependentUpon>EchoConnection.idl</DependentUpon>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="TelnetConnection.h">
|
|
||||||
<DependentUpon>TelnetConnection.idl</DependentUpon>
|
|
||||||
</ClInclude>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="init.cpp" />
|
<ClCompile Include="init.cpp" />
|
||||||
@@ -47,16 +44,12 @@
|
|||||||
<DependentUpon>ConptyConnection.idl</DependentUpon>
|
<DependentUpon>ConptyConnection.idl</DependentUpon>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
|
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
|
||||||
<ClCompile Include="TelnetConnection.cpp">
|
|
||||||
<DependentUpon>TelnetConnection.idl</DependentUpon>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Midl Include="ITerminalConnection.idl" />
|
<Midl Include="ITerminalConnection.idl" />
|
||||||
<Midl Include="ConptyConnection.idl" />
|
<Midl Include="ConptyConnection.idl" />
|
||||||
<Midl Include="EchoConnection.idl" />
|
<Midl Include="EchoConnection.idl" />
|
||||||
<Midl Include="AzureConnection.idl" />
|
<Midl Include="AzureConnection.idl" />
|
||||||
<Midl Include="TelnetConnection.idl" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PRIResource Include="Resources\en-US\Resources.resw" />
|
<PRIResource Include="Resources\en-US\Resources.resw" />
|
||||||
@@ -88,14 +81,12 @@
|
|||||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Error Condition="!Exists('..\..\..\packages\vcpkg-cpprestsdk.2.10.14\build\native\vcpkg-cpprestsdk.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\vcpkg-cpprestsdk.2.10.14\build\native\vcpkg-cpprestsdk.targets'))" />
|
<Error Condition="!Exists('..\..\..\packages\vcpkg-cpprestsdk.2.10.14\build\native\vcpkg-cpprestsdk.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\vcpkg-cpprestsdk.2.10.14\build\native\vcpkg-cpprestsdk.targets'))" />
|
||||||
<Error Condition="!Exists('..\..\..\packages\vcpkg-telnetpp.1.0.1\build\native\vcpkg-telnetpp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\vcpkg-telnetpp.1.0.1\build\native\vcpkg-telnetpp.targets'))" />
|
|
||||||
</Target>
|
</Target>
|
||||||
<ItemDefinitionGroup>
|
<ItemDefinitionGroup>
|
||||||
<Link>
|
<Link>
|
||||||
<AdditionalDependencies>$(OpenConsoleCommonOutDir)\conptylib.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>$(OpenConsoleCommonOutDir)\conptylib.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<Import Project="..\..\..\packages\vcpkg-telnetpp.1.0.1\build\native\vcpkg-telnetpp.targets" Condition="Exists('..\..\..\packages\vcpkg-telnetpp.1.0.1\build\native\vcpkg-telnetpp.targets')" />
|
|
||||||
|
|
||||||
<Import Project="$(SolutionDir)build\rules\CollectWildcardResources.targets" />
|
<Import Project="$(SolutionDir)build\rules\CollectWildcardResources.targets" />
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -18,21 +18,18 @@
|
|||||||
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
|
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
|
||||||
<ClCompile Include="AzureConnection.cpp" />
|
<ClCompile Include="AzureConnection.cpp" />
|
||||||
<ClCompile Include="init.cpp" />
|
<ClCompile Include="init.cpp" />
|
||||||
<ClCompile Include="TelnetConnection.cpp" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="pch.h" />
|
<ClInclude Include="pch.h" />
|
||||||
<ClInclude Include="EchoConnection.h" />
|
<ClInclude Include="EchoConnection.h" />
|
||||||
<ClInclude Include="AzureConnection.h" />
|
<ClInclude Include="AzureConnection.h" />
|
||||||
<ClInclude Include="AzureClientID.h" />
|
<ClInclude Include="AzureClientID.h" />
|
||||||
<ClInclude Include="TelnetConnection.h" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Midl Include="ITerminalConnection.idl" />
|
<Midl Include="ITerminalConnection.idl" />
|
||||||
<Midl Include="EchoConnection.idl" />
|
<Midl Include="EchoConnection.idl" />
|
||||||
<Midl Include="AzureConnection.idl" />
|
<Midl Include="AzureConnection.idl" />
|
||||||
<Midl Include="ConptyConnection.idl" />
|
<Midl Include="ConptyConnection.idl" />
|
||||||
<Midl Include="TelnetConnection.idl" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include <LibraryResources.h>
|
#include <LibraryResources.h>
|
||||||
|
#include <WilErrorReporting.h>
|
||||||
|
|
||||||
// Note: Generate GUID using TlgGuid.exe tool
|
// Note: Generate GUID using TlgGuid.exe tool
|
||||||
#pragma warning(suppress : 26477) // One of the macros uses 0/NULL. We don't have control to make it nullptr.
|
#pragma warning(suppress : 26477) // One of the macros uses 0/NULL. We don't have control to make it nullptr.
|
||||||
@@ -21,6 +22,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD reason, LPVOID /*reserved*/)
|
|||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
DisableThreadLibraryCalls(hInstDll);
|
DisableThreadLibraryCalls(hInstDll);
|
||||||
TraceLoggingRegister(g_hTerminalConnectionProvider);
|
TraceLoggingRegister(g_hTerminalConnectionProvider);
|
||||||
|
Microsoft::Console::ErrorReporting::EnableFallbackFailureReporting(g_hTerminalConnectionProvider);
|
||||||
break;
|
break;
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
if (g_hTerminalConnectionProvider)
|
if (g_hTerminalConnectionProvider)
|
||||||
|
|||||||
@@ -2,5 +2,4 @@
|
|||||||
<packages>
|
<packages>
|
||||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.200316.3" targetFramework="native" />
|
<package id="Microsoft.Windows.CppWinRT" version="2.0.200316.3" targetFramework="native" />
|
||||||
<package id="vcpkg-cpprestsdk" version="2.10.14" targetFramework="native" />
|
<package id="vcpkg-cpprestsdk" version="2.10.14" targetFramework="native" />
|
||||||
<package id="vcpkg-telnetpp" version="1.0.1" targetFramework="native" />
|
</packages>
|
||||||
</packages>
|
|
||||||
|
|||||||
@@ -10,8 +10,6 @@
|
|||||||
// Needs to be defined or we get redeclaration errors
|
// Needs to be defined or we get redeclaration errors
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
|
||||||
#define BLOCK_GSL
|
|
||||||
|
|
||||||
// Manually include til after we include Windows.Foundation to give it winrt superpowers
|
// Manually include til after we include Windows.Foundation to give it winrt superpowers
|
||||||
#define BLOCK_TIL
|
#define BLOCK_TIL
|
||||||
#include <LibraryIncludes.h>
|
#include <LibraryIncludes.h>
|
||||||
|
|||||||
@@ -176,6 +176,6 @@
|
|||||||
<value>Resume</value>
|
<value>Resume</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="HowToOpenRun.Text" xml:space="preserve">
|
<data name="HowToOpenRun.Text" xml:space="preserve">
|
||||||
<value>ctrl+click to follow link</value>
|
<value>Ctrl+Click to follow link</value>
|
||||||
</data>
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||||||
_actualFont{ DEFAULT_FONT_FACE, 0, DEFAULT_FONT_WEIGHT, { 0, DEFAULT_FONT_SIZE }, CP_UTF8, false },
|
_actualFont{ DEFAULT_FONT_FACE, 0, DEFAULT_FONT_WEIGHT, { 0, DEFAULT_FONT_SIZE }, CP_UTF8, false },
|
||||||
_touchAnchor{ std::nullopt },
|
_touchAnchor{ std::nullopt },
|
||||||
_cursorTimer{},
|
_cursorTimer{},
|
||||||
|
_blinkTimer{},
|
||||||
_lastMouseClickTimestamp{},
|
_lastMouseClickTimestamp{},
|
||||||
_lastMouseClickPos{},
|
_lastMouseClickPos{},
|
||||||
_selectionNeedsToBeCopied{ false },
|
_selectionNeedsToBeCopied{ false },
|
||||||
@@ -721,6 +722,24 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||||||
_cursorTimer = std::nullopt;
|
_cursorTimer = std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set up blinking attributes
|
||||||
|
BOOL animationsEnabled = TRUE;
|
||||||
|
SystemParametersInfoW(SPI_GETCLIENTAREAANIMATION, 0, &animationsEnabled, 0);
|
||||||
|
if (animationsEnabled && blinkTime != INFINITE)
|
||||||
|
{
|
||||||
|
// Create a timer
|
||||||
|
DispatcherTimer blinkTimer;
|
||||||
|
blinkTimer.Interval(std::chrono::milliseconds(blinkTime));
|
||||||
|
blinkTimer.Tick({ get_weak(), &TermControl::_BlinkTimerTick });
|
||||||
|
blinkTimer.Start();
|
||||||
|
_blinkTimer.emplace(std::move(blinkTimer));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// The user has disabled blinking
|
||||||
|
_blinkTimer = std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
// import value from WinUser (convert from milli-seconds to micro-seconds)
|
// import value from WinUser (convert from milli-seconds to micro-seconds)
|
||||||
_multiClickTimer = GetDoubleClickTime() * 1000;
|
_multiClickTimer = GetDoubleClickTime() * 1000;
|
||||||
|
|
||||||
@@ -873,7 +892,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||||||
// keybindings on the keyUp, then we'll still send the keydown to the
|
// keybindings on the keyUp, then we'll still send the keydown to the
|
||||||
// connected terminal application, and something like ctrl+shift+T will
|
// connected terminal application, and something like ctrl+shift+T will
|
||||||
// emit a ^T to the pipe.
|
// emit a ^T to the pipe.
|
||||||
if (!modifiers.IsAltGrPressed() && keyDown && _TryHandleKeyBinding(vkey, modifiers))
|
if (!modifiers.IsAltGrPressed() && keyDown && _TryHandleKeyBinding(vkey, scanCode, modifiers))
|
||||||
{
|
{
|
||||||
e.Handled(true);
|
e.Handled(true);
|
||||||
return;
|
return;
|
||||||
@@ -895,8 +914,9 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||||||
// - Attempt to handle this key combination as a key binding
|
// - Attempt to handle this key combination as a key binding
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// - vkey: The vkey of the key pressed.
|
// - vkey: The vkey of the key pressed.
|
||||||
|
// - scanCode: The scan code of the key pressed.
|
||||||
// - modifiers: The ControlKeyStates representing the modifier key states.
|
// - modifiers: The ControlKeyStates representing the modifier key states.
|
||||||
bool TermControl::_TryHandleKeyBinding(const WORD vkey, ::Microsoft::Terminal::Core::ControlKeyStates modifiers) const
|
bool TermControl::_TryHandleKeyBinding(const WORD vkey, const WORD scanCode, ::Microsoft::Terminal::Core::ControlKeyStates modifiers) const
|
||||||
{
|
{
|
||||||
auto bindings = _settings.KeyBindings();
|
auto bindings = _settings.KeyBindings();
|
||||||
if (!bindings)
|
if (!bindings)
|
||||||
@@ -904,12 +924,44 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bindings.TryKeyChord({
|
auto success = bindings.TryKeyChord({
|
||||||
modifiers.IsCtrlPressed(),
|
modifiers.IsCtrlPressed(),
|
||||||
modifiers.IsAltPressed(),
|
modifiers.IsAltPressed(),
|
||||||
modifiers.IsShiftPressed(),
|
modifiers.IsShiftPressed(),
|
||||||
vkey,
|
vkey,
|
||||||
});
|
});
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let's assume the user has bound the dead key "^" to a sendInput command that sends "b".
|
||||||
|
// If the user presses the two keys "^a" it'll produce "bâ", despite us marking the key event as handled.
|
||||||
|
// The following is used to manually "consume" such dead keys and clear them from the keyboard state.
|
||||||
|
_ClearKeyboardState(vkey, scanCode);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method Description:
|
||||||
|
// - Discards currently pressed dead keys.
|
||||||
|
// Arguments:
|
||||||
|
// - vkey: The vkey of the key pressed.
|
||||||
|
// - scanCode: The scan code of the key pressed.
|
||||||
|
void TermControl::_ClearKeyboardState(const WORD vkey, const WORD scanCode) const noexcept
|
||||||
|
{
|
||||||
|
std::array<BYTE, 256> keyState;
|
||||||
|
if (!GetKeyboardState(keyState.data()))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// As described in "Sometimes you *want* to interfere with the keyboard's state buffer":
|
||||||
|
// http://archives.miloush.net/michkap/archive/2006/09/10/748775.html
|
||||||
|
// > "The key here is to keep trying to pass stuff to ToUnicode until -1 is not returned."
|
||||||
|
std::array<wchar_t, 16> buffer;
|
||||||
|
while (ToUnicodeEx(vkey, scanCode, keyState.data(), buffer.data(), gsl::narrow_cast<int>(buffer.size()), 0b1, nullptr) < 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
@@ -919,6 +971,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||||||
// - Makes the cursor briefly visible during typing.
|
// - Makes the cursor briefly visible during typing.
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// - vkey: The vkey of the key pressed.
|
// - vkey: The vkey of the key pressed.
|
||||||
|
// - scanCode: The scan code of the key pressed.
|
||||||
// - states: The Microsoft::Terminal::Core::ControlKeyStates representing the modifier key states.
|
// - states: The Microsoft::Terminal::Core::ControlKeyStates representing the modifier key states.
|
||||||
// - keyDown: If true, the key was pressed, otherwise the key was released.
|
// - keyDown: If true, the key was pressed, otherwise the key was released.
|
||||||
bool TermControl::_TrySendKeyEvent(const WORD vkey,
|
bool TermControl::_TrySendKeyEvent(const WORD vkey,
|
||||||
@@ -931,8 +984,9 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||||||
// flow through to the terminal.
|
// flow through to the terminal.
|
||||||
// GH#6423 - don't dismiss selection if the key that was pressed was a
|
// GH#6423 - don't dismiss selection if the key that was pressed was a
|
||||||
// modifier key. We'll wait for a real keystroke to dismiss the
|
// modifier key. We'll wait for a real keystroke to dismiss the
|
||||||
|
// GH #7395 - don't dismiss selection when taking PrintScreen
|
||||||
// selection.
|
// selection.
|
||||||
if (_terminal->IsSelectionActive() && !KeyEvent::IsModifierKey(vkey))
|
if (_terminal->IsSelectionActive() && !KeyEvent::IsModifierKey(vkey) && vkey != VK_SNAPSHOT)
|
||||||
{
|
{
|
||||||
_terminal->ClearSelection();
|
_terminal->ClearSelection();
|
||||||
_renderer->TriggerSelection();
|
_renderer->TriggerSelection();
|
||||||
@@ -1777,6 +1831,11 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||||||
_cursorTimer.value().Start();
|
_cursorTimer.value().Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_blinkTimer.has_value())
|
||||||
|
{
|
||||||
|
_blinkTimer.value().Start();
|
||||||
|
}
|
||||||
|
|
||||||
_UpdateSystemParameterSettings();
|
_UpdateSystemParameterSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1822,6 +1881,11 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||||||
_cursorTimer.value().Stop();
|
_cursorTimer.value().Stop();
|
||||||
_terminal->SetCursorOn(false);
|
_terminal->SetCursorOn(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_blinkTimer.has_value())
|
||||||
|
{
|
||||||
|
_blinkTimer.value().Stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
@@ -2035,6 +2099,22 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||||||
_terminal->SetCursorOn(!_terminal->IsCursorOn());
|
_terminal->SetCursorOn(!_terminal->IsCursorOn());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Method Description:
|
||||||
|
// - Toggle the blinking rendition state when called by the blink timer.
|
||||||
|
// Arguments:
|
||||||
|
// - sender: not used
|
||||||
|
// - e: not used
|
||||||
|
void TermControl::_BlinkTimerTick(Windows::Foundation::IInspectable const& /* sender */,
|
||||||
|
Windows::Foundation::IInspectable const& /* e */)
|
||||||
|
{
|
||||||
|
if (!_closing)
|
||||||
|
{
|
||||||
|
auto& renderTarget = *_renderer;
|
||||||
|
auto& blinkingState = _terminal->GetBlinkingState();
|
||||||
|
blinkingState.ToggleBlinkingRendition(renderTarget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - Sets selection's end position to match supplied cursor position, e.g. while mouse dragging.
|
// - Sets selection's end position to match supplied cursor position, e.g. while mouse dragging.
|
||||||
// Arguments:
|
// Arguments:
|
||||||
@@ -2889,10 +2969,20 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||||||
// - Checks if the uri is valid and sends an event if so
|
// - Checks if the uri is valid and sends an event if so
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// - The uri
|
// - The uri
|
||||||
void TermControl::_HyperlinkHandler(const std::wstring_view uri)
|
winrt::fire_and_forget TermControl::_HyperlinkHandler(const std::wstring_view uri)
|
||||||
{
|
{
|
||||||
auto hyperlinkArgs = winrt::make_self<OpenHyperlinkEventArgs>(winrt::hstring{ uri });
|
// Save things we need to resume later.
|
||||||
_openHyperlinkHandlers(*this, *hyperlinkArgs);
|
winrt::hstring heldUri{ uri };
|
||||||
|
auto strongThis{ get_strong() };
|
||||||
|
|
||||||
|
// Pop the rest of this function to the tail of the UI thread
|
||||||
|
// Just in case someone was holding a lock when they called us and
|
||||||
|
// the handlers decide to do something that take another lock
|
||||||
|
// (like ShellExecute pumping our messaging thread...GH#7994)
|
||||||
|
co_await Dispatcher();
|
||||||
|
|
||||||
|
auto hyperlinkArgs = winrt::make_self<OpenHyperlinkEventArgs>(heldUri);
|
||||||
|
_openHyperlinkHandlers(*strongThis, *hyperlinkArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user