## Summary of the Pull Request
The original `DECPS` implementation made use of the Windows MIDI APIs to
generate the sound, but that required a 3MB package dependency for the
GS wavetable DLS. This PR reimplements the `MidiAudio` class using
`DirectSound`, so we can avoid that dependency.
## References
The original `DECPS` implementation was added in PR #13208, but was
hidden behind a velocity flag in #13258.
## PR Checklist
* [x] Closes#13252
* [x] CLA signed.
* [ ] Tests added/passed
* [ ] Documentation updated.
* [ ] Schema updated.
* [x] I've discussed this with core contributors already. Issue number
where discussion took place: #13252
## Detailed Description of the Pull Request / Additional comments
The way it works is by creating a sound buffer with a single triangle
wave that is played in a loop. We generate different notes simply by
adjusting the frequency at which that buffer is played.
When we need a note to end, we just set the volume to its minimum value
rather than stopping the buffer. If we don't do that, the repeated
starting and stopping tends to produce a lot of static in the output. We
also use two buffers, which we alternate between notes, as another way
to reduce that static.
One other thing worth mentioning is the handling of the buffer position.
At the end of each note we save the current position, and then use an
offset from that position when starting the following note. This helps
produce a clearer separation between tones when repeating sequences of
the same note.
In an ideal world, we should really have something like an attack-decay-
sustain-release envelope for each note, but the above hack seems to work
reasonably well, and keeps the implementation simple.
## Validation Steps Performed
I've manually tested both conhost and Terminal with the sample tunes
listed in issue #8687, as well as a couple of games that I have which
make use of `DECPS` sound effects.
(cherry picked from commit bc79867b38)
Service-Card-Id: 84270205
Service-Version: 1.15
Does what it says on the tin. When we get focused, temporarily turn off readonly mode, as to not pop the dialog when the focus sequence is eventually sent to the connection.
* closes#13461
(cherry picked from commit b4a52c847f)
Service-Card-Id: 84111371
Service-Version: 1.15
## Summary of the Pull Request
When the debug tap converts control characters into visible glyphs, it
ends up losing the structure of the output, and that can sometimes make
things difficult to read. This PR attempts to alleviate that problem by
reinjecting an actual line break in the debug stream whenever an `LF`
control is received.
## PR Checklist
* [x] Closes#12312
* [x] CLA signed.
* [ ] Tests added/passed
* [ ] Documentation updated.
* [ ] Schema updated.
* [x] I've discussed this with core contributors already. Issue number
where discussion took place: #12312
## Validation Steps Performed
I've tested the updated debug tab with a number of different shells, and
also a couple of different apps. When there aren't many linefeeds in the
output, it's obviously not going to make much of a difference, but when
there are, I think it definitely improves the readability.
(cherry picked from commit 04478d1df0)
Service-Card-Id: 84116395
Service-Version: 1.15
If launch mode is set to full screen quake window is opened in full
screen.
## Validation Steps Performed
- Set startup > launch mode > full screen
- Launch quake window
- Quake window shouldn't be opened in full screen
Closes#12894
(cherry picked from commit 589286a357)
Service-Card-Id: 84116410
Service-Version: 1.15
In non-en-us locales, these tooltips can get really long and get clipped.
Closes MSFT:39603031
See Also #9913
(cherry picked from commit 32379c29f0)
Service-Card-Id: 84008282
Service-Version: 1.15
## Summary of the Pull Request
When you create a console alias that overrides an existing command, it
should still be possible to execute the original command by prefixing it
with a space. However, at some point in the past, there was an attempt
to improve the usability by trimming leading spaces, and that ended up
breaking this functionality. This PR reverts that change, so leading
spaces can once again be used to bypass an alias.
## PR Checklist
* [x] Closes#4189
* [x] CLA signed.
* [x] Tests added/passed
* [ ] Documentation updated.
* [ ] Schema updated.
* [x] I've discussed this with core contributors already. Issue number
where discussion took place: #4189
## Validation Steps Performed
I've updated the existing alias unit test for leading spaces to match
the new behavior, i.e. it now confirms that a command with leading
spaces will not match the alias.
I've also manually confirmed that the `doskey` test case reported in
issue #4189 is now working as expected.
(cherry picked from commit cd2166aedf)
Service-Card-Id: 84072860
Service-Version: 1.15
This one's pretty obvious. I added another scrollbar sized grid to the terminal,
but I forgot to collapse it when the user requests `"scrollbarState": "hidden"`.
* [x] Closes#13446
* [x] I work here
(cherry picked from commit aa4e9f5414)
Service-Card-Id: 83969639
Service-Version: 1.15
The hover tab color used to be generated from the selected tab color, which would end up lighter or darker, and white-gray colors would end up pink.
It is now simply the selected tab color with 60% opacity. This is also how brushes are created for accent buttons and color buttons (although with different opacity levels).
(cherry picked from commit c6b67aad4b)
Service-Card-Id: 83894208
Service-Version: 1.15
The main result of this fallback is that we attempt to launch wsl.exe
when the user hasn't installed or interacted with WSL. On our test
machines, that results in the creation of a wsl.exe process that tells
us precisely nothing; on WDAC managed machines it results in an Event
Log entry about spawning another (possibly blocked) process.
The registry is more reliable, and if the "API" it provides changes we
can just rev terminal.
Closes#11716
(cherry picked from commit f025c53dba)
Service-Card-Id: 83892844
Service-Version: 1.15
## Summary of the Pull Request
In #13370, we should be notifying the renderer that the selection changed. Minor oversight and simple fix.
## References
#4993#13370Closes#13413
(cherry picked from commit 66ecb0bd63)
Service-Card-Id: 83892665
Service-Version: 1.15
This commit fixes a minor race condition covered as part of #13368.
The member `_pfnHandoff` was read without the mutex `_mtx` being locked first.
The issue was solved by acquiring the lock early and running the entire
`s_StopListening` function with that lock held.
(cherry picked from commit 95a19624a4)
Service-Card-Id: 83893126
Service-Version: 1.15
Update schema with the settings/actions added in #12948
## PR Checklist
* [x] Closes#13404
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [x] Schema updated.
(cherry picked from commit 478c2c3613)
Service-Card-Id: 83790285
Service-Version: 1.15
## Summary of the Pull Request
Introduces the `switchSelectionEndpoint` action which switches whichever selection endpoint is targeted when a selection is present. For example, if you are targeting "start", `switchSelectionEndpoint` makes it so that now you are targeting "end". This also updates the selection markers appropriately.
## References
Spec - #5804#13358Closes#3663
## Detailed Description of the Pull Request / Additional comments
Most of the code is just standard code of adding a new action. Other than that, we have...
- if there is no selection, the action fails and the keybinding is passed through (similar to `copy()`)
- when we update the selection endpoint, we need to also update the "pivot". This ensures that future calls of `UpdateSelection()` respect this swap.
- [Corner Case] if the cursor is being moved, we make it so that you basically "anchored" an endpoint and you don't have to hold shift anymore.
## Why is this change being made?
Our conhost OneCore backend isn't as thoroughly tested as our Win32 one and fell victim to the general "bugginess" of our shutdown handling centered around `ServiceLocator::RundownAndExit`. In the past we simply leaked all resources, but changed it so that a cleanup on exit occurs, so that we can track resource leaks for instance. This broke OneCore which has a more delicate shutdown than Win32.
## What changed?
This commit reverts changes being made in 9d7a46f64c and after.
## How was the change tested?
This change was tested in a OneCore VM by repeatedly spawning subprocesses and ensuring they exit in a timely manner and without unexpected crashes.
Related work items: MSFT-40226902, MSFT-22128499
Retrieved from https://microsoft.visualstudio.com os.2020 OS official/rs_wdx_dxp_windev 0683758a0846aefbbe50730c3cd336623328ddeb
## Summary of the Pull Request
1. [copy on select] when manually copying text (i.e. kbd or right-click) while in mark/quick-edit mode, we now dismiss the selection.
2. `Enter` is now bound to copy by default.
- This works very well with mark mode and provides a more consistent behavior with conhost's selection experience overall.
- "why not hardcode `Enter` as a way to copy when in mark mode?"
- In an effort to make this as configurable as possible, I decided to make it a configurable keybinding, but am open to suggestions.
3. selection markers
a. we now hide the selection markers when multi-clicking the terminal.
b. selection markers are now properly shown when a single cell selection exists
- Prior to this PR, any single cell selection would display both markers. Now, we actually track which endpoint we're moving and display the appropriate one.
4. ensures that when you use keyboard selection to move past the top/bottom of the scroll area, we clamp it to the origin/bottom-right respectively. The fix is also better here in that it provides consistent behavior across all of the `_MoveByX` functions.
5. adds `toggleBlockSelection` to the schema
## References
#13053
## Validation Steps Performed
Did a whole flowchart of expected behavior with copy on select:
- enable `copyOnSelect`
- make a selection with the mouse
- ✅ right-click should copy the text --> clear the selection --> paste
- use keyboard selection to quick-edit the existing selection
- ✅ `copy` action should clear the selection
- ✅ right-click should copy the text --> clear the selection --> paste
Played with selection markers a bit in mark mode and quick edit mode. Markers are updating appropriately.
FabricBot is now a [config-as-code-only] platform. As a result, while
you can still use the [FabricBot Configuration Portal] to modify your
FabricBot configuration, you can no longer save the changes. The only
way to save changes to your configuration at the moment is to _export
configuration_ from the portal and upload the exported configuration to
`.github/fabricbot.json` in your repository. In this pull request, we
are adding your FabricBot configuration to your repository at
`.github/fabricbot.json` so that you can make changes to it going
forward.
While the [FabricBot Configuration Portal] is the *only way* to modify
your FabricBot configuration at the moment, we have a feature on our
backlog to publish the JSON schema defining the structure of the
FabricBot configuration file. With the JSON schema, you can (1) use a
plaintext editor of your choice to modify the FabricBot configuration
file and use the schema to validate the file after editing or (2)
[configure VS Code] to use the schema when editing FabricBot
configuration file to take advantage of convenience features such as
automatic code completion and field description on mouseover.
[config-as-code-only]: https://eng.ms/docs/products/1es-data-insights/merlinbot/extensions/bot-config-as-code
[FabricBot Configuration Portal]: https://portal.fabricbot.ms/bot/?repo=microsoft/terminal
[configure VS Code]: https://code.visualstudio.com/Docs/languages/json#_json-schemas-and-settings
Co-authored-by: msftbot[bot] <48340428+msftbot[bot]@users.noreply.github.com>
Co-authored-by: Dustin Howett <duhowett@microsoft.com>
## Summary of the Pull Request
Replaces most uses of `Viewport::CompareInBounds()` with `til::point`'s `<` and `>` operators. `CompareInBounds` has been the cause of a bunch of UIA crashes over the years. Replacing them entirely ensures that the `FAILFAST_IF` isn't ever touched.
Unfortunately, we still need `IncrementInBounds` and `DecrementInBounds` to have support for that exclusive end.
## References
#13183
This commit fixes a bug causing the OpenConsole to get increasingly larger
every time the font is changed when the AtlasEngine is active.
The only impact this bug had on Windows Terminal is that the
`font-size` in HTML and RTF selection copies are too large.
## Validation Steps Performed
* OpenConsole window size doesn't change when
switching between main and alt buffer ✅
[Git2Git] Merged PR 7517171: Fix a race condition in ServiceLocator::RundownAndExit
The whole premise of RundownAndExit is that one thread enters it, runs
down the console and terminates it. One thread enters, 0 threads leave.
After some recent console locking changes, we found that on OneCore
devices it was possible for two threads (the I/O thread and the coniosrv
Input thread) to try to rundown and exit at the same time.
This SRWLOCK prevents that from happening.
Fixes#40146639
Related work items: #40146639 Retrieved from https://microsoft.visualstudio.com os.2020 OS official/rs_wdx_dxp_windev ff235c6e49e065bccc937dee91f43ff310b5743c
Related work items: #40146639
[Git2Git] Merged PR 7517072: conhost: Force the double-click tests to have a high click timeout
The conhost tests might run somewhere that does not have a double click time.
We should hardcode a value for the purposes of testing.
Retrieved from https://microsoft.visualstudio.com os.2020 OS official/rs_wdx_dxp_windev 3c2620dab577e16e8672b369e4dfcde7c02881a1
Related work items: MSFT-40150725
This introduces the build rules for midi.lib to the OS!
Retrieved from https://microsoft.visualstudio.com os.2020 OS official/rs_wdx_dxp_windev fb066544f112ae491bb1d1f73578bc47fa167b41
In #6810, we introduced a "quirk" for all known versions of PowerShell
that suppressed their requests for black background/gray foreground.
This was done to avoid an [issue in PSReadline] where it would paint
black bars all over the screen if the default background color wasn't
the same as the ANSI black color.
Years have passed since that quirk was introduced. The underlying bug
was fixed, and the fix was released broadly long ago. It's time for us
to remove the quirk... almost.
Terminal still runs on versions of Windows that ship a broken version of
PSReadline. We must maintain the quirk there -- the user can't do
anything about it, and we would make their experience worse if we
removed the quirk entirely.
PowerShell 7.0 also ships a broken version of PSReadline. It is still in
support for another 6 months, but updates have been available for some
time. We can encourage users to update.
Therefore, we only need the quirk for Windows PowerShell, and then only
for specific versions of Windows.
_Inside Windows_, we don't even need that: we're guaranteed to be built
alongside a fixed version of PowerShell!
Closes#6807
[issue in PSReadline]: https://github.com/PowerShell/PSReadLine/issues/830#issuecomment-650508857
## Summary of the Pull Request
Introduced in #10824, this fixes a bug where you could use keyboard selection to move below the scroll area. Instead, we now clamp movement to the mutable viewport (aka the scrollable area). Specifically, we clamp to the corners (i.e. 0,0 or bottom right cell of scroll area).
## Validation Steps Performed
✅ (no output) try to move past bottom of viewport
✅ (with output, at bottom of scroll area) try to move past viewport
✅ (with output, NOT at bottom of scroll area) try to move past viewport
✅ try to move past top of viewport
It's not useful to notify users that WT can be made the default if it's already
clearly being used for handoff. This commit will suppresses the banner then.
## PR Checklist
* [x] Closes#13314
* [x] I work here
## Validation Steps Performed
* Modify `TerminalPage::ShowSetAsDefaultInfoBar` to not check for
`CascadiaSettings::IsDefaultTerminalSet()`
* Set Terminal Dev as the default
* Set incoming connections to open in the latest Terminal window
* Delete `state.json` after every test below
* Launching Terminal Dev shows the banner ✅
Launching `cmd.exe` dismisses the banner in the current Terminal ✅
* Launching `cmd.exe` launches Terminal Dev without banner ✅
These files are vestigial, because we are also shipping (either as loose
files or embedded in resources.pri) precompiled xbf/xaml binary format
files.
This saves us almost 500kb on disk.
Fixes#11687
Validation
----------
I ran a local build and saw that it produced a working Terminal, packaged
and unpackaged.
## Summary of the Pull Request
This introduces a selection marker overlay that tells the user which endpoint is currently being moved by the keyboard. The selection markers are respect font size changes and `cursor` color.
## References
#715 - Keyboard Selection
#2840 - Keyboard Selection Spec
#5804 - Mark Mode Spec
## Detailed Description of the Pull Request / Additional comments
- `TermControl` layer:
- Use a canvas (similar to the one used for hyperlinks) to be able to draw the selection markers.
- If we are notified that the selection changed, update the selection markers appropriately.
- `UpdateSelectionMarkersEventArgs` lets us distinguish between mouse and keyboard selections. `ClearMarkers` is set to true in the following cases...
1. Mouse selection, via SetEndSelectionPoint
2. `LeftClickOnTerminal`, pretty self-explanatory
3. a selection created from searching for text
- `ControlCore` layer:
- Responsible for notifying `TermControl` to update the selection markers when a selection has changed.
- Transfers info (the selection endpoint positions and which endpoint we're moving) from the terminal core to the term control.
- `TerminalCore` layer:
- Provides the viewport position of the selection endpoints.
## Validation Steps Performed
- mouse selection (w/ and w/out shift) --> no markers
- keyboard selection --> markers
- markers update appropriately when we pivot the selection
- markers scroll when you hit a boundary
- markers take the color of the cursor color setting
- markers are resized when the font size changes
## Summary of the Pull Request
When you execute a `cls` in the cmd shell, or `Clear-Host` in
PowerShell, we have a pair of shims that attempt to detect those
operations and forward an `ED3` sequence to conpty to clear the
scrollback.
If there was a linefeed at the bottom of the viewport immediately
prior to those functions being called, that event might still be
pending, and only forwarded to conpty after the `ED3`. The result
then is a line pushed into the scrollback that shouldn't be there.
This PR tries to avoid that situation by forcing the renderer to
flush before the `ED3` sequence is sent.
## References
The `cls` and `Clear-Host` shims were originally added in PR #5627.
## PR Checklist
* [x] Closes#5770
* [x] Closes#13320
* [x] CLA signed.
* [ ] Tests added/passed
* [ ] Documentation updated.
* [ ] Schema updated.
* [ ] I've discussed this with core contributors already. If not
checked, I'm ready to accept this work might be rejected in favor of a
different grand plan. Issue number where discussion took place: #xxx
## Validation Steps Performed
I've manually tested in PowerShell with `echo Hello; Clear-Host` (this
is the only way I could reliably reproduce the original problem), and in
the cmd shell with `cls`. Both cases are now working as expected.
When we send this ShowWindow message, if we send it to it's
going to need to get processed by the window message thread before
returning. We're handling this message under lock. However, the first
thing the conhost message thread does is lock the console. That'll
deadlock us. So unlock here, first, to let the message thread deal with
this message, then re-lock so later on this thread can unlock again
safely.
* [x] Closes#13301
* [x] Tested conhost
* [x] Tested terminal
When I moved this into ControlCore, I forgot that UserScrollViewport is usually triggered by the scrollbar updating, so it doesn't ask the UI to update. Since this logic is in ControlCore, it's sorta in a weird place where it needs to communicate both up and down:
* update the `Terminal`'s viewport position
* update the `TermControl`'s scrollbar position
Checklist:
* [x] Closes a bug bash bug
* [x] Missed in #12948
* See also #11000
ed27737 contains a regression were a `RECT` in `GdiEngine` wasn't properly
initialized anymore. Due to this, rendering during scrolling behaved erratic.
To find other cases of this bug in ed27737 the following regex was used:
```
^-.* = \{\s*\d*\s*\};
```
It appears that only `GdiEngine` was affected by a bug of this kind,
but just to be sure, this PR reverts all other instances.
This bug was likely caused when I tried to undo some of the changes in
ed27737 to make the PR smaller, but failed to revert the code properly.
## PR Checklist
* [x] Closes#13270
* [x] I work here
## Validation Steps Performed
I'm unable to reproduce the issue on my hardware and am unable to test
this change, but the uninitialized struct is clearly a bug regardless.
Co-authored-by: James Holderness <j4_james@hotmail.com>
Adds an accelerator key for the shell extension: `T` for stable, `P` for preview and `D` for dev.
# Validation
Ran a dev build and saw the keyboard accelerator assigned.
Closes#13061
## Summary of the Pull Request
Up to now we haven't supported passing `DCS` sequences over conpty, so
any `DCS` operations would just be ignored in Windows Terminal. This PR
introduces a mechanism whereby we can selectively pass through
operations that could reasonably be handled by the connected terminal
without interfering with the regular conpty renderer. For now this is
just used to support restoring the `DECCTR` color table report.
## References
Support for `DECCTR` was originally added to conhost in PR #13139.
## PR Checklist
* [x] Closes#13223
* [x] CLA signed.
* [x] Tests added/passed
* [ ] Documentation updated.
* [ ] Schema updated.
* [ ] I've discussed this with core contributors already. If not
checked, I'm ready to accept this work might be rejected in favor of a
different grand plan. Issue number where discussion took place: #xxx
## Detailed Description of the Pull Request / Additional comments
The way this works is we have a helper method in `AdaptDispatch` that
`DCS` operations can use to create a passthrough `StringHandler` for the
incoming data instead of their usual handler. To make this passthrough
process more efficient, the handler buffers the data before forwarding
it to conpty.
However, it's important that we aren't holding back data if output is
paused before the string terminator, so we need to flush the buffer
whenever we reach the end of the current write operation. This is
achieved by querying a new method in the `StateMachine` that lets us
know if we're currently dealing with the last character.
Another issue that came up was with the way the `StateMachine` caches
sequences that it might later need to forward to conpty. In the case of
string sequences like `DCS`, we don't want the actual string data cached
here, because that will just waste memory, and can also result in the
data being mistakenly output. So I've now disabled that caching when
we're in any of the string processing states.
## Validation Steps Performed
I've manually confirmed that the `DECCTR` sequence can now update the
color table in Windows Terminal. I've also added a new unit test in
`ConptyRoundtripTests` to verify the sequence is being passed through
successfully.
As described in #13238. libuv sends a focus event to jiggle the handle. Now that we support focus events as VT input (#12900), we'd translate those focus events to VT input as well. That combination of things caused exiting neovim to emit a `\x1b[O` to the input line of the shell when exited.
To fix this, we're going to secretly filter out any focus events that came from the API, before translating to VT. We're fortunate here, the `FOCUS_EVENT_RECORD` version of the ctor is only called by the API.
* [x] Closes#13238
When loading color schemes from Json, check if GetValueForKey failed. If
it did, and we were searching for the colors "purple"/"brightPurple",
swap out the color name with "magenta"/"brightMagenta" and try again.
This was tested manually by creating a new color scheme using the colors
"magenta"/"brightMagenta" and loading it, then printing colored text in
the terminal to assure that the colors were correctly assigned as
purple.
This changes the color loader to use an index pair table to add support
for alternate color names.
## Validation Steps Performed
- Manually edit settings.json, creating a new color scheme with colors
"magenta" and "brightMagenta"
- View the color scheme in settings - the colors will appear as "purple"
and "brightPurple" in the UI
- Run a program that prints colored text, purple and brightPurple text
will appear in the colors defined as magenta and brightMagenta
- Modify the color scheme in the settings UI and save it, the colors
will be saved as "purple" and "brightPurple" *(I think this is the
right behavior, since calling them "magenta" is technically a
mistake)*
- Repeat the steps above with a normal color scheme - colors named
"purple" and "brightPurple" still load properly
Closes#11456
Windows Terminal Preview gets existing settings from Release build if
Preview settings are empty
This ensures that when settings are empty or not existent, we check if
we're currently in a preview build and if we are, we attempt to grab
settings from the Release build's setting path instead. We tested it
manually by changing settings in Release build and confirming that
changes migrated to Preview when settings are empty or not existent.
Additionally, we tested that settings.json of the running build changed.
We also ran existing TAEF testing locally and it passed.
In LoadAll() function in
src\cascadia\TerminalSettingsModel\CascadiaSettingsSerialization.cpp, we
first checked if the settings file us empty/exists via settingsString.
If it does not and we are in the Preview build, we try loading the
Release build's settings. We created modified versions of
CascadiaSettings::_settingsPath() and GetBaseSettingsPath() to get the
path for the Release build's settings. If the Release build settings do
exist and firstTimeSetup is true, we set it to settingsString so it can
be written to disk via WriteSettingsToDisk(). Note that currently we
hardcode the path of the Release build. This pull request was worked on
with @Dannihu01.
## Validation Steps Performed Test1: Setting to firstTimeSetup is true
and loading settings.json from WT release when release exists -> Result:
settings.json AND GUI reflected WT release’s settings
Test2: Setting to firstTimeSetup is true and loading settings.json from
WT release when release doesn’t exist -> Result: settings.json AND GUI
reflected DEFAULT settings
Test3: (After running Test1) Setting to firstTimeSetup is false and
seeing if current settings.json matches WT release. (See if it doesn’t
change) -> Result: settings.json AND GUI reflected WT release’s settings
Closes#6855
Co-authored-by: Danniell Hu <dannihu@umich.edu>
## Summary of the Pull Request
This fixes the crashes caused by using a screen reader when in an app that uses the alt buffer via two changes:
1. Fix `Terminal::ViewEndIndex()`
- `UiaTextRangeBase` receives a coordinate that is outside of the bounds of the text buffer via the following chain of functions... `_getDocumentEnd()` --> `GetLastNonSpaceCharacter()` --> `_getOptimizedBufferSize()` --> `GetTextBufferEndPoisition()` --> `ViewEndIndex()`
- Since support for the alt buffer was added recently, `ViewEndIndex()` was recently changed, so that explains why this issue came up recently. We were accidentally setting the view end index to `height` instead of `height-1`. Thanks @j4james for finding this!
- The UIA code would get the "exclusive end" of the alt buffer. Since it was using `ViewEndIndex()` to calculate that, it was one more than it should be. The UIA code has explicit allowance for "one past the end of the viewport" in its `IsInBounds()` check. Since the `ViewEndIndex()` is way beyond that, it's not allowed, hitting the fail fast.
2. Replace `FAIL_FAST_IF` with `assert`
- These fail fast calls have caused so many issues with our UIA code. Those checks still provide value, but they shouldn't take the whole app down. This change replaces the `Viewport` and `UiaTextRangeBase` fail fasts with asserts to still perform those checks, but not take down the entire app in release builds.
Closes#13183
## Validation Steps Performed
While using Narrator...
- opened nano in bash
- generated text and scrolled in nano
- generated text and scrolled in PowerShell
See also: #12799, the origin of much of this.
This change evolved over multiple phases.
### Part the first
When we create a defterm connection in `TerminalPage::_OnNewConnection`,
we don't have the hosting HWND yet, so the tab gets created without one.
We'll later get called with the owner, in `Initialize`.
To remedy this, we need to:
* In `Initialize`, make sure to update any existing controls with the
new owner.
* In `ControlCore`, actually propogate the new owner down to the
connection
### Part the second
DefTerm launches don't actually request focus mode, so the Terminal
never sends them focus events. We need those focus events so that the
console can request foreground rights.
To remedy this, we need to:
* pass `--win32input` to the commandline used to initialize OpenConsole
in ConPTY mode. We request focus events at the same time we request
win32-input-mode.
* I also added `--resizeQuirk`, because _by all accounts that should be
there_. Resizing in defterm windows should be _wacky_ without it, and
I'm a little surprised we haven't seen any bugs due to this yet.
### Part the third
`ConsoleSetForeground` expects a `HANDLE` to the process we want to give
foreground rights to. The problem is, the wire format we used _also_
decided that a HANDLE value was a good idea. It's not. If we pass the
literal value of the HANDLE to the process from OpenConsole to conhost,
so conhost can call that API, the value that conhost uses there will
most likely be an invalid handle. The HANDLE's value is its value in
_OpenConsole_, not in conhost.
To remedy this, we need to:
* Just not forward `ConsoleSetForeground`. Turns out, we _can_ just call
that in OpenConsole safely. There's no validation. So just instantiate
a static version of the Win32 version of ConsoleControl, just to use
for SetForeground. (thanks Dustin)
* [x] Tested manually - Win+R `powershell`, `notepad` spawns on top.
Closes#13211
Implements the **FTCS_PROMPT** sequence, `OSC 133 ; A ST`. In this PR, it's just used to set a simple Prompt mark on the current line, in the same way that the iTerm2 sequence works.
There's rumination in #11000 on how to implement the rest of the FTCS sequences.
This is broken into its own PR at the moment. [Quoth j4james](https://github.com/microsoft/terminal/pull/12948#issuecomment-1136360132):
> That should be just as easy, and I've noticed a couple of other terminals that are doing that, so it's not unprecedented. If we don't have any immediate use for the other options, there shouldn't be any harm in ignoring them initially.
>
> And the benefit of going with the more widely supported sequence is that we're more likely to benefit from any shells that have this functionality built in. Otherwise they're forced to try and detect the terminal, which is practically impossible for Windows Terminal. Even iTerm2 supports the `OSC 133` sequence, so we'd probably be the only odd one out.
This part of the plumbing is super easy, so I thought it would be valuable to add regardless if we get to the whole of FTCS in 1.15.
* [x] I work here
* [x] Tested manually - in my pwsh `$PROFILE`:
```pwsh
function prompt {
$loc = $($executionContext.SessionState.Path.CurrentLocation);
$out = "PS $loc$('>' * ($nestedPromptLevel + 1)) ";
$out += "$([char]27)]9;9;`"$loc`"$([char]07)";
$out += "$([char]27)]133;A;$([char]7)"; # add the FTCS_PROMPT to the... well, end, but you get the point
return $out
}
```
* See also #11000
* conhost requires an additional dependency in Windows, which might
cause us trouble in WPG
* Terminal requires an additional *package* dependency, which *will*
cause us trouble in WPG (since GmDls is about 3MB)
I chose to scope the feature checks to MidiOut directly, as I wanted to
keep the delay behavior in MidiAudio::PlayNote. This is negotiable.
References #13252
Adds support for marks in the scrollbar. These marks can be added in 3
ways:
* Via the iterm2 `OSC 1337 ; SetMark` sequence
* Via the `addMark` action
* Automatically when the `experimental.autoMarkPrompts` per-profile
setting is enabled.
#11000 has more tracking for the big-picture for this feature, as well
as additional follow-ups. This set of functionality seemed complete
enough to send a review for now. That issue describes these how I wish
these actions to look in the fullness of time. This is simply the v0.1
from the hackathon last month.
#### Actions
* `addMark`: add a mark to the buffer. If there's a selection, use
place the mark covering at the selection. Otherwise, place the mark
on the cursor row.
- `color`: a color for the scrollbar mark. This is optional - defaults
to the `foreground` color of the current scheme if omitted.
* `scrollToMark`
- `direction`: `["first", "previous", "next", "last"]`
* `clearMark`: Clears marks at the current postition (either the
selection if there is one, or the cursor position.
* `clearAllMarks`: Don't think this needs explanation.
#### Per-profile settings
* `experimental.autoMarkPrompts`: `bool`, default `false`.
* `experimental.showMarksOnScrollbar`: `bool`
## PR Checklist
* [x] Closes#1527
* [x] Closes#6232
## Detailed Description of the Pull Request / Additional comments
This is basically hackathon code. It's experimental! That's okay! We'll
figure the rest of the design in post.
Theoretically, I should make these actions `experimental.` as well, but
it seemed like since the only way to see these guys was via the
`experimental.showMarksOnScrollbar` setting, you've already broken
yourself into experimental jail, and you know what you're doing.
Things that won't work as expected:
* resizing, ESPECIALLY reflowing
* Clearing the buffer with ED sequences / Clear Buffer
I could theoretically add velocity around this in the `TermControl`
layer. Always prevent marks from being visible, ignore all the actions.
Marks could still be set by VT and automark, but they'd be useless.
Next up priorities:
* Making this work with the FinalTerm sequences
* properly speccing
* adding support for `showMarksOnScrollbar: flags(categories)`, so you
can only display errors on the scrollbar
* adding the `category` flag to the `addMark` action
## Validation Steps Performed
I like using it quite a bit. The marks can get noisy if you have them
emitted on every prompt and the buffer has 9000 lines. But that's the
beautiful thing, the actions work even if the marks aren't visible, so
you can still scroll between prompts.
<details>
<summary>Settings blob</summary>
```jsonc
// actions
{ "keys": "ctrl+up", "command": { "action": "scrollToMark", "direction": "previous" }, "name": "Previous mark" },
{ "keys": "ctrl+down", "command": { "action": "scrollToMark", "direction": "next" }, "name": "Next mark" },
{ "keys": "ctrl+pgup", "command": { "action": "scrollToMark", "direction": "first" }, "name": "First mark" },
{ "keys": "ctrl+pgdn", "command": { "action": "scrollToMark", "direction": "last" }, "name": "Last mark" },
{ "command": { "action": "addMark" } },
{ "command": { "action": "addMark", "color": "#ff00ff" } },
{ "command": { "action": "addMark", "color": "#0000ff" } },
{ "command": { "action": "clearAllMarks" } },
// profiles.defaults
"experimental.autoMarkPrompts": true,
"experimental.showMarksOnScrollbar": true,
```
</details>
ed27737 contains a regression where (pseudocode)
```c
unsigned long ulActualDelta;
short ScreenInfo.WheelDelta;
delta *= (ScreenInfo.WheelDelta / (short)ulActualDelta);
// ^^^^^^^
```
was changed to
```c
delta *= (ScreenInfo.WheelDelta / ulActualDelta);
```
Due to `ulActualDelta` being unsigned, the new code casts the signed integer
to a unsigned one first, before doing the division. This causes scrolling
downwards (`WheelDelta` is negative) to appear as a large positive `delta`.
## PR Checklist
* [x] Closes#13253
* [x] I work here
## Validation Steps Performed
* Scrolling up/down works in OpenConsole again ✅
When #13160 introduced a new interface to the IConsoleHandoff idl, it
changed midl's RPC proxy stub lookup algorithm from a direct GUID
comparison to an unrolled binary search. Now, that would ordinarily not
be a problem...
However, in #11610, we took a shortcut and replaced `memcmp` -- used
only by RPC for GUID comparison -- with a direct GUID-only equality
comparator. This worked totally fine, and ordinarily would not be a
problem...
The unrolled binary search unfortunately _relies on memcmp's contract_:
it uses memcmp to match against a fully sorted set. Our memcmp only
returned 0 or 1 (equal or not), and it knew nothing about ordering.
When a package that contains a PackagedCOM proxy stub is installed, it
is selected as the primary proxy stub for any interfaces it can proxy.
After all, interfaces are immutable, so it doesn't matter whose proxy
you're using. Now, given that we installed a *broken* proxy... *all*
IIDs that got whacked by our memcmp issue broke for every consumer.
To fix it: instead of implementing memcmp ourselves, we're just going to
take a page out of WinAppSDK's book and link this binary using the
"Hybrid CRT" model. It will statically link any parts of the STL it uses
(none) and dynamically link the ucrt (which is guaranteed to be present
on Windows.)
Sure, the binary size goes up from 8k to 24k, but... the cost is never
having to worry about this again.
Closes#13251
## Summary of the Pull Request
When a profile gets deleted, we were navigating to the next item assuming it was a profile when it may not be. This commit fixes this by checking the tag of the next menu item before we navigate to it.
## PR Checklist
* [x] Closes#13125
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [x] I work here
## Validation Steps Performed
Deleting the last profile in the SUI doesn't cause a crash
If we want to make Windows Terminal the default terminal under Windows,
we'll have to make conhost "handoff" incoming connections by default.
But this poses a problem: How can the seldomly updated conhost know
whether the routinely updated Windows Terminal version is actually willing
to accept such handoffs by default (it might be unwilling due to bugs, etc.)?
This commit solves the issue by introducing:
* A marker interface (`IDefaultTerminalMarker`): If it exists,
Windows Terminal indicates its willingness to accept the handoff.
* Turning the all-0 GUID from being synonymous for conhost,
to being synonymous for "Let Windows decide". Without this we wouldn't
be able to differentiate between users who consciously chose conhost
as their default terminal, vs. users who want the standard behavior.
Testing fallback behavior:
* Install "Terminal" 1.13
* Delete the 2 keys below `HKCU\Console\%%Startup`
* Enable `Feature_AttemptHandoff` in `features.xml`
Return `true` from `DefaultApp::CheckShouldTerminalBeDefault`
* Replace `conhost.exe` and `console.dll` with `sfpcopy` after building
* Launching `cmd.exe` launches as a conhost window ✅
(because "Terminal" 1.13 lacks the marker interface)
* Open properties page in `conhost.exe`
"Let Windows decide" is select by default ✅
* Changing the selection writes the new value ✅
Testing the new behavior:
* Delete the 2 keys below `HKCU\Console\%%Startup`
* Enable `Feature_AttemptHandoff` in `features.xml`
Return `true` from `DefaultApp::CheckShouldTerminalBeDefault`
* Use `CLSID_WindowsTerminalConsoleDev` and `CLSID_WindowsTerminalTerminalDev`
for the initialization of `TerminalDelegationPair`
* Replace `conhost.exe` and `console.dll` with `sfpcopy` after building
* Deploy the "Terminal Dev" package
* Launching `cmd.exe` launches "Terminal Dev" ✅
(because "Terminal Dev" has the marker interface)
* Open the settings tab
"Let Windows decide" is select by default ✅
* Changing the selection and saving writes the new value ✅
(cherry picked from commit 1b81c6540f)
Service-Card-Id: 82925080
Service-Version: Inbox
If we want to make Windows Terminal the default terminal under Windows,
we'll have to make conhost "handoff" incoming connections by default.
But this poses a problem: How can the seldomly updated conhost know
whether the routinely updated Windows Terminal version is actually willing
to accept such handoffs by default (it might be unwilling due to bugs, etc.)?
This commit solves the issue by introducing:
* A marker interface (`IDefaultTerminalMarker`): If it exists,
Windows Terminal indicates its willingness to accept the handoff.
* Turning the all-0 GUID from being synonymous for conhost,
to being synonymous for "Let Windows decide". Without this we wouldn't
be able to differentiate between users who consciously chose conhost
as their default terminal, vs. users who want the standard behavior.
## Validation Steps Performed
Testing fallback behavior:
* Install "Terminal" 1.13
* Delete the 2 keys below `HKCU\Console\%%Startup`
* Enable `Feature_AttemptHandoff` in `features.xml`
Return `true` from `DefaultApp::CheckShouldTerminalBeDefault`
* Replace `conhost.exe` and `console.dll` with `sfpcopy` after building
* Launching `cmd.exe` launches as a conhost window ✅
(because "Terminal" 1.13 lacks the marker interface)
* Open properties page in `conhost.exe`
"Let Windows decide" is select by default ✅
* Changing the selection writes the new value ✅
Testing the new behavior:
* Delete the 2 keys below `HKCU\Console\%%Startup`
* Enable `Feature_AttemptHandoff` in `features.xml`
Return `true` from `DefaultApp::CheckShouldTerminalBeDefault`
* Use `CLSID_WindowsTerminalConsoleDev` and `CLSID_WindowsTerminalTerminalDev`
for the initialization of `TerminalDelegationPair`
* Replace `conhost.exe` and `console.dll` with `sfpcopy` after building
* Deploy the "Terminal Dev" package
* Launching `cmd.exe` launches "Terminal Dev" ✅
(because "Terminal Dev" has the marker interface)
* Open the settings tab
"Let Windows decide" is select by default ✅
* Changing the selection and saving writes the new value ✅
## Summary of the Pull Request
This introduced the `toggleBlockSelection` action to allow users to create a block selection using only the keyboard. This is not bound to any keys by default, however it is added to the command palette.
## References
#4993 - Epic
#5804 - Spec
## Validation Steps Performed
- [X] Mark mode always starts in line selection mode
- [X] Mouse selections are always in line selection mode by default
- [X] Can toggle block selection for an existing selection (regardless of how it was created)
- [X] The selection is copied properly (aka, no rendering issues)
Previously this project used a great variety of types to present text buffer
coordinates: `short`, `unsigned short`, `int`, `unsigned int`, `size_t`,
`ptrdiff_t`, `COORD`/`SMALL_RECT` (aka `short`), and more.
This massive commit migrates almost all use of those types over to the
centralized types `til::point`/`size`/`rect`/`inclusive_rect` and their
underlying type `til::CoordType` (aka `int32_t`).
Due to the size of the changeset and statistics I expect it to contain bugs.
The biggest risk I see is that some code potentially, maybe implicitly, expected
arithmetic to be mod 2^16 and that this code now allows it to be mod 2^32.
Any narrowing into `short` later on would then throw exceptions.
## PR Checklist
* [x] Closes#4015
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
Casual usage of OpenConsole and Windows Terminal. ✅
This PR introduces the framework for the `DECRSTS` sequence which is
used to restore terminal state reports. But to start with, I've just
implemented the `DECCTR` color table report, which provides a way for
applications to alter the terminal's color scheme.
## PR Checklist
* [x] Closes#13132
* [x] CLA signed.
* [x] Tests added/passed
* [ ] Documentation updated.
* [ ] Schema updated.
* [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx
## Detailed Description of the Pull Request / Additional comments
I've added the functions for parsing DEC RGB and HLS color formats into
the `Utils` class, where we've got all our other color parsing routines,
since this functionality will eventually be needed in other VT protocols
like Sixel and ReGIS.
Since `DECRSTS` is a `DCS` sequence, this only works in conhost for now,
or when using the experimental passthrough mode in Windows Terminal.
## Validation Steps Performed
I've added a number of unit tests to check that the `DECCTR` report is
being interpreted as expected. This includes various edge cases (e.g.
omitted and out-of-range parameters), which I have confirmed to match
the color parsing on a real VT240 terminal.
## Summary of the Pull Request
The `DECPS` (Play Sound) escape sequence provides applications with a
way to play a basic sequence of musical notes. This emulates
functionality that was originally supported on the DEC VT520 and VT525
hardware terminals.
## PR Checklist
* [x] Closes#8687
* [x] CLA signed.
* [ ] Tests added/passed
* [ ] Documentation updated.
* [ ] Schema updated.
* [x] I've discussed this with core contributors already. Issue number
where discussion took place: #8687
## Detailed Description of the Pull Request / Additional comments
When a `DECPS` control is executed, any further output is blocked until
all the notes have finished playing. So to prevent the UI from hanging
during this period, we have to temporarily release the console/terminal
lock, and then reacquire it before returning.
The problem we then have is how to deal with the terminal being closed
during that unlocked interval. The way I've dealt with that is with a
promise that is set to indicate a shutdown. This immediately aborts any
sound that is in progress, but also signals the thread that it needs to
exit as soon as possible.
The thread exit is achieved by throwing a custom exception which is
recognised by the state machine and rethrown instead of being logged.
This gets it all the way up to the root of the write operation, so it
won't attempt to process anything further output that might still be
buffered.
## Validation Steps Performed
Thanks to the testing done by @jerch on a real VT525 terminal, we have a
good idea of how this sequence is supposed to work, and I'm fairly
confident that our implementation is reasonably compatible.
The only significant difference I'm aware of is that we support multiple
notes in a sequence. That was a feature that was documented in the
VT520/VT525 manual, but didn't appear to be supported on the actual
device.
MSFT-33471786 is one of the most common crashes we have right now.
Memory dumps suggest that `VtEngine::UpdateViewport` is called with a rectangle
like `(0, 46, 119, 29)` (left, top, right, bottom), which is a rectangle of
negative height. When the `_invalidMap` is resized the negative size gets
turned into a very large unsigned integer, which results in an OOM exception,
crashing OpenConsole.
`VtEngine::UpdateViewport` is called by `Renderer::_CheckViewportAndScroll`
which holds a (cached) old and a new viewport. The old viewport was
`(0, 46, 119, 75)` which is exceedingly similar to the invalid, new viewport.
It's bottom coordinate is also coincidentally larger by exactly 46 (top).
The viewport comes from the `SCREEN_INFORMATION` class whose `SetViewport`
function was highly suspicious as it has a branch which updates the bottom
to be the buffer height, but leaves the top unmodified.
`SCREEN_INFORMATION::SetViewport` is called by `SetConsoleWindowInfo` which
processes user-provided data. A repro of the crash can be constructed with:
```
SMALL_RECT rect{0, 46, 119, 75};
SetConsoleWindowInfo(GetStdHandle(STD_OUTPUT_HANDLE), TRUE, &rect);
```
Closes#13193
Closes MSFT-33471786
## Validation Steps Performed
Ensured the following code doesn't crash when run under Windows Terminal:
```
SMALL_RECT rect{0, 46, 119, 75};
SetConsoleWindowInfo(GetStdHandle(STD_OUTPUT_HANDLE), TRUE, &rect);
```
This commit hides the "Open in Terminal" context menu option when the
context menu is opened in a non-filesystem path like "Quick Actions".
Closes#12578
This is a big hammer to put out this fire. We're keeping the hiding around for now, cause we think that's likely the one that the internal tests use that we really care about here. If we need to bring this back, we can.
* [x] Closes#13158
* [x] Closes#13162
* [x] Validated these both manually
* [x] `[Native]::ShowWindow([Native]::GetConsoleWindow(), 6)` still works
Prevents a null pointer dereference when attempting to split a settings tab, due to it not being a terminal tab.
* [x] Closes#13166
## Validation Steps Performed
Manually tested.
This only impacts the UI. We can take a workitem to rename the loc data
later. When the user specifies zh-Hans/zh-Hant, the resource mapper does
the right thing.
Related to #8984
Use a throttled update to update 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. "Should" is doing a lot of work in this sentence.
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 desync'd.
I think we're overall not super confident that this fixes the root causes of the issue. Rather, we're hopeful that a small amount of throttling here should leave time for the Terminal and pty to sync back up. We're comfortable enough with that as a bandaid for 1.14 preview, to see how this behaves in the wild.
ThemeResources are a persistent pain.
Regressed in #13083. See also #12775 et. al.
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, regarless of the requested theme. Kinda the same thing we've had to do with TabViewBackground in the past.
* [x] Fixes something we noticed right before shipping
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.
* [x] Closes#13143
* [x] I work here
* [x] validated manually:
- [x] showTabsInTitlebar: false, true
- [x] useAcrylicInTabRow: false, true
- [x] theme: light, dark
* [x] Need to check if this is regressed the same in 1.13. I suspect it is.
## Summary of the Pull Request
Introduces a non-configurable version of mark mode to Windows Terminal. It has the following interactions defined:
- <kbd>ctrl+shift+m</kbd> --> Enter Mark Mode
- when in Mark Mode...
- <kbd>ESC</kbd> --> Exit Mark Mode
- arrow keys --> move "start"
- <kbd>shift</kbd> + arrow keys --> anchor "start", move "end"
- <kbd>ctrl+a</kbd> --> select all
- when a selection is active...
When in mark mode, the cursor does not blink.
## References
#4993 - [Epic] Keyboard Selection
## PR Checklist
* [X] Closes#715
* [X] Provides a resolution for #11985
## Detailed Description of the Pull Request / Additional comments
- `TermControl`:
- `TermControl.cpp` just adds logic to prevent the cursor from blinking when in mark mode
- `ControlCore`
- in the same place we handle quick edit, we add an entry point to mark mode
- `TerminalCore`
- this leverages `UpdateSelection()` and other quick edit functions to make mark mode happen
## Validation Steps Performed
- [x] Make selection, split pane, close pane
- NOTE: A similar scenario caused a crash at one point. Really weird. Keep an eye on it.
- [x] Cursor is off when in mark mode
- [x] general movement/selection
- [x] general movement/selection that forces the viewport to move
- [x] In mark mode, selectAll...
- [x] arrow keys --> move start
- [x] shift + arrow keys --> move end
- [x] (regardless of mark mode) if selection active, enter --> copy to clipboard
Well this one feels dumb.
Make sure to also initially set the visibility of ConPTY windows created for DefTerm connections.
* [x] Closes#13066 for real.
* [x] tested manually.
A bad merge, that actually revealed a horrible bug.
There was a secret conflict between the code in #12526 and #12515. 69b77ca was a bad merge that hid just how bad the issue was. Fixing the one line `nullptr`->`this` in `InteractivityFactory` resulted in a window that would flash uncontrollably, as it minimized and restored itself in a loop. Great.
This can seemingly be fixed by making sure that the conpty window is initially created with the owner already set, rather than relying on a `SetParent` call in post. This does pose some complications for the #1256 future we're approaching. However, this is a blocking bug _now_, and we can figure out the tearout/`SetParent` thing in post.
* fixes#13066.
* Tested with the script in that issue.
* Window doesn't flash uncontrollably.
* `gci | ogv` still works right
* I work here.
* Opening a new tab doesn't spontaneously cause the window to minimize
* Restoring from minimized doesn't yeet focus to an invisible window
* Opening a new tab doesn't yeet focus to an invisible window
* There _is_ a viable way to call `GetAncestor` s.t. it returns the Terminal's hwnd in Terminal, and the console's in Conhost
The `SW_SHOWNOACTIVATE` change is also quite load bearing. With just `SW_NORMAL`, the pseudo window (which is invisible!) gets activated whenever the terminal window is restored from minimized. That's BAD.
There's actually more to this as well.
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.
Without `SetParent`, however, the pty HWND is no longer a descendant of the Terminal HWND, so that means `GA_ROOT` can no longer be used to find the owner's hwnd. For even more insanity, without `WS_POPUP`, none of the values of `GetAncestor` will actually get the terminal HWND. So, now we also need `WS_POPUP` on the pty hwnd. To get at the Terminal hwnd, you'll need
```c++
GetAncestor(GetConsoleWindow(), GA_ROOTOWNER)
```
This PR adds support for the VT line rendition attributes in the DirectX
renderer, which allows for double-width and double-height line
renditions.
Line renditions were first implemented in conhost (with the GDI
renderer) in PR #8664. Supporting them in the DX renderer now is a
small step towards #11595.
The DX implementation is very similar to the GDI one. When a particular
line rendition is requested, we create a transform that is applied to
the render target. And in the case of double-height renditions, we also
initialize some clipping offsets to allow for the fact that we only
render half of a line at a time.
One additional complication exists when drawing the cursor, which
requires a two part process where it first renders to a command list,
and then draw the command list in a second step. We need to temporarily
reset the transform in that first stage otherwise it ends up being
applied twice.
I've manually tested the renderer in conhost by setting the `UseDx`
registry entry and confirmed that it passes the _Vttest_ double-size
tests as well as several of my own tests. I've also checked that the
renderer can now handle horizontal scrolling, which is a feature we get
for free with the transforms.
## Summary of the Pull Request
When the conpty passthrough mode is enabled, it often needs to send `DSR-CPR` queries (cursor position reports) to the client terminal to obtain the current cursor position. However, the code that originally handled the responses to these queries got broken by the refactoring of the `ConGetSet` API. This PR is an attempt to correct that regression.
## References
The conpty passthrough mode was introduced in PR #11264.
The refactoring that broke the cursor position handling was in PR #12703.
## PR Checklist
* [x] Closes#13106
* [x] CLA signed.
* [ ] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx
## Detailed Description of the Pull Request / Additional comments
Prior to the `ConGetSet` refactoring, the code that handled `DSR-CPR` responses (`InteractDispatch::MoveCursor`) would pass the cursor position to `ConGetSet::SetCursorPosition`, which in turn would forward it to the `SetConsoleCursorPositionImpl` API, and from there to the `VtIo` class.
After the refactor, all of those intermediate steps were removed - the cursor was simply updated directly in `InteractDispatch::MoveCursor`, and the `VtIo` call was moved from `SetConsoleCursorPositionImpl` to `InteractDispatch` (since that was the only place it was actually required).
However, when the conpty passthrough mode was introduced - which happened in parallel - it relied on the `SetConsoleCursorPositionImpl` API being called from `InteractDispatch` in order to handle its own `DSR-CPR` responses, and that's why things stopped working when the two PRs merged.
So what I've done now is made `InteractDispatch::MoveCursor` method call `SetConsoleCursorPositionImpl` again (although without the intermediate `ConGetSet` overhead), and moved the `VtIo::SetCursorPosition` call back into `SetConsoleCursorPositionImpl`.
This is not ideal, and there are still a bunch of problems with the `DSR-CPR` handling in passthrough mode, but it's at least as good as it was before.
## Validation Steps Performed
I've just manually tested various shells with passthrough mode enabled, and confirmed that they're working better now. There are still issues, but nothing that wasn't already a problem in the initial implementation, at least as far as I can tell.
This regressed in ad2358d.
We're interested in the size of the viewport only, but it can shift up/down
during scrolling. In these situations we shouldn't resize our buffers of course.
## Validation Steps Performed
* Scroll
* Not setting `ApiInvalidations::Size` ✅
## Summary of the Pull Request
Add `Find` to tab context menu as describe in issue #5633.
## PR Checklist
* [x] Closes#5633
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
## Detailed Description of the Pull Request / Additional comments
Just wanted to solve `Easy Starter` issue, so any corrections/suggestions welcome. There's a couple of points I'm not sure of
* Placement of item within menu, currently it's at the end before close tab block.
* Should it be named longer, something like `Find in Tab` of just `Find` is fine?
* The workaround for focus similar to tab rename is a bit annoying, especially because it required adding a method to `TermControl` but without it find window obviously opens without focus which is bad.
## Validation Steps Performed
Open menu, press menu item try to find things via opened find dialog.
This commit includes various minor improvements to til::hash/point/size/rect
which accumulated while working on #4015.
* Allow xvalue containers and non-`size_t` indices in `til::at`.
* `til::as_unsigned` can be used to reinterpret a potentially signed integer
as a unsigned one. This can potentially enable some optimizations as no sign
extension is needed anymore. `til::hash` can make use of this to drop about
20% of the hashing of signed integers <= 32 bit. On x86 this translates to
a `mov` (virtually no latency) or no instructions at all, instead of
requiring a `movsx` (some latency) for sign extension.
* `til::point` operators that prefer mutability.
This is a opinionated change, but it follows the STL style beter and
generates less assembly.
* Simpler `rect` scale_up/down and `size` divide_ceil.
`scale_up` will not depend on the operator header anymore.
`scale_down` / `divide_ceil` can be implemented without checked numerics,
so I did. It also follows the related GdiEngine code better now, which
makes me confident that we can replace GdiEngine's code with this.
* Removal of rect-size-shift operators.
They were only used in DxEngine and confusing as they weren't commutative.
Adding and then subtracting a size from a rect (and vice versa) didn't do
what you'd intuitively think it'd do. The code was replaced with addition
and clamps in DxEngine.
* Various unsafe `as_` casts for point/size/rect.
This will aid the migration in #4015.
## Validation Steps Performed
* Vertical scrolling works in `DxEngine` ✅
This commit is one of the more difficult rewrites that were necessary as part
of #4015, but still simple enough that it can be done as a separate commit.
The search for the `lastNonSpace` was replaced with a simpler
`std::string_view::find_last_not_of`.
## Validation Steps Performed
ConPTY appears to work ✅
This reverts commit 14098d71f2.
## Summary of the Pull Request
@zadjii-msft found that this is causing persisted windows on a secondary monitor to shrink a little each time. We're choosing to revert this commit until that gets resolved.
## References
#12979
This commit fixes various bugs in our unit/feature test suite:
* 2 tests failed at 150% scale.
* The "null key" (@ on a US keyboard) isn't necessarily Shift+2.
The proper way to get it is with `LOBYTE(VkKeyScanW(0))`
* `InputEngineTest::C0Test` never worked as it overwrote
the loop variable, exiting the loop early
Fixes the following issues:
* `desktopWallpaper` not working
* switching tabs/panes causes the background to flicker
* settings preview having a transparent background
## PR Checklist
* [x] Closes#13002
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
Tested the 3 cases above. ✅
## Summary of the Pull Request
For some reason, the PGO tests (specifically the `RunMakeKillTabs` test) started to fail after #12979 merged. After closer inspection, the test was actually improperly written. We should be using <kbd>ctrl+shift+t</kbd> to open new tabs, not <kbd>alt+shift+t</kbd>. Presumably, the <kbd>alt</kbd> was copied over from the previous test, because they look _very_ similar.
So I went ahead and fixed the test, and it now (1) tests what it's intended to test and (2) doesn't fail. Why did #12979 cause the tests to fail? idk, but it works now.
## References
#10071 - Introduce PGO Tests
## Validation Steps Performed
Ran PGO tests locally and confirmed that it works.
Ran PGO pipeline and confirmed that it works.
When the buffer is resized with a reflow, we were previously calculating
the new virtual bottom based on the position of last non-space
character. If the viewport was largely blank when resized, this could
result in the new virtual bottom being higher than it should be.
This PR attempts to address that problem by restoring the virtual bottom
to a position that is the same distance from the cursor row as it was
prior to the resize.
This was a regression introduced in PR #12972.
We still take the last non-space row into account when determining the
virtual bottom, because if the content of the screen is forced to wrap,
the virtual bottom will need to be lower (relative to the cursor) than
it was before.
We also need to check that we don't overflow the bottom of the buffer,
which can occur when the viewport is at the bottom of the buffer, and
the cursor position is pushed down as a result of content wrapping above
it.
I've manually confirmed that this fixes the problem reported in issue
#13078, and I've also extended the existing `RefreshWithReflow` unit
test to cover that particular scenario.
Closes#13078
The `DECAC` (Assign Colors) escape sequence controls which color table
entries are associated with the default foreground and background
colors. This is how you would change the default colors on the the
original DEC VT525 terminals.
But `DECAC` also allows you to assign the color table entries for the
"window frame", which in our case is mapped to the tab color (just the
background for now). So this now gives us a way to control the tab color
via an escape sequence as well.
DETAILS
-------
The way this works is there are now two new entries in the color table
for the frame colors, and two new aliases in the color alias table that
are mapped to those color table entries. As previously mentioned, only
the background is used for now.
By default, the colors are set to `INVALID_COLOR`, which indicates that
the system colors should be used. But if the user has set a `tabColor`
property in their profile, the frame background will be initialized with
that value instead.
And note that some of the existing color table entries are now
renumbered for compatibility with XTerm, which uses entries 256 to 260
for special colors which we don't yet support. Our default colors are
now at 261 and 262, the frame colors are 263 and 264, and the cursor
color is 265.
So at runtime, you can change the tab color programmatically by setting
the color table entry at index 262 using `OSC 4` (assuming you need a
specific RGB value). Otherwise if you just want to set the tab color to
an existing color index, you can use `DECAC 2`.
You can even make the tab color automatically match background color by
mapping the frame background alias to the color table entry for the
default background, using `DECAC 2;261;262` (technically this is mapping
both the the foreground and background).
This PR doesn't include support for querying the color mapping with
`DECRQSS`, and doesn't support resetting the colors with `RIS`, but
hopefully those can be figured out in a future PR - there are some
complications that'll need to be resolved first.
## Validation Steps Performed
I've added a basic unit test that confirms the `DECAC` escape sequence
updates the color aliases in the render settings as expected. I've also
manually confirmed that the tab color in Windows Terminal is updated by
`DECAC 2`, and the default colors are updated in both conhost and WT
using `DECAC 1`.
Closes#6574
Fixes the SUI background being red in high contrast mode. The issue was
that `SolidBackgroundFillColorTertiary` purposefully has a bad High
Contrast color[^1].
The fix was to be explicit in the theme resources so that
`SolidBackgroundFillColorTertiary` is used in light and dark mode, but
the standard high contrast one is used in high contrast mode. Since the
page is the top-level XAML element in the Editor project, I had to
introduce this in the App.xaml resources so that the page can find the
theme resource.
Closes#13065Closes#13070
[^1]: 40df43a61c/dev/CommonStyles/Common_themeresources_any.xaml (L650-L651)
## Summary of the Pull Request
When calculating the position of the virtual bottom after a resize with
reflow, it was possible for it to end up less than the height of the
viewport. This meant that the top of the virtual viewport would be
negative, which resulted in other operations failing further down the
line. This PR updates the virtual bottom calculation to fix that
scenario.
## References
This was probably a regression introduced in PR #12972.
## PR Checklist
* [x] Closes#13034
* [x] CLA signed.
* [x] Tests added/passed
* [ ] Documentation updated.
* [ ] Schema updated.
* [x] I've discussed this with core contributors already. Issue number where discussion took place: #13034
## Validation Steps Performed
I wasn't able to replicate the exact case described in issue #13034,
because I don't have Windows 11, so can't configure the default
terminal. However, I was able to reproduce a similar failure using a
`SetConsoleScreenBufferInfoEx` call, and I've confirmed that this PR
has fixed that.
I've also added another screen buffer test to make sure the
`ResizeWithReflow` method doesn't shrink the virtual bottom when
resizing at the top of the buffer.
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~ just not show 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.
I 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.
* [x] Closes#11561
* [x] Tested manually
* [x] I work here.
* [x] Accidentally also closes#9053. By switching the initial call from `ShowWindow(SW_SHOW)` to `ShowWindow(SW_SHOWDEFAULT)`, we actually obey the startup info now.
Adds the `selectAll` action which can be used to select all text in the buffer (regardless of whether a selection is present).
## References
#3663 - Mark Mode
#4993 - [Scenario] Keyboard selection
## PR Checklist
* [x] Closes#1469
* [x] Tests added/passed
## Detailed Description of the Pull Request / Additional comments
I've made it such that selecting the "entire buffer" really just selects up to the mutable viewport. This seems like a nice QOL improvement since there's generally nothing past that.
When the user selects all, the viewport does not move. This is consistent with CMD behavior and is intended to allow the user to not lose context when selecting everything.
A minor change had to be made to the DxRenderer because this uncovered an underflow issue. Basically, the selection rects were handed to the DxEngine relative to the viewport (which means that some had a negative y-value). At some point, those rects were stored into `size_t`s, resulting in an underflow issue. This caused the renderer to behave strangely when rendering the selection. Generally, these kinds of issues weren't really noticed because selection would always modify a portion of the viewport.
Funny enough, in a way, this satisfies the "mark mode" scenario because the user now has a way to initiate a selection using only the keyboard. Though this isn't ideal, just a fun thing to point out (that's why I'm not closing the mark mode issue).
## Validation Steps Performed
- Verified using DxEngine and AtlasEngine
- select all --> keyboard selection --> start moving the top-left endpoint (and scroll to there)
- select all --> do not scroll automatically
Turns out if you add that Delete handler there, then every time you navigate to the profile, we'll add another Delete handler to the list of handlers. That's bad - that'll cause us to try and delete the profile multiple times.
The repro I had before was 100%, now it's fixed.
* [x] Closes#13017
`TextAttribute` and `TextColor` are commonly used structures in hot paths.
This commit replaces more complex comparisons where each field is compared
independently with a single call to `memcmp`. This compiles down to just
a few instructions. This reduces code and binary size and improves
performance for paths were `TextAttribute`s need to be compared.
## PR Checklist
* [x] Supports #10563
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [x] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx
## Validation Steps Performed
* termbench still works ✔️
Co-authored-by: Leonard Hecker <lhecker@microsoft.com>
## Summary of the Pull Request
As discussed in team sync. Ignore `newTab` actions with a profile index greater than the number of profiles.
## PR Checklist
* [x] Closes#11114
* [x] I work here
* [ ] Tests added/passed
* [ ] Requires documentation to be updated - maybe❓
In classic fashion, we never run the LocalTests locally before committing, so stuff breaks from time to time.
This time, the main trick was that the tests had a pretty hardcore dependency on the inner workings of `_PreviewActionHandler`, and when that changed, they broke.
Also, there was a weird crash I saw when I had the default terminal set to the Dev build version. That crash would let the test contents pass, but ultimately fail when TAEF tore down the conhost. Unsetting that fixed the crash 🤷Closes#12158
## Summary of the Pull Request
When `TerminalDispatch` was merged with `AdaptDispatch` in PR #13024,
that broke the Terminal's `EraseAll` operation in the alt buffer. The
problem was that the `EraseAll` implementation makes a call to
`SetViewportPosition` which wasn't taking the alt buffer into account,
and thus modified the main viewport instead.
This PR corrects that mistake. If we're in the alt buffer, the
`SetViewportPosition` method now does nothing, since the alt buffer
viewport should always be at 0,0.
## References
This was a regression introduced in PR #13024.
## PR Checklist
* [x] Closes#13038
* [x] CLA signed.
* [ ] Tests added/passed
* [ ] Documentation updated.
* [ ] Schema updated.
* [x] I've discussed this with core contributors already. Issue number where discussion took place: #13038
## Validation Steps Performed
I've confirmed that the test case reported in issue #13038 is no longer
failing. I've also made sure the `ED 2` and `ED 3` sequences are still
working correctly in the main buffer.
To quote an internal wiki:
> It generally provides improved footprint and performance over the
> existing default heap for native win32 applications.
It is apparently the default heap on ARM64, and for all UWPs.
This heap has different allocation and compaction characteristics.
I am not sure how it will impact terminal.
## Summary of the Pull Request
Make sure we set `Name` and `FullDescription` on expander-style settings in the SUI
## PR Checklist
* [x] Closes#13019
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [x] I work here
## Validation Steps Performed
Accessibility insights now shows the name/full description for the expander-style settings
## Summary of the Pull Request
This PR replaces the `TerminalDispatch` class with the `AdaptDispatch` class from conhost, so we're no longer duplicating the VT functionality in two places. It also gives us a more complete VT implementation on the Terminal side, so it should work better in pass-through mode.
## References
This is essentially part two of PR #12703.
## PR Checklist
* [x] Closes#3849
* [x] CLA signed.
* [ ] Tests added/passed
* [ ] Documentation updated.
* [ ] Schema updated.
* [x] I've discussed this with core contributors already. Issue number where discussion took place: #12662
## Detailed Description of the Pull Request / Additional comments
The first thing was to give the `ConGetSet` interface a new name, since it's now no longer specific to conhost. I went with `ITerminalApi`, since that was the equivalent interface on the terminal side, and it still seemed like a generic enough name. I also changed the way the api is managed by the `AdaptDispatch` class, so it's now stored as a reference rather than a `unique_ptr`, which more closely matches the way the `TerminalDispatch` class worked.
I then had to make sure that `AdaptDispatch` actually included all of the functionality currently in `TerminalDispatch`. That meant copying across the code for bracketed paste mode, the copy to clipboard operation, and the various ConEmu OSC operations. This also required a few new methods to the `ConGetSet`/`ITerminalApi` interface, but for now these are just stubs in conhost.
Then there were a few thing in the api interface that needed cleaning up. The `ReparentWindow` method doesn't belong there, so I've moved that into `PtySignalInputThread` class. And the `WriteInput` method was too low-level for the Terminal requirements, so I've replaced that with a `ReturnResponse` method which takes a `wstring_view`.
It was then a matter of getting the `Terminal` class to implement all the methods in the new `ITerminalApi` interface that it didn't already have. This was mostly mapping to existing functionality, but there are still a number of methods that I've had to leave as stubs for now. However, what we have is still good enough that I could then nuke the `TerminalDispatch` class from the Terminal code and replace it with `AdaptDispatch`.
One oddity that came up in testing, though, was the `AdaptDispatch` implementation of `EraseAll` would push a blank line into the scrollback when called on an empty buffer, whereas the previous terminal implementation did not. That caused problems for the conpty connection, because one of the first things it does on startup is send an `ED 2` sequence. I've now updated the `AdaptDispatch` implementation to match the behavior of the terminal implementation in that regard.
Another problem was that the terminal implementation of the color table commands had special handling for the background color to notify the application window that it needed to repaint the background. I didn't want to have to push the color table operations through the `ITerminalApi` interface, so I've instead moved the handling of the background update into the renderer, initiated by a flag on the `TriggerRefreshAll` method.
## Validation Steps Performed
Surprisingly this PR didn't require a lot of changes to get the unit tests working again. There were just a few methods used from the original `ITerminalApi` that have now been removed, and which needed an equivalent replacement. Also the updated behavior of the `EraseAll` method in conhost resulted in a change to the expected cursor position in one of the screen buffer tests.
In terms of manual testing, I've tried out all the different shells in Windows Terminal to make sure there wasn't anything obviously wrong. And I've run a bunch of the tests from _vttest_ to try and get a wider coverage of the VT functionality, and confirmed everything still works at least as well as it used to. I've also run some of my own tests to verify the operations that had to be copied from `TerminalDispatch` to `AdaptDispatch`.
`InteractivityOneCore` and `RendererWddmCon` were the last two remaining
projects which are relevant for our internal console builds, but couldn't be
easily compiled publicly by users on GitHub. This commit adds all definitions
required to compile the two projects into dysfunctional libraries at least.
(Since the added definitions are deliberately incorrect.)
Additionally this commit fixes the AuditMode build for the two projects.
## Validation Steps Performed
The two new projects compile fine.
As noted in the issue. There's a case where backing up the `lineEnd` can result in the `lineEnd` pointing at exactly the `lineBegin`, which results in an empty view, which causes all sorts of pain later.
Instead, just return early in this case.
* tested with an 80x24 conhost
* tested with an 79x24 conhost
I also tried making this a FAILFAST or a THROW_HR, but the failfast immediately died (of course it did), and the throw would result in a few frames where the composition was just... entirely not displayed? Probably not what we wanted.
* [x] Closes#12730
Modified the scope of input control, it used to be `Text`, now it is
`AlphanumericHalfWidth`. This input scope actually accepts any
characters, but English characters are preferred, and the soft keyboard
also displays English by default.
This should improve user friendliness for users using composition mode
input methods.
As a user who uses the composition mode input method, in applications
like windows terminal that should usually be input in English, it is
always required to manually switch to English mode by pressing Shift
before entering commands.
One keystroke is not a problem, but often for some reason there is no or
no successful switching, and additional more keystrokes are required to
clear the wrong input.
The input method that comes with windows will automatically switch to
English mode for a few programs such as conhost, but windows terminal is
not in this list.
This change should have no negative impact. Even if someone does tend to
use a shell oriented towards composition characters or non-alpha
letters, there should also were more users who in the same language are
more inclined to English characters shells, for example, cmd,
powershell, bash that comes with windows.
If there's any reason to have to keep the Text inputScope, maybe making
this setting customizable via `settings.json` would be a good idea, but
I don't see the need to do this, `AlphanumericHalfWidth` is perfect.
Closes#12731
`_api.cellCount` caches the `TextBuffer` size in AtlasEngine.
Calculating it based on the `_api.sizeInPixel` is incorrect as the
`TextBuffer` size doesn't necessarily have to be the size of the window.
This can occur when the window is resized, as the main thread is receiving its
`WM_SIZE` message and resizing the `TextBuffer` concurrently with the render
thread performing a render pass and AtlasEngine checking the `GetClientRect`.
In order to inform `AtlasEngine` about the initial buffer size, `Renderer`
was modified to also invoke `UpdateViewport()` on the first render cycle.
The only other user of `UpdateViewport()` is `VtEngine` which used to call
`InvalidateAll()` in these situations. In order to prevent the `InvalidateAll()`
call, `VtEngine::UpdateViewport()` was modified to suppress this.
## Validation Steps Performed
* Resizing wide characters doesn't crash the terminal anymore ✅
* The additional call to `UpdateViewport()` doesn't break VtEngine ✅
There are 3 en-dashes`(U+2013)` in the file when they should be hyphen `(U+002D)`.
This character causes the file to fail to compile in a non-utf8 encoding environment.
Just modified 3 characters to make it fall within the scope of ascii and keep it consistent with other files of the project.
The "virtual bottom" marks the last line of the mutable viewport area,
which is the part of the buffer that VT sequences can write to. This
region should typically only move downwards as new lines are added to
the buffer, but there were a number of cases where it was incorrectly
being moved up, or moved down further than necessary. This PR attempts
to fix that.
There was an earlier, unsuccessful attempt to fix this in PR #9770 which
was later reverted (issue #9872 was the reason it had to be reverted).
PRs #2666, #2705, and #5317 were fixes for related virtual viewport
problems, some of which have either been extended or superseded by this
PR.
`SetConsoleCursorPositionImpl` is one of the cases that actually does
need to move the virtual viewport upwards sometimes, in particular when
the cmd shell resets the buffer with a `CLS` command. But when this
operation "snaps" the viewport to the location of the cursor, it needs
to use the virtual viewport as the frame of reference. This was
partially addressed by PR #2705, but that only applied in
terminal-scrolling mode, so I've now applied that fix regardless of the
mode.
`SetViewportOrigin` takes a flag which determines whether it will also
move the virtual bottom to match the visible viewport. In some case this
is appropriate (`SetConsoleCursorPositionImpl` being one example), but
in other cases (e.g. when panning the viewport downwards in the
`AdjustCursorPosition` function), it should only be allowed to move
downwards. We can't just not set the update flag in those cases, because
that also determines whether or not the viewport would be clamped, and
we don't want change that. So what I've done is limit
`SetViewportOrigin` to only move the virtual bottom downwards, and added
an explicit `UpdateBottom` call in those places that may also require
upward movement.
`ResizeWindow` in the `ConhostInternalGetSet` class has a similar
problem to `SetConsoleCursorPositionImpl`, in that it's updating the
viewport to account for the new size, but if that visible viewport is
scrolled back or forward, it would end up placing the virtual viewport
in the wrong place. So again the solution here was to use the virtual
viewport as the frame of reference for the position. However, if the
viewport is being shrunk, this can still result in the cursor falling
below the bottom, so we need an additional check to adjust for that.
This can't be applied in pty mode, though, because that would break the
conpty resizing operation.
`_InternalSetViewportSize` comes into play when resizing the window
manually, and again the viewport after the resize can end up truncating
the virtual bottom if not handled correctly. This was partially
addressed in the original code by clamping the new viewport above the
virtual bottom under certain conditions, and only in terminal scrolling
mode. I've replaced that with a new algorithm which links the virtual
bottom to the visible viewport bottom if the two intersect, but
otherwise leaves it unchanged. This applies regardless of the scrolling
mode.
`ResizeWithReflow` is another sizing operation that can affect the
virtual bottom. This occurs when a change of the window width requires
the buffer to be reflowed, and we need to reposition the viewport in the
newly generated buffer. Previously we were just setting the virtual
bottom to align with the new visible viewport, but that could easily
result in the buffer truncation if the visible viewport was scrolled
back at the time. We now set the virtual bottom to the last non-space
row, or the cursor row (whichever is larger). There'll be edge cases
where this is probably not ideal, but it should still work reasonably
well.
`MakeCursorVisible` was another case where the virtual bottom was being
updated (when requested with a flag) via a `SetViewportOrigin` call.
When I checked all the places it was used, though, none of them actually
required that behavior, and doing so could result in the virtual bottom
being incorrectly positioned, even after `SetViewportOrigin` was limited
to moving the virtual bottom downwards. So I've now made it so that
`MakeCursorVisible` never updates the virtual bottom.
`SelectAll` in the `Selection` class was a similar case. It was calling
`SetViewportOrigin` with the `updateBottom` flag set when that really
wasn't necessary and could result in the virtual bottom being
incorrectly set. I've changed the flag to false now.
## Validation Steps Performed
I've manually confirmed that the test cases in issue #9754 are working
now, except for the one involving margins, which is bigger problem with
`AdjustCursorPosition` which will need to be addressed separately.
I've also double checked the test cases from several other virtual
bottom issues (#1206, #1222, #5302, and #9872), and confirmed that
they're still working correctly with these changes.
And I've added a few screen buffer tests in which I've tried to cover as
many of the problematic code paths as possible.
Closes#9754
## Summary of the Pull Request
Ensures the tab close button color matches the text color.
## PR Checklist
* [x] Closes#13010
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx
## Detailed Description of the Pull Request / Additional comments
Also re-ordered and aligned the properties cleared in the `_ClearTabBackgroundColor()` method to match `_ApplyTabColor()`.
## Validation Steps Performed
Manually tested
This pull request introduces a packaging phase that emits
Microsoft.Windows.Console.ConPTY, a nuget package that contains the
pseudoconsole API as well as the requisite copies of conhost.
* winconpty learned to load a version of OpenConsole.exe specific to the
processor architecture on its hosting machine
* the package, as well as its contents, is signed properly and is nearly
ready for distribution via nuget.org
* the API in conpty-static.h has been adjusted to expose
CreatePseudoConsoleAsUser and stamp out the correct DLL import/export
annotations.
* getting .NET to play right was somewhat challenging, but I tested this
against .NET 6.0 and it seemed to work properly; it shipped conpty.dll
in the right places, and it shipped OpenConsole.exe next to the
published application.
In the future, we could provide an interop assembly for C# consumers;
that is, unfortunately, out of scope today.
Closes#3577Closes#3568
Obsoletes #1130
Propagate show/hide window calls against the ConPTY pseudo window to the Terminal
## PR Checklist
* [x] Closes#12570
* [x] I work here
* [x] Manual Tests passed
* [x] Spec Link: →[Doc Link](https://github.com/microsoft/terminal/blob/dev/miniksa/msgs/doc/specs/%2312570%20-%20Show%20Hide%20operations%20on%20GetConsoleWindow%20via%20PTY.md)←
## Detailed Description of the Pull Request / Additional comments
- See the spec. It's pretty much everything I went through deciding on this.
## Validation Steps Performed
- [x] Manual validation against scratch application calling all of the `::ShowWindow` commands against the pseudo console "fake window" and observing the real terminal window state
If we are building a branch called "release-*", we will also change the
NuGet suffix to "preview". If we don't do that, XES will set the suffix
to "release1" because it truncates the value after the first period. In
general, though, we want to disable the suffix entirely if we're Release
branded while on a release branch.
In effect:
BRANCH / BRANDING | Release | Preview
------------------|------------------------|------------------------
release-* | 1.12.20220427 | 1.13.20220427-preview
all others | 1.14.20220427-mybranch | 1.14.20220427-mybranch
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
## Summary of the Pull Request
Fixes#6028
Setting is "experimental.useBackgroundImageForWindow"
<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? -->
## References
https://github.com/microsoft/terminal/issues/6028
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [X] Closes#6028
* [X] CLA signed.
* [ ] Tests added/passed
* [ ] Documentation updated. I read CONTRIBUTING.md, but I'm not sure if a spec is needed for an experimental feature such as this one.
* [ ] Schema updated. I added a JSON key, not sure where I need to update it.
* [X] I've discussed this with core contributors already. Somewhat discussed in https://github.com/microsoft/terminal/issues/6028
<!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here
## Detailed Description of the Pull Request / Additional comments -->
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Set ` "experimental.useBackgroundImageForWindow": true` and a bg image for one profile, then make splits and tabs and make sure the bg updates accordingly:

I also did the same with the setting off to make sure it still works correctly and didn't break. And I made sure opening the settings tab does not crash or show the bg image.
#4015 requires sweeping changes in order to allow a migration of our buffer
coordinates from `int16_t` to `int32_t`. This commit reduces the size of
future commits by using type inference wherever possible, dropping the
need to manually adjust types throughout the project later.
As an added bonus this commit standardizes the alignment of cv qualifiers
to be always left of the type (e.g. `const T&` instead of `T const&`).
The migration to type inference with `auto` was mostly done
using JetBrains Resharper with some manual intervention and the
standardization of cv qualifier alignment using clang-format 14.
## References
This is preparation work for #4015.
## Validation Steps Performed
* Tests pass ✅
Fixed various small issues:
* Made TabView bottom border span the entire window width
* Made ScrollBar inner thumb rounded again
* Made SplitButton look more like the new add tab button
* Adjusted rename box height (24px, like the official compact sizing height)
* Adjusted caption button colors to match Windows 11
* ColorPicker can now escape window bounds
* Tweaked ColorPicker buttons
Further builds on #12799. #12799 assumes that the connection is prepared to receive FocusIn/FocusOut events as input. For ConPTY we can be relatively sure of that, but that's not _technically_ correct. In the hypothetical world where the connection is not a ConPTY connection, then the other side might not be expecting those sequences.
This remedies the issue by
* ConPTY will always request focus event mode (from the terminal) when it starts up
* when a client tries to disable focus events in conpty, conpty is gonna note that internally, but never transmit that to the hosting terminal, to leave the terminal in focus event mode.
* `TerminalDispatch` and `ControlCore` are hooked up now to only send focus events when the Terminal is in focus event mode (which will be always for conpty)
* At this point, it was like, 4LOC in `terminalInput.cpp` to add support for focus events to conhost as well.
## checklist
* [x] closes#11682
* This combined with #12515 will finally close out #2988 as well, but we can do that manually.
* [x] I work here
* [ ] There aren't tests for this. There probably should be.
This commit replaces our use of `size_t` to represent VT parameters with
`int32_t`. While unsigned integers have the inherent benefit of being less
ambiguous and enjoying two's complement, our buffer coordinates use signed
integers. Since a number of VT functions need to convert their parameters
to coordinates, this commit makes the conversion easier.
The benefit of this change becomes even more apparent if one considers
that a number of places performed unsafe conversions
of their size_t parameters to int or short already.
Files that had to be modified were converted to use til
wrappers instead of COORD or SMALL_RECT wherever possible.
## References
This commit contains about 20% of the work for #4015.
## PR Checklist
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
I'm mostly relying on our unit tests here. Both OpenConsole and WT appear to work fine.
#### ⚠️ _Targets #12799_ ⚠️
This is an atomic bit of code that partners with #12799. It's separated as an individual PR to keep diffs more simple.
This ensures that when a terminal tells ConPTY that it's focused, that ConPTY doesn't do the `ConsoleControl(CONSOLE_FOREGROUND` thing unless the terminal application is actually in the foreground. This prevents a trivial exploit whereby a `malicious.exe` could create a PTY, tell ConPTY it has focus (when it doesn't), then use this mechanism to launch an instance of itself into the foreground.
When the terminal tells us it's in the foreground, we're gonna look at the owner of the ConPTY window handle. If that owner has focus, then cool, this is allowed. Otherwise, we won't grant them the FG right. For this to work, the terminal just have already called `ReparentPseudoConsole`.
* built on top of #12799 and #12526
* [x] Part of #2988
* [x] Tested manually.
## Window shenanigans, part the third:
Hooks the Terminal's focus state up to the underlying ConPTY. This is LOAD BEARING for allowing windows created by console applications to bring themselves to the foreground.
We're using the [FocusIn/FocusOut](https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-FocusIn_FocusOut) sequences to communicate to ConPTY when a control gains/loses focus. Theoretically, other terminals could do this as well.
## References
#11682 tracks _real_ support for this sequence in Console & conpty. When we do that, we should consider even if a client application disables this mode, the Terminal & conpty should always request this from the hosting terminal (and just ignore internally to ConPTY).
See also #12515, #12526, which are the other two parts of this effort. This was tested with all three merged together, and they worked beautifully for all our scenarios. They are kept separate for ease of review.
## PR Checklist
* [x] This is prototype 3 for #2988
* [x] I work here
* [ ] Tests added/passed
* [n/a] Requires documentation to be updated
## Detailed Description of the Pull Request / Additional comments
This allows windows spawned by console processes to bring themselves to the foreground _when the console is focused_. (Historically, this is also called in the WndProc, when focus changes).
Notably, before this, ConPTY was _never_ focused, so windows could never bring themselves to the foreground when run from a ConPTY console. We're not blanket granting the SetForeground right to all console apps when run in ConPTY. It's the responsibility of the hosting terminal emulator to always tell ConPTY when a particular instance is focused.
## Validation Steps Performed
(gif below)
This will result in the deletion of the following directories from the OS tree, under `onecore/windows/core/console/open`:
* doc/
* src/tools/MonarchPeasantPackage/
* src/api-ms-win-core-synch-l1-2-0/
* src/tools/ansi-color/
* src/tools/ColorTool/
We have gotten some PoliCheck flags on `doc/` (thanks to Niksa.md), but also the OS build just doesn't need these folders 😄
(cherry picked from commit 27b63ad02a)
Service-Card-Id: 80783789
Service-Version: Inbox
This will result in the deletion of the following directories from the OS tree, under `onecore/windows/core/console/open`:
* doc/
* src/tools/MonarchPeasantPackage/
* src/api-ms-win-core-synch-l1-2-0/
* src/tools/ansi-color/
* src/tools/ColorTool/
We have gotten some PoliCheck flags on `doc/` (thanks to Niksa.md), but also the OS build just doesn't need these folders 😄
#12149 introduced a bug where `ClearCommandline()` is called on any user
profile containing the non-canonical strings "cmd.exe" or "powershell.exe"
in the "commandline" field. If you happen to have set the "commandline"
field in your `profiles.defaults`, this will cause these user profiles
to adopt the base layer command-line instead of the defaults layer one.
This commit fixes the issue, by checking the command-line after the call
to `ClearCommandline()` and ensuring it's the expected string.
Additionally this moves the migration logic to `SettingsLoader` as this allows
us to write the fixed settings to disk, if any fixed had to be applied.
## PR Checklist
* [x] Closes#12842
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* The modified unit test fails without these changes ✅
* The modified unit test succeeds with these changes ✅
* Setting `profiles.defaults.commandline` to "pwsh.exe" and setting
my "...\\powershell.exe" profile to use just "powershell.exe" as
the `commandline`, doesn't cause it to use "pwsh.exe" ✅
The fixed settings are written to settings.json ✅
This is exactly the same as #12855, save for one small difference:
```diff
diff --git a/build/pipelines/ci.yml b/build/pipelines/ci.yml
index e4e53e9b2..dc9040aeb 100644
--- a/build/pipelines/ci.yml
+++ b/build/pipelines/ci.yml
@@ -99,7 +99,6 @@ stages:
- stage: CodeIndexer
displayName: Github CodeNav Indexer
dependsOn: [Build_x64]
- condition: succeeded()
+ condition: and(succeeded(), not(eq(variables['Build.Reason'], 'PullRequest')))
jobs:
- template: ./templates/codenav-indexer.yml
- condition: not(eq(variables['Build.Reason'], 'PullRequest'))
```
Because the first ones failed with an error about a duplicate condition
And that hosed the whole CI
VTE only rewraps the contents of the (normal screen + its scrollback
buffer) on a resize event. It doesn't rewrap the contents of the
alternate screen. The alternate screen is used by applications which
repaint it after a resize event. So, it doesn't really matter. However,
in that short time window, after resizing the terminal but before the
application catches up, this prevents vertical lines
It was really hard to get a gif of this where it happened and was small
enough to upload to GH, but there is one in #12719.
There's something in this branch that fixes a scrolling issue in the
parent PR. I'm partially filing this so I can look at the diffs here and
try and figure out what that is. I kinda want to just take all 3 alt
buffer PRs as a single atomic unit, but splitting them up made sense
from a review standpoint.
Closes#3493
The original research for a solution all the way back in #11032 contained an
unfortunate flaw. The nearby font loading code was written under the assumption
that Cascadia is missing in the system font collection, leading to our issues.
Adding nearby fonts last into the collection would thus ensure that we use
the system fonts whenever possible, but only have nearby fonts as a fallback.
This didn't work and we figured that we'd have to always prefer loading nearby
fonts over system fonts. #12554 tried to achieve this, but failed to change
the order in which the font set is built. In order to prefer nearby fonts
over system ones, we have to add the system font collection last.
## PR Checklist
* [x] Closes#11648
* [x] I work here
* [x] Tests added/passed
* [x] Embarrassment for my incompetence
## Validation Steps Performed
* Put Jetbrains Mono into the AppX directory of the Debug build
* Jetbrains Mono shows up in the font selector and is useable
Additionally a more complex mini-test was built:
Using FontForge I've cloned arial.ttf and removed all characters except for
the letter "0". Afterwards I've build a custom font collection the same way
we do it in Terminal, extracted a `FontFace` named "Arial" and called
`IDWriteFont::HasCharacter` for the letter "1".
Loading the system font collection first results in `TRUE` and loading it last
results in `FALSE` (since my custom arial.ttf doesn't have the letter "1").
This confirms that we need to load the system font collection last.
We discussed this with the GitHub folks. It's pretty cool.
(Rich code nav) brings editor-level navigation capabilities into
GitHub.com for C++ and C# repos
If you want to try it out, you can go to github.dev for this repo.
If you haven't used github.dev before there are two steps to get setup:
1. In the settings file you'll need to enable Rich Code Nav. If you just
search for "rich", there'll be a checkbox to enable it.
2. Refresh the page and you should see a stacked papers icon in the task
bar at the bottom. Click on that and select "Latest Index". Then one
more refresh and you should be good to go with navigation in both C#
and C++ files!
This is an attempt to simplify the `ConGetSet` interface down to the
smallest set of methods necessary to support the `AdaptDispatch` class.
The idea is that it should then be easier to implement that interface in
Windows Terminal, so we can replace the `TerminalDispatch` class with
`AdaptDispatch`.
This is a continuation of the refactoring started in #12247, and a
significant step towards #3849.
## Detailed Description of the Pull Request / Additional comments
The general idea was to give the `AdaptDispatch` class direct access to
the high-level structures on which it needs to operate. Some of these
structures are now passed in when the class is constructed (the
`Renderer`, `RenderSettings`, and `TerminalInput`), and some are exposed
as new methods in `ConGetSet` (`GetStateMachine`, `GetTextBuffer`, and
`GetViewport`).
Many of the existing `ConhostInternalGetSet` methods could easily then
be reimplemented in `AdaptDispatch`, since they were often simply
forwarding to methods in one of the above structures. Some were a little
more complicated, though, and require further explanation.
* `GetConsoleScreenBufferInfoEx`: What we were typically using this for
was to obtain the viewport, although what we really wanted was the
virtual viewport, which is now accessible via the `GetViewport`
method. This was also used to obtain the cursor position and buffer
width, which we can now get via the `GetTextBuffer` method.
* `SetConsoleScreenBufferInfoEx`: This was only really used for the
`AdaptDispatch::SetColumns` implementation (for `DECCOLM` mode), and
that could be replaced with `ResizeWindow`. This is a slight change in
behaviour (it sizes the window rather than the buffer), but neither is
technically correct for `DECCOLM`, so I think it's good enough for
now, and at least it's consistent with the other VT sizing operations.
* `SetCursorPosition`: This could mostly be replaced with direct
manipulation of the `Cursor` object (accessible via the text buffer),
although again this is a slight change in behavior. The original code
would also have made a call to `ConsoleImeResizeCompStrView` (which I
don't think is applicable to VT movement), and would potentially have
moved the viewport (not essential for now, but could later be
supported by `DECHCCM`). It also called `VtIo::SetCursorPosition` to
handle cursor inheritance, but that should only apply to
`InteractDispatch`, so I've moved that to the
`InteractDispatch::MoveCursor` method.
* `ScrollRegion`: This has been replaced by two simple helper methods in
`AdaptDispatch` which better meet the VT requirements -
`_ScrollRectVertically` and `_ScrollRectHorizontally`. Unlike the
original `ScrollRegion` implementation, these don't generate
`EVENT_CONSOLE_UPDATE_SCROLL` events (see #12656 for more details).
* `FillRegion`: This has been replaced by the `_FillRect` helper method
in `AdaptDispatch`. It differs from the original `FillRegion` in that
it takes a rect rather than a start position and length, which gives
us more flexibility for future operations.
* `ReverseLineFeed`: This has been replaced with a somewhat refactored
reimplementation in `AdaptDispatch`, mostly using the
`_ScrollRectVertically` helper described above.
* `EraseAll`: This was previously handled by
`SCREEN_INFORMATION::VtEraseAll`, but has now been entirely
reimplemented in the `AdaptDispatch::_EraseAll` method.
* `DeleteLines`/`InsertLines`/`_modifyLines`: These have been replaced
by the `_InsertDeleteLineHelper` method in `AdaptDispatch`, which
mostly relies on the `_ScrollRectVertically` helper described above.
Finally there were a few methods that weren't actually needed in the
`ConGetSet` interface:
* `MoveToBottom`: This was really just a hack to get the virtual
viewport from `GetConsoleScreenBufferInfoEx`. We may still want
something like in the future (e.g. to support `DECVCCM` or #8879), but
I don't think it's essential for now.
* `SuppressResizeRepaint`: This was only needed in `InteractDispatch`
and `PtySignalInputThread`, and they could easily access the `VtIo`
object to implement it themselves.
* `ClearBuffer`: This was only used in `PtySignalInputThread`, and that
could easily access the buffer directly via the global console
information.
* `WriteControlInput`: This was only used in `InteractDispatch`, and
that could easily be replaced with a direct call to
`HandleGenericKeyEvent`.
As part of these changes, I've also refactored some of the existing
`AdaptDispatch` code:
* `_InsertDeleteHelper` (renamed `_InsertDeleteCharacterHelper`) is now
just a straightforward call to the new `_ScrollRectHorizontally`
helper.
* `EraseInDisplay` and `EraseInLine` have been implemented as a series
of `_FillRect` calls, so `_EraseSingleLineHelper` is no longer
required.
* `_EraseScrollback` is a essentially a special form of scrolling
operation, which mostly depends on the `TextBuffer::ScrollRows`
method, and with the filling now provided by the new `_FillRect`
helper.
* There are quite a few operations now in `AdaptDispatch` that are
affected by the scrolling margins, so I've pulled out the common
margin setup into a new `_GetVerticalMargins` helper method. This also
fixes some edge cases where margins could end up out of range.
## Validation Steps Performed
There were a number of unit tests that needed to be updated to work
around functions that have now been removed, but these substitutions
were fairly straightforward for the most part.
The adapter tests were a different story, though. In that case we were
explicitly testing how operations were passed through to the `ConGetSet`
interface, but with more than half those methods now gone, a significant
rewrite was required.
I've tried to retain the crux of the original tests, but we now have to
validate the state changes on the underlying data structures, where
before that state would have been tracked in the `TestGetSet` mock. And
in some cases we were testing what happened when a method failed, but
since that scenario is no longer possible, I've simply removed those
tests.
I've also tried to manually test all the affected operations to confirm
that they're still working as expected, both in vttest as well as my own
test scripts.
Closes#12662
"Alternate scroll mode" is a neat little mode where the app wants mouse wheel events to come through as arrow keypresses instead, when in the alternate buffer. Now that we've got support for the alt buffer in the Terminal, we can support this as well.
* [x] Closes https://github.com/microsoft/terminal/issues/3321
* [x] I work here
* [ ] Tests would be nice
Tested manually with
```bash
printf "\e[?1007h" ; man ps
```
## Window shenanigans, part the first:
This PR enables terminals to tell ConPTY what the owning window for the
pseudo window should be. This allows thigs like MessageBoxes created by
console applications to work. It also enables console apps to use
`GetAncestor(GetConsoleWindow(), GA_ROOT)` to get directly at the HWND
of the Terminal (but _don't please_).
This is tested with our internal partners and seems to work for their
scenario.
See #2988, #12799, #12515, #12570.
## PR Checklist
This is 1/3 of #2988.
This PR allows the Terminal to actually use the alt buffer
appropriately. Currently, we just render the alt buffer state into the
main buffer and that is wild. It means things like `vim` will let the
user scroll up to see the previous history (which it shouldn't).
Very first thing this PR does: updates the
`{Trigger|Invalidate}Circling` methods to instead be
`{Trigger|Invalidate}Flush(bool circling)`. We need this so that when an
app requests the alt buffer in conpty, we can immediately flush the
frame before asking the Terminal side to switch to the other buffer. The
`Circling` methods was a great place to do this, but we don't actually
want to set the circled flag in VtRenderer when that happens just for a
flush.
The Terminal's implementation is a little different than conhost's.
Conhost's implementation grew organically, so I had it straight up
create an entire new screen buffer for the alt buffer. The Terminal
doesn't need all that! All we need to do is have a separate `TextBuffer`
for the alt buffer contents. This makes other parts easier as well - we
don't really need to do anything with the `_mutableViewport` in the alt
buffer, because it's always in the same place. So, we can just leave it
alone and when we come back to the main buffer, there it is. Helper
methods have been updated to account for this.
* [x] Closes#381
* [x] Closes#3492
* #3686, #3082, #3321, #3493 are all good follow-ups here.
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
## Summary of the Pull Request
Specs for feature request "Theme-controlled color scheme switch".
<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? -->
## References
#4066
This is all of course, conjecture. This crash is totally wild and makes no sense at all. But, we're hoping that this fixes it. This should also make calls to the Monarch a little easier.
You may be asking yourself - why aren't I doing this for the Peasant too? Well, because the Peasant simply doesn't crash like the monarch does. I'm not gonna touch something that's not broken _during ask mode_.
References #12774. We can close the bug if it is verified fixed.
855e136 contains a regression which breaks buffer reflow if wide surrogate
characters are present. This happens because we made use of the
`TextBufferCellIterator` whose increment operator skips 2 cells for wide
characters. This created a "misalignment" in the reflow logic which was written
for cell-wise iteration. This commit fixes the issue, by reverting back to the
previous algorithm without iterators.
Closes#12837
Closes MSFT-38904421
## Validation Steps Performed
* Run ``pwsh -noprofile -command echo "`u{D83D}`u{DE43}"``
* Resizing conhost preserves all contents ✅
* Resizing Windows Terminal doesn't crash it ✅
* Added a test covering this issue ✅
(cherry picked from commit 10b9044120)
Service-Card-Id: 80340091
Service-Version: Inbox
855e136 contains a regression which breaks buffer reflow if wide surrogate
characters are present. This happens because we made use of the
`TextBufferCellIterator` whose increment operator skips 2 cells for wide
characters. This created a "misalignment" in the reflow logic which was written
for cell-wise iteration. This commit fixes the issue, by reverting back to the
previous algorithm without iterators.
Closes#12837
Closes MSFT-38904421
## Validation Steps Performed
* Run ``pwsh -noprofile -command echo "`u{D83D}`u{DE43}"``
* Resizing conhost preserves all contents ✅
* Resizing Windows Terminal doesn't crash it ✅
* Added a test covering this issue ✅
If we delete a scheme, and the next scheme we've loaded is an inbox one
that _can't_ be deleted, then we need to toss focus to something
sensible, rather than letting it fall out to the tab item.
When deleting a scheme and the next scheme _is_ deletable, this isn't an
issue, we'll already correctly focus the Delete button.
125e9c4790 focused the SelectionBackground
button, which is the _previous_ focusable control, rather than the
following one.
However, it seems even more useful for focus to ALWAYS land on the
scheme dropdown box. This forces Narrator to read the name of the newly
selected color scheme, which seemed more useful.
I'm waiting on feedback from a11y team to see if this solution is
acceptable.
* [x] Is for #11971
After switching to ControlsV2, it seems that
delay-loading a dialog causes the ContentDialog to be assigned a
Height equal to it's content size. If we DON'T assign the
ContentDialog a Row, I believe it's assigned Row 0 by default. So,
when the dialog gets opened, the dialog seemingly causes a giant
hole to appear in the body of the app.
Assigning all the dialogs to Row 2 (where the rest of the content
is) makes the "hole" appear in the same space as the rest of the
TabContent, fixing the issue.
Note that the actual content in a content dialog gets parented to
the PopupRoot, so it actually always appeared in the correct place, it's
just this weird hole that appeared in Row 0.
* [x] Closes#12775
* See also:
* #12202 was fixed by #12208
* #12447 was fixed by #12517
* [x] Tested manually
* [x] Reverts #12625
* [x] Reverts #12517
You'd think that if a key wasn't present in a ThemeDictionary, it'd fall back to the original value. You'd be wrong - if you provide a Light&dark version of a resource, but not the HighContrast version, the resource loader will fall back to the _Light_ value. Of course.
Before (left top), after (right bottom)

Closes MSFT:38264744
This is like, 2-4% of our crashes. Impossible to say for sure, but this _looks_ like it's the root cause. This is just another one of our `HandleCommandlineArgs` buckets, hopefully the last.
* [x] Hopefully should close out MSFT:38542548
* [ ] No I didn't write tests, impossible to test
* [x] it builds
Replaces all the `RadioButton` expanders with `ComboBox`es, which can have the options inline, as opposed to in the expander content. For example, here's a single commit with the changes for a single one of these settings: 745c77d03e
### Checklist
* [x] Closes#12648
* [x] Actually closes#9566 as well (by just removing all radio buttons)
* [x] I work here
* [x] Tested manually
* [x] I'd love @carlos-zamora to have an a11y pass at this, just to see if it's egregious or not.
### Before, after:

This commit fixes some formatting bugs by upgrading clang-format and ensures
that our code is again formatted the same way Visual Studio 2022 would do it.
This is a crazy idea Dustin and I had.
> we can't repro this at will. But we kinda have an idea of where the deref is. We don't know if the small patch (throw, and try again) will fix it. We're sure that the "just fall back to an isolated monarch" will work. I'd almost rather take a build testing the small patch first, to see if that works
> This might seem crazy
> in 1.12, isolated monarch. In 1.13, "small patch". In 1.14, we can wait and see
I can write more details in the morning. It's 5pm here so if we want this today, here it is.
@dhowett double check my velocity flag logic here. Should be always true for Release, and off for Dev, Preview.
* [x] closes#12774
On certain builds of Windows, when Terminal is set as the default it
will accumulate an unbounded amount of queued animations while the
screen is off and it is servicing window management for console
applications.
This results in Terminal hanging when left overnight, as it has millions
of animations to process.
The new call into TerminalThemeHelpers will tell our compositor to
automatically complete animations that are scheduled while the screen is
off.
Fixes MSFT-38506980
Before #12691, the msixbundle version was of the format YYYY.MM.DD.0.
After #12691, it became the same as the build of Terminal it contained.
This caused some trouble for _some_ systems: major version 1 is much,
much smaller than 2022.
Adding 3000 to the major version component, _only for the bundle_, gets
around this. Ugh.
Fixes#12816.
Adds the common nuget import to the Fuzz project so that it compiles.
## References
Broken in #12778, Issue identified by #12796
## Validation Steps Performed
`Host.FuzzWrapper` project builds.
## Summary of the Pull Request
Prevents the Fuzz pipeline from failing by refactoring the nuget restore pipeline steps.
## References
Broken in #12778.
## PR Checklist
* [ ] Closes #xxx
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx
Does what it says on the tin. This is maximal BODGE.
`TeachingTip` doesn't provide an `Opened` event.
(https://github.com/microsoft/microsoft-ui-xaml/issues/1607). But we
want to focus the renamer text box when it's opened. We can't do that
immediately, the TextBox technically isn't in the visual tree yet. We
have to wait for it to get added some time after we call IsOpen. How do
we do that reliably? Usually, for this kind of thing, we'd just use a
one-off LayoutUpdated event, as a notification that the TextBox was
added to the tree. HOWEVER:
* The _first_ time this is fired, when the box is _first_ opened,
yeeting focus doesn't work on the first LayoutUpdated. It does work on
the second LayoutUpdated. Okay, so we'll wait for two LayoutUpdated
events, and focus on the second.
* On subsequent opens: We only ever get a single LayoutUpdated. Period.
But, you can successfully focus it on that LayoutUpdated.
So, we'll keep track of how many LayoutUpdated's we've _ever_ gotten. If
we've had at least 2, then we can focus the text box.
We're also not using a ContentDialog for this, because in Xaml Islands a
text box in a ContentDialog won't receive _any_ keypresses. Fun!
## References
* microsoft/microsoft-ui-xaml#1607
* microsoft/microsoft-ui-xaml#6910
* microsoft/microsoft-ui-xaml#3257
* microsoft/terminal#9662
## PR Checklist
* [x] Will close out #12021, but that's an a11y bug that needs secondary
validation
* [x] Closes#11322
* [x] I work here
* [x] Tests added/passed
* [n/a] Requires documentation to be updated
## Validation Steps Performed
Tested manually
Make a VTApiRoutines servicer that does minimal translations instead of
environmental simulation for some output methods. Remaining methods are
backed on the existing console host infrastructure (primarily input
related methods).
## PR Checklist
* [x] I work here
* [x] It's Fix-Hack-Learn quality so it's behind a feature gate so we
can keep refining it. But it's a start!
To turn this on, you will have to be in the Dev or Preview rings
(feature staged). Then add `experimental.connection.passthroughMode:
true` to a profile and on the next launch, the flags will propagate down
through the `ConptyConnection` into the underlying `Openconsole.exe`
startup and tell it to use the passthrough mode instead of the full
simulation mode.
## Validation Steps Performed
- Played with it manually in CMD.exe, it seems to work mostly.
- Played with it manually in Ubuntu WSL, it seems to work.
- Played with it manually in Powershell and it's mostly sad. It'll get
there.
Starts #1173
This script takes pull requests from a project board, cherry-picks them,
and updates the project board. It also yells at you if there are
conflicts to resolve, and generally tries to keep track of everything.
It is quite cool.
The `cascadia/` directory straight up isn't checked into the OS. So adding a test dependency on code in there was a BAD IDEA.
(cherry picked from commit 4e61be9cd7)
Service-Card-Id: 79863821
Service-Version: Inbox
If we do not include mp:PhoneIdentity in our AppxManifest, the store
will edit our package and re-sign it for distribution. When that
happens, it creates a divergence: there are now two versions of our
package with the same name and version number, but different contents.
This breaks everything.
**THIS IS LOAD BEARING**
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
## Summary of the Pull Request
This builds on top of #12707. As I understand it the primary motivation for using a git submodule instead of NuGet is just that it is too annoying to have to manage dozens of packages.config files and their corresponding import statements. Now that there is a single global nuget definition that is a nonissue and we can switch over.
This also updates to the latest version of WIL.
Now that the latest version of WIL is available it uses it to replace `winrt::resume_foreground` with `wil::resume_foreground`. See [492c01bb53) for a detailed explanation of the problems with `winrt::resume_foreground` and how WIL addresses them.
<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? -->
## References
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [ ] Closes#12776, Closes#12777
* [ ] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx
<!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Ran `git clean -fdx` to wipe my clone to be completely clean. Opened the solution in Visual Studio 2022 and build it. Used `razzle.cmd`, `b`, and `runut.cmd` to run the tests.
## THE WHITE WHALE
This is a fairly naive fix for this bug. It's not terribly performant,
but neither is resize in the first place.
When the buffer gets resized, typically we only copy the text up to the
`MeasureRight` point, the last printable char in the row. Then we'd just
use the last char's attributes to fill the remainder of the row.
Instead, this PR changes how reflow behaves when it gets to the end of
the row. After we finish copying text, then manually walk through the
attributes at the end of the row, and copy them over. This ensures that
cells that just have a colored space in them get copied into the new
buffer as well, and we don't just blat the last character's attributes
into the rest of the row. We'll do a similar thing once we get to the
last printable char in the buffer, copying the remaining attributes.
This could DEFINITELY be more performant. I think this current
implementation walks the attrs _on every cell_, then appends the new
attrs to the new ATTR_ROW. That could be optimized by just using the
actual iterator. The copy after the last printable char bit is also
especially bad in this regard. That could likely be a blind copy - I
just wanted to get this into the world.
Finally, we now copy the final attributes to the correct buffer: the new
one. We used to copy them to the _old_ buffer, which we were about to
destroy.
## Validation
I'll add more gifs in the morning, not enough time to finish spinning a
release Terminal build with this tonight.
Closes#32🎉🎉🎉🎉🎉🎉🎉🎉🎉Closes#12567
(cherry picked from commit 855e1360c0)
These changes are purely a refactoring of the build files. There should
be no difference to the compiled result or runtime behavior.
Currently there are packages.config files in lots of directories, with
those same projects referencing props/targets from packages/ with a
version string in the path. This is frustrating because version changes
or new dependencies require updating lots and lots of build files
identically. There is also the possibility of error where locations are
missed.
With these changes there is a single canonical nuget configuration that
takes effect for all of OpenConsole.sln. Updating version numbers
should be limited to a single set of global files.
The changes were done incrementally but the result is basically that
dep\nuget\packages.config serves as the global NuGet dependency list. A
pair of common build files (common.nugetversions.props and
common.nugetversions.targets) were added to contain the various imports
and error checks. There is also a special build target to ensure that
the restore happens before builds even though a given directory doesn't
have a packages.config for Visual Studio to observe.
These new *.nugetversions.* files are imported in pretty much every
vcxproj/csproj in the solution in the appropriate place to satisfy the
need for packages. There are opt-in configuration values (e.g.
`TerminalCppWinrt=true`) that must be set to opt into a given
dependency. Adding a new dependency is just a matter of adding a new
opt-in value. The ordering of include does matter, which was a
difficult challenge to realize and address.
There was also a preexisting issue in 3 test projects where
cppwinrt.props was included but not cppwinrt.targets. By consolidating
things globally that "error" was fixed, but broke the build in a way
that was very confusing. Those projects don't need the cppwinrt targets
so they were opted out of the cppwinrt build files entirely to fix the
breaks and get back to previous behavior.
There are two notable exceptions to this canonical versioning. The
first is that there are dueling XAML 2.7 dependencies. I avoided that
by leaving those as per-project package.config entries. The second is
that any projects outside of the .sln (such as the Island samples) were
not touched.
## Validation Steps Performed
The primary validation is that the solution builds without errors. That
is what I'm seeing (x64|Debug). I also ran `git clean -fdx` from the
root of the repo to wipe it to clean and then opened the solution and
was able to build successfully. The project F5 deploys and looks fine
to me with just a cursory glance. The tests also largely pass (7418
pass, 188 fail, 14 other) which is as good or better than the baseline I
established from a clean clone.
Closes#12708
In two instances, the help text for the settings UI refers to _transparency_ when we're really talking about _opacity._ This PR changes those occurences to more accurately reflect the setting being described.
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes#12592
Previously we would only call `SetWindowSize` and `TriggerRedrawAll` if the
viewport size in characters changed. This commit removes the limitation.
Since the if-condition limiting full redraws is now gone, this commit
moves the responsibility of limiting the calls up the call chain.
With `_refreshSizeUnderLock` now being a heavier function call
than before, some surrounding code was thus refactored.
## PR Checklist
* [x] Closes#11317
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
Test relevant for #11317:
* Print text, filling the entire window
* Move the window from a 150% scale to a 300% scale monitor
* The application works as expected ✅
Regression tests:
* Text zoom with Ctrl+Plus/Minus/0 works as before ✅
* Resizing a window works as before ✅
* No deadlocks, etc. during settings updates ✅
Changed the default value of `"trimBlockSelection"` to `true`.
* [x] Closes#12536
## Validation Steps Performed
Without editing the setting, the toggle switch was enabled by default in the settings UI.
Since RS1 (CL 3427806), gdi32 has been available on OneCoreUAP-based
editions of Windows. Therefore, we no longer need the indirect call to
TranslateCharsetInfo and without that, IInputServices doesn't have a
reason to exist.
In an ideal world.
Unfortunately, we actually do use IInputServices as a backhanded way to
get at the ConIoSrvComm from other OneCoreInteractivity components...
we also use it in a trick we play in RundownAndExit to make sure that
the ConIoSrv connection tears down at the right time.
I've replaced that trick with an equally dirty trick, but one that is
*very explicit* about what it's doing.
This change would break CJK+Grid Lines and GetConsoleLangID on
OneCore-based editions that do not host the extension apiset
ext-ms-win-gdi-font-l1... so we're falling back to the old ConIoSrvComm
implementation directly in `dbcs.cpp`.
Retrieved from https://microsoft.visualstudio.com os.2020 OS official/rs_wdx_dxp_windev 74ca635710701c45cda9eefd13dafc6f180feb49
Related work items: MSFT-38632962
5964060 contains a regression were the grayscale blending algorithm used the
gamma corrected foreground color as the pixel color, instead of blending that
color with the background color first. Due to that the background color
got lost / got set to black. This breaks any dark-on-bright outputs.
## PR Checklist
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
All 3 "antialiasing" settings work just like in DxEngine. ✅
## Summary of the Pull Request
Fixes a bug in ConHost where Narrator wouldn't read the deleted letter after the user pressed backspace.
## References
MSFT:31748387
## Detailed Description of the Pull Request / Additional comments
`WriteCharsLegacy()` already calls `NotifyAccessibilityEventing()` when text is inserted into the buffer ([see code](855e1360c0/src/host/_stream.cpp (L559-L563))). However, when backspace is pressed, the entire if-condition is skipped over, resulting in the accessibility event not being fired. `WriteCharsLegacy()` has a separate branch that is dedicated to handling backspace, so I added a call to the relevant logic to notify UIA at the end of that.
## Validation Steps Performed
✅ <kbd>Backspace</kbd> deletes a character and Narrator reads it
✅ <kbd>Backspace</kbd> still works with NVDA and JAWS (unchanged behavior)
✅ if the input buffer had wrapped text, the above scenario works as expected
✅ scenario works for CMD, PowerShell Core, and WSL
PR #12722 introduced a dependency on usp10.dll. The Script* APIs are split
between gdi32 and usp10, so we needed to add a new entry to the sources
files for anybody who consumed the GDI renderer.
## Summary of the Pull Request
Fixes a bug in ConHost where Narrator wouldn't read the deleted letter after the user pressed backspace.
## References
MSFT:31748387
## Detailed Description of the Pull Request / Additional comments
`WriteCharsLegacy()` already calls `NotifyAccessibilityEventing()` when text is inserted into the buffer ([see code](855e1360c0/src/host/_stream.cpp (L559-L563))). However, when backspace is pressed, the entire if-condition is skipped over, resulting in the accessibility event not being fired. `WriteCharsLegacy()` has a separate branch that is dedicated to handling backspace, so I added a call to the relevant logic to notify UIA at the end of that.
## Validation Steps Performed
✅ <kbd>Backspace</kbd> deletes a character and Narrator reads it
✅ <kbd>Backspace</kbd> still works with NVDA and JAWS (unchanged behavior)
✅ if the input buffer had wrapped text, the above scenario works as expected
✅ scenario works for CMD, PowerShell Core, and WSL
Some applications like `vim -H` implement their own BiDi reordering.
Previously we used `PolyTextOutW` which supported such arrangements,
but with a0527a1 and the switch to `ExtTextOutW` we broke such applications.
This commit restores the old behavior by reimplementing the basics
of `ExtTextOutW`'s internal workings while enforcing LTR ordering.
## Validation Steps Performed
* Create a text file with "ץחסק פחופפסנ חס קוח ז׳חסש ץקקטק פחטסץ"
Viewing the text file with `vim -H` presents the contents as expected ✅
* Printing enwik8 is as fast as before ✅
* Font fallback for various eastern scripts in enwik8 works as expected ✅
* `DECDWL` double-width sequences ✅
* Horizontal scrolling (apart from producing expected artifacts) ✅Closes#12294
(cherry picked from commit d97d9f0fcf)
The legacy console used to use case-sensitive history deduplication and
this change reverts the logic to restore ye olde history functionality.
This commit additionally changes the other remaining `std::equal` plus
`std::towlower` check into a `CompareStringOrdinal` call,
just because that's what MSDN suggests to use in such situations.
## PR Checklist
* [x] Closes#4186
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* Enter `test /v`
* Enter `test /V`
* Browsing through the history yields both items ✅
(cherry picked from commit 6bc2b4af09)
`WideCharToMultiByte` doesn't write a final null-byte by default.
`til::u16u8` avoids the problem.
## PR Checklist
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* Test passes in Debug builds ✅
(cherry picked from commit 5072ee640f)
This removes one source of potential integer overflows from the Viewport class.
Other parts were left untouched, as this entire class of overflow issues gets
fixed all at once, as soon as we replace COORD with til::coord (etc.).
## PR Checklist
* [x] Closes#5271
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* Call `ScrollConsoleScreenBufferW` with out of bounds coordinates
* Doesn't crash ✅
(cherry picked from commit a4a6dfcc8d)
As noted in #6759:
> `RtlCreateUnicodeString` creates a copy of the string on the process heap and the `PortName` variable has local-scope. The string doesn't get freed with `RtlFreeUnicodeString` before the function returns creating a memory leak.
> `CIS_ALPC_PORT_NAME` is a constant string and the `PortName` variable should instead be initialized using the `RTL_CONSTANT_STRING` macro:
>
> ```c++
> static UNICODE_STRING PortName = RTL_CONSTANT_STRING(CIS_ALPC_PORT_NAME);
> ```
I actually built this in the OS repo to make sure it'll still build, because this code doesn't even build outside Windows.
* [x] Closes#6759
* I work here.
(cherry picked from commit 349b76795f)
This adds some validation in the `UiaTextRange` ctor for the cursor position.
#8730 was caused by creating a `UiaTextRange` at the cursor position when it was in a delayed state (meaning it's purposefully hanging off of the right edge of the buffer). Normally, `Cursor` maintains a flag to keep track of when that occurs, but Windows Terminal isn't maintaining that properly in `Terminal::WriteBuffer`.
The _correct_ approach would be to fix `WriteBuffer` then leverage that flag for validation in `UiaTextRange`. However, messing with `WriteBuffer` is a little too risky for our comfort right now. So we'll do the second half of that by checking if the cursor position is valid. Since the cursor is really only expected to be out of bounds when it's in that delayed state, we get the same result (just maybe a tad slower than simply checking a flag).
Closes#8730
Filed #12440 to track changes in `Terminal::_WriteBuffer` for delayed EOL wrap.
## Validation Steps Performed
While using magnifier, input/delete wrapped text in input buffer.
(cherry picked from commit 5dcf5262b4)
This commit fixes an issue, where we failed to emit a DECTCEM sequence to hide
the cursor if it was hidden before XtermEngine's first frame was finalized.
Even in such cases we need to emit a DECTCEM sequence
in order to ensure we're in a consistent state.
## Validation Steps Performed
* Added test✅
* Run #12401's repro steps around 30 times✅Closes#12401
(cherry picked from commit dbb70778d4)
The pull request fixes the issue where "sizeof" parameter was use instead of "ARRAYSIZE".
## PR Checklist
* [x] Closes #xxx
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [x] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [x] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx
## Detailed Description of the Pull Request / Additional comments
This was a pretty straight forward issue, i just replace sizeof which gives the byte size with ARRAYSIZE which give the number of elements in the array.
(cherry picked from commit 5fa1ba8dab)
In !1806141, MapVirtualKey and VkKeyScan became part of OneCore (yeah,
in 2018!). GetKeyState I can't quite figure out... but it looks like
the places we would use it (Win32 Window and Selection) already either
don't exist (window) or don't work (selection) in OneCore conhost.
Removing these redirects reduces our maintenance burden quite a bit.
Because we had to run all keyboard code through the service locator,
anything that had a dependency on key translation needed to link the
entire console host. Therefore, for anything that conhost depended upon,
so did the unit test binaries. Ugh.
I chose to keep TranslateCharsetInfo, even though it looks like gdi32 is
hosted in OneCore and the code appears as though it would work. It was
not in my critical path, and is a very basic local lookup that only powers
whether gridlines are available and the console's "Lang ID".
TEST RESULTS FROM ONECORE
Microsoft.Console.Host.FeatureTests.dll
Summary: Total=408, Passed=140, Failed=266, Blocked=0, Not Run=0, Skipped=2
I do not know how to make sure that the feature tests run properly on
OneCore. It looks like ModuleSetup is failing, which is unlikely to be
related to this change (especially given that conhost *does* launch.)
If I re-run the categories individually, they either pass or get marked
as skipped intentionally.
Microsoft.Console.Host.IntegrityTests.dll
Summary: Total=5, Passed=0, Failed=5, Blocked=0, Not Run=0, Skipped=0
Same.
Microsoft.Console.Interactivity.Win32.UnitTests.dll
Summary: Total=392, Passed=392, Failed=0, Blocked=0, Not Run=0, Skipped=0
Microsoft.Console.TextBuffer.UnitTests.dll
Summary: Total=27, Passed=27, Failed=0, Blocked=0, Not Run=0, Skipped=0
Microsoft.Console.Host.UIAutomationTests.dll
Summary: Total=6, Passed=0, Failed=0, Blocked=6, Not Run=0, Skipped=0
Microsoft.Console.Types.UnitTests.dll
Summary: Total=8, Passed=8, Failed=0, Blocked=0, Not Run=0, Skipped=0
Microsoft.Terminal.Til.UnitTests.dll
Summary: Total=290, Passed=290, Failed=0, Blocked=0, Not Run=0, Skipped=0
Microsoft.Console.VirtualTerminal.Parser.UnitTests.dll
Summary: Total=748, Passed=747, Failed=0, Blocked=0, Not Run=0, Skipped=1
Microsoft.Console.VirtualTerminal.Adapter.UnitTests.dll
Summary: Total=222, Passed=222, Failed=0, Blocked=0, Not Run=0, Skipped=0
Microsoft.Console.Host.UnitTests.dll
Summary: Total=5235, Passed=5222, Failed=0, Blocked=12, Not Run=0, Skipped=1
Retrieved from https://microsoft.visualstudio.com os.2020 OS official/rs_wdx_dxp_windev c4c0267e1139d8d205bc9995da7906e5b09f03db
Related work items: MSFT-38632962
Some applications like `vim -H` implement their own BiDi reordering.
Previously we used `PolyTextOutW` which supported such arrangements,
but with a0527a1 and the switch to `ExtTextOutW` we broke such applications.
This commit restores the old behavior by reimplementing the basics
of `ExtTextOutW`'s internal workings while enforcing LTR ordering.
## Validation Steps Performed
* Create a text file with "ץחסק פחופפסנ חס קוח ז׳חסש ץקקטק פחטסץ"
Viewing the text file with `vim -H` presents the contents as expected ✅
* Printing enwik8 is as fast as before ✅
* Font fallback for various eastern scripts in enwik8 works as expected ✅
* `DECDWL` double-width sequences ✅
* Horizontal scrolling (apart from producing expected artifacts) ✅Closes#12294
[Git2Git] Merged PR 7088552: Silence TVS by using %d (int) instead of %td (ptrdiff_t)
Silence TVS by using %d (int) instead of %td (ptrdiff_t)
This commit also includes an automatic sources.dep fix.
Fixes MSFT-38106841
Fixes MSFT-38106866
Related work items: #38106841, #38106866 Retrieved from https://microsoft.visualstudio.com os.2020 OS official/rs_wdx_dxp_windev 5983633fe90cccdb1165ab28935bd704414bb6f2
Related work items: #38106841, #38106866
## THE WHITE WHALE
This is a fairly naive fix for this bug. It's not terribly performant,
but neither is resize in the first place.
When the buffer gets resized, typically we only copy the text up to the
`MeasureRight` point, the last printable char in the row. Then we'd just
use the last char's attributes to fill the remainder of the row.
Instead, this PR changes how reflow behaves when it gets to the end of
the row. After we finish copying text, then manually walk through the
attributes at the end of the row, and copy them over. This ensures that
cells that just have a colored space in them get copied into the new
buffer as well, and we don't just blat the last character's attributes
into the rest of the row. We'll do a similar thing once we get to the
last printable char in the buffer, copying the remaining attributes.
This could DEFINITELY be more performant. I think this current
implementation walks the attrs _on every cell_, then appends the new
attrs to the new ATTR_ROW. That could be optimized by just using the
actual iterator. The copy after the last printable char bit is also
especially bad in this regard. That could likely be a blind copy - I
just wanted to get this into the world.
Finally, we now copy the final attributes to the correct buffer: the new
one. We used to copy them to the _old_ buffer, which we were about to
destroy.
## Validation
I'll add more gifs in the morning, not enough time to finish spinning a
release Terminal build with this tonight.
Closes#32🎉🎉🎉🎉🎉🎉🎉🎉🎉Closes#12567
The x86 Conhost UTs were failing because--when run in a specific order
(SearchTests, then SelectionInputTests)--PrepareGlobalScreenBuffer would
attempt to enable painting on a renderer that was dead and gone and
pushing up daisies.
The legacy console used to use case-sensitive history deduplication and
this change reverts the logic to restore ye olde history functionality.
This commit additionally changes the other remaining `std::equal` plus
`std::towlower` check into a `CompareStringOrdinal` call,
just because that's what MSDN suggests to use in such situations.
## PR Checklist
* [x] Closes#4186
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* Enter `test /v`
* Enter `test /V`
* Browsing through the history yields both items ✅
HLSL uses 32-bit booleans, while C++ uses 8-bit ones aligned by 32-bit.
This meant that the shader was accessing uninitialized memory
forcing ClearType blending to be randomly enabled.
This regressed in commit 5964060.
## PR Checklist
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* ClearType blending works ✅
* Enabling transparent backgrounds forces grayscale blending ✅
`WideCharToMultiByte` doesn't write a final null-byte by default.
`til::u16u8` avoids the problem.
## PR Checklist
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* Test passes in Debug builds ✅
`std::basic_string_view::substr` throws an exception if the first argument
(offset) is out of range. If UIA is running, this creates _a lot_ of exceptions
and associated log output. This trivial change takes care of that.
After this commit we only set the default fields of a profile - primarily the
name field - as late as possible, after layering has already completed.
This ensures that we pick up any modifications from fragments.
## PR Checklist
* [x] Closes#12520
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* Add a fragment at
`%LocalAppData%\Microsoft\Windows Terminal\Fragments\Fragment\fragment.json`
with
`{"profiles":[{"updates":"{61c54bbd-c2c6-5271-96e7-009a87ff44bf}","name":"NewName"}]}`
* Windows PowerShell profile is created with the name "NewName" in settings.json ✅
* Drop engine support for DirectX 9.1
Practically no one has such old hardware anymore and AtlasEngine additionally
drops support for 10.0. The fallback also didn't work properly,
because the `FeatureLevels` array failed to include 9.2 and 9.3.
We'll simply fall back to WARP on all such devices.
* Optimize shaders during compilation
The two new flags increase shader performance sometimes significantly.
* Fix shader feature level flags
D3D feature level 10.0 only support 4.0 and 10.1 only 4.1 shaders.
## PR Checklist
* [x] Closes#12655
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* Add `WindowsTerminal.exe` in `dxcpl.exe`
* Add a basic `experimental.pixelShaderPath`
* All forced feature levels between `9_1` and `11_1` render as expected ✅
## Summary of the Pull Request
The purpose of the `IRenderTarget` interface was to support the concept
of multiple buffers in conhost. When a text buffer needed to trigger a
redraw, the render target implementation would be responsible for
deciding whether to forward that redraw to the renderer, depending on
whether the buffer was active or not.
This PR instead introduces a flag in the `TextBuffer` class to track
whether it is active or not, and it can then simply check the flag to
decide whether it needs to trigger a redraw or not. That way it can work
with the `Renderer` directly, and we can avoid a bunch of virtual calls
for the various redraw methods.
## PR Checklist
* [x] Closes#12551
* [x] CLA signed.
* [ ] Tests added/passed
* [ ] Documentation updated.
* [ ] Schema updated.
* [x] I've discussed this with core contributors already. Issue number
where discussion took place: #12551
## Detailed Description of the Pull Request / Additional comments
Anywhere that had previously been getting an `IRenderTarget` from the
`TextBuffer` class in order to trigger a redraw, will now just call the
`TriggerRedraw` method on the `TextBuffer` class itself, since that will
handle the active check which used to be the responsibility of the
render target. All the redraw methods that were in `IRenderTarget` are
now exposed in `TextBuffer` instead.
For this to work, though, the `Renderer` needed to be available before
the `TextBuffer` could be constructed, which required a change in the
conhost initialization order. In the `ConsoleInitializeConnectInfo`
function, I had to move the `Renderer` initialization up so it could be
constructed before the call to `SetUpConsole` (which initializes the
buffer). Once both are ready, the `Renderer::EnablePainting` method is
called to start the render thread.
The other catch is that the renderer used to setup its initial viewport
in the constructor, but with the new initialization order, the viewport
size would not be known at that point. I've addressed that problem by
moving the viewport initialization into the `EnablePainting` method,
since that will only be called after the buffer is setup.
## Validation Steps Performed
The changes in architecture required a number of tweaks to the unit
tests. Some were using a dummy `IRenderTarget` implementation which now
needed to be replaced with a full `Renderer` (albeit with mostly null
parameters). In the case of the scroll test, a mock `IRenderTarget` was
used to track the scroll delta, which now had to be replaced with a mock
`RenderEngine` instead.
Some tests previously relied on having just a `TextBuffer` but without a
`Renderer`, and now they require both. And tests that were constructing
the `TextBuffer` and `Renderer` themselves had to be updated to use the
new initialization order, i.e. with the renderer constructed first.
Semantically, though, the tests still essentially work the same way as
they did before, and they all still pass.
## Summary of the Pull Request
Closes#12670
Visual Studio 2022 offered to upgrade .NET Framework from an unsupported 4.5 to a supported 4.8. I let it do its thing (and undid a number of whitespace-only changes that aren't necessary). The project still builds after this. The UIA tests fail to run but I think that is preexisting and will be filing a new issue momentarily.
## PR Checklist
* [x] Closes#12670
* [x] Tests added/passed
## Validation Steps Performed
The solution compiles in VS2022 (except for #12673).
The store did not like when I uploaded two Windows Terminal packages
built on the same date, because the appxbundle version defaulted to
YYYY.MMDD.something.
There was a risk that using *this* version number will fail because it is
thousands of numbers less than "2022". We'll have to see if the store
rolls it out properly. I cannot find any documentation on how the store
rolls out *bundle* versions (it is very aware of .appx versions...).
A local test with 1.14.72x (Preview) published via the store seems to
have worked.
This commit fixes a stray exception during settings loading,
caused by a failure to obtain the app's extension catalog.
## PR Checklist
* [x] Closes#12305
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
I'm unable to replicate the issue. ❌
However an error log was provided in #12305 with which
the function causing the exception could be determined.
This regressed recently in cfaa315.
Initially I tried to migrate TestHostApp to C++/WinRT, but due to the
unbearable compile times I've reverted it back to C++/CX (>20x difference).
Unfortunately I then forgot to fix the underlying issue before submitting a PR.
## PR Checklist
* [x] Closes#12673
* [x] I work here
* [x] Tests added/passed
Many articles I read while writing this engine claimed that GPUs can't
do branches like CPUs can. One common approach to branching in GPUs is
apparently to "mask" out results, a technique called branch predication.
The GPU will simply execute all instructions in your shader linearly,
but if a branch isn't taken, it'll ignore the computation results.
This is unfortunate for our shader, since most branches we have are
only very seldomly taken. The cursor for instance is only drawn
on a single cell and underlines are seldomly used.
But apparently modern GPUs (2010s and later?) are actually entirely
capable of branching, _if_ all lanes ("pixels") processed by a
wave (""GPU core"") take the same branch.
On both my Nvidia GPU (RTX 3080) and Intel iGPU (Intel HD Graphics 530)
this change has a positive impact on power draw. Most noticeably on the
latter this reduces power draw from 900mW down to 600mW at 60 FPS.
## PR Checklist
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
It seems to work fine on Intel and Nvidia GPUs.
Unfortunately I don't have a AMD GPU to test this on, but I suspect it can't be worse.
## Summary of the Pull Request
This change makes Windows Terminal raise a `RaiseNotificationEvent()` ([docs](https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.automation.peers.automationpeer.raisenotificationevent?view=winrt-22000)) for new text output to the buffer.
This is intended to help Narrator identify what new output appears and reduce the workload of diffing the buffer when a `TextChanged` event occurs.
## Detailed Description of the Pull Request / Additional comments
The flow of the event occurs as follows:
- `Terminal::_WriteBuffer()`
- New text is output to the text buffer. Notify the renderer that we have new text (and what that text is).
- `Renderer::TriggerNewTextNotification()`
- Cycle through all the rendering engines and tell them to notify handle the new text output.
- None of the rendering engines _except_ `UiaEngine` has it implemented, so really we're just notifying UIA.
- `UiaEngine::NotifyNewText()`
- Concatenate any new output into a string.
- When we're done painting, tell the notification system to actually notify of new events occurring and clear any stored output text. That way, we're ready for the next renderer frame.
- `InteractivityAutomationPeer::NotifyNewOutput()` --> `TermControlAutomationPeer::NotifyNewOutput`
- NOTE: these are split because of the in-proc and out-of-proc separation of the buffer.
- Actually `RaiseNotificationEvent()` for the new text output.
Additionally, we had to handle the "local echo" problem: when a key is pressed, the character is said twice (once for the keyboard event, and again for the character being written to the buffer). To accomplish this, we did the following:
- `TermControl`:
- here, we already handle keyboard events, so I added a line saying "if we have an automation peer attached, record the keyboard event in the automation peer".
- `TermControlAutomationPeer`:
- just before the notification is dispatched, check if the string of recent keyboard events match the beginning of the string of new output. If that's the case, we can assume that the common prefix was the "local echo".
This is a fairly naive heuristic, but it's been working.
Closes the following ADO bugs:
- https://dev.azure.com/microsoft/OS/_workitems/edit/36506838
- (Probably) https://dev.azure.com/microsoft/OS/_workitems/edit/38011453
## Test cases
- [x] Base case: "echo hello"
- [x] Partial line change
- [x] Scrolling (should be unaffected)
- [x] Large output
- [x] "local echo": keyboard events read input character twice
This sure is bodgy, but it makes sense. Right now, when we delete a profile, we load in a totally new content for the new profile's settings. That one resets the scroll view and the focus, and now the "delete" button is obviously not focused.
Instead, this PR will manually re-focus the delete button of a profile page when the page is navigated to _because we deleted another profile_.
* [x] This will take care of #11971
This removes one source of potential integer overflows from the Viewport class.
Other parts were left untouched, as this entire class of overflow issues gets
fixed all at once, as soon as we replace COORD with til::coord (etc.).
## PR Checklist
* [x] Closes#5271
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* Call `ScrollConsoleScreenBufferW` with out of bounds coordinates
* Doesn't crash ✅
This fixes a pair of inbox bugs, hopefully.
* MSFT:35731327
* There's a small window where a peasant is being created when a monarch is exiting. When that happens, the new peasant will try to tell itself (the new monarch) when the peasant was last activated, but because the window hasn't actually finished instantiating, the peasant doesn't yet have a LastActivatedArgs to tell the monarch about.
* MSFT:32518679 (ARM version) / MSFT:32279047 (AMD64 version)
* This one's tricky. Not totally sure this is the fix, bug assuming my hypothesis is correct, this should fix it. Regardless, this does fix a bug that was in the code.
* If the king dies right as another window is starting, right while the new window is starting to ProposeCommandline to the monarch, the monarch could die. If it does, the new window just explodes too. Not what you want.
Vaguely tested the second bug manually, by setting breakpoints in the monarch, starting a defterm, then exiting the monarch while the handoff was in process. That now creates a new window, so that's at least something. `RemotingTests::TestProposeCommandlineWithDeadMonarch` was the closest I could get to testing that.
The first bug only got an eye check. Not sure how to repro, but I figured yeet and hopefully we get it.
* [x] Closes#12624
The `bg != _r.backgroundColor` invalidation check wasn't symmetric with
us setting `_r.backgroundColor` to `bg | _api.backgroundOpaqueMixin`.
Due to this, when the `backgroundOpaqueMixin` changed,
we didn't always update the const buffer appropriately.
## PR Checklist
* [x] Closes#11773
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* Enable window transparency (`backgroundOpaqueMixin == 0x00000000`)
* Maximize window (ensure we have gutters in the first place)
* Disable window transparency (`backgroundOpaqueMixin == 0xff000000`)
* Gutters are filled ✅
This commit enables `/std:c++20` for local development under VS17.
Our CIs will continue to use VS16 and C++17 for now in order to reduce
the likelihood of regressions during the current development cycle.
It's expected that we'll migrate to VS17 soon, as this
is what conhost is already being built with anyways.
## PR Checklist
* [x] Closes#12510
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* Everything compiles under `/std:c++20` ✅
This regressed in 2b202ce6, which removed `ACTCTX_FLAG_RESOURCE_NAME_VALID`
during `CreateActCtxW` under the assumption that an executable only has
one manifest. conhost has two however and we need to pick the correct one.
On OpenConsole this causes the expected `ERROR_SXS_PROCESS_DEFAULT_ALREADY_SET`.
Closes MSFT:38355907
(cherry picked from commit c820af46b7)
By replacing `IDWriteFontSetBuilder2::AddFontFile` with
`IDWriteFactory5::CreateFontFileReference` and
`IDWriteFontSetBuilder1::AddFontFile` we add nearby
font loading support for Windows 10, build 15021.
This commit also fixes font fallback for AtlasEngine,
which was crashing during testing.
Finally it fixes a bug in DxEngine, where we only created a "nearby" font
collection if we couldn't find the font in the system collection. This doesn't
fix the bug, if the font is locked or broken in the system collection.
This is related to #11648.
## PR Checklist
* [x] Closes#12420
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* Build a Debug version of Windows Terminal
* Put Jetbrains Mono into the writeable AppX directory
* Jetbrains Mono is present in the settings UI ✅
* DxEngine works with Jetbrains Mono ✅
* AtlasEngine works with Jetbrains Mono ✅
This regressed in 2b202ce6, which removed `ACTCTX_FLAG_RESOURCE_NAME_VALID`
during `CreateActCtxW` under the assumption that an executable only has
one manifest. conhost has two however and we need to pick the correct one.
On OpenConsole this causes the expected `ERROR_SXS_PROCESS_DEFAULT_ALREADY_SET`.
Closes MSFT:38355907
## Summary of the Pull Request
This makes it so that the settings.json backups are no longer created when the user saves their settings via the Settings UI.
Closes#11703
"Summon" was translated as a synonym for "citation" in Spanish instead
of treating it as a RPG-related word. "Show/Hide" will hopefully
allow an improved automatic translation in the future.
Closes#10691
2b202ce6 introduced a bug, where FreeProcessData was called without the console
lock being held. The previous code can be found in 40e3dea, on line 441-454.
## PR Checklist
* [x] Closes MSFT:21372705
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
None, as this fix is purely theoretic, but it matches the stack trace
and 40e3dea clearly wasn't correctly ported to strict C++ either.
## Summary of the Pull Request
Fixes RTF generation for text with Unicode characters.
## PR Checklist
* [x] Closes#12379
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [x] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx
## Validation Steps Performed
Added some unit tests.
Ran the following in PowerShell and copied the emitted text into WordPad.
```pwsh
echo "This is some Ascii \ {}`nLow code units: á é í ó ú `u{2b81} `u{2b82}`nHigh code units: `u{a7b5} `u{a7b7}`nSurrogates: `u{1f366} `u{1f47e} `u{1f440}"
```
2b202ce6 introduced a bug, where FreeProcessData was called without the console
lock being held. The previous code can be found in 40e3dea, on line 441-454.
## PR Checklist
* [x] Closes MSFT:21372705
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
None, as this fix is purely theoretic, but it matches the stack trace
and 40e3dea clearly wasn't correctly ported to strict C++ either.
From MSFT:36797001. Okay so this is only .22% of our crashes, but every little bit helps, right?
Turns out this is also hitting in:
* MSFT:35726322
* MSFT:34662459
and together they're a fairly hot bug.
There's a large class of bugs where we might get a callback to one of our event handlers when we call `app.Close()` in the `AppHost` dtor. This PR adds manual revokers to these events, and makes sure to revoke them BEFORE nulling out the `_window`. That will prevent callbacks during the rest of the dtor, when the `_window` is null.
This is intended to be a PR triggered build that only runs when
features.xml has been touched, to validate that the disabled features do
not cause compilation errors.
Four (4) squashed changes, with messages preserved.
## release: move symbol publication into its own phase
Right now, symbol publication happens every time we produce a final
bundle. In the future, we may be producing multiple bundles from the
same pipeline run, and we need to make sure we only do *one* symbol
publication to MSDL.
When we do that, it will be advantageous for us to have just one phase
that source-indexes and publishes all of the symbols.
## Remove Terminal's built-in copy of the VC Runtime
This removes the trick we pulled in #5661 and saves us ~550kb per arch.
Some of our dependencies still depend on the "app" versions of the
runtime libraries, so we are going to continue shipping the forwarders
in our package. Build rules have been updated to remove the non-Desktop
VCLibs dependency to slim down our package graph.
This is not a problem on Windows 11 -- it looks like it's shipped inbox.
**BREAKING CHANGE**: When launched unpackaged, Terminal now requires the
vcruntime redist to be installed.
## Prepare for toggling XAML between 2.7.0 and -prerelease on Win11
common.openconsole.props is a pretty good place to stash the XAML
version since it is included in every project (including the WAP
project (unlike the C++ build props!)).
I've gone ahead and added a "double dependency" on multiple XAML
versions. We'll toggle them with a build flag.
## Run the release pipeline twice, for Win10 and Win11, at the same time
This required some changes in how we download artifacts to make sure
that we could control which version of Windows we were processing in any
individual step.
We're also going to patch the package manifest on the Windows 11 version
so the store targets it more specifically.
On top of the prior three steps, this lets us ship a Windows 11
package that costs only ~15MB on disk. The Windows 10 version, for
comparison, is about 40.
The previous implementation only inverted the RGB values of the cell,
but failed to account for situations where the `color` is transparent,
which is the case when `backgroundOpaqueMixin` is 0 (for instance if
acrylic backgrounds are enabled). In these situations the alpha
component remained 0 which caused the cursor to be invisible.
For some inexplicable reason this issue is only visible on a HDR display,
even though it should also effect regular ones. God knows why.
With this commit the cursor texture is treated as a mask that inverts the color.
We use branching here, because I couldn't come up with a more clever solution.
## PR Checklist
* [x] Closes#12507
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* Cursor is visible on a HDR display with acrylic background ✅
* TBD performance benchmark for `[branch]` ❌
Fixes two crashes amounting to 14% of our crash burden in Simulated
Selfhost. I can't reproduce this organically, but I was able to do so by
forcing the command palette to be empty.
## Summary of the Pull Request
In PR #12462, a new `maxversiontested` entry was added to the
_WindowsTerminal.manifest_ file which now gets propagated to the
_TerminalApp.Unit.Tests.manifest_ file whenever a full build is
executed. This PR is just committing the updated test manifest.
## PR Checklist
* [x] Closes#12543
* [x] CLA signed.
* [ ] Tests added/passed
* [ ] Documentation updated.
* [ ] Schema updated.
* [x] I've discussed this with core contributors already. Issue number
where discussion took place: #12543
## Summary of the Pull Request
Prevents a crash that could occur when invoking `wt C:\`
## PR Checklist
* [x] Closes#12535
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [x] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx
## Detailed Description of the Pull Request / Additional comments
Updates `CascadiaSettings::NormalizeCommandLine()` to check that there are a suitable number of command line arguments to be concatenated together, to prevent accessing an array index in `argv` that doesn't exist.
Also prevents a test flake that could occur in `TerminalSettingsTests::CommandLineToArgvW()`, due to generating an empty command line argument.
## Validation Steps Performed
Added a test, and checked that invoking each of the command lines below behaved as expected:
```
wtd C:\ # Window pops up with [error 2147942405 (0x80070005) when launching `C:\']
wtd C:\Program Files # Window pops up with [error 2147942402 (0x80070002) when launching `C:\Program Files']
wtd cmd # cmd profile pops up
wtd C:\Program Files\Powershell\7\pwsh -WorkingDirectory C:\ # PowerShell profile pops up in C:\
wtd "C:\Program Files\Powershell\7\pwsh" -WorkingDirectory C:\ # PowerShell profile pops up in C:\
wtd . # Window pops up with [error 2147942405 (0x80070005) when launching `.']
```
## Summary of the Pull Request
Somehow, the controls v2 update caused an issue where if you as much as _load_ a content dialog when there's already one open, we get holes in the terminal window (#12447)
This commit introduces logic to `TerminalPage` to check whether there is a content dialog open before we try to load another one.
## PR Checklist
* [x] Closes#12447
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [x] I work here
## Validation Steps Performed
Can no longer repro #12447
"Acrylic material" is the official name as used on Microsoft Docs
and should ensure it gets properly translated in all languages.
## PR Checklist
* [x] Closes#9846
* [x] Closes MSFT:36776499
* [x] I work here
## Detailed Description of the Pull Request / Additional comments
We originally intended to replace the strings with "acrylic transparency",
but "acrylic material" is actually the official term on Microsoft Docs.
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
## Summary of the Pull Request
Fix typos found by codespell. Some of it in documentation and user-visible text, mostly in code comments. While I understand you might not be interested in fixing code comments, one of the reasons being extra noise in git history, kindly note that most spell checking tools do not discriminate between documentation and code comments. So it's easier to fix everything for long maintenance.
<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? -->
## References
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [ ] Closes #xxx
* [X] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [x] Tests added/passed
* [X] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: [#501](https://github.com/MicrosoftDocs/terminal/pull/501)
* [ ] Schema updated.
* [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx
<!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
I have checked and re-checked all changes.
When the dpi is changed, call `updateFont()` instead of `TriggerFontChange`, this
means that we continue to use the existing font features/axes
Closes#11287
## Summary of the Pull Request
Modifies the OneFuzz CI Job so that it attempts to read the notification config from a file rather than the command line.
## References
Potential oversight in #10431.
## PR Checklist
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
## Detailed Description of the Pull Request / Additional comments
Noticed that the CI job was failing on main, so took a look. According to the [docs](7f7d76fa7f/docs/notifications.md (implementation)), files should be referenced using `@./` notation.
We chose to use the "ContextMenu" resource compartment when we
changed the package name to Terminal in #12264 because it was more
broadly localized than the rest of the application.
It appears as though some platform features have trouble with the
"more qualified" resource paths that #12264 required.
To fix this, we will:
1. Copy all of the ContextMenu localizations into CascadiaPackage's
resource root
2. Switch all manifest resource paths to use resources from the package
root.
Regressed in #12264Closes#12384Closes#12406 (tracked in microsoft/powertoys#16118)
As noted in #6759:
> `RtlCreateUnicodeString` creates a copy of the string on the process heap and the `PortName` variable has local-scope. The string doesn't get freed with `RtlFreeUnicodeString` before the function returns creating a memory leak.
> `CIS_ALPC_PORT_NAME` is a constant string and the `PortName` variable should instead be initialized using the `RTL_CONSTANT_STRING` macro:
>
> ```c++
> static UNICODE_STRING PortName = RTL_CONSTANT_STRING(CIS_ALPC_PORT_NAME);
> ```
I actually built this in the OS repo to make sure it'll still build, because this code doesn't even build outside Windows.
* [x] Closes#6759
* I work here.
I believe this fixes#12383, but I can't seem to find a way to set up a N SKU VM to confirm this.
* [ ] TODO: wait till the morning to finish copying the N vhd I found off the build shares, to confirm this doesn't crash on launch.
This has been a saga.
Basically, any resources in `App.xaml` aren't going to be able to reference other theme-aware resources. We can't change the theme of the app at runtime, only elements within the app. So we can't use `ApplicationPageBackgroundThemeBrush` in app.xaml, because it will ALWAYS be evaluated as the OS theme version of that brush.
* regressed in #12326
* See also #10864
* #3917 CANNOT be fixed in the same way. We're lucky here that the TabView uses a `{ThemeResource TabViewBackground}` in markup to set the bg. We're not similarly lucky with the Pane one.
* [x] closes#12356
* [x] Tested manually. You can confirm, my eyes are bleeding from the OS-wide light mode
#12348 introduced an off-by-one bug. While the `NormalizeCommandLine` loop
should exit early when there aren't at least _two_ arguments to be joined,
the final argument-append needs to happen even if just _one_ argument exists.
This commit fixes the issue and introduces changes to additionally monitor
the early loop exit, as well as the call to `ExpandEnvironmentStringsW`.
## PR Checklist
* [x] Closes#12461
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* All `TerminalSettingsTests` tests pass ✅
* use `FontFamily="{ThemeResource SymbolThemeFontFamily}"` where possible, in XAML
* use `FontFamily{ L"Segoe Fluent Icons, Segoe MDL2 Assets" }` in codebehind
Basically just a simple string replace.
* [x] This was a bullet point in #11353
* [x] Confirmed manually on my win10 PC
* see also #12438
Actually, this is the last bullet in #11353, so I'm gonna say closes#11353.
Screenshots below.
AtlasEngine enables various debug options for D2D and D3D in Debug builds.
Among those are resource leak checks, which were broken in OpenConsole
due to the unclean exit in `ServiceLocator::RundownAndExit`.
This commit fixes the issue by running the destructors
of any renderers registered in the Window class first.
## PR Checklist
* [x] Closes#12414
* [x] I work here
## Validation Steps Performed
* Set `HKEY_CURRENT_USER\Console\UseDx` to `2`
* Run `OpenConsole.exe`
* Exit
* No exceptions are thrown ✅
Now that we've figured out how to publish the public symbols to the official Microsoft download server... we may as well embed the source code linking information inside of them given that it's right here on GitHub. This attempts to run our existing source linking scripts against the public copy of the symbols.
## PR Checklist
* [x] Closes#12443
* [x] I work here
* [x] Tested manually
## Validation Steps Performed
* [x] Build with it: https://dev.azure.com/microsoft/Dart/_build/results?buildId=44930661&view=logs&j=8f802011-b567-5b81-5fa6-bce316c020ce
* [x] Point the debugger at them and see if it can find the sources
* [x] Maybe also look at them in a hex editor or whatnot and validate I can see the source paths pointing at GitHub
Updates this narrator announcement message to include the number of results it found. There are two versions:
* one for a singular result
* one for multiple results.
which should help with loc.
We're trying to get this in with the loc hotfix, so 👀 please
* [x] will take care of the last bit of #7907
verified with narrator locally.
We're now building a fully provenance, compliance, and security
validated package (vpack) through our Release pipeline. This attaches
the last phase which automates the submission into the Windows product.
It will also automatically trace back the source, commit SHA, and build
to the submission here from the Windows side.
* [x] Automates a manual activity I performed a few times recently
* [x] I work here
* [x] Ran a test of it against `release-1.12` and it worked
## Summary of the Pull Request
Followup from our discussion during team sync, the 'automatic adjustment of indistinguishable text' setting is going to be enabled for dev builds only.
## References
#12160
## PR Checklist
* [ ] Closes #xxx
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [x] I work here
## Validation Steps Performed
Setting appears on dev build and the feature works
## Summary of the Pull Request
The only method that was really needed in the `AdaptDefault` class was
the `PrintString` method, and that could easily be moved into the
`ConGetSet` interface. That lets us get rid of the `AdaptDefault` class
altogether, simplifying the construction of the `AdaptDispatch` class,
and brings us more in line with the `TerminalDispatch` implementation.
## PR Checklist
* [x] Closes#12318
* [x] CLA signed.
* [ ] Tests added/passed
* [ ] Documentation updated.
* [ ] Schema updated.
* [x] I've discussed this with core contributors already. Issue number
where discussion took place: #12318
## Detailed Description of the Pull Request / Additional comments
The `Execute` method was never used at all, so there was no problem with
losing that. But I also noticed there was an equivalent `ExecuteChar`
method in the `ITerminalApi` interface, which also wasn't being used, so
I've removed that too.
Then there was a `Print` method taking a single `wchar_t` parameter, but
that was ultimately implemented as a `PrintString` call anyway, so that
translation could easily be accomplished in the `AdaptDispatch` calling
code, the same way it's done in `TerminalDispatch`.
That left us with the `PrintString` method, which could simply be moved
into the `ConGetSet` interface, which would then more closely match the
`ITerminalApi` interface.
There was also a `GetResult` method, that returned the status of the
last `PrintString`, but that result was never actually checked anywhere.
What I've done now is make the `PrintString` method throw an exception
on failure, and that will be caught and logged in the `StateMachine`.
## Validation Steps Performed
I've started a bash shell in conhost to verify that it still works.
Since almost everything goes through `PrintString` in VT mode, it should
be obvious if something was broken.
## Summary of the Pull Request
Other than the `s_ResizeWindow` function, the `DispatchCommon` class was
just a couple of static functions indirectly calling the `ConGetSet`
interface. So by moving the `s_ResizeWindow` implementation into the
`ConhostInternalGetSet` class, we could easily replace all usage of
`DispatchCommon` with direct calls to `ConGetSet`.
## PR Checklist
* [x] Closes#12253
* [x] CLA signed.
* [ ] Tests added/passed
* [ ] Documentation updated.
* [ ] Schema updated.
* [x] I've discussed this with core contributors already. Issue number
where discussion took place: #12253
## Validation Steps Performed
I've manually confirmed the resizing operations still work as expected.
The other functions are harder to test, but were trivial replacements.
Basically, some WSL distros ship fragments that replace the `commandline` with the executable for their distro (`ubuntu.exe`, etc.). We didn't expect that when we changed the `startingDirectory` for them all to `~`.
Unfortunately, `~` is really never a valid path for a process on windows, so those distros would now fail with
```
[error 2147942667 (0x8007010b) when launching `ubuntu1804.exe']
Could not access starting directory "~"
```
If we find that we were unable to mangle `~` into the user's WSL `commandline`, then we will re-evaluate that `startingDirectory` as `%USERPROFILE%`, which is at least something sensible, if albeit not what they wanted.
* regressed in #12315
* [x] Closes#12353
* [x] Tested with a (`ubuntu1804.exe`, `~`) profile - launched successfully, where 1.13 in market fails.
* [x] added tests
We absolutely cannot allow a defterm connection to
auto-elevate. Defterm doesn't work for elevated senarios in the
first place. If we try accepting the connection, the spawning an
elevated version of the Terminal with that profile... that's a
recipe for disaster. We won't ever open up a tab in this window.
* [x] Closes#12370
* [x] Tested manually, since there's not a great way to add defterm tests
This PR updates the `ITerminalApi` and `TerminalDispatch` classes to
allow exceptions to be thrown in case of errors instead of using boolean
return values.
## References
This brings the Terminal code into alignment with the `AdaptDispatch`
and `ConGetSet` changes made in PR #12247.
And while this isn't exactly a fix for #12378, it does at least stop the
app from crashing now.
## Detailed Description of the Pull Request / Additional comments
All the `TerminalDispatch` methods have had their `noexcept` specifiers
dropped, and any `try`/`catch` wrapping removed, so exceptions will now
fall through to the `StateMachine` class where they should be safely
caught and logged.
The same goes for the `ITerminalApi` interface and its implementation in
the `Terminal` class. And many of the methods in this interface have
also had their `bool` return values changed to `void`, since there is
usually not a need for error return values now.
## Validation Steps Performed
I've manually tested the `OSC 9;9` sequence described in #12378 and
confirmed that it no longer crashes.
This adds some validation in the `UiaTextRange` ctor for the cursor position.
#8730 was caused by creating a `UiaTextRange` at the cursor position when it was in a delayed state (meaning it's purposefully hanging off of the right edge of the buffer). Normally, `Cursor` maintains a flag to keep track of when that occurs, but Windows Terminal isn't maintaining that properly in `Terminal::WriteBuffer`.
The _correct_ approach would be to fix `WriteBuffer` then leverage that flag for validation in `UiaTextRange`. However, messing with `WriteBuffer` is a little too risky for our comfort right now. So we'll do the second half of that by checking if the cursor position is valid. Since the cursor is really only expected to be out of bounds when it's in that delayed state, we get the same result (just maybe a tad slower than simply checking a flag).
Closes#8730
Filed #12440 to track changes in `Terminal::_WriteBuffer` for delayed EOL wrap.
## Validation Steps Performed
While using magnifier, input/delete wrapped text in input buffer.
With the recent change to allow text boxes to be bigger, the `Browse` button that some of them have was getting cut off when the window was too narrow. This change puts the `Browse` button below the text box instead of next to it to prevent this issue.
## PR Checklist
* [x] Closes#12335
Segoe Fluent isn't available on Windows 10, and doesn't stealthily ship with WinUI. So if we manually set the font family to `"Segoe Fluent Icons"`, then that will just display boxes in Win10.
This instead uses the resource `"{ThemeResource SymbolThemeFontFamily}"` which will gracefully fall back on Win10.
See:
* https://github.com/microsoft/microsoft-ui-xaml/issues/3745, which inspired this solution.
Guess what! The backgound image icons were also manually specifying this font, so they had to get updated too. I couldn't find any other `Segoe Fluent` references in the code.
* [x] Closes#12350
* [x] Checked Windows 11 locally
* [x] Checked Win10 (screenshots incoming from other machine)
This commit fixes an issue, where we failed to emit a DECTCEM sequence to hide
the cursor if it was hidden before XtermEngine's first frame was finalized.
Even in such cases we need to emit a DECTCEM sequence
in order to ensure we're in a consistent state.
## Validation Steps Performed
* Added test✅
* Run #12401's repro steps around 30 times✅Closes#12401
The focus box around the color schemes combo box was getting cut off, this change adds a small margin to the stackpanel to allow space for the focus box
## PR Checklist
* [x] Closes#12328
I have no idea how this is even possible to hit. If this is able to be null, then we failed to load the settings in such a catastrophic way that nothing should work. However, OP's Terminal seemed to have already loaded the settings. By all accounts, doesn't make sense.
Regardless, the code here would crash if this ever is null, so we may as well catch it.
* [x] Closes#12360
* [ ] No way to verify this since it isn't even reproable on OPs machine, but it does have a lot of hits for that failure bucket (!!!)
The previous code had two bugs for:
* paths with more than 1 whitespace
The code joins the argv array by replacing null-word terminators with
whitespace. Unfortunately it always referred to the separator between
`argv[0]` and `argv[1]` for this instead of continuing to join
those between 1 and 2, etc.
* paths sharing a common prefix with another directory
`SearchPathW` returns paths that aren't necessarily paths to files.
A call to `GetFileAttributesW` was added, ensuring we only resolve file paths.
## PR Checklist
* [x] Closes#12345
* [x] I work here
* [ ] Tests added/passed
## Validation Steps Performed
* Paths with more than 1 whitespace resolve correctly ✅
* Paths with neighboring directories sharing a common prefix resolve correctly ✅
* Tests added ✅
## Summary of the Pull Request
After 'must', the verb is used without 'to'. Correct: "must" or "have to".
## PR Checklist
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
## Validation Steps Performed
Not required, only comment has been changed.
## Summary of the Pull Request
We no longer do anything when the rightmost breadcrumb is invoked
## PR Checklist
* [x] Closes#12325
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [x] I work here
## Validation Steps Performed
Tested manually, cannot repro #12325 anymore
The `x-generate` statement seems to have fallen apart somewhere and is no longer generating the valid list of languages for display. This hardcodes the list into the manifest to restore it, which is a valid option per the documentation.
We also hardcode the limited subset of languages into the Settings application because the main application supports fewer languages than we have been translated into for the shell extensions for Windows Explorer and Start Menu integration.
## PR Checklist
* [x] Closes#12351
* [x] I work here.
* [x] Manual tests below
## Validation Steps Performed
- [x] Clean built locally with `msbuild.exe openconsole.sln /p:Configuration=Release /p:Platform=x64 /p:WindowsTerminalBranding=Release /t:Terminal\CascadiaPackage /m /bl:log4.binlog` and checked that the `appxmanifest.xml` that popped out the other side contained the same languages that it used to contain.
- [x] Built in the release pipeline
- [x] Installed release and preview branded packages. Changed my machine language to Polish (pl-PL) which is not one of the fully localized languages, but is one of the limited ones. Checked the start menu and right-click menus and saw Polish text for Terminal and Terminal Preview. Checked the Settings page in our app and saw only the limited 14 language list for the application itself.
## Summary of the Pull Request
Reducing the `MinWidth` of a toggle switch means it no longer needs a negative margin to align it correctly
## PR Checklist
* [ ] Closes #xxx
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [x] I work here
## Validation Steps Performed
Setting a different language no longer causes the toggle switch to fall out of the expander
We're investigating an issue where the build succeeded but something still got lost somewhere. If we had the binlogs, maybe we could diff and track it down faster.
## Summary of the Pull Request
This PR refactors the `ConGetSet` API, eliminating some of the bloat produced by the `DoSrvPrivateXXXX` functions, simplifying the method naming to more closely match the `ITerminalApi` interface, and making better use of exceptions for error conditions in place of boolean return values.
## References
This is another small step towards merging the `AdaptDispatch` and `TerminalDispatch` classes (#3849).
## PR Checklist
* [x] Closes#12193
* [x] Closes#12194
* [x] CLA signed.
* [ ] Tests added/passed
* [ ] Documentation updated.
* [ ] Schema updated.
* [x] I've discussed this with core contributors already. Issue number where discussion took place: #3849
## Detailed Description of the Pull Request / Additional comments
There are two main parts to this. The first step was to get rid of all the `DoSrvPrivateXXX` functions, and move their implementation directly into the `ConhostInternalGetSet` class. For the most part this was just copying and pasting the code, but I also fixed a couple of bugs where we were using the wrong output buffer (the global buffer rather than the one associated with the output handle), and got rid of some unnecessary calls to `GetActiveBuffer`.
The second part was to make better use of exceptions for error conditions. Instead of catching the exceptions at the `ConGetSet` level, we now allow them to fall through all the way to the `StateMachine`. This greatly simplifies the `AdaptDispatch` implementation since it no longer needs to check a boolean return value on every `ConGetSet` call. This also enables the getter methods to return properties directly instead of having to use a reference parameter.
## Validation Steps Performed
A number of the unit tests had to be updated to match the new API. Sometimes this just required changes to method names, but in other cases error conditions that were previously detected with boolean returns now needed to be caught as exceptions.
There were also a few direct calls to `DoSrvPrivateXXX` functions that now needed to be invoked through other means: either by generating an equivalent escape sequence, or calling a lower level API serving the same purpose.
And in the adapter tests, the mock `ConGetSet` implementation required significant refactoring to match the new interface, mostly to account for the changes in error handling.
We have to do this so that the store sees us as one thing ("Windows
Terminal") and the Start menu sees us as another ("Terminal").
The store will reject our package if the value we use for "DisplayName"
here doesn't match the store's "reserved names".
This value is *not used* by the start menu.
- The add new profile page now uses a dropdown rather than radio buttons
- Subheaders, breadcrumb bar, buttons etc are now all centralized when the window is maximized (so they all align with the expanders now)
- We no longer override the titlebar colors and instead use the xaml defaults (these still aren't great but at least we will get the fix automatically when it happens upstream)
- Breadcrumb bar no longer has a negative margin, so there's no weird overlap that happens when the window becomes small
- The number boxes for launch size and font size now use the `Inline` placement mode rather than compact, allowing modification to the number with fewer clicks
- Textboxes now have a greater max width so they can occupy more space in the expander if needed
## Summary of the Pull Request
When using a screen reader, the buttons on the "add a new profile" page were being read weirdly:
- "New empty profile" button read as "create new button button"
- "duplicate" button read as "duplicate button button"
It's generally standard to read out the text inside the button, so I did just that by reusing the existing localized resources. This also removes the redundant "button" that is said by the screen reader.
I also removed the unused `AutomationId` and unnecessary `Button.Content` tags.
#11156 can be closed upon validation by the accessibility team.
## Validation Steps Performed
✅ navigate to both buttons using Narrator; make sure it sounds right
## Summary of the Pull Request
Adds some polish around the navigators in the profile page (i.e. "appearance" and "advanced" button) by doing the following:
- use the localized resources for the pivot on the navigators
- simplify the navigators to be buttons instead of toggle buttons
Doing so has Narrator identify these as buttons rather than toggle buttons. So now Narrator won't say that the button is "off", which just makes more sense.
## Validation Steps Performed
✅ Narrator says "Advanced button" or "Appearance button" on the navigator
✅ The navigators look the same as before
Since we turned this feature on in windows, and it relies on _lying
about the contents of the registry_, Terminal needs to be in on the
joke.
This will need to be reverted and serviced if we choose not to ship like
this.
Fixes#12308
`IDWriteTextAnalyzer::GetGlyphs` is not enough to get a
`DWRITE_SHAPING_TEXT_PROPERTIES::canBreakShapingAfter`
value that works for combining diacritical marks.
This requires an additional call to `GetGlyphPlacements`.
This commit increases CPU usage for complex text by ~10%.
## PR Checklist
* [x] Closes#11925
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* ``echo "[e`u{0301}`u{0301}]"`` prints an "e" with 2 accents ✅
I added a condition to exclude some of the NuGet PGO stuff when there was no build mode, but appear to not have propagated any of it in the PGD merge job. This sets it to Optimize here so it'll go through.
## PR Checklist
* [x] Closes#12300
* [x] I work here.
* [x] It blends.
## Validation Steps Performed
* [x] Ran the PGO Instrument Phase
* [x] Ran the PGO Optimize Phase
Basically, this is the same as #12266, but for the `SearchBoxControl`. Trickily, the ControlCore is the one that knows if there were search results, but the TermControl has to be the one to announce it.
* [x] Will take care of #11973 once a11y team confirms
* [x] Tested manually with Narrator
* [x] Resolves a part of #6319, which I'm repurposing just to displaying the number of results in general.
* See also #3920
The pull request fixes the issue where "sizeof" parameter was use instead of "ARRAYSIZE".
## PR Checklist
* [x] Closes #xxx
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [x] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [x] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx
## Detailed Description of the Pull Request / Additional comments
This was a pretty straight forward issue, i just replace sizeof which gives the byte size with ARRAYSIZE which give the number of elements in the array.
## Summary of the Pull Request
This adds names to more of our focusable elements. This should be the rest of them that I missed in #11364
## References
* #9990: a11y megathread
* #11155: original version of this
## PR Checklist
* [x] Should take care of #11996 once confirmed
* [x] I work here
## Validation Steps Performed
Used Accessibility Insights to verify.
## Detailed Description of the Pull Request / Additional comments
There is one other weird bit. All the expanders that have content below the expander (not inline), show up as focusable, but don't have names. Even when I add names to them. I believe this is due to https://github.com/microsoft/microsoft-ui-xaml/issues/5820, which is fixed in https://github.com/microsoft/microsoft-ui-xaml/pull/6032, in https://github.com/microsoft/microsoft-ui-xaml/releases/tag/v2.8.0-prerelease.220118001. Unfortunately, we're on a 2.7 prerelease, so we don't have that fix yet. I may see how painful moving to that is, because we're gonna get another a11y ping as soon as 1.13 ships.
I pre-emptively added names to these guys in f7ba158dc, so that the new MUX should just fix this without any thinking on our part.
Introduced in #11416
We weren't using these macros for duplicating as well, so I forgot to duplicate a couple settings. This PR switches duplicating over to using the macros as well, which shou;d reduce future bugs.
Also adds notes to which properties are intentionally omitted from these macros.
* [x] closes#12265
* [x] Verified manually that #12120 still works as expected
Sorry for combining two fixes in one PR. I can separate if need be.
* [x] Closes#12276:
- `"bellSound": null` didn't work. This one was easier, and is atomically in bcc2ca04fc. Basically, we would deserialize that as an array with a single empty string in it, which we'd try to then play. I think it's more idomatic to have that deserialized as an empty array, which correctly falls back to playing the default sound.
* [x] Closes#12258:
- This one is the majority of the rest of the PR. If you leave the MediaPlayer open, then the media keys will _affect the Terminal_. More importantly, once the bell sounds, they'd replay the bell, which is insane. So the fix is to re-create the media player when we need it. We do this per-pane for simpler lifetime tracking. I'm not worried about the overhead of creating a mediaplayer here, since we're already throttling bells.
* Originally added in #11511
* [x] Tested manually
- Use [`no.mp4`](https://www.youtube.com/watch?v=x2w9TyCv2gk) for this since that's like, 17s long
- Checked that closing panes / the terminal while a bell was playing didn't crash
- Playing a bunch of bells at once works
- closing a pane stops the bell it's playing
- once the bell stops, the media keys went back to working for Spotify
* [x] I work here
## Summary of the Pull Request
Fix various things from the recent SUI changes
- The Appearance/Advanced toggle buttons now have a max width
- We don't need `Profiles.cpp` anymore
- The `Elevate` setting is now back in the SUI
- There is no longer an alignment difference between non-expander settings and expander settings
- Expander settings no longer require hitting `Tab` twice to get to them
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [ ] Closes #xxx
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [x] I work here
## Summary of the Pull Request
According to https://github.com/microsoft/microsoft-ui-xaml/issues/1971, `PaneFooter` does not set the `SizeOfSet` or `PositionInSet` properties. However, `FooterMenuItems` does and works for our scenario. So we just replaced `PaneFooter` with `FooterMenuItems`.
Will handle #11154 upon verification from the accessibility team.
## Validation Steps Performed
✅ Verified using Accessibility Insights
✅ "Open Json File" button can still be invoked and keyboard navigated to as expected
There were a number of methods in the `IStateMachineEngine` interface
which controlled how the `StateMachine` interpreted escape sequences.
But essentially what it came down to was a bunch of a properties that
were always true for the `InputStateMachineEngine`, and always false for
the `OutputStateMachine` engine. To simplify the implementation, and
make things a little more efficient, I've now replaced all of those
virtual calls with a single boolean field in the `StateMachine` that is
initialised in the constructor.
I started by adding an `isEngineForInput` parameter to the constructor
to indicate the the type of engine being passed in. But to keep things
simple for callers, and I also then added a constructor without that
parameter, which could derive the value automatically based on the type
of the engine pointer.
Then in the `StateMachine` implementation, anywhere we were previously
calling `ParseControlSequenceAfterSs3`, `FlushAtEndOfString`,
`DispatchControlCharsFromEscape`, or `DispatchIntermediatesFromEscape`,
we now just reference `_isEngineForInput`. But I've also copied across
some of the original comments from those methods, to make it clear at
the point of usage why we have a difference in behavior for input and
output.
To make sure the unit tests would catch any problems, I hardcoded the
`_isEngineForInput` field to `false`, and confirmed that it broke a
bunch of input engine tests. Then I hardcoded it to `true`, and
confirmed that it broke a bunch of state machine and output engine
tests. With the `_isEngineForInput` set correctly, everything passed.
I also manually tested the various output edge cases that would be
effected by this code - C0 controls within an escape sequence, time
delays in the middle of an escape sequence, `SCS` character set
selection which requires intermediates following an escape, and a G3
single shift select which depends on `SS3`.
Closes#12254
I didn't have the tray icon enabled before I suppose, so this never got hit? Anyhow, we need to change where we look for the AppName. Otherwise we crash on launch 😨
* [x] fixes `main`
* [x] I work here
* regressed in #12264
* [x] Tested by: actually running the Terminal with this, it launched
## Summary of the Pull Request
**Note: This PR targets #11720**
Replaces our old pivot-style settings UI with a breadcrumb bar style, as per the windows 11 style guidelines. This required splitting `Profiles.xaml` into 3 separate files, `Profiles_Base.xaml` for general settings, `Profiles_Appearance.xaml` for appearance settings, `Profiles_Advanced.xaml` for advanced settings
The header in the navigation view is now a [BreadcrumbBar](https://docs.microsoft.com/en-us/windows/apps/design/controls/breadcrumbbar), which can be used to navigate back to `Profiles_Base` after moving into the advanced or appearance page (see GIF below)
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [ ] Closes #xxx
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [x] I work here
## Validation Steps Performed

This commit fixes the following issues when ClearType rendering is enabled:
* Colored glyphs are now drawn using grayscale AA, similar to all current
browsers. This ensures proper gamma correctness during blending in our
shader, while generally making no discernable difference for legibility.
* Our ClearType shader only emits fully opaque colors, just like the official
ClearType implementation. Due to this we need to force grayscale AA if the
user specifies both ClearType and a background image, as the image would
otherwise not be visible.
## PR Checklist
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* Grayscale AA when drawing emojis ✅
* Grayscale AA when using a background image ✅
## Summary of the Pull Request
Updates our SUI to follow the windows 11 style guidelines. Includes updating our setting containers to follow the 'expander' style.
## PR Checklist
* [x] Closes#10631
* [x] Closes#9978
* [x] Closes#9595
* [x] Closes#11231
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [x] I work here
## Summary of the Pull Request
This fixes a bug where several settings would not show the reset button. The root cause of this issue is two fold:
1. Hooking up `CurrentXXX`
- `GETSET_BINDABLE_ENUM_SETTING` was hooked up to the **settings** model profile object instead of the **view** model profile object. Since the settings model has no `PropertyChanged` system, any changes were directly being applied to the setting, but not notifying the view model (and thus, the view, by extension) to update themselves.
- This fix required me to slightly modify the macro. Rather than using two parameters (object and function name), I used one parameter (path to getter/setter).
2. Responding to the `PropertyChanged` notifications
- Now that we're actually dispatching the `PropertyChanged` notifications, we need to actually respond to them. This behavior was defined in `Profiles::OnNavigatedTo()` in the `PropertyChanged()` handler. Funny enough, that code was still there, it just didn't do anything because it was trying to notify that `Profiles::CurrentXXX` changed. This is invalid because `CurrentXXX` got moved to `ProfileViewModel`.
- The fix here was pretty easy. Just move the property changed handler to `ProfileViewModel`'s `PropertyChanged` handler that is defined in the ctor.
## References
Bug introduced in #11877
## Validation Steps Performed
✅ Profile termination behavior
✅ Bell notification style
✅ Text antialiasing
✅ Scrollbar visibility
Turns out, this bug only repros in Controls version 2. I'm not sure why, but it didn't repro only on main. So this fix does nothing until #11720 merges.
This PR prevents us from setting properties on the paste warning dialog unless we actually need to paste. 5f9c551b7e proves that settings these properties is what would cause the bug in the first place.
I went a step further and cleaned this up a bit. This was always a little weird, having to get the `BracketedPasteEnabled` for the active control on the UI thread before we actually display the warning. In the post-#5000 future where going back to the control like this would be a x-proc hop, I figured I should just skip that entirely and plumb the `BracketedPaste` state out in the initial request.
* [x] Closes#12202
* [x] I work here
* [x] No tests, but there's not a great place for a test like this
* [x] Doesn't affect docs
See also: #12241 which would introduce #12202 on its own.
Just like the shift+click and the alt click shortcuts, now Ctrl+Click will launch a new window with that profile, elevated.
I also found that the GenerateName wasn't updated for the elevate arg, so added that. I considered adding the following to the defaults, but decided against it. It added 10 more entries to the command palette that were only separated by the `elevate: true` param, so that didn't feel valuable. Those are posted below for posterity.
* [x] closes https://github.com/microsoft/terminal/projects/5#card-50759221
* [x] Tested manually
Includes a semi-related dead code removal for the `elevated` param for `_OpenNewWindow`, which didn't end up being used, and wouldn't work as intended anyways.
This should be most of the surfaces that we really care about for displaying "Windows Terminal". There's a pile of other references in code, but I couldn't find any other resources that mention it.
I left a lot of the references to Windows Terminal throughout. Seemed like it was fine to keep calling it that in most places, just these localized strings that are going to be displayed in the Shell that should be changed.
Rough compare:

The strings were also moved to the Context Menu resources file, because that's localized into more languages.
@DHowett we may want to spin a full build to make sure this works and I didn't miss anything
* [x] Closes#12091
There are a couple places where we now bail immediately on startup, if we think the window is going to get created without any tabs. We do that to prevent a blank window from flashing on the screen when launching auto-elevate profiles. Unfortunately, those broke defterm in a particularly hard to debug way. In the defterm invocation, there actually aren't any tabs when the app completes initialization. We use the initialization to actually accept the defterm handoff. So what would happen is that the window would immediately close itself gracefully, never accepting the handoff.
In my defense, #8514, the original auto-elevated PR, predates defterm merging (906edf7) by a few months, so I totally forgot to test this when rolling it into the subsequent iterations of that PR.
* Related to:
* #7489
* #12137
* #12205
* [x] Closes#12267
* [x] I work here
* [ ] No tests on this code unfortunately
* [x] Tested manually
Includes a semi-related code fix to #10922 to make that quieter. That is perpetually noisy, and when trying to debug defterm, you've only got about 30s to do that before it bails, so the `sxe eh` breaks in there are quite annoying.
This commit extracts DirectWrite related shader code into dwrite.hlsl
and adds support for ClearType blending.
Additionally the following changes are piggybacked into this commit:
* Some incorrect code around fallback glyph sizing was removed as
this is already accomplished by `CreateTextLayout` internally
* Hot-reload failed to work with dwrite.hlsl as the `pFileName`
parameter was missing
* Legibility of the dotted underline was improved by increasing
the line gap from 1:1 to 3:1
Part of #9999.
## PR Checklist
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* Types are clear ✅
When we gave users the ability to configure how the `SGR 1` attribute
should be rendered, we described those options as "intense is bright"
and "intense is bold". Internally, though, we still referred to the `SGR 1`
attribute as bold. This PR renames all occurrences of "Bold" (when
referring to the `SGR 1` attribute) as "Intense", so the terminology is
more consistent now.
PR #10969 is where we decided on the wording to describe the `SGR 1`
attribute.
Specific changes include:
* `TextAttribute::IsBold` method renamed to `IsIntense`
* `TextAttribute::SetBold` method renamed to `SetIntense`
* `VtEngine::_SetBold` method renamed to `_SetIntense`
* `ExtendedAttributes::Bold` enum renamed to `Intense`
* `GraphicsOptions::BoldBright` enum renamed to `Intense`
* `GraphicsOptions::NotBoldOrFaint` enum renamed to `NotIntenseOrFaint`
* `SgrSaveRestoreStackOptions::Boldness` enum renamed to `Intense`
## Validation Steps Performed
I've checked that the code still compiles and the unit tests still run
successfully.
Closes#12252
## Summary of the Pull Request
Expands on #9582. If the command palette finds results, the screen reader says "Suggestions available".
Makes the scenario mentioned in #7907 work.
This is sufficient for various reasons:
1. According to the bug report, saying that suggestions are available is sufficient
> Screen reader should provide the results info on searching commands like 10 results found or suggestions available when there are any search results (Source: #7907)
2. This is common practice. Settings app and XAML Controls Gallery do this for their search box.
Also, the user should be able to know how many results were found by tabbing/selecting a result item. When this is done, the screen reader will use `SizeOfSet` and `PositionInSet` to announce how many results were found and which one we're currently on.
## Validation Steps Performed
Verified this behavior using Narrator.
Verified it matches the behavior of the Settings app and the XAML Controls Gallery.
This makes the scenario mentioned in #8480 work. It's maybe not as holistic a solution as we'd like, but it definitely works.
Tested both with Narrator, and using the TabView scroll handles to get tab focus into the tab row manually
* [x] Closing the _active_ tab with <kbd>Ctrl+Shift+w</kbd> works (not the `TabViewItem` that has focus, but that's how Edgium works so that seems fine)
* [x] Opening a tab with <kbd>Ctrl+Shift+t</kbd> works
* [x] Opening the cmdpal with <kbd>Ctrl+Shift+p</kbd> works
* [x] Will take care of #8480 once we get the a11y team to validate
* [x] I work here
#### Notes:
None of
```xaml
PreviewKeyDown="_KeyDownHandler"
KeyDown="_KeyDownHandler"
KeyUp="_KeyDownHandler"
```
On the TerminalPage directly seem to fire when the focus is in the `TabViewItem` or the New Tab flyout. But they fire just fine when focus is in the `TermControl`. Interesting, because you'd think that the `TermControl` would have already handled the key...
## Summary of the Pull Request
Makes `Model::DefaultTerminal` an `IStringable`, which presents it as a string, when possible. This enables text search for defterm's setting. This also enables screen readers to identify the combo box items by their text content (app name, author, and version) as opposed to being treated as an item containing more text. As a part of that, I cleaned up the UIA tree to treat the item's name as "\<name\>, \<author\>, \<version\>". This is consistent with how the Settings App presents installed apps in Apps > Installed apps.
#11251 will be resolved upon verification by the accessibility team.
## Validation Steps Performed
Verified using Narrator and Accessibility Insights.
The PGO helpers NuGet had the Y2K22 bug. This receives and integrates the updated package in our project to restore NuGet functionality.
## PR Checklist
* [x] Closes#12261
* [x] I work here
* [x] If it builds it sits.
## Validation Steps Performed
* [x] Build new PGO instrument data with this pipeline update: https://dev.azure.com/microsoft/Dart/_build/results?buildId=44304850&view=results
More fallout from the settings refactor. Probably because testing on a Windows
10 device is hard, because you actually need a physical machine to get acrylic
to behave correctly.
Basically, the code is simpler now, but we missed the windows 10 only edge case
where acrylic can get turned on, but we forget to enable the acrylic brush, so
it just stays off.
Refer to #11619 where this regressed, and #11643, #12229, because this is just a
hard problem apparently
* [x] Closes#11743. Technically OP is complaining about behavior that's
by-design, but it made me realize this regressed in 1.12.
* [ ] No tests on this part of the `TermControl` unfortunately.
* [x] Hauled out my old Win10 laptop to verify that opacity works right:
- [x] A fresh profile isn't created with any opacity
- [x] Mouse wheeling turns on acrylic
- [x] Using `opacity` only in the settings still stealthily enables acrylic
This will turn the feature on always from this point on. That means 1.13 Stble
would be the first Stable release to have this feature (unless we cherry-pick
this to 1.12 stable, which we may)
* [x] Closes#12220
* [x] I work here
Manifest validation won't accept migration/initialization of HKCU-based registry keys anymore. The enforcement scripts says that they should be defined in code instead. So here it is: defined in code insteead.
Retrieved from https://microsoft.visualstudio.com os.2020 OS official/rs_wdx_dxp_windev 67c720b628de4acefbc381891b7e7d29d387038e
Related work items: MSFT-37867666
[Git2Git] Merged PR 6881093: BUILD FIX: Reintroduce BOM to conhost manifests
Related work items: MSFT-37882151
Retrieved from https://microsoft.visualstudio.com os.2020 OS official/rs_wdx_dxp_windev b6f388b08b0b431ffc5663fe27eef260688febd6
I can find the commit where this regressed tomorrow if needed. In #10685 we stopped emitting these notifications while we were deferring cursor drawing. We however forgot to send the notification at the end of the defer.
This likely has a small perf impact. We however do need these cursor position events for IMEs to be able to track the cursor position (and low key for #10821)
* [x] regressed in #10685
* [x] Closes#11170
* [x] I work here
* [x] Tests added
This gets rid of warnings like
```
NU1102: Unable to find package Microsoft.NETCore.App.Host.win-x64 with version (= 3.1.21)
- Found 1 version(s) in TerminalDependencies [ Nearest version: 3.1.18 ]
```
Technically, there's a `NETCore.App.Host.3.1.21` that's out now. We _could_
migrate to that, but then we'd have to make sure to manually re-upload that
nuget package to our nuget feed, and then we'd still get this warning the
next time that package is updated.
Theoretically, there's a 6.x version too, but considering this is a debugging
tool, we don't care all that much.
* [x] I work here
* [x] Discussed this with Dustin
* [x] Gets rid of a SUPER TRIVIAL warning.
Since `AtlasEngine` prefers drawing without alpha for performance reasons,
calls to `EnableTransparentBackground` require a draw cycle.
This PR makes `Renderer::_NotifyPaintFrame` public and calls it.
Related to #9999.
## PR Checklist
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* Open Windows Terminal command palette
* Choose "Set background opacity..."
* Cycling through the items without selecting one
changes background opacity immediately ✅
`Renderer` owns the information of the hovered interval in `_hoveredInterval`
and provides no access to this information. We can only infer it from calls
to `PaintBufferGridLines`, if we're given the request to draw an underline
despite the previous call to `UpdateDrawingBrushes` not specifying it.
While it'd be possible to fix this and pass the underline flag to
`UpdateDrawingBrushes`, I personally consider this aspect of `Renderer` to be
a "leaky abstraction" as it's inherently incompatible with any engine not
working like `DxEngine`, such as the `AtlasEngine`. It's likely more
worthwhile to fundamentally change the `Renderer` architecture in the future.
## PR Checklist
* [x] Closes#11871
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* Launch pwsh.exe
* Hyperlinks are underlined when hovered ✅
* Launch WSL / bash
* Run `printf '\e]8;;http://example.com\e\\This is a link\e]8;;\e\\\n'`
* Hyperlink is underlined when hovered ✅
Less "merge conflict" and more "something that got missed in a merge".
The offending commits are
* 68ab807
* b3fab51
The Fuzzer build doesn't run on PR, so it didn't notice this couldn't build.
@carlos-zamora as an FYI
This commit also introduces a check that we are in an interactive
session before we perform handoff, so as to not break service accounts.
It also adds some tracing.
The only way to notice that LeaveCriticalSection() was called more
often than EnterCriticalSection() is by calling EnterCriticalSection()
again in the future, which will then deadlock.
Since this bug occurs on exit it wasn't noticeable with the old console lock.
With the new, stricter ticket lock this bug causes a fail-fast exit.
## PR Checklist
* [x] Closes#12168
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* Launch and then exit Windows Terminal
* OpenConsole cleanly exits ✅
This is a collection of fixes:
* dd213a5c18: This was a crash I discovered while investigating. Probably not the root cause crash, but a crash nonetheless.
* ba491212afcbafdabc89d88b78f1dc5076dea0c3...0b18ae4ed73cbb15452c7c15aefa0c2671db9605: A collection of fixes to _not_ create the window when we're about to handoff each of the new tabs, panes, to an elevated window. That should prevent us from starting up XAML at all, which should take care of #12169. Additionally, it'll prevent us from restoring the unelevated windows, which should resolve#12190
* The remainder of the commits where fixes for other weird edge cases as a part of this. Notably:
* ff72599189: Autopromote the first `split-pane` to a new tab, in the case that it's preceded with only `new-tab` actions that opened elevated windows.
#### checklist
* [x] I work here
* [x] Docs are fine
* [x] Closes#12190
* [x] Closes#12169
This commit correctly restores the previous opacity when the command palette
preview is cancelled. It includes an additional change in order to make the
`AdjustOpacity` setter consistent and symmetric with the `Opacity` getter.
## PR Checklist
* [x] Closes#12228
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* Open Windows Terminal command palette
* Choose "Set background opacity..."
* Cycle through the items without selecting one
* Press Escape
* Previous opacity is restored ✅
This minor change makes it possible to hot-reload the AtlasEngine shaders under
Windows Terminal. Launching an UWP application from Visual Studio doesn't
necessarily result in a working directory inside the project folder,
which makes relative file paths impractical. While the `__FILE__` macro is
compiler dependent it works under our build setup with MSVC at least.
## Validation Steps Performed
* Shader hot-reloading works under Windows Terminal ✅
With the introduction of a common `RenderSettings` class in 62c95b5,
`PaintBufferGridLines` was now uniformly called with a proper alpha-less
`COLORREF` argument. This commit crudely fixes the issue by forcing
the color to be fully opaque in the `DxEngine` class.
## PR Checklist
* [x] Closes#12223
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* Launch pwsh.exe
* Hyperlinks get underlines on hover ✅
When title updates are forwarded from the host to the client terminal,
they're passed over conpty in an `OSC 0` sequence. If there are any
control characters embedded in that title text it's essential they be
filtered out, otherwise they are likely to be misinterpreted by the VT
parser on the other side. This PR fixes a case where that sanitization
step was missed for titles initialized at startup.
Originally the sanitization step was handled in `DoSrvSetConsoleTitleW`,
which catches title changes made via VT escape sequences, or through the
console API, but missed the title initialization at startup. I've now
moved that sanitization code into the `CONSOLE_INFORMATION::SetTitle`
method, which should cover all cases.
This sanitization is only meant to occur when in "pty mode", though,
which we were originally establishing with an `IsInVtIoMode` call.
However, `IsInVtIoMode` does not return the correct result when the
title is set at startup, since the VT I/O thread is not initialized at
that point. So I've instead had to change that to an `InConptyMode`
call, which determines the conpty state from the launch args.
## Validation Steps Performed
I've manually confirmed the test case described in issue #12206 is now
working correctly.
However, the change to using `InConptyMode` caused some of the unit
tests to fail, because there isn't a real conpty connection when
testing. Fortunately there are some `EnableConptyModeForTests` methods
used by the unit tests to fake the appearance of a conpty connection,
and I just needed to add some additional state in one of those methods
to trigger the correct `InConptyMode` response.
Closes#12206
The atlas engine currently applies colors and flags (underline,
overline, ...) based on the first column in a glyph; this means that
every member of a ligature is drawn in the same color with the same
underline style.
This commit makes us look up cell color and flags based on the actual
buffer column it represents, so that ligatures can be printed in
multiple colors and with different underline styles.
## Summary of the Pull Request
This PR sets up a OneFuzz pipeline on Azure DevOps for our repo.
## Detailed Description of the Pull Request / Additional comments
- fuzz.yml: defines the stages and pipeline for ADO
- build-console-fuzzing: builds the solution in the Fuzzing configuration
- build-console-steps: omits a few tasks that are unnecessary for this build configuration
- sln and vcxproj changes: the solution wasn't building in CI. This makes sure that's fixed.
- fuzzing.md: a short guide on how to get OneFuzz set up and add a new fuzzer
## References
#7638
[Git2Git] Merged PR 6814613: conhost FT: skip a test that fails on OneCore
Fixes MSFT-33720056
Retrieved from https://microsoft.visualstudio.com os.2020 OS official/rs_wdx_dxp_windev 6410311eee21e9ce147464af89d35f3569d4d2b9
## Summary of the Pull Request
Disables the automatic adjustment of indistinguishable text (added in #11095) because of the concerns brought up in #11917. Also, the setting is hidden in the SUI for as long as this feature remains disabled.
## PR Checklist
* [ ] Closes #xxx
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [x] I work here
## Summary of the Pull Request
Prevents a potential null pointer crash in the export buffer action.
## PR Checklist
* [x] Closes#12170
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx
## Validation Steps Performed
Manually tested.
This commit replaces the console lock was replaced with a fair ticket
lock implementation, as only fair locks guarantee us that the renderer
(or other parts) can acquire the lock, once the VT parser has finally
released it.
This is related to #11794.
## Validation Steps Performed
* No obvious crashes ✅
* No text/VT performance regression ✅
* Cursor blinker starts/stops on focus/defocus of the window ✅
## Summary of the Pull Request
This PR moves the color table and related render settings, which are common to both conhost and Windows Terminal, into a shared class that can be accessed directly from the renderer. This avoids the overhead of having to look up these properties via the `IRenderData` interface, which relies on inefficient virtual function calls.
This also introduces the concept of color aliases, which determine the position in the color table that colors like the default foreground and background are stored. This allows the option of mapping them to one of the standard 16 colors, or to have their own separate table entries.
## References
This is a continuation of the color table refactoring started in #11602 and #11784. The color alias functionality is a prerequisite for supporting a default bold color as proposed in #11939. The color aliases could also be a way for us to replace the PowerShell color quirk for #6807.
## PR Checklist
* [x] Closes#12002
* [x] CLA signed.
* [ ] Tests added/passed
* [ ] Documentation updated.
* [ ] Schema updated.
* [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx
## Detailed Description of the Pull Request / Additional comments
In addition to the color table, this new `RenderSettings` class manages the blinking state, the code for adjusting indistinguishable colors, and various boolean properties used in the color calculations. These boolean properties are now stored in a `til::enumset` so they can all be managed through a single `SetRenderMode` API, and easily extended with additional modes that we're likely to need in the future.
In Windows Terminal we have an instance of `RenderSettings` stored in the `Terminal` class, and in conhost it's stored in the `Settings` class. In both cases, a reference to this class is passed to the `Renderer` constructor, so it now has direct access to that data. The renderer can then pass that reference to the render engines where it's needed in the `UpdateDrawingBrushes` method.
This means the renderer no longer needs the `IRenderData` interface to access the `GetAttributeColors`, `GetCursorColor`, or `IsScreenReversed` methods, so those have now been removed. We still need access to `GetAttributeColors` in certain accessibility code, though, so I've kept that method in the `IUIAData` interface, but the implementation just forwards to the `RenderSettings` class.
The implementation of the `RenderSettings::GetAttributeColors` method is loosely based on the original `Terminal` code, only the `CalculateRgbColors` call has now been incorporated directly into the code. This let us deduplicate some bits that were previously repeated in the section for adjusting indistinguishable colors. The last steps, where we calculate the alpha components, have now been split in to a separate `GetAttributeColorsWithAlpha` method, since that's typically not needed.
## Validation Steps Performed
There were quite a lot changes needed in the unit tests, but they're mostly straightforward replacements of one method call with another.
In the `TextAttributeTests`, where we were previously testing the `CalculateRgbColors` method, we're now running those tests though `RenderSettings::GetAttributeColors`, which incorporates the same functionality. The only complication is when testing the `IntenseIsBright` option, that needs to be set with an additional `SetRenderMode` call where previously it was just a parameter on `CalculateRgbColors`.
In the `ScreenBufferTests` and `TextBufferTests`, calls to `LookupAttributeColors` have again been replaced by the `RenderSettings::GetAttributeColors` method, which serves the same purpose, and calls to `IsScreenReversed` have been replaced with an appropriate `GetRenderMode` call. In the `VtRendererTests`, all the calls to `UpdateDrawingBrushes` now just need to be passed a reference to a `RenderSettings` instance.
This commit makes the following changes to `til::point/size/rectangle`
for the following reasons:
* Rename `rectangle` into `rect`
This will make the naming consistent with a later `small_rect` struct
as well as the existing Win32 POINT/SIZE/RECT structs.
* Standardizes til wrappers on `int32_t` instead of `ptrdiff_t`
Provides a consistent behavior between x86 and x64, preventing accidental
errors on x86, as it's less rigorously tested than x64. Additionally it
improves interop with MIDL3 which only supports fixed width integer types.
* Standardizes til wrappers on throwing `gsl::narrow_error`
Makes the behavior of our code more consistent.
* Makes all eligible functions `constexpr`
Because why not.
* Removes implicit constructors and conversion operators
This is a complex and controversial topic. My reasons are: You can't Ctrl+F
for an implicit conversion. This breaks most non-IDE engines, like the one on
GitHub or those we have internally at MS. This is important for me as these
implicit conversion operators aren't cost free. Narrowing integers itself,
as well as the boundary checks that need to be done have a certain,
fixed overhead each time. Additionally the lack of noexcept prevents
many advanced compiler optimizations. Removing their use entirely
drops conhost's code segment size by around ~6.5%.
## References
Preliminary work for #4015.
## PR Checklist
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
I'm mostly relying on our unit tests here. Both OpenConsole and WT appear to work fine.
In previous releases, we had the commandlines for the Command Prompt and PowerShell profiles unqualified, as `cmd.exe` and `powershell.exe`. This was bad - theoretically, that would have preferred the cmd that was in the CWD over the one in System32. Or, something could insert itself into the path, and you'd end up with a malicious `cmd.exe` before the real one.
In #11437, we made sure that the `userDefaults` are initiated with the fully qualified paths. However, that didn't fix the issue for folks who already had settings files.
In an effort to better prevent this kind of badness, if we see a profile _with a default profile guid_, AND the unqualified version of the path, then we'll stealth replace it with the fully qualified one.
* Related to #11437
* [x] fixes#12126
* [x] Tests added
Adds an action which can be used to change the opacity at runtime. This is a follow up to some of the other work I had been doing around opacity and settings previewing at the end of the year.
> edit: pseudo-spec
>
> * `adjustOpacity`:
> * `"opacity"`: (**required**) an integer number to set the opacity to.
> * `"relative"`: (defaults to `true`)
> * If false, set the opacity to the given value, which should be between [0, 100].
> * If true, then use `opacity` as a relative adjustment to the current opacity. So the implementation would get the current opacity for this pane, then add this action's opacity to that value. Should be between [-100, 100]
>
> This would allow both setting exactly 25% opacity with an action, and binding an action that increases/decreases the opacity one {amount}
It's preview-able too, which is neat.

* [x] Closes#11205
* [x] I work here
* [x] Docs updated: https://github.com/MicrosoftDocs/terminal/pull/477
When I added these macros in #11619, the real purpose was to make sure we don't forget to add new settings to these test mocks as well. However, I totally forgot to convert those. I guess that happens with a 1300 line diff ¯\\\_(ツ)_/¯
* [x] Is a codehealth thing
* [x] I work here
* [x] tests still pass
This was a simple oversight. No user profile ever has `connectionType` set, because why would they. So even for the Azure Shell, which needed this, the check would fail and we'd forget to duplicate the connectionType to the new profile.
* [x] I work here
* [x] Closes#12120
* [x] Tested manually
Title says it all. This is on by default, and we've committed to keeping it around. Having a velocity flag for it is redundant now.
* [x] Closes#11454
* [x] I work here
This adds an action for the context menu entry we added in #11062. That PR added support for exporting the buffer, exclusively through the tab item's context menu. This adds an action that can additionally be bound, which also can export the buffer to a file. This action accepts a `path` param. If empty/ommitted, then the Terminal will prompt for the file to export the buffer to.
* Does a part of #9700
* Spec in #11090, but I doubt this is contentious
* [x] This will satisfy #12052
* [x] I work here
* [x] docs added: https://github.com/MicrosoftDocs/terminal/pull/479
## Summary of the Pull Request
This is the resurrection of #8514 and #11310. WE determined that we didn't want to do #11308 after all, so this should be profile auto-elevation, without the warning.
This PR adds two features:
* the `elevate: bool` property to profiles
- If the user is running unelevated, **and** `elevate` is set to `true`, then instead of opening a new tab, we'll open an elevated Terminal window with the profile.
- Otherwise, we'll just open a new tab in the existing window. This includes cases where the window is elevated, and the profile is set to `elevate:false`. `elevate:false` basically just means "do nothing special with me".
* the `elevate: bool?` property to `NewTerminalArgs` (`newTab`, `splitPane`)
- This allows a user to create an action that will elevate the profile, even if the profile is not otherwise set to auto-elevate.
- `elevate:null` (_the default_) does not change the profile's elevation status. The action will use whatever is set by the profile.
- `elevate:true` will attempt to auto-elevate the profile
- `elevate:false` will do nothing special.
## References
* #5000 for obvious reasons
* Spec'd in #8455
## PR Checklist
* [x] Closes#632
* [x] I work here
* [x] Tests added/passed
* [ ] Requires documentation to be updated - sure does, but that'll come all at the end.
## Detailed Description of the Pull Request / Additional comments
After playing with de-elevation a bit, it turns out it behaves weirdly with packaged applications. I can try and ask `explorer.exe` to launch the process on our behalf. However, if the thing we're launching is an execution alias (`wt.exe`), and we're elevated, then the child process will _still launch elevated_.
There's also something super BODGEY at work here. `ShellExecute` is the function we use to ask the OS to elevate something for us. But `ShellExecute` needs to be able to send a window message to the process that called it (if the caller was a WINDOWS subsystem application). So if we die immediately after calling `ShellExecute`, then the elevated process never actually spawns - sad. So we're adding a helper process, `elevate-shim.exe`, that lives in our process. That'll be the one that actually calls `ShellExecute`, so that it can live for the duration of the UAC prompt.
## Validation Steps Performed
* Ran tests
* Opened a bunch of terminal tabs at various different elevation levels
* opened new splits too
* In the defaults (base layer) as well, for madness
Some settings to use for testing
<details>
```jsonc
"keybindings" :
[
////////// ELEVATION ///////////////
{ "keys": "f1", "name": "ELEVATED TAB", "icon": "\uEA18", "command": { "action": "newTab", "elevate": true } },
{ "keys": "f2", "name": "ELEVATED, Color", "icon": "\uEA18", "command": {
"action": "newTab", "elevate": true, "commandline": "PowerShell.exe", "startingDirectory": "C:\\Windows", "tabColor": "#bbaa00"
} },
{ "keys": "f3", "name": "unelevated ELEVATED", "icon": "🙃", "command": {
"action": "newTab", "elevate": false, "profile": "elevated cmd"
} },
//////////////////////////////
],
"profiles":
{
"defaults":
{
"elevate": true,
},
"list":
[
{
"hidden":false,
"name" : "cmd",
"commandline" : "cmd.exe",
"guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}",
"startingDirectory" : "%USERPROFILE%",
"opacity" : 20
},
{
"name" : "the COOLER cmd",
"commandline" : "c:\\windows\\system32\\cmd.exe",
"startingDirectory" : "%USERPROFILE%",
},
{
"name" : "the sneaky cmd",
"commandline" : "c:\\windows\\system32\\cmd.exe /k echo sneaky sneaks",
"startingDirectory" : "%USERPROFILE%",
},
{
"name": "elevated cmd",
"commandline": "cmd.exe /k echo This profile is always elevated",
"startingDirectory" : "well this is garbage",
"elevate": true,
"background": "#9C1C0C",
"tabColor": "#9C1C0C",
"colorScheme": "Desert"
},
{
"name": "unelevated cmd",
"commandline": "cmd.exe /k echo This profile is just as elevated as you started with",
"elevate": false,
"background": "#1C0C9C",
"tabColor": "#1C0C9C",
"colorScheme": "DotGov",
"useAcrylic": true
},
]
```
</details>
Also try:
* `wtd nt -p "elevated cmd" ; sp -p "elevated cmd"`
* `wtd nt -p "elevated cmd" ; nt -p "elevated cmd"`
This was merged manually via
```
git diff dev/migrie/f/non-terminal-content-elevation-warning dev/migrie/f/632-on-warning-dialog > ..\632.patch
git apply ..\632.patch --ignore-whitespace --reject
```
Revert "Fix environment block creation (#7401)"
This reverts commit 7886f16714.
(cherry picked from commit e46ba65665)
Revert "Always create a new environment block before we spawn a process (#7243)"
This reverts commit 849243af99.
(cherry picked from commit 4204d2535c)
(cherry picked from commit f8e8572c23)
(cherry picked from commit cb4c4f7b73)
(cherry picked from commit afb0cac3e3)
(cherry picked from commit b25dc74a1d)
(cherry picked from commit 5f7c66bc0c)
Fixes#7418
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
## Summary of the Pull Request
- add suport for light backgrounds
- make color tool use 90-97 and 100-107 sequences for fg/bg
- fix loops stop condition
<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? -->
## References
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx
<!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
additional improvements that I've seen while working on #12087
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
This commit fixes the compilation under VS 2022.1 and clang, by evaluating a
`static_assert(false)` safety check only when the template is instantiated.
This is achieved by making the assertion depend on the template parameter.
## Validation Steps Performed
* Host.EXE compiles under VS 17.1.0 Preview 3.0 (32110.40.d17.1) ✅
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
## Summary of the Pull Request
Add an action to restore the last closed pane or tab. When all you have is restoring last sessions everything looks like a `std::vector<ActionAndArgs>`.
<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? -->
## References
#9800
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Partially closes#960
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [x] Schema updated.
* [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx
<!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
- Keep a buffer of panes/tabs that were closed recently in the form of a list
of actions to remake it.
- To restore the pane or tab just run the list of actions.
- This (deliberately) does not restore the exact visual state as focus could
have changed / new panes might have been created in the mean time. Mostly
this means that restoring a pane will just attach to the currently focused
pane instead of whatever its old neighbor was.
- Buffer is limited to 100 entries which might as well be "infinite" by most reasonable
standards, but prevents complaints about there being memory leaks in long running
instances.
- The action name could be potentially changed, but it felt unwieldy as "restoreLastClosedPaneOrTab".
- This does not handle restoring the actual running contents of a pane.
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Colortool: add support for truecolor fg/bg and cursor
## PR Checklist
* [x] Closes#1160
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [x] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx
## Detailed Description of the Pull Request / Additional comments
- add support to RGB values in FOREGROUND/BACKGROUND keys of ini colorschemes.
- add support to parse and change cursor color
- add support for true rgb fg/bg to colortool, will only work for vt and default console as there's no way to set rgb values through the win api.
- this pr does not add support for exporting an colorscheme with rgb fg/bg
- this is my first time using C# so any feedback is appreciated.
## Validation Steps Performed
manual testing
This PR does two things, which are best viewed as atomic commits:
* e64ae7d: Move the `MangleStartingDirectoryForWSL` to `types/utils`. It doesn't _really_ make sense in `types`, since it's only really being used in a single place in TerminalConnection. However, TerminalConnection doesn't have tests, and types does. So this commit move the function there, and adds tests from #9223 to the types tests.
* 42036c5: This actually fixes the bug in #11994. Unfortunately, `wsl --cd` will try to treat paths starting with `//wsl$` as a linux-relative path, when the user almost certainly wanted a windows-relative one. So we'll mangle that back into a path that looks like `\\wsl$\foo\bar`.
* [x] closes#11994
* [x] I work here
* [x] tests added 🎉
As discussed. We're not going to be able to consistently get bugfixes below Vb anymore, so let's leave that as the MinVersion, so we can start adding features that depend on those bugfixes.
* [x] Closes#11371
I'm not 100% sure that this is the right solution, but it does seem to work well enough. This is unfortunately a classic heisenbug. It was already hard enough to repro originally, but attaching a debugger made it totally impossible to hit.
My theory is that it's possible for the GotFocus event to fire before the LayoutUpdated event does. If that were to occur, then we'd try to turn on the cursor timer before it exists, gracefully do nothing, then create the timer. In that case, we'd never get a subsequent message to start the blinking.
I tested that theory by just initializing the cursor blinker to our `_focused` state. In that case, if the control has already been focused at the time of the LayoutUpdated event, then we can init the cursor to the correct state. Testing that out, I couldn't once get this to repro, which makes me think this works. I've opened some 900 (<sup>hyperbole</sup>) tabs now, so I'm pretty confident I'd have seen it by now.
* Regressed in #10978
* [x] fixes#11411
* [x] I made sure I didn't regress #6586
* [x] I work here
This commit adds additional information to the persisted window layouts.
- Runtime tab titles
- Focus, Maximized, and Fullscreen modes.
Also,
- Adds actions for Set{Focus,FullScreen} that take a boolean
to work in addition to the current Toggle{Focus, Fullscreen} actions.
- Adds SetMaximized that takes a boolean.
This adds the capability to maximize (resp restore) a window using
standard terminal actions.
This also involves hooking up a good amount of state tracking between
the terminal page and the window to see when maximize state has changed
so that it can be persisted.
- These actions are not added to the default settings, but they could be.
The intention is that they could assist with automation (and was originally)
how I planned on persisting the state instead of augmenting the LaunchMode.
- The fullscreen/maximized saving isn't perfect because we don't have a
way to save the non-maximized/fullscreen size, so exiting the modes
won't restore whatever the previous size was.
References #9800Closes#11878Closes#11426
This PR makes sure profile appearances in SUI set both focused and unfocused members of the control. I totally forgot about the fact that the control is _unfocused_ in the SUI. Verified manually, I didn't think it deserved a gif.
* regressed in #11619
* Closes#11893
* I work here
This commit removes some pure virtual base classes from conhost,
found with the help of SizeBench. This reduces binary size by 5kB.
The reduction in code size however is the main benefit of this.
Additionally this fixes a mysterious, undebuggable crash in
~RenderThread(), caused by a Control Flow Guard failure when
the class was destroyed over its IRenderThread interface.
## PR Checklist
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* Printing text works ✅
* Printing VT works ✅
* Performance is alright ✅
When editing colors in the conhost properties dialog, and you select an
item to update (e.g. Screen Text, or Screen Background), the associated
color swatch for that item would be highlighted, but the RGB color
values weren't updated to reflect that selection. This PR fixes it so
the RGB values are now correctly refreshed.
I just copied the three lines used up update the color value fields from
the code that handles changes to the color swatch selection. I didn't
think it was worth pulling those three lines out into a separate
function.
## Validation Steps Performed
I've manually verified that the RGB values are now refreshed correctly
when selecting a color item to update.
Closes#1220
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
## Summary of the Pull Request
- Settings > Add a new profile
- Disable "Duplicate" button until a profile is selected

<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? -->
## References
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Should take care of #12056, once we can get a build to the a11y team (MAINTAINER EDIT: we unfortunately can't just say "closes #foo" for issues like this one, we need another team to validate the following build.)
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx
<!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
## Summary of the Pull Request
Adds a per-profile setting for setting the audio sound for the bell. The setting is `bellSound`, it accepts a path. We'll use the file at that path as the sound for the bell. If it doesn't exist, then oh well, so sound for you.
It'll also secretly accept an array of paths. If you provide an array, it will pick one at random.
## PR Checklist
* [x] Closes#8366
* [x] I work here
* [ ] Tests - lol this is the hackathon, I'm just messing around
* [ ] Requires documentation to be updated
## Validation Steps Performed
I'm not suggesting that anyone go to [this post](https://www.reddit.com/r/untitledgoosegame/comments/d77le4/honk_ringtones/) and download a zip full of `honk.mp3`s. I'm definitely not suggesting you add it to your settings like
```jsonc
"bellSound": [
"C:\\Users\\migrie\\Downloads\\memes\\honks\\Honk1.mp3",
"C:\\Users\\migrie\\Downloads\\memes\\honks\\Honk2.mp3",
"C:\\Users\\migrie\\Downloads\\memes\\honks\\Honk3.mp3",
"C:\\Users\\migrie\\Downloads\\memes\\honks\\Honk4.mp3",
"C:\\Users\\migrie\\Downloads\\memes\\honks\\Honk-muffled1.mp3",
"C:\\Users\\migrie\\Downloads\\memes\\honks\\Honk-muffled2.mp3",
"C:\\Users\\migrie\\Downloads\\memes\\honks\\Honk-muffled3.mp3"
]
```
No, don't do that.
https://user-images.githubusercontent.com/18356694/137389503-91e43dba-8f7b-4078-9d35-23ceb2ac9432.mp4
* [x] It surprisingly works elevated
* [x] We should probably accept env vars in these paths
* [x] We may only want one `MediaPlayer` per terminal, rather than one per pane
* [ ] We may want to validate the paths, and discard ones that don't exist.
* [x] alternatively, _meh_
Enables a series of tasks run against our release pipeline that validate the security and compliance status of our code in an automated fashion. These checks include:
- Component Governance - (we had this one, it was moved to here) - Inventories open-source components used in our build
- PREfast - C/C++ static analysis for common code errors and exploits
- Policheck - Searches source code, comments, and text for words that could be sensitive legally, culturally, or geopolitically
- Credscan - Looks for credentials left behind in the code/documents and build output files
- BinSkim - Searches for common vulnerabilities in binaries
- CheckCFlags - Validates that compile/link flags match the policies recommended by Windows engineering for inclusion into the OS product image
- CFGCheck/XFGCheck - Validates that the CFG and/or XFG settings were enabled at compile and link time to guard against control flow attacks.
We're also required to run the SBOM one, but that was done in a separate PR and we're still pending the detectors being updated.
## References
- #11948 - Move from CFG to XFG once XFG task folks get back to me on it
- #11949 - Enable bug filing for SecComp tasks
- #11950 - Bulk process bugs filed by SecComp tasks
- #11947 - Validate SBOM when checkers come online
## Checklist
- [x] - Fixes#10735
- [x] - Fixes#908
- [x] - I work here
- [x] - If it fits, it sits.
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
## Summary of the Pull Request
fix#11432
<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? -->
## References
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes#11432
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx
<!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
compiled and verified that "\~" , "/usr/bin" , "~/.config" and "/" as stating directory didn't get relative path resolve
verified that '.' did
Ensures the PowerShell Core profile's commandline is quoted. This allows
the profile to work correctly if there are files in place on the machine
(e.g. one called `C:\Program`) that prevent `CreateProcess()` from
invoking the un-quoted commandline.
## Validation Steps Performed
Created a file called `C:\Program` and opened the PowerShell profile in
terminal.
Closes#11717
Adds the Ansi-Color tool, completing #6470.
What started out as an experiment to see the support of ANSI support to
conhost, I wanted to write a Windows equivalent of Daniel Crisman's
[BASH script on tldp.org]. I didn't like how the BASH script hard coded
in whitespace and I thought Windows could do better. I applied
techniques to speed up the execution and tried to use the Command Script
batch language in ways that pushed the limits for what I thought it
could do. Running this from withing PowerShell, `&cmd /c ansi-color.cmd`,
I found out that the active code page is already 65001, but when ran
from a Command Prompt, the active code page depends on the regional
settings and I would have a dependency on CHCP to detect the active code
page, change to 65001 if necessary, and restore the previous code page
after running. I found it useful for designing color schemes and writing
shaders, and I started using an earlier version for logging bugs.
Initially it was a single script which I would dump every SGR
combination I could think of, and many which weren't implemented yet,
but as I was looking at other tools which had been written I wanted to
mimic the same output so I could do side-by-side comparisons. First I
wrote `crisman.def` and then `colortool.def`. So I had to align text.
Then output was slow for big tables so I wrote to an outbuffer and made
use of macros. I wanted to handle flags instead of needing to change
settings every time, so I added argument parsing and loading external
files.
It's a batch file that has some really useful purposes and does nothing
I've seen before.
I've ran every definition in a Command Prompt, with CP 437 and CP 65001
to make sure it works. Posted as a Gist on my account for about year, a
Portuguese (Brazilian as I recall), speaking user tried the Gist and it
was failing because CHCP is localized. I've taken an approach to try and
make it work for different localizations, but this is a potential
problem. I also ran every definition in PowerShell 7, shelling down to
`cmd` to actually run it. Lastly, I went through using the flags and
made sure that help would be shown. Error messages generate error levels
when the script exits, so those could be used to use this in an
automated test and catch if there was a problem with the script
executing. It won't be able to validate if the generated output shows
correctly, but it would fail if a definition file is missing or if it
needed to switch to Unicode and wasn't flagged or configured to do so.
For trying to build the table stub and headers, there is some debug code
which will output what was parsed. This is the last debug code in the
script itself, but I found it to be useful at times, so there is a
configuration setting which can turn that debug output back on.
Technically there is also a debug statement to break after adding the
macros and parsing the arguments, but before it does any configuration
changes, changes the code page, or anything. This was useful for making
changes to macros and being able to test them as well as making sure
that flags and arguments are parsed correctly. It was a rather cryptic
discovery to call `cmd /c exit -1073741510` to break out, so in part
that was my reason to leave this in. The definition files themselves
could be cleaned up further, but in both of them there are a lot of
Unicode codepoints that could be useful when defining division lines for
the headers so I opted to just comment them out. I initially had the
default definition to require Unicode, but now it just changes to a
non-Unicode output if it can't. And this brings up the last concern. The
way certain settings are set, is that they are defined in the
`__TABLE__` section of the definition file. With `PARSE_TABLE_DATA`,
the script looks line by line for `SET *` or `IF *` and if found it will
effectively eval that line. The definition files are written so that for
instance `SET "CELL= gYw "` could be used to set the code which is used.
`If` was allow so that there could be a test if Unicode were available
and set something different for ASCII and Unicode. But it also opens the
possibility that a rogue actor could create a `ansi-color.cmd`
definition file something like `SET "foo=bar" & DoSomethingBad.exe`.
First of all I'd be flattered that anyone would use this very niche
tool, but it is something I think which needs to be called out.
Essentially the definition files are just batch files, but they are
extremely limited to executing only one line at a time and only
supporting IF and SET commands. I think this is a minimal risk because
at that point batch files would already be more effective, but there
should also be an expectation that a batch file will run something and
the same may not be true for the heavily degraded definition files. I
think the risk is minimal but it is a risk I wanted to make clear. This
really showcases some interesting techniques and ideas, and I hope that
it is useful. All told, there are a couple years of incremental changes
in this PR.
Closes#6470
[BASH script on tldp.org]: https://tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html
The `IRenderData::GetDefaultBrushColors` method was intended to return
the default attributes from which the renderer would calculate the
default background color. It should always have been returning a default
`TextAttribute` object, but the conhost `RenderData` implementation was
mistakenly returning the active attributes instead. This resulted in
margin areas being filled with the wrong color. To correct that, this PR
simply replaces all usage of `GetDefaultBrushColors` with hardcoded
default attributes.
## Validation Steps Performed
I've manually checked the test case described in issue #11976 and
confirmed that the conhost margin areas are now correctly filled with
the default background color.
Closes#11976
When copying content from the terminal to the clipboard (with
formatting), a default background color needs to be set to fill the
unused area of the pasted block. Prior to this PR, that color was not
correctly set, so the pasted content did not match what was seen on
screen.
Windows Terminal previously used the default background from the initial
color scheme, so it didn't take palette changes into account.
OpenConsole did use the active default color, but didn't take the
reverse screen mode into account, so could end up using the foreground
rather than the background color.
In both case I've changed the code to lookup the runtime colors in the
same way that renderer does, so they should now match what is seen on
screen.
## Validation Steps Performed
I've manually confirmed that the background color is now correctly set
when copying from both Windows Terminal and OpenConsole.
Closes#11988
## Summary of the Pull Request
When a conhost window is resized, the cursor is temporarily hidden, and the visibility is restored when the resize is finished. However, it wasn't taking into account that the cursor may already have been hidden to start with, in which case it would mistakenly force the cursor to be visible. This PR now saves the initial state of the visibility, so it can be correctly restored.
## PR Checklist
* [x] Closes#12024
* [x] CLA signed.
* [ ] Tests added/passed
* [ ] Documentation updated.
* [ ] Schema updated.
* [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx
## Validation Steps Performed
I've manually verified that this fixes the issue, and the cursor is no longer forced to be visible when the window is resized.
Only look for PGO package if build mode targeted; add packages.config dependency to ease restoration
## PR Checklist
* [x] Closes#11978
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [x] Test of restore and build on fresh repo copy passed.
This PR attempts to minimize the amount of fiddling we do with the alpha
color components, by storing all colors with a zero alpha (the default
for `COLORREF` values) and then leaving it up to the renderer to adjust
the final alpha value as required (which it was already doing anyway).
This gets rid of the `argb.h` header file, which was originally being
used to produce `COLORREF` values with custom alpha components, and thus
is no longer required. Anywhere that was using the `ARGB` macro is now
using a standard `RGB` macro with a 0 alpha.
The `Utils::SetColorTableAlpha` method has also been removed, since that
was only really used to force an alpha of 255 on all the color table
entries, which isn't necessary.
There were also a number of places where we were using
`til::color::with_alpha`, to switch alpha components back and forth
between 0 and 255, which have now been removed. Some of these were
essentially noops, because the `til::color` class already applied the
appropriate alpha changes when converting from or to a `COLORREF`.
I've manually run a few attribute rendering tests to check that the
colors were still working correctly, and the default background color is
appropriately transparent when in acrylic mode.
Closes#11885
To unify with WinUI, we're going to share an engineering component of this particular NuGet package full of scripts and utilities to make PGOing things easier.
This basically removes all of the scripts that I ~blatantly stole~ copied from https://github.com/microsoft/microsoft-ui-xaml and moves to the NuGet package that the team generates instead. A bunch of build things had to be massaged to make it work in our pipeline.
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
## Summary of the Pull Request
Properly handle UTF-16 surrogates when calculating the position of matched pattern.
Fix#8709
<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? -->
## References
b88ffb21b0/src/buffer/out/search.cpp (L335-L339)
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [ ] Closes#8709
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx
<!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
use `Utf16Parser::Parse` to handle code points from U+010000 to U+10FFFF in UTF-16.
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed

also the case by @mas90 https://github.com/microsoft/terminal/issues/8709#issuecomment-884915485:

Microsoft will be providing a Software Bill of Materials for our products. This onboards the Windows Terminal product to the common engineering system task that can scavenge for this information within our build project (already recorded for internal compliance reasons) and present it in a machine-readable interchange format.
See also: https://devblogs.microsoft.com/engineering-at-microsoft/generating-software-bills-of-materials-sboms-with-spdx-at-microsoft/
This does not yet include packaging and distributing the SBOM with our final packages. We are waiting for that tooling to come online for MSIX. Guidance is "Coming Soon™️."
## References
- https://github.com/microsoft/dropvalidator/issues/216 - `cgmanifest.json` are not being pulled in yet, but I've been told internally this will fix it. I will double-check when I hear back on this issue.
## PR Checklist
* [x] Closes#11810
* [x] I work here
* [x] I ran it and I see the manifest generated.
00fe2b0 made the mistake of hashing the pointer of `NewTerminalArgs` instances
instead of their content. This commit calls `NewTerminalArgs::Hash` instead.
## PR Checklist
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* New test passes ✅
Some changes I had sitting around after working on #11153 that weren't
appropriate to put in that pr. Each commit should be independent if
particular ones are unwanted.
Slight overlap with #11305. There is some more code removal that can be
done after that is merged, specifically `AttachPane` can be deleted once
`SplitPane` handles adding multiple panes at once correctly.
## Details
- Makes `WalkTree` more useful, and closer to a real iterator. Add a
convenient `_FindPane` built on top of that.
- Coalesces `PrecalculateAutoSplit` and `PreCalculateCanSplit` since
they are basically identical logic.
- `Pane::Relayout` functionally did nothing because sizing was switched
to `star` sizing at some point in the past, so it was just deleted.
## Validation
Quick smoke test to make sure automatic splitting works, focus movement
still works correctly.
This commit enables /permissive- for all projects, as well as all other /Zc
flags not enabled by default by /permissive-. Some projects continue to be
built under /Zc:twoPhase- as JsonUtils.h fails to compile otherwise.
## PR Checklist
* [x] Closes#10703
* [x] I work here
* [x] Tests added/passed
## Summary of the Pull Request
Cleans up `ProfileViewModel`, `Profiles`, and `ProfilePageNavigationState` to move all of the view model responsibilities over to `ProfileViewModel`. We don't actually store the `ProfilePageNavigationState` anymore. We only use it as a way to transfer information to the new page.
## References
#9207 - Apply MVVM
## Detailed Description of the Pull Request / Additional comments
- I pulled out `ProfileViewModel` into its own file to keep things cleaner. It was getting pretty big.
- The font lists are now stored in a static location in `ProfileViewModel`, which means that we can reuse the same list between pages.
- the profile pivot was also moved to the `ProfileViewModel` and stored as a static value.
## Validation Steps Performed
✅ pivot behavior is the same
✅ font list is still populated
This commit serves two purposes:
* Simplify construction of hashes for non-trivial structs
This is especially helpful for ActionArgs
* Improve hash quality by not needlessly throwing away entropy
`til::hasher` is modeled after Rust's `std::hash::Hasher` and works similar.
The idea is simple: A stateful hash function can hash multiple unrelated fields,
without loosing entropy by running a finalizer after hashing each interim field.
This is especially useful for modern hash functions, which often have a wider
internal state than the output width. Additionally this improves performance
for hash functions with complex finalizers.
Most of this is of course a bit moot right now, considering that `til::hasher`
is still based on STL's FNV1a algorithm, which offers a very poor hash quality.
But counterintuitively, FNV1a actually benefits most from this PR: Since it
lacks a finalizer entirely, this commit greatly improves hash quality as
it encodes more data into FNV's state and thus improves randomness.
## PR Checklist
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* No unusual behavior ✅
## Summary of the Pull Request
This replaces the `std::bitset` for the `SgrSaveRestoreStackOptions` enum with a `til::enumset` type, thus avoiding the need to cast the `enum` to a `size_t` every time a value is set or tested.
This also fixes an issue with the handling of omitted and zero parameters in the `XTPUSHSGR` sequence, which are meant to be ignored, and not interpreted as "all".
## PR Checklist
* [x] Closes#11879
* [x] Closes#11883
* [x] CLA signed.
* [ ] Tests added/passed
* [ ] Documentation updated.
* [ ] Schema updated.
* [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx
## Detailed Description of the Pull Request / Additional comments
In addition to dropping all the `static_cast` operations, the use of the `til::enumset` also allowed us to get rid of the `try`/`catch` handling that was previously required in a couple of places, since the `til::enumset` operations don't throw.
And to fix the zero parameter handling, we just needed to add an additional lower bound when validating that options are in range - if an option is 0 (`All`), it will now just be ignored.
## Validation Steps Performed
The updated code still passes the existing unit tests, and I've manually confirmed that it fixes the test case for omitted and zero parameters from issue #11883.
* Adds the `cppwinrt_utils.h` to the include path for all winrt projects.
* Adds the file to the pch.h's for every project, so you don't need to include it in every header.
* Replaces some usages of `DECLARE_EVENT`/`DEFINE_EVENT` with `WINRT_CALLBACK`, which will do it in a oneliner
* Adds more `BASIC_FACTORY` usage.
* [x] Closes#2456
It's 92 files with one-line changes, don't be scared.
This adds x-macros for each of the actions, greatly reducing the amount of boilerplate needed for each action args.
Originally, I wanted to do more with this, but I think the x-macros we've discovered properly treads the line of ease-of-use and native c++ support, with how much it'll do for us
* [x] Closes#3475
* [x] Sure enough, the tests still pass.
* [ ] mmmmmmm 
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
## Summary of the Pull Request
Clean up an invalid access that I introduced in #11440
<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? -->
## References
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes#11684
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx
<!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
## Summary of the Pull Request
This PR gets rids of the unused `RendererTests.cpp` file and removes
the `Renderer::s_CreateInstance` method declarations that were only
ever reference from that file, and weren't actually defined anywhere.
## PR Checklist
* [x] Closes#11870
* [x] CLA signed.
* [ ] Tests added/passed
* [ ] Documentation updated.
* [ ] Schema updated.
* [ ] I've not discussed this with core contributors already.
## Validation Steps Performed
Compiled the solution and ran the tests - everything still worked.
We have been advised to give not only the PDB paths, but paths to the EXE and DLL files we produce, to the PublishSymbols build task. We are assured by our engineering systems teams that enlightening the task to all of this information helps it hook things up better somewhere between our build machine and the symbol server such that debugging is more robust, especially around thrown exception stacks.
## PR Checklist
* [x] Closes#11737 - main fix for feeding EXEs and DLLs into the symbol publisher
* [x] Closes#11860 - bonus fix because I noticed the PDB source linking wasn't working
* [x] I work here.
* [x] If it fits, it sits.
## Summary of the Pull Request
Currently, the TermControl and ControlCore recieve a settings object that implements `IControlSettings`. They use for this for both reading the settings they should use, and also storing some runtime overrides to those settings (namely, `Opacity`). The object they recieve currently is a `T.S.M.TerminalSettings` object, as well as another `TerminalSettings` object if the user wants to have an `unfocusedAppearance`. All these are all hosted in the same process, so everything is fine and dandy.
With the upcoming move to having the Terminal split into multiple processes, this will no longer work. If the `ControlCore` in the Content Process is given a pointer to a `TerminalSettings` in a certain Window Process, and that control is subsequently moved to another window, then there's no guarantee that the original `TerminalSettings` object continues to exist. In this scenario, when window 1 is closed, now the Core is unable to read any settings, because the process that owned that object no longer exists.
The solution to this issue is to have the `ControlCore`'s own their own copy of the settings they were created with. that way, they can be confident those settings will always exist. Enter `ControlSettings`, a dumb struct for just storing all the contents of the Settings. I used x-macros for this, so that we don't need to copy-paste into this file every time we add a setting.
Changing this has all sorts of other fallout effects:
* Previewing a scheme/anything is a tad bit more annoying. Before, we could just sneak the previewed scheme into a `TerminalSettings` that lived between the settings we created the control with, and the settings they were actually using, and it would _just work_. Even explaining that here, it sounds like magic, because it was. However, now, the TermControl can't use a layered `TerminalSettings` for the settings anymore. Now we need to actually read out the current color table, and set the whole scheme when we change it. So now there's also a `Microsoft.Terminal.Core.Scheme` _struct_ for holding that data.
- Why a `struct`? Because that will go across the process boundary as a blob, rather than as a pointer to an object in the other process. That way we can transit the whole struct from window to core safely.
* A TermControl doesn't have a `IControlSettings` at all anymore - it initalizes itself via the settings in the `Core`. This will be useful for tear-out, when we need to have the `TermControl` initialize itself from just a `ControlCore`, without being able to rebuild the settings from scratch.
* The `TabTests` that were written under the assumption that the Control had a layered `TerminalSettings` obviously broke, as they were designed to. They've been modified to reflect the new reality.
* When we initialize the Control, we give it the settings and the `UnfocusedAppearance` all at once. If we don't give it an `unfocusedAppearance`, it will just use the focused appearance as the unfocused appearance.
* The Control no longer can _write_ settings to the `ControlSettings`. We don't want to be storing things in there. Pretty much everything we set in the control, we store somewhere other than in the settings object itself. However, `opacity` and `useAcrylic`, we need to store in a handy new `RUNTIME_SETTING` property. We can write those runtime overrides to those properties.
* We no longer store the color scheme for a pane in the persisted state. I'm tracking that in #9800. I don't think it's too hard to add back, but I wanted this in front of eyes sooner than later.
## References
* #1256
* #5000
* #9794 has the scheme previewing in it.
* #9818 is WAY more possible now.
## PR Checklist
* [x] Surprisingly there wasn't ever a card or issue for this one. This was only ever a bullet point in #5000.
* A bunch of these issues were fixed along the way, though I never intended to fix them:
* [x] Closes#11571
* [x] Closes#11586
* [x] Closes#7219
* [x] Closes#11067
* [x] I think #11623 actually ended up resolving this one, but I'm double tapping on it here: Closes#5703
* [x] I work here
* [x] Tests added/passed
* [n/a] Requires documentation to be updated
## Detailed Description of the Pull Request / Additional comments
Along the way I tried to clean up code where possible, but not too agressively.
I didn't end up converting the various `MockTerminalSettings` classes used in tests to the x macros quite yet. I wanted to merge this with #11416 in `main` before I went too crazy.
## Validation Steps Performed
* [x] Scheme previewing works
* [x] Adjusting the font size works
* [x] focused/unfocused appearances still work
* [x] mouse-wheeling opacity still works
* [x] acrylic & cleartype still does the right thing
* [x] saving the settings still works
* [x] going wild on sliding the opacity slider in the settings doesn't crash the terminal
* [x] toggling retro effects with a keybinding still works
* [x] toggling retro effects with the command palette works
* [x] The matrix of (`useAcrylic(true,false)`)x(`opacity(50,100)`)x(`antialiasingMode(cleartype, grayscale)`) works as expected. Slightly changed, falls back to grayscale more often, but looks more right.
Unfortunately, does not come up with a good inner loop for buidling the package from the commandline. The inner loop for the resources just sucks.
* [x] closes#926
Adds snap layout support to the Terminal's maximize button. This PR is
full of BODGY, so brace yourselves.
Big thanks to Chris Swan in #11134 for building the prototype.
I don't believe this solves #8795, because XAML islands can't get
nchittest messages
- The window procedure for the drag bar forwards clicks on its client
area to its parent as non-client clicks.
- BODGY: It also _manually_ handles the caption buttons. They exist in
the titlebar, and work reasonably well with just XAML, if the drag bar
isn't covering them.
- However, to get snap layout support, we need to actually return
`HTMAXBUTTON` where the maximize button is. If the drag bar doesn't
cover the caption buttons, then the core input site (which takes up
the entirety of the XAML island) will steal the `WM_NCHITTEST` before
we get a chance to handle it.
- So, the drag bar covers the caption buttons, and manually handles
hovering and pressing them when needed. This gives the impression that
they're getting input as they normally would, even if they're not
_really_ getting input via XAML.
- We also need to manually display the button tooltips now, because XAML
doesn't know when they've been hovered for long enough. Hence, the
`_displayToolTip` `ThrottledFuncTrailing`
## Validation
Minimized, maximized, restored down, hovered the buttons slowly, moved
the mouse over them quickly, they feel the same as before. But now with
snap layouts appearing.
## TODO!
* [x] I'm working on getting the ToolTips on the caption buttons back. Alas, I needed a demo of this _today_, so I'll fix that tomorrow morning.
* [x] mild concern: I should probably test Win 10 to make sure there wasn't weird changes to the message loop in win11 that means this is broken on win10.
* [x] I think I used the wrong issue number for tons of my comments throughout this PR. Double check that. Should be #9443, not #9447.
Closes#9443
I thought this took care of #8587 ~as a bonus, because I was here, and the fix is _now_ trivial~, but looking at the latest commit that regressed.
Co-authored-by: Chris Swan <chswan@microsoft.com>
This is a followup commit for 168d28b.
By renaming `IInheritable::InsertParent(com_ptr)` and
`InsertParent(size_t, com_ptr)` into `AddLeastImportantParent(com_ptr)`
and `AddMostImportantParent(com_ptr)` respectively, we can improve
the clarity of our code's intent without the need for comments.
## PR Checklist
* [x] I work here
* [x] Tests added/passed
As VS 2022 doesn't seem to store files with UTF-8 BOM as often anymore, we've
been getting more and more pull requests which seemingly randomly change files.
This cleans the situation up by removing the BOM from all files that have one.
Additionally, `Host.Tests.Feature.rc` was converted from UTF-16 to UTF-8.
This commit approximately doubles the performance of til::enumset
and reduces it's binary footprint by approximately 1kB.
Most of the binary size can be attributed to exception handling.
Unfortunately this commit removes assertions that the given values are less than
the number of bits in the `underlying_type`. However I believe this to be a good
trade-off as the tests previously only happened at runtime, while tests at
compile time would be highly preferable. Such tests are technically possible,
however MSVC fails to compile (valid) `static_assert`s containing
`static_cast`s over a parameter pack at the time of writing.
With future MSVC versions such checks can be added to this class.
This change was initially discussed in #10492, but was forgotten to
be considered before it was merged. Since the work was already done,
this commit re-introduces the optimization. It's free!
## PR Checklist
* [x] I work here.
* [x] Tests added/passed
## Validation Steps Performed
* Run `printf '\e]8;;http://example.com\e\\This is a link\e]8;;\e\\\n'` in WSL
* A wild dotted line appears ✔️
Since the settings UI's input fields behave similarly to the terminal's input,
`TerminalPage::_KeyDownHandler` also needs to behave similarly to
`TermControl::_KeyHandler`. This commit copies all relevant code
over from the latter into the former, including the suppression
of AltGr keys for keychord/action handling.
## PR Checklist
* [x] Closes#11788
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* Use a German keyboard layout
* Open 2 regular tabs and 1 settings tab and focus an input field
* AltGr+2 produces the character ² ✔️
* Ctrl+Alt+2 opens the second tab ✔️
This PR merges the default colors and cursor color into the main color
table, enabling us to simplify the `ConGetSet` and `ITerminalApi`
interfaces, with just two methods required for getting and setting any
form of color palette entry.
The is a follow-up to the color table standardization in #11602, and a
another small step towards de-duplicating `AdaptDispatch` and
`TerminalDispatch` for issue #3849. It should also make it easier to
support color queries (#3718) and a configurable bold color (#5682) in
the future.
On the conhost side, default colors could originally be either indexed
positions in the 16-color table, or separate standalone RGB values. With
the new system, the default colors will always be in the color table, so
we just need to track their index positions.
To make this work, those positions need to be calculated at startup
based on the loaded registry/shortcut settings, and updated when
settings are changed (this is handled in
`CalculateDefaultColorIndices`). But the plus side is that it's now much
easier to lookup the default color values for rendering.
For now the default colors in Windows Terminal use hardcoded positions,
because it doesn't need indexed default colors like conhost. But in the
future I'd like to extend the index handling to both terminals, so we
can eventually support the VT525 indexed color operations.
As for the cursor color, that was previously stored in the `Cursor`
class, which meant that it needed to be copied around in various places
where cursors were being instantiated. Now that it's managed separately
in the color table, a lot of that code is no longer required.
## Validation
Some of the unit test initialization code needed to be updated to setup
the color table and default index values as required for the new system.
There were also some adjustments needed to account for API changes, in
particular for methods that now take index values for the default colors
in place of COLORREFs. But for the most part, the essential behavior of
the tests remains unchanged.
I've also run a variety of manual tests looking at the legacy console
APIs as well as the various VT color sequences, and checking that
everything works as expected when color schemes are changed, both in
Windows Terminal and conhost, and in the latter case with both indexed
colors and RGB values.
Closes#11768
I'm pretty exactly following the diff from #917. These paths weren't wrapped in `"`s, so building the solution in a directory with a space in it would explode.
Closes#917.
Turns out, the diff provided by that user wasn't exactly right. I've tested building in a directory with spaces now, and this seems to work.
Also caught a bug in the Generate Feature Flags script.
I'm working on making the FastUpToDate check in Vs work for the Terminal project. This is one of a few PRs in this area.
FastUpToDate lets vs check quickly determine that it doesn't need to do anything for a given project.
However, a few of our projects don't produce all the right artifacts, or check too many things, and this eventually causes the `wapproj` to rebuild, EVERY TIME YOU F5 in VS.
This second PR deals with some projects MYSTERIOUSLY depending on the `.xaml` files from `Terminal.Control`, even when they by all accounts shouldn't. TerminalSettingsModel ISN'T EVEN A XAML project, so I have no idea why it thinks it needs these xaml files. The TerminalAppLib project thinking it needs them - makes more sense, but is still confusing.
Below are my verbatim notes, which led to the solution in this PR.
```
34>------ Up-To-Date check: Project: Microsoft.Terminal.Settings.Model.Lib, Configuration: Debug x64 ------
34>Project is not up-to-date: build output 'c:\users\migrie\dev\public\terminal\bin\x64\debug\microsoft.terminal.settings.model.lib\microsoft.terminal.control\searchboxcontrol.xaml' is missing
```
* Just copying the xaml files from `bin\x64\debug\microsoft.terminal.control\microsoft.terminal.control\*.xaml` to `bin\x64\debug\microsoft.terminal.settings.model.lib\microsoft.terminal.control` seemed to fix this.
* the .xbfs were already there
* It's very unclear why these were ever needed? They aren't used in the build for `Microsoft.Terminal.Settings.Model.Lib`. They aren't copied as a part of the build either - no .xaml files are copied at all in fact
* [ ] Does TSE have these .xamls in it's output?
* UPDATE: checking out main, and building again - ran into this again. WHY??
* Cleaned again, then built TerminalApp.vcxproj. File is no longer needed? nothing makes sense.
* `obj\x64\Debug\Microsoft.Terminal.Settings.Model.Lib\Microsof.CA5CAD1A.tlog\Microsoft.Terminal.Settings.Model.Lib.write.1u.tlog`:
```
C:\Users\migrie\dev\public\terminal\bin\x64\Debug\Microsoft.Terminal.Settings.Model.Lib\Microsoft.Terminal.Control\SearchBoxControl.xbf
C:\Users\migrie\dev\public\terminal\bin\x64\Debug\Microsoft.Terminal.Settings.Model.Lib\Microsoft.Terminal.Control\TermControl.xbf
C:\Users\migrie\dev\public\terminal\bin\x64\Debug\Microsoft.Terminal.Settings.Model.Lib\Microsoft.Terminal.Control\TSFInputControl.xbf
C:\Users\migrie\dev\public\terminal\bin\x64\Debug\Microsoft.Terminal.Settings.Model.Lib\Microsoft.UI.Xaml\Assets\NoiseAsset_256X256_PNG.png
C:\Users\migrie\dev\public\terminal\bin\x64\Debug\Microsoft.Terminal.Settings.Model.Lib\Microsoft.Terminal.Control\SearchBoxControl.xbf
C:\Users\migrie\dev\public\terminal\bin\x64\Debug\Microsoft.Terminal.Settings.Model.Lib\Microsoft.Terminal.Control\TermControl.xbf
C:\Users\migrie\dev\public\terminal\bin\x64\Debug\Microsoft.Terminal.Settings.Model.Lib\Microsoft.Terminal.Control\TSFInputControl.xbf
C:\Users\migrie\dev\public\terminal\bin\x64\Debug\Microsoft.Terminal.Settings.Model.Lib\Microsoft.Terminal.Control\SearchBoxControl.xbf
C:\Users\migrie\dev\public\terminal\bin\x64\Debug\Microsoft.Terminal.Settings.Model.Lib\Microsoft.Terminal.Control\TermControl.xbf
C:\Users\migrie\dev\public\terminal\bin\x64\Debug\Microsoft.Terminal.Settings.Model.Lib\Microsoft.Terminal.Control\TSFInputControl.xbf
C:\Users\migrie\dev\public\terminal\bin\x64\Debug\Microsoft.Terminal.Settings.Model.Lib\Microsoft.Terminal.Control\SearchBoxControl.xaml
C:\Users\migrie\dev\public\terminal\bin\x64\Debug\Microsoft.Terminal.Settings.Model.Lib\Microsoft.Terminal.Control\TermControl.xaml
C:\Users\migrie\dev\public\terminal\bin\x64\Debug\Microsoft.Terminal.Settings.Model.Lib\Microsoft.Terminal.Control\TSFInputControl.xaml
```
From the build:
```
18>Target _CopyOutOfDateSourceItemsToOutputDirectory:
18> Skipping target "_CopyOutOfDateSourceItemsToOutputDirectory" because all output files are up-to-date with respect to the input files.
18> Input files:
18> C:\Users\migrie\dev\public\terminal\bin\x64\Debug\Microsoft.Terminal.Control\Microsoft.Terminal.Control\SearchBoxControl.xbf
18> C:\Users\migrie\dev\public\terminal\bin\x64\Debug\Microsoft.Terminal.Control\Microsoft.Terminal.Control\TermControl.xbf
18> C:\Users\migrie\dev\public\terminal\bin\x64\Debug\Microsoft.Terminal.Control\Microsoft.Terminal.Control\TSFInputControl.xbf
18> C:\Users\migrie\dev\public\terminal\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\runtimes\win10-x64\native\Microsoft.UI.Xaml\Assets\NoiseAsset_256X256_PNG.png
18> Output files:
18> C:\Users\migrie\dev\public\terminal\bin\x64\Debug\Microsoft.Terminal.Settings.Model.Lib\Microsoft.Terminal.Control\SearchBoxControl.xbf
18> C:\Users\migrie\dev\public\terminal\bin\x64\Debug\Microsoft.Terminal.Settings.Model.Lib\Microsoft.Terminal.Control\TermControl.xbf
18> C:\Users\migrie\dev\public\terminal\bin\x64\Debug\Microsoft.Terminal.Settings.Model.Lib\Microsoft.Terminal.Control\TSFInputControl.xbf
18> C:\Users\migrie\dev\public\terminal\bin\x64\Debug\Microsoft.Terminal.Settings.Model.Lib\Microsoft.UI.Xaml\Assets\NoiseAsset_256X256_PNG.png
```
* Hmm, `21>Project is not up-to-date: build output 'c:\users\migrie\dev\public\terminal\bin\x64\debug\terminalapplib\microsoft.terminal.control\searchboxcontrol.xaml' is missing`
as well.
That's what the original purpose of #865 was, but I went ahead and added some additiona text, now that we've got more of a flow for github figured out.
Closes#865
If msbuild is already on the path, we don't need to look for it.
Also,
> I know what I did. I installed VS 2022, which is a prerelease VS install. `tools\razzle` prefers the stable builds. I think I'm gonna remove that.
* [x] Closes#1313
* [x] Closes#11446
I'm working on making the FastUpToDate check in Vs work for the Terminal project. This is one of a few PRs in this area.
FastUpToDate lets vs check quickly determine that it doesn't need to do anything for a given project.
However, a few of our projects don't produce all the right artifacts, or check too many things, and this eventually causes the `wapproj` to rebuild, EVERY TIME YOU F5 in VS.
This first PR deals with the `.copycomplete` file in `obj\x64\debug\terminalconnection\`. Below are my verbatim notes, which led to the solution in this PR.
### Problem 1 ✅
* There were missing `.copycomplete` files across the repo.
```
obj\x64\debug\microsoft.terminal.settings.model.lib\microsoft.terminal.settings.modellib.vcxproj.copycomplete
obj\x64\debug\microsoft.terminal.settings.model\microsoft.terminal.settings.model.vcxproj.copycomplete
obj\x64\debug\terminalapplib\terminalapplib.vcxproj.copycomplete
obj\x64\debug\terminalapp\terminalapp.vcxproj.copycomplete
obj\x64\debug\terminalconnection\terminalconnection.vcxproj.copycomplete
```
- just making empty files there seemed good enough.
- Might be because the CopyLocal target was already there, but the task didn't ever run to create that file? Weird.
* UPDATE: checking out main, and building again - the `.copycomplete`s are gone. So that's something that can be improved.
* The only place I could find a reference was in `"obj\x64\Debug\TerminalConnection\TerminalConnection.vcxproj.FileListAbsolute.txt"`, which will get updated if you remove the line from that file (but no one seemingly writes it or mentiones it in the log)
* Deleting `bin\x64\Debug\TerminalConnection\cpprest142_2_10d.dll` then building the project did copy the file, but it didn't touch the copycomplete. Weird.
* Why does
- `TerminalConnection` think it needs this
- `Microsoft.Terminal.Settings.Model.Lib` have one
- `Microsoft.Terminal.Control*` **NOT** have one
* This file is a [`@(CopyUpToDateMarker)`](https://github.com/dotnet/msbuild/blob/main/src/Tasks/Microsoft.Common.CurrentVersion.targets#L392)
* The target [`_CopyFilesMarkedCopyLocal`](https://github.com/dotnet/msbuild/blob/main/src/Tasks/Microsoft.Common.CurrentVersion.targets#L4795) touches `@(CopyUpToDateMarker)`, when:
- `"'@(ReferencesCopiedInThisBuild)' != ''` and
- `'$(WroteAtLeastOneFile)' == 'true'"`
* In out build output:
```
6>Target _CopyFilesMarkedCopyLocal:
6> Using "Copy" task from assembly "Microsoft.Build.Tasks.Core, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
6> Task "Copy"
6> Did not copy from file "C:\Users\migrie\dev\public\terminal\bin\x64\Debug\TerminalConnection\cpprest142_2_10d.dll" to file "C:\Users\migrie\dev\public\terminal\bin\x64\Debug\TerminalConnection\cpprest142_2_10d.dll" because the "SkipUnchangedFiles" parameter was set to "true" in the project and the files' sizes and timestamps match.
6> Done executing task "Copy".
6> Task "Touch" skipped, due to false condition; ('@(ReferencesCopiedInThisBuild)' != '' and '$(WroteAtLeastOneFile)' == 'true') was evaluated as ('C:\Users\migrie\dev\public\terminal\bin\x64\Debug\TerminalConnection\cpprest142_2_10d.dll' != '' and 'False' == 'true').
```
- So `WroteAtLeastOneFile` should be true, when it's currently false. That _looks_ like it's set to true when the file does get copied, wheich did't happen because the copy was skipped.
- WAIT LOOK AT THAT MESSAGE. "Did not copy from file "
`"C:\Users\migrie\dev\public\terminal\bin\x64\Debug\TerminalConnection\cpprest142_2_10d.dll"` to file
`"C:\Users\migrie\dev\public\terminal\bin\x64\Debug\TerminalConnection\cpprest142_2_10d.dll"`
THESE ARE THE SAME FILE.
`@(ReferenceCopyLocalPaths)` is filled with the file already?!
- The Target `AppLocalFromInstalled` is the only other thing that references `cpprest142_2_10d.dll`.
- Even if you delete the `cpprest142_2_10d.dll`, then `_CopyFilesMarkedCopyLocal` still evaluates the Touch condition as false, and doesn't touch it.
- the `deployBinary()` function in `packages\vcpkg-cpprestsdk.2.10.14\scripts\buildsystems\msbuild\applocal.ps1` does the actual job of copying the file. It copies it outside of MsBuild, which prevents MsBuild from copying it, and now MsBuild thinks it shouldn't write the `.copycomplete` file itself.
I'm working on making the FastUpToDate check in Vs work for the Terminal project. This is one of a few PRs in this area.
FastUpToDate lets vs check quickly determine that it doesn't need to do anything for a given project.
However, a few of our projects don't produce all the right artifacts, or check too many things, and this eventually causes the `wapproj` to rebuild, EVERY TIME YOU F5 in VS.
This third PR deals with the Actual fast up to date check for the CascadiaPackage.wapproj. When #11804, #11805 and this PR are all merged, you should be able to just F5 the Terminal in VS, and then change NOTHING, and F5 it again, without doing a build at all.
The wapproj `GetResolvedWinMD` target tries to get a winmd from every cppwinrt
executable we put in the package. But we DON'T produce a winmd. This makes the
FastUpToDate check fail every time, and leads to the whole wapproj build
running even if you're just f5'ing the package. EVEN AFTER A SUCCESSFUL BUILD.
Setting GenerateWindowsMetadata=false is enough to tell the build system that
we don't produce one, and get it off our backs.
### teams chat where we figured this out
[3:38 PM] Dustin Howett
however, that's not the only thing that "GetTargetPath" checks.
[3:38 PM] Dustin Howett
oh yeah more info: wapproj calls GetTargetPath on all projects it references
[3:38 PM] Dustin Howett
when it calls GTP on WindowsTerminal.vcxproj it is getting back a winmd (!)
[3:39 PM] Dustin Howett
here's the magic
[3:39 PM] Dustin Howett

[3:39 PM] Dustin Howett
it checks if any Link items specify GenerateWindowsMetadata

Upgrades our SDK from 19041 (Windows 10 20H1) to 22000 (Windows 11 RTM).
The newer SDK is more compatible with /Zc:preprocessor
and will allow us to use newer Windows 11 APIs directly.
## PR Checklist
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* Compiles ✔️
* Runs ✔️
til::equals:
At the time of writing wmemcmp() is not an intrinsic for MSVC,
but the STL uses it to implement wide string comparisons.
This produces 3x the assembly _per_ comparison and increases
runtime by 2-3x for strings of medium length (16 characters)
and 5x or more for long strings (128 characters or more).
See: https://github.com/microsoft/STL/issues/2289
Additionally a number of case insensitive, locale unaware
helpers for prefix/suffix comparisons are introduced.
There are some code pages with "unmapped" code points in the C1 range,
which results in them being translated into Unicode C1 control codes,
even though that is not their intended use. To avoid having these
characters triggering unintentional escape sequences, this PR now
disables C1 controls by default.
Switching to ISO-2022 encoding will re-enable them, though, since that
is the most likely scenario in which they would be required. They can
also be explicitly enabled, even in UTF-8 mode, with the `DECAC1` escape
sequence.
What I've done is add a new mode to the `StateMachine` class that
controls whether C1 code points are interpreted as control characters or
not. When disabled, these code points are simply dropped from the
output, similar to the way a `NUL` is interpreted.
This isn't exactly the way they were handled in the v1 console (which I
think replaces them with the font _notdef_ glyph), but it matches the
XTerm behavior, which seems more appropriate considering this is in VT
mode. And it's worth noting that Windows Explorer seems to work the same
way.
As mentioned above, the mode can be enabled by designating the ISO-2022
coding system with a `DOCS` sequence, and it will be disabled again when
UTF-8 is designated. You can also enable it explicitly with a `DECAC1`
sequence (originally this was actually a DEC printer sequence, but it
doesn't seem unreasonable to use it in a terminal).
I've also extended the operations that save and restore "cursor state"
(e.g. `DECSC` and `DECRC`) to include the state of the C1 parser mode,
since it's closely tied to the code page and character sets which are
also saved there. Similarly, when a `DECSTR` sequence resets the code
page and character sets, I've now made it reset the C1 mode as well.
I should note that the new `StateMachine` mode is controlled via a
generic `SetParserMode` method (with a matching API in the `ConGetSet`
interface) to allow for easier addition of other modes in the future.
And I've reimplemented the existing ANSI/VT52 mode in terms of these
generic methods instead of it having to have its own separate APIs.
## Validation Steps Performed
Some of the unit tests for OSC sequences were using a C1 `0x9C` for the
string terminator, which doesn't work by default anymore. Since that's
not a good practice anyway, I thought it best to change those to a
standard 7-bit terminator. However, in tests that were explicitly
validating the C1 controls, I've just enabled the C1 parser mode at the
start of the tests in order to get them working again.
There were also some ANSI mode adapter tests that had to be updated to
account for the fact that it has now been reimplemented in terms of the
`SetParserMode` API.
I've added a new state machine test to validate the changes in behavior
when the C1 parser mode is enabled or disabled. And I've added an
adapter test to verify that the `DesignateCodingSystems` and
`AcceptC1Controls` methods toggle the C1 parser mode as expected.
I've manually verified the test cases in #10069 and #10310 to confirm
that they're no longer triggering control sequences by default.
Although, as I explained above, the C1 code points are completely
dropped from the output rather than displayed as _notdef_ glyphs. I
think this is a reasonable compromise though.
Closes#10069Closes#10310
This commit is a minimal fix in order to pass the
`IDWriteFontCollection` we create out of .ttf files residing next to our
binaries to the `IDWriteFontFallback::MapCharacters` call. The
`IDWriteTextFormat` is used in order to carry the font collection over
into `CustomTextLayout`.
## Validation
* Put `JetBrainsMono-Regular.ttf` into the binary output directory
* Modify `HKCU:\Console\*\FaceName` to `JetBrains Mono`
* Launch OpenConsole.exe
* OpenConsole uses JetBrains Mono ✔️Closes#11032Closes#11648
## Summary of the Pull Request
This creates an `elevated-state.json` that lives in `%LOCALAPPDATA%` next to `state.json`, that's only writable when elevated. It doesn't _use_ this file for anything, it just puts the framework down for use later.
It's _just like `ApplicationState`_. We'll use it the same way.
It's readable when unelevated, which is nice, but not writable. If you're dumb and try to write to the file when unelevated, it'll just silently do nothing.
If we try opening the file and find out the permissions are different, we'll _blow the file away entirely_. This is to prevent someone from renaming the original file (which they can do unelevated), then slapping a new file that's writable by them down in it's place.
## References
* We're going to use this in #11096, but these PRs need to be broken up.
## PR Checklist
* [x] Closes nothing
* [x] I work here
* [x] Tests added/passed
* [ ] Requires documentation to be updated - maybe? not sure we have docs on `state.json` at all yet
## Validation Steps Performed
I've played with this much more in `dev/migrie/f/non-terminal-content-elevation-warning`
###### followed by #11308, #11310
This commit introduces "AtlasEngine", a new text renderer based on DxEngine.
But unlike it, DirectWrite and Direct2D are only used to rasterize glyphs.
Blending and placing these glyphs into the target view is being done using
Direct3D and a simple HLSL shader. Since this new renderer more aggressively
assumes that the text is monospace, it simplifies the implementation:
The viewport is divided into cells, and its data is stored as a simple matrix.
Modifications to this matrix involve only simple pointer arithmetic and is easy
to understand. But just like with DxEngine however, DirectWrite
related code remains extremely complex and hard to understand.
Supported features:
* Basic text rendering with grayscale AA
* Foreground and background colors
* Emojis, including zero width joiners
* Underline, dotted underline, strikethrough
* Custom font axes and features
* Selections
* All cursor styles
* Full alpha support for all colors
* _Should_ work with Windows 7
Unsupported features:
* A more conservative GPU memory usage
The backing texture atlas for glyphs is grow-only and will not shrink.
After 256MB of memory is used up (~20k glyphs) text output
will be broken until the renderer is restarted.
* ClearType
* Remaining gridlines (left, right, top, bottom, double underline)
* Hyperlinks don't get full underlines if hovered in WT
* Softfonts
* Non-default line renditions
Performance:
* Runs at up to native display refresh rate
Unfortunately the frame rate often drops below refresh rate, due us
fighting over the buffer lock with other parts of the application.
* CPU consumption is up to halved compared to DxEngine
AtlasEngine is still highly unoptimized. Glyph hashing
consumes up to a third of the current CPU time.
* No regressions in WT performance
VT parsing and related buffer management takes up most of the CPU time (~85%),
due to which the AtlasEngine can't show any further improvements.
* ~2x improvement in raw text throughput in OpenConsole
compared to DxEngine running at 144 FPS
* ≥10x improvement in colored VT output in WT/OpenConsole
compared to DxEngine running at 144 FPS
Drag and drop does not work for WSL because paths are pasted as windows
paths having incorrect path separator and path root. This PR adds code
to correct the path in TerminalControl before pasting to WSL terminals.
One problem with this approach is that it assumes the default WSL
automount root of "/mnt". It would be possible to add a setting like
"WslDragAndDropMountRoot"... but I decided it if someone wants to change
automount location it would be simple enough just to create the "/mnt"
symlink in WSL.
## Validation
Couldn't find an obvious place to add a test. Manually tested
cut-n-paste from following paths:
- "c:\"
- "c:\subdir"
- "c:\subdir\subdir"
- "\\wsl.localhost\<distro>"
- \\wsl.localhost\<distro>\subdir"
Closes#331
6140fd9 causes a binary size regression in conhost.
This PR fixes most if not all of the regression, by replacing `FMT_STRING`
with `FMT_COMPILE` allowing us to drop most of the formatters built
into fmt during linking (for instance floating point formatters).
Additionally `std::wstring` was replaced with `fmt::basic_memory_buffer`
in the same vein as was done for VtEngine. Stack is
cheap and this prevents any unnecessary allocations.
## PR Checklist
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* vttest 11.2.5.3.6.7 and .8 (DECSTBM and SGR) complete successfully ✅
Retrieved from https://microsoft.visualstudio.com os.2020 OS official/rs_wdx_dxp_windev 063b86ac10af16cade5c0754adcbf27e7e9ae266
Related work items: MSFT-34534216, MSFT-36986009, MSFT-36986203
Fixes MSFT:34673647, at least I'm pretty sure. That's only ever hit a few
times externally, and internally it's hitting a lot on 1.9.1942 builds, which
doesn't really make any sense.
Window sends an event that requests exit from fullscreen then SC_RESTORE messages is sent and it is in fullscreen mode.
Closes#10607
## Validation Steps Performed
Border and tabbar now appear after exiting fullscreen via "win+arrow down".
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
## Summary of the Pull Request
Checked the link, skipping the redirect HTTP => HTTPS this way 0:-)
This one
http://azuredevopspodcast.clear-measure.com/kayla-cinnamon-and-rich-turner-on-devops-on-the-windows-terminal-team-episode-54
is still only available via HTTP, sadly.
<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? -->
## References
<http://www.runasradio.com/Shows/Show/645> is being redirected to <https://www.runasradio.com/Shows/Show/645>
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* N/A Closes #xxx
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* N/A Tests added/passed
* N/A Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* N/A Schema updated.
* [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx
<!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here -->
## ~~Detailed Description of the Pull Request / Additional comments~~
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Opened the link.
Implements `_MakePane` in `TerminalPage`, which creates a pane that then can be used to pass into another pane to split or to create a new tab with. Places where we split pane or create a new tab now use `_MakePane`.
## PR Checklist
* [x] Closes#11021
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [x] I work here
## Validation Steps Performed
Stands up to manual testing with multiple new pane/new tab commands as well as startup actions
## Summary of the Pull Request
In the original implementation, we used two different orderings for the color tables. The WT color table used ANSI order, while the conhost color table used a Windows-specific order. This PR standardizes on the ANSI color order everywhere, so the usage of indexed colors is consistent across both parts of the code base, which will hopefully allow more of the code to be shared one day.
## References
This is another small step towards de-duplicating `AdaptDispatch` and `TerminalDispatch` for issue #3849, and is essentially a followup to the SGR dispatch refactoring in PR #6728.
## PR Checklist
* [x] Closes#11461
* [x] CLA signed.
* [x] Tests added/passed
* [ ] Documentation updated.
* [ ] Schema updated.
* [x] I've discussed this with core contributors already. Issue number where discussion took place: #11461
## Detailed Description of the Pull Request / Additional comments
Conhost still needs to deal with legacy attributes using Windows color order, so those values now need to be transposed to ANSI colors order when creating a `TextAttribute` object. This is done with a simple mapping table, which also handles the translation of the default color entries, so it's actually slightly faster than the original code.
And when converting `TextAttribute` values back to legacy console attributes, we were already using a mapping table to handle the narrowing of 256-color values down to 16 colors, so we just needed to adjust that table to account for the translation from ANSI to Windows, and then could make use of the same table for both 256-color and 16-color values.
There are also a few places in conhost that read from or write to the color tables, and those now need to transpose the index values. I've addressed this by creating separate `SetLegacyColorTableEntry` and `GetLegacyColorTableEntry` methods in the `Settings` class which take care of the mapping, so it's now clearer in which cases the code is dealing with legacy values, and which are ANSI values.
These methods are used in the `SetConsoleScreenBufferInfoEx` and `GetConsoleScreenBufferInfoEx` APIs, as well as a few place where color preferences are handled (the registry, shortcut links, and the properties dialog), none of which are particularly sensitive to performance. However, we also use the legacy table when looking up the default colors for rendering (which happens a lot), so I've refactored that code so the default color calculations now only occur once per frame.
The plus side of all of this is that the VT code doesn't need to do the index translation anymore, so we can finally get rid of all the calls to `XTermToWindowsIndex`, and we no longer need a separate color table initialization method for conhost, so I was able to merge a number of color initialization methods into one. We also no longer need to translate from legacy values to ANSI when generating VT sequences for conpty.
The one exception to that is the 16-color VT renderer, which uses the `TextColor::GetLegacyIndex` method to approximate 16-color equivalents for RGB and 256-color values. Since that method returns a legacy index, it still needs to be translated to ANSI before it can be used in a VT sequence. But this should be no worse than it was before.
One more special case is conhost's secret _Color Selection_ feature. That uses `Ctrl`+Number and `Alt`+Number key sequences to highlight parts of the buffer, and the mapping from number to color is based on the Windows color order. So that mapping now needs to be transposed, but that's also not performance sensitive.
The only thing that I haven't bothered to update is the trace logging code in the `Telemetry` class, which logs the first 16 entries in the color table. Those entries are now going to be in a different order, but I didn't think that would be of great concern to anyone.
## Validation Steps Performed
A lot of unit tests needed to be updated to use ANSI color constants when setting indexed colors, where before they might have been expecting values in Windows order. But this replaced a wild mix of different constants, sometimes having to use bit shifting, as well as values mapped with `XTermToWindowsIndex`, so I think the tests are a whole lot clearer now. Only a few cases have been left with literal numbers where that seemed more appropriate.
In addition to getting the unit tests working, I've also manually tested the behaviour of all the console APIs which I thought could be affected by these changes, and confirmed that they produced the same results in the new code as they did in the original implementation.
This includes:
- `WriteConsoleOutput`
- `ReadConsoleOutput`
- `SetConsoleTextAttribute` with `WriteConsoleOutputCharacter`
- `FillConsoleOutputAttribute` and `FillConsoleOutputCharacter`
- `ScrollConsoleScreenBuffer`
- `GetConsoleScreenBufferInfo`
- `GetConsoleScreenBufferInfoEx`
- `SetConsoleScreenBufferInfoEx`
I've also manually tested changing colors via the console properties menu, the registry, and shortcut links, including setting default colors and popup colors. And I've tested that the "Quirks Mode" is still working as expected in PowerShell.
In terms of performance, I wrote a little test app that filled a 80x9999 buffer with random color combinations using `WriteConsoleOutput`, which I figured was likely to be the most performance sensitive call, and I think it now actually performs slightly better than the original implementation.
I've also tested similar code - just filling the visible window - with SGR VT sequences of various types, and the performance seems about the same as it was before.
#11404 changed `_OpenSettingsUI` to `OpenSettingsUI` in `TerminalPage`, but there is still one leftover reference to `_OpenSettingsUI`. This commit fixes that.
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
## Summary of the Pull Request
Adds ability for app to change system context menu
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes#9666
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Introduces X-macros to reduce the number of places we need to write essentially the same line of code but for a different setting (declaring it in the header file, in `Copy`, `LayerJson`, `ToJson`, etc).
## Summary of the Pull Request
There is a non-zero subset of applications that randomly output _Locking Shift_ escape sequences which will invoke a character set from G2 or G3 into the left half of the code table. If those G-sets are mapped to Latin1, that can result in the terminal producing output that appears to be broken. This PR now defaults all G-sets to ASCII, to prevent an unintentional _Locking Shift_ from having any effect.
## PR Checklist
* [x] Closes#10408
* [x] CLA signed.
* [ ] Tests added/passed
* [ ] Documentation updated.
* [ ] Schema updated.
* [x] I've discussed this with core contributors already. Issue number where discussion took place: #10408
## Detailed Description of the Pull Request / Additional comments
Most other modern terminals also default to ASCII in all G-sets, so this shouldn't break any modern applications. Legacy 8-bit applications may still expect the G2 and G3 sets mapped to Latin1, but they would also need to have the ISO-2022 encoding enabled, so we can keep them happy by setting G2 and G3 correctly when the ISO-2022 encoding is requested.
## Validation Steps Performed
I've manually confirmed that `echo -e "\en"` and `echo -e "\eo"` no longer have any visible effect on the output (at least without first invoking another character set into G2 or G3). I've also confirmed that they do still work as expected (i.e. selecting Latin1) after enabling the ISO-2022 encoding.
## Summary of the Pull Request
When we are on a settings UI tab, `_GetActiveControl` returns a `nullptr`, make sure not to try and focus it in that case
## PR Checklist
* [x] Closes#11633
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [x] I work here
## Validation Steps Performed
No longer crashes
This is a pretty obvious typo in retrospect. Never hit it before, because in all non-defterm windows, the `_startupActions` always has one action.
* [x] Closes#11463
FontInfoBase and it's descendents are missing noexcept annotations, which
virally forces other code to not be noexcept as well during AuditMode checks.
Apart from adding noexcept, this commit also
* Passes std::wstring_view by reference.
* Pass the FillLegacyNameBuffer argument as a simple pointer-to-array,
allowing us to fill the buffer with a single memcpy.
(gsl::span's iterators inhibit any internal STL optimizations.)
* Move operator== declarations inside the class to reduce code size.
All other changes are an effect of the virality of noexcept.
This is an offshoot from #11623.
## Validation Steps Performed
* It still compiles ✔️
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
## Summary of the Pull Request
Opt in setting to trim trailing white space when pasting a text into the terminal
<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? -->
## References
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes#9400
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx
<!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Manually testing to paste text with and without trailing white spaces, with and without the option activated
The "updates" key is an alternative "guid" key for fragment profiles.
But SettingsLoader::_appendProfile stores and deduplicates profiles according
to their "guid" only. We need to modify the function to optionally store
profiles by their "updates" key as well, otherwise multiple fragment
profiles without "guid" might collide as they produce the same default GUID.
## PR Checklist
* [x] Closes#11597
* [x] I work here
* [ ] Tests added/passed
* [ ] Schema updated.
* [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx
## Validation Steps Performed
* Unit tests pass ✔️
* Issue #11597 doesn't reproduce anymore ✔️
We don't actually have a hard date for 2.0 anymore, so I'm removing those dates to make room for 1.13, 1.14, etc. Also updated the list of milestones with the current state. We're actually doing pretty darn good (considering there was a bit of a global pandemic to contend with!)
This commit renames `Base64::s_Decode` into `Base64::Decode` and improves its
average performance on short strings of less than 200 characters by 4.5x.
This is achieved by implementing a classic base64 decoder that reads 4
characters at a time and produces 3 output bytes. Furthermore a small
128 byte lookup table is used to quickly map characters to values.
## PR Checklist
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* Run WSL in Windows Terminal
* Run `printf "\033]52;c;aHR0cHM6Ly9naXRodWIuY29tL21pY3Jvc29mdC90ZXJtaW5hbC9wdWxsLzExNDY3\a"`
* Clipboard contains `https://github.com/microsoft/terminal/pull/11467` ✔️
Instead of having a separate method for setting each mouse and keyboard
mode, this PR consolidates them all into a single method which takes a
mode parameter, and stores the modes in a `til::enumset` rather than
having a separate `bool` for each mode.
This enables us to get rid of a lot of boilerplate code, and makes the
code easier to extend when we want to introduce additional modes in the
future. It'll also makes it easier to read back the state of the various
modes when implementing the `DECRQM` query.
Most of the complication is in the `TerminalInput` class, which had to
be adjusted to work with an `enumset` in place of all the `bool` fields.
For the rest, it was largely a matter of replacing calls to all the old
mode setting methods with the new `SetInputMode` method, and deleting a
bunch of unused code.
One thing worth mentioning is that the `AdaptDispatch` implementation
used to have a `_ShouldPassThroughInputModeChange` method that was
called after every mode change. This code has now been moved up into the
`SetInputMode` implementation in `ConhostInternalGetSet` so it's just
handled in one place. Keeping this out of the dispatch class will also
be beneficial for sharing the implementation with `TerminalDispatch`.
## Validation
The updated interface necessitated some adjustments to the tests in
`AdapterTest` and `MouseInputTest`, but the essential structure of the
tests remains unchanged, and everything still passes.
I've also tested the keyboard and mouse modes in Vttest and confirmed
they still work at least as well as they did before (both conhost and
Windows Terminal), and I tested the alternate scroll mode manually
(conhost only).
Simplifying the `ConGetSet` and `ITerminalApi` is also part of the plan
to de-duplicate the `AdaptDispatch` and `TerminalDispatch`
implementation (#3849).
Fixes#11606
This is weird, but the infobars would appear totally on top of the
TerminalPage when `showTabsInTitlebar:false`. This would result in the infobar
obscuring the tabs.
Now, the infobars are strictly inserted after the tabs, before the content. So
when they appear, they will reduce the amount of space usable for the control.
That is a little annoying, but preferable to the tabs totally not existing.
Relevant conversation notes from #10798:
> > If the info bar is not local to the tab, then its location between the tab
> > bar (when the title bar is hidden) and the terminal panes feels
> > misleading. Should it instead be above the tab bar or below the terminal
> > panes?
>
> You're... not wrong here. It's maybe not the best place for it, but _on top_
> of the tabs would look insane, and probably wouldn't even work easily, given
> the way we reparent the tab row into the titlebar.
>
> In the pane itself would make more sense, but that runs abreast of all sorts
> of things like #9024, #4998, which might make more sense.
I'm just gonna go with this now, because it's _better_ than before, while we
work out what's _best_.

After this commit OpenConsoleProxy will be built without a CRT.
This cuts down its binary size and DLL dependency bloat.
We hope that this fixes a COM server activation bug if the
user doesn't have a CRT installed globally on their system.
Fixes#11529
## Summary of the Pull Request
Ensures that the background image path is displayed in the settings UI.
## References
One of the items on #11353
## PR Checklist
* [x] Closes#11541
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
## Validation Steps Performed
Set the background image path and saw that it was displayed in the settings UI.
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
## Summary of the Pull Request
Moves baskgroung image update releated code into separate function and adds uri path construction exeption handling.
<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? -->
## References
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes#11361
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx
<!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Tried to put garbage as a path. Terminal didn't crashed.
[Git2Git] Merged PR 6303114: Prepare command history before COOKED_READ in tests
PR !6278637 introduced a dependency from COOKED_READ_DATA on the ability
to locate a command history for a process handle (here, `nullptr`).
The tests were blowing up because no such history had been allocated.
Closes MSFT-34812916
Closes MSFT-34813774
Closes MSFT-34815941
Closes MSFT-34817558
Closes MSFT-34817540 (Watson)
Retrieved from https://microsoft.visualstudio.com os.2020 OS official/rs_wdx_dxp_windev f7517e686447fc0469f6b83df19760dc3dafd577
This is equivalent to commit 8779249b1, but reflected from the OS repository.
Retrieved from https://microsoft.visualstudio.com os.2020 OS official/rs_wdx_dxp_windev a4d67e9b05039f365a1a0c58e9c63474c58073a1
Related work items: MSFT-34777060
Related work items: MSFT-32957145
Retrieved from https://microsoft.visualstudio.com os.2020 OS official/rs_wdx_dxp_windev bdb25dc99dcb2f1ee483dffe883d0178ea9d18dc
As identified by Michael Niksa, our MDE heuristics for understanding relationship between conhost and related processes was incorrect. Exposing trace here to assist in correlation.
Related work items: MSFT-32957145
Retrieved from https://microsoft.visualstudio.com os.2020 OS official/rs_wdx_dxp_windev 3c886da66d77d1aa36b52794929e388af292539c
Fix unbound read of cooked read buffer
Retrieved from https://microsoft.visualstudio.com os.2020 OS official/rs_wdx_dxp_windev 756c8dcd4cf9551f5bf090b98bf3fba5498f8eff
Related work items: MSFT-32957145
An internal change CommandLineToArgVW to an apiset.
Retrieved from https://microsoft.visualstudio.com os.2020 OS official/rs_wdx_dxp_windev a71b943e06c009085d6a2bb886dd50c2d0d2c276
Related work items: MSFT-32178383
2021-07-19 19:51:47 +00:00
1352 changed files with 55744 additions and 35488 deletions
@@ -99,15 +99,29 @@ If you don't have any additional info/context to add but would like to indicate
## Contributing fixes / features
For those able & willing to help fix issues and/or implement features ...
If you're able & willing to help fix issues and/or implement features, we'd love your contribution!
The best place to start is the list of ["Easy Starter"](https://github.com/microsoft/terminal/issues?q=is%3Aopen+is%3Aissue+label%3A%22Help+Wanted%22+label%3A%22Easy+Starter%22+) issues. These are bugs or tasks that we on the team believe would be easier to implement for someone without any prior experience in the codebase. Once you're feeling more comfortable in the codebase, feel free to just use the ["Help Wanted"](https://github.com/microsoft/terminal/issues?q=is%3Aopen+is%3Aissue+label%3A%22Help+Wanted%22+) label, or just find an issue your interested in and hop in!
Generally, we categorize issues in the following way, which is largely derived from our old internal work tracking system:
* ["Bugs"](https://github.com/microsoft/terminal/issues?q=is%3Aopen+is%3Aissue+label%3A%22Issue-Bug%22+) are parts of the Terminal & Console that are not quite working the right way. There's code to already support some scenario, but it's not quite working right. Fixing these is generally a matter of debugging the broken functionality and fixing the wrong code.
* ["Tasks"](https://github.com/microsoft/terminal/issues?q=is%3Aopen+is%3Aissue+label%3A%22Issue-Task%22+) are usually new pieces of functionality that aren't yet implemented for the Terminal/Console. These are usually smaller features, which we believe
- could be a single, atomic PR
- Don't require much design consideration, or we've already written the spec for the larger feature they belong to.
* ["Features"](https://github.com/microsoft/terminal/issues?q=is%3Aopen+is%3Aissue+label%3A%22Issue-Feature%22+) are larger pieces of new functionality. These are usually things we believe would require larger discussion of how they should be implemented, or they'll require some complicated new settings. They might just be features that are composed of many individual tasks. Often times, with features, we like to have a spec written before development work is started, to make sure we're all on the same page (see below).
Bugs and tasks are obviously the easiest to get started with, but don't feel afraid of features either! We've had some community members contribute some amazing "feature"-level work to the Terminal (albeit, with lots of discussion 😄).
Often, we like to assign issues that generally belong to somebody's area of expertise to the team member that owns that area. This doesn't mean the community can't jump in -- they should reach out and have a chat with the assignee to see if it'd okay to take. If an issue's been assigned more than a month ago, there's a good chance it's fair game to try yourself.
### To Spec or not to Spec
Some issues/features may be quick and simple to describe and understand. For such scenarios, once a team member has agreed with your approach, skip ahead to the section headed "Fork, Branch, and Create your PR", below.
Small issues that do not require a spec will be labelled Issue-Bug or Issue-Task.
Small issues that do not require a spec will be labelled `Issue-Bug` or `Issue-Task`.
However, some issues/features will require careful thought & formal design before implementation. For these scenarios, we'll request that a spec is written and the associated issue will be labeled Issue-Feature.
However, some issues/features will require careful thought & formal design before implementation. For these scenarios, we'll request that a spec is written and the associated issue will be labeled `Issue-Feature`. More often than not, we'll add such features to the ["Specification Tracker" project](https://github.com/microsoft/terminal/projects/1).
Specs help collaborators discuss different approaches to solve a problem, describe how the feature will behave, how the feature will impact the user, what happens if something goes wrong, etc. Driving towards agreement in a spec, before any code is written, often results in simpler code, and less wasted effort in the long run.
@@ -302,6 +299,7 @@ If you would like to ask a question that you feel doesn't warrant an issue
* Universal Windows Platform Development
* **The following Individual Components**
* C++ (v142) Universal Windows Platform Tools
* You must install the [.NET Framework Targeting Pack](https://docs.microsoft.com/dotnet/framework/install/guide-for-developers#to-install-the-net-framework-developer-pack-or-targeting-pack) to build test projects
## Building the Code
@@ -339,7 +337,9 @@ Solution Explorer) and go to properties. In the Debug menu, change "Application
process" and "Background task process" to "Native Only".
You should then be able to build & debug the Terminal project by hitting
<kbd>F5</kbd>.
<kbd>F5</kbd>. Make sure to select either the "x64" or the "x86" platform - the
Terminal doesn't build for "Any Cpu" (because the Terminal is a C++ application,
not a C# one).
> 👉 You will _not_ be able to launch the Terminal directly by running the
> WindowsTerminal.exe. For more details on why, see
<!-- Mandatory. Major version number of the PGO database which should match the version of the product. This can be hardcoded or obtained from other sources in build system. -->
<!-- Mandatory. Minor version number of the PGO database which should match the version of the product. This can be hardcoded or obtained from other sources in build system. -->
<!-- Mandatory, defaults to 0. Patch version number of the PGO database which should match the version of the product. This can be hardcoded or obtained from other sources in build system. -->
<!-- Optional, defaults to empty. Prerelease version number of the PGO database which should match the version of the product. This can be hardcoded or obtained from other sources in build system. -->
<!-- Copying the PGO runtime brings along a CRT. If we do that under normal circumstances, WAPPROJ will get its grubby hands on it and mess up all the CRT shenanigans we have to pull to make MSIX packages happy. So only pull it in for Instrument builds.-->
<!-- This file is read by XES, which we use in our Release builds. -->
<PropertyGroup Label="Version">
<!--
The Windows 11 build is going to have the same package name, so it *must* have a different version.
The easiest way for us to do this is to add 1 to the revision field.
In short, for a given Terminal build 1.11, we will emit two different versions (assume this is build
4 on day 23 of the year):
- 1.11.234.0 for Windows 10
- 1.11.235.0 for Windows 11
This presents a potential for conflicts if we want to ship two builds produced back to back on the
same day... which is terribly unlikely.
-->
<VersionBuildRevision Condition="'$(TerminalTargetWindowsVersion)'=='Win11' and '$(VersionBuildRevision)'!=''">$([MSBuild]::Add($(VersionBuildRevision), 1))</VersionBuildRevision>
@@ -163,7 +163,7 @@ Given that we're using Xaml islands to host a modern UI and stitching a DirectX
Now, the obvious followup question is _"why can't you have one elevated connection in a tab next to a non-elevated connection?"_ This is where @sba923 should pick up reading (:smile:). I'm probably going to cover some things that you (@robomac) know already.
[2] When you have two windows on the same desktop in the same window station, they can communicate with eachother. I can use `SendKeys` easily through `WScript.Shell` to send keyboard input to any window that the shell can see.
[2] When you have two windows on the same desktop in the same window station, they can communicate with eachother. I can use `SendKeys` easily through `WScript.Shell` to send keyboard input to any window that the shell can see.
Running a process elevated _severs_ that connection. The shell can't see the elevated window. No other program at the same integrity level as the shell can see the elevated window. Even if it has its window handle, it can't really interact with it. This is also why you can't drag/drop from explorer into notepad if notepad is running elevated. Only another elevated process can interact with another elevated window.
Most Nuget package references in this project are centralized in a single configuration so that there is a single canonical version for everything. This canonical version is restored before builds by the build pipeline, environment initialization scripts, or Visual Studio (as appropriate).
The canonical version numbers are defined in dep/nuget/packages.config. That defines what will be downloaded by nuget.exe. Most Nuget packages also have a .props and/or .targets file that must be imported by every project that consumes it. Those import statements are consolidated in:
- src/common.nugetversions.props
- src/common.nugetversions.targets
When a globally managed version changes all three of those files must be changed in unison.
Certain Nuget package references in this project, like `Microsoft.UI.Xaml`, must be updated outside of the Visual Studio NuGet package manager. This can be done using the snippet below.
> Note that to run this snippet, you need to use WSL as the command uses `sed`.
To update the version of a given package, use the following snippet
@@ -87,3 +96,46 @@ If you want to use .nupkg files instead of the downloaded Nuget package, you can
2. Create the folder /dep/packages
3. Put your .nupkg files in /dep/packages
4. If you are using different versions than those already being used, you need to update the references as well. How to do that is explained under "Updating Nuget package references".
## Building the Terminal package from the commandline
The Terminal is bundled as an `.msix`, which is produced by the `CascadiaPackage.wapproj` project. To build that project from the commandline, you can run the following (from a window you've already run `tools\razzle.cmd` in):
(yes, the cmd version is just calling powershell to do the powershell version. Too lazy to convert the rest by hand, I'm already copying from `.vscode\tasks.json`)
Building the package from VS generates the loose layout to begin with, and then registers the loose manifest, skipping the msix stop. It's a lot faster than the commandline inner loop here, unfortunately.
"description":"Sets the file location of the sound played when the application emits a BEL character. If the path is invalid no sound will be played. This property also accepts an array of sounds and the terminal will pick one at random.",
"oneOf":[
{
"type":[
"string",
"null"
]
},
{
"type":"array",
"items":{
"type":"string"
}
}
]
},
"AppearanceConfig":{
"properties":{
"colorScheme":{
@@ -281,6 +299,7 @@
"ShortcutActionName":{
"enum":[
"adjustFontSize",
"clearBuffer",
"closeOtherTabs",
"closePane",
"closeTab",
@@ -289,6 +308,7 @@
"commandPalette",
"copy",
"duplicateTab",
"exportBuffer",
"find",
"findMatch",
"focusPane",
@@ -298,6 +318,7 @@
"moveFocus",
"movePane",
"swapPane",
"markMode",
"moveTab",
"multipleActions",
"newTab",
@@ -329,14 +350,26 @@
"switchToTab",
"tabSearch",
"toggleAlwaysOnTop",
"toggleBlockSelection",
"toggleFocusMode",
"selectAll",
"setFocusMode",
"switchSelectionEndpoint",
"toggleFullscreen",
"setFullScreen",
"setMaximized",
"togglePaneZoom",
"toggleSplitOrientation",
"toggleReadOnlyMode",
"toggleShaderEffects",
"wt",
"quit",
"adjustOpacity",
"restoreLastClosed",
"addMark",
"scrollToMark",
"clearMark",
"clearAllMarks",
"unbound"
],
"type":"string"
@@ -356,6 +389,15 @@
],
"type":"string"
},
"ScrollToMarkDirection":{
"enum":[
"previous",
"next",
"first",
"last"
],
"type":"string"
},
"ResizeDirection":{
"enum":[
"left",
@@ -430,6 +472,14 @@
],
"type":"string"
},
"ClearBufferType":{
"enum":[
"all",
"screen",
"scrollback"
],
"type":"string"
},
"NewTerminalArgs":{
"properties":{
"commandline":{
@@ -465,6 +515,11 @@
"colorScheme":{
"description":"The name of a color scheme to use, instead of the one specified by the profile",
"type":"string"
},
"elevate":{
"type":"boolean",
"default":false,
"description":"This will override the profile's `elevate` setting."
}
},
"type":"object"
@@ -692,6 +747,30 @@
"direction"
]
},
"ScrollToMarkAction":{
"description":"Arguments corresponding to a Scroll to Mark Action",
"allOf":[
{
"$ref":"#/$defs/ShortcutAction"
},
{
"properties":{
"action":{
"type":"string",
"const":"scrollToMark"
},
"direction":{
"$ref":"#/$defs/ScrollToMarkDirection",
"default":"previous",
"description":"The direction to scroll to a mark."
}
}
}
],
"required":[
"direction"
]
},
"SendInputAction":{
"description":"Arguments corresponding to a Send Input Action",
"allOf":[
@@ -799,6 +878,27 @@
}
]
},
"AddMarkAction":{
"description":"Arguments corresponding to an Add Mark Action",
"allOf":[
{
"$ref":"#/$defs/ShortcutAction"
},
{
"properties":{
"action":{
"type":"string",
"const":"addMark"
},
"color":{
"$ref":"#/$defs/Color",
"default":null,
"description":"If provided, will set the mark's color to the given value."
}
}
}
]
},
"SetColorSchemeAction":{
"description":"Arguments corresponding to a Set Color Scheme Action",
"allOf":[
@@ -823,6 +923,66 @@
"colorScheme"
]
},
"SetFocusModeAction":{
"description":"Arguments for a setFocusMode action",
"allOf":[
{
"$ref":"#/$defs/ShortcutAction"
},
{
"properties":{
"action":{
"type":"string",
"const":"setFocusMode"
},
"isFocusMode":{
"type":"boolean",
"description":"whether focus mode is enabled"
}
}
}
]
},
"SetFullScreenAction":{
"description":"Arguments for a setFullScreen action",
"allOf":[
{
"$ref":"#/$defs/ShortcutAction"
},
{
"properties":{
"action":{
"type":"string",
"const":"setFullScreen"
},
"isFullScreen":{
"type":"boolean",
"description":"whether the window should be full screen"
}
}
}
]
},
"SetMaximizedAction":{
"description":"Arguments for a setMaximized action",
"allOf":[
{
"$ref":"#/$defs/ShortcutAction"
},
{
"properties":{
"action":{
"type":"string",
"const":"setMaximized"
},
"isMaximized":{
"type":"boolean",
"description":"whether the window should be maximized"
}
}
}
]
},
"WtAction":{
"description":"Arguments corresponding to a wt Action",
"allOf":[
@@ -1197,6 +1357,48 @@
}
]
},
"ClearBufferAction":{
"description":"Arguments corresponding to a clearBuffer Action",
"allOf":[
{
"$ref":"#/$defs/ShortcutAction"
},
{
"properties":{
"action":{
"type":"string",
"const":"clearBuffer"
},
"clear":{
"$ref":"#/$defs/ClearBufferType",
"default":"all",
"description":"What to clear. Accepts one of `screen`, `scrollback` or `all` (for both)."
}
}
}
]
},
"ExportBufferAction":{
"description":"Arguments corresponding to a exportBuffer Action",
"allOf":[
{
"$ref":"#/$defs/ShortcutAction"
},
{
"properties":{
"action":{
"type":"string",
"const":"exportBuffer"
},
"path":{
"type":"string",
"default":"",
"description":"The path to export the text buffer to. If left blank, the Terminal will open a file picker to choose the path."
}
}
}
]
},
"GlobalSummonAction":{
"description":"This is a special action that works globally in the OS, rather than only in the context of the terminal window. When pressed, this action will summon the terminal window.",
"allOf":[
@@ -1264,6 +1466,34 @@
}
]
},
"AdjustOpacityAction":{
"description":"Changes the opacity of the active Terminal window. If `relative` is specified, then this action will increase/decrease relative to the current opacity.",
"allOf":[
{
"$ref":"#/$defs/ShortcutAction"
},
{
"properties":{
"action":{
"type":"string",
"const":"adjustOpacity"
},
"opacity":{
"type":"integer",
"minimum":-100,
"maximum":100,
"default":0,
"description":"How opaque the terminal should become or how much the opacity should be changed by, depending on the value of `relative`"
},
"relative":{
"type":"boolean",
"default":true,
"description":"If true, then adjust the current opacity by the given `opacity` parameter, additively. If false, set the opacity to exactly that value."
}
}
}
]
},
"Keybinding":{
"additionalProperties":false,
"properties":{
@@ -1360,12 +1590,21 @@
{
"$ref":"#/$defs/FocusPaneAction"
},
{
"$ref":"#/$defs/ExportBufferAction"
},
{
"$ref":"#/$defs/ClearBufferAction"
},
{
"$ref":"#/$defs/GlobalSummonAction"
},
{
"$ref":"#/$defs/QuakeModeAction"
},
{
"$ref":"#/$defs/AdjustOpacityAction"
},
{
"type":"null"
}
@@ -1474,15 +1713,30 @@
"$ref":"#/$defs/CopyFormat"
},
"trimBlockSelection":{
"default":false,
"default":true,
"description":"When set to true, trailing white-spaces will be removed from text in rectangular (block) selection while copied to your clipboard. When set to false, the white-spaces will be preserved.",
"type":"boolean"
},
"trimPaste":{
"default":true,
"description":"When enabled, the Terminal will automatically trim trailing whitespace characters when pasting text",
"type":"boolean"
},
"experimental.detectURLs":{
"default":true,
"description":"When set to true, URLs will be detected by the Terminal. This will cause URLs to underline on hover and be clickable by pressing Ctrl.",
"type":"boolean"
},
"experimental.autoMarkPrompts":{
"default":false,
"description":"When set to true, prompts will automatically be marked.",
"type":"boolean"
},
"experimental.showMarksOnScrollbar":{
"default":false,
"description":"When set to true, marks added to the buffer via the addMark action will appear on the scrollbar.",
"type":"boolean"
},
"disableAnimations":{
"default":false,
"description":"When set to `true`, visual animations will be disabled across the application.",
@@ -1525,6 +1779,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.",
@@ -1545,7 +1804,7 @@
},
"startOnUserLogin":{
"default":false,
"description":"When set to true, this enables the launch of Windows Terminal at startup. Setting this to false will disable the startup task entry. If the Windows Terminal startup task entry is disabled either by org policy or by user action this setting will have no effect.",
"description":"When set to true, this enables the launch of Terminal at startup. Setting this to false will disable the startup task entry. If the Terminal startup task entry is disabled either by org policy or by user action this setting will have no effect.",
"type":"boolean"
},
"firstWindowPreference":{
@@ -1597,7 +1856,7 @@
},
"useAcrylicInTabRow":{
"default":false,
"description":"When set to true, the tab row will have an acrylic background with 50% opacity.",
"description":"When set to true, the tab row will have an acrylic material background with 50% opacity.",
"type":"boolean"
},
"actions":{
@@ -1822,6 +2081,10 @@
"description":"Controls what happens when the application emits a BEL character. When set to \"all\", the Terminal will play a sound, flash the taskbar icon (if the terminal window is not in focus) and flash the window. An array of specific behaviors can also be used. Supported array values include `audible`, `window` and `taskbar`. When set to \"none\", nothing will happen.",
"$ref":"#/$defs/BellStyle"
},
"bellSound":{
"description":"Sets the sound played when the application emits a BEL. When set to an array, the terminal will pick one of those sounds at random.",
"$ref":"#/$defs/BellSound"
},
"closeOnExit":{
"default":"graceful",
"description":"Sets how the profile reacts to termination or failure to launch. Possible values:\n -\"graceful\" (close when exit is typed or the process exits normally)\n -\"always\" (always close)\n -\"never\" (never close).\ntrue and false are accepted as synonyms for \"graceful\" and \"never\" respectively.",
@@ -1882,6 +2145,15 @@
],
"type":"string"
},
"elevate":{
"type":"boolean",
"default":false,
"description":"When true, this profile should always open in an elevated context. If the window isn't running as an Administrator, then a new elevated window will be created."
},
"experimental.connection.passthroughMode":{
"description":"When set to true, directs the PTY for this connection to use pass-through mode instead of the original Conhost PTY simulation engine. This is an experimental feature, and its continued existence is not guaranteed.",
"type":"boolean"
},
"experimental.retroTerminalEffect":{
"description":"When set to true, enable retro terminal effects. This is an experimental feature, and its continued existence is not guaranteed.",
"type":"boolean"
@@ -1890,6 +2162,11 @@
"description":"Use to set a path to a pixel shader to use with the Terminal. Overrides `experimental.retroTerminalEffect`. This is an experimental feature, and its continued existence is not guaranteed.",
"type":"string"
},
"experimental.useAtlasEngine":{
"description":"Enable using the experimental new rendering engine for this profile. This is an experimental feature, and its continued existence is not guaranteed.",
"type":"boolean",
"default":false
},
"fontFace":{
"default":"Cascadia Mono",
"description":"[deprecated] Define 'face' within the 'font' object instead.",
@@ -2050,7 +2327,7 @@
},
"useAcrylic":{
"default":false,
"description":"When set to true, the window will have an acrylic background. When set to false, the window will have a plain, untextured background.",
"description":"When set to true, the window will have an acrylic material background. When set to false, the window will have a plain, untextured background.",
OpenConsole can be built with a `Fuzzing` configuration. To set up a fuzzer, you'll need an `LLVMFuzzerTestOneInput` function. This serves as a way for the fuzzer to attach itself and inject tests into your fuzz target.
To build the fuzzer locally, build the OpenConsole solution in the `Fuzzing` configuration. This should output an executable that runs the fuzzer on the provided test case. In the case of PR #9604, the desired executable is located at `bin\x64\Fuzzing\OpenConsoleFuzzer.exe`.
OneFuzz allows us to run our fuzzers in CI and be alerted of new bugs found in this endeavor.
### Installing OneFuzz
You can download the latest OneFuzz CLI on their [releases page](https://github.com/microsoft/onefuzz/releases).
### Configuring OneFuzz
To run OneFuzz locally, you'll need to configure its endpoint, client ID, and client secret. Windows has a preset configuration available; this can be found at [this tutorial](https://www.osgwiki.com/wiki/Fuzzing_Service_-_Azure_Edge_and_Platform#Configure_OneFuzz_CLI) on osgwiki.
-`build`: the identifier for the build (i.e. commit SHA1)
-`pool`: the VM pool to run this on
-`exe_path`: the fuzzer executable output from building your project
This should also output more information (i.e. job ID) about the newly created job in a JSON format.
### Enabling notifications
**NOTE**: Our pipeline is already set up with this functionality. However, here is a quick guide on how to get it set up and modify it to our liking.
OneFuzz supports multiple notification systems at once including MS Teams and Azure DevOps. See the resources below to learn more about setting these up.
Our pipeline has been set up to create Azure DevOps work items.
This document outlines the roadmap of features we're planning for the Windows Terminal during 2022. This serves as a successor to the [Terminal v2 Roadmap], to reflect changes to our planning going forward.
Initially we had planned on a discrete "Terminal v2" goal, but over the last 18 months it's become clear to the team that we don't need a strict "2.0" release. We can continue serving the community effectively with continual, incremental updates. Should a future release warrant a substantial change to the Terminal worthy of the "2.0" moniker, we can re-evaluate then.
In 2022, we're going to try tracking our overall work with two "semester" milestones, "[22H1]" and "[22H2]", which roughly align with internal deadlines. Although the Windows Terminal ships updates out-of-band from the rest of the OS, we still have commitments to fixing bugs in the broader console ecosystem. Those changes need to be made in sync with the rest of the OS. Aligning our external milestones with those deadlines should help make sure we get bugs resolved in a timely fashion and checked into the OS.
These have additionally inherited the remainder of the work that was originally targeting the Terminal v2 milestone. As we burn down the features and bugs in these milestones, we'll draw new features into them from the "[Up Next]" milestone, which is itself populated from the highest-priority elements of the [Backlog].
## Milestones
Windows Terminal is engineered and delivered as a set of 6-week milestones. New features will go into [Windows Terminal Preview](https://aka.ms/terminal-preview) first, then a month after they've been in Preview, those features will move into [Windows Terminal](https://aka.ms/terminal). These timelines are rough estimates, not strict rules.
## Terminal Roadmap / Timeline
Below is the schedule for when milestones will be included in release builds of Windows Terminal and Windows Terminal Preview. The dates are rough estimates and are subject to change.
| Milestone End Date | Milestone Name | Preview Release Blog Post |
| 2020-06-18 | [1.1] in Windows Terminal Preview | [Windows Terminal Preview 1.1 Release](https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-1-release/) |
| 2020-07-31 | [1.2] in Windows Terminal Preview<br>[1.1] in Windows Terminal | [Windows Terminal Preview 1.2 Release] |
| 2020-08-31 | [1.3] in Windows Terminal Preview<br>[1.2] in Windows Terminal | [Windows Terminal Preview 1.3 Release] |
| 2020-09-30 | [1.4] in Windows Terminal Preview<br>[1.3] in Windows Terminal | [Windows Terminal Preview 1.4 Release] |
| 2020-11-30 | [1.5] in Windows Terminal Preview<br>[1.4] in Windows Terminal | [Windows Terminal Preview 1.5 Release] |
| 2021-01-31 | [1.6] in Windows Terminal Preview<br>[1.5] in Windows Terminal | [Windows Terminal Preview 1.6 Release] |
| 2021-03-01 | [1.7] in Windows Terminal Preview<br>[1.6] in Windows Terminal | [Windows Terminal Preview 1.7 Release] |
| 2021-04-14 | [1.8] in Windows Terminal Preview<br>[1.7] in Windows Terminal | [Windows Terminal Preview 1.8 Release] |
| 2021-05-31 | [1.9] in Windows Terminal Preview<br>[1.8] in Windows Terminal | [Windows Terminal Preview 1.9 Release] |
| 2021-07-14 | [1.10] in Windows Terminal Preview<br>[1.9] in Windows Terminal | [Windows Terminal Preview 1.10 Release] |
| 2021-08-31 | [1.11] in Windows Terminal Preview<br>[1.10] in Windows Terminal | [Windows Terminal Preview 1.11 Release] |
| 2021-10-20 | [1.12] in Windows Terminal Preview<br>[1.11] in Windows Terminal | [Windows Terminal Preview 1.12 Release] |
| 2022-02-03 | [1.13] in Windows Terminal Preview<br>[1.12] in Windows Terminal | [Windows Terminal Preview 1.13 Release] |
| 2022-05-24 | [1.14] in Windows Terminal Preview<br>[1.13] in Windows Terminal | [Windows Terminal Preview 1.14 Release] |
| | [1.15] in Windows Terminal Preview<br>[1.14] in Windows Terminal | |
| | [1.16] in Windows Terminal Preview<br>[1.15] in Windows Terminal | |
| | [1.17] in Windows Terminal Preview<br>[1.16] in Windows Terminal | |
### Release outline
Below is a VERY vague outline of the remaining calendar year that was drafted late May 2022. This was drafted for internal planning purposes, as a guide. It is not meant to represent official dates. More often than not, releases are synced to official features landing, rather than arbitrary dates. Drift from this initial draft is entirely expected.
```mermaid
gantt
title Proposed Terminal Releases 1.14-1.18
dateFormat YYYY-MM-DD
axisFormat %d %b
section Terminal 1.14
Lock down & bake :done, 2022-05-06, 2w
Release 1.14 :milestone, 2022-05-24
section Terminal 1.15
Features :done, a1, 2022-05-06, 4w
Bugfix :active, a2, after a1 , 1w
Lock down & bake :after a2 , 1w
Release 1.15 :milestone, 2022-06-21, 0
1.15 becomes Stable :milestone, after b3, 0
section Terminal 1.16
Features :b1, after a2, 4w
Bugfix :b2, after b1 , 2w
Lock down & bake :b3, after b2 , 2w
Release 1.16 :milestone, after b3, 0
1.16 becomes Stable :milestone, after c3, 0
section Terminal 1.17
Features :c1, after b2, 4w
Bugfix :c2, after c1 , 2w
Lock down & bake :c3, after c2 , 2w
Release 1.17 :milestone, after c3, 0
1.17 becomes Stable :milestone, after d3, 0
section Terminal 1.18
Features :d1, after c2, 4w
Bugfix :d2, after d1 , 2w
Lock down & bake :d3, after d2 , 2w
Release 1.18 :milestone, after d3, 0
```
## Issue Triage & Prioritization
Incoming issues/asks/etc. are triaged several times a week, labeled appropriately, and assigned to a milestone in priority order:
* P0 (serious crashes, data loss, etc.) issues are scheduled to be dealt with ASAP. These go in the current release milestone (e.g. at time of writing, these would go into 1.13).
* P1 issues/features/asks are typically assigned to the current or the following release milestone.
* P2 & P3 issues will typically go in the second semester for the year.
* Accessibility and Console issues that need to go into the Windows OS typically go into the current semester.
* Issues/features/asks not related to existing features in the 22H1/22H2 semesters are assigned to the [Backlog] for subsequent triage, prioritization & scheduling.
# Show Hide operations on GetConsoleWindow via PTY
## Abstract
To maintain compatibility with command-line tools, utilities, and tests that desire to
manipulate the final presentation window of their output through retrieving the raw
console window handle and performing `user32` operations against it like [ShowWindow](https://docs.microsoft.com//windows/win32/api/winuser/nf-winuser-showwindow),
we will create a compatibility layer that captures this intent and translates it into
the nearest equivalent in the cross-platform virtual terminal language and implement the
understanding of these sequences in our own Windows Terminal.
## Inspiration
When attempting to enable the Windows Terminal as the default terminal application on Windows
(to supersede the execution of command-line utilities inside the classic console host window),
we discovered that there were a bunch of automated tests, tools, and utilities that relied on
showing and hiding the console window using the `::GetConsoleWindow()` API in conjunction with
`::ShowWindow()`.
When we initially invented the ConPTY, we worked to ensure that we built to the common
denominator that would work cross-platform in all scenarios, avoiding situations that were
dependent on Windows-isms like `user32k` including the full knowledge of how windowing occurs
specific to the Windows platform.
We also understood that on Windows, the [**CreateProcess**](https://docs.microsoft.com/windows/win32/procthread/process-creation-flags) API provides ample flags specifically
for command-line applications to command the need for (or lack thereof) a window on startup
such as `CREATE_NEW_CONSOLE`, `CREATE_NO_WINDOW`, and `DETACHED_PROCESS`. The understanding
was that people who didn't need or want a window, or otherwise needed to manipulate the
console session, would use those flags on process creation to dictate the session. Additionally,
the `::CreateProcess` call will accept information in `STARTUPINFO` or `STARTUPINFOEX` that
can dictate the placement, size, and visibility of a window... including some fields specific
to console sessions. We had accepted those as ways applications would specify their intent.
Those assumptions have proven incorrect. Because it was too easy to just `::CreateProcess` in
the default manner and then get access to the session after-the-fact and manipulate it with
APIs like `::GetConsoleWindow()`, tooling and tests organically grew to make use of this process.
Instead of requesting up front that they didn't need a window or the overhead of a console session,
they would create one anyway by default and then manipulate it afterward to hide it, move it off-
screen, or otherwise push it around. Overall, this is terrible for their performance and overall
reliability because they've obscured their intent by not asking for it upfront and impacted their
performance by having the entire subsystem spin up interactive work when they intend to not use it.
But Windows is the place for compatibility, so we must react and compensate for the existing
non-ideal situation.
We will implement a mechanism to compensate for these that attempts to capture the intent of the
requests from the calling applications against the ConPTY and translates them into the "universal"
Virtual Terminal language to the best of its ability to make the same effects as prior to the
change to the new PTY + Terminal platform.
## Solution Design
Overall, there are three processes involved in this situation:
1. The client command-line application utility, tool, or test that will manipulate the window.
1. The console host (`conhost.exe` or `openconsole.exe`) operating in PTY mode.
1. The terminal (`windowsterminal.exe` when it's Windows Terminal, but could be a third party).
The following diagram shows the components and how they will interact.
1. The command-line tool calls `::GetConsoleWindow()` on the PTY host
2. The PTY host returns the raw `HWND` to the *Hidden Fake PTY Window* in its control
3. The command-line tool calls `::ShowWindow()` on the `user32.dll` API surface to manipulate that window.
4.`user32.dll` sends a message to the window message queue on the *Fake PTY Window*
5. The PTY host retrieves the message from the queue and translates it to a virtual terminal message
6. The Windows Terminal connection layer receives the virtual terminal message and decodes it into a window operation.
7. The true displayed *Windows Terminal Window* is told to change its status to show or hide.
8. The changed Show/Hide status is returned to the back-end on completion.
9. The Windows Terminal connection layer returns that information to the PTY host so it can remain in-the-know.
10. The PTY updates its *Fake PTY Window* status to match the real one so it continues to receive appropriate messages from `user32`.
This can be conceptually understood in a few phases:
- The client application grabs a handle and attempts to send a command via a back-channel through user32.
- User32 decides what message to send based on the window state of the handle.
- The message is translated by the PTY and propagated to the true visible window.
- The visible window state is returned back to the hidden/fake window to remain in synchronization so the next call to user32 can make the correct decision.
The communication between the PTY and the hosting terminal application occurs with a virtual terminal sequence.
Fortunately, *xterm* had already invented and implemented one for this behavior called **XTWINOPS** which means
we should be able to utilize that one and not worry about inventing our own Microsoft-specific thing. This ensures
that there is some precedence for what we're doing, guarantees a major third party terminal can support the same
sequence, and induces a high probability of other terminals already using it given *xterm* is the defacto standard
for terminal emulation.
Information about **XTWINOPS** can be found at [Xterm control sequences](https://invisible-island.net/xterm/ctlseqs/ctlseqs.html). Search for *XTWINOPS*.
The sequence is **CSI***Ps*; *Ps*; *Ps***t**. It starts with the common "control sequence initiator" of `ESC [` (`0x1B 0x5B`).
Then between 1 and 3 numerical parameters are given, separated by semicolons (`0x3B`).
And finally, the sequence is terminated with `t` (`0x74`).
Specifically, the two parameter commands of `1` for *De-iconify window* and `2` for *Iconify window* appear relevant to our interests.
In `user32` parlance, "iconify" traditionally corresponds to minimize/restore state and is a good proxy for overall visibility of the window.
The theory then is to detect when the assorted calls to `::ShowWindow()` against the *Fake PTY Window* are asking for a command that
maps to either "iconify" or "deiconify" and translate them into the corresponding message over the VT channel to the attached terminal.
To detect this, we need to use some heuristics inside the [window procedure](https://docs.microsoft.com/windows/win32/winmsg/window-procedures) for the window owned by the PTY.
Unfortunately, calls to `::ShowWindow()` on research with the team that owns `user32` do not go straight into the window message queue. Instead, they're dispatched straight into `win32k` to be analyzed and then trigger an array of follow on window messages into the queue depending on the `HWND`'s current state. Most specifically, they vary based on the `WS_VISIBLE` state of the `HWND`. (See [Window Styles](https://docs.microsoft.com/windows/win32/winmsg/window-styles) for details on the `WS_VISIBLE` flag.)
I evaluated a handful of messages with the help of the IXP Essentials team to see which ones would telegraph the changes from `::ShowWindow()` into our window procedure:
- [WM_QUERYOPEN](https://docs.microsoft.com/windows/win32/winmsg/wm-queryopen) - This one allows us to accept/reject a minimize/restore call. Not really useful for finding out current state
- [WM_SYSCOMMAND](https://docs.microsoft.com/windows/win32/menurc/wm-syscommand) - This one is what is called when the minimize, maximize/restore, and exit buttons are called in the window toolbar. But apparently it is not generated for these requests coming from outside the window itself through the `user32` APIs.
- [WM_SHOWWINDOW](https://docs.microsoft.com/windows/win32/winmsg/wm-showwindow) - This one provides some insight in certain transitions, specifically around force hiding and showing. When the `lParam` is `0`, we're supposed to know that someone explicitly called `::ShowWindow()` to show or hide with the `wParam` being a `BOOL` where `TRUE` is "show" and `FALSE` is "hide". We can translate that into *de-iconify* and *iconify* respectively.
- [WM_WINDOWPOSCHANGING](https://docs.microsoft.com/windows/win32/winmsg/wm-windowposchanging) - This one I evaluated extensively as it looked to provide us insight into how the window was about to change before it did so and offered us the opportunity to veto some of those changes (for instance, if we wanted to remain invisible while propagating a "show" message). I'll detail more about this one in a sub-heading below.
- [WM_SIZE](https://docs.microsoft.com/windows/win32/winmsg/wm-size) - This one has a `wParam` that specifically sends `SIZE_MINIMIZED` (`1`) and `SIZE_RESTORED` (`0`) that should translate into *iconify* and *de-iconify respectively.
#### WM_WINDOWPOSCHANGING data
In investigating `WM_WINDOWPOSCHANGING`, I built a table of some of the states I observed while receiving messages from an external caller that was using `::ShowWindow()`:
- integer - The value of the Show Window constant `SW_*` (see [ShowWindow](https://docs.microsoft.com/windows/win32/api/winuser/nf-winuser-showwindow))
- constant - The name of the Show Window constant
- flags - The `lParam` field is a pointer to a [**WINDOWPOS**](https://docs.microsoft.com/windows/win32/api/winuser/ns-winuser-windowpos) structure during this message. This the `UINT flags` field of that structure.
- Should Hide? - Whether or not I believe that the window should hide if this constant is seen. (Conversely, should show on the opposite.)
- minimizing - This is the `BOOL` response from a call to [**IsIconic()**](https://docs.microsoft.com/windows/win32/api/winuser/nf-winuser-isiconic) during this message.
- maximizing - This is the `BOOL` response from a call to [**IsZoomed()**](https://docs.microsoft.com/windows/win32/api/winuser/nf-winuser-iszoomed) during this message.
- showing - This is whether `SWP_SHOWWINDOW` is set on the `WINDOWPOS.flags` field during this message.
- hiding - This is whether `SWP_HIDEWINDOW` is set on the `WINDOWPOS.flags` field during this message.
- activating - This is the inverse of whether `SWP_NOACTIVATE` is set on the `WINDOWPOS.flags` field during this message.
- Remaining headings are `flags` values expanded to `X` is set and blank is unset. See [**SetWindowPos()**](https://docs.microsoft.com/windows/win32/api/winuser/nf-winuser-setwindowpos) for the definitions of all the flags.
From this data collection, I noticed a few things:
- The data in this table was unstable. The fields varied depending on the order in which I called the various constants against `ShowWindow()`. This is just one particular capture.
- Some of the states, I wouldn't see any message data at all (`SW_HIDE` and `SW_FORCEMINIMIZE`).
- There didn't seem to be a definitive way to use this data to reliably decide when to show or hide the window. I didn't have a reliable way of pulling this together with my *Should Hide?* column.
On further investigation, it became apparent that the values received were sometimes not coming through or varying because the `WS_VISIBLE` state of the `HWND` affected how `win32k` decided to dispatch messages and what values they contained. This is where I determined that steps #8-10 in the diagram above were going to be necessary: to report the state of the real window back to the *fake window* so it could report status to `user32` and `win32k` and receive state-appropriate messages.
For reporting back #8-10, I initially was going to use the `XTWINOPS` call with parameter `11`. The PTY could ask the attached terminal for its state and expect to hear back an answer of either `1` or `2` in the same format message depending on the state. However, on further consideration, I realized that the real window could change at a moments notice without prompting from the PTY, so I instead wrote the PTY to always listen for this and had the Windows Terminal send this back down unprompted.
#### Refined WM_SHOWWINDOW and WM_SIZE data
Upon setting up the synchronization for #8-10, I then tried again to build the table using just the two window messages that were giving me reliable data: `WM_SHOWWINDOW` and `WM_SIZE`:
|integer|constant|Should Hide?|`WM_SHOWWINDOW` OR `WM_SIZE` reported hide?|
|---|---|---|---|
|0|`SW_HIDE`|YES|YES|
|1|`SW_NORMAL`|NO|NO|
|2|`SW_SHOWMINIMIZED`|YES|YES|
|3|`SW_SHOWMAXIMIZED`|NO|NO|
|4|`SW_SHOWNOACTIVATE`|NO|NO|
|5|`SW_SHOW`|NO|NO|
|6|`SW_MINIMIZE`|YES|YES|
|7|`SW_SHOWMINNOACTIVE`|YES|YES|
|8|`SW_SHOWNA`|NO|NO|
|9|`SW_RESTORE`|NO|NO|
|10|`SW_SHOWDEFAULT`|NO|NO|
|11|`SW_FORCEMINIMIZE`|YES|YES|
Since this now matched up perfectly with what I was suspecting should happen *and* it was easier to implement than picking apart the `WM_WINDOWPOSCHANGING` message, it is what I believe the design should be.
Finally, with the *fake window* changing state to and from `WS_VISIBLE`... it was appearing on the screen and showing up in the taskbar and alt-tab. To resolve this, I utilized [**DWMWA_CLOAK**](https://docs.microsoft.com//windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute) which makes the window completely invisible even when in a normally `WS_VISIBLE` state. I then added the [**WS_EX_TOOLWINDOW**](https://docs.microsoft.com/windows/win32/winmsg/extended-window-styles) extended window style to hide it from alt-tab and taskbar.
With this setup, the PTY now has a completely invisible window with a synchronized `WS_VISIBLE` state with the real terminal window, a bidirectional signal channel to adjust the state between the terminal and PTY, and the ability to catch `user32` calls being made against the *fake window* that the PTY stands up for the client command-line application.
## UI/UX Design
The visible change in behavior is that a call to `::ShowWindow()` against the `::GetConsoleWindow()`
handle that is returned by the ConPTY will be propagated to the attached Terminal. As such, a
user will see the entire window be shown or hidden if one of the underlying attached
command-line applications requests a show or hide.
At the initial moment, the fact that the Terminal contains tabbed and/or paned sessions and
therefore multiple command-line clients on "different sessions" are attached to the same window
is partially ignored. If one attached client calls "show", the entire window will be shown with
all tabs. If another calls "hide", the entire window will be hidden including the other tab
that just requested a show. In the opposite direction, when the window is shown, all attached
PTYs for all tabs/panes will be alerted that they're now shown at once.
## Capabilities
### Accessibility
Users of assistive devices will have the same experience that they did with the legacy Windows
Console after this change. If a command-line application decides to show or hide the window
through the API without their consent, they will receive notification of the showing/hiding
window through our UIA framework.
Prior to this change, the window would have always remained visible and there would be no
action.
Overall, the experience will be consistent between what is happening on-screen and what is
presented through the UIA framework to assistive tools.
For third party terminals, it will be up to them to decide what their reaction and experience is.
### Security
We will maintain the security and integrity of the Terminal application chosen for presentation
by not revealing its true window handle information to the client process through the existing
`::GetConsoleWindow()` API. Through our design for default terminal applications, the final
presentation terminal could be Windows Terminal or it could be any third-party terminal that
meets the same specifications for communication. Giving raw access to its `HWND` to a client
application could disrupt its security.
By maintaining a level of separation with this feature by generating a "fake window" in the
ConPTY layer and only forwarding events, the attached terminal (whether ours or a 3rd party)
maintains the final level of control on whether or not it processes the message. This is
improved security over the legacy console host where the tool had full backdoor style access
to all `user32` based window APIs.
### Reliability
This test doesn't improve overall reliability in the system because utilities that are relying
on the behavior that this compatibility shim will restore are already introducing additional
layers of complexity and additional processes into their operation than were strictly necessary
simply by not stating their desires upfront at creation time.
In some capacity, you could argue it increases reliability of the existing tests that were
using this complex behavior in that they didn't work before and they will work now, but
the entire process is fragile. We're just restoring the fragile process instead of having
it not work at all.
### Compatibility
This change restores compatibility with existing applications that were relying on the behavior
we had excluded from our initial designs.
### Performance, Power, and Efficiency
The performance of tooling that is leveraging this process to create a console and then hide
or manipulate the session after the fact will be significantly worse when we enable the
default Windows Terminal than it was with the old Windows Console. This is because the
Terminal is significantly heavier weight (with its modern technologies like WinUI) and
will take more time to start and more committed memory. Additionally, more processes
will be in use because there will be the `conhost.exe` doing the ConPTY translation
and then the `windowsterminal.exe` doing the presentation.
However, this particular feature doesn't do anything to make that better or worse.
The appropriate solution for any tooling, test, or scenario that has a need for
performance and efficiency is to use the flags to `::CreateProcess` in the first place
to specify that they did not need a console window session at all, or to direct its
placement and visibility as a part of the creation call. We are working with
Microsoft's test automation tooling (TAEF) as well as the Windows performance
fundamentals (FUN) team to ensure that the test automation supports creating sessions
without a console window and that our internal performance test suite uses those
specifications on creation so we have accurate performance testing of the operating
system.
## Potential Issues
### Multiple clients sharing the same window host
With the initial design, multiple clients sharing the same window host will effectively
share the window state. Two different tabs or panes with two different client applications
could fight over the show/hide state of the window. In the initial revision, this is
ignored because this feature is being driven by a narrow failure scenario in the test gates.
In the reported scenario, a singular application is default-launched into a singular tab
in a terminal window and then the application expects to be able to hide it after the creation.
In the future, we may have to implement a conflict resolution or a graphical variance to
compensate for multiple tabs.
### Other verbs against the console window handle
This scenario initially focuses on just the `::ShowWindow()` call against the window handle
from `::GetConsoleWindow()`. Other functions from `user32` against the `HWND` will not
necessarily be captured and forwarded to the attached terminal application. And even more
specifically, we're focusing only on the Show and Hide state. Other state modifications that
are subtle related to z-ordering, activation, maximizing, snapping, and so on are not considered.
## Future considerations
### Multiple clients
If the multiple clients problem becomes more widespread, we may need to change the graphical
behavior of the Windows Terminal window to only hide certain tabs or panes when a command
comes in instead of hiding the entire window (unless of course there is only one tab/pane).
We may also need to adjust that once consensus is reached among tabs/panes that it can then
and only then propagate up to the entire window.
We will decide on this after we receive feedback that it is a necessary scenario. Otherwise,
we will hold for now.
### Other verbs
If it turns out that we discover tests/scenarios that need maximizing, activation, or other
properties of the `::ShowWindow()` call to be propagated to maintain compatibility, we will
be able to carry those through on the same channel and command. Most of them have an existing
equivalent in `XTWINOPS`. Those that do not, we would want to probably avoid as they will not
be implemented in any other terminal. We would extend the protocol as an absolute last resort
and only after receiving feedback from the greater worldwide terminal community.
### Z-ordering
The channel we're establishing here to communicate information about the window and its
placement may be useful for the z-ordering issues we have in #2988. In those scenarios,
a console client application is attempting to launch and position a window on top of the
terminal, wherever it is. Further synchronizing the state of the new fake-window in the
ConPTY with the real window on the terminal side may enable those tools to function as
they expect.
This is another circumstance we didn't expect: having command-line applications create windows
with a need for complex layout and ordering. These sorts of behaviors cannot be translated
to a universal language and will not be available off the singular machine, so encouraged
alternative methods like command-line based UI. However, for single-box scenarios, this
behavior is engrained in some Windows tooling due to its ease of use.
@@ -60,7 +60,7 @@ Users will be able to add a new setting to their font objects (added in [#10433]
There is one point to note here about clashing. For example, if a user has the old "weight" setting defined _as well as_ a "wght" axis defined, we will only use the "wght" axis value. We prioritize that value for a few reasons:
1. It is the more recent addition to our settings model. Thus, it is likely that a user that has defined both values probably just forgot to remove the old value.
2. It is the more precise value, it is a specific float value whereas the the old "weight" setting is an enum (that eventually gets mapped to a float value).
2. It is the more precise value, it is a specific float value whereas the old "weight" setting is an enum (that eventually gets mapped to a float value).
## Capabilities
@@ -74,7 +74,7 @@ Should not affect security.
### Reliability
Aside from additional parsing required for the settings file (which inherently offers more locations for parsing to fail), we need to be careful about badly formed/non-existant feature tags or axes specified in the user-defined dictionaries. We must make sure to ignore such declarations (perhaps alongside emitting a warning to the user) and only apply those that are correctly formed and exist.
Aside from additional parsing required for the settings file (which inherently offers more locations for parsing to fail), we need to be careful about badly formed/non-existent feature tags or axes specified in the user-defined dictionaries. We must make sure to ignore such declarations (perhaps alongside emitting a warning to the user) and only apply those that are correctly formed and exist.
The idea is for Windows Terminal to change automatically its color schemes according to what theme is selected, including the case where `system` theme is selected.
## Inspiration
I work remotely as a developer, so I have to spend a lot of hours in front of my PC screen. In my setup, right behind my desk I have a window, which is the only source of natural sunlight in my room.
Normally I like dark modes in all the programs and apps I use, but when there's too much sunlight, it becomes annoying, and sometimes even painful, to work in dark mode. So, I have all the programs and apps I use (at least, those that can) set to switch their color themes to what the system has.
The company I work for sent me a Macbook Pro, and my personal phone is an Android, both with automatic dark mode at sunset and light mode at sunrise, and in those devices it's been working relatively well. In Windows, as it is known, there's no such feature, so I manually change between dark and light mode when it's needed, and most of the programs and apps I use go along with this change. Windows Terminal, is not one of them.
The theme changes just as expected, but in an app like this, this change only affects the top of the window, leaving almost all of the screen at the mercy of what the color scheme is, and it doesn't depend on the theme, which defeats any attempt to make a good use of the `system` theme feature.
## Solution Design
Could be implemented in the form of:
```json
"colorScheme":{
"light":"BlulocoLight",
"dark":"BlulocoDark"
}
```
or:
```json
"colorSchemeLight":"BlulocoLight",
"colorSchemeDark":"BlulocoDark"
```
## UI/UX Design
In a first version it could look like the terminal in Visual Studio Code, and an improvement could be to have light mode specific color schemes, just like those already present in Windows terminal. A good idea could be to get an inspiration in Dark++ and Light++ VSCode color themes.
A user could benefit from a more healthy light level contrast between the screen their looking at and the environment they are, reducing the risk of headache or developing/intensifying eye problems, and any other related eye conditions. Plus, it adds to a more consistent experience between different programs and apps, and the system itself.
## Capabilities
### Accessibility
This feature improves accessibility more than any other capability, because the key is to be able to read and see anything better when the environment, both the external to the device, and the device's system itself, is in a certain mode (dark/light).
### Security
The proposed solution is based in the current way one sets Windows Terminal settings, so it isn't expected to add any security issues.
### Reliability
Adding this feature would make Windows Terminal more reliable when it's expected that it changes it's visual theme/color scheme along with the whole system.
### Compatibility
The solution is not expected to break anything.
### Performance, Power, and Efficiency
It might increase the energy spent in the cases where people who were used to use the terminal in regular dark color schemes start using more light color schemes, but that is the case for any other program that shows lighter colors and I don't think the increment would be as high as to be even considered a downside.
## Potential Issues
Some users might not like the change in color schemes or be too used to the terminal being dark, but this may be avoided making the current schemes a default and adding this solution as an alternative setting.
## Future considerations
This solution might bring more attention to the color schemes setting, even more when considering light mode specific color schemes
## Resources
Inspired by what's been said in the issue comments. Credits to them.
Since the beginning, Windows has offered a single choice in default terminal hosting behavior. Specifically, the default terminal is defined as the one that the operating system will start on your behalf when a command-line application is started without a terminal attached. This specification intends to detail how we will offer customers the ultimate in choice among first and third party replacements for their default terminal experience.
## Inspiration
We've had a lot of success in the past several years on our terminal team journey. We updated the old console host user interface with long-desired features. We updated the console environment to bring Windows closer to Linux and Mac by implementing the client (receiving) end of Virtual Terminal sequences to unlock WSL, Docker, and other cross-platform command-line application compatibility. We then created the ConPTY to expose the server end of the console environment to first and third party applications to enable the hosting of any of those command-line clients within their own user interfaces by implementing the server (sending) end of Virtual Terminal sequences. And then we built Windows Terminal as our flagship implementation of the development environment on this model.
Through all of this, the entrypoint for alternatives to the console host UX continued to be "Start your alternative terminal implementation first, then start the command-line application inside." For those familiar with Linux and Mac or for those using the broad ecosystem of alternative Windows Terminals like ConEmu, Cmder, Console2, and the like... that was natural. But Windows did it differently a long time ago allowing the starting of a command-line application directly from the shell or kernel without a terminal specified. On noticing the missing terminal, the system would just-in-time start and attach the one terminal it could count on as always present, `conhost.exe`.
And so the inspiration of this is simple: We want to allow our customers to choose whichever terminal they want as the just-in-time terminal attached to an application without one present/specified on launch. This final move completes our journey to allow the ultimate in choice AND decouple the terminal experience from the operating system release schedule.
## Solution Design
There are three components to the proposed design:
1.**Inbox console**: This is the `conhost.exe` that is resident inside every Windows installation.
1.**Updated console**: This is the `openconsole.exe` that we ship with the Windows Terminal to provide a more up-to-date console server experience.
1.**Terminal UX**: This is `WindowsTerminal.exe`, the new Terminal user interface that runs on VT sequences.
And there are a few scenarios here to consider:
1. Replacement console API server and replacement terminal UX.
1. This is the Windows Terminal scenario today. `OpenConsole.exe` is packed in the package to be the console API server and ConPTY environment for `WindowsTerminal.exe`.
1. Replacement console API server and legacy terminal UX.
1. We don't explicitly distribute this today, but it's technically possible to just run `OpenConsole.exe` to accomplish this.
1. Inbox console API server and replacement terminal UX.
1. The WSL environment does this when doing Windows interop and I believe VS Code does this too when told to use the ConPTY environment. (And since VS Code does it, anything using node-pty also does it, covering some 3rd party terminals as well).
1. Inbox console API server and inbox terminal UX.
1. This is what we have today in `conhost.exe` running as the default application.
The goal is to offer the ultimate in choice here where any of the components can be replaced as necessary for a 1st or 3rd party scenario.
### Overview
#### Inbox console
The inbox console will be updated to support delegation of the incoming console client application connection to another console API server if one is registered and available.
We leave the inbox console in-place and always available on the operating system for these reasons:
1. A last chance fall-back should any of the delegation operations fail
1. An ongoing host for applications that aren't going to need a window at all
1. Continued support of our legacy `conhostv1.dll` environment, if chosen
The general operation is as follows:
- A command-line client application is started (from the start menu, run box, or any other `CreateProcess` or `ShellExecute` route) without an existing console server attached
- The inbox console is launched from `C:\windows\system32\conhost.exe` as always by the initialization routines inside `kernelbase.dll`.
- The inbox console accepts the incoming initial connection and looks for the `ShowWindow` information on the connection packet, as received from the kernel's process creation routines based on the parameters given to the `CreateProcess` call. (See [CREATE_NO_WINDOW](https://docs.microsoft.com/en-us/windows/win32/procthread/process-creation-flags) flag for details.)
- If the session is about to create a window, check for registration of a delegated/updated console and hand-off to it if it exists.
- Otherwise, start normally.
This workflow affords us several benefits:
- The only inbox component we have to change is `conhost.exe`, the one we already regularly update from open source on a regular basis. There is no change to the `kernelbase.dll` console initialization routines, `conclnt.lib` communication protocol, nor the `condrv.sys` driver.
- We should be able to make this change quickly, relatively easily, and the code delta should be relatively small
- This makes it easy to squeeze in early in the development of the solution and get it into the Windows OS product as soon as possible for self-hosting, validation, and potentially shipping in the OS before the remainder of the solution has shaken out
- This also makes it potentially possible to backport this portion of the code change to popular in-market versions of Windows 10. For instance, WSL2 has just backported to 1903 and 1909. The less churn and risk, the easier it is to sell a backport.
*Potential future:*
- ~~If no updated console exists, potentially check for registration of a terminal UX that is willing to use the inbox ConPTY bits, start it, and transition to being a PTY instead.~~
- **CUT FROM v1**: To simplify the story for end-users, we're offering this as a package deal in the first revision. Explaining the difference between consoles and terminals to end users is very difficult.
The registration would operate as follows:
- A registry key in `HKCU\Console\%%Startup` (format `REG_SZ`, name `DelegationConsole`) would specify ~~the path to ~~the replacement console that would be used to service the remainder of the connection process.
- Alternatively or additionally, this same `REG_SZ` could list a COM server ID that could be looked up in the classes root and invoked. **V1 NOTE:** This was what was done.
- Packaged applications and classic applications can easily register a COM server
- WinRT libraries should be able to be easily registered as the COM server as well (given WinRT is COM underneath)
- WinRT cannot be exposed outside of the package context itself, so the `conhost.exe` that is in the OS and is naturally outside the package cannot find it.
- **V1 NOTE:** The subkey `%%Startup` was chosen to separate these keys (this one and the `DelegationTerminal` one below) in case we needed to ACL them or protect them in some way. We want a per-user choice of which Terminal/Console are used, but we might need to take action to prevent these keys from being slammed at some point in the future. Why `%%`? The subkeys are traditionally used to resolve paths to client binaries that have their own console preferences set. The `%%` should never be resolvable as it won't lead to a valid path or expanded path variable.
The delegation process would operate as follows:
- A method contract is established between the existing inbox console and any updated console (an interface).
-`HANDLE server`: This is the server side handle to the console driver, used with `DeviceIoControl` to receive/send messages with the client command-line application
-`HANDLE driverInputEvent`: The input event is created and assigned to the driver immediately on first connection, before any messages are read from the driver, to ensure that it can track a blocking state should first message be an input request that we do not yet have data to fill. As such, the inbox console will have created this and assigned it to the driver before pulling off the connection packet and determining that it wants to delegate. Therefore, we will transfer ownership of this event to the updated console.
- ~~`const PortableArguments* const args`: This contains the startup argument information that was passed in when the process was started including the original command line and the in/out handles.~~
- ~~The `ConsoleArguments` structure could technically change between versions, so we will make a version agnostic portable structure that just carries the communication from the old one to the new one.~~
- **CUT FROM V1**: The only arguments coming in from a default light-up are the server handle. Pretty much all the other arguments are related to the operation of the PTY. Since this feature is about "default application" launches where no arguments are specified, this was cut from the initial revision.
-`const PortableConnectMessage* const msg`:
- The `CONSOLE_API_MSG` structure contains both the actual packet data from the driver as well as some overhead/administration data related to the packet state, ordering, completion, errors, and buffers. It's a broad scope structure for every type of message we process and it can change over time as we improve the way the `conserver.lib` handles packets.
- This represents a version agnostic variant for ONLY the connect message that can pass along the initial connect information structure, the packet sequencing information, and other relevant payload only to that one message type. It will purposefully discard references to things like a specific set of API servicing routines because the point of handing off is to get updated routines, if necessary.
- **V1 NOTE:** This was named `CONSOLE_PORTABLE_ATTACH_MSG`
-`HANDLE signalPipe`: During authoring, it was identified that <kbd>Ctrl+C</kbd> and other similar signals need to make it back to the original `conhost.exe` application as the Operating System grants it special privilege over the originally attached client application. This privilege cannot be transferred to the delegated console. So this channel remains for the delegated one to send its signals back through the original one for commanding the underlying client. (This also implies the original `conhost.exe` inbox cannot close and must remain a part of the process tree for the life of the session to maintain this control.)
-`HANDLE inboxProcess`: Since we have to keep the inbox `conhost.exe` running for signal/ownership reasons, we also need to track its lifetime. If it disappears for whatever reason, we need to tear down the entire chain as part of our operation has been compromised.
-`HANDLE* process`: On the contrary to `inboxProcess`, we need to give our process handle back so it can also be tracked. After the inbox console delegates, it remains in a very limited capacity. If the delegation one disappears, the session will no longer function and needs to be torn down (and the client closed).
- *Return* `HRESULT`: This is one of the older style methods in the initialization. We moved them from mostly `NTSTATUS` to mostly `HRESULT` a while ago to take advantage of `wil`. This one will continue to follow the pattern and not move to exceptions. A return of `S_OK` will symbolize that the handoff worked and the inbox console can clean itself up and stop handling the session.
- When the connection packet is parsed for visibility information (see `srvinit.cpp`), we will attempt to resolve the registered handoff and call it.
- ~~In the initial revision here, I have this as a `LoadLibrary`/`GetProcAddress` to the above exported contract method from the updated console. This maintains the server session in the same process space and avoids:~~
1.~~The issue of passing the server, event, and other handles into another process space. We're not entirely sure if the console driver will happily accept these things moving to a different process. It probably should, but unconfirmed.~~
1.~~Some command-line client applications rely on spelunking the process tree to figure out who is their servicing application. Maintaining the delegated/updated console inside the same process space maintains some level of continuity for these sorts of applications.~~
- **Alternative:** We may make this just be a COM server/client contract. ~~An in-proc COM server should operate in much the same fashion here (loading the DLL into the process and running particular method) while being significantly more formal and customizable (version revisions, moving to out-of-proc, not really needing to know the binary path because the catalog knows).~~
- **V1 NOTE:** We landed on an out-of-proc COM server/client here. This maintains the isolation of the newly running code from the old code. Since we're maintaining the original `conhost.exe` for signaling purposes, we're no longer worried about the spelunking the process tree and not having the relationship for clients to find.
- **Not considering:** ~~WinRT. `conhost.exe` has no WinRT. Adding WinRT to it would significantly increase the complexity of compilation in the inbox and out of box code base. It would also significantly increase the compilation time, binary size, library link list, etc... unless we use just the ABI to access it. But I don't see an advantage to that over just using classic COM at that point. This is only one handoff method and a rather simplistic one at that. Every benefit WinRT provides is outweighed by the extra effort that would be required over just a classic COM server in this case.~~
- After delegation is complete, the inbox console will have to clean up any threads, handles, and state related to the session. We do a fairly good job with this normally, but some portions of the `conhost.exe` codebase are reliant on the process exiting for final cleanup. There may be a bit of extra effort to do some explicit cleanup here.
- **V1 NOTE:** The inbox one cleans up everything it can and sits in a state waiting for the child/delegated process handle to exit. It also maintains a thread listening for the signals to come through in case it needs to send a command to the client application using the privilege granted to it by the driver.
#### Updated console
The updated replacement console will have the same console API server capabilities as the inbox console, but will be a later, updated, or customized-to-the-scenario version of the API server generally revolving around improving ConPTY support for a Terminal application.
On receiving the handoff from the method signature listed above, the updated console will:
- Establish its own set of IO threading, device communication infrastructure, and API messaging routines while storing the handles given
- ~~Re-parse the command line arguments, if necessary, and store them for guiding the remainder of launch~~
- Dispatch the attach message as if it were received normally
- Continue execution from there
There will then either be a registration for a Terminal UX to take over the session by using ConPTY, ~~or the updated console will choose to launch its potentially updated version of the `conhost` UX~~.
For registration, we repeat the dance above with another key:
- A registry key in `HKCU\Console\%%Startup` (format `REG_SZ`, name `DelegationTerminal`).
The delegation repeats the same dance as above as well:
- A contract (interface) is established between the updated console and the terminal
-`HANDLE in`: The handle to read client application output from the ConPTY and display on the Terminal
-`HANDLE out`: The handle to write user input from the Terminal to the ConPTY
-`HANDLE signal`: The signal handle for the ConPTY for out-of-band communication between PTY server and Terminal application
- ~~`COORD size`: The initial window size from the starting application, as it can be a preference in the connection structure. (A resize message may get sent back downward almost immediately from the Terminal as its dimensions could be different.)~~ **V1 NOTE:** This proved unnecessary as the resize operations sorted themselves out naturally.
-`HANDLE ref`: This is a "client reference handle" to the console driver and session. We hold onto a copy of this in the Terminal so the session will stay alive until we let go. (The other console hosts in the chain also hold one of these, as should the client.)
-`HANDLE server`: This is a process handle to the PTY we're attached to. We monitor this to know when the PTY is still alive from the Terminal side.
-`HANDLE client`: This is a process handle to the underlying client application. The terminal tracks this for exit handling.
- **Alternative:** This should likely just be a COM server/client contract as well. This would be consistent with the above and wouldn't require argument parsing or wink/nudge understanding of standard handle passing. It also conveys the same COM flexibility as described in the inbox console section. **V1 NOTE:** We used this alternative. We used COM, not a well-known exported function from the prototype.
- The contract is called and on success, responsibility of the UX is given over to the Terminal. The console sits in PTY mode.
- On failure, the console launches interactive.
#### Terminal UX
The terminal will be its own complete presentation and input solution on top of a ConPTY connection, separating the concerns between API servicing and the user experience.
Today the Terminal knows how to start and then launches a ConPTY under it. The Terminal will need to be updated to accept a pre-existing ConPTY connection on launch (or when the multi-process model arrives, as an inbound connection), and connect that to a new tab/pane instead of using the `winconpty.lib` libraries to make its own.
For now, I'm considering only the fresh-start scenario.
- The Terminal will have to detect the inbound connection through ~~its argument parsing (or through~~ a new entrypoint in the COM alternative ~~)~~ and store the PTY in/out/signal handles for that connection in the startup arguments information
- When the control is instantiated on a new tab, that initial creation where normally the "default profile" is launched will instead have to place the PTY in/out/signal handles already received into the `ConPtyConnection` object and use that as if it was already created.
- The Terminal can then let things run normally and the connection will come through and be hosted inside the session.
There are several issues/concerns:
- Which profile/settings get loaded? We don't really know anything about the client that is coming in already-established. That makes it difficult to know what user preferences to apply to the inbound tab. We could:
- Use only the defaults for the incoming connection. Do not apply any profile-specific settings.
- Use the profile information from the default profile to some degree. This could cause some weird scenarios/mismatches if that profile has a particular icon or a color scheme that makes it recognizable to the user.
- Create some sort of "inbound profile" profile that is used for incoming connections
- Add a heuristic that attempts to match the name/path of the connecting client binary to a profile that exists and use those settings, falling back if one is not found.
- **Proposal:** Do the first one immediately for bootstrapping, then investigate the others as a revision going forward.
- The handles that are coming in are "raw" and "unpacked", not in the nice opaque `HPCON` structure that is usually provided to the `ConPtyConnection` object by the `winconpty.lib`.
- Add methods to `winconpty.lib` that allow for the packing of incoming raw handles into the `HPCON` structure so the rest of the lifetime can be treated the same
- Put the entrypoint for the COM server (or delegate the entrypoint for an argument) directly into this library so it can pack them up right away and hand of a ready-made `HPCON`.
## UI/UX Design
The user experience for this feature overall should be:
1. The user launches a command-line client application through the Start Menu, Win+X menu, the Windows Explorer, the Run Dialog box (WinKey+R), or through another existing Windows application.
1. Using the established settings, the console system transparently starts, delegates itself to the updated console, switches itself into ConPTY mode, and a copy of Windows Terminal launches with the first tab open to host the command-line client application.
- **NOTE:** I'm not precluding 3rd party registrations of either the delegation updated console nor the delegation terminal. It is our intention to allow either or both of these pieces to be replaced to the user's desires. The example is for brevity of our golden path and motivation for this scenario.
1. The user is able to interact with the command-line client application as they would with the original console host.
- The user receives the additional benefit that short-running executions of a command-line application may not "blink in and disappear" as they do today when a user runs something like `ipconfig` from the run dialog. The Terminal's default states tend to leave the tab open and say that the client has exited. This would allow a Run Dialog `ipconfig` user an improved experience over the default console host state of disappearing quickly.
1. If any portion of the delegation fails, we will progressively degrade back to a `conhost` style Win32+GDI UX and nothing will be different from before.
The settings experience includes:
- Configuration of the delegation operations:
- Locations:
- With the registry
- This is what's going to be available first and will remain available. We will progress to some or all of the below after.
- We will need to potentially add specifications to this to both the default profile (for new installations of Windows) or to upgrade/migration profiles (for users coming from previous editions of Windows) to enable the delegation process, especially if we put a copy of Windows Terminal directly into the box.
- **V1 NOTE:** we didn't add additional migration logic here as `HKCU\Console*` and subkeys were already in the migration logic, so adding another should just carry along.
- Inside Windows Terminal
- Inside the new Settings UI, we will likely need a page that configures the delegation keys in `HKCU\Console\%%Startup`~~or a link out to the Windows Settings panel, should we manage to get the settings configurable there~~.
- Inside the console property sheet
- Same as for Terminal but with `comctl` controls over XAML +/- a link to the Windows Settings panel
- Inside the Settings panel for Windows (probably on the developer settings page)
- The ultimate location for this is likely a panel directly inside Windows. This is the hardest one to accomplish because of the timelines of the Windows product. We may not get this in an initial revision, but it should likely be our ultimate goal. **V1 NOTE:** We did it!
- Operation:
- Specify paths/server IDs - This is the initial revision
- Offer a list of registered servers or discovered manifests from the app catalog - This is the ideal scenario where we search the installed app catalog +/- the COM catalog and offer a list of apps that conform to the contract in a drop-down.
- The final process was to use [App Extensions](https://docs.microsoft.com/windows/uwp/launch-resume/how-to-create-an-extension) inside the Terminal APPX package to declare the COM GUIDs that were available for the `DelegationConsole` and `DelegationTerminal` fields respectively. A configuration class `DelegationConfig` was added to `propslib.lib` that enables the lookup of these from the application state catalog and presents a list of them to choose from. It also manages reading and writing the registry keys.
- **V1 NOTE:** Our configuration options currently allow pairings of replacement consoles and terminals to be adjusted in lock-step from the UI. That's not to say further combinations are not possible or even necessarily inhibited by the code. We just went for minimal confusion in our first round.
- Configuration of the legacy console state:
- ~~Since we could end up in an experience where the default launch experience gets you directly into Windows Terminal, we believe that the Terminal will likely need an additional setting or settings in the new Settings UI that will allow the toggling of some of the `HKCU\Console` values to do things like set/remove the legacy console state.~~ **V1 NOTE:** Cut as low priority. Switch back to console and configure it that way or use the existing property sheet or tamper with registry keys.
- We have left the per-launch debugging and advanced access hole of calling something like `conhost.exe cmd.exe` which will use the inbox conhost to launch `cmd.exe` even if there is a default specified.
Concerns:
- State separation policy for Windows. I believe `HKCU\Console` is already specified as a part of the "user state" that should be mutable and carried forward on OS Swap, especially as we have been improving the OS swap experience.
- Ability for installers/elevated scripts to stomp the Delegation keys
- This was a long time problem for default app registrations and was limited in our OS. Are we about to run down the same path?
- What is the alternative here? To use a protocol handler? To store this configuration state data with other protected state in a registry area that is mutable, but only ACL'd to the `SYSTEM` user like some other things in the Settings control panel?
- **V1 NOTE:** We set ourselves up for some future ACL thing with the subkey, but we otherwise haven't enforced anything at this time.
## Capabilities
### Accessibility
Accessibility applications are the most likely to resort to a method of spelunking the process tree or window handles to attempt to find content to read out. Presuming they have hardcoded rules for console-type applications, these algorithms could be surprised by the substitution of another terminal environment.
The major players here that I am considering are NVDA, JAWS, and Narrator. As far as I am aware, all of these applications attempt to drive their interactivity through UI Automation where possible. And we have worked with all of these applications in the past in improving their support for both `conhost.exe` and the Windows Terminal product. I have relatively high confidence that we will be able to work with them again to help update these assistive products to understand the new UI delegation, if necessary.
### Security
Let's hit the elephant in the room. "You plan on pulling a completely different binary inside the `conhost.exe` process and just... delegating all activity to it?" Yes.
(**V1 NOTE:** Well, it's out of proc now. But it is at the same privilege level as the original one thanks to the mechanics of COM.)
As far as I'm concerned, the `conhost.exe` that is started to host the command-line client application is running at the same integrity level as the client binary that is partially started and waiting for its server to be ready. This is the long-standing existing protection that we have from the Windows operating system. Anything running in the same integrity level is already expected to be able to tamper with anything else at the same integrity level. The delegated binary that we would be loading into our process space will also be at the same integrity level. Nothing really stops a malicious actor from launching that binary in any other way in the same integrity level as a part of the command-line client application's startup.
The mitigation here, if necessary, would be to use `WinVerifyTrust` to validate the certification path of the `OpenConsole.exe` binary to ensure that only one that is signed by Microsoft can be the substitute server host for the application. This doesn't stop third parties from redistributing our `OpenConsole.exe` off of GitHub if necessary with their products, but it would stop someone from introducing any random binary that met the signature interface of the delegation methods into `conhost.exe`. The only value I see this providing is stopping someone from being "tricked" into delegating their `conhost.exe` to another binary through the configuration methods we provide. It doesn't really stop someone (or an attacker) from taking ownership of the `conhost.exe` in System32 and replacing it directly. So this point might be moot. (It is expected that replacement of the System32 one is already protected, to some degree, by being owned by the SYSTEM account and requiring some measure of authority to replace.)
### Reliability
The change on its own may honestly improve reliability of the hosting system. The existing just-in-time startup of the console host application only had a single chance at initializing a user experience before it would give up and return that the command-line application could not be started.
However, there are now several phases in the startup process that will have the opportunity to make multiple attempts at multiple versions or applications to find a suitable host for the starting application before giving up.
One layer of this is where the `conhost.exe` baked into the operating system will be on the lookout for an `OpenConsole.exe` that will replace its server activities. The delegation binary loses a bit of reliability, theoretically, by the fact that loading another process during launch could have versioning/resolution/path/dependency issues, but it simultaneously offers us the opportunity for improved reliability by being able to service that binary quickly outside the Windows OS release cycle. Fixes can arrive in days instead of months to years.
Another layer of this is where either `conhost.exe` or the delegated `OpenConsole.exe` server will search for a terminal user experience host, like `WindowsTerminal.exe` or another registered first or third party host, and split the responsibility of hosting the session with that binary. Again, there's a theoretical reliability loss with the additional process launch/load, but there's much to be gained by reducing the scope of what each binary must accomplish. Removing the need to handle user interaction from `conhost.exe` or `OpenConsole.exe` and delegating those activities means there is less surface area running and less chance for a UX interaction to interfere with API call servicing and vice versa. And again, having the delegation to external components means that they can be fixed on a timeline of days instead of months or years as when baked into the operating system.
### Compatibility
One particular scenario that this could break is an application that makes use of spelunking the process tree when a command-line application starts to identify the hosting terminal application window by HWND to inject input, extract output, or otherwise hook and bind to hosting services. As the default application UI that will launch may not have the `conhost.exe` name (for spelunking via searching processes) and the HWND located may either be the ConPTY fake HWND or an HWND belonging to a completely different UI, these applications might not work.
Two considerations here:
1. At a minimum, we must offer an opt-out of the delegation to another terminal for the default application.
1. We may also want to offer a process-name, policy, manifest, or other per client application opt-out mechanism.
**V1 NOTE:** There is no per-client specific way of doing this. The toggle is per-user and can be adjusted in 3 different places.
### Performance, Power, and Efficiency
I expect to take some degree of performance, power, and efficiency hit by implementing this replacement default app scenario just by it's nature. We will be loading multiple processes, performing tests and branches during startup, and we will likely need to load COM/WinRT and packaging data that was not loaded prior to resolve the final state of default application load. I would expect this to accrue to some failures in the performance and power gates inside the Windows product. Additionally, the efficiency of running pretty much everything through the ConPTY is lower than just rendering it directly to `conhost.exe`'s embedded GDI-powered UI itself thanks to the multiple levels of translation and parsing that occur in this scenario.
The mitigations to these losses are as follows:
1. We will delay load any of the interface load and packaging data lookup libraries to only be pulled into process space should we determine that the application is non-interactive.
1. That should save us some of the commit and power costs for the sorts of non-interactive scripts and applications that typically run early in OS startup (and leverage `conhost.exe` as their host environment).
1. We will still likely get hit with the on-disk commit cost for the additional export libraries linked as well as additional code. That would be a by-design change.
1. We plan to begin Profile Guided Optimization across our `OpenConsole.exe` and `WindowsTerminal.exe` binaries. This should allow us to optimize the startup paths for this scenario and bias the `OpenConsole.exe` binary that we redistribute to focus its efforts and efficiency on the ConPTY role specifically, ignoring all of the interactive Win32/GDI portions that aren't typically used.
1. We may need to add a PGO scenario inside Windows to tune the optimization of `conhost.exe` especially if we're going to go full on Windows Terminal in the box default application. The existing PGO that occurs in the optimization branches is running on several `conhost.exe` interactive scenarios, none of which will be relevant here. We would probably want to update it to focus on the default app delegation routine AND on the non-interactive scenario for hosted applications (where delegation will not occur but Win32/GDI will still not be involved).
## Potential Issues
### Passing Handles with COM
COM doesn't inherently expose a way for us to pass handles directly between processes with the existing contracts. We know this is possible because Windows does it all the time, but it doesn't appear to be public. We believe the mission forward is to expose this functionality to the public as if it's good enough for us internally and it is a requirement to build complex functionality like this... then it should be good enough for the public.
**V1 NOTE:** We gained approval to open this up and documented it. [`system_handle` attribute](https://docs.microsoft.com/windows/win32/midl/system-handle). It didn't require any code changes because the public IDL compiler already recognized the existence of this attribute and did the correct thing. It just wasn't documented for use.
## Future considerations
* We additionally would like to leave the door open to distributing updated `OpenConsole.exe`s in their own app package as a dependency that others could rely on.
* This was one of the original management requests when we were opening the source of the console product as well as the Terminal back in spring of 2019. For the sake of ongoing servicing and maintainability, it was requested that we reach a point where our dependencies could be serviced potentially independently of the product as a whole static unit. We didn't achieve that goal initially, but this design would enable us to do something like this.
* One negative to this scenario is that dependency resolution and the installation of dependent packages through APPX is currently lacking in several ways. It's difficult/impossible to do in environments where the store or the internet is unavailable. And it's a problem often enough that the Windows Terminal package embeds the VC runtimes inside itself instead of relying on the dependency resolution of the app platform.
## Resources
- [Windows Terminal Process Model 2.0 spec](https://github.com/microsoft/terminal/pull/7240)
- [Windows Terminal 2.0 Process Model Improvements](https://github.com/microsoft/terminal/issues/5000)
@@ -124,7 +124,7 @@ There's a few areas to study here.
#### Communicating the launch
For the parameters passing, I see a few options:
1.`conhost.exe` can look up the package registration for `wt.exe` and call an entrypoint with arguments. This could be adapted to instead look up which package is registered as the default one instead of `wt.exe` for third party hosts. We would have to build provisions into the OS to select this, or use some sort of publically documented registry key mechanism. Somewhat gross.
1.`conhost.exe` can look up the package registration for `wt.exe` and call an entrypoint with arguments. This could be adapted to instead look up which package is registered as the default one instead of `wt.exe` for third party hosts. We would have to build provisions into the OS to select this, or use some sort of publicly documented registry key mechanism. Somewhat gross.
1.`conhost.exe` can call the execution alias with parameters. WSL distro launchers use this.
1. We can define a protocol handler for these sorts of connections and let `wt.exe` register for it. Protocol handlers are already well supported and understood both by classic applications and by packaged/modern applications on Windows. They must have provisions to communicate at least some semblance of argument data as well. This is the route I'd probably prefer. `ms-term://incoming/<session-id>` or something like that. The receiving `wt.exe` can contact the manager process (or set one up if it is the first) and negotiate receiving the session that was specified into a new tab.
@@ -114,7 +114,7 @@ The jumplist will have to be saved each time a profile change occurs but the fre
#### Should it open a new instance of the terminal or open in a new tab?
#### What should happen if a non existant profile is launched
#### What should happen if a non existent profile is launched
The jumplist is only updated when the application is running so the profiles could be modified or deleted outside and the jumplist will not be updated. Handling will be done by whatever handles the command line parsing.
> This document has been superseded by the [Terminal 2022 Roadmap]. Please refer to that document for the updated roadmap.
## Overview
This document outlines the roadmap towards delivering Windows Terminal 2.0 by Winter 2021.
This document outlines the roadmap towards delivering Windows Terminal 2.0.
## Milestones
@@ -31,9 +35,7 @@ Below is the schedule for when milestones will be included in release builds of
| 2021-05-31 | [1.9] in Windows Terminal Preview<br>[1.8] in Windows Terminal | [Windows Terminal Preview 1.9 Release](https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-9-release/) |
| 2021-07-14 | [1.10] in Windows Terminal Preview<br>[1.9] in Windows Terminal | [Windows Terminal Preview 1.10 Release](https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-10-release/) |
| 2021-08-31 | [1.11] in Windows Terminal Preview<br>[1.10] in Windows Terminal | [Windows Terminal Preview 1.11 Release](https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-11-release/) |
| 2021-10-31 | 1.12 in Windows Terminal Preview<br>1.11 in Windows Terminal | |
| 2021-11-30 | 2.0 RC in Windows Terminal Preview<br>2.0 RC in Windows Terminal | |
| 2021-12-31 | [2.0] in Windows Terminal Preview<br>[2.0] in Windows Terminal | |
| 2021-10-20 | [1.12] in Windows Terminal Preview<br>[1.11] in Windows Terminal | [Windows Terminal Preview 1.12 Release](https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-12-release/) |
## Issue Triage & Prioritization
@@ -49,28 +51,32 @@ The following are a list of the key scenarios we're aiming to deliver for Termin
> 👉 Note: There are many other features that don't fit within 2.0, but will be re-assessed and prioritized for 3.0, the plan for which will be published in 2021.
| Priority\* | Scenario | Description/Notes |
| ---------- | -------- | ----------------- |
| 0 | Settings UI | A user interface that connects to settings.json. This provides a way for people to edit their settings without having to edit a JSON file.<br><br>Issue: [#1564]<br>Specs: [#6720], [#6904]<br>Implementation: [#7283], [#7370], [#8048] |
| 0 | Command palette | A popup menu to list possible actions and commands.<br><br>Issues: [#5400], [#2046]<br>Spec: [#2193]<br>Implementation: [#6635] |
| 1 | Tab tear-off | The ability to tear a tab out of the current window and spawn a new window or attach it to a separate window.<br><br>Issue: [#1256], [#5000]<br>Spec: [#2080], [#7240] |
| 1 | Clickable links | Hyperlinking any links that appear in the text buffer. When clicking on the link, the link will open in your default browser.<br><br>Issue: [#574]<br>Implementation: [#7251] |
| 1 | Default terminal | If a command-line application is spawned, it should open in Windows Terminal (if installed) or your preferred terminal<br><br>Issue: [#492]<br>Spec: [#2080], [#7414] |
| 1 | Overall theme support | Tab coloring, title bar coloring, pane border coloring, pane border width, definition of what makes a theme<br><br>Issue: [#3327]<br>Spec: [#5772] |
| 1 | Open profile elevated | Configure profiles to always open elevated (if Terminal was run unelevated)<br><br>Issue: [#5000], [#632]<br>Spec: [#8455] |
| 1 | Open tab in existing window | Open new tabs in existing Terminal windows<br><br>Issue: [#5000], [#4472]<br>Spec: [#8135] |
| 1 | Traditional opacity | Have a transparent background without the acrylic blur.<br><br>Issue: [#603] <br>**Current State**: Blocked on WinUI 3.0 |
| 2 | SnapOnOutput, scroll lock | Pause output or scrolling on click.<br><br>Issue: [#980]<br>Spec: [#2529]<br>Implementation: [#6062] |
| 2 | Infinite scrollback | Have an infinite history for the text buffer.<br><br>Issue: [#1410] |
| 2 | Pane management | All issues listed out in the original issue. Some features include pane resizing with mouse, pane zooming, and opening a pane by prompting which profile to use.<br><br>Issue: [#1000] |
| 2 | Theme marketplace | Marketplace for creation and distribution of themes.<br>Dependent on overall theming |
| 2 | Jump list | Show profiles from task bar (on right click)/start menu.<br><br>Issue: [#576]<br>Implementation: [#7515] |
| 2 | Open with multiple tabs | A setting that allows Windows Terminal to launch with a specific tab configuration (not using only command line arguments).<br><br>Issue: [#756] |
| 3 | Open in Windows Terminal | Functionality to right click on a file or folder and select Open in Windows Terminal.<br><br>Issue: [#1060]<br>Implementation: [#6100] |
| 3 | Session restoration | Launch Windows Terminal and the previous session is restored with the proper tab and pane configuration and starting directories.<br><br>Issues: [#961], [#960], [#766] |
| 3 | Quake mode | Provide a quick launch terminal that appears and disappears when a hotkey is pressed.<br><br>Issue: [#653] |
| 3 | Settings migration infrastructure | Migrate people's settings without breaking them. Hand-in-hand with settings UI. |
| 3 | Pointer bindings | Provide settings that can be bound to the mouse.<br><br>Issue: [#1553] |
| Priority\* | Scenario | Description/Notes | State |
| 0 | Settings UI | A user interface that connects to settings.json. This provides a way for people to edit their settings without having to edit a JSON file.<br><br>Issue: [#1564]<br>Specs: [#6720], [#6904]<br>Implementation: [#7283], [#7370], [#8048] | ✔️ |
| 0 | Command palette | A popup menu to list possible actions and commands.<br><br>Issues: [#5400], [#2046]<br>Spec: [#2193]<br>Implementation: [#6635] | ✔️ |
| 1 | Tab tear-off | The ability to tear a tab out of the current window and spawn a new window or attach it to a separate window.<br><br>Issue: [#1256], [#5000]<br>Spec: [#2080], [#7240] | 📝 |
| 1 | Clickable links | Hyperlinking any links that appear in the text buffer. When clicking on the link, the link will open in your default browser.<br><br>Issue: [#574]<br>Implementation: [#7251] | ✔️ |
| 1 | Default terminal | If a command-line application is spawned, it should open in Windows Terminal (if installed) or your preferred terminal<br><br>Issue: [#492]<br>Spec: [#2080], [#7414] | ✔️ |
| 1 | Overall theme support | Tab coloring, title bar coloring, pane border coloring, pane border width, definition of what makes a theme<br><br>Issue: [#3327]<br>Spec: [#5772] | 🦶 |
| 1 | Open profile elevated | Configure profiles to always open elevated (if Terminal was run unelevated)<br><br>Issue: [#5000], [#632]<br>Spec: [#8455] | 📝 |
| 1 | Open tab in existing window | Open new tabs in existing Terminal windows<br><br>Issue: [#5000], [#4472]<br>Spec: [#8135] | ✔️ |
| 1 | Traditional opacity | Have a transparent background without the acrylic blur.<br><br>Issue: [#603] | ✔️ |
| 2 | SnapOnOutput, scroll lock | Pause output or scrolling on click.<br><br>Issue: [#980]<br>Spec: [#2529]<br>Implementation: [#6062] | ✔️ |
| 2 | Infinite scrollback | Have an infinite history for the text buffer.<br><br>Issue: [#1410] | 🦶 |
| 2 | Pane management | All issues listed out in the original issue. Some features include pane resizing with mouse, pane zooming, and opening a pane by prompting which profile to use.<br><br>Issue: [#1000] | 📝 |
| 2 | Theme marketplace | Marketplace for creation and distribution of themes.<br>Dependent on overall theming | 🦶 |
| 2 | Jump list | Show profiles from task bar (on right click)/start menu.<br><br>Issue: [#576]<br>Implementation: [#7515] | ✔️ |
| 2 | Open with multiple tabs | A setting that allows Windows Terminal to launch with a specific tab configuration (not using only command line arguments).<br><br>Issue: [#756] | ✔️ |
| 3 | Open in Windows Terminal | Functionality to right click on a file or folder and select Open in Windows Terminal.<br><br>Issue: [#1060]<br>Implementation: [#6100] | ✔️ |
| 3 | Session restoration | Launch Windows Terminal and the previous session is restored with the proper tab and pane configuration and starting directories.<br><br>Issues: [#961], [#960], [#766] | ✔️ |
| 3 | Quake mode | Provide a quick launch terminal that appears and disappears when a hotkey is pressed.<br><br>Issue: [#653] | ✔️ |
| 3 | Settings migration infrastructure | Migrate people's settings without breaking them. Hand-in-hand with settings UI. | 🦶 |
| 3 | Pointer bindings | Provide settings that can be bound to the mouse.<br><br>Issue: [#1553] | 🦶 |
* 📝: The feature is currently in progress
* ✔️: The feature is complete and shipped in a Preview build
* 🦶: The feature is at risk of being punted to a future release cycle (beyond 2.0)
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.