mirror of
https://github.com/microsoft/terminal.git
synced 2026-04-07 06:39:44 +00:00
Compare commits
24 Commits
dev/lhecke
...
dev/cazamo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9445c7e93e | ||
|
|
f0e47ed32f | ||
|
|
70ee1578f5 | ||
|
|
0f04f8b7fe | ||
|
|
73be370e89 | ||
|
|
9c61dcfcfe | ||
|
|
47458ae7f7 | ||
|
|
783b479606 | ||
|
|
997b4acce5 | ||
|
|
287db8a483 | ||
|
|
07f7717112 | ||
|
|
39c71d6421 | ||
|
|
c0e6c259fc | ||
|
|
6d636056a0 | ||
|
|
20a6c7078b | ||
|
|
eec6a882d6 | ||
|
|
bc9e43a19d | ||
|
|
858359e62e | ||
|
|
5fbd5392e7 | ||
|
|
28284e824f | ||
|
|
61e6927f34 | ||
|
|
95693e9079 | ||
|
|
eb40b51b79 | ||
|
|
521d968a75 |
15
.github/actions/spelling/README.md
vendored
Normal file
15
.github/actions/spelling/README.md
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
# check-spelling/check-spelling configuration
|
||||
|
||||
File | Purpose | Format | Info
|
||||
-|-|-|-
|
||||
[allow/*.txt](allow/) | Add words to the dictionary | one word per line (only letters and `'`s allowed) | [allow](https://github.com/check-spelling/check-spelling/wiki/Configuration#allow)
|
||||
[reject.txt](reject.txt) | Remove words from the dictionary (after allow) | grep pattern matching whole dictionary words | [reject](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-reject)
|
||||
[excludes.txt](excludes.txt) | Files to ignore entirely | perl regular expression | [excludes](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-excludes)
|
||||
[patterns/*.txt](patterns/) | Patterns to ignore from checked lines | perl regular expression (order matters, first match wins) | [patterns](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-patterns)
|
||||
[candidate.patterns](candidate.patterns) | Patterns that might be worth adding to [patterns.txt](patterns.txt) | perl regular expression with optional comment block introductions (all matches will be suggested) | [candidates](https://github.com/check-spelling/check-spelling/wiki/Feature:-Suggest-patterns)
|
||||
[line_forbidden.patterns](line_forbidden.patterns) | Patterns to flag in checked lines | perl regular expression (order matters, first match wins) | [patterns](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-patterns)
|
||||
[expect/*.txt](expect.txt) | Expected words that aren't in the dictionary | one word per line (sorted, alphabetically) | [expect](https://github.com/check-spelling/check-spelling/wiki/Configuration#expect)
|
||||
[advice.md](advice.md) | Supplement for GitHub comment when unrecognized words are found | GitHub Markdown | [advice](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-advice)
|
||||
|
||||
Note: you can replace any of these files with a directory by the same name (minus the suffix)
|
||||
and then include multiple files inside that directory (with that suffix) to merge multiple files together.
|
||||
38
.github/actions/spelling/advice.md
vendored
38
.github/actions/spelling/advice.md
vendored
@@ -1,4 +1,4 @@
|
||||
<!-- markdownlint-disable MD033 MD041 -->
|
||||
<!-- See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-advice --> <!-- markdownlint-disable MD033 MD041 -->
|
||||
<details>
|
||||
<summary>
|
||||
:pencil2: Contributor please read this
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
By default the command suggestion will generate a file named based on your commit. That's generally ok as long as you add the file to your commit. Someone can reorganize it later.
|
||||
|
||||
:warning: The command is written for posix shells. You can copy the contents of each `perl` command excluding the outer `'` marks and dropping any `'"`/`"'` quotation mark pairs into a file and then run `perl file.pl` from the root of the repository to run the code. Alternatively, you can manually insert the items...
|
||||
:warning: The command is written for posix shells. If it doesn't work for you, you can manually _add_ (one word per line) / _remove_ items to `expect.txt` and the `excludes.txt` files.
|
||||
|
||||
If the listed items are:
|
||||
|
||||
@@ -20,31 +20,29 @@ See the `README.md` in each directory for more information.
|
||||
|
||||
:microscope: You can test your commits **without** *appending* to a PR by creating a new branch with that extra change and pushing it to your fork. The [check-spelling](https://github.com/marketplace/actions/check-spelling) action will run in response to your **push** -- it doesn't require an open pull request. By using such a branch, you can limit the number of typos your peers see you make. :wink:
|
||||
|
||||
<details><summary>:clamp: If you see a bunch of garbage</summary>
|
||||
|
||||
If it relates to a ...
|
||||
<details><summary>well-formed pattern</summary>
|
||||
<details><summary>If the flagged items are :exploding_head: false positives</summary>
|
||||
|
||||
See if there's a [pattern](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns) that would match it.
|
||||
If items relate to a ...
|
||||
* binary file (or some other file you wouldn't want to check at all).
|
||||
|
||||
If not, try writing one and adding it to a `patterns/{file}.txt`.
|
||||
Please add a file path to the `excludes.txt` file matching the containing file.
|
||||
|
||||
Patterns are Perl 5 Regular Expressions - you can [test](
|
||||
https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your lines.
|
||||
|
||||
Note that patterns can't match multiline strings.
|
||||
</details>
|
||||
<details><summary>binary-ish string</summary>
|
||||
|
||||
Please add a file path to the `excludes.txt` file instead of just accepting the garbage.
|
||||
|
||||
File paths are Perl 5 Regular Expressions - you can [test](
|
||||
File paths are Perl 5 Regular Expressions - you can [test](
|
||||
https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your files.
|
||||
|
||||
`^` refers to the file's path from the root of the repository, so `^README\.md$` would exclude [README.md](
|
||||
`^` refers to the file's path from the root of the repository, so `^README\.md$` would exclude [README.md](
|
||||
../tree/HEAD/README.md) (on whichever branch you're using).
|
||||
</details>
|
||||
|
||||
|
||||
* well-formed pattern.
|
||||
|
||||
If you can write a [pattern](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns) that would match it,
|
||||
try adding it to the `patterns.txt` file.
|
||||
|
||||
Patterns are Perl 5 Regular Expressions - you can [test](
|
||||
https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your lines.
|
||||
|
||||
Note that patterns can't match multiline strings.
|
||||
</details>
|
||||
|
||||
</details>
|
||||
|
||||
23
.github/actions/spelling/allow/allow.txt
vendored
23
.github/actions/spelling/allow/allow.txt
vendored
@@ -1,20 +1,21 @@
|
||||
admins
|
||||
apc
|
||||
allcolors
|
||||
Apc
|
||||
bsd
|
||||
apc
|
||||
breadcrumb
|
||||
breadcrumbs
|
||||
bsd
|
||||
calt
|
||||
CMMI
|
||||
ccmp
|
||||
changelog
|
||||
clickable
|
||||
clig
|
||||
CMMI
|
||||
copyable
|
||||
cybersecurity
|
||||
dalet
|
||||
dcs
|
||||
Dcs
|
||||
dcs
|
||||
dialytika
|
||||
dje
|
||||
downside
|
||||
@@ -26,15 +27,19 @@ EDDC
|
||||
Enum'd
|
||||
Fitt
|
||||
formattings
|
||||
FTCS
|
||||
ftp
|
||||
fvar
|
||||
gantt
|
||||
gcc
|
||||
geeksforgeeks
|
||||
ghe
|
||||
github
|
||||
gje
|
||||
godbolt
|
||||
hostname
|
||||
hostnames
|
||||
https
|
||||
hyperlink
|
||||
hyperlinking
|
||||
hyperlinks
|
||||
@@ -44,19 +49,21 @@ inlined
|
||||
It'd
|
||||
kje
|
||||
libfuzzer
|
||||
libuv
|
||||
liga
|
||||
lje
|
||||
Llast
|
||||
llvm
|
||||
Lmid
|
||||
locl
|
||||
lol
|
||||
lorem
|
||||
Lorigin
|
||||
maxed
|
||||
minimalistic
|
||||
mkmk
|
||||
mnt
|
||||
mru
|
||||
noreply
|
||||
nje
|
||||
noreply
|
||||
ogonek
|
||||
@@ -77,13 +84,16 @@ runtimes
|
||||
shcha
|
||||
slnt
|
||||
Sos
|
||||
ssh
|
||||
timeline
|
||||
timelines
|
||||
timestamped
|
||||
TLDR
|
||||
tokenizes
|
||||
tonos
|
||||
toolset
|
||||
tshe
|
||||
ubuntu
|
||||
uiatextrange
|
||||
UIs
|
||||
und
|
||||
@@ -92,6 +102,7 @@ versioned
|
||||
vsdevcmd
|
||||
We'd
|
||||
wildcards
|
||||
XBox
|
||||
YBox
|
||||
yeru
|
||||
zhe
|
||||
allcolors
|
||||
|
||||
24
.github/actions/spelling/allow/apis.txt
vendored
24
.github/actions/spelling/allow/apis.txt
vendored
@@ -5,6 +5,7 @@ aclapi
|
||||
alignas
|
||||
alignof
|
||||
APPLYTOSUBMENUS
|
||||
appxrecipe
|
||||
bitfield
|
||||
bitfields
|
||||
BUILDBRANCH
|
||||
@@ -14,6 +15,7 @@ BYCOMMAND
|
||||
BYPOSITION
|
||||
charconv
|
||||
CLASSNOTAVAILABLE
|
||||
CLOSEAPP
|
||||
cmdletbinding
|
||||
COLORPROPERTY
|
||||
colspan
|
||||
@@ -28,10 +30,14 @@ dataobject
|
||||
dcomp
|
||||
DERR
|
||||
dlldata
|
||||
DNE
|
||||
DONTADDTORECENT
|
||||
DWORDLONG
|
||||
DWMSBT
|
||||
DWMWA
|
||||
DWMWA
|
||||
DWORDLONG
|
||||
endfor
|
||||
ENDSESSION
|
||||
enumset
|
||||
environstrings
|
||||
EXPCMDFLAGS
|
||||
@@ -71,6 +77,7 @@ IDirect
|
||||
IExplorer
|
||||
IFACEMETHOD
|
||||
IFile
|
||||
IGraphics
|
||||
IInheritable
|
||||
IMap
|
||||
IMonarch
|
||||
@@ -85,6 +92,7 @@ istream
|
||||
IStringable
|
||||
ITab
|
||||
ITaskbar
|
||||
itow
|
||||
IUri
|
||||
IVirtual
|
||||
KEYSELECT
|
||||
@@ -96,12 +104,15 @@ lround
|
||||
Lsa
|
||||
lsass
|
||||
LSHIFT
|
||||
LTGRAY
|
||||
MAINWINDOW
|
||||
memchr
|
||||
memicmp
|
||||
MENUCOMMAND
|
||||
MENUDATA
|
||||
MENUITEMINFOW
|
||||
MENUINFO
|
||||
MENUITEMINFOW
|
||||
mmeapi
|
||||
MOUSELEAVE
|
||||
mov
|
||||
mptt
|
||||
@@ -137,16 +148,18 @@ OUTLINETEXTMETRICW
|
||||
overridable
|
||||
PACL
|
||||
PAGESCROLL
|
||||
PATINVERT
|
||||
PEXPLICIT
|
||||
PICKFOLDERS
|
||||
pmr
|
||||
ptstr
|
||||
QUERYENDSESSION
|
||||
rcx
|
||||
REGCLS
|
||||
RETURNCMD
|
||||
rfind
|
||||
roundf
|
||||
ROOTOWNER
|
||||
roundf
|
||||
RSHIFT
|
||||
SACL
|
||||
schandle
|
||||
@@ -155,7 +168,6 @@ serializer
|
||||
SETVERSION
|
||||
SHELLEXECUTEINFOW
|
||||
shobjidl
|
||||
SHOWDEFAULT
|
||||
SHOWHIDE
|
||||
SHOWMINIMIZED
|
||||
SHOWTIP
|
||||
@@ -177,6 +189,8 @@ Stubless
|
||||
Subheader
|
||||
Subpage
|
||||
syscall
|
||||
SYSTEMBACKDROP
|
||||
TABROW
|
||||
TASKBARCREATED
|
||||
TBPF
|
||||
THEMECHANGED
|
||||
@@ -196,6 +210,8 @@ UOI
|
||||
UPDATEINIFILE
|
||||
userenv
|
||||
USEROBJECTFLAGS
|
||||
Viewbox
|
||||
virtualalloc
|
||||
wcsstr
|
||||
wcstoui
|
||||
winmain
|
||||
|
||||
2
.github/actions/spelling/allow/names.txt
vendored
2
.github/actions/spelling/allow/names.txt
vendored
@@ -69,6 +69,8 @@ Rincewind
|
||||
rprichard
|
||||
Schoonover
|
||||
shadertoy
|
||||
Shomnipotence
|
||||
simioni
|
||||
Somuah
|
||||
sonph
|
||||
sonpham
|
||||
|
||||
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-)/
|
||||
44
.github/actions/spelling/excludes.txt
vendored
44
.github/actions/spelling/excludes.txt
vendored
@@ -1,28 +1,39 @@
|
||||
# See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-excludes
|
||||
(?:(?i)\.png$)
|
||||
(?:^|/)(?i)COPYRIGHT
|
||||
(?:^|/)(?i)LICEN[CS]E
|
||||
(?:^|/)3rdparty/
|
||||
(?:^|/)dirs$
|
||||
(?:^|/)go\.mod$
|
||||
(?:^|/)go\.sum$
|
||||
(?:^|/)package-lock\.json$
|
||||
(?:^|/)package(?:-lock|)\.json$
|
||||
(?:^|/)sources(?:|\.dep)$
|
||||
SUMS$
|
||||
(?:^|/)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$
|
||||
@@ -30,28 +41,52 @@ SUMS$
|
||||
\.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/
|
||||
@@ -78,6 +113,5 @@ SUMS$
|
||||
^src/tools/U8U16Test/(?:fr|ru|zh)\.txt$
|
||||
^src/types/ut_types/UtilsTests.cpp$
|
||||
^tools/ReleaseEngineering/ServicingPipeline.ps1$
|
||||
^\.github/actions/spelling/
|
||||
^\.gitignore$
|
||||
^\XamlStyler.json$
|
||||
ignore$
|
||||
SUMS$
|
||||
|
||||
8
.github/actions/spelling/expect/alphabet.txt
vendored
8
.github/actions/spelling/expect/alphabet.txt
vendored
@@ -5,26 +5,19 @@ AAAAAABBBBBBCCC
|
||||
AAAAABBBBBBCCC
|
||||
abcd
|
||||
abcd
|
||||
abcde
|
||||
abcdef
|
||||
ABCDEFG
|
||||
ABCDEFGH
|
||||
ABCDEFGHIJ
|
||||
abcdefghijk
|
||||
ABCDEFGHIJKLMNO
|
||||
abcdefghijklmnop
|
||||
ABCDEFGHIJKLMNOPQRST
|
||||
abcdefghijklmnopqrstuvwxyz
|
||||
ABCG
|
||||
ABE
|
||||
abf
|
||||
BBBBB
|
||||
BBBBBBBB
|
||||
BBBBBBBBBBBBBBDDDD
|
||||
BBBBBCCC
|
||||
BBBBCCCCC
|
||||
BBGGRR
|
||||
CCE
|
||||
EFG
|
||||
EFGh
|
||||
QQQQQQQQQQABCDEFGHIJ
|
||||
@@ -33,7 +26,6 @@ QQQQQQQQQQABCDEFGHIJKLMNOPQRSTQQQQQQQQQQ
|
||||
QQQQQQQQQQABCDEFGHIJPQRSTQQQQQQQQQQ
|
||||
qrstuvwxyz
|
||||
qwerty
|
||||
QWERTYUIOP
|
||||
qwertyuiopasdfg
|
||||
YYYYYYYDDDDDDDDDDD
|
||||
ZAAZZ
|
||||
|
||||
882
.github/actions/spelling/expect/expect.txt
vendored
882
.github/actions/spelling/expect/expect.txt
vendored
File diff suppressed because it is too large
Load Diff
23
.github/actions/spelling/expect/web.txt
vendored
23
.github/actions/spelling/expect/web.txt
vendored
@@ -1,29 +1,6 @@
|
||||
http
|
||||
www
|
||||
easyrgb
|
||||
php
|
||||
ecma
|
||||
rapidtables
|
||||
WCAG
|
||||
freedesktop
|
||||
ycombinator
|
||||
robertelder
|
||||
kovidgoyal
|
||||
leonerd
|
||||
fixterms
|
||||
winui
|
||||
appshellintegration
|
||||
mdtauk
|
||||
cppreference
|
||||
gfycat
|
||||
Guake
|
||||
azurewebsites
|
||||
askubuntu
|
||||
dostips
|
||||
viewtopic
|
||||
rosettacode
|
||||
Rexx
|
||||
tldp
|
||||
HOWTO
|
||||
uwspace
|
||||
uwaterloo
|
||||
|
||||
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
|
||||
82
.github/actions/spelling/patterns/patterns.txt
vendored
82
.github/actions/spelling/patterns/patterns.txt
vendored
@@ -1,11 +1,6 @@
|
||||
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-]+\.|)github(?:usercontent|)\.com/[-a-zA-Z0-9?%&=_\/.+]*
|
||||
https://www.xfree86.org/[-a-zA-Z0-9?&=\/_#]*
|
||||
# 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
|
||||
@@ -28,3 +23,74 @@ vcvars\w*
|
||||
ROY\sG\.\sBIV
|
||||
!(?:(?i)ESC)!\[
|
||||
!(?:(?i)CSI)!(?:\d+(?:;\d+|)m|[ABCDF])
|
||||
|
||||
# Python stringprefix / binaryprefix
|
||||
\b(?:B|BR|Br|F|FR|Fr|R|RB|RF|Rb|Rf|U|UR|Ur|b|bR|br|f|fR|fr|r|rB|rF|rb|rf|u|uR|ur)'
|
||||
|
||||
# Automatically suggested patterns
|
||||
# hit-count: 3831 file-count: 582
|
||||
# IServiceProvider
|
||||
\bI(?=(?:[A-Z][a-z]{2,})+\b)
|
||||
|
||||
# hit-count: 71 file-count: 35
|
||||
# Compiler flags
|
||||
(?:^|[\t ,"'`=(])-[D](?=[A-Z]{2,}|[A-Z][a-z])
|
||||
(?:^|[\t ,"'`=(])-[X](?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,})
|
||||
|
||||
# hit-count: 41 file-count: 28
|
||||
# version suffix <word>v#
|
||||
(?:(?<=[A-Z]{2})V|(?<=[a-z]{2}|[A-Z]{2})v)\d+(?:\b|(?=[a-zA-Z_]))
|
||||
|
||||
# hit-count: 20 file-count: 9
|
||||
# hex runs
|
||||
\b[0-9a-fA-F]{16,}\b
|
||||
|
||||
# hit-count: 10 file-count: 7
|
||||
# uuid:
|
||||
\b[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}\b
|
||||
|
||||
# hit-count: 4 file-count: 4
|
||||
# mailto urls
|
||||
mailto:[-a-zA-Z=;:/?%&0-9+@.]{3,}
|
||||
|
||||
# hit-count: 4 file-count: 1
|
||||
# ANSI color codes
|
||||
(?:\\(?:u00|x)1b|\x1b)\[\d+(?:;\d+|)m
|
||||
|
||||
# hit-count: 2 file-count: 1
|
||||
# latex
|
||||
\\(?:n(?:ew|ormal|osub)|r(?:enew)|t(?:able(?:of|)|he|itle))(?=[a-z]+)
|
||||
|
||||
# hit-count: 1 file-count: 1
|
||||
# hex digits including css/html color classes:
|
||||
(?:[\\0][xX]|\\u|[uU]\+|#x?|\%23)[0-9_a-fA-FgGrR]*?[a-fA-FgGrR]{2,}[0-9_a-fA-FgGrR]*(?:[uUlL]{0,3}|u\d+)\b
|
||||
|
||||
# hit-count: 1 file-count: 1
|
||||
# Non-English
|
||||
[a-zA-Z]*[ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź][a-zA-Z]{3}[a-zA-ZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź]*
|
||||
|
||||
# hit-count: 1 file-count: 1
|
||||
# French
|
||||
# This corpus only had capital letters, but you probably want lowercase ones as well.
|
||||
\b[LN]'+[a-z]{2,}\b
|
||||
|
||||
# acceptable duplicates
|
||||
# ls directory listings
|
||||
[-bcdlpsw](?:[-r][-w][-sx]){3}\s+\d+\s+(\S+)\s+\g{-1}\s+\d+\s+
|
||||
# C/idl types + English ...
|
||||
\s(Guid|long|LONG|that) \g{-1}\s
|
||||
|
||||
# javadoc / .net
|
||||
(?:[\\@](?:groupname|param)|(?:public|private)(?:\s+static|\s+readonly)*)\s+(\w+)\s+\g{-1}\s
|
||||
|
||||
# Commit message -- Signed-off-by and friends
|
||||
^\s*(?:(?:Based-on-patch|Co-authored|Helped|Mentored|Reported|Reviewed|Signed-off)-by|Thanks-to): (?:[^<]*<[^>]*>|[^<]*)\s*$
|
||||
|
||||
# Autogenerated revert commit message
|
||||
^This reverts commit [0-9a-f]{40}\.$
|
||||
|
||||
# vtmode
|
||||
--vtmode\s+(\w+)\s+\g{-1}\s
|
||||
|
||||
# ignore long runs of a single character:
|
||||
\b([A-Za-z])\g{-1}{3,}\b
|
||||
|
||||
28
.github/actions/spelling/reject.txt
vendored
28
.github/actions/spelling/reject.txt
vendored
@@ -1,22 +1,12 @@
|
||||
^attache$
|
||||
^attacher$
|
||||
^attachers$
|
||||
^spae$
|
||||
^spaebook$
|
||||
^spaecraft$
|
||||
^spaed$
|
||||
^spaedom$
|
||||
^spaeing$
|
||||
^spaeings$
|
||||
^spae-man$
|
||||
^spaeman$
|
||||
^spaer$
|
||||
^Spaerobee$
|
||||
^spaes$
|
||||
^spaewife$
|
||||
^spaewoman$
|
||||
^spaework$
|
||||
^spaewright$
|
||||
^wether$
|
||||
^wethers$
|
||||
^wetherteg$
|
||||
benefitting
|
||||
occurences?
|
||||
^dependan.*
|
||||
^oer$
|
||||
Sorce
|
||||
^[Ss]pae.*
|
||||
^untill$
|
||||
^untilling$
|
||||
^wether.*
|
||||
|
||||
132
.github/workflows/spelling2.yml
vendored
132
.github/workflows/spelling2.yml
vendored
@@ -1,20 +1,134 @@
|
||||
# spelling.yml is blocked per https://github.com/check-spelling/check-spelling/security/advisories/GHSA-g86g-chm8-7r2p
|
||||
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:
|
||||
pull_request_target:
|
||||
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: checkout-merge
|
||||
if: "contains(github.event_name, 'pull_request')"
|
||||
uses: actions/checkout@v2
|
||||
- name: check-spelling
|
||||
id: spelling
|
||||
uses: check-spelling/check-spelling@v0.0.21
|
||||
with:
|
||||
ref: refs/pull/${{github.event.pull_request.number}}/merge
|
||||
- name: checkout
|
||||
if: "!contains(github.event_name, 'pull_request')"
|
||||
uses: actions/checkout@v2
|
||||
- uses: check-spelling/check-spelling@v0.0.19
|
||||
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 }}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- Optional, defaults to main. Name of the branch which will be used for calculating branch point. -->
|
||||
<PGOBranch>main</PGOBranch>
|
||||
<PGOBranch>release-1.14</PGOBranch>
|
||||
|
||||
<!-- Mandatory. Name of the NuGet package which will contain PGO databases for consumption by build system. -->
|
||||
<PGOPackageName>Microsoft.Internal.Windows.Terminal.PGODatabase</PGOPackageName>
|
||||
|
||||
@@ -1708,6 +1708,11 @@
|
||||
"description": "Force the terminal to use the legacy input encoding. Certain keys in some applications may stop working when enabling this setting.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"experimental.useBackgroundImageForWindow": {
|
||||
"default": false,
|
||||
"description": "When set to true, the background image for the currently focused profile is expanded to encompass the entire window, beneath other panes.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"initialCols": {
|
||||
"default": 120,
|
||||
"description": "The number of columns displayed in the window upon first load. If \"launchMode\" is set to \"maximized\" (or \"maximizedFocus\"), this property is ignored.",
|
||||
|
||||
@@ -1142,7 +1142,7 @@ const COORD TextBuffer::GetWordStart(const COORD target, const std::wstring_view
|
||||
// that it actually points to a space in the buffer
|
||||
copy = { bufferSize.RightInclusive(), bufferSize.BottomInclusive() };
|
||||
}
|
||||
else if (bufferSize.CompareInBounds(target, limit.to_win32_coord(), true) >= 0)
|
||||
else if (til::point{ target.X, target.Y } >= limit)
|
||||
{
|
||||
// if at/past the limit --> clamp to limit
|
||||
copy = limitOptional->to_win32_coord();
|
||||
@@ -1257,8 +1257,8 @@ const COORD TextBuffer::GetWordEnd(const COORD target, const std::wstring_view w
|
||||
|
||||
// Already at/past the limit. Can't move forward.
|
||||
const auto bufferSize{ GetSize() };
|
||||
const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
|
||||
if (bufferSize.CompareInBounds(target, limit.to_win32_coord(), true) >= 0)
|
||||
const auto limit{ limitOptional.value_or(til::point{ bufferSize.Left(), bufferSize.BottomExclusive() }) };
|
||||
if (til::point{ target.X, target.Y } >= limit)
|
||||
{
|
||||
return target;
|
||||
}
|
||||
@@ -1286,7 +1286,7 @@ const COORD TextBuffer::_GetWordEndForAccessibility(const COORD target, const st
|
||||
const auto bufferSize{ GetSize() };
|
||||
auto result{ target };
|
||||
|
||||
if (bufferSize.CompareInBounds(target, limit, true) >= 0)
|
||||
if (til::point{ target.X, target.Y } >= til::point{ limit.X, limit.Y })
|
||||
{
|
||||
// if we're already on/past the last RegularChar,
|
||||
// clamp result to that position
|
||||
@@ -1421,14 +1421,15 @@ bool TextBuffer::MoveToNextWord(COORD& pos, const std::wstring_view wordDelimite
|
||||
// This is also the inclusive start of the next word.
|
||||
const auto bufferSize{ GetSize() };
|
||||
const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
|
||||
const auto copy{ _GetWordEndForAccessibility(pos, wordDelimiters, limit.to_win32_coord()) };
|
||||
const auto copyCoord{ _GetWordEndForAccessibility(pos, wordDelimiters, limit.to_win32_coord()) };
|
||||
const til::point copy{ copyCoord.X, copyCoord.Y };
|
||||
|
||||
if (bufferSize.CompareInBounds(copy, limit.to_win32_coord(), true) >= 0)
|
||||
if (copy >= limit)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
pos = copy;
|
||||
pos = copy.to_win32_coord();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1470,7 +1471,8 @@ const til::point TextBuffer::GetGlyphStart(const til::point pos, std::optional<t
|
||||
const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
|
||||
|
||||
// Clamp pos to limit
|
||||
if (bufferSize.CompareInBounds(resultPos, limit.to_win32_coord(), true) > 0)
|
||||
// NOTE: here, pos == resultPos
|
||||
if (pos > limit)
|
||||
{
|
||||
resultPos = limit.to_win32_coord();
|
||||
}
|
||||
@@ -1498,7 +1500,7 @@ const til::point TextBuffer::GetGlyphEnd(const til::point pos, bool accessibilit
|
||||
const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
|
||||
|
||||
// Clamp pos to limit
|
||||
if (bufferSize.CompareInBounds(resultPos, limit.to_win32_coord(), true) > 0)
|
||||
if (til::point{ resultPos.X, resultPos.Y } > limit)
|
||||
{
|
||||
resultPos = limit.to_win32_coord();
|
||||
}
|
||||
@@ -1528,9 +1530,19 @@ const til::point TextBuffer::GetGlyphEnd(const til::point pos, bool accessibilit
|
||||
bool TextBuffer::MoveToNextGlyph(til::point& pos, bool allowExclusiveEnd, std::optional<til::point> limitOptional) const
|
||||
{
|
||||
const auto bufferSize = GetSize();
|
||||
const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
|
||||
bool pastEndInclusive;
|
||||
til::point limit;
|
||||
{
|
||||
// if the limit is past the end of the buffer,
|
||||
// 1) clamp limit to end of buffer
|
||||
// 2) set pastEndInclusive
|
||||
const til::point endInclusive{ bufferSize.RightInclusive(), bufferSize.BottomInclusive() };
|
||||
const auto val = limitOptional.value_or(endInclusive);
|
||||
pastEndInclusive = val > endInclusive;
|
||||
limit = pastEndInclusive ? endInclusive : val;
|
||||
}
|
||||
|
||||
const auto distanceToLimit{ bufferSize.CompareInBounds(pos.to_win32_coord(), limit.to_win32_coord(), true) };
|
||||
const auto distanceToLimit{ bufferSize.CompareInBounds(pos.to_win32_coord(), limit.to_win32_coord()) + (pastEndInclusive ? 1 : 0) };
|
||||
if (distanceToLimit >= 0)
|
||||
{
|
||||
// Corner Case: we're on/past the limit
|
||||
@@ -1573,7 +1585,7 @@ bool TextBuffer::MoveToPreviousGlyph(til::point& pos, std::optional<til::point>
|
||||
const auto bufferSize = GetSize();
|
||||
const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
|
||||
|
||||
if (bufferSize.CompareInBounds(pos.to_win32_coord(), limit.to_win32_coord(), true) > 0)
|
||||
if (pos > limit)
|
||||
{
|
||||
// we're past the end
|
||||
// clamp us to the limit
|
||||
@@ -1606,16 +1618,18 @@ bool TextBuffer::MoveToPreviousGlyph(til::point& pos, std::optional<til::point>
|
||||
// the buffer rather than the screen.
|
||||
// Return Value:
|
||||
// - the delimiter class for the given char
|
||||
const std::vector<SMALL_RECT> TextBuffer::GetTextRects(COORD start, COORD end, bool blockSelection, bool bufferCoordinates) const
|
||||
const std::vector<SMALL_RECT> TextBuffer::GetTextRects(COORD startCoord, COORD endCoord, bool blockSelection, bool bufferCoordinates) const
|
||||
{
|
||||
std::vector<SMALL_RECT> textRects;
|
||||
|
||||
const auto bufferSize = GetSize();
|
||||
til::point start{ startCoord.X, startCoord.Y };
|
||||
til::point end{ endCoord.X, endCoord.Y };
|
||||
|
||||
// (0,0) is the top-left of the screen
|
||||
// the physically "higher" coordinate is closer to the top-left
|
||||
// the physically "lower" coordinate is closer to the bottom-right
|
||||
const auto [higherCoord, lowerCoord] = bufferSize.CompareInBounds(start, end) <= 0 ?
|
||||
const auto [higherCoord, lowerCoord] = start <= end ?
|
||||
std::make_tuple(start, end) :
|
||||
std::make_tuple(end, start);
|
||||
|
||||
@@ -1625,19 +1639,19 @@ const std::vector<SMALL_RECT> TextBuffer::GetTextRects(COORD start, COORD end, b
|
||||
{
|
||||
SMALL_RECT textRow;
|
||||
|
||||
textRow.Top = row;
|
||||
textRow.Bottom = row;
|
||||
textRow.Top = base::ClampedNumeric<short>(row);
|
||||
textRow.Bottom = base::ClampedNumeric<short>(row);
|
||||
|
||||
if (blockSelection || higherCoord.Y == lowerCoord.Y)
|
||||
{
|
||||
// set the left and right margin to the left-/right-most respectively
|
||||
textRow.Left = std::min(higherCoord.X, lowerCoord.X);
|
||||
textRow.Right = std::max(higherCoord.X, lowerCoord.X);
|
||||
textRow.Left = base::ClampedNumeric<short>(std::min(higherCoord.X, lowerCoord.X));
|
||||
textRow.Right = base::ClampedNumeric<short>(std::max(higherCoord.X, lowerCoord.X));
|
||||
}
|
||||
else
|
||||
{
|
||||
textRow.Left = (row == higherCoord.Y) ? higherCoord.X : bufferSize.Left();
|
||||
textRow.Right = (row == lowerCoord.Y) ? lowerCoord.X : bufferSize.RightInclusive();
|
||||
textRow.Left = (row == higherCoord.Y) ? base::saturated_cast<SHORT>(higherCoord.X) : bufferSize.Left();
|
||||
textRow.Right = (row == lowerCoord.Y) ? base::saturated_cast<SHORT>(lowerCoord.X) : bufferSize.RightInclusive();
|
||||
}
|
||||
|
||||
// If we were passed screen coordinates, convert the given range into
|
||||
|
||||
@@ -153,10 +153,6 @@
|
||||
|
||||
<StaticResource x:Key="UnfocusedBorderBrush"
|
||||
ResourceKey="ApplicationPageBackgroundThemeBrush" />
|
||||
|
||||
<StaticResource x:Key="SettingsPageBackground"
|
||||
ResourceKey="SolidBackgroundFillColorTertiary" />
|
||||
|
||||
</ResourceDictionary>
|
||||
|
||||
<ResourceDictionary x:Key="Light">
|
||||
@@ -170,9 +166,6 @@
|
||||
|
||||
<StaticResource x:Key="UnfocusedBorderBrush"
|
||||
ResourceKey="ApplicationPageBackgroundThemeBrush" />
|
||||
|
||||
<StaticResource x:Key="SettingsPageBackground"
|
||||
ResourceKey="SolidBackgroundFillColorTertiary" />
|
||||
</ResourceDictionary>
|
||||
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
@@ -190,9 +183,6 @@
|
||||
-->
|
||||
<StaticResource x:Key="TabViewBackground"
|
||||
ResourceKey="SystemColorButtonFaceColorBrush" />
|
||||
|
||||
<StaticResource x:Key="SettingsPageBackground"
|
||||
ResourceKey="SystemColorWindowColorBrush" />
|
||||
</ResourceDictionary>
|
||||
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
|
||||
@@ -199,7 +199,6 @@ namespace winrt::TerminalApp::implementation
|
||||
FORWARDED_TYPED_EVENT(FullscreenChanged, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, FullscreenChanged);
|
||||
FORWARDED_TYPED_EVENT(ChangeMaximizeRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, ChangeMaximizeRequested);
|
||||
FORWARDED_TYPED_EVENT(AlwaysOnTopChanged, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, AlwaysOnTopChanged);
|
||||
FORWARDED_TYPED_EVENT(Initialized, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, Initialized);
|
||||
FORWARDED_TYPED_EVENT(RaiseVisualBell, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, RaiseVisualBell);
|
||||
FORWARDED_TYPED_EVENT(SetTaskbarProgress, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, SetTaskbarProgress);
|
||||
FORWARDED_TYPED_EVENT(IdentifyWindowsRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, IdentifyWindowsRequested);
|
||||
|
||||
@@ -122,7 +122,6 @@ namespace TerminalApp
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> FullscreenChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> ChangeMaximizeRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> AlwaysOnTopChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> Initialized;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> RaiseVisualBell;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> SetTaskbarProgress;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> IdentifyWindowsRequested;
|
||||
|
||||
@@ -9,8 +9,11 @@
|
||||
xmlns:local="using:TerminalApp"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
|
||||
Background="{ThemeResource TabViewBackground}"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<!-- GH#13143: Make sure that the Background is actually TabViewBackground here, not Transparent. This is load bearing, for showTabsInTitlebar=false. -->
|
||||
|
||||
<mux:TabView x:Name="TabView"
|
||||
VerticalAlignment="Bottom"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
|
||||
@@ -218,6 +218,24 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
// Inform the host that our titlebar content has changed.
|
||||
_SetTitleBarContentHandlers(*this, _tabRow);
|
||||
|
||||
// GH#13143 Manually set the tab row's background to transparent here.
|
||||
//
|
||||
// We're doing it this way because ThemeResources are tricky. We
|
||||
// default in XAML to using the appropriate ThemeResource background
|
||||
// color for our TabRow. When tabs in the titlebar are _disabled_,
|
||||
// this will ensure that the tab row has the correct theme-dependent
|
||||
// value. When tabs in the titlebar are _enabled_ (the default),
|
||||
// we'll switch the BG to Transparent, to let the Titlebar Control's
|
||||
// background be used as the BG for the tab row.
|
||||
//
|
||||
// We can't do it the other way around (default to Transparent, only
|
||||
// switch to a color when disabling tabs in the titlebar), because
|
||||
// looking up the correct ThemeResource from and App dictionary is a
|
||||
// capital-H Hard problem.
|
||||
const auto transparent = Media::SolidColorBrush();
|
||||
transparent.Color(Windows::UI::Colors::Transparent());
|
||||
_tabRow.Background(transparent);
|
||||
}
|
||||
|
||||
// Hookup our event handlers to the ShortcutActionDispatch
|
||||
@@ -659,7 +677,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
winrt::fire_and_forget TerminalPage::_CompleteInitialization()
|
||||
void TerminalPage::_CompleteInitialization()
|
||||
{
|
||||
_startupState = StartupState::Initialized;
|
||||
|
||||
@@ -679,55 +697,10 @@ namespace winrt::TerminalApp::implementation
|
||||
if (_tabs.Size() == 0 && !(_shouldStartInboundListener || _isEmbeddingInboundListener))
|
||||
{
|
||||
_LastTabClosedHandlers(*this, nullptr);
|
||||
co_return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// GH#11561: When we start up, our window is initially just a frame
|
||||
// with a transparent content area. We're gonna do all this startup
|
||||
// init on the UI thread, so the UI won't actually paint till it's
|
||||
// all done. This results in a few frames where the frame is
|
||||
// visible, before the page paints for the first time, before any
|
||||
// tabs appears, etc.
|
||||
//
|
||||
// To mitigate this, we're gonna wait for the UI thread to finish
|
||||
// everything it's gotta do for the initial init, and _then_ fire
|
||||
// our Initialized event. By waiting for everything else to finish
|
||||
// (CoreDispatcherPriority::Low), we let all the tabs and panes
|
||||
// actually get created. In the window layer, we're gonna cloak the
|
||||
// window till this event is fired, so we don't actually see this
|
||||
// frame until we're actually all ready to go.
|
||||
//
|
||||
// This will result in the window seemingly not loading as fast, but
|
||||
// it will actually take exactly the same amount of time before it's
|
||||
// usable.
|
||||
//
|
||||
// We also experimented with drawing a solid BG color before the
|
||||
// initialization is finished. However, there are still a few frames
|
||||
// after the frame is displayed before the XAML content first draws,
|
||||
// so that didn't actually resolve any issues.
|
||||
|
||||
auto weak{ get_weak() };
|
||||
|
||||
// Switch to the BG thread -
|
||||
co_await winrt::resume_background();
|
||||
|
||||
if (auto self{ weak.get() })
|
||||
{
|
||||
// Then enqueue the rest of this function for after the UI thread settles.
|
||||
co_await wil::resume_foreground(self->Dispatcher(), CoreDispatcherPriority::Low);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We don't exist anymore? Well, we probably don't need to fire
|
||||
// off an Initialized event then...
|
||||
co_return;
|
||||
}
|
||||
|
||||
if (auto self{ weak.get() })
|
||||
{
|
||||
self->_InitializedHandlers(*self, nullptr);
|
||||
}
|
||||
_InitializedHandlers(*this, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1849,9 +1822,17 @@ namespace winrt::TerminalApp::implementation
|
||||
// Instead, let's just promote this first split to be a tab instead.
|
||||
// Crash avoided, and we don't need to worry about inserting a new-tab
|
||||
// command in at the start.
|
||||
if (!focusedTab && _tabs.Size() == 0)
|
||||
if (!focusedTab)
|
||||
{
|
||||
_CreateNewTabFromPane(newPane);
|
||||
if (_tabs.Size() == 0)
|
||||
{
|
||||
_CreateNewTabFromPane(newPane);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The focused tab isn't a terminal tab
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2476,7 +2457,10 @@ namespace winrt::TerminalApp::implementation
|
||||
TermControl term{ settings.DefaultSettings(), settings.UnfocusedSettings(), connection };
|
||||
|
||||
// GH#12515: ConPTY assumes it's hidden at the start. If we're not, let it know now.
|
||||
term.WindowVisibilityChanged(_visible);
|
||||
if (_visible)
|
||||
{
|
||||
term.WindowVisibilityChanged(_visible);
|
||||
}
|
||||
|
||||
if (_hostingHwnd.has_value())
|
||||
{
|
||||
@@ -2596,7 +2580,8 @@ namespace winrt::TerminalApp::implementation
|
||||
// - <none>
|
||||
void TerminalPage::_SetBackgroundImage(const winrt::Microsoft::Terminal::Settings::Model::IAppearanceConfig& newAppearance)
|
||||
{
|
||||
if (newAppearance.BackgroundImagePath().empty())
|
||||
const auto path = newAppearance.ExpandedBackgroundImagePath();
|
||||
if (path.empty())
|
||||
{
|
||||
_tabContent.Background(nullptr);
|
||||
return;
|
||||
@@ -2605,7 +2590,7 @@ namespace winrt::TerminalApp::implementation
|
||||
Windows::Foundation::Uri imageUri{ nullptr };
|
||||
try
|
||||
{
|
||||
imageUri = Windows::Foundation::Uri{ newAppearance.BackgroundImagePath() };
|
||||
imageUri = Windows::Foundation::Uri{ path };
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
@@ -2622,7 +2607,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
if (imageSource == nullptr ||
|
||||
imageSource.UriSource() == nullptr ||
|
||||
imageSource.UriSource().RawUri() != imageUri.RawUri())
|
||||
!imageSource.UriSource().Equals(imageUri))
|
||||
{
|
||||
Media::ImageBrush b{};
|
||||
// Note that BitmapImage handles the image load asynchronously,
|
||||
|
||||
@@ -147,7 +147,7 @@ namespace winrt::TerminalApp::implementation
|
||||
TYPED_EVENT(AlwaysOnTopChanged, IInspectable, IInspectable);
|
||||
TYPED_EVENT(RaiseVisualBell, IInspectable, IInspectable);
|
||||
TYPED_EVENT(SetTaskbarProgress, IInspectable, IInspectable);
|
||||
TYPED_EVENT(Initialized, IInspectable, IInspectable);
|
||||
TYPED_EVENT(Initialized, IInspectable, winrt::Windows::UI::Xaml::RoutedEventArgs);
|
||||
TYPED_EVENT(IdentifyWindowsRequested, IInspectable, IInspectable);
|
||||
TYPED_EVENT(RenameWindowRequested, Windows::Foundation::IInspectable, winrt::TerminalApp::RenameWindowRequestedArgs);
|
||||
TYPED_EVENT(IsQuakeWindowChanged, IInspectable, IInspectable);
|
||||
@@ -390,7 +390,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void _StartInboundListener();
|
||||
|
||||
winrt::fire_and_forget _CompleteInitialization();
|
||||
void _CompleteInitialization();
|
||||
|
||||
void _FocusActiveControl(IInspectable sender, IInspectable eventArgs);
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace TerminalApp
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> FocusModeChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> FullscreenChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> AlwaysOnTopChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> Initialized;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Windows.UI.Xaml.RoutedEventArgs> Initialized;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> SetTaskbarProgress;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> IdentifyWindowsRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, RenameWindowRequestedArgs> RenameWindowRequested;
|
||||
|
||||
@@ -311,13 +311,17 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
|
||||
THROW_IF_FAILED(_CreatePseudoConsoleAndPipes(dimensions, flags, &_inPipe, &_outPipe, &_hPC));
|
||||
|
||||
// GH#12515: The conpty assumes it's hidden at the start. If we're visible, let it know now.
|
||||
THROW_IF_FAILED(ConptyShowHidePseudoConsole(_hPC.get(), _initialVisibility));
|
||||
if (_initialParentHwnd != 0)
|
||||
{
|
||||
THROW_IF_FAILED(ConptyReparentPseudoConsole(_hPC.get(), reinterpret_cast<HWND>(_initialParentHwnd)));
|
||||
}
|
||||
|
||||
// GH#12515: The conpty assumes it's hidden at the start. If we're visible, let it know now.
|
||||
if (_initialVisibility)
|
||||
{
|
||||
THROW_IF_FAILED(ConptyShowHidePseudoConsole(_hPC.get(), _initialVisibility));
|
||||
}
|
||||
|
||||
THROW_IF_FAILED(_LaunchAttachedClient());
|
||||
}
|
||||
// But if it was an inbound handoff... attempt to synchronize the size of it with what our connection
|
||||
@@ -336,6 +340,11 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
|
||||
THROW_IF_FAILED(ConptyResizePseudoConsole(_hPC.get(), dimensions));
|
||||
THROW_IF_FAILED(ConptyReparentPseudoConsole(_hPC.get(), reinterpret_cast<HWND>(_initialParentHwnd)));
|
||||
|
||||
if (_initialVisibility)
|
||||
{
|
||||
THROW_IF_FAILED(ConptyShowHidePseudoConsole(_hPC.get(), _initialVisibility));
|
||||
}
|
||||
}
|
||||
|
||||
_startTime = std::chrono::high_resolution_clock::now();
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
hstring _commandline{};
|
||||
hstring _startingDirectory{};
|
||||
hstring _startingTitle{};
|
||||
bool _initialVisibility{ false };
|
||||
bool _initialVisibility{ true };
|
||||
Windows::Foundation::Collections::ValueSet _environment{ nullptr };
|
||||
guid _guid{}; // A unique session identifier for connected client
|
||||
hstring _clientName{}; // The name of the process hosted by this ConPTY connection (as of launch).
|
||||
|
||||
@@ -1210,8 +1210,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
void ControlCore::_terminalShowWindowChanged(bool showOrHide)
|
||||
{
|
||||
auto showWindow = winrt::make_self<implementation::ShowWindowArgs>(showOrHide);
|
||||
_ShowWindowChangedHandlers(*this, *showWindow);
|
||||
if (_initializedTerminal)
|
||||
{
|
||||
auto showWindow = winrt::make_self<implementation::ShowWindowArgs>(showOrHide);
|
||||
_ShowWindowChangedHandlers(*this, *showWindow);
|
||||
}
|
||||
}
|
||||
|
||||
bool ControlCore::HasSelection() const
|
||||
@@ -1712,10 +1715,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// - <none>
|
||||
void ControlCore::WindowVisibilityChanged(const bool showOrHide)
|
||||
{
|
||||
// show is true, hide is false
|
||||
if (auto conpty{ _connection.try_as<TerminalConnection::ConptyConnection>() })
|
||||
if (_initializedTerminal)
|
||||
{
|
||||
conpty.ShowHide(showOrHide);
|
||||
// show is true, hide is false
|
||||
if (auto conpty{ _connection.try_as<TerminalConnection::ConptyConnection>() })
|
||||
{
|
||||
conpty.ShowHide(showOrHide);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -426,7 +426,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
if (imageSource == nullptr ||
|
||||
imageSource.UriSource() == nullptr ||
|
||||
imageSource.UriSource().RawUri() != imageUri.RawUri())
|
||||
!imageSource.UriSource().Equals(imageUri))
|
||||
{
|
||||
// Note that BitmapImage handles the image load asynchronously,
|
||||
// which is especially important since the image
|
||||
|
||||
@@ -182,7 +182,7 @@ void Terminal::SetSelectionEnd(const COORD viewportPos, std::optional<SelectionE
|
||||
// - the new start/end for a selection
|
||||
std::pair<COORD, COORD> Terminal::_PivotSelection(const COORD targetPos, bool& targetStart) const
|
||||
{
|
||||
if (targetStart = _activeBuffer().GetSize().CompareInBounds(targetPos, _selection->pivot) <= 0)
|
||||
if (targetStart = til::point{ targetPos } <= til::point{ _selection->pivot })
|
||||
{
|
||||
// target is before pivot
|
||||
// treat target as start
|
||||
@@ -371,7 +371,7 @@ void Terminal::_MoveByWord(SelectionDirection direction, COORD& pos)
|
||||
{
|
||||
case SelectionDirection::Left:
|
||||
const auto wordStartPos{ _activeBuffer().GetWordStart(pos, _wordDelimiters) };
|
||||
if (_activeBuffer().GetSize().CompareInBounds(_selection->pivot, pos) < 0)
|
||||
if (til::point{ _selection->pivot } < til::point{ pos })
|
||||
{
|
||||
// If we're moving towards the pivot, move one more cell
|
||||
pos = wordStartPos;
|
||||
@@ -392,7 +392,7 @@ void Terminal::_MoveByWord(SelectionDirection direction, COORD& pos)
|
||||
break;
|
||||
case SelectionDirection::Right:
|
||||
const auto wordEndPos{ _activeBuffer().GetWordEnd(pos, _wordDelimiters) };
|
||||
if (_activeBuffer().GetSize().CompareInBounds(pos, _selection->pivot) < 0)
|
||||
if (til::point{ pos } < til::point{ _selection->pivot })
|
||||
{
|
||||
// If we're moving towards the pivot, move one more cell
|
||||
pos = _activeBuffer().GetWordEnd(pos, _wordDelimiters);
|
||||
|
||||
@@ -37,8 +37,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
L"qps-PLOCA",
|
||||
L"qps-PLOCM",
|
||||
L"ru",
|
||||
L"zh-Hans-CN",
|
||||
L"zh-Hant-TW",
|
||||
L"zh-Hans",
|
||||
L"zh-Hant",
|
||||
};
|
||||
|
||||
GlobalAppearance::GlobalAppearance()
|
||||
|
||||
@@ -9,13 +9,43 @@
|
||||
xmlns:local="using:Microsoft.Terminal.Settings.Editor"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
|
||||
Background="{ThemeResource SettingsPageBackground}"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Page.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="CommonResources.xaml" />
|
||||
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
|
||||
<!--
|
||||
These two values are "SolidBackgroundFillColorTertiary".
|
||||
We can't just put those here though as
|
||||
StaticResources, because XAML will evaluate their
|
||||
values when the App is first loaded, and we'll
|
||||
always use the value from the OS theme, regardless
|
||||
of the requested theme. Kinda the same thing we've
|
||||
had to do with TabViewBackground in the past.
|
||||
-->
|
||||
|
||||
<ResourceDictionary x:Key="Dark">
|
||||
<Color x:Key="SettingsPageBackground">#282828</Color>
|
||||
</ResourceDictionary>
|
||||
|
||||
<ResourceDictionary x:Key="Light">
|
||||
<Color x:Key="SettingsPageBackground">#F9F9F9</Color>
|
||||
</ResourceDictionary>
|
||||
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<!-- Define resources for HighContrast mode here -->
|
||||
<StaticResource x:Key="SettingsPageBackground"
|
||||
ResourceKey="SystemColorWindowColorBrush" />
|
||||
</ResourceDictionary>
|
||||
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
</ResourceDictionary>
|
||||
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<SolidColorBrush x:Key="NavigationViewExpandedPaneBackground"
|
||||
@@ -30,7 +60,7 @@
|
||||
</Page.Resources>
|
||||
|
||||
<muxc:NavigationView x:Name="SettingsNav"
|
||||
Background="Transparent"
|
||||
Background="{ThemeResource SettingsPageBackground}"
|
||||
IsBackButtonVisible="Collapsed"
|
||||
IsSettingsVisible="False"
|
||||
ItemInvoked="SettingsNav_ItemInvoked"
|
||||
|
||||
@@ -107,7 +107,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
Model::TerminalSettings ProfileViewModel::TermSettings() const
|
||||
{
|
||||
return Model::TerminalSettings::CreateWithProfile(_appSettings, _profile, nullptr).DefaultSettings();
|
||||
return Model::TerminalSettings::CreateForPreview(_appSettings, _profile);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
||||
@@ -50,6 +50,25 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
return { horizAlign, vertAlign };
|
||||
}
|
||||
|
||||
winrt::com_ptr<implementation::TerminalSettings> TerminalSettings::_CreateWithProfileCommon(const Model::CascadiaSettings& appSettings, const Model::Profile& profile)
|
||||
{
|
||||
auto settings{ winrt::make_self<TerminalSettings>() };
|
||||
|
||||
const auto globals = appSettings.GlobalSettings();
|
||||
settings->_ApplyProfileSettings(profile);
|
||||
settings->_ApplyGlobalSettings(globals);
|
||||
settings->_ApplyAppearanceSettings(profile.DefaultAppearance(), globals.ColorSchemes());
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
Model::TerminalSettings TerminalSettings::CreateForPreview(const Model::CascadiaSettings& appSettings, const Model::Profile& profile)
|
||||
{
|
||||
const auto settings = _CreateWithProfileCommon(appSettings, profile);
|
||||
settings->UseBackgroundImageForWindow(false);
|
||||
return *settings;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Create a TerminalSettingsCreateResult for the provided profile guid. We'll
|
||||
// use the guid to look up the profile that should be used to
|
||||
@@ -64,17 +83,13 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
// one for when the terminal is focused and the other for when the terminal is unfocused
|
||||
Model::TerminalSettingsCreateResult TerminalSettings::CreateWithProfile(const Model::CascadiaSettings& appSettings, const Model::Profile& profile, const IKeyBindings& keybindings)
|
||||
{
|
||||
auto settings{ winrt::make_self<TerminalSettings>() };
|
||||
const auto settings = _CreateWithProfileCommon(appSettings, profile);
|
||||
settings->_KeyBindings = keybindings;
|
||||
|
||||
const auto globals = appSettings.GlobalSettings();
|
||||
settings->_ApplyProfileSettings(profile);
|
||||
settings->_ApplyGlobalSettings(globals);
|
||||
settings->_ApplyAppearanceSettings(profile.DefaultAppearance(), globals.ColorSchemes());
|
||||
|
||||
Model::TerminalSettings child{ nullptr };
|
||||
if (const auto& unfocusedAppearance{ profile.UnfocusedAppearance() })
|
||||
{
|
||||
const auto globals = appSettings.GlobalSettings();
|
||||
auto childImpl = settings->CreateChild();
|
||||
childImpl->_ApplyAppearanceSettings(unfocusedAppearance, globals.ColorSchemes());
|
||||
child = *childImpl;
|
||||
|
||||
@@ -55,6 +55,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
{
|
||||
TerminalSettings() = default;
|
||||
|
||||
static Model::TerminalSettings CreateForPreview(const Model::CascadiaSettings& appSettings, const Model::Profile& profile);
|
||||
|
||||
static Model::TerminalSettingsCreateResult CreateWithProfile(const Model::CascadiaSettings& appSettings,
|
||||
const Model::Profile& profile,
|
||||
const Control::IKeyBindings& keybindings);
|
||||
@@ -159,6 +161,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
private:
|
||||
std::optional<std::array<Microsoft::Terminal::Core::Color, COLOR_TABLE_SIZE>> _ColorTable;
|
||||
gsl::span<Microsoft::Terminal::Core::Color> _getColorTableImpl();
|
||||
|
||||
static winrt::com_ptr<implementation::TerminalSettings> _CreateWithProfileCommon(const Model::CascadiaSettings& appSettings, const Model::Profile& profile);
|
||||
void _ApplyProfileSettings(const Model::Profile& profile);
|
||||
|
||||
void _ApplyGlobalSettings(const Model::GlobalAppSettings& globalSettings) noexcept;
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
{
|
||||
TerminalSettings();
|
||||
|
||||
static TerminalSettings CreateForPreview(CascadiaSettings appSettings, Profile profile);
|
||||
static TerminalSettingsCreateResult CreateWithProfile(CascadiaSettings appSettings, Profile profile, Microsoft.Terminal.Control.IKeyBindings keybindings);
|
||||
static TerminalSettingsCreateResult CreateWithNewTerminalArgs(CascadiaSettings appSettings, NewTerminalArgs newTerminalArgs, Microsoft.Terminal.Control.IKeyBindings keybindings);
|
||||
|
||||
|
||||
@@ -73,7 +73,8 @@ AppHost::AppHost() noexcept :
|
||||
auto pfn = std::bind(&AppHost::_HandleCreateWindow,
|
||||
this,
|
||||
std::placeholders::_1,
|
||||
std::placeholders::_2);
|
||||
std::placeholders::_2,
|
||||
std::placeholders::_3);
|
||||
_window->SetCreateCallback(pfn);
|
||||
|
||||
_window->SetSnapDimensionCallback(std::bind(&winrt::TerminalApp::AppLogic::CalcSnappedDimension,
|
||||
@@ -116,6 +117,19 @@ AppHost::AppHost() noexcept :
|
||||
{
|
||||
_BecomeMonarch(nullptr, nullptr);
|
||||
}
|
||||
|
||||
// Create a throttled function for updating the window state, to match the
|
||||
// one requested by the pty. A 200ms delay was chosen because it's the
|
||||
// typical animation timeout in Windows. This does result in a delay between
|
||||
// the PTY requesting a change to the window state and the Terminal
|
||||
// realizing it, but should mitigate issues where the Terminal and PTY get
|
||||
// de-sync'd.
|
||||
_showHideWindowThrottler = std::make_shared<ThrottledFuncTrailing<bool>>(
|
||||
winrt::Windows::System::DispatcherQueue::GetForCurrentThread(),
|
||||
std::chrono::milliseconds(200),
|
||||
[this](const bool show) {
|
||||
_window->ShowWindowChanged(show);
|
||||
});
|
||||
}
|
||||
|
||||
AppHost::~AppHost()
|
||||
@@ -128,6 +142,8 @@ AppHost::~AppHost()
|
||||
// out the window, then close the app.
|
||||
_revokers = {};
|
||||
|
||||
_showHideWindowThrottler.reset();
|
||||
|
||||
_window = nullptr;
|
||||
_app.Close();
|
||||
_app = nullptr;
|
||||
@@ -378,7 +394,6 @@ void AppHost::Initialize()
|
||||
_revokers.FullscreenChanged = _logic.FullscreenChanged(winrt::auto_revoke, { this, &AppHost::_FullscreenChanged });
|
||||
_revokers.FocusModeChanged = _logic.FocusModeChanged(winrt::auto_revoke, { this, &AppHost::_FocusModeChanged });
|
||||
_revokers.AlwaysOnTopChanged = _logic.AlwaysOnTopChanged(winrt::auto_revoke, { this, &AppHost::_AlwaysOnTopChanged });
|
||||
_revokers.Initialized = _logic.Initialized(winrt::auto_revoke, { this, &AppHost::_AppInitializedHandler });
|
||||
_revokers.RaiseVisualBell = _logic.RaiseVisualBell(winrt::auto_revoke, { this, &AppHost::_RaiseVisualBell });
|
||||
_revokers.SystemMenuChangeRequested = _logic.SystemMenuChangeRequested(winrt::auto_revoke, { this, &AppHost::_SystemMenuChangeRequested });
|
||||
_revokers.ChangeMaximizeRequested = _logic.ChangeMaximizeRequested(winrt::auto_revoke, { this, &AppHost::_ChangeMaximizeRequested });
|
||||
@@ -520,31 +535,12 @@ LaunchPosition AppHost::_GetWindowLaunchPosition()
|
||||
return pos;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Callback for when the window is first being created (during WM_CREATE).
|
||||
// Stash the proposed size for later. We'll need that once we're totally
|
||||
// initialized, so that we can show the window in the right position *when we
|
||||
// want to show it*. If we did the _initialResizeAndRepositionWindow work now,
|
||||
// it would have no effect, because the window is not yet visible.
|
||||
// Arguments:
|
||||
// - hwnd: The HWND of the window we're about to create.
|
||||
// - proposedRect: The location and size of the window that we're about to
|
||||
// create. We'll use this rect to determine which monitor the window is about
|
||||
// to appear on.
|
||||
void AppHost::_HandleCreateWindow(const HWND /* hwnd */, RECT proposedRect)
|
||||
{
|
||||
// GH#11561: Hide the window until we're totally done being initialized.
|
||||
// More commentary in TerminalPage::_CompleteInitialization
|
||||
_proposedRect = proposedRect;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Resize the window we're about to create to the appropriate dimensions, as
|
||||
// specified in the settings. This is called once the app has finished it's
|
||||
// initial setup, once we have created all the tabs, panes, etc. We'll load
|
||||
// the settings for the app, then get the proposed size of the terminal from
|
||||
// the app. Using that proposed size, we'll resize the window we're creating,
|
||||
// so that it'll match the values in the settings.
|
||||
// specified in the settings. This will be called during the handling of
|
||||
// WM_CREATE. We'll load the settings for the app, then get the proposed size
|
||||
// of the terminal from the app. Using that proposed size, we'll resize the
|
||||
// window we're creating, so that it'll match the values in the settings.
|
||||
// Arguments:
|
||||
// - hwnd: The HWND of the window we're about to create.
|
||||
// - proposedRect: The location and size of the window that we're about to
|
||||
@@ -553,7 +549,7 @@ void AppHost::_HandleCreateWindow(const HWND /* hwnd */, RECT proposedRect)
|
||||
// - launchMode: A LaunchMode enum reference that indicates the launch mode
|
||||
// Return Value:
|
||||
// - None
|
||||
void AppHost::_initialResizeAndRepositionWindow(const HWND hwnd, RECT proposedRect, LaunchMode& launchMode)
|
||||
void AppHost::_HandleCreateWindow(const HWND hwnd, RECT proposedRect, LaunchMode& launchMode)
|
||||
{
|
||||
launchMode = _logic.GetLaunchMode();
|
||||
|
||||
@@ -1416,7 +1412,14 @@ void AppHost::_QuitAllRequested(const winrt::Windows::Foundation::IInspectable&,
|
||||
void AppHost::_ShowWindowChanged(const winrt::Windows::Foundation::IInspectable&,
|
||||
const winrt::Microsoft::Terminal::Control::ShowWindowArgs& args)
|
||||
{
|
||||
_window->ShowWindowChanged(args.ShowOrHide());
|
||||
// GH#13147: Enqueue a throttled update to our window state. Throttling
|
||||
// should prevent scenarios where the Terminal window state and PTY window
|
||||
// state get de-sync'd, and cause the window to minimize/restore constantly
|
||||
// in a loop.
|
||||
if (_showHideWindowThrottler)
|
||||
{
|
||||
_showHideWindowThrottler->Run(args.ShowOrHide());
|
||||
}
|
||||
}
|
||||
|
||||
void AppHost::_SummonWindowRequested(const winrt::Windows::Foundation::IInspectable& sender,
|
||||
@@ -1575,22 +1578,3 @@ void AppHost::_CloseRequested(const winrt::Windows::Foundation::IInspectable& /*
|
||||
const auto pos = _GetWindowLaunchPosition();
|
||||
_logic.CloseWindow(pos);
|
||||
}
|
||||
|
||||
void AppHost::_AppInitializedHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/,
|
||||
const winrt::Windows::Foundation::IInspectable& /*arg*/)
|
||||
{
|
||||
// GH#11561: We're totally done being initialized. Resize the window to
|
||||
// match the initial settings, and then call ShowWindow to finally make us
|
||||
// visible.
|
||||
|
||||
LaunchMode launchMode{};
|
||||
_initialResizeAndRepositionWindow(_window->GetHandle(), _proposedRect, launchMode);
|
||||
|
||||
auto nCmdShow = SW_SHOWDEFAULT;
|
||||
if (WI_IsFlagSet(launchMode, LaunchMode::MaximizedMode))
|
||||
{
|
||||
nCmdShow = SW_MAXIMIZE;
|
||||
}
|
||||
|
||||
ShowWindow(_window->GetHandle(), nCmdShow);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "pch.h"
|
||||
#include "NonClientIslandWindow.h"
|
||||
#include "NotificationIcon.h"
|
||||
#include <til/throttled_func.h>
|
||||
#include <ThrottledFunc.h>
|
||||
|
||||
class AppHost
|
||||
{
|
||||
@@ -31,16 +31,16 @@ private:
|
||||
|
||||
bool _shouldCreateWindow{ false };
|
||||
bool _useNonClientArea{ false };
|
||||
RECT _proposedRect{};
|
||||
|
||||
std::optional<til::throttled_func_trailing<>> _getWindowLayoutThrottler;
|
||||
std::shared_ptr<ThrottledFuncTrailing<bool>> _showHideWindowThrottler;
|
||||
winrt::Windows::Foundation::IAsyncAction _SaveWindowLayouts();
|
||||
winrt::fire_and_forget _SaveWindowLayoutsRepeat();
|
||||
|
||||
void _HandleCommandlineArgs();
|
||||
winrt::Microsoft::Terminal::Settings::Model::LaunchPosition _GetWindowLaunchPosition();
|
||||
|
||||
void _HandleCreateWindow(const HWND hwnd, RECT proposedRect);
|
||||
void _HandleCreateWindow(const HWND hwnd, RECT proposedRect, winrt::Microsoft::Terminal::Settings::Model::LaunchMode& launchMode);
|
||||
void _UpdateTitleBarContent(const winrt::Windows::Foundation::IInspectable& sender,
|
||||
const winrt::Windows::UI::Xaml::UIElement& arg);
|
||||
void _UpdateTheme(const winrt::Windows::Foundation::IInspectable&,
|
||||
@@ -53,9 +53,6 @@ private:
|
||||
const winrt::Windows::Foundation::IInspectable& arg);
|
||||
void _AlwaysOnTopChanged(const winrt::Windows::Foundation::IInspectable& sender,
|
||||
const winrt::Windows::Foundation::IInspectable& arg);
|
||||
void _AppInitializedHandler(const winrt::Windows::Foundation::IInspectable& sender,
|
||||
const winrt::Windows::Foundation::IInspectable& arg);
|
||||
|
||||
void _RaiseVisualBell(const winrt::Windows::Foundation::IInspectable& sender,
|
||||
const winrt::Windows::Foundation::IInspectable& arg);
|
||||
void _WindowMouseWheeled(const til::point coord, const int32_t delta);
|
||||
@@ -125,9 +122,6 @@ private:
|
||||
const winrt::Windows::Foundation::IInspectable& args);
|
||||
void _HideNotificationIconRequested(const winrt::Windows::Foundation::IInspectable& sender,
|
||||
const winrt::Windows::Foundation::IInspectable& args);
|
||||
|
||||
void _initialResizeAndRepositionWindow(const HWND hwnd, RECT proposedRect, winrt::Microsoft::Terminal::Settings::Model::LaunchMode& launchMode);
|
||||
|
||||
std::unique_ptr<NotificationIcon> _notificationIcon;
|
||||
winrt::event_token _ReAddNotificationIconToken;
|
||||
winrt::event_token _NotificationIconPressedToken;
|
||||
@@ -154,7 +148,6 @@ private:
|
||||
winrt::TerminalApp::AppLogic::FullscreenChanged_revoker FullscreenChanged;
|
||||
winrt::TerminalApp::AppLogic::FocusModeChanged_revoker FocusModeChanged;
|
||||
winrt::TerminalApp::AppLogic::AlwaysOnTopChanged_revoker AlwaysOnTopChanged;
|
||||
winrt::TerminalApp::AppLogic::Initialized_revoker Initialized;
|
||||
winrt::TerminalApp::AppLogic::RaiseVisualBell_revoker RaiseVisualBell;
|
||||
winrt::TerminalApp::AppLogic::SystemMenuChangeRequested_revoker SystemMenuChangeRequested;
|
||||
winrt::TerminalApp::AppLogic::ChangeMaximizeRequested_revoker ChangeMaximizeRequested;
|
||||
|
||||
@@ -112,7 +112,7 @@ void IslandWindow::Close()
|
||||
// window.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void IslandWindow::SetCreateCallback(std::function<void(const HWND, const RECT)> pfn) noexcept
|
||||
void IslandWindow::SetCreateCallback(std::function<void(const HWND, const RECT, LaunchMode& launchMode)> pfn) noexcept
|
||||
{
|
||||
_pfnCreateCallback = pfn;
|
||||
}
|
||||
@@ -154,13 +154,19 @@ void IslandWindow::_HandleCreateWindow(const WPARAM, const LPARAM lParam) noexce
|
||||
rc.right = rc.left + pcs->cx;
|
||||
rc.bottom = rc.top + pcs->cy;
|
||||
|
||||
auto launchMode = LaunchMode::DefaultMode;
|
||||
if (_pfnCreateCallback)
|
||||
{
|
||||
_pfnCreateCallback(_window.get(), rc);
|
||||
_pfnCreateCallback(_window.get(), rc, launchMode);
|
||||
}
|
||||
|
||||
// GH#11561: DO NOT call ShowWindow here. The AppHost will call ShowWindow
|
||||
// once the app has completed its initialization.
|
||||
auto nCmdShow = SW_SHOW;
|
||||
if (WI_IsFlagSet(launchMode, LaunchMode::MaximizedMode))
|
||||
{
|
||||
nCmdShow = SW_MAXIMIZE;
|
||||
}
|
||||
|
||||
ShowWindow(_window.get(), nCmdShow);
|
||||
|
||||
UpdateWindow(_window.get());
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ public:
|
||||
|
||||
virtual void Initialize();
|
||||
|
||||
void SetCreateCallback(std::function<void(const HWND, const RECT)> pfn) noexcept;
|
||||
void SetCreateCallback(std::function<void(const HWND, const RECT, winrt::Microsoft::Terminal::Settings::Model::LaunchMode& launchMode)> pfn) noexcept;
|
||||
void SetSnapDimensionCallback(std::function<float(bool widthOrHeight, float dimension)> pfn) noexcept;
|
||||
|
||||
void FocusModeChanged(const bool focusMode);
|
||||
@@ -94,7 +94,7 @@ protected:
|
||||
winrt::Windows::UI::Xaml::Controls::Grid _rootGrid;
|
||||
wil::com_ptr<ITaskbarList3> _taskbar;
|
||||
|
||||
std::function<void(const HWND, const RECT)> _pfnCreateCallback;
|
||||
std::function<void(const HWND, const RECT, winrt::Microsoft::Terminal::Settings::Model::LaunchMode& launchMode)> _pfnCreateCallback;
|
||||
std::function<float(bool, float)> _pfnSnapDimensionCallback;
|
||||
|
||||
void _HandleCreateWindow(const WPARAM wParam, const LPARAM lParam) noexcept;
|
||||
|
||||
@@ -155,13 +155,13 @@ namespace WindowsTerminal.UIA.Tests
|
||||
{
|
||||
var root = app.GetRoot();
|
||||
|
||||
root.SendKeys(Keys.LeftAlt + Keys.LeftShift + "T");
|
||||
root.SendKeys(Keys.LeftControl + Keys.LeftShift + "T");
|
||||
Globals.WaitForTimeout();
|
||||
root.SendKeys(Keys.LeftAlt + Keys.LeftShift + "T");
|
||||
root.SendKeys(Keys.LeftControl + Keys.LeftShift + "T");
|
||||
Globals.WaitForTimeout();
|
||||
root.SendKeys(Keys.LeftAlt + Keys.LeftShift + "T");
|
||||
root.SendKeys(Keys.LeftControl + Keys.LeftShift + "T");
|
||||
Globals.WaitForTimeout();
|
||||
root.SendKeys(Keys.LeftAlt + Keys.LeftShift + "T");
|
||||
root.SendKeys(Keys.LeftControl + Keys.LeftShift + "T");
|
||||
Globals.WaitForTimeout();
|
||||
root.SendKeys(Keys.LeftControl + Keys.LeftShift + "W");
|
||||
Globals.WaitForTimeout();
|
||||
|
||||
@@ -75,11 +75,20 @@ void PtySignalInputThread::ConnectConsole() noexcept
|
||||
_DoShowHide(_initialShowHide->show);
|
||||
}
|
||||
|
||||
// If we were given a owner HWND, then manually start the pseudo window now.
|
||||
if (_earlyReparent)
|
||||
{
|
||||
_DoSetWindowParent(*_earlyReparent);
|
||||
}
|
||||
// We should have successfully used the _earlyReparent message in CreatePseudoWindow.
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Create our pseudo window. We're doing this here, instead of in
|
||||
// ConnectConsole, because the window is created in
|
||||
// ConsoleInputThreadProcWin32, before ConnectConsole is first called. Doing
|
||||
// this here ensures that the window is first created with the initial owner
|
||||
// set up (if so specified).
|
||||
// - Refer to GH#13066 for details.
|
||||
void PtySignalInputThread::CreatePseudoWindow()
|
||||
{
|
||||
HWND owner = _earlyReparent.has_value() ? reinterpret_cast<HWND>((*_earlyReparent).handle) : HWND_DESKTOP;
|
||||
ServiceLocator::LocatePseudoWindow(owner);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -227,15 +236,28 @@ void PtySignalInputThread::_DoShowHide(const bool show)
|
||||
// - <none>
|
||||
void PtySignalInputThread::_DoSetWindowParent(const SetParentData& data)
|
||||
{
|
||||
const auto owner{ reinterpret_cast<HWND>(data.handle) };
|
||||
// This will initialize s_interactivityFactory for us. It will also
|
||||
// conveniently return 0 when we're on OneCore.
|
||||
//
|
||||
// If the window hasn't been created yet, by some other call to
|
||||
// LocatePseudoWindow, then this will also initialize the owner of the
|
||||
// window.
|
||||
if (const auto pseudoHwnd{ ServiceLocator::LocatePseudoWindow(reinterpret_cast<HWND>(data.handle)) })
|
||||
if (const auto pseudoHwnd{ ServiceLocator::LocatePseudoWindow(owner) })
|
||||
{
|
||||
LOG_LAST_ERROR_IF_NULL(::SetParent(pseudoHwnd, reinterpret_cast<HWND>(data.handle)));
|
||||
// DO NOT USE SetParent HERE!
|
||||
//
|
||||
// Calling SetParent on a window that is WS_VISIBLE will cause the OS to
|
||||
// hide the window, make it a _child_ window, then call SW_SHOW on the
|
||||
// window to re-show it. SW_SHOW, however, will cause the OS to also set
|
||||
// that window as the _foreground_ window, which would result in the
|
||||
// pty's hwnd stealing the foreground away from the owning terminal
|
||||
// window. That's bad.
|
||||
//
|
||||
// SetWindowLongPtr seems to do the job of changing who the window owner
|
||||
// is, without all the other side effects of reparenting the window.
|
||||
// See #13066
|
||||
::SetWindowLongPtr(pseudoHwnd, GWLP_HWNDPARENT, reinterpret_cast<LONG_PTR>(owner));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ namespace Microsoft::Console
|
||||
PtySignalInputThread& operator=(const PtySignalInputThread&) = delete;
|
||||
|
||||
void ConnectConsole() noexcept;
|
||||
void CreatePseudoWindow();
|
||||
|
||||
private:
|
||||
enum class PtySignal : unsigned short
|
||||
|
||||
@@ -300,18 +300,34 @@ bool VtIo::IsUsingVt() const
|
||||
|
||||
if (_pPtySignalInputThread)
|
||||
{
|
||||
// IMPORTANT! Start the pseudo window on this thread. This thread has a
|
||||
// message pump. If you DON'T, then a DPI change in the owning hwnd will
|
||||
// cause us to get a dpi change as well, which we'll never deque and
|
||||
// handle, effectively HANGING THE OWNER HWND.
|
||||
// Let the signal thread know that the console is connected.
|
||||
//
|
||||
// Let the signal thread know that the console is connected
|
||||
// By this point, the pseudo window should have already been created, by
|
||||
// ConsoleInputThreadProcWin32. That thread has a message pump, which is
|
||||
// needed to ensure that DPI change messages to the owning terminal
|
||||
// window don't end up hanging because the pty didn't also process it.
|
||||
_pPtySignalInputThread->ConnectConsole();
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Create our pseudo window. This is exclusively called by
|
||||
// ConsoleInputThreadProcWin32 on the console input thread.
|
||||
// * It needs to be called on that thread, before any other calls to
|
||||
// LocatePseudoWindow, to make sure that the input thread is the HWND's
|
||||
// message thread.
|
||||
// * It needs to be plumbed through the signal thread, because the signal
|
||||
// thread knows if someone should be marked as the window's owner. It's
|
||||
// VERY IMPORTANT that any initial owners are set up when the window is
|
||||
// first created.
|
||||
// - Refer to GH#13066 for details.
|
||||
void VtIo::CreatePseudoWindow()
|
||||
{
|
||||
_pPtySignalInputThread->CreatePseudoWindow();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Create and start the signal thread. The signal thread can be created
|
||||
// independent of the i/o threads, and doesn't require a client first
|
||||
|
||||
@@ -52,6 +52,8 @@ namespace Microsoft::Console::VirtualTerminal
|
||||
|
||||
[[nodiscard]] HRESULT ManuallyClearScrollback() const noexcept;
|
||||
|
||||
void CreatePseudoWindow();
|
||||
|
||||
private:
|
||||
// After CreateIoHandlers is called, these will be invalid.
|
||||
wil::unique_hfile _hInput;
|
||||
|
||||
@@ -719,6 +719,10 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont
|
||||
position.Y < 0));
|
||||
// clang-format on
|
||||
|
||||
// MSFT: 15813316 - Try to use this SetCursorPosition call to inherit the cursor position.
|
||||
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
||||
RETURN_IF_FAILED(gci.GetVtIo()->SetCursorPosition(position));
|
||||
|
||||
RETURN_IF_NTSTATUS_FAILED(buffer.SetCursorPosition(position, true));
|
||||
|
||||
LOG_IF_FAILED(ConsoleImeResizeCompStrView());
|
||||
|
||||
@@ -285,7 +285,7 @@ void ConhostInternalGetSet::ShowWindow(bool showOrHide)
|
||||
{
|
||||
const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
||||
const auto hwnd = gci.IsInVtIoMode() ? ServiceLocator::LocatePseudoWindow() : ServiceLocator::LocateConsoleWindow()->GetWindowHandle();
|
||||
::ShowWindow(hwnd, showOrHide ? SW_NORMAL : SW_MINIMIZE);
|
||||
::ShowWindow(hwnd, showOrHide ? SW_SHOWNOACTIVATE : SW_MINIMIZE);
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
|
||||
@@ -1453,6 +1453,8 @@ bool SCREEN_INFORMATION::IsMaximizedY() const
|
||||
|
||||
// Save cursor's relative height versus the viewport
|
||||
const auto sCursorHeightInViewportBefore = _textBuffer->GetCursor().GetPosition().Y - _viewport.Top();
|
||||
// Also save the distance to the virtual bottom so it can be restored after the resize
|
||||
const auto cursorDistanceFromBottom = _virtualBottom - _textBuffer->GetCursor().GetPosition().Y;
|
||||
|
||||
// skip any drawing updates that might occur until we swap _textBuffer with the new buffer or we exit early.
|
||||
newTextBuffer->GetCursor().StartDeferDrawing();
|
||||
@@ -1464,14 +1466,20 @@ bool SCREEN_INFORMATION::IsMaximizedY() const
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
// Make sure the new virtual bottom is far enough down to include both
|
||||
// the cursor row and the last non-space row. It also shouldn't be less
|
||||
// than the height of the viewport, otherwise the top of the virtual
|
||||
// viewport would end up negative.
|
||||
// Since the reflow doesn't preserve the virtual bottom, we try and
|
||||
// estimate where it ought to be by making it the same distance from
|
||||
// the cursor row as it was before the resize. However, we also need
|
||||
// to make sure it is far enough down to include the last non-space
|
||||
// row, and it shouldn't be less than the height of the viewport,
|
||||
// otherwise the top of the virtual viewport would end up negative.
|
||||
const auto cursorRow = newTextBuffer->GetCursor().GetPosition().Y;
|
||||
const auto lastNonSpaceRow = newTextBuffer->GetLastNonSpaceCharacter().Y;
|
||||
const auto estimatedBottom = gsl::narrow_cast<short>(cursorRow + cursorDistanceFromBottom);
|
||||
const auto viewportBottom = gsl::narrow_cast<short>(_viewport.Height() - 1);
|
||||
_virtualBottom = std::max({ cursorRow, lastNonSpaceRow, viewportBottom });
|
||||
_virtualBottom = std::max({ lastNonSpaceRow, estimatedBottom, viewportBottom });
|
||||
|
||||
// We can't let it extend past the bottom of the buffer either.
|
||||
_virtualBottom = std::min(_virtualBottom, newTextBuffer->GetSize().BottomInclusive());
|
||||
|
||||
// Adjust the viewport so the cursor doesn't wildly fly off up or down.
|
||||
const auto sCursorHeightInViewportAfter = cursorRow - _viewport.Top();
|
||||
|
||||
@@ -6291,6 +6291,18 @@ void ScreenBufferTests::UpdateVirtualBottomAfterResizeWithReflow()
|
||||
Log::Comment(L"Confirm that the virtual viewport includes the last non-space row");
|
||||
const auto lastNonSpaceRow = si.GetTextBuffer().GetLastNonSpaceCharacter().Y;
|
||||
VERIFY_IS_GREATER_THAN_OR_EQUAL(si._virtualBottom, lastNonSpaceRow);
|
||||
|
||||
Log::Comment(L"Clear the screen and note the cursor distance to the virtual bottom");
|
||||
stateMachine.ProcessString(L"\033[H\033[2J");
|
||||
const auto cursorDistanceFromBottom = si._virtualBottom - si.GetTextBuffer().GetCursor().GetPosition().Y;
|
||||
VERIFY_ARE_EQUAL(si.GetViewport().Height() - 1, cursorDistanceFromBottom);
|
||||
|
||||
Log::Comment(L"Stretch the viewport back to full width");
|
||||
bufferSize.X *= 2;
|
||||
VERIFY_NT_SUCCESS(si.ResizeWithReflow(bufferSize));
|
||||
|
||||
Log::Comment(L"Confirm cursor distance to the virtual bottom is unchanged");
|
||||
VERIFY_ARE_EQUAL(cursorDistanceFromBottom, si._virtualBottom - si.GetTextBuffer().GetCursor().GetPosition().Y);
|
||||
}
|
||||
|
||||
void ScreenBufferTests::DontShrinkVirtualBottomDuringResizeWithReflowAtTop()
|
||||
|
||||
@@ -320,8 +320,14 @@ using namespace Microsoft::Console::Interactivity;
|
||||
// as far as the difference between parent/child and owner/owned
|
||||
// windows). Evan K said we should do it this way, and he
|
||||
// definitely knows.
|
||||
const auto windowStyle = WS_OVERLAPPEDWINDOW;
|
||||
const auto exStyles = WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_LAYERED;
|
||||
//
|
||||
// GH#13066: Load-bearing: Make sure to set WS_POPUP. If you
|
||||
// don't, then GetAncestor(GetConsoleWindow(), GA_ROOTOWNER)
|
||||
// will return the console handle again, not the owning
|
||||
// terminal's handle. It's not entirely clear why, but WS_POPUP
|
||||
// is absolutely vital for this to work correctly.
|
||||
const auto windowStyle = WS_OVERLAPPEDWINDOW | WS_POPUP;
|
||||
const auto exStyles = WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_LAYERED | WS_EX_NOACTIVATE;
|
||||
|
||||
// Attempt to create window.
|
||||
hwnd = CreateWindowExW(exStyles,
|
||||
@@ -335,7 +341,7 @@ using namespace Microsoft::Console::Interactivity;
|
||||
owner,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr);
|
||||
this);
|
||||
|
||||
if (hwnd == nullptr)
|
||||
{
|
||||
@@ -472,7 +478,18 @@ void InteractivityFactory::SetPseudoWindowCallback(std::function<void(bool)> fun
|
||||
// - <none>
|
||||
void InteractivityFactory::_WritePseudoWindowCallback(bool showOrHide)
|
||||
{
|
||||
if (_pseudoWindowMessageCallback)
|
||||
// BODGY
|
||||
//
|
||||
// GH#13158 - At least temporarily, only allow the PTY to HIDE the terminal
|
||||
// window. There seem to be many issues with this so far, and the quickest
|
||||
// route to mitigate them seems to be limiting the interaction here to
|
||||
// allowing ConPTY to minimize the terminal only. This will still allow
|
||||
// applications to hide the Terminal via GetConsoleWindow(), but should
|
||||
// broadly prevent any other impact of this feature.
|
||||
//
|
||||
// Should we need to restore this functionality in the future, we should
|
||||
// only do so with great caution.
|
||||
if (_pseudoWindowMessageCallback && showOrHide == false)
|
||||
{
|
||||
_pseudoWindowMessageCallback(showOrHide);
|
||||
}
|
||||
|
||||
@@ -484,9 +484,9 @@ class UiaTextRangeTests
|
||||
|
||||
Log::Comment(L"_start and end should be 2 units apart. Sign depends on order of comparison.");
|
||||
THROW_IF_FAILED(utr1->CompareEndpoints(TextPatternRangeEndpoint_End, utr2.Get(), TextPatternRangeEndpoint_End, &comparison));
|
||||
VERIFY_IS_TRUE(comparison == -2);
|
||||
VERIFY_IS_TRUE(comparison == -1);
|
||||
THROW_IF_FAILED(utr2->CompareEndpoints(TextPatternRangeEndpoint_End, utr1.Get(), TextPatternRangeEndpoint_End, &comparison));
|
||||
VERIFY_IS_TRUE(comparison == 2);
|
||||
VERIFY_IS_TRUE(comparison == 1);
|
||||
}
|
||||
|
||||
TEST_METHOD(ExpandToEnclosingUnit)
|
||||
|
||||
@@ -1036,9 +1036,18 @@ DWORD WINAPI ConsoleInputThreadProcWin32(LPVOID /*lpParameter*/)
|
||||
// If we are headless (because we're a pseudo console), we
|
||||
// will still need a window handle in the win32 environment
|
||||
// in case anyone sends messages at that HWND (vim.exe is an example.)
|
||||
// We have to CreateWindow on the same thread that will pump the messages
|
||||
// which is this thread.
|
||||
ServiceLocator::LocatePseudoWindow();
|
||||
//
|
||||
// IMPORTANT! We have to CreateWindow on the same thread that will pump
|
||||
// the messages, which is this thread. If you DON'T, then a DPI change
|
||||
// in the owning hwnd will cause us to get a dpi change as well, which
|
||||
// we'll never deque and handle, effectively HANGING THE OWNER HWND.
|
||||
// ServiceLocator::LocatePseudoWindow();
|
||||
//
|
||||
// Instead of just calling LocatePseudoWindow, make sure to go through
|
||||
// VtIo's CreatePseudoWindow, which will make sure that the window is
|
||||
// successfully created with the owner configured when the window is
|
||||
// first created. See GH#13066 for details.
|
||||
ServiceLocator::LocateGlobals().getConsoleInformation().GetVtIo()->CreatePseudoWindow();
|
||||
}
|
||||
|
||||
UnlockConsole();
|
||||
|
||||
@@ -174,9 +174,15 @@ constexpr HRESULT vec2_narrow(U x, U y, AtlasEngine::vec2<T>& out) noexcept
|
||||
|
||||
[[nodiscard]] HRESULT AtlasEngine::UpdateViewport(const SMALL_RECT srNewViewport) noexcept
|
||||
{
|
||||
_api.cellCount.x = gsl::narrow_cast<u16>(srNewViewport.Right - srNewViewport.Left + 1);
|
||||
_api.cellCount.y = gsl::narrow_cast<u16>(srNewViewport.Bottom - srNewViewport.Top + 1);
|
||||
WI_SetFlag(_api.invalidations, ApiInvalidations::Size);
|
||||
const u16x2 cellCount{
|
||||
gsl::narrow_cast<u16>(srNewViewport.Right - srNewViewport.Left + 1),
|
||||
gsl::narrow_cast<u16>(srNewViewport.Bottom - srNewViewport.Top + 1),
|
||||
};
|
||||
if (_api.cellCount != cellCount)
|
||||
{
|
||||
_api.cellCount = cellCount;
|
||||
WI_SetFlag(_api.invalidations, ApiInvalidations::Size);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -150,15 +150,10 @@ bool InteractDispatch::MoveCursor(const VTInt row, const VTInt col)
|
||||
|
||||
const auto coordCursorShort = til::unwrap_coord(coordCursor);
|
||||
|
||||
// MSFT: 15813316 - Try to use this MoveCursor call to inherit the cursor position.
|
||||
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
||||
RETURN_IF_FAILED(gci.GetVtIo()->SetCursorPosition(coordCursorShort));
|
||||
|
||||
// Finally, attempt to set the adjusted cursor position back into the console.
|
||||
auto& cursor = _api.GetTextBuffer().GetCursor();
|
||||
cursor.SetPosition(coordCursorShort);
|
||||
cursor.SetHasMoved(true);
|
||||
return true;
|
||||
const auto api = gsl::not_null{ ServiceLocator::LocateGlobals().api };
|
||||
auto& info = ServiceLocator::LocateGlobals().getConsoleInformation().GetActiveOutputBuffer();
|
||||
return SUCCEEDED(api->SetConsoleCursorPositionImpl(info, coordCursorShort));
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
@@ -204,11 +199,19 @@ bool InteractDispatch::FocusChanged(const bool focused) const
|
||||
{
|
||||
// They want focus, we found a pseudo hwnd.
|
||||
|
||||
// Note: ::GetParent(pseudoHwnd) will return 0. GetAncestor works though.
|
||||
// GA_PARENT and GA_ROOT seemingly return the same thing for
|
||||
// Terminal. We're going with GA_ROOT since it seems
|
||||
// semantically more correct here.
|
||||
if (const auto ownerHwnd{ ::GetAncestor(pseudoHwnd, GA_ROOT) })
|
||||
// BODGY
|
||||
//
|
||||
// This needs to be GA_ROOTOWNER here. Not GA_ROOT, GA_PARENT,
|
||||
// or GetParent. The ConPTY hwnd is an owned, top-level, popup,
|
||||
// non-parented window. It does not have a parent set. It does
|
||||
// have an owner set. It is not a WS_CHILD window. This
|
||||
// combination of things allows us to find the owning window
|
||||
// with GA_ROOTOWNER. GA_ROOT will get us ourselves, and
|
||||
// GA_PARENT will return the desktop HWND.
|
||||
//
|
||||
// See GH#13066
|
||||
|
||||
if (const auto ownerHwnd{ ::GetAncestor(pseudoHwnd, GA_ROOTOWNER) })
|
||||
{
|
||||
// We have an owner from a previous call to ReparentWindow
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ try
|
||||
RETURN_IF_FAILED(RuntimeClassInitialize(pData, pProvider, wordDelimiters));
|
||||
|
||||
// start is before/at end, so this is valid
|
||||
if (_pData->GetTextBuffer().GetSize().CompareInBounds(start, end, true) <= 0)
|
||||
if (til::point{ start } <= til::point{ end })
|
||||
{
|
||||
_start = start;
|
||||
_end = end;
|
||||
@@ -166,7 +166,7 @@ bool UiaTextRangeBase::SetEndpoint(TextPatternRangeEndpoint endpoint, const COOR
|
||||
case TextPatternRangeEndpoint_End:
|
||||
_end = val;
|
||||
// if end is before start...
|
||||
if (bufferSize.CompareInBounds(_end, _start, true) < 0)
|
||||
if (til::point{ _end } < til::point{ _start })
|
||||
{
|
||||
// make this range degenerate at end
|
||||
_start = _end;
|
||||
@@ -175,7 +175,7 @@ bool UiaTextRangeBase::SetEndpoint(TextPatternRangeEndpoint endpoint, const COOR
|
||||
case TextPatternRangeEndpoint_Start:
|
||||
_start = val;
|
||||
// if start is after end...
|
||||
if (bufferSize.CompareInBounds(_start, _end, true) > 0)
|
||||
if (til::point{ _start } > til::point{ _end })
|
||||
{
|
||||
// make this range degenerate at start
|
||||
_end = _start;
|
||||
@@ -241,18 +241,20 @@ try
|
||||
|
||||
// get endpoint value that we're comparing to
|
||||
const auto other = range->GetEndpoint(targetEndpoint);
|
||||
const til::point otherPt{ other.X, other.Y };
|
||||
|
||||
// get the values of our endpoint
|
||||
const auto mine = GetEndpoint(endpoint);
|
||||
const til::point minePt{ mine.X, mine.Y };
|
||||
|
||||
// TODO GH#5406: create a different UIA parent object for each TextBuffer
|
||||
// This is a temporary solution to comparing two UTRs from different TextBuffers
|
||||
// Ensure both endpoints fit in the current buffer.
|
||||
const auto bufferSize = _pData->GetTextBuffer().GetSize();
|
||||
RETURN_HR_IF(E_FAIL, !bufferSize.IsInBounds(mine, true) || !bufferSize.IsInBounds(other, true));
|
||||
// We should return E_FAIL if we detect that the endpoints are from two different TextBuffer objects.
|
||||
// For now, we're fine to not do that because we're not using any code that can FAIL_FAST anymore.
|
||||
|
||||
// compare them
|
||||
*pRetVal = bufferSize.CompareInBounds(mine, other, true);
|
||||
*pRetVal = minePt < otherPt ? -1 :
|
||||
minePt > otherPt ? 1 :
|
||||
0;
|
||||
|
||||
UiaTracing::TextRange::CompareEndpoints(*this, endpoint, *range, targetEndpoint, *pRetVal);
|
||||
return S_OK;
|
||||
@@ -293,7 +295,7 @@ void UiaTextRangeBase::_expandToEnclosingUnit(TextUnit unit)
|
||||
// If we're past document end,
|
||||
// set us to ONE BEFORE the document end.
|
||||
// This allows us to expand properly.
|
||||
if (bufferSize.CompareInBounds(_start, documentEnd.to_win32_coord(), true) >= 0)
|
||||
if (til::point{ _start } >= documentEnd)
|
||||
{
|
||||
_start = documentEnd.to_win32_coord();
|
||||
bufferSize.DecrementInBounds(_start, true);
|
||||
@@ -652,8 +654,8 @@ try
|
||||
bufferSize.IncrementInBounds(end, true);
|
||||
|
||||
// make sure what was found is within the bounds of the current range
|
||||
if ((searchDirection == Search::Direction::Forward && bufferSize.CompareInBounds(end, _end, true) < 0) ||
|
||||
(searchDirection == Search::Direction::Backward && bufferSize.CompareInBounds(start, _start) > 0))
|
||||
if ((searchDirection == Search::Direction::Forward && til::point{ end } < til::point{ _end }) ||
|
||||
(searchDirection == Search::Direction::Backward && til::point{ start } > til::point{ _start }))
|
||||
{
|
||||
RETURN_IF_FAILED(Clone(ppRetVal));
|
||||
auto& range = static_cast<UiaTextRangeBase&>(**ppRetVal);
|
||||
@@ -865,29 +867,29 @@ IFACEMETHODIMP UiaTextRangeBase::GetBoundingRectangles(_Outptr_result_maybenull_
|
||||
|
||||
// these viewport vars are converted to the buffer coordinate space
|
||||
const auto viewport = bufferSize.ConvertToOrigin(_pData->GetViewport());
|
||||
const auto viewportOrigin = viewport.Origin();
|
||||
const auto viewportEnd = viewport.EndExclusive();
|
||||
const til::point viewportOrigin{ viewport.Origin().X, viewport.Origin().Y };
|
||||
const til::point viewportEnd{ viewport.EndExclusive().X, viewport.EndExclusive().Y };
|
||||
|
||||
// startAnchor: the earliest COORD we will get a bounding rect for
|
||||
auto startAnchor = GetEndpoint(TextPatternRangeEndpoint_Start);
|
||||
if (bufferSize.CompareInBounds(startAnchor, viewportOrigin, true) < 0)
|
||||
if (til::point{ startAnchor } < viewportOrigin)
|
||||
{
|
||||
// earliest we can be is the origin
|
||||
startAnchor = viewportOrigin;
|
||||
startAnchor = viewportOrigin.to_win32_coord();
|
||||
}
|
||||
|
||||
// endAnchor: the latest COORD we will get a bounding rect for
|
||||
auto endAnchor = GetEndpoint(TextPatternRangeEndpoint_End);
|
||||
if (bufferSize.CompareInBounds(endAnchor, viewportEnd, true) > 0)
|
||||
if (til::point{ endAnchor } > viewportEnd)
|
||||
{
|
||||
// latest we can be is the viewport end
|
||||
endAnchor = viewportEnd;
|
||||
endAnchor = viewportEnd.to_win32_coord();
|
||||
}
|
||||
|
||||
// _end is exclusive, let's be inclusive so we don't have to think about it anymore for bounding rects
|
||||
bufferSize.DecrementInBounds(endAnchor, true);
|
||||
|
||||
if (IsDegenerate() || bufferSize.CompareInBounds(_start, viewportEnd, true) > 0 || bufferSize.CompareInBounds(_end, viewportOrigin, true) < 0)
|
||||
if (IsDegenerate() || til::point{ _start } > viewportEnd || til::point{ _end } < viewportOrigin)
|
||||
{
|
||||
// An empty array is returned for a degenerate (empty) text range.
|
||||
// reference: https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationtextrange-getboundingrectangles
|
||||
@@ -994,10 +996,7 @@ std::wstring UiaTextRangeBase::_getTextValue(std::optional<unsigned int> maxLeng
|
||||
// TODO GH#5406: create a different UIA parent object for each TextBuffer
|
||||
// nvaccess/nvda#11428: Ensure our endpoints are in bounds
|
||||
// otherwise, we'll FailFast catastrophically
|
||||
if (!bufferSize.IsInBounds(_start, true) || !bufferSize.IsInBounds(_end, true))
|
||||
{
|
||||
THROW_HR(E_FAIL);
|
||||
}
|
||||
THROW_HR_IF(E_FAIL, !bufferSize.IsInBounds(_start) || !bufferSize.IsInBounds(_end));
|
||||
|
||||
// convert _end to be inclusive
|
||||
auto inclusiveEnd = _end;
|
||||
@@ -1044,14 +1043,14 @@ try
|
||||
// If so, clamp each endpoint to the end of the document.
|
||||
constexpr auto endpoint = TextPatternRangeEndpoint::TextPatternRangeEndpoint_Start;
|
||||
const auto bufferSize{ _pData->GetTextBuffer().GetSize() };
|
||||
const auto documentEnd = _getDocumentEnd().to_win32_coord();
|
||||
if (bufferSize.CompareInBounds(_start, documentEnd, true) > 0)
|
||||
const auto documentEnd = _getDocumentEnd();
|
||||
if (til::point{ _start } > documentEnd)
|
||||
{
|
||||
_start = documentEnd;
|
||||
_start = documentEnd.to_win32_coord();
|
||||
}
|
||||
if (bufferSize.CompareInBounds(_end, documentEnd, true) > 0)
|
||||
if (til::point{ _end } > documentEnd)
|
||||
{
|
||||
_end = documentEnd;
|
||||
_end = documentEnd.to_win32_coord();
|
||||
}
|
||||
|
||||
const auto wasDegenerate = IsDegenerate();
|
||||
@@ -1112,20 +1111,20 @@ IFACEMETHODIMP UiaTextRangeBase::MoveEndpointByUnit(_In_ TextPatternRangeEndpoin
|
||||
// If so, clamp each endpoint to the end of the document.
|
||||
const auto bufferSize{ _pData->GetTextBuffer().GetSize() };
|
||||
|
||||
auto documentEnd = bufferSize.EndExclusive();
|
||||
til::point documentEnd{ bufferSize.EndExclusive().X, bufferSize.EndExclusive().Y };
|
||||
try
|
||||
{
|
||||
documentEnd = _getDocumentEnd().to_win32_coord();
|
||||
documentEnd = _getDocumentEnd();
|
||||
}
|
||||
CATCH_LOG();
|
||||
|
||||
if (bufferSize.CompareInBounds(_start, documentEnd, true) > 0)
|
||||
if (til::point{ _start } > documentEnd)
|
||||
{
|
||||
_start = documentEnd;
|
||||
_start = documentEnd.to_win32_coord();
|
||||
}
|
||||
if (bufferSize.CompareInBounds(_end, documentEnd, true) > 0)
|
||||
if (til::point{ _end } > documentEnd)
|
||||
{
|
||||
_end = documentEnd;
|
||||
_end = documentEnd.to_win32_coord();
|
||||
}
|
||||
|
||||
try
|
||||
@@ -1173,7 +1172,7 @@ try
|
||||
const auto bufferSize = _pData->GetTextBuffer().GetSize();
|
||||
const auto mine = GetEndpoint(endpoint);
|
||||
const auto other = range->GetEndpoint(targetEndpoint);
|
||||
RETURN_HR_IF(E_FAIL, !bufferSize.IsInBounds(mine, true) || !bufferSize.IsInBounds(other, true));
|
||||
RETURN_HR_IF(E_FAIL, !bufferSize.IsInBounds(mine) || !bufferSize.IsInBounds(other));
|
||||
|
||||
SetEndpoint(endpoint, range->GetEndpoint(targetEndpoint));
|
||||
|
||||
@@ -1199,10 +1198,7 @@ try
|
||||
else
|
||||
{
|
||||
const auto bufferSize = _pData->GetTextBuffer().GetSize();
|
||||
if (!bufferSize.IsInBounds(_start, true) || !bufferSize.IsInBounds(_end, true))
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
RETURN_HR_IF(E_FAIL, !bufferSize.IsInBounds(_start) || !bufferSize.IsInBounds(_end));
|
||||
auto inclusiveEnd = _end;
|
||||
bufferSize.DecrementInBounds(inclusiveEnd);
|
||||
_pData->SelectNewRegion(_start, inclusiveEnd);
|
||||
@@ -1516,7 +1512,7 @@ void UiaTextRangeBase::_moveEndpointByUnitWord(_In_ const int moveCount,
|
||||
{
|
||||
case MovementDirection::Forward:
|
||||
{
|
||||
if (bufferSize.CompareInBounds(nextPos, documentEnd.to_win32_coord(), true) >= 0)
|
||||
if (til::point{ nextPos } >= documentEnd)
|
||||
{
|
||||
success = false;
|
||||
}
|
||||
@@ -1730,20 +1726,20 @@ void UiaTextRangeBase::_moveEndpointByUnitDocument(_In_ const int moveCount,
|
||||
{
|
||||
case MovementDirection::Forward:
|
||||
{
|
||||
auto documentEnd{ bufferSize.EndExclusive() };
|
||||
til::point documentEnd{ bufferSize.EndExclusive().X, bufferSize.EndExclusive().Y };
|
||||
try
|
||||
{
|
||||
documentEnd = _getDocumentEnd().to_win32_coord();
|
||||
documentEnd = _getDocumentEnd();
|
||||
}
|
||||
CATCH_LOG();
|
||||
|
||||
if (preventBoundary || bufferSize.CompareInBounds(target, documentEnd, true) >= 0)
|
||||
if (preventBoundary || til::point{ target } >= documentEnd)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetEndpoint(endpoint, documentEnd);
|
||||
SetEndpoint(endpoint, documentEnd.to_win32_coord());
|
||||
(*pAmountMoved)++;
|
||||
}
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user