Compare commits

...

380 Commits

Author SHA1 Message Date
Mike Griese
ad2f6a7649 I cannot believe setting an AUMID like this works this well 2023-08-16 16:08:37 -05:00
Mike Griese
32bd9d34ce this api is useless 2023-08-16 15:38:10 -05:00
Mike Griese
aefa5d64f1 derp 2023-08-16 15:37:49 -05:00
Mike Griese
ba9c3eb94b Okay this at least sometimes works 2023-08-16 15:37:23 -05:00
Mike Griese
ba35bff71a yep works with exes and such 2023-08-16 13:54:10 -05:00
Mike Griese
26c394c6c9 Successfully load ms-appx images 2023-08-16 13:38:41 -05:00
Mike Griese
f9bb867231 chef_kiss.png. Loads pngs, gifs, anything local. This is great 2023-08-16 12:44:18 -05:00
Mike Griese
bf20c753c8 try another method of manually cracking open bitmaps 2023-08-16 12:39:36 -05:00
Mike Griese
8ef2307b67 POC: Load an image to an HICON, and set that icon as the taskbar overlay. Now the much harder task of doing that with an arbitrary icon 2023-08-16 11:12:30 -05:00
Mike Griese
697e1189e0 fix build break in scratch 2023-08-16 06:58:03 -05:00
Leonard Hecker
a7a44901c2 AtlasEngine: Fix ligature splitting for JetBrains Mono (#15810)
Some fonts implement ligatures by replacing a string like "&&" with
a whitespace padding glyph, followed by the actual "&&" glyph which
has a 1 column advance width. In that case the algorithm in
`_drawTextOverlapSplit` will get confused because it strictly scans
the input from left to right, searching for color changes.
The initial color is the glyph's color and so it breaks for such fonts
because then the first split will retain the last column's color.

## Validation Steps Performed
* Use JetBrains Mono
* Print ``"`e[91m`&`e[96m&`e[m"``
* Red and blue `&` appear 

---------

Co-authored-by: Tushar Singh <tusharvickey1999@gmail.com>
Co-authored-by: Dustin L. Howett <duhowett@microsoft.com>
2023-08-15 19:50:47 +00:00
Leonard Hecker
3701d0ee95 Avoid async infinite loop on tab close (#15335)
When a tab gets closed, `_RemoveTab` will call `TabBase::Shutdown()`,
which then re-raises the `Closed` event, which will end up calling
`_RemoveTab` again, etc. The only reason this didn't crash WT so far
is because `_RemoveOnCloseRoutine` contains a `resume_foreground`,
which would resolve the recursion and turn it into CPU usage.
It would spin as long as WinUI hasn't discard the tab object,
which takes an unpredictable amount of time.

Raising the `Closed` event from `Shutdown()` is unnecessary, because
the handlers of the event end up calling `_RemoveTab` anyways.
Technically the entire `Closed` event can be removed now, but I left it
in anyways because resolving the architectural "knot" around the way
tab closing after the last pane closes is implemented requires much
more significant changes.

This commit additionally removes the `_createCloseLock` mutex in `Pane`
as it was very likely not working as intended anyways. Only some methods
were protected by it and it doesn't avoid any STA/MTA/NA issues either.

## Validation Steps Performed
* Closing tabs and panes always ends up calling `Shutdown()` 
2023-08-15 19:12:19 +00:00
Mike Griese
127df073fa Add support for "Tasks" in the Suggestions UI (#15664)
_targets #15027_

Adds a new suggestion source, `tasks`, that allows a user to open the
Suggestions UI with `sendInput` commands saved in their settings.
`source` becomes a flag setting, so it can be combined like so:

```json
        {
            "keys": "ctrl+shift+h", "command": { "action": "suggestions", "source": "commandHistory", "useCommandline":true },
        },
        {
            "keys": "ctrl+shift+y", "command": { "action": "suggestions", "source": "tasks", "useCommandline":false },
        },
        {
            "keys": "ctrl+shift+b", "command": { "action": "suggestions", "source": ["all"], "useCommandline":true },
        },
```

If a nested command has `sendInput` commands underneath it, this will
build a tree of commands that only include `sendInput`s as leaves (but
leave the rest of the nesting structure intact).


## References and Relevant Issues

Closes #1595

See also #13445 
As spec'd in #14864 

## Validation Steps Performed

Tested manually
2023-08-15 19:01:34 +00:00
Mike Griese
3afe7a8d11 Add a useCommandline property to the suggestions action (#15027)
_targets #14943_

When this is true, this will re-use the existing commandline to
pre-filter the results. This is especially helpful for completing a
suggestion based on the text that's already been typed.

Like with command history, this requires that shell integration is
enabled before it will work.## Summary of the Pull Request

## References and Relevant Issues

See also #13445 
As spec'd in #14864 

## Validation Steps Performed

Tested manually
2023-08-15 15:39:36 +00:00
Mike Griese
8f4c63e81b Plumb test failures through to github (#15831)
This does two bits:
1. correctly marks our tests as failed in xUnit, so that AzDo will pick
up that the tests have failed.
2. Actually intentionally mark skipped tests as skipped in xUnit. We
were doing this accidentally before.
3. Add a CI step to log test failures in a way that they can show up on
GitHub


Probably regressed around #6992 and #4490.

### details

#### Part the first
We were relying on the MUX build scripts to convert our WTT test logs to
xUnit format, which AzDo then ingests. That script we used relied on
some WinUI-specific logic around retrying tests. They have some logic to
auto-retry failed tests. They then mark a test as "skipped" if it passed
less than some threshold of times. Since we were never setting that
variable, we would mark a test as "skipped" if it had _0_ passes. So,
all failures showed up on AzDo as "skipped".

Why didn't we notice this? Well, the `Run-Tests.ps1` script will still
return `1` if _any_ tests failed. So the test job would fail if there
was a failure, AzDo just wouldn't know which test it was.

#### part the second
Updates `ConvertWttLogToXUnitLog` in `HelixTestHelpers.cs` to understand
that a test can be skipped, in addition to pass/fail. Removes all the
logic for dealing with retries, cause we didn't need that.

#### part the third
TAEF doesn't emit error messages in a way that AzDo can immediately pick
up on which tests failed. This means that Github gives us this useless
error message:

![image](https://github.com/microsoft/terminal/assets/18356694/3be6de00-22e1-421c-93d4-176bd2be4cab)
That's the only "error" that AzDo knows about. 

This PR changes that by adding a build step to manually parse the xUnit
results, and log the names of any tests that failed. By logging them
with a prefix of `##vso[task.logissue type=error]`, then AzDo will
surface that text as an error message. GitHub can then grab that text
and surface it too.

### Addenda: Why aren't we using the VsTest module
as noted in
https://github.com/microsoft/terminal/pull/4490#issuecomment-583104982,
the vstest module is literally 6x slower than just running TAEF
directly.
2023-08-15 09:50:15 -05:00
Mike Griese
e5a430ff68 Add support for opening the Suggestions UI with recent commands (#14943)
This adds support for a new action, `showSuggestions`, as described in
#14864. This adds just one `source` currently, `recentCommands`. This
requires shell integration to be enabled in the shell to work properly.
When it is enabled, activating that action will invoke the suggestions
UI as a palette, populated with `sendInput` actions for each of the
user's recent commands.

* These don't persist across reboots. 
* These are per-control.

There's mild plans to remedy that in a follow-up, though that needs a
bit more design consideration.

Closes #14779
2023-08-15 08:48:09 -05:00
Mike Griese
b556594793 Add an experimental setting for moving the cursor with the mouse (#15758)
## Summary of the Pull Request

This adds a new experimental per-setting to the terminal. 

```ts
"experimental.repositionCursorWithMouse": bool
```

When:
* the setting is on 
* AND you turn on shell integration (at least `133;B`)
* AND you click is somewhere _after_ the "active command" mark

we'll send a number of simulated keystrokes to the terminal based off
the number of cells between the place clicked and where the current
mouse cursor is.


## PR Checklist
- [ ] Related to #8573. I'm not marking as _closed_, because we should
probably polish this before we close that out. This is more a place to
start.

## Detailed Description of the Pull Request / Additional comments

There was a LOT of discussion in #8573. This is kinda a best effort
feature - it won't always work, but it should improve the experience
_most of the time_. We all kinda agreed that as much as the shell
probably should be responsible for doing this, there's myriad reasons
that won't work in practicality:
* That would also disable selection made by the terminal. That's a hard
sell.
* We'd need to invent some new mouse mode to support
click-to-reposition-but-drags-to-select-I-don't-want
* We'd then need shells to adopt that functionality.

And eventually settled that this was the least horrifying comprimise.

This has _e d g e  c a s e s_: 
* Does it work for wrapped lines? Well, kinda okay actually.
* Does it work for `vim`/`emacs`? Nope. 
* Does it work for emoji/wide glyphs? I wouldn't expect it to! I mean,
emoji input is messed up anyways, right?
* Other characters like `ESC` (which are rendered by the shell as two
cells "^[")? Nope.
* Does it do selections? Nope.
* Clicking across lines with continuation prompts? Nope.
* Tabs? Nope.
* Wraps within tmux/screen? Nope.


https://github.com/xtermjs/xterm.js/blob/master/src/browser/input/MoveToCell.ts
has probably a more complete implementation of how we'd want to generate
the keypresses and such.
2023-08-14 07:37:13 -05:00
Mike Griese
a0c88bb511 Add Suggestions UI & experimental shell completions support (#14938)
There's two parts to this PR that should be considered _separately_.
1. The Suggestions UI, a new graphical menu for displaying suggestions /
completions to the user in the context of the terminal the user is
working in.
2. The VsCode shell completions protocol. This enables the shell to
invoke this UI via a VT sequence.

These are being introduced at the same time, because they both require
one another. However, I need to absolutely emphasize:

### THE FORMAT OF THE COMPLETION PROTOCOL IS EXPERIMENTAL AND SUBJECT TO
CHANGE

This is what we've prototyped with VsCode, but we're still working on
how we want to conclusively define that protocol. However, we can also
refine the Suggestions UI independently of how the protocol is actually
implemented.

This will let us rev the Suggestions UI to support other things like
tooltips, recent commands, tasks, INDEPENDENTLY of us rev'ing the
completion protocol.

So yes, they're both here, but let's not nitpick that protocol for now. 

### Checklist

* Doesn't actually close anything
* Heavily related to #3121, but I'm not gonna say that's closed till we
settle on the protocol
* See also:
  * #1595
  * #14779
  * https://github.com/microsoft/vscode/pull/171648

### Detailed Description

#### Suggestions UI

The Suggestions UI is spec'ed over in #14864, so go read that. It's
basically a transient Command Palette, that floats by the user's cursor.
It's heavily forked from the Command Palette code, with all the business
about switching modes removed. The major bit of new code is
`SuggestionsControl::Anchor`. It also supports two "modes":
* A "palette", which is like the command palette - a list with a text
box
* A "menu", which is more like the intellisense flyout. No text box.
This is the mode that the shell completions use

#### Shell Completions Protocol

I literally cannot say this enough times - this protocol is experimental
and subject to change. Build on it at your own peril. It's disabled in
Release builds (but available in preview behind
`globals.experimental.enableShellCompletionMenu`), so that when it
ships, no one can take a dependency on it accidentally.

Right now we're just taking a blob of JSON, passing that up to the App
layer, who asks `Command` to parse it and build a list of `sendInput`
actions to populate the menu with. It's not a particularly elegant
solution, but it's good enough to prototype with.

#### How do I test this?

I've been testing this in two parts. You'll need a snippet in your
powershell profile, and a keybinding in the Terminal settings to trigger
it. The work together by binding <kbd>Ctrl+space</kbd> to _essentially_
send <kbd>F12</kbd><kbd>b</kbd>. Wacky, but it works.

```json
{ "command": { "action": "sendInput","input": "\u001b[24~b" }, "keys": "ctrl+space" },
```

```ps1
function Send-Completions2 {
  $commandLine = ""
  $cursorIndex = 0
  # TODO: Since fuzzy matching exists, should completions be provided only for character after the
  #       last space and then filter on the client side? That would let you trigger ctrl+space
  #       anywhere on a word and have full completions available
  [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$commandLine, [ref]$cursorIndex)
  $completionPrefix = $commandLine

  # Get completions
  $result = "`e]633;Completions"
  if ($completionPrefix.Length -gt 0) {
    # Get and send completions
    $completions = TabExpansion2 -inputScript $completionPrefix -cursorColumn $cursorIndex
    if ($null -ne $completions.CompletionMatches) {
      $result += ";$($completions.ReplacementIndex);$($completions.ReplacementLength);$($cursorIndex);"
      $result += $completions.CompletionMatches | ConvertTo-Json -Compress
    }
  }
  $result += "`a"

  Write-Host -NoNewLine $result
}

function Set-MappedKeyHandlers {
  # VS Code send completions request (may override Ctrl+Spacebar)
  Set-PSReadLineKeyHandler -Chord 'F12,b' -ScriptBlock {
    Send-Completions2
  }
}

# Register key handlers if PSReadLine is available
if (Get-Module -Name PSReadLine) {
  Set-MappedKeyHandlers
}

```


### TODO

* [x] `(prompt | format-hex).`<kbd>Ctrl+space</kbd> -> This always
throws an exception. Seems like the payload is always clipped to

```{"CompletionText":"Ascii","ListItemText":"Ascii","ResultType":5,"ToolTip":"string
Ascii { get```
  and that ain't JSON. Investigate on the pwsh side?
2023-08-14 05:46:42 -05:00
Dustin L. Howett
69eff7e9fd Rewrite the entire Azure DevOps build system (#15808)
This pull request rewrites the entire Azure DevOps build system.

The guiding principles behind this rewrite are:

- No pipeline definitions should contain steps (or tasks) directly.
- All jobs should be in template files.
- Any set of steps that is reused across multiple jobs must be in
  template files.
- All artifact names can be customized (via a property called
  `artifactStem` on all templates that produce or consume artifacts).
- No compilation happens outside of the "Build" phase, to consolidate
  the production and indexing of PDBs.
- **Building the project produces a `bin` directory.** That `bin`
  directory is therefore the primary currency of the build. Jobs will
  either produce or consume `bin` if they want to do anything with the
  build outputs.
- All step and job templates are named with `step` or `job` _first_,
  which disambiguates them in the templates directory.
- Most jobs can be run on different `pool`s, so that we can put
  expensive jobs on expensive build agents and cheap jobs on cheap
  build agents. Some jobs handle pool selection on their own, however.

Our original build pipelines used the `VSBuild` task _all over the
place._ This resulted in Terminal being built in myriad ways, different
for every pipeline. There was an attempt at standardization early on,
where `ci.yml` consumed jobs and steps templates... but when
`release.yml` was added, all of that went out the window.

The new pipelines are consistent and focus on a small, well-defined set
of jobs:

- `job-build-project`
    - This is the big one!
    - Takes a list of build configurations and platforms.
    - Produces an artifact named `build-PLATFORM-CONFIG` for the entire
      matrix of possibilities.
    - Optionally signs the output and produces a bill of materials.
    - Admittedly has a lot going on.
- `job-build-package-wpf`
    - Takes a list of build configurations and platforms.
    - Consumes the `build-` artifact for every config/platform
      possibility, plus one for "Any CPU" (hardcoded; this is where the
      .NET code builds)
    - Produces one `wpf-nupkg-CONFIG` for each configuration, merging
      all platforms.
    - Optionally signs the output and produces a bill of materials.
- `job-merge-msix-into-bundle`
    - Takes a list of build configurations and platforms.
    - Consumes the `build-` artifact for every config/platform
    - Produces one `appxbundle-CONFIG` for each configuration, merging
      all platforms for that config into one `msixbundle`.
    - Optionally signs the output and produces a bill of materials.
- `job-package-conpty`
    - Takes a list of build configurations and platforms.
    - Consumes the `build-` artifact for every config/platform
    - Produces one `conpty-nupkg-CONFIG` for each configuration, merging
      all platforms.
    - Optionally signs the output and produces a bill of materials.
- `job-test-project`
    - Takes **one** build config and **one** platform.
    - Consumes `build-PLATFORM-CONFIG`
    - Selects its own pools (hardcoded) because it knows about
      architectures and must choose the right agent arch.
    - Runs tests (directly on the build agent).
- `job-run-pgo-tests`
    - Just like the above, but runs tests where `IsPgo` is `true`
    - Collects all of the PGO counts and publishes a `pgc-intermediates`
      artifact for that platform and configuration.
- `job-pgo-merge-pgd`
    - Takes **one** build config and multiple platforms.
    - Consumes `build-$platform-CONFIG` for each platform.
    - Consumes `pgc-intermediates-$platform-CONFIG` for each platform.
    - Merges the `pgc` files into `pgd` files
    - Produces a new `pgd-` artifact.
- `job-pgo-build-nuget-and-publish`
    - Consumes the `pgd-` artifact from above.
    - Packs it into a `nupkg` and publishes it.
- `job-submit-windows-vpack`
    - Only expected to run against `Release`.
    - Consumes the `appxbundle-CONFIG` artifact.
    - Publishes it to a vpack for Windows to consume.
- `job-check-code-format`
    - Does not use artifacts. Runs `clang-format`.
- `job-index-github-codenav`
    - Does not use artifacts.

Fuzz submission is broken due to changes in the `onefuzz` client.

I have removed the compliance and security build because it is no longer
supported.

Finally, this pull request has some additional benefits:

- I've expanded the PGO build phase to cover ARM64!
- We can remove everything Helix-related except the WTT parser
    - We no longer depend on Helix submission or Helix pools
- The WPF control's inner DLLs are now codesigned (#15404)
- Symbols for the WPF control, both .NET and C++, are published
  alongside all other symbols.
- The files we submit to ESRP for signing are batched up into a single
  step[^1]

Closes #11874
Closes #11974
Closes #15404

[^1]: This will have to change if we want to sign the individual
per-architecture `.appx` files before bundling so that they can be
directly installed.
2023-08-11 14:06:30 -05:00
Mike Griese
d943fa41f6 Add walkthroughs to CONTRIBUTING.md (#15799)
Change the "good first issues" text to talk about walkthroughs instead.
2023-08-11 14:57:40 +00:00
Leonard Hecker
5b44476048 Replace IInputEvent with INPUT_RECORD (#15673)
`IInputEvent` makes adding Unicode support to `InputBuffer` more
difficult than necessary as the abstract class makes downcasting
as well as copying quite verbose. I found that using `INPUT_RECORD`s
directly leads to a significantly simplified implementation.

In addition, this commit fixes at least one bug: The previous approach
to detect the null key via `DoActiveModifierKeysMatch` didn't work.
As it compared the modifier keys as a bitset with `==` it failed to
match whenever the numpad key was set, which it usually is.

## Validation Steps Performed
* Unit and feature tests are 
2023-08-11 14:06:08 +00:00
Leonard Hecker
e9c8391fd5 Fix compilation with Visual Studio 17.8 (#15819)
This broke with https://github.com/microsoft/STL/pull/3721
It's a minor issue and a minor fix. :)
2023-08-11 15:17:18 +02:00
Mike Griese
256d46ad6b Fix the TilWinRT tests (#15820)
It's unknown how this ever worked, or why it stopped working recently.

We removed our desire to directly compare property against T at some point.
2023-08-10 22:13:36 +00:00
LitoMore
6a29ca2ada README: Fix GitHub built-in note highlight styles (#15807)
## Summary of the Pull Request

I updated the note prefix for blockquotes with GitHub latest built-in
styles.

## References and Relevant Issues

- https://github.com/orgs/community/discussions/16925

## Detailed Description of the Pull Request / Additional comments

This PR fixed the broken style due to their format change.

## Related former Pull Request

- https://github.com/microsoft/terminal/pull/13615
2023-08-08 11:15:16 -05:00
Mike Griese
1ed57cc5c9 Add a note about how to run the UIA tests locally (#15806)
Carlos and I spent an hour rediscovering how to make this work. I
figured it'd be best to leave notes behind for future archeologists.
2023-08-08 11:14:47 -05:00
Tushar Singh
9b70a40bf9 ConHost: Ignore WM_[SYS]KEYDOWN/WM_[SYS]KEYUP events with an invalid virtual keycode and a scan code of 0 (#15753)
## Summary
Applications like PowerToys, with their keyboard remapping features
frequently (i.e whenever a remapped shortcut is triggerred) send
`KeyEvent` with out-of-range virtual keycode values (E.g. 0xFF). This is
fixed for WT in #7145, we just needed it in our good ol' `conhost`.

After this PR, Key events with an invalid virtual keycode and
scancode==0 are ignored, and are not added to the `InputBuffer`. Incase,
only virtual keycode is valid but not scancode, we will try to infer the
correct scancode using the virtual keycode mapping.

## References and Relevant Issues
#7145 
#7064 

## Validation Steps Performed

- Triggered a remapped shortcut and verified that `showkey -a` doesn't
output `^@` unexpectedly.
- Key events with an Invalid virtual Keycode and Scancode == 0 are
ignored.
- This PR doesn't include any changes for `WM_[SYS][DEAD]CHAR` messages,
they are left unchanged.
2023-08-08 10:58:34 -05:00
Leonard Hecker
c6e5f79115 Modernize CommandHistory and switch to int32 (#15782)
This commit slightly modernizes `CommandHistory` by leaning more heavily
on the STL container functionalities. For one, it uses for-range
iterations to loop through `_commands` instead of using `GetNth`
on every iteration. Another major improvement however is that
the code previously copied entire `CommandHistory` instances out of
the linked list `s_historyLists`, then removed the slot and copied
(not moved!) that instance into the front again. Now it uses the
`splice` function from `std::list` to do it in `O(1)` and virtually
cost-free.

Another major improvement (and the one I'm personally interested in)
is the switch from `SHORT` to `int32_t`. This will greatly simplify
the implementation of the future `COOKED_READ_DATA` class, as the
larger integer type will remove worries about over/underflow.
For instance, we can then just blindly increment/decrement the history
position and then only later clamp it to the expected range.

## Validation Steps Performed
* Existing history tests 
* History cycling with F8 
* Navigating history with F7 
2023-08-01 22:46:40 +00:00
Leonard Hecker
2d7066f5c6 Remove IsValidStringBuffer helper (#15781)
This change is a fairly subjective one. It was done because
`IsValidStringBuffer` will very soon be the only function left
in `cmdline.cpp`. Removing it allows removing `cmdline.cpp`.
While the code that replaces it is somewhat tricky, it's also much
more straightforward, as the `IsValidStringBuffer` function didn't
just check if the string buffer is valid - it also retrieved the
pointers to each of the strings contained in the buffer.

## Validation Steps Performed
Exhaustively covered by conhost feature tests 
2023-08-01 19:27:08 +00:00
Leonard Hecker
07566fac4c Merge ReadConsoleA/W API routines (#15780)
This is a minor cleanup to deduplicate the two ReadConsole methods
and will help with making changes to how `COOKED_READ_DATA` is called.
It additionally changes the initial data payload from a `string_view`
to a `wstring_view` as it is guaranteed to be `wchar_t`.
This matches the current `COOKED_READ_DATA` implementation which
blindly assumes that the initial data consists of `wchar_t`.

Closes #5618
2023-08-01 16:13:51 +00:00
Leonard Hecker
a4340af1e7 Add text based cursor movement helpers (#15779)
`COOKED_READ_DATA` is a little special and requires cursor navigation
based on the raw (buffered) text contents instead of what's in the
text buffer. This requires the introduction of new helper functions
to implement such cursor navigation. They're made part of `TextBuffer`
as these helpers will get support graphemes in the future.
It also helps keeping it close to `TextBuffer` as the cursor
navigation should optimally behave identical between the two.

Part of #8000.
2023-08-01 00:00:57 +00:00
Brandon Dong
57b9549ff8 Fix matches of multiple schemas on "colorScheme" (#15748)
Adds proper `type` for `SchemePair` definition to avoid warnings about matches of multiple schemas.

Same fix as https://github.com/microsoft/terminal/pull/4045

## Validation Steps Performed
- Pointed $schema to local file instead of https://aka.ms/terminal-profiles-schema
- Confirmed warning goes away when using a string
- Confirmed using the light/dark object format still passes validation
- Confirmed values like `"colorScheme": 3` no longer incorrectly pass validation whereas they would before
2023-07-26 17:13:49 -07:00
Carlos Zamora
1f9426b051 Fix Default Terminal and Color Scheme ComboBoxes cropping at 200% Text Size (#15762)
When the OS' "text size" setting gets set to 200% and the display
resolution is reduced quite a bit, we get some cropped text in the SUI's
Default Terminal ComboBox. Turns out, we have a height set on the items.
I went ahead and removed that so we don't crop the text. Everything
looks good still!

A similar issue occurs in the Profile > Appearance > Color Scheme
ComboBox. I went ahead and fixed that too by removing the height
restriction.

Other minor changes:
- fixed the comments
- changed "author and version" row to "auto" instead of "*" (star sizing
is great for proportional sizing, so we're not really taking advantage
of it)

Closes #15149
2023-07-26 18:25:19 -05:00
Dustin L. Howett
cbe915c554 Add support for ARM64 testing, reintroduce it in CI (#15761)
This pull request introduces the arm64 testing agents and a few build
phases to use them.

In addition to running the ARM64 tests in CI, it makes the following
changes:

- The x64 tests now run on equivalent x64 testing agents
- We now run ARM64 builds (and tests!) on all pull requests
- I've deduplicated a lot of the build and test stages
- New queue-time parameters have been added to control various phases,
  for quick pipeline testing
- A bunch of conditions have been promoted to compile-time checks to
  control the existence of stages and steps more tightly
2023-07-26 16:22:18 -07:00
Carlos Zamora
d70794a246 Add UIA element grouping to SettingsContainer (#15756)
Adds an `AutomationProperty.Name` to the main grid in the `SettingContainer`. Doing so makes it so that the group of elements is considered a "group \<header\>".

Now, when navigating with a screen reader, when you enter the group of elements, the "group \<header\>" will be presented. Thus, if the user navigates to the "reset" button, it'll be prefaced with a "group \<header\>" announcement first. If the user navigates to it from the other direction (the setting control), this announcement isn't made, but the user already has an understanding of what group of settings they're in, which is standard practice.

Closes #15158
2023-07-25 13:42:47 -07:00
Dustin L. Howett
1a40ff3746 Switch away from the WinDev agent pools (#15755)
Using our own pools like this gives us a lot of freedom in the tooling
that's installed, the OS versions it targets, and when we take on Visual
Studio updates.

As part of this effort, I've also stood up a "small" agent pool. At the
time of this PR, that pool is using D2ads-v5 SKU VMs (2 vcore 8 GiB)
versus the "large" agent pool's D8as-v5 (8 vcore 32 GiB). Smaller build
tasks have been moved over to the small pool. Compilation's the hard
part, so it gets to stay on the large pool.
2023-07-25 13:19:41 -07:00
Dustin L. Howett
5daf4983d2 Consolidate and clean up all API logging (#15737)
`s_TraceApi` was a magic function in Tracing that logged a different
event based on what type it was called with. It was bad for two reasons:

1. I wanted to add a field to each trace indicating the originating
process and thread. This would have required adding a `CONSOLE_API_MSG`
parameter to _every instance_ of `s_TraceApi`, and even then it would
have not been particularly consistent.
2. The design of Tracing, where the TraceLogging macros are hidden
inside opaque functions, subverts the lightweight trace probe detection
present in `TraceLoggingWrite`. Every tracing probe turned into a call
to a cold function which, in 99% of cases, returned immediately.

To that end, I've introduced a new macro _only_ to ApiDispatchers that
emits a named probe with a set of preloaded information. It is a macro
to avoid any unnecessary branching or the emission of any explicit
tracing functions into the final binary.

I have also removed the generic handler for timing any/all API calls, as
we never used them and they were largely redundant with the information
we were capturing from API-specific reports.

I've also removed tracing from all APIs that do not mutate console
state. With the notable exception of ReadConsoleInput, we will see logs
only for things that change mutable console state.

All these things together allows us to construct a process+API-focused
timeline of console events, ala:

```
cmd.exe (20304)   CookedRead          pwsh                4                07/13/2023 22:02:53.751
cmd.exe (20304)   API_GetConsoleMode  True
cmd.exe (20304)   API_SetConsoleMode  False               0x00000003
cmd.exe (20304)   API_SetConsoleMode  True                0x000001F7
pwsh.exe (4032)   ConsoleAttachDetach 07/13/2023 22:03:17.393              True                True
pwsh.exe (4032)   API_GetConsoleMode  False
pwsh.exe (4032)   API_GetConsoleMode  False
pwsh.exe (4032)   API_SetConsoleMode  False               0x00000007
```

This pull request also switches the ConsoleAttachDetach and CookedRead
reports to use the PID and FILETIME markings for their pids and
filetimes. This is compatible with the uint32 and uint64 fields that
used to use those names, so anybody who was depending on them will
experience no change in functionality.

I also switched up their order to make them more ergonomic in WPA when
combined with the other API_ tracing (as viewed above.)
2023-07-21 19:00:37 +00:00
Tushar Singh
3de496d589 Add support for ITU's T.416 - ODA SGR (38/48) sequence (#15729)
This PR adds support for **ITU's T.416 - ODA SGR (38/48)** colour
sequence, which makes use of colon instead of semi-colon as a parameter
separator.

- We use semi-colons as the only parameter separator while sending SGR
color sequences to a ConPTY client. This is to keep backward
compatibility.
- In response to `DECRQSS` query, we have decided to use colons, as the
major usecase for such queries are feature detection (whether client
supports ODA colours), and tracking the original separator may add too
much complexity to the codebase.

## Validation Steps Performed

- Made sure that we are always sending semi-colon separated parameters
regardless of whether the original sequence used colons.
- Made sure that we are always using colons as the parameter separator
in a `DECRQSS` response.
- Added new tests!

Closes #15706
2023-07-21 10:47:54 -05:00
James Pack
7fba298a60 Replace deprecated await winrt::apartment_context pattern (#15725)
Replace deprecated winrt::apartment_context pattern

I only found 2 instances of this pattern in use and one of them was
actually already replaced but the `co_await winrt::apartment_context`
code was still there.

Tested both window renaming and opening terminal with persisted layouts.
Both still work.

Closes #12982
2023-07-20 17:25:22 -05:00
Mike Griese
0e90b85f5a Spec for shell integration marks (#14792)
## Summary of the Pull Request

> ## Abstract
> 
> _"Shell integration" refers to a broad category of ways by which a
commandline
> shell can drive richer integration with the terminal. This spec in
particular is
> most concerned with "marks" and other semantic markup of the buffer._
> 
> Marks are a new buffer-side feature that allow the commandline
application or
> user to add a bit of metadata to a range of text. This can be used for
marking a
> region of text as a prompt, marking a command as succeeded or failed,
quickly
> marking errors in the output. These marks can then be exposed to the
user as
> pips on the scrollbar, or as icons in the margins. Additionally, the
user can
> quickly scroll between different marks, to allow easy navigation
between
> important information in the buffer.
> 
> Marks in the Windows Terminal are a combination of functionality from
a variety
> of different terminal emulators. "Marks" attmepts to unify these
different, but
> related pieces of functionality.


## Detailed Description of the Pull Request / Additional comments

_\*<sup>\*</sup><sub>\*</sub> read the spec
<sub>\*</sub><sup>\*</sup>\*_

In all seriousness, I've already implemented a pile of this. This is
just putting the finishing touches of formalizing it.

## PR Checklist
- [x] This is a spec for #11000 and everything linked to that.
2023-07-20 17:24:42 -05:00
James Pack
42e9ddcc78 Add support for running profiles from Add tab menu as admin without a keyboard (#15679)
## Summary of the Pull Request
Add support for running profiles in the Add Tab drop down as
administrator without a keyboard.
## References and Relevant Issues
#14517 
## Detailed Description of the Pull Request / Additional comments
This pull request adds a FlyoutMenu to each Profile entry in the Add New
tab drop down. When a profile is right clicked or held for 2 seconds in
the case of no mouse input will present a MenuItem to allow the user to
click and run the selected profile as administrator
## Validation Steps Performed
- Responds to pointer input events (mouse, pointer, touchpad)
- Adjusts to theme changes.
- Only shows when a profile is selected. Will not show on settings or
pallete entries

## PR Checklist
- [x] Closes #14517 
- [ ] 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 (if necessary)
2023-07-20 11:09:57 -05:00
Mike Griese
648d240105 Add an action to display toast with the CWD of the Terminal (#15282)
Adds an action to display a toast containing the Terminal's "virtual"
CWD.

As described in
https://github.com/microsoft/terminal/issues/4637#issuecomment-1531979200.

Useful for debugging #5506 et. al. I almost left it as a debug-only
feature, but figured it would be helpful for others in the #4637
landscape of things.
2023-07-20 11:09:21 -05:00
Mike Griese
7010626497 Refrigerate our threads for later reuse (#15424)
This is my proposed solution to #15384.

Basically, the issue is that we cannot ever close a
`DesktopWindowXamlSource` ("DWXS"). If we do, then any other thread that
tries to access XAML metadata will explode, which happens frequently. A
DWXS is inextricably linked to an HWND. That means we have to not only
reuse DWXS's, but the HWNDs themselves. XAML also isn't agile, so we've
got to keep the `thread` that the DWXS was started on alive as well.

To do this, we're going to introduce the ability to "refrigerate" and
"reheat" window threads.
* A window thread is "**hot**" if it's actively got a window, and is
pumping window messages, and generally, is a normal thing.
* When a window is closed, we need to "**refrigerate**" it's
`WindowThread` and `IslandWindow`. `WindowEmperor` will take care of
tracking the threads that are refrigerated.
* When a new window is requested, the Emperor first try to
"**reheat**"/"**microwave**" a refrigerated thread. When a thread gets
reheated, we'll create a new AppHost (and `TerminalWindow`/`Page`), and
we'll use the _existing_ `IslandWindow` for that instance.

<sub>The metaphor is obviously ridiculous, but _you get it_ so who
cares.</sub>

In this way, we'll keep all the windows we've ever created around in
memory, for later reuse. This means that the leak goes from (~12MB x
number of windows closed) to (~12MB x maximum number of simultaneously
open Terminal windows). It's still not good.

We won't do this on Windows 11, because the bug that is the fundamental
premise of this issue is fixed already in the OS.




I'm not 100% confident in this yet. 
* [x] There's still a d3d leak of some sort on exit in debug builds.
(maybe #15306 related)
* havent seen this in a while. Must have been a issue in an earlier
revision.
* [x] I need to validate more on Windows 11
* [x] **BAD**: Closing the last tab on Windows 11 doesn't close the
window
* [x] **BAD**: Closing a window on Windows 11 doesn't close the window -
it just closes the one tab item and keeps on choochin'
* [x] **BAD**: Close last tab, open new one, attempt to close window -
ALL windows go \*poof\*. Cause of course. No break into post-mortem
either.
* [x] more comments
* [ ] maybe a diagram
* [x] Restoring windows is at the wrong place entirely? I once reopened
the Terminal with two persisted windows, and it created one at 0,0
* [x] Remaining code TODO!s: 0 (?)
* [ ] "warm-reloading" `useTabsInTitlebar` (change while terminal is
running after closing a window, open a new one) REALLY doesn't work.
Obviously restores the last kind of window. Yike.

is all about #15384

closes #15410 along the way. Might fork that fix off.
2023-07-19 15:52:18 +00:00
Mike Griese
6a10ea5a7e Add support for broadcasting to all panes in a tab (#14393)
Resurrection of #9222. 
Spec draft in #9365.

Consensus from community feedback is that the whole of that spec is
_nice to have_, but what REALLY matters is just broadcasting to all the
panes in a tab. So, in the interest of best serving our community, I'm
pushing this out as the initial implementation, before we figure out the
rest of design. Regardless of how we choose to implement the rest of the
features detailed in the spec, the UX for this part of the feature
remains the same.

This PR adds a new action: `toggleBroadcastInput`. Performing this
action starts broadcasting to all panes in this tab. Keystrokes in one
pane will be sent to all panes in the tab.

An icon in the tab is used to indicate when this mode is active.
Furthermore, the borders of all panes will be highlighted with
`SystemAccentColorDark2`/`SystemAccentColorLight2` (depending on the
theme), to indicate they're also active.

* [x] Closes #2634. 
  - (we should lick a reserved thread for follow-ups)

Co-authored-by: Don-Vito khvitaly@gmail.com
2023-07-19 15:45:25 +00:00
Mike Griese
b4042eaaf0 Let marks be cleared by clear (and friends) (#15686)
Move scroll marks to `TextBuffer`, so they can be cleared by
EraseInDisplay and EraseScrollback.

Also removes the namespacing on them.

## References and Relevant Issues
* see also #11000 and #15057
* Resize/Reflow _doesn't_ work yet and I'm not attempting this here. 

## Validation Steps Performed

* `cls` works
* `Clear-Host` works
* `clear` works
* the "Clear buffer" action works
* They work when there's marks above the current viewport, and clear the
scrollback
* they work if you clear multiple "pages" of output, then scroll back to
where marks previously were
* resizing doesn't totally destroy the marks

Closes #15426
2023-07-18 21:10:57 +00:00
Florian Heberl
482c724de6 Add Christopher Nguyen to the README (#15723)
Add Christopher Nguyen to Readme

Co-authored-by: Mike Griese <migrie@microsoft.com>
2023-07-18 14:29:52 -05:00
Mike Griese
df8addb068 update zadjii's socials 2023-07-18 14:28:13 -05:00
Leonard Hecker
89c39b06ed Fix horizontal scrolling bugs in AtlasEngine/DxEngine (#15707)
This commit fixes a number of issues around horizontal scrolling.
DxEngine only had one bug, where the clip rect would cause any content
outside of the actual viewport to be invisible. AtlasEngine had more
bugs, mostly around the conversion from textbuffer-relative coordinates
to viewport-relative coordinates, since AtlasEngine stores things like
the cursor position, attributes, etc., relative to the viewport.

It also renames `cellCount` to `viewportCellCount`, because I realized
that it might have to deal with a `textBufferCellCount` or similar in
the future. I hope that the new name is more descriptive of what it
refers to.

Future improvements to AtlasEngine in particular would be to not copy
the entire `Settings` struct every time the horizontal scroll offset
changes, and to trim trailing whitespace before shaping text.

This is in preparation for #1860

## Validation Steps Performed
* Patch `RenderingTests` to run in the main (and not alt) buffer
* Horizontal scrolling of line renditions and attributes works 
* Selection retains its position (mostly) 
2023-07-18 13:35:18 -05:00
Tushar Singh
6873c85d2d Add support for colon separated sub-parameters (#15648)
Adds support for colon `:` separated sub parameters in parser.
Technically, after this PR, nothing should change except, now sub
parameters are parsed, stored safely and we don't invalidate the whole
sequence when a `:` is received within a parameter substring.

In this PR:
- If sub parameters are detected with a parameter, but the usage is
unrecognised, we simply *skip* the parameter in `adaptDispatch`.
- A separate store for sub parameters is used to avoid too many changes
to the codebase.
- We currently allow up to `6` sub parameters for each parameter, extra
sub parameters are *ignored*.
- Introduced `VTSubParameters` for easy access to underlying sub
parameters.

> **Info**: We don't use sub parameters for any feature yet, this is
just the core implementation to support newer usecases.

## Validation Steps Performed
- [x] Use of sub parameters must not have any effect on the output.
- [x] Skip parameters with unexpected set of sub parameters.
- [x] Skip sequences with unexpected set of sub parameters.

References #4321
References #7228
References #15599
References https://github.com/xtermjs/xterm.js/pull/2751
Closes #4321
2023-07-18 13:28:45 -05:00
Leonard Hecker
11a9808d85 Clean up WriteConsoleInputA conversion (#15672)
This commit inlines `EventsToUnicode` into `WriteConsoleInputAImpl`
because soon we'll not use deques for events anymore and so the old
code won't work. It cleans up the implementation because I intend to
move all this code directly into `InputBuffer` to have a better and
tighter control over how text gets converted. UTF-8 input for instance
requires the storage of up to 3 input events and this code is not fit
to handle that. It's also unmaintainable because our input handling
code shouldn't be spread over a dozen files either. 😄

## Validation Steps Performed
* Unit and feature tests are 
2023-07-18 18:16:03 +00:00
Dave Rayment
1c8862938b Add winget installation note for README.md (#15674)
Adds a note to the ReadMe's installation instructions which describes
why current versions of Terminal are unavailable via winget.

## PR Checklist
- [x] Closes #15663 
- [ ] 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 (if necessary)
2023-07-18 14:49:14 +00:00
nxya
91012a4e3f Added background to CommandKeyChord (#15677)
## Summary of the Pull Request

Adds a background to key chord border in the CommandPalette Screen. This
prevents certain accent colors from rendering the KeyChords unreadable.

Before (where the text is unreadble);

![image](https://github.com/microsoft/terminal/assets/33658638/370fa7c7-f42e-48b3-af54-6fe7d5f89c73)

After (from this PR):

![image](https://github.com/microsoft/terminal/assets/33658638/5ce8601a-80f2-4efe-9270-9dd7209cdfff)

See #15228 for more details
2023-07-17 19:27:05 +00:00
Dan Albrecht
f4bcbfbadd Fix C2664 errors (#15714)
## Summary of the Pull Request
Fix C2664 errors under latest compiler.

## References and Relevant Issues
#15309

## Detailed Description of the Pull Request / Additional comments
- Latest compilers are more strict
- Internal background of change:
[DevDiv:1810844](https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1810844)

## Validation Steps Performed
- Now successfully builds under VS `17.8.0 Preview 1.0 `
- Still successfully builds under VS `17.6.5`

## PR Checklist
- [x] Closes #15309
- [ ] 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 (if necessary)

---------

Co-authored-by: Dan Albrecht <danalb@ntdev.microsoft.com>
2023-07-17 13:57:27 +00:00
Leonard Hecker
e078ddd129 Add ConsoleMonitor: A tool for displaying ConPTY contents (#15692)
I wrote this tool to help me test the buffer reflow code in Windows
Terminal. It needs to stay in sync with the buffer contents in ConPTY
which is somewhat tricky to achieve. This tool will make this easier
because it allows me to quickly, visually compare the contents.
2023-07-17 13:42:40 +00:00
Leonard Hecker
e1ab64e056 Clean up InputBuffer coalescing and preprocessing (#15671)
This reverts a number of changes to input handling to how it used to be
in conhost v1. It merges the input event coalescing logic into a single
function and inlines the console suspension event handling, because
soon these functions will receive `std::span` arguments which cannot
be preprocessed anymore, unlike a `std::deque`.

It also adds back support for Ctrl-S being an alias for VK_PAUSE
which was lost in commit fccc7410 in 2018.

Closes #809

## Validation Steps Performed
* Unit and feature tests are 
* Ctrl-S pauses output 🎉
2023-07-12 17:18:17 +00:00
Dustin L. Howett
2f0d3dc17a Remove TerminalTrySetDarkTheme, use the DWMWA directly (#15667)
The DWMWA for this has been documented for quite a while now!

I've also updated to a version of TerminalThemeHelpers that removes all the Dark Theme exports.
2023-07-07 05:46:06 -05:00
microsoft-github-policy-service[bot]
258a31cdf7 Onboard to GitOps.ResourceManagement (#15557)
Add prIssueManagement.yml to onboard repo to GitOps.ResourceManagement
as FabricBot replacement

---------

Co-authored-by: microsoft-github-policy-service[bot] <77245923+microsoft-github-policy-service[bot]@users.noreply.github.com>
2023-07-06 17:03:01 -05:00
Gonzalo García
0c64b8a105 Added: Copy text without dismissing the selection (#15552)
## Summary of the Pull Request
Adds a dismiss selection option to the "copy" action.

## PR Checklist
- [x] Closes #15371
- [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:
MicrosoftDocs/terminal#686
- [x] Schema updated (if necessary)

---------

Co-authored-by: Carlos Zamora <carlos.zamora@microsoft.com>
2023-07-06 16:37:59 +00:00
Leonard Hecker
167819a8f4 Add an ASCII fast-pass to ROW (#15499)
Performance of printing enwik8.txt at the following block sizes:
4KiB (printf): 78MB/s -> 93MB/s
128KiB (cat): 117MB/s -> 156MB/s

The change itself is rather self-explanatory.
A tighter, simpler loop runs faster.

## Validation Steps Performed
Mixed ASCII/Unicode text output looks generally correct. 
2023-07-05 21:26:15 +02:00
Leonard Hecker
94e6b91c78 We've been trying to reach you about your WriteCharsLegacy's extended Emoji support (#15567)
This is a complete rewrite of the old `WriteCharsLegacy` function
which is used when VT mode is disabled as well as for all interactive
console input handling on Windows. The previous code was almost
horrifying in some aspects as it first wrote the incoming text into a
local buffer, stripping/replacing any control characters. That's not
particular fast and never was. It's unknown why it was like that.

It also measured the width of each glyph to correctly determine the
cursor position and line wrapping. Presumably this used to work quite
well in the original console code, because it would then just copy
that local buffer into the destination text buffer, but with the
introduction of the broken and extremely slow `OutputCellIterator`
abstraction this would end up measuring all text twice and cause
disagreements between `WriteCharsLegacy`'s idea of the cursor position
and `OutputCellIterator`'s cursor position. Emoji input was basically
entirely broken. This PR fixes it by passing any incoming text
straight to the `TextBuffer` as well as by using its cursor positioning
facilities to correctly implement wrapping and backspace handling.

Backspacing over Emojis and an array of other aspects still don't work
correctly thanks to cmdline.cpp, but it works quite a lot better now.

Related to #8000
Closes #8839
Closes #10808

## Validation Steps Performed
* Printing various Unicode text 
* On an fgets() input line
  * Typing text works 
  * Inserting text works anywhere 
  * Ctrl+X is translated to ^X 
  * Null is translated to ^@ 
    This was tested by hardcoding the `OutputMode` to 3 instead of 7.
  * Backspace only advances to start of the input 
  * Backspace deletes the entire preceding tab 
  * Backspace doesn't delete whitespace preceding a tab 
  * Backspacing a force-wrapped wide glyph unwraps the line break 
  * Backspacing ^X deletes both glyphs 
  * Backspacing a force-wrapped tab deletes trailing whitespace 
* When executing
  ```cpp
  fputs("foo: ", stdout);
  fgets(buffer, stdin);
  ```
  pressing tab and then backspace does not delete the whitespace
  that follows after the "foo:" string (= `sOriginalXPosition`).
2023-06-30 14:51:07 -05:00
Leonard Hecker
030db09528 Refactor TerminalInput to return strings (#15611)
`TerminalInput` is configurable, but almost entirely state-less.
As such it isn't helpful that it emits its output via a callback.
It makes tracing the flow of data harder purely from reading the code
and also raises uncertainty about when `TerminalInput` may generate
output. This commit makes it more robust by having `TerminalInput`
simply return its data. Furthermore, it returns that data as a string
instead of converting back and forth between text and `IInputEvent`.

This change will help me make conhost's `InputBuffer` implementation
leaner and help me confidently make more difficult changes to it
with the goal to improve our Unicode support/correctness.

## Validation Steps Performed
* Windows Terminal produces correct results with `showkey -a` 
2023-06-30 09:37:54 -07:00
Leonard Hecker
a084834596 AtlasEngine: Harden against empty target sizes (#15615)
The WPF control has a minor bug where it initializes the renderer
when there isn't even a window yet. When it then calls `SetWindowSize`
it'll pass the result of `GetWindowRect` which is `0,0,0,0`.
This made AtlasEngine unhappy because it restricted the glyph atlas
size to some multiple of the window size. If the window size is `0,0`
then there couldn't be a glyph atlas and so it crashed.

## Validation Steps Performed
* Fixes WPF test control crash on startup 
2023-06-30 16:35:05 +00:00
Leonard Hecker
d628c46cd6 Add benchcat: cat + throughput measurements (#15564)
benchcat, "bc" for short, is a tool that I've written over the last
two years to help me benchmark OpenConsole and Windows Terminal.
Initially it only measured the time it took to print a file as fast as
possible, but it's grown to support a number of arguments, including
chunk (`WriteFile` call) sizes, repeat counts and VT mode with italic
and colorized output. In the future I also wish to add a way to
generate the output data on the fly via command line arguments.

One unusual trait of benchcat is that it is compiled entirely without
CRT and vcruntime. I did this so that I could test it on Windows XP.
Also, it's kind of funny seeing how it's only about 11kB.

This commit also fixes a couple `$LASTEXITCODE` cases, because our
spellchecker was bothering me a lot with this PR and so I just fixed it.
2023-06-30 14:18:35 +00:00
Leonard Hecker
c22d9b1c77 Vectorize StateMachine::ProcessString (#15498)
The added explicit vectorization allows us to skip plain text faster
and pass it immediately to the deeper `TextBuffer` parts.

Performance of printing enwik8.txt at the following block sizes:
4KiB (printf): 54MB/s -> 58MB/s
128KiB (cat): 103MB/s -> 116MB/s

## Validation Steps Performed
* Works on x64 
* Works on ARM 
2023-06-30 14:10:58 +00:00
Leonard Hecker
358e10b17f Fix VtEngine hang when resizing while scrolling (#15618)
This fixes a bug reported internally that occurs when resizing the
terminal while also scolling the contents. The easiest way to reproduce
it is to resize the terminal to 0 rows, but it's much more prominent
in a debug build where everything goes out of sync almost immediately.

The underlying issue is that `VtEngine::_wrappedRow` may contain an
offset that is outside of the viewport bounds, because reflowing and
scrolling aren't properly synchronized. The previous `bitmap` code
would then throw an exception for such invalid coordinates and cause
the internal `VtEngine` state to be broken. Once `_wrappedRow` got
to a negative value at least once, it would stay that way unless you're
scrolling up. If the contents are actively scrolling it would quickly
reach a negative value from which it can never recover. At that point
OpenConsole would enter a tight exception-throw-catch-retry loop
and Windows Terminal seemingly cease to show any content.

## Validation Steps Performed
* Resize WT to the minimal window size repeatedly
* Doesn't hang 
2023-06-29 15:49:56 -05:00
Dustin L. Howett
80f2776272 Launch the settings in the PGO harness (#15631)
When we moved the settings UI to lazy initialization in #15628, we broke
PGO. Apparently, we were PGOing the tiny part of Settings that was being
loaded on every launch (e.g. the XAML metadata provider 🤦)

Let's actually PGO launching the settings.
2023-06-29 15:48:54 -05:00
Leonard Hecker
a56029a807 Update /Zc build flags to be more standard conforming (#15604)
This commit removes some flags that we don't need anymore, and adds all
those `/Zc` (standard conformance) switches that aren't enabled by
default yet. This will help us and the MSVC team detect bugs early.

This removes:
* `/fp:contract`: With the addition of `TIL_FAST_MATH_BEGIN`
  all the code that benefits from FMA now uses `/fp:fast`.
* `/Zc:lambda`: Automatically enabled with C++20.

This adds:
* `/Zc:__cplusplus` / `/Zc:__STDC__`: Without these `__cplusplus`
  defaults to `199711L` and `__STDC__` remains undefined.
* `/Zc:enumTypes`: The C++ standard specifies that an enum with
  unspecifies size has a size that fits its members exactly.
  An enum with byte-sized members has a `sizeof` of 1 and not 4.
* `/Zc:templateScope`: Emit errors when shadowing template parameters.

And most importantly:
* `<RemoveUnreferencedCodeData>`, which is `/Zc:inline`
  Without this, MSVC treats `inline` functions sort of like external
  linkage ones. You can declare an inline function in one file and
  then just define it in another. Or use an inline function from
  another file. With this flag, the compiler can stop emitting
  COMDAT references for these which reduces object file sizes.
2023-06-28 23:59:26 +00:00
Dustin L. Howett
0f41851e67 Lazily load the settings UI DLL (#15628)
Due to an implementation detail in the Xaml compiler--which wants to
ensure that all metadata providers on an App are available
immediately--we were eagerly loading the settings UI DLL and all of its
dependencies, even in sessions where the user was not going to open
Settings.

By turning off eager provider generation and handling it ourselves, we
get to control exactly when the settings UI is loaded.

This required some gentle poking-through of the barrier between App and
Page, but it is almost certainly worth it.

Turning on the Xaml code generation flag to not generate providers
automatically adds an `AddProvider` member to the internal interface for
the autogenerated XamlMetadataProvider. We needed to switch to using the
internal interface rather than the projected type in our custom App base
class to get at it.

Providers that App/Page use must be initialized by the time we start the
WindowsXamlManager, so we load Control and Controls (ha) eagerly and
early.

It looks like it may save 400ms of CPU time (?) on startup.
2023-06-28 15:32:51 -05:00
Leonard Hecker
72b44888b5 Reduce GdiEngine input latency (#15608)
This commit reduces GdiEngine's average display latency by 8ms,
which caused it to miss a v-blank about half the time at 60Hz.

Closes #15607

## Validation Steps Performed
Input latency with `frarees/typometer` matches conhost from Win10 
2023-06-28 00:14:42 +02:00
Dustin L. Howett
99c18ce57e wpf: delay-load UIAutomationCore because it's incomplete in RS1 (#15614)
UiaRaiseNotificationEvent is not present on Windows Server 2016, even
though it is documented as being present.
This also removes the cost of loading up UIAutomationCore from the
critical path.
2023-06-27 21:42:20 +00:00
Leonard Hecker
58e1380b8f Properly filter focus events from the console API (#15606)
This is an improved fix for #13238. Instead of handling focus events in
the `TerminalInput::HandleKey` function and the need to filter them
out depending on where they came from, we simply don't call `HandleKey`
in the first place. This makes the somewhat unreliable `CameFromApi`
function unnecessary and the code a bit more robust.

This change is required because `CameFromApi` is not representable
in a `INPUT_RECORD` and I'm getting rid of `IInputEvent`.

## Validation Steps Performed
* No `[O` when exiting nvim 
* Mouse input in nvim works 
2023-06-27 17:50:51 +02:00
Leonard Hecker
a5960049bf Deduplicate INPUT_RECORD based ApiRoutines (#15605)
`(Peek|Read)ConsoleInput(A|W)Impl` make a distinction that doesn't make
a lot of sense in our code base: On the calling side (`ApiDispatchers`)
there's just one function calling all 4 (`ServerGetConsoleInput`) and
on the callee side they all 4 just call `_DoGetConsoleInput` anyways.

## Validation Steps Performed
* It compiles 
2023-06-27 15:33:57 +02:00
Leonard Hecker
f0291c6501 Remove boolean success return values from TextBuffer (#15566)
I've removed these because it made some of my new code pretty
convoluted for now good reason as most of these functions aren't
exception safe to begin with. Basically, their boolean status
is often just a pretense because they can crash or throw anyways.

Furthermore, `WriteCharsLegacy` failed to check the status code
returned by `AdjustCursorPosition` in some of its parts too.

In the future we should instead probably strive to continue
make our legacy code more exception safe.
2023-06-22 16:24:10 -07:00
Leonard Hecker
e594d97c90 Allow ROW::CopyRangeFrom to be vectorized (#15267)
By rewriting the first major copy loop in `CopyRangeFrom` to use
pointers/iterators instead of indices for iteration, the autovectorizer
kicks in end neatly rewrites it as an unrolled SIMD loop. This improves
performance during traditional window resizes by roughly 2x and will
be quite helpful in the future for our more complex reflow resize.

Unfortunately, MSVC unrolls the loop by 4x which is too much for our
purpose, but there's no option to change that. It's still better than
not having any vectorization however, since it kicks in at 32 columns.

It also renames the function to `CopyTextFrom` be more in line with
the others and to avoid confusion, because it doesn't copy attributes.

## Validation Steps Performed
* Traditional resizing works 
2023-06-22 17:17:46 -05:00
Dustin L. Howett
191eb00f43 Add the drop validator task, rework some build artifacts (#15568)
I originally intended to add the Drop Validator (which is a compliance
requirement) task to the build, but I quickly realized that we weren't
generating a complete SBOM manifest covering every artifact that we
produced.

We were generating the SBOM manifest, and then re-packing the Terminal
app which very likely invalidated all of the hashes and signatures in
the SBOM manifest!

We were also missing the unpackaged build.

I've removed the `appx-PLATFORM-CONFIG` and `unpackaged-PLAT-CONF`
artifacts and combined them into a single one, `terminal-PLAT-CONF`.
2023-06-21 16:01:45 -05:00
Dustin L. Howett
a46a2719b8 Stop committing the whole buffer when determining if it's empty (#15582)
As a shortcut, GetLastNonSpaceCharacter can start with the last
committed row. It's guaranteed that there isn't anything of worth below
that point, so why bother checking?

Without this, Terminal immediately commits the entire 9031-line buffer
on startup while trying to--get this!--clear the screen!

---------

Co-authored-by: Leonard Hecker <lhecker@microsoft.com>
2023-06-21 13:52:01 -07:00
MPela
40963c7b18 Add an action to search the web for selected text (#15539)
This PR adds a `searchWeb` command to search the selected text on the web.
Arguments:
- `queryUrl`: URL of the web page to launch (the selected text will be
inserted where the first `%s` is found in the query string)

To make the search text more "compact" and handle multi-line selections,
I'm concatenating the selected lines and replacing consecutive
whitespaces with a single space (we may change this with something more
clever in case).

## Validation Steps Performed
Manual testing with single, multi-line, block selections.

Closes #10175

---------

Co-authored-by: Marco Pelagatti <marco.pelagatti@iongroup.com>
Co-authored-by: Mike Griese <migrie@microsoft.com>
2023-06-21 12:24:45 -05:00
Tushar Singh
2386abb8df unhide nuget packages/ for VSCode (#15579)
Don't exclude nuget `packages/` in vscode. Excluding via `file.exclude`
also excludes them from c++ language extension's `includePath` and
generates missing include files and header errors.

We might still like to exclude them from full text search, so we do it
using `search.exclude`.

Closes #15578
2023-06-21 11:46:05 -05:00
Leonard Hecker
b8f402f64b Reduce cost of resetting row attributes (#15497)
Performance of printing enwik8.txt at the following block sizes:
4KiB (printf): 54MB/s -> 54MB/s
128KiB (cat): 101MB/s -> 104MB/s

## Validation Steps Performed
This change is easily verifiable via review.
2023-06-15 15:34:29 +00:00
Leonard Hecker
f3e2890084 Vectorize ROW initialization (#15501)
Performance of printing enwik8.txt at the following block sizes:
4KiB (printf): 51MB/s -> 54MB/s
128KiB (cat): 92MB/s -> 103MB/s

## Validation Steps Performed
* Rows are properly filled with whitespace at various
  window sizes as observed under a debugger 
2023-06-15 14:45:35 +00:00
Leonard Hecker
427b37c07d Fix a crash when duplicating tabs with elevate:true (#15548)
When `elevate` is set to `true`, `_maybeElevate` would try to
modify `newTerminalArgs` and crash, because during tab duplication
there aren't any `newTerminalArgs`. This issue may happen for instance
when receiving hand-off from a non-elevated client and then trying
to duplicate that tab.

Closes #15534

## Validation Steps Performed
* Launch with `"elevate": false`
* Set `"elevate": true`
* Duplicate a tab
* Doesn't crash 
2023-06-15 14:43:43 +00:00
Leonard Hecker
a38388615e Fix new AuditMode failures up to VS 17.7 Preview 2 (#15547)
* Fixes warnings related to missing `const` in 2 places, which seems
  to be something that's being detected more reliably by 17.6 now.
* Fixes `DxSoftFont` not initializing all members,
  which is also suddenly being detected by 17.6 now.
* Fixes 1 new VS 17.7 warning (C26435) by removing `virtual` from
  methods declared as `override` already.
* Disables 2 new VS 17.7 warnings that are part of C++ Core Guidelines
  c.128, because they don't really bring any benefit to this project.

As an additional bonus it disables a spellcheck warning that has been
going around ever since I put a Punycode URL in a comment.
2023-06-15 00:24:21 +02:00
Leonard Hecker
c183d12649 Move AdaptDispatch::_FillRect into TextBuffer (#15541)
This commit makes 2 changes:
* Expose dirty-range information from `ROW::CopyTextFrom`
  This will allow us to call `TriggerRedraw`, which is an aspect
  I haven't previously considered as something this API needs.
* Add a `FillRect` API to `TextBuffer` and refactor `AdeptDispatch`
  to use that API. Even if we determine that the new text APIs are
  unfit (for instance too difficult to use), this will make it simpler
  to write efficient implementations right inside `TextBuffer`.

Since the new `FillRect` API lacks bounds checks the way `WriteLine`
has them, it breaks `AdaptDispatch::_EraseAll` which failed to adjust
the bottom parameter after scrolling the contents. This would result
in more rows being erased than intended.

## Validation Steps Performed
* `chcp 65001`
* Launch `pwsh`
* ``"`e[29483`$x"`` fills the viewport with cats 
* `ResizeTraditional` still doesn't work any worse than it used to 
2023-06-14 14:34:42 -05:00
Leonard Hecker
8f8c79ff58 Various fixes and improvements for ConsoleTypes.natvis (#15543)
Fixes the broken types for `TextAttribute`, `til::size`, `til::point`
and `til::rect` and adds a new type for `TextBuffer` which without
this would now be much harder to inspect due to introduction of
the manual virtual memory management in 612b00c.
2023-06-13 15:12:10 -05:00
Leonard Hecker
612b00cd44 Initialize rows lazily (#15524)
For a 120x9001 terminal, a01500f reduced the private working set of
conhost by roughly 0.7MB, presumably due to tighter `ROW` packing, but
also increased it by 2.1MB due to the addition of the `_charOffsets`
array on each `ROW` instance. An option to fix this would be to only
allocate a `_charOffsets` if the first wide or complex Unicode glyph
is encountered. But on one hand this would be quite western-centric
and unfairly hurt most languages that exist and on another we can get
rid of the `_charOffsets` array entirely in the future by injecting
ZWNJs if a write begins with a combining glyph and just recount each
row from the start. That's still faster than fragmented memory.

This commit goes a different way and instead reduces the working
set of conhost after it launches from 7MB down to just 2MB,
by only committing ROWs when they're first used.

Finally, it adds a "scratchpad" row which can be used to build
more complex contents, for instance to horizontally scroll them.

## Validation Steps Performed
* Traditional resize
  * Horizontal shrinking works 
  * Vertical shrinking works  and cursor stays in the viewport 
* Reflow works 
* Filling the buffer with ASCII works  and no leaks 
* Filling the buffer with complex Unicode works  and no leaks 
* `^[[3J` erases scrollback 
* Test `ScrollRows` with a positive delta 
* I don't know how to test `Reset`.  Unit tests use it though
2023-06-10 13:17:18 +00:00
Jvr for school
17596d2623 Improve Run-Tests.ps1's maintainability and readability (#15407)
Improvements and explanations:
* Added proper indentation and spacing for better readability.
* Added comments to explain the purpose of different sections of the
  code.
* Utilized the $LASTEXITCODE variable instead of $lastexitcode to ensure
  consistency.
* Changed the variable name from $testdlls to $testDlls for better
  naming convention.
* Moved the Exit 0 statement to the end (outside the if condition).
* Since Exit statements terminate the script immediately, it's better to
  have them at the end of the script to ensure that all necessary
  cleanup or additional operations are performed before exiting.
* These improvements enhance the code's readability, maintainability,
  and adherence to best practices.
2023-06-09 23:06:29 +00:00
Dustin L. Howett
37e8aff967 Detect likely Powerline fonts, add a special powerline preview (#15365)
When we detect a font that has a glyph for `U+E0B6`, we will switch the
preview connection text to contain a special powerline prompt. This will
allow people to see how different settings might impact their real-world
environment.

When we _don't_ detect such support, we fall back to the CMD-style
`C:\>` prompt.

Pros:
- It's beautiful.

Cons:
- More code

Risks:
- `U+E0B6` is part of the private use area, and fonts that have symbols
there (such as Cirth as sub-allocated by the ConScript Unicode Registry)
will result in something unexpected.
- Actually, `E0B6` isn't part of base powerline... but I think this
specific set of characters looks too good to pass up.
2023-06-09 22:22:21 +00:00
Leonard Hecker
c16a74ba39 Fix small_vector issues when assigning it to itself (#15525)
This commit achieves fixes the issue as described in the title by
checking whether the `this` and `other` pointer are identical.
As an added bonus it makes the copy and move constructors slightly
cheaper, as they don't try to destruct existing data anymore,
which doesn't exist anyways.

## Validation Steps Performed
* It blends 
2023-06-09 18:18:34 +00:00
James Holderness
7a3bf7017c Add support for Erase Color Mode (DECECM) (#15469)
The _Erase Color Mode_ determines what attributes are written to the
buffer when erasing content, or when new content is scrolled onto the
screen. When the mode is reset (which is the default), we erase with the
active colors, but with rendition attributes cleared. When the mode is
set, we erase with the default attributes, i.e. with neither color nor
rendition attributes applied.

This could be used to address the problem described in issue #10556.

Most of the affected operations are handled within the `AdaptDispatch`
class, so I've simply updated them all to use a new helper method which
returns the appropriate erase attributes for the active mode.

However, there were a couple of operations that are handled elsewhere,
and which now require the erase attributes to be passed to them as a
parameter.

* The `TextBuffer::IncrementCircularBuffer` method, which is used to
recycle the topmost row when scrolling past the bottom of the buffer.

* The `TextBuffer::SetCurrentLineRendition` method, which has to clear
the second half of the line when switching to a double width rendition.

* The `ITerminalApi::UseAlternateScreenBuffer` method, which has to
clear the screen when switching to the alternate buffer.

Then there is also a Clear Buffer action in Windows Terminal, which is
ultimately handled by the `SCREEN_INFORMATION::ClearBuffer` method in
ConHost. That class has no access to the erase color mode, so has no way
of knowing which attributes to use. So I've now rewritten it to use the
`AdaptDispatch::EraseInDisplay` method to handle the erasing.

## Validation Steps Performed

I wrote a little test script that exercises the operations affected by
`DECECM`, which @al20878 kindly tested for us on a real DEC VT525, and
provided screenshots of the output. I've manually confirmed that our
implementation exactly matches those results.

I've also added a unit test that runs through the same set of operations
and verified that each of them is using the appropriate attributes when
`DECECM` is enabled and enabled.

Closes #14983
2023-06-09 00:02:49 +00:00
Leonard Hecker
f1aa6993f1 Display Unicode URIs side-by-side with their Punycode encoding (#15488)
06174a9 didn't properly fix the issue of us showing homoglyphs in our
URI tooltip. This commit introduces a different approach where we
display both, the Punycode and Unicode encoding, whenever we encounter
an IDN. This isn't perfect but simple to implement.

Closes #15432

## Validation Steps Performed
* `https://www.xn--fcbook-3nf5b.com/` (which contains confusing glyphs)
  is shown both in its Punycode and Unicode form simultaneously. 

---------

Co-authored-by: Carlos Zamora <carlos.zamora@microsoft.com>
2023-06-08 23:56:04 +00:00
Mike Griese
8f83322322 Add support for setting the window frame color (#15441)
Add support for `$theme.window.frame`, `.unfocusedFrame`, and `.rainbowFrame`. The first two accept a `ThemeColor` to set the window frame, using [`DwmSetWindowAttribute`](https://learn.microsoft.com/en-us/windows/win32/api/dwmapi/nf-dwmapi-dwmsetwindowattribute) with [`DWMWA_BORDER_COLOR`](https://learn.microsoft.com/en-us/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute). `rainbowFrame` accepts a `bool`. When enabled, it'll cycle the color of the frame through all the hues, ala [this gif](https://user-images.githubusercontent.com/18356694/164307822-e4267965-2ce0-4294-8499-59c3ba7edbae.gif) (but, constantly, instead of just when the window moves). 

This only works on Windows 11.

## Validation Steps Performed
* Works on Windows 11
* Doesn't explode on Windows 10

## PR Checklist
- [x] Closes #12950
- See also #3327
- [x] Schema updated (if necessary)


### other details

There's probably some impact to perf with `rainbowFrame`. It's one `DispatcherTimer` per window. That could probably be optimized somehow to like, one per process, but meh?
2023-06-06 16:17:03 -07:00
ebarnabas
c627991522 Project build with space in filepath fix (#15447)
## Summary of the Pull Request
Fixing a problem where the repo build failed when the project location
path contained space character.

## References and Relevant Issues
Closes #15370 

## Detailed Description of the Pull Request / Additional comments
Placing missing quote, amp and apos symbols when calling commands with
filepath parameters.

## Validation Steps Performed
Built locally.

## PR Checklist
- [x] Closes #xxx
- [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: #xxx
- [x] Schema updated (if necessary)
2023-06-06 23:15:37 +00:00
Leonard Hecker
f0705fb7f7 AtlasEngine: Fix some Windows 10 <14393 bugs (#15485)
This fixes a couple spots where I wasn't properly checking
for the existence of some optional D2D interfaces.

## Validation Steps Performed
I haven't tested this and don't intend to do it just yet.
Windows Terminal requires build 19041 at least anyways.
2023-06-05 16:36:09 -07:00
Carlos Zamora
0425ab0c1d Expose 'Default' tag to Screen Readers in Color Schemes page (#15486)
## Summary of the Pull Request
This removes the "default" text box from the UI Automation tree, thus
preventing screen readers from navigating to it. This was a confusing
scenario for users because the "default" tag was unclear if it was a
part of the previous or next color scheme (i.e. consider hearing
"Campbell, default, Campbell PowerShell"; it's unclear which one is
default).

This also appends the "default" string to the `ToString` function of the
color scheme view model. This makes it so that the combo box and list
view visually appear the same, but can be quick searched or read out by
the screen reader with the 'default' tag.

## Validation Steps Performed
- [x] Verified this works on Windows 11
- [x] Verified this works on Windows 10
- Scenarios tested:
   - [x] saving settings after changing the default scheme
   - [x] saving settings.json to force a refresh in SUI

Closes #14401
2023-06-05 19:50:23 +00:00
James Holderness
e9de646e54 Remove the telemetry for VT sequences (#15494)
This removes the telemetry tracking which counted how many times each VT
sequence was executed, and how many times there were "failures". This
information isn't needed any more, and we were reaching the limit of how
many sequences we could track anyway.

Essentially what's been removed is the `TermTelemetry` class, but we are
still tracking some statemachine telemetry in the `ParserTracing` class.
And since that used the same trace logging provider as `TermTelemetry`,
I've now moved that definition into the `tracing.cpp` file. 

The code still compiles and runs without exploding.

Closes #15482
2023-06-05 16:41:32 +00:00
James Holderness
8aefc7a697 Make sure RIS re-enables win32 input and focus events (#15476)
When an `RIS` (hard reset) sequence is executed, ConHost will pass that
through to the connected conpty terminal, which results in all modes
being reset to their initial state. To work best, though, conpty needs
to have the win32 input mode enabled, as well as the focus event mode.
This PR addresses that by explicitly requesting the required modes after
an `RIS` is passed through.

Originally these modes were only set if the `--win32input` option was
given, but there is really no need for that, since terminals that don't
support them should simply ignore the request. To avoid that additional
complication, I've now removed the option (i.e. ConHost will now always
attempt to set the modes it needs).

I've manually confirmed that keypresses are still passed through with
win32 input sequences after a hard reset, and that focus events are
still being generated. I've also updated the existing conpty round-trip
test for `RIS` to confirm that it's now also passing through the mode
requests that it needs.

Closes #15461
2023-06-02 13:41:49 -05:00
Leonard Hecker
1bec08ec0a Modernize til::static_map with C++20 (#15484)
I wanted to show `til::static_map` to someone and noticed it hasn't been
updated since we updated to C++20. We can now make use of `constexpr`
`std::sort` and `constinit` to skip the initialization of the maps in
`KeyChordSerialization.cpp`. Also, I removed the comparator argument
to make the map a little more compact.
2023-05-31 12:59:03 -05:00
Mike Griese
c9e993a38e Exit the process after commandline-only invocations (#15445)
Yep it's that dumb

Closes #15443
2023-05-26 19:59:38 +00:00
Leonard Hecker
cd6b0832e2 Hotfix block selection linebreaks in conhost (#15423)
This regressed in a1f42e8 which only made changes to Windows Terminal
but forgot to make equivalent ones in OpenConsole/conhost.
Without this fix, line breaks in block selections are missing if the
line doesn't force a wrap via an explicit newline.

Closes #15153

## Validation Steps Performed
* Run Far or print long lines of text
* Trigger block selection via Ctrl+M or Edit > Mark
* Clipboard contains N-1 newlines lines for N selected rows 
2023-05-26 14:32:15 -05:00
Mike Griese
8611d901b6 Theoretical fix for some crashes (#15457)
RE: 
* #15454
* MSFT:44725712 "WindowsTerminal.exe!NonClientIslandWindow::OnSize"
* MSFT:44754014 "NonClientIslandWindow::GetTotalNonClientExclusiveSize"

I think this should fix all of those, but I want to ship and verify
live, since I can't repro this locally.
2023-05-26 14:31:21 -05:00
Leonard Hecker
a19d30a25a AtlasEngine: Improve scroll and swap chain invalidation (#15425)
`_p.MarkAllAsDirty()` sets `_p.scrollOffset` to 0, so we need to use
that instead of `_api.scrollOffset` when getting the offset.
Additionally, the previous code failed to release the swap chain
when recreating the backend, which is technically not correct.
I'm not sure to what issues this might have led, as it didn't had any
negative effects on my PC, but it's definitely not according to spec.

## Validation Steps Performed
Difficult to test but it seems alright.
2023-05-26 14:30:57 -05:00
Steve Otteson
709189d471 env: always expand PATH vars (#15444)
Make sure we always expand path env vars, even if they're REG_SZ in the
registry.

## Detailed Description of the Pull Request / Additional comments
On some systems path vars are REG_SZ instead of REG_EXPAND_SZ. We need
to make sure we always expand them. We looked at the system code, and it
also makes to sure to always expand them.

## Validation Steps Performed
Built locally and made sure the problem went away. Also stepped through
in the debugger to make sure things were working correctly.

Closes #15442
2023-05-26 18:45:10 +00:00
Mike Griese
aa8ed8c2d4 AGAIN, intentionally leak our App, so that we DON'T crash on exit (#15451)
This is a resurrection of #5629. As it so happens, this crash-on-exit
was _not_ specific to my laptop. It's a bug in the XAML platform
somewhere, only on Windows 10.

In #14843, we moved this leak into `becomeMonarch`. Turns out, we don't
just need this leak for the monarch process, but for all of them.

It's not a real "leak", because ultimately, our `App` lives for the
entire lifetime of our process, and then gets cleaned up when we do. But
`dtor`ing the `App` - that's apparently a no-no.

Was originally in #15424, but I'm pulling it out for a super-hotfix
release.


Closes #15410

MSFT:35761869 looks like it was closed as no repro many moons ago. This
should close out our hits there (firmly **40% of the crashes we've
gotten on 1.18**)
2023-05-26 13:09:00 -05:00
James Holderness
3c3b1aac02 Add support for horizontal scrolling sequences (#15368)
This PR introduces four new escapes sequences: `DECIC` (Insert Column),
`DECDC` (Delete Column), `DECBI` (Back Index), and `DECFI` (Forward
Index), which allow for horizontal scrolling within a margin area.

## References and Relevant Issues

This follows on from the horizontal margins PR #15084 to complete the
requirements for the horizontal scrolling extension.

## Detailed Description of the Pull Request / Additional comments

The implementation is fairly straightforward, since they're all built on
top of the existing `_ScrollRectHorizontally` method.

## Validation Steps Performed

Thanks to @al20878, these operations have been extensively tested on a
number of DEC terminals and I've manually confirmed our implementation
matches their behavior.

I've also added a unit tests that covers the basic execution of each of
the operations.

Closes #15109
2023-05-25 20:36:56 +00:00
Mike Griese
6775300f42 Fix focusFollowMouse (#15420)
Because this looks like it's entirely broken in `main`, and possibly in
1.17(?)

We didn't take a strong ref to the coroutine parameter. As to be
expected, that explodes.

Closes #15412
2023-05-25 22:25:10 +02:00
Jaswir
f5a703c711 Add support for a "Move Tab to New Window" tab context menu item (#15376)
## Summary of the Pull Request
Add the "Move Tab to New Window" item to the context menu of the tabs 

## References and Relevant Issues
https://github.com/microsoft/terminal/issues/15127

## Detailed Description of the Pull Request / Additional comments
Add the "Move Tab to New Window" item to the context menu of the tabs. 

![Detailed_description_of_commit_PR1](https://github.com/microsoft/terminal/assets/15957528/915ac07b-1fdd-456b-b180-2645dbc29e48)

## Validation Steps Performed
Checked Code Style
https://github.com/microsoft/terminal/blob/main/doc/STYLE.md

## PR Checklist
- [ V] Closes #15127
-  [?] 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: #xxx
- [ V] Schema updated (if necessary)

---------

Co-authored-by: Mike Griese <migrie@microsoft.com>
2023-05-25 18:22:58 +00:00
Leonard Hecker
7650ecf658 AtlasEngine: Fix cursor invalidation for BackendD2D (#15427)
TIL: `CreateCompatibleRenderTarget` does not initialize the bitmap
it returns. You got to do that yourself just like in D3D.

## Validation Steps Performed
* Set `ATLAS_DEBUG_FORCE_D2D_MODE` to 1
* Changing the cursor in the settings immediately updates it 
2023-05-25 18:22:07 +00:00
Leonard Hecker
0073e36d81 Fix VS profile command generation (#15439)
This regressed in f06cd17. It seems like the change went untested,
because it appends an extra " after -startdir=none.
This changeset also avoids calling `append()` twice.

Closes #15436

## Validation Steps Performed
* VS Developer Command Prompt works 
2023-05-25 18:21:57 +00:00
Leonard Hecker
245b13b94e AtlasEngine: Fix nullptr crash when using soft fonts (#15419)
Woops. Regressed in #15343. Fixes #15409.

## Validation Steps Performed
* Run `RenderingTests.exe`
* Soft fonts work 
2023-05-25 18:21:55 +00:00
Leonard Hecker
a9f34e3095 AtlasEngine: Fix Present() of out of bounds glyphs (#15403)
`til::rect`'s truthiness check (= rect is valid) returns `false` for
any rects that have negative coordinates. This makes sense for buffer
handling, but breaks AtlasEngine, where glyph coordinates can go out
of bounds and it's entirely valid for that to happen.

Closes #15416

## Validation Steps Performed
* Use MesloLGM NF and print NF glyphs in the first row
* Text rendering, selection, etc., still works 

---------

Co-authored-by: Dustin L. Howett <duhowett@microsoft.com>
2023-05-25 17:39:44 +00:00
Mike Griese
c589784b54 Leak the window when it closes on Windows 10 (#15397)
Re: #15384

Basically, when we close a `DesktopWindowXamlSource`, it calls to `Windows_UI_Xaml!DirectUI::MetadataAPI::Reset`, which resets the XAML metadata provider _for the process_. So, closing one DWXS on one thread will force an A/V next time another thread tries to do something like... display a tooltip. Not immediately, but surely soon enough.

This was fixed in Windows 11 by os.2020!5837001. That wasn't backported to Windows 10.

This will cause a ~15MB memory leak PER WINDOW. OBVIOUSLY, this is bad, but it's less bad than crashing. 

We're gonna keep using #15384 for other ideas here too.
2023-05-22 11:00:44 -05:00
Mike Griese
910c61b7e1 Manually close the ContentDialog in teardown (#15387)
As discussed. Closes #15364.

Prevents one crash on Windows 10. Opens the door to may more horrors.

Co-authored-by: James Holderness <j4_james@hotmail.com>
2023-05-22 06:07:59 -05:00
Dustin L. Howett
0ee2c74cd4 Switch the Preview text emoji to one that exists on Win10 (#15381) 2023-05-18 16:27:33 +00:00
Dustin L. Howett
125026dbb6 Remove the pending update version from the About dialog (#15378)
It turns out that the store API *doesn't* tell us what the new version
is. We were loading up our own package and checking its version instead.

The best we can do is tell users that an update--any update--is
available.
2023-05-18 10:22:29 -05:00
Dustin L. Howett
ce60bf290a Make the preview text 100% more accurate (#15366) 2023-05-16 17:59:36 -05:00
Dustin L. Howett
e269945a74 Reword the AdjustIndistinguishableColors subhead and perf. note (#15361)
I've changed the wording so that it flows better.
2023-05-16 15:01:31 -05:00
Dustin L. Howett
fbe45fafb5 Add a fun new preview text in the SUI, enable the cursor (#15363)
Our existing preview text was not very helpful in learning how different
settings impacted the display of text in Terminal.

This new preview text contains:
* Bold text, which is controlled by intenseTextStyle
* Colors
* Emoji
* A cursor, which overlaps a single character to show inversion behavior
2023-05-16 14:59:49 -05:00
Dustin L. Howett
62766db94d Reword or remove a bunch of subheadings in the SUI (#15362)
Some of these were reundant, and some didn't feel right when I read
them.

Oh, and I got rid of all of these particularly unhelpful or non-additive
resources:

```
Color Scheme        [                     v ]
Is a color scheme
```
2023-05-16 14:59:28 -05:00
James Holderness
b00b77a7ac Add support for horizontal margin sequences (#15084)
This PR introduces two new escapes sequences: `DECLRMM` (Left Right
Margin Mode), which enables the horizontal margin support, and `DECSLRM`
(Set Left and Right Margins), which does exactly what the name suggests.

A whole lot of existing operations have then been updated to take those
horizontal margins into account.

## Detailed Description of the Pull Request / Additional comments

The main complication was in figuring out in what way each operation is
affected, since there's a fair amount of variation.

* When writing text to the buffer, we need to wrap within the horizontal
margins, but only when the cursor is also within the vertical margins,
otherwise we just wrap within the boundaries of the screen.

* Not all cursor movement operations are constrained by the margins, but
for those that are, we clamp within both the vertical and horizontal
margins. But if the cursor is already outside the margins, it is just
clamped at the edges of the screen.

* The `ICH` and `DCH` operations are constrained by the horizontal
margins, but only when inside the vertical margins. And if the cursor is
outside the horizontal margins, these operations have no effect at all.

* The rectangular area operations are clamped within the horizontal
margins when in the origin mode, the same way they're clamped within the
vertical margins.

* The scrolling operations only scroll the area inside both horizontal
and vertical margins. This includes the `IL` and `DL` operations, but
they also won't have any effect at all unless the cursor is already
inside the margin area.

* `CR` returns to the left margin rather than the start of the line,
unless the cursor is already left of that margin, or outside the
vertical margins.

* `LF`, `VT`, `FF`, and `IND` only trigger a scroll at the bottom margin
if the cursor is already inside both vertical and horizontal margins.
The same rules apply to `RI` when triggering a scroll at the top margin.

Another thing worth noting is the change to the `ANSISYSSC` operation.
Since that shares the same escape sequence as `DECSLRM`, they can't both
be active at the same time. However, the latter is only meant to be
active when `DECLRMM` is set, so by default `ANSISYSC` will still work,
but it'll no longer apply once the `DECLRMM` mode is enabled.

## Validation Steps Performed

Thanks to @al20878, these operations have been extensively tested on a
number of DEC terminals and I've manually confirmed our implementation
matches their behavior.

I've also extended some of our existing unit tests to cover at least the
basic margin handling, although not all of the edge cases.

Closes #14876
2023-05-15 22:32:30 +00:00
Leonard Hecker
4628ceb295 AtlasEngine: Clip box glyphs to their cells (#15343)
Overhangs for box glyphs can produce unsightly effects, where the
antialiased edges of horizontal and vertical lines overlap between
neighboring glyphs and produce "boldened" intersections.
This avoids the issue in most cases by simply clipping the glyph to the
size of a single cell. The downside is that it fails to work well for
custom line heights, etc.

## Validation Steps Performed

* With Cascadia Code, printing ``"`u{2593}`n`u{2593}"`` in pwsh
  doesn't produce a brightened overlap anymore 
* ``"`e#3`u{2502}`n`e#4`u{2502}"`` produces a fat vertical line 
2023-05-16 00:05:16 +02:00
Mike Griese
9a4f4abaf2 Manually pre-evaluate the starting directory when calling elevate-shim (#15286)
_targets #15280_

When ctrl+clicking on a profile, pre-evaluate the starting directory of
that profile, and stash that in the commandline we pass to elevate shim.

So in the case of something like "use parent process directory", we'll
run `elevate-shim new-tab -p {guid} -d "C:\\the path\\of\\terminal\\."`


Closes #15173

---------

Co-authored-by: Leonard Hecker <lhecker@microsoft.com>
2023-05-15 20:10:43 +00:00
Leonard Hecker
f6e9f91504 Fix AtlasEngine not being used in the appearance settings (#15355)
`TermControl` cannot change the text rendering engine after its
construction. Fix the issue by deferring the construction until
after we got the initial profile settings.

## Validation Steps Performed
* A line height of 0.5 shows up with overlapping rows 
2023-05-15 21:14:21 +02:00
Leonard Hecker
457bc65d7e AtlasEngine: Fix animated shaders (#15353)
We need to avoid calling `Present1()` with an empty dirty rect, but the
backends are what determines the resulting dirty rect, so we need to
first run the backend code and then decide if we `Present1()` or not.

## Validation Steps Performed
* `Animate_scan.hlsl` shows a smoothly animated line 
2023-05-15 13:46:39 -05:00
Leonard Hecker
4c3d3d83a5 AtlasEngine: Fix han unification issues (#15358)
This commit ensures that we pass the user's locale to `MapCharacters`.

## Validation Steps Performed
See: https://heistak.github.io/your-code-displays-japanese-wrong/
After modifying the `userLocaleName` to contain `ja-JP`, `zh-CN` and
`zh-TW`, printing "刃直海角骨入" produces the expected, localized result.
2023-05-15 20:40:41 +02:00
Leonard Hecker
af5a6ea640 AtlasEngine: Fix multiple minor issues (#15357)
This commit fixes 3 bugs that I found while working on another feature:
* `GetGlyphIndices` doesn't return an error when the codepoint couldn't
  be found, it simply returns a glyph index of 0.
* `_resetGlyphAtlas` failed to reset the `linear_flat_set` "load" to 0
  which would result in an unbounded memory growth over time.
* `linear_flat_set` was missing move constructors/operators, which
  would've led to crashes, etc., but thankfully we haven't made use
  of these operators yet. But better fix it now than never.
2023-05-15 20:40:13 +02:00
Leonard Hecker
ba39db52d7 Fix DesktopWindowXamlSource related crashes when closing a window (#15338)
XAML/WinUI may pump the event loop internally. One of the functions
that does this right now is `DesktopWindowXamlSource::Close()`.

This is problematic in the previous code, because we'd set `_window`
to `nullptr` before calling `Close()` and so any of the `IslandWindow`
callbacks may be invoked during shutdown, which then try to potentially
access `_window` and end up crashing. This commit fixes the issue by
simply not nulling out the `_window` and calling `Close()` directly.

Furthermore, `NonClientIslandWindow` may directly access WinUI
objects in its message handlers which also crashes.

I've had this happen roughly ~1% of my test exits in a debug build
and every single time on a (artificial) very slow CPU.

## Validation Steps Performed
* Closing a window destroys the rendering instance 
2023-05-15 14:11:22 +00:00
James Holderness
3d737214a4 Add support for LNM (Line Feed/New Line Mode) (#15261)
This PR adds support for the ANSI Line Feed/New Line mode (`LNM`), which
determines whether outputting a linefeed control should also trigger a
carriage return, and whether the `Return` key should generate an `LF` in
addition to `CR`.

## Detailed Description of the Pull Request / Additional comments

In ConHost, there was already a console mode which handled the output
side of things, but I've now also added a `TerminalInput` mode that
controls the behavior of the `Return` key. When `LNM` is set, both the
output and input modes are enabled, and when reset, they're disabled.

If they're not already matching, then `LNM` has no effect, and will be
reported as unknown when queried. This is the typical state for legacy
console applications, which expect a linefeed to trigger a carriage
return, but wouldn't want the `Return` key generating both `CR`+`LF`.

As part of this PR, I've also refactored the `ITerminalApi` interface to
consolidate what I'm now calling the "system" modes: bracketed paste,
auto wrap, and the new line feed mode. This closes another gap between
Terminal and ConHost, so both auto wrap, and line feed mode will now be
supported for conpty pass through.

## Validation Steps Performed

I've added an `LNM` test that checks the escape sequence is triggering
both of the expected mode changes, and added an additional `DECRQM` test
covering the currently implemented standard modes: the new `LNM`, and
the existing `IRM` (which wasn't previously tested). I've also extended
the `DECRQM` private mode test to cover `DECAWM` and Bracketed Paste
(which we also weren't previously testing).

I've manually tested `LNM` in Vttest to confirm the keyboard is working
as expected.

Closes #15167
2023-05-12 18:16:48 -05:00
Mike Griese
1324a0148a Don't even try to MoveContent to the same window you started in (#15325)
Don't go.
Tracked in #14957
2023-05-12 17:24:31 -05:00
Mike Griese
1bf2fcb6e0 Don't dismiss the command palette when the new tab menu closes (#15340)
Transient UIs are hard.

Regressed in #15077.

Closes #15305
2023-05-12 17:22:21 -05:00
Leonard Hecker
95944e5939 Make path-string conversions cheaper (#15332)
`native()` returns a `const std::wstring&`, whereas `wstring()`
returns a copy. Use the former to make path conversions cheaper.
2023-05-12 20:51:00 +00:00
Leonard Hecker
488de2d42c Fix WindowEmperor exiting too early (#15337)
`WindowEmperor` would exit as soon as the last window would enter
`RundownForExit()`, which is too early and triggers leak checks.
This commit splits up the shutdown up into deregistering the window from
the list of windows and into actually decrementing the window count.

Closes #15306

## Validation Steps Performed
* D2D leak warnings seem to disappear 
2023-05-12 20:15:50 +00:00
Leonard Hecker
bf8ef638b7 Avoid recreating the bell MediaPlayer every time (#15333)
We don't need to recreate the `MediaPlayer` to avoid the influence of
media keys if we simply opt out of media key controls.

## Validation Steps Performed
* Set a random .wav as the bell sound
* Bell is audible 
* Media keys have no effect while the sound plays 
2023-05-12 20:15:36 +00:00
Leonard Hecker
6a26fd68c4 Fix race conditions in ControlCore (#15334)
`ControlCore` contained two bugs:
* Race condition on access of the 3 throttled funcs which may now
  be `reset()` during tear out
* The `ScrollPositionChanged` event emitter was written incorrectly
  and would emit the event from the background thread without
  throttling during tear out
2023-05-12 20:11:22 +00:00
Dustin L. Howett
d6eb022975 Stage the fonts with the Helix payload (#15317)
I found that in all our Helix runs, we had a pesky dialog sitting on top
of the Terminal. Probably the entire time.

This will, as a side effect, PGO the nearby font loader.
2023-05-12 14:26:47 -05:00
Mike Griese
d0f66b9668 Restore the tab padding (#15339)
Honestly, I don't really know where it regressed. There isn't time for
me to go digging.

See also
* #15313
* #15164

Closes #15326
2023-05-12 13:26:05 -05:00
Mike Griese
5c08a86c49 Use a "virtual CWD" for each terminal window (#15280)
Before process model v3, each Terminal window was running in its own process, each with its own CWD. This allowed `startingDirectory: .` to work relative to the terminal's own CWD. However, now all windows share the same process, so there can only be one CWD. That's not great - folks who right-click "open in terminal", then "Use parent process directory" are only ever going to be able to use the CWD of the _first_ terminal opened. 

This PR remedies this issue, with a theory we had for another issue. Essentially, we'll give each Terminal window a "virtual" CWD. The Terminal isn't actually in that CWD, the terminal is in `system32`. This also will prevent the Terminal from locking the directory it was originally opened in. 

* Closes #5506
* There wasn't a 1.18 issue for "Use parent process directory is broken" yet, presumably selfhosters aren't using that feature
* Related to #14957

Many more notes on this topic in https://github.com/microsoft/terminal/issues/4637#issuecomment-1531979200


> **Warning** 
> ## Breaking change‼️

This will break a profile like 

```json
{
    "commandline": "media-test.exe",
    "name": "Use CWD for media-test",
    "startingDirectory": "."
},
```

if the user right-clicks "open in terminal", then attempts to open that profile. There's some theoretical work we could do in a follow up to fix this, but I'm inclined to say that relative paths for `commandline`s were already dangerous and should have been avoided.
2023-05-12 18:20:27 +00:00
Leonard Hecker
99abb2a6b5 Fix theoretical new-tab file drop crash (#15336)
After retrieving the items via `GetStorageItemsAsync()` inside a try
clause it fails to check if the pointer is actually non-null.
Apart from this this commit fixes the unsafe use of `this` by properly
using `get_weak()`. Finally it allows >1 paths to be dropped.

## Validation Steps Performed
* Dropping >1 file works 
* Dropping >1 directory works 
2023-05-12 13:14:07 -05:00
Dustin Howett
c6215c8b51 version: bump to 1.19 on main
Signed-off-by: Dustin Howett <duhowett@microsoft.com>
2023-05-11 16:33:49 -05:00
Mike Griese
63644507da Prevent flickering in nushell due to FTCS marks (#14677)
Tl;dr: Conpty would flush a frame whenever it encountered a FTCS mark.
Combine that with the whole-line redrawing that nushell does, and the
Terminal would get the prompt in two frames instead of one, causing a
slight flickering. This fixes that by rendering the frame, but not
flushing to the pipe when we encounter one of these sequences.

Closes #13710 

A complication here: there are some sequences that we passthrough
_immediately_ when we encounter them. For example, `\x1b[ 2q`. we need
to also not flush when we encounter one of these sequences. nushell
emits one of these as a part of the prompt, and that would force the
buffered frame to get written _anyways_, before writing that to the
pipe.
2023-05-11 16:11:30 -05:00
michalnpl
b2dd7fa600 Add support for CSI 18t (#15295)
Adds support for CSI 18t to report the buffer screen size in characters.

This pull request adds support for **CSI 18t**. When submitted to the
terminal, it will respond with **"\033[8;{A};{B}t"** where **A** is
equal to the **height** and **B** is equal to the **width** of the
screen buffer in the number of characters (not pixels).

## Validation Steps Performed
Manual tests against PowerShell 7 and ConHost.
Added adapterTest

Closes #13944
2023-05-11 12:06:39 -05:00
Mike Griese
c553b2123d Don't let a window be created with the literal name "new" (#15323)
As on the tin.

Blocking for 1.18.

Tracked in #14957
2023-05-11 12:03:47 +00:00
Mike Griese
076c36c6cb Add an action for manually invoking the control context menu (#15254)
Adds 

```
        { "command": "showContextMenu", "keys": "menu" },
```

as a default action. This will manually invoke the control context menu
(from #14775), even with the setting disabled.

As discussed with Dustin.
2023-05-10 22:32:27 -05:00
Mike Griese
0553f3ebf1 Fix an infinite loop when pressing alt (#15253)
As discussed in
https://github.com/microsoft/terminal/issues/14051#issuecomment-1517973776

regressed in #15189
2023-05-10 22:20:24 -05:00
Mike Griese
48eee4d75a Update MUX to 2.8.4 (#15313)
Reverts #15164, because that's fixed upstream now.

Closes #15139. 

Reverts #15178, but also closes #15121, because that's fixed upstream.

see also:
* https://github.com/microsoft/microsoft-ui-xaml/pull/8430
* https://github.com/microsoft/microsoft-ui-xaml/pull/8420
2023-05-10 13:04:41 -05:00
Mike Griese
6ad8cd0a63 Make conhost act in VtIo mode earlier in startup (#15298)
We need to act like a ConPTY just a little earlier in startup. My relevant notes start here: https://github.com/microsoft/terminal/issues/15245#issuecomment-1536150388. 

Basically, we'd create the first screen buffer with 9001 rows, because it would be created _before_ VtIo would be in a state to say "yes, we're a conpty". Then, if a CLI app emits an entire screenful of text _before_ the terminal has a chance to resize the conpty, then the conpty will explode during `_DoLineFeed`. That method is absolutely not expecting the buffer to get resized (and the old text buffer deallocated). 

Instead, this will treat the console as in ConPty mode as soon as `VtIo::Initialize` is called (this is during `ConsoleCreateIoThread`, which is right at the end of `ConsoleEstablishHandoff`, which is before the API server starts to process the client connect message).  THEORETICALLY, `VtIo` could `Initialize` then fail to create objects in `CreateIoHandlers` (which is what we used to treat as the moment that we were in conpty mode). However, if we do fail out of `CreateIoHandlers`, then the console itself will fail to start up, and just die. So I don't think that's needed.

This fixes #15245. I think this is PROBABLY also the solution to #14512, but I'm not gonna explicitly mark closed. We'll loop back on it.
2023-05-10 07:16:44 -05:00
Leonard Hecker
4dd9493135 Use Oklab for text and cursor contrast adjustments (#15283)
Oklab by Björn Ottosson is a color space that has less irregularities
than the CIELAB color space used for ΔE2000. The distance metric for
Oklab (ΔEOK) is defined by CSS4 as the simple euclidian distance.
This allows us to drastically simplify the code needed to determine
a color that has enough contrast. The new implementation still lacks
proper gamut mapping, but that's another and less important issue.
I also made it so that text with the dim attribute gets adjusted just
like regular text, since this is an accessibility feature after all.

The new code is so much faster than the old code (12-125x) that I
dropped any caching code we had. While this increases the CPU overhead
when printing lots of indexed colors, the code is way less complex now.
"Increases" in this case however means something in the order of 15-60ns
per color change (as measured on my CPU). It's possible to further
improve the performance using explicit SIMD instructions, but I've
left that as a future improvement, since that will make the code quite
a bit more verbose and I didn't want to hinder the initial review.

Finally, these new routines are also used for ensuring that the
AtlasEngine cursors remains visible at all times.

Closes #9610

## Validation Steps Performed
* When `adjustIndistinguishableColors` is enabled
  colors are distinguishable 
* An inverted cursor on top of a `#7f7f7f` foreground & background
  is still visible 
* A colored cursor on top of a background with identical color
  is still visible 
* Cursors on a transparent background are visible 
2023-05-08 19:16:26 +00:00
Leonard Hecker
cc89787c34 Fix Present1 params when scrolling the entire viewport (#15262)
This commit makes a few changes to avoid bugs, but they basically boil
down to: When we scroll by an entire viewport worth of content, we must
ensure that the scroll offset is 0, because otherwise the scroll rect
(that's basically the viewport, but excluding the scroll offset) will
end up being empty, which the `Present1` API chokes on. This commit
avoids this situation by shuffling around some code to first calculate
the dirty rows, _then_ check if it affects all of them and in that case
sets the scroll offset to 0, and only then finally actually does any
scrolling if there's still something to scroll.

## Validation Steps Performed
* Start pwsh
* Zoom in twice with Ctrl+Scrollwheel
* Print a few viewports worth of text
* Press Ctrl+L
* No errors 
2023-05-08 21:02:02 +02:00
Mike Griese
c18a4febe7 Remove the IsolatedMonarchMode velocity flag (#15300)
This was removed in #14843, but the velocity flag wasn't.

Related to #14957
2023-05-08 12:50:34 -05:00
Leonard Hecker
10c6206bfe AtlasEngine: Add support for locl variants (#15278)
Get the locale from `GetUserDefaultLocaleName` and pass it to
DirectWrite's `GetGlyphs` / `GetGlyphPlacements`.

This change is very important for some fonts, which heavily depend on
the locl table, like Source Han Sans for instance.

Closes #13685

## Validation Steps Performed
* Set font to Cascadia Code
* Set locale to "pl-PL"
* Type "Ć"
* The acute is less angled and almost vertical 
2023-05-04 19:08:09 +00:00
Mike Griese
ae7595b8e1 Add til::property and other winrt helpers (#15029)
## Summary of the Pull Request

This was a fever dream I had last July. What if, instead of `WINRT_PROPERTY` magic macros everywhere, we had actual templated versions you could debug into. 

So instead of 

```c++
WINRT_PROPERTY(bool, Deleted, false);
WINRT_PROPERTY(OriginTag, Origin, OriginTag::None);
WINRT_PROPERTY(guid, Updates);
```

you'd do 

```c++
til::property<bool> Deleted{ false };
til::property<OriginTag> Origin{ OriginTag::None };
til::property<guid> Updates;
```

.... and then I just kinda kept doing that. So I did that for `til::event`.

**AND THEN LAST WEEK**

Raymond Chen was like: ["this is a good idea"](https://devblogs.microsoft.com/oldnewthing/20230317-00/?p=107946)

So here it is. 

## Validation Steps Performed
Added some simple tests.

Co-authored-by: Leonard Hecker <lhecker@microsoft.com>
2023-05-03 12:41:36 -05:00
Leonard Hecker
23d45a7e3a Avoid loading nearby fonts unless necessary (#15239)
`IDWriteFontSetBuilder` is super expensive (~40ms of CPU for building a
single font set on a high-end CPU from ~2021). Let's avoid the cost,
by only constructing it if Cascadia Code is actually missing.
To not overcomplicate the code and to support any additional fonts we
might ship in the future, I'm not checking for the font name, and
instead I just construct the font set whenever any font is missing.

Part of #5907

## Validation Steps Performed
* Breakpoints in FontCache aren't hit 
* App doesn't crash 
2023-05-03 11:30:54 +00:00
kovdu
18d4f1ace8 Add support to show close button for active tab only. (#15237)
This MR introduces `activeOnly ` for the `showCloseButton` theme option
causing the close button only to appear on the active tab.

This is more or less following the approach explained here
https://github.com/orgs/microsoft/projects/686/views/2?pane=issue&itemId=19775774
which indeed just works 😄 .

You notice when switching theme the close buttons is back on all tabs
again as well.

Closes #13672

I didn't check specific unit tests for this. I hope by making this MR
the pipeline will show if I broke something. Or just let me know if you
want me to add something specific for this.
2023-05-03 11:21:46 +00:00
Mike Griese
4feeef2155 Don't auto-dismiss the warning dialog on launch (#15273)
Apparently, `ShowWindow` also sends a `WM_MOVE`, which we then turn
around and use to dismiss open dialogs.

Closes #15170

Regressed in #13811
2023-05-02 20:22:12 +02:00
Mike Griese
e88e0be190 Move session restore into a helper in AppHost (#15263)
Just move session restoration into a helper function, as suggested by
Leonard.
2023-05-02 17:35:43 +00:00
Ben Constable
6abd72177b Make reset button accessible (#15257)
Make the reset button accessible by adding description in reset.

Closes #12044

---------

Co-authored-by: Dustin L. Howett <dustin@howett.net>
2023-05-02 17:33:50 +00:00
James Holderness
8c28e132b5 Preserve active attributes during VT resize operations (#15269)
## Summary of the Pull Request

When the screen is resized in ConHost via a VT escape sequence, the
active text attributes could end up being corrupted if they were set to
something that the legacy console APIs didn't support (e.g. RGB colors).
This PR fixes that issue.

## Detailed Description of the Pull Request / Additional comments

The way a resize is implemented is by retrieving the buffer information
with `GetConsoleScreenBufferInfoEx`, updating the size fields, and then
writing the data back out again with `SetConsoleScreenBufferInfoEx`.
However, this also results in the active attributes being updated via
the `wAttributes` field, and that's only capable of representing legacy
console attributes.

We address this by saving the full `TextAttribute` value before it gets
corrupted in the `SetConsoleScreenBufferInfoEx` call, and then restore
it again afterwards.

## Validation Steps Performed

I've added a unit test to verify the attributes are correctly preserved
for all VT resize operations, and I've also manually confirmed the test
case in #2540 is now working as expected.

## PR Checklist
- [x] Closes #2540
- [x] Tests added/passed
- [ ] Documentation updated
- [ ] Schema updated (if necessary)
2023-05-02 15:04:01 +02:00
Mike Griese
1da6131cb2 Add default bindings for "move tab/pane to a new window" (#15258)
This was in pursuit of #15156. I need an ack from OP to make sure this
is good enough.

Related to #14957
2023-05-01 15:20:23 +00:00
Mike Griese
20eabb35ba Another theoretical fix for another race condition (#15251)
Basically, just make sure that we register our `SettingsChanged` handler
in `TerminalWindow` _after_ `TerminalWindow` is actually ready to handle
it. _duh_.

Closes #15209
2023-05-01 14:43:38 +00:00
Mike Griese
97a617a909 Don't explode when we tear out the last tab of the window (#15259)
If you were really fast, and closed one window, and then tried to drag
the only tab out of the last remaining window, the Terminal could
explode. It'd attempt to restore the previous window state, and explode.

Easy way to stop this (also, be more robust): just don't attempt to
restore windows during tear-out. That's obvious.

This is a part of #14957
2023-04-28 18:10:19 -05:00
Mike Griese
c4944c3a23 Move the Close... actions to a nested menu on the tab (#15250)
A resurrection of the original nested "Close" menu from #7728. We
discovered that nested flyouts crash in #8238. Those are fixed now
though! So we can bring this back.

This also includes the "Close Pane" item from #15198.
2023-04-28 18:05:28 -05:00
Mike Griese
70e44c7915 Add an action for immediately restarting a connection (#15241)
Adds an action for immediately restarting the connection. I suspect
most folks that wanted #3726 will be happy just with the
<kbd>enter</kbd> solution from #14060, but this will work without having
to `exit` the client. Just, relaunch whatever the commandline is. Easy
peasy.

Closes #3726.

Obsoletes #14549
2023-04-28 22:50:12 +00:00
Mike Griese
0d6642ac6d (A better) Refactoring of how connection restarting is handled (#15240)
A different take on #14548.

> We didn't love that a connection could transition back in the state
diagram, from Closed -> Start. That felt wrong. To remedy this, we're
going to allow the ControlCore to...

ASK the app to restart its connection. This is a much more sensible
approach, than leaving the ConnectionInfo in the core and having the
core do the restart itself. That's mental.

Cleanup from #14060

Closes #14327

Obsoletes #14548
2023-04-28 20:01:12 +00:00
Mike Griese
bfcdc64ab1 Make the rclick menu pre-populate "Find" with the selected text (#15252)
As it says on the tin
2023-04-28 19:25:04 +00:00
Mike Griese
fc90045cc3 Don't just die if the user doesn't have the dx debugging tools (#15249)
This PR gives the atlas engine an attempt to retry a couple operations
where it asks for debug flags when we're in debug mode. If you don't
have the Graphics debugger and GPU profiler for DirectX installed, then
these calls will fail, and we end up blowing up the renderer. Instead,
just try again.

Originally, I actually thought I had hit #14082, but after sorting this
out, it was just #14316.

closes #14316
2023-04-27 12:08:31 -05:00
James Pack
4d5962e7b5 Add jump list support for indirect icon references (#15221)
Adds support to jump list generation for icon paths that include an
indirect reference e.g. `c:\windows\system32\shell32.dll,214`

If given a path that has an indirect icon reference parse the path into
component parts `filePath` and `iconIndex` and use
`IShellLinkW::SetIconLocation` to set the Icon for the entry. Otherwise
do what we always do.

This PR also introduces `til::to_int`, which is based on `til::to_ulong`
and supports signed integers.

## Validation Steps Performed
Icons were visible in the jump list and in terminal next to the
profiles.

Closes #15205
2023-04-26 22:34:15 +00:00
joadoumie
ca5834e922 Added Close Pane to Context Menu (#15198)
## Summary of the Pull Request
Adding a 'Close Pane' menu item in the context menu.

## References and Relevant Issues
#13580 

## Detailed Description of the Pull Request / Additional comments
If a user decides to split a tab to create multiple panes through the
context menu, they should be able to then close the pane via the context
menu too. This PR introduces a new context menu item, 'Close Pane', that
only appears when a user has 2 or more panes in a tab. When a user
clicks close pane, the _active_pane will be closed.

## Validation Steps Performed

![close_pane_terminal](https://user-images.githubusercontent.com/98557455/232649000-8b521070-4f1b-4da9-8092-6ff802e91e2c.gif)

As it's my first PR, I still need to understand how to go through the
testing suite.

## PR Checklist
- [x] Closes #13580 
- [ ] 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 (if necessary)

---------

Co-authored-by: Carlos Zamora <carlos.zamora@microsoft.com>
2023-04-26 17:37:08 +00:00
James Holderness
a49b5a6045 Provide a more detailed Device Attributes report (#14906)
This is an update of our Primary Device Attributes report, which better
indicates the feature extensions that we now support.

## Detailed Description of the Pull Request / Additional comments

This first parameter of the response is 61, representing a conformance
level of 1. The subsequent parameters identify the supported feature
extensions.

1 = 132 column mode
6 = Selective erase
7 = Soft fonts
22 = Color text
23 = Greek character sets
24 = Turkish character sets
28 = Rectangular area operations
32 = Text macros
42 = ISO Latin-2 character set

Most of these features are handled entirely within `AdaptDispatch`, so
they apply to all clients. However, 132 column mode is only supported by
ConHost, so we don't report that for conpty clients.

And note that soft fonts won't necessarily work in all conpty clients,
but we don't have an easy way of determining that, so we just report
soft font support for everyone.

## Validation Steps Performed

I've manually verified that the `DA1` report is returning the expected
response in Vttest, both from ConHost and Windows Terminal.

I've also updated the `DeviceAttributesTests` in the adapter tests to
account for the new expected response.

Closes #14491
2023-04-26 11:56:22 -05:00
James Holderness
6030616d27 Add support for bracketed paste mode in ConHost (#15155)
This adds support for XTerm's "bracketed paste" mode in ConHost. When
enabled, any pasted text is bracketed with a pair of escape sequences,
which lets the receiving application know that the content was pasted
rather than typed.

## References and Relevant Issues

Bracketed paste mode was added to Windows Terminal in PR #9034.
Adding it to ConHost ticks one more item off the list in #13408. 

## Detailed Description of the Pull Request / Additional comments

This only applies when VT input mode is enabled, since that is the way
Windows Terminal currently works.

When it comes to filtering, though, the only change I've made is to
filter out the escape character, and only when bracketed mode is
enabled. That's necessary to prevent any attempts to bypass the
bracketing, but I didn't want to mess with the expected behavior for
legacy apps if bracketed mode is disabled.

## Validation Steps Performed

Manually tested in bash with `bind 'set enable-bracketed-paste on'` and
confirmed that pasted content is now buffered, instead of being executed
immediately.

Also tested in VIM, and confirmed that you can now paste preformatted
code without the autoindent breaking the formatting.

Closes #395
2023-04-26 11:37:21 -05:00
Leonard Hecker
2e3d5e658e Rewrite AtlasEngine to allow arbitrary overhangs (#14959)
This is practically a from scratch rewrite of AtlasEngine.

The initial approach used a very classic monospace text renderer, where
the viewport is subdivided into cells and each cell is assigned one
glyph texture, just like how real terminals used to work.
While we knew that it would have problems with overly large glyphs,
like those found in less often used languages, we didn't expect the
absolutely massive number of fonts that this approach would break.
For one, the assumption that monospace fonts are actually mostly
monospace has turned out to be a complete lie and we can't force users
to use better designed fonts. But more importantly, we can't just
design an entire Unicode fallback font collection from scratch where
every major glyph is monospace either. This is especially problematic
for vertical overhangs which are extremely difficult to handle in a
way that outperforms the much simpler alternative approach:
Just implementing a bog-standard, modern, quad-based text renderer.

Such an approach is both, less code and runs faster due to a less
complex CPU-side. The text shaping engine (in our case DirectWrite)
has to resolve text into glyph indices anyways, so using them directly
for text rendering allows reduces the effort of turning it back into
text ranges and hashing those. It's memory overhead is also reduced,
because we can now break up long ligatures into their individual glyphs.
Especially on AMD APUs I found this approach to run much faster.

A list of issues I think are either obsolete (and could be closed)
or resolved with this PR in combination with #14255:

Closes #6864
Closes #6974
Closes #8993
Closes #9940
Closes #10128
Closes #12537
Closes #13064
Closes #13527
Closes #13662
Closes #13700
Closes #13989
Closes #14022
Closes #14057
Closes #14094
Closes #14098
Closes #14117
Closes #14533
Closes #14877

## PR Checklist
* Enabling software rendering enables D2D mode 
* Both D2D and D3D:
  * Background appears correctly 
  * Text appears correctly
    * Cascadia Code Regular 
    * Cascadia Code Bold 
    * Cascadia Code Italic 
    * Cascadia Code block chars leave (almost) no gaps 
    * Terminus TTF at 13.5pt leaves no gaps between block chars 
    * ``"`u{e0b2}`u{e0b0}"`` in Fira Code Nerd Font forms a square 
  * Cursor appears correctly
    * Legacy small/medium/large 
    * Vertical bar 
    * Underscore 
    * Empty box 
    * Full box 
    * Double underscore 
  * Changing the cursor color works 
  * Selection appears correctly 
  * Scrolling in various manners always renders correctly 
  * Changing the text antialising mode works 
  * Semi-transparent backgrounds work 
  * Scroll-zooming the font size works 
  * Double-size characters work 
  * Resizing while text is printing works 
  * DWM `+Heatmap_ShowDirtyRegions` shows that only the cursor
    region is dirty when it's blinking 
* D2D
  * Margins are filled with background color 
    They're filled with the neighboring's cell background color for
    convenience, as D2D doesn't support `D3D11_TEXTURE_ADDRESS_BORDER`
* D3D
  * Margins are filled with background color 
  * Soft fonts work 
  * Custom shaders enable continous redraw if time constant is used 
  * Retro shader appears correctly 
  * Resizing while a custom shader is running works 
2023-04-26 12:02:51 +00:00
Leonard Hecker
405fb51201 Fix AppInitialized latency metric (#15206)
The AppInitialized latency metric logs how long the application needs
to initialize the UI. 5b434dc broke this metric, because it was now
executing the code outside of the `Initialized` callback.
It's the difference between a "latency" of ~50ms and ~350ms.

As an added bonus it moves the `_ApplyStartupTaskStateChange` task
into the `Initialized` callback as well, because why not.

## Validation Steps Performed
* Breakpoint into "AppInitialized" - latency is now correct 

Co-authored-by: Dustin L. Howett <duhowett@microsoft.com>
2023-04-25 22:28:07 +00:00
James Holderness
e413a4148e Prevent crash when VTParameters::subspan is out of range (#15235)
## Summary of the Pull Request

There are certain escape sequences that use the `VTParameters::subspan`
method to access a subsection of the provided parameter list. When the
parameter list is empty, that `subspan` call can end up using an offset
that is out of range, which causes the terminal to crash. This PR stops
that from happening by clamping the offset so it's in range.

## References and Relevant Issues

This bug effected the `DECCARA` and `DECRARA` operations introduced in
PR #14285, and the `DECPS` operation introduced in PR #13208.

## Validation Steps Performed

I've manually confirmed that the sequences mentioned above are no longer
crashing when executed with an empty parameter list, and I've added a
little unit test that checks `VTParameters::subspan` method is returning
the expected results when passed an offset that is out of range.

## PR Checklist
- [x] Closes #15234
- [x] Tests added/passed
- [ ] Documentation updated
- [ ] Schema updated (if necessary)
2023-04-25 16:52:33 -05:00
Mike Griese
4ebc383cb6 A hypothetical fix for hidden windows (#15213)
We had a report in a mail thread that someone's Terminal windows were
getting created hidden, and never showing themselves.

As a theory, I'm guessing that dwFlags didn't say that we should
actually use `wShowWindow`. So, to be more correct, let's actually obey
that.

I'm gonna send this package to them to see if it fixes them.

Related to #14957.

Likely regressed in #13838.
2023-04-25 16:42:09 -05:00
James Pack
fea6eeddfd Disable the context menu command inside a zipped folder (#15236)
Closes #15190
2023-04-25 21:36:20 +00:00
Leonard Hecker
adbe4a0d0c Fix missing call to UpdateViewport::UpdateViewport during tearout (#15175)
This bug causes AtlasEngine to render buffer contents with an incorrect
`cellCount`, which may either cause it to draw the contents only
partially, or potentially access the TextBuffer contents out of bounds.

`EnablePainting` sets the `_viewport` to the current viewport for some
unfortunate (and quite buggy/incorrect) caching purposes, which causes
`_CheckViewportAndScroll()` to think that the viewport hasn't changed
in the new window. We can ensure `_CheckViewportAndScroll()` works
by also setting `_forceUpdateViewport` to `true`.

Part of #14957

## PR Checklist
* Tear out a tab from a smaller window to a larger window
* Renderer contents adept to the larger window size 

---------

Co-authored-by: Mike Griese <migrie@microsoft.com>
Co-authored-by: Dustin L. Howett <duhowett@microsoft.com>
2023-04-25 16:32:44 -05:00
Mike Griese
7e9f09f495 A very sensible Pane refactoring (#15232)
It seemed dangerous to just have places all over Pane where we
manipulate the whole cadre of TermControl events. Seemed ripe for a
copypasta error. This moves that around, so there's only two methods for
messing with the TermControl callbacks: `_setupControlEvents` and
`_removeControlEvents`.

Closes: nothing. This was an off-the-cuff commit that seemed valuable.
2023-04-25 20:58:13 +00:00
Mike Griese
06dc975a0e Switch to function pointers (#15233)
Apparently, `std::function` is bad and we should feel bad. I friggen
hate the c++ function pointer syntax, but [I do what I'm
told](https://getyarn.io/yarn-clip/85c318d8-f4a7-4da6-ae20-23d7b737e71c)

I missed this comment in #15020. Sorry!
2023-04-25 20:25:30 +00:00
Kevin Kostrzewa
def3742a2e Fix focus issue when profile selected from nested menu entry (#15077)
Original bug report #15049
Relates to feature #1571 

MenuFlyoutSubItem, when collapsing from profile selection, move focus
back to the titlebar.
An extra Closing event handler is needed to keep focus on the command
shell.

Closes #15049
2023-04-25 15:24:06 -05:00
Dustin L. Howett
5ed3c76dcb Remove IsUwp, RunAsUwp, defaults-universal and all fallout (#15222)
The ability to build and run Terminal as a UWP application was removed
in #12119. We left some of its vestiges around, but now there is no need
for them.
2023-04-25 09:28:55 -07:00
Mike Griese
e491141bd9 Remove the window thread from the list of threads before nulling the AppHost (#15231)
See
https://github.com/microsoft/terminal/issues/14957#issuecomment-1520522722.

I think there's a race here that lets the WindowEmperor muck around with
the window after it's done, but before we remove it from our list of
threads.

This _should_ remove the thread from the list, _then_ null out the
AppHost, then flush the XAML queue, preventing the A/V.

Closes MSFT:43995981
2023-04-25 14:43:51 +00:00
Mike Griese
0d1540bbd2 Add buttons for selecting commands, output to context menu (#15020)
Adds a "Select command" and a "Select output" entry to the right-click
context menu when the user has shell integration enabled. This lets the
user quickly right-click on a command and select the entire commandline
or all of its output.

This was a "I'm waiting for reviews" sorta idea. Seemed like a
reasonable combination of features. Related to #13445, #11000.

Tested manually.

---------

Co-authored-by: Dustin L. Howett <duhowett@microsoft.com>
2023-04-25 14:43:49 +00:00
Dustin L. Howett
2cfd73d819 Enable WINRT_LEAN_AND_MEAN (#15215)
`WINRT_LEAN_AND_MEAN` removes a bunch of less often used parts of the
C++/WinRT headers:

- `std::hash` specializations for every object
- `operator <<(ostream)` overloads for any `IStringable`
- Interface producers for interfaces that are marked "exclusive"

There's only one place where we were using even one of these.

Enabling this saves us (optimistically) 30 seconds of build time on the
CI agents and shrinks our largest PCH (TerminalApp, x64, Debug) by about
150MiB.

It's not huge, but it's not nothing.
2023-04-25 00:14:17 +02:00
Mike Griese
ee05307379 Also do the VisualState dance on the tab item (#15217)
Just changing the Theme also doesn't seem to work by itself - there
seems to be a way for the tab to set the deselected foreground onto
itself as it becomes selected. If the mouse isn't over the tab, that can
result in mismatched fg/bg's

Regressed around #15078 

Closes #15184
2023-04-24 16:41:10 -05:00
Mike Griese
478834756e Make sure the command palette isn't null (#15220)
Fixes a crash when pressing a keybinding in the settings tab. 

Regressed in #15196.

Noted in #14051
2023-04-21 23:36:19 +02:00
James Pack
210414e5a8 Default to XamlRoot when unable to find focused object (#15189)
Default to XamlRoot when unable to find a focused object in
DirectKeyEvents

This may not be the most appropriate "fix" for this. Certainly open to
criticism and feedback. We are trapping the alt+space key chord on the
win32 side and forwarding it to the xaml side. There we try to find a
focused object by walking the xaml tree. If we are unable to find a
focused object we return false and do nothing. I suspect that the area
that has focus that prevents this from working normally is on the win32
side. Since we want to handle the system menu anyway and are explicitly
trapping that key combo and forwarding it on I thought this was the best
approach. If we cant find a focused object default to the xaml root.

## Validation Steps Performed
System menu opens as it should.

Closes #14397
2023-04-20 14:00:37 -05:00
Mike Griese
2aefb30355 Remove a 1px gap under the tabs only visible at >150% (#15164)
Set the padding to the default TabViewHeaderPadding (8,0,0,0), but with
-1 on the bottom. This prevents a small 1px gap that can appear on 150%
scale displays between the tab item and the content. The 1 on top helps
keep
the tab the correct relative height within the tab row.


Regressed in #15078 

See also MSFT:40692364
2023-04-20 12:13:40 -05:00
Ben Constable
ffda8c4a95 Add automation heading level 1 to fix about dialog (#15200)
Add automation heading level 1 to fix the about dialog by adding an
automation property.

Allows screen reader to pick up that this is a heading and read
properly.

Closes #11912

---------

Co-authored-by: Mike Griese <migrie@microsoft.com>
2023-04-20 13:18:13 +00:00
Dustin L. Howett
2fd33ba510 unpackaged: allow building an unpackaged distribution from layout (#15133)
This PR adds a convenience feature to New-UnpackagedTerminalDistribution
that produces an unpackaged layout from an already-unpacked AppX, like
the one Visual Studio registers.

```powershell
New-UnpackagedTerminalDistribution `
    -TerminalLayout path\to\bin\x64\Debug\AppX `
    -XamlAppX path\to\xaml\2.8.appx
```

The output item when you build an unpackaged layout is the temp folder
in which the distribution was built. It will not make a zip file for
you.
2023-04-20 07:47:05 -05:00
James Pack
2c165438ef Add a warning when a proportional font is selected (#15195)
## Summary of the Pull Request
Add an infobar warning when a non-monospaced font is selected.
## References and Relevant Issues
#13389 
## Detailed Description of the Pull Request / Additional comments
I initially had the `IsOpen` property of the infobar bound to the
`ShowAllFonts` checkbox property. However, I felt we could do better by
adding a property for it since there was already a method defined to
inspect whether the selected font was in the `MonoSpaceFontList`.
## Validation Steps Performed
Warning shows up when a non-monospaced font is selected either globally
or on individual profiles. All existing tests continue to pass.
<img width="868" alt="image"
src="https://user-images.githubusercontent.com/2086722/232594214-cd42397b-ce9d-499c-aa73-3feaa45e850e.png">

## PR Checklist
- [x] Closes #13389 
- [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 (if necessary)
2023-04-20 07:42:14 -05:00
Mike Griese
0e86ce559e Add the ability to select a whole command (or its output) (#14807)
Adds two new commands, `selectOutput` and `selectCommand`. These don't
do much without shell integration enabled, unfortunately. If you do
enable it, however, you can use these commands to quickly navigate the
history to select whole commands (or their output).

Some sample JSON:

```json
        { "keys": "ctrl+shift+<", "command": { "action": "selectCommand", "direction": "prev" } },
        { "keys": "ctrl+shift+>", "command": { "action": "selectCommand", "direction": "next" } },
        { "keys": "ctrl+shift+[", "command": { "action": "selectOutput", "direction": "prev" } },
        { "keys": "ctrl+shift+]", "command": { "action": "selectOutput", "direction": "next" } },
```

**Demo gifs** in
https://github.com/microsoft/terminal/issues/4588#issuecomment-1352042789

closes #4588

Tested manually. 

<details>
<summary>CMD.exe user? It's dangerous to go alone! Take this.</summary>

Surely, there's a simpler way to do it, this is adapted from my own
script.

```cmd
prompt $e]133;D$e\$e]133;A$e\$e\$e]9;9;$P$e\$e[30;107m[$T]$e[97;46m$g$P$e[36;49m$g$e[0m$e[K$_$e[0m$e[94m%username%$e[0m@$e[32m%computername%$e[0m$G$e]133;B$e\
```

</details>
2023-04-20 07:34:58 -05:00
Leonard Hecker
35b9e75574 Avoid animations during startup (#15204)
This fixes 3 sources for animations:
* `TabView`'s `EntranceThemeTransition` causes tabs to slowly slide in
  from the bottom. Removing the transition requires you to override the
  entire list of transitions obviously, which is a global change. Nice.
  Am I glad I don't need to deal with the complexity of CSS. /s
* `TabBase`, `SettingsTab` and `TerminalTab` were using a lot of
  coroutines with `resume_foreground` even though almost none of the
  functions are called from background tabs in the first place. This
  caused us to miss the initial XAML drawing pass, which resulted in
  animations when the tab icons would asynchronously pop into existence.
  It also appears as if `resume_foreground`, etc. have a very high CPU
  cost attached, which surprises me absolutely not at all given WinRT.

The improvement is difficult to quantify because the run to run
variation is very high. But it seems like this shaves about 10% off
of the ~500ms startup delay on my PC depending on how you measure it.

Part of #5907

## PR Checklist
* It starts when it should 
* It doesn't "exit" when it shouldn't 
  (Scrolling, Settings reload, Bell `\a`, Progress `\e]9;4;2;80\e\\`)
2023-04-20 07:31:44 -05:00
Leonard Hecker
da0a6d468a Lazy load CommandPalette and AboutDialog (#15203)
This sets `x:Load` to `false` for the two elements.
On my system, with Windows Defender disabled, this reduces CPU
usage by 15ms and the visual delay during launch by 40ms.

Part of #5907

## Validation Steps Performed
* Ctrl+Shift+P opens command palette 
* Context menu opens command palette 
* Context menu opens about dialog 
2023-04-19 19:18:36 +00:00
Leonard Hecker
c2dd6143ac Fix Peasant::ActivateWindow being called with an all 0 GUID (#15187)
`WM_ACTIVATE` is sent on window creation, whereas `WM_SHOWWINDOW` is
sent when the window is shown. Before we call `Peasant::ActivateWindow`
in the `WM_ACTIVATE` handler, we try to get the virtual desktop GUID of
our window, but since it's not shown yet during startup, there's also
no GUID that can be retrieved. This results in an error log message and
an all 0 GUID to be sent via `Peasant::ActivateWindow`.
The GUID of the window that actually spawned on the other hand is never
reported until the first time you reactivate it again, leading to a
number of subtle bugs around window activity.

Additionally, this commit fixes a race condition and pointer unsafety,
by pulling all relevant member variables onto the coroutine's stack,
before it yields itself to a background thread.

## Validation Steps Performed
- Set a trace breakpoint on `_peasantNotifyActivateWindow`
- GUID is non-zero 
2023-04-19 12:42:24 -05:00
James Pack
27bcf7e41c Add subtext to why Always show tabs is not toggleable in SUI. (#15154)
## Summary of the Pull Request
Add subtext that lets the user know why Always show tabs is not
toggleable in SUI. Also adds some additional information to the comment
for this value that points to the Globals_ShowTitlebar.Header setting.

## References and Relevant Issues
#13984 
## Detailed Description of the Pull Request / Additional comments
Simple updates to the resources that add some additional helpful
information for the user.
## Validation Steps Performed
Verified the updates show in the SUI and that they render correctly.
## PR Checklist
- [ ] Closes #13984 
- [ ] 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 (if necessary)

---------

Co-authored-by: Mike Griese <migrie@microsoft.com>
2023-04-18 16:23:17 +00:00
Mike Griese
2c16e7c07b Respect the startup info state initially passed to wt via ShellExecute (#13838)
Original description, pre-process model v3:

> This is just the `SHOWDEFAULT` bit from #12979. This seems to also
work now, but I'm PR'ing it separately so it can be a separate revert
from #13811, if it is problematic.

More accurately: 
This PR enables terminal windows to use the `wShowCmd` from the
STARTUPINFO passed to `windowsterminal.exe` to set the initial
visibility of the window. We can't just use `SW_SHOWDEFAULT`, because
all the windows are running in the initial process! After the first
window, the subsequent ones would ignore any params passed to their
originating `windowsterminal.exe` processes. To mitigate, we pass that
`wShowCmd` info from the source process, to the actual running terminal
process. That accounts for most of the delta here.

Closes #9053


This doesn't do the same for defterm-initiated connections. This is
because we don't need to! Defterm very explicitly rejects handoff for
minimized console apps. This is probably for the best! I put an attempt
in 66f8b25ec before I forgot that it was filtered long before the
Terminal. NOT doing this for /min saves us all sorts of "what happens if
`start /min cmd` tries to glom?" or "what if someone does `start /min
cmd && start /max cmd` and they glom together?".

<hr>

Also closes #15193, which was introduced as a part of this.

---------

Co-authored-by: Dustin L. Howett <duhowett@microsoft.com>
2023-04-18 16:23:11 +00:00
Mike Griese
1825ca104e fix not updating the nav view when add/removing profiles (#15162)
* make the list of MenuItems observable, so the nav view can actually
listen for changes to it
* Use the MenuItemsSource to find the index to add at, rather than the
MenuItems (which isn't accurate anymore)
* Stash a single observable vector as the menuitemsource, and modify
that whenever we need to do modifications.
* I attempted to create a new vector, then copy into the new one, then
replace the MenuItemsSource with the new vector, but that _refused_ to
work. So let's just... not.

Regressed in #14630
Closes #15140

Manually validated that this and #13673 are still fixed
2023-04-17 09:53:59 -05:00
James Pack
e106c095a5 Enable ctrl+shift to run terminal elevated from context menu (#15137)
This pull request adds the requirement for the shift key to be pressed
in addition to the control key.

References #14810
Implemented in #14873

This is follow up work from my last pull request that was merged that
only required the control key to be pressed to launch the terminal as
admin from the shell context menu. After some discussion it was decided
that the shift key should be required as well as that is the norm on
Windows.

## Validation Steps Performed

Tested all combinations of shift+ctrl and verified that the terminal
only requests elevation when a shift and control key are pressed
together. The shell launches regularly if not.
2023-04-17 14:12:45 +00:00
Mike Griese
52171d2dab Update to MUX 2.8.3 (#15183)
This fixes the BreadcrumbBar issue that would crash into the debugger
anytime you open the SUI on a second thread.

See #14957.

Maybe also tracked in #15144 - let's have @j4james test when this
merges.
2023-04-17 15:28:29 +02:00
Mike Griese
9b960bc88c Fix reordering tabs mysteriously shuffling the actual backing tabs (#15178)
TL;DR: we stopped getting `TabView.TabItemsChanged`. This meant that the
tab view would change its apparent order, but we wouldn't change the
backing tab order.

I'm fixing this by grabbing the index of the tab that starts the drag,
and the index of the tab view item at the end of the drag, and using
that to reorder our backing list.

Closes #15121

Upstream https://github.com/microsoft/microsoft-ui-xaml/issues/8388

Regressed in #15078 - I'm pretty confident about this, since I've got a
1.18.931 build of the Terminal with tear-out, but not MUX 2.8.
2023-04-17 15:27:52 +02:00
Leonard Hecker
1d354d0f5c Fix a hang when writing wide glyphs into a 1 column terminal (#15171)
The code changes are mostly self-explanatory: Just skip glyphs
that can never be inserted. I implemented it slightly incorrectly
(a newline will be inserted every time you write such a wide glyph),
but it's a niche issue and I think the simplicity of the fix is
more important than its exact correctness.

It also contains a fix for some severe log spam due to
`_PrepareForDoubleByteSequence` complaining in this situation.
The spam is so bad that it freezes the app for a few seconds
during text buffer reflow.

Closes #7416

## Validation Steps Performed
* Open an extra pane and run `TerminalStress.exe` in there
* Resize to 1 column
* Doesn't hang 
2023-04-14 23:15:08 +02:00
Mitch Capper (they, them)
eb725e9993 fix: WpfTerminalControl allow Connection set to null (#15062)
Hides the cursor when null, shows it when not.
Clear the screen any time the connection is changed.

This prevents the WPF Control from crashing when set back to null, clears
the console and hides the mouse as well.

It sends 3 VT sequences as well now:
1) When the Connection is set to null the cursor is hidden (reflects
what the default state is)
2) When the Connection is set to a value and it was null before we show
the cursor (not a breaking change as requires it to have been null which
previously would cause a crash, except for for set)
3) When the Connection is changed the terminal is reset. A breaking
change officially although not sure if there are use cases where this
behavior is not desired. For added safety we could make sure we are not
being set to the same value we currently are.

None of the ansi commands are needed, users could do it all themselves
as well, the behavior largely seemed natural though. I didn't see any
ansi constants anywhere so they are just hard coded with comments, but
not sure if there is an established better practice.

Closes #15061
2023-04-14 20:25:07 +00:00
James Pack
19069e03be A more efficient copy assignment operator for Pane.LayoutSizeNode (#15169)
## Summary of the Pull Request
This pull request updates the implementation of the copy assignment
operator for Pane::LayoutSizeNode to a more efficient version and
eliminates the need for the _AssignChildNode code block.
## References and Relevant Issues
#11965 #11963 
## Detailed Description of the Pull Request / Additional comments
My understanding of the discussion and intent of the two linked issues
is that this is a more efficient way to implement the copy assignment
operator for Pane.LayoutSizeNode and eliminates the need for the code
block _AssignChildNode. Since both were relatively small changes, I
combined the two in one PR. If that is not desirable, I can separate
them. All existing tests continue to pass.

<img width="769" alt="image"
src="https://user-images.githubusercontent.com/2086722/231326683-8f685f58-5748-4d49-8a38-80ef5db3d5a2.png">

## Validation Steps Performed
All existing tests pass. No visible changes in behavior of the terminal.
## PR Checklist
- [x] Closes #11963  
- [x] Closes #11965 
- [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 (if necessary)
2023-04-14 18:52:39 +00:00
Mike Griese
21464fe41c Manually hide our DesktopWindowXamlSource (#15165)
As discussed in #6507

Newer builds of Windows do this automatically. However, this was spotted
in the wild on 1.18. It's possible the threading changes created a
situation where the OS-side fix no longer applied to us. So let's just
do it manually. It doesn't have any side effects.

I saw this once on Win11, but couldn't repro it this morning when I
tried to add this fix. I'm just gonna assume this worked, despite the
fact that I can't repro it on win11 anymore.

closes #6507

See also #14957

## detailed description

> `WindowsXamlManager::XamlCore::Initialize` calls
`ConfigureCoreWindow`, which creates a `CoreWindow` on the thread

> Problem is, we're calling that on the main thread (which doesn't have
_any_ windows), and then eventually creating a `DesktopWindowXamlSource`
on a second thread for the actual window

> It's not that it "manages a window", it's that it "manages xaml on
Windows OS". just use ICoreWindowInterop -- QI for ICoreWindowInterop
and call get_WindowHandle.

Also see:
*
[ICoreWindowInterop](https://learn.microsoft.com/en-us/windows/win32/api/corewindow/nn-corewindow-icorewindowinterop)
*
[WindowsXamlManager.InitializeForCurrentThread](https://learn.microsoft.com/en-us/uwp/api/windows.ui.xaml.hosting.windowsxamlmanager.initializeforcurrentthread?view=winrt-22621#windows-ui-xaml-hosting-windowsxamlmanager-initializeforcurrentthread)
* The source code in
`onecoreuap\windows\dxaml\xcp\dxaml\lib\WindowsXamlManager_Partial.*`
* os.2020!6102020 which fixed MSFT:33498969, MSFT:27807465,
MSFT:21854264
2023-04-14 13:07:05 -05:00
Mike Griese
789b0b065f Actually use the persisted position with centerOnLaunch:true (#15179)
Fixes an issue when using both:

```json
    "centerOnLaunch": true,
    "firstWindowPreference": "persistedWindowLayout",
```

In this case, the Terminal would ignore the persisted location and still
just center on launch. This has been really annoying while testing
tear-out, as we keep re-opening all my debug windows as a stack on top
of each other.
2023-04-14 19:13:07 +02:00
Mike Griese
72d0566fa6 Back off between attempts to start the tests (#15106)
Looking through this test, I seriously don't understand how this doesn't
work. I mean, I don't really get how it _does_ work, but at this point
in the tests, we've actually established that both `Nihilist.exe` _and_
openconsole are running. From my read, there's no reason these should be
failing at this point.

We previously added a "retry 5 times" bit to this test, in #8534. That
did work back then. So uh, just do that... again?
2023-04-13 13:38:38 -05:00
Mike Griese
f671f065bf Register the GetWindowLayoutRequested handler only when ready (#15161)
Moves our `GetWindowLayoutRequested` handler AFTER the xaml island is
started. The `AppHost::_GetWindowLayoutAsync` handler requires us to be
able to work on our UI thread, which requires that we have a
`Dispatcher` ready for us to move to. If we set up this callback in the
ctor, then it is possible for there to be a time slice where
* the monarch creates the peasant for us,
* we get ctor'ed (registering the callback)
* then the monarch attempts to query all _peasants_ for their layout,
coming back to ask us even before XAML has been created.

I believe this was the source of the crash that was reported in a mail
thread. It actually happened to me once while debugging another branch.
Alas, this was realy hard to hit in the first place, so I'm not
_totally_ certain this fixes it.

Related to #14957
2023-04-12 11:57:25 -05:00
James Pack
10bdadffbd Skip generating a profile for rancher-desktop (#15166)
Don't generate a profile for rancher-desktop utility WSL distro.

Adds a check for rancher-desktop as well as docker. As mentioned in the
discussion of this issue. This becomes much more difficult to maintain
once other folks inevitably start to follow this pattern. But the easy
win was up for grabs so I took it :)

Closes #12757
2023-04-12 11:56:55 -05:00
Ian O'Neill
56d451ded7 Support environment variables in the settings (#15082)
Existing environment variables can be referenced by enclosing the name
in percent characters (e.g. `%PATH%`).

Resurrects #9287 by @christapley.

Tests added and manually tested.

Closes #2785
Closes #9233

Co-authored-by: Chris Tapley <chris.tapley.81@gmail.com>
2023-04-11 18:01:11 -05:00
James Holderness
508adbb1ec Send a KeyUp sequence only once a key has been released (#15130)
When win32-input-mode is enabled, we generate an input sequence for both
key down and key up events. However, in the initial implementation the
key up sequence for most keypresses would be faked - they were generated
at the same time as the key down sequence, regardless of when the key
was actually released. After this PR, we'll only generate the key up
sequence once a key has actually been released.

## References and Relevant Issues

The initial implementation of win32-input-mode was in PR #6309.
The spec for win32-input-mode was in PR #5887.

## Validation Steps Performed

I've manually tested this with an app that polls `ReadConsoleInput` in a
loop and logs the results. With this PR applied, I can now see the key
up events as a key is released, rather than when it was first pressed.

When compared with conhost, though, there are some differences. When
typing a shifted key, e.g. `Shift`+`A`, WT generates key down and key up
events for both the `Shift` and the `A`, while conhost only generates
both events for the `Shift` - the `A` won't generate a key up event
unless you release the `Shift` before the `A`. That seems more like a
conhost flaw though.

Another case I tested was the Japanese Microsoft IME, which in conhost
will generate a key down event for the Japanese character being inserted
followed by a key up event for for `Return`. WT generates key up events
for the ASCII characters being typed in the IME, then both a key down
and key up event for the inserted Japanese character, and finally a key
up event for `Return`. Both of those seem weird, but they still appear
to work OK. 

The current version of WT actually produces the most sensible behavior
for the IME - it just generates key up and key down events for the
inserted character. But that's only because it's dropping most of the
system generated key up events.

Closes #8440
2023-04-11 17:59:25 -05:00
Mike Griese
b4f65030e3 Fix re-persisting the new legacy themes (#15160)
Yep, I forgot to not write them back to the settings file here.

Regressed in #15108 

Closes #15152
2023-04-11 17:10:11 -05:00
Dustin L. Howett
90bbd2927d Helix: Decode HTML entities in the test comment field (#15141
I have observed the test comment coming back from Helix with `&quot;`
and friends in it.

It ends badly as you might imagine.

This unescape will be a no-op if the data is already well-formed.
2023-04-10 15:17:29 -05:00
Dustin L. Howett
ea44375f6d Check for updates automatically (but don't install) (#13437)
This PR adds support to the About Dialog for checking the store to see
if there's a new version of the Terminal package available. We'll only
do this once per day, per terminal window.

In dev mode, we'll always fake it and say there's an update to `x.y.z`
available.

This also involved pulling all of the About dialog code out into its own
class. All that is goodness.

We don't currently provide a button for _installing_ the update. We just
check. Incremental progress is better than none.

Co-authored-by: Mike Griese <migrie@microsoft.com>
Co-authored-by: Leonard Hecker <lhecker@microsoft.com>
2023-04-06 18:31:19 -05:00
Dustin L. Howett
7fbd3be8c3 Only try to hand off to ConhostV1 if building for Windows (#15131)
Some of our automated tooling detects this as being a private API that
we're accessing via LoadLibrary/GetProcAddress. It's not *wrong*, but
it's also not *right*.

It's easier for us to just not do it (and save all the code for it!) in
OpenConsole.
2023-04-06 16:32:40 -05:00
Dustin L. Howett
de09671d8a wpf: Bump the history length to 9001 instead of 1000 (#15129)
This was an oversight in the original implementation.
2023-04-06 15:03:12 -05:00
Dustin L. Howett
c7498a4269 PGO: Update the Helix payload to rely on the unpackaged distribution (#15123)
The unpackaged distribution was made for this exact use, so let's *do
it*!
2023-04-06 22:01:00 +02:00
Mike Griese
083fc647bb Revert the revert of "Hide the window until we're finished with initialization" (#13811)
This is a revert of the revert of #12979. We mainly reverted that PR
because of an issue where restored windows would grow/shrink slightly on
external displays. It was too close to the ship date for that release,
so we backed it out wholesale (in #13098). I think I've found the real
root of the problem, and fixed it here.

The money diff here from the original PR:
4c08b9a1bc2e90b8284e4d8117d0de400784520f...c34495dcfc19ea67a9f4f9673d422760200683ab.
Basically, I had put the part where we actually handle the creation of
the window into `_AppInitializedHandler`, when we should have left the
window to be created in `_HandleCreateWindow` We create it there,
_hidden_, and then should only _show_ it in `_AppInitializedHandler`.

I'm _NOT_ incorporating the change for #9053. I reverted that bit in
1fac40355. I am too worried about that messing with the phwnd that I
wanted to get that reviewed and committed atomically, separately.

* fixes  #11561
* tested manually
* I work here
2023-04-06 18:03:25 +00:00
Mike Griese
6f8ef58673 Add support for running the Terminal without _any_ windows (#14944)
This adds a setting (`compatibility.allowHeadless`) to let the Terminal
keep running even when all windows are closed. This lets hotkeys keep
working, because the Emperor thread is still running, just, without any
windows.

I'm really tempted to invoke the magic "closes" word on #9996, but
honestly, we should also add some sort of support for `wt --headless` or
`wt --hidden` or whatever, before we close that. There's also #13630
which seems imminently doable.

Tested manually. I'd post a gif of "close all terminal windows, then
invoke the quakeMode binding and \*presto\*, but that would be an
unnecessarily big gif.

Related to #9996 but not enough to close it if you ask me
2023-04-06 12:39:40 -05:00
Mike Griese
fe66ba5f58 Add "legacy" themes (#15108)
This is a minimal version of the requests for #14858. In that thread we
discussed FULL reverting the default themes to the old ones. In later
discussion, we decided _meh_, let's just ship the legacy themes too, so
it's easy to go back if you should choose. The default still remains the
sane `dark`, but the `legacy*` themes are all right there, and given the
same special treatment as the other inbox themes.

Closes #14858
Closes #14844
2023-04-06 16:50:30 +00:00
michalnpl
e73362d45b Respect the codepage stored in .LNK files in conhost (#15111)
Making Conhost pick up codepage from .lnk files.

Because of the wrong assignment order, the Conhost was not picking up
the codepage stored in .lnk shortcut files. This change fixes this issue
by changing the order of the assignment to the correct one.

This is a potential backward compatibility issue.

Since this issue has been present in the codebase for years, this change
runs a high risk of breaking backward compatibility with software that
depends on incorrect behavior.

## Validation Steps Performed
Tested fix manually (using chcp command, making sure each .lnk codepage
was picked up.) against Debug/Release x64 builds with 5 different .lnk
files:

1. Arabic codepage 1256
2. Greek 869
3. Latin2 852
4. Thai 874
5. Traditional Chinese 50229

Ran TAEF tests against Debug/Release x64/x86 with identical results as
main branch.

Tested against invalid codepage numbers by manually manipulating .lnk
file binary. In case of an invalid codepage number, Conhost defaults to
a valid default one, which I assume is expected behavior.

Closes #14942
2023-04-06 10:51:57 -05:00
Dustin L. Howett
a98a0cf2c6 Stop the beef when you hover off a hyperlink (#15120)
Big surprise, apparently W.F.Uri can parse the empty string into
garbage!
2023-04-05 16:10:54 -07:00
Leonard Hecker
5db8af6277 Return success if ReadCharacterInput read >0 characters (#15122)
This is a regression caused by 599b550. If I'm reading `stream.cpp`
in cf87590 right, it returns `STATUS_SUCCESS` if `ReadCharacterInput`
read at least 1 character. I think? this PR makes the code behave
exactly equivalent. The old code is a bit of an "acquired taste"
so it's a bit hard to tell.

Closes #15116

## PR Checklist
* Run `more long_text_file.txt` in cmd
* Press Spacebar
* Scrolls down 
* Press Q
* Exits 
2023-04-05 22:52:04 +00:00
Dustin L. Howett
5f70920491 When unpackaged, isolate the monarch by the install path (#15118)
Unpackaged installations don't have the luxury of magic package
isolation to stop them from accidentally touching each other's monarchs.
We need to enforce that ourselves by making their monarch CLSIDs unique
per install.

We'll use a v5 UUID based on the install folder to unique them.

Closes #15117
2023-04-05 17:04:58 -05:00
Leonard Hecker
62448969b3 Upgrade clang-format to 15.0.7 (#15110)
Upgrading clang-format lead to a few changes in the formatting
of code inside macros. Apart from the upgrade, I've also spent
some time removing all options from .clang-format that are
redundant with `BasedOnStyle: Microsoft`.
2023-04-05 10:03:20 -05:00
Leonard Hecker
ecb5e37a7d Use new row primitives for ResizeTraditional (#15105)
This will allow us to share the same fundamental text insertion
logic for both `ResizeTraditional` and `Reflow`, because both
can be implemented with `ROW::CopyRangeFrom`. It also replaces
the `BufferAllocator` struct with a `_allocateBuffer` function
which will help us allocate scratch buffer rows in the future.

Closes #14696

## PR Checklist
* Disable reflow resize in conhost
* Print "zhwik8.txt" - a enwik8.txt equivalent of Chinese Wikipedia
* Run `color 80` in cmd
* Resize windows from 120 to 119 columns
* Wide glyphs disappear and are replaced with whitespace 
* Resizing the window to >120 columns adds gray whitespace 
2023-04-05 09:59:20 -05:00
James Holderness
aea0477bda Filter out control characters that don't do anything (#15075)
On a real VT terminal, most of the control characters that don't do
anything are supposed to be filtered out, and not written to the buffer.
Up to to now, though, we've only been filtering out `NUL`. This PR
extends our control processing to filter the remaining characters that
aren't supposed to be displayed.

We introduced filtering for the `NUL` control in PR #3015.

The are two special cases worth mentioning.

1. The `SUB` control's main purpose is to the cancel a control sequence
that is in progress, but it also needs to output an error character (a
reverse question mark) to the display.

2. The `DEL` control is typically filtered out, but when a 96-character
set is designated, it can sometimes be mapped to a printable glyph that
needs to be displayed.

## Validation Steps Performed

I've manually tested that all the controls that are meant to be filtered
out are no longer being displayed.

I've also extended the existing `NUL` unit test to cover the full set of
controls characters that are supposed to be filtered.

Closes #10786
2023-04-05 09:58:52 -05:00
Dustin L. Howett
06526cac0c Remove our dependency on any CRT--AppX or forwarders (#15097)
The upgrade to Microsoft.UI.Xaml 2.8 was the last piece we needed to
break our dependency on the App CRT *and* any CRT whatsoever.
2023-04-04 16:11:12 -05:00
Leonard Hecker
9dfdf2afa3 Introduce til::linear_flat_set (#15089)
`til::linear_flat_set` is a primitive hash map with linear probing.
The implementation is slightly complicated due to the use of templates.
I've strongly considered just writing multiple copies of this class,
by hand since the code is indeed fairly trivial but ended up deciding
against it, because this templated approach makes testing easier.

This class is in the order of 10x faster than `std::unordered_map`.
2023-04-04 19:50:10 +02:00
Leonard Hecker
2a839d8c5a Fix accuracy bugs around float/double/int conversions (#15098)
I noticed this bug while resizing my window on my 150% scale display.
Every 3 "snaps" of the window size, it would fail to resize the text
buffer. I found that this occurs, because we convert the swap chain
size from a float into a double, which converts my 597.333313 height
into 597.33331298828125, which then multiplied by 1.5 results in
895.999969482421875. If you just cast this to an integer, it'll
result in a height of 895px instead of the expected 896px.

This PR addresses the issue in two ways:
* Replace casts to integers with `lrint` or `floor`, etc.
* Remove many of the redundant double <> float conversions.

## PR Checklist
* Resizing my window always resizes the text buffer 
2023-04-04 11:33:17 -05:00
James Pack
da995a014f Enable holding ctrl to open the Terminal elevated from File Explorer
## Summary of the Pull Request
This pull request adds support for holding the control key and clicking
the Open Terminal Here context menu item to elevate the request.
## References and Relevant Issues
#14810

## Detailed Description of the Pull Request / Additional comments

## Validation Steps Performed

## PR Checklist
- [x] Closes #14810
- [ ] 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 (if necessary)

---------

Co-authored-by: Mike Griese <migrie@microsoft.com>
2023-04-04 16:24:33 +00:00
Leonard Hecker
47a17cf2d7 Replace statics in headers with inline constants (#15100)
C++ is a very well balanced and reasonable language, which is why
`static` inside classes means "shared between all instances", whereas
`static` outside of classes means "not shared between all .cpp files".

32 years after this problem was written onto parchment it was fixed with
the introduction of inline variables in C++17, which tell the compiler
to deduplicate variables the same way it deduplicates functions.
2023-04-04 10:19:20 -05:00
Mike Griese
c0f14567f3 Use DIPs for the window bounds when tearing out (#15094)
Fixes a bug where you'd drag across the boundary and the new window
would be at the wrong size

related to #14957
2023-04-04 14:21:43 +00:00
Leonard Hecker
5de1fd9a7b Introduce til::generational - a struct comparison helper (#15088)
It can be costly, difficult, or often impossible to compare two
instances of a struct. This little helper can simplify this.

The underlying idea is that changes in state occur much less often than
the amount of data that's being processed in between. As such, this
helper assumes that _any_ modification to the struct it wraps is a
state change. When you compare the modified instance with another
the comparison operator will then always return false. This makes
state changes potentially more costly, because more state might be
invalidated than was necessary, but on the other hand it makes both,
the code simpler and the fast-path (no state change) much faster.

For instance, let's look at the amount of data that represents a
user's chosen font: It encompasses the font family, size and weight,
font axes (a vector of tuples), dpi and cell height/width overrides.
Comparing all that data, every time the user changes anything, is
fairly complex to code and maintain and costly at runtime, even though
the user will change the only font very seldomly. Instead, we can
optimize for the common case of no font changes occuring and simply
assume that if any font related field changed, all fields changed.
This is exactly what `til::generational` does.
2023-04-04 15:47:36 +02:00
Mike Griese
17cf44fa71 Upgrade to MUX 2.8 (#15078)
Updates the Terminal to Microsoft.UI.Xaml v2.8. 

* MUX 2.8 adds a dependency on WebView2, so we need to include parts of it too.
* See https://github.com/microsoft/microsoft-ui-xaml/pull/7574 for why
we're adding the `.props`
* The TabView thing: 
> tl;dr: In >=MUX 2.7, we were updating our tab colors by doing a
"Visual State Dance", as I called it. We'd manually change the
`TabViewItem`'s VisualState to one that it wasn't in, then change it
back to the one it should be in. This seemingly re-applied the new
values of the brushes. However in 2.8, this seemingly didn't work
anymore!
  > 
  > So instead, we do a "Theme Dance", like so:
  > ```c++
  >   const auto& reqTheme = TabViewItem().RequestedTheme();
  >   TabViewItem().RequestedTheme(ElementTheme::Light);
  >   TabViewItem().RequestedTheme(ElementTheme::Dark);
  >   TabViewItem().RequestedTheme(reqTheme);
  >   ```
> This causes the `ThemeResource`s to be re-evaluated to the new values.
> We never got to the root cause of why this seems different in 2.8. It
literally makes no sense.
Closes #13495

Co-authored-by: Dustin L. Howett <duhowett@microsoft.com>
2023-04-03 22:40:46 +00:00
Dustin L. Howett
06174a9cb3 Format URLs for display when we show the tooltip (#15095)
This will reduce the incidence of confusables, RTL, and non-printables
messing with the display of the URL.
2023-04-03 21:22:25 +00:00
Leonard Hecker
0656afcf13 Expose hyperlink attributes in PaintBufferGridLines (#15090)
Rendering hyperlinks is unneccessarily complex at the moment, because
it requires you to implement `UpdateDrawingBrushes`, manually extract
the hyperlink flag from the given `TextAttribute` and save it until the
next call to `PaintBufferGridLines` which does not get that flag.
This isn't particularly clean as it assumes that `PaintBufferGridLines`
will be called after `UpdateDrawingBrushes` in the first place.

Instead, we can simply pass the hyperlink flag to `UpdateDrawingBrushes`
so that the renderers don't need to deal with this anymore.

## PR Checklist
* Hyperlinks show up with a dotted line 
* Hovering hyperlinks underline them 
2023-04-03 20:39:36 +02:00
Leonard Hecker
0d38d17299 Add a simple tool to test rendering functionality (#15091)
This tool augments `vttest` by adding some things that are specific to
us (like non-VT console attributes), and some things `vttest` is
seemingly too old for (like emojis). I'm planning to add more "pages"
of tests to the application in the future, whenever the need arises.
2023-04-03 13:21:22 -05:00
Leonard Hecker
7ddd98de0a Fix warnings in til for an upcoming version of MSVC (#15087)
A trivial change. :)
2023-04-03 13:14:01 -05:00
Sam Meyer
0105807be2 Add pre-build PowerShell version check (#14947)
Two PowerShell scripts were added so that developers new to the project
know if they have the wrong version of PowerShell installed.

When first building Terminal, it would continuously fail, and I didn't
really know why. I'm new to both this project and to open source, so
when I saw an error message about "pwsh.exe" not being found I was
confused and didn't know what went wrong. What I didn't know is that
Windows PowerShell and PowerShell Core had different names for
their .exe files, and since I had the latest version of Windows
PowerShell installed, I figured that I was completely set. So, once I
realized that Windows PowerShell (what I had installed) is
powershell.exe and PowerShell Core (what I needed to have installed) is
pwsh.exe, I downloaded PowerShell Core, and it built without issue. So,
in order to help other newbies, I made two scripts, `CheckPSVersion` and
`WindowsCheckPSVersion`, which make sure that PowerShell Core 7.0.0+ is
installed, outputting an error telling the developer to download Core
7.0.0+ if they have Windows PowerShell but not Core. These scripts are
run pre-build courtesy of `Microsoft.Terminal.Settings.ModelLib.vcxproj`

## Validation Steps Performed
Building with both Windows PowerShell and PowerShell core: builds
perfectly, no issues.
Building with Windows PowerShell but not PowerShell core: build fails,
but a nice error prints out that reminds the user to download the
correct version of PowerShell core.

Closes #14797
2023-03-31 18:02:29 -05:00
Dustin L. Howett
e6a3fa8d4e Add "portable mode", where settings load from the install path (#15051)
This pull request implements portable mode for Windows Terminal, which
will make side by side deployment of different versions generally more
feasible.

Portable mode was specified in #15032.

There are three broad categories of changes in this PR:

1. Changes to settings loading.
2. A new indicator in the settings UI plus a link to the portable mode
   docs.
3. A new application display name, `Terminal (Portable)`, which users
   will hopefully include in their bug reports.

It's surprisingly small for how big a deal it is!

Related to #15034
Closes #1386
2023-03-31 17:12:00 -05:00
Mike Griese
bbd4d1b1e4 Fix a crash in the rclick context menu (#15079)
Due to a bad merge a few commits back. This event should have had a
revoker.

Probably regressed in #14851
2023-03-31 13:49:12 -07:00
Dustin L. Howett
984b03ca33 [SPEC] Add a lightweight spec for Portable Mode (#15032) 2023-03-31 15:46:00 -05:00
Mike Griese
7b0aca444f Enable tearing out tabs to create new windows (#14935)
_This is the last one 🎉_

## Summary

_In the final chapter of our tale, we present a PR of great
significance. It grants the power to tear tabs from their windows and
create a new window where they may be dropped, one not necessarily of
the Terminal sort. The dimensions of the original window are transferred
to this new abode, and its placement on the screen is determined by the
user's placement of the tab._
_This is the last main chapter of the tear-out saga, and the dawning of
the new age._

Closes #5000
Related to #1256

## Detailed description

We're really leaning on the existing `RequestNewWindow` event that the
monarch already had - honestly, most of that was so simple that it could
have just been in the parent PRs. We just need to add new support for
passing in a content blob of json, and making sure the Terminal always
uses that over commandline args. Easy enough.

There's a bit of wackiness here in adjusting the positioning just right
so that the new window appears in the right place, but it feels...
pretty good all things considered.
2023-03-31 19:37:17 +00:00
Dustin L. Howett
dd63a0590b Add support for an unpackaged distribution of Terminal (#15034)
Since the removal of the Win10-specific variant of the Terminal MSIX in
#15031, there has been no officially-sanctioned (or even unofficially
tested!) way to get an unzippable double-click-runnable version of
Windows Terminal.

Due to a quirk in the resource loading system, an unpackaged
distribution of Terminal needs to ship all of XAML's resources and all
of is own resources in a single `resources.pri` file. The tooling to
support this is minimal, and we were previously just coasting by on
Visual Studio's generosity plus how the prerelease distribution of XAML
embedded itself into the consuming package.

This pull request introduces a build phase plus a supporting script (or
three) that produces a ZIP file distribution of Windows Terminal when
given a Terminal MSIX and an XAML AppX.

The three scripts are:

1. A script to merge any number of PRI files and/or PRI dump files (made
   with `makepri dump /dt detailed`)
2. A script that specifically merges XAML's resources with Terminal's.
   This is necessary because the XAML package emits a couple PRI
   resources into Terminal's resources _even when it is not
   co-packaged._ We need to remove the conflicting resources.
3. Finally, a script to take a WT and XAML distribution and combine them
   -- resources, files, everything -- and strip out the things that we
   don't need. This script is an all-in-one that calls the other two and
   produces a ZIP file at the end.

The final distribution is named after the PFN
(`Microsoft.WindowsTerminal`, or `...Preview` or `WindowsTerminalDev`),
the version number and the architecture. When expanded, it produces a
directory named `terminal-X.Y.Z.A` (version number.)

I've also added the build script to the release pipeline.

As a treat, this also produces an unpackaged distribution out of every
CI build... that way, contributors can download live deployable copies
of WT Unpackaged to test out their changes. Pretty cool.

Refs #1386
2023-03-30 16:38:10 -05:00
James Holderness
fc95802531 Merge the LineFeed functionality into AdaptDispatch (#14874)
The main purpose of this PR was to merge the `ITerminalApi::LineFeed`
implementations into a shared method in `AdaptDispatch`, and avoid the
VT code path depending on the `AdjustCursorPosition` function (which
could then be massively simplified). This refactoring also fixes some
bugs that existed in the original `LineFeed` implementations.

## References and Relevant Issues

This helps to close the gap between the Conhost and Terminal (#13408).
This improves some of the scrollbar mark bugs mentioned in #11000.

## Detailed Description of the Pull Request / Additional comments

I had initially hoped the line feed functionality could be implemented
entirely within `AdaptDispatch`, but there is still some Conhost and
Terminal-specific behavior that needs to be triggered when we reach the
bottom of the buffer, and the row coordinates are cycled.

In Conhost we need to trigger an accessibility scroll event, and in
Windows Terminal we need to update selection and marker offsets, reset
pattern intervals, and preserve the user's scroll offset. This is now
handled by a new `NotifyBufferRotation` method in `ITerminalApi`.

But this made me realise that the `_EraseAll` method should have been
doing the same thing when it reached the bottom of the buffer. So I've
added a call to the new `NotifyBufferRotation` API from there as well.

And in the case of Windows Terminal, the scroll offset preservation was
something that was also needed for a regular viewport pan. So I've put
that in a separate `_PreserveUserScrollOffset` method which is called
from the `SetViewportPosition` handler as well.

## Validation Steps Performed

Because of the API changes, there were a number of unit tests that
needed to be updated:

- Some of the `ScreenBufferTests` were accessing margin state in the
`SCREEN_INFORMATION` class which doesn't exist anymore, so I had to add
a little helper function which now manually detects the active margins.

- Some of the `AdapterTest` tests were dependent on APIs that no longer
exist, so they needed to be rewritten so they now check the resulting
state rather than expecting a mock API call.

- The `ScrollWithMargins` test in `ConptyRoundtripTests` was testing
functionality that didn't previously work correctly (issue #3673). Now
that it's been fixed, that test needed to be updated accordingly.

Other than getting the unit tests working, I've manually verified that
issue #3673 is now fixed. And I've also checked that the scroll markers,
selections, and user scroll offset are all being updated correctly, both
with a regular viewport pan, as well as when overrunning the buffer.

Closes #3673
2023-03-30 13:32:54 -05:00
Leonard Hecker
da3a33f3bc Minor cleanups after #14745 (#14748)
#14745 removed the only user of `GetAugmentedOutputBuffer`.
2023-03-30 10:27:04 -05:00
Mike Griese
9514c1191a Enable dragging tabs between windows (#14901)
_Behold, the penultimate chapter in the saga of tear-out! This
significant update bestows upon the user the power to transport tabs
betwixt Terminal windows. Alas, the drag and drop capabilities of
TabView are not yet refined, so this PR primarily concerns itself with
the intricacies of plumbing. When a tab is extracted and deposited
elsewhere, it is necessary to have the recipient make an inquiry to the
Monarch, who in turn will beseech the sender to transmit the tab
content, akin to the act of moving a tab. Curious it may seem, but the
method has proven effective._

The penultimate tear-out PR. This PR enables the user to move tabs from
one Terminal window to another. The TabView drag/drop APIs have some
rough edges, so this PR is mostly plumbing. When a tab is drag/dropped,
we need to get the recipient to ask the Monarch to ask the sender to
send the tab content, like a MoveTab action. Wacky, but it works.

There's a LONG tail of UX gaps. Those I'm going to track in #14900. It
is more valuable for us to merge this now than to figure out workarounds
immediately.

The next PR will be the last main PR in this saga - in which we enable
dragging a tab out of the window and dropping to create a new window.


* Closes #1256
* Related to #5000
* Follow-ups get to go in #14900 


## Detailed description

As I mentioned, it's mostly plumbing. The order that we get tab drag
events is... unfortunate... for our use case. So we do a lot of sending
`RequestReceiveContentArgs` up and down between windows, just to
communicate who the tab was dropped on to whomever the tab was dragged
from.

There's a diagram for this that I originally put in
https://github.com/microsoft/terminal/issues/5000#issuecomment-1435328038:

```mermaid  
sequenceDiagram
    participant Source
    participant Target
    participant Monarch

    Note Left of Source: _onTabDragStarting
    Source --> Source: stash dragged content
    Source --> Source: pack window ID into DataPackage

    Source ->> Target: Drag tab
    Note right of Target: _onTabStripDragOver
    Target ->> Target: AcceptedOperation(DataPackageOperation::Move)
    
    Source --> Target: Release mouse (to drop)
    
    Note right of Target: _onTabStripDrop
    Target --> Target: get WindowID from DataPackage
    Target -) Monarch: Request that WindowID sends content to us<br>RequestRecieveContent
    Monarch -) Source: Tell to send content to Target.Id<br>RequestSendContent, SendContent
    Source --> Source: detach our content
    Source -) Monarch: RequestMoveContent(stashed, target.id)
    Monarch -) Target: AttachContent(stashed)

    # Target -->> Source: 
    # Note Left of Source: TabViewTabDragStartingEventArgs<br>.OperationCompleted
    # Note Left of Source: _onTabDroppedCompleted
```

Really really though, let's try to avoid nits about the UX at this time.
This PR works with what we've got. Mail threads are percolating. I've
got 19 chapters worth of Hobbit branch names to use for those follow
ups.
2023-03-30 15:20:23 +00:00
Mike Griese
17a5b77335 Add support for moving panes and tabs between windows (#14866)
_Lo! Harken to me, for I shall divulge the heart of the tab tear-out
saga. Verily, this PR shall bestow upon thee the power to move tabs and
panes between windows by means of pre-defined actions. Though be warned,
it does not yet grant thee the power to drag and drop them as thou
mayest desire. Yet, the same plumbing that underpins this work shall
remain steadfast. Behold, the majority of this undertaking concerns the
elevation of the RequestMoveContent event from the TerminalPage to the
very summit of the Monarch. From thence, a great AttachContent method
shall descend back to the lowest depths. Furthermore, there are minor
revisions to TermControl that shall enable thee to better detach the
content and attach it to a new one._

This is the most important part of the tab tear-out saga. This PR
enables the user to move tabs and panes between windows using
pre-defined actions. It does _not_ enable the user to drag/drop them
yet, but the same fundamental plumbing will still apply. Most of the PR
is plumbing the `RequestMoveContent` event up from the `TerminalPage` up
to the `Monarch`, and then plumbing an `AttachContent` method back down.
There are also small changes to `TermControl` to better support
detaching the content and attaching to a new one.

For testing, I recommend:

```json
        { "keys": "f1", "command": { "action": "moveTab", "window": "1" } },
        { "keys": "f2", "command": { "action": "moveTab", "window": "2" } },

        { "keys": "f3", "command": { "action": "movePane", "window": "1" } },
        { "keys": "f4", "command": { "action": "movePane", "window": "2" } },

        { "keys": "shift+f3", "command": { "action": "movePane", "window": "1", "index": 3 } },
        { "keys": "shift+f4", "command": { "action": "movePane", "window": "2", "index": 3 } },
```

* Related to #1256
* Related to #5000

---------

Co-authored-by: Carlos Zamora <carlos.zamora@microsoft.com>
2023-03-30 14:37:53 +00:00
James Holderness
34aa6aa0d4 Update DECSC/DECRC to match the newer DEC terminals (#15054)
When saving and restoring the cursor position with origin mode enabled,
we originally matched the behavior of the early DEC terminals, which
stored the position as an absolute offset. But if the margin boundaries
were changed prior to restoring the position, that could result in the
cursor being outside the margins, potentially with negative coordinates.

Our implementation avoided that bug by clamping the coordinates back
into range, but that's not how DEC ultimately fixed the issue. Starting
with the VT420, they began using relative coordinates (i.e. relative to
the margin origin), so a restored position could never end up negative.
This PR updates our implementation to match that newer behavior.

## Validation Steps Performed

Thank to testing performed by @al20878, we know this was the algorithm
used on the VT420, VT520, and VT525, and I've manually confirmed that
our implementation now matches their behavior.

I've also updated the `CursorSaveRestore` unit test which previously
covered our clamping behavior - it's now being used to confirm that
we're correctly using relative offsets when restoring the cursor.

Closes #15048
2023-03-28 14:03:41 -05:00
Dustin L. Howett
c7816fdb05 Add flexible virtualization rules for HKCU\Console\Startup (#15050)
[Flexible Virtualization] is a little more restrictive than
`unvirtualizedResources`, but it's more descriptive and stands a chance
of working on Windows 10.

This makes `unvirtualizedResources` actually work for us - we can tell
the system exactly which registry keys we want to use. This is required
for our registry writes to work on Windows 10.

[Flexible Virtualization]:
https://learn.microsoft.com/en-us/windows/msix/desktop/flexible-virtualization
2023-03-28 10:23:57 -05:00
Leonard Hecker
d9efdae982 Fix font size of HTML clipboard contents (#15046)
This regression is caused by 0eff8c0. It previously said `.Y` here.
I went through the diff again and found no other width/height mistake.

Closes #14762
Closes #15043
2023-03-27 11:44:54 -05:00
Dustin L. Howett
c4d029829a Add a second way of detecting whether DefTerm is available (#15040)
This will become meaningful soon.
2023-03-24 17:21:50 -05:00
Leonard Hecker
f20cd3a9d3 Add an efficient text stream write function (#14821)
This adds PR adds a couple foundational functions and classes to make
our TextBuffer more performant and allow us to improve our Unicode
correctness in the future, by getting rid of our dependence on
`OutputCellIterator`. In the future we can then replace the simple
UTF-16 code point iterator with a proper grapheme cluster iterator.

While my focus is technically on Unicode correctness, the ~4x VT
throughput increase in OpenConsole is pretty nice too.

This PR adds:
* A new, simpler ROW iterator (unused in this PR)
* Cursor movement functions (`NavigateToPrevious`, `NavigateToNext`)
  They're based on functions that align the cursor to the start/end
  of the _current_ cell, so such functions can be added as well.
* `ReplaceText` to write a raw string of text with the possibility to
  specify a right margin.
* `CopyRangeFrom` will allow us to make reflow much faster, as it's able
  to bulk-copy already measured strings without re-measuring them.

Related to #8000

## Validation Steps Performed
* enwik8.txt, zhwik8.txt, emoji-test.txt, all work with proper
  wide glyph reflow at the end of a row 
* This produces "a 咪" where only "a" has a white background:
  ```sh
  printf '\e7こん\e8\x1b[107ma\x1b[m\n'
  ```
* This produces "abん":
  ```sh
  stdbuf -o0 printf '\x1b7こん\x1b8a'; printf 'b\n'
  ```
* This produces "xy" at the end of the line:
  ```sh
  stdbuf -o0 printf '\e[999C\bこ\bx'; printf 'y\n'
  ```
* This produces red whitespace followed by "こ " in the default
  background color at the end of the line, and "ん" on the next line:
  ```sh
  printf '\e[41m\e[K\e[m\e[999C\e[2Dこん\n'
  ```
2023-03-24 17:20:53 -05:00
Dustin L. Howett
f5e9e8ea77 Consolidate our MSIX distribution back down to one package (#15031)
We ship a separate package to Windows 10, which contains a copy of XAML
embedded in it, because of a bug in activating classes from framework
packages while we're elevated.

We did this to avoid wasting disk space on Windows 11 installs (which is
critical given that we're preinstalled in the Windows image.)

The fix for this issue was released in a servicing update in April 2022.
Thanks to KB5011831, we no longer need this workaround!

And finally, this means that we no longer need to depend on a copy of
"pre-release" XAML. We only did that because it would copy all of its
assets into our package.

Introduced in #12560
Closes #14106
Closes (discussion) #14981
Reverts #14660
2023-03-24 08:31:17 -05:00
Mike Griese
36c6b7748e Clean up more warnings (#15039)
* These `Icon` bindings were to `Profile`s which aren't Observable, but
it also doesn't matter
* More c# warnings

hopefully we'll just jump straight to real errors now.
2023-03-24 08:30:58 -05:00
Mike Griese
b34444f40a Fix wt -w _quake by not throwing when setting the window name (#15030)
If we get initialized with a window name, this will be called before
XAML is stood up, and constructing a PropertyChangedEventArgs will
throw. So don't.


Regressed in #14843 

Related to #5000, #14957
2023-03-24 08:30:37 -05:00
Dustin L. Howett
f06cd1759f VsDevCmdGenerator: respect the user's startingDirectory (#15035)
The PowerShell equivalent was added in the initial pull request, #7774.

Closes #13721
2023-03-23 18:14:48 -05:00
James Holderness
0f7d1f4568 Add support for the Presentation State reports (#14998)
This PR introduces two new sequences, `DECRQPSR` and `DECRSPS`, which
provide a way for applications to query and restore the presentation
state reports. This includes the tab stop report (`DECTABSR`) and the
cursor information report (`DECCIR`). 

One part of the cursor information report contains the character set
designations and mapped G-sets. But we weren't tracking that data in a
way that could easily be reported, so I needed to do some refactoring in
the `TerminalOutput` class to make that accessible.

Other than that, the rest was fairly straightforward. It was just a
matter of packaging up all the information into the correct format for
the returned `DCS` string, and in the case of the restore operations,
parsing the incoming data and applying the new state. 

## Validation Steps Performed

Thanks to @al20878, we were able to test these operations on a real
VT525, and I've manually verified that our implementation matches that
behavior. I've also added some unit tests covering both reports.

Closes #14984
2023-03-23 17:46:17 -05:00
James Holderness
7a2e4f8d9b Fix DECCRA when copying from a double-width line (#15026)
When a `DECCRA` operation is copying content that spans a double width
line, it's possible that some range of the bounding rectangle will be
off-screen, and that range is not supposed to be copied. However, the
code checking for off-screen positions was using incorrect coordinates,
so we would mistakenly copy content that shouldn't be copied, and drop
content that should have been copied. This PR fixes that.

## References and Relevant Issues

This was a regression introduced in PR #14650 when fixing an issue with
horizontal scrolling of DBCS characters.

## Validation Steps Performed

I manually verified this fixes the test case in #15019, and I've also
added a unit test that replicates that case.

Closes #15019
2023-03-22 12:37:08 -05:00
Alex Noble
2acdc9d7e2 Add options to enable and disable read only mode (#14995)
## Summary of the Pull Request
PR adds functionality to enable or disable readOnly mode within panes.
This functionality is different to toggling as if you call the same
functionality twice, it will not toggle between states.

## References and Relevant Issues
- Closes https://github.com/microsoft/terminal/issues/14415
- Documentation https://github.com/MicrosoftDocs/terminal/pull/645

## Validation Steps Performed
- Checked readOnly is enabled when command triggered
- Checked readOnly is enabled when command triggered while read only
already enabled
- Checked readOnly is disabled when command triggered while read only is
enabled
- Checked readOnly stays disabled when command triggered while read only
is disabled
- Checked above with multiple tabs and split panes

## PR Checklist
- [ ] Closes #14415 
- [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:
https://github.com/MicrosoftDocs/terminal/pull/645
- [X] Schema updated (if necessary)

---------

Co-authored-by: Mike Griese <migrie@microsoft.com>
2023-03-22 12:32:56 -05:00
Mike Griese
f3a722e0e9 Introduce a ContentManager helper (#14851)
## Summary

_Thus we come to the introduction of a new servant, the
`ContentManager`, a singular entity that serves at the behest of the
`emperor`. It is its charge to keep track of all `TermControl` instances
created by the windows, for each window must seek its blessing before
calling forth such an instance._
_With the aid of the `ContentManager`, the `TermControl` shall now be
traced by the hand of fate through the use of unique identifying marks,
known as `GUID`s. Yet, its purpose remains yet unknown, for it is merely
a waypoint upon the journey yet to come._
_This act of bridging also brings a change to the handling of events
within the `TermControl`. This change shall see the addition of a
revoker, similar to the manner in which the `AppHost` hath employed it,
to the `TermControl`. Additionally, there is a new layer of indirection
between the `ControlCore` and the `App` layer, making ready for the day
when the `TermControl` may be repositioned and re-parented with ease._
_Consider this but a trivial act, a mere shadow of things yet to come,
for its impact shall be felt but briefly, like the passing of a gentle
breeze._

Related to #5000
Related to #1256

# Detailed description

This PR is another small bridge PR between the big work in #14843, and
the PR that will enable panes to move between windows.

This introduces a new class, called `ContentManager`. This is a global
singleton object, owned by the emperor. Whenever a window wants to
instantiate a new `TermControl`, it must ask the ContentManager to give
it one. This allows the ContentManager to track each "content" by GUID.
That's it. We don't do anything with them in this PR by itself, we just
track them.

This also includes a small change to the way TermControl events are
handled. It adds an `AppHost`-like revoker struct, and weak_ref's all
the handlers. We also add a layer of indirection between the
ControlCore's raising of events and the App layer's handling. This will
make reparenting content easier in the future.

This is a pretty trivial change which shouldn't have any major side
effects. Consider it exposition of the things to come. It's
intentionally small to try and keep the reviews more managable.
2023-03-22 12:11:44 -05:00
Dustin L. Howett
e0046a4cca Remove useRegExe and add rescap:unvirtualizedResources (#15028)
Due to a limitation in the Windows App Installer UI, Terminal had to
shell out to `reg.exe` to write the Delegation registry keys. The team
in charge of AppInstaller lifted that (once by-policy) limitation.

Therefore, we can remove our BODGY workaround.
2023-03-21 15:18:21 -05:00
Dustin L. Howett
5a34d92cb5 winget.yml: switch to manually using wingetcreate (#15023)
It was brought to my attention that we should be more restrictive in
which tasks we ovver a GitHub token to. Sorry!

With thanks to sitiom for the version parsing and the magic GitHub
action syntax incantation for determining what is a prerelease.
2023-03-20 17:38:20 -05:00
Dustin Howett
e1079d8f55 winget: use the correct fork-user 2023-03-20 11:15:27 -05:00
Mike Griese
b9248fa903 One process to rule them all (#14843)
## Summary

_In the days of old, the windows were sundered, each with its own
process, like the scattered stars in the sky. But a new age hath dawned,
for all windows now reside within a single process, like the bright gems
of a single crown._
_And lo, there came the `WindowEmperor`, a new lord to rule over the
global state, wielding the power of hotkeys and the beacon of the
notification icon. The `WindowManager` was cast aside, no longer needed
to seek out other processes or determine the `Monarch`._
_Should the `WindowEmperor` determine that a new window shall be raised,
it shall set forth a new thread, born from the ether, to govern this new
realm. On the main thread shall reside a message loop, charged with the
weighty task of preserving the global state, guarded by hotkeys and the
beacon of the notification icon._
_Each window doth live on its own thread, each guarded by the new
`WindowThread`, a knightly champion to hold the `TerminalWindow`,
`AppHost`, and `IslandWindow` in its grasp. And so the windows shall run
free, no longer burdened by their former ways._


All windows are now in a single process, rather than in one process per
window. We'll add a new `WindowEmperor` class to manage global state
such as hotkeys and the notification icon. The `WindowManager` has been
streamlined and no longer needs to connect to other processes or
determine a new `Monarch`. Each window will run on its own thread, using
the new `WindowThread` class to encapsulate the thread and manage the
`TerminalWindow`, `AppHost`, and `IslandWindow`.


* Related to #5000
* Related to #1256

## Windows Terminal Process Model 3.0

Everything is now one process. All the windows for a single Terminal
instance live in a singular Terminal process. When a new terminal
process launches, it will still attempt to communicate with an existing
one. If it finds one, it'll pass the commandline to that process and
exit. Otherwise, it'll become the "monarch" and create a new window.

We'll introduce a new abstraction here, called the `WindowEmperor`.
`Monarch` & `Peasant` will still remain, for facilitating cross-window
communication. The Emperor will allow us to have a single dedicated
class for all global state, and will now always represent the "monarch"
(rather than our previously established non-deterministic monarchy to
elevate a random peasant to the role of monarch). We still need to do a
very minimal amount of x-proc calls. Namely, one right on startup, to
see if another `Terminal.exe` was already running. If we find one, then
we toss our commandline at it and bail. If we don't, then we need to
`CoRegister` the Monarch still, to prepare for subsequent launches to
send commands to us.

`WindowManager` takes the most changes here. It had a ton of logic to
redundantly attempt to connect to other monarchs of other processes, or
elect a new one. It doesn't need to do any of that anymore, which is a
pretty dramatic change to that class.

This creates the opportunity to move some lifetime management around.
We've played silly games in the past trying to have individual windows
determine if they're the singular monarch for global state.
`IslandWindow`s no longer need to track things like global hotkeys or
the notification icon. The emperor can do that - there's only ever one
emperor. It can also own a singular copy of the settings model, and hand
out references to each other thread.

Each window lives on separate threads. We'll need to separately
initialize XAML islands for each thread. This is totally fine, and
actually supported these days. We'll use a new class called
`WindowThread` to encapsulate one of these threads. It'll be responsible
for owning the `TerminalWindow`, `AppHost` and `IslandWindow` for a
single thread.

This introduces new classes of bugs we'll need to worry about. It's now
easier than ever to have "wrong thread" bugs when interacting with any
XAML object from another thread. A good case in point - we used to stash
a `static` `Brush` in `Pane`, for the color of the borders. We can't do
that anymore! The first window will end up stashing a brush from its
thread. So now when a second window starts, the app explodes, because
the panes of that window try to draw their borders using a brush from
the wrong thread.

_Another fun change_: The keybinding labels of the command palette.
`TerminalPage` is the thing that ends up expanding iterable `Command`s.
It does this largely with copies - it makes a new `map`, a new `vector`,
copies the `Command`s over, and does the work there before setting up
the cmdpal.
Except, it's not making a copy of the `Command`s, it's making a copy of
the `vector`, with winrt objects all pointing at the `Command` objects
that are ultimately owned by `CascadiaSettings`.
This doesn't matter if there's only one `TerminalPage` - we'll only ever
do that once. However, now there are many Pages, on different threads.
That causes one `TerminalPage` to end up expanding the subcommands of a
`Command` while another `TerminalPage` is ALSO iterating on those
subcommands.

_Emperor message window_: The Emperor will have its own HWND, that's
entirely unrelated to any terminal window. This window is a
`HWND_MESSAGE` window, which specifically cannot be visible, but is
useful for getting messages. We'll use that to handle the notification
icon and global hotkeys. This alleviates the need for the IslandWindow
to raise events for the tray icon up to the AppHost to handle them. Less
plumbing=more good.

### Class ownership diagram

_pretend that I know UML for a second_:

```mermaid
classDiagram
    direction LR
    class Monarch
    class Peasant
    class Emperor
    class WindowThread
    class AppHost

    Monarch "1" --o "*" Peasant: Tracks
    Emperor --* "1" AppLogic: 
    Monarch <..> "1" Emperor
    Peasant "1" .. "1" WindowThread
    Emperor "1" --o "*" WindowThread: Tracks
    WindowThread --* AppHost
    AppHost --* IslandWindow
    AppHost --* TerminalWindow
    TerminalWindow --* TerminalPage
```

* There's still only one `Monarch`. One for the Terminal process.
* There's still many `Peasant`s, one per window.
* The `Monarch` is no longer associated with a window. It's associated
with the `Emperor`, who maintains _all_ the Terminal windows (but is not
associated with any particular window)
* It may be relevant to note: As far as the `Remoting` dll is concerned,
it doesn't care if monarchs and peasants are associated with windows or
not. Prior to this PR, _yes_, the Monarch was in fact associated with a
specific window (which was also associated with a window). Now, the
monarch is associated with the Emperor, who isn't technically any of the
windows.
* The `Emperor` owns the `App` (and by extension, the single `AppLogic`
instance).
* Each Terminal window lives on its own thread, owed by a `WindowThread`
object.
* There's still one `AppHost`, one `IslandWindow`, one `TerminalWindow`
& `TerminalPage` per window.
* `AppLogic` hands out references to its settings to each
`TerminalWindow` as they're created.

### Isolated Mode

This was a bit of a tiny brainstorm Dustin and I discussed. This is a
new setting introduced as an escape watch from the "one process to rule
them all" model. Technically, the Terminal already did something like
this if it couldn't find a `Monarch`, though, we were never really sure
if that hit. This just adds a setting to manually enable this mode.

In isolated mode, we always instantiate a Monarch instance locally,
without attempting to use the `CoRegister`-ed one, and we _never_
register one. This prevents the Terminal from talking with other
windows.
* Global hotkeys won't work right
* Trying to run commandlines in other windows (`wt -w foo`) won't work
* Every window will be its own process again
* Tray icon behavior is left undefined for now.
* Tab tearout straight-up won't work.

### A diagram about settings

This helps explain how settings changes get propagated

```mermaid
sequenceDiagram
    participant Emperor
    participant AppLogic
    
    participant AppHost
    participant TerminalWindow
    participant TerminalPage

    Note Right of AppLogic: AL::ReloadSettings
    AppLogic ->> Emperor: raise SettingsChanged
    Note left of Emperor: E::...GlobalHotkeys
    Note left of Emperor: E::...NotificationIcon
    AppLogic ->> TerminalWindow: raise SettingsChanged<br>(to each window)
    AppLogic ->> TerminalWindow: 
    AppLogic ->> TerminalWindow: 
    Note right of TerminalWindow: TW::UpdateSettingsHandler
    Note right of TerminalWindow: TW::UpdateSettings
    TerminalWindow ->> TerminalPage: SetSettings
    TerminalWindow ->> AppHost: raise SettingsChanged
    Note right of AppHost: AH::_HandleSettingsChanged
```
2023-03-17 17:59:35 -05:00
sitiom
bee22f3ec8 Add a Winget Releaser workflow (#14965)
[The winget-releaser action] automatically generates manifests for the
[Winget Community Repository] and submits them.

I suggest adding Dependabot to keep the action up to date. There were
many cases where the action was failing due to an outdated version.

Closes #14795

[The winget-releaser action]:
https://github.com/vedantmgoyal2009/winget-releaser
[Winget Community Repository]: https://github.com/microsoft/winget-pkgs
2023-03-17 17:57:42 -05:00
Dustin L. Howett
b6bb3e0a80 Enable the Hybrid CRT for all C++ projects (#15010)
The less we need the C++ runtime, the better.

I measured this as growing our package by a fair amount...
but less than the size of XamlHost and all the forwarders combined.

Reducing our dependency surface makes us easier to deploy and more
reliable.

_as of 1.17 (2022-10)_

| **File**                | **Before** | **After** |        **Delta** |
| ----------------------- | ----------:| ---------:| ----------------:|
| `OpenConsole`           |  1,273,344 | 1,359,360 |   +86,016 (84kb) |
| `TerminalApp`           |  2,037,248 | 2,120,704 |   +83,456 (82kb) |
| `TerminalControl`       |  1,412,608 | 1,502,720 |   +90,112 (88kb) |
| `TerminalSettingsModel` |  1,510,912 | 1,621,504 | +110,592 (108kb) |
| `wt`                    |     97,280 |   122,368 |   +25,088 (25kb) |
| `WindowsTerminal`       |    508,928 |   575,488 |   +66,560 (65kb) |
| **MSIX Overall**        |  6,488,301 | 6,799,017 | +310,716 (303kb) |
2023-03-17 17:12:32 -05:00
Mike Griese
c5c15e86f3 Clearly differentiate running elevated vs. drag/drop breaking (#14946)
Credit where credit is due - @jboelter did literally all the hard work.

I just separated this out to two elements:
* Are we running elevated?
* Can we drag drop?

As we learned in #7754, the builtin administrator _can_ drag drop. But
critically, they are also running as admin! The way we had this logic
before, we're treat them as unelevated, because we had been overloading
the meaning here.

This splits these into two separate functions. Comes with the added
benefit of re-adding the elevation shield to the Terminal window for
users with UAC disabled (which was missing before) (and can _still_ be
disabled).

Closes #13928

Tested on a Win10 VM with `EnableLua=0`
2023-03-17 17:01:37 -05:00
Leonard Hecker
00af187a97 Fix console aliases not working (#14991)
#14745 contains two regressions related to console alias handling:
* When `ProcessAliases` expands the backup buffer into (an) aliased
  command(s) it changes the `_bytesRead` field of `COOKED_READ_DATA`,
  requiring us to re-read it and reconstruct the `input` string-view.
* Multiline aliases are read line-by-line whereas #14745 didn't treat
  them any different from regular single-line inputs.

## Validation Steps Performed
In `cmd.exe` run
```
doskey test=echo foo$Techo bar$Techo baz
test
```
The output should look exactly like this:
```
C:\>doskey test=echo foo$Techo bar$Techo baz

C:\>test
foo

C:\>bar

C:\>baz

C:\>
```
2023-03-17 13:43:44 -07:00
James Holderness
2810155046 Add support for querying the DECAC settings (#14990)
This PR adds support for querying the color indices set by the `DECAC`
control, using the existing `DECRQSS` implementation.

## References and Relevant Issues

The initial `DECRQSS` support was added in PR #11152.
The `DECAC` functionality was added in PR #13058, but at the time we
didn't know how to format the associated `DECRQSS` query.

## Detailed Description of the Pull Request / Additional comments

For most `DECRQSS` queries, the setting being requested is identified by
the final characters of its escape sequence. However, for the `DECAC`
settings, you also need to include a parameter value, to indicate which
color item you're querying.

This meant we needed to extend the `DECRQSS` parser, so I also took this
opportunity to ensure we correctly parsed any parameter prefix chars. We
don't yet support any setting requiring a prefix, but this makes sure we
don't respond incorrectly if an app does query such a setting.

## Validation Steps Performed

Thanks to @al20878, we've been able to test how these queries are parsed
on a real VT525 terminal, and I've manually verified our implementation
matches that behavior.

I've also extended the existing `DECRQSS` unit test to confirm that we
are responding to the `DECAC` queries as expected.

Closes #13091
2023-03-17 14:16:47 -05:00
Mike Griese
5c9f756891 Properly configure the project dependencies for TerminalAzBridge (#15008)
I don't think this is the resolution for #14581, but this can't hurt. These deps were using the wrong GUIDs
2023-03-17 13:59:35 -05:00
Mike Griese
7383b260e1 Add support for a right-click context menu (#14775)
Experimental for now. `experimental.rightClickContextMenu`, a
per-profile setting. Long term we want to enable full mouse bindings, at
which point this would be replaced.

Closes #3337

This adds **two** context menus to the `TermControl` - one for
right-clicking with a selection, and one without. The implementation is
designed to follows the API experience of the context menu on something
like a [`RichEditBox`](winui2gallery://item/RichEditBox). The hosting
application adds a handler for the menu's `Opening` event, and appends
whatever items it wants at that time.

So `TermControl` only implements a few "actions" by default - copy,
past, find. `TerminalApp` is then responsible for adding anything else
it needs. Right now, those actions are:
* Duplicate tab
* Duplicate pane
* Close Tab
* Close pane

Screenshots in
https://github.com/microsoft/terminal/pull/14775#issuecomment-1415737393
2023-03-17 13:54:10 -05:00
Mike Griese
4ca19623ca Fix some simple C# linter warnings (#15011)
Azure Devops jumps to these as the first "error" when you open a failing
build. But these are warnings, not errors. So you're left hunting for
the real error. _If only someone had scrollbar marks for indicating
lines with error messages..._

May as well clean them up.
2023-03-17 13:52:23 -05:00
Ian O'Neill
51661487c2 Reload environment variables by default; add setting to disable (#14999)
Adds a global setting `compatibility.reloadEnvironmentVariables` with a
default value of `true`. When set, during connection creation a new
environment block will be generated to ensure it has the latest
environment variables.

Closes #1125

Co-authored-by: Leonard Hecker <lhecker@microsoft.com>
2023-03-17 13:50:18 -05:00
Mike Griese
65640f6fe3 Allow wsl$ in file URIs; generally allow all URI schemes (#14993)
Does two things related to URLs emitted via OSC8. 

* Allows `wsl$` and `wsl.localhost` as the hostname in `file://` URIs
* Generally allows _all_ URIs that parse as a URI. 

The relevant security comments: https://github.com/microsoft/terminal/pull/7526#issuecomment-764160208
> this doesn't let a would-be attacker specify command-line arguments (ala "cmd.exe /s /c do_a_bad_thing") (using somebody else's reputation to cause mayhem)
> 
> `ShellExecute` de-elevates because it bounces a launch request off the shell
> 
> "Works predictably for 15% of applications" (h/t to PhMajerus' AXSH, and other on-Windows requestors) is better in so many ways than "Works for 0% of applications", in my estimation. Incremental progress 😄 while we work on features that'll make it even more broadly applicable.

Closes #10188
Closes #7562
2023-03-17 11:29:42 -07:00
Mike Griese
5b434dcda4 Split AppLogic into "App logic" and "Window logic" (#14825)
_And so begins the first chapter in the epic tale of the Terminal's tab
tear-out. This commit, though humble in its nature, shall mark the
beginning of a grand journey._
_This initial offering, though small in its scope, doth serve to divide
the code that currently resides within TerminalPage and AppLogic, moving
it unto a new entity known as TerminalWindow. In the ages to come, these
classes shall take on separate responsibilities, each with their own
purpose._
_The AppLogic shall hold sway over the entire process, shared among all
Terminal windows, while the AppHost, TerminalWindow, and TerminalPage
shall rule over each individual window._
_This pull request prepares the way for the future, moving state that
pertains to the individual windows into the TerminalWindow. This is a
task of great labor, for it requires moving much code, but the end
result shall bring greater organization to the codebase._
_And so the stage is set, for in the next pull request, the Process
Model v3 shall be revealed, unifying all Terminal windows into a single
process, a grand accomplishment indeed._

_courtesy of G.P.T. Tolkien_

<details>
<summary>Or, as I wrote it originally. </summary>

This is the first of the commits in the long saga which will culminate
in tab tear-out for the Terminal.

This the most functionally trivial of the PRs. It mostly just splits up
code that's currently in TerminalPage & AppLogic, and moves it into a
new class `TerminalWindow`. In the future, these classes will separate
responsibility as such:
* There will be one `AppLogic` per process, shared across all Terminal
windows.
* There will be one `AppHost`, `TerminalWindow`, and `TerminalPage` for
each individual window in the process.

This PR prepares for that by moving some state that's applicable to
_individual windows_ into `TerminalWindow`. This is almost exclusively a
code moving PR. There should be minimal functional changes.

</details>


In the next PR, we'll introduce the actual "Process Model v3", merging
all Terminal windows into a single terminal process.

Related to #5000. See
https://github.com/Microsoft/terminal/issues/5000#issuecomment-1407110045
for my current todo list.
Related to #1256. 

These commits are all artificially broken down pieces. Honestly, I don't
want to really merge them till they're all ready, so we know that the
work e2e. This my feigned attempt to break it into digestable PRs.

Lightly manually tested, things seem to still all work? Most of this
code was actually written in deeper branches, it was only today I
realized it all needed to come back to this branch.

* [x] The window persistence fishy-ness of the subsequent PR isn't
present here. So that's something.
* [x] Localtests still pass

### Detailed description

> Q: Does `AppLogic` not keep track of its windows?

Sure doesn't! I didn't think that was something it needed to know.

>Q: Why does `TerminalWindow` (per-window) have access to the
commandline args (per-process)

It's because it's _not_ per process. Commandline args _are_ per-window.
Consider - you launch the Terminal, then run a `wt -w -1 -- foo`. That
makes its own window. In this process, yes. But that new window has its
own commandline args, separate from the ones that started the original
process.
2023-03-17 09:17:11 -05:00
Mike Griese
8c17475a9f Rebuild the profile nav via MenuItemsSource; mitigate a crash (#14630)
Directly manipulating the `NavigationView::MenuItems` vector is bad. If
you do that, you're gonna get crashes, in WinUI code for `Measure`.
However, a WinUI PR (below) gave me an idea: Changing
`NavigationView::MenuItemsSource` will wholly invalidate the entirety of
the nav view items, and that will avoid the crash.

This code does that. It's a wee bit janky, but it works. 

Closes #13673

_might_ affect #12333, need to try and repro. 

See also:
* #9273
* #10390
* https://github.com/microsoft/microsoft-ui-xaml/issues/6302
* https://github.com/microsoft/microsoft-ui-xaml/pull/3138, which was
the fix for https://github.com/microsoft/microsoft-ui-xaml/issues/2818
2023-03-16 15:41:46 -05:00
Leonard Hecker
6c80390de7 Fix offset calculation in the outlines shader (#14971)
The `Sample` method has an offset parameter which we can use here.
The result is not identical to the old shader, as the older shader
used the height of the terminal for drawing horizontal edges and so
the result looked way fatter than it was seemingly originally intended.
On my 150% scale display I found an offset of +/- 2px to produce an
acceptable result, although in the future it might be worthwhile to
make the offset dependent on the UI scale.

Closes #14953
2023-03-16 15:21:32 -05:00
James Holderness
7562c81066 Fix audit failures in TerminalCore (#15002)
## Summary of the Pull Request

This fixes a couple of audit failures in `TerminalCore` where the
compiler was complaining about functions that should have been declared
as `noexcept`.

These failures have actually existed for a while, but you'd only see
them if you ran the audit build locally. They only recently started
showing up on the CI build server - I'm guessing because the compiler
there has now been upgraded.

## Validation Steps Performed

Compiled the audit build locally and it no longer fails.
2023-03-16 17:51:53 +01:00
James Holderness
931aa8c87e Add support for the DECRQCRA checksum report (#14989)
This PR implements the `DECRQCRA` escape sequence, which lets you
request a checksum of a portion of the screen. This is most useful in
automated testing to verify that the generated screen content is what it
was expected to be. 

For now this functionality is gated behind a feature flag which is only
enabled for dev builds.

## Detailed Description of the Pull Request / Additional comments

I've done my best to match the DEC checksum algorithm as closely as
possible, which we've determined by testing on a real VT525 terminal
(many thanks to @al20878 for that).

The checksum is an unsigned 16-bit value that starts off at zero, and
from which you then subtract the ordinal value of every character in the
selected range. It's also affected by the rendition attributes in the
selected cells.

* Bold/Intense - subtract 0x80
* Blinking - subtract 0x40
* Reverse video - subtract 0x20
* Underlined - subtract 0x10
* Invisible - subtract 0x08
* Protected - subtract 0x04
* Background color - subtract the color index
* Foreground color - subtract the color index * 0x10

I should note that our ordinal calculation only matches DEC for the
characters in the ASCII and Latin-1 range, because the original
algorithm predates Unicode. If we want to support the other character
sets correctly we'll need custom mapping tables, but I didn't think that
was essential for now.

It's also worth mentioning that we don't handle "empty" cells correctly,
but that's not the fault of the checksum calculation - it's just that
our default fill character is a space rather than a `NUL`.

## Validation Steps Performed

I've manually compared our implementation against the tests results that
@al20878 got from the VT525, and confirmed that we match as well as was
expected (i.e. taking into account the limitations mentioned above).

I've also added a few basic unit tests that verify we're generating the
expected checksums for the various renditions and color attributes.

Closes #14974
2023-03-14 11:45:45 -05:00
Ian O'Neill
eb871bf8c0 Create til::env to help with refreshing environment variables (#14839)
Adds a helper that replicates how the `RegenerateUserEnvironment()`
method in `shell32.dll` behaves.

* Raises #12516 from the dead.
* Half of #1125

Co-authored-by: Michael Niksa <miniksa@microsoft.com>
2023-03-13 18:10:38 -05:00
James Holderness
fe2220e07b Ensure that delayed EOL wrap is reset when necessary (#14936)
When a character is written in the last column of a row, the cursor
doesn't move, but instead sets a "delayed EOL wrap" flag. If another
character is then output while that flag is still set, the cursor moves
to the start of the next line, before writing to the buffer.

That flag is supposed to be reset when certain control sequences are
executed, but prior to now we haven't always handled that correctly.
With this PR, we should be resetting the flag appropriately in all the
places that it's expected to be reset.

For the most part, I'm following the DEC STD 070 reference, which lists
a bunch of operations that are intended to reset the delayed wrap flag:

`DECSTBM`, `DECSWL`, `DECDWL`, `DECDHL`, setting `DECCOLM` and `DECOM`,
resetting `DECCOLM`, `DECOM`, and `DECAWM`, `CUU`, `CUD`, `CUF`, `CUB`,
`CUP`, `HVP`, `BS`, `LF`, `VT`, `FF`, `CR`, `IND`, `RI`, `NEL`, `ECH`,
`DCH`, `ICH`, `EL`, `DECSEL`, `DL`, `IL`, `ED`, and `DECSED`.

We were already resetting the flag for any of the operations that
performed cursor movement, since that always triggers a reset for us.
However, I've now also added manual resets in those ops that weren't
moving the cursor.

Horizontal tabs are a special case, though. Technically the standard
says they should reset the flag, but most DEC terminals never followed
that rule, and most modern terminals agree that it's best for a tab to
leave the flag as it is. Our implementation now does that too.

But as mentioned above, we automatically reset the flag on any cursor
movement, so the tab operation had to be handled as a special case,
saving and restoring the flag when the cursor is updated.

Another flaw in our implementation was that we should have been saving
and restoring the flag as part of the cursor state in the `DECSC` and
`DECRC` operations. That's now been fixed in this PR too.

I should also mention there was a change I had to make to the conpty
renderer, because it was sometimes using an `EL` sequence while the
terminal was in the delayed EOL wrap state. This would reset the flag,
and break subsequent output, so I've now added a check to prevent that
from happening.

## Validation Steps Performed

I've added some unit tests that confirm the operations listed above are
now resetting the delayed EOL wrap as expected, and I've expanded the
existing `CursorSaveRestore` test to make sure the flag is being saved
and restored correctly.

I've also manually confirmed that the test case in issue #3177 now
matches XTerm's output, and I've confirmed that the results of the
wraptest script[^1] now match XTerm's results.

[^1]: https://github.com/mattiase/wraptest/

Closes #3177
2023-03-03 18:57:51 -06:00
Dustin L. Howett
3e7e8d59f2 Switch to the new Helix queues (#14933)
The old ones are pushing up daisies.
2023-03-03 15:26:39 -06:00
Leonard Hecker
599b550817 Remove TranslateUnicodeToOem and all related code (#14745)
The overarching intention of this PR is to improve our Unicode support.
Most
of our APIs still don't support anything beyond UCS-2 and DBCS
sequences.
This commit doesn't fix the UTF-16 support (by supporting surrogate
pairs),
but it does improve support for UTF-8 by allowing longer `char`
sequences.

It does so by removing `TranslateUnicodeToOem` which seems to have had
an almost
viral effect on code quality wherever it was used. It made the
assumption that
_all_ narrow glyphs encode to 1 `char` and most wide glyphs to 2
`char`s.
It also didn't bother to check whether `WideCharToMultiByte` failed or
returned
a different amount of `char`s. So up until now it was easily possible to
read
uninitialized stack memory from conhost. Any code that used this
function was
forced to do the same "measurement" of narrow/wide glyphs, because _of
course_
it didn't had any way to indicate to the caller how much memory it needs
to
store the result. Instead all callers were forced to sorta replicate how
it
worked to calculate the required storage ahead of time.
Unsurprisingly, none of the callers used the same algorithm...

Without it the code is much leaner and easier to understand now. The
best
example is `COOKED_READ_DATA::_handlePostCharInputLoop` which used to
contain 3
blocks of _almost_ identical code, but with ever so subtle differences.
After
reading the old code for hours I still don't know if they were relevant
or not.
It used to be 200 lines of code lacking any documentation and it's now
50 lines
with descriptive function names. I hope this doesn't break anything, but
to
be honest I can't imagine anyone having relied on this mess in the first
place.

I needed some helpers to handle byte slices (`std::span<char>`), which
is why
a new `til/bytes.h` header was added. Initially I wrote a `buf_writer`
class
but felt like such a wrapper around a slice/span was annoying to use.
As such I've opted for freestanding functions which take slices as
mutable
references and "advance" them (offset the start) whenever they're read
from
or written to. I'm not particularly happy with the design but they do
the job.

Related to #8000
Fixes #4551
Fixes #7589
Fixes #8663

## Validation Steps Performed
* Unit and feature tests 
* Far Manager 
* Fixes test cases in #4551, #7589 and #8663 
2023-02-28 14:55:18 -06:00
Leonard Hecker
cf87590b31 Address remaining review feedback for #14255 (#14931)
This just removes some leftover code that I forgot to remove before the merge.
Additionally I forgot to add a newly added file to our `sources` build file.
2023-02-28 19:50:13 +01:00
Leonard Hecker
814e44bf45 AtlasEngine: Fix calculation of advanceScale (#14883)
Woops. Closes #14878

## Validation Steps Performed
* Font Family: Iosevka Term (v19.0.1)
* Font Size: 11pt (or 10px cell height in conhost)
* Display Scale: 100%
* "--------------" leaves no gap between the text and the cursor 
2023-02-21 15:23:38 -06:00
Dustin L. Howett
a5fc302716 Correctness: Remove JsonUtils and IconConverter's 2-phase lookup bugs (#14870)
Our templates were declared in the wrong order in JsonUtils, so all we
needed to do was reorder them. The tests bear this out.

This allows us to disable two-phase template name lookup. I also fixed a
minor issue that resulted in the inclusion of too many copies of
expandIconPath.
2023-02-17 16:26:30 -08:00
Dustin L. Howett
2cd280eeef Move to CppWinRT 2.0.230207.1 (#14869)
Interesting things we could do after this:
- remove all `InitializeComponent` calls - they do it automatically
- have some Clang support (!)
- use `std::optional`<->`IReference` automatic binding
- use `std::format` support (!) for json/uri/hostname/http stuff/all
`IStringable`s
- potentially move to `/await:strict` for C++20 coroutines

I've also fixed up a couple ambiguities introduced by this change.
2023-02-17 16:19:47 -08:00
Dustin L. Howett
c4c046595e Fix a number of minor correctness issues that Clang flagged (#14871)
* `lld-link` is more strict about the casing of keywords in `.def` files
* `[[nodiscard]]` must come before `virtual` and `static` qualifiers
* `precomp.h` is never to be included with `<>`
* We were calling the jsoncpp constructors directly (oops) as functions
(oops)
* ClipboardTests constructed `KeyEvent`s by copy instead of directly
* While we can `await` a `Dispatcher`, it's clearer to add `resume_foreground`
2023-02-17 16:13:13 -08:00
Dustin L. Howett
e1145c362f Add a proper reference from TermCore to MidiAudio (#14868)
It was just by luck that TerminalCore usually built after MidiAudio
2023-02-17 16:12:10 -08:00
Leonard Hecker
9dcdcac0bb Ignore CHAR_INFO trailers during WriteConsoleOutput (#14840)
#13626 contains a small "regression" compared to #13321:
It now began to store trailers in the buffer wherever possible to allow
a region
of the buffer to be backed up and restored via Read/WriteConsoleOutput.
But we're unfortunately still ill-equipped to handle anything but UCS-2
via
WriteConsoleOutput, so it's best to again ignore trailers just like in
#13321.

## Validation Steps Performed
* Added unit test 
2023-02-15 17:40:24 -06:00
Leonard Hecker
6a8bba96b2 Update ControlsV2 scrollbar template (#14846)
This commit updates our scrollbar template to microsoft-ui-xaml at ceeab5f.
This incorporates the bug fix for MSFT-39442675.
2023-02-15 17:36:40 -06:00
Dustin L. Howett
c08742ff18 Consolidate NTSTATUS and remove INLINE_NSTATUS_FROM_WIN32 (#14822)
This commit makes the following project-wide changes/replacements as a
first step in cleaning up our use of `NTSTATUS`.

* Rewriting any uses of `NTSTATUS_FROM_WIN32` that were vulnerable to multiple evaluation bugs
  * This is required because the macro version of `NTSTATUS_FROM_WIN32` evaluates its argument twice
* Removing all our local redefinitions of `NTSTATUS` in favor of that of `winternl.h`
  * Because of this, we got to (had to?) remove some old transclusions from `conddkrefs.h`
* `NT_SUCCESS` (ours) -> `SUCCEEDED_NTSTATUS` (wil)
* `VERIFY_IS_TRUE(NT_SUCCESS())` (overly elaborate) -> `VERIFY_NT_SUCCESS` (WEX)
* `VERIFY_SUCCESS_NTSTATUS` (ours) -> `VERIFY_NT_SUCCESS` (WEX)
* `!SUCCEEDED_NTSTATUS` -> `FAILED_NTSTATUS`
* One bad use of S_OK as an NTSTATUS -> `STATUS_SUCCESS`
* Removing `NTSTATUS` from any projects that do not use it
2023-02-14 15:48:24 -06:00
Leonard Hecker
b6e6dd861d Implement cell size customizations (#14255)
Does what it says in the title. After this commit you can customize the height
and width of the terminal's cells. This commit supports parts of CSS'
`<length-percentage>` data type: Font-size relative sizes as multiples (`1.2`),
percentage (`120%`), or advance-width relative (`1.2ch`), as well as absolute
sizes in CSS pixels (`px`) or points (`pt`).

This PR is neither bug free in DxEngine, nor in AtlasEngine.
The former fails to implement glyph advance corrections (for instance #9381),
as well as disallowing glyphs to overlap rows. The latter has the same
overlap issue, but more severely as it tries to shrink glyphs to fit in.

Closes #3498
Closes #14068

## Validation Steps Performed
* Setting `height` to `1` creates 12pt tall rows 
* Setting `height` to `1ch` creates square cells 
* Setting `width` to `1` creates square cells 
* Setting `width` or `height` to `Npx` or `Npt` works 
* Trailing zeroes are trimmed properly during serialization 
* Patching the PR to allow >100 line heights and entering "100.123456"
  displays 6 fractional digits 
2023-02-14 22:42:14 +01:00
PankajBhojwani
e4bba3cd9a Pass the window root to the profile page views, instead of the view model (#14816)
## Summary of the Pull Request
Let the profile pages' views have access to the window root, rather than the `ProfileViewModel`. The window root is passed along when the page is navigated to.

## Validation Steps Performed
Clicking `Browse` no longer crashes.

## PR Checklist
- [x] Closes #14808
2023-02-10 17:39:08 -06:00
Dustin L. Howett
9bab7d5d80 Reformat RegistrySerialization.cpp (#14824)
We had accidentally left clang-format turned off.
2023-02-10 16:52:07 -06:00
Marcel Wagner
143127d6c4 Update tab drop behavior to select dropped tab (#14787)
Dragging and dropping tabs now selects them

Closes #12473
2023-02-07 17:45:33 -06:00
Dustin L. Howett
4903cfd484 AzureConnection: remove our dependency on cpprestsdk (#14776)
This pull request removes, in full, our dependency on cpprestsdk. This
allows us to shed 500KiB-1.2MiB from our package off the top and enables
the following future investments:

- Removal of the App CRT forwarders to save an additional ~500KiB
- Switching over to the HybridCRT and removing our dependency on _any
  CRT_.

cpprest was built on my dev box two or so years ago, and is in _utter_
violation of our compliance guidelines on SBOM et al.

In addition, this change allows us to use the proxy server configured
in Windows Settings.

I did this in four steps (represented roughly by the individual commits):

1. Switch from cpprest's http_client/json to Windows.Web.Http and
   Windows.Data.Json
2. Switch from websocketpp to winhttp.dll's WebSocket implementation¹
3. Remove all remaining utility classes
4. Purge all dependencies from all projects and scripts on cpprest.

I also took this opportunity to add a feature flag that allows Dev
builds to run AzureConnection in-process.

¹ Windows.Networking.Sockets' API is so unergonomic that it was simply
infeasible (and also _horrible_) to use it.

## Validation Steps

I've run the Azure Connection quite a bit inproc.

Closes #4575.
Might be related to #5977, #11714, and with the user agent thing maybe #14403.
2023-02-07 15:13:10 -06:00
Leonard Hecker
42e8de3b52 Replace gsl::byte/span with std (#14763)
This is a rather trivial changeset. Now that these two are present in the
`std` namespace there's no reason for us to continue using the `gsl` ones.
Additionally this ensures future compatibility with other 3rd party libraries.
2023-02-02 13:24:13 -08:00
Leonard Hecker
8100d24bd0 Minor improvements for SplitToOem (#14746)
When working on #14745 I noticed that `SplitToOem` was in a bit of a poor state
as well. Instead of simply iterating over its `deque` argument and writing the
results into a new `deque` it used `pop` to advance the head of both queues.
This isn't quite exception safe and rather bloaty. Additionally there's no need
to call `WideCharToMultiByte` twice on each character if we know that the most
verbose encoding is UTF-8 which can't be any more than 4 chars anyways.

Related to #8000.

## PR Checklist
* 2 unit tests cover this 
2023-02-02 13:14:51 -08:00
Leonard Hecker
ddc349be81 Make KeyEvent char data a little less confusing (#14747)
When working on #14745 I found `KeyEvent`s a little hard to read in the
debugger. I noticed that this is because of sign extension when converting
`char`s to `wchar_t`s in `KeyEvent::SetCharData`.
2023-02-02 13:12:38 -08:00
James Holderness
282c583731 Make all console output modes more strictly buffer state (#14735)
The original console output modes were considered attributes of the
buffer, while later additions were treated as global state, and yet both
were accessed via the same buffer-based API. This could result in the
reported modes being out of sync with the way the system was actually
behaving, and a call to `SetConsoleMode` without updating anything could
still trigger unpredictable changes in behavior.

This PR attempts to address that problem by making all modes part of the
buffer state, and giving them predictable default values.

While this won't solve all the tmux layout-breaking issues in #6987, it
does at least fix one case which was the result of an unexpected change
in the `DISABLE_NEWLINE_AUTO_RETURN` mode.

All access to the output modes is now done via the `OutputMode` field in
`SCREEN_INFORMATION`. The fields that were tracking global state in the
`Settings` class (`_fAutoReturnOnNewline` and  `_fRenderGridWorldwide`)
have now been removed.

We still have a global `_dwVirtTermLevel` field, though, but that now
serves as a default value for the `ENABLE_VIRTUAL_TERMINAL_PROCESSING`
mode when creating a new buffer. It's enabled for conpty mode, and when
the VT level in the registry is not 0. That default doesn't change.

For the VT alternate buffer, things works slightly differently, since
there is an expectation that VT modes are global. So when creating an
alt buffer, we copy the current modes from the main buffer, and when
it's closed, we copy them back again.

## Validation Steps Performed

I've manually confirmed that this fixes the problem described in issue
#14690. I've also added a basic feature test that confirms the modes are
initialized as expected when creating new buffers, and changes to the
modes in one buffer do not impact any other buffers.

Closes #14690
2023-01-27 20:38:37 +00:00
Dustin L. Howett
fc960e3327 Generalize OpenConsoleProxy's HybridCRT logic (#14733)
This pull request moves the Hybrid CRT logic out of the Host.Proxy
project and makes it available for all other projects in our solution.
2023-01-27 19:17:30 +00:00
Dustin L. Howett
6a610334af When generating a stacked changelog, note which branch/es contain a commit (#14728)
New-TerminalStackedChangelog used to generate logs that looked like this:

```
* [3] A commit that was seen 3 times
* A commit that was only seen once
* [2] Some other commit
```

Now it will generate logs that look like this:

```
   / base..branch-1
   |/ base..branch-2
   ||/ base..branch-3
* [XXX] A commit that was seen 3 times
* [ X ] A commit that was only seen once
* [XX ] Some other commit
```

This format is more expressive, as it indicates _which branches_ contain which commits.

As a reminder, my release note writing style starts with a stacked changelog. It's how I tell (1) which commits are in the new preview release only, (2) which commits are in the new preview and the new stable release and (3) which commits were already released in a previous stable release.

Changes from 1 get included in the new changelog, changes from 2 get included in both and changes from 3 get deleted because they have already been released.
2023-01-25 10:52:11 -08:00
Dustin Howett
7d0baa7946 Revert "Manually set the automation name of the default color scheme for screen reader (#14704)"
This reverts commit 47f38e31a1.
2023-01-23 19:01:49 -06:00
Carlos Zamora
a0e830cc1a [UIA] Dispatch a TextChanged event on new output (#14723)
For some reason, Windows Terminal stops dispatching UIA TextChanged events sometimes. There isn't a reliable repro for this bug.

However, under NVDA's logger, it appears that when the bug does occur, we still dispatch UIA notifications (which may be ignored by NVDA in some configurations). A "quick fix" here is to dispatch a TextChanged event if we're going to dispatch a notification. Since we're just enabling a flag, we won't send two events at once.

Closes #10911
2023-01-23 21:53:09 +00:00
Mike Griese
a4cf4e2761 Resize our ContentDialog's when the window resizes (#14722)
Major thanks to @dongle-the-gadget in https://github.com/microsoft/microsoft-ui-xaml/issues/3577#issuecomment-1399250405 for coming up with this workaround.

This PR will manually forward a `WM_SIZE` message to our `CoreWindow`, to trigger the `ContentDialog` to resize itself. 

We always closed these issues as dupes of the upstream one, so this doesn't actually close anything.
HOWEVER, these are the following issues that reported this bug:
- #2380
- #4463
- #5252
- #5810
- #6181
- #7113
- #7225
- #8245
- #8496
- #8643
- #9336
- #9563
- #5808
- #10351
- #10634
- #10995
- #11770
- #13796
2023-01-23 12:42:27 -06:00
Carlos Zamora
3dd40791c9 Ensure TermControl is not closing when firing UIA events (#14714)
The `SignalTextChanged` crash seems to be occurring due to the `TermControlAutomationPeer` being destructed by the time the UIA event is actually dispatched. Even though we're already checking if TCAP and TermControl still exist, it could be that the TermControl is being closed as text is being output.

The proposed fix here is to record when the closing process starts and exposing that information directly to the TCAP. If TCAP sees that we're in the process of closing, don't bother sending a UIA event.


Closes #13978
2023-01-21 15:48:33 +00:00
Dustin Howett
8f1960d0b4 version: bump to 1.18 on main 2023-01-20 15:24:08 -06:00
Dustin L. Howett
72be9a95af Code sign the contents of the Terminal package (#14710)
Up until now, we have been relying on the catalog signature produced for our MSIX package.
There are some things (Packaged COM, Process Explorer as of 2022) that cannot handle catalog-signed
files. It's easier and safer for us to simply sign all the executables we produce before packaging them.

Unfortunately, we can't do it before we package them. We have to unpack and re-pack our package.

In the future, this will allow us to provide a codesigned distribution that is not in an MSIX package.

TEST=Ran a build and checked out the contents of the package. They were all signed!

Closes #13294
Closes #12695
Closes #9670
2023-01-20 11:47:18 -06:00
Mike Griese
596d0c5155 Update the titlebar visibility when we gain/lose focus too (#14708)
We forgot to updateTheme again when we change the titlebar color. That would result in us setting the titlebar visibility only when the settings were reloaded, but if the unfocused BG was opaque, and the focused was transparent, we'd use the current _unfocused_ color to set the titlebar visibility. 

Also, this fixes a bug with `tabRow.BG: terminalBackground`

from teams for brevity 

> tabRow.BG = terminalBackground might not work, and here's why
>
> the termcontrol's BG brush might be (r,g,b, 255), with an Opacity of 0
> 
> so my "use mica when the brush's A is <1.0" doesn't work
> 

closes #14563
2023-01-20 01:38:34 +00:00
Mike Griese
79eb9b3d3c Use a dark titlebar when we've requested dark theme (#14536)
This applies to `"showTabsInTitlebar": false,`. We literally never set that for the `IslandWindow` before, only ever the NCIW. 

Closes #11589


![update-titlebar-for-theme](https://user-images.githubusercontent.com/18356694/207109370-a63a8b19-4c42-4b1f-8d39-8c3abdf1b403.gif)


For a dramatic example - here's the IW with mica enabled, in dark mode:

![image](https://user-images.githubusercontent.com/18356694/207109465-a6165637-31a5-45a4-bff0-51ac79404cd6.png)

Theme json:

```json
        {
            "name": "chonk",
            "tab":
            {
                "background": "#00000000",
                "unfocusedBackground": "#00000000",
                "showCloseButton": "never"
            },
            "tabRow":
            {
                "background": "#00000000",
                "unfocusedBackground": "#00000000",
            },
            "window":
            {
                "applicationTheme": "dark",
                "useMica": true
            }
        },
```
2023-01-19 23:51:21 +00:00
Joshua Boelter
eab1c239a9 Launch elevated instances via shell:AppFolder (#14637)
This uses `shell:AppsFolder` to launch elevated instances of the app via
`ShellExecuteEx` and `runas` in elevate-shim.exe. The app to launch is
discovered via the `GetCurrentApplicationUserModelId` API.

e.g. `shell:AppsFolder\WindowsTerminalDev_8wekyb3d8bbwe!App`

This will fallback to launching `WindowsTerminal.exe` if it fails to
discover the app user model id to launch.

This also fixes a bug in elevate-shim where the first argument of
WinMain was lost (e.g. `new-tab`). 

Curiously, `AppLogic::RunAsUwp()` is never called and
`AppLogic::IsUwp()` is always false when running debug builds locally
(e.g. WindowsTerminalDev). It's not clear if this is an artifact of
development packages or something else.

## Validation Steps Performed

Various manual debug/execution scenarios.

Verified the fallback path by running the unbundled app by extracting
the `CascadiaPackage_0.0.1.0_x64.msix` from the 'drop' build artifact.

Fixes #14501
2023-01-19 23:40:53 +00:00
PankajBhojwani
96a9dd5209 Automatically focus the ColorSchemeListView when we navigate to the ColorSchemes page (#14631)
This regressed when we implemented ColorSchemeViewModel in #13179.
This commit fixes that by automatically focusing the ColorSchemeListView
when we navigate to the ColorSchemes page, which makes sense from a
user experience perspective anyway.

Closes #11971
2023-01-19 23:20:56 +00:00
PankajBhojwani
6278a2d9bf Fix the selected color scheme list item container background being blue in Windows 10 (#14706)
Specify the resource to use for the list view item background when selected.

References #14693 

## Validation Steps Performed
Background is no longer blue, it is light gray (like in Windows 11). Screenshots below.
2023-01-19 22:04:28 +00:00
PankajBhojwani
16fe2e5905 Add color chips to the color scheme dropdown in Appearance (#14587)
Does what it says on the tin.
2023-01-19 21:46:59 +00:00
Mike Griese
f2b82cd054 Only use Mica in the SUI if Mica is available (#14675)
This should make sure we only use Mica for the BG of the SUI when we're on a Windows build that supports it. Otherwise, we're just gonna get the emergency backstop / full transparency under it. 

Confirmed this fixes it on my win10 VM.

Closes #14667
2023-01-19 21:06:49 +00:00
James Holderness
7813953b23 Add support for IRM (Insert Replace Mode) (#14700)
This PR add support for the ANSI Insert/Replace mode (`IRM`), which
determines whether output characters are inserted at the active cursor
position, moving existing content to the right, or whether they should
overwrite the content that is already there.

The implementation is a bit of a hack. When that mode is enabled, it
first measures how many cells the string is expected to occupy, then
scrolls the target line right by that amount before writing out the new
text.

In the longer term it might be better if this was implemented entirely
in the `TextBuffer` itself, so the scrolling could take place at the
same time as the content was being written.

## Validation Steps Performed

I've added a very basic unit test that verifies the mode is working as
expected. But I've also done a lot more manual testing, confirming edge
cases like wide characters, double-width lines, and both with and
without wrapping mode enabled.

Closes #1947
2023-01-19 19:59:05 +00:00
PankajBhojwani
47f38e31a1 Manually set the automation name of the default color scheme for screen reader (#14704)
## Summary of the Pull Request
When we navigate to the color schemes page, find the default color scheme (if present) and manually set the container's automation name to include the word 'default'. 

Note that we don't want to change the actual `ColorSchemeViewModel`'s name since that name is used internally to identify schemes. We only want to change the `ListViewItem`'s name, i.e. the container in the SUI.

## PR Checklist
* [x] Closes #14401 
* [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

## Validation Steps Performed
Screen reader reads out the 'default' text now. It also correctly reads out the new default scheme if the default scheme is changed via SUI or json.
2023-01-19 19:39:08 +00:00
Mike Griese
0fe0868f98 Remove the win10/win11 digit from our version number. (#14660)
As of about 2022, the one's digit of the Build of our version is a placeholder value to differentiate the Windows 10 build from the Windows 11 build. Let's trim that out, it's only a source of confusion.

For additional clarity, let's omit the Revision, which _must_ be `.0`, and doesn't provide any value to report.

We will need to make sure we report releases as `1.17.ABC` now, instead of `1.17.ABC1.0`/`1.17.ABC2.0`

Let's not backport this. 1.17 will be the start of the new numbering scheme. Otherwise, `1.16.EFG` < `1.16.ABC1.0`, for an old version `ABC1` and a new version `EFG`.

* closes #14106
* As summarized here: https://github.com/microsoft/terminal/issues/14106#issuecomment-1289462310
2023-01-19 19:32:23 +00:00
Dustin L. Howett
179bb9bded Add TerminalStress, Mike Treit's application for breaking WT (#14701)
From Treit/TerminalStress@39c03e2d00

Co-authored-by: Dustin L. Howett <duhowett@microsoft.com>
Co-authored-by: Mike Treit <mtreit@ntdev.microsoft.com>
2023-01-19 13:20:43 -06:00
Mike Griese
90485e4c79 Fix a crash on startup with a folder entry without entries (#14629)
`_Entries` was getting default constructed to `nullptr`. We should be careful about that. 

Adds a test too, and fixes a regression in the local tests introduced in #13763.

Closes #14557
2023-01-19 19:12:40 +00:00
Dustin L. Howett
29ef49252b Make the PR template less unfriendly (#14697)
Dunno how to feel about this. I want to guide people, but i don't want HTML comments in my `git log`
2023-01-19 11:39:04 +00:00
PankajBhojwani
5614116c6e Update Profile and Appearance VMs to use CSVM; remove nav state (#14572)
ColorScheme MVVM was implemented in #13179. This PR updates the
ProfileViewModel/AppearanceViewModels to use color scheme view models
instead of the raw settings model objects.

* [x] Updates ProfileViewModel/AppearanceViewModel to use
  ColorSchemesPageViewModel/ColorSchemeViewModel implemented in #13179
* [x] Removes ProfilePageNavigationState

## Validation Steps Performed
Settings UI still works (we _probably_ want to bug bash this at some
point though as with all SUI changes)
2023-01-18 15:30:00 -06:00
James Holderness
a1865b9cf7 Merge the PrintString functionality into AdaptDispatch (#14640)
The main purpose of this PR was to merge the `ITerminalApi::PrintString`
implementations into a shared method in `AdaptDispatch`, and avoid the
VT code path depending on `WriteCharsLegacy`. But this refactoring has
also fixed some bugs that existed in the original implementations. 

This helps to close the gap between the Conhost and Terminal (#13408).

I started by taking the `WriteCharsLegacy` implementation, and stripping
out everything that didn't apply to the VT code path. What was left was
a fairly simple loop with the following steps:

1. Check if _delayed wrap_ is set, and if so, move to the next line.
2. Write out as much of the string as will fit on the current line.
3. If we reach the end of the line, set the _delayed wrap_ flag again.
4. Repeat the loop until the entire string has been output.

But step 2 was a little more complicated than necessary because of its
legacy history. It was copying the string into a temporary buffer,
manually estimated how much of it would fit, and then passing on that
partial buffer to the `TextBuffer::Write` method.

In the new implementation, we just pass the entire string directly to
`TextBuffer::WriteLine`, and that handles the clipping itself. The
returned `OutputCellIterator` tells us how much of the string is left.
This approach fixes some issues with wide characters, and should also
cope better with future buffer enhancements.

Another improvement from the new implementation is that the Terminal now
handles delayed EOL wrap correctly. However, the downside of this is
that it introduced a cursor-dropping bug that previously only affected
conhost. I hadn't originally intended to fix that, but it became more of
an issue now.

The root cause was the fact that we called `cursor.StartDeferDrawing()`
before outputting the text, and this was something I had adopted in the
new implementation as well. But I've now removed that, and instead just
call `cursor.SetIsOn(false)`. This seems to avoid the cursor droppings,
and hopefully still has similar performance benefits.

The other thing worth mentioning is that I've eliminated some special
casing handling for the `ENABLE_VIRTUAL_TERMINAL_PROCESSING` mode and
the `WC_DELAY_EOL_WRAP` flag in the `WriteCharsLegacy` function. They
were only used for VT output, so aren't needed here anymore.

## Validation Steps Performed

I've just been testing manually, writing out sample text both in ASCII
and with wide Unicode chars. I've made sure it wraps correctly when
exceeding the available space, but doesn't wrap when stopped at the last
column, and with `DECAWM` disabled, it doesn't wrap at all.

I've also confirmed that the test case from issue #12739 is now working
correctly, and the cursor no longer disappears in Windows Terminal when
writing to the last column (i.e. the delayed EOL wrap is working).

Closes #780
Closes #6162
Closes #6555
Closes #12440
Closes #12739
2023-01-18 20:26:04 +00:00
Mike Griese
c79298d3fd Use ThemeLookup for the SUI bg too (#14644)
I can't exactly repro #14559. I suspect that's due to #14567 having been merged. This, however, seemed related. Without this, we'll use the App's `RequestedTheme` (the one that can't be changed at runtime), rather than the user's `requestedTheme`. That will do weird things, like make the BG of the SUI dark, with white expanders.

I think this should close #14559.
2023-01-18 18:31:21 +00:00
Carlos Zamora
8e041692b3 Add mutex to keyEvents in TermControlAutomationPeer (#14694)
Some investigation revealed that `_keyEvents` would get a `NULL_POINTER_READ` error. On the main thread, `RecordKeyEvent()` would be called, which mainly updates `_keyEvents`. On the renderer thread, `NotifyNewOutput()` would be called, which starts by iterating through `_keyEvents` and slowly clearing it out. On occasion, these two threads are modifying `_keyEvents` simultaneously, causing a crash.

The fix is to add a mutex on this variable. 

Closes #14592
2023-01-18 07:28:06 +00:00
Mike Griese
4c7879bfb5 Make sure focused tab text color accounts for alpha (#14643)
Basically what it says on the tin. For transparent tabs, we should layer on to the tab row to evaluate what the actual color of the tab will be. We did this for deselected tabs, but not for selected ones.

Gif below.

Closes #14561
2023-01-16 20:04:30 +00:00
Ian O'Neill
f3439e201e Ensure export and find tab context menu items work for unfocused tabs (#14673)
## Summary of the Pull Request
Updates the tab event handling so that the "Export Text" and "Find" tab context menu items work when a tab isn't focused.

## PR Checklist
* [x] Closes #13948
* [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.
2023-01-16 18:18:06 +00:00
musvaage
d3264964a9 Fix some additional typos (#14671)
Fix spelling errors in code comments and markdown
Closes #14670
2023-01-16 16:17:54 +00:00
Mike Griese
dd2736f334 Make sure to update the selection pivot while circling (#14636)
This builds upon #10749. When we added a separate pivot to track the "active" anchor, we forgot to update the pivot while circling. What does that mean? Moving the mouse would trigger us to update the selection using new endpoint and the old _pivot_, which hadn't been updated. 

There's probably a more elegant way of doing this, but it's good enough. 

Updated the test to cover this as well. 

Closes #14462
2023-01-16 16:13:20 +00:00
Mike Griese
020746d93d Update the Theme schema for 1.17 (#14666)
What it says on the tin. 

I finally figured out the right way to validate schema updates in VsCode, which made this a lot faster. Tossed notes in the wiki for next time I do this. 

Closes #14560
2023-01-13 16:40:09 -08:00
Carlos Zamora
dc6d82e9bc [WPF] Add TermCore null checks to HwndTerminal (#14678)
#14461 is caused by a null pointer exception in `TerminalIsSelectionActive()`. Since this reveals that it is possible to enter a state where `_terminal` is null, I've gone ahead and added null-checks throughout the code to make it more stable.

Closes #14461

## Validation Steps Performed
Ran locally. Still works.
2023-01-13 23:03:14 +00:00
Dustin L. Howett
239b4d16b9 Fix an issue where JsonUtils produces a bad error message (#14668)
CascadiaSettings relies on getting a JsonUtils::DeserializationException
from the various JSON Utility functions, and then formatting that into
an error message. Well, DeserializationException tries to include an
object representation in its what() message . . . and generates an
exception trying to do so. CascadiaSettings never gets the
DeserializationException, and displays a weird message.

It's safe to remove the stringification in DeserializationException
because CascadiaSettings was never using it (_and_ because
CascadiaSettings was using an even better version of the same logic.)

Fixes #14373
2023-01-13 00:43:24 +00:00
James Holderness
fb485a2b40 Prevent horizontally scrolling wide chars erasing themselves (#14650)
When the buffer contains wide characters that occupy more than one cell,
and those cells are scrolled horizontally by exactly one column, that
operation can result in the wide characters being completely erased.
This PR attempts to fix that bug, although it's not an ideal long term
solution.

Although not really to blame, it was PR #13626 that exposed this issue.

The root of the problem is that scrolling operations copy cells one by
one, but wide characters are written to the buffer two cells at a time.
So when you move a wide character one position to the left or right, it
can overwrite itself before it's finished copying, and the end result is
the whole character gets erased.

I've attempt to solve this by getting the affected operations to read
two cells in advance before they start writing, so there's no risk of
losing the source data before it's fully output. This may not work in
the long term, with characters wider than two cells, but it should at
least be good enough for now.

I've also changed the `TextBuffer::Write` call to a `WriteLine` call to
improve the handling of a wide character on the end of the line, where
moving it right by one column would place it half off screen. It should
just be dropped, but with the `Write` method, it would end up pushed
onto the following line.

## Validation Steps Performed

I've manually confirmed this fixes all the test cases described in
#14626, and also added some unit tests that replicate those scenarios.

Closes #14626
2023-01-13 00:10:22 +00:00
Mike Griese
45a36cf83a Enable switching app theme based off of OS theme (#14497)
This is basically just like #14064, but with the `theme` instead.

If you define a pair of `theme` names:

```json
    "theme": { "dark": "light", "light": "dark" },
```

then the Terminal will use the one relevant for the current OS theme. This cooperates with #14064, who sets the `scheme` based on the app's theme. 

This was spec'd as a part of #3327 / #12530, but never promoted to its own issue. 
Gif below.
2023-01-12 15:43:40 +00:00
Carlos Zamora
09273be1c8 Introduce PseudoConsoleWindow a11y provider (#14541)
In order to modify the accessibility information for the PseudoConsoleWindow, it needs to have a UIA provider registered. This PR introduces `PseudoConsoleWindowAccessibilityProvider` and registers it as a UIA provider appropriately. The registration process is based on that of the `WindowUiaProvider` for ConHost.

Closes #14385

## Validation Steps Performed
Run Accessibility Insights FastPass on the window. The PseudoConsoleWindow no longer is tagged as missing a name.
2023-01-12 00:05:55 +00:00
James Holderness
f1090a07f5 Correct the cursor invalidation region (#14661)
Depending on the line rendition, and whether the cursor is over a wide
character or not, it's possible for the width to take up anywhere from 1
to 4 cells. And when it's more than 1 cell wide, part of the cursor may
end up off screen. However, our bounds check requires the entire cursor
to be on screen, otherwise it doesn't render anything, and that can
result in cursor droppings being left behind. This PR fixes that.

The bounds check that is causing this issue was introduced in #13001 to
fix a debug assertion.

To fix this, I've removed the bounds checking, and instead clip the
cursor rect to the boundaries of the viewport. This is what the original
code was trying to do prior to the #13001 fix, but was mistakenly using
the `Viewport:Clamp` method, instead of `TrimToViewport`. Since this
implementation doesn't require a clamp, there should be no risk of the
debug assertion returning.

## Validation Steps Performed

I've confirmed that the test case in #14657 is now working correctly,
and not leaving cursor droppings behind. I've also tested under conhost
with buffer sizes wider than the viewport, and confirmed it can handle a
wide cursor partially scrolled off screen.

Closes #14657
2023-01-11 21:01:34 +00:00
Jie 'Jason' Liu
b7e537e5e7 Fix missing paths when items dropped from archive (#14648)
Grab all paths from `DROPFILES` struct provided in drag event data

`GetStorageItemsAsync()` only giving up to 16 items when items are dropped from any archives
- When this occurs, we should look into `FileDrop` key for a stream of the [`DROPFILES struct`](https://learn.microsoft.com/en-us/windows/win32/shell/clipboard#cf_hdrop)
- This struct contains a null-character delimited string of paths which we can just read out

## Validation Steps Performed
* [X] Unit tests pass locally
* [X] Drag and drop paths work for both archives and non-archives files, folders, shortcuts, etc.

Closes #14628
2023-01-11 00:40:22 +00:00
Joshua Boelter
7b9ec0ed6a Check for null lParam in WM_SETTINGSCHANGE (#14653)
Fix access violation on lParam when constructing wstring.

Per the [WM_SETTINGSCHANGE docs], NULL is a valid value for lParam. A
null lParam was observed when using the 'Switch User' feature of Windows
while developing the Terminal app.

## Validation Steps Performed
Reproduced the scenario w/ the check in place and verified no crash.

Closes #14652

[WM_SETTINGSCHANGE docs]: https://learn.microsoft.com/en-us/windows/win32/winmsg/wm-settingchange
2023-01-10 00:01:58 +00:00
grammar-police
06baead9ea Minor grammar fix (#14614)
`s/it's/its/`

Note that I didn't touch the several errors in the doc and doc/spec directories, since those seem to be dated and signed email excerpts, and I don't want to violate authorial integrity. Let me know if you would like me to fix those as well.

## References
p 57.  Murray, L.  (1824).  English grammar.  Philadelphia :  E. T. Scott.

I skimmed several hundred usages of the word "it's" in the code. This actually wasn't as tiresome as it sounds, since many of the code comments in this repo are entertaining and educational &mdash; the adjectives do not _necessarily_ apply in that order, but do _possibly_ apply in that order.
2023-01-09 19:25:03 +00:00
Mike Griese
21a62c5fef Change "easy starter" -> "good first issue"
I changed that label months ago, but forgot about this doc
2023-01-05 13:30:24 -06:00
Vamsi Krishna Kanjeevaram
2d66dc44f5 Duplicated tabs open next to the current tab (#14521)
<!-- 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
Added an additional optional parameter that indicates the position of the new tab being created.

https://user-images.githubusercontent.com/17508246/206831900-d8349fb6-4241-4c37-8dd8-e1645ba94c90.mp4

https://user-images.githubusercontent.com/17508246/206831949-02e4156e-f471-4d2f-b54b-3b0d294c62fe.mp4


<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes #14313 
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [x] Tests added/passed

<!-- 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
An optional parameter is added to TerminalPage::_CreateNewTabPane() and TerminalPage::_InitializeTab() which indicates the insert position of the duplicated tab.
During a new tab creation (not duplicate), this optional parameter has a default value(-1) and the new tab is inserted at the end.
The duplicated tab is inserted next to the original one even if it is not focused.

<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Created different tabs and duplicated them.
Duplicated tabs that are focused and not focused.
2023-01-04 14:16:31 +00:00
Alex
547349af77 GitHub Workflows security hardening (#14513)
This PR adds explicit [permissions section] to workflows. This is a
security best practice because by default workflows run with [extended
set of permissions] (except from `on: pull_request` [from external
forks]). By specifying any permission explicitly all others are set to
none. By using the principle of least privilege the damage a compromised
workflow can do (because of an [injection] or compromised third party
tool or action) is restricted.

It is recommended to have [most strict permissions on the top level] and
grant write permissions on [job level] case by case.

[permissions section]: https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions
[extended set of permissions]: https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token
[from external forks]: https://securitylab.github.com/research/github-actions-preventing-pwn-requests/
[injection]: https://securitylab.github.com/research/github-actions-untrusted-input/
[most strict permissions on the top level]: https://github.com/ossf/scorecard/blob/main/docs/checks.md#token-permissions
[job level]: https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs
2022-12-19 12:07:25 -08:00
Carlos Zamora
7ab0e982c7 Replace UIA CompareInBounds with til::point comparators (#14551)
This PR replaces the uses of `Viewport::CompareInBounds()` in the UIA code with `til::point` comparators. Additionally, it simplifies the logic further by using `std::max` and `std::min`.

In doing so, we are no longer hitting the `assert` in `CompareInBounds()`.


Closes #14542
2022-12-19 18:09:42 +00:00
Leonard Hecker
165d3edde9 Add support for start /B and FreeConsole (#14544)
2 new ConPTY APIs were added as part of this commit:
* `ClosePseudoConsoleTimeout`
  Complements `ClosePseudoConsole`, allowing users to override the `INFINITE`
  wait for OpenConsole to exit with any arbitrary timeout, including 0.
* `ConptyReleasePseudoConsole`
  This releases the `\Reference` handle held by the `HPCON`. While it makes
  launching further PTY clients via `PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE`
  impossible, it does allow conhost/OpenConsole to exit naturally once all
  console clients have disconnected. This makes it unnecessary to having to
  monitor the exit of the spawned shell/application, just to then call
  `ClosePseudoConsole`, while carefully continuing to read from the output
  pipe. Instead users can now just read from the output pipe until it is
  closed, knowing for sure that no more data will come or clients connect.
  This is especially useful in combination with `ClosePseudoConsoleTimeout`
  and a timeout of 0, to allow conhost/OpenConsole to exit asynchronously.

These new APIs are used to fix an array of bugs around Windows Terminal exiting
either too early or too late. They also make usage of the ConPTY API simpler in
most situations (when spawning a single application and waiting for it to exit).

Depends on #13882, #14041, #14160, #14282

Closes #4564
Closes #14416
Closes MSFT-42244182

## Validation Steps Performed
* Calling `FreeConsole` in a handoff'd application closes the tab 
* Create a .bat file containing only `start /B cmd.exe`.
  If WT stable is the default terminal the tab closes instantly 
  With these changes included the tab stays open with a cmd.exe prompt 
* New ConPTY tests 
2022-12-16 22:06:30 +00:00
Carlos Zamora
a3c7bc3349 [SUI] Polish Launch Parameters setting controls (#14569)
## Summary of the Pull Request
Performs some cleanup in the Settings UI for the Launch Parameters settings:
1. Updates all `NumberBox` controls in the Settings UI to have a `Compact` `SpinButtonPlacementMode` instead of an inline one. This alleviates the XAML bug where the spin button would appear over the number box's input value.
2. Fixes an issue where a long X/Y value would resize the settings controls weirdly. This was fixed by introducing a `Grid` inside the main grid and applying a width to the number boxes.
3. Rename "Use system default" checkbox to be more clear. Propagate the new localized string into expander preview.


Closes #14558
2022-12-16 21:00:30 +00:00
Mike Griese
772ed3a7b7 Use mica in the SUI if mica is enabled in the theme (#14567)
Does what it says on the tin!
2022-12-16 17:36:08 +00:00
Carlos Zamora
dbc27ab041 Match 'add appearance' button text to AutoProp.Name (#14564)
Similar to #14519.

Voice Access allows for functionality like "click <name>" to automatically move the cursor and click on a control. The Search Box had an AutoProp.Name that didn't match the button text, leading to confusion because Voice Access wouldn't be able to find a control named "Create".

To fix this, we simply aligned the button text and the AutoProp.Name.

Closes #13808
2022-12-15 23:50:34 +00:00
PankajBhojwani
286fdfea79 Fix use of tabs instead of spaces in ColorSchemesPageViewModel.idl (#14550)
Didn't know the code formatter won't hit `idl` files
2022-12-13 23:39:53 +00:00
PankajBhojwani
decbc0f5a4 Improve the color schemes page in the SUI (#14470)
## Summary of the Pull Request

- [x] Clicking a color scheme in the list view immediately takes you to the page to edit the scheme
- [x] Adding a new scheme immediately takes you to the page to edit the new scheme
- [x] 'delete' and 'set as default' buttons have been moved to the edit scheme page

## PR Checklist
* [x] Closes #14289 
* [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'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
The schemes page still works, keyboard navigation also works
2022-12-13 21:57:16 +00:00
Carlos Zamora
f9a36f1ff7 Match SearchBox AutoProp.Name to placeholder text (#14519)
Voice Access allows for functionality like "click \<name\>" to automatically move the cursor and click on a control. The Search Box had an AutoProp.Name that didn't match the placeholder text, leading to confusion because Voice Access wouldn't be able to find a control named "Find...".

To fix this, we simply aligned the placeholder text and the AutoProp.Name to be "Find". The elipses were removed because no dialog is opened.

The fix was accomplished in two ways to ensure that this is backportable:
1. via code, directly set the AutoProp.Name to match the placeholder text. 
2. in the resources file, explicitly match the AutoProp.Name to the placeholder text. This allows this change to be backportable in the event that the code above wasn't backported.

Closes #14398
2022-12-13 21:40:08 +00:00
Ian O'Neill
6a763bcd41 Ensure X/Y controls are updated when default launch pos selected (#14522)
Ensures the X & Y XAML controls are updated when the default launch position checkbox is toggled.
References #14518
2022-12-13 19:00:37 +00:00
Mike Griese
69728632eb Fix a crash when the theme doesn't have a window (#14540)
From team sync today.
2022-12-13 18:50:31 +00:00
Mike Griese
3a122bf420 DRAFT Spec for Broadcast Input (#9365)
### ⇒ [doc link](https://github.com/microsoft/terminal/blob/dev/migrie/s/2634-broadcast-input/doc/specs/drafts/%232634%20-%20Broadcast%20Input/%232634%20-%20Broadcast%20Input.md) ⇐

## Summary of the Pull Request

This is supposed to be a quick and dirty spec to socialize the various different options for Broadcast Input mode with the team. Hopefully we can come up with a big-picture design for the feature, so we can unblock #9222. 

### Abstract

> With a viable prototype in #9222, it's important that we have a well-defined
> plan for how we want this feature to be exposed before merging that PR. This
> spec is intended to be a lighter-than-usual spec to build consensus on the
> design of how the actions should be expressed.

...

> _**Fortunately**_: All these proposals actually use the same set of actions. So
> it doesn't _really_ matter which we pick right now. We can unblock #9222 as
> the implementation of the `"tab"` scope, and address other scopes in the future.
> We should still decide long-term which of these we'd like, but the actions seem
> universal.


## PR Checklist
* [x] Specs: #2634
* [x] References: #9222, #4998
* [x] I work here

## Detailed Description of the Pull Request / Additional comments
_\*<sup>\*</sup><sub>\*</sub> read the spec  <sub>\*</sub><sup>\*</sup>\*_
2022-12-13 10:40:40 -08:00
Carlos Zamora
28d28cb469 Introduce WT A11y Proposal 2023 (#14319)
The release of Windows Terminal has served as a way to reinvigorate the command-line ecosystem on Windows by providing a modern experience that is consistently updated. This experience has caused faster innovation in the Windows command-line ecosystem that can be seen across various areas like expanded virtual terminal sequence support and enhanced accessibility. Command-line apps can now leverage these innovations to create a better experience for the end-user.

Since accessibility is a very broad area, this document is intended to present recent innovations in the accessibility space for the command-line ecosystem. Furthermore, it will propose additional improvements that can be made alongside key stakeholders that could benefit from such changes.
2022-12-13 10:22:29 -08:00
Mike Griese
274bbf0e44 DRAFT Spec for Buffer Exporting and Logging (#11090)
### ⇒ [doc link](https://github.com/microsoft/terminal/blob/dev/migrie%2Fs%2F642-logging/doc/specs/drafts/%23642%20-%20Buffer%20Exporting%20and%20Logging/%23642%20-%20Buffer%20Exporting%20and%20Logging.md) ⇐

## Summary of the Pull Request

This is an intentionally brief spec to address the full scope of #642. The
intention of this spec is to quickly build consensus around all the features we
want for logging, and prepare an implementation plan.

### Abstract

> A common user need is the ability to export the history of a terminal session to
> a file, for later inspection or validation. This is something that could be
> triggered manually. Many terminal emulators provide the ability to automatically
> log the output of a session to a file, so the history is always captured. This
> spec will address improvements to the Windows Terminal to enable these kinds of
> exporting and logging scenarios.

## PR Checklist
* [x] Specs: #642
* [x] References: #5000, #9287, #11045, #11062
* [x] I work here

## Detailed Description of the Pull Request / Additional comments
_\*<sup>\*</sup><sub>\*</sub> read the spec  <sub>\*</sub><sup>\*</sup>\*_

## Open Discussion
* [ ] What formatting string syntax and variables do we want to use?
* [ ] How exactly do we want to handle "log printable output"? Do we include backspaces? Do we only log on newlines?
* [ ] > maybe consider even simpler options like just `${date}` and `${time}`, and allow for future variants with something like `${date:yyyy-mm-dd}` or `${time:hhmm}`
2022-12-13 17:06:28 +00:00
Dustin L. Howett
68cce101bc Remove our dependency on Microsoft.Toolkit.Win32.UI.XamlApplication (#14520)
We originally needed this library (or a separate DLL in our own project)
to handle hooking up the XAML resource loader to the providers that our
application needed. It was introduced in its nascent form in 2019, in a
PR titled "Make XAML files work."

It appears we no longer need it, and the provider hookup is being
handled by our `AppT2` base class override. I've tested this in Windows
10 Vb running unpackaged, and it seems to work totally fine. Crazy.

Removing this dependency saves us a couple hundred kilobytes on disk and
removes one consumer of the App CRT from our package.
2022-12-12 20:59:23 +00:00
Mike Griese
58ce22d484 Don't crash when turning on Voice Access (#14534)
I should have checked the `wparam`. 

Regressed in #14064.

Tested manually. No more crashy. 

Closes #14504
2022-12-12 19:25:00 +00:00
Floris Westerman
2668273616 New Tab Menu Customization (#13763)
Implements an initial version of #1571 as it has been specified, the
only big thing missing now is the possibility to add actions, which
depends on #6899.

Further upcoming spec tracked in #12584 

Implemented according to [instructions by @zadjii-msft]. Mostly
relatively straightforward, but some notable details:
- In accordance with the spec, the counting/indexing of profiles is
  based on their index in the json (so the index of the profile, not of
  the entry in the menu).
- Resolving a profile name to an actual profile is done in a similar
  fashion as how currently the `DefaultProfile` field is populated: the
  `CascadiaSettings` constructor now has an extra `_resolve` function
  that will iterate over all entries and resolve the names to instances;
  this same function will compute all profile sets (the set of all
  profiles from source "x", and the set of all remaining profiles)
- ~Fun~ fact: I spent two whole afternoons and evenings trying to add 2
  classes (which turned out to be a trivial `.vcxproj` error), and then
  managed to finish the entire rest of it in another afternoon and
  evening...

## Validation Steps Performed
A lot of manual testing; as mentioned above I was not able to run any
tests so I could not add them for now. However, the logic is not too
tricky so it should be relatively safe.

Closes #1571

[instructions by @zadjii-msft]: https://github.com/microsoft/terminal/issues/1571#issuecomment-1184851000
2022-12-09 22:40:38 +00:00
Jon Thysell
a5f9c85c39 Dynamically generate profiles from hosts in OpenSSH config files (#14042)
This PR adds a new dynamic profile generator which creates profiles to
quickly connect to detected SSH hosts.

This PR adds a new `SshHostGenerator` inbox dynamic profile generator.
When run, it looks for an install of our
[Win32-OpenSSH](https://github.com/PowerShell/Win32-OpenSSH) client app
`ssh.exe` in all of the (official) places it gets installed. If the exe
is found, the generator then looks for and parses both the user and
system OpenSSH config files for valid SSH hosts. Each host is then
converted into a profiles to call `ssh.exe` and connect to those hosts.

VALIDATION
Installed OpenSSH, configured host for alt.org NetHack server, connected
and played some NetHack from the created profile.

* [x] When OpenSSH is not installed, don't add profiles
* [x] Detected when installed via Optional Features (installs in
  `System32\OpenSSH`, added to PATH)
* [x] Detected when installed via the 32-Bit OpenSSH MSI from GitHub
  (installs in `Program Files (x86)\OpenSSH`, not added to PATH)
* [x] Detected when installed via the 64-Bit OpenSSH MSI from GitHub
  (installs in `Program Files\OpenSSH`, not added to PATH)
* [x] Detected when installed via `winget install
  Microsoft.OpenSSH.Beta` (uses MSI from GitHub)
* [x] With `"disabledProfileSources": ["Windows.Terminal.SSH"]` the
  profiles are not generated

Closes #9031

Co-authored-by: Carlos Zamora <carlos.zamora@microsoft.com>
Co-authored-by: Mike Griese <migrie@microsoft.com>
Closes https://github.com/microsoft/terminal/issues/9031
2022-12-09 16:01:53 -06:00
Mike Griese
84bb98bc81 Make the Pane inactive border respect the theme.window.applicationTheme (#14486)
We couldn't do this before, because `App::Current().Resources().Lookup()` would always return the OS theme version of a resource. That thread has lengthy details on why.

FORTUNATELY FOR US, this isn't the first time we've dealt with this. We've come up with a workaround in the past, and we can just use it again here. 

Closes #3917

This will also make #3061 easy 😉
2022-12-09 21:26:17 +00:00
James Holderness
4d27a05318 Add support for DEC macro operations (#14402)
## Summary of the Pull Request

This PR adds support for the DEC macro operations `DECDMAC` (Define Macro), and `DECINVM` (Invoke Macro), which allow an application to define a sequence of characters as a macro, and then later invoke that macro to execute the content as if it had just been received from the host.

This PR also adds two new `DSR` queries: one for reporting the available space remaining in the macro buffer (`DECMSR`), and another reporting a checksum of the macros that are currently defined (`DECCKSR`).

## PR Checklist
* [x] Closes #14205
* [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 created a separate `MacroBuffer` class to handle the parsing and storage of macros, so the `AdaptDispatch` class doesn't have to do much more than delegate the macro operations to that.

The one complication is the macro invocation, which requires injecting characters back into the state machine's input stream. Ideally we'd just pass the content to the `ProcessString` method, but we can't do that when it's already in the middle of a `CSI` dispatch.

My solution for this was to add an `OnCsiComplete` method via which we could register a callback function that injects the macro sequence only once the state machine has returned to the ground state. This feels a bit hacky, but that was the best approach I could come up with.

## Validation Steps Performed

Thanks to @KalleOlaviNiemitalo, we've been able to do some testing on a real VT420 to determine how the macro operations are intended to work, and I've tried to get our implementation to match that behavior as much as possible (we differ in some aspects of the checksum reporting, where the VT420 behavior seemed undesirable, or potentially buggy).

I've also added unit tests covering some of the same scenarios that we tested on the VT420.
2022-12-09 21:10:41 +00:00
Bharat Dev Burman
86aa666903 reword en-US value for confirmCloseAllTabs (#14473)
Fixes #14433
2022-12-09 14:54:55 -06:00
Mike Griese
031271f824 Re-add support for Mica, transparent titlebars (#13935)
This reverts commit 19b6d35.

This re-enables support for Mica, and transparent titlebars in general. It also syncs the titlebar opacity with the control opacity for `terminalBackground`. It also somehow fixes the bug where the bottom few pixels of the max btn doesn't work to trigger the snap flyout.

Closes #10509 

Does nothing for #13631

### To-done's

* [x] Check the mica API on 22000, windows 11 RTM
  - this works on 10.0.22621.674, but that's not 22000
* [x] Check how this behaves on windows 10. 
  - For both, this API just no-ops. That's fine! we can just say "Mica is only supported on >=22621"
2022-12-09 20:52:03 +00:00
Mike Griese
a5c5b8a50e Enable vintage opacity on Windows 10 (#14481)
This reverts #11372 and #11285, and brings #11180 to everyone, now that MSFT:37879806 has been serviced to everyone in [KB5011831](https://support.microsoft.com/en-gb/topic/april-25-2022-kb5011831-os-builds-19042-1682-19043-1682-and-19044-1682-preview-fe4ff411-d25a-4185-aabb-8bc66e9dbb6c)[1].

I tested this on my home Win10 laptop that's super old and doesn't have a functioning clock, but it does have that update at the very least. 

I don't think we had an issue tracking this?

[1]: I'm pretty sure about this at least
2022-12-09 20:50:56 +00:00
Leonard Hecker
c5d417fcaf Harden against resizing down to 0 columns/rows (#14467)
This changeset includes various guards against resizing the terminal down to 0
columns/rows: The 2 `TextBuffer` locations that accept new sizes, as well as
the `HwndTerminal::Refresh` which was the entrypoint causing the issue.

Closes #14404
2022-12-09 20:15:49 +00:00
PankajBhojwani
b9c3b5cd1e Fix setting launch position in the Settings UI not working (#14518)
## Summary of the Pull Request
This change should have been a part of #14190 but was missed. 

## PR Checklist
* [x] Closes #14469 
* [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'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
Setting launch position in the settings UI works now
2022-12-09 17:51:26 +00:00
Javier
79c47f64a2 Added null check before rendering a string from the terminal connection (#14515)
## Summary of the Pull Request
Watson reports show that Visual Studio terminal attempts to render a string that is null causing the renderer to crash.

More specifically, we see "NULL_POINTER_WRITE_c0000005_PublicTerminalCore.dll!TextBuffer::WriteLine" with the following stack:
PublicTerminalCore!TextBuffer::WriteLine+0x1da
PublicTerminalCore!TextBuffer::Write+0x191
PublicTerminalCore!Microsoft::Terminal::Core::Terminal::_WriteBuffer+0x1d3
PublicTerminalCore!Microsoft::Terminal::Core::Terminal::PrintString+0x9
PublicTerminalCore!TerminalDispatch::PrintString+0x22
PublicTerminalCore!Microsoft::Console::VirtualTerminal::OutputStateMachineEngine::ActionPrintString+0x42
PublicTerminalCore!Microsoft::Console::VirtualTerminal::StateMachine::ProcessString+0x123
PublicTerminalCore!TerminalSendOutput+0x68
Microsoft_DotNet_MSBuildSdkResolver!DomainBoundILStubClass.IL_STUB_PInvoke(IntPtr, System.String)+0x8f
Microsoft_Terminal_Wpf!Microsoft.Terminal.Wpf.TerminalContainer.Connection_TerminalOutput(System.Object, Microsoft.Terminal.Wpf.TerminalOutputEventArgs)+0x20
Microsoft_VisualStudio_Terminal_Implementation!Microsoft.VisualStudio.Terminal.TerminalWindowBase+<>c__DisplayClass59_0+<<BeginProcessingPtyData>b__0>d.MoveNext()+0x55f

## References
Internal bug: [Bug 1614709](https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1614709): [Watson] crash64: NULL_POINTER_WRITE_c0000005_PublicTerminalCore.dll!TextBuffer::WriteLine

## Detailed Description of the Pull Request / Additional comments
Added a null check before PInvoking TerminalSendOutput.

## Validation Steps Performed
Validated locally that the check prevents null strings from rendering.
2022-12-09 17:44:35 +00:00
Steve Otteson
c0e4689e77 When the terminal has exited, ctrl+D to close pane, Enter to restart terminal (#14060)
When a terminal process exits (successful or not) and the profile isn't
set to automatically close the pane, a new message is displayed:

You can now close this terminal with ^D or Enter to restart.

Ctrl+D then is able to close the pane and Enter restarts it.

I originally tried to do this at the ConptyConnection layer by changing
the connection state from Failed to Closed, but then that didn't work
for the case where the process exited successfully but the profile isn't
set to exit automatically. So, I added an event to
ControlCore/TermControl that Pane watches. ControlCore watches to see if
the input is Ctrl+D (0x4) and if the connection is closed or failed, and
then raises the event so that Pane can close itself. As it turned out, I
think this is the better place to have the logic to watch for the Ctrl+D
key. Doing it at the ConptyConnection layer meant I had to parse out the
key from the escaped text passed to ConptyConnection::WriteInput.

## Validation Steps Performed
Tried adding lots of panes and then killing the processes outside of
Terminal. Each showed the new message and I could close them with Ctrl+D
or restart them with Enter. Also set a profile to never close
automatically to make sure Ctrl+D would work when a process exits
successfully.

Closes #12849 
Closes #11570
Closes #4379
2022-12-08 13:29:34 +00:00
Nicholas Bennett
da2b80bc0a Add support for switching the scheme based on the app's theme (#14064)
<!-- 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 pull request solved the problem of users not being able to set color schemes specifically for dark or light mode. Now the code has been updated to accept a dark and light color scheme in the json. The old setting is still compatible. Keep in mind if you update your color scheme through the settings UI, it will set both dark and light to the color scheme selected. This is because the settings UI update for selecting both Dark and Light color schemes is not supported yet.

This also solves the problem of the UI not using the system OS theme. Now you can select system theme and your color scheme will be selected based on if the system theme is dark or light.


<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> 
## References
#4066 

<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes #4066 
* [x] Closes #14050
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA. 
* [x] Tests added/passed I believe so, added one test to ColorSchemeTests.cpp and I believe it passed. Also had to modify TerminalSettingsTests.cpp to accept the new ApplyAppearanceSettings function template
* [ ] 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.
* [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: #4066 and also teams messages with @carlos-zamora 

<!-- 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
-Removed ColorSchemeName from MTSMSettings.h in order to process the setting for both string and object.
-Added DarkColorSchemeName and LightColorSchemeName properties to the AppearanceConfig to replace ColorSchemeName.
-Hacked a few processes to play nice with all 3 properties listed above as in some cases around the UI, we need to still use the ColorSchemeName. Once we change the UI I believe we can go back to just Dark and LightColorSchemeName
-Added and Updated Test to align to the new code.

Acceptable Json values,

"colorScheme": 
                {
                    "dark": "Campbell",
                    "light": "Campbell"
                }
or

"colorScheme": "Campbell"

<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Individual testing along with the test case added.
2022-12-06 17:33:22 +00:00
Dustin L. Howett
32bf894f14 Add an empty PGO rule to the wpf test harness app (#14484)
This should fix the PGO build.
2022-12-06 16:26:06 +00:00
Mike Griese
b89c8ced22 Remove "Requires relaunch" from "use acrylic in tab row" text (#14478)
what it says on the can. 

* [x] closes #14182

![image](https://user-images.githubusercontent.com/18356694/205180310-e08c3fb2-0e99-41a4-ba60-7eba09fbb328.png)
2022-12-06 00:28:28 +00:00
Leonard Hecker
4d9a266c12 Merge IBaseData, IRenderData and IUiaData (#14427)
My goal is to make `IRenderData` "snapshottable", so that we
can render a frame of text without holding the console lock.
To facilitate this, this commit merges our 3 data interfaces
into one. It includes no actual changes apart from renames.
2022-12-05 19:38:31 +00:00
Leonard Hecker
391abafc2e Refactor ConsoleProcessList (#14421)
This commit is just a slight refactor of `ConsoleProcessList` which I've noticed
was in a poor shape. It replaces iterators with for-range loops, etc.

Additionally this fixes a bug in `SetConsoleWindowOwner`, where it used to
default to the newest client process instead of the oldest.

Finally, it changes the process container type from a doubly linked list
over to a simple array/vector, because using linked lists for heap allocated
elements felt quite a bit silly. To preserve the previous behavior of
`GetProcessList`, it simply iterates through the vector backwards.

## Validation Steps Performed
* All unit/feature tests pass 
* Launching a TUI application inside pwsh inside cmd
  and exiting kills all 3 applications 
2022-12-02 23:15:57 +00:00
Leonard Hecker
3c78e01ab5 Fix a potential deadlock for PtySignal::SetParent (#14463)
This changeset consists of two parts:
* Refactor `PtySignalInputThread` to move more code from `_InputThread`
  into the various `_Do*` handlers. This allows us to precisely control
  console locking behavior which is the cause of this bug.
* Add the 1-line fix to `_DoSetWindowParent` to unlock the console before
  calling foreign functions (`SetWindowLongPtrW` in this case).

This fix is theoretical in nature, based on a memory dump from an affected user
and most likely fixes: https://developercommunity.visualstudio.com/t/10199439

## Validation Steps Performed
* ConPTY tests complete. 
2022-12-01 23:13:18 +00:00
Leonard Hecker
4bbe3a388c Clean up CodepointWidthDetector (#14396)
My long-term plan is to replace the `CodepointWidth` enum with a simple integer
return value that indicates the amount of columns a codepoint is wide.
This is necessary so that we can return 0 for ZWJs (zero width joiners).

This initial commit represents a cleanup effort around `CodepointWidthDetector`.
Since less code runs faster, this change has the nice side-effect of running
roughly 5-10% faster across the board. It also drops the binary size by ~1.2kB.

## Validation Steps Performed
* `CodepointWidthDetectorTests` passes 
* U+26bf (``"`u{26bf}"`` inside pwsh) is a wide glyph
  in OpenConsole and narrow one in Windows Terminal 
2022-12-01 22:23:25 +00:00
Dustin L. Howett
62ffa4ba41 Give the root PID ownership of the pseudoconsole window (#14196)
This is a partial fix for the Get-Credential issue. While investigating it, I found that the pseudoconsole window is not marked as being "owned" (in NTUSER) by the PID/TID of the console application that is "hosted" "in" it. Doing this does not (and cannot) fix `Get-Credential` failing in DefTerm scenarios.

ConsoleSetWindowOwner is one of the operations that can be done by a conhost to any window, and so the RemoteConsoleControl can call through to the Win32 ConsoleControl to pull it off.

I chose to add SetWindowOwner to the IConsoleControl interface instead of moving ConsoleControl::Control into the interface to reduce the amount of churn and better separate interface responsibilities.

References #14119
2022-12-01 22:22:50 +00:00
Mike Griese
37aa29545b Implement the rest of the FTCS marks (#14341)
As noted in #11000.

This adds support for `FTCS_COMMAND_START`, `FTCS_COMMAND_EXECUTED` and `FTCS_COMMAND_FINISHED`, which allow a shell to more clearly markup parts of the buffer. 

As a trick, I'm also making the `experimental.autoMarkPrompts` setting act like a `FTCS_COMMAND_EXECUTED` if it comes after a `FTCS_COMMAND_START`. This lets the whole sequence work for cmd.exe (which wouldn't otherwise be possible).

* My cmd prompt
  ```bat
  PROMPT $e]133;D$e\$e]133;A$e\$e]9;9;$P$e\[$T]$e[97;46m%_seperator%$P$e[36;49m%_seperator%$e[0m$_$e[0m%_GITPROMPT%$e[94m%username%$e[0m@$e[32m%computername%$e[0m$G$e]133;B$e\
  ```
* pwsh profile, heavily cribbed from vscode
  ```pwsh

	$Global:__LastHistoryId = -1
	
	function Global:__Terminal-Get-LastExitCode {
	  if ($? -eq $True) {
	    return 0
	  }
	  # TODO: Should we just return a string instead?
	  # return -1
	  if ("$LastExitCode" -ne "") { return $LastExitCode }
	  return -1
	}
	
	function prompt {
	  # $gle = $LastExitCode
	
	
	  $gle = $(__Terminal-Get-LastExitCode);
	  $LastHistoryEntry = $(Get-History -Count 1)
	  # Skip finishing the command if the first command has not yet started
	  if ($Global:__LastHistoryId -ne -1) {
	    if ($LastHistoryEntry.Id -eq $Global:__LastHistoryId) {
	      # Don't provide a command line or exit code if there was no history entry (eg. ctrl+c, enter on no command)
	      $out += "`e]133;D`a"
	    } else {
	      # Command finished exit code
	      # OSC 633 ; D [; <ExitCode>] ST
	      $out += "`e]133;D;$gle`a"
	    }
	  }
	
	
	  $loc = $($executionContext.SessionState.Path.CurrentLocation);
	  # IMPORTANT: Make sure there's a printable charater _last_ in the prompt.
	  # Otherwise, PSReadline is gonna use the terminating `\` here and colorize
	  # that if it detects a syntax error
	  $out += "`e]133;A$([char]07)";
	  $out += "`e]9;9;`"$loc`"$([char]07)";
	  $out += "PWSH $loc$('>' * ($nestedPromptLevel + 1)) ";
	  $out += "`e]133;B$([char]07)";
	
	  $Global:__LastHistoryId = $LastHistoryEntry.Id
	
	  return $out
	}
  ```



* Doesn't close any issues, because this was always just an element in #11000
* I work here
* From FHL code
2022-12-01 22:22:07 +00:00
Mike Griese
52cc523ed2 Find out how often are people actually using marks, Themes (#14356)
Let's find out!

* [x] This is all the current bullets in #14324. I'm going to leave that open till we signoff on the release.
2022-12-01 02:10:53 +00:00
Leonard Hecker
0eff8c06e3 Clean up til::point/size/rect member usage (#14458)
This is a follow-up of #13025 to make the members of `til::point/size/rect`
uniform and consistent without the use of `unions`. The only file that has
any changes is `src/host/getset.cpp` where an if condition was simplified.

## Validation Steps Performed
* Host unit tests 
* Host feature tests 
* ControlCore feature tests 
2022-12-01 00:40:00 +00:00
James Holderness
437914807a Add support for the DECRQM escape sequence (#14444)
This PR adds support for the `DECRQM` (Request Mode) escape sequence,
which allows applications to query the state of the various modes
supported by the terminal. It also adds support for the `DECNKM` mode,
which aliases the existing `DECKPAM` and `DECKPNM` operations, so they
can be queried with `DECRQM` too.

This is one solution for #10153 (saving and restoring the state of
bracketed paste mode), and should also help with #1040 (providing a way
for clients to determine the capabilities of the terminal).

Prior to adding `DECRQM`, I also did some refactoring of the mode
handling to get rid of the mode setting methods in the `ITermDispatch`
interface that had no need to be there. Most of them were essentially a
single line of code that could easily be executed directly from the
`_ModeParamsHelper` handler anyway.

As part of this refactoring I combined all the internal `AdaptDispatch`
modes into an `enumset` to allow for easier management, and made sure
all modes were correctly reset in the `HardReset` method (prior to this,
there were a number of modes that we weren't restoring when we should
have been).

And note that there are some differences in behavior between conhost and
Windows Terminal. In conhost, `DECRQM` will report bracketed paste mode
as unsupported, and in Terminal, both `DECCOLM` and `AllowDECCOLM` are
reported as unsupported. And `DECCOLM` is now explicitly ignored in
conpty mode, to avoid the conpty client and conhost getting out of sync.
 
## Validation Steps Performed

I've manually confirmed that all the supported modes are reported in the
`DECRQM` tests in Vttest, and I have my own test scripts which I've used
to confirm that `RIS` is now resetting the modes correctly.

I've also added a unit test in `AdapterTest` that iterates through the
modes, checking the responses from `DECRQM` for both the set and reset
states.

I should also mention that I had to do some refactoring of the existing
tests to compensate for methods that were removed from `ITermDispatch`,
particularly in `OutputEngineTest`. In many cases, though, these tests
weren't doing much more than testing the test framework.
2022-11-30 22:05:54 +00:00
Dustin L. Howett
d1fbbb8a83 Merge the DotNet_###Test "platforms" back into the right place (#14468)
I originally added these platforms to prevent the .NET components from
building when you built the entire solution, and to prevent them from
building in CI.

It turns out that managing an extra thousand project-platform-config
triples is an absolute pain, **and** that we should have been building
these things in CI the entire time. So.

This should make life _a lot_ easier.

As a bonus, this PR enables the WPF test harness to build for ARM64.
2022-11-30 19:46:29 +00:00
874 changed files with 49420 additions and 34299 deletions

View File

@@ -1,57 +1,25 @@
---
Language: Cpp
BasedOnStyle: Microsoft
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AllowAllArgumentsOnNextLine: true
AlignConsecutiveMacros: false
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AllowAllConstructorInitializersOnNextLine: true
AlignEscapedNewlines: Left
AlignOperands: true
AlignTrailingComments: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Never
AllowShortFunctionsOnASingleLine: All
AllowShortCaseLabelsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: Never
#AllowShortLambdasOnASingleLine: Inline
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: false
BinPackParameters: false
BraceWrapping:
AfterCaseLabel: true
AfterClass: true
AfterControlStatement: true
AfterEnum: true
AfterFunction: true
AfterNamespace: true
AfterObjCDeclaration: true
AfterStruct: true
AfterUnion: true
AfterExternBlock: false
BeforeCatch: true
BeforeElse: true
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BreakBeforeTernaryOperators: false
BreakConstructorInitializers: AfterColon
BreakInheritanceList: AfterColon
ColumnLimit: 0
CommentPragmas: "suppress"
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: false
DeriveLineEnding: true
DerivePointerAlignment: false
FixNamespaceComments: false
IncludeBlocks: Regroup
IncludeCategories:
@@ -63,35 +31,13 @@ IncludeCategories:
Priority: 2
- Regex: '.*'
Priority: 3
IndentCaseLabels: false
IndentPPDirectives: None
IndentWidth: 4
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: "BEGIN_TEST_METHOD_PROPERTIES|BEGIN_MODULE|BEGIN_TEST_CLASS|BEGIN_TEST_METHOD"
MacroBlockEnd: "END_TEST_METHOD_PROPERTIES|END_MODULE|END_TEST_CLASS|END_TEST_METHOD"
MaxEmptyLinesToKeep: 1
NamespaceIndentation: All
PointerAlignment: Left
ReflowComments: false
SortIncludes: false
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Latest
TabWidth: 4
UseTab: Never

View File

@@ -1,20 +1,14 @@
<!-- 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
<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? -->
## References
## References and Relevant Issues
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [ ] Closes #xxx
* [ ] 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
## PR Checklist
- [ ] Closes #xxx
- [ ] 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 (if necessary)

View File

@@ -2,6 +2,7 @@ admins
allcolors
Apc
apc
backpressure
breadcrumb
breadcrumbs
bsd
@@ -12,18 +13,23 @@ clickable
clig
CMMI
copyable
CtrlDToClose
cybersecurity
dalet
Dcs
dcs
deselection
dialytika
diffing
dje
downside
downsides
dze
dzhe
DTo
EDDB
EDDC
Emacspeak
Enum'd
Fitt
formattings
@@ -60,6 +66,7 @@ lol
lorem
Lorigin
maxed
megathread
minimalistic
mkmk
mnt
@@ -71,6 +78,8 @@ ok'd
overlined
pipeline
postmodern
Powerline
powerline
ptys
qof
qps
@@ -85,6 +94,8 @@ shcha
slnt
Sos
ssh
stakeholders
sxn
timeline
timelines
timestamped
@@ -92,6 +103,7 @@ TLDR
tokenizes
tonos
toolset
truthiness
tshe
ubuntu
uiatextrange
@@ -100,6 +112,8 @@ und
unregister
versioned
vsdevcmd
walkthrough
walkthroughs
We'd
wildcards
XBox

View File

@@ -28,13 +28,13 @@ CYICON
Dacl
dataobject
dcomp
delayimp
DERR
dlldata
DNE
DONTADDTORECENT
DWMSBT
DWMWA
DWMWA
DWORDLONG
endfor
ENDSESSION
@@ -55,6 +55,8 @@ GETMOUSEHOVERTIME
Hashtable
HIGHCONTRASTON
HIGHCONTRASTW
hinternet
HINTERNET
hotkeys
href
hrgn
@@ -74,6 +76,7 @@ IConnection
ICustom
IDialog
IDirect
Idn
IExplorer
IFACEMETHOD
IFile
@@ -85,6 +88,7 @@ IObject
iosfwd
IPackage
IPeasant
isa
ISetup
isspace
IStorage
@@ -106,12 +110,14 @@ lsass
LSHIFT
LTGRAY
MAINWINDOW
MAXIMIZEBOX
memchr
memicmp
MENUCOMMAND
MENUDATA
MENUINFO
MENUITEMINFOW
MINIMIZEBOX
mmeapi
MOUSELEAVE
mov
@@ -158,11 +164,13 @@ rcx
REGCLS
RETURNCMD
rfind
RLO
ROOTOWNER
roundf
RSHIFT
SACL
schandle
SEH
semver
serializer
SETVERSION
@@ -194,6 +202,7 @@ TABROW
TASKBARCREATED
TBPF
THEMECHANGED
THICKFRAME
tlg
TME
tmp
@@ -210,10 +219,14 @@ UOI
UPDATEINIFILE
userenv
USEROBJECTFLAGS
Vcpp
Viewbox
virtualalloc
vsnwprintf
wcsstr
wcstoui
WDJ
winhttp
winmain
winsta
winstamin
@@ -221,6 +234,7 @@ wmemcmp
wpc
WSF
wsregex
WWH
wwinmain
xchg
XDocument
@@ -246,3 +260,4 @@ xtree
xutility
YIcon
YMax
zwstring

View File

@@ -9,9 +9,11 @@ appxbundle
appxerror
appxmanifest
ATL
autoexec
backplating
bitmaps
BOMs
COMPUTERNAME
CPLs
cpptools
cppvsdbg
@@ -26,6 +28,7 @@ dotnetfeed
DTDs
DWINRT
enablewttlogging
HOMESHARE
Intelli
IVisual
libucrt
@@ -33,6 +36,7 @@ libucrtd
LKG
LOCKFILE
Lxss
makepri
mfcribbon
microsoft
microsoftonline
@@ -50,14 +54,19 @@ pgo
pgosweep
powerrename
powershell
priconfig
PRIINFO
propkey
pscustomobject
QWORD
regedit
resfiles
robocopy
SACLs
segoe
sdkddkver
Shobjidl
sid
Skype
SRW
sxs
@@ -70,6 +79,7 @@ tdbuildteamid
ucrt
ucrtd
unvirtualized
USERDNSDOMAIN
VCRT
vcruntime
Virtualization

View File

@@ -1,6 +1,6 @@
Anup
austdi
arkthur
austdi
Ballmer
bhoj
Bhojwani
@@ -23,6 +23,7 @@ Griese
Hernan
Howett
Illhardt
Imms
iquilezles
italo
jantari
@@ -30,10 +31,11 @@ jerrysh
Kaiyu
kimwalisch
KMehrain
KODELIFE
Kodelife
KODELIFE
Kourosh
kowalczyk
leonardder
leonmsft
Lepilleur
lhecker
@@ -52,6 +54,7 @@ mikegr
mikemaccana
miloush
miniksa
nguyen
niksa
nvaccess
nvda
@@ -59,6 +62,7 @@ oising
oldnewthing
opengl
osgwiki
Ottosson
pabhojwa
panos
paulcam
@@ -77,15 +81,18 @@ sonpham
stakx
talo
thereses
Thysell
Walisch
WDX
Wellons
Westerman
Wirt
Wojciech
zadjii
Zamor
Zamora
zamora
Zamora
zljubisic
Zoey
zorio
Zverovich

View File

@@ -371,8 +371,6 @@ ipfs://[0-9a-z]*
\b(?:[0-9a-fA-F]{0,4}:){3,7}[0-9a-fA-F]{0,4}\b
# c99 hex digits (not the full format, just one I've seen)
0x[0-9a-fA-F](?:\.[0-9a-fA-F]*|)[pP]
# Punycode
\bxn--[-0-9a-z]+
# sha
sha\d+:[0-9]*[a-f]{3,}[0-9a-f]*
# sha-... -- uses a fancy capture

View File

@@ -106,11 +106,14 @@
^src/terminal/parser/ft_fuzzwrapper/run\.bat$
^src/terminal/parser/ut_parser/Base64Test.cpp$
^src/terminal/parser/ut_parser/run\.bat$
^src/tools/benchcat
^src/tools/integrity/packageuwp/ConsoleUWP\.appxSources$
^src/tools/lnkd/lnkd\.bat$
^src/tools/pixels/pixels\.bat$
^src/tools/RenderingTests/main.cpp$
^src/tools/texttests/fira\.txt$
^src/tools/U8U16Test/(?:fr|ru|zh)\.txt$
^src/types/ColorFix.cpp
^src/types/ut_types/UtilsTests.cpp$
^tools/ReleaseEngineering/ServicingPipeline.ps1$
ignore$

View File

@@ -9,6 +9,7 @@ ABCDEFGHIJ
abcdefghijk
ABCDEFGHIJKLMNO
abcdefghijklmnop
ABCDEFGHIJKLMNOPQRS
ABCDEFGHIJKLMNOPQRST
ABCG
ABE
@@ -18,11 +19,15 @@ BBBBBBBB
BBBBBCCC
BBBBCCCCC
BBGGRR
efg
EFG
EFGh
KLMNOQQQQQQQQQQ
QQQQQQQQQQABCDEFGHIJ
QQQQQQQQQQABCDEFGHIJKLMNOPQRS
QQQQQQQQQQABCDEFGHIJKLMNOPQRSTQQQQQQQQQ
QQQQQQQQQQABCDEFGHIJKLMNOPQRSTQQQQQQQQQQ
QQQQQQQQQQABCDEFGHIJPQRST
QQQQQQQQQQABCDEFGHIJPQRSTQQQQQQQQQQ
qrstuvwxyz
qwerty

View File

@@ -1,7 +1,9 @@
aabbcc
aarch
ABANDONFONT
abbcc
ABCDEFGHIJKLMNOPQRSTUVWXY
ABCF
abgr
abi
ABORTIFHUNG
@@ -37,10 +39,12 @@ ansicpg
ANSISYS
ANSISYSRC
ANSISYSSC
answerback
antialiasing
ANull
anycpu
APARTMENTTHREADED
APCA
APCs
APIENTRY
apiset
@@ -61,7 +65,6 @@ argb
ARRAYSIZE
ARROWKEYS
asan
ASBRST
ASBSET
ASDF
asdfghjkl
@@ -102,6 +105,7 @@ bcx
bcz
BEFOREPARENT
beginthread
benchcat
bgfx
bgidx
Bgk
@@ -155,7 +159,6 @@ capslock
CARETBLINKINGENABLED
CARRIAGERETURN
cascadia
castsi
catid
cazamor
CBash
@@ -176,7 +179,6 @@ CConsole
CConversion
CCRT
cdd
CDeclaration
CEdit
CELLSIZE
cfae
@@ -194,7 +196,8 @@ chh
chk
CHT
Cic
CLA
cielab
Cielab
Clcompile
CLE
cleartype
@@ -214,11 +217,11 @@ cmder
CMDEXT
cmh
CMOUSEBUTTONS
cmpeq
cmt
cmw
cmyk
CNL
cnn
cnt
CNTRL
Codeflow
@@ -252,6 +255,7 @@ conattrs
conbufferout
concfg
conclnt
concretizations
conddkrefs
condrv
conechokey
@@ -332,7 +336,7 @@ Cspace
csrmsg
CSRSS
csrutil
cstyle
CSTYLE
CSwitch
CTerminal
CText
@@ -407,35 +411,50 @@ DECANM
DECARM
DECAUPSS
DECAWM
DECBI
DECBKM
DECCARA
DECCIR
DECCKM
DECCKSR
DECCOLM
DECCRA
DECCTR
DECDC
DECDHL
decdld
DECDMAC
DECDWL
DECECM
DECEKBD
DECERA
DECFI
DECFRA
DECIC
DECID
DECINVM
DECKPAM
DECKPM
DECKPNM
DECLRMM
DECMSR
DECNKM
DECNRCM
DECOM
decommit
DECPCTERM
DECPS
DECRARA
DECRC
DECREQTPARM
DECRLM
DECRPM
DECRQCRA
DECRQM
DECRQPSR
DECRQSS
DECRQTSR
DECRSPS
decrst
DECSACE
DECSASD
@@ -453,8 +472,10 @@ DECSLRM
DECSMKR
DECSR
DECSTBM
DECSTGLT
DECSTR
DECSWL
DECTABSR
DECTCEM
DECXCPR
DEFAPP
@@ -474,7 +495,6 @@ defterm
DELAYLOAD
DELETEONRELEASE
Delt
demoable
depersist
deprioritized
deserializers
@@ -531,7 +551,6 @@ DSSCL
DSwap
DTest
DTTERM
DUMMYUNIONNAME
dup'ed
dvi
dwl
@@ -559,6 +578,7 @@ EDITTEXT
EDITUPDATE
edputil
Efast
efghijklmn
EHsc
EINS
EJO
@@ -575,6 +595,7 @@ ENU
ENUMLOGFONT
ENUMLOGFONTEX
enumranges
EOK
eplace
EPres
EQU
@@ -584,7 +605,6 @@ ETW
EUDC
EVENTID
eventing
everytime
evflags
evt
execd
@@ -606,8 +626,12 @@ FACESIZE
FAILIFTHERE
fastlink
fcharset
FDEA
fdw
FECF
FEEF
fesb
FFAF
FFDE
FFrom
fgbg
@@ -792,7 +816,6 @@ HIBYTE
hicon
HIDEWINDOW
hinst
Hirots
HISTORYBUFS
HISTORYNODUP
HISTORYSIZE
@@ -804,13 +827,18 @@ hkl
HKLM
hlocal
hlsl
HMB
HMK
hmod
hmodule
hmon
homeglyphs
homoglyph
HORZ
hostable
hostlib
HPA
hpcon
HPCON
hpj
HPR
@@ -892,7 +920,6 @@ INSERTMODE
INTERACTIVITYBASE
INTERCEPTCOPYPASTE
INTERNALNAME
inthread
intsafe
INVALIDARG
INVALIDATERECT
@@ -953,13 +980,15 @@ KLF
KLMNO
KLMNOPQRST
KLMNOPQRSTQQQQQ
KLMNOPQRSTUVWXY
KLMNOPQRSTY
KOK
KPRIORITY
KVM
langid
LANGUAGELIST
lasterror
lastexitcode
LASTEXITCODE
LAYOUTRTL
lbl
LBN
@@ -995,7 +1024,6 @@ lnkd
lnkfile
LNM
LOADONCALL
loadu
LOBYTE
localappdata
locsrc
@@ -1004,6 +1032,7 @@ LOGFONT
LOGFONTA
LOGFONTW
logissue
losslessly
loword
lparam
LPCCH
@@ -1111,10 +1140,12 @@ Mip
MMBB
mmcc
MMCPL
MMIX
mmsystem
MNC
MNOPQ
MNOPQR
MNOPQRSTUVWXY
MODALFRAME
MODERNCORE
MONITORINFO
@@ -1124,7 +1155,6 @@ MOUSEACTIVATE
MOUSEFIRST
MOUSEHWHEEL
MOUSEMOVE
movemask
MOVESTART
msb
msctf
@@ -1249,20 +1279,17 @@ ntm
nto
ntrtl
ntstatus
ntsubauth
NTSYSCALLAPI
nttree
nturtl
ntuser
NTVDM
ntverp
NTWIN
nugetversions
nullability
nullness
nullonfailure
nullopts
NULs
numlock
numpad
NUMSCROLL
@@ -1277,6 +1304,8 @@ OEMFONT
OEMFORMAT
OEMs
offboarded
oklab
Oklab
OLEAUT
OLECHAR
onecore
@@ -1295,8 +1324,6 @@ opencode
opencon
openconsole
openconsoleproxy
OPENIF
OPENLINK
openps
openvt
ORIGINALFILENAME
@@ -1349,9 +1376,7 @@ pcg
pch
PCIDLIST
PCIS
PCLIENT
PCLONG
PCOBJECT
pcon
PCONSOLE
PCONSOLEENDTASK
@@ -1363,7 +1388,6 @@ pcshell
PCSHORT
PCSR
PCSTR
PCUNICODE
PCWCH
PCWCHAR
PCWSTR
@@ -1412,7 +1436,6 @@ PLOGICAL
pnm
PNMLINK
pntm
PNTSTATUS
POBJECT
Podcast
POINTSLIST
@@ -1432,7 +1455,6 @@ ppguid
ppidl
pplx
PPROC
PPROCESS
ppropvar
ppsi
ppsl
@@ -1496,7 +1518,6 @@ ptrs
ptsz
PTYIn
PUCHAR
PUNICODE
pwch
PWDDMCONSOLECONTEXT
pws
@@ -1558,7 +1579,6 @@ REGISTEROS
REGISTERVDM
regkey
REGSTR
reingest
RELBINPATH
remoting
renamer
@@ -1570,6 +1590,7 @@ replatformed
Replymessage
repositorypath
Requiresx
rerasterize
rescap
Resequence
RESETCONTENT
@@ -1758,7 +1779,6 @@ somefile
SOURCEBRANCH
sourced
spammy
spand
SRCCODEPAGE
SRCCOPY
SRCINVERT
@@ -1766,10 +1786,13 @@ srcsrv
SRCSRVTRG
srctool
srect
srgb
Srgb
srv
srvinit
srvpipe
ssa
startdir
STARTF
STARTUPINFO
STARTUPINFOEX
@@ -1779,6 +1802,7 @@ STARTWPARMS
STARTWPARMSA
STARTWPARMSW
Statusline
stb
stdafx
STDAPI
stdc
@@ -1818,6 +1842,7 @@ SYSCOMMAND
SYSDEADCHAR
SYSKEYDOWN
SYSKEYUP
SYSLIB
SYSLINK
SYSMENU
sysparams
@@ -1851,6 +1876,7 @@ TDP
TEAMPROJECT
tearoff
Teb
Techo
tellp
teraflop
terminalcore
@@ -1942,6 +1968,7 @@ trx
tsattrs
tsf
tsgr
tsm
TStr
TSTRFORMAT
TSub
@@ -1993,7 +2020,6 @@ unittesting
unittests
unk
unknwn
unmark
UNORM
unparseable
unregistering
@@ -2028,6 +2054,7 @@ USRDLL
utr
UVWX
UVWXY
UVWXYZ
uwa
uwp
uxtheme
@@ -2038,6 +2065,7 @@ vcpkg
vcprintf
vcxitems
vec
vectorize
vectorized
VERCTRL
VERTBAR
@@ -2183,6 +2211,7 @@ wnd
WNDALLOC
WNDCLASS
WNDCLASSEX
WNDCLASSEXW
WNDCLASSW
Wndproc
WNegative
@@ -2277,7 +2306,6 @@ xunit
xutr
XVIRTUALSCREEN
XWalk
xwwyzz
xxyyzz
yact
YCast
@@ -2288,6 +2316,9 @@ YOffset
YSubstantial
YVIRTUALSCREEN
YWalk
Zab
zabcd
Zabcdefghijklmn
Zabcdefghijklmnopqrstuvwxyz
ZCmd
ZCtrl

View File

@@ -10,4 +10,4 @@
\\tests(?![a-z])
\\thread(?![a-z])
\\tools(?![a-z])
\\types(?![a-z])
\\types?(?![a-z])

View File

@@ -27,6 +27,12 @@ ROY\sG\.\sBIV
# Python stringprefix / binaryprefix
\b(?:B|BR|Br|F|FR|Fr|R|RB|RF|Rb|Rf|U|UR|Ur|b|bR|br|f|fR|fr|r|rB|rF|rb|rf|u|uR|ur)'
# SSE intrinsics like "_mm_subs_epu16"
\b_mm(?:|256|512)_\w+\b
# ARM NEON intrinsics like "vsubq_u16"
\bv\w+_[fsu](?:8|16|32|64)\b
# Automatically suggested patterns
# hit-count: 3831 file-count: 582
# IServiceProvider
@@ -35,7 +41,7 @@ ROY\sG\.\sBIV
# hit-count: 71 file-count: 35
# Compiler flags
(?:^|[\t ,"'`=(])-[D](?=[A-Z]{2,}|[A-Z][a-z])
(?:^|[\t ,"'`=(])-[X](?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,})
(?:^|[\t ,"'`=(])-[X](?!aml)(?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,})
# hit-count: 41 file-count: 28
# version suffix <word>v#

3156
.github/fabricbot.json vendored

File diff suppressed because it is too large Load Diff

751
.github/policies/resourceManagement.yml vendored Normal file
View File

@@ -0,0 +1,751 @@
id:
name: GitOps.PullRequestIssueManagement
description: GitOps.PullRequestIssueManagement primitive
owner:
resource: repository
disabled: false
where:
configuration:
resourceManagementConfiguration:
scheduledSearches:
- description:
frequencies:
- hourly:
hour: 3
filters:
- isIssue
- isOpen
- hasLabel:
label: Needs-Author-Feedback
- hasLabel:
label: No-Recent-Activity
- noActivitySince:
days: 3
actions:
- closeIssue
- description:
frequencies:
- hourly:
hour: 3
filters:
- isIssue
- isOpen
- hasLabel:
label: Needs-Author-Feedback
- noActivitySince:
days: 4
- isNotLabeledWith:
label: No-Recent-Activity
actions:
- addLabel:
label: No-Recent-Activity
- addReply:
reply: This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for **4 days**. It will be closed if no further activity occurs **within 3 days of this comment**.
- description:
frequencies:
- hourly:
hour: 3
filters:
- isIssue
- isOpen
- hasLabel:
label: Resolution-Duplicate
- noActivitySince:
days: 1
actions:
- addReply:
reply: This issue has been marked as duplicate and has not had any activity for **1 day**. It will be closed for housekeeping purposes.
- closeIssue
- description:
frequencies:
- hourly:
hour: 3
filters:
- isPullRequest
- isOpen
- hasLabel:
label: Needs-Author-Feedback
- hasLabel:
label: No-Recent-Activity
- noActivitySince:
days: 7
actions:
- closeIssue
- description:
frequencies:
- hourly:
hour: 3
filters:
- isPullRequest
- isOpen
- hasLabel:
label: Needs-Author-Feedback
- noActivitySince:
days: 7
- isNotLabeledWith:
label: No-Recent-Activity
actions:
- addLabel:
label: No-Recent-Activity
- addReply:
reply: This pull request has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for **7 days**. It will be closed if no further activity occurs **within 7 days of this comment**.
eventResponderTasks:
- if:
- payloadType: Issues
- or:
- and:
- isAction:
action: Opened
- not:
hasLabel:
label: ⛺ Reserved
then:
- addLabel:
label: Needs-Triage
description:
- if:
- payloadType: Issue_Comment
- isAction:
action: Created
- isActivitySender:
issueAuthor: True
- hasLabel:
label: Needs-Author-Feedback
then:
- addLabel:
label: Needs-Attention
- removeLabel:
label: Needs-Author-Feedback
description:
- if:
- payloadType: Issues
- not:
isAction:
action: Closed
- hasLabel:
label: No-Recent-Activity
then:
- removeLabel:
label: No-Recent-Activity
description:
- if:
- payloadType: Issue_Comment
- hasLabel:
label: No-Recent-Activity
then:
- removeLabel:
label: No-Recent-Activity
description:
- if:
- payloadType: Pull_Request_Review
- isAction:
action: Submitted
- isReviewState:
reviewState: Changes_requested
then:
- addLabel:
label: Needs-Author-Feedback
description:
- if:
- payloadType: Pull_Request
- isActivitySender:
issueAuthor: True
- not:
isAction:
action: Closed
- hasLabel:
label: Needs-Author-Feedback
then:
- removeLabel:
label: Needs-Author-Feedback
description:
- if:
- payloadType: Issue_Comment
- isActivitySender:
issueAuthor: True
- hasLabel:
label: Needs-Author-Feedback
then:
- removeLabel:
label: Needs-Author-Feedback
description:
- if:
- payloadType: Pull_Request_Review
- isActivitySender:
issueAuthor: True
- hasLabel:
label: Needs-Author-Feedback
then:
- removeLabel:
label: Needs-Author-Feedback
description:
- if:
- payloadType: Pull_Request
- not:
isAction:
action: Closed
- hasLabel:
label: No-Recent-Activity
then:
- removeLabel:
label: No-Recent-Activity
description:
- if:
- payloadType: Issue_Comment
- hasLabel:
label: No-Recent-Activity
then:
- removeLabel:
label: No-Recent-Activity
description:
- if:
- payloadType: Pull_Request_Review
- hasLabel:
label: No-Recent-Activity
then:
- removeLabel:
label: No-Recent-Activity
description:
- if:
- payloadType: Pull_Request
- hasLabel:
label: AutoMerge
then:
- enableAutoMerge:
mergeMethod: Squash
description:
- if:
- payloadType: Pull_Request
- labelRemoved:
label: AutoMerge
then:
- disableAutoMerge
description:
- if:
- payloadType: Issues
- or:
- and:
- isLabeled
- hasLabel:
label: Mass-Chaos
- isOpen
- isLabeled
- not:
hasLabel:
label: Needs-Tag-Fix
- or:
- and:
- not:
hasLabel:
label: Area-Accessibility
- not:
hasLabel:
label: Area-Build
- not:
hasLabel:
label: Area-Extensibility
- not:
hasLabel:
label: Area-Fonts
- not:
hasLabel:
label: Area-Input
- not:
hasLabel:
label: Area-Interaction
- not:
hasLabel:
label: Area-Interop
- not:
hasLabel:
label: Area-Output
- not:
hasLabel:
label: Area-Performance
- not:
hasLabel:
label: Area-Rendering
- not:
hasLabel:
label: Area-Server
- not:
hasLabel:
label: Area-Settings
- not:
hasLabel:
label: Area-TerminalConnection
- not:
hasLabel:
label: Area-TerminalControl
- not:
hasLabel:
label: Area-User Interface
- not:
hasLabel:
label: Area-VT
- not:
hasLabel:
label: Area-CodeHealth
- not:
hasLabel:
label: Area-Quality
- not:
hasLabel:
label: Area-AzureShell
- not:
hasLabel:
label: Area-Schema
- not:
hasLabel:
label: Area-Commandline
- not:
hasLabel:
label: Area-ShellExtension
- not:
hasLabel:
label: Area-WPFControl
- not:
hasLabel:
label: Area-Settings UI
- not:
hasLabel:
label: Area-DefApp
- not:
hasLabel:
label: Area-Remoting
- not:
hasLabel:
label: Area-Windowing
- not:
hasLabel:
label: Area-Theming
- not:
hasLabel:
label: Area-Localization
- and:
- not:
hasLabel:
label: Issue-Bug
- not:
hasLabel:
label: Issue-Docs
- not:
hasLabel:
label: Issue-Feature
- not:
hasLabel:
label: Issue-Question
- not:
hasLabel:
label: Issue-Samples
- not:
hasLabel:
label: Issue-Task
- not:
hasLabel:
label: Issue-Scenario
- and:
- not:
hasLabel:
label: Product-Cmd.exe
- not:
hasLabel:
label: Product-Colortool
- not:
hasLabel:
label: Product-Conhost
- not:
hasLabel:
label: Product-Conpty
- not:
hasLabel:
label: Product-Meta
- not:
hasLabel:
label: Product-Powershell
- not:
hasLabel:
label: Product-Terminal
- not:
hasLabel:
label: Product-WSL
- and:
- not: isOpen
- and:
- not:
hasLabel:
label: Resolution-Answered
- not:
hasLabel:
label: Resolution-By-Design
- not:
hasLabel:
label: Resolution-Duplicate
- not:
hasLabel:
label: Resolution-External
- not:
hasLabel:
label: Resolution-Fix-Available
- not:
hasLabel:
label: Resolution-Fix-Committed
- not:
hasLabel:
label: Resolution-Won't-Fix
- not:
hasLabel:
label: Needs-Triage
- not:
hasLabel:
label: Resolution-Duplicate
- not:
hasLabel:
label: ⛺ Reserved
- not:
hasLabel:
label: Tracking-External
then:
- addLabel:
label: Needs-Tag-Fix
description:
- if:
- payloadType: Issues
- and:
- isLabeled
- hasLabel:
label: Needs-Tag-Fix
- and:
- or:
- hasLabel:
label: Area-Accessibility
- hasLabel:
label: Area-Build
- hasLabel:
label: Area-Extensibility
- hasLabel:
label: Area-Fonts
- hasLabel:
label: Area-Input
- hasLabel:
label: Area-Interaction
- hasLabel:
label: Area-Interop
- hasLabel:
label: Area-Output
- hasLabel:
label: Area-Performance
- hasLabel:
label: Area-Rendering
- hasLabel:
label: Area-Server
- hasLabel:
label: Area-Settings
- hasLabel:
label: Area-TerminalConnection
- hasLabel:
label: Area-TerminalControl
- hasLabel:
label: Area-User Interface
- hasLabel:
label: Area-VT
- hasLabel:
label: Area-CodeHealth
- hasLabel:
label: Area-Quality
- hasLabel:
label: Area-Schema
- hasLabel:
label: Area-AzureShell
- hasLabel:
label: Area-Commandline
- hasLabel:
label: Area-ShellExtension
- hasLabel:
label: Area-WPFControl
- hasLabel:
label: Area-Settings UI
- hasLabel:
label: Area-DefApp
- hasLabel:
label: Area-Localization
- hasLabel:
label: Area-Windowing
- hasLabel:
label: Area-Theming
- hasLabel:
label: Area-AtlasEngine
- hasLabel:
label: Area-CmdPal
- or:
- hasLabel:
label: Issue-Bug
- hasLabel:
label: Issue-Docs
- hasLabel:
label: Issue-Feature
- hasLabel:
label: Issue-Question
- hasLabel:
label: Issue-Samples
- hasLabel:
label: Issue-Task
- hasLabel:
label: Issue-Scenario
- or:
- hasLabel:
label: Product-Cmd.exe
- hasLabel:
label: Product-Colortool
- hasLabel:
label: Product-Conhost
- hasLabel:
label: Product-Conpty
- hasLabel:
label: Product-Meta
- hasLabel:
label: Product-Powershell
- hasLabel:
label: Product-Terminal
- hasLabel:
label: Product-WSL
- or:
- isOpen
- and:
- not: isOpen
- or:
- hasLabel:
label: Resolution-Answered
- hasLabel:
label: Resolution-By-Design
- hasLabel:
label: Resolution-Duplicate
- hasLabel:
label: Resolution-External
- hasLabel:
label: Resolution-Fix-Available
- hasLabel:
label: Resolution-Fix-Committed
- hasLabel:
label: Resolution-Won't-Fix
- hasLabel:
label: Tracking-External
then:
- removeLabel:
label: Needs-Tag-Fix
description:
- if:
- payloadType: Pull_Request
then:
- inPrLabel:
label: In-PR
description:
- if:
- payloadType: Issues
- hasLabel:
label: Needs-Tag-Fix
- hasLabel:
label: Resolution-Duplicate
then:
- removeLabel:
label: Needs-Tag-Fix
description:
- if:
- payloadType: Issues
- or:
- titleContains:
pattern: ^\s*Bug Report \(IF I DO NOT CHANGE THIS THE ISSUE WILL BE AUTO-CLOSED\)\s*$
isRegex: True
- titleContains:
pattern: ^\s*Bug Report\s*$
isRegex: True
- or:
- isAction:
action: Opened
- isAction:
action: Reopened
- not:
activitySenderHasPermission:
permission: Write
- not:
activitySenderHasPermission:
permission: Admin
then:
- closeIssue
- addLabel:
label: Needs-Author-Feedback
- addReply:
reply: Hi! Thanks for attempting to open an issue. Unfortunately, your title wasn't changed from the original template which makes it very hard for us to track and triage. You are welcome to fix up the title and try again with a new issue.
description:
- if:
- payloadType: Issues
- or:
- isAction:
action: Opened
- isAction:
action: Reopened
- or:
- not:
bodyContains:
pattern: .+
isRegex: True
then:
- closeIssue
- addLabel:
label: Needs-Author-Feedback
- addReply:
reply: "Hi! Thanks for attempting to open an issue. Unfortunately, you didn't write anything in the body which makes it impossible to understand your concern. You are welcome to fix up the issue and try again by opening another issue with the body filled out. "
description:
- if:
- payloadType: Pull_Request
- isLabeled
- hasLabel:
label: Needs-Second
- isOpen
then:
- requestReview:
reviewer: zadjii-msft
- requestReview:
reviewer: PankajBhojwani
- requestReview:
reviewer: carlos-zamora
- requestReview:
reviewer: dhowett
- requestReview:
reviewer: lhecker
description:
- if:
- payloadType: Pull_Request_Review
- not: isOpen
- hasLabel:
label: Needs-Second
then:
- removeLabel:
label: Needs-Second
description:
- if:
- payloadType: Issues
- hasLabel:
label: In-PR
- hasLabel:
label: Help Wanted
- isLabeled
then:
- removeLabel:
label: Help-Wanted
description:
- if:
- payloadType: Issue_Comment
- commentContains:
pattern: '\/dup(licate|e)?(\s+of)?\s+\#[\d]+'
isRegex: True
- or:
- activitySenderHasPermission:
permission: Admin
- activitySenderHasPermission:
permission: Write
then:
- addReply:
reply: Hi! We've identified this issue as a duplicate of another one that already exists on this Issue Tracker. This specific instance is being closed in favor of tracking the concern over on the referenced thread. Thanks for your report!
- closeIssue
- removeLabel:
label: Needs-Triage
- addLabel:
label: Resolution-Duplicate
- removeLabel:
label: Needs-Tag-Fix
- removeLabel:
label: Needs-Attention
- removeLabel:
label: Needs-Author-Feedback
- removeLabel:
label: Needs-Repro
- removeLabel:
label: Needs-Second
description:
- if:
- payloadType: Issue_Comment
- commentContains:
pattern: '\/feedback'
isRegex: True
- or:
- activitySenderHasPermission:
permission: Admin
- activitySenderHasPermission:
permission: Write
then:
- addReply:
reply: >2-
Hi there!<br><br>Can you please send us feedback with the [Feedback Hub](https://support.microsoft.com/en-us/windows/send-feedback-to-microsoft-with-the-feedback-hub-app-f59187f8-8739-22d6-ba93-f66612949332) with this issue? Make sure to click the "Start recording" button, then reproduce the issue before submitting the feedback. Once it's submitted, paste the link here so we can more easily find your crash information on the back end?<br><br>Thanks!<br><br>![image](https://user-images.githubusercontent.com/18356694/140811502-a068f78b-89d2-4587-925a-73e19652b830.png)<br><br>![image](https://user-images.githubusercontent.com/18356694/140811557-cdc22a0f-fa6a-4f6a-953e-73b51f5548a3.png)<br><br>![image](https://user-images.githubusercontent.com/18221333/62478649-6de55400-b760-11e9-806e-5aab7e085a9f.png)
- addLabel:
label: Needs-Author-Feedback
description:
- if:
- payloadType: Issue_Comment
then:
- cleanEmailReply
description:
- if:
- payloadType: Pull_Request
then:
- labelSync:
pattern: Issue-
- labelSync:
pattern: Area-
- labelSync:
pattern: Priority-
- labelSync:
pattern: Product-
- labelSync:
pattern: Severity-
- labelSync:
pattern: Impact-
description:
- if:
- payloadType: Issue_Comment
- commentContains:
pattern: '\/dup(licate|e)?(\s+of)?\s+https'
isRegex: True
- or:
- activitySenderHasPermission:
permission: Admin
- activitySenderHasPermission:
permission: Write
then:
- addReply:
reply: Hi! We've identified this issue as a duplicate of one that exists on somebody else's Issue Tracker. Please make sure you subscribe to the referenced external issue for future updates. Thanks for your report!
- closeIssue
- removeLabel:
label: Needs-Triage
- addLabel:
label: Resolution-External
- removeLabel:
label: Needs-Attention
- removeLabel:
label: Needs-Author-Feedback
- removeLabel:
label: Needs-Bisect
- removeLabel:
label: Needs-Repro
- removeLabel:
label: Needs-Second
description:
- if:
- payloadType: Issue_Comment
- commentContains:
pattern: /?
isRegex: False
- or:
- activitySenderHasPermission:
permission: Admin
- activitySenderHasPermission:
permission: Write
then:
- removeLabel:
label: Needs-Attention
- addLabel:
label: Needs-Author-Feedback
description:
onFailure:
onSuccess:

View File

@@ -7,6 +7,7 @@ on:
- labeled
- unlabeled
permissions: {}
jobs:
add-to-project:
name: Add issue to project

24
.github/workflows/winget.yml vendored Normal file
View File

@@ -0,0 +1,24 @@
name: Publish to Winget
on:
release:
types: [published]
env:
REGEX: 'Microsoft\.WindowsTerminal(?:Preview)?_([\d.]+)_8wekyb3d8bbwe\.msixbundle$'
jobs:
publish:
runs-on: windows-latest # Action can only run on Windows
steps:
- name: Publish Windows Terminal ${{ github.event.release.prerelease && 'Preview' || 'Stable' }}
run: |
$assets = '${{ toJSON(github.event.release.assets) }}' | ConvertFrom-Json
$wingetRelevantAsset = $assets | Where-Object { $_.name -like '*.msixbundle' } | Select-Object -First 1
$regex = [Regex]::New($env:REGEX)
$version = $regex.Match($wingetRelevantAsset.name).Groups[1].Value
$wingetPackage = "Microsoft.WindowsTerminal${{ github.event.release.prerelease && '.Preview' || '' }}"
& curl.exe -JLO https://aka.ms/wingetcreate/latest
& .\wingetcreate.exe update $wingetPackage -s -v $version -u $wingetRelevantAsset.browser_download_url -t "${{ secrets.WINGET_TOKEN }}"

View File

@@ -6,7 +6,7 @@
"C_Cpp.loggingLevel": "None",
"files.associations": {
"xstring": "cpp",
"*.idl": "cpp",
"*.idl": "midl3",
"array": "cpp",
"future": "cpp",
"istream": "cpp",
@@ -103,7 +103,9 @@
"files.exclude": {
"**/bin/**": true,
"**/obj/**": true,
"**/packages/**": true,
"**/Generated Files/**": true
},
"search.exclude": {
"**/packages/**": true
}
}
}

View File

@@ -101,7 +101,7 @@ If you don't have any additional info/context to add but would like to indicate
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!
The best place to start is the list of ["walkthroughs"](https://aka.ms/terminal-walkthroughs). This is a collection of issues where we've written a "walkthrough", little guides to help get started with a particular issue. These are usually good first issues, and are a great way to get familiar with the codebase. Additionally, the list of ["good first issue"](https://github.com/microsoft/terminal/issues?q=is%3Aopen+is%3Aissue+label%3A%22Help+Wanted%22++label%3A%22good+first+issue%22+)s is another set of issues that might be easier for first-time contributors. 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 any issue you're 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.

View File

@@ -276,41 +276,53 @@ OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>
```
## ConEmu
**Source**: [https://github.com/Maximus5/ConEmu](https://github.com/Maximus5/ConEmu)
## stb
**Source**: [https://github.com/nothings/stb](https://github.com/nothings/stb)
### License
```
BSD 3-Clause License
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
software, either in source code form or as a compiled binary, for any purpose,
commercial or non-commercial, and by any means.
In jurisdictions that recognize copyright laws, the author or authors of this
software dedicate any and all copyright interest in the software to the public
domain. We make this dedication for the benefit of the public at large and to
the detriment of our heirs and successors. We intend this dedication to be an
overt act of relinquishment in perpetuity of all present and future rights to
this software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
```
Copyright (c) 2009-2017, Maximus5 <ConEmu.Maximus5@gmail.com>
All rights reserved.
## Oklab
**Source**: [https://bottosson.github.io/posts/oklab/](https://bottosson.github.io/posts/oklab/)
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
### License
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
```
Copyright (c) 2020 Björn Ottosson
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```
# Microsoft Open Source

File diff suppressed because it is too large Load Diff

View File

@@ -21,7 +21,8 @@ Related repositories include:
## Installing and running Windows Terminal
> **Note**: Windows Terminal requires Windows 10 2004 (build 19041) or later
> **Note**\
> Windows Terminal requires Windows 10 2004 (build 19041) or later
### Microsoft Store [Recommended]
@@ -52,9 +53,10 @@ fails for any reason, you can try the following command at a PowerShell prompt:
Add-AppxPackage Microsoft.WindowsTerminal_<versionNumber>.msixbundle
```
> **Note**: If you install Terminal manually:
> **Note**\
> If you install Terminal manually:
>
> * You may need to install the [VC++ v14 Desktop Framework Package](https://docs.microsoft.com/troubleshoot/cpp/c-runtime-packages-desktop-bridge#how-to-install-and-update-desktop-framework-packages).
> * You may need to install the [VC++ v14 Desktop Framework Package](https://docs.microsoft.com/troubleshoot/cpp/c-runtime-packages-desktop-bridge#how-to-install-and-update-desktop-framework-packages).
> This should only be necessary on older builds of Windows 10 and only if you get an error about missing framework packages.
> * Terminal will not auto-update when new builds are released so you will need
> to regularly install the latest Terminal release to receive all the latest
@@ -70,6 +72,9 @@ package:
winget install --id Microsoft.WindowsTerminal -e
```
> **Note**\
> Due to a dependency issue, Terminal's current versions cannot be installed via the Windows Package Manager CLI. To install the stable release 1.17 or later, or the Preview release 1.18 or later, please use an alternative installation method.
#### Via Chocolatey (unofficial)
[Chocolatey](https://chocolatey.org) users can download and install the latest
@@ -235,7 +240,8 @@ Cause: You're launching the incorrect solution in Visual Studio.
Solution: Make sure you're building & deploying the `CascadiaPackage` project in
Visual Studio.
> **Note**: `OpenConsole.exe` is just a locally-built `conhost.exe`, the classic
> **Note**\
> `OpenConsole.exe` is just a locally-built `conhost.exe`, the classic
> Windows Console that hosts Windows' command-line infrastructure. OpenConsole
> is used by Windows Terminal to connect to and communicate with command-line
> applications (via
@@ -271,10 +277,10 @@ similar open/closed preexisting issues before creating a new issue.**
If you would like to ask a question that you feel doesn't warrant an issue
(yet), please reach out to us via Twitter:
* Kayla Cinnamon, Program Manager:
[@cinnamon\_msft](https://twitter.com/cinnamon_msft)
* Christopher Nguyen, Product Manager:
[@nguyen_dows](https://twitter.com/nguyen_dows)
* Dustin Howett, Engineering Lead: [@dhowett](https://twitter.com/DHowett)
* Mike Griese, Senior Developer: [@zadjii](https://twitter.com/zadjii)
* Mike Griese, Senior Developer: [@zadjii@mastodon.social](https://mastodon.social/@zadjii)
* Carlos Zamora, Developer: [@cazamor_msft](https://twitter.com/cazamor_msft)
* Pankaj Bhojwani, Developer
* Leonard Hecker, Developer: [@LeonardHecker](https://twitter.com/LeonardHecker)

View File

@@ -1,175 +0,0 @@
function GetAzureDevOpsBaseUri
{
Param(
[string]$CollectionUri,
[string]$TeamProject
)
return $CollectionUri + $TeamProject
}
function GetQueryTestRunsUri
{
Param(
[string]$CollectionUri,
[string]$TeamProject,
[string]$BuildUri,
[switch]$IncludeRunDetails
)
if ($IncludeRunDetails)
{
$includeRunDetailsParameter = "&includeRunDetails=true"
}
else
{
$includeRunDetailsParameter = ""
}
$baseUri = GetAzureDevOpsBaseUri -CollectionUri $CollectionUri -TeamProject $TeamProject
$queryUri = "$baseUri/_apis/test/runs?buildUri=$BuildUri$includeRunDetailsParameter&api-version=5.0"
return $queryUri
}
function Get-HelixJobTypeFromTestRun
{
Param ($testRun)
$testRunSingleResultUri = "$($testRun.url)/results?`$top=1&`$skip=0&api-version=5.1"
$singleTestResult = Invoke-RestMethod -Uri $testRunSingleResultUri -Method Get -Headers $azureDevOpsRestApiHeaders
$count = $singleTestResult.value.Length
if($count -eq 0)
{
# If the count is 0, then results have not yet been reported for this run.
# We only care about completed runs with results, so it is ok to just return 'UNKNOWN' for this run.
return "UNKNOWN"
}
else
{
$info = ConvertFrom-Json $singleTestResult.value.comment
$helixJobId = $info.HelixJobId
$job = Invoke-RestMethodWithRetries "https://helix.dot.net/api/2019-06-17/jobs/${helixJobId}?access_token=${HelixAccessToken}"
return $job.Type
}
}
function Append-HelixAccessTokenToUrl
{
Param ([string]$url, [string]$token)
if($url.Contains("?"))
{
$url = "$($url)&access_token=$($token)"
}
else
{
$url = "$($url)?access_token=$($token)"
}
return $url
}
# The Helix Rest api is sometimes unreliable. So we call these apis with retry logic.
# Note: The Azure DevOps apis are stable and do not need to be called with this retry logic.
$helixApiRetries = 0
$helixApiRetriesMax = 10
function Download-StringWithRetries
{
Param ([string]$fileName, [string]$url)
$result = ""
$done = $false
while(!($done))
{
try
{
Write-Host "Downloading $fileName"
$result = (New-Object System.Net.WebClient).DownloadString($url)
$done = $true
}
catch
{
Write-Host "Failed to download $fileName $($PSItem.Exception)"
$helixApiRetries = $helixApiRetries + 1
if($helixApiRetries -lt $helixApiRetriesMax)
{
Write-Host "Sleep and retry download of $fileName"
Start-Sleep 60
}
else
{
throw "Failed to download $fileName"
}
}
}
return $result
}
function Invoke-RestMethodWithRetries
{
Param ([string]$url,$Headers)
$result = @()
$done = $false
while(!($done))
{
try
{
$result = Invoke-RestMethod -Uri $url -Method Get -Headers $Headers
$done = $true
}
catch
{
Write-Host "Failed to invoke Rest method $($PSItem.Exception)"
$helixApiRetries = $helixApiRetries + 1
if($helixApiRetries -lt $helixApiRetriesMax)
{
Write-Host "Sleep and retry invoke"
Start-Sleep 60
}
else
{
throw "Failed to invoke Rest method"
}
}
}
return $result
}
function Download-FileWithRetries
{
Param ([string]$fileurl, [string]$destination)
$done = $false
while(!($done))
{
try
{
Write-Host "Downloading $destination"
$webClient.DownloadFile($fileurl, $destination)
$done = $true
}
catch
{
Write-Host "Failed to download $destination $($PSItem.Exception)"
$helixApiRetries = $helixApiRetries + 1
if($helixApiRetries -lt $helixApiRetriesMax)
{
Write-Host "Sleep and retry download of $destination"
Start-Sleep 60
}
else
{
throw "Failed to download $destination"
}
}
}
}

View File

@@ -20,9 +20,7 @@ Param(
$helixResultsContainerUri = $Env:HELIX_RESULTS_CONTAINER_URI
$helixResultsContainerRsas = $Env:HELIX_RESULTS_CONTAINER_RSAS
$rerunPassesRequiredToAvoidFailure = $env:rerunPassesRequiredToAvoidFailure
Add-Type -Language CSharp -ReferencedAssemblies System.Xml,System.Xml.Linq,System.Runtime.Serialization,System.Runtime.Serialization.Json (Get-Content $PSScriptRoot\HelixTestHelpers.cs -Raw)
$testResultParser = [HelixTestHelpers.TestResultParser]::new($TestNamePrefix, $helixResultsContainerUri, $helixResultsContainerRsas)
$testResultParser.ConvertWttLogToXUnitLog($WttInputPath, $WttSingleRerunInputPath, $WttMultipleRerunInputPath, $XUnitOutputPath, $rerunPassesRequiredToAvoidFailure)
$testResultParser.ConvertWttLogToXUnitLog($WttInputPath, $WttSingleRerunInputPath, $WttMultipleRerunInputPath, $XUnitOutputPath)

View File

@@ -1,112 +0,0 @@
$scriptDirectory = $script:MyInvocation.MyCommand.Path | Split-Path -Parent
# List all processes to aid debugging:
Write-Host "All processes running:"
Get-Process
tasklist /svc
# Add this test directory as an exclusion for Windows Defender
Write-Host "Add $scriptDirectory as Exclusion Path"
Add-MpPreference -ExclusionPath $scriptDirectory
Write-Host "Add $($env:HELIX_CORRELATION_PAYLOAD) as Exclusion Path"
Add-MpPreference -ExclusionPath $env:HELIX_CORRELATION_PAYLOAD
Get-MpPreference
Get-MpComputerStatus
# Minimize all windows:
$shell = New-Object -ComObject "Shell.Application"
$shell.minimizeall()
# Kill any instances of Windows Security Alert:
$windowTitleToMatch = "*Windows Security Alert*"
$procs = Get-Process | Where {$_.MainWindowTitle -like "*Windows Security Alert*"}
foreach ($proc in $procs)
{
Write-Host "Found process with '$windowTitleToMatch' title: $proc"
$proc.Kill();
}
# Kill processes by name that are known to interfere with our tests:
$processNamesToStop = @("Microsoft.Photos", "WinStore.App", "SkypeApp", "SkypeBackgroundHost", "OneDriveSetup", "OneDrive")
foreach($procName in $processNamesToStop)
{
Write-Host "Attempting to kill $procName if it is running"
Stop-Process -ProcessName $procName -Verbose -ErrorAction Ignore
}
Write-Host "All processes running after attempting to kill unwanted processes:"
Get-Process
tasklist /svc
$platform = $env:testbuildplatform
if(!$platform)
{
$platform = "x86"
}
function UninstallApps {
Param([string[]]$appsToUninstall)
foreach($pkgName in $appsToUninstall)
{
foreach($pkg in (Get-AppxPackage $pkgName).PackageFullName)
{
Write-Output "Removing: $pkg"
Remove-AppxPackage $pkg
}
}
}
function UninstallTestApps {
Param([string[]]$appsToUninstall)
foreach($pkgName in $appsToUninstall)
{
foreach($pkg in (Get-AppxPackage $pkgName).PackageFullName)
{
Write-Output "Removing: $pkg"
Remove-AppxPackage $pkg
}
# Sometimes an app can get into a state where it is no longer returned by Get-AppxPackage, but it is still present
# which prevents other versions of the app from being installed.
# To handle this, we can directly call Remove-AppxPackage against the full name of the package. However, without
# Get-AppxPackage to find the PackageFullName, we just have to manually construct the name.
$packageFullName = "$($pkgName)_1.0.0.0_$($platform)__8wekyb3d8bbwe"
Write-Host "Removing $packageFullName if installed"
Remove-AppPackage $packageFullName -ErrorVariable appxerror -ErrorAction SilentlyContinue
if($appxerror)
{
foreach($error in $appxerror)
{
# In most cases, Remove-AppPackage will fail due to the package not being found. Don't treat this as an error.
if(!($error.Exception.Message -match "0x80073CF1"))
{
Write-Error $error
}
}
}
else
{
Write-Host "Successfully removed $packageFullName"
}
}
}
Write-Host "Uninstall AppX packages that are known to cause issues with our tests"
UninstallApps("*Skype*", "*Windows.Photos*")
Write-Host "Uninstall any of our test apps that may have been left over from previous test runs"
UninstallTestApps("NugetPackageTestApp", "NugetPackageTestAppCX", "IXMPTestApp", "MUXControlsTestApp")
Write-Host "Uninstall MUX Framework package that may have been left over from previous test runs"
# We don't want to uninstall all versions of the MUX Framework package, as there may be other apps preinstalled on the system
# that depend on it. We only uninstall the Framework package that corresponds to the version of MUX that we are testing.
[xml]$versionData = (Get-Content "version.props")
$versionMajor = $versionData.GetElementsByTagName("MUXVersionMajor").'#text'
$versionMinor = $versionData.GetElementsByTagName("MUXVersionMinor").'#text'
UninstallApps("Microsoft.UI.Xaml.$versionMajor.$versionMinor")
Get-Process

View File

@@ -1,336 +0,0 @@
[CmdLetBinding()]
Param(
[Parameter(Mandatory = $true)]
[string]$TestFile,
[Parameter(Mandatory = $true)]
[string]$OutputProjFile,
[Parameter(Mandatory = $true)]
[string]$JobTestSuiteName,
[Parameter(Mandatory = $true)]
[string]$TaefPath,
[string]$TaefQuery
)
Class TestCollection
{
[string]$Name
[string]$SetupMethodName
[string]$TeardownMethodName
[System.Collections.Generic.Dictionary[string, string]]$Properties
TestCollection()
{
if ($this.GetType() -eq [TestCollection])
{
throw "This class should never be instantiated directly; it should only be derived from."
}
}
TestCollection([string]$name)
{
$this.Init($name)
}
hidden Init([string]$name)
{
$this.Name = $name
$this.Properties = @{}
}
}
Class Test : TestCollection
{
Test([string]$name)
{
$this.Init($name)
}
}
Class TestClass : TestCollection
{
[System.Collections.Generic.List[Test]]$Tests
TestClass([string]$name)
{
$this.Init($name)
$this.Tests = @{}
}
}
Class TestModule : TestCollection
{
[System.Collections.Generic.List[TestClass]]$TestClasses
TestModule([string]$name)
{
$this.Init($name)
$this.TestClasses = @{}
}
}
function Parse-TestInfo([string]$taefOutput)
{
enum LineType
{
None
TestModule
TestClass
Test
Setup
Teardown
Property
}
[string]$testModuleIndentation = " "
[string]$testClassIndentation = " "
[string]$testIndentation = " "
[string]$setupBeginning = "Setup: "
[string]$teardownBeginning = "Teardown: "
[string]$propertyBeginning = "Property["
function Get-LineType([string]$line)
{
if ($line.Contains($setupBeginning))
{
return [LineType]::Setup;
}
elseif ($line.Contains($teardownBeginning))
{
return [LineType]::Teardown;
}
elseif ($line.Contains($propertyBeginning))
{
return [LineType]::Property;
}
elseif ($line.StartsWith($testModuleIndentation) -and -not $line.StartsWith("$testModuleIndentation "))
{
return [LineType]::TestModule;
}
elseif ($line.StartsWith($testClassIndentation) -and -not $line.StartsWith("$testClassIndentation "))
{
return [LineType]::TestClass;
}
elseif ($line.StartsWith($testIndentation) -and -not $line.StartsWith("$testIndentation "))
{
return [LineType]::Test;
}
else
{
return [LineType]::None;
}
}
[string[]]$lines = $taefOutput.Split(@([Environment]::NewLine, "`n"), [StringSplitOptions]::RemoveEmptyEntries)
[System.Collections.Generic.List[TestModule]]$testModules = @()
[TestModule]$currentTestModule = $null
[TestClass]$currentTestClass = $null
[Test]$currentTest = $null
[TestCollection]$lastTestCollection = $null
foreach ($rawLine in $lines)
{
[LineType]$lineType = (Get-LineType $rawLine)
# We don't need the whitespace around the line anymore, so we'll discard it to make things easier.
[string]$line = $rawLine.Trim()
if ($lineType -eq [LineType]::TestModule)
{
if ($currentTest -ne $null -and $currentTestClass -ne $null)
{
$currentTestClass.Tests.Add($currentTest)
}
if ($currentTestClass -ne $null -and $currentTestModule -ne $null)
{
$currentTestModule.TestClasses.Add($currentTestClass)
}
if ($currentTestModule -ne $null)
{
$testModules.Add($currentTestModule)
}
$currentTestModule = [TestModule]::new($line)
$currentTestClass = $null
$currentTest = $null
$lastTestCollection = $currentTestModule
}
elseif ($lineType -eq [LineType]::TestClass)
{
if ($currentTest -ne $null -and $currentTestClass -ne $null)
{
$currentTestClass.Tests.Add($currentTest)
}
if ($currentTestClass -ne $null -and $currentTestModule -ne $null)
{
$currentTestModule.TestClasses.Add($currentTestClass)
}
$currentTestClass = [TestClass]::new($line)
$currentTest = $null
$lastTestCollection = $currentTestClass
}
elseif ($lineType -eq [LineType]::Test)
{
if ($currentTest -ne $null -and $currentTestClass -ne $null)
{
$currentTestClass.Tests.Add($currentTest)
}
$currentTest = [Test]::new($line)
$lastTestCollection = $currentTest
}
elseif ($lineType -eq [LineType]::Setup)
{
if ($lastTestCollection -ne $null)
{
$lastTestCollection.SetupMethodName = $line.Replace($setupBeginning, "")
}
}
elseif ($lineType -eq [LineType]::Teardown)
{
if ($lastTestCollection -ne $null)
{
$lastTestCollection.TeardownMethodName = $line.Replace($teardownBeginning, "")
}
}
elseif ($lineType -eq [LineType]::Property)
{
if ($lastTestCollection -ne $null)
{
foreach ($match in [Regex]::Matches($line, "Property\[(.*)\]\s+=\s+(.*)"))
{
[string]$propertyKey = $match.Groups[1].Value;
[string]$propertyValue = $match.Groups[2].Value;
$lastTestCollection.Properties.Add($propertyKey, $propertyValue);
}
}
}
}
if ($currentTest -ne $null -and $currentTestClass -ne $null)
{
$currentTestClass.Tests.Add($currentTest)
}
if ($currentTestClass -ne $null -and $currentTestModule -ne $null)
{
$currentTestModule.TestClasses.Add($currentTestClass)
}
if ($currentTestModule -ne $null)
{
$testModules.Add($currentTestModule)
}
return $testModules
}
Write-Verbose "TaefQuery = $TaefQuery"
$TaefSelectQuery = ""
$TaefQueryToAppend = ""
if($TaefQuery)
{
$TaefSelectQuery = "/select:`"$TaefQuery`""
$TaefQueryToAppend = " and $TaefQuery"
}
Write-Verbose "TaefSelectQuery = $TaefSelectQuery"
$taefExe = "$TaefPath\te.exe"
[string]$taefOutput = & "$taefExe" /listproperties $TaefSelectQuery $TestFile | Out-String
[System.Collections.Generic.List[TestModule]]$testModules = (Parse-TestInfo $taefOutput)
$projFileContent = @"
<Project>
<ItemGroup>
"@
foreach ($testModule in $testModules)
{
foreach ($testClass in $testModules.TestClasses)
{
Write-Host "Generating Helix work item for test class $($testClass.Name)..."
[System.Collections.Generic.List[string]]$testSuiteNames = @()
$testSuiteExists = $false
$suitelessTestExists = $false
foreach ($test in $testClass.Tests)
{
# A test method inherits its 'TestSuite' property from its TestClass
if (!$test.Properties.ContainsKey("TestSuite") -and $testClass.Properties.ContainsKey("TestSuite"))
{
$test.Properties["TestSuite"] = $testClass.Properties["TestSuite"]
}
if ($test.Properties.ContainsKey("TestSuite"))
{
[string]$testSuite = $test.Properties["TestSuite"]
if (-not $testSuiteNames.Contains($testSuite))
{
Write-Host " Found test suite $testSuite. Generating Helix work item for it as well."
$testSuiteNames.Add($testSuite)
}
$testSuiteExists = $true
}
else
{
$suitelessTestExists = $true
}
}
$testClassSelectPattern = "$($testClass.Name).*"
if($testClass.Name.Contains("::"))
{
$testClassSelectPattern = "$($testClass.Name)::*"
}
$testNameQuery= "(@Name='$testClassSelectPattern')"
$workItemName = $testClass.Name
# Native tests use '::' as a separator, which is not valid for workItem names.
$workItemName = $workItemName -replace "::", "-"
if ($suitelessTestExists)
{
$projFileContent += @"
<HelixWorkItem Include="$($workItemName)" Condition="'`$(TestSuite)'=='$($JobTestSuiteName)'">
<Timeout>00:30:00</Timeout>
<Command>call %HELIX_CORRELATION_PAYLOAD%\runtests.cmd /select:"(@Name='$($testClass.Name)*'$(if ($testSuiteExists) { "and not @TestSuite='*'" }))$($TaefQueryToAppend)"</Command>
</HelixWorkItem>
"@
}
foreach ($testSuiteName in $testSuiteNames)
{
$projFileContent += @"
<HelixWorkItem Include="$($workItemName)-$testSuiteName" Condition="'`$(TestSuite)'=='$($JobTestSuiteName)'">
<Timeout>00:30:00</Timeout>
<Command>call %HELIX_CORRELATION_PAYLOAD%\runtests.cmd /select:"(@Name='$($testClass.Name)*' and @TestSuite='$testSuiteName')$($TaefQueryToAppend)"</Command>
</HelixWorkItem>
"@
}
}
}
$projFileContent += @"
</ItemGroup>
</Project>
"@
Set-Content $OutputProjFile $projFileContent -NoNewline -Encoding UTF8

View File

@@ -20,32 +20,13 @@ namespace HelixTestHelpers
public string Name { get; set; }
public string SourceWttFile { get; set; }
public bool Passed { get; set; }
public bool Skipped { get; set; }
public bool CleanupPassed { get; set; }
public TimeSpan ExecutionTime { get; set; }
public string Details { get; set; }
public List<string> Screenshots { get; private set; }
public List<TestResult> RerunResults { get; private set; }
// Returns true if the test pass rate is sufficient to avoid being counted as a failure.
public bool PassedOrUnreliable(int requiredNumberOfPasses)
{
if(Passed)
{
return true;
}
else
{
if(RerunResults.Count == 1)
{
return RerunResults[0].Passed;
}
else
{
return RerunResults.Where(r => r.Passed).Count() >= requiredNumberOfPasses;
}
}
}
}
//
@@ -221,7 +202,9 @@ namespace HelixTestHelpers
testsExecuting--;
// If any inner test fails, we'll still fail the outer
currentResult.Passed &= element.Attribute("Result").Value == "Pass";
var value = element.Attribute("Result").Value;
currentResult.Passed = value == "Pass";
currentResult.Skipped = value == "Skipped";
// Only gather execution data if this is the outer test we ran initially
if (testsExecuting == 0)
@@ -498,7 +481,7 @@ namespace HelixTestHelpers
return subResultsJsonByMethod;
}
public void ConvertWttLogToXUnitLog(string wttInputPath, string wttSingleRerunInputPath, string wttMultipleRerunInputPath, string xunitOutputPath, int requiredPassRateThreshold)
public void ConvertWttLogToXUnitLog(string wttInputPath, string wttSingleRerunInputPath, string wttMultipleRerunInputPath, string xunitOutputPath)
{
TestPass testPass = TestPass.ParseTestWttFileWithReruns(wttInputPath, wttSingleRerunInputPath, wttMultipleRerunInputPath, cleanupFailuresAreRegressions: true, truncateTestNames: false);
var results = testPass.TestResults;
@@ -510,8 +493,8 @@ namespace HelixTestHelpers
// If the test failed sufficiently often enough for it to count as a failed test (determined by a property on the
// Azure DevOps job), we'll later mark it as failed during test results processing.
int failedCount = results.Where(r => !r.PassedOrUnreliable(requiredPassRateThreshold)).Count();
int skippedCount = results.Where(r => !r.Passed && r.PassedOrUnreliable(requiredPassRateThreshold)).Count();
int failedCount = results.Where(r => !r.Passed).Count();
int skippedCount = results.Where(r => (!r.Passed && r.Skipped)).Count();
var root = new XElement("assemblies");
@@ -557,12 +540,13 @@ namespace HelixTestHelpers
string resultString = string.Empty;
if (result.Passed)
if (result.Passed && !result.Skipped)
{
resultString = "Pass";
}
else if(result.PassedOrUnreliable(requiredPassRateThreshold))
else if (result.Skipped)
{
resultString = "Skip";
}
else
@@ -571,31 +555,25 @@ namespace HelixTestHelpers
}
test.SetAttributeValue("result", resultString);
if (!result.Passed)
{
// If a test failed, we'll have rerun it multiple times.
// We'll save the subresults to a JSON text file that we'll upload to the helix results container -
// this allows it to be as long as we want, whereas the reason field in Azure DevOps has a 4000 character limit.
string subResultsFileName = methodName + "_subresults.json";
string subResultsFilePath = Path.Combine(Path.GetDirectoryName(wttInputPath), subResultsFileName);
if (result.PassedOrUnreliable(requiredPassRateThreshold))
if (result.Skipped)
{
var reason = new XElement("reason");
reason.Add(new XCData(GetUploadedFileUrl(subResultsFileName, helixResultsContainerUri, helixResultsContainerRsas)));
reason.Add(new XCData("Test skipped"));
test.Add(reason);
}
else
{
else {
var failure = new XElement("failure");
var message = new XElement("message");
message.Add(new XCData(GetUploadedFileUrl(subResultsFileName, helixResultsContainerUri, helixResultsContainerRsas)));
message.Add(new XCData("Test failed"));
failure.Add(message);
test.Add(failure);
}
}
test.SetAttributeValue("result", resultString);
collection.Add(test);
}

View File

@@ -1,12 +0,0 @@
# Displaying progress is unnecessary and is just distracting.
$ProgressPreference = "SilentlyContinue"
$dependencyFiles = Get-ChildItem -Filter "*Microsoft.VCLibs.*.appx"
foreach ($file in $dependencyFiles)
{
Write-Host "Adding dependency $($file)..."
Add-AppxPackage $file
}

View File

@@ -1,8 +0,0 @@
Param(
[Parameter(Mandatory = $true)]
[string]$WttInputPath
)
Add-Type -Language CSharp -ReferencedAssemblies System.Xml,System.Xml.Linq,System.Runtime.Serialization,System.Runtime.Serialization.Json (Get-Content $PSScriptRoot\HelixTestHelpers.cs -Raw)
[HelixTestHelpers.FailedTestDetector]::OutputFailedTestQuery($WttInputPath)

View File

@@ -1,32 +0,0 @@
Param(
[Parameter(Mandatory = $true)]
[string]$WttInputPath,
[Parameter(Mandatory = $true)]
[string]$WttSingleRerunInputPath,
[Parameter(Mandatory = $true)]
[string]$WttMultipleRerunInputPath,
[Parameter(Mandatory = $true)]
[string]$TestNamePrefix
)
# Ideally these would be passed as parameters to the script. However ps makes it difficult to deal with string literals containing '&', so we just
# read the values directly from the environment variables
$helixResultsContainerUri = $Env:HELIX_RESULTS_CONTAINER_URI
$helixResultsContainerRsas = $Env:HELIX_RESULTS_CONTAINER_RSAS
Add-Type -Language CSharp -ReferencedAssemblies System.Xml,System.Xml.Linq,System.Runtime.Serialization,System.Runtime.Serialization.Json (Get-Content $PSScriptRoot\HelixTestHelpers.cs -Raw)
$testResultParser = [HelixTestHelpers.TestResultParser]::new($TestNamePrefix, $helixResultsContainerUri, $helixResultsContainerRsas)
[System.Collections.Generic.Dictionary[string, string]]$subResultsJsonByMethodName = $testResultParser.GetSubResultsJsonByMethodName($WttInputPath, $WttSingleRerunInputPath, $WttMultipleRerunInputPath)
$subResultsJsonDirectory = [System.IO.Path]::GetDirectoryName($WttInputPath)
foreach ($methodName in $subResultsJsonByMethodName.Keys)
{
$subResultsJson = $subResultsJsonByMethodName[$methodName]
$subResultsJsonPath = [System.IO.Path]::Combine($subResultsJsonDirectory, $methodName + "_subresults.json")
Out-File $subResultsJsonPath -Encoding utf8 -InputObject $subResultsJson
}

View File

@@ -0,0 +1,38 @@
Param(
[Parameter(Mandatory = $true)]
[string]$XUnitOutputPath
)
# This script is used to parse the XUnit output from the test runs and print out
# the tests that failed.
#
# Why you might ask? Well, it sure seems like Azure DevOps doesn't like the fact
# that we just call our tests in a powershell script. It can't seemingly find
# the actual errors in the TAEF logs. That means when you just go to the
# "Checks" page on GitHub, the Azure DevOps integration doesn't have anything
# meaningful to say other than "PowerShell exited with code '1'". If we however,
# just manually emit the test names formatted with "#[error]" in front of them,
# well, then the integration will all work like magic.
# Load the test results as a XML object
$testResults = [xml](Get-Content -Path $XUnitOutputPath)
# Our XML looks like:
# <assemblies>
# <assembly name="MUXControls.Test.dll" test-framework="TAEF" run-date="2023-08-14" run-time="11:38:01" total="524" passed="520" failed="4" skipped="1" time="8943" errors="0">
# <collection total="524" passed="520" failed="4" skipped="1" name="Test collection" time="8943">
# <test name="ControlCoreTests::TestSimpleClickSelection" type="ControlCoreTests" method="TestSimpleClickSelection" time="0.016" result="Fail">
# Iterate over all the assemblies and print all the tests that failed
foreach ($assembly in $testResults.assemblies.assembly) {
foreach ($collection in $assembly.collection) {
foreach ($test in $collection.test) {
if ($test.result -eq "Fail") {
# This particular format is taken from the Azure DevOps documentation:
# https://github.com/microsoft/azure-pipelines-tasks/blob/master/docs/authoring/commands.md
# This will treat this line as an error message
Write-Output "##vso[task.logissue type=error]$($test.name) Failed"
}
}
}
}

View File

@@ -1,131 +0,0 @@
Param(
[Parameter(Mandatory = $true)]
[int]$MinimumExpectedTestsExecutedCount,
[string]$AccessToken = $env:SYSTEM_ACCESSTOKEN,
[string]$CollectionUri = $env:SYSTEM_COLLECTIONURI,
[string]$TeamProject = $env:SYSTEM_TEAMPROJECT,
[string]$BuildUri = $env:BUILD_BUILDURI,
[bool]$CheckJobAttempt
)
$azureDevOpsRestApiHeaders = @{
"Accept"="application/json"
"Authorization"="Basic $([System.Convert]::ToBase64String([System.Text.ASCIIEncoding]::ASCII.GetBytes(":$AccessToken")))"
}
. "$PSScriptRoot/AzurePipelinesHelperScripts.ps1"
Write-Host "Checking test results..."
$queryUri = GetQueryTestRunsUri -CollectionUri $CollectionUri -TeamProject $TeamProject -BuildUri $BuildUri -IncludeRunDetails
Write-Host "queryUri = $queryUri"
$testRuns = Invoke-RestMethodWithRetries $queryUri -Headers $azureDevOpsRestApiHeaders
[System.Collections.Generic.List[string]]$failingTests = @()
[System.Collections.Generic.List[string]]$unreliableTests = @()
[System.Collections.Generic.List[string]]$unexpectedResultTest = @()
[System.Collections.Generic.List[string]]$namesOfProcessedTestRuns = @()
$totalTestsExecutedCount = 0
# We assume that we only have one testRun with a given name that we care about
# We only process the last testRun with a given name (based on completedDate)
# The name of a testRun is set to the Helix queue that it was run on (e.g. windows.10.amd64.client21h1.xaml)
# If we have multiple test runs on the same queue that we care about, we will need to re-visit this logic
foreach ($testRun in ($testRuns.value | Sort-Object -Property "completedDate" -Descending))
{
if ($CheckJobAttempt)
{
if ($namesOfProcessedTestRuns -contains $testRun.name)
{
Write-Host "Skipping test run '$($testRun.name)', since we have already processed a test run of that name."
continue
}
}
Write-Host "Processing results from test run '$($testRun.name)'"
$namesOfProcessedTestRuns.Add($testRun.name)
$totalTestsExecutedCount += $testRun.totalTests
$testRunResultsUri = "$($testRun.url)/results?api-version=5.0"
$testResults = Invoke-RestMethodWithRetries "$($testRun.url)/results?api-version=5.0" -Headers $azureDevOpsRestApiHeaders
foreach ($testResult in $testResults.value)
{
$shortTestCaseTitle = $testResult.testCaseTitle -replace "[a-zA-Z0-9]+.[a-zA-Z0-9]+.Windows.UI.Xaml.Tests.MUXControls.",""
if ($testResult.outcome -eq "Failed")
{
if (-not $failingTests.Contains($shortTestCaseTitle))
{
$failingTests.Add($shortTestCaseTitle)
}
}
elseif ($testResult.outcome -eq "Warning")
{
if (-not $unreliableTests.Contains($shortTestCaseTitle))
{
$unreliableTests.Add($shortTestCaseTitle)
}
}
elseif ($testResult.outcome -ne "Passed")
{
# We should only see tests with result "Passed", "Failed" or "Warning"
if (-not $unexpectedResultTest.Contains($shortTestCaseTitle))
{
$unexpectedResultTest.Add($shortTestCaseTitle)
}
}
}
}
if ($unreliableTests.Count -gt 0)
{
Write-Host @"
##vso[task.logissue type=warning;]Unreliable tests:
##vso[task.logissue type=warning;]$($unreliableTests -join "$([Environment]::NewLine)##vso[task.logissue type=warning;]")
"@
}
if ($failingTests.Count -gt 0)
{
Write-Host @"
##vso[task.logissue type=error;]Failing tests:
##vso[task.logissue type=error;]$($failingTests -join "$([Environment]::NewLine)##vso[task.logissue type=error;]")
"@
}
if ($unexpectedResultTest.Count -gt 0)
{
Write-Host @"
##vso[task.logissue type=error;]Tests with unexpected results:
##vso[task.logissue type=error;]$($unexpectedResultTest -join "$([Environment]::NewLine)##vso[task.logissue type=error;]")
"@
}
if($totalTestsExecutedCount -lt $MinimumExpectedTestsExecutedCount)
{
Write-Host "Expected at least $MinimumExpectedTestsExecutedCount tests to be executed."
Write-Host "Actual executed test count is: $totalTestsExecutedCount"
Write-Host "##vso[task.complete result=Failed;]"
}
elseif ($failingTests.Count -gt 0)
{
Write-Host "At least one test failed."
Write-Host "##vso[task.complete result=Failed;]"
}
elseif ($unreliableTests.Count -gt 0)
{
Write-Host "All tests eventually passed, but some initially failed."
Write-Host "##vso[task.complete result=Succeeded;]"
}
else
{
Write-Host "All tests passed."
Write-Host "##vso[task.complete result=Succeeded;]"
}

View File

@@ -1,68 +0,0 @@
[CmdLetBinding()]
Param(
[string]$Platform,
[string]$Configuration,
[string]$ArtifactName='drop'
)
$payloadDir = "HelixPayload\$Configuration\$Platform"
$repoDirectory = Join-Path (Split-Path -Parent $script:MyInvocation.MyCommand.Path) "..\..\"
$nugetPackagesDir = Join-Path (Split-Path -Parent $script:MyInvocation.MyCommand.Path) "packages"
# Create the payload directory. Remove it if it already exists.
If(test-path $payloadDir)
{
Remove-Item $payloadDir -Recurse
}
New-Item -ItemType Directory -Force -Path $payloadDir
# Copy files from nuget packages
Copy-Item "$nugetPackagesDir\microsoft.windows.apps.test.1.0.181203002\lib\netcoreapp2.1\*.dll" $payloadDir
Copy-Item "$nugetPackagesDir\Microsoft.Taef.10.60.210621002\build\Binaries\$Platform\*" $payloadDir
Copy-Item "$nugetPackagesDir\Microsoft.Taef.10.60.210621002\build\Binaries\$Platform\NetFx4.5\*" $payloadDir
New-Item -ItemType Directory -Force -Path "$payloadDir\.NETCoreApp2.1\"
Copy-Item "$nugetPackagesDir\runtime.win-$Platform.microsoft.netcore.app.2.1.0\runtimes\win-$Platform\lib\netcoreapp2.1\*" "$payloadDir\.NETCoreApp2.1\"
Copy-Item "$nugetPackagesDir\runtime.win-$Platform.microsoft.netcore.app.2.1.0\runtimes\win-$Platform\native\*" "$payloadDir\.NETCoreApp2.1\"
New-Item -ItemType Directory -Force -Path "$payloadDir\content\"
Copy-Item "$nugetPackagesDir\Microsoft.Internal.Windows.Terminal.TestContent.1.0.1\content\*" "$payloadDir\content\"
function Copy-If-Exists
{
Param($source, $destinationDir)
if (Test-Path $source)
{
Write-Host "Copy from '$source' to '$destinationDir'"
Copy-Item -Force $source $destinationDir
}
else
{
Write-Host "'$source' does not exist."
}
}
# Copy files from the 'drop' artifact dir
Copy-Item "$repoDirectory\Artifacts\$ArtifactName\$Configuration\$Platform\Test\*" $payloadDir -Recurse
# Copy files from the repo
New-Item -ItemType Directory -Force -Path "$payloadDir"
Copy-Item "build\helix\ConvertWttLogToXUnit.ps1" "$payloadDir"
Copy-Item "build\helix\OutputFailedTestQuery.ps1" "$payloadDir"
Copy-Item "build\helix\OutputSubResultsJsonFiles.ps1" "$payloadDir"
Copy-Item "build\helix\HelixTestHelpers.cs" "$payloadDir"
Copy-Item "build\helix\runtests.cmd" $payloadDir
Copy-Item "build\helix\InstallTestAppDependencies.ps1" "$payloadDir"
Copy-Item "build\Helix\EnsureMachineState.ps1" "$payloadDir"
# Copy the APPX package from the 'drop' artifact dir and Windows Kits
Copy-Item "$repoDirectory\Artifacts\$ArtifactName\appx\CascadiaPackage_0.0.1.0_$Platform.msix" $payloadDir\CascadiaPackage.zip
Copy-Item "C:\program files (x86)\Microsoft SDKs\Windows Kits\10\ExtensionSDKs\Microsoft.VCLibs.Desktop\14.0\Appx\Retail\x64\Microsoft.VCLibs.x64.14.00.Desktop.appx" $payloadDir\VCLibs.zip
# Rename it to extension of ZIP because Expand-Archive is real sassy on the build machines
# and refuses to unzip it because of its file extension while on a desktop, it just
# does the job without complaining.
# Extract the APPX package
Expand-Archive -LiteralPath $payloadDir\CascadiaPackage.zip -DestinationPath $payloadDir\appx
Expand-Archive -LiteralPath $payloadDir\VCLibs.zip -DestinationPath $payloadDir\appx -Force

View File

@@ -1,130 +0,0 @@
Param(
[string]$AccessToken = $env:SYSTEM_ACCESSTOKEN,
[string]$HelixAccessToken = $env:HelixAccessToken,
[string]$CollectionUri = $env:SYSTEM_COLLECTIONURI,
[string]$TeamProject = $env:SYSTEM_TEAMPROJECT,
[string]$BuildUri = $env:BUILD_BUILDURI,
[string]$OutputFolder = "HelixOutput"
)
$helixLinkFile = "$OutputFolder\LinksToHelixTestFiles.html"
function Generate-File-Links
{
Param ([Array[]]$files,[string]$sectionName)
if($files.Count -gt 0)
{
Out-File -FilePath $helixLinkFile -Append -InputObject "<div class=$sectionName>"
Out-File -FilePath $helixLinkFile -Append -InputObject "<h4>$sectionName</h4>"
Out-File -FilePath $helixLinkFile -Append -InputObject "<ul>"
foreach($file in $files)
{
$url = Append-HelixAccessTokenToUrl $file.Link "{Your-Helix-Access-Token-Here}"
Out-File -FilePath $helixLinkFile -Append -InputObject "<li>$($url)</li>"
}
Out-File -FilePath $helixLinkFile -Append -InputObject "</ul>"
Out-File -FilePath $helixLinkFile -Append -InputObject "</div>"
}
}
function Append-HelixAccessTokenToUrl
{
Param ([string]$url, [string]$token)
if($token)
{
if($url.Contains("?"))
{
$url = "$($url)&access_token=$($token)"
}
else
{
$url = "$($url)?access_token=$($token)"
}
}
return $url
}
#Create output directory
New-Item $OutputFolder -ItemType Directory
$azureDevOpsRestApiHeaders = @{
"Accept"="application/json"
"Authorization"="Basic $([System.Convert]::ToBase64String([System.Text.ASCIIEncoding]::ASCII.GetBytes(":$AccessToken")))"
}
. "$PSScriptRoot/AzurePipelinesHelperScripts.ps1"
$queryUri = GetQueryTestRunsUri -CollectionUri $CollectionUri -TeamProject $TeamProject -BuildUri $BuildUri -IncludeRunDetails
Write-Host "queryUri = $queryUri"
$testRuns = Invoke-RestMethodWithRetries $queryUri -Headers $azureDevOpsRestApiHeaders
$webClient = New-Object System.Net.WebClient
[System.Collections.Generic.List[string]]$workItems = @()
foreach ($testRun in $testRuns.value)
{
Write-Host "testRunUri = $testRun.url"
$testResults = Invoke-RestMethodWithRetries "$($testRun.url)/results?api-version=5.0" -Headers $azureDevOpsRestApiHeaders
$isTestRunNameShown = $false
foreach ($testResult in $testResults.value)
{
$info = ConvertFrom-Json $testResult.comment
$helixJobId = $info.HelixJobId
$helixWorkItemName = $info.HelixWorkItemName
$workItem = "$helixJobId-$helixWorkItemName"
Write-Host "Helix Work Item = $workItem"
if (-not $workItems.Contains($workItem))
{
$workItems.Add($workItem)
$filesQueryUri = "https://helix.dot.net/api/2019-06-17/jobs/$helixJobId/workitems/$helixWorkItemName/files"
$filesQueryUri = Append-HelixAccessTokenToUrl $filesQueryUri $helixAccessToken
$files = Invoke-RestMethodWithRetries $filesQueryUri
$screenShots = $files | where { $_.Name.EndsWith(".jpg") }
$dumps = $files | where { $_.Name.EndsWith(".dmp") }
$pgcFiles = $files | where { $_.Name.EndsWith(".pgc") }
if ($screenShots.Count + $dumps.Count + $pgcFiles.Count -gt 0)
{
if(-Not $isTestRunNameShown)
{
Out-File -FilePath $helixLinkFile -Append -InputObject "<h2>$($testRun.name)</h2>"
$isTestRunNameShown = $true
}
Out-File -FilePath $helixLinkFile -Append -InputObject "<h3>$helixWorkItemName</h3>"
Generate-File-Links $screenShots "Screenshots"
Generate-File-Links $dumps "CrashDumps"
Generate-File-Links $pgcFiles "PGC files"
$misc = $files | where { ($screenShots -NotContains $_) -And ($dumps -NotContains $_) -And ($visualTreeVerificationFiles -NotContains $_) -And ($pgcFiles -NotContains $_) }
Generate-File-Links $misc "Misc"
foreach($pgcFile in $pgcFiles)
{
$flavorPath = $testResult.automatedTestName.Split('.')[0]
$archPath = $testResult.automatedTestName.Split('.')[1]
$fileName = $pgcFile.Name
$fullPath = "$OutputFolder\PGO\$flavorPath\$archPath"
$destination = "$fullPath\$fileName"
Write-Host "Copying $($pgcFile.Name) to $destination"
if (-Not (Test-Path $fullPath))
{
New-Item $fullPath -ItemType Directory
}
$link = $pgcFile.Link
Write-Host "Downloading $link to $destination"
$link = Append-HelixAccessTokenToUrl $link $HelixAccessToken
Download-FileWithRetries $link $destination
}
}
}
}
}

View File

@@ -1,20 +0,0 @@
<Project Sdk="Microsoft.DotNet.Helix.Sdk" DefaultTargets="Test">
<PropertyGroup>
<HelixSource>pr/terminal/$(BUILD_SOURCEBRANCH)/</HelixSource>
<EnableXUnitReporter>true</EnableXUnitReporter>
<EnableAzurePipelinesReporter>true</EnableAzurePipelinesReporter>
<FailOnMissionControlTestFailure>true</FailOnMissionControlTestFailure>
<HelixPreCommands>$(HelixPreCommands);set testnameprefix=$(Configuration).$(Platform);set testbuildplatform=$(Platform);set rerunPassesRequiredToAvoidFailure=$(rerunPassesRequiredToAvoidFailure)</HelixPreCommands>
<OutputPath>..\..\bin\$(Platform)\$(Configuration)\</OutputPath>
</PropertyGroup>
<ItemGroup>
<HelixCorrelationPayload Include="..\..\HelixPayload\$(Configuration)\$(Platform)" />
</ItemGroup>
<!-- These .proj files are generated by the build machine prior to running tests via GenerateTestProjFile.ps1. -->
<Import Project="$(ProjFilesPath)\$(Configuration)\$(Platform)\RunTestsInHelix-TerminalAppLocalTests.proj" Condition=" '$(TestSuite)'=='DevTestSuite' " />
<Import Project="$(ProjFilesPath)\$(Configuration)\$(Platform)\RunTestsInHelix-SettingsModelLocalTests.proj" Condition=" '$(TestSuite)'=='DevTestSuite' " />
<Import Project="$(ProjFilesPath)\$(Configuration)\$(Platform)\RunTestsInHelix-HostTestsUIA.proj" Condition=" '$(TestSuite)'=='DevTestSuite' " />
<Import Project="$(ProjFilesPath)\$(Configuration)\$(Platform)\RunTestsInHelix-WindowsTerminalUIATests.proj" Condition=" '$(TestSuite)'=='PgoInstrumentationSuite' " />
</Project>

View File

@@ -1,136 +0,0 @@
[CmdLetBinding()]
Param(
[Parameter(Mandatory = $true)]
[int]$RerunPassesRequiredToAvoidFailure,
[string]$AccessToken = $env:SYSTEM_ACCESSTOKEN,
[string]$CollectionUri = $env:SYSTEM_COLLECTIONURI,
[string]$TeamProject = $env:SYSTEM_TEAMPROJECT,
[string]$BuildUri = $env:BUILD_BUILDURI
)
. "$PSScriptRoot/AzurePipelinesHelperScripts.ps1"
$azureDevOpsRestApiHeaders = @{
"Accept"="application/json"
"Authorization"="Basic $([System.Convert]::ToBase64String([System.Text.ASCIIEncoding]::ASCII.GetBytes(":$AccessToken")))"
}
$queryUri = GetQueryTestRunsUri -CollectionUri $CollectionUri -TeamProject $TeamProject -BuildUri $BuildUri
Write-Host "queryUri = $queryUri"
# To account for unreliable tests, we'll iterate through all of the tests associated with this build, check to see any tests that were unreliable
# (denoted by being marked as "skipped"), and if so, we'll instead mark those tests with a warning and enumerate all of the attempted runs
# with their pass/fail states as well as any relevant error messages for failed attempts.
$testRuns = Invoke-RestMethodWithRetries $queryUri -Headers $azureDevOpsRestApiHeaders
$timesSeenByRunName = @{}
foreach ($testRun in $testRuns.value)
{
$testRunResultsUri = "$($testRun.url)/results?api-version=5.0"
Write-Host "Marking test run `"$($testRun.name)`" as in progress so we can change its results to account for unreliable tests."
Invoke-RestMethod "$($testRun.url)?api-version=5.0" -Method Patch -Body (ConvertTo-Json @{ "state" = "InProgress" }) -Headers $azureDevOpsRestApiHeaders -ContentType "application/json" | Out-Null
Write-Host "Retrieving test results..."
$testResults = Invoke-RestMethodWithRetries $testRunResultsUri -Headers $azureDevOpsRestApiHeaders
foreach ($testResult in $testResults.value)
{
$testNeedsSubResultProcessing = $false
if ($testResult.outcome -eq "NotExecuted")
{
$testNeedsSubResultProcessing = $true
}
elseif($testResult.outcome -eq "Failed")
{
$testNeedsSubResultProcessing = $testResult.errorMessage -like "*_subresults.json*"
}
if ($testNeedsSubResultProcessing)
{
Write-Host " Test $($testResult.testCaseTitle) was detected as unreliable. Updating..."
# The errorMessage field contains a link to the JSON-encoded rerun result data.
$resultsJson = Download-StringWithRetries "Error results" $testResult.errorMessage
$rerunResults = ConvertFrom-Json $resultsJson
[System.Collections.Generic.List[System.Collections.Hashtable]]$rerunDataList = @()
$attemptCount = 0
$passCount = 0
$totalDuration = 0
foreach ($rerun in $rerunResults.results)
{
$rerunData = @{
"displayName" = "Attempt #$($attemptCount + 1) - $($testResult.testCaseTitle)";
"durationInMs" = $rerun.duration;
"outcome" = $rerun.outcome;
}
if ($rerun.outcome -eq "Passed")
{
$passCount++
}
if ($attemptCount -gt 0)
{
$rerunData["sequenceId"] = $attemptCount
}
Write-Host " Attempt #$($attemptCount + 1): $($rerun.outcome)"
if ($rerun.outcome -ne "Passed")
{
$screenshots = "$($rerunResults.blobPrefix)/$($rerun.screenshots -join @"
$($rerunResults.blobSuffix)
$($rerunResults.blobPrefix)
"@)$($rerunResults.blobSuffix)"
# We subtract 1 from the error index because we added 1 so we could use 0
# as a default value not injected into the JSON in order to keep its size down.
# We did this because there's a maximum size enforced for the errorMessage parameter
# in the Azure DevOps REST API.
$fullErrorMessage = @"
Log: $($rerunResults.blobPrefix)/$($rerun.log)$($rerunResults.blobSuffix)
Screenshots:
$screenshots
Error log:
$($rerunResults.errors[$rerun.errorIndex - 1])
"@
$rerunData["errorMessage"] = $fullErrorMessage
}
$attemptCount++
$totalDuration += $rerun.duration
$rerunDataList.Add($rerunData)
}
$overallOutcome = "Warning"
if ($attemptCount -eq 2)
{
Write-Host " Test $($testResult.testCaseTitle) passed on the immediate rerun, so we'll mark it as unreliable."
}
elseif ($passCount -gt $RerunPassesRequiredToAvoidFailure)
{
Write-Host " Test $($testResult.testCaseTitle) passed on $passCount of $attemptCount attempts, which is greater than or equal to the $RerunPassesRequiredToAvoidFailure passes required to avoid being marked as failed. Marking as unreliable."
}
else
{
Write-Host " Test $($testResult.testCaseTitle) passed on only $passCount of $attemptCount attempts, which is less than the $RerunPassesRequiredToAvoidFailure passes required to avoid being marked as failed. Marking as failed."
$overallOutcome = "Failed"
}
$updateBody = ConvertTo-Json @(@{ "id" = $testResult.id; "outcome" = $overallOutcome; "errorMessage" = " "; "durationInMs" = $totalDuration; "subResults" = $rerunDataList; "resultGroupType" = "rerun" }) -Depth 5
Invoke-RestMethod -Uri $testRunResultsUri -Method Patch -Headers $azureDevOpsRestApiHeaders -Body $updateBody -ContentType "application/json" | Out-Null
}
}
Write-Host "Finished updates. Re-marking test run `"$($testRun.name)`" as completed."
Invoke-RestMethod -Uri "$($testRun.url)?api-version=5.0" -Method Patch -Body (ConvertTo-Json @{ "state" = "Completed" }) -Headers $azureDevOpsRestApiHeaders -ContentType "application/json" | Out-Null
}

View File

@@ -1,5 +0,0 @@
{
"msbuild-sdks": {
"Microsoft.DotNet.Helix.Sdk": "6.0.0-beta.22525.5"
}
}

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="MUXCustomBuildTasks" version="1.0.48" targetFramework="native" />
<package id="Microsoft.Internal.Windows.Terminal.TestContent" version="1.0.1" />
<package id="Microsoft.Taef" version="10.60.210621002" targetFramework="native" />
<package id="microsoft.windows.apps.test" version="1.0.181203002" targetFramework="native" />
<package id="runtime.win-x86.microsoft.netcore.app" version="2.1.0" targetFramework="native" />
<package id="runtime.win-x64.microsoft.netcore.app" version="2.1.0" targetFramework="native" />
</packages>

View File

@@ -1,32 +0,0 @@
This directory contains code and configuration files to run WinUI tests in Helix.
Helix is a cloud hosted test execution environment which is accessed via the Arcade SDK.
More details:
* [Arcade](https://github.com/dotnet/arcade)
* [Helix](https://github.com/dotnet/arcade/tree/master/src/Microsoft.DotNet.Helix/Sdk)
WinUI tests are scheduled in Helix by the Azure DevOps Pipeline: [RunHelixTests.yml](../RunHelixTests.yml).
The workflow is as follows:
1. NuGet Restore is called on the packages.config in this directory. This downloads any runtime dependencies
that are needed to run tests.
2. PrepareHelixPayload.ps1 is called. This copies the necessary files from various locations into a Helix
payload directory. This directory is what will get sent to the Helix machines.
3. RunTestsInHelix.proj is executed. This proj has a dependency on
[Microsoft.DotNet.Helix.Sdk](https://github.com/dotnet/arcade/tree/master/src/Microsoft.DotNet.Helix/Sdk)
which it uses to publish the Helix payload directory and to schedule the Helix Work Items. The WinUI tests
are parallelized into multiple Helix Work Items.
4. Each Helix Work Item calls [runtests.cmd](runtests.cmd) with a specific query to pass to
[TAEF](https://docs.microsoft.com/en-us/windows-hardware/drivers/taef/) which runs the tests.
5. If a test is detected to have failed, we run it again, first once, then eight more times if it fails again.
If it fails all ten times, we report the test as failed; otherwise, we report it as unreliable,
which will show up as a warning, but which will not fail the build. When a test is reported as unreliable,
we include the results for each individual run via a JSON string in the original test's errorMessage field.
6. TAEF produces logs in WTT format. Helix is able to process logs in XUnit format. We run
[ConvertWttLogToXUnit.ps1](ConvertWttLogToXUnit.ps1) to convert the logs into the necessary format.
7. RunTestsInHelix.proj has EnableAzurePipelinesReporter set to true. This allows the XUnit formatted test
results to be reported back to the Azure DevOps Pipeline.
8. We process unreliable tests once all tests have been reported by reading the JSON string from the
errorMessage field and calling the Azure DevOps REST API to modify the unreliable tests to have sub-results
added to the test and to mark the test as "warning", which will enable people to see exactly how the test
failed in runs where it did.

View File

@@ -1,105 +0,0 @@
setlocal ENABLEDELAYEDEXPANSION
echo %TIME%
robocopy %HELIX_CORRELATION_PAYLOAD% . /s /NP > NUL
echo %TIME%
reg add HKLM\Software\Policies\Microsoft\Windows\Appx /v AllowAllTrustedApps /t REG_DWORD /d 1 /f
rem enable dump collection for our test apps:
rem note, this script is run from a 32-bit cmd, but we need to set the native reg-key
FOR %%A IN (TestHostApp.exe,te.exe,te.processhost.exe,conhost.exe,OpenConsole.exe,WindowsTerminal.exe) DO (
%systemroot%\sysnative\cmd.exe /c reg add "HKLM\Software\Microsoft\Windows\Windows Error Reporting\LocalDumps\%%A" /v DumpFolder /t REG_EXPAND_SZ /d %HELIX_DUMP_FOLDER% /f
%systemroot%\sysnative\cmd.exe /c reg add "HKLM\Software\Microsoft\Windows\Windows Error Reporting\LocalDumps\%%A" /v DumpType /t REG_DWORD /d 2 /f
%systemroot%\sysnative\cmd.exe /c reg add "HKLM\Software\Microsoft\Windows\Windows Error Reporting\LocalDumps\%%A" /v DumpCount /t REG_DWORD /d 10 /f
)
echo %TIME%
:: kill dhandler, which is a tool designed to handle unexpected windows appearing. But since our tests are
:: expected to show UI we don't want it running.
taskkill -f -im dhandler.exe
echo %TIME%
powershell -ExecutionPolicy Bypass .\EnsureMachineState.ps1
echo %TIME%
powershell -ExecutionPolicy Bypass .\InstallTestAppDependencies.ps1
echo %TIME%
set testBinaryCandidates=TerminalApp.LocalTests.dll SettingsModel.LocalTests.dll Conhost.UIA.Tests.dll WindowsTerminal.UIA.Tests.dll
set testBinaries=
for %%B in (%testBinaryCandidates%) do (
if exist %%B (
set "testBinaries=!testBinaries! %%B"
)
)
echo %TIME%
te.exe %testBinaries% /enablewttlogging /unicodeOutput:false /sessionTimeout:0:15 /testtimeout:0:10 /screenCaptureOnError %*
echo %TIME%
powershell -ExecutionPolicy Bypass Get-Process
move te.wtl te_original.wtl
copy /y te_original.wtl %HELIX_WORKITEM_UPLOAD_ROOT%
copy /y WexLogFileOutput\*.jpg %HELIX_WORKITEM_UPLOAD_ROOT%
copy /y *.pgc %HELIX_WORKITEM_UPLOAD_ROOT%
set FailedTestQuery=
for /F "tokens=* usebackq" %%I IN (`powershell -ExecutionPolicy Bypass .\OutputFailedTestQuery.ps1 te_original.wtl`) DO (
set FailedTestQuery=%%I
)
rem The first time, we'll just re-run failed tests once. In many cases, tests fail very rarely, such that
rem a single re-run will be sufficient to detect many unreliable tests.
if "%FailedTestQuery%" == "" goto :SkipReruns
echo %TIME%
te.exe %testBinaries% /enablewttlogging /unicodeOutput:false /sessionTimeout:0:15 /testtimeout:0:10 /screenCaptureOnError /select:"%FailedTestQuery%"
echo %TIME%
move te.wtl te_rerun.wtl
copy /y te_rerun.wtl %HELIX_WORKITEM_UPLOAD_ROOT%
copy /y WexLogFileOutput\*.jpg %HELIX_WORKITEM_UPLOAD_ROOT%
rem If there are still failing tests remaining, we'll run them eight more times, so they'll have been run a total of ten times.
rem If any tests fail all ten times, we can be pretty confident that these are actual test failures rather than unreliable tests.
if not exist te_rerun.wtl goto :SkipReruns
set FailedTestQuery=
for /F "tokens=* usebackq" %%I IN (`powershell -ExecutionPolicy Bypass .\OutputFailedTestQuery.ps1 te_rerun.wtl`) DO (
set FailedTestQuery=%%I
)
if "%FailedTestQuery%" == "" goto :SkipReruns
echo %TIME%
te.exe %testBinaries% /enablewttlogging /unicodeOutput:false /sessionTimeout:0:15 /testtimeout:0:10 /screenCaptureOnError /testmode:Loop /LoopTest:8 /select:"%FailedTestQuery%"
echo %TIME%
powershell -ExecutionPolicy Bypass Get-Process
move te.wtl te_rerun_multiple.wtl
copy /y te_rerun_multiple.wtl %HELIX_WORKITEM_UPLOAD_ROOT%
copy /y WexLogFileOutput\*.jpg %HELIX_WORKITEM_UPLOAD_ROOT%
powershell -ExecutionPolicy Bypass .\CopyVisualTreeVerificationFiles.ps1
:SkipReruns
powershell -ExecutionPolicy Bypass Get-Process
echo %TIME%
powershell -ExecutionPolicy Bypass .\OutputSubResultsJsonFiles.ps1 te_original.wtl te_rerun.wtl te_rerun_multiple.wtl %testnameprefix%
powershell -ExecutionPolicy Bypass .\ConvertWttLogToXUnit.ps1 te_original.wtl te_rerun.wtl te_rerun_multiple.wtl testResults.xml %testnameprefix%
echo %TIME%
copy /y *_subresults.json %HELIX_WORKITEM_UPLOAD_ROOT%
type testResults.xml
echo %TIME%

View File

@@ -1,51 +0,0 @@
{
"Version": "1.0.0",
"UseMinimatch": false,
"SignBatches": [
{
"MatchedPath": [
"conpty.dll",
"OpenConsole.exe"
],
"SigningInfo": {
"Operations": [
{
"KeyCode": "CP-230012",
"OperationSetCode": "SigntoolSign",
"Parameters": [
{
"parameterName": "OpusName",
"parameterValue": "Microsoft"
},
{
"parameterName": "OpusInfo",
"parameterValue": "http://www.microsoft.com"
},
{
"parameterName": "FileDigest",
"parameterValue": "/fd \"SHA256\""
},
{
"parameterName": "PageHash",
"parameterValue": "/NPH"
},
{
"parameterName": "TimeStamp",
"parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
}
],
"ToolName": "sign",
"ToolVersion": "1.0"
},
{
"KeyCode": "CP-230012",
"OperationSetCode": "SigntoolVerify",
"Parameters": [],
"ToolName": "sign",
"ToolVersion": "1.0"
}
]
}
}
]
}

View File

@@ -0,0 +1,47 @@
[
{
"MatchedPath": [
"conpty.dll",
"OpenConsole.exe"
],
"SigningInfo": {
"Operations": [
{
"KeyCode": "CP-230012",
"OperationSetCode": "SigntoolSign",
"Parameters": [
{
"parameterName": "OpusName",
"parameterValue": "Microsoft"
},
{
"parameterName": "OpusInfo",
"parameterValue": "http://www.microsoft.com"
},
{
"parameterName": "FileDigest",
"parameterValue": "/fd \"SHA256\""
},
{
"parameterName": "PageHash",
"parameterValue": "/NPH"
},
{
"parameterName": "TimeStamp",
"parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
}
],
"ToolName": "sign",
"ToolVersion": "1.0"
},
{
"KeyCode": "CP-230012",
"OperationSetCode": "SigntoolVerify",
"Parameters": [],
"ToolName": "sign",
"ToolVersion": "1.0"
}
]
}
}
]

View File

@@ -0,0 +1,65 @@
[
{
"MatchedPath": [
// Namespaced DLLs
"PackageContents/Microsoft.Terminal.*.dll",
"PackageContents/Microsoft.Terminal.*.winmd",
// ConPTY and DefTerm
"PackageContents/OpenConsole.exe",
"PackageContents/OpenConsoleProxy.dll",
// Legacy DLLs with old names
"PackageContents/TerminalApp.dll",
"PackageContents/TerminalApp.winmd",
"PackageContents/TerminalConnection.dll",
"PackageContents/TerminalThemeHelpers.dll",
"PackageContents/WindowsTerminalShellExt.dll",
// The rest
"PackageContents/TerminalAzBridge.exe",
"PackageContents/wt.exe",
"PackageContents/WindowsTerminal.exe",
"PackageContents/elevate-shim.exe"
],
"SigningInfo": {
"Operations": [
{
"KeyCode": "CP-230012",
"OperationSetCode": "SigntoolSign",
"Parameters": [
{
"parameterName": "OpusName",
"parameterValue": "Microsoft"
},
{
"parameterName": "OpusInfo",
"parameterValue": "http://www.microsoft.com"
},
{
"parameterName": "FileDigest",
"parameterValue": "/fd \"SHA256\""
},
{
"parameterName": "PageHash",
"parameterValue": "/NPH"
},
{
"parameterName": "TimeStamp",
"parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
}
],
"ToolName": "sign",
"ToolVersion": "1.0"
},
{
"KeyCode": "CP-230012",
"OperationSetCode": "SigntoolVerify",
"Parameters": [],
"ToolName": "sign",
"ToolVersion": "1.0"
}
]
}
}
]

View File

@@ -0,0 +1,46 @@
[
{
"MatchedPath": [
"PublicTerminalCore.dll"
],
"SigningInfo": {
"Operations": [
{
"KeyCode": "CP-230012",
"OperationSetCode": "SigntoolSign",
"Parameters": [
{
"parameterName": "OpusName",
"parameterValue": "Microsoft"
},
{
"parameterName": "OpusInfo",
"parameterValue": "http://www.microsoft.com"
},
{
"parameterName": "FileDigest",
"parameterValue": "/fd \"SHA256\""
},
{
"parameterName": "PageHash",
"parameterValue": "/NPH"
},
{
"parameterName": "TimeStamp",
"parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
}
],
"ToolName": "sign",
"ToolVersion": "1.0"
},
{
"KeyCode": "CP-230012",
"OperationSetCode": "SigntoolVerify",
"Parameters": [],
"ToolName": "sign",
"ToolVersion": "1.0"
}
]
}
}
]

View File

@@ -0,0 +1,47 @@
[
{
"MatchedPath": [
"WpfTerminalControl/net472/Microsoft.Terminal.Wpf.dll",
"WpfTerminalControl/net6.0-windows/Microsoft.Terminal.Wpf.dll"
],
"SigningInfo": {
"Operations": [
{
"KeyCode": "CP-230012",
"OperationSetCode": "SigntoolSign",
"Parameters": [
{
"parameterName": "OpusName",
"parameterValue": "Microsoft"
},
{
"parameterName": "OpusInfo",
"parameterValue": "http://www.microsoft.com"
},
{
"parameterName": "FileDigest",
"parameterValue": "/fd \"SHA256\""
},
{
"parameterName": "PageHash",
"parameterValue": "/NPH"
},
{
"parameterName": "TimeStamp",
"parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
}
],
"ToolName": "sign",
"ToolVersion": "1.0"
},
{
"KeyCode": "CP-230012",
"OperationSetCode": "SigntoolVerify",
"Parameters": [],
"ToolName": "sign",
"ToolVersion": "1.0"
}
]
}
}
]

View File

@@ -3,8 +3,6 @@
<package id="MUXCustomBuildTasks" version="1.0.48" targetFramework="native" />
<package id="Microsoft.Taef" version="10.60.210621002" targetFramework="native" />
<package id="Microsoft.Internal.PGO-Helpers.Cpp" version="0.2.34" targetFramework="native" />
<!-- This cannot be included in another project that depends on XAML (as it would be a duplicate package ID) -->
<package id="Microsoft.UI.Xaml" version="2.7.3" targetFramework="native" />
<package id="Microsoft.Debugging.Tools.PdbStr" version="20220617.1556.0" targetFramework="native" />
<package id="Microsoft.Debugging.Tools.SrcTool" version="20220617.1556.0" targetFramework="native" />
</packages>

View File

@@ -1,4 +1,5 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="Terminal.PGO.props" />
<Import Project="$(PkgMicrosoft_PGO_Helpers_Cpp)\build\Microsoft.PGO-Helpers.Cpp.props" />
<Import Project="$(PkgMicrosoft_PGO_Helpers_Cpp)\build\Microsoft.PGO-Helpers.Cpp.targets" />
</Project>
</Project>

View File

@@ -12,5 +12,6 @@
<files>
<!-- The target directories for pgd files need to remain as is. PGO optimization pass will rely on this exact directory layout. -->
<file src="x64\*.pgd" target="tools\x64"/>
<file src="arm64\*.pgd" target="tools\arm64"/>
</files>
</package>

View File

@@ -46,6 +46,5 @@
<PGOCopyRuntime Condition="'$(PGOBuildMode)' == 'Instrument'">true</PGOCopyRuntime>
</PropertyGroup>
<!-- Import PGO-Helpers -->
<Import Project="$(PkgMicrosoft_PGO_Helpers_Cpp)\build\Microsoft.PGO-Helpers.Cpp.props" />
<!-- Do not import PGO-Helpers props here, as it is too early to detect the C++ tools directory -->
</Project>

View File

@@ -29,76 +29,78 @@ variables:
# 0.0.1904.0900
name: 0.0.$(Date:yyMM).$(Date:dd)$(Rev:rr)
parameters:
- name: auditMode
displayName: "Build in Audit Mode (x64)"
type: boolean
default: true
- name: runTests
displayName: "Run Tests"
type: boolean
default: true
- name: buildPlatforms
type: object
default:
- x64
- x86
- arm64
stages:
- stage: Audit_x64
displayName: Audit Mode
dependsOn: []
condition: succeeded()
jobs:
- template: ./templates/build-console-audit-job.yml
parameters:
platform: x64
- ${{ if eq(parameters.auditMode, true) }}:
- stage: Audit_x64
displayName: Audit Mode
dependsOn: []
jobs:
- template: ./templates-v2/job-build-project.yml
parameters:
pool:
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
name: SHINE-OSS-L
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
name: SHINE-INT-L
buildPlatforms: [x64]
buildConfigurations: [AuditMode]
buildEverything: true
keepAllExpensiveBuildOutputs: false
- stage: Build_x64
displayName: Build x64
dependsOn: []
condition: succeeded()
jobs:
- template: ./templates/build-console-ci.yml
parameters:
platform: x64
- stage: Build_x86
displayName: Build x86
- stage: CodeHealth
displayName: Code Health
dependsOn: []
jobs:
- template: ./templates/build-console-ci.yml
parameters:
platform: x86
- stage: Build_ARM64
displayName: Build ARM64
dependsOn: []
condition: not(eq(variables['Build.Reason'], 'PullRequest'))
jobs:
- template: ./templates/build-console-ci.yml
parameters:
platform: ARM64
- template: ./templates-v2/job-check-code-format.yml
- stage: Test_x64
displayName: Test x64
dependsOn: [Build_x64]
condition: succeeded()
jobs:
- template: ./templates/test-console-ci.yml
parameters:
platform: x64
- stage: Test_x86
displayName: Test x86
dependsOn: [Build_x86]
jobs:
- template: ./templates/test-console-ci.yml
parameters:
platform: x86
- ${{ each platform in parameters.buildPlatforms }}:
- stage: Build_${{ platform }}
displayName: Build ${{ platform }}
dependsOn: []
jobs:
- template: ./templates-v2/job-build-project.yml
parameters:
pool:
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
name: SHINE-OSS-L
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
name: SHINE-INT-L
buildPlatforms:
- ${{ platform }}
buildConfigurations: [Release]
buildEverything: true
keepAllExpensiveBuildOutputs: false
- stage: Helix_x64
displayName: Helix x64
dependsOn: [Build_x64]
condition: and(succeeded(), not(eq(variables['Build.Reason'], 'PullRequest')))
jobs:
- template: ./templates/console-ci-helix-job.yml
parameters:
platform: x64
- ${{ if eq(parameters.runTests, true) }}:
- stage: Test_${{ platform }}
displayName: Test ${{ platform }}
dependsOn:
- Build_${{ platform }}
condition: succeeded()
jobs:
- template: ./templates-v2/job-test-project.yml
parameters:
platform: ${{ platform }}
- stage: Scripts
displayName: Code Health Scripts
dependsOn: []
condition: succeeded()
jobs:
- template: ./templates/check-formatting.yml
- stage: CodeIndexer
displayName: Github CodeNav Indexer
dependsOn: [Build_x64]
condition: and(succeeded(), not(eq(variables['Build.Reason'], 'PullRequest')))
jobs:
- template: ./templates/codenav-indexer.yml
- ${{ if ne(variables['Build.Reason'], 'PullRequest') }}:
- stage: CodeIndexer
displayName: Github CodeNav Indexer
dependsOn: []
jobs:
- template: ./templates-v2/job-index-github-codenav.yml

View File

@@ -27,6 +27,7 @@ steps:
clean: true
submodules: false
fetchDepth: 1 # Don't need a deep checkout for loc files!
fetchTags: false # Tags still result in depth > 1 fetch; we don't need them here
persistCredentials: true
path: s # Adding a second repo made Azure DevOps change where we're checked out.

View File

@@ -7,6 +7,7 @@ pr:
paths:
include:
- src/features.xml
- build/pipelines/feature-flag-ci.yml
variables:
- name: runCodesignValidationInjectionBG
@@ -21,9 +22,19 @@ parameters:
# Dev is built automatically
# WindowsInbox does not typically build with VS.
jobs:
stages:
- ${{ each branding in parameters.buildBrandings }}:
- template: ./templates/build-console-ci.yml
parameters:
platform: x64
branding: ${{ branding }}
- stage: Build_${{ branding }}
dependsOn: []
displayName: Build ${{ branding }}
jobs:
- template: ./templates-v2/job-build-project.yml
parameters:
pool: # This only runs in CI
name: SHINE-OSS-L
buildPlatforms: [x64]
buildConfigurations: [Release]
buildEverything: true
branding: ${{ branding }}
keepAllExpensiveBuildOutputs: false
artifactStem: -${{ branding }} # Disambiguate artifacts with the same config/platform

View File

@@ -16,44 +16,52 @@ pr: none
name: 0.0.$(Date:yyMM).$(Date:dd)$(Rev:rr)
stages:
- stage: Build_Fuzz_Config
displayName: Build Fuzzers
- stage: Build
displayName: Fuzzing Build
dependsOn: []
condition: succeeded()
jobs:
- template: ./templates/build-console-fuzzing.yml
parameters:
platform: x64
- stage: OneFuzz
displayName: Submit OneFuzz Job
dependsOn: ['Build_Fuzz_Config']
- template: ./templates-v2/job-build-project.yml
parameters:
pool:
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
name: SHINE-OSS-L
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
name: SHINE-INT-L
buildPlatforms: [x64]
buildConfigurations: [Fuzzing]
buildEverything: true
keepAllExpensiveBuildOutputs: false
- stage: Submit
displayName: Submit to OneFuzz
dependsOn: [Build]
condition: succeeded()
pool:
vmImage: 'ubuntu-latest'
variables:
artifactName: fuzzingBuildOutput
jobs:
- job:
steps:
- task: DownloadBuildArtifacts@0
inputs:
artifactName: $(artifactName)
downloadPath: $(Build.ArtifactStagingDirectory)
- task: UsePythonVersion@0
inputs:
versionSpec: '3.x'
addToPath: true
architecture: 'x64'
- bash: |
set -ex
pip -q install onefuzz
onefuzz config --endpoint $(endpoint) --client_id $(client_id) --authority $(authority) --tenant_domain $(tenant_domain) --client_secret $(client_secret)
sed -i s/INSERT_PAT_HERE/$(ado_pat)/ build/Fuzz/notifications-ado.json
sed -i s/INSERT_ASSIGNED_HERE/$(ado_assigned_to)/ build/Fuzz/notifications-ado.json
displayName: Configure OneFuzz
- bash: |
onefuzz template libfuzzer basic --colocate_all_tasks --vm_count 1 --target_exe $target_exe_path --notification_config @./build/Fuzz/notifications-ado.json OpenConsole $test_name $(Build.SourceVersion) default
displayName: Submit OneFuzz Job
env:
target_exe_path: $(Build.ArtifactStagingDirectory)/$(artifactName)/Fuzzing/x64/test/OpenConsoleFuzzer.exe
test_name: WriteCharsLegacy
- job:
pool:
vmImage: 'ubuntu-latest'
steps:
- task: DownloadPipelineArtifact@2
displayName: Download artifacts
inputs:
artifactName: build-x64-Fuzzing
downloadPath: $(Build.ArtifactStagingDirectory)
- task: UsePythonVersion@0
inputs:
versionSpec: '3.x'
addToPath: true
architecture: 'x64'
- bash: |
set -ex
pip -q install onefuzz
onefuzz config --endpoint $(endpoint) --client_id $(client_id) --authority $(authority) --tenant_domain $(tenant_domain) --client_secret $(client_secret)
sed -i s/INSERT_PAT_HERE/$(ado_pat)/ build/Fuzz/notifications-ado.json
sed -i s/INSERT_ASSIGNED_HERE/$(ado_assigned_to)/ build/Fuzz/notifications-ado.json
displayName: Configure OneFuzz
- bash: |
onefuzz template libfuzzer basic --colocate_all_tasks --vm_count 1 --target_exe $target_exe_path --notification_config @./build/Fuzz/notifications-ado.json OpenConsole $test_name $(Build.SourceVersion) default
displayName: Submit OneFuzz Job
env:
target_exe_path: $(Build.ArtifactStagingDirectory)/OpenConsoleFuzzer.exe
test_name: WriteCharsLegacy

View File

@@ -1,5 +1,27 @@
trigger: none
pr: none
schedules:
- cron: "0 5 * * 2-6" # Run at 05:00 UTC Tuesday through Saturday (Even later than Localization, after the work day in Pacific, Mon-Fri)
displayName: "Nightly Instrumentation Build"
branches:
include:
- main
always: false # only run if there's code changes!
parameters:
- name: branding
displayName: "Branding (Build Type)"
type: string
default: Preview # By default, we'll PGO the Preview builds to get max coverage
values:
- Release
- Preview
- Dev
- name: buildPlatforms
type: object
default:
- x64
- arm64
variables:
- name: runCodesignValidationInjectionBG
@@ -10,18 +32,57 @@ variables:
name: 0.0.$(Date:yyMM).$(Date:dd)$(Rev:rr)
stages:
- stage: Build_x64
displayName: Build x64
- stage: Build
displayName: Build
dependsOn: []
condition: succeeded()
jobs:
- template: ./templates/build-console-pgo.yml
- template: ./templates-v2/job-build-project.yml
parameters:
platform: x64
- stage: Publish_PGO_Databases
displayName: Publish PGO databases
dependsOn: ['Build_x64']
pool:
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
name: SHINE-OSS-L
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
name: SHINE-INT-L
branding: ${{ parameters.branding }}
buildPlatforms: ${{ parameters.buildPlatforms }}
buildConfigurations: [Release]
buildEverything: true
pgoBuildMode: Instrument
artifactStem: -instrumentation
- stage: RunPGO
displayName: Run PGO
dependsOn: [Build]
condition: succeeded()
jobs:
- template: ./templates/pgo-build-and-publish-nuget-job.yml
- ${{ each platform in parameters.buildPlatforms }}:
- template: ./templates-v2/job-run-pgo-tests.yml
parameters:
# This job chooses its own pools based on platform
buildPlatform: ${{ platform }}
buildConfiguration: Release
artifactStem: -instrumentation
- stage: FinalizePGO
displayName: Finalize PGO and Publish
dependsOn: [RunPGO]
condition: succeeded()
jobs:
# This job takes multiple platforms and fans them back in to a single artifact.
- template: ./templates-v2/job-pgo-merge-pgd.yml
parameters:
pgoArtifact: 'PGO'
jobName: MergePGD
pool:
vmImage: 'windows-2022'
buildConfiguration: Release
buildPlatforms: ${{ parameters.buildPlatforms }}
artifactStem: -instrumentation
- template: ./templates-v2/job-pgo-build-nuget-and-publish.yml
parameters:
pool:
vmImage: 'windows-2022'
dependsOn: MergePGD
buildConfiguration: Release
artifactStem: -instrumentation

View File

@@ -3,8 +3,8 @@ trigger: none
pr: none
pool:
name: WinDevPool-L
demands: ImageOverride -equals WinDevVS17-latest
name: SHINE-INT-S # By default, send jobs to the small agent pool.
demands: ImageOverride -equals SHINE-VS17-Latest
parameters:
- name: branding
@@ -14,22 +14,11 @@ parameters:
values:
- Release
- Preview
- Dev
- name: buildTerminal
displayName: "Build Windows Terminal MSIX"
type: boolean
default: true
- name: runCompliance
displayName: "Run Compliance and Security Build"
type: boolean
default: true
- name: publishSymbolsToPublic
displayName: "Publish Symbols to MSDL"
type: boolean
default: true
- name: buildTerminalVPack
displayName: "Build Windows Terminal VPack"
type: boolean
default: false
- name: buildConPTY
displayName: "Build ConPTY NuGet"
type: boolean
@@ -47,23 +36,44 @@ parameters:
- Instrument
- None
- name: buildConfigurations
displayName: "Build Configurations"
type: object
default:
- Release
- name: buildPlatforms
displayName: "Build Platforms"
type: object
default:
- x64
- x86
- arm64
- name: buildWindowsVersions
type: object
default:
- Win10
- Win11
- name: codeSign
displayName: "Sign all build outputs"
type: boolean
default: true
- name: generateSbom
displayName: "Generate a Bill of Materials"
type: boolean
default: true
- name: terminalInternalPackageVersion
displayName: "Terminal Internal Package Version"
type: string
default: '0.0.8'
- name: runCompliance
displayName: "Run Compliance and Security Build"
type: boolean
default: true
- name: publishSymbolsToPublic
displayName: "Publish Symbols to MSDL"
type: boolean
default: true
- name: publishVpackToWindows
displayName: "Publish VPack to Windows"
type: boolean
default: false
variables:
TerminalInternalPackageVersion: "0.0.7"
# If we are building a branch called "release-*", 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.
@@ -86,638 +96,115 @@ variables:
NuGetPackBetaVersion: preview
${{ elseif eq(variables['Build.SourceBranchName'], 'main') }}:
NuGetPackBetaVersion: experimental
# The NuGet packages have to use *somebody's* DLLs. We used to force them to
# use the Win10 build outputs, but if there isn't a Win10 build we should use
# the Win11 one.
${{ if containsValue(parameters.buildWindowsVersions, 'Win10') }}:
TerminalBestVersionForNuGetPackages: Win10
${{ else }}:
TerminalBestVersionForNuGetPackages: Win11
name: $(BuildDefinitionName)_$(date:yyMM).$(date:dd)$(rev:rrr)
resources:
repositories:
- repository: self
type: git
ref: main
jobs:
- job: Build
strategy:
matrix:
${{ each config in parameters.buildConfigurations }}:
${{ each platform in parameters.buildPlatforms }}:
${{ each windowsVersion in parameters.buildWindowsVersions }}:
${{ config }}_${{ platform }}_${{ windowsVersion }}:
BuildConfiguration: ${{ config }}
BuildPlatform: ${{ platform }}
TerminalTargetWindowsVersion: ${{ windowsVersion }}
displayName: Build
timeoutInMinutes: 240
cancelTimeoutInMinutes: 1
steps:
- checkout: self
clean: true
submodules: true
persistCredentials: True
- task: PkgESSetupBuild@12
displayName: Package ES - Setup Build
inputs:
disableOutputRedirect: true
- task: PowerShell@2
displayName: Rationalize Build Platform
inputs:
targetType: inline
script: >-
$Arch = "$(BuildPlatform)"
If ($Arch -Eq "x86") { $Arch = "Win32" }
stages:
- stage: Build
displayName: Build
dependsOn: []
jobs:
- template: ./templates-v2/job-build-project.yml
parameters:
pool:
name: SHINE-INT-L # Run the compilation on the large agent pool, rather than the default small one.
demands: ImageOverride -equals SHINE-VS17-Latest
branding: ${{ parameters.branding }}
buildTerminal: ${{ parameters.buildTerminal }}
buildConPTY: ${{ parameters.buildConPTY }}
buildWPF: ${{ parameters.buildWPF }}
pgoBuildMode: ${{ parameters.pgoBuildMode }}
buildConfigurations: ${{ parameters.buildConfigurations }}
buildPlatforms: ${{ parameters.buildPlatforms }}
generateSbom: ${{ parameters.generateSbom }}
codeSign: ${{ parameters.codeSign }}
beforeBuildSteps: # Right before we build, lay down the universal package and localizations
- task: PkgESSetupBuild@12
displayName: Package ES - Setup Build
inputs:
disableOutputRedirect: true
Write-Host "##vso[task.setvariable variable=RationalizedBuildPlatform]${Arch}"
- template: .\templates\restore-nuget-steps.yml
- task: UniversalPackages@0
displayName: Download terminal-internal Universal Package
inputs:
feedListDownload: 2b3f8893-a6e8-411f-b197-a9e05576da48
packageListDownload: e82d490c-af86-4733-9dc4-07b772033204
versionListDownload: $(TerminalInternalPackageVersion)
- task: TouchdownBuildTask@1
displayName: Download Localization Files
inputs:
teamId: 7105
authId: $(TouchdownAppId)
authKey: $(TouchdownAppKey)
resourceFilePath: >-
src\cascadia\TerminalApp\Resources\en-US\Resources.resw
- task: UniversalPackages@0
displayName: Download terminal-internal Universal Package
inputs:
feedListDownload: 2b3f8893-a6e8-411f-b197-a9e05576da48
packageListDownload: e82d490c-af86-4733-9dc4-07b772033204
versionListDownload: ${{ parameters.terminalInternalPackageVersion }}
src\cascadia\TerminalApp\Resources\en-US\ContextMenu.resw
- template: ./templates-v2/steps-fetch-and-prepare-localizations.yml
parameters:
includePseudoLoc: true
src\cascadia\TerminalControl\Resources\en-US\Resources.resw
- ${{ if eq(parameters.buildWPF, true) }}:
# Add an Any CPU build flavor for the WPF control bits
- template: ./templates-v2/job-build-project.yml
parameters:
# This job is allowed to run on the default small pool.
jobName: BuildWPF
branding: ${{ parameters.branding }}
buildTerminal: false
buildWPFDotNetComponents: true
buildConfigurations: ${{ parameters.buildConfigurations }}
buildPlatforms:
- Any CPU
generateSbom: ${{ parameters.generateSbom }}
codeSign: ${{ parameters.codeSign }}
beforeBuildSteps:
- task: PkgESSetupBuild@12
displayName: Package ES - Setup Build
inputs:
disableOutputRedirect: true
# WPF doesn't need the localizations or the universal package, but if it does... put them here.
src\cascadia\TerminalConnection\Resources\en-US\Resources.resw
- stage: Package
displayName: Package
dependsOn: [Build]
jobs:
- ${{ if eq(parameters.buildTerminal, true) }}:
- template: ./templates-v2/job-merge-msix-into-bundle.yml
parameters:
jobName: Bundle
branding: ${{ parameters.branding }}
buildConfigurations: ${{ parameters.buildConfigurations }}
buildPlatforms: ${{ parameters.buildPlatforms }}
generateSbom: ${{ parameters.generateSbom }}
codeSign: ${{ parameters.codeSign }}
src\cascadia\TerminalSettingsModel\Resources\en-US\Resources.resw
- ${{ if eq(parameters.buildConPTY, true) }}:
- template: ./templates-v2/job-package-conpty.yml
parameters:
buildConfigurations: ${{ parameters.buildConfigurations }}
buildPlatforms: ${{ parameters.buildPlatforms }}
generateSbom: ${{ parameters.generateSbom }}
codeSign: ${{ parameters.codeSign }}
src\cascadia\TerminalSettingsEditor\Resources\en-US\Resources.resw
- ${{ if eq(parameters.buildWPF, true) }}:
- template: ./templates-v2/job-build-package-wpf.yml
parameters:
buildConfigurations: ${{ parameters.buildConfigurations }}
buildPlatforms: ${{ parameters.buildPlatforms }}
generateSbom: ${{ parameters.generateSbom }}
codeSign: ${{ parameters.codeSign }}
src\cascadia\CascadiaPackage\Resources\en-US\Resources.resw
appendRelativeDir: true
localizationTarget: false
pseudoSetting: Included
- task: PowerShell@2
displayName: Move Loc files one level up
inputs:
targetType: inline
script: >-
$Files = Get-ChildItem . -R -Filter 'Resources.resw' | ? FullName -Like '*en-US\*\Resources.resw'
- stage: Publish
displayName: Publish
dependsOn: [Build, Package]
jobs:
# We only support the vpack for Release builds that include Terminal
- ${{ if and(containsValue(parameters.buildConfigurations, 'Release'), parameters.buildTerminal, parameters.publishVpackToWindows) }}:
- template: ./templates-v2/job-submit-windows-vpack.yml
parameters:
buildConfiguration: Release
generateSbom: ${{ parameters.generateSbom }}
$Files | % { Move-Item -Verbose $_.Directory $_.Directory.Parent.Parent -EA:Ignore }
pwsh: true
- task: PowerShell@2
displayName: Copy the Context Menu Loc Resources to CascadiaPackage
inputs:
filePath: ./build/scripts/Copy-ContextMenuResourcesToCascadiaPackage.ps1
pwsh: true
- task: PowerShell@2
displayName: Generate NOTICE.html from NOTICE.md
inputs:
filePath: .\build\scripts\Generate-ThirdPartyNotices.ps1
arguments: -MarkdownNoticePath .\NOTICE.md -OutputPath .\src\cascadia\CascadiaPackage\NOTICE.html
pwsh: true
- ${{ if eq(parameters.buildTerminal, true) }}:
- pwsh: |-
./build/scripts/Patch-ManifestsToWindowsVersion.ps1 -NewWindowsVersion "10.0.22000.0"
displayName: Update manifest target version to Win11 (if necessary)
condition: and(succeeded(), eq(variables['TerminalTargetWindowsVersion'], 'Win11'))
- task: VSBuild@1
displayName: Build solution **\OpenConsole.sln
condition: true
inputs:
solution: '**\OpenConsole.sln'
msbuildArgs: /p:WindowsTerminalOfficialBuild=true /p:WindowsTerminalBranding=${{ parameters.branding }};PGOBuildMode=${{ parameters.pgoBuildMode }} /t:Terminal\CascadiaPackage /p:WindowsTerminalReleaseBuild=true /bl:$(Build.SourcesDirectory)\msbuild.binlog
platform: $(BuildPlatform)
configuration: $(BuildConfiguration)
clean: true
maximumCpuCount: true
- task: PublishBuildArtifacts@1
displayName: 'Publish Artifact: binlog'
condition: failed()
continueOnError: True
inputs:
PathtoPublish: $(Build.SourcesDirectory)\msbuild.binlog
ArtifactName: binlog-$(BuildPlatform)-$(TerminalTargetWindowsVersion)
- task: PowerShell@2
displayName: Check MSIX for common regressions
inputs:
targetType: inline
script: >-
$Package = Get-ChildItem -Recurse -Filter "CascadiaPackage_*.msix"
- template: ./templates-v2/job-publish-symbols.yml
parameters:
includePublicSymbolServer: ${{ parameters.publishSymbolsToPublic }}
.\build\scripts\Test-WindowsTerminalPackage.ps1 -Verbose -Path $Package.FullName
pwsh: true
- ${{ if eq(parameters.buildWPF, true) }}:
- task: VSBuild@1
displayName: Build solution **\OpenConsole.sln for PublicTerminalCore
inputs:
solution: '**\OpenConsole.sln'
msbuildArgs: /p:WindowsTerminalOfficialBuild=true /p:WindowsTerminalBranding=${{ parameters.branding }};PGOBuildMode=${{ parameters.pgoBuildMode }} /p:WindowsTerminalReleaseBuild=true /t:Terminal\wpf\PublicTerminalCore
platform: $(BuildPlatform)
configuration: $(BuildConfiguration)
- ${{ if eq(parameters.buildConPTY, true) }}:
- task: VSBuild@1
displayName: Build solution **\OpenConsole.sln for ConPTY
inputs:
solution: '**\OpenConsole.sln'
msbuildArgs: /p:WindowsTerminalOfficialBuild=true /p:WindowsTerminalBranding=${{ parameters.branding }};PGOBuildMode=${{ parameters.pgoBuildMode }} /p:WindowsTerminalReleaseBuild=true /t:Conhost\Host_EXE;Conhost\winconpty_DLL
platform: $(BuildPlatform)
configuration: $(BuildConfiguration)
- task: PowerShell@2
displayName: Source Index PDBs
inputs:
filePath: build\scripts\Index-Pdbs.ps1
arguments: -SearchDir '$(Build.SourcesDirectory)' -SourceRoot '$(Build.SourcesDirectory)' -recursive -Verbose -CommitId $(Build.SourceVersion)
errorActionPreference: silentlyContinue
pwsh: true
- task: PowerShell@2
displayName: Run Unit Tests
condition: and(succeeded(), or(eq(variables['BuildPlatform'], 'x64'), eq(variables['BuildPlatform'], 'x86')))
enabled: False
inputs:
filePath: build\scripts\Run-Tests.ps1
arguments: -MatchPattern '*unit.test*.dll' -Platform '$(RationalizedBuildPlatform)' -Configuration '$(BuildConfiguration)'
- task: PowerShell@2
displayName: Run Feature Tests
condition: and(succeeded(), eq(variables['BuildPlatform'], 'x64'))
enabled: False
inputs:
filePath: build\scripts\Run-Tests.ps1
arguments: -MatchPattern '*feature.test*.dll' -Platform '$(RationalizedBuildPlatform)' -Configuration '$(BuildConfiguration)'
- ${{ if eq(parameters.buildTerminal, true) }}:
- task: CopyFiles@2
displayName: Copy *.appx/*.msix to Artifacts
inputs:
Contents: >-
**/*.appx
**/*.msix
**/*.appxsym
!**/Microsoft.VCLibs*.appx
TargetFolder: $(Build.ArtifactStagingDirectory)/appx
OverWrite: true
flattenFolders: true
- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
displayName: 'Generate SBOM manifest'
inputs:
BuildDropPath: '$(System.ArtifactsDirectory)/appx'
- task: PublishBuildArtifacts@1
displayName: Publish Artifact (appx)
inputs:
PathtoPublish: $(Build.ArtifactStagingDirectory)/appx
ArtifactName: appx-$(BuildPlatform)-$(BuildConfiguration)-$(TerminalTargetWindowsVersion)
- ${{ if eq(parameters.buildConPTY, true) }}:
- task: CopyFiles@2
displayName: Copy ConPTY to Artifacts
inputs:
Contents: |-
$(Build.SourcesDirectory)/bin/**/conpty.dll
$(Build.SourcesDirectory)/bin/**/conpty.lib
$(Build.SourcesDirectory)/bin/**/conpty.pdb
$(Build.SourcesDirectory)/bin/**/OpenConsole.exe
$(Build.SourcesDirectory)/bin/**/OpenConsole.pdb
TargetFolder: $(Build.ArtifactStagingDirectory)/conpty
OverWrite: true
flattenFolders: true
- task: PublishBuildArtifacts@1
displayName: Publish Artifact (ConPTY)
inputs:
PathtoPublish: $(Build.ArtifactStagingDirectory)/conpty
ArtifactName: conpty-dll-$(BuildPlatform)-$(BuildConfiguration)-$(TerminalTargetWindowsVersion)
- ${{ if eq(parameters.buildWPF, true) }}:
- task: CopyFiles@2
displayName: Copy PublicTerminalCore.dll to Artifacts
inputs:
Contents: >-
**/PublicTerminalCore.dll
TargetFolder: $(Build.ArtifactStagingDirectory)/wpf
OverWrite: true
flattenFolders: true
- task: PublishBuildArtifacts@1
displayName: Publish Artifact (PublicTerminalCore)
inputs:
PathtoPublish: $(Build.ArtifactStagingDirectory)/wpf
ArtifactName: wpf-dll-$(BuildPlatform)-$(BuildConfiguration)-$(TerminalTargetWindowsVersion)
- task: PublishSymbols@2
displayName: Publish symbols path
continueOnError: True
inputs:
SearchPattern: |
$(Build.SourcesDirectory)/bin/**/*.pdb
$(Build.SourcesDirectory)/bin/**/*.exe
$(Build.SourcesDirectory)/bin/**/*.dll
IndexSources: false
SymbolServerType: TeamServices
- ${{ if eq(parameters.runCompliance, true) }}:
- template: ./templates/build-console-compliance-job.yml
- ${{ if eq(parameters.buildTerminal, true) }}:
- job: BundleAndSign
strategy:
matrix:
${{ each windowsVersion in parameters.buildWindowsVersions }}:
${{ windowsVersion }}:
TerminalTargetWindowsVersion: ${{ windowsVersion }}
displayName: Create and sign AppX/MSIX bundles
variables:
${{ if eq(parameters.branding, 'Release') }}:
BundleStemName: Microsoft.WindowsTerminal
${{ elseif eq(parameters.branding, 'Preview') }}:
BundleStemName: Microsoft.WindowsTerminalPreview
${{ else }}:
BundleStemName: WindowsTerminalDev
dependsOn: Build
steps:
- checkout: self
clean: true
fetchDepth: 1
submodules: true
persistCredentials: True
- task: PkgESSetupBuild@12
displayName: Package ES - Setup Build
inputs:
disableOutputRedirect: true
- ${{ each platform in parameters.buildPlatforms }}:
- task: DownloadBuildArtifacts@0
displayName: Download Artifacts ${{ platform }} $(TerminalTargetWindowsVersion)
inputs:
artifactName: appx-${{ platform }}-Release-$(TerminalTargetWindowsVersion)
# Add 3000 to the major version component, but only for the bundle.
# This is to ensure that it is newer than "2022.xx.yy.zz" or whatever the original bundle versions were before
# we switched to uniform naming.
- pwsh: |-
$VersionEpoch = 3000
$Components = "$(XES_APPXMANIFESTVERSION)" -Split "\."
$Components[0] = ([int]$Components[0] + $VersionEpoch)
$BundleVersion = $Components -Join "."
New-Item -Type Directory "$(System.ArtifactsDirectory)\bundle"
.\build\scripts\Create-AppxBundle.ps1 -InputPath "$(System.ArtifactsDirectory)" -ProjectName CascadiaPackage -BundleVersion $BundleVersion -OutputPath "$(System.ArtifactsDirectory)\bundle\$(BundleStemName)_$(TerminalTargetWindowsVersion)_$(XES_APPXMANIFESTVERSION)_8wekyb3d8bbwe.msixbundle"
displayName: Create WindowsTerminal*.msixbundle
- task: EsrpCodeSigning@1
displayName: Submit *.msixbundle to ESRP for code signing
inputs:
ConnectedServiceName: 9d6d2960-0793-4d59-943e-78dcb434840a
FolderPath: $(System.ArtifactsDirectory)\bundle
Pattern: $(BundleStemName)*.msixbundle
UseMinimatch: true
signConfigType: inlineSignParams
inlineOperation: >-
[
{
"KeyCode": "Dynamic",
"CertTemplateName": "WINMSAPP1ST",
"CertSubjectName": "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US",
"OperationCode": "SigntoolSign",
"Parameters": {
"OpusName": "Microsoft",
"OpusInfo": "http://www.microsoft.com",
"FileDigest": "/fd \"SHA256\"",
"TimeStamp": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
},
"ToolName": "sign",
"ToolVersion": "1.0"
},
{
"KeyCode": "Dynamic",
"CertTemplateName": "WINMSAPP1ST",
"CertSubjectName": "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US",
"OperationCode": "SigntoolVerify",
"Parameters": {},
"ToolName": "sign",
"ToolVersion": "1.0"
}
]
- task: PublishBuildArtifacts@1
displayName: 'Publish Artifact: appxbundle-signed'
inputs:
PathtoPublish: $(System.ArtifactsDirectory)\bundle
ArtifactName: appxbundle-signed-$(TerminalTargetWindowsVersion)
- ${{ if eq(parameters.buildConPTY, true) }}:
- job: PackageAndSignConPTY
strategy:
matrix:
${{ each config in parameters.buildConfigurations }}:
${{ config }}:
BuildConfiguration: ${{ config }}
displayName: Create NuGet Package (ConPTY)
dependsOn: Build
steps:
- checkout: self
clean: true
fetchDepth: 1
submodules: true
persistCredentials: True
- task: PkgESSetupBuild@12
displayName: Package ES - Setup Build
inputs:
disableOutputRedirect: true
- ${{ each platform in parameters.buildPlatforms }}:
- task: DownloadBuildArtifacts@0
displayName: Download ${{ platform }} ConPTY binaries
inputs:
artifactName: conpty-dll-${{ platform }}-$(BuildConfiguration)-$(TerminalBestVersionForNuGetPackages)
downloadPath: bin\${{ platform }}\$(BuildConfiguration)\
extractTars: false
- task: PowerShell@2
displayName: Move downloaded artifacts around
inputs:
targetType: inline
# Find all artifact files and move them up a directory. Ugh.
script: |-
Get-ChildItem bin -Recurse -Directory -Filter conpty-dll-* | % {
$_ | Get-ChildItem -Recurse -File | % {
Move-Item -Verbose $_.FullName $_.Directory.Parent.FullName
}
}
Move-Item bin\x86 bin\Win32
- task: EsrpCodeSigning@1
displayName: Submit ConPTY libraries and OpenConsole for code signing
inputs:
ConnectedServiceName: 9d6d2960-0793-4d59-943e-78dcb434840a
FolderPath: '$(Build.SourcesDirectory)/bin'
signType: batchSigning
batchSignPolicyFile: '$(Build.SourcesDirectory)\build\config\ESRPSigning_ConPTY.json'
- task: NuGetToolInstaller@1
displayName: Use NuGet 5.10.0
inputs:
versionSpec: 5.10.0
- task: NuGetCommand@2
displayName: NuGet pack
inputs:
command: pack
packagesToPack: $(Build.SourcesDirectory)\src\winconpty\package\winconpty.nuspec
packDestination: '$(Build.ArtifactStagingDirectory)/nupkg'
versioningScheme: byEnvVar
versionEnvVar: XES_PACKAGEVERSIONNUMBER
- task: EsrpCodeSigning@1
displayName: Submit *.nupkg to ESRP for code signing
inputs:
ConnectedServiceName: 9d6d2960-0793-4d59-943e-78dcb434840a
FolderPath: $(Build.ArtifactStagingDirectory)/nupkg
Pattern: '*.nupkg'
UseMinimatch: true
signConfigType: inlineSignParams
inlineOperation: >-
[
{
"KeyCode": "CP-401405",
"OperationCode": "NuGetSign",
"Parameters": {},
"ToolName": "sign",
"ToolVersion": "1.0"
},
{
"KeyCode": "CP-401405",
"OperationCode": "NuGetVerify",
"Parameters": {},
"ToolName": "sign",
"ToolVersion": "1.0"
}
]
- task: PublishBuildArtifacts@1
displayName: Publish Artifact (nupkg)
inputs:
PathtoPublish: $(Build.ArtifactStagingDirectory)\nupkg
ArtifactName: conpty-nupkg-$(BuildConfiguration)
- ${{ if eq(parameters.buildWPF, true) }}:
- job: PackageAndSignWPF
strategy:
matrix:
${{ each config in parameters.buildConfigurations }}:
${{ config }}:
BuildConfiguration: ${{ config }}
displayName: Create NuGet Package (WPF Terminal Control)
dependsOn: Build
steps:
- checkout: self
clean: true
fetchDepth: 1
submodules: true
persistCredentials: True
- task: PkgESSetupBuild@12
displayName: Package ES - Setup Build
inputs:
disableOutputRedirect: true
- ${{ each platform in parameters.buildPlatforms }}:
- task: DownloadBuildArtifacts@0
displayName: Download ${{ platform }} PublicTerminalCore
inputs:
artifactName: wpf-dll-${{ platform }}-$(BuildConfiguration)-$(TerminalBestVersionForNuGetPackages)
itemPattern: '**/*.dll'
downloadPath: bin\${{ platform }}\$(BuildConfiguration)\
extractTars: false
- task: PowerShell@2
displayName: Move downloaded artifacts around
inputs:
targetType: inline
# Find all artifact files and move them up a directory. Ugh.
script: |-
Get-ChildItem bin -Recurse -Directory -Filter wpf-dll-* | % {
$_ | Get-ChildItem -Recurse -File | % {
Move-Item -Verbose $_.FullName $_.Directory.Parent.FullName
}
}
Move-Item bin\x86 bin\Win32
- task: NuGetToolInstaller@1
displayName: Use NuGet 5.10.0
inputs:
versionSpec: 5.10.0
- task: NuGetCommand@2
displayName: NuGet restore copy
inputs:
selectOrConfig: config
nugetConfigPath: NuGet.Config
- task: VSBuild@1
displayName: Build solution **\OpenConsole.sln for WPF Control
inputs:
solution: '**\OpenConsole.sln'
msbuildArgs: /p:WindowsTerminalReleaseBuild=$(UseReleaseBranding);Version=$(XES_PACKAGEVERSIONNUMBER) /t:Pack
platform: Any CPU
configuration: $(BuildConfiguration)
maximumCpuCount: true
- task: PublishSymbols@2
displayName: Publish symbols path
continueOnError: True
inputs:
SearchPattern: |
$(Build.SourcesDirectory)/bin/**/*.pdb
$(Build.SourcesDirectory)/bin/**/*.exe
$(Build.SourcesDirectory)/bin/**/*.dll
IndexSources: false
SymbolServerType: TeamServices
SymbolsArtifactName: Symbols_WPF_$(BuildConfiguration)
- task: CopyFiles@2
displayName: Copy *.nupkg to Artifacts
inputs:
Contents: '**/*Wpf*.nupkg'
TargetFolder: $(Build.ArtifactStagingDirectory)/nupkg
OverWrite: true
flattenFolders: true
- task: EsrpCodeSigning@1
displayName: Submit *.nupkg to ESRP for code signing
inputs:
ConnectedServiceName: 9d6d2960-0793-4d59-943e-78dcb434840a
FolderPath: $(Build.ArtifactStagingDirectory)/nupkg
Pattern: '*.nupkg'
UseMinimatch: true
signConfigType: inlineSignParams
inlineOperation: >-
[
{
"KeyCode": "CP-401405",
"OperationCode": "NuGetSign",
"Parameters": {},
"ToolName": "sign",
"ToolVersion": "1.0"
},
{
"KeyCode": "CP-401405",
"OperationCode": "NuGetVerify",
"Parameters": {},
"ToolName": "sign",
"ToolVersion": "1.0"
}
]
- task: PublishBuildArtifacts@1
displayName: Publish Artifact (nupkg)
inputs:
PathtoPublish: $(Build.ArtifactStagingDirectory)\nupkg
ArtifactName: wpf-nupkg-$(BuildConfiguration)
- ${{ if eq(parameters.publishSymbolsToPublic, true) }}:
- job: PublishSymbols
displayName: Publish Symbols
dependsOn: BundleAndSign
steps:
- checkout: self
clean: true
fetchDepth: 1
submodules: true
- task: PkgESSetupBuild@12
displayName: Package ES - Setup Build
- template: .\templates\restore-nuget-steps.yml
# Download the appx-PLATFORM-CONFIG-VERSION artifact for every platform/version combo
- ${{ each platform in parameters.buildPlatforms }}:
- ${{ each windowsVersion in parameters.buildWindowsVersions }}:
- task: DownloadBuildArtifacts@0
displayName: Download Symbols ${{ platform }} ${{ windowsVersion }}
inputs:
artifactName: appx-${{ platform }}-Release-${{ windowsVersion }}
# It seems easier to do this -- download every appxsym -- then enumerate all the PDBs in the build directory for the
# public symbol push. Otherwise, we would have to list all of the PDB files one by one.
- pwsh: |-
mkdir $(Build.SourcesDirectory)/appxsym-temp
Get-ChildItem "$(System.ArtifactsDirectory)" -Filter *.appxsym -Recurse | % {
$src = $_.FullName
$dest = Join-Path "$(Build.SourcesDirectory)/appxsym-temp/" $_.Name
mkdir $dest
Write-Host "Extracting $src to $dest..."
tar -x -v -f $src -C $dest
}
displayName: Extract symbols for public consumption
- task: PowerShell@2
displayName: Source Index PDBs (the public ones)
inputs:
filePath: build\scripts\Index-Pdbs.ps1
arguments: -SearchDir '$(Build.SourcesDirectory)/appxsym-temp' -SourceRoot '$(Build.SourcesDirectory)' -recursive -Verbose -CommitId $(Build.SourceVersion)
pwsh: true
# Publish the app symbols to the public MSDL symbol server
# accessible via https://msdl.microsoft.com/download/symbols
- task: PublishSymbols@2
displayName: 'Publish app symbols to MSDL'
inputs:
symbolsFolder: '$(Build.SourcesDirectory)/appxsym-temp'
searchPattern: '**/*.pdb'
SymbolsMaximumWaitTime: 30
SymbolServerType: 'TeamServices'
SymbolsProduct: 'Windows Terminal Application Binaries'
SymbolsVersion: '$(XES_APPXMANIFESTVERSION)'
# The ADO task does not support indexing of GitHub sources.
indexSources: false
detailedLog: true
# There is a bug which causes this task to fail if LIB includes an inaccessible path (even though it does not depend on it).
# To work around this issue, we just force LIB to be any dir that we know exists.
# Copied from https://github.com/microsoft/icu/blob/f869c214adc87415dfe751d81f42f1bca55dcf5f/build/azure-nuget.yml#L564-L583
env:
LIB: $(Build.SourcesDirectory)
ArtifactServices_Symbol_AccountName: microsoftpublicsymbols
ArtifactServices_Symbol_PAT: $(ADO_microsoftpublicsymbols_PAT)
- ${{ if eq(parameters.buildTerminalVPack, true) }}:
- job: VPack
displayName: Create Windows vPack
dependsOn: BundleAndSign
steps:
- checkout: self
clean: true
fetchDepth: 1
submodules: true
- task: PkgESSetupBuild@12
displayName: Package ES - Setup Build
- task: DownloadBuildArtifacts@0
displayName: Download Build Artifacts
inputs:
artifactName: appxbundle-signed-Win11
extractTars: false
- task: PowerShell@2
displayName: Rename and stage packages for vpack
inputs:
targetType: inline
script: >-
# Rename to known/fixed name for Windows build system
Get-ChildItem Microsoft.WindowsTerminal_Win11_*.msixbundle | Rename-Item -NewName { 'Microsoft.WindowsTerminal_8wekyb3d8bbwe.msixbundle' }
# Create vpack directory and place item inside
mkdir WindowsTerminal.app
mv Microsoft.WindowsTerminal_8wekyb3d8bbwe.msixbundle .\WindowsTerminal.app\
workingDirectory: $(System.ArtifactsDirectory)\appxbundle-signed-Win11
- task: PkgESVPack@12
displayName: 'Package ES - VPack'
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
inputs:
sourceDirectory: $(System.ArtifactsDirectory)\appxbundle-signed-Win11\WindowsTerminal.app
description: VPack for the Windows Terminal Application
pushPkgName: WindowsTerminal.app
owner: conhost
githubToken: $(GitHubTokenForVpackProvenance)
- task: PublishPipelineArtifact@1
displayName: 'Copy VPack Manifest to Drop'
inputs:
targetPath: $(XES_VPACKMANIFESTDIRECTORY)
artifactName: VPackManifest
- task: PkgESFCIBGit@12
displayName: 'Submit VPack Manifest to Windows'
inputs:
configPath: '$(Build.SourcesDirectory)\build\config\GitCheckin.json'
artifactsDirectory: $(XES_VPACKMANIFESTDIRECTORY)
prTimeOut: 5
...

View File

@@ -0,0 +1,134 @@
parameters:
- name: buildConfigurations
type: object
- name: buildPlatforms
type: object
- name: generateSbom
type: boolean
default: false
- name: codeSign
type: boolean
default: false
- name: pool
type: object
default: []
- name: dependsOn
type: object
default: null
- name: artifactStem
type: string
default: ''
- name: jobName
type: string
default: PackWPF
jobs:
- job: ${{ parameters.jobName }}
${{ if ne(length(parameters.pool), 0) }}:
pool: ${{ parameters.pool }}
${{ if eq(parameters.codeSign, true) }}:
displayName: Pack and Sign Microsoft.Terminal.Wpf
${{ else }}:
displayName: Pack Microsoft.Terminal.Wpf
strategy:
matrix:
${{ each config in parameters.buildConfigurations }}:
${{ config }}:
BuildConfiguration: ${{ config }}
dependsOn: ${{ parameters.dependsOn }}
variables:
OutputBuildPlatform: AnyCPU
Terminal.BinDir: $(Build.SourcesDirectory)/bin/$(OutputBuildPlatform)/$(BuildConfiguration)
steps:
- checkout: self
clean: true
fetchDepth: 1
fetchTags: false # Tags still result in depth > 1 fetch; we don't need them here
submodules: true
persistCredentials: True
- task: PkgESSetupBuild@12
displayName: Package ES - Setup Build
inputs:
disableOutputRedirect: true
- template: steps-download-bin-dir-artifact.yml
parameters:
buildPlatforms:
- ${{ parameters.buildPlatforms }}
- Any CPU # Make sure we grab the precompiled WPF bits
# This build is already matrix'd on configuration, so
# just pass a single config into the download template.
buildConfigurations:
- $(BuildConfiguration)
artifactStem: ${{ parameters.artifactStem }}
- template: .\steps-restore-nuget.yml
- task: VSBuild@1
displayName: Build solution OpenConsole.sln for WPF Control (Pack)
inputs:
solution: 'OpenConsole.sln'
msbuildArgs: >-
/p:WindowsTerminalReleaseBuild=true;Version=$(XES_PACKAGEVERSIONNUMBER)
/p:NoBuild=true
/p:IncludeSymbols=true
/t:Terminal\wpf\WpfTerminalControl:Pack
platform: Any CPU
configuration: $(BuildConfiguration)
maximumCpuCount: true
clean: false
- task: CopyFiles@2
displayName: Copy *.nupkg to Artifacts
inputs:
Contents: 'bin/**/*Wpf*.nupkg'
TargetFolder: $(Build.ArtifactStagingDirectory)/nupkg
OverWrite: true
flattenFolders: true
- ${{ if eq(parameters.codeSign, true) }}:
- task: EsrpCodeSigning@1
displayName: Submit *.nupkg to ESRP for code signing
inputs:
ConnectedServiceName: 9d6d2960-0793-4d59-943e-78dcb434840a
FolderPath: $(Build.ArtifactStagingDirectory)/nupkg
Pattern: '*.nupkg'
UseMinimatch: true
signConfigType: inlineSignParams
inlineOperation: >-
[
{
"KeyCode": "CP-401405",
"OperationCode": "NuGetSign",
"Parameters": {},
"ToolName": "sign",
"ToolVersion": "1.0"
},
{
"KeyCode": "CP-401405",
"OperationCode": "NuGetVerify",
"Parameters": {},
"ToolName": "sign",
"ToolVersion": "1.0"
}
]
- ${{ if eq(parameters.generateSbom, true) }}:
- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
displayName: 'Generate SBOM manifest (wpf)'
inputs:
BuildDropPath: '$(System.ArtifactsDirectory)/nupkg'
BuildComponentPath: '$(Build.SourcesDirectory)/bin'
- task: DropValidatorTask@0
displayName: 'Validate wpf SBOM manifest'
inputs:
BuildDropPath: '$(System.ArtifactsDirectory)/nupkg'
OutputPath: 'output.json'
ValidateSignature: true
Verbosity: 'Verbose'
- publish: $(Build.ArtifactStagingDirectory)\nupkg
artifact: wpf-nupkg-$(BuildConfiguration)${{ parameters.artifactStem }}
displayName: Publish nupkg

View File

@@ -0,0 +1,263 @@
parameters:
- name: branding
type: string
default: Dev
values: [Release, Preview, Dev]
- name: additionalBuildOptions
type: string
default: ''
- name: buildTerminal
type: boolean
default: true
- name: buildConPTY
type: boolean
default: false
- name: buildWPF
type: boolean
default: false
- name: buildWPFDotNetComponents # This weird hack is to make sure we sign and source index the .NET pieces
type: boolean
default: false
- name: buildEverything
displayName: "Build Everything (Overrides all other build options)"
type: boolean
default: false
- name: pgoBuildMode
type: string
default: None
values: [Optimize, Instrument, None]
- name: buildConfigurations
type: object
default:
- Release
- name: buildPlatforms
type: object
default:
- x64
- x86
- arm64
- name: generateSbom
type: boolean
default: false
- name: codeSign
type: boolean
default: false
- name: keepAllExpensiveBuildOutputs
type: boolean
default: true
- name: artifactStem
type: string
default: ''
- name: jobName
type: string
default: 'Build'
- name: pool
type: object
default: []
- name: beforeBuildSteps
type: stepList
default: []
jobs:
- job: ${{ parameters.jobName }}
${{ if ne(length(parameters.pool), 0) }}:
pool: ${{ parameters.pool }}
strategy:
matrix:
${{ each config in parameters.buildConfigurations }}:
${{ each platform in parameters.buildPlatforms }}:
${{ config }}_${{ platform }}:
BuildConfiguration: ${{ config }}
BuildPlatform: ${{ platform }}
${{ if eq(platform, 'x86') }}:
OutputBuildPlatform: Win32
${{ elseif eq(platform, 'Any CPU') }}:
OutputBuildPlatform: AnyCPU
${{ else }}:
OutputBuildPlatform: ${{ platform }}
variables:
MakeAppxPath: 'C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x86\MakeAppx.exe'
Terminal.BinDir: $(Build.SourcesDirectory)/bin/$(OutputBuildPlatform)/$(BuildConfiguration)
# Azure DevOps abhors a vacuum
# If these are blank, expansion will fail later on... which will result in direct substitution of the variable *names*
# later on. We'll just... set them to a single space and if we need to, check IsNullOrWhiteSpace.
# Yup.
BuildTargetParameter: ' '
SelectedSigningFragments: ' '
displayName: Build
timeoutInMinutes: 240
cancelTimeoutInMinutes: 1
steps:
- checkout: self
clean: true
submodules: true
persistCredentials: True
# This generates either nothing for BuildTargetParameter, or /t:X;Y;Z, to control targets later.
- pwsh: |-
If (-Not [bool]::Parse("${{ parameters.buildEverything }}")) {
$BuildTargets = @()
$SignFragments = @()
If ([bool]::Parse("${{ parameters.buildTerminal }}")) {
$BuildTargets += "Terminal\CascadiaPackage"
$SignFragments += "terminal_constituents"
}
If ([bool]::Parse("${{ parameters.buildWPFDotNetComponents }}")) {
$BuildTargets += "Terminal\wpf\WpfTerminalControl"
$SignFragments += "wpfdotnet"
}
If ([bool]::Parse("${{ parameters.buildWPF }}")) {
$BuildTargets += "Terminal\wpf\PublicTerminalCore"
$SignFragments += "wpf"
}
If ([bool]::Parse("${{ parameters.buildConPTY }}")) {
$BuildTargets += "Conhost\Host_EXE;Conhost\winconpty_DLL"
$SignFragments += "conpty"
}
Write-Host "Targets: $($BuildTargets -Join ";")"
Write-Host "Sign targets: $($SignFragments -Join ";")"
Write-Host "##vso[task.setvariable variable=BuildTargetParameter]/t:$($BuildTargets -Join ";")"
Write-Host "##vso[task.setvariable variable=SelectedSigningFragments]$($SignFragments -Join ";")"
}
displayName: Prepare Build and Sign Targets
- pwsh: |-
.\build\scripts\Generate-ThirdPartyNotices.ps1 -MarkdownNoticePath .\NOTICE.md -OutputPath .\src\cascadia\CascadiaPackage\NOTICE.html
displayName: Generate NOTICE.html from NOTICE.md
- template: .\steps-restore-nuget.yml
- ${{ parameters.beforeBuildSteps }}
- task: VSBuild@1
displayName: Build OpenConsole.sln
inputs:
solution: 'OpenConsole.sln'
msbuildArgs: >-
/p:WindowsTerminalOfficialBuild=true;WindowsTerminalBranding=${{ parameters.branding }};PGOBuildMode=${{ parameters.pgoBuildMode }}
${{ parameters.additionalBuildOptions }}
/bl:$(Build.SourcesDirectory)\msbuild.binlog
$(BuildTargetParameter)
platform: $(BuildPlatform)
configuration: $(BuildConfiguration)
maximumCpuCount: true
- publish: $(Build.SourcesDirectory)/msbuild.binlog
artifact: logs-$(BuildPlatform)-$(BuildConfiguration)${{ parameters.artifactStem }}
condition: always()
displayName: Publish Build Log
# This saves ~2GiB per architecture. We won't need these later.
# Removes:
# - All .lib that do not have an associated .exp (which would indicate that they are import libs)
# - All .pdbs from those .libs (which were only used during linking)
# - Directories ending in Lib (static lib projects that we fully linked into DLLs which may also contain unnecessary resources)
# - All LocalTests_ project outputs, as they were subsumed into TestHostApp
# - All PDB files inside the WindowsTerminal/ output, which do not belong there.
- pwsh: |-
$binDir = '$(Terminal.BinDir)'
$ImportLibs = Get-ChildItem $binDir -Recurse -File -Filter '*.exp' | ForEach-Object { $_.FullName -Replace "exp$","lib" }
$StaticLibs = Get-ChildItem $binDir -Recurse -File -Filter '*.lib' | Where-Object FullName -NotIn $ImportLibs
$Items = @()
$Items += $StaticLibs
$Items += Get-Item ($StaticLibs.FullName -Replace "lib$","pdb") -ErrorAction:Ignore
$Items += Get-ChildItem $binDir -Directory -Filter '*Lib'
$Items += Get-ChildItem $binDir -Directory -Filter 'LocalTests_*'
$Items += Get-ChildItem "${$binDir}\WindowsTerminal" -Filter '*.pdb' -ErrorAction:Ignore
If (-Not [bool]::Parse('${{ parameters.keepAllExpensiveBuildOutputs }}')) {
$Items += Get-ChildItem '$(Terminal.BinDir)' -Filter '*.pdb' -Recurse
}
$Items | Remove-Item -Recurse -Force -Verbose -ErrorAction:Ignore
displayName: Clean up static libs and extra symbols
errorActionPreference: silentlyContinue # It's OK if this silently fails
# We cannot index PDBs that we have deleted!
- ${{ if eq(parameters.keepAllExpensiveBuildOutputs, true) }}:
- pwsh: |-
build\scripts\Index-Pdbs.ps1 -SearchDir '$(Terminal.BinDir)' -SourceRoot '$(Build.SourcesDirectory)' -recursive -Verbose -CommitId $(Build.SourceVersion)
displayName: Source Index PDBs
errorActionPreference: silentlyContinue
- ${{ if or(parameters.buildTerminal, parameters.buildEverything) }}:
- pwsh: |-
$Package = (Get-ChildItem -Recurse -Filter "CascadiaPackage*.msix" | Select -First 1)
$PackageFilename = $Package.FullName
Write-Host "##vso[task.setvariable variable=WindowsTerminalPackagePath]${PackageFilename}"
displayName: Locate the MSIX
# CHECK EXCEPTION
# PGO requires a desktop CRT
- ${{ if ne(parameters.pgoBuildMode, 'Instrument') }}:
- pwsh: |-
.\build\scripts\Test-WindowsTerminalPackage.ps1 -Verbose -Path "$(WindowsTerminalPackagePath)"
displayName: Check MSIX for common regressions
condition: and(succeeded(), ne(variables.WindowsTerminalPackagePath, ''))
- ${{ if eq(parameters.codeSign, true) }}:
- pwsh: |-
& "$(MakeAppxPath)" unpack /p "$(WindowsTerminalPackagePath)" /d "$(Terminal.BinDir)/PackageContents"
displayName: Unpack the MSIX for signing
- ${{ if eq(parameters.codeSign, true) }}:
- template: steps-create-signing-config.yml
parameters:
outFile: '$(Build.SourcesDirectory)/ESRPSigningConfig.json'
stage: build
fragments: $(SelectedSigningFragments)
# Code-sign everything we just put together.
# We run the signing in Terminal.BinDir, because all of the signing batches are relative to the final architecture/configuration output folder.
- task: EsrpCodeSigning@1
displayName: Submit Signing Request
inputs:
ConnectedServiceName: 9d6d2960-0793-4d59-943e-78dcb434840a
FolderPath: '$(Terminal.BinDir)'
signType: batchSigning
batchSignPolicyFile: '$(Build.SourcesDirectory)/ESRPSigningConfig.json'
# We only need to re-pack the MSIX if we actually signed, so this can stay in the codeSign conditional
- ${{ if or(parameters.buildTerminal, parameters.buildEverything) }}:
- pwsh: |-
$outDir = New-Item -Type Directory "$(Terminal.BinDir)/_appx" -ErrorAction:Ignore
$PackageFilename = Join-Path $outDir.FullName (Split-Path -Leaf "$(WindowsTerminalPackagePath)")
& "$(MakeAppxPath)" pack /h SHA256 /o /p $PackageFilename /d "$(Terminal.BinDir)/PackageContents"
Write-Host "##vso[task.setvariable variable=WindowsTerminalPackagePath]${PackageFilename}"
displayName: Re-pack the new Terminal package after signing
- ${{ else }}: # No Signing
- ${{ if or(parameters.buildTerminal, parameters.buildEverything) }}:
- pwsh: |-
$outDir = New-Item -Type Directory "$(Terminal.BinDir)/_appx" -ErrorAction:Ignore
$PackageFilename = Join-Path $outDir.FullName (Split-Path -Leaf "$(WindowsTerminalPackagePath)")
Copy-Item "$(WindowsTerminalPackagePath)" $PackageFilename
Write-Host "##vso[task.setvariable variable=WindowsTerminalPackagePath]${PackageFilename}"
displayName: Stage the package (unsigned)
condition: and(succeeded(), ne(variables.WindowsTerminalPackagePath, ''))
- ${{ if or(parameters.buildTerminal, parameters.buildEverything) }}:
- pwsh: |-
$XamlAppxPath = (Get-Item "src\cascadia\CascadiaPackage\AppPackages\*\Dependencies\$(BuildPlatform)\Microsoft.UI.Xaml*.appx").FullName
$outDir = New-Item -Type Directory "$(Terminal.BinDir)/_unpackaged" -ErrorAction:Ignore
& .\build\scripts\New-UnpackagedTerminalDistribution.ps1 -TerminalAppX $(WindowsTerminalPackagePath) -XamlAppX $XamlAppxPath -Destination $outDir.FullName
displayName: Build Unpackaged Distribution (from MSIX)
condition: and(succeeded(), ne(variables.WindowsTerminalPackagePath, ''))
- ${{ if eq(parameters.generateSbom, true) }}:
- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
displayName: 'Generate SBOM manifest'
inputs:
BuildDropPath: '$(Terminal.BinDir)'
- task: DropValidatorTask@0
displayName: 'Validate SBOM manifest'
inputs:
BuildDropPath: '$(Terminal.BinDir)'
OutputPath: 'output.json'
ValidateSignature: true
Verbosity: 'Verbose'
- publish: $(Terminal.BinDir)
artifact: build-$(BuildPlatform)-$(BuildConfiguration)${{ parameters.artifactStem }}
displayName: Publish All Outputs

View File

@@ -0,0 +1,15 @@
jobs:
- job: CodeFormatCheck
displayName: Check Code Format
pool: { vmImage: windows-2022 }
steps:
- checkout: self
fetchDepth: 1
fetchTags: false # Tags still result in depth > 1 fetch; we don't need them here
submodules: false
clean: true
- powershell: |-
.\build\scripts\Invoke-FormattingCheck.ps1
displayName: 'Run formatters'

View File

@@ -1,21 +1,15 @@
parameters:
artifactName: 'drop'
jobs:
- job: CodeNavIndexer
displayName: Run Github CodeNav Indexer
pool: { vmImage: windows-2019 }
pool: { vmImage: windows-2022 }
steps:
- checkout: self
fetchDepth: 1
fetchTags: false # Tags still result in depth > 1 fetch; we don't need them here
submodules: false
clean: true
- task: DownloadBuildArtifacts@0
inputs:
artifactName: ${{ parameters.artifactName }}
- task: RichCodeNavIndexer@0
inputs:
languages: 'cpp,csharp'

View File

@@ -0,0 +1,133 @@
parameters:
- name: branding
type: string
- name: buildConfigurations
type: object
- name: buildPlatforms
type: object
- name: generateSbom
type: boolean
default: false
- name: codeSign
type: boolean
default: false
- name: pool
type: object
default: []
- name: dependsOn
type: object
default: null
- name: artifactStem
type: string
default: ''
- name: jobName
type: string
default: Bundle
jobs:
- job: ${{ parameters.jobName }}
${{ if ne(length(parameters.pool), 0) }}:
pool: ${{ parameters.pool }}
${{ if eq(parameters.codeSign, true) }}:
displayName: Pack and Sign Terminal MSIXBundle
${{ else }}:
displayName: Pack Terminal MSIXBundle
strategy:
matrix:
${{ each config in parameters.buildConfigurations }}:
${{ config }}:
BuildConfiguration: ${{ config }}
variables:
${{ if eq(parameters.branding, 'Release') }}:
BundleStemName: Microsoft.WindowsTerminal
${{ elseif eq(parameters.branding, 'Preview') }}:
BundleStemName: Microsoft.WindowsTerminalPreview
${{ else }}:
BundleStemName: WindowsTerminalDev
dependsOn: ${{ parameters.dependsOn }}
steps:
- checkout: self
clean: true
fetchDepth: 1
fetchTags: false # Tags still result in depth > 1 fetch; we don't need them here
submodules: true
persistCredentials: True
- task: PkgESSetupBuild@12
displayName: Package ES - Setup Build
inputs:
disableOutputRedirect: true
- template: steps-download-bin-dir-artifact.yml
parameters:
buildPlatforms: ${{ parameters.buildPlatforms }}
# This build is already matrix'd on configuration, so
# just pass a single config into the download template.
buildConfigurations:
- $(BuildConfiguration)
artifactStem: ${{ parameters.artifactStem }}
# Add 3000 to the major version component, but only for the bundle.
# This is to ensure that it is newer than "2022.xx.yy.zz" or whatever the original bundle versions were before
# we switched to uniform naming.
- pwsh: |-
$VersionEpoch = 3000
$Components = "$(XES_APPXMANIFESTVERSION)" -Split "\."
$Components[0] = ([int]$Components[0] + $VersionEpoch)
$BundleVersion = $Components -Join "."
New-Item -Type Directory "$(System.ArtifactsDirectory)/bundle"
.\build\scripts\Create-AppxBundle.ps1 -InputPath 'bin/' -ProjectName CascadiaPackage -BundleVersion $BundleVersion -OutputPath "$(System.ArtifactsDirectory)\bundle\$(BundleStemName)_$(XES_APPXMANIFESTVERSION)_8wekyb3d8bbwe.msixbundle"
displayName: Create msixbundle
- ${{ if eq(parameters.codeSign, true) }}:
- task: EsrpCodeSigning@1
displayName: Submit *.msixbundle to ESRP for code signing
inputs:
ConnectedServiceName: 9d6d2960-0793-4d59-943e-78dcb434840a
FolderPath: $(System.ArtifactsDirectory)\bundle
Pattern: $(BundleStemName)*.msixbundle
UseMinimatch: true
signConfigType: inlineSignParams
inlineOperation: >-
[
{
"KeyCode": "Dynamic",
"CertTemplateName": "WINMSAPP1ST",
"CertSubjectName": "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US",
"OperationCode": "SigntoolSign",
"Parameters": {
"OpusName": "Microsoft",
"OpusInfo": "http://www.microsoft.com",
"FileDigest": "/fd \"SHA256\"",
"TimeStamp": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
},
"ToolName": "sign",
"ToolVersion": "1.0"
},
{
"KeyCode": "Dynamic",
"CertTemplateName": "WINMSAPP1ST",
"CertSubjectName": "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US",
"OperationCode": "SigntoolVerify",
"Parameters": {},
"ToolName": "sign",
"ToolVersion": "1.0"
}
]
- ${{ if eq(parameters.generateSbom, true) }}:
- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
displayName: 'Generate SBOM manifest (bundle)'
inputs:
BuildDropPath: '$(System.ArtifactsDirectory)/bundle'
BuildComponentPath: '$(Build.SourcesDirectory)/bin'
- task: DropValidatorTask@0
displayName: 'Validate bundle SBOM manifest'
inputs:
BuildDropPath: '$(System.ArtifactsDirectory)/bundle'
OutputPath: 'output.json'
ValidateSignature: true
Verbosity: 'Verbose'
- publish: '$(System.ArtifactsDirectory)/bundle'
artifact: appxbundle-$(BuildConfiguration)${{ parameters.artifactStem }}
displayName: Publish msixbundle

View File

@@ -0,0 +1,118 @@
parameters:
- name: buildConfigurations
type: object
- name: buildPlatforms
type: object
- name: generateSbom
type: boolean
default: false
- name: codeSign
type: boolean
default: false
- name: pool
type: object
default: []
- name: dependsOn
type: object
default: null
- name: artifactStem
type: string
default: ''
- name: jobName
type: string
default: PackConPTY
jobs:
- job: ${{ parameters.jobName }}
${{ if ne(length(parameters.pool), 0) }}:
pool: ${{ parameters.pool }}
${{ if eq(parameters.codeSign, true) }}:
displayName: Pack and Sign Microsoft.Windows.Console.ConPTY
${{ else }}:
displayName: Pack Microsoft.Windows.Console.ConPTY
strategy:
matrix:
${{ each config in parameters.buildConfigurations }}:
${{ config }}:
BuildConfiguration: ${{ config }}
dependsOn: ${{ parameters.dependsOn }}
steps:
- checkout: self
clean: true
fetchDepth: 1
fetchTags: false # Tags still result in depth > 1 fetch; we don't need them here
submodules: true
persistCredentials: True
- task: PkgESSetupBuild@12
displayName: Package ES - Setup Build
inputs:
disableOutputRedirect: true
- template: steps-download-bin-dir-artifact.yml
parameters:
buildPlatforms: ${{ parameters.buildPlatforms }}
# This build is already matrix'd on configuration, so
# just pass a single config into the download template.
buildConfigurations:
- $(BuildConfiguration)
artifactStem: ${{ parameters.artifactStem }}
- template: steps-ensure-nuget-version.yml
# In the Microsoft Azure DevOps tenant, NuGetCommand is ambiguous.
# This should be `task: NuGetCommand@2`
- task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2
displayName: NuGet pack
inputs:
command: pack
packagesToPack: $(Build.SourcesDirectory)\src\winconpty\package\winconpty.nuspec
packDestination: '$(Build.ArtifactStagingDirectory)/nupkg'
versioningScheme: byEnvVar
versionEnvVar: XES_PACKAGEVERSIONNUMBER
- ${{ if eq(parameters.codeSign, true) }}:
- task: EsrpCodeSigning@1
displayName: Submit *.nupkg to ESRP for code signing
inputs:
ConnectedServiceName: 9d6d2960-0793-4d59-943e-78dcb434840a
FolderPath: $(Build.ArtifactStagingDirectory)/nupkg
Pattern: '*.nupkg'
UseMinimatch: true
signConfigType: inlineSignParams
inlineOperation: >-
[
{
"KeyCode": "CP-401405",
"OperationCode": "NuGetSign",
"Parameters": {},
"ToolName": "sign",
"ToolVersion": "1.0"
},
{
"KeyCode": "CP-401405",
"OperationCode": "NuGetVerify",
"Parameters": {},
"ToolName": "sign",
"ToolVersion": "1.0"
}
]
- ${{ if eq(parameters.generateSbom, true) }}:
- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
displayName: 'Generate SBOM manifest (conpty)'
inputs:
BuildDropPath: '$(System.ArtifactsDirectory)/nupkg'
BuildComponentPath: '$(Build.SourcesDirectory)/bin'
- task: DropValidatorTask@0
displayName: 'Validate conpty SBOM manifest'
inputs:
BuildDropPath: '$(System.ArtifactsDirectory)/nupkg'
OutputPath: 'output.json'
ValidateSignature: true
Verbosity: 'Verbose'
- publish: $(Build.ArtifactStagingDirectory)\nupkg
artifact: conpty-nupkg-$(BuildConfiguration)${{ parameters.artifactStem }}
displayName: Publish nupkg

View File

@@ -1,14 +1,26 @@
# From our friends at MUX: https://github.com/microsoft/microsoft-ui-xaml/blob/main/build/AzurePipelinesTemplates/MUX-BuildAndPublishPGONuGet-Job.yml
parameters:
dependsOn: ''
pgoArtifact: PGO
- name: buildConfiguration
type: string
- name: pool
type: object
default: []
- name: dependsOn
type: object
default: null
- name: artifactStem
type: string
default: ''
- name: jobName
type: string
default: BuildAndPublishPGONuget
jobs:
- job: BuildAndPublishPGONuGet
- job: ${{ parameters.jobName }}
${{ if ne(length(parameters.pool), 0) }}:
pool: ${{ parameters.pool }}
dependsOn: ${{ parameters.dependsOn }}
pool:
vmImage: 'windows-2019'
displayName: Package and Publish PGO Databases
variables:
artifactsPath: $(Build.SourcesDirectory)\Artifacts
pgoToolsPath: $(Build.SourcesDirectory)\build\PGO
@@ -16,20 +28,25 @@ jobs:
nuspecFilename: PGO.nuspec
steps:
- task: DownloadBuildArtifacts@0
- checkout: self
clean: true
# It is important that this be 0, otherwise git will not fetch the branch ref names that the PGO rules require.
fetchDepth: 0
submodules: false
persistCredentials: false
- task: DownloadPipelineArtifact@2
displayName: Download Final PGO Databases
inputs:
artifactName: ${{ parameters.pgoArtifact }}
artifact: pgd-merged-${{ parameters.buildConfiguration }}${{ parameters.artifactStem }}
downloadPath: $(artifactsPath)
- template: steps-ensure-nuget-version.yml
- task: NuGetAuthenticate@0
inputs:
nuGetServiceConnections: 'Terminal Public Artifact Feed'
- task: NuGetToolInstaller@0
displayName: 'Use NuGet 5.8.0'
inputs:
versionSpec: 5.8.0
# In the Microsoft Azure DevOps tenant, NuGetCommand is ambiguous.
# This should be `task: NuGetCommand@2`
- task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2
@@ -45,12 +62,11 @@ jobs:
displayName: 'Create PGO Nuget'
inputs:
solution: $(pgoToolsPath)\PGO.DB.proj
msbuildArguments: '/t:CreatePGONuGet /p:PGOBuildMode=Instrument /p:PGDPathForAllArch=$(artifactsPath)\${{ parameters.pgoArtifact }} /p:PGOOutputPath=$(Build.ArtifactStagingDirectory)'
msbuildArguments: '/t:CreatePGONuGet /p:PGOBuildMode=Instrument /p:PGDPathForAllArch=$(artifactsPath) /p:PGOOutputPath=$(Build.ArtifactStagingDirectory)'
- task: PublishBuildArtifacts@1
inputs:
pathToPublish: $(Build.ArtifactStagingDirectory)
artifactName: ${{ parameters.pgoArtifact }}
- publish: $(Build.ArtifactStagingDirectory)
artifact: pgo-nupkg-${{ parameters.buildConfiguration }}${{ parameters.artifactStem }}
displayName: "Publish Pipeline Artifact"
- task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2
displayName: 'NuGet push'

View File

@@ -0,0 +1,75 @@
parameters:
- name: buildConfiguration
type: string
- name: buildPlatforms
type: object
- name: pool
type: object
default: []
- name: dependsOn
type: object
default: null
- name: artifactStem
type: string
default: ''
- name: jobName
type: string
default: MergePGD
jobs:
- job: ${{ parameters.jobName }}
${{ if ne(length(parameters.pool), 0) }}:
pool: ${{ parameters.pool }}
dependsOn: ${{ parameters.dependsOn }}
displayName: Merge PGO Counts for ${{ parameters.buildConfiguration }}
steps:
# The environment variable VCToolsInstallDir isn't defined on lab machines, so we need to retrieve it ourselves.
- script: |
"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -Latest -requires Microsoft.Component.MSBuild -property InstallationPath > %TEMP%\vsinstalldir.txt
set /p _VSINSTALLDIR15=<%TEMP%\vsinstalldir.txt
del %TEMP%\vsinstalldir.txt
call "%_VSINSTALLDIR15%\Common7\Tools\VsDevCmd.bat"
echo VCToolsInstallDir = %VCToolsInstallDir%
echo ##vso[task.setvariable variable=VCToolsInstallDir]%VCToolsInstallDir%
displayName: 'Retrieve VC tools directory'
- ${{ each platform in parameters.buildPlatforms }}:
- task: DownloadPipelineArtifact@2
displayName: Download PGO Databases for ${{ platform }}
inputs:
artifactName: build-${{ platform }}-${{ parameters.buildConfiguration }}${{ parameters.artifactStem }}
itemPattern: '**/*.pgd'
downloadPath: '$(Build.SourcesDirectory)/pgd/${{ platform }}/${{ parameters.buildConfiguration }}'
- task: DownloadPipelineArtifact@2
displayName: Download PGO Counts for ${{ platform }}
inputs:
artifactName: pgc-intermediates-${{ platform }}-${{ parameters.buildConfiguration }}${{ parameters.artifactStem }}
downloadPath: '$(Build.SourcesDirectory)/pgc/${{ platform }}/${{ parameters.buildConfiguration }}'
- pwsh: |-
$Arch = '${{ platform }}'
$Conf = '${{ parameters.buildConfiguration }}'
$PGCDir = '$(Build.SourcesDirectory)/pgc/${{ platform }}/${{ parameters.buildConfiguration }}'
$PGDDir = '$(Build.SourcesDirectory)/pgd/${{ platform }}/${{ parameters.buildConfiguration }}'
# Flatten the PGD directory
Get-ChildItem $PGDDir -Recurse -Filter *.pgd | Move-Item -Destination $PGDDir -Verbose
Get-ChildItem $PGCDir -Filter *.pgc |
ForEach-Object {
$Parts = $_.Name -Split "!";
$_ | Add-Member Module $Parts[0] -PassThru
} |
Group-Object Module |
ForEach-Object {
& "$(VCToolsInstallDir)\bin\Hostx64\${{ platform }}\pgomgr.exe" /merge $_.Group.FullName "$PGDDir\$($_.Name).pgd"
}
displayName: Merge PGO Counts for ${{ platform }}
- task: CopyFiles@2
displayName: 'Copy merged pgds to artifact staging'
inputs:
sourceFolder: '$(Build.SourcesDirectory)/pgd/${{ platform }}/${{ parameters.buildConfiguration }}'
contents: '**\*.pgd'
targetFolder: '$(Build.ArtifactStagingDirectory)\out-pgd\${{ platform }}'
- publish: $(Build.ArtifactStagingDirectory)\out-pgd
artifact: pgd-merged-${{ parameters.buildConfiguration }}${{ parameters.artifactStem }}
displayName: "Publish merged PGDs"

View File

@@ -0,0 +1,81 @@
parameters:
- name: includePublicSymbolServer
type: boolean
default: false
- name: pool
type: object
default: []
- name: dependsOn
type: object
default: null
- name: artifactStem
type: string
default: ''
- name: jobName
type: string
default: PublishSymbols
jobs:
- job: ${{ parameters.jobName }}
${{ if ne(length(parameters.pool), 0) }}:
pool: ${{ parameters.pool }}
${{ if eq(parameters.includePublicSymbolServer, true) }}:
displayName: Publish Symbols to Internal and MSDL
${{ else }}:
displayName: Publish Symbols Internally
dependsOn: ${{ parameters.dependsOn }}
steps:
- checkout: self
clean: true
fetchDepth: 1
fetchTags: false # Tags still result in depth > 1 fetch; we don't need them here
submodules: true
persistCredentials: True
- task: PkgESSetupBuild@12
displayName: Package ES - Setup Build
inputs:
disableOutputRedirect: true
- task: DownloadPipelineArtifact@2
displayName: Download all PDBs from all prior build phases
inputs:
itemPattern: '**/*.pdb'
targetPath: '$(Build.SourcesDirectory)/bin'
- task: PublishSymbols@2
displayName: Publish Symbols (to current Azure DevOps tenant)
continueOnError: True
inputs:
SymbolsFolder: '$(Build.SourcesDirectory)/bin'
SearchPattern: '**/*.pdb'
IndexSources: false
DetailedLog: true
SymbolsMaximumWaitTime: 30
SymbolServerType: 'TeamServices'
SymbolsProduct: 'Windows Terminal Converged Symbols'
SymbolsVersion: '$(XES_APPXMANIFESTVERSION)'
env:
LIB: $(Build.SourcesDirectory)
- ${{ if eq(parameters.includePublicSymbolServer, true) }}:
- task: PublishSymbols@2
displayName: 'Publish symbols to MSDL'
continueOnError: True
inputs:
SymbolsFolder: '$(Build.SourcesDirectory)/bin'
SearchPattern: '**/*.pdb'
IndexSources: false
DetailedLog: true
SymbolsMaximumWaitTime: 30
SymbolServerType: 'TeamServices'
SymbolsProduct: 'Windows Terminal Converged Symbols'
SymbolsVersion: '$(XES_APPXMANIFESTVERSION)'
# The ADO task does not support indexing of GitHub sources.
# There is a bug which causes this task to fail if LIB includes an inaccessible path (even though it does not depend on it).
# To work around this issue, we just force LIB to be any dir that we know exists.
# Copied from https://github.com/microsoft/icu/blob/f869c214adc87415dfe751d81f42f1bca55dcf5f/build/azure-nuget.yml#L564-L583
env:
LIB: $(Build.SourcesDirectory)
ArtifactServices_Symbol_AccountName: microsoftpublicsymbols
ArtifactServices_Symbol_PAT: $(ADO_microsoftpublicsymbols_PAT)

View File

@@ -0,0 +1,83 @@
parameters:
buildConfiguration: 'Release'
buildPlatform: ''
artifactStem: ''
testLogPath: '$(Build.BinariesDirectory)\$(BuildPlatform)\$(BuildConfiguration)\testsOnBuildMachine.wtl'
jobs:
- job: PGO${{ parameters.buildPlatform }}${{ parameters.buildConfiguration }}
displayName: PGO ${{ parameters.buildPlatform }} ${{ parameters.buildConfiguration }}
variables:
BuildConfiguration: ${{ parameters.buildConfiguration }}
BuildPlatform: ${{ parameters.buildPlatform }}
OutputBuildPlatform: ${{ parameters.buildPlatform }}
Terminal.BinDir: $(Build.SourcesDirectory)/bin/$(OutputBuildPlatform)/$(BuildConfiguration)
pool:
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
${{ if ne(parameters.buildPlatform, 'ARM64') }}:
name: SHINE-OSS-Testing-x64
${{ else }}:
name: SHINE-OSS-Testing-arm64
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
${{ if ne(parameters.buildPlatform, 'ARM64') }}:
name: SHINE-INT-Testing-x64
${{ else }}:
name: SHINE-INT-Testing-arm64
steps:
- checkout: self
submodules: false
clean: true
fetchDepth: 1
fetchTags: false # Tags still result in depth > 1 fetch; we don't need them here
- task: DownloadPipelineArtifact@2
displayName: Download artifacts
inputs:
artifactName: build-${{ parameters.buildPlatform }}-$(BuildConfiguration)${{ parameters.artifactStem }}
downloadPath: $(Terminal.BinDir)
# The tests expect Terminal to be an unpackaged distribution named terminal-0.0.1.0 (after the dev build version scheme)
# Extract to that folder explicitly and strip the embedded folder name from the unpackaged archive.
- powershell: |-
$TargetDirectory = New-Item -Type Directory (Join-Path "$(Terminal.BinDir)" "terminal-0.0.1.0")
& tar.exe -x -v -f (Get-Item "$(Terminal.BinDir)/_unpackaged/*.zip") -C $TargetDirectory.FullName --strip-components=1
displayName: Extract the unpackaged build for PGO
- template: steps-ensure-nuget-version.yml
- powershell: |-
$Package = 'Microsoft.Internal.Windows.Terminal.TestContent'
$Version = '1.0.1'
& nuget.exe install $Package -Version $Version
Write-Host "##vso[task.setvariable variable=TerminalTestContentPath]$(Build.SourcesDirectory)\packages\${Package}.${Version}\content"
displayName: Install Test Content
- task: PowerShell@2
displayName: 'Run PGO Tests'
inputs:
targetType: filePath
filePath: build\scripts\Run-Tests.ps1
arguments: >-
-MatchPattern '*UIA.Tests.dll'
-Platform '$(OutputBuildPlatform)'
-Configuration '$(BuildConfiguration)'
-LogPath '${{ parameters.testLogPath }}'
-Root "$(Terminal.BinDir)"
-AdditionalTaefArguments '/select:(@IsPGO=true)','/p:WTTestContent=$(TerminalTestContentPath)'
condition: and(succeeded(), ne(variables['PGOBuildMode'], 'Instrument'))
- task: CopyFiles@2
displayName: 'Copy PGO outputs to Artifacts'
condition: always()
inputs:
Contents: |
**/*.pgc
${{ parameters.testLogPath }}
TargetFolder: '$(Build.ArtifactStagingDirectory)/$(BuildConfiguration)/$(BuildPlatform)/pgc'
OverWrite: true
flattenFolders: true
- publish: '$(Build.ArtifactStagingDirectory)/$(BuildConfiguration)/$(BuildPlatform)/pgc'
artifact: pgc-intermediates-$(BuildPlatform)-$(BuildConfiguration)${{ parameters.artifactStem }}
condition: always()

View File

@@ -0,0 +1,70 @@
parameters:
- name: buildConfiguration
type: string
- name: generateSbom
type: boolean
default: false
- name: pool
type: object
default: []
- name: dependsOn
type: object
default: null
- name: artifactStem
type: string
default: ''
jobs:
- job: VPack
${{ if ne(length(parameters.pool), 0) }}:
pool: ${{ parameters.pool }}
displayName: Create and Submit Windows vPack
dependsOn: ${{ parameters.dependsOn }}
steps:
- checkout: self
clean: true
fetchDepth: 1
fetchTags: false # Tags still result in depth > 1 fetch; we don't need them here
submodules: true
persistCredentials: True
- task: PkgESSetupBuild@12
displayName: Package ES - Setup Build
inputs:
disableOutputRedirect: true
- task: DownloadPipelineArtifact@2
displayName: Download MSIX Bundle Artifact
inputs:
artifactName: appxbundle-${{ parameters.buildConfiguration }}${{ parameters.artifactStem }}
downloadPath: '$(Build.SourcesDirectory)/bundle'
# Rename to known/fixed name for Windows build system
- powershell: |-
# Create vpack directory and place item inside
$TargetFolder = New-Item -Type Directory '$(Build.SourcesDirectory)/WindowsTerminal.app'
Get-ChildItem bundle/Microsoft.WindowsTerminal_*.msixbundle | Move-Item (Join-Path $TargetFolder.FullName 'Microsoft.WindowsTerminal_8wekyb3d8bbwe.msixbundle') -Verbose
displayName: Stage packages for vpack
- task: PkgESVPack@12
displayName: 'Package ES - VPack'
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
inputs:
sourceDirectory: '$(Build.SourcesDirectory)/WindowsTerminal.app'
description: VPack for the Windows Terminal Application
pushPkgName: WindowsTerminal.app
owner: conhost
githubToken: $(GitHubTokenForVpackProvenance)
- publish: $(XES_VPACKMANIFESTDIRECTORY)
artifact: vpack-manifest${{ parameters.artifactStem }}
displayName: 'Publish VPack Manifest to Drop'
- task: PkgESFCIBGit@12
displayName: 'Submit VPack Manifest to Windows'
inputs:
configPath: '$(Build.SourcesDirectory)\build\config\GitCheckin.json'
artifactsDirectory: $(XES_VPACKMANIFESTDIRECTORY)
prTimeOut: 5

View File

@@ -1,9 +1,8 @@
parameters:
configuration: 'Release'
platform: ''
additionalBuildArguments: ''
artifactName: 'drop'
testLogPath: '$(Build.BinariesDirectory)\$(BuildPlatform)\$(BuildConfiguration)\testsOnBuildMachine.wtl'
artifactStem: ''
jobs:
- job: Test${{ parameters.platform }}${{ parameters.configuration }}
@@ -11,47 +10,52 @@ jobs:
variables:
BuildConfiguration: ${{ parameters.configuration }}
BuildPlatform: ${{ parameters.platform }}
${{ if eq(parameters.platform, 'x86') }}:
OutputBuildPlatform: Win32
${{ else }}:
OutputBuildPlatform: ${{ parameters.platform }}
Terminal.BinDir: $(Build.SourcesDirectory)/bin/$(OutputBuildPlatform)/$(BuildConfiguration)
pool:
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
name: WinDevPoolOSS-L
${{ if ne(parameters.platform, 'ARM64') }}:
name: SHINE-OSS-Testing-x64
${{ else }}:
name: SHINE-OSS-Testing-arm64
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
name: WinDevPool-L
demands: ImageOverride -equals WinDevVS17-latest
${{ if ne(parameters.platform, 'ARM64') }}:
name: SHINE-INT-Testing-x64
${{ else }}:
name: SHINE-INT-Testing-arm64
steps:
- checkout: self
submodules: true
submodules: false
clean: true
fetchDepth: 1
fetchTags: false # Tags still result in depth > 1 fetch; we don't need them here
- task: DownloadBuildArtifacts@0
- task: DownloadPipelineArtifact@2
displayName: Download artifacts
inputs:
artifactName: ${{ parameters.artifactName }}
- task: PowerShell@2
displayName: 'Rationalize build platform'
inputs:
targetType: inline
script: |
$Arch = "$(BuildPlatform)"
If ($Arch -Eq "x86") { $Arch = "Win32" }
Write-Host "##vso[task.setvariable variable=RationalizedBuildPlatform]${Arch}"
artifactName: build-${{ parameters.platform }}-$(BuildConfiguration)${{ parameters.artifactStem }}
downloadPath: $(Terminal.BinDir)
- task: PowerShell@2
displayName: 'Run Unit Tests'
inputs:
targetType: filePath
filePath: build\scripts\Run-Tests.ps1
arguments: -MatchPattern '*unit.test*.dll' -Platform '$(RationalizedBuildPlatform)' -Configuration '$(BuildConfiguration)' -LogPath '${{ parameters.testLogPath }}' -Root "$(System.ArtifactsDirectory)\\${{ parameters.artifactName }}\\$(BuildConfiguration)\\$(BuildPlatform)\\test"
condition: and(and(succeeded(), ne(variables['PGOBuildMode'], 'Instrument')), or(eq(variables['BuildPlatform'], 'x64'), eq(variables['BuildPlatform'], 'x86')))
arguments: -MatchPattern '*unit.test*.dll' -Platform '$(OutputBuildPlatform)' -Configuration '$(BuildConfiguration)' -LogPath '${{ parameters.testLogPath }}' -Root "$(Terminal.BinDir)"
condition: and(succeeded(), ne(variables['PGOBuildMode'], 'Instrument'))
- task: PowerShell@2
displayName: 'Run Feature Tests (x64 only)'
inputs:
targetType: filePath
filePath: build\scripts\Run-Tests.ps1
arguments: -MatchPattern '*feature.test*.dll' -Platform '$(RationalizedBuildPlatform)' -Configuration '$(BuildConfiguration)' -LogPath '${{ parameters.testLogPath }}' -Root "$(System.ArtifactsDirectory)\\${{ parameters.artifactName }}\\$(BuildConfiguration)\\$(BuildPlatform)\\test"
condition: and(and(succeeded(), ne(variables['PGOBuildMode'], 'Instrument')), eq(variables['BuildPlatform'], 'x64'))
- ${{ if or(eq(parameters.platform, 'x64'), eq(parameters.platform, 'arm64')) }}:
- task: PowerShell@2
displayName: 'Run Feature Tests'
inputs:
targetType: filePath
filePath: build\scripts\Run-Tests.ps1
arguments: -MatchPattern '*feature.test*.dll' -Platform '$(OutputBuildPlatform)' -Configuration '$(BuildConfiguration)' -LogPath '${{ parameters.testLogPath }}' -Root "$(Terminal.BinDir)"
condition: and(succeeded(), ne(variables['PGOBuildMode'], 'Instrument'))
- task: PowerShell@2
displayName: 'Convert Test Logs from WTL to xUnit format'
@@ -59,7 +63,15 @@ jobs:
targetType: filePath
filePath: build\Helix\ConvertWttLogToXUnit.ps1
arguments: -WttInputPath '${{ parameters.testLogPath }}' -WttSingleRerunInputPath 'unused.wtl' -WttMultipleRerunInputPath 'unused2.wtl' -XUnitOutputPath 'onBuildMachineResults.xml' -TestNamePrefix '$(BuildConfiguration).$(BuildPlatform)'
condition: and(ne(variables['PGOBuildMode'], 'Instrument'),or(eq(variables['BuildPlatform'], 'x64'), eq(variables['BuildPlatform'], 'x86')))
condition: ne(variables['PGOBuildMode'], 'Instrument')
- task: PowerShell@2
displayName: 'Manually log test failures'
inputs:
targetType: filePath
filePath: build\Helix\OutputTestErrorsForAzureDevops.ps1
arguments: -XUnitOutputPath 'onBuildMachineResults.xml'
condition: ne(variables['PGOBuildMode'], 'Instrument')
- task: PublishTestResults@2
displayName: 'Upload converted test logs'
@@ -67,13 +79,9 @@ jobs:
inputs:
testResultsFormat: 'xUnit' # Options: JUnit, NUnit, VSTest, xUnit, cTest
testResultsFiles: '**/onBuildMachineResults.xml'
#searchFolder: '$(System.DefaultWorkingDirectory)' # Optional
#mergeTestResults: false # Optional
#failTaskOnFailedTests: false # Optional
testRunTitle: 'On Build Machine Tests' # Optional
buildPlatform: $(BuildPlatform) # Optional
buildConfiguration: $(BuildConfiguration) # Optional
#publishRunAttachments: true # Optional
- task: CopyFiles@2
displayName: 'Copy result logs to Artifacts'
@@ -87,4 +95,4 @@ jobs:
flattenFolders: true
- publish: '$(Build.ArtifactStagingDirectory)/$(BuildConfiguration)/$(BuildPlatform)/test-logs'
artifact: TestLogs$(BuildPlatform)$(BuildConfiguration)
artifact: test-logs-$(BuildPlatform)-$(BuildConfiguration)${{ parameters.artifactStem }}

View File

@@ -0,0 +1,35 @@
parameters:
- name: stage
type: string
- name: outFile
type: string
- name: fragments
type: string
# This build step template takes all files named "esrp.STAGE.batch.*.json"
# and merges them into a single output signing config.
#
# We generate the batch signing config by sticking together multiple "batches".
# The filter below (with Fragments) works by splitting the filename, esrp.s.batch.x.json,
# to get 'x' and then checking whether x is in Fragments.
# We have to manually strip comments out of the batch fragments due to https://github.com/PowerShell/PowerShell/issues/14553
steps:
- pwsh: |-
$SignBatchFiles = (Get-Item build/config/esrp.${{ parameters.stage }}.batch.*.json)
$Fragments = "${{ parameters.fragments }}"
If (-Not [String]::IsNullOrWhiteSpace($Fragments)) {
$FragmentList = $Fragments -Split ";"
If ($FragmentList.Length -Gt 0) {
$SignBatchFiles = $SignBatchFiles | Where-Object { ($_.Name -Split '\.')[3] -In $FragmentList }
}
}
Write-Host "Found $(@($SignBatchFiles).Length) Signing Configs"
Write-Host ($SignBatchFiles.Name -Join ";")
$FinalSignConfig = @{
Version = "1.0.0";
UseMinimatch = $false;
SignBatches = @($SignBatchFiles | ForEach-Object { Get-Content $_ | Where-Object { $_ -NotMatch "^\s*\/\/" } | ConvertFrom-Json -Depth 10 });
}
$FinalSignConfig | ConvertTo-Json -Depth 10 | Out-File -Encoding utf8 "${{ parameters.outFile }}"
displayName: Merge ${{ parameters.stage }} signing configs (${{ parameters.outFile }})

View File

@@ -0,0 +1,24 @@
parameters:
- name: buildConfigurations
type: object
- name: buildPlatforms
type: object
- name: artifactStem
type: string
default: ''
steps:
- ${{ each configuration in parameters.buildConfigurations }}:
- ${{ each platform in parameters.buildPlatforms }}:
- task: DownloadPipelineArtifact@2
displayName: Download artifacts for ${{ platform }} ${{ configuration }}
inputs:
# Make sure to download the entire artifact, because it includes the SPDX SBOM
artifactName: build-${{ platform }}-${{ configuration }}${{ parameters.artifactStem }}
# Downloading to the source directory should ensure that the later SBOM generator can see the earlier SBOMs.
${{ if eq(platform, 'x86') }}:
downloadPath: '$(Build.SourcesDirectory)/bin/Win32/${{ configuration }}'
${{ elseif eq(platform, 'Any CPU') }}:
downloadPath: '$(Build.SourcesDirectory)/bin/AnyCPU/${{ configuration }}'
${{ else }}:
downloadPath: '$(Build.SourcesDirectory)/bin/${{ platform }}/${{ configuration }}'

View File

@@ -0,0 +1,5 @@
steps:
- task: NuGetToolInstaller@1
displayName: Use NuGet 6.6.1
inputs:
versionSpec: 6.6.1

View File

@@ -0,0 +1,27 @@
parameters:
- name: includePseudoLoc
type: boolean
default: true
steps:
- task: TouchdownBuildTask@1
displayName: Download Localization Files
inputs:
teamId: 7105
authId: $(TouchdownAppId)
authKey: $(TouchdownAppKey)
resourceFilePath: |
src\cascadia\**\en-US\*.resw
appendRelativeDir: true
localizationTarget: false
${{ if eq(parameters.includePseudoLoc, true) }}:
pseudoSetting: Included
- pwsh: |-
$Files = Get-ChildItem . -R -Filter 'Resources.resw' | ? FullName -Like '*en-US\*\Resources.resw'
$Files | % { Move-Item -Verbose $_.Directory $_.Directory.Parent.Parent -EA:Ignore }
displayName: Move Loc files into final locations
- pwsh: |-
./build/scripts/Copy-ContextMenuResourcesToCascadiaPackage.ps1
displayName: Copy the Context Menu Loc Resources to CascadiaPackage

View File

@@ -1,11 +1,13 @@
steps:
- task: NuGetToolInstaller@0
displayName: 'Use NuGet 6.3.0'
inputs:
versionSpec: 6.3.0
- template: steps-ensure-nuget-version.yml
- task: NuGetAuthenticate@0
- script: |-
echo ##vso[task.setvariable variable=NUGET_RESTORE_MSBUILD_ARGS]/p:Platform=$(BuildPlatform)
displayName: Ensure NuGet restores for $(BuildPlatform)
condition: and(succeeded(), ne(variables['BuildPlatform'], 'Any CPU'))
# In the Microsoft Azure DevOps tenant, NuGetCommand is ambiguous.
# This should be `task: NuGetCommand@2`
- task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2

View File

@@ -1,34 +0,0 @@
parameters:
platform: ''
additionalBuildArguments: ''
jobs:
- job: Build${{ parameters.platform }}AuditMode
displayName: Static Analysis Build ${{ parameters.platform }}
variables:
BuildConfiguration: AuditMode
BuildPlatform: ${{ parameters.platform }}
pool:
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
name: WinDevPoolOSS-L
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
name: WinDevPool-L
demands: ImageOverride -equals WinDevVS17-latest
steps:
- checkout: self
submodules: true
clean: true
fetchDepth: 1
- template: restore-nuget-steps.yml
- task: VSBuild@1
displayName: 'Build solution **\OpenConsole.sln'
inputs:
solution: '**\OpenConsole.sln'
platform: '$(BuildPlatform)'
configuration: '$(BuildConfiguration)'
msbuildArgs: ${{ parameters.additionalBuildArguments }}
clean: true
maximumCpuCount: true

View File

@@ -1,31 +0,0 @@
parameters:
configuration: 'Release'
branding: 'Dev'
platform: ''
additionalBuildArguments: ''
jobs:
- job: Build${{ parameters.platform }}${{ parameters.configuration }}${{ parameters.branding }}
displayName: Build ${{ parameters.platform }} ${{ parameters.configuration }} ${{ parameters.branding }}
variables:
BuildConfiguration: ${{ parameters.configuration }}
BuildPlatform: ${{ parameters.platform }}
WindowsTerminalBranding: ${{ parameters.branding }}
EnableRichCodeNavigation: true
pool:
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
name: WinDevPoolOSS-L
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
name: WinDevPool-L
demands: ImageOverride -equals WinDevVS17-latest
steps:
- template: build-console-steps.yml
parameters:
additionalBuildArguments: ${{ parameters.additionalBuildArguments }}
# It appears that the Component Governance build task that gets automatically injected stopped working
# when we renamed our main branch.
- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
displayName: 'Component Detection'
condition: and(succeededOrFailed(), not(eq(variables['Build.Reason'], 'PullRequest')))

View File

@@ -1,203 +0,0 @@
jobs:
- job: Compliance
# We don't *need* a matrix but there's no other way to set parameters on a "job"
# in the AzDO YAML syntax. It would have to be a "stage" or a "template".
# Doesn't matter. We're going to do compliance on Release x64 because
# that's the one all the tooling works against for sure.
strategy:
matrix:
Release_x64:
BuildConfiguration: Release
BuildPlatform: x64
displayName: Validate Security and Compliance
timeoutInMinutes: 240
steps:
- checkout: self
clean: true
submodules: true
persistCredentials: True
- task: PkgESSetupBuild@12
displayName: Package ES - Setup Build
inputs:
disableOutputRedirect: true
- task: PowerShell@2
displayName: Rationalize Build Platform
inputs:
targetType: inline
script: >-
$Arch = "$(BuildPlatform)"
If ($Arch -Eq "x86") { $Arch = "Win32" }
Write-Host "##vso[task.setvariable variable=RationalizedBuildPlatform]${Arch}"
- template: restore-nuget-steps.yml
- task: UniversalPackages@0
displayName: Download terminal-internal Universal Package
inputs:
feedListDownload: 2b3f8893-a6e8-411f-b197-a9e05576da48
packageListDownload: e82d490c-af86-4733-9dc4-07b772033204
versionListDownload: $(TerminalInternalPackageVersion)
- task: TouchdownBuildTask@1
displayName: Download Localization Files
inputs:
teamId: 7105
authId: $(TouchdownAppId)
authKey: $(TouchdownAppKey)
resourceFilePath: >-
src\cascadia\TerminalApp\Resources\en-US\Resources.resw
src\cascadia\TerminalControl\Resources\en-US\Resources.resw
src\cascadia\TerminalConnection\Resources\en-US\Resources.resw
src\cascadia\TerminalSettingsModel\Resources\en-US\Resources.resw
src\cascadia\TerminalSettingsEditor\Resources\en-US\Resources.resw
src\cascadia\CascadiaPackage\Resources\en-US\Resources.resw
appendRelativeDir: true
localizationTarget: false
pseudoSetting: Included
- task: PowerShell@2
displayName: Move Loc files one level up
inputs:
targetType: inline
script: >-
$Files = Get-ChildItem . -R -Filter 'Resources.resw' | ? FullName -Like '*en-US\*\Resources.resw'
$Files | % { Move-Item -Verbose $_.Directory $_.Directory.Parent.Parent -EA:Ignore }
pwsh: true
# 1ES Component Governance onboarding (Detects open source components). See https://docs.opensource.microsoft.com/tools/cg.html
- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
displayName: Component Detection
# # PREfast and PoliCheck need Node. Install that first.
- task: NodeTool@0
# !!! NOTE !!! Run PREfast first. Some of the other tasks are going to run on a completed build.
# PREfast is going to build the code as a part of its analysis and the generated sources
# and output binaries will be sufficient for the rest of the analysis.
# If you disable this, the other tasks won't likely work. You would have to add a build
# step instead that builds the code normally before calling them.
# Also... PREfast will rebuild anyway so that's why we're not running a normal build first.
# Waste of time to build twice.
# PREfast. See https://www.1eswiki.com/wiki/SDL_Native_Rules_Build_Task
# The following 1ES tasks all operate completely differently and have a different syntax for usage.
# Most notable is every one of them has a different way of excluding things.
# Go see their 1eswiki.com pages to figure out how to exclude things.
# When writing exclusions, try to make them narrow so when new projects/binaries are added, they
# cause an error here and have to be explicitly pulled out. Don't write an exclusion so broad
# that it will catch other new stuff.
# https://www.1eswiki.com/wiki/PREfast_Build_Task
# Builds the project with C/C++ static analysis tools to find coding flaws and vulnerabilities
# !!! WARNING !!! It doesn't work with WAPPROJ packaging projects. Build the sub-projects instead.
- task: securedevelopmentteam.vss-secure-development-tools.build-task-prefast.SDLNativeRules@3
displayName: 'Run the PREfast SDL Native Rules for MSBuild'
condition: succeededOrFailed()
inputs:
setupCommandlines: '"C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsMSBuildCmd.bat"'
msBuildCommandline: msbuild.exe /nologo /m /p:WindowsTerminalOfficialBuild=true /p:WindowsTerminalBranding=${{ parameters.branding }} /p:WindowsTerminalReleaseBuild=true /p:platform=$(BuildPlatform) /p:configuration=$(BuildConfiguration) /t:Terminal\Window\WindowsTerminal /p:VisualStudioVersion=17.0 $(Build.SourcesDirectory)\OpenConsole.sln
msBuildVersion: "17.0"
# Copies output from PREfast SDL Native Rules task to expected location for consumption by PkgESSecComp
- task: CopyFiles@1
displayName: 'Copy PREfast xml files to SDLNativeRulesDir'
inputs:
SourceFolder: '$(Agent.BuildDirectory)'
Contents: |
**\*.nativecodeanalysis.xml
TargetFolder: '$(Agent.BuildDirectory)\_sdt\logs\SDLNativeRules'
# https://www.1eswiki.com/index.php?title=PoliCheck_Build_Task
# Scans the text of source code, comments, and content for terminology that could be sensitive for legal, cultural, or geopolitical reasons.
# (Also finds vulgarities... takes all the fun out of everything.)
- task: securedevelopmentteam.vss-secure-development-tools.build-task-policheck.PoliCheck@2
displayName: 'Run PoliCheck'
inputs:
targetType: F
targetArgument: $(Build.SourcesDirectory)
result: PoliCheck.xml
optionsFC: 1
optionsXS: 1
optionsUEPath: $(Build.SourcesDirectory)\build\config\PolicheckExclusions.xml
optionsHMENABLE: 0
continueOnError: true
# https://www.1eswiki.com/wiki/CredScan_Azure_DevOps_Build_Task
# Searches through source code and build outputs for a credential left behind in the open
- task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@3
displayName: 'Run CredScan'
inputs:
outputFormat: pre
# suppressionsFile: LocalSuppressions.json
batchSize: 20
debugMode: false
continueOnError: true
# https://www.1eswiki.com/wiki/BinSkim_Build_Task
# Searches managed and unmanaged binaries for known security vulnerabilities.
- task: securedevelopmentteam.vss-secure-development-tools.build-task-binskim.BinSkim@4
displayName: 'Run BinSkim'
inputs:
TargetPattern: guardianGlob
# See https://aka.ms/gdn-globs for how to do match patterns
AnalyzeTargetGlob: $(Build.SourcesDirectory)\bin\**\*.dll;$(Build.SourcesDirectory)\bin\**\*.exe;-:file|**\Microsoft.UI.Xaml.dll;-:file|**\Microsoft.Toolkit.Win32.UI.XamlHost.dll;-:file|**\vcruntime*.dll;-:file|**\vcomp*.dll;-:file|**\vccorlib*.dll;-:file|**\vcamp*.dll;-:file|**\msvcp*.dll;-:file|**\concrt*.dll;-:file|**\TerminalThemeHelpers*.dll;-:file|**\cpprest*.dll
continueOnError: true
# Set XES_SERIALPOSTBUILDREADY to run Security and Compliance task once per build
- powershell: Write-Host "##vso[task.setvariable variable=XES_SERIALPOSTBUILDREADY;]true"
displayName: 'Set XES_SERIALPOSTBUILDREADY Vars'
# https://www.osgwiki.com/wiki/Package_ES_Security_and_Compliance
# Does a few things:
# - Ensures that Windows-required compliance tasks are run either inside this task
# or were run as a previous step prior to this one
# (PREfast, PoliCheck, Credscan)
# - Runs Windows-specific compliance tasks inside the task
# + CheckCFlags - ensures that compiler and linker flags meet Windows standards
# + CFGCheck/XFGCheck - ensures that Control Flow Guard (CFG) or
# eXtended Flow Guard (XFG) are enabled on binaries
# NOTE: CFG is deprecated and XFG isn't fully ready yet.
# NOTE2: CFG fails on an XFG'd binary
# - Brokers all security/compliance task logs to "Trust Services Automation (TSA)" (https://aka.ms/tsa)
# which is a system that maps all errors into the appropriate bug database
# template for each organization since they all vary. It should also suppress
# new bugs when one already exists for the product.
# This one is set up to go to the OS repository and use the given parameters
# to file bugs to our AzDO product path.
# If we don't use PkgESSecComp to do this for us, we need to install the TSA task
# ourselves in this pipeline to finalize data upload and bug creation.
# !!! NOTE !!! This task goes *LAST* after any other compliance tasks so it catches their logs
- task: PkgESSecComp@10
displayName: 'Security and Compliance tasks'
inputs:
fileNewBugs: false
areaPath: 'OS\WDX\DXP\WinDev\Terminal'
teamProject: 'OS'
iterationPath: 'OS\Future'
bugTags: 'TerminalReleaseCompliance'
scanAll: true
errOnBugs: false
failOnStdErr: true
taskLogVerbosity: Diagnostic
secCompConfigFromTask: |
# Overrides default build sources directory
sourceTargetOverrideAll: $(Build.SourcesDirectory)
# Overrides default build binaries directory when "Scan all" option is specified
binariesTargetOverrideAll: $(Build.SourcesDirectory)\bin
# Set the tools to false if they should not run in the build
tools:
- toolName: CheckCFlags
enable: true
- toolName: CFGCheck
enable: true
- toolName: Policheck
enable: false
- toolName: CredScan
enable: false
- toolName: XFGCheck
enable: false

View File

@@ -1,90 +0,0 @@
parameters:
configuration: 'Fuzzing'
platform: ''
additionalBuildArguments: ''
jobs:
- job: Build${{ parameters.platform }}${{ parameters.configuration }}
displayName: Build ${{ parameters.platform }} ${{ parameters.configuration }}
variables:
BuildConfiguration: ${{ parameters.configuration }}
BuildPlatform: ${{ parameters.platform }}
pool:
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
name: WinDevPoolOSS-L
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
name: WinDevPool-L
demands: ImageOverride -equals WinDevVS17-latest
steps:
- checkout: self
submodules: true
clean: true
- template: restore-nuget-steps.yml
# The environment variable VCToolsInstallDir isn't defined on lab machines, so we need to retrieve it ourselves.
- script: |
"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -Latest -requires Microsoft.Component.MSBuild -property InstallationPath > %TEMP%\vsinstalldir.txt
set /p _VSINSTALLDIR15=<%TEMP%\vsinstalldir.txt
del %TEMP%\vsinstalldir.txt
call "%_VSINSTALLDIR15%\Common7\Tools\VsDevCmd.bat"
echo VCToolsInstallDir = %VCToolsInstallDir%
echo ##vso[task.setvariable variable=VCToolsInstallDir]%VCToolsInstallDir%
displayName: 'Retrieve VC tools directory'
- task: VSBuild@1
displayName: 'Build solution **\OpenConsole.sln'
inputs:
solution: '**\OpenConsole.sln'
platform: '$(BuildPlatform)'
configuration: '$(BuildConfiguration)'
msbuildArgs: "${{ parameters.additionalBuildArguments }}"
clean: true
maximumCpuCount: true
- task: PowerShell@2
displayName: 'Rationalize build platform'
inputs:
targetType: inline
script: |
$Arch = "$(BuildPlatform)"
If ($Arch -Eq "x86") { $Arch = "Win32" }
Write-Host "##vso[task.setvariable variable=RationalizedBuildPlatform]${Arch}"
- task: CopyFiles@2
displayName: 'Copy result logs to Artifacts'
inputs:
Contents: |
**/*.wtl
**/*onBuildMachineResults.xml
${{ parameters.testLogPath }}
TargetFolder: '$(Build.ArtifactStagingDirectory)/$(BuildConfiguration)/$(BuildPlatform)/test'
OverWrite: true
flattenFolders: true
- task: CopyFiles@2
displayName: 'Copy outputs needed for test runs to Artifacts'
inputs:
Contents: |
$(Build.SourcesDirectory)/bin/$(RationalizedBuildPlatform)/$(BuildConfiguration)/*.exe
$(Build.SourcesDirectory)/bin/$(RationalizedBuildPlatform)/$(BuildConfiguration)/*.dll
$(Build.SourcesDirectory)/bin/$(RationalizedBuildPlatform)/$(BuildConfiguration)/*.xml
**/Microsoft.VCLibs.*.appx
**/TestHostApp/*.exe
**/TestHostApp/*.dll
**/TestHostApp/*.xml
!**/*.pdb
!**/*.ipdb
!**/*.obj
!**/*.pch
TargetFolder: '$(Build.ArtifactStagingDirectory)/$(BuildConfiguration)/$(BuildPlatform)/test'
OverWrite: true
flattenFolders: true
condition: succeeded()
- task: PublishBuildArtifacts@1
displayName: 'Publish All Build Artifacts'
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactName: 'fuzzingBuildOutput'

View File

@@ -1,55 +0,0 @@
parameters:
configuration: 'Release'
platform: ''
additionalBuildArguments: ''
minimumExpectedTestsExecutedCount: 1 # Sanity check for minimum expected tests to be reported
rerunPassesRequiredToAvoidFailure: 5
jobs:
- job: Build${{ parameters.platform }}${{ parameters.configuration }}
displayName: Build ${{ parameters.platform }} ${{ parameters.configuration }}
variables:
BuildConfiguration: ${{ parameters.configuration }}
BuildPlatform: ${{ parameters.platform }}
PGOBuildMode: 'Instrument'
pool:
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
name: WinDevPoolOSS-L
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
name: WinDevPool-L
demands: ImageOverride -equals WinDevVS17-latest
steps:
- template: build-console-steps.yml
parameters:
additionalBuildArguments: '${{ parameters.additionalBuildArguments }}'
- template: helix-runtests-job.yml
parameters:
name: 'RunTestsInHelix'
dependsOn: Build${{ parameters.platform }}${{ parameters.configuration }}
condition: succeeded()
testSuite: 'PgoInstrumentationSuite'
taefQuery: '@IsPgo=true'
configuration: ${{ parameters.configuration }}
platform: ${{ parameters.platform }}
rerunPassesRequiredToAvoidFailure: ${{ parameters.rerunPassesRequiredToAvoidFailure }}
- template: helix-processtestresults-job.yml
parameters:
name: 'ProcessTestResults'
pgoArtifact: 'PGO'
dependsOn:
- RunTestsInHelix
condition: succeededOrFailed()
rerunPassesRequiredToAvoidFailure: ${{ parameters.rerunPassesRequiredToAvoidFailure }}
minimumExpectedTestsExecutedCount: ${{ parameters.minimumExpectedTestsExecutedCount }}
- template: pgo-merge-pgd-job.yml
parameters:
name: 'MergePGD'
dependsOn:
- ProcessTestResults
pgoArtifact: 'PGO'
platform: ${{ parameters.platform }}
configuration: ${{ parameters.configuration }}

View File

@@ -1,130 +0,0 @@
parameters:
additionalBuildArguments: ''
steps:
- checkout: self
submodules: true
clean: true
fetchDepth: 1
- template: restore-nuget-steps.yml
# The environment variable VCToolsInstallDir isn't defined on lab machines, so we need to retrieve it ourselves.
- script: |
"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -Latest -requires Microsoft.Component.MSBuild -property InstallationPath > %TEMP%\vsinstalldir.txt
set /p _VSINSTALLDIR15=<%TEMP%\vsinstalldir.txt
del %TEMP%\vsinstalldir.txt
call "%_VSINSTALLDIR15%\Common7\Tools\VsDevCmd.bat"
echo VCToolsInstallDir = %VCToolsInstallDir%
echo ##vso[task.setvariable variable=VCToolsInstallDir]%VCToolsInstallDir%
displayName: 'Retrieve VC tools directory'
- task: CmdLine@1
displayName: 'Display build machine environment variables'
inputs:
filename: 'set'
- task: VSBuild@1
displayName: 'Build solution **\OpenConsole.sln'
inputs:
solution: '**\OpenConsole.sln'
platform: '$(BuildPlatform)'
configuration: '$(BuildConfiguration)'
msbuildArgs: "${{ parameters.additionalBuildArguments }} /p:PGOBuildMode=$(PGOBuildMode) /bl:$(Build.SourcesDirectory)\\msbuild.binlog"
clean: true
maximumCpuCount: true
- task: PowerShell@2
displayName: 'Check MSIX for common regressions'
# PGO runtime needs its own CRT and it's in the package for convenience.
# That will make this script mad so skip since we're not shipping the PGO Instrumentation one anyway.
condition: ne(variables['PGOBuildMode'], 'Instrument')
inputs:
targetType: inline
script: |
$Package = Get-ChildItem -Recurse -Filter "CascadiaPackage_*.msix"
.\build\scripts\Test-WindowsTerminalPackage.ps1 -Verbose -Path $Package.FullName
- task: powershell@2
displayName: 'Source Index PDBs'
condition: ne(variables['PGOBuildMode'], 'Instrument')
inputs:
targetType: filePath
filePath: build\scripts\Index-Pdbs.ps1
arguments: -SearchDir '$(Build.SourcesDirectory)' -SourceRoot '$(Build.SourcesDirectory)' -recursive -Verbose -CommitId $(Build.SourceVersion)
errorActionPreference: silentlyContinue
- task: PowerShell@2
displayName: 'Rationalize build platform'
inputs:
targetType: inline
script: |
$Arch = "$(BuildPlatform)"
If ($Arch -Eq "x86") { $Arch = "Win32" }
Write-Host "##vso[task.setvariable variable=RationalizedBuildPlatform]${Arch}"
- task: CopyFiles@2
displayName: 'Copy *.appx/*.msix to Artifacts (Non-PR builds only)'
inputs:
Contents: |
**/*.appx
**/*.msix
**/*.appxsym
!**/Microsoft.VCLibs*.appx
TargetFolder: '$(Build.ArtifactStagingDirectory)/appx'
OverWrite: true
flattenFolders: true
condition: succeeded()
- task: CopyFiles@2
displayName: 'Copy outputs needed for test runs to Artifacts'
inputs:
Contents: |
$(Build.SourcesDirectory)/bin/$(RationalizedBuildPlatform)/$(BuildConfiguration)/*.exe
$(Build.SourcesDirectory)/bin/$(RationalizedBuildPlatform)/$(BuildConfiguration)/*.dll
$(Build.SourcesDirectory)/bin/$(RationalizedBuildPlatform)/$(BuildConfiguration)/*.xml
**/Microsoft.VCLibs.*.appx
**/*unit.test*.dll
**/*unit.test*.manifest
**/TestHostApp/*.exe
**/TestHostApp/*.dll
**/TestHostApp/*.xml
!**/*.pdb
!**/*.ipdb
!**/*.obj
!**/*.pch
TargetFolder: '$(Build.ArtifactStagingDirectory)/$(BuildConfiguration)/$(BuildPlatform)/test'
OverWrite: true
flattenFolders: true
condition: succeeded()
- task: PublishBuildArtifacts@1
displayName: 'Publish All Build Artifacts'
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactName: 'drop'
- task: CopyFiles@2
displayName: 'Copy PGO databases needed for PGO instrumentation run'
inputs:
Contents: |
**/*.pgd
TargetFolder: '$(Build.ArtifactStagingDirectory)/$(BuildConfiguration)/PGO/$(BuildPlatform)'
OverWrite: true
flattenFolders: true
condition: and(succeeded(), eq(variables['PGOBuildMode'], 'Instrument'))
- task: PublishBuildArtifacts@1
displayName: 'Publish All PGO Artifacts'
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)/$(BuildConfiguration)/PGO'
ArtifactName: 'PGO'
condition: and(succeeded(), eq(variables['PGOBuildMode'], 'Instrument'))
- task: PublishBuildArtifacts@1
displayName: 'Publish Artifact: binlog'
condition: always()
continueOnError: True
inputs:
PathtoPublish: $(Build.SourcesDirectory)\msbuild.binlog
ArtifactName: binlog-$(BuildPlatform)

View File

@@ -1,17 +0,0 @@
jobs:
- job: CodeFormatCheck
displayName: Proper Code Formatting Check
pool: { vmImage: windows-2022 }
steps:
- checkout: self
fetchDepth: 1
submodules: false
clean: true
- task: PowerShell@2
displayName: 'Code Formatting Check'
inputs:
targetType: filePath
filePath: '.\build\scripts\Invoke-FormattingCheck.ps1'

View File

@@ -1,25 +0,0 @@
parameters:
configuration: 'Release'
platform: ''
minimumExpectedTestsExecutedCount: 10 # Sanity check for minimum expected tests to be reported
rerunPassesRequiredToAvoidFailure: 5
jobs:
- template: helix-runtests-job.yml
parameters:
name: 'RunTestsInHelix'
# We're not setting dependsOn as we want to rely on the "stage" dependency above us
testSuite: 'DevTestSuite'
platform: ${{ parameters.platform }}
configuration: ${{ parameters.configuration }}
rerunPassesRequiredToAvoidFailure: ${{ parameters.rerunPassesRequiredToAvoidFailure }}
- template: helix-processtestresults-job.yml
parameters:
dependsOn:
- RunTestsInHelix
# the default condition is succeededOrFailed(), and the "stage" condition ensures we only run as needed
platform: ${{ parameters.platform }}
configuration: ${{ parameters.configuration }}
rerunPassesRequiredToAvoidFailure: ${{ parameters.rerunPassesRequiredToAvoidFailure }}
minimumExpectedTestsExecutedCount: ${{ parameters.minimumExpectedTestsExecutedCount }}

View File

@@ -1,15 +0,0 @@
parameters:
condition: ''
testFilePath: ''
outputProjFileName: ''
testSuite: ''
taefQuery: ''
steps:
- task: powershell@2
displayName: 'Create ${{ parameters.outputProjFileName }}'
condition: ${{ parameters.condition }}
inputs:
targetType: filePath
filePath: build\Helix\GenerateTestProjFile.ps1
arguments: -TestFile '${{ parameters.testFilePath }}' -OutputProjFile '$(Build.ArtifactStagingDirectory)\$(BuildConfiguration)\$(BuildPlatform)\${{ parameters.outputProjFileName }}' -JobTestSuiteName '${{ parameters.testSuite }}' -TaefPath '$(Build.SourcesDirectory)\build\Helix\packages\Microsoft.Taef.10.60.210621002\build\Binaries\x86' -TaefQuery '${{ parameters.taefQuery }}'

View File

@@ -1,71 +0,0 @@
parameters:
condition: 'succeededOrFailed()'
dependsOn: ''
rerunPassesRequiredToAvoidFailure: 5
minimumExpectedTestsExecutedCount: 10
checkJobAttempt: false
pgoArtifact: ''
jobs:
- job: ProcessTestResults
displayName: Process Helix Results ${{ parameters.platform }} ${{ parameters.configuration }}
condition: ${{ parameters.condition }}
dependsOn: ${{ parameters.dependsOn }}
pool:
vmImage: 'windows-2019'
timeoutInMinutes: 120
variables:
helixOutputFolder: $(Build.SourcesDirectory)\HelixOutput
steps:
- task: powershell@2
displayName: 'UpdateUnreliableTests.ps1'
condition: succeededOrFailed()
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
HelixAccessToken: $(HelixApiAccessToken)
inputs:
targetType: filePath
filePath: build\Helix\UpdateUnreliableTests.ps1
arguments: -RerunPassesRequiredToAvoidFailure '${{ parameters.rerunPassesRequiredToAvoidFailure }}'
- task: powershell@2
displayName: 'OutputTestResults.ps1'
condition: succeededOrFailed()
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
HelixAccessToken: $(HelixApiAccessToken)
inputs:
targetType: filePath
filePath: build\Helix\OutputTestResults.ps1
arguments: -MinimumExpectedTestsExecutedCount '${{ parameters.minimumExpectedTestsExecutedCount }}' -CheckJobAttempt $${{ parameters.checkJobAttempt }}
- task: powershell@2
displayName: 'ProcessHelixFiles.ps1'
condition: succeededOrFailed()
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
HelixAccessToken: $(HelixApiAccessToken)
inputs:
targetType: filePath
filePath: build\Helix\ProcessHelixFiles.ps1
arguments: -OutputFolder '$(helixOutputFolder)'
- ${{if ne(parameters.pgoArtifact, '') }}:
- script: move /y $(helixOutputFolder)\PGO $(Build.ArtifactStagingDirectory)
displayName: 'Move pgc files to PGO artifact'
- task: PublishBuildArtifacts@1
displayName: 'Publish Helix files'
condition: succeededOrFailed()
inputs:
PathtoPublish: $(helixOutputFolder)
artifactName: drop
- ${{if ne(parameters.pgoArtifact, '') }}:
- task: PublishBuildArtifacts@1
displayName: 'Publish pgc files'
condition: succeededOrFailed()
inputs:
PathtoPublish: $(Build.ArtifactStagingDirectory)\PGO\Release
artifactName: ${{ parameters.pgoArtifact }}

View File

@@ -1,164 +0,0 @@
parameters:
name: 'RunTestsInHelix'
dependsOn: ''
condition: ''
testSuite: ''
# If a Pipeline runs this template more than once, this parameter should be unique per build flavor to differentiate the
# the different test runs:
helixType: 'test/devtest'
artifactName: 'drop'
maxParallel: 4
rerunPassesRequiredToAvoidFailure: 5
taefQuery: ''
configuration: ''
platform: ''
# if 'useBuildOutputFromBuildId' is set, we will default to using a build from this pipeline:
useBuildOutputFromPipeline: $(System.DefinitionId)
openHelixTargetQueues: 'windows.10.amd64.client21h1.open.xaml'
closedHelixTargetQueues: 'windows.10.amd64.client21h1.xaml'
jobs:
- job: ${{ parameters.name }}
displayName: Submit Helix ${{ parameters.platform }} ${{ parameters.configuration }}
dependsOn: ${{ parameters.dependsOn }}
condition: ${{ parameters.condition }}
pool:
vmImage: 'windows-2019'
timeoutInMinutes: 120
strategy:
maxParallel: ${{ parameters.maxParallel }}
variables:
buildConfiguration: ${{ parameters.configuration }}
buildPlatform: ${{ parameters.platform }}
openHelixTargetQueues: ${{ parameters.openHelixTargetQueues }}
closedHelixTargetQueues: ${{ parameters.closedHelixTargetQueues }}
artifactsDir: $(Build.SourcesDirectory)\Artifacts
taefPath: $(Build.SourcesDirectory)\build\Helix\packages\Microsoft.Taef.10.60.210621002\build\Binaries\$(buildPlatform)
helixCommonArgs: '/binaryLogger:$(Build.SourcesDirectory)/${{parameters.name}}.$(buildPlatform).$(buildConfiguration).binlog /p:HelixBuild=$(Build.BuildId).$(buildPlatform).$(buildConfiguration) /p:Platform=$(buildPlatform) /p:Configuration=$(buildConfiguration) /p:HelixType=${{parameters.helixType}} /p:TestSuite=${{parameters.testSuite}} /p:ProjFilesPath=$(Build.ArtifactStagingDirectory) /p:rerunPassesRequiredToAvoidFailure=${{parameters.rerunPassesRequiredToAvoidFailure}}'
steps:
- task: CmdLine@1
displayName: 'Display build machine environment variables'
inputs:
filename: 'set'
- task: NuGetToolInstaller@0
displayName: 'Use NuGet 6.3.0'
inputs:
versionSpec: 6.3.0
- task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2
displayName: 'NuGet restore build/Helix/packages.config'
inputs:
restoreSolution: build/Helix/packages.config
feedsToUse: config
nugetConfigPath: nuget.config
restoreDirectory: packages
- task: DownloadBuildArtifacts@0
condition:
and(succeeded(),eq(variables['useBuildOutputFromBuildId'],''))
inputs:
artifactName: ${{ parameters.artifactName }}
downloadPath: '$(artifactsDir)'
- task: DownloadBuildArtifacts@0
condition:
and(succeeded(),ne(variables['useBuildOutputFromBuildId'],''))
inputs:
buildType: specific
buildVersionToDownload: specific
project: $(System.TeamProjectId)
pipeline: ${{ parameters.useBuildOutputFromPipeline }}
buildId: $(useBuildOutputFromBuildId)
artifactName: ${{ parameters.artifactName }}
downloadPath: '$(artifactsDir)'
- task: CmdLine@1
displayName: 'Display Artifact Directory payload contents'
inputs:
filename: 'dir'
arguments: '/s $(artifactsDir)'
- task: powershell@2
displayName: 'PrepareHelixPayload.ps1'
inputs:
targetType: filePath
filePath: build\Helix\PrepareHelixPayload.ps1
arguments: -Platform '$(buildPlatform)' -Configuration '$(buildConfiguration)' -ArtifactName '${{ parameters.artifactName }}'
- task: CmdLine@1
displayName: 'Display Helix payload contents'
inputs:
filename: 'dir'
arguments: '/s $(Build.SourcesDirectory)\HelixPayload'
- task: PowerShell@2
displayName: 'Make artifact directories'
inputs:
targetType: inline
script: |
New-Item -ItemType Directory -Force -Path "$(Build.ArtifactStagingDirectory)\$(BuildConfiguration)\"
New-Item -ItemType Directory -Force -Path "$(Build.ArtifactStagingDirectory)\$(BuildConfiguration)\$(BuildPlatform)\"
- template: helix-createprojfile-steps.yml
parameters:
condition: and(succeeded(),eq('${{ parameters.testSuite }}','DevTestSuite'))
testFilePath: '$(artifactsDir)\${{ parameters.artifactName }}\$(buildConfiguration)\$(buildPlatform)\Test\TerminalApp.LocalTests.dll'
outputProjFileName: 'RunTestsInHelix-TerminalAppLocalTests.proj'
testSuite: '${{ parameters.testSuite }}'
taefQuery: ${{ parameters.taefQuery }}
- template: helix-createprojfile-steps.yml
parameters:
condition: and(succeeded(),eq('${{ parameters.testSuite }}','DevTestSuite'))
testFilePath: '$(artifactsDir)\${{ parameters.artifactName }}\$(buildConfiguration)\$(buildPlatform)\Test\SettingsModel.LocalTests.dll'
outputProjFileName: 'RunTestsInHelix-SettingsModelLocalTests.proj'
testSuite: '${{ parameters.testSuite }}'
taefQuery: ${{ parameters.taefQuery }}
- template: helix-createprojfile-steps.yml
parameters:
condition: and(succeeded(),eq('${{ parameters.testSuite }}','DevTestSuite'))
testFilePath: '$(artifactsDir)\${{ parameters.artifactName }}\$(buildConfiguration)\$(buildPlatform)\Test\Conhost.UIA.Tests.dll'
outputProjFileName: 'RunTestsInHelix-HostTestsUIA.proj'
testSuite: '${{ parameters.testSuite }}'
taefQuery: ${{ parameters.taefQuery }}
- template: helix-createprojfile-steps.yml
parameters:
condition: and(succeeded(),or(eq('${{ parameters.testSuite }}','PgoInstrumentationSuite'),eq('${{ parameters.testSuite }}','DevTestSuite')))
testFilePath: '$(artifactsDir)\${{ parameters.artifactName }}\$(buildConfiguration)\$(buildPlatform)\Test\WindowsTerminal.UIA.Tests.dll'
outputProjFileName: 'RunTestsInHelix-WindowsTerminalUIATests.proj'
testSuite: '${{ parameters.testSuite }}'
taefQuery: ${{ parameters.taefQuery }}
- task: PublishBuildArtifacts@1
displayName: 'Publish generated .proj files'
inputs:
PathtoPublish: $(Build.ArtifactStagingDirectory)
artifactName: ${{ parameters.artifactName }}
- task: DotNetCoreCLI@2
displayName: 'Run tests in Helix (open queues)'
condition: and(succeeded(),eq(variables['System.CollectionUri'],'https://dev.azure.com/ms/'))
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
inputs:
command: custom
projects: build\Helix\RunTestsInHelix.proj
custom: msbuild
arguments: '$(helixCommonArgs) /p:IsExternal=true /p:Creator=Terminal /p:HelixTargetQueues=$(openHelixTargetQueues)'
- task: DotNetCoreCLI@2
displayName: 'Run tests in Helix (closed queues)'
condition: and(succeeded(),ne(variables['System.CollectionUri'],'https://dev.azure.com/ms/'))
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
HelixAccessToken: $(HelixApiAccessToken)
inputs:
command: custom
projects: build\Helix\RunTestsInHelix.proj
custom: msbuild
arguments: '$(helixCommonArgs) /p:HelixTargetQueues=$(closedHelixTargetQueues)'

View File

@@ -1,70 +0,0 @@
parameters:
dependsOn: ''
pgoArtifact: PGO
platform: ''
configuration: ''
jobs:
- job: MergePGD
dependsOn: ${{ parameters.dependsOn }}
pool:
vmImage: 'windows-2019'
variables:
artifactsPath: $(Build.SourcesDirectory)\Artifacts
pgoArtifactsPath: $(artifactsPath)\${{ parameters.pgoArtifact }}
buildPlatform: ${{ parameters.platform }}
buildConfiguration: ${{ parameters.configuration }}
steps:
# The environment variable VCToolsInstallDir isn't defined on lab machines, so we need to retrieve it ourselves.
- script: |
"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -Latest -requires Microsoft.Component.MSBuild -property InstallationPath > %TEMP%\vsinstalldir.txt
set /p _VSINSTALLDIR15=<%TEMP%\vsinstalldir.txt
del %TEMP%\vsinstalldir.txt
call "%_VSINSTALLDIR15%\Common7\Tools\VsDevCmd.bat"
echo VCToolsInstallDir = %VCToolsInstallDir%
echo ##vso[task.setvariable variable=VCToolsInstallDir]%VCToolsInstallDir%
displayName: 'Retrieve VC tools directory'
- task: NuGetToolInstaller@0
displayName: 'Use NuGet 6.3.0'
inputs:
versionSpec: 6.3.0
- task: NuGetAuthenticate@0
# In the Microsoft Azure DevOps tenant, NuGetCommand is ambiguous.
# This should be `task: NuGetCommand@2`
- task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2
displayName: Restore NuGet packages for extraneous build actions
inputs:
command: restore
feedsToUse: config
configPath: NuGet.config
restoreSolution: build/packages.config
restoreDirectory: '$(Build.SourcesDirectory)\packages'
- task: DownloadBuildArtifacts@0
inputs:
artifactName: ${{ parameters.pgoArtifact }}
downloadPath: $(artifactsPath)
- task: MSBuild@1
displayName: Merge counts into PGD
inputs:
solution: $(Build.SourcesDirectory)\OpenConsole.sln
platform: $(buildPlatform)
configuration: $(buildConfiguration)
msbuildArguments: '/t:MergePGOCounts /p:PGOBuildMode=Instrument /p:PGDPath=$(pgoArtifactsPath)\$(buildPlatform) /p:PGCRootPath=$(pgoArtifactsPath)\$(buildPlatform)'
- task: CopyFiles@2
displayName: 'Copy merged pgd to artifact staging'
inputs:
sourceFolder: $(pgoArtifactsPath)
contents: '**\$(buildPlatform)\*.pgd'
targetFolder: $(Build.ArtifactStagingDirectory)
- task: PublishBuildArtifacts@1
inputs:
pathToPublish: $(Build.ArtifactStagingDirectory)
artifactName: ${{ parameters.pgoArtifact }}

View File

@@ -30,7 +30,7 @@
DependsOnTargets="_ConsoleMapWinmdsToManifestFiles">
<!-- This target is batched and a new Exec is spawned for each entry in _ConsoleWinmdManifest. -->
<Exec Command="mt.exe -winmd:%(_ConsoleWinmdManifest.WinMDPath) -dll:%(_ConsoleWinmdManifest.Implementation) -out:%(_ConsoleWinmdManifest.Identity)" />
<Exec Command="mt.exe -winmd:&quot;%(_ConsoleWinmdManifest.WinMDPath)&quot; -dll:%(_ConsoleWinmdManifest.Implementation) -out:&quot;%(_ConsoleWinmdManifest.Identity)&quot;" />
<ItemGroup>
<!-- Emit the generated manifest into the Link inputs. -->

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!--
This file contains targets that override behavior in Microsoft.UI.Xaml and
related packages.
For example: All XAML needs is a reference to WebView2; it does not need the
DLL and it does not need for us to copy the WinMD into the output folder. It
also doesn't require the WebView2 loader since we're not actually using
WebView2. Therefore, we can get away with *not including the WebView2
package* and only adding a reference to its winmd.
-->
<ItemGroup>
<Reference Include="$(WebView2PackageRoot)\lib\Microsoft.Web.WebView2.Core.winmd" />
</ItemGroup>
</Project>

View File

@@ -10,7 +10,7 @@ function Invoke-CheckBadCodeFormatting() {
# returns a non-zero exit code if there are any diffs in the tracked files in the repo
git diff-index --quiet HEAD --
if ($lastExitCode -eq 1) {
if ($LASTEXITCODE -eq 1) {
# Write the list of files that need updating to the log
git diff-index --name-only HEAD

View File

@@ -0,0 +1,78 @@
Param(
[Parameter(Mandatory,
HelpMessage="List of PRI files or XML dumps (detailed only) to merge")]
[string[]]
$Path,
[Parameter(Mandatory,
HelpMessage="Output Path")]
[string]
$OutputPath,
[Parameter(HelpMessage="Name of index in output file; defaults to 'Application'")]
[string]
$IndexName = "Application",
[Parameter(HelpMessage="Path to makepri.exe")]
[ValidateScript({Test-Path $_ -Type Leaf})]
[string]
$MakePriPath = "C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64\MakePri.exe"
)
$ErrorActionPreference = 'Stop'
$tempDir = Join-Path ([System.IO.Path]::GetTempPath()) "tmp$([Convert]::ToString((Get-Random 65535),16).PadLeft(4,'0')).tmp"
New-Item -ItemType Directory -Path $tempDir | Out-Null
$priConfig = Join-Path $tempDir "priconfig.xml"
$priListFile = Join-Path $tempDir "pri.resfiles"
$dumpListFile = Join-Path $tempDir "dump.resfiles"
@"
<?xml version="1.0" encoding="utf-8"?>
<resources targetOsVersion="10.0.0" majorVersion="1">
<index root="\" startIndexAt="dump.resfiles">
<default>
<qualifier name="Language" value="en-US" />
<qualifier name="Contrast" value="standard" />
<qualifier name="Scale" value="200" />
<qualifier name="HomeRegion" value="001" />
<qualifier name="TargetSize" value="256" />
<qualifier name="LayoutDirection" value="LTR" />
<qualifier name="DXFeatureLevel" value="DX9" />
<qualifier name="Configuration" value="" />
<qualifier name="AlternateForm" value="" />
<qualifier name="Platform" value="UAP" />
</default>
<indexer-config type="PRIINFO" />
<indexer-config type="RESFILES" qualifierDelimiter="." />
</index>
<index root="\" startIndexAt="pri.resfiles">
<default>
<qualifier name="Language" value="en-US" />
<qualifier name="Contrast" value="standard" />
<qualifier name="Scale" value="200" />
<qualifier name="HomeRegion" value="001" />
<qualifier name="TargetSize" value="256" />
<qualifier name="LayoutDirection" value="LTR" />
<qualifier name="DXFeatureLevel" value="DX9" />
<qualifier name="Configuration" value="" />
<qualifier name="AlternateForm" value="" />
<qualifier name="Platform" value="UAP" />
</default>
<indexer-config type="PRI" />
<indexer-config type="RESFILES" qualifierDelimiter="." />
</index>
</resources>
"@ | Out-File -Encoding:utf8NoBOM $priConfig
$Path | Where { $_ -Like "*.pri" } | ForEach-Object {
Get-Item $_ | Select -Expand FullName
} | Out-File -Encoding:utf8NoBOM $priListFile
$Path | Where { $_ -Like "*.xml" } | ForEach-Object {
Get-Item $_ | Select -Expand FullName
} | Out-File -Encoding:utf8NoBOM $dumpListFile
& $MakePriPath new /pr $tempDir /cf $priConfig /o /in $IndexName /of $OutputPath
Remove-Item -Recurse -Force $tempDir

View File

@@ -0,0 +1,47 @@
Param(
[Parameter(Mandatory,
HelpMessage="Root directory of extracted Terminal AppX")]
[string[]]
$TerminalRoot,
[Parameter(Mandatory,
HelpMessage="Root directory of extracted Xaml AppX")]
[string[]]
$XamlRoot,
[Parameter(Mandatory,
HelpMessage="Output Path")]
[string]
$OutputPath,
[Parameter(HelpMessage="Path to makepri.exe")]
[ValidateScript({Test-Path $_ -Type Leaf})]
[string]
$MakePriPath = "C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64\MakePri.exe"
)
$ErrorActionPreference = 'Stop'
$tempDir = Join-Path ([System.IO.Path]::GetTempPath()) "tmp$([Convert]::ToString((Get-Random 65535),16).PadLeft(4,'0')).tmp"
New-Item -ItemType Directory -Path $tempDir | Out-Null
$terminalDump = Join-Path $tempDir "terminal.pri.xml"
& $MakePriPath dump /if (Join-Path $TerminalRoot "resources.pri") /of $terminalDump /dt detailed
Write-Verbose "Removing Microsoft.UI.Xaml node from Terminal to prevent a collision with XAML"
$terminalXMLDocument = [xml](Get-Content $terminalDump)
$resourceMap = $terminalXMLDocument.PriInfo.ResourceMap
$fileSubtree = $resourceMap.ResourceMapSubtree | Where-Object { $_.Name -eq "Files" }
$subtrees = $fileSubtree.ResourceMapSubtree
$xamlSubtreeChild = ($subtrees | Where-Object { $_.Name -eq "Microsoft.UI.Xaml" })
if ($Null -Ne $xamlSubtreeChild) {
$null = $fileSubtree.RemoveChild($xamlSubtreeChild)
$terminalXMLDocument.Save($terminalDump)
}
$indexName = $terminalXMLDocument.PriInfo.ResourceMap.name
& (Join-Path $PSScriptRoot "Merge-PriFiles.ps1") -Path $terminalDump, (Join-Path $XamlRoot "resources.pri") -IndexName $indexName -OutputPath $OutputPath -MakePriPath $MakePriPath
Remove-Item -Recurse -Force $tempDir

View File

@@ -0,0 +1,140 @@
[CmdletBinding(DefaultParameterSetName = 'AppX')]
Param(
[Parameter(Mandatory, HelpMessage="Path to Terminal AppX", ParameterSetName = 'AppX')]
[ValidateScript({Test-Path $_ -Type Leaf})]
[string]
$TerminalAppX,
[Parameter(Mandatory, HelpMessage="Path to Terminal Layout Deployment", ParameterSetName='Layout')]
[ValidateScript({Test-Path $_ -Type Container})]
[string]
$TerminalLayout,
[Parameter(Mandatory, HelpMessage="Path to Xaml AppX", ParameterSetName='AppX')]
[Parameter(Mandatory, HelpMessage="Path to Xaml AppX", ParameterSetName='Layout')]
[ValidateScript({Test-Path $_ -Type Leaf})]
[string]
$XamlAppX,
[Parameter(HelpMessage="Output Directory", ParameterSetName='AppX')]
[Parameter(HelpMessage="Output Directory", ParameterSetName='Layout')]
[string]
$Destination = ".",
[Parameter(HelpMessage="Path to makeappx.exe", ParameterSetName='AppX')]
[Parameter(HelpMessage="Path to makeappx.exe", ParameterSetName='Layout')]
[ValidateScript({Test-Path $_ -Type Leaf})]
[string]
$MakeAppxPath = "C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64\MakeAppx.exe"
)
$filesToRemove = @("*.xml", "*.winmd", "Appx*", "Images/*Tile*", "Images/*Logo*") # Remove from Terminal
$filesToKeep = @("Microsoft.Terminal.Remoting.winmd") # ... except for these
$filesToCopyFromXaml = @("Microsoft.UI.Xaml.dll", "Microsoft.UI.Xaml") # We don't need the .winmd
$ErrorActionPreference = 'Stop'
If ($null -Eq (Get-Item $MakeAppxPath -EA:SilentlyContinue)) {
Write-Error "Could not find MakeAppx.exe at `"$MakeAppxPath`".`nMake sure that -MakeAppxPath points to a valid SDK."
Exit 1
}
$tempDir = Join-Path ([System.IO.Path]::GetTempPath()) "tmp$([Convert]::ToString((Get-Random 65535),16).PadLeft(4,'0')).tmp"
New-Item -ItemType Directory -Path $tempDir | Out-Null
$XamlAppX = Get-Item $XamlAppX | Select-Object -Expand FullName
########
# Reading the AppX Manifest for preliminary info
########
If ($TerminalAppX) {
$appxManifestPath = Join-Path $tempDir AppxManifest.xml
& tar.exe -x -f "$TerminalAppX" -C $tempDir AppxManifest.xml
} ElseIf($TerminalLayout) {
$appxManifestPath = Join-Path $TerminalLayout AppxManifest.xml
}
$manifest = [xml](Get-Content $appxManifestPath)
$pfn = $manifest.Package.Identity.Name
$version = $manifest.Package.Identity.Version
$architecture = $manifest.Package.Identity.ProcessorArchitecture
$distributionName = "{0}_{1}_{2}" -f ($pfn, $version, $architecture)
$terminalDir = "terminal-{0}" -f ($version)
########
# Unpacking Terminal and XAML
########
$terminalAppPath = Join-Path $tempdir $terminalDir
If ($TerminalAppX) {
$TerminalAppX = Get-Item $TerminalAppX | Select-Object -Expand FullName
New-Item -ItemType Directory -Path $terminalAppPath | Out-Null
& $MakeAppxPath unpack /p $TerminalAppX /d $terminalAppPath /o | Out-Null
If ($LASTEXITCODE -Ne 0) {
Throw "Unpacking $TerminalAppX failed"
}
} ElseIf ($TerminalLayout) {
Copy-Item -Recurse -Path $TerminalLayout -Destination $terminalAppPath
}
$xamlAppPath = Join-Path $tempdir "xaml"
New-Item -ItemType Directory -Path $xamlAppPath | Out-Null
& $MakeAppxPath unpack /p $XamlAppX /d $xamlAppPath /o | Out-Null
If ($LASTEXITCODE -Ne 0) {
Throw "Unpacking $XamlAppX failed"
}
########
# Some sanity checking
########
$xamlManifest = [xml](Get-Content (Join-Path $xamlAppPath "AppxManifest.xml"))
If ($xamlManifest.Package.Identity.Name -NotLike "Microsoft.UI.Xaml*") {
Throw "$XamlAppX is not a XAML package (instead, it looks like $($xamlManifest.Package.Identity.Name))"
}
If ($xamlManifest.Package.Identity.ProcessorArchitecture -Ne $architecture) {
Throw "$XamlAppX is not built for $architecture (instead, it is built for $($xamlManifest.Package.Identity.ProcessorArchitecture))"
}
########
# Preparation of source files
########
$itemsToRemove = $filesToRemove | ForEach-Object {
Get-Item (Join-Path $terminalAppPath $_) -EA:SilentlyContinue | Where-Object {
$filesToKeep -NotContains $_.Name
}
} | Sort-Object FullName -Unique
$itemsToRemove | Remove-Item -Recurse
$filesToCopyFromXaml | ForEach-Object {
Get-Item (Join-Path $xamlAppPath $_)
} | Copy-Item -Recurse -Destination $terminalAppPath
########
# Resource Management
########
$finalTerminalPriFile = Join-Path $terminalAppPath "resources.pri"
& (Join-Path $PSScriptRoot "Merge-TerminalAndXamlResources.ps1") `
-TerminalRoot $terminalAppPath `
-XamlRoot $xamlAppPath `
-OutputPath $finalTerminalPriFile `
-Verbose:$Verbose | Out-Host
########
# Packaging
########
If ($PSCmdlet.ParameterSetName -Eq "AppX") {
# We only produce a ZIP when we're combining two AppX directories.
New-Item -ItemType Directory -Path $Destination -ErrorAction:SilentlyContinue | Out-Null
$outputZip = (Join-Path $Destination ("{0}.zip" -f ($distributionName)))
& tar -c --format=zip -f $outputZip -C $tempDir $terminalDir
Remove-Item -Recurse -Force $tempDir -EA:SilentlyContinue
Get-Item $outputZip
} ElseIf ($PSCmdlet.ParameterSetName -Eq "Layout") {
Get-Item $terminalAppPath
}

View File

@@ -1,14 +0,0 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
Param(
[string]$NewWindowsVersion = "10.0.22000.0"
)
Get-ChildItem src/cascadia/CascadiaPackage -Recurse -Filter *.appxmanifest | ForEach-Object {
$xml = [xml](Get-Content $_.FullName)
$xml.Package.Dependencies.TargetDeviceFamily | Where-Object Name -Like "Windows*" | ForEach-Object {
$_.MinVersion = $NewWindowsVersion
}
$xml.Save($_.FullName)
}

View File

@@ -1,27 +1,37 @@
[CmdLetBinding()]
Param(
[Parameter(Mandatory=$true, Position=0)][string]$MatchPattern,
[Parameter(Mandatory=$true, Position=1)][string]$Platform,
[Parameter(Mandatory=$true, Position=2)][string]$Configuration,
[Parameter(Mandatory=$false, Position=3)][string]$LogPath,
[Parameter(Mandatory=$false)][string]$Root = ".\bin\$Platform\$Configuration"
[Parameter(Mandatory=$true, Position=0)]
[string]$MatchPattern,
[Parameter(Mandatory=$true, Position=1)]
[string]$Platform,
[Parameter(Mandatory=$true, Position=2)]
[string]$Configuration,
[Parameter(Mandatory=$false, Position=3)]
[string]$LogPath,
[Parameter(Mandatory=$false)]
[string]$Root = ".\bin\$Platform\$Configuration",
[string[]]$AdditionalTaefArguments
)
$testdlls = Get-ChildItem -Path "$Root" -Recurse -Filter $MatchPattern
# Find test DLLs based on the provided root, match pattern, and recursion
$testDlls = Get-ChildItem -Path $Root -Recurse -Filter $MatchPattern
$args = @()
$args = @();
if ($LogPath)
{
$args += '/enablewttlogging';
$args += '/appendwttlogging';
$args += "/logFile:$LogPath";
Write-Host "Wtt Logging Enabled";
# Check if the LogPath parameter is provided and enable WTT logging
if ($LogPath) {
$args += '/enablewttlogging'
$args += '/appendwttlogging'
$args += "/logFile:$LogPath"
Write-Host "WTT Logging Enabled"
}
&"$Root\te.exe" $args $testdlls.FullName
# Invoke the te.exe executable with arguments and test DLLs
& "$Root\te.exe" $args $testDlls.FullName $AdditionalTaefArguments
if ($lastexitcode -Ne 0) { Exit $lastexitcode }
# Check the exit code of the te.exe process and exit accordingly
if ($LASTEXITCODE -ne 0) {
Exit $LASTEXITCODE
}
Exit 0

View File

@@ -70,23 +70,24 @@ Try {
$dependencies = $Manifest.Package.Dependencies.PackageDependency.Name
$depsHasVclibsDesktop = ("Microsoft.VCLibs.140.00.UWPDesktop" -in $dependencies) -or ("Microsoft.VCLibs.140.00.Debug.UWPDesktop" -in $dependencies)
$depsHasVcLibsAppX = ("Microsoft.VCLibs.140.00" -in $dependencies) -or ("Microsoft.VCLibs.140.00.Debug" -in $dependencies)
$depsHasVclibsAppX = ("Microsoft.VCLibs.140.00" -in $dependencies) -or ("Microsoft.VCLibs.140.00.Debug" -in $dependencies)
$filesHasVclibsDesktop = ($null -ne (Get-Item "$AppxPackageRootPath\vcruntime140.dll" -EA:Ignore)) -or ($null -ne (Get-Item "$AppxPackageRootPath\vcruntime140d.dll" -EA:Ignore))
$filesHasVclibsAppX = ($null -ne (Get-Item "$AppxPackageRootPath\vcruntime140_app.dll" -EA:Ignore)) -or ($null -ne (Get-Item "$AppxPackageRootPath\vcruntime140d_app.dll" -EA:Ignore))
If ($depsHasVclibsDesktop -Eq $filesHasVclibsDesktop) {
$eitherBoth = if ($depsHasVclibsDesktop) { "both" } else { "neither" }
$neitherNor = if ($depsHasVclibsDesktop) { "and" } else { "nor" }
Throw "Package has $eitherBoth Dependency $neitherNor Integrated Desktop VCLibs"
If ($filesHasVclibsDesktop) {
Throw "Package contains the desktop VCLibs"
}
If ($depsHasVclibsAppx -Eq $filesHasVclibsAppx) {
if ($depsHasVclibsAppx) {
# We've shipped like this forever, so downgrade to warning.
Write-Warning "Package has both Dependency and Integrated AppX VCLibs"
} else {
Throw "Package has neither Dependency nor Integrated AppX VCLibs"
}
If ($depsHasVclibsDesktop) {
Throw "Package has a dependency on the desktop VCLibs"
}
If ($filesHasVclibsAppX) {
Throw "Package contains the AppX VCLibs"
}
If ($depsHasVclibsAppX) {
Throw "Package has a dependency on the AppX VCLibs"
}
### Check that we have an App.xbf (which is a proxy for our resources having been merged)
@@ -96,11 +97,6 @@ Try {
Throw "Failed to find App.xbf (TerminalApp project) in resources.pri"
}
If (($null -eq (Get-Item "$AppxPackageRootPath\cpprest142_2_10.dll" -EA:Ignore)) -And
($null -eq (Get-Item "$AppxPackageRootPath\cpprest142_2_10d.dll" -EA:Ignore))) {
Throw "Failed to find cpprest142_2_10.dll -- check the WAP packaging project"
}
If (($null -eq (Get-Item "$AppxPackageRootPath\wtd.exe" -EA:Ignore)) -And
($null -eq (Get-Item "$AppxPackageRootPath\wt.exe" -EA:Ignore))) {
Throw "Failed to find wt.exe/wtd.exe -- check the WAP packaging project"

View File

@@ -10,22 +10,4 @@
<OpenConsoleDir>$(MSBuildThisFileDirectory)</OpenConsoleDir>
</PropertyGroup>
<PropertyGroup>
<!--
For the Windows 10 build, we're targeting the prerelease version of Microsoft.UI.Xaml.
This version emits every XAML DLL directly into our package.
This is a workaround for us not having deliverable MSFT-21242953 on this version of Windows.
This version should be tracked in all project packages.config files for projects that depend on Xaml.
-->
<TerminalMUXVersion>2.7.3-prerelease.220816001</TerminalMUXVersion>
<!--
For the Windows 11-specific build, we're targeting the public version of Microsoft.UI.Xaml.
This version emits a package dependency instead of embedding the dependency in our own package.
This version should be tracked in build/packages.config.
-->
<TerminalMUXVersion Condition="'$(TerminalTargetWindowsVersion)'=='Win11'">2.7.3</TerminalMUXVersion>
</PropertyGroup>
</Project>

View File

@@ -2,22 +2,10 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- 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>
<XesUseOneStoreVersioning>true</XesUseOneStoreVersioning>
<XesBaseYearForStoreVersion>2022</XesBaseYearForStoreVersion>
<XesBaseYearForStoreVersion>2023</XesBaseYearForStoreVersion>
<VersionMajor>1</VersionMajor>
<VersionMinor>17</VersionMinor>
<VersionMinor>19</VersionMinor>
<VersionInfoProductName>Windows Terminal</VersionInfoProductName>
</PropertyGroup>
</Project>

View File

@@ -2,15 +2,13 @@
<!-- The packages.config acts as the global version for all of the NuGet packages contained within. -->
<packages>
<!-- Native packages -->
<package id="Microsoft.Toolkit.Win32.UI.XamlApplication" version="6.1.3" targetFramework="native" />
<package id="Microsoft.Internal.PGO-Helpers.Cpp" version="0.2.34" targetFramework="native" />
<package id="Microsoft.Taef" version="10.60.210621002" targetFramework="native" />
<package id="Microsoft.Windows.CppWinRT" version="2.0.210825.3" targetFramework="native" />
<package id="vcpkg-cpprestsdk" version="2.10.14" targetFramework="native" />
<package id="Microsoft.VCRTForwarders.140" version="1.0.4" targetFramework="native" />
<package id="Microsoft.Internal.Windows.Terminal.ThemeHelpers" version="0.6.220404001" targetFramework="native" />
<package id="Microsoft.Windows.CppWinRT" version="2.0.230207.1" targetFramework="native" />
<package id="Microsoft.Internal.Windows.Terminal.ThemeHelpers" version="0.7.230706001" targetFramework="native" />
<package id="Microsoft.VisualStudio.Setup.Configuration.Native" version="2.3.2262" targetFramework="native" developmentDependency="true" />
<package id="Microsoft.UI.Xaml" version="2.7.3-prerelease.220816001" targetFramework="native" />
<package id="Microsoft.UI.Xaml" version="2.8.4" targetFramework="native" />
<package id="Microsoft.Web.WebView2" version="1.0.1661.34" targetFramework="native" />
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.220201.1" targetFramework="native" developmentDependency="true" />
<!-- Managed packages -->

View File

@@ -145,7 +145,7 @@ Our only backport successes really come from corporations with massive addressab
It's also costly in terms of time, effort, and testing for us to validate a modification to a released OS. We have a mindbogglingly massive amount of automated machinery dedicated to processing and validating the things that we check in while developing the current OS builds. But it's a special costly ask to spin up some to all of those activities to validate backported fixes. We do it all the time for Patch Tuesday, but in those patches, they only pass through the minimum number of fixes required to maximize the restoration of productivity/security/revenue/etc. because every additional fix adds additional complexity and additional risk.
So from our little team working hard to make developers happy, we virtually never make the cut for servicing. We're sorry, but we hope you can understand. It's just the reality of the situation to say "nope" when people ask for a backport. In our team's ideal world, you would all be running the latest console bits everywhere everytime we make a change. But that's just not how it is today.
So from our little team working hard to make developers happy, we virtually never make the cut for servicing. We're sorry, but we hope you can understand. It's just the reality of the situation to say "nope" when people ask for a backport. In our team's ideal world, you would all be running the latest console bits everywhere every time we make a change. But that's just not how it is today.
Original Source: https://github.com/microsoft/terminal/issues/279#issuecomment-439179675

View File

@@ -24,6 +24,13 @@
"pattern": "^(-?\\d+)?(,\\s?(-?\\d+)?)?$",
"type": "string"
},
"CSSLengthPercentage": {
"pattern": "^[+-]?\\d+(?:\\.\\d+)?(?:%|ch|pt|px)?$",
"type": [
"string",
"null"
]
},
"DynamicProfileSource": {
"enum": [
"Windows.Terminal.Wsl",
@@ -78,11 +85,44 @@
}
]
},
"BuiltinSuggestionSource": {
"enum": [
"commandHistory",
"tasks",
"all"
],
"type": "string"
},
"SuggestionSource": {
"default": "all",
"description": "Either a single suggestion source, or an array of sources to concatenate. Built-in sources include `commandHistory`, `directoryHistory`, and `tasks`. The special value `all` indicates all suggestion sources should be included",
"$comment": "`tasks` and `local` are sources that would be added by the Tasks feature, as a follow-up",
"oneOf": [
{
"type": [ "string", "null", "BuiltinSuggestionSource" ]
},
{
"type": "array",
"items": { "type": "BuiltinSuggestionSource" }
},
{
"type": "array",
"items": { "type": "string" }
}
]
},
"AppearanceConfig": {
"properties": {
"colorScheme": {
"description": "The name of a color scheme to use when unfocused.",
"type": "string"
"oneOf": [
{
"$ref": "#/$defs/SchemePair"
},
{
"type": "string"
}
]
},
"foreground": {
"$ref": "#/$defs/Color",
@@ -233,6 +273,22 @@
},
"type": "object"
},
"SchemePair": {
"description": "Contains both a light and dark color scheme for the Terminal to use, depending on the theme of the application.",
"properties": {
"light": {
"default": "Campbell",
"description": "Name of the scheme to use when the app is using light theme",
"type": "string"
},
"dark": {
"default": "Campbell",
"description": "Name of the scheme to use when the app is using dark theme",
"type": "string"
}
},
"type": "object"
},
"FontConfig": {
"properties": {
"face": {
@@ -292,6 +348,14 @@
}
},
"additionalProperties": false
},
"cellWidth": {
"$ref": "#/$defs/CSSLengthPercentage",
"description": "Override the width of the terminal's cells. The override works similar to CSS' letter-spacing. It defaults to the natural glyph advance width of the primary font rounded to the nearest pixel."
},
"cellHeight": {
"$ref": "#/$defs/CSSLengthPercentage",
"description": "Override the height of the terminal's cells. The override works similar to CSS' line-height. Defaults to the sum of the natural glyph ascend, descend and line-gap of the primary font rounded to the nearest pixel. The default is usually quite close to setting this to 1.2."
}
},
"type": "object"
@@ -360,6 +424,7 @@
"sendInput",
"setColorScheme",
"setTabColor",
"showSuggestions",
"splitPane",
"switchToTab",
"tabSearch",
@@ -384,6 +449,7 @@
"scrollToMark",
"clearMark",
"clearAllMarks",
"searchWeb",
"experimental.colorSelection",
"unbound"
],
@@ -539,6 +605,160 @@
},
"type": "object"
},
"NewTabMenuEntryType": {
"enum": [
"source",
"profile",
"folder",
"separator",
"remainingProfiles",
"matchProfiles"
]
},
"NewTabMenuEntry": {
"properties": {
"type": {
"description": "The type of menu entry",
"$ref": "#/$defs/NewTabMenuEntryType"
}
},
"required": [
"type"
],
"type": "object"
},
"FolderEntryInlining": {
"enum": [
"never",
"auto"
]
},
"FolderEntry": {
"description": "A folder entry in the new tab dropdown",
"allOf": [
{
"$ref": "#/$defs/NewTabMenuEntry"
},
{
"properties": {
"type": {
"type": "string",
"const": "folder"
},
"name": {
"type": "string",
"default": "",
"description": "The name of the folder to show in the menu"
},
"icon": {
"$ref": "#/$defs/Icon"
},
"entries": {
"type": "array",
"description": "The entries to put inside this folder",
"minItems": 1,
"items": {
"$ref": "#/$defs/NewTabMenuEntry"
}
},
"inline": {
"description": "When set to auto and the folder only has a single entry, the entry will show directly and no folder will be rendered",
"default": "never",
"$ref": "#/$defs/FolderEntryInlining"
},
"allowEmpty": {
"description": "Whether to render a folder without entries, or to hide it",
"default": "false",
"type": "boolean"
}
}
}
]
},
"SeparatorEntry": {
"description": "A separator in the new tab dropdown",
"allOf": [
{
"$ref": "#/$defs/NewTabMenuEntry"
},
{
"properties": {
"type": {
"type": "string",
"const": "separator"
}
}
}
]
},
"ProfileEntry": {
"description": "A profile in the new tab dropdown",
"allOf": [
{
"$ref": "#/$defs/NewTabMenuEntry"
},
{
"properties": {
"type": {
"type": "string",
"const": "profile"
},
"profile": {
"type": "string",
"default": "",
"description": "The name or GUID of the profile to show in this entry"
}
}
}
]
},
"RemainingProfilesEntry": {
"description": "The set of profiles that are not yet explicitly included in another entry, such as the profile or source entries. This entry can be used at most one time!",
"allOf": [
{
"$ref": "#/$defs/NewTabMenuEntry"
},
{
"properties": {
"type": {
"type": "string",
"const": "remainingProfiles"
}
}
}
]
},
"MatchProfilesEntry": {
"description": "A set of profiles all matching the given name, source, or command line, to show in the new tab dropdown",
"allOf": [
{
"$ref": "#/$defs/NewTabMenuEntry"
},
{
"properties": {
"type": {
"type": "string",
"const": "matchProfiles"
},
"name": {
"type": "string",
"default": "",
"description": "The name of the profiles to match"
},
"source": {
"type": "string",
"default": "",
"description": "The source of the profiles to match"
},
"commandline": {
"type": "string",
"default": "",
"description": "The command line of the profiles to match"
}
}
}
]
},
"SwitchToAdjacentTabArgs": {
"oneOf": [
{
@@ -607,6 +827,11 @@
"default": false,
"description": "If true, the copied content will be copied as a single line (even if there are hard line breaks present in the text). If false, newlines persist from the selected text."
},
"dismissSelection": {
"type": "boolean",
"default": true,
"description": "If false, the copied content will be copied and the selection will not be dismissed. If true, the selection will be dismissed."
},
"copyFormatting": {
"default": null,
"description": "When set to `true`, the color and font formatting of selected text is also copied to your clipboard. When set to `false`, only plain text is copied to your clipboard. An array of specific formats can also be used. Supported array values include `html` and `rtf`. Plain text is always copied. Not setting this value inherits the behavior of the `copyFormatting` global setting.",
@@ -1518,6 +1743,29 @@
}
]
},
"SearchWebAction": {
"description": "Search the web for selected text",
"allOf": [
{
"$ref": "#/$defs/ShortcutAction"
},
{
"properties": {
"action": {
"type": "string",
"const": "searchWeb"
},
"queryUrl": {
"type": "string",
"description": "URL of the web page to launch, %s is replaced with the selected text"
}
}
}
],
"required": [
"queryUrl"
]
},
"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": [
@@ -1546,6 +1794,183 @@
}
]
},
"ShowSuggestionsAction": {
"description": "Arguments corresponding to a Open Suggestions Action",
"allOf": [
{
"$ref": "#/$defs/ShortcutAction"
},
{
"properties": {
"action": {
"type": "string",
"const": "showSuggestions"
},
"source": {
"$ref": "#/$defs/SuggestionSource",
"description": "Which suggestion sources to filter."
},
"useCommandline": {
"default": false,
"description": "When set to `true`, the current commandline the user has typed will pre-populate the filter of the Suggestions UI. This requires that the user has enabled shell integration in their shell's config. When set to false, the filter will start empty."
}
}
}
]
},
"ShowCloseButton": {
"enum": [
"always",
"hover",
"never",
"activeOnly"
],
"type": "string"
},
"ThemeColor": {
"description": "A special kind of color for use in themes. Can be an #rrggbb color, #rrggbbaa color, or a special value. 'accent' is evaluated as the user's selected Accent color in the OS, and 'terminalBackground' will be evaluated as the background color of the active terminal pane.",
"oneOf": [
{
"pattern": "^#[A-Fa-f0-9]{3}(?:[A-Fa-f0-9]{3}(?:[A-Fa-f0-9]{2})?)?$",
"type": "string",
"format": "color",
"default": "#000000ff"
},
{
"const": "accent",
"type": "string"
},
{
"const": "terminalBackground",
"type": "string"
},
{
"type": "null"
}
]
},
"TabTheme": {
"additionalProperties": false,
"description": "A set of properties for customizing the appearance of the tabs",
"properties": {
"background": {
"description": "The color of a tab when it is the active tab",
"$ref": "#/$defs/ThemeColor"
},
"unfocusedBackground": {
"description": "The color of a tab when it is not the active tab",
"$ref": "#/$defs/ThemeColor"
},
"showCloseButton": {
"description": "Controls the visibility of the close button on the tab",
"$ref": "#/$defs/ShowCloseButton"
}
}
},
"TabRowTheme": {
"additionalProperties": false,
"description": "A set of properties for customizing the appearance of the tab row",
"properties": {
"background": {
"description": "The color of the tab row when the window is the foreground window.",
"$ref": "#/$defs/ThemeColor"
},
"unfocusedBackground": {
"description": "The color of the tab row when the window is inactive",
"$ref": "#/$defs/ThemeColor"
}
}
},
"WindowTheme": {
"additionalProperties": false,
"description": "A set of properties for customizing the appearance of the window itself",
"properties": {
"applicationTheme": {
"description": "Which UI theme the Terminal should use for controls",
"enum": [ "light", "dark", "system" ],
"type": "string"
},
"useMica": {
"description": "True if the Terminal should use a Mica backdrop for the window. This will apply underneath all controls (including the terminal panes and the titlebar)",
"type": "boolean",
"default": false
},
"experimental.rainbowFrame": {
"description": "When enabled, the frame of the window will cycle through all the colors. Enabling this will override the `frame` and `unfocusedFrame` settings.",
"type": "boolean",
"default": false
},
"frame": {
"description": "The color of the window frame when the window is inactive. This only works on Windows 11",
"$ref": "#/$defs/ThemeColor"
},
"unfocusedFrame": {
"description": "The color of the window frame when the window is inactive. This only works on Windows 11",
"$ref": "#/$defs/ThemeColor"
}
}
},
"Theme": {
"additionalProperties": false,
"description": "A set of properties for customizing the appearance of the window. This controls things like the titlebar, the tabs, the application theme.",
"properties": {
"name": {
"type": "string",
"description": "The name of the theme. This will be displayed in the settings UI.",
"not": {
"enum": [ "light", "dark", "system" ]
}
},
"tab": {
"$ref": "#/$defs/TabTheme"
},
"tabRow": {
"$ref": "#/$defs/TabRowTheme"
},
"window": {
"$ref": "#/$defs/WindowTheme"
}
}
},
"ThemePair": {
"additionalProperties": false,
"description": "A pair of Theme names, to allow the Terminal to switch theme based on the OS theme",
"properties": {
"light": {
"type": "string",
"description": "The name of the theme to use when the OS is in Light theme",
"default": "light"
},
"dark": {
"type": "string",
"description": "The name of the theme to use when the OS is in Dark theme",
"default": "dark"
}
}
},
"NewTabMenu": {
"description": "Defines the order and structure of the 'new tab' menu. It can consist of e.g. profiles, folders, and separators.",
"type": "array",
"items": {
"oneOf": [
{
"$ref": "#/$defs/FolderEntry"
},
{
"$ref": "#/$defs/SeparatorEntry"
},
{
"$ref": "#/$defs/ProfileEntry"
},
{
"$ref": "#/$defs/MatchProfilesEntry"
},
{
"$ref": "#/$defs/RemainingProfilesEntry"
}
]
}
},
"Keybinding": {
"additionalProperties": false,
"properties": {
@@ -1660,6 +2085,12 @@
{
"$ref": "#/$defs/ColorSelectionAction"
},
{
"$ref": "#/$defs/SearchWebAction"
},
{
"$ref": "#/$defs/ShowSuggestionsAction"
},
{
"type": "null"
}
@@ -1762,6 +2193,11 @@
"description": "When set to true, the terminal will focus the pane on mouse hover.",
"type": "boolean"
},
"compatibility.isolatedMode": {
"default": false,
"description": "When set to true, Terminal windows will not be able to interact with each other (including global hotkeys, tab drag/drop, running commandlines in existing windows, etc.). This is a compatibility escape hatch for users who are running into certain windowing issues.",
"type": "boolean"
},
"copyFormatting": {
"default": true,
"description": "When set to `true`, the color and font formatting of selected text is also copied to your clipboard. When set to `false`, only plain text is copied to your clipboard. An array of specific formats can also be used. Supported array values include `html` and `rtf`. Plain text is always copied.",
@@ -1834,6 +2270,11 @@
"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"
},
"compatibility.reloadEnvironmentVariables": {
"default": true,
"description": "When set to true, when opening a new tab or pane it will get reloaded environment variables.",
"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.",
@@ -1924,20 +2365,32 @@
},
"type": "array"
},
"newTabMenu": {
"$ref": "#/$defs/NewTabMenu"
},
"language": {
"default": "",
"description": "Sets an override for the app's preferred language, expressed as a BCP-47 language tag like en-US.",
"type": "string"
},
"theme": {
"default": "system",
"description": "Sets the theme of the application. The special value \"system\" refers to the active Windows system theme.",
"enum": [
"light",
"dark",
"system"
],
"type": "string"
"default": "dark",
"description": "Sets the theme of the application. This value should be the name of one of the themes defined in `themes`. The Terminal also includes the themes `dark`, `light`, and `system`.",
"oneOf": [
{
"type": "string"
},
{
"$ref": "#/$defs/ThemePair"
}
]
},
"themes": {
"description": "The list of available themes",
"items": {
"$ref": "#/$defs/Theme"
},
"type": "array"
},
"showTabsInTitlebar": {
"default": true,
@@ -2170,7 +2623,14 @@
"colorScheme": {
"default": "Campbell",
"description": "Name of the terminal color scheme to use. Color schemes are defined under \"schemes\".",
"type": "string"
"oneOf": [
{
"$ref": "#/$defs/SchemePair"
},
{
"type": "string"
}
]
},
"commandline": {
"description": "Executable used in the profile.",
@@ -2215,6 +2675,13 @@
"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."
},
"environment": {
"description": "Key-value pairs representing environment variables to set. Environment variable names are not case sensitive. You can reference existing environment variable names by enclosing them in literal percent characters (e.g. %PATH%).",
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"experimental.autoMarkPrompts": {
"default": false,
"description": "When set to true, prompts will automatically be marked.",

235
doc/color_nudging.html Normal file
View File

@@ -0,0 +1,235 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Perceptual Color Nudging</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<style>
html {
background-color: #0c0c0c;
color: #cccccc;
font-family: "Cascadia Code", "Cascadia Mono", monospace;
}
body {
display: flex;
margin: 0;
white-space: nowrap;
min-height: 100vh;
}
body>div {
display: flex;
flex-direction: column;
align-items: center;
padding: 2rem;
}
form,
h2 {
margin: 1rem;
}
p,
pre {
margin: 0.5rem;
}
table {
border-collapse: collapse;
}
table td {
padding: 0.5rem;
}
</style>
</head>
<body>
<div style="flex: 2; align-items: flex-start; background-color: #0c0c0c">
<form>
<input id="background-color" name="background-color" type="color" value="#0c0c0c" />
<label for="background-color">background color</label>
</form>
<table>
<tr>
<td>Input</td>
<td>WCAG21:<br>APCA:</td>
<td id="stats-input"></td>
</tr>
<tr>
<td>&Delta;E2000<br>(ConEmu)</td>
<td>WCAG21:<br>APCA:</td>
<td id="stats-cielab"></td>
</tr>
<tr>
<td>&Delta;EOK</td>
<td>WCAG21:<br>APCA:</td>
<td id="stats-oklab"></td>
</tr>
</table>
</div>
<div id="input" style="flex: 1">
<h2>Input</h2>
<pre style="font-size: 8pt">&#29483;</pre>
<pre style="font-size: 10pt">&#29483;</pre>
<pre style="font-size: 12pt">&#29483;</pre>
<pre style="font-size: 14pt">&#29483;</pre>
<pre style="font-size: 16pt">&#29483;</pre>
<pre style="font-size: 32pt">&#29483;</pre>
<pre style="font-size: 64pt">&#29483;</pre>
</div>
<div id="cielab" style="flex: 1">
<h2>&Delta;E2000 (ConEmu)</h2>
<pre style="font-size: 8pt">&#29483;</pre>
<pre style="font-size: 10pt">&#29483;</pre>
<pre style="font-size: 12pt">&#29483;</pre>
<pre style="font-size: 14pt">&#29483;</pre>
<pre style="font-size: 16pt">&#29483;</pre>
<pre style="font-size: 32pt">&#29483;</pre>
<pre style="font-size: 64pt">&#29483;</pre>
</div>
<div id="oklab" style="flex: 1">
<h2>&Delta;EOK</h2>
<pre style="font-size: 8pt">&#29483;</pre>
<pre style="font-size: 10pt">&#29483;</pre>
<pre style="font-size: 12pt">&#29483;</pre>
<pre style="font-size: 14pt">&#29483;</pre>
<pre style="font-size: 16pt">&#29483;</pre>
<pre style="font-size: 32pt">&#29483;</pre>
<pre style="font-size: 64pt">&#29483;</pre>
</div>
<script type="module">
import Color from "https://cdn.jsdelivr.net/npm/colorjs.io@0.4.3/+esm";
window.Color = Color;
const input = document.getElementById("input");
const cielab = document.getElementById("cielab");
const oklab = document.getElementById("oklab");
const statsInput = document.getElementById("stats-input");
const statsCielab = document.getElementById("stats-cielab");
const statsOklab = document.getElementById("stats-oklab");
let backgroundColor = new Color("#0c0c0c");
let foregroundColor = new Color("#0c0c0c");
let foregroundColorRange = null;
let previousSecsIntegral = -1;
function saturate(val) {
return val < 0 ? 0 : val > 1 ? 1 : val;
}
function clipToSrgb(color) {
return color.to("srgb").toGamut({ method: "clip" });
}
function nudgeCielab(backgroundColor, foregroundColor) {
const backgroundCielab = backgroundColor.to("lab-d65");
const foregroundCielab = foregroundColor.to("lab-d65");
const de1 = Color.deltaE(foregroundColor, backgroundCielab, "2000");
if (de1 >= 12.0) {
return foregroundColor;
}
for (let i = 0; i <= 1; i++) {
const step = (i == 0) ? 5.0 : -5.0;
foregroundCielab.l += step;
while (((i == 0) && foregroundCielab.l <= 100) || (i == 1 && foregroundCielab.l >= 0)) {
const de2 = Color.deltaE(foregroundCielab, backgroundCielab, "2000");
if (de2 >= 20.0) {
return clipToSrgb(foregroundCielab);
}
foregroundCielab.l += step;
}
}
}
function nudgeOklab(backgroundColor, foregroundColor) {
const backgroundOklab = backgroundColor.to("oklab");
const foregroundOklab = foregroundColor.to("oklab");
const deltaSquared = {
l: (backgroundOklab.l - foregroundOklab.l) ** 2,
a: (backgroundOklab.a - foregroundOklab.a) ** 2,
b: (backgroundOklab.b - foregroundOklab.b) ** 2,
};
const distance = deltaSquared.l + deltaSquared.a + deltaSquared.b;
if (distance >= 0.25) {
return foregroundColor;
}
let deltaL = Math.sqrt(0.25 - deltaSquared.a - deltaSquared.b);
if (foregroundOklab.l < backgroundOklab.l)
{
deltaL = -deltaL;
}
foregroundOklab.l = backgroundOklab.l + deltaL;
if (foregroundOklab.l < 0 || foregroundOklab.l > 1)
{
foregroundOklab.l = backgroundOklab.l - deltaL;
}
return clipToSrgb(foregroundOklab);
}
function contrastStringLevels(num, level0, level1) {
const str = num.toFixed(1);
if (num < level0) {
return `<span style="color:crimson">${str}</span>`;
}
if (num < level1) {
return `<span style="color:coral">${str}</span>`;
}
return str;
}
function contrastString(foregroundColor) {
const contrastWCAG21 = contrastStringLevels(foregroundColor.contrast(backgroundColor, "WCAG21"), 3, 4.5);
const contrastAPCA = contrastStringLevels(Math.abs(foregroundColor.contrast(backgroundColor, "APCA")), 45, 60);
return `${contrastWCAG21}<br/>${contrastAPCA}`;
}
function animate(time) {
const timeScale = time / 1000;
const secsIntegral = Math.trunc(timeScale);
const secsFractional = timeScale % 1;
if (previousSecsIntegral != secsIntegral) {
const foregroundColorTarget = new Color("srgb", backgroundColor.coords.map(c => saturate(c + Math.random() - 0.5)));
foregroundColorRange = foregroundColor.range(foregroundColorTarget, { space: "srgb" });
previousSecsIntegral = secsIntegral;
}
foregroundColor = foregroundColorRange(secsFractional);
input.style.color = foregroundColor.toString({ inGamut: false });
const foregroundCielabNudged = nudgeCielab(backgroundColor, foregroundColor);
const foregroundOklabNudged = nudgeOklab(backgroundColor, foregroundColor);
cielab.style.color = foregroundCielabNudged;
oklab.style.color = foregroundOklabNudged;
statsInput.innerHTML = contrastString(foregroundColor);
statsCielab.innerHTML = contrastString(foregroundCielabNudged);
statsOklab.innerHTML = contrastString(foregroundOklabNudged);
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
document.getElementById("background-color").addEventListener("input", event => {
backgroundColor = new Color(event.target.value);
document.documentElement.style.backgroundColor = backgroundColor;
}, false);
document.documentElement.style.backgroundColor = backgroundColor;
</script>
</body>
</html>

View File

@@ -0,0 +1,499 @@
---
author: Mike Griese
created on: 2022-03-28
last updated: 2023-07-19
issue id: 11000, 1527, 6232
---
##### [Original issue: [#1527]] [experimental PR [#12948]] [remaining marks [#14341]]
# Windows Terminal - Shell Integration (Marks)
## Abstract
_"Shell integration" refers to a broad category of ways by which a commandline
shell can drive richer integration with the terminal. This spec in particular is
most concerned with "marks" and other semantic markup of the buffer._
Marks are a new buffer-side feature that allow the commandline application or
user to add a bit of metadata to a range of text. This can be used for marking a
region of text as a prompt, marking a command as succeeded or failed, quickly
marking errors in the output. These marks can then be exposed to the user as
pips on the scrollbar, or as icons in the margins. Additionally, the user can
quickly scroll between different marks, to allow easy navigation between
important information in the buffer.
Marks in the Windows Terminal are a combination of functionality from a variety
of different terminal emulators. "Marks" attempts to unify these different, but
related pieces of functionality.
## Background
There's a large amount of prior art on this subject. I've attempted to collect
as much as possible in the ["Relevant external docs"](#Relevant-external-docs)
section below. "Marks" have been used in different scenarios by different
emulators for different purposes. The common thread running between them of
marking a region of text in the buffer with a special meaning.
* iTerm2, ConEmu, FinalTerm et.al. support emitting a VT sequence to indicate
that a line is a "prompt" line. This is often used for quick navigation
between these prompts.
* FinalTerm (and xterm.js) also support marking up more than just the prompt.
They go so far as to differentiate the start/end of the prompt, the start of
the commandline input, and the start/end of the command output.
`FTCS_COMMAND_FINISHED` is even designed to include metadata indicating
whether a command succeeded or failed.
* Additionally, Terminal.app allows users to "bookmark" lines via the UI. That
allows users to quickly come back to something they feel is important.
* Consider also editors like Visual Studio. VS also uses little marks on the
scrollbar to indicate where other matches are for whatever the given search
term is.
### "Elevator" pitch
The Terminal provides a way for command line shells to semantically mark parts
of the command-line output. By marking up parts of the output, the Terminal can
provide richer experiences. The Terminal will know where each command starts and
stops, what the actual command was and what the output of that command is. This
allows the terminal to expose quick actions for:
* Quickly navigating the history by scrolling between commands
* Re-running a previous command in the history
* Copying all the output of a single command
* A visual indicator to separate out one command-line from the next, for quicker
mental parsing of the output of the command-line.
* Collapsing the output of a command, as to reduce noise
* Visual indicators that highlight commands that succeeded or failed.
* Jumping to previously used directories
### User Stories
This is a bit of a unusual section, as this feature was already partially
implemented when this spec was written.
Story | Size | Description
--|-----------|--
A | ✅ Done | The user can use mark each prompt and have a mark displayed on the scrollbar
B | ✅ Done | The user can perform an action to scroll between marks
C | ✅ Done | The user can manually add marks to the buffer
D | ✅ Done | The shell can emit different marks to differentiate between prompt, command, and output
E | ✅ Done | Clearing the buffer clears marks
F | 🐣 Crawl | Marks stay in the same place you'd expect after resizing the buffer.
G | ✅ Done | Users can perform an action to select the previous command's output
H | 🚶 Walk | The find dialog can display marks on the scrollbar indicating the position of search matches
I | 🏃‍♂️ Run | The terminal can display icons in the gutter, with quick actions for that command (re-run, copy output, etc)
J | 🏃‍♂️ Run | The terminal can display a faint horizontal separator between commands in the buffer.
K | 🚀 Sprint | The terminal can "collapse" content between two marks.
L | 🚀 Sprint | The terminal can display a sticky header above the control which displays the most recent command
M | 🚀 Sprint | The user can open a dialog to manually bookmark a line with a custom comment
## Solution Design
### Supported VT sequences
* [x] iTerm2's OSC `SetMark` (in [#12948])
* [x] FinalTerm prompt markup sequences
- [x] **FTCS_PROMPT** was added in [#13163]
- [x] The rest in [#14341]
* [ ] additionally, VsCode's FinalTerm prompt markup variant, `OSC 663`
* [ ] [ConEmu's
`OSC9;12`](https://conemu.github.io/en/AnsiEscapeCodes.html#ConEmu_specific_OSC)
* [ ] Any custom OSC we may want to author ourselves.
The FinalTerm prompt sequences are probably the most complicated version of all
these, so it's important to give these a special callout. Almost all the other
VT sequences are roughly equivalent to **FTCS_PROMPT**. The xterm.js / VsCode
version has additional cases, that they ironically added to work around conpty
not understanding these sequences originally.
#### FinalTerm sequences
The relevant FinalTerm sequences for marking up the prompt are as follows.
![image](FTCS-diagram.png)
* **FTCS_PROMPT**: `OSC 133 ; A ST`
- The start of a prompt. Internally, this sets a marker in the buffer
indicating we started a prompt at the current cursor position, and that
marker will be used when we get a **FTCS_COMMAND_START**
* **FTCS_COMMAND_START**: `OSC 133 ; B ST`
- The start of a commandline (READ: the end of the prompt). When it follows a
**FTCS_PROMPT**, it creates a mark in the buffer from the location of the
**FTCS_PROMPT** to the current cursor position, with the category of
`prompt`
* **FTCS_COMMAND_EXECUTED**: `OSC 133 ; C ST`
- The start of the command output / the end of the commandline.
* **FTCS_COMMAND_FINISHED**: `OSC 133 ; D ; [Ps] ST`
- the end of a command.
Same deal for the **FTCS_COMMAND_EXECUTED**/**FTCS_COMMAND_FINISHED** ones.
**FTCS_COMMAND_EXECUTED** does nothing until we get a **FTCS_COMMAND_FINISHED**,
and the `[Ps]` parameter determines the category.
- `[Ps] == 0`: success
- anything else: error
This whole sequence will get turned into a single mark.
When we get the **FTCS_COMMAND_FINISHED**, set the category of the prompt mark
that preceded it, so that the `prompt` becomes an `error` or a `success`.
### Buffer implementation
In the initial PR ([#12948]), marks were stored simply as a `vector<Mark>`,
where a mark had a start and end point. These wouldn't reflow on resize, and
didn't support all of the FTCS sequences.
There's ultimately three types of region here we need to mark:
* The prompt (starting from A)
* the command (starting from B)
* the output (starting from C)
That intuitively feels a bit like a text attribute almost. Additionally, the
prompt should be connected to its subsequent command and output, s.t. we can
* Select command output
* re-run command
easily. Supposedly, we could do this by iterating through the whole buffer to
find the previous/next {whatever}[[1](#footnote-1)]. Additionally, the prompt
needs to be able to contain the status / category, and a `133;D` needs to be
able to change the category of the previous prompt/command.
If we instead do a single mark for each command, from `133;A` to `133;A`, and
have sub-points for elements within the command
* `133;A` starts a mark on the current line, at the current position.
* `133;B` sets the end of the mark to the current position.
* `133;C` updates the mark's `commandStart` to the current end, then sets the
end of the mark to the current position.
* `133;D` updates the mark's `outputStart` to the current end, then sets the end
of the mark to the current position. It also updates the category of the mark,
if needed.
Each command then only shows up as a single mark on the scrollbar. Jumping
between commands is easy, `scrollToMark` operates on `mark.start`, which is
where the prompt started. "Bookmarks", i.e. things started by the user wouldn't
have `commandStart` or `outputStart` in them. Getting the text of the command,
of the output is easy - it's just the text between sub-points.
Reflow still sucks though - we'd need to basically iterate over all the marks as
we're reflowing, to make sure we put them into the right place in the new
buffer. This is annoying and tedious, but shouldn't realistically be a
performance problem.
#### Cmd.exe considerations
`cmd.exe` is generally a pretty bad shell, and doesn't have a lot of the same
hooks that other shells do, that might allow for us to emit the
**FTCS_COMMAND_EXECUTED** sequence. However, cmd.exe also doesn't allow
multiline prompts, so we can be relatively certain that when the user presses
<kbd>enter</kbd>, that's the end of the prompt. We will treat the
`autoMarkPrompts` setting (which auto-marks <kbd>enter</kbd>) as the _end of the
prompt_. That would at least allow cmd.exe to emit a {command finished}{prompt
start}{prompt...}{command start} in the prompt, and have us add the command
executed. It is not perfect (we wouldn't be able to get error information), but
it does work well enough.
```cmd
PROMPT $e]133;D$e\$e]133;A$e\$e]9;9;$P$e\%PROMPT%$e]133;B$e\
```
## Settings proposals
The below are the proposed additions to the settings for supporting marks and
interacting with them. Some of these have already been added as experimental
settings - these would be promoted to no longer be experimental.
Many of the sub-points on these settings are definitely "Future Consideration"
level settings. For example, the `scrollToMark` `"highlight"` property. That one
is certainly not something we need to ship with.
### Actions
In addition to driving marks via the output, we will also want to support adding
marks manually. These can be thought of like "bookmarks" - a user indicated
region that means something to the user.
* [ ] `addMark`: add a mark to the buffer. If there's a selection, place the
mark covering at the selection. Otherwise, place the mark on the cursor row.
- [x] `color`: a color for the scrollbar mark. (in [#12948])
- [ ] `category`: one of `{"prompt", "error", "warning", "success", "info"}`
* [ ] `scrollToMark`
- [x] `direction`: `["first", "previous", "next", "last"]` (in [#12948])
- [ ] `category`: `flags({categories}...)`, default `"all"`. Only scroll to
one of the categories specified (e.g. only scroll to the previous error,
only the previous prompt, or just any mark)
- [ ] [#13449] - `center` or some other setting that controls how the mark is scrolled in.
- Maybe `top` (current) /`center` (as proposed) /`nearestEdge` (when
scrolling down, put the mark at the bottom line of viewport , up -> top
line)?
- [ ] [#13455] - `highlight`: `bool`, default true. Display a temporary
highlight around the mark when scrolling to it. ("Highlight" != "select")
- If the mark has prompt/command/output sections, only select the prompt and command.
- If the mark has zero width (i.e. the user just wanted to bookmark a line),
then highlight the entire row.
* [x] `clearMark`: Remove any marks in the selected region (or at the cursor
position) (in [#12948])
* [x] `clearAllMarks`: Remove all the marks from the buffer. (in [#12948])
#### Selecting commands & output
_Inspired by a long weekend of manually copying .csv output from the Terminal to
a spreadsheet, only to discover that we rejected [#4588] some years ago._
* [x] `selectCommand(direction=[prev, next])`: Starting at the active selection
anchor, (or the cursor if there's no selection), select the command that
starts before/after this point (exclusive). Probably shouldn't wrap around
the buffer.
* Since this will create a selection including the start of the command,
performing this again will select the _next_ command (in whatever
direction).
* [x] `selectOutput(direction=[prev, next])`: same as above, but with command outputs.
A convenient workflow might be a `multipleActions([selectOutput(prev),
copy()])`, to quickly select the previous commands output.
### Per-profile settings
* [x] `autoMarkPrompts`: `bool`, default `false`. (in [#12948])
* [ ] `showFindMatchesOnScrollbar`: `bool`, default `true`.
* [ ] `showMarksOnScrollbar`: `bool` or `flags({categories}...)`
* As an example: `"showMarksOnScrollbar": ["error", "success"]`).
* Controls if marks should be displayed on the scrollbar.
* If `true`/`"all"`, then all marks are displayed.
* If `false`/`"none"`, then no marks are displayed.
* If a set of categories are provided, only display marks from those categories.
* [x] the bool version is (in [#12948])
* [ ] The `flags({categories}...)` version is not done yet.
* [ ] `showGutterIcons`, for displaying gutter icons.
## UX Design
An example of what colored marks look like:
![Select the entire output of a command](https://user-images.githubusercontent.com/18356694/207696859-a227abe2-ccd4-4b81-8a2c-8a22219cd0dd.gif)
This gif demos both prompt marks and marks for search results:
![](https://user-images.githubusercontent.com/18356694/191330278-3f6bc207-1bd5-4ebd-bb0e-1f84b0170f49.gif)
### Gutter icons
![](vscode-shell-integration-gutter-mark.png)
_An example of what the icons in the VsCode gutter look like_
### Multiple marks on the same line
When it comes to displaying marks on the scrollbar, or in the margins, the
relative priority of these marks matters. Marks are given the following
priority, with errors being the highest priority.
* Error
* Warning
* Success
* Prompt
* Info (default)
## Work needed to get marks to v1
* [x] Clearing the screen leaves marks behind
* [x] Make sure `ED2` works to clear/move marks
* [x] Same with `ED3`
* [x] Same with `cls` / `Clear-Host`
* [x] Clear Buffer action too.
* [X] Circling doesn't update scrollbar
* I think this was fixed in [#14341], or in [#14045]
* [ ] Resizing / reflowing marks
* [x] marks should be stored in the `TextBuffer`
## Future Considerations
* adding a timestamp for when a line was marked?
* adding a comment to the mark. How do we display that comment? a TeachingTip on
the scrollbar maybe (actually that's a cool idea)
* adding a shape to the mark? Terminal.app marks prompt lines with brackets in
the margins
* Marks are currently just displayed as "last one in wins", they should have a
real sort order
* Should the height of a mark on the scrollbar be dependent on font size &
buffer height? I think I've got it set to like, a static 2dip, but maybe it
should represent the actual height of the row (down to a min 1dip)
* [#13455] - highlight a mark when scrolled to with the `scrollToMark` action.
This is left as a future consideration to figure out what kind of UI we want
here. Do we want to highlight
- the prompt?
- the whole row of the prompt?
- the prompt and the command?
- The whole prompt & command & output?
* an `addBookmark` action: This one's basically just `addMark`, but opens a prompt
(like the window renamer) to add some text as a comment. Automatically
populated with the selected text (if there was some).
- A dedicated transient pane for displaying non-terminal content might be
useful for such a thing.
- This might just make more sense as a parameter to `addMark`.
* Other ideas for `addMark` parameters:
- `icon`: This would require us to better figure out how we display gutter
icons. This would probably be like, a _shape_ rather than an arbitrary
image.
- `note`: a note to stick on the mark, as a comment. Might be more valuable
with something like `addBookmark`.
### Gutter icons
VsCode implements a set of gutter icons to the left of the buffer lines, to
provide a UI element for exposing some quick actions to perform, powered by
shell integration.
Gutter icons don't need to implement app-level actions at all. They _should_ be
part of the control. At least, part of the UWP `TermControl`. These are some
basic "actions" we could add to that menu. Since these are all attached to a
mark anyways, we already know what mark the user interacted with, and where the
start/end already is.
* Copy command
* Copy output
* Re-run command
* Save as task
* Explain this (for errors)
To allow comments in marks (ala "bookmarks"), we can use
the gutter flyout to display the comment, and have the tooltip display that
comment.
This is being left as a future consideration for now. We need to really sit and
consider what the UX is like for this.
* Do we just stick the gutter icons in the margin/padding?
* Have it be a separate space in the "buffer"
- If it's in the buffer itself, we can render it with the renderer, which by
all accounts, we probably should.
### Edge cases where these might not work as expected
Much of the benefits of shell integration come from literal buffer text parsing.
This can lead to some rough edge cases, such as:
* the user presses <kbd>Ctrl+V</kbd><kbd>Escape</kbd> to input an ESC character
and the shell displays it as `^[`
* the user presses <kbd>Ctrl+V</kbd><kbd>Ctrl+J</kbd> to input an LF character
and the shell displays it as a line break
* the user presses <kbd>Enter</kbd> within a quoted string and the shell
displays a continuation prompt
* the user types a command including an exclamation point, and the shell invokes
history expansion and echoes the result of expansion before it runs the
command
* The user has a prompt with a right-aligned status, ala
![](https://user-images.githubusercontent.com/189190/254475719-5007df07-6cc3-42e8-baf7-2572579eb2b9.png)
In these cases, the effects of shell integration will likely not work as
intended. There are various possible solutions that are being explored. We might
want to in the future also use [VsCode's extension to the FTCS sequences] to
enable the shell to tell the terminal the literal resulting commandline.
There's been [other proposals] to extend shell integration features as well.
### Rejected ideas
There was originally some discussion as to whether this is a design that should
be unified with generic pattern matchers. Something like the URL detection,
which identifies part of the buffer and then "marks" it. Prototypes for both of
these features are going in very different directions, however. Likely best to
leave them separate.
## Resources
### Other related issues
Not necessarily marks related, but could happily leverage this functionality.
* [#5916] and [#12366], which are likely to be combined into a single thread
- Imagine a trigger that automatically detects `error:.*` and then marks the line
* [#9583]
- Imagine selecting some text, colorizing & marking it all at once
- `addMark(selection:false)`, above, was inspired by this.
* [#7561] (and broadly, [#3920])
- Search results should maybe show up here on the scrollbar too.
* [#13455]
* [#13449]
* [#4588]
* [#14754] - A "sticky header" for the `TermControl` that could display the
previous command at the top of the buffer.
* [#2226] - a scrollable "minimap" in te scrollbar, as opposed to marks
### Relevant external docs
* **GREAT** summary of the state of the ecosystem: https://gitlab.freedesktop.org/terminal-wg/specifications/-/issues/28
* https://iterm2.com/documentation-escape-codes.html
- `OSC 1337 ; SetMark ST` under "Set Mark"
- under "Shell Integration/FinalTerm
* https://support.apple.com/en-ca/guide/terminal/trml135fbc26/mac
- discusses auto-marked lines on `enter`/`^C`/`^D`
- allows bookmarking lines with selection
- bookmarks can have a name (maybe not super important)
* [How to Use Marks in OS Xs Terminal for Easier Navigation](https://www.howtogeek.com/256548/how-to-use-marks-in-os-xs-terminal-for-easier-navigation/)
* [Terminal: The \[ Marks the Spot](https://scriptingosx.com/2017/03/terminal-the-marks-the-spot/)
* Thread with VsCode (xterm.js) implementation notes: https://github.com/microsoft/terminal/issues/1527#issuecomment-1076455642
* [xterm.js prompt markup sequences](https://github.com/microsoft/vscode/blob/39cc1e1c42b2e53e83b1846c2857ca194848cc1d/src/vs/workbench/contrib/terminal/browser/xterm/shellIntegrationAddon.ts#L50-L52)
* [VsCode command tracking release notes](https://code.visualstudio.com/updates/v1_22#_command-tracking), also [Terminal shell integration](https://code.visualstudio.com/updates/v1_65#_terminal-shell-integration)
* ConEMU:
Sequence | Description
-- | --
ESC ] 9 ; 12 ST | Let ConEmu treat current cursor position as prompt start. Useful with PS1.
* https://iterm2.com/documentation-one-page.html#documentation-triggers.html"
### Footnotes
<a name="footnote-1"><a>[1]: Intuitively, this feels prohibitively expensive,
but you'd be mistaken.
An average device right now (I mean something that was alright about 5 years
ago, like an 8700k with regular DDR4) does about 4GB/s of random, un-cached
memory access. While low-end devices are probably a bit slower, I think 4GB/s is
a good estimate regardless. That's because non-random memory access is way way
faster than that at around 20GB/s (DDR4 2400 - what most laptops had for the
last decade).
Assuming a 120 column * 32k line buffer (our current maximum), the buffer would
be about 21MB large. Going through the entire buffer linearly at 20GB/s would
take just 1ms (including all text and metadata). If we assume that each row has
a mark, that marks are 36 byte large and assuming the worst case of random
access, we can go through all 32k within about 0.3ms.
_(Thanks lhecker for these notes)_
[#1527]: https://github.com/microsoft/terminal/issues/1527
[#12948]: https://github.com/microsoft/terminal/issues/12948
[#1527]: https://github.com/microsoft/terminal/issues/1527
[#6232]: https://github.com/microsoft/terminal/issues/6232
[#2226]: https://github.com/microsoft/terminal/issues/2226
[#12948]: https://github.com/microsoft/terminal/issues/12948
[#13163]: https://github.com/microsoft/terminal/issues/13163
[#12948]: https://github.com/microsoft/terminal/issues/12948
[#12948]: https://github.com/microsoft/terminal/issues/12948
[#12948]: https://github.com/microsoft/terminal/issues/12948
[#13455]: https://github.com/microsoft/terminal/issues/13455
[#13449]: https://github.com/microsoft/terminal/issues/13449
[#12948]: https://github.com/microsoft/terminal/issues/12948
[#12948]: https://github.com/microsoft/terminal/issues/12948
[#4588]: https://github.com/microsoft/terminal/issues/4588
[#5804]: https://github.com/microsoft/terminal/issues/5804
[#12948]: https://github.com/microsoft/terminal/issues/12948
[#12948]: https://github.com/microsoft/terminal/issues/12948
[#13455]: https://github.com/microsoft/terminal/issues/13455
[#5916]: https://github.com/microsoft/terminal/issues/5916
[#12366]: https://github.com/microsoft/terminal/issues/12366
[#9583]: https://github.com/microsoft/terminal/issues/9583
[#7561]: https://github.com/microsoft/terminal/issues/7561
[#3920]: https://github.com/microsoft/terminal/issues/3920
[#13455]: https://github.com/microsoft/terminal/issues/13455
[#13449]: https://github.com/microsoft/terminal/issues/13449
[#4588]: https://github.com/microsoft/terminal/issues/4588
[#14341]: https://github.com/microsoft/terminal/issues/14341
[#14045]: https://github.com/microsoft/terminal/issues/14045
[#14754]: https://github.com/microsoft/terminal/issues/14754
[#14341]: https://github.com/microsoft/terminal/issues/14341
[VsCode's extension to the FTCS sequences]: https://code.visualstudio.com/docs/terminal/shell-integration#_vs-code-custom-sequences-osc-633-st
[other proposals]: https://gitlab.freedesktop.org/terminal-wg/specifications/-/merge_requests/6#f6de1e5703f5806d0821d92b0274e895c4b6d850

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 KiB

Some files were not shown because too many files have changed in this diff Show More