diff --git a/.github/actions/spell-check/advice.txt b/.github/actions/spell-check/advice.txt
index 37cdd512048..7a5ed8d20c3 100644
--- a/.github/actions/spell-check/advice.txt
+++ b/.github/actions/spell-check/advice.txt
@@ -3,13 +3,21 @@
:pencil2: Contributor please read this
-* If the items listed above are names, please add them to `.github/actions/spell-check/dictionary/names.txt`.
-* If they're APIs, you can add them to a file in `.github/actions/spell-check/dictionary/`.
-* If they're just things you're using, please add them to an appropriate file in `.github/actions/spell-check/whitelist/`.
-* If you need to use a specific token in one place and it shouldn't generally be used, you can
-add an item in an appropriate file in `.github/actions/spell-check/patterns/`.
+By default the command suggestion will generate a file named based on your commit. That's generally ok as long as you add the file to your commit. Someone can reorganize it later.
+
+:warning: The command is written for posix shells. You can copy the contents of each `perl` command excluding the outer `'` marks and dropping any `'"`/`"'` quotation mark pairs into a file and then run `perl file.pl` from the root of the repository to run the code. Alternatively, you can manually insert the items...
+
+If the listed items are:
+* ... **misspelled**, then please *correct* them instead of using the command.
+* ... *names*, please add them to `.github/actions/spell-check/dictionary/names.txt`.
+* ... APIs, you can add them to a file in `.github/actions/spell-check/dictionary/`.
+* ... just things you're using, please add them to an appropriate file in `.github/actions/spell-check/expect/`.
+* ... tokens you only need in one place and shouldn't *generally be used*, you can add an item in an appropriate file in `.github/actions/spell-check/patterns/`.
See the `README.md` in each directory for more information.
+
+:microscope: You can test your commits **without** *appending* to a PR by creating a new branch with that extra change and pushing it to your fork. The [:check-spelling](https://github.com/marketplace/actions/check-spelling) action will run in response to your **push** -- it doesn't require an open pull request. By using such a branch, you can limit the number of typos your peers see you make. :wink:
+
#### :warning: Reviewers
diff --git a/.github/actions/spell-check/dictionary/apis.txt b/.github/actions/spell-check/dictionary/apis.txt
index 31381336e89..f54829e13c3 100644
--- a/.github/actions/spell-check/dictionary/apis.txt
+++ b/.github/actions/spell-check/dictionary/apis.txt
@@ -1,17 +1,29 @@
+ACCEPTFILES
+ACCESSDENIED
bitfield
bitfields
+CLASSNOTAVAILABLE
+EXPCMDFLAGS
+EXPCMDSTATE
+fullkbd
href
IBox
+IBind
ICustom
+IClass
+IExplorer
IMap
IObject
+IStorage
LCID
NCHITTEST
NCLBUTTONDBLCLK
NCRBUTTONDBLCLK
+NOAGGREGATION
NOREDIRECTIONBITMAP
oaidl
ocidl
rfind
roundf
SIZENS
+tmp
diff --git a/.github/actions/spell-check/dictionary/microsoft.txt b/.github/actions/spell-check/dictionary/microsoft.txt
index 50831af918c..62cd27b72cd 100644
--- a/.github/actions/spell-check/dictionary/microsoft.txt
+++ b/.github/actions/spell-check/dictionary/microsoft.txt
@@ -3,6 +3,7 @@ mfcribbon
microsoft
microsoftonline
osgvsowi
+powerrename
powershell
tdbuildteamid
vcruntime
diff --git a/.github/actions/spell-check/dictionary/names.txt b/.github/actions/spell-check/dictionary/names.txt
index 737c6932e24..6d47c4e98e9 100644
--- a/.github/actions/spell-check/dictionary/names.txt
+++ b/.github/actions/spell-check/dictionary/names.txt
@@ -3,6 +3,7 @@ austdi
Ballmer
bhoj
Bhojwani
+carlos
dhowett
Diviness
dsafa
@@ -53,6 +54,8 @@ Wirt
Wojciech
zadjii
Zamor
+Zamora
+zamora
Zoey
zorio
Zverovich
diff --git a/.github/actions/spell-check/excludes.txt b/.github/actions/spell-check/excludes.txt
index c470442f2f2..97eb58e3ff7 100644
--- a/.github/actions/spell-check/excludes.txt
+++ b/.github/actions/spell-check/excludes.txt
@@ -51,6 +51,7 @@ SUMS$
\.xpm$
\.yml$
\.zip$
+^consolegit2gitfilters\.json$
^dep/
^oss/
^doc/reference/UTF8-torture-test\.txt$
diff --git a/.github/actions/spell-check/expect/README.md b/.github/actions/spell-check/expect/README.md
new file mode 100644
index 00000000000..d94245a184f
--- /dev/null
+++ b/.github/actions/spell-check/expect/README.md
@@ -0,0 +1,13 @@
+The contents of each `.txt` file in this directory are merged together.
+
+* [alphabet](alphabet.txt) is a sample for alphabet related items
+* [web](web.txt) is a sample for web/html related items
+* [expect](expect.txt) is the main list of expected items -- there is nothing
+particularly special about the file name (beyond the extension which is
+important).
+
+These terms are things which temporarily exist in the project, but which
+aren't necessarily words.
+
+If something is a word that could come and go, it probably belongs in a
+[dictionary](../dictionary/README.md).
diff --git a/.github/actions/spell-check/whitelist/alphabet.txt b/.github/actions/spell-check/expect/alphabet.txt
similarity index 98%
rename from .github/actions/spell-check/whitelist/alphabet.txt
rename to .github/actions/spell-check/expect/alphabet.txt
index c23b6c91d2b..3644d8e5922 100644
--- a/.github/actions/spell-check/whitelist/alphabet.txt
+++ b/.github/actions/spell-check/expect/alphabet.txt
@@ -1,4 +1,3 @@
-abcd
abcde
abcdef
ABCDEFG
@@ -8,6 +7,7 @@ abcdefghijk
abcdefghijklmnop
ABCDEFGHIJKLMNOPQRST
abcdefghijklmnopqrstuvwxyz
+ABE
BBBBBBBBBBBBBBDDDD
QQQQQQQQQQABCDEFGHIJ
QQQQQQQQQQABCDEFGHIJKLMNOPQRSTQQQQQQQQQ
diff --git a/.github/actions/spell-check/whitelist/whitelist.txt b/.github/actions/spell-check/expect/expect.txt
similarity index 98%
rename from .github/actions/spell-check/whitelist/whitelist.txt
rename to .github/actions/spell-check/expect/expect.txt
index e77a94ec6b3..b80f28df503 100644
--- a/.github/actions/spell-check/whitelist/whitelist.txt
+++ b/.github/actions/spell-check/expect/expect.txt
@@ -2,18 +2,11 @@ AAAAAABBBBBBCCC
AAAAABBBBBBBCCC
AAAAABCCCCCCCCC
AAAAADCCCCCCCCC
-AAD
ABANDONFONT
ABCDEFGHIJKLMNO
ABCG
-abe
-abec
abf
abi
-acb
-accd
-ACCEPTFILES
-ACCESSDENIED
acec
acf
acidev
@@ -29,10 +22,7 @@ ADDREF
addressof
ADDSTRING
ADDTOOL
-aeed
AEnd
-afae
-afceeeaa
AFew
AFill
AFX
@@ -131,7 +121,6 @@ awch
azuredevopspodcast
azurewebsites
azzle
-baac
backend
backgrounded
Backgrounder
@@ -142,23 +131,15 @@ Batang
baz
Bazz
BBBBCCCCC
-bbc
-bbd
BBDM
-bbe
bbwe
bc
-bca
-bcb
-bcc
bcount
bcrypt
bcx
bcz
-bda
BEFOREPARENT
beginthread
-bfb
bgcolor
bgfx
bgidx
@@ -172,7 +153,6 @@ binplace
binplaced
bitcoin
bitcrazed
-bitfield
bitflag
bitmask
BITOPERATION
@@ -215,7 +195,6 @@ BValue
byref
bytearray
bytebuffer
-caa
Cac
callee
cang
@@ -226,7 +205,6 @@ cascadia
catid
cazamor
CBash
-cbb
cbegin
cbiex
CBN
@@ -247,12 +225,9 @@ CConversion
CCRT
cctype
CDATA
-CDBA
cdd
-CDE
cdecl
CDeclaration
-cebb
CEdit
CELLSIZE
cend
@@ -500,14 +475,10 @@ dai
DATABLOCK
DATAVIEW
DATAW
-dba
DBatch
-dbb
dbcs
DBCSCHAR
DBCSFONT
-dbd
-DBDCF
dbg
DBGALL
DBGCHARS
@@ -518,13 +489,11 @@ dblclk
DBlob
dbproj
DBUILD
-dcf
DColor
DCOLORVALUE
dcommon
DCompile
dcompiler
-ddb
dde
DDESHARE
DDevice
@@ -557,6 +526,7 @@ deconstructed
DECPCTERM
DECRC
DECRLM
+DECRQM
DECRST
DECSASD
DECSC
@@ -616,7 +586,6 @@ devicefamily
devops
Dext
df
-dfa
DFactory
dh
dialogbox
@@ -637,6 +606,7 @@ dllexport
DLLGETVERSIONPROC
dllimport
dllinit
+dllmain
DLLVERSIONINFO
DLOAD
DLOOK
@@ -684,14 +654,9 @@ dxgidwm
dxinterop
dxttbmp
eachother
-EAEC
eaf
EASTEUROPE
eb
-eba
-ebce
-EBFB
-ECFB
ECH
echokey
ecount
@@ -701,8 +666,6 @@ EDITTEXT
EDITUPDATE
edputil
edu
-eeb
-eee
Efast
EHsc
EJO
@@ -712,7 +675,6 @@ Elems
elif
elseif
emacs
-Emojis
emptybox
enabledelayedexpansion
endian
@@ -731,6 +693,7 @@ ENUMLOGFONTEX
enumranges
envvar
eol
+EPres
ERASEBKGND
errno
errorlevel
@@ -769,26 +732,17 @@ failfast
FAILIFTHERE
fallthrough
FARPROC
-fba
-fbb
-fbd
-fbdc
-FBE
fcb
-fcc
fcharset
fclose
fcntl
-fd
-fdb
fdc
-fdd
+FDD
fde
fdopen
fdw
fea
fesb
-ffc
FFDE
FFF
FFrom
@@ -934,7 +888,6 @@ Gfun
gfx
gh
github
-githubusercontent
gitlab
gle
globals
@@ -1027,7 +980,6 @@ hpp
HPR
HPROPSHEETPAGE
HREDRAW
-HREF
hresult
HRSRC
hscroll
@@ -1398,7 +1350,6 @@ memallocator
memcmp
memcopy
memcpy
-memcpying
memmove
memset
MENUCHAR
@@ -1672,11 +1623,9 @@ Outof
OUTOFCONTEXT
OUTOFMEMORY
outout
-OUTPATHROOT
Outptr
Ov
OVERLAPPEDWINDOW
-OVR
OWNDC
OWNERDRAWFIXED
packageuwp
@@ -2146,6 +2095,7 @@ SHIFTJIS
Shl
shlguid
shlobj
+shobjidl
shlwapi
SHORTPATH
SHOWCURSOR
@@ -2233,7 +2183,6 @@ stgm
stl
stoi
stol
-storageitems
storelogo
stoul
stoutapot
@@ -2339,7 +2288,6 @@ TEXCOORD
texel
textattribute
TEXTATTRIBUTEID
-textblock
Textbox
textboxes
textbuffer
@@ -2367,7 +2315,6 @@ TLEN
Tlg
Tlgdata
TMAE
-tmp
TMPF
TMult
tmultiple
@@ -2400,7 +2347,6 @@ TRACKCOMPOSITION
trackpad
transcoder
transitioning
-trc
Trd
TREX
triaged
@@ -2438,6 +2384,7 @@ uap
uapadmin
ubuntu
ucd
+UCD
uch
UCHAR
ucs
@@ -2520,7 +2467,6 @@ USESHOWWINDOW
USESIZE
USESTDHANDLES
ushort
-usr
USRDLL
utf
utils
@@ -2562,7 +2508,6 @@ vkey
VKKEYSCAN
VMs
VPA
-vpack
VPATH
VPR
VPrintf
@@ -2637,7 +2582,6 @@ wfdopen
WFill
wfopen
wfstream
-WGL
WHelper
whitelisting
WIDTHSCROLL
@@ -2659,6 +2603,7 @@ wincontypes
WINCORE
windbg
WINDEF
+winget
WINDIR
windll
WINDOWALPHA
@@ -2743,7 +2688,6 @@ WRITECONSOLEINPUT
WRITECONSOLEOUTPUT
WRITECONSOLEOUTPUTSTRING
wrl
-wrn
wrp
WRunoff
WScript
diff --git a/.github/actions/spell-check/whitelist/web.txt b/.github/actions/spell-check/expect/web.txt
similarity index 79%
rename from .github/actions/spell-check/whitelist/web.txt
rename to .github/actions/spell-check/expect/web.txt
index 407af43b036..c0c237ed13c 100644
--- a/.github/actions/spell-check/whitelist/web.txt
+++ b/.github/actions/spell-check/expect/web.txt
@@ -11,3 +11,5 @@ kovidgoyal
leonerd
fixterms
uk
+winui
+appshellintegration
diff --git a/.github/actions/spell-check/patterns/patterns.txt b/.github/actions/spell-check/patterns/patterns.txt
index 6f8607216b3..cddd540bffe 100644
--- a/.github/actions/spell-check/patterns/patterns.txt
+++ b/.github/actions/spell-check/patterns/patterns.txt
@@ -1,9 +1,12 @@
-https://(?:(?:[-a-zA-Z0-9?&=]*\.|)microsoft\.com)/[-a-zA-Z0-9?&=_\/.]*
+https://(?:(?:[-a-zA-Z0-9?&=]*\.|)microsoft\.com)/[-a-zA-Z0-9?&=_#\/.]*
https://aka\.ms/[-a-zA-Z0-9?&=\/_]*
https://www.w3.org/[-a-zA-Z0-9?&=\/_#]*
https://(?:(?:www\.|)youtube\.com|youtu.be)/[-a-zA-Z0-9?&=]*
+https://[a-z-]+\.githubusercontent\.com/[-a-zA-Z0-9?&=_\/.]*
+[Pp]ublicKeyToken="?[0-9a-fA-F]{16}"?
+(?:[{"]|UniqueIdentifier>)[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}(?:[}"]| * Be sure to install the [Desktop Bridge VC++ v14 Redistributable Package](https://www.microsoft.com/en-us/download/details.aspx?id=53175) otherwise Terminal may not install and/or run and may crash at startup
> * Terminal will not auto-update when new builds are released so you will need to regularly install the latest Terminal release to receive all the latest fixes and improvements!
+#### Via Windows Package Manager CLI (aka winget)
+
+[winget](https://github.com/microsoft/winget-cli) users can download and install the latest Terminal release by installing the `Microsoft.WindowsTerminal` package:
+
+```powershell
+winget install --id=Microsoft.WindowsTerminal -e
+```
+
#### Via Chocolatey (unofficial)
[Chocolatey](https://chocolatey.org) users can download and install the latest Terminal release by installing the `microsoft-windows-terminal` package:
@@ -61,12 +71,6 @@ ColorTool|![](https://microsoft.visualstudio.com/_apis/public/build/definitions/
---
-## Windows Terminal v1.0 Roadmap
-
-The plan for delivering Windows Terminal v1.0 [is described here](/doc/terminal-v1-roadmap.md), and will be updated as the project proceeds.
-
----
-
## Terminal & Console Overview
Please take a few minutes to review the overview below before diving into the code:
@@ -131,7 +135,7 @@ Solution: Make sure you're building & deploying the `CascadiaPackage` project in
## Documentation
-All project documentation is located in the `./doc` folder. If you would like to contribute to the documentation, please submit a pull request.
+All project documentation is located at aka.ms/terminal-docs. If you would like to contribute to the documentation, please submit a pull request on the [Windows Terminal Documentation repo](https://github.com/MicrosoftDocs/terminal).
---
@@ -226,4 +230,4 @@ For more information see the [Code of Conduct FAQ][conduct-FAQ] or contact [open
[conduct-code]: https://opensource.microsoft.com/codeofconduct/
[conduct-FAQ]: https://opensource.microsoft.com/codeofconduct/faq/
[conduct-email]: mailto:opencode@microsoft.com
-[store-install-link]: https://aka.ms/windowsterminal
+[store-install-link]: https://aka.ms/terminal
diff --git a/doc/cascadia/SettingsSchema.md b/doc/cascadia/SettingsSchema.md
index 0ee88a6d5c5..55a0f7ec616 100644
--- a/doc/cascadia/SettingsSchema.md
+++ b/doc/cascadia/SettingsSchema.md
@@ -47,6 +47,7 @@ Properties listed below are specific to each unique profile.
| `cursorShape` | Optional | String | `bar` | Sets the cursor shape for the profile. Possible values: `"vintage"` ( ▃ ), `"bar"` ( ┃ ), `"underscore"` ( ▁ ), `"filledBox"` ( █ ), `"emptyBox"` ( ▯ ) |
| `fontFace` | Optional | String | `Cascadia Mono` | Name of the font face used in the profile. We will try to fallback to Consolas if this can't be found or is invalid. |
| `fontSize` | Optional | Integer | `12` | Sets the font size. |
+| `fontWeight` | Optional | String | `normal` | Sets the weight (lightness or heaviness of the strokes) for the given font. Possible values: `"thin"`, `"extra-light"`, `"light"`, `"semi-light"`, `"normal"`, `"medium"`, `"semi-bold"`, `"bold"`, `"extra-bold"`, `"black"`, `"extra-black"`, or the corresponding numeric representation of OpenType font weight. |
| `foreground` | Optional | String | | Sets the foreground color of the profile. Overrides `foreground` set in color scheme if `colorscheme` is set. Uses hex color format: `#rgb` or `"#rrggbb"`. |
| `hidden` | Optional | Boolean | `false` | If set to true, the profile will not appear in the list of profiles. This can be used to hide default profiles and dynamically generated profiles, while leaving them in your settings file. |
| `historySize` | Optional | Integer | `9001` | The number of lines above the ones displayed in the window you can scroll back to. |
diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json
index 8ebcb9746e4..59592b51f64 100644
--- a/doc/cascadia/profiles.schema.json
+++ b/doc/cascadia/profiles.schema.json
@@ -531,6 +531,33 @@
"minimum": 1,
"type": "integer"
},
+ "fontWeight": {
+ "default": "normal",
+ "description": "Sets the weight (lightness or heaviness of the strokes) for the given font. Possible values:\n -\"thin\"\n -\"extra-light\"\n -\"light\"\n -\"semi-light\"\n -\"normal\" (default)\n -\"medium\"\n -\"semi-bold\"\n -\"bold\"\n -\"extra-bold\"\n -\"black\"\n -\"extra-black\" or the corresponding numeric representation of OpenType font weight.",
+ "oneOf": [
+ {
+ "enum": [
+ "thin",
+ "extra-light",
+ "light",
+ "semi-light",
+ "normal",
+ "medium",
+ "semi-bold",
+ "bold",
+ "extra-bold",
+ "black",
+ "extra-black"
+ ],
+ "type": "string"
+ },
+ {
+ "maximum": 990,
+ "minimum": 100,
+ "type": "integer"
+ }
+ ]
+ },
"foreground": {
"$ref": "#/definitions/Color",
"default": "#cccccc",
diff --git a/doc/specs/#4999 - Improved keyboard handling in Conpty.md b/doc/specs/#4999 - Improved keyboard handling in Conpty.md
index a113a483a63..29d12218823 100644
--- a/doc/specs/#4999 - Improved keyboard handling in Conpty.md
+++ b/doc/specs/#4999 - Improved keyboard handling in Conpty.md
@@ -1,7 +1,7 @@
---
author: Mike Griese @zadjii-msft
created on: 2020-05-07
-last updated: 2020-05-13
+last updated: 2020-05-20
issue id: 4999
---
@@ -61,7 +61,6 @@ The goal we're trying to achieve is communicating `INPUT_RECORD`s from the
terminal to the client app via conpty. This isn't supposed to be a \*nix
terminal compatible communication, it's supposed to be fundamentally Win32-like.
-
Keys that we definitely need to support, that don't have unique VT sequences:
* Ctrl+Space ([#879], [#2865])
* Shift+Enter ([#530])
@@ -69,6 +68,12 @@ Keys that we definitely need to support, that don't have unique VT sequences:
* Ctrl+Alt+? ([#3079])
* Ctrl, Alt, Shift, (without another keydown/up) ([#3608], [#4334], [#4446])
+> 👉 NOTE: There are actually 5 types of events that can all be encoded as an
+> `INPUT_RECORD`. This spec primarily focuses on the encoding of
+> `KEY_EVENT_RECORD`s. It is left as a Future Consideration to add support for
+> the other types of `INPUT_RECORD` as other sequences, which could be done
+> trivially similarly to the following proposal.
+
## Solution Design
### Inspiration
@@ -94,24 +99,25 @@ The design we've settled upon is one that's highly inspired by a few precedents:
### Requesting `win32-input-mode`
-An application can request `win32-input-mode` with the following OSC sequence
+An application can request `win32-input-mode` with the following private mode sequence:
```
- ^[ ] 1000 ; 1 ; Ps ST
-
- Ps: Whether to enable or disable win32-input-mode. If omitted, defaults to '0'.
- 0: Disable win32-input-mode
- 1: Enable win32-input-mode
+ ^[ [ ? 9001 h/l
+ l: Disable win32-input-mode
+ h: Enable win32-input-mode
```
-OSC 1000 seemed to be unused according to [this discussion of used
-OSCs](https://gitlab.freedesktop.org/terminal-wg/specifications/-/issues/10).
-This seems like a reasonable place to stake a claim for sequences used by the
-the Windows Terminal - future WT-specific sequences could also be placed as `OSC
-1000;2`, `OSC 1000;3`, etc. This pattern is also similar to the way iTerm2
-defines their own sequences.
+Private mode `9001` seems unused according to the [xterm
+documentation](https://invisible-island.net/xterm/ctlseqs/ctlseqs.html). This is
+stylistically similar to how `DECKPM`, `DECCKM`, and `kitty`'s ["full mode"] are
+enabled.
+
+> 👉 NOTE: an earlier draft of this spec used an OSC sequence for enabling these
+> sequences. This was abandoned in favor of the more stylistically consistent
+> private mode params proposed above. Additionally, if implemented as a private
+> mode, then a client app could query if this setting was set with `DECRQM`
-When a terminal receives a `^[]1000;1;1ST` sequence, they should switch into
+When a terminal receives a `^[[?9001h` sequence, they should switch into
`win32-input-mode`. In `win32-input-mode`, the terminal will send keyboard input
to the connected client application in the following format:
@@ -140,11 +146,7 @@ unused as a terminator by sequences _output_ by a client application, and
doesn't seem to be used as an _input_ sequence terminator either.
```
- ^[ [ Kd ; Rc ; Vk ; Sc ; Uc ; Cs _
-
- Kd: the value of bKeyDown - either a '0' or '1'. If omitted, defaults to '0'.
-
- Rc: the value of wRepeatCount - any number. If omitted, defaults to '0'.
+ ^[ [ Vk ; Sc ; Uc ; Kd ; Cs ; Rc _
Vk: the value of wVirtualKeyCode - any number. If omitted, defaults to '0'.
@@ -153,7 +155,12 @@ doesn't seem to be used as an _input_ sequence terminator either.
Uc: the decimal value of UnicodeChar - for example, NUL is "0", LF is
"10", the character 'A' is "65". If omitted, defaults to '0'.
+ Kd: the value of bKeyDown - either a '0' or '1'. If omitted, defaults to '0'.
+
Cs: the value of dwControlKeyState - any number. If omitted, defaults to '0'.
+
+ Rc: the value of wRepeatCount - any number. If omitted, defaults to '1'.
+
```
> 👉 NOTE: an earlier draft of this spec used an APC sequence for encoding the
@@ -179,10 +186,10 @@ send 4 input records to the client application:
Encoded in `win32-input-mode`, this would look like the following:
```
-^[[1;1;17;29;0;8_
-^[[1;1;112;59;0;8_
-^[[0;1;112;59;0;8_
-^[[0;1;17;29;0;0_
+^[[17;29;0;1;8;1_
+^[[112;59;0;1;8;1_
+^[[112;59;0;0;8;1_
+^[[17;29;0;0;0;1_
Down: 1 Repeat: 1 KeyCode: 0x11 ScanCode: 0x1d Char: \0 (0x0) KeyState: 0x28
Down: 1 Repeat: 1 KeyCode: 0x70 ScanCode: 0x3b Char: \0 (0x0) KeyState: 0x28
@@ -192,12 +199,12 @@ Down: 0 Repeat: 1 KeyCode: 0x11 ScanCode: 0x1d Char: \0 (0x0) KeyState: 0x20
Similarly, for a keypress like Ctrl+Alt+A, which is 6 key events:
```
-^[[1;1;17;29;0;8_
-^[[1;1;18;56;0;10_
-^[[1;1;65;30;0;10_
-^[[0;1;65;30;0;10_
-^[[0;1;18;56;0;8_
-^[[0;1;17;29;0;0_
+^[[17;29;0;1;8;1_
+^[[18;56;0;1;10;1_
+^[[65;30;0;1;10;1_
+^[[65;30;0;0;10;1_
+^[[18;56;0;0;8;1_
+^[[17;29;0;0;0;1_
Down: 1 Repeat: 1 KeyCode: 0x11 ScanCode: 0x1d Char: \0 (0x0) KeyState: 0x28
Down: 1 Repeat: 1 KeyCode: 0x12 ScanCode: 0x38 Char: \0 (0x0) KeyState: 0x2a
@@ -209,10 +216,10 @@ Down: 0 Repeat: 1 KeyCode: 0x11 ScanCode: 0x1d Char: \0 (0x0) KeyState: 0x20
Or, for something simple like A (which is 4 key events):
```
-^[[1;1;16;42;0;16_
-^[[1;1;65;30;65;16_
-^[[0;1;16;42;0;0_
-^[[0;1;65;30;97;0_
+^[[16;42;0;1;16;1_
+^[[65;30;65;1;16;1_
+^[[16;42;0;0;0;1_
+^[[65;30;97;0;0;1_
Down: 1 Repeat: 1 KeyCode: 0x10 ScanCode: 0x2a Char: \0 (0x0) KeyState: 0x30
Down: 1 Repeat: 1 KeyCode: 0x41 ScanCode: 0x1e Char: A (0x41) KeyState: 0x30
@@ -224,6 +231,47 @@ Down: 0 Repeat: 1 KeyCode: 0x41 ScanCode: 0x1e Char: a (0x61) KeyState: 0x20
> NumLock key instead pressed, all the KeyState parameters would have bits 0x20
> set. To get these keys with a NumLock, add 32 to the value.
+These parameters are ordered based on how likely they are to be used. Most of
+the time, the repeat count is not needed (it's almost always `1`), so it can be
+left off when not required. Similarly, the control key state is probably going
+to be 0 a lot of the time too, so that is second last. Even keydown will be 0 at
+least half the time, so that can be omitted some of the time.
+
+Furthermore, considering omitted values in CSI parameters default to the values
+specified above, the above sequences could each be shortened to the following.
+
+* Ctrl+F1
+```
+^[[17;29;;1;8_
+^[[112;59;;1;8_
+^[[112;59;;;8_
+^[[17;29_
+```
+
+* Ctrl+Alt+A
+```
+^[[17;29;;1;8_
+^[[18;56;;1;10_
+^[[65;30;;1;10_
+^[[65;30;;;10_
+^[[18;56;;;8_
+^[[17;29;;_
+```
+
+* A (which is shift+a)
+```
+^[[16;42;;1;16_
+^[[65;30;65;1;16_
+^[[16;42_
+^[[65;30;97_
+```
+
+* Or even easier, just a
+```
+^[[65;30;97;1_
+^[[65;30;97_
+```
+
### Scenarios
#### User is typing into WSL from the Windows Terminal
@@ -231,12 +279,18 @@ Down: 0 Repeat: 1 KeyCode: 0x41 ScanCode: 0x1e Char: a (0x61) KeyState: 0x20
`WT -> conpty[1] -> wsl`
* Conpty[1] will ask for `win32-input-mode` from the Windows Terminal when
- conpty[1] first boots up.
+ conpty[1] first boots up. Conpty will _always_ as for win32-input-mode -
+ Terminals that _don't_ support this mode will ignore this sequence on startup.
* When the user types keys in Windows Terminal, WT will translate them into
win32 sequences and send them to conpty[1]
-* Conpty[1] will translate those win32 sequences into `INPUT_RECORD`s
-* When WSL reads the input, conpty[1] will translate the `INPUT_RECORD`s into VT
- sequences corresponding to whatever input mode the linux app is in.
+* Conpty[1] will translate those win32 sequences into `INPUT_RECORD`s.
+ - When those `INPUT_RECORD`s are written to the input buffer, they'll be
+ converted into VT sequences corresponding to whatever input mode the linux
+ app is in.
+* When WSL reads the input, it'll read (using `ReadConsoleInput`) a stream of
+ `INPUT_RECORD`s that contain only character information, which it will then
+ pass to the linux application.
+ - This is how `wsl.exe` behaves today, before this change.
#### User is typing into `cmd.exe` running in WSL interop
@@ -246,12 +300,19 @@ Down: 0 Repeat: 1 KeyCode: 0x41 ScanCode: 0x1e Char: a (0x61) KeyState: 0x20
* Conpty[2] will ask for `win32-input-mode` from conpty[1] when conpty[2] first
boots up.
+ - As conpty[1] is just a conhost that knows how to handle
+ `win32-input-mode`, it will switch its own VT input handling into
+ `win32-input-mode`
* When the user types keys in Windows Terminal, WT will translate them into
win32 sequences and send them to conpty[1]
-* Conpty[1] will translate those win32 sequences into `INPUT_RECORD`s
-* When WSL reads the input, conpty[1] will translate the `INPUT_RECORD`s into VT
- sequences for the `win32-input-mode`, because it believes the client (in this
- case, the conpty[2] running attached to `wsl`) wants `win32-input-mode`.
+* Conpty[1] will translate those win32 sequences into `INPUT_RECORD`s. When
+ conpty[1] writes these to its buffer, it will translate the `INPUT_RECORD`s
+ into VT sequences for the `win32-input-mode`. This is because it believes the
+ client (in this case, the conpty[2] running attached to `wsl`) wants
+ `win32-input-mode`.
+* When WSL reads the input, it'll read (using `ReadConsoleInput`) a stream of
+ `INPUT_RECORD`s that contain only character information, which it will then
+ use to pass a stream of characters to conpty[2].
* Conpty[2] will get those sequences, and will translate those win32 sequences
into `INPUT_RECORD`s
* When `cmd.exe` reads the input, they'll receive the full `INPUT_RECORD`s
@@ -302,13 +363,14 @@ _(no change expected)_
* We could also hypothetically use this same mechanism to send Win32-like mouse
events to conpty, since similar to VT keyboard events, VT mouse events don't
have the same fidelity that Win32 mouse events do.
- - We could enable this with a different terminating character, like `"`
+ - We could enable this with a different terminating character, to identify
+ which type of `INPUT_RECORD` event we're encoding.
* Client applications that want to be able to read full Win32 keyboard input
- from `conhost` _using VT_ will also be able to use OSC 1000;1 to do this. If
- they emit OSC 1000;1, then conhost will switch itself into `win32-input-mode`,
- and the client will read `win32-input-mode` encoded sequences as input. This
- could enable other cross-platform applications to also use win32-like input in
- the future.
+ from `conhost` _using VT_ will also be able to use `^[[?9001h` to do this. If
+ they emit `^[[?9001h`, then conhost will switch itself into
+ `win32-input-mode`, and the client will read `win32-input-mode` encoded
+ sequences as input. This could enable other cross-platform applications to
+ also use win32-like input in the future.
## Options Considered
@@ -355,17 +417,17 @@ _(no change expected)_
hit `SendChar`) would still just come through as the normal char.
#### Cons:
-* Their encoding table is _mad_. [Look at
+* Their encoding table is _odd_. [Look at
this](https://sw.kovidgoyal.net/kitty/key-encoding.html). What order is that
in? Obviously the first column is sorted alphabetically, but the mapping of
- key->char is in a seemingly bonkers order.
+ key->char is in a certainly hard to decipher order.
* I can't get it working locally, so hard to test 😐
* They do declare the `fullkbd` terminfo capability to identify that they
support this mode, but I'm not sure anyone else uses it.
- I'm also not sure that any _client_ apps are reading this currently.
* This isn't designed to be full `KEY_EVENT`s - where would we put the scancode
(for apps that think that's important)?
- - We'd have to extend this protocol _anyways_
+ - We'd have to extend this protocol _anyways_
### `xterm` "Set key modifier options"
Notably looking at
@@ -434,7 +496,7 @@ Notably looking at
* [iterm2 specific sequences](https://www.iterm2.com/documentation-escape-codes.html)
* [terminal-wg draft list of OSCs](https://gitlab.freedesktop.org/terminal-wg/specifications/-/issues/10)
-<_-- Footnotes -->
+
[#530]: https://github.com/microsoft/terminal/issues/530
[#879]: https://github.com/microsoft/terminal/issues/879
[#1119]: https://github.com/microsoft/terminal/issues/1119
diff --git a/doc/user-docs/UsingJsonSettings.md b/doc/user-docs/UsingJsonSettings.md
index 90e1bbc0f99..5fab48d289c 100644
--- a/doc/user-docs/UsingJsonSettings.md
+++ b/doc/user-docs/UsingJsonSettings.md
@@ -88,7 +88,7 @@ This will allow you to simplify the above snippet as follows:
}
```
-
+A list of default key bindings is available [here](https://github.com/microsoft/terminal/blob/master/src/cascadia/TerminalApp/defaults.json#L204).
### Unbinding keys
@@ -160,7 +160,7 @@ Example settings include
The profile GUID is used to reference the default profile in the global settings.
-The values for background image stretch mode are documented [here](https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.media.stretch)
+The values for background image stretch mode are documented [here](https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.media.stretch).
### Hiding a profile
diff --git a/doc/user-docs/index.md b/doc/user-docs/index.md
index b2c58291c5a..80e48522d5a 100644
--- a/doc/user-docs/index.md
+++ b/doc/user-docs/index.md
@@ -45,7 +45,7 @@ To customize the shell list, see the _Configuring Windows Terminal_ section belo
## Starting a new PowerShell tab with admin privilege
-There is no current plan to support this feature for security reasons. See issue [#623](https://github.com/microsoft/terminal/issues/632)
+There is no current plan to support this feature for security reasons. See issue [#632](https://github.com/microsoft/terminal/issues/632)
## Selecting and Copying Text in Windows Terminal
@@ -87,4 +87,5 @@ For an introduction to the various settings, see [Using Json Settings](UsingJson
2. Terminal zoom can be changed by holding Ctrl and scrolling with mouse.
3. Background opacity can be changed by holding Ctrl+Shift and scrolling with mouse. Note that acrylic transparency is limited by the OS only to focused windows.
4. Open Windows Terminal in current directory by typing `wt -d .` in the address bar.
-5. Please add more Tips and Tricks.
+5. Pin the Windows Terminal to the taskbar. Now it can be launched using the Windows shortcut Win+Number (e.g. Win+1 or any other number based on the position in the taskbar!). Press Win+Shift+Number to always launch a new window.
+6. Please add more Tips and Tricks.
diff --git a/res/Cascadia.ttf b/res/Cascadia.ttf
index 792a7aabf8b..eefcc2d857a 100644
Binary files a/res/Cascadia.ttf and b/res/Cascadia.ttf differ
diff --git a/res/CascadiaMono.ttf b/res/CascadiaMono.ttf
index 2e2dbe076bc..39c9a1b1851 100644
Binary files a/res/CascadiaMono.ttf and b/res/CascadiaMono.ttf differ
diff --git a/res/README.md b/res/README.md
index de5f698eab4..48cc358f5c0 100644
--- a/res/README.md
+++ b/res/README.md
@@ -17,5 +17,5 @@ Please consult the [license](https://raw.githubusercontent.com/microsoft/cascadi
### Fonts Included
-* Cascadia Code, Cascadia Mono (2004.30)
- * from microsoft/cascadia-code@5795d16e36748612b726164fd8b59f3c1c8b0788
+* Cascadia Code, Cascadia Mono (2005.15)
+ * from microsoft/cascadia-code@0610f2df4356200adb93cb5bca2221b92ad6ee7e
diff --git a/src/buffer/out/TextAttribute.cpp b/src/buffer/out/TextAttribute.cpp
index aa66a3ed419..ee779402202 100644
--- a/src/buffer/out/TextAttribute.cpp
+++ b/src/buffer/out/TextAttribute.cpp
@@ -10,6 +10,11 @@ bool TextAttribute::IsLegacy() const noexcept
return _foreground.IsLegacy() && _background.IsLegacy();
}
+bool TextAttribute::IsHighColor() const noexcept
+{
+ return _foreground.IsHighColor() || _background.IsHighColor();
+}
+
// Arguments:
// - None
// Return Value:
@@ -72,12 +77,22 @@ void TextAttribute::SetBackground(const COLORREF rgbBackground) noexcept
void TextAttribute::SetIndexedForeground(const BYTE fgIndex) noexcept
{
- _foreground = TextColor(fgIndex);
+ _foreground = TextColor(fgIndex, false);
}
void TextAttribute::SetIndexedBackground(const BYTE bgIndex) noexcept
{
- _background = TextColor(bgIndex);
+ _background = TextColor(bgIndex, false);
+}
+
+void TextAttribute::SetIndexedForeground256(const BYTE fgIndex) noexcept
+{
+ _foreground = TextColor(fgIndex, true);
+}
+
+void TextAttribute::SetIndexedBackground256(const BYTE bgIndex) noexcept
+{
+ _background = TextColor(bgIndex, true);
}
void TextAttribute::SetColor(const COLORREF rgbColor, const bool fIsForeground) noexcept
diff --git a/src/buffer/out/TextAttribute.hpp b/src/buffer/out/TextAttribute.hpp
index edabdc45661..df6278e3f0b 100644
--- a/src/buffer/out/TextAttribute.hpp
+++ b/src/buffer/out/TextAttribute.hpp
@@ -42,8 +42,8 @@ class TextAttribute final
constexpr TextAttribute(const WORD wLegacyAttr) noexcept :
_wAttrLegacy{ gsl::narrow_cast(wLegacyAttr & META_ATTRS) },
- _foreground{ gsl::narrow_cast(wLegacyAttr & FG_ATTRS) },
- _background{ gsl::narrow_cast((wLegacyAttr & BG_ATTRS) >> 4) },
+ _foreground{ gsl::narrow_cast(wLegacyAttr & FG_ATTRS), true },
+ _background{ gsl::narrow_cast((wLegacyAttr & BG_ATTRS) >> 4), true },
_extendedAttrs{ ExtendedAttributes::Normal }
{
// If we're given lead/trailing byte information with the legacy color, strip it.
@@ -59,12 +59,13 @@ class TextAttribute final
{
}
- constexpr WORD GetLegacyAttributes() const noexcept
+ WORD GetLegacyAttributes() const noexcept
{
const BYTE fg = (_foreground.GetIndex() & FG_ATTRS);
const BYTE bg = (_background.GetIndex() << 4) & BG_ATTRS;
const WORD meta = (_wAttrLegacy & META_ATTRS);
- return (fg | bg | meta) | (IsBold() ? FOREGROUND_INTENSITY : 0);
+ const bool brighten = _foreground.IsIndex16() && IsBold();
+ return (fg | bg | meta) | (brighten ? FOREGROUND_INTENSITY : 0);
}
// Method Description:
@@ -79,15 +80,16 @@ class TextAttribute final
// the background not be a legacy style attribute.
// Return Value:
// - a WORD with legacy-style attributes for this textattribute.
- constexpr WORD GetLegacyAttributes(const BYTE defaultFgIndex,
- const BYTE defaultBgIndex) const noexcept
+ WORD GetLegacyAttributes(const BYTE defaultFgIndex,
+ const BYTE defaultBgIndex) const noexcept
{
const BYTE fgIndex = _foreground.IsLegacy() ? _foreground.GetIndex() : defaultFgIndex;
const BYTE bgIndex = _background.IsLegacy() ? _background.GetIndex() : defaultBgIndex;
const BYTE fg = (fgIndex & FG_ATTRS);
const BYTE bg = (bgIndex << 4) & BG_ATTRS;
const WORD meta = (_wAttrLegacy & META_ATTRS);
- return (fg | bg | meta) | (IsBold() ? FOREGROUND_INTENSITY : 0);
+ const bool brighten = _foreground.IsIndex16() && IsBold();
+ return (fg | bg | meta) | (brighten ? FOREGROUND_INTENSITY : 0);
}
COLORREF CalculateRgbForeground(std::basic_string_view colorTable,
@@ -117,6 +119,7 @@ class TextAttribute final
friend constexpr bool operator!=(const WORD& legacyAttr, const TextAttribute& attr) noexcept;
bool IsLegacy() const noexcept;
+ bool IsHighColor() const noexcept;
bool IsBold() const noexcept;
bool IsItalic() const noexcept;
bool IsBlinking() const noexcept;
@@ -139,6 +142,8 @@ class TextAttribute final
void SetBackground(const COLORREF rgbBackground) noexcept;
void SetIndexedForeground(const BYTE fgIndex) noexcept;
void SetIndexedBackground(const BYTE bgIndex) noexcept;
+ void SetIndexedForeground256(const BYTE fgIndex) noexcept;
+ void SetIndexedBackground256(const BYTE bgIndex) noexcept;
void SetColor(const COLORREF rgbColor, const bool fIsForeground) noexcept;
void SetDefaultForeground() noexcept;
@@ -149,11 +154,6 @@ class TextAttribute final
void SetStandardErase() noexcept;
- constexpr bool IsRgb() const noexcept
- {
- return _foreground.IsRgb() || _background.IsRgb();
- }
-
// This returns whether this attribute, if printed directly next to another attribute, for the space
// character, would look identical to the other one.
bool HasIdenticalVisualRepresentationForBlankSpace(const TextAttribute& other, const bool inverted = false) const noexcept
@@ -224,26 +224,6 @@ constexpr bool operator!=(const TextAttribute& a, const TextAttribute& b) noexce
return !(a == b);
}
-constexpr bool operator==(const TextAttribute& attr, const WORD& legacyAttr) noexcept
-{
- return attr.GetLegacyAttributes() == legacyAttr;
-}
-
-constexpr bool operator!=(const TextAttribute& attr, const WORD& legacyAttr) noexcept
-{
- return !(attr == legacyAttr);
-}
-
-constexpr bool operator==(const WORD& legacyAttr, const TextAttribute& attr) noexcept
-{
- return attr == legacyAttr;
-}
-
-constexpr bool operator!=(const WORD& legacyAttr, const TextAttribute& attr) noexcept
-{
- return !(attr == legacyAttr);
-}
-
#ifdef UNIT_TESTING
#define LOG_ATTR(attr) (Log::Comment(NoThrowString().Format( \
diff --git a/src/buffer/out/TextColor.cpp b/src/buffer/out/TextColor.cpp
index 05fcded149a..11c054fe805 100644
--- a/src/buffer/out/TextColor.cpp
+++ b/src/buffer/out/TextColor.cpp
@@ -4,6 +4,36 @@
#include "precomp.h"
#include "TextColor.h"
+bool TextColor::IsLegacy() const noexcept
+{
+ return IsIndex16() || (IsIndex256() && _index < 16);
+}
+
+bool TextColor::IsHighColor() const noexcept
+{
+ return IsRgb() || (IsIndex256() && _index >= 16);
+}
+
+bool TextColor::IsIndex16() const noexcept
+{
+ return _meta == ColorType::IsIndex16;
+}
+
+bool TextColor::IsIndex256() const noexcept
+{
+ return _meta == ColorType::IsIndex256;
+}
+
+bool TextColor::IsDefault() const noexcept
+{
+ return _meta == ColorType::IsDefault;
+}
+
+bool TextColor::IsRgb() const noexcept
+{
+ return _meta == ColorType::IsRgb;
+}
+
// Method Description:
// - Sets the color value of this attribute, and sets this color to be an RGB
// attribute.
@@ -23,11 +53,12 @@ void TextColor::SetColor(const COLORREF rgbColor) noexcept
// - Sets this TextColor to be a legacy-style index into the color table.
// Arguments:
// - index: the index of the colortable we should use for this TextColor.
+// - isIndex256: is this a 256 color index (true) or a 16 color index (false).
// Return Value:
// -
-void TextColor::SetIndex(const BYTE index) noexcept
+void TextColor::SetIndex(const BYTE index, const bool isIndex256) noexcept
{
- _meta = ColorType::IsIndex;
+ _meta = isIndex256 ? ColorType::IsIndex256 : ColorType::IsIndex16;
_index = index;
}
@@ -48,15 +79,15 @@ void TextColor::SetDefault() noexcept
// * If we're an RGB color, we'll use that value.
// * If we're an indexed color table value, we'll use that index to look up
// our value in the provided color table.
-// - If brighten is true, and the index is in the "dark" portion of the
-// color table (indices [0,7]), then we'll look up the bright version of
-// this color (from indices [8,15]). This should be true for
-// TextAttributes that are "Bold" and we're treating bold as bright
-// (which is the default behavior of most terminals.)
+// - If brighten is true, and we've got a 16 color index in the "dark"
+// portion of the color table (indices [0,7]), then we'll look up the
+// bright version of this color (from indices [8,15]). This should be
+// true for TextAttributes that are "Bold" and we're treating bold as
+// bright (which is the default behavior of most terminals.)
// * If we're a default color, we'll return the default color provided.
// Arguments:
-// - colorTable: The table of colors we should use to look up the value of a
-// legacy attribute from
+// - colorTable: The table of colors we should use to look up the value of
+// an indexed attribute from.
// - defaultColor: The color value to use if we're a default attribute.
// - brighten: if true, we'll brighten a dark color table index.
// Return Value:
@@ -94,21 +125,13 @@ COLORREF TextColor::GetColor(std::basic_string_view colorTable,
{
return _GetRGB();
}
+ else if (IsIndex16() && brighten)
+ {
+ return colorTable.at(_index | 8);
+ }
else
{
- FAIL_FAST_IF(colorTable.size() < _index);
- // If the color is already bright (it's in index [8,15] or it's a
- // 256color value [16,255], then boldness does nothing.
- if (brighten && _index < 8)
- {
- FAIL_FAST_IF(colorTable.size() < 16);
- FAIL_FAST_IF(gsl::narrow_cast(_index) + 8 > colorTable.size());
- return colorTable.at(gsl::narrow_cast(_index) + 8);
- }
- else
- {
- return colorTable.at(_index);
- }
+ return colorTable.at(_index);
}
}
diff --git a/src/buffer/out/TextColor.h b/src/buffer/out/TextColor.h
index 21896ca0413..08db63b831b 100644
--- a/src/buffer/out/TextColor.h
+++ b/src/buffer/out/TextColor.h
@@ -41,9 +41,10 @@ Revision History:
enum class ColorType : BYTE
{
- IsIndex = 0x0,
- IsDefault = 0x1,
- IsRgb = 0x2
+ IsIndex256 = 0x0,
+ IsIndex16 = 0x1,
+ IsDefault = 0x2,
+ IsRgb = 0x3
};
struct TextColor
@@ -57,9 +58,9 @@ struct TextColor
{
}
- constexpr TextColor(const BYTE wLegacyAttr) noexcept :
- _meta{ ColorType::IsIndex },
- _index{ wLegacyAttr },
+ constexpr TextColor(const BYTE index, const bool isIndex256) noexcept :
+ _meta{ isIndex256 ? ColorType::IsIndex256 : ColorType::IsIndex16 },
+ _index{ index },
_green{ 0 },
_blue{ 0 }
{
@@ -76,23 +77,15 @@ struct TextColor
friend constexpr bool operator==(const TextColor& a, const TextColor& b) noexcept;
friend constexpr bool operator!=(const TextColor& a, const TextColor& b) noexcept;
- constexpr bool IsLegacy() const noexcept
- {
- return !(IsDefault() || IsRgb());
- }
-
- constexpr bool IsDefault() const noexcept
- {
- return _meta == ColorType::IsDefault;
- }
-
- constexpr bool IsRgb() const noexcept
- {
- return _meta == ColorType::IsRgb;
- }
+ bool IsLegacy() const noexcept;
+ bool IsHighColor() const noexcept;
+ bool IsIndex16() const noexcept;
+ bool IsIndex256() const noexcept;
+ bool IsDefault() const noexcept;
+ bool IsRgb() const noexcept;
void SetColor(const COLORREF rgbColor) noexcept;
- void SetIndex(const BYTE index) noexcept;
+ void SetIndex(const BYTE index, const bool isIndex256) noexcept;
void SetDefault() noexcept;
COLORREF GetColor(std::basic_string_view colorTable,
diff --git a/src/buffer/out/ut_textbuffer/TextColorTests.cpp b/src/buffer/out/ut_textbuffer/TextColorTests.cpp
index 3497bdcae41..794331fee3d 100644
--- a/src/buffer/out/ut_textbuffer/TextColorTests.cpp
+++ b/src/buffer/out/ut_textbuffer/TextColorTests.cpp
@@ -81,7 +81,7 @@ void TextColorTests::TestDefaultColor()
void TextColorTests::TestDarkIndexColor()
{
- TextColor indexColor((BYTE)(7));
+ TextColor indexColor((BYTE)(7), false);
VERIFY_IS_FALSE(indexColor.IsDefault());
VERIFY_IS_TRUE(indexColor.IsLegacy());
@@ -104,7 +104,7 @@ void TextColorTests::TestDarkIndexColor()
void TextColorTests::TestBrightIndexColor()
{
- TextColor indexColor((BYTE)(15));
+ TextColor indexColor((BYTE)(15), false);
VERIFY_IS_FALSE(indexColor.IsDefault());
VERIFY_IS_TRUE(indexColor.IsLegacy());
@@ -186,7 +186,7 @@ void TextColorTests::TestChangeColor()
color = rgbColor.GetColor(view, _defaultBg, true);
VERIFY_ARE_EQUAL(_defaultBg, color);
- rgbColor.SetIndex(7);
+ rgbColor.SetIndex(7, false);
color = rgbColor.GetColor(view, _defaultFg, false);
VERIFY_ARE_EQUAL(_colorTable[7], color);
@@ -199,7 +199,7 @@ void TextColorTests::TestChangeColor()
color = rgbColor.GetColor(view, _defaultBg, true);
VERIFY_ARE_EQUAL(_colorTable[15], color);
- rgbColor.SetIndex(15);
+ rgbColor.SetIndex(15, false);
color = rgbColor.GetColor(view, _defaultFg, false);
VERIFY_ARE_EQUAL(_colorTable[15], color);
diff --git a/src/cascadia/CascadiaPackage/CascadiaPackage.wapproj b/src/cascadia/CascadiaPackage/CascadiaPackage.wapproj
index cfff16b6435..6fbd04d0d53 100644
--- a/src/cascadia/CascadiaPackage/CascadiaPackage.wapproj
+++ b/src/cascadia/CascadiaPackage/CascadiaPackage.wapproj
@@ -64,7 +64,9 @@
+
+
diff --git a/src/cascadia/CascadiaPackage/Package-Dev.appxmanifest b/src/cascadia/CascadiaPackage/Package-Dev.appxmanifest
index a8ccfe6c73c..da2051a1711 100644
--- a/src/cascadia/CascadiaPackage/Package-Dev.appxmanifest
+++ b/src/cascadia/CascadiaPackage/Package-Dev.appxmanifest
@@ -3,9 +3,13 @@
@@ -39,7 +43,7 @@
Square150x150Logo="Images\Square150x150Logo.png"
Square44x44Logo="Images\Square44x44Logo.png">
@@ -58,6 +62,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/cascadia/CascadiaPackage/Package-Pre.appxmanifest b/src/cascadia/CascadiaPackage/Package-Pre.appxmanifest
index c69242ccb1b..d38b642dc77 100644
--- a/src/cascadia/CascadiaPackage/Package-Pre.appxmanifest
+++ b/src/cascadia/CascadiaPackage/Package-Pre.appxmanifest
@@ -3,11 +3,14 @@
@@ -41,13 +44,13 @@
Square150x150Logo="Images\Square150x150Logo.png"
Square44x44Logo="Images\Square44x44Logo.png">
-
+
@@ -60,6 +63,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/cascadia/CascadiaPackage/Package.appxmanifest b/src/cascadia/CascadiaPackage/Package.appxmanifest
index ad429698b69..76401a73f17 100644
--- a/src/cascadia/CascadiaPackage/Package.appxmanifest
+++ b/src/cascadia/CascadiaPackage/Package.appxmanifest
@@ -3,11 +3,14 @@
@@ -41,7 +44,7 @@
Square150x150Logo="Images\Square150x150Logo.png"
Square44x44Logo="Images\Square44x44Logo.png">
@@ -60,6 +63,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp b/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp
index 4bc51dbcd26..612f2b0dd0f 100644
--- a/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp
+++ b/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp
@@ -783,7 +783,7 @@ namespace TerminalAppLocalTests
VERIFY_IS_FALSE(profile0._guid.has_value());
- const auto serialized0Profile = profile0.ToJson();
+ const auto serialized0Profile = profile0.GenerateStub();
const auto profile1 = Profile::FromJson(serialized0Profile);
VERIFY_IS_FALSE(profile0._guid.has_value());
VERIFY_ARE_EQUAL(profile1._guid.has_value(), profile0._guid.has_value());
@@ -794,7 +794,7 @@ namespace TerminalAppLocalTests
VERIFY_IS_TRUE(settings._profiles.at(0)._guid.has_value());
- const auto serialized1Profile = settings._profiles.at(0).ToJson();
+ const auto serialized1Profile = settings._profiles.at(0).GenerateStub();
const auto profile2 = Profile::FromJson(serialized1Profile);
VERIFY_IS_TRUE(settings._profiles.at(0)._guid.has_value());
diff --git a/src/cascadia/ShellExtension/OpenTerminalHere.cpp b/src/cascadia/ShellExtension/OpenTerminalHere.cpp
new file mode 100644
index 00000000000..8091754832c
--- /dev/null
+++ b/src/cascadia/ShellExtension/OpenTerminalHere.cpp
@@ -0,0 +1,211 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+
+#include "pch.h"
+#include "OpenTerminalHere.h"
+
+// TODO GH#6112: Localize these strings
+static constexpr std::wstring_view VerbDisplayName{ L"Open in Windows Terminal" };
+static constexpr std::wstring_view VerbDevBuildDisplayName{ L"Open in Windows Terminal (Dev Build)" };
+static constexpr std::wstring_view VerbName{ L"WindowsTerminalOpenHere" };
+
+static constexpr std::wstring_view WtExe{ L"wt.exe" };
+static constexpr std::wstring_view WtdExe{ L"wtd.exe" };
+static constexpr std::wstring_view WindowsTerminalExe{ L"WindowsTerminal.exe" };
+
+static constexpr std::wstring_view LocalAppDataAppsPath{ L"%LOCALAPPDATA%\\Microsoft\\WindowsApps\\" };
+
+// This code is aggressively copied from
+// https://github.com/microsoft/Windows-classic-samples/blob/master/Samples/
+// Win7Samples/winui/shell/appshellintegration/ExplorerCommandVerb/ExplorerCommandVerb.cpp
+
+// Function Description:
+// - This is a helper to determine if we're running as a part of the Dev Build
+// Package or the release package. We'll need to return different text, icons,
+// and use different commandlines depending on which one the user requested.
+// - Uses a C++11 "magic static" to make sure this is only computed once.
+// - If we can't determine if it's the dev build or not, we'll default to true
+// Arguments:
+// -
+// Return Value:
+// - true if we believe this extension is being run in the dev build package.
+static bool IsDevBuild()
+{
+ // use C++11 magic statics to make sure we only do this once.
+ static bool isDevBuild = []() -> bool {
+ try
+ {
+ const auto package{ winrt::Windows::ApplicationModel::Package::Current() };
+ const auto id = package.Id();
+ const std::wstring name{ id.FullName() };
+ // Does our PFN start with WindowsTerminalDev?
+ return name.rfind(L"WindowsTerminalDev", 0) == 0;
+ }
+ CATCH_LOG();
+ return true;
+ }();
+
+ return isDevBuild;
+}
+
+// Function Description:
+// - Helper function for getting the path to the appropriate executable to use
+// for this instance of the shell extension. If we're running the dev build,
+// it should be a `wtd.exe`, but if we're preview or release, we want to make
+// sure to get the correct `wt.exe` that corresponds to _us_.
+// - If we're unpackaged, this needs to get us `WindowsTerminal.exe`, because
+// the `wt*exe` alias won't have been installed for this install.
+// Arguments:
+// -
+// Return Value:
+// - the full path to the exe, one of `wt.exe`, `wtd.exe`, or `WindowsTerminal.exe`.
+static std::wstring _getExePath()
+{
+ // use C++11 magic statics to make sure we only do this once.
+ static const std::wstring exePath = []() -> std::wstring {
+ // First, check a packaged location for the exe. If we've got a package
+ // family name, that means we're one of the packaged Dev build, packaged
+ // Release build, or packaged Preview build.
+ //
+ // If we're the preview or release build, there's no way of knowing if the
+ // `wt.exe` on the %PATH% is us or not. Fortunately, _our_ execution alias
+ // is located in "%LOCALAPPDATA%\Microsoft\WindowsApps\", _always_, so we can use that to look up the exe easier.
+ try
+ {
+ const auto package{ winrt::Windows::ApplicationModel::Package::Current() };
+ const auto id = package.Id();
+ const std::wstring pfn{ id.FamilyName() };
+ if (!pfn.empty())
+ {
+ const std::filesystem::path windowsAppsPath{ wil::ExpandEnvironmentStringsW(LocalAppDataAppsPath.data()) };
+ const std::filesystem::path wtPath = windowsAppsPath / pfn / (IsDevBuild() ? WtdExe : WtExe);
+ return wtPath;
+ }
+ }
+ CATCH_LOG();
+
+ // If we're here, then we couldn't resolve our exe from the package. This
+ // means we're running unpackaged. We should just use the
+ // WindowsTerminal.exe that's sitting in the directory next to us.
+ try
+ {
+ HMODULE hModule = GetModuleHandle(nullptr);
+ THROW_LAST_ERROR_IF(hModule == nullptr);
+ std::wstring dllPathString;
+ THROW_IF_FAILED(wil::GetModuleFileNameW(hModule, dllPathString));
+ const std::filesystem::path dllPath{ dllPathString };
+ const std::filesystem::path rootDir = dllPath.parent_path();
+ std::filesystem::path wtPath = rootDir / WindowsTerminalExe;
+ return wtPath;
+ }
+ CATCH_LOG();
+
+ return L"wt.exe";
+ }();
+ return exePath;
+}
+
+// Method Description:
+// - This method is called when the user activates the context menu item. We'll
+// launch the Terminal using the current working directory.
+// Arguments:
+// - psiItemArray: a IShellItemArray which contains the item that's selected.
+// Return Value:
+// - S_OK if we successfully attempted to launch the Terminal, otherwise a
+// failure from an earlier HRESULT.
+HRESULT OpenTerminalHere::Invoke(IShellItemArray* psiItemArray,
+ IBindCtx* /*pBindContext*/)
+{
+ DWORD count;
+ psiItemArray->GetCount(&count);
+
+ winrt::com_ptr psi;
+ RETURN_IF_FAILED(psiItemArray->GetItemAt(0, psi.put()));
+
+ wil::unique_cotaskmem_string pszName;
+ RETURN_IF_FAILED(psi->GetDisplayName(SIGDN_FILESYSPATH, &pszName));
+
+ {
+ wil::unique_process_information _piClient;
+ STARTUPINFOEX siEx{ 0 };
+ siEx.StartupInfo.cb = sizeof(STARTUPINFOEX);
+
+ // Append a "\." to the given path, so that this will work in "C:\"
+ std::wstring cmdline = fmt::format(L"\"{}\" -d \"{}\\.\"", _getExePath(), pszName.get());
+ RETURN_IF_WIN32_BOOL_FALSE(CreateProcessW(
+ nullptr,
+ cmdline.data(),
+ nullptr, // lpProcessAttributes
+ nullptr, // lpThreadAttributes
+ false, // bInheritHandles
+ EXTENDED_STARTUPINFO_PRESENT | CREATE_UNICODE_ENVIRONMENT, // dwCreationFlags
+ nullptr, // lpEnvironment
+ nullptr,
+ &siEx.StartupInfo, // lpStartupInfo
+ &_piClient // lpProcessInformation
+ ));
+ }
+
+ return S_OK;
+}
+
+HRESULT OpenTerminalHere::GetToolTip(IShellItemArray* /*psiItemArray*/,
+ LPWSTR* ppszInfoTip)
+{
+ // tooltip provided here, in this case none is provided
+ *ppszInfoTip = nullptr;
+ return E_NOTIMPL;
+}
+
+HRESULT OpenTerminalHere::GetTitle(IShellItemArray* /*psiItemArray*/,
+ LPWSTR* ppszName)
+{
+ // Change the string we return depending on if we're running from the dev
+ // build package or not.
+ const bool isDevBuild = IsDevBuild();
+ return SHStrDup(isDevBuild ? VerbDevBuildDisplayName.data() : VerbDisplayName.data(), ppszName);
+}
+
+HRESULT OpenTerminalHere::GetState(IShellItemArray* /*psiItemArray*/,
+ BOOL /*fOkToBeSlow*/,
+ EXPCMDSTATE* pCmdState)
+{
+ // compute the visibility of the verb here, respect "fOkToBeSlow" if this is
+ // slow (does IO for example) when called with fOkToBeSlow == FALSE return
+ // E_PENDING and this object will be called back on a background thread with
+ // fOkToBeSlow == TRUE
+
+ // We however don't need to bother with any of that, so we'll just return
+ // ECS_ENABLED.
+
+ *pCmdState = ECS_ENABLED;
+ return S_OK;
+}
+
+HRESULT OpenTerminalHere::GetIcon(IShellItemArray* /*psiItemArray*/,
+ LPWSTR* ppszIcon)
+{
+ // the icon ref ("dll,-") is provided here, in this case none is provided
+ *ppszIcon = nullptr;
+ // TODO GH#6111: Return the Terminal icon here
+ return E_NOTIMPL;
+}
+
+HRESULT OpenTerminalHere::GetFlags(EXPCMDFLAGS* pFlags)
+{
+ *pFlags = ECF_DEFAULT;
+ return S_OK;
+}
+
+HRESULT OpenTerminalHere::GetCanonicalName(GUID* pguidCommandName)
+{
+ *pguidCommandName = __uuidof(this);
+ return S_OK;
+}
+
+HRESULT OpenTerminalHere::EnumSubCommands(IEnumExplorerCommand** ppEnum)
+{
+ *ppEnum = nullptr;
+ return E_NOTIMPL;
+}
diff --git a/src/cascadia/ShellExtension/OpenTerminalHere.h b/src/cascadia/ShellExtension/OpenTerminalHere.h
new file mode 100644
index 00000000000..c79fc3424aa
--- /dev/null
+++ b/src/cascadia/ShellExtension/OpenTerminalHere.h
@@ -0,0 +1,51 @@
+/*++
+Copyright (c) Microsoft Corporation
+Licensed under the MIT license.
+
+Module Name:
+- OpenTerminalHere.h
+
+Abstract:
+- This is the class that implements our Explorer Context Menu item. By
+ implementing IExplorerCommand, we can provide an entry to the context menu to
+ allow the user to open the Terminal in the current working directory.
+- Importantly, we need to make sure to declare the GUID of this implementation
+ class explicitly, so we can refer to it in our manifest, and use it to create
+ instances of this class when the shell asks for one.
+- This is defined as a WRL type, so that we can use WRL's CoCreatableClass magic
+ to create the class factory and module management for us. See more details in
+ dllmain.cpp.
+
+Author(s):
+- Mike Griese - May 2020
+
+--*/
+#pragma once
+
+#include
+#include "../../cascadia/inc/cppwinrt_utils.h"
+
+using namespace Microsoft::WRL;
+
+struct __declspec(uuid("9f156763-7844-4dc4-b2b1-901f640f5155"))
+ OpenTerminalHere : public RuntimeClass, IExplorerCommand>
+{
+#pragma region IExplorerCommand
+ STDMETHODIMP Invoke(IShellItemArray* psiItemArray,
+ IBindCtx* pBindContext);
+ STDMETHODIMP GetToolTip(IShellItemArray* psiItemArray,
+ LPWSTR* ppszInfoTip);
+ STDMETHODIMP GetTitle(IShellItemArray* psiItemArray,
+ LPWSTR* ppszName);
+ STDMETHODIMP GetState(IShellItemArray* psiItemArray,
+ BOOL fOkToBeSlow,
+ EXPCMDSTATE* pCmdState);
+ STDMETHODIMP GetIcon(IShellItemArray* psiItemArray,
+ LPWSTR* ppszIcon);
+ STDMETHODIMP GetFlags(EXPCMDFLAGS* pFlags);
+ STDMETHODIMP GetCanonicalName(GUID* pguidCommandName);
+ STDMETHODIMP EnumSubCommands(IEnumExplorerCommand** ppEnum);
+#pragma endregion
+};
+
+CoCreatableClass(OpenTerminalHere);
diff --git a/src/cascadia/ShellExtension/PlaceholderType.cpp b/src/cascadia/ShellExtension/PlaceholderType.cpp
new file mode 100644
index 00000000000..dc45a6a1e47
--- /dev/null
+++ b/src/cascadia/ShellExtension/PlaceholderType.cpp
@@ -0,0 +1,10 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+
+#include "pch.h"
+#include "PlaceholderType.h"
+#include "PlaceholderType.g.cpp"
+
+namespace winrt::Microsoft::Terminal::ShellExtension::implementation
+{
+}
diff --git a/src/cascadia/ShellExtension/PlaceholderType.h b/src/cascadia/ShellExtension/PlaceholderType.h
new file mode 100644
index 00000000000..d56395c9257
--- /dev/null
+++ b/src/cascadia/ShellExtension/PlaceholderType.h
@@ -0,0 +1,37 @@
+/*++
+Copyright (c) Microsoft Corporation
+Licensed under the MIT license.
+
+Module Name:
+- PlaceholderType.h
+
+Abstract:
+- This class is just here to make our .wapproj play nicely with this project. If
+ we don't define any winrt types, then we won't generate a .winmd, and the
+ .wapproj will become _very_ mad at this project. So we'll use this placeholder
+ class just to trick cppwinrt into generating a winmd for us. If we ever _do_
+ add a real winrt type to this project, this can be removed.
+
+Author(s):
+- Mike Griese - May 2020
+
+--*/
+#pragma once
+
+#include
+#include "PlaceholderType.g.h"
+#include "../../cascadia/inc/cppwinrt_utils.h"
+
+namespace winrt::Microsoft::Terminal::ShellExtension::implementation
+{
+ struct PlaceholderType : PlaceholderTypeT
+ {
+ PlaceholderType() = default;
+ GETSET_PROPERTY(int32_t, Placeholder, 42);
+ };
+}
+
+namespace winrt::Microsoft::Terminal::ShellExtension::factory_implementation
+{
+ BASIC_FACTORY(PlaceholderType);
+}
diff --git a/src/cascadia/ShellExtension/PlaceholderType.idl b/src/cascadia/ShellExtension/PlaceholderType.idl
new file mode 100644
index 00000000000..0dbe7adfacc
--- /dev/null
+++ b/src/cascadia/ShellExtension/PlaceholderType.idl
@@ -0,0 +1,21 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+
+// This class is just here to make our .wapproj play nicely with this project.
+// If we don't define any winrt types, then we won't generate a .winmd, and the
+// .wapproj will become _very_ mad at this project. So we'll use this
+// placeholder class just to trick cppwinrt into generating a winmd for us. If
+// we ever _do_ add a real winrt type to this project, this can be removed.
+
+namespace Microsoft.Terminal.ShellExtension
+{
+ [default_interface] runtimeclass PlaceholderType {
+ PlaceholderType();
+ Int32 Placeholder
+ {
+ get;
+ set;
+ };
+ };
+
+}
diff --git a/src/cascadia/ShellExtension/WindowsTerminalShellExt.def b/src/cascadia/ShellExtension/WindowsTerminalShellExt.def
new file mode 100644
index 00000000000..d0e5f0b59d3
--- /dev/null
+++ b/src/cascadia/ShellExtension/WindowsTerminalShellExt.def
@@ -0,0 +1,4 @@
+EXPORTS
+DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE
+DllGetActivationFactory = WINRT_GetActivationFactory PRIVATE
+DllGetClassObject PRIVATE
diff --git a/src/cascadia/ShellExtension/WindowsTerminalShellExt.vcxproj b/src/cascadia/ShellExtension/WindowsTerminalShellExt.vcxproj
new file mode 100644
index 00000000000..12565176959
--- /dev/null
+++ b/src/cascadia/ShellExtension/WindowsTerminalShellExt.vcxproj
@@ -0,0 +1,68 @@
+
+
+
+ {f2ed628a-db22-446f-a081-4cc845b51a2b}
+ WindowsTerminalShellExt
+ Microsoft.Terminal.ShellExtension
+
+
+ DynamicLibrary
+ Console
+
+ true
+
+ true
+
+
+
+
+
+
+
+
+
+ PlaceholderType.idl
+
+
+
+
+ Create
+
+
+ PlaceholderType.idl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {18D09A24-8240-42D6-8CB6-236EEE820263}
+
+
+ {CA5CAD1A-039A-4929-BA2A-8BEB2E4106FE}
+ false
+
+
+
+
+
+
diff --git a/src/cascadia/ShellExtension/dllmain.cpp b/src/cascadia/ShellExtension/dllmain.cpp
new file mode 100644
index 00000000000..d7c93e96f31
--- /dev/null
+++ b/src/cascadia/ShellExtension/dllmain.cpp
@@ -0,0 +1,33 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+
+#include "pch.h"
+#include "OpenTerminalHere.h"
+
+// For reference, see:
+// * https://docs.microsoft.com/en-us/cpp/cppcx/wrl/how-to-create-a-classic-com-component-using-wrl?view=vs-2019
+// * https://docs.microsoft.com/en-us/windows/uwp/cpp-and-winrt-apis/move-to-winrt-from-wrl#porting-a-wrl-module-microsoftwrlmodule
+//
+// We don't need to implement DllGetActivationFactory or DllCanUnloadNow
+// manually, since the generated module.g.cpp will handle it for us, and will
+// handle our WRL types appropriately.
+//
+// We DO need to implement DllGetClassObject, because that's what explorer.exe
+// will call to attempt to create a class factory for our shell extension. The
+// CoCreatableClass macro in OpenTerminalHere.h will create the factory for us,
+// so that the GetClassObject call will work like magic.
+
+STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, _COM_Outptr_ void** ppv)
+{
+ return Microsoft::WRL::Module::GetModule().GetClassObject(rclsid, riid, ppv);
+}
+
+STDAPI_(BOOL)
+DllMain(_In_opt_ HINSTANCE hinst, DWORD reason, _In_opt_ void*)
+{
+ if (reason == DLL_PROCESS_ATTACH)
+ {
+ DisableThreadLibraryCalls(hinst);
+ }
+ return TRUE;
+}
diff --git a/src/cascadia/ShellExtension/packages.config b/src/cascadia/ShellExtension/packages.config
new file mode 100644
index 00000000000..8db4233e6a9
--- /dev/null
+++ b/src/cascadia/ShellExtension/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/src/cascadia/ShellExtension/pch.cpp b/src/cascadia/ShellExtension/pch.cpp
new file mode 100644
index 00000000000..3c27d44d570
--- /dev/null
+++ b/src/cascadia/ShellExtension/pch.cpp
@@ -0,0 +1,4 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+
+#include "pch.h"
diff --git a/src/cascadia/ShellExtension/pch.h b/src/cascadia/ShellExtension/pch.h
new file mode 100644
index 00000000000..5962c68100a
--- /dev/null
+++ b/src/cascadia/ShellExtension/pch.h
@@ -0,0 +1,30 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+//
+// pch.h
+// Header for platform projection include files
+//
+
+#pragma once
+
+#define WIN32_LEAN_AND_MEAN
+
+#include
+// This is inexplicable, but for whatever reason, cppwinrt conflicts with the
+// SDK definition of this function, so the only fix is to undef it.
+// from WinBase.h
+// Windows::UI::Xaml::Media::Animation::IStoryboard::GetCurrentTime
+#ifdef GetCurrentTime
+#undef GetCurrentTime
+#endif
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+#include
diff --git a/src/cascadia/TerminalApp/AppLogic.idl b/src/cascadia/TerminalApp/AppLogic.idl
index 513f6c543e7..12368a8ab10 100644
--- a/src/cascadia/TerminalApp/AppLogic.idl
+++ b/src/cascadia/TerminalApp/AppLogic.idl
@@ -11,6 +11,7 @@ namespace TerminalApp
{
DefaultMode,
MaximizedMode,
+ FullscreenMode,
};
[default_interface] runtimeclass AppLogic : IF7Listener
diff --git a/src/cascadia/TerminalApp/ColorScheme.cpp b/src/cascadia/TerminalApp/ColorScheme.cpp
index 4673bcc3bb8..45d4e7748e4 100644
--- a/src/cascadia/TerminalApp/ColorScheme.cpp
+++ b/src/cascadia/TerminalApp/ColorScheme.cpp
@@ -47,7 +47,7 @@ ColorScheme::ColorScheme() :
{
}
-ColorScheme::ColorScheme(std::wstring name, COLORREF defaultFg, COLORREF defaultBg, COLORREF cursorColor) :
+ColorScheme::ColorScheme(std::wstring name, til::color defaultFg, til::color defaultBg, til::color cursorColor) :
_schemeName{ name },
_table{},
_defaultForeground{ defaultFg },
@@ -70,44 +70,18 @@ ColorScheme::~ColorScheme()
// -
void ColorScheme::ApplyScheme(TerminalSettings terminalSettings) const
{
- terminalSettings.DefaultForeground(_defaultForeground);
- terminalSettings.DefaultBackground(_defaultBackground);
- terminalSettings.SelectionBackground(_selectionBackground);
- terminalSettings.CursorColor(_cursorColor);
+ terminalSettings.DefaultForeground(static_cast(_defaultForeground));
+ terminalSettings.DefaultBackground(static_cast(_defaultBackground));
+ terminalSettings.SelectionBackground(static_cast(_selectionBackground));
+ terminalSettings.CursorColor(static_cast(_cursorColor));
auto const tableCount = gsl::narrow_cast(_table.size());
for (int i = 0; i < tableCount; i++)
{
- terminalSettings.SetColorTableEntry(i, _table[i]);
+ terminalSettings.SetColorTableEntry(i, static_cast(_table[i]));
}
}
-// Method Description:
-// - Serialize this object to a JsonObject.
-// Arguments:
-// -
-// Return Value:
-// - a JsonObject which is an equivalent serialization of this object.
-Json::Value ColorScheme::ToJson() const
-{
- Json::Value root;
- root[JsonKey(NameKey)] = winrt::to_string(_schemeName);
- root[JsonKey(ForegroundKey)] = Utils::ColorToHexString(_defaultForeground);
- root[JsonKey(BackgroundKey)] = Utils::ColorToHexString(_defaultBackground);
- root[JsonKey(SelectionBackgroundKey)] = Utils::ColorToHexString(_selectionBackground);
- root[JsonKey(CursorColorKey)] = Utils::ColorToHexString(_cursorColor);
-
- int i = 0;
- for (const auto& colorName : TableColors)
- {
- auto& colorValue = _table.at(i);
- root[JsonKey(colorName)] = Utils::ColorToHexString(colorValue);
- i++;
- }
-
- return root;
-}
-
// Method Description:
// - Create a new instance of this class from a serialized JsonObject.
// Arguments:
@@ -193,27 +167,27 @@ std::wstring_view ColorScheme::GetName() const noexcept
return { _schemeName };
}
-std::array& ColorScheme::GetTable() noexcept
+std::array& ColorScheme::GetTable() noexcept
{
return _table;
}
-COLORREF ColorScheme::GetForeground() const noexcept
+til::color ColorScheme::GetForeground() const noexcept
{
return _defaultForeground;
}
-COLORREF ColorScheme::GetBackground() const noexcept
+til::color ColorScheme::GetBackground() const noexcept
{
return _defaultBackground;
}
-COLORREF ColorScheme::GetSelectionBackground() const noexcept
+til::color ColorScheme::GetSelectionBackground() const noexcept
{
return _selectionBackground;
}
-COLORREF ColorScheme::GetCursorColor() const noexcept
+til::color ColorScheme::GetCursorColor() const noexcept
{
return _cursorColor;
}
diff --git a/src/cascadia/TerminalApp/ColorScheme.h b/src/cascadia/TerminalApp/ColorScheme.h
index 0357a63d3be..92f8f4f6d70 100644
--- a/src/cascadia/TerminalApp/ColorScheme.h
+++ b/src/cascadia/TerminalApp/ColorScheme.h
@@ -35,32 +35,31 @@ class TerminalApp::ColorScheme
{
public:
ColorScheme();
- ColorScheme(std::wstring name, COLORREF defaultFg, COLORREF defaultBg, COLORREF cursorColor);
+ ColorScheme(std::wstring name, til::color defaultFg, til::color defaultBg, til::color cursorColor);
~ColorScheme();
void ApplyScheme(winrt::Microsoft::Terminal::Settings::TerminalSettings terminalSettings) const;
- Json::Value ToJson() const;
static ColorScheme FromJson(const Json::Value& json);
bool ShouldBeLayered(const Json::Value& json) const;
void LayerJson(const Json::Value& json);
std::wstring_view GetName() const noexcept;
- std::array& GetTable() noexcept;
- COLORREF GetForeground() const noexcept;
- COLORREF GetBackground() const noexcept;
- COLORREF GetSelectionBackground() const noexcept;
- COLORREF GetCursorColor() const noexcept;
+ std::array& GetTable() noexcept;
+ til::color GetForeground() const noexcept;
+ til::color GetBackground() const noexcept;
+ til::color GetSelectionBackground() const noexcept;
+ til::color GetCursorColor() const noexcept;
static std::optional GetNameFromJson(const Json::Value& json);
private:
std::wstring _schemeName;
- std::array _table;
- COLORREF _defaultForeground;
- COLORREF _defaultBackground;
- COLORREF _selectionBackground;
- COLORREF _cursorColor;
+ std::array _table;
+ til::color _defaultForeground;
+ til::color _defaultBackground;
+ til::color _selectionBackground;
+ til::color _cursorColor;
friend class TerminalAppLocalTests::SettingsTests;
friend class TerminalAppLocalTests::ColorSchemeTests;
diff --git a/src/cascadia/TerminalApp/GlobalAppSettings.cpp b/src/cascadia/TerminalApp/GlobalAppSettings.cpp
index 5e7ab955246..cdb67c1b81d 100644
--- a/src/cascadia/TerminalApp/GlobalAppSettings.cpp
+++ b/src/cascadia/TerminalApp/GlobalAppSettings.cpp
@@ -38,6 +38,7 @@ static constexpr std::string_view ConfirmCloseAllKey{ "confirmCloseAllTabs" };
static constexpr std::string_view SnapToGridOnResizeKey{ "snapToGridOnResize" };
static constexpr std::wstring_view DefaultLaunchModeValue{ L"default" };
static constexpr std::wstring_view MaximizedLaunchModeValue{ L"maximized" };
+static constexpr std::wstring_view FullscreenLaunchModeValue{ L"fullscreen" };
static constexpr std::wstring_view LightThemeValue{ L"light" };
static constexpr std::wstring_view DarkThemeValue{ L"dark" };
static constexpr std::wstring_view SystemThemeValue{ L"system" };
@@ -249,40 +250,6 @@ void GlobalAppSettings::ApplyToSettings(TerminalSettings& settings) const noexce
settings.SoftwareRendering(_softwareRendering);
}
-// Method Description:
-// - Serialize this object to a JsonObject.
-// Arguments:
-// -
-// Return Value:
-// - a JsonObject which is an equivalent serialization of this object.
-Json::Value GlobalAppSettings::ToJson() const
-{
- Json::Value jsonObject;
-
- jsonObject[JsonKey(DefaultProfileKey)] = winrt::to_string(Utils::GuidToString(_defaultProfile));
- jsonObject[JsonKey(InitialRowsKey)] = _initialRows;
- jsonObject[JsonKey(InitialColsKey)] = _initialCols;
- jsonObject[JsonKey(RowsToScrollKey)] = _rowsToScroll;
- jsonObject[JsonKey(InitialPositionKey)] = _SerializeInitialPosition(_initialX, _initialY);
- jsonObject[JsonKey(AlwaysShowTabsKey)] = _alwaysShowTabs;
- jsonObject[JsonKey(ShowTitleInTitlebarKey)] = _showTitleInTitlebar;
- jsonObject[JsonKey(ShowTabsInTitlebarKey)] = _showTabsInTitlebar;
- jsonObject[JsonKey(WordDelimitersKey)] = winrt::to_string(_wordDelimiters);
- jsonObject[JsonKey(CopyOnSelectKey)] = _copyOnSelect;
- jsonObject[JsonKey(CopyFormattingKey)] = _copyFormatting;
- jsonObject[JsonKey(LaunchModeKey)] = winrt::to_string(_SerializeLaunchMode(_launchMode));
- jsonObject[JsonKey(ThemeKey)] = winrt::to_string(_SerializeTheme(_theme));
- jsonObject[JsonKey(TabWidthModeKey)] = winrt::to_string(_SerializeTabWidthMode(_tabWidthMode));
- jsonObject[JsonKey(KeybindingsKey)] = _keybindings->ToJson();
- jsonObject[JsonKey(ConfirmCloseAllKey)] = _confirmCloseAllTabs;
- jsonObject[JsonKey(SnapToGridOnResizeKey)] = _SnapToGridOnResize;
- jsonObject[JsonKey(ForceFullRepaintRenderingKey)] = _forceFullRepaintRendering;
- jsonObject[JsonKey(SoftwareRenderingKey)] = _softwareRendering;
- jsonObject[JsonKey(DebugFeaturesKey)] = _debugFeatures;
-
- return jsonObject;
-}
-
// Method Description:
// - Create a new instance of this class from a serialized JsonObject.
// Arguments:
@@ -507,6 +474,10 @@ LaunchMode GlobalAppSettings::_ParseLaunchMode(const std::wstring& launchModeStr
{
return LaunchMode::MaximizedMode;
}
+ else if (launchModeString == FullscreenLaunchModeValue)
+ {
+ return LaunchMode::FullscreenMode;
+ }
return LaunchMode::DefaultMode;
}
@@ -524,6 +495,8 @@ std::wstring_view GlobalAppSettings::_SerializeLaunchMode(const LaunchMode launc
{
case LaunchMode::MaximizedMode:
return MaximizedLaunchModeValue;
+ case LaunchMode::FullscreenMode:
+ return FullscreenLaunchModeValue;
default:
return DefaultLaunchModeValue;
}
diff --git a/src/cascadia/TerminalApp/GlobalAppSettings.h b/src/cascadia/TerminalApp/GlobalAppSettings.h
index d390403e93e..72bd1cd8c02 100644
--- a/src/cascadia/TerminalApp/GlobalAppSettings.h
+++ b/src/cascadia/TerminalApp/GlobalAppSettings.h
@@ -82,7 +82,6 @@ class TerminalApp::GlobalAppSettings final
bool DebugFeaturesEnabled() const noexcept;
- Json::Value ToJson() const;
static GlobalAppSettings FromJson(const Json::Value& json);
void LayerJson(const Json::Value& json);
diff --git a/src/cascadia/TerminalApp/JsonUtils.cpp b/src/cascadia/TerminalApp/JsonUtils.cpp
index 8331612a8bc..f4282097b83 100644
--- a/src/cascadia/TerminalApp/JsonUtils.cpp
+++ b/src/cascadia/TerminalApp/JsonUtils.cpp
@@ -8,9 +8,9 @@
void TerminalApp::JsonUtils::GetOptionalColor(const Json::Value& json,
std::string_view key,
- std::optional& target)
+ std::optional& target)
{
- const auto conversionFn = [](const Json::Value& value) -> uint32_t {
+ const auto conversionFn = [](const Json::Value& value) -> til::color {
return ::Microsoft::Console::Utils::ColorFromHexString(value.asString());
};
GetOptionalValue(json,
diff --git a/src/cascadia/TerminalApp/JsonUtils.h b/src/cascadia/TerminalApp/JsonUtils.h
index 423f43c274a..1845a9d6524 100644
--- a/src/cascadia/TerminalApp/JsonUtils.h
+++ b/src/cascadia/TerminalApp/JsonUtils.h
@@ -17,7 +17,7 @@ namespace TerminalApp::JsonUtils
{
void GetOptionalColor(const Json::Value& json,
std::string_view key,
- std::optional& target);
+ std::optional& target);
void GetOptionalString(const Json::Value& json,
std::string_view key,
diff --git a/src/cascadia/TerminalApp/MinMaxCloseControl.cpp b/src/cascadia/TerminalApp/MinMaxCloseControl.cpp
index 0be83621099..ee5f3e0d9b7 100644
--- a/src/cascadia/TerminalApp/MinMaxCloseControl.cpp
+++ b/src/cascadia/TerminalApp/MinMaxCloseControl.cpp
@@ -40,15 +40,53 @@ namespace winrt::TerminalApp::implementation
void MinMaxCloseControl::SetWindowVisualState(WindowVisualState visualState)
{
+ // Look up the heights we should use for the caption buttons from our
+ // XAML resources. "CaptionButtonHeightWindowed" and
+ // "CaptionButtonHeightMaximized" define the size we should use for the
+ // caption buttons height for the windowed and maximized states,
+ // respectively.
+ //
+ // use C++11 magic statics to make sure we only do this once.
+ static auto heights = [this]() {
+ const auto res = Resources();
+ const auto windowedHeightKey = winrt::box_value(L"CaptionButtonHeightWindowed");
+ const auto maximizedHeightKey = winrt::box_value(L"CaptionButtonHeightMaximized");
+
+ auto windowedHeight = 0.0;
+ auto maximizedHeight = 0.0;
+ if (res.HasKey(windowedHeightKey))
+ {
+ const auto valFromResources = res.Lookup(windowedHeightKey);
+ windowedHeight = winrt::unbox_value_or(valFromResources, 0.0);
+ }
+ if (res.HasKey(maximizedHeightKey))
+ {
+ const auto valFromResources = res.Lookup(maximizedHeightKey);
+ maximizedHeight = winrt::unbox_value_or(valFromResources, 0.0);
+ }
+ return std::tuple{ windowedHeight, maximizedHeight };
+ }();
+ static const auto windowedHeight = std::get<0>(heights);
+ static const auto maximizedHeight = std::get<1>(heights);
+
switch (visualState)
{
case WindowVisualState::WindowVisualStateMaximized:
- winrt::Windows::UI::Xaml::VisualStateManager::GoToState(MaximizeButton(), L"WindowStateMaximized", false);
+ VisualStateManager::GoToState(MaximizeButton(), L"WindowStateMaximized", false);
+
+ MinimizeButton().Height(maximizedHeight);
+ MaximizeButton().Height(maximizedHeight);
+ CloseButton().Height(maximizedHeight);
break;
+
case WindowVisualState::WindowVisualStateNormal:
case WindowVisualState::WindowVisualStateIconified:
default:
- winrt::Windows::UI::Xaml::VisualStateManager::GoToState(MaximizeButton(), L"WindowStateNormal", false);
+ VisualStateManager::GoToState(MaximizeButton(), L"WindowStateNormal", false);
+
+ MinimizeButton().Height(windowedHeight);
+ MaximizeButton().Height(windowedHeight);
+ CloseButton().Height(windowedHeight);
break;
}
}
diff --git a/src/cascadia/TerminalApp/MinMaxCloseControl.xaml b/src/cascadia/TerminalApp/MinMaxCloseControl.xaml
index d986b9be190..305303d665c 100644
--- a/src/cascadia/TerminalApp/MinMaxCloseControl.xaml
+++ b/src/cascadia/TerminalApp/MinMaxCloseControl.xaml
@@ -62,6 +62,18 @@ the MIT License. See LICENSE in the project root for license information. -->
+
+ 36.0
+ 32.0
+