Compare commits

..

64 Commits

Author SHA1 Message Date
Dustin L. Howett
dedbffe84d more horrors from beyond the edge of the universe 2024-03-12 15:48:05 -05:00
Dustin L. Howett
5aa26349fa remove ARM build configs 2024-03-12 14:09:54 -05:00
Dustin L. Howett
2dbc5f09b5 Merge remote-tracking branch 'origin/main' into dev/duhowett/interface-projects 2024-03-12 14:09:25 -05:00
Windows Console Service Bot
5022caf6cf Localization Updates - main - 03/12/2024 03:03:57 (#16865) 2024-03-12 09:28:59 -05:00
PankajBhojwani
7f02b25437 spec: update the spec for Action IDs (#16816)
As we start to work on implementing Action IDs, the spec written a few
years ago needs some updates. This PR makes those updates for the
current implementation plan.

References #6899
2024-03-09 13:11:50 -06:00
Windows Console Service Bot
274eaae730 Localization Updates - main - 03/09/2024 03:03:55 (#16850) 2024-03-09 11:43:36 -06:00
Windows Console Service Bot
c238416ae1 Localization Updates - main - 03/08/2024 20:28:42 (#16847) 2024-03-08 15:04:07 -06:00
Dustin L. Howett
ab4b140aa4 Check the localizations into the project nightly (#16835)
Right now, the localization submission pipeline runs every night and
sends our localizable resources over to Touchdown. Later, release builds
pick up the localizations directly from Touchdown, move them into place,
and consume them.

This allowed us to avoid having localized content in the repository, but
it came with too many downsides:

- Users could not contribute additional localizations very easily
- We use the same release pipeline and Touchdown configuration for every
  branch, so strings needed to either slightly match or _entirely match_
  across an entire set of active release branches
- Building from day to day can pull in different strings, making the
  product not reproduceable
- Calling TDBuild during release builds requires network access from the
  build machine (so does restoring NuGet packages, but that's neither
  here nor there)
- Local developers and users could not test out other languages

This pull request moves all localization processing into the nightly
build phase and introduces support for checking loc in and submitting a
pull request. The pull request will not be created anew if one already
exists which has not been merged.

Anything we needed to do on release is now done overnight. This includes
moving loc files into the right places and merging the Cascadia
resources with the Context Menu resources (so that we can work around a
relatively lower amount of translations being chosen for the app versus
the context menu; see #12491 for more info.)

There are some smaller downsides to this approach and its
implementation:

- The first commit is going to be huge
- Right now, it only manages a single branch and uses a force push; if a
  PR is not reviewed timely, it will be force-pushed and you cannot see
  the day-to-day changes in the strings. Hopefully there won't be any.

I've taken great care to ensure that repeated runs of this new pipeline
will not result in unnecessary whitespace changes. This required
changing how we merge ContextMenu.resw into CascadiaPackage to always
use the .NET XmlWriter with specific flags.

NOTE that this does not allow users to _contribute_ translation fixes
for the 10 languages which we are importing. We will still need to pull
changes out of those files and submit them as bugs to the localization
team separately, and hope they come back around in another nightly
build. However, there is no reason users cannot contribute
_non-Touchdown_ languages.
2024-03-08 14:22:11 -06:00
Dustin L. Howett
73fdac6308 Make ColorFromXOrgAppColorName both smaller and more correct (#16824)
We don't need to use `stringstream` to generate a ten-character string,
and we for _sure_ don't need to use the locale-aware ctype functions
after we just wrote a comment saying "XOrg colors are always Latin-1"

| Size Diff | Object         | Library  |
| --------- | -------------- | -------- |
| -11.8 KB  | colorTable.obj | ConTypes |
2024-03-08 14:14:40 -06:00
Mårten Rånge
0ba680ad53 Added experimental.pixelShaderImagePath (#14073)
I realize I might be one of the few developers that care about custom
shader support in terminal but I thought it's worth proposing it and see
what you think.

This is to support custom shaders with custom textures.

I was thinking of exposing the background image to the shader but that
felt complicated after looking into it.

I have tested exploratively. I think the texture loader is possible to
unit test so that is a possible improvement.

The error reporting (as with other custom pixel shader code) is not very
good. That is also an area that I could improve upon.

I do think the risk of adding this is rather low as the new code is only
executed when experimental.pixelShaderImagePath is set.

### Details

Only added to the Atlas engine.

Instead I load the texture using WIC into a shader resource view. When
binding shader resources I test for presence of custom texture and bind
it to register t1.

The image loading code was found in [the D3D Texture documentation].
It's a mouthful but seems rather robust.


Tested setting: "experimental.pixelShaderImagePath"

1. Tested not specifying it.
2. Tested setting it.
3. Tested changing it (the changes are picked up)
4. Tested invalid path
5. Tested a custom shader that made use of the custom texture.

[the D3D Texture documentation]: https://learn.microsoft.com/en-us/windows/win32/direct3d11/overviews-direct3d-11-resources-textures-how-to

Co-authored-by: Mike Griese <migrie@microsoft.com>
Co-authored-by: Leonard Hecker <lhecker@microsoft.com>
2024-03-08 18:01:53 +00:00
Carlos Zamora
8a1e8ace97 Fix Scratch.sln (#16815)
"ConptyConnection::CreateSettings()" was modified to include some extra
parameters related to the environment variable changes. This just
updates the call in Scratch.sln so that it builds and deploys properly.
2024-03-07 16:55:50 -06:00
James Holderness
563b7312b6 Fix conpty rendering of control characters in the buffer (#16825)
When using the legacy console APIs, it's possible to write arbitrary
codepoints into the buffer. If any of those codepoints are in the C0 or
C1 range, and the buffer contents are forwarded over conpty, they can
end up mistakenly interpreted as controls by the connected terminal.

This PR fixes that issue by converting any C0 and C1 codepoints in the
buffer into printable glyphs before forwarding them over conpty. I've
used the C0 glyphs from the DOS 437 codepage and just a `?` for the C1
codepoints, since that's what you would typically have seen in the v1
console with a raster font.

Although this doesn't address the main problem in #16410, it should at
least fix the rendering issues they're seeing when running their app in
Windows Terminal.

I've confirmed that the test case in #4363 now looks the same in Windows
Terminal as it does in conhost, and I've tested the Windows version of
the terminal game [Gorched], and confirmed that it now works correctly
in Window Terminal.

[Gorched]: https://github.com/zladovan/gorched

Closes #4363
Closes #6265
2024-03-06 13:16:03 -06:00
Mike Griese
338c5047d7 Fix the velocity script to actually support canary (#16810)
Welp, would you look at that? We never actually supported "canary"
feature settings. Canary's been defaulting to the "Dev" config since
inception.

There's a couple things that are supposed to only be on in Dev and not
Canary. They clearly haven't mattered, but better safe than sorry!
2024-03-04 14:03:27 -06:00
James Holderness
33589cd8db Add support for the DECSWT (Set Window Title) escape sequence (#16804)
This PR adds support for the `OSC 21` sequence used on DEC terminals to
set the window title. It's just an alias of the `OSC 2` title sequence
used by XTerm.

This PR also corrects the handling of blank title sequences, which are
supposed to reset the title to its default value, but were previously
ignored.

## Detailed Description of the Pull Request / Additional comments

To handle the blank title parsing correctly, I had to make some changes
to the state machine. Previously it would not have dispatched an `OSC`
sequence unless it received a semicolon following the `OSC` number, but
when there's a blank string, that semicolon should not be required.

I also took this opportunity to simplify the `OSC` parsing in the state
machine, and eliminate the `_GetOscTitle` method which no longer served
any purpose.

## Validation Steps Performed

I've manually confirmed that the title sequences are now working as
expected, and added some state machine unit tests covering the blank
value handling for these sequences.

I also had to update one of the existing state machine tests to account
for the changes I made to allow the semicolon to be omitted.

Closes #16783
Closes #16784
2024-03-04 14:03:14 -06:00
Dustin L. Howett
ad51b22f44 Introduce Microsoft.Terminal.UI and consolidate UI helpers (#15107)
This pull request introduces the module Microsoft.Terminal.UI.dll, and
moves into it the following things:

- Any `IDirectKeyListener`
- All XAML converter helpers from around the project
   - ... including `IconPathConverter` from TerminalSettingsModel
   - ... but not `EmptyStringVisibilityConverter`, which has died

It also adds a XAML Markup Extension named `mtu:ResourceString`, which
will allow us to refer to string resources directly from XAML. It will
allow us to remove all of the places in the code where we manually set
resources on XAML controls.

---------

Co-authored-by: Leonard Hecker <lhecker@microsoft.com>
2024-03-01 17:56:49 +00:00
PankajBhojwani
ec5d246b35 Fix being unable to delete a changed Font Axis or Font Feature (#16790)
Make sure the delete button's `Tag` updates when the selected
axis/feature changes, so that the correct key value gets propagated when
the delete button is clicked.

Refs #16678 #16104 

## Validation Steps Performed
1. Add a new feature/axis
2. Change the key
3. Click the delete button
4. Delete button works
2024-03-01 05:43:57 -06:00
Leonard Hecker
043d5cd484 Fix bugs in CharToColumnMapper (#16787)
Aside from overall simplifying `CharToColumnMapper` this fixes 2 bugs:
* The backward search loop may have iterated 1 column too far,
  because it didn't stop at `*current <= *target`, but rather at
  `*(current - 1) <= *target`. This issue was only apparent when
  surrogate pairs were being used in a row.
* When the target offset is that of a trailing surrogate pair
  the forward search loop may have iterated 1 column too far.
  It's somewhat unlikely for this to happen since this code is
  only used through ICU, but you never know.

This is a continuation of PR #16775.
2024-02-29 13:59:15 -08:00
Leonard Hecker
b780d8ab7e A minor cleanup of ProfileViewModel (#16788)
This is just a minor cleanup I did as a drive-by while working on
customized font fallback. The benefit of this change is that it's
a tiny bit less expensive, but also that it's a lot easier to read.
The split into "get index" and "get string by index" helps us to
more easily handle both, missing locales and locale fallback.
The code that ties everything together then ends up being just 7 lines.
2024-02-29 14:25:29 -06:00
PankajBhojwani
6e451a2d4b Allow editing font features in the Settings UI (#16678)
## Summary of the Pull Request
**Targets #16104** 

Same as #16104, but for font features

## References and Relevant Issues
#10000 

## Validation Steps Performed
Font features are detected correctly and can be set in the settings UI

![image](https://github.com/microsoft/terminal/assets/26824113/054c30fa-c584-4b71-872d-d956526c373b)

![image](https://github.com/microsoft/terminal/assets/26824113/484a20eb-abe9-478c-99cf-f63939ab4c5b)

## 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)
2024-02-29 20:08:52 +00:00
PankajBhojwani
99042d2f0c Allow editing font axes in the Settings UI (#16104)
## Summary of the Pull Request
Allow editing of font features and axes in the SUI to get the UI closer
towards JSON parity

The allowed font axes are obtained directly from the currently selected
font, and their display names are presented to the user in the user's
current locale (if it exists). Otherwise, we just display the axis tag
to the user.

## References and Relevant Issues
#10000 

## Validation Steps Performed

- [x] Font Axes can be added/changed/removed from the Settings UI


![image](https://github.com/microsoft/terminal/assets/26824113/b1c3ed57-e329-4893-9f15-7b60154b5ea0)

![image](https://github.com/microsoft/terminal/assets/26824113/e1f1ea22-857d-4392-8a15-f81539fe9257)

## 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)
2024-02-29 18:39:26 +00:00
Dustin L. Howett
30dbd3b554 Make the Settings Model tests into proper CI tests (#16773)
This pull request removes the need for the SettingsModel tests to run in
a UAP harness and puts them into the standard CI rotation.

This required some changes to `Run-Tests.ps1` to ensure that the right
`te.exe` is selected for each test harness. It's a bit annoying, but for
things that depend on a `resources.pri`, that file must be in the same
directory as the EXE that is hosting the test. Not the DLL, mind you,
the EXE. In our case, that's `TE.ProcessHost.exe`

The bulk of the change is honestly namespace tidying.

Co-authored-by: Mike Griese <migrie@microsoft.com>
Co-authored-by: Leonard Hecker <lhecker@microsoft.com>
2024-02-29 09:00:04 -08:00
Leonard Hecker
94e74d22c6 Make shaded block glyphs look even betterer (#16760)
Shaded glyphs (U+2591..3, etc.) all have one problem in common:
The cell size may not be evenly divisible by the pixel/dot size in
the glyph. This either results in blurring, or in moiré-like patterns
at the edges of the cells with its neighbors, because they happen to
start with a pattern that overlaps with the end of the previous cell.

This PR solves the issue by moving the pixel/dot pattern generation
into the shader. That way the pixel/dot location can be made dependent
on the viewport-position of the actual underlying pixels, which avoids
repeating patterns between cells.

The PR contains some additional modifications, all of which either
extend or improve the existing debug facilities in AtlasEngine.
Suppressing whitespaces changes makes the diff way smaller.
2024-02-28 11:25:58 -06:00
Leonard Hecker
badc00e83b Add new and extend existing til::string helpers (#16772)
`wstring_case_insensitive_compare` is not a great name for what it
does as it's incorrect to use for regular (human readable) strings.
This PR thus renames it to `env_key_sorter`.

`compare_string_ordinal` was renamed to `compare_ordinal_insensitive`
to make sure callers know that the comparison is insensitive
(this may otherwise be incorrect in certain contexts after all).
The return value was changed to match `memcmp` so that the API
is detached from its underlying implementation (= NLS).

`compare_linguistic_insensitive` and `contains_linguistic_insensitive`
were added to sort and filter human-readable strings respectively.

`prefix_split` was extended to allow for needles that are just a
single character. This significantly improves the generated assembly
and is also usually what someone would want to actually use.
I've left the string-as-needle variant in just in case.

This PR is prep-work for #2664
2024-02-28 10:57:22 -06:00
Comzyh
e7796e7db3 Fix the hyperlink detection when there are leading wide glyph in the row (#16775)
## Summary of the Pull Request

URL detection was broken again in #15858. When the regex matched, we
calculate the column(cell) by its offset, we use forward or backward
iteration of the column to find the correct column that displays the
glyphs of `_chars[offset]`.


abf5d9423a/src/buffer/out/Row.cpp (L95-L104)

However, when calculating the `currentOffset` we forget that MSB of
`_charOffsets[col]` could be `1`, or col is pointing to another glyph in
preceding column.


abf5d9423a/src/buffer/out/Row.hpp (L223-L226)
2024-02-28 16:34:40 +00:00
Dustin L. Howett
de0f702c74 Deduplicate identical inbox color schemes to heal user settings (#12800)
Up until now, we have treated inbox, fragment and user color schemes the
same: we load them all into one big map and when we save the settings
file we write them *all* out. It's been a big annoyance pretty much
forever.

In addition to cluttering the user's settings file, it prevents us from
making changes to the stock color schemes (like to change the cursor
color, or to adjust the colors in Tango Dark, or what have you) because
they're already copied in full in the user settings. It also means that
we need some special UI affordances for color schemes that you are
allowed to view but not to delete or rename.

We also have a funny hardcoded list of color scheme names and we use
that to determine whether they're "inbox" for UI purposes.

Because of all that, we are hesitant to add *more* color schemes to the
default set.

This pull request resolves all of those issues at once.

It:
- Adds an "origin" to color schemes indicating where they're from
  (Inbox, Fragment, User, ...)
- Replaces the Edit UI with a much simpler version that pretty much only
  has a "duplicate this color scheme to start editing it" button
- Deletes color schemes that we consider to be equivalent to inbox ones;
  this allows us to finally disentangle the user's preferences from the
  terminal's.
- Migrates all user settings that referred to schemes they may have
  modified (even implicitly!) to their modified versions.

The equivalence check intentionally leaves out the cursor and selection
colors, so that we have the freedom to change them in the future.

The Origin is part of a new interface, `ISettingsModelObject`, which we
can use in the future for things like Themes and Actions.
2024-02-27 19:07:08 +00:00
Dustin L. Howett
abf5d9423a Add a script to publish a folder of binaries as a GH release (#13629)
I thought, "what if I could just have a script make all the releases,
tags and names and upload all the assets to the right place?"

So, here's that script.
2024-02-26 15:35:54 -06:00
Mike Griese
4ff38c260f When the profile icon is set to null, fall back to the icon of the commandline (#15843)
Basically, title. If you null out the icon, we'll automatically try to
use the `commandline` as an icon (because we can now). We'll even be
smart about it - `cmd.exe /k echo wassup` will still just use the ico of
`cmd.exe`.

This doesn't work for `ubuntu.exe` (et. al), because that commandline is
technically a reparse point, that doesn't actually have an icon
associated with it.
Closes #705

`"none"` becomes our sentinel value for "no icon". 

This will also use the same `NormalizeCommandLine` we use for
commandline matching for finding the full path to the exe.
2024-02-26 15:32:19 -06:00
Dustin Howett
fefee50757 Fix spelling for openconsole/inbox merge 2024-02-26 14:33:26 -06:00
Dustin L. Howett
7c031a2893 Merge remote-tracking branch 'origin/release-1.19'
# Conflicts:
#	src/interactivity/win32/Clipboard.cpp
#	src/interactivity/win32/clipboard.hpp
2024-02-26 14:33:19 -06:00
Mike Griese
88def9ddcd Add support for actions in fragments (#16185)
Surprisingly easier than I thought this would be. ActionMap already
supports layering (from defaults.json), so this basically re-uses a lot
of that for fun and profit.

The trickiest bits:
* In `SettingsLoader::_parseFragment`, I'm constructing a fake, empty
JSON object, and taking _only_ the actions out from the fragment, and
stuffing them into this temp json. Then, I parse that as a globals
object, and set _that_ as the parent to the user settings file. That
results in _only_ the actions from the fragment being parsed before the
user's actions.
* In that same method, I'm also explicitly preventing the ActionMap (et
al.) from parsing `keys` from these actions. We don't want fragments to
be able to say "ctrl+f is clear buffer" or something like that. This
required a bit of annoying plumbing.


Closes #16063 
Tests added.
Docs need to be updated.
2024-02-26 14:27:57 -06:00
Dustin L. Howett
bb5f56e704 Upgrade Microsoft.Windows.ImplementationLibrary to 1.0.240122.1 (#16617)
This includes a fix for the hang on shutdown due to the folder change
reader.

WIL now validates format strings in `LOG...` macros (yay!) and so we
needed to fix some of our `LOG` macros.

Closes #16456

(cherry picked from commit ce30e7c89c)
Service-Card-Id: 91923199
Service-Version: 1.19
2024-02-26 12:34:20 -06:00
Leonard Hecker
e5d7fd0230 AtlasEngine: Improve dotted, dashed and curly underlines (#16719)
This changeset makes 3 improvements:
* Dotted lines now use a 2:1 ratio between gaps and dots (from 1:1).
  This makes the dots a lot easier to spot at small font sizes.
* Dashed lines use a 1:2 ratio and a cells-size independent stride.
  By being cell-size independent it works more consistently with a
  wider variety of fonts with weird cell aspect ratios.
* Curly lines are now cell-size independent as well and have a
  height that equals the double-underline size.
  This ensures that the curve isn't cut off anymore and just like
  with dashed lines, that it works under weird aspect ratios.

Closes #16712

## Validation Steps Performed
This was tested using RenderingTests using Cascadia Mono, Consolas,
Courier New, Lucida Console and MS Gothic.

(cherry picked from commit 9c8058c326)
Service-Card-Id: 91922825
Service-Version: 1.19
2024-02-26 11:47:40 -06:00
Dustin L. Howett
7c1edbdb5f build: add a tsa configuration for asyncSdl (#16728)
(cherry picked from commit e3ff44bb82)
Service-Card-Id: 91922822
Service-Version: 1.19
2024-02-26 11:47:38 -06:00
Dustin L. Howett
2dfa3da199 build: switch to NuGetAuthenticate@1 (#16752)
It keeps warning us that v0 has been deprecated.

(cherry picked from commit 6b29ef51e3)
Service-Card-Id: 91903282
Service-Version: 1.19
2024-02-26 11:43:41 -06:00
Leonard Hecker
a6a0e44088 Add support for custom box drawing and powerline glyphs (#16729)
This adds support for drawing our own box drawing, block element,
and basic Powerline (U+E0Bx) glyphs in AtlasEngine.

This PR consists of 4 parts:
* AtlasEngine was refactored to simplify `_drawGlyph` because I've
  wanted to do that for ~1 year now and never got a chance.
  Well, now I'm doing it and you all will review it muahahaha.
  The good news is that it removes a goto usage that even for my
  standards was rather dangerous. Now it's gone and the risk with it.
* AtlasEngine was further refactored to properly parse out text that
  we want to handle different from regular text. Previously, we only
  did that for soft fonts, but now we want to do that for a lot more,
  so a refactor was in order. The new code is still extremely
  disgusting, because I now stuff `wchar_t`s into an array that's
  intended for glyph indices, but that's the best way to make it fast
  and not blow up the complexity of the code even further.
* Finally this adds a huge LUT for all the aforementioned glyphs.
  The LUT has 4 "drawing instruction" entries per glyph which describe
  the shape (rectangle, circle, lines, etc.) and the start/end coord.
  With a lot of bit packing each entry is only 4 bytes large.
* Finally-finally a `builtinGlyphs` setting was added to the font
  object and it defaults to `true`.

Closes #5897

## Validation Steps Performed
* RenderingTests with soft fonts 
* All the aforementioned glyphs 
* ...with color 
* `customGlyphs` setting can be toggled on and off 
2024-02-23 15:40:29 -06:00
Dustin L. Howett
6b29ef51e3 build: switch to NuGetAuthenticate@1 (#16752)
It keeps warning us that v0 has been deprecated.
2024-02-23 05:34:02 -06:00
Leonard Hecker
ec434e3fba Add an automated conhost benchmark tool (#16453)
`ConsoleBench` is capable of launching conhost instances and measuring
their performance characteristics. It writes these out as an HTML file
with violin graphs (using plotly.js) for easy comparison.
Currently, only a small number of tests have been added, but the code
is structured in such a way that more tests can be added easily.
2024-02-22 06:31:31 -06:00
Leonard Hecker
9c8058c326 AtlasEngine: Improve dotted, dashed and curly underlines (#16719)
This changeset makes 3 improvements:
* Dotted lines now use a 2:1 ratio between gaps and dots (from 1:1).
  This makes the dots a lot easier to spot at small font sizes.
* Dashed lines use a 1:2 ratio and a cells-size independent stride.
  By being cell-size independent it works more consistently with a
  wider variety of fonts with weird cell aspect ratios.
* Curly lines are now cell-size independent as well and have a
  height that equals the double-underline size.
  This ensures that the curve isn't cut off anymore and just like
  with dashed lines, that it works under weird aspect ratios.

Closes #16712

## Validation Steps Performed
This was tested using RenderingTests using Cascadia Mono, Consolas,
Courier New, Lucida Console and MS Gothic.
2024-02-22 12:53:02 +01:00
Leonard Hecker
bf25595961 Remove DxEngine (#16278)
With AtlasEngine being fairly stable at this point and being enabled
by default in the 1.19 branch, this changeset removes DxEngine.

## Validation Steps Performed
* WT builds and runs 
* WpfTestNetCore 
* Saving the config removes the `useAtlasEngine` key 
2024-02-21 23:50:59 +00:00
James Holderness
9654fc6afe Complete the 8-bit interface architecture (#16547)
## Summary of the Pull Request

This PR adds support for the missing operations that are required in the
8-bit interface architecture extension.

`DECAUPSS` - Assign User-Preference Supplemental Set
`DECRQUPSS` - Request User-Preference Supplemental Set
`ACS` - Announce Code Structure for ANSI levels 1, 2, and 3

## Detailed Description of the Pull Request / Additional comments

For the UPSS assignment there's a new `wstring_view` in `TerminalOutput`
that tracks the current mapping table for the character set, and a new
`VTID` field tracking the ID so it can be queried. The ANSI conformance
just required a couple of calls to existing methods to designate the
appropriate character sets and GL/GR maps.

And now that we've implemented everything that's required, I've updated
our device attributes report (`DA1`) to indicate support for the 8-bit
interface architecture (feature 14).

This PR also addresses some issues with the way the 8-bit GR capability
is managed. Previously a soft reset (`DECSTR`) would return the code
page to its startup state, and the restore cursor operation (`DECRC`)
could have a similar effect. This was a problem for 8-bit apps that
weren't expecting that behavior.

I've now made it so those operations no longer have any effect on the
code page, and the same applies to the C1 parsing option (`DECAC1`). The
only way to restore the code page and C1 parsing to their startup state
now is with a hard reset (`RIS`).

## Validation Steps Performed

I've added unit tests covering the `DECAUPSS` and `DECRQUPSS` sequences,
and I've also manually tested their behavior in Vttest.

## PR Checklist
- [x] Closes #16546
- [x] Tests added/passed
2024-02-21 21:15:06 +00:00
Dustin L. Howett
3f27765861 hygiene: remove derelict ARM build configurations (#16746) 2024-02-21 20:31:00 +01:00
Leonard Hecker
d3ec47a7fc Fix an apparent x86 miscompilation on MSVC 19.38 (#16742)
There's an apparent miscompilation of `dynamic_bitset` on x86 with
MSVC 19.38, where the following code:
```cpp
dynamic_bitset<uint64_t> bits(80 * 24, 0);
bits.set(0, 3 * 80, true);
```

is expected to set the first 3.75 blocks to 1 which should produce
the following blocks:
```
0xffffffffffffffff
0xffffffffffffffff
0xffffffffffffffff
0x0000ffffffffffff
```

but it actually produces:
```
0xffffffffffffffff
0x00000000ffffffff
0xffffffffffffffff
0x0000ffffffffffff
```

The weird thing here is that this only happens if `til::bitmap`
uses a `dynamic_bitset<uint64_t>`. As soon as it uses `<uint32_t>`
any other instantiation of `<uint64_t>` is magically fixed.

Conclusion: Use `size_t` until we know what's going on.
Last known good CL version: 14.37.32822
Current broken CL version: 14.38.33130

## Validation Steps Performed

The following test completes successfully again:
```cpp
til::bitmap map{ { 80, 24 } };
map.translate({ 0, 3 }, true);
VERIFY_ARE_EQUAL(3u, map.runs().size());
```
2024-02-21 09:54:35 -08:00
Leonard Hecker
5e9f223a6c COOKED_READ: Fix tab not erasing the prompt (#16718)
Write "<command that doesn't exist> foo" in cmd.exe, move yours cursor
past the <command> and press tab. The "foo" will still be there but
will be inaccessible. This commit fixes the issue. As far as I can
tell, this never worked in any conhost version ever.

Closes #16704
2024-02-21 11:53:30 -06:00
Dustin L. Howett
7ba92193a9 Merge remote-tracking branch 'origin/main' into dev/duhowett/interface-projects 2024-02-19 13:36:39 -06:00
Dustin L. Howett
e3ff44bb82 build: add a tsa configuration for asyncSdl (#16728) 2024-02-18 23:22:41 -06:00
PankajBhojwani
f30cbef34d Implement MVVM for the Actions page (#14292)
## Summary of the Pull Request
Implements an `ActionsViewModel` for the `Actions` page in the SUI

## References

## PR Checklist
* [ ] Closes #xxx
* [x] CLA signed. If not, go over
[here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign
the CLA
* [ ] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on
[our docs repo](https://github.com/MicrosoftDocs/terminal) and link it
here: #xxx
* [ ] Schema updated.
* [x] I'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
A few annoyances:
- Because of the shifts in the UI when switching between edit
mode/regular mode on the `KeyBindingViewModel`s, the page used to
manually handle moving focus accordingly so that focus does not get
lost. However, the page no longer owns the `KeyBindingViewModel`,
instead the `ActionsViewModel` owns them but the `ActionsViewModel`
cannot manually move focus around since it does not own the UI Element.
So, the `ActionsViewModel` emits an event for the page to catch that
tells the page to move focus (`FocusContainer`).
- Similarly, the page used to manually update the `ContainerBackground`
of the `KeyBindingViewModel` when the kbdVM enters `EditMode`. The
`ActionsViewModel` does not have access to the page's resources though
(to determine the correct background brush to use). So, the
`ActionsViewModel` emits another event for the page to catch
(`UpdateBackground`).

## Validation Steps Performed
Actions page still works as before

---------

Co-authored-by: Dustin L. Howett <duhowett@microsoft.com>
2024-02-13 19:25:09 +00:00
Sarim Khan
d3a18b9041 schema: add experimental.repositionCursorWithMouse (#16652)
Add experimental.repositionCursorWithMouse to profiles.schema.json. So
when editing settings.json with vscode, it autocompletes and don't
complain.
2024-02-09 14:31:29 -06:00
e82eric
bef234081a Fix for search selections highlight going backward when the selection wraps to next line (#16691)
Hi, I realized I had a bug in my pull request for search selections
where when the highlight is wrapped it causes the selection to select
back to start of the current line instead of wrapping to the next line.

PR where I introduced this bug: #16227
2024-02-09 14:30:02 -06:00
Dustin L. Howett
71c35cf24c Add a spec for #7335, "console allocation policy" (#7337)
This is a specification for a way to customize console allocations.
The new manifest type `consoleAllocationPolicy` and the new
`AllocConsoleWithOptions` API were already added to the console
client library internally.

Closes #7335
2024-02-07 07:48:52 -06:00
Mike Griese
71efdcb21b Disable DECKPAM mode behind velocity (#16675)
DECKPAM originally tracked in #16506.
Support was added in #16511.
But turns out people didn't expect the Terminal to actually be like,
compliant: #16654

This closes #16654 while we think over in #16672 how we want to solve
this
2024-02-06 23:11:34 +00:00
James Holderness
ec91be5995 Improve handling of Space key combinations (#16645)
This fixes two issues where the `Space` key wasn't being handled
correctly:

* Keyboards with an `AltGr`+`Space` mapping were not generating the
  expected character.
* Pressing a dead key followed by `Space` is supposed to generate the
  accent character associated with that key, but it wasn't doing so.

## References and Relevant Issues

These were both regressions from the keyboard refactor in PR #16511.

## Detailed Description of the Pull Request / Additional comments

The problem was that we were treating `VK_SPACE` as a "functional" key,
which means it gets hardcoded VT mappings which take precedence over
whatever is in the keyboard layout. This was deemed necessary to deal
with the fact that many keyboards incorrectly map `Ctrl`+`Space` as a
`SP` character, when it's expected to be `NUL`.

I've now dropped `VK_SPACE` from the functional mapping table and allow
it be handled by the default mapping algorithm for "graphic" keys.
However, I've also introduced a special case check for `Ctrl`+`Space`
(and other modifier variants), so we can bypass any incorrect keyboard
layouts for those combinations.

## Validation Steps Performed

I couldn't test with a French-BEPO keyboard layout directly, because the
MS Keyboard Layout Creator wouldn't accept a `Space` key mapping that
wasn't whitespace. However, if I remapped the `AltGr`+`Space` combo to
`LF`, I could confirm that we are now generating that correctly.

I've also tested the dead key `Space` combination on various keyboard
layouts and confirmed that that is now working correctly, and checked
that the `Ctrl`+`Space` combinations are still working too.

Closes #16641
Closes #16642
2024-02-06 17:02:25 -06:00
Leonard Hecker
5dda50767b General improvements in preparation for #16598 (#16601)
This contains all the parts of #16598 that aren't specific to session
restore, but are required for the code in #16598:
* Adds new GUID<>String functions that remove the `{}` brackets.
* Adds `SessionId` to the `ITerminalConnection` interface.
* Flush the `ApplicationState` before we terminate the process.
* Not monitoring `state.json` for changes is important as it prevents
  disturbing the session state while session persistence is ongoing.
  That's because when `ApplicationState` flushes to disk, the FS
  monitor will be triggered and reload the `ApplicationState` again.
2024-02-06 23:58:19 +01:00
Leonard Hecker
b70fd5e9c6 Port clipboard improvements from inbox to oss (#16670)
#16618 contained a bug which was fixed inbox. This ports the
changes to the OSS repo manually since the two slightly diverged.
2024-02-06 23:50:15 +01:00
Leonard Hecker
ef96e225da Restore support for pasting files (#16634)
TIL: You could Ctrl+V files into Windows Terminal and here I am,
always opening the context menu and selecting "Copy as path"... smh

This restores the support by adding a very rudimentary HDROP handler.
The flip side of the regression is that I learned about this and so
conhost also gets this now, because why not!

Closes #16627

## Validation Steps Performed
* Single files can be pasted in WT and conhost 
2024-02-02 00:49:57 +01:00
Leonard Hecker
c669afe2a0 Fix a bug caused by #16592 (#16624)
#16592 passes the return value of `GetEnvironmentStringsW` directly
to the `hstring` constructor even though the former returns a
double-null terminated string and the latter expects a regular one.

This PR fixes the issue by using a basic strlen() loop to compute
the length ourselves. It's still theoretically beneficial over
the previous code, but now it's rather bitter since the code isn't
particularly short anymore and so the biggest benefit is gone.

Closes #16623

## Validation Steps Performed
* Validated the `env` string in a debugger 
  It's 1 character shorter than the old `til::env` string.
  That's fine however, since any `HSTRING` is always null-terminated
  anyways and so we get an extra null-terminator for free.
* `wt powershell` works 
2024-01-31 00:16:24 +00:00
Dustin L. Howett
ce30e7c89c Upgrade Microsoft.Windows.ImplementationLibrary to 1.0.240122.1 (#16617)
This includes a fix for the hang on shutdown due to the folder change
reader.

WIL now validates format strings in `LOG...` macros (yay!) and so we
needed to fix some of our `LOG` macros.

Closes #16456
2024-01-30 16:01:12 -08:00
Dustin L. Howett
bcca7aac1b build: remove symbols' dependency on the Package phase (#16625)
Due to things outside our control, sometimes the Package phase fails
when VPack publication is enabled. Because of this, symbols won't be
published. We still want these builds to be considered "golden" and we
are still shipping them, so we *must* publish symbols.
2024-01-30 15:34:27 -08:00
Dustin L. Howett
a2bb3136bb version: bump to 1.21 on main 2024-01-29 19:24:18 -06:00
Dustin L. Howett
6524eb7012 Merge remote-tracking branch 'origin/main' into dev/duhowett/interface-projects 2023-11-01 22:15:23 -05:00
Dustin L. Howett
22a304454b Merge remote-tracking branch 'origin/main' into dev/duhowett/interface-projects 2023-08-20 23:17:37 -05:00
Dustin L. Howett
ce907ce4cd Merge remote-tracking branch 'origin/main' into dev/duhowett/interface-projects 2023-04-02 14:23:04 -05:00
Dustin Howett
2eb4b2876c Move M.T.Core's *interfaces* to a separate project 2023-02-10 14:00:24 -06:00
Dustin Howett
0420bb21e6 Move M.T.TerminalConnection's *interfaces* to a separate project
This leverages Microsoft.Windows.MidlRT to have a project that only
produces a .winmd file, plus a custom MSBuild target that allows for the
TerminalConnection *DLL* project to statically "link" and re-emit the
interface WinMD as its own.
2023-02-10 13:57:46 -06:00
Dustin Howett
8594e9d751 nuget: add M.W.MidlRT, governed by TerminalMidlRT 2023-02-09 17:05:20 -06:00
386 changed files with 12496 additions and 13244 deletions

View File

@@ -18,6 +18,8 @@ consvc
copyable
Counterintuitively
CtrlDToClose
CVS
CUI
cybersecurity
dalet
Dcs
@@ -81,19 +83,24 @@ noreply
ogonek
ok'd
overlined
perlw
pipeline
postmodern
Powerline
powerline
ptys
pwshw
qof
qps
Remappings
Retargets
rclt
reimplementation
reserialization
reserialize
reserializes
rlig
rubyw
runtimes
servicebus
shcha
@@ -114,6 +121,7 @@ toolset
truthiness
tshe
ubuntu
UEFI
uiatextrange
UIs
und

View File

@@ -1,9 +1,12 @@
aalt
abvm
ACCEPTFILES
ACCESSDENIED
acl
aclapi
alignas
alignof
allocconsolewithoptions
APPLYTOSUBMENUS
appxrecipe
bitfield
@@ -21,7 +24,9 @@ COLORPROPERTY
colspan
COMDLG
commandlinetoargv
commoncontrols
comparand
COPYFROMRESOURCE
cstdint
CXICON
CYICON
@@ -33,6 +38,7 @@ delayimp
DERR
dlldata
DNE
dnom
DONTADDTORECENT
DWMSBT
DWMWA
@@ -41,10 +47,12 @@ endfor
ENDSESSION
enumset
environstrings
EXACTSIZEONLY
EXPCMDFLAGS
EXPCMDSTATE
filetime
FILTERSPEC
fina
FORCEFILESYSTEM
FORCEMINIMIZE
frac
@@ -58,6 +66,7 @@ Hashtable
HIGHCONTRASTON
HIGHCONTRASTW
hinternet
HIGHQUALITYSCALE
HINTERNET
hotkeys
href
@@ -74,6 +83,7 @@ IBox
IClass
IComparable
IComparer
ICONINFO
IConnection
ICustom
IDialog
@@ -83,6 +93,7 @@ IExplorer
IFACEMETHOD
IFile
IGraphics
IImage
IInheritable
IMap
IMonarch
@@ -113,6 +124,7 @@ LSHIFT
LTGRAY
MAINWINDOW
MAXIMIZEBOX
medi
memchr
memicmp
MENUCOMMAND
@@ -143,6 +155,7 @@ NOTIFYBYPOS
NOTIFYICON
NOTIFYICONDATA
ntprivapi
numr
oaidl
ocidl
ODR
@@ -156,6 +169,7 @@ OUTLINETEXTMETRICW
overridable
PACL
PAGESCROLL
PALLOC
PATINVERT
PEXPLICIT
PICKFOLDERS
@@ -167,9 +181,11 @@ REGCLS
RETURNCMD
rfind
RLO
rnrn
ROOTOWNER
roundf
RSHIFT
rvrn
SACL
schandle
SEH

View File

@@ -20,6 +20,7 @@ cpptools
cppvsdbg
CPRs
cryptbase
cscript
DACL
DACLs
defaultlib
@@ -31,7 +32,6 @@ DWINRT
enablewttlogging
HOMESHARE
Intelli
issecret
IVisual
libucrt
libucrtd
@@ -46,6 +46,7 @@ MSAA
msixbundle
MSVC
MSVCP
mtu
muxc
netcore
Onefuzz
@@ -73,7 +74,6 @@ sid
Skype
SRW
sxs
symbolrequestprod
Sysinternals
sysnative
systemroot
@@ -90,8 +90,10 @@ Virtualization
visualstudio
vscode
VSTHRD
WINBASEAPI
winsdkver
wlk
wscript
wslpath
wtl
wtt

View File

@@ -115,6 +115,7 @@
^src/terminal/parser/ut_parser/Base64Test.cpp$
^src/terminal/parser/ut_parser/run\.bat$
^src/tools/benchcat
^src/tools/ConsoleBench
^src/tools/integrity/dirs$
^src/tools/integrity/packageuwp/ConsoleUWP\.appxSources$
^src/tools/RenderingTests/main\.cpp$

View File

@@ -185,6 +185,7 @@ chh
chshdng
CHT
Cic
CLASSSTRING
CLE
cleartype
CLICKACTIVE
@@ -228,7 +229,6 @@ commandline
commctrl
commdlg
COMMITID
commoncontrols
componentization
conapi
conareainfo
@@ -285,7 +285,6 @@ convarea
conwinuserrefs
coordnew
COPYCOLOR
COPYFROMRESOURCE
CORESYSTEM
cotaskmem
countof
@@ -432,6 +431,7 @@ DECRQM
DECRQPSR
DECRQSS
DECRQTSR
DECRQUPSS
DECRSPS
decrst
DECSACE
@@ -454,6 +454,7 @@ DECSTBM
DECSTGLT
DECSTR
DECSWL
DECSWT
DECTABSR
DECTCEM
DECXCPR
@@ -581,7 +582,6 @@ EVENTID
eventing
evflags
evt
EXACTSIZEONLY
execd
executionengine
exemain
@@ -607,7 +607,6 @@ FEEF
fesb
FFAF
FFDE
FFFDb
FFrom
fgbg
FGCOLOR
@@ -777,7 +776,6 @@ hhx
HIBYTE
hicon
HIDEWINDOW
HIGHQUALITYSCALE
hinst
HISTORYBUFS
HISTORYNODUP
@@ -827,7 +825,6 @@ hwnd
HWNDPARENT
iccex
ICONERROR
ICONINFO
ICONINFORMATION
IConsole
ICONSTOP
@@ -849,7 +846,6 @@ IGNOREEND
IGNORELANGUAGE
IHosted
iid
IImage
IIo
ILC
ILCo
@@ -1127,8 +1123,8 @@ msix
msrc
MSVCRTD
MTSM
Munged
munges
Munged
murmurhash
muxes
myapplet
@@ -1892,8 +1888,8 @@ UINTs
ul
ulcch
uld
uldash
uldb
uldash
ulwave
Unadvise
unattend
@@ -1917,6 +1913,7 @@ UPDATEDISPLAY
UPDOWN
UPKEY
UPSS
upss
uregex
URegular
usebackq

File diff suppressed because it is too large Load Diff

View File

@@ -33,8 +33,6 @@ extends:
publishSymbolsToPublic: true
publishVpackToWindows: false
symbolExpiryTime: 15
symbolPublishingSubscription: $(SymbolPublishingServiceConnection)
symbolPublishingProject: $(SymbolPublishingProject)
${{ if eq(true, parameters.publishToAzure) }}:
extraPublishJobs:
- template: build/pipelines/templates-v2/job-deploy-to-azure-storage.yml@self

View File

@@ -81,5 +81,3 @@ extends:
terminalInternalPackageVersion: ${{ parameters.terminalInternalPackageVersion }}
publishSymbolsToPublic: ${{ parameters.publishSymbolsToPublic }}
publishVpackToWindows: ${{ parameters.publishVpackToWindows }}
symbolPublishingSubscription: $(SymbolPublishingServiceConnection)
symbolPublishingProject: $(SymbolPublishingProject)

View File

@@ -1,117 +0,0 @@
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
- name: symbolExpiryTime
type: string
default: 36530 # This is the default from PublishSymbols@2
- name: variables
type: object
default: {}
- name: subscription
type: string
- name: symbolProject
type: string
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 }}
variables:
${{ insert }}: ${{ parameters.variables }}
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'
- powershell: |-
Get-PackageProvider -Name NuGet -ForceBootstrap
Install-Module -Verbose -AllowClobber -Force Az.Accounts, Az.Storage, Az.Network, Az.Resources, Az.Compute
displayName: Install Azure Module Dependencies
# Transit the Azure token from the Service Connection into a secret variable for the rest of the pipeline to use.
- task: AzurePowerShell@5
displayName: Generate an Azure Token
inputs:
azureSubscription: ${{ parameters.subscription }}
azurePowerShellVersion: LatestVersion
pwsh: true
ScriptType: InlineScript
Inline: |-
$AzToken = (Get-AzAccessToken -ResourceUrl api://30471ccf-0966-45b9-a979-065dbedb24c1).Token
Write-Host "##vso[task.setvariable variable=SymbolAccessToken;issecret=true]$AzToken"
- 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)'
SymbolsArtifactName: 'WindowsTerminal_$(XES_APPXMANIFESTVERSION)'
SymbolExpirationInDays: ${{ parameters.symbolExpiryTime }}
env:
LIB: $(Build.SourcesDirectory)
- pwsh: |-
# Prepare the defaults for IRM
$PSDefaultParameterValues['Invoke-RestMethod:Headers'] = @{ Authorization = "Bearer $(SymbolAccessToken)" }
$PSDefaultParameterValues['Invoke-RestMethod:ContentType'] = "application/json"
$PSDefaultParameterValues['Invoke-RestMethod:Method'] = "POST"
$BaseUri = "https://symbolrequestprod.trafficmanager.net/projects/${{ parameters.symbolProject }}/requests"
# Prepare the request
$expiration = (Get-Date).Add([TimeSpan]::FromDays(${{ parameters.symbolExpiryTime }}))
$createRequestBody = @{
requestName = "WindowsTerminal_$(XES_APPXMANIFESTVERSION)";
expirationTime = $expiration.ToString();
}
Write-Host "##[debug]Starting request $($createRequestBody.requestName) with expiration date of $($createRequestBody.expirationTime)"
Invoke-RestMethod -Uri "$BaseUri" -Body ($createRequestBody | ConvertTo-Json -Compress) -Verbose
# Request symbol publication
$publishRequestBody = @{
publishToInternalServer = $true;
publishToPublicServer = $${{ parameters.includePublicSymbolServer }};
}
Write-Host "##[debug]Submitting request $($createRequestBody.requestName) ($($publishRequestBody | ConvertTo-Json -Compress))"
Invoke-RestMethod -Uri "$BaseUri/$($createRequestBody.requestName)" -Body ($publishRequestBody | ConvertTo-Json -Compress) -Verbose
displayName: Publish Symbols using internal REST API

View File

@@ -56,6 +56,7 @@ jobs:
- task: PowerShell@2
displayName: 'Run PGO Tests'
inputs:
pwsh: true
targetType: filePath
filePath: build\scripts\Run-Tests.ps1
arguments: >-

View File

@@ -44,6 +44,7 @@ jobs:
- task: PowerShell@2
displayName: 'Run Unit Tests'
inputs:
pwsh: true
targetType: filePath
filePath: build\scripts\Run-Tests.ps1
arguments: -MatchPattern '*unit.test*.dll' -Platform '$(OutputBuildPlatform)' -Configuration '$(BuildConfiguration)' -LogPath '${{ parameters.testLogPath }}' -Root "$(Terminal.BinDir)"
@@ -52,6 +53,7 @@ jobs:
- task: PowerShell@2
displayName: 'Run Feature Tests'
inputs:
pwsh: true
targetType: filePath
filePath: build\scripts\Run-Tests.ps1
arguments: -MatchPattern '*feature.test*.dll' -Platform '$(OutputBuildPlatform)' -Configuration '$(BuildConfiguration)' -LogPath '${{ parameters.testLogPath }}' -Root "$(Terminal.BinDir)"

View File

@@ -52,10 +52,6 @@ parameters:
- name: publishVpackToWindows
type: boolean
default: false
- name: symbolPublishingSubscription
type: string
- name: symbolPublishingProject
type: string
- name: extraPublishJobs
type: object
@@ -252,13 +248,12 @@ extends:
displayName: Publish
dependsOn: [Build]
jobs:
- template: ./build/pipelines/templates-v2/job-publish-symbols-using-symbolrequestprod-api.yml@self
- template: ./build/pipelines/templates-v2/job-publish-symbols.yml@self
parameters:
pool: { type: windows }
includePublicSymbolServer: ${{ parameters.publishSymbolsToPublic }}
symbolPatGoesInTaskInputs: true # onebranch tries to muck with the PAT variable, so we need to change how it get the PAT
symbolExpiryTime: ${{ parameters.symbolExpiryTime }}
subscription: ${{ parameters.symbolPublishingSubscription }}
symbolProject: ${{ parameters.symbolPublishingProject }}
variables:
ob_git_checkout: false # This job checks itself out
ob_git_skip_checkout_none: true

View File

@@ -1,2 +1,2 @@
variables:
WindowsContainerImage: 'onebranch.azurecr.io/windows/ltsc2022/vse2022:1.0.02566.28'
WindowsContainerImage: 'onebranch.azurecr.io/windows/ltsc2022/vse2022:latest'

View File

@@ -0,0 +1,49 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<OpenConsoleGetUtilityProjectWinMDReferencesDependsOn></OpenConsoleGetUtilityProjectWinMDReferencesDependsOn>
<OpenConsoleGetUtilityProjectWinMDReferencesDependsOn Condition="'$(TerminalCppWinRT)'=='true'">
GetCppWinRTProjectWinMDReferences;
$(OpenConsoleGetUtilityProjectWinMDReferencesDependsOn)
</OpenConsoleGetUtilityProjectWinMDReferencesDependsOn>
<OpenConsoleGetUtilityProjectWinMDReferencesDependsOn Condition="'$(TerminalMidlRT)'=='true'">
GetMidlRTProjectWinMDReferences;
$(OpenConsoleGetUtilityProjectWinMDReferencesDependsOn)
</OpenConsoleGetUtilityProjectWinMDReferencesDependsOn>
<CppWinRTResolveReferencesDependsOn>$(CppWinRTResolveReferencesDependsOn);OpenConsoleSwitchUpMergeInputs;</CppWinRTResolveReferencesDependsOn>
<MidlRTResolveReferencesDependsOn>$(MidlRTResolveReferencesDependsOn);OpenConsoleSwitchUpMergeInputs;</MidlRTResolveReferencesDependsOn>
</PropertyGroup>
<Target Name="OpenConsoleGetUtilityProjectWinMDReferences"
DependsOnTargets="ResolveProjectReferences;$(OpenConsoleGetUtilityProjectWinMDReferencesDependsOn)"
Returns="@(OpenConsoleUtilityProjectWinMDReferences)">
<ItemGroup>
<_OpenConsoleUtilityProjectReferences Remove="@(_OpenConsoleUtilityProjectReferences)"/>
<_OpenConsoleUtilityProjectReferences Include="@(_ResolvedProjectReferencePaths)"
Condition= "'%(_ResolvedProjectReferencePaths.ProjectType)'=='Utility' AND
'%(_ResolvedProjectReferencePaths.WinMDFile)' == 'true' AND
'%(_ResolvedProjectReferencePaths.OpenConsoleImplementInterface)' == 'true'"/>
</ItemGroup>
<ItemGroup>
<OpenConsoleUtilityProjectWinMDReferences Remove="@(OpenConsoleUtilityProjectWinMDReferences)" />
<OpenConsoleUtilityProjectWinMDReferences Include="@(_OpenConsoleUtilityProjectReferences)">
<WinMDPath>%(FullPath)</WinMDPath>
</OpenConsoleUtilityProjectWinMDReferences>
</ItemGroup>
</Target>
<!-- Calculates the input files and metadata directories to be passed to MdMerge -->
<Target Name="OpenConsoleSwitchUpMergeInputs"
DependsOnTargets="OpenConsoleGetUtilityProjectWinMDReferences">
<ItemGroup>
<!-- Utility projects should be consumed statically, not as dynamic references. -->
<CppWinRTDynamicProjectWinMDReferences Remove="@(OpenConsoleUtilityProjectWinMDReferences)" />
<CppWinRTStaticProjectWinMDReferences Include="@(OpenConsoleUtilityProjectWinMDReferences)" />
<MidlRTDynamicProjectWinMDReferences Remove="@(OpenConsoleUtilityProjectWinMDReferences)" />
<MidlRTStaticProjectWinMDReferences Include="@(OpenConsoleUtilityProjectWinMDReferences)" />
</ItemGroup>
</Target>
</Project>

View File

@@ -30,6 +30,7 @@
<IntermediateOutputPath>$(SolutionDir)obj\$(Configuration)\GenerateFeatureFlags\</IntermediateOutputPath>
<OpenConsoleCommonOutDir>$(SolutionDir)bin\$(Configuration)\</OpenConsoleCommonOutDir>
<_WTBrandingName Condition="'$(WindowsTerminalBranding)'=='Canary'">Canary</_WTBrandingName>
<_WTBrandingName Condition="'$(WindowsTerminalBranding)'=='Preview'">Preview</_WTBrandingName>
<_WTBrandingName Condition="'$(WindowsTerminalBranding)'=='Release'">Release</_WTBrandingName>
<_WTBrandingName Condition="'$(_WTBrandingName)'==''">Dev</_WTBrandingName>

View File

@@ -16,22 +16,48 @@ Param(
# Find test DLLs based on the provided root, match pattern, and recursion
$testDlls = Get-ChildItem -Path $Root -Recurse -Filter $MatchPattern
$args = @()
$teArgs = @()
# Check if the LogPath parameter is provided and enable WTT logging
if ($LogPath) {
$args += '/enablewttlogging'
$args += '/appendwttlogging'
$args += "/logFile:$LogPath"
$teArgs += '/enablewttlogging'
$teArgs += '/appendwttlogging'
$teArgs += "/logFile:$LogPath"
Write-Host "WTT Logging Enabled"
}
# Invoke the te.exe executable with arguments and test DLLs
& "$Root\te.exe" $args $testDlls.FullName $AdditionalTaefArguments
$rootTe = "$Root\te.exe"
# Check the exit code of the te.exe process and exit accordingly
if ($LASTEXITCODE -ne 0) {
Exit $LASTEXITCODE
# Some of our test fixtures depend on resources.pri in the same folder as the .exe hosting them.
# Unfortunately, that means that we need to run the te.exe *next to* each test DLL we discover.
# This code establishes a mapping from te.exe to test DLL (or DLLs)
$testDllTaefGroups = $testDlls | % {
$localTe = Get-Item (Join-Path (Split-Path $_ -Parent) "te.exe") -EA:Ignore
If ($null -eq $localTe) {
$finalTePath = $rootTe
} Else {
$finalTePath = $localTe.FullName
}
[PSCustomObject]@{
TePath = $finalTePath;
TestDll = $_;
}
}
# Invoke the te.exe executables with arguments and test DLLs
$anyFailed = $false
$testDllTaefGroups | Group-Object TePath | % {
$te = $_.Group[0].TePath
$dlls = $_.Group.TestDll
Write-Verbose "Running $te (for $($dlls.Name))"
& $te $teArgs $dlls.FullName $AdditionalTaefArguments
if ($LASTEXITCODE -ne 0) {
$anyFailed = $true
}
}
if ($anyFailed) {
Exit 1
}
Exit 0

View File

@@ -3,9 +3,9 @@
<!-- This file is read by XES, which we use in our Release builds. -->
<PropertyGroup Label="Version">
<XesUseOneStoreVersioning>true</XesUseOneStoreVersioning>
<XesBaseYearForStoreVersion>2023</XesBaseYearForStoreVersion>
<XesBaseYearForStoreVersion>2024</XesBaseYearForStoreVersion>
<VersionMajor>1</VersionMajor>
<VersionMinor>20</VersionMinor>
<VersionMinor>21</VersionMinor>
<VersionInfoProductName>Windows Terminal</VersionInfoProductName>
</PropertyGroup>
</Project>

View File

@@ -10,6 +10,7 @@
<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.240122.1" targetFramework="native" developmentDependency="true" />
<package id="Microsoft.Windows.MidlRT" version="2.0.200924.1" targetFramework="native" />
<!-- Managed packages -->
<package id="Appium.WebDriver" version="3.0.0.2" targetFramework="net45" />

View File

@@ -2791,11 +2791,6 @@
"description": "Use to set a path to a pixel shader to use with the Terminal. Overrides `experimental.retroTerminalEffect`. This is an experimental feature, and its continued existence is not guaranteed.",
"type": "string"
},
"useAtlasEngine": {
"description": "Windows Terminal 1.16 and later ship with a new, performant text renderer. Set this to false to revert back to the old text renderer.",
"type": "boolean",
"default": true
},
"fontFace": {
"default": "Cascadia Mono",
"description": "[deprecated] Define 'face' within the 'font' object instead.",

View File

@@ -23,7 +23,7 @@ contexts without needing to replicate an entire json blob.
This spec was largely inspired by the following diagram from @DHowett:
![figure 1](data-mockup.png)
![figure 1](data-mockup-002.png)
The goal is to introduce an `id` parameter by which actions could be uniquely
referred to. If we'd ever like to use an action outside the list of `actions`, we
@@ -36,38 +36,54 @@ Discussion with the team lead to the understanding that the name `actions` would
be even better, as a way of making the meaning of the "list of actions" more
obvious.
When we're parsing `actions`, we'll make three passes:
* The first pass will scan the list for objects with an `id` property. We'll
We will then restructure `defaults.json`, and also users' settings files (via `fixUpUserSettings`), in the following manner:
* Instead of each `command` json block containing both the `action` (along with additional arguments) and the `keys`, these will now be split up -
* There will now be one json block for just the `command`/`action`, which will also contain the `id`. These json blocks will be in their own list called `actions`.
* There will be another json block for the `keys`, which will refer to the action to be invoked by `id`. These json blocks will be in their own list called `keybindings`.
For example, let's take a look at the `split pane right` action in `defaults.json` as we currently have it:
`"actions": [..., { "command": { "action": "splitPane", "split": "right" }, "keys": "alt+shift+plus" }, ...]`
This will now become:
`"actions": [..., { "command": { "action": "splitPane", "split": "right" }, "id": "Terminal.SplitPaneRight" }, ...]`
`"keybindings": [..., { "keys": "alt+shift+plus", "id": "Terminal.SplitPaneRight" }, ...]`
Here is how we will parse settings file and construct the relevant settings model objects:
* We will first scan the `actions` list. We'll
attempt to parse those entries into `ActionAndArgs` which we'll store in the
global `id->ActionAndArgs` map. If any entry doesn't have an `id` set, we'll
skip it in this phase. If an entry doesn't have a `command` set, we'll ignore
it in this pass.
* The second pass will scan for _keybindings_. Any entries with `keys` set will
create a `KeyChord->ActionAndArgs` entry in the keybindings map. If the entry
has an `id` set, then we'll simply re-use the action we've already parsed for
the `id`, from the action map. If there isn't an `id`, then we'll parse the
action manually at this time. Entries without a `keys` set will be ignored in
this pass.
* The final pass will be to generate _commands_. Similar to the keybindings
pass, we'll attempt to lookup actions for entries with an `id` set. If there
isn't an `id`, then we'll parse the action manually at this time. We'll then
get the name for the entry, either from the `name` property if it's set, or
the action's `GenerateName` method.
global `id->ActionAndArgs` map. All actions defined in `defaults.json` must have an `id` specified, and all actions provided by fragments must also have `id`s. Any actions from the defaults or fragments that do not provide `id`s will be ignored. As for user-specified commands, if no `id` is set, we will auto-generate one for that command based on the action and any additional arguments. For example, the `split pane right` command above might result in an autogenerated id `User.SplitPaneRight`.
* Note: this step is also where we will generate _commands_. We will use the name provided in the entry if it's set or the action's `GenerateName` method.
* Next we will scan the `keybindings` list. These entries will
create a `KeyChord->ActionAndArgs` entry in the keybindings map. Since these objects should all contain an `id`, we will simply use the `id->ActionAndArgs` map we created in the previous step. Any object with `keys` set but no `id` will be ignored.
For a visual representation, let's assume the user has the following in their
`actions`:
For a visual representation:
![figure 2](data-mockup-actions.png)
![figure 2](data-mockup-actions-ids-keys-maps.png)
We'll first parse the `actions` to generate the mapping of `id`->`Actions`:
### Nested actions
![figure 3](data-mockup-actions-and-ids.png)
We allow certain actions that take a form like this:
Then, we'll parse the `actions` to generate the mapping of keys to actions, with
some actions already being defined in the map of `id`->`Actions`:
```
{
// Select color scheme...
"name": { "key": "SetColorSchemeParentCommandName" },
"commands": [
{
"iterateOn": "schemes",
"name": "${scheme.name}",
"command": { "action": "setColorScheme", "colorScheme": "${scheme.name}" }
}
]
}
```
![figure 4](data-mockup-actions-and-ids-and-keys.png)
For this case, having an `id` on the top level could potentially make sense when it comes to using that `id` in a menu, but not in the case of using that `id` for a keybinding. For the initial implementation, we will not support an `id` for these types of actions, which leaves us open to revisiting this in the future.
### Layering
When layering `actions`, if a later settings file contains an action with the
same `id`, it will replace the current value. In this way, users can redefine
@@ -87,6 +103,9 @@ As we add additional menus to the Terminal, like the customization for the new
tab dropdown, or the tab context menu, or the `TermControl` context menu, they
could all refer to these actions by `id`, rather than duplicating the same json.
As for fragments, all actions in fragments _must_ have an `id`. If a fragment provides an action without an `id`, or provides an `id` that clashes with one of the actions in `defaults.json`, that action will be ignored.
> 👉 NOTE: This will mean that actions will now need an `OriginTag`, similar to profiles and color schemes
### Existing Scenarios

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

View File

@@ -0,0 +1,396 @@
---
author: Dustin Howett @DHowett <duhowett@microsoft.com>
created on: 2020-08-16
last updated: 2023-12-12
issue id: "#7335"
---
# Console Allocation Policy
## Abstract
Due to the design of the console subsystem on Windows as it has existed since Windows 95, every application that is
stamped with the `IMAGE_SUBSYSTEM_WINDOWS_CUI` subsystem in its PE header will be allocated a console by kernel32.
Any application that is stamped `IMAGE_SUBSYSTEM_WINDOWS_GUI` will not automatically be allocated a console.
This has worked fine for many years: when you double-click a console application in your GUI shell, it is allocated a
console. When you run a GUI application from your console shell, it is **not** allocated a console. The shell will
**not** wait for it to exit before returning you to a prompt.
There is a large class of applications that do not fit neatly into this mold. Take Python, Ruby, Perl, Lua, or even
VBScript: These languages are not relegated to running in a console session; they can be used to write fully-fledged GUI
applications like any other language.
Because their interpreters are console subsystem applications, however, any user double-clicking a shortcut to a Python
or Perl application will be presented with a console window that the language runtime may choose to garbage collect, or
may choose not to.
If the runtime chooses to hide the window, there will still be a brief period during which that window is visible. It is
inescapable.
Likewise, any user running that GUI application from a console shell will see their shell hang until the application
terminates.
All of these scripting languages worked around this by shipping two binaries each, identical in every way expect in
their subsystem fields. python/pythonw, perl/perlw, ruby/rubyw, wscript/cscript.
PowerShell[^1] is waiting to deal with this problem because they don't necessarily want to ship a `pwshw.exe` for all
of their GUI-only authors. Every additional `*w` version of an application is an additional maintenance burden and
source of cognitive overhead[^2] for users.
On the other side, you have mostly-GUI applications that want to print output to a console **if there is one
connected**.
These applications are still primarily GUI-driven, but they might support arguments like `/?` or `--help`. They only
need a console when they need to print out some text. Sometimes they'll allocate their own console (which opens a new
window) to display in, and sometimes they'll reattach to the originating console. VSCode does the latter, and so when
you run `code` from CMD, and then `exit` CMD, your console window sticks around because VSCode is still attached to it.
It will never print anything, and your only option is to close it.
There's another risk in reattaching, too. Given that the shell decides whether to wait based on the subsystem
field, GUI subsystem applications that reattach to their owning consoles *just to print some text* end up stomping on
the output of any shell that doesn't wait for them:
```
C:\> application --help
application - the interesting application
C:\> Usage: application [OPTIONS] ...
```
> _(the prompt is interleaved with the output)_
## Solution Design
I propose that we introduce a fusion manifest field, **consoleAllocationPolicy**, with the following values:
* _absent_
* `detached`
This field allows an application to disable the automatic allocation of a console, regardless of the [process creation flags]
passed to [`CreateProcess`] and its subsystem value.
It would look (roughly) like this:
```xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<application>
<windowsSettings>
<consoleAllocationPolicy xmlns="http://schemas.microsoft.com/SMI/2024/WindowsSettings">detached</consoleAllocationPolicy>
</windowsSettings>
</application>
</assembly>
```
The effects of this field will only apply to binaries in the `IMAGE_SUBSYSTEM_WINDOWS_CUI` subsystem, as it pertains to
the particulars of their console allocation.
**All console inheritance will proceed as normal.** Since this field takes effect only in the absence of console
inheritance, CUI applications will still be able to run inside an existing console session.
| policy | behavior |
| - | - |
| _absent_ | _default behavior_ |
| `detached` | The new process is not attached to a console session (similar to `DETACHED_PROCESS`) unless one was inherited. |
An application that specifies the `detached` allocation policy will _not_ present a console window when launched by
Explorer, Task Scheduler, etc.
### Interaction with existing APIs
[`CreateProcess`] supports a number of [process creation flags] that dictate how a spawned application will behave with
regards to console allocation:
* `DETACHED_PROCESS`: No console inheritance, no console host spawned for the new process.
* `CREATE_NEW_CONSOLE`: No console inheritance, new console host **is** spawned for the new process.
* `CREATE_NO_WINDOW`: No console inheritance, new console host **is** spawned for the new process.
* this is the same as `CREATE_NEW_CONSOLE`, except that the first connection packet specifies that the window should
be invisible
Due to the design of [`CreateProcess`] and `ShellExecute`, this specification recommends that an allocation policy of
`detached` _override_ the inclusion of `CREATE_NEW_CONSOLE` in the `dwFlags` parameter to [`CreateProcess`].
> **Note**
> `ShellExecute` passes `CREATE_NEW_CONSOLE` _by default_ on all invocations. This impacts our ability to resolve the
> conflicts between these two APIs--`detached` policy and `CREATE_NEW_CONSOLE`--without auditing every call site in
> every Windows application that calls `ShellExecute` on a console application. Doing so is infeasible.
### Application impact
An application that opts into the `detached` console allocation policy will **not** be allocated a console unless one is
inherited. This presents an issue for applications like PowerShell that do want a console window when they are launched
directly.
Applications in this category can call `AllocConsole()` early in their startup to get fine-grained control over when a
console is presented.
The call to `AllocConsole()` will fail safely if the application has already inherited a console handle. It will succeed
if the application does not currently have a console handle.
> **Note**
> **Backwards Compatibility**: The behavior of `AllocConsole()` is not changing in response to this specification;
> therefore, applications that intend to run on older versions of Windows that do not support console allocation
> policies, which call `AllocConsole()`, will continue to behave normally.
### New APIs
Because a console-subsystem application may still want fine-grained control over when and how its console window is
spawned, we propose the inclusion of a new API, `AllocConsoleWithOptions(PALLOC_CONSOLE_OPTIONS)`.
#### `AllocConsoleWithOptions`
```c++
// Console Allocation Modes
typedef enum ALLOC_CONSOLE_MODE {
ALLOC_CONSOLE_MODE_DEFAULT = 0,
ALLOC_CONSOLE_MODE_NEW_WINDOW = 1,
ALLOC_CONSOLE_MODE_NO_WINDOW = 2
} ALLOC_CONSOLE_MODE;
typedef enum ALLOC_CONSOLE_RESULT {
ALLOC_CONSOLE_RESULT_NO_CONSOLE = 0,
ALLOC_CONSOLE_RESULT_NEW_CONSOLE = 1,
ALLOC_CONSOLE_RESULT_EXISTING_CONSOLE = 2
} ALLOC_CONSOLE_RESULT, *PALLOC_CONSOLE_RESULT;
typedef
struct ALLOC_CONSOLE_OPTIONS
{
ALLOC_CONSOLE_MODE mode;
BOOL useShowWindow;
WORD showWindow;
} ALLOC_CONSOLE_OPTIONS, *PALLOC_CONSOLE_OPTIONS;
WINBASEAPI
HRESULT
WINAPI
AllocConsoleWithOptions(_In_opt_ PALLOC_CONSOLE_OPTIONS allocOptions, _Out_opt_ PALLOC_CONSOLE_RESULT result);
```
**AllocConsoleWithOptions** affords an application control over how and when it begins a console session.
> [!NOTE]
> Unlike `AllocConsole`, `AllocConsoleWithOptions` without a mode (`ALLOC_CONSOLE_MODE_DEFAULT`) will only allocate a console if one was
> requested during `CreateProcess`.
>
> To override this behavior, pass one of `ALLOC_CONSOLE_MODE_NEW_WINDOW` (which is equivalent to being spawned with
> `CREATE_NEW_WINDOW`) or `ALLOC_CONSOLE_MODE_NO_WINDOW` (which is equivalent to being spawned with `CREATE_NO_CONSOLE`.)
##### Parameters
**allocOptions**: A pointer to a `ALLOC_CONSOLE_OPTIONS`.
**result**: An optional out pointer, which will be populated with a member of the `ALLOC_CONSOLE_RESULT` enum.
##### `ALLOC_CONSOLE_OPTIONS`
###### Members
**mode**: See the table below for the descriptions of the available modes.
**useShowWindow**: Specifies whether the value in `showWindow` should be used.
**showWindow**: If `useShowWindow` is set, specifies the ["show command"] used to display your
console window.
###### Return Value
`AllocConsoleWithOptions` will return `S_OK` and populate `result` to indicate whether--and how--a console session was
created.
`AllocConsoleWithOptions` will return a failing `HRESULT` if the request could not be completed.
###### Modes
| Mode | Description |
|:-------------------------------:| ------------------------------------------------------------------------------------------------------------------------------ |
| `ALLOC_CONSOLE_MODE_DEFAULT` | Allocate a console session if (and how) one was requested by the parent process. |
| `ALLOC_CONSOLE_MODE_NEW_WINDOW` | Allocate a console session with a window, even if this process was created with `CREATE_NO_CONSOLE` or `DETACHED_PROCESS`. |
| `ALLOC_CONSOLE_MODE_NO_WINDOW` | Allocate a console session _without_ a window, even if this process was created with `CREATE_NEW_WINDOW` or `DETACHED_PROCESS` |
###### Notes
Applications seeking backwards compatibility are encouraged to delay-load `AllocConsoleWithOptions` or check for its presence in
the `api-ms-win-core-console-l1` APISet.
## Inspiration
Fusion manifest entries are used to make application-scoped decisions like this all the time, like `longPathAware` and
`heapType`.
CUI applications that can spawn a UI (or GUI applications that can print to a console) are commonplace on other
platforms because there is no subsystem differentiation.
## UI/UX Design
There is no UI for this feature.
## Capabilities
### Accessibility
This should have no impact on accessibility.
### Security
One reviewer brought up the potential for a malicious actor to spawn an endless stream of headless daemon processes.
This proposal in no way changes the facilities available to malicious people for causing harm: they could have simply
used `IMAGE_SUBSYSTEM_WINDOWS_GUI` and not presented a UI--an option that has been available to them for 35 years.
### Reliability
This should have no impact on reliability.
### Compatibility
An existing application opting into **detached** may constitute a breaking change, but the scope of the breakage is
restricted to that application and is expected to be managed by the application.
All behavioral changes are opt-in.
> **EXAMPLE**: If Python updates python.exe to specify an allocation policy of **detached**, graphical python applications
> will become double-click runnable from the graphical shell without spawning a console window. _However_, console-based
> python applications will no longer spawn a console window when double-clicked from the graphical shell.
>
> In addition, if python.exe specifies **detached**, Console APIs will fail until a console is allocated.
Python could work around this by calling [`AllocConsole`] or [new API `AllocConsoleWithOptions`](#allocconsolewithoptions)
if it can be detected that console I/O is required.
#### Downlevel
On downlevel versions of Windows that do not understand (or expect) this manifest field, applications will allocate
consoles as specified by their image subsystem (described in the [abstract](#abstract) above).
### Performance, Power, and Efficiency
This should have no impact on performance, power or efficiency.
## Potential Issues
### Shell Hang
I am **not** proposing a change in how shells determine whether to wait for an application before returning to a prompt.
This means that a console subsystem application that intends to primarily present a UI but occasionally print text to a
console (therefore choosing the **detached** allocation policy) will cause the shell to "hang" and wait for it to
exit.
The decision to pause/wait is made entirely in the calling shell, and the console subsystem cannot influence that
decision.
Because the vast majority of shells on Windows "hang" by calling `WaitFor...Object` with a HANDLE to the spawned
process, an application that wants to be a "hybrid" CUI/GUI application will be forced to spawn a separate process to
detach from the shell and then terminate its main process.
This is very similar to the forking model seen in many POSIX-compliant operating systems.
### Launching interactively from Explorer, Task Scheduler, etc.
Applications like PowerShell may wish to retain automatic console allocation, and **detached** would be unsuitable for
them. If PowerShell specifies the `detached` console allocation policy, launching `pwsh.exe` from File Explorer it will
no longer spawn a console. This would almost certainly break PowerShell for all users.
Such applications can use `AllocConsole()` early in their startup.
At the same time, PowerShell wants `-WindowStyle Hidden` to suppress the console _before it's created_.
Applications in this category can use `AllocConsoleWithOptions()` to specify additional information about the new console window.
PowerShell, and any other shell that wishes to maintain interactive launch from the graphical shell, can start in
**detached** mode and then allocate a console as necessary. Therefore:
* PowerShell will set `<consoleAllocationPolicy>detached</consoleAllocationPolicy>`
* On startup, it will process its commandline arguments.
* If `-WindowStyle Hidden` is **not** present (the default case), it can:
* `AllocConsole()` or `AllocConsoleWithOptions(NULL)`
* Either of these APIs will present a console window (or not) based on the flags passed through `STARTUPINFO` during
[`CreateProcess`].
* If `-WindowStyle Hidden` is present, it can:
* `AllocConsoleWithOptions(&alloc)` where `alloc.mode` specifies `ALLOC_CONSOLE_MODE_HIDDEN`
## Future considerations
We're introducing a new manifest field today -- what if we want to introduce more? Should we have a `consoleSettings`
manifest block?
Are there other allocation policies we need to consider?
## Resources
### Rejected Solutions
- A new PE subsystem, `IMAGE_SUBSYSTEM_WINDOWS_HYBRID`
- it would behave like **inheritOnly**
- relies on shells to update and check for this
- checking a subsystem doesn't work right with app execution aliases[^3]
- This is not a new problem, but it digs the hole a little deeper.
- requires standardization outside of Microsoft because the PE format is a dependency of the UEFI specification[^4]
- requires coordination between tooling teams both within and without Microsoft (regarding any tool that operates on
or produces PE files)
- An exported symbol that shells can check for to determine whether to wait for the attached process to exit
- relies on shells to update and check for this
- cracking an executable to look for symbols is probably the last thing shells want to do
- we could provide an API to determine whether to wait or return?
- fragile, somewhat silly, exporting symbols from EXEs is annoying and uncommon
An earlier version of this specification offered the **always** allocation policy, with the following behaviors:
> **STRUCK FROM SPECIFICATION**
>
> * A GUI subsystem application would always get a console window.
> * A command-line shell would not wait for it to exit before returning a prompt.
It was cut because a GUI application that wants a console window can simply attach to an existing console session or
allocate a new one. We found no compelling use case that would require the forced allocation of a console session
outside of the application's code.
An earlier version of this specification offered the **inheritOnly** allocation policy, instead of the finer-grained
**hidden** and **detached** policies. We deemed it insufficient for PowerShell's use case because any application
launched by an **inheritOnly** PowerShell would immediately force the uncontrolled allocation of a console window.
> **STRUCK FROM SPECIFICATION**
>
> The move to **hidden** allows PowerShell to offer a fully-fledged console connection that can be itself inherited by a
> downstream application.
#### Additional allocation policies
An earlier revision of this specification suggested two allocation policies:
> **STRUCK FROM SPECIFICATION**
>
> **hidden** is intended to be used by console applications that want finer-grained control over the visibility of their
> console windows, but that still need a console host to service console APIs. This includes most scripting language
> interpreters.
>
> **detached** is intended to be used by primarily graphical applications that would like to operate against a console _if
> one is present_ but do not mind its absence. This includes any graphical tool with a `--help` or `/?` argument.
The `hidden` policy was rejected due to an incompatibility with modern console hosting, as `hidden` would require an
application to interact with the console window via `GetConsoleWindow()` and explicitly show it.
> **STRUCK FROM SPECIFICATION**
>
> ##### ShowWindow and ConPTY
>
> The pseudoconsole creates a hidden window to service `GetConsoleWindow()`, and it can be trivially shown using
> `ShowWindow`. If we recommend that applications `ShowWindow` on startup, we will need to guard the pseudoconsole's
> pseudo-window from being shown.
[^1]: [Powershell -WindowStyle Hidden still shows a window briefly]
[^2]: [StackOverflow: pythonw.exe or python.exe?]
[^3]: [PowerShell: Windows Store applications incorrectly assumed to be console applications]
[^4]: [UEFI spec 2.6 appendix Q.1]
[Powershell -WindowStyle Hidden still shows a window briefly]: https://github.com/PowerShell/PowerShell/issues/3028
[PowerShell: Windows Store applications incorrectly assumed to be console applications]: https://github.com/PowerShell/PowerShell/issues/9970
[StackOverflow: pythonw.exe or python.exe?]: https://stackoverflow.com/questions/9705982/pythonw-exe-or-python-exe
[UEFI spec 2.6 appendix Q.1]: https://www.uefi.org/sites/default/files/resources/UEFI%20Spec%202_6.pdf
[`AllocConsole`]: https://docs.microsoft.com/windows/console/allocconsole
[`CreateProcess`]: https://docs.microsoft.com/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw
[process creation flags]: https://docs.microsoft.com/en-us/windows/win32/procthread/process-creation-flags
["show command"]: https://learn.microsoft.com/windows/win32/api/winuser/nf-winuser-showwindow

View File

@@ -0,0 +1,23 @@
// Demo shader to show passing in an image using
// experimental.pixelShaderImagePath. This shader simply displays the Terminal
// contents on top of the given image.
//
// The image loaded by the terminal will be placed into the `image` texture.
SamplerState samplerState;
Texture2D shaderTexture : register(t0);
Texture2D image : register(t1);
cbuffer PixelShaderSettings {
float Time;
float Scale;
float2 Resolution;
float4 Background;
};
float4 main(float4 pos : SV_POSITION, float2 tex : TEXCOORD) : SV_TARGET
{
float4 terminalColor = shaderTexture.Sample(samplerState, tex);
float4 imageColor = image.Sample(samplerState, tex);
return lerp(imageColor, terminalColor, terminalColor.a);
}

View File

@@ -31,9 +31,12 @@ namespace winrt::SampleApp::implementation
auto connectionSettings{ TerminalConnection::ConptyConnection::CreateSettings(L"cmd.exe /k echo This TermControl is hosted in-proc...",
winrt::hstring{},
L"",
false,
L"",
nullptr,
32,
80,
winrt::guid(),
winrt::guid()) };
// "Microsoft.Terminal.TerminalConnection.ConptyConnection"

View File

@@ -25,8 +25,20 @@ namespace Microsoft.Terminal.TerminalConnection
void Close();
event TerminalOutputHandler TerminalOutput;
event Windows.Foundation.TypedEventHandler<ITerminalConnection, Object> StateChanged;
Guid SessionId { get; };
ConnectionState State { get; };
};
interface ITerminalConnectionWithWindow
{
void ShowHide(Boolean show);
void ReparentWindow(UInt64 newParent);
};
interface ITerminalConnectionWithBufferState
{
void ClearBuffer();
};
}

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<ProjectGuid>{EFC0B7EF-BB0D-44EC-BFC9-772AE4391D17}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<ProjectName>Microsoft.Terminal.Connection.Interfaces</ProjectName>
<TargetName>Microsoft.Terminal.Connection.Interfaces</TargetName>
<ConfigurationType>Utility</ConfigurationType>
<RootNamespace>Microsoft.Terminal.TerminalConnection</RootNamespace>
<TerminalMidlRT>true</TerminalMidlRT>
<!-- Force our output directory -->
<OpenConsoleCppWinRTProject>true</OpenConsoleCppWinRTProject>
</PropertyGroup>
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
<Import Project="$(OpenConsoleDir)src\common.nugetversions.props" />
<Import Project="$(OpenConsoleDir)src\common.build.pre.props" />
<ItemGroup>
<Midl Include="ITerminalConnection.idl" />
</ItemGroup>
<!-- Careful reordering these. Some default props (contained in these files) are order sensitive. -->
<Import Project="$(OpenConsoleDir)src\common.build.post.props" />
<Import Project="$(OpenConsoleDir)src\common.nugetversions.targets" />
</Project>

View File

@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import "..\ICoreAppearance.idl";
import "ICoreAppearance.idl";
namespace Microsoft.Terminal.Core
{

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<ProjectGuid>{40503EDC-E3E4-46AB-BC26-D293B956CAE8}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<ProjectName>Microsoft.Terminal.Core.Interfaces</ProjectName>
<TargetName>Microsoft.Terminal.Core.Interfaces</TargetName>
<ConfigurationType>Utility</ConfigurationType>
<RootNamespace>Microsoft.Terminal.Core</RootNamespace>
<TerminalMidlRT>true</TerminalMidlRT>
<!-- Force our output directory -->
<OpenConsoleCppWinRTProject>true</OpenConsoleCppWinRTProject>
</PropertyGroup>
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
<Import Project="$(OpenConsoleDir)src\common.nugetversions.props" />
<Import Project="$(OpenConsoleDir)src\common.build.pre.props" />
<ItemGroup>
<Midl Include="ICoreSettings.idl" />
<Midl Include="ICoreAppearance.idl" />
</ItemGroup>
<!-- Careful reordering these. Some default props (contained in these files) are order sensitive. -->
<Import Project="$(OpenConsoleDir)src\common.build.post.props" />
<Import Project="$(OpenConsoleDir)src\common.nugetversions.targets" />
</Project>

View File

@@ -1,404 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "../TerminalSettingsModel/ColorScheme.h"
#include "../TerminalSettingsModel/CascadiaSettings.h"
#include "../types/inc/colorTable.hpp"
#include "JsonTestClass.h"
using namespace Microsoft::Console;
using namespace winrt::Microsoft::Terminal;
using namespace winrt::Microsoft::Terminal::Settings::Model::implementation;
using namespace WEX::Logging;
using namespace WEX::TestExecution;
using namespace WEX::Common;
namespace SettingsModelLocalTests
{
// TODO:microsoft/terminal#3838:
// Unfortunately, these tests _WILL NOT_ work in our CI. We're waiting for
// an updated TAEF that will let us install framework packages when the test
// package is deployed. Until then, these tests won't deploy in CI.
class ColorSchemeTests : public JsonTestClass
{
// Use a custom AppxManifest to ensure that we can activate winrt types
// from our test. This property will tell taef to manually use this as
// the AppxManifest for this test class.
// This does not yet work for anything XAML-y. See TabTests.cpp for more
// details on that.
BEGIN_TEST_CLASS(ColorSchemeTests)
TEST_CLASS_PROPERTY(L"RunAs", L"UAP")
TEST_CLASS_PROPERTY(L"UAP:AppXManifest", L"TestHostAppXManifest.xml")
END_TEST_CLASS()
TEST_METHOD(ParseSimpleColorScheme);
TEST_METHOD(LayerColorSchemesOnArray);
TEST_METHOD(UpdateSchemeReferences);
static Core::Color rgb(uint8_t r, uint8_t g, uint8_t b) noexcept
{
return Core::Color{ r, g, b, 255 };
}
};
void ColorSchemeTests::ParseSimpleColorScheme()
{
const std::string campbellScheme{ "{"
"\"background\" : \"#0C0C0C\","
"\"black\" : \"#0C0C0C\","
"\"blue\" : \"#0037DA\","
"\"brightBlack\" : \"#767676\","
"\"brightBlue\" : \"#3B78FF\","
"\"brightCyan\" : \"#61D6D6\","
"\"brightGreen\" : \"#16C60C\","
"\"brightPurple\" : \"#B4009E\","
"\"brightRed\" : \"#E74856\","
"\"brightWhite\" : \"#F2F2F2\","
"\"brightYellow\" : \"#F9F1A5\","
"\"cursorColor\" : \"#FFFFFF\","
"\"cyan\" : \"#3A96DD\","
"\"foreground\" : \"#F2F2F2\","
"\"green\" : \"#13A10E\","
"\"name\" : \"Campbell\","
"\"purple\" : \"#881798\","
"\"red\" : \"#C50F1F\","
"\"selectionBackground\" : \"#131313\","
"\"white\" : \"#CCCCCC\","
"\"yellow\" : \"#C19C00\""
"}" };
const auto schemeObject = VerifyParseSucceeded(campbellScheme);
auto scheme = ColorScheme::FromJson(schemeObject);
VERIFY_ARE_EQUAL(L"Campbell", scheme->Name());
VERIFY_ARE_EQUAL(til::color(0xf2, 0xf2, 0xf2, 255), til::color{ scheme->Foreground() });
VERIFY_ARE_EQUAL(til::color(0x0c, 0x0c, 0x0c, 255), til::color{ scheme->Background() });
VERIFY_ARE_EQUAL(til::color(0x13, 0x13, 0x13, 255), til::color{ scheme->SelectionBackground() });
VERIFY_ARE_EQUAL(til::color(0xFF, 0xFF, 0xFF, 255), til::color{ scheme->CursorColor() });
std::array<COLORREF, COLOR_TABLE_SIZE> expectedCampbellTable;
const auto campbellSpan = std::span{ expectedCampbellTable };
Utils::InitializeColorTable(campbellSpan);
for (size_t i = 0; i < expectedCampbellTable.size(); i++)
{
const til::color expected{ expectedCampbellTable.at(i) };
const til::color actual{ scheme->Table().at(static_cast<uint32_t>(i)) };
VERIFY_ARE_EQUAL(expected, actual);
}
Log::Comment(L"Roundtrip Test for Color Scheme");
auto outJson{ scheme->ToJson() };
VERIFY_ARE_EQUAL(schemeObject, outJson);
}
void ColorSchemeTests::LayerColorSchemesOnArray()
{
static constexpr std::string_view inboxSettings{ R"({
"schemes": [
{
"background": "#0C0C0C",
"black": "#0C0C0C",
"blue": "#0037DA",
"brightBlack": "#767676",
"brightBlue": "#3B78FF",
"brightCyan": "#61D6D6",
"brightGreen": "#16C60C",
"brightPurple": "#B4009E",
"brightRed": "#E74856",
"brightWhite": "#F2F2F2",
"brightYellow": "#F9F1A5",
"cursorColor": "#FFFFFF",
"cyan": "#3A96DD",
"foreground": "#CCCCCC",
"green": "#13A10E",
"name": "Campbell",
"purple": "#881798",
"red": "#C50F1F",
"selectionBackground": "#FFFFFF",
"white": "#CCCCCC",
"yellow": "#C19C00"
}
]
})" };
static constexpr std::string_view userSettings{ R"({
"profiles": [
{
"name" : "profile0"
}
],
"schemes": [
{
"background": "#121314",
"black": "#121314",
"blue": "#121314",
"brightBlack": "#121314",
"brightBlue": "#121314",
"brightCyan": "#121314",
"brightGreen": "#121314",
"brightPurple": "#121314",
"brightRed": "#121314",
"brightWhite": "#121314",
"brightYellow": "#121314",
"cursorColor": "#121314",
"cyan": "#121314",
"foreground": "#121314",
"green": "#121314",
"name": "Campbell",
"purple": "#121314",
"red": "#121314",
"selectionBackground": "#121314",
"white": "#121314",
"yellow": "#121314"
},
{
"background": "#012456",
"black": "#0C0C0C",
"blue": "#0037DA",
"brightBlack": "#767676",
"brightBlue": "#3B78FF",
"brightCyan": "#61D6D6",
"brightGreen": "#16C60C",
"brightPurple": "#B4009E",
"brightRed": "#E74856",
"brightWhite": "#F2F2F2",
"brightYellow": "#F9F1A5",
"cursorColor": "#FFFFFF",
"cyan": "#3A96DD",
"foreground": "#CCCCCC",
"green": "#13A10E",
"name": "Campbell Powershell",
"purple": "#881798",
"red": "#C50F1F",
"selectionBackground": "#FFFFFF",
"white": "#CCCCCC",
"yellow": "#C19C00"
}
]
})" };
const auto settings = winrt::make_self<CascadiaSettings>(userSettings, inboxSettings);
const auto colorSchemes = settings->GlobalSettings().ColorSchemes();
VERIFY_ARE_EQUAL(2u, colorSchemes.Size());
const auto scheme0 = winrt::get_self<ColorScheme>(colorSchemes.Lookup(L"Campbell"));
VERIFY_ARE_EQUAL(rgb(0x12, 0x13, 0x14), scheme0->Foreground());
VERIFY_ARE_EQUAL(rgb(0x12, 0x13, 0x14), scheme0->Background());
const auto scheme1 = winrt::get_self<ColorScheme>(colorSchemes.Lookup(L"Campbell Powershell"));
VERIFY_ARE_EQUAL(rgb(0xCC, 0xCC, 0xCC), scheme1->Foreground());
VERIFY_ARE_EQUAL(rgb(0x01, 0x24, 0x56), scheme1->Background());
}
void ColorSchemeTests::UpdateSchemeReferences()
{
static constexpr std::string_view settingsString{ R"json({
"defaultProfile": "Inherited reference",
"profiles": {
"defaults": {
"colorScheme": "Campbell"
},
"list": [
{
"name": "Explicit scheme reference",
"colorScheme": "Campbell"
},
{
"name": "Explicit reference; hidden",
"colorScheme": "Campbell",
"hidden": true
},
{
"name": "Inherited reference"
},
{
"name": "Different reference",
"colorScheme": "One Half Dark"
},
{
"name": "rename neither",
"colorScheme":
{
"dark": "One Half Dark",
"light": "One Half Light"
}
},
{
"name": "rename only light",
"colorScheme":
{
"dark": "One Half Dark",
"light": "Campbell"
}
},
{
"name": "rename only dark",
"colorScheme":
{
"dark": "Campbell",
"light": "One Half Light"
}
}
]
},
"schemes": [
{
"background": "#0C0C0C",
"black": "#0C0C0C",
"blue": "#0037DA",
"brightBlack": "#767676",
"brightBlue": "#3B78FF",
"brightCyan": "#61D6D6",
"brightGreen": "#16C60C",
"brightPurple": "#B4009E",
"brightRed": "#E74856",
"brightWhite": "#F2F2F2",
"brightYellow": "#F9F1A5",
"cursorColor": "#FFFFFF",
"cyan": "#3A96DD",
"foreground": "#CCCCCC",
"green": "#13A10E",
"name": "Campbell",
"purple": "#881798",
"red": "#C50F1F",
"selectionBackground": "#FFFFFF",
"white": "#CCCCCC",
"yellow": "#C19C00"
},
{
"background": "#0C0C0C",
"black": "#0C0C0C",
"blue": "#0037DA",
"brightBlack": "#767676",
"brightBlue": "#3B78FF",
"brightCyan": "#61D6D6",
"brightGreen": "#16C60C",
"brightPurple": "#B4009E",
"brightRed": "#E74856",
"brightWhite": "#F2F2F2",
"brightYellow": "#F9F1A5",
"cursorColor": "#FFFFFF",
"cyan": "#3A96DD",
"foreground": "#CCCCCC",
"green": "#13A10E",
"name": "Campbell (renamed)",
"purple": "#881798",
"red": "#C50F1F",
"selectionBackground": "#FFFFFF",
"white": "#CCCCCC",
"yellow": "#C19C00"
},
{
"background": "#282C34",
"black": "#282C34",
"blue": "#61AFEF",
"brightBlack": "#5A6374",
"brightBlue": "#61AFEF",
"brightCyan": "#56B6C2",
"brightGreen": "#98C379",
"brightPurple": "#C678DD",
"brightRed": "#E06C75",
"brightWhite": "#DCDFE4",
"brightYellow": "#E5C07B",
"cursorColor": "#FFFFFF",
"cyan": "#56B6C2",
"foreground": "#DCDFE4",
"green": "#98C379",
"name": "One Half Dark",
"purple": "#C678DD",
"red": "#E06C75",
"selectionBackground": "#FFFFFF",
"white": "#DCDFE4",
"yellow": "#E5C07B"
},
{
"name": "One Half Light",
"foreground": "#383A42",
"background": "#FAFAFA",
"cursorColor": "#4F525D",
"black": "#383A42",
"red": "#E45649",
"green": "#50A14F",
"yellow": "#C18301",
"blue": "#0184BC",
"purple": "#A626A4",
"cyan": "#0997B3",
"white": "#FAFAFA",
"brightBlack": "#4F525D",
"brightRed": "#DF6C75",
"brightGreen": "#98C379",
"brightYellow": "#E4C07A",
"brightBlue": "#61AFEF",
"brightPurple": "#C577DD",
"brightCyan": "#56B5C1",
"brightWhite": "#FFFFFF"
}
]
})json" };
const auto settings{ winrt::make_self<CascadiaSettings>(settingsString) };
const auto newName{ L"Campbell (renamed)" };
settings->UpdateColorSchemeReferences(L"Campbell", newName);
VERIFY_ARE_EQUAL(newName, settings->ProfileDefaults().DefaultAppearance().DarkColorSchemeName());
VERIFY_ARE_EQUAL(newName, settings->ProfileDefaults().DefaultAppearance().LightColorSchemeName());
VERIFY_IS_TRUE(settings->ProfileDefaults().DefaultAppearance().HasDarkColorSchemeName());
VERIFY_IS_TRUE(settings->ProfileDefaults().DefaultAppearance().HasLightColorSchemeName());
const auto& profiles{ settings->AllProfiles() };
{
const auto& prof{ profiles.GetAt(0) };
VERIFY_ARE_EQUAL(newName, prof.DefaultAppearance().DarkColorSchemeName());
VERIFY_IS_TRUE(prof.DefaultAppearance().HasDarkColorSchemeName());
VERIFY_ARE_EQUAL(newName, prof.DefaultAppearance().LightColorSchemeName());
VERIFY_IS_TRUE(prof.DefaultAppearance().HasLightColorSchemeName());
}
{
const auto& prof{ profiles.GetAt(1) };
VERIFY_ARE_EQUAL(newName, prof.DefaultAppearance().DarkColorSchemeName());
VERIFY_IS_TRUE(prof.DefaultAppearance().HasDarkColorSchemeName());
VERIFY_ARE_EQUAL(newName, prof.DefaultAppearance().LightColorSchemeName());
VERIFY_IS_TRUE(prof.DefaultAppearance().HasLightColorSchemeName());
}
{
const auto& prof{ profiles.GetAt(2) };
VERIFY_ARE_EQUAL(newName, prof.DefaultAppearance().DarkColorSchemeName());
VERIFY_IS_FALSE(prof.DefaultAppearance().HasDarkColorSchemeName());
VERIFY_ARE_EQUAL(newName, prof.DefaultAppearance().LightColorSchemeName());
VERIFY_IS_FALSE(prof.DefaultAppearance().HasLightColorSchemeName());
}
{
const auto& prof{ profiles.GetAt(3) };
VERIFY_ARE_EQUAL(L"One Half Dark", prof.DefaultAppearance().DarkColorSchemeName());
VERIFY_IS_TRUE(prof.DefaultAppearance().HasDarkColorSchemeName());
VERIFY_ARE_EQUAL(L"One Half Dark", prof.DefaultAppearance().LightColorSchemeName());
VERIFY_IS_TRUE(prof.DefaultAppearance().HasLightColorSchemeName());
}
{
const auto& prof{ profiles.GetAt(4) };
VERIFY_ARE_EQUAL(L"One Half Dark", prof.DefaultAppearance().DarkColorSchemeName());
VERIFY_ARE_EQUAL(L"One Half Light", prof.DefaultAppearance().LightColorSchemeName());
VERIFY_IS_TRUE(prof.DefaultAppearance().HasDarkColorSchemeName());
VERIFY_IS_TRUE(prof.DefaultAppearance().HasLightColorSchemeName());
}
{
const auto& prof{ profiles.GetAt(5) };
VERIFY_ARE_EQUAL(L"One Half Dark", prof.DefaultAppearance().DarkColorSchemeName());
VERIFY_ARE_EQUAL(newName, prof.DefaultAppearance().LightColorSchemeName());
VERIFY_IS_TRUE(prof.DefaultAppearance().HasDarkColorSchemeName());
VERIFY_IS_TRUE(prof.DefaultAppearance().HasLightColorSchemeName());
}
{
const auto& prof{ profiles.GetAt(6) };
VERIFY_ARE_EQUAL(newName, prof.DefaultAppearance().DarkColorSchemeName());
VERIFY_ARE_EQUAL(L"One Half Light", prof.DefaultAppearance().LightColorSchemeName());
VERIFY_IS_TRUE(prof.DefaultAppearance().HasDarkColorSchemeName());
VERIFY_IS_TRUE(prof.DefaultAppearance().HasLightColorSchemeName());
}
}
}

View File

@@ -4,7 +4,7 @@
#include "pch.h"
#include "../TerminalApp/TerminalPage.h"
#include "../LocalTests_SettingsModel/TestUtils.h"
#include "../UnitTests_SettingsModel/TestUtils.h"
using namespace Microsoft::Console;
using namespace WEX::Logging;

View File

@@ -133,7 +133,6 @@
<ItemGroup>
<TestDll Include="$(OpenConsoleCommonOutDir)\LocalTests_TerminalApp\TerminalApp.LocalTests.dll" />
<TestDll Include="$(OpenConsoleCommonOutDir)\LocalTests_SettingsModel\SettingsModel.LocalTests.dll" />
</ItemGroup>
<Target Name="AfterBuild" Inputs="@(TestDll)" Outputs="@(TestDll->'$(TargetDir)'\%(Filename)%(Extension)')">

View File

@@ -0,0 +1,5 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "GetWindowLayoutArgs.h"
#include "GetWindowLayoutArgs.g.cpp"

View File

@@ -0,0 +1,31 @@
/*++
Copyright (c) Microsoft Corporation
Licensed under the MIT license.
Class Name:
- GetWindowLayoutArgs.h
Abstract:
- This is a helper class for getting the window layout from a peasant.
Depending on if we are running on the monarch or on a peasant we might need
to switch what thread we are executing on. This gives us the option of
either returning the json result synchronously, or as a promise.
--*/
#pragma once
#include "GetWindowLayoutArgs.g.h"
namespace winrt::Microsoft::Terminal::Remoting::implementation
{
struct GetWindowLayoutArgs : public GetWindowLayoutArgsT<GetWindowLayoutArgs>
{
WINRT_PROPERTY(winrt::hstring, WindowLayoutJson, L"");
WINRT_PROPERTY(winrt::Windows::Foundation::IAsyncOperation<winrt::hstring>, WindowLayoutJsonAsync, nullptr)
};
}
namespace winrt::Microsoft::Terminal::Remoting::factory_implementation
{
BASIC_FACTORY(GetWindowLayoutArgs);
}

View File

@@ -37,6 +37,12 @@
<ClInclude Include="WindowActivatedArgs.h">
<DependentUpon>Peasant.idl</DependentUpon>
</ClInclude>
<ClInclude Include="GetWindowLayoutArgs.h">
<DependentUpon>Peasant.idl</DependentUpon>
</ClInclude>
<ClInclude Include="QuitAllRequestedArgs.h">
<DependentUpon>Monarch.idl</DependentUpon>
</ClInclude>
<ClInclude Include="pch.h" />
<ClInclude Include="MonarchFactory.h" />
<ClInclude Include="Peasant.h">
@@ -72,6 +78,12 @@
<ClCompile Include="WindowActivatedArgs.cpp">
<DependentUpon>Peasant.idl</DependentUpon>
</ClCompile>
<ClCompile Include="GetWindowLayoutArgs.cpp">
<DependentUpon>Peasant.idl</DependentUpon>
</ClCompile>
<ClCompile Include="QuitAllRequestedArgs.cpp">
<DependentUpon>Monarch.idl</DependentUpon>
</ClCompile>
<ClCompile Include="pch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>

View File

@@ -6,6 +6,7 @@
#include "Monarch.h"
#include "CommandlineArgs.h"
#include "FindTargetWindowArgs.h"
#include "QuitAllRequestedArgs.h"
#include "ProposeCommandlineResult.h"
#include "Monarch.g.cpp"
@@ -134,13 +135,21 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
// - <none> used
// Return Value:
// - <none>
void Monarch::_handleQuitAll(const winrt::Windows::Foundation::IInspectable& /*sender*/, const winrt::Windows::Foundation::IInspectable& /*args*/)
winrt::fire_and_forget Monarch::_handleQuitAll(const winrt::Windows::Foundation::IInspectable& /*sender*/,
const winrt::Windows::Foundation::IInspectable& /*args*/)
{
if (_quitting.exchange(true, std::memory_order_relaxed))
// Let the process hosting the monarch run any needed logic before
// closing all windows.
auto args = winrt::make_self<implementation::QuitAllRequestedArgs>();
_QuitAllRequestedHandlers(*this, *args);
if (const auto action = args->BeforeQuitAllAction())
{
return;
co_await action;
}
_quitting.store(true);
// Tell all peasants to exit.
const auto callback = [&](const auto& id, const auto& p) {
// We want to tell our peasant to quit last, so that we don't try
// to perform a bunch of elections on quit.
@@ -188,7 +197,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
// If we are quitting we don't care about maintaining our list of
// peasants anymore, and don't need to notify the host that something
// changed.
if (_quitting.load(std::memory_order_relaxed))
if (_quitting.load(std::memory_order_acquire))
{
return;
}
@@ -1027,6 +1036,30 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
_forEachPeasant(func, onError);
}
// Method Description:
// - Ask all peasants to return their window layout as json
// Arguments:
// - <none>
// Return Value:
// - The collection of window layouts from each peasant.
Windows::Foundation::Collections::IVector<winrt::hstring> Monarch::GetAllWindowLayouts()
{
std::vector<winrt::hstring> vec;
auto callback = [&](const auto& /*id*/, const auto& p) {
vec.emplace_back(p.GetWindowLayout());
};
auto onError = [](auto&& id) {
TraceLoggingWrite(g_hRemotingProvider,
"Monarch_GetAllWindowLayouts_Failed",
TraceLoggingInt64(id, "peasantID", "The ID of the peasant which we could not get a window layout from"),
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE),
TraceLoggingKeyword(TIL_KEYWORD_TRACE));
};
_forEachPeasant(callback, onError);
return winrt::single_threaded_vector(std::move(vec));
}
void Monarch::RequestMoveContent(winrt::hstring window,
winrt::hstring content,
uint32_t tabIndex,

View File

@@ -96,6 +96,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
void SummonAllWindows();
bool DoesQuakeWindowExist();
Windows::Foundation::Collections::IVectorView<winrt::Microsoft::Terminal::Remoting::PeasantInfo> GetPeasantInfos();
Windows::Foundation::Collections::IVector<winrt::hstring> GetAllWindowLayouts();
void RequestMoveContent(winrt::hstring window, winrt::hstring content, uint32_t tabIndex, const Windows::Foundation::IReference<Windows::Foundation::Rect>& windowBounds);
void RequestSendContent(const Remoting::RequestReceiveContentArgs& args);
@@ -105,6 +106,8 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
TYPED_EVENT(HideNotificationIconRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
TYPED_EVENT(WindowCreated, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
TYPED_EVENT(WindowClosed, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
TYPED_EVENT(QuitAllRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::QuitAllRequestedArgs);
TYPED_EVENT(RequestNewWindow, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::WindowRequestedArgs);
private:
@@ -143,8 +146,8 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
void _renameRequested(const winrt::Windows::Foundation::IInspectable& sender,
const winrt::Microsoft::Terminal::Remoting::RenameRequestArgs& args);
void _handleQuitAll(const winrt::Windows::Foundation::IInspectable& sender,
const winrt::Windows::Foundation::IInspectable& args);
winrt::fire_and_forget _handleQuitAll(const winrt::Windows::Foundation::IInspectable& sender,
const winrt::Windows::Foundation::IInspectable& args);
// Method Description:
// - Helper for doing something on each and every peasant.

View File

@@ -46,6 +46,11 @@ namespace Microsoft.Terminal.Remoting
Windows.Foundation.IReference<UInt64> WindowID;
}
[default_interface] runtimeclass QuitAllRequestedArgs {
QuitAllRequestedArgs();
Windows.Foundation.IAsyncAction BeforeQuitAllAction;
}
struct PeasantInfo
{
UInt64 Id;
@@ -67,6 +72,7 @@ namespace Microsoft.Terminal.Remoting
void SummonAllWindows();
Boolean DoesQuakeWindowExist();
Windows.Foundation.Collections.IVectorView<PeasantInfo> GetPeasantInfos { get; };
Windows.Foundation.Collections.IVector<String> GetAllWindowLayouts();
void RequestMoveContent(String window, String content, UInt32 tabIndex, Windows.Foundation.IReference<Windows.Foundation.Rect> bounds);
void RequestSendContent(RequestReceiveContentArgs args);
@@ -76,6 +82,7 @@ namespace Microsoft.Terminal.Remoting
event Windows.Foundation.TypedEventHandler<Object, Object> HideNotificationIconRequested;
event Windows.Foundation.TypedEventHandler<Object, Object> WindowCreated;
event Windows.Foundation.TypedEventHandler<Object, Object> WindowClosed;
event Windows.Foundation.TypedEventHandler<Object, QuitAllRequestedArgs> QuitAllRequested;
event Windows.Foundation.TypedEventHandler<Object, WindowRequestedArgs> RequestNewWindow;
};

View File

@@ -5,6 +5,7 @@
#include "Peasant.h"
#include "CommandlineArgs.h"
#include "SummonWindowBehavior.h"
#include "GetWindowLayoutArgs.h"
#include "Peasant.g.cpp"
#include "../../types/inc/utils.hpp"
#include "AttachRequest.g.cpp"
@@ -308,6 +309,26 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
TraceLoggingKeyword(TIL_KEYWORD_TRACE));
}
// Method Description:
// - Request and return the window layout from the current TerminalPage
// Arguments:
// - <none>
// Return Value:
// - the window layout as a json string
hstring Peasant::GetWindowLayout()
{
auto args = winrt::make_self<implementation::GetWindowLayoutArgs>();
_GetWindowLayoutRequestedHandlers(nullptr, *args);
if (const auto op = args->WindowLayoutJsonAsync())
{
// This will fail if called on the UI thread, so the monarch should
// never set WindowLayoutJsonAsync.
auto str = op.get();
return str;
}
return args->WindowLayoutJson();
}
void Peasant::SendContent(const Remoting::RequestReceiveContentArgs& args)
{
_SendContentRequestedHandlers(*this, args);

View File

@@ -65,6 +65,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
winrt::Microsoft::Terminal::Remoting::CommandlineArgs InitialArgs();
winrt::hstring GetWindowLayout();
void SendContent(const winrt::Microsoft::Terminal::Remoting::RequestReceiveContentArgs& args);
WINRT_PROPERTY(winrt::hstring, WindowName);
@@ -81,6 +82,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
TYPED_EVENT(HideNotificationIconRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
TYPED_EVENT(QuitAllRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
TYPED_EVENT(QuitRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
TYPED_EVENT(GetWindowLayoutRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::GetWindowLayoutArgs);
TYPED_EVENT(AttachRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::AttachRequest);
TYPED_EVENT(SendContentRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::RequestReceiveContentArgs);

View File

@@ -32,6 +32,12 @@ namespace Microsoft.Terminal.Remoting
Windows.Foundation.DateTime ActivatedTime { get; };
};
[default_interface] runtimeclass GetWindowLayoutArgs {
GetWindowLayoutArgs();
String WindowLayoutJson;
Windows.Foundation.IAsyncOperation<String> WindowLayoutJsonAsync;
}
enum MonitorBehavior
{
InPlace,
@@ -82,6 +88,7 @@ namespace Microsoft.Terminal.Remoting
void RequestHideNotificationIcon();
void RequestQuitAll();
void Quit();
String GetWindowLayout();
void AttachContentToWindow(AttachRequest request);
void SendContent(RequestReceiveContentArgs args);
@@ -95,6 +102,7 @@ namespace Microsoft.Terminal.Remoting
event Windows.Foundation.TypedEventHandler<Object, Object> ShowNotificationIconRequested;
event Windows.Foundation.TypedEventHandler<Object, Object> HideNotificationIconRequested;
event Windows.Foundation.TypedEventHandler<Object, GetWindowLayoutArgs> GetWindowLayoutRequested;
event Windows.Foundation.TypedEventHandler<Object, Object> QuitAllRequested;
event Windows.Foundation.TypedEventHandler<Object, Object> QuitRequested;

View File

@@ -0,0 +1,5 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "QuitAllRequestedArgs.h"
#include "QuitAllRequestedArgs.g.cpp"

View File

@@ -0,0 +1,29 @@
/*++
Copyright (c) Microsoft Corporation
Licensed under the MIT license.
Class Name:
- QuitAllRequestedArgs.h
Abstract:
- This is a helper class for allowing the monarch to run code before telling all
peasants to quit. This way the monarch can raise an event and get back a future
to wait for before continuing.
--*/
#pragma once
#include "QuitAllRequestedArgs.g.h"
namespace winrt::Microsoft::Terminal::Remoting::implementation
{
struct QuitAllRequestedArgs : public QuitAllRequestedArgsT<QuitAllRequestedArgs>
{
WINRT_PROPERTY(winrt::Windows::Foundation::IAsyncAction, BeforeQuitAllAction, nullptr)
};
}
namespace winrt::Microsoft::Terminal::Remoting::factory_implementation
{
BASIC_FACTORY(QuitAllRequestedArgs);
}

View File

@@ -92,6 +92,8 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
_monarch.WindowCreated({ get_weak(), &WindowManager::_WindowCreatedHandlers });
_monarch.WindowClosed({ get_weak(), &WindowManager::_WindowClosedHandlers });
_monarch.FindTargetWindowRequested({ this, &WindowManager::_raiseFindTargetWindowRequested });
_monarch.QuitAllRequested({ get_weak(), &WindowManager::_QuitAllRequestedHandlers });
_monarch.RequestNewWindow({ get_weak(), &WindowManager::_raiseRequestNewWindow });
}
@@ -354,6 +356,8 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
_monarch.AddPeasant(*p);
p->GetWindowLayoutRequested({ get_weak(), &WindowManager::_GetWindowLayoutRequestedHandlers });
TraceLoggingWrite(g_hRemotingProvider,
"WindowManager_CreateOurPeasant",
TraceLoggingUInt64(p->GetID(), "peasantID", "The ID of our new peasant"),
@@ -408,6 +412,18 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
return 0;
}
// Method Description:
// - Ask the monarch to quit all windows.
// Arguments:
// - <none>
// Return Value:
// - <none>
winrt::fire_and_forget WindowManager::RequestQuitAll(Remoting::Peasant peasant)
{
co_await winrt::resume_background();
peasant.RequestQuitAll();
}
bool WindowManager::DoesQuakeWindowExist()
{
return _monarch.DoesQuakeWindowExist();
@@ -418,6 +434,19 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
winrt::get_self<implementation::Peasant>(peasant)->ActiveTabTitle(title);
}
Windows::Foundation::Collections::IVector<winrt::hstring> WindowManager::GetAllWindowLayouts()
{
if (_monarch)
{
try
{
return _monarch.GetAllWindowLayouts();
}
CATCH_LOG()
}
return nullptr;
}
winrt::fire_and_forget WindowManager::RequestMoveContent(winrt::hstring window,
winrt::hstring content,
uint32_t tabIndex,

View File

@@ -38,8 +38,10 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
uint64_t GetNumberOfPeasants();
static winrt::fire_and_forget RequestQuitAll(Remoting::Peasant peasant);
void UpdateActiveTabTitle(const winrt::hstring& title, const Remoting::Peasant& peasant);
Windows::Foundation::Collections::IVector<winrt::hstring> GetAllWindowLayouts();
bool DoesQuakeWindowExist();
winrt::fire_and_forget RequestMoveContent(winrt::hstring window, winrt::hstring content, uint32_t tabIndex, Windows::Foundation::IReference<Windows::Foundation::Rect> windowBounds);
@@ -49,6 +51,9 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
TYPED_EVENT(WindowCreated, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
TYPED_EVENT(WindowClosed, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
TYPED_EVENT(QuitAllRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::QuitAllRequestedArgs);
TYPED_EVENT(GetWindowLayoutRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::GetWindowLayoutArgs);
TYPED_EVENT(RequestNewWindow, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::WindowRequestedArgs);
private:

View File

@@ -14,10 +14,12 @@ namespace Microsoft.Terminal.Remoting
void SignalClose(Peasant p);
void UpdateActiveTabTitle(String title, Peasant p);
static void RequestQuitAll(Peasant p);
void SummonWindow(SummonWindowSelectionArgs args);
void SummonAllWindows();
Windows.Foundation.Collections.IVector<String> GetAllWindowLayouts();
Windows.Foundation.Collections.IVectorView<PeasantInfo> GetPeasantInfos();
UInt64 GetNumberOfPeasants();
@@ -31,6 +33,8 @@ namespace Microsoft.Terminal.Remoting
event Windows.Foundation.TypedEventHandler<Object, Object> WindowCreated;
event Windows.Foundation.TypedEventHandler<Object, Object> WindowClosed;
event Windows.Foundation.TypedEventHandler<Object, QuitAllRequestedArgs> QuitAllRequested;
event Windows.Foundation.TypedEventHandler<Object, GetWindowLayoutArgs> GetWindowLayoutRequested;
event Windows.Foundation.TypedEventHandler<Object, WindowRequestedArgs> RequestNewWindow;

View File

@@ -697,6 +697,22 @@ namespace winrt::TerminalApp::implementation
return _settings.GlobalSettings().ShouldUsePersistedLayout();
}
void AppLogic::SaveWindowLayoutJsons(const Windows::Foundation::Collections::IVector<hstring>& layouts)
{
std::vector<WindowLayout> converted;
converted.reserve(layouts.Size());
for (const auto& json : layouts)
{
if (json != L"")
{
converted.emplace_back(WindowLayout::FromJson(json));
}
}
ApplicationState::SharedInstance().PersistedWindowLayouts(winrt::single_threaded_vector(std::move(converted)));
}
TerminalApp::ParseCommandlineResult AppLogic::GetParseCommandlineMessage(array_view<const winrt::hstring> args)
{
::TerminalApp::AppCommandlineArgs _appArgs;

View File

@@ -53,7 +53,9 @@ namespace winrt::TerminalApp::implementation
void NotifyRootInitialized();
bool HasSettingsStartupActions() const noexcept;
bool ShouldUsePersistedLayout() const;
void SaveWindowLayoutJsons(const Windows::Foundation::Collections::IVector<hstring>& layouts);
[[nodiscard]] Microsoft::Terminal::Settings::Model::CascadiaSettings GetSettings() const noexcept;

View File

@@ -37,6 +37,7 @@ namespace TerminalApp
Boolean HasSettingsStartupActions();
Boolean ShouldUsePersistedLayout();
void SaveWindowLayoutJsons(Windows.Foundation.Collections.IVector<String> layouts);
void ReloadSettings();

View File

@@ -843,16 +843,6 @@ namespace winrt::TerminalApp::implementation
void CommandPalette::_filterTextChanged(const IInspectable& /*sender*/,
const Windows::UI::Xaml::RoutedEventArgs& /*args*/)
{
// When we are executing the _SelectNextTab in the TabManagement.cpp, this method
// is getting triggered because we set up the default value for that CommandPalette
// with an empty string. Therefore, to avoid the reset of the index when executing
// the Next/Prev tab command, we are skipping this execution.
// Check issue https://github.com/microsoft/terminal/issues/11146
if (_currentMode == CommandPaletteMode::TabSwitchMode)
{
return;
}
if (_currentMode == CommandPaletteMode::CommandlineMode)
{
_evaluatePrefix();

View File

@@ -2,13 +2,12 @@
// Licensed under the MIT license.
import "TabBase.idl";
import "IDirectKeyListener.idl";
import "HighlightedTextControl.idl";
import "FilteredCommand.idl";
namespace TerminalApp
{
[default_interface] runtimeclass CommandPalette : Windows.UI.Xaml.Controls.UserControl, Windows.UI.Xaml.Data.INotifyPropertyChanged, IDirectKeyListener
[default_interface] runtimeclass CommandPalette : Windows.UI.Xaml.Controls.UserControl, Windows.UI.Xaml.Data.INotifyPropertyChanged, Microsoft.Terminal.UI.IDirectKeyListener
{
CommandPalette();

View File

@@ -9,7 +9,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:TerminalApp"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:model="using:Microsoft.Terminal.Settings.Model"
xmlns:mtu="using:Microsoft.Terminal.UI"
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
AllowFocusOnInteraction="True"
AutomationProperties.Name="{x:Bind ControlName, Mode=OneWay}"
@@ -23,12 +23,6 @@
<UserControl.Resources>
<ResourceDictionary>
<!-- This creates an instance of our CommandKeyChordVisibilityConverter we can reference below -->
<local:EmptyStringVisibilityConverter x:Key="CommandKeyChordVisibilityConverter" />
<local:EmptyStringVisibilityConverter x:Key="ParsedCommandLineTextVisibilityConverter" />
<local:EmptyStringVisibilityConverter x:Key="ParentCommandVisibilityConverter" />
<model:IconPathConverter x:Key="IconSourceConverter" />
<DataTemplate x:Key="ListItemTemplate"
x:DataType="local:FilteredCommand">
<ListViewItem HorizontalContentAlignment="Stretch"
@@ -62,8 +56,7 @@
<!--
The block for the key chord is only visible
when there's actual text set as the label. See
CommandKeyChordVisibilityConverter for details.
when there's actual text set as the label.
We're setting the accessibility view on the
border and text block to Raw because otherwise,
Narrator will read out the key chord. Problem is,
@@ -77,7 +70,7 @@
AutomationProperties.AccessibilityView="Raw"
Background="{ThemeResource FlyoutPresenterBackground}"
Style="{ThemeResource KeyChordBorderStyle}"
Visibility="{x:Bind Item.KeyChordText, Mode=OneWay, Converter={StaticResource CommandKeyChordVisibilityConverter}}">
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(Item.KeyChordText), Mode=OneWay}">
<TextBlock AutomationProperties.AccessibilityView="Raw"
FontSize="12"
@@ -113,8 +106,7 @@
<!--
The block for the key chord is only visible
when there's actual text set as the label. See
CommandKeyChordVisibilityConverter for details.
when there's actual text set as the label.
We're setting the accessibility view on the
border and text block to Raw because otherwise,
Narrator will read out the key chord. Problem is,
@@ -127,7 +119,7 @@
VerticalAlignment="Center"
AutomationProperties.AccessibilityView="Raw"
Style="{ThemeResource KeyChordBorderStyle}"
Visibility="{x:Bind Item.KeyChordText, Mode=OneWay, Converter={StaticResource CommandKeyChordVisibilityConverter}}">
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(Item.KeyChordText), Mode=OneWay}">
<TextBlock AutomationProperties.AccessibilityView="Raw"
FontSize="12"
@@ -347,12 +339,12 @@
VerticalAlignment="Center"
FontSize="14"
Text="{x:Bind PrefixCharacter, Mode=OneWay}"
Visibility="{x:Bind PrefixCharacter, Mode=OneWay, Converter={StaticResource ParentCommandVisibilityConverter}}" />
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(PrefixCharacter), Mode=OneWay}" />
<StackPanel Grid.Row="1"
Margin="8,0,8,8"
Orientation="Horizontal"
Visibility="{x:Bind ParentCommandName, Mode=OneWay, Converter={StaticResource ParentCommandVisibilityConverter}}">
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(ParentCommandName), Mode=OneWay}">
<Button x:Name="_parentCommandBackButton"
x:Uid="ParentCommandBackButton"
@@ -377,7 +369,7 @@
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Style="{ThemeResource ParsedCommandLineBorderStyle}"
Visibility="{x:Bind ParsedCommandLineText, Mode=OneWay, Converter={StaticResource ParsedCommandLineTextVisibilityConverter}}">
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(ParsedCommandLineText), Mode=OneWay}">
<ScrollViewer MaxHeight="200"
VerticalScrollBarVisibility="Auto">

View File

@@ -50,6 +50,7 @@ namespace winrt::Microsoft::TerminalApp::implementation
void TerminalOutput(const winrt::event_token& token) noexcept { _wrappedConnection.TerminalOutput(token); };
winrt::event_token StateChanged(const TypedEventHandler<ITerminalConnection, IInspectable>& handler) { return _wrappedConnection.StateChanged(handler); };
void StateChanged(const winrt::event_token& token) noexcept { _wrappedConnection.StateChanged(token); };
winrt::guid SessionId() const noexcept { return {}; }
ConnectionState State() const noexcept { return _wrappedConnection.State(); }
private:
@@ -98,6 +99,15 @@ namespace winrt::Microsoft::TerminalApp::implementation
_wrappedConnection = nullptr;
}
guid DebugTapConnection::SessionId() const noexcept
{
if (const auto c = _wrappedConnection.get())
{
return c.SessionId();
}
return {};
}
ConnectionState DebugTapConnection::State() const noexcept
{
if (auto strongConnection{ _wrappedConnection.get() })

View File

@@ -19,6 +19,8 @@ namespace winrt::Microsoft::TerminalApp::implementation
void WriteInput(const hstring& data);
void Resize(uint32_t rows, uint32_t columns);
void Close();
winrt::guid SessionId() const noexcept;
winrt::Microsoft::Terminal::TerminalConnection::ConnectionState State() const noexcept;
void SetInputTap(const Microsoft::Terminal::TerminalConnection::ITerminalConnection& inputTap);

View File

@@ -1,38 +0,0 @@
#include "pch.h"
#include "EmptyStringVisibilityConverter.h"
#include "EmptyStringVisibilityConverter.g.cpp"
using namespace winrt::Windows;
using namespace winrt::Windows::UI::Xaml;
namespace winrt::TerminalApp::implementation
{
// Method Description:
// - Attempt to convert something into another type. For the
// EmptyStringVisibilityConverter, we're gonna check if `value` is a
// string, and try and convert it into a Visibility value. If the input
// param wasn't a string, or was the empty string, we'll return
// Visibility::Collapsed. Otherwise, we'll return Visible.
// Arguments:
// - value: the input object to attempt to convert into a Visibility.
// Return Value:
// - Visible if the object was a string and wasn't the empty string.
Foundation::IInspectable EmptyStringVisibilityConverter::Convert(const Foundation::IInspectable& value,
const Windows::UI::Xaml::Interop::TypeName& /* targetType */,
const Foundation::IInspectable& /* parameter */,
const hstring& /* language */)
{
const auto& name = winrt::unbox_value_or<hstring>(value, L"");
return winrt::box_value(name.empty() ? Visibility::Collapsed : Visibility::Visible);
}
// unused for one-way bindings
Foundation::IInspectable EmptyStringVisibilityConverter::ConvertBack(const Foundation::IInspectable& /* value */,
const Windows::UI::Xaml::Interop::TypeName& /* targetType */,
const Foundation::IInspectable& /* parameter */,
const hstring& /* language */)
{
throw hresult_not_implemented();
}
}

View File

@@ -1,26 +0,0 @@
#pragma once
#include "EmptyStringVisibilityConverter.g.h"
namespace winrt::TerminalApp::implementation
{
struct EmptyStringVisibilityConverter : EmptyStringVisibilityConverterT<EmptyStringVisibilityConverter>
{
EmptyStringVisibilityConverter() = default;
Windows::Foundation::IInspectable Convert(const Windows::Foundation::IInspectable& value,
const Windows::UI::Xaml::Interop::TypeName& targetType,
const Windows::Foundation::IInspectable& parameter,
const hstring& language);
Windows::Foundation::IInspectable ConvertBack(const Windows::Foundation::IInspectable& value,
const Windows::UI::Xaml::Interop::TypeName& targetType,
const Windows::Foundation::IInspectable& parameter,
const hstring& language);
};
}
namespace winrt::TerminalApp::factory_implementation
{
BASIC_FACTORY(EmptyStringVisibilityConverter);
}

View File

@@ -1,19 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace TerminalApp
{
// See https://docs.microsoft.com/en-us/windows/uwp/data-binding/data-binding-quickstart
// We use the default attribute to declare IValueConverter as the default
// interface. In the listing, EmptyStringVisibilityConverter has only a
// constructor, and no methods, so no default interface is generated for it.
// The default attribute is optimal if you won't be adding instance members
// to EmptyStringVisibilityConverter, because no QueryInterface will be
// required to call the IValueConverter methods
runtimeclass EmptyStringVisibilityConverter : [default] Windows.UI.Xaml.Data.IValueConverter
{
EmptyStringVisibilityConverter();
};
}

View File

@@ -1,14 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace TerminalApp
{
// C++/winrt makes it difficult to share this idl between two projects,
// Instead, we just pin the uuid and include it in both TermControl and App
// If you update this one, please update the one in TerminalControl\TermControl.idl
// If you change this interface, please update the guid.
// If you press F7 or Alt and get a runtime error, go make sure both copies are the same.
[uuid("0ddf4edc-3fda-4dee-97ca-a417ee3dd510")] interface IDirectKeyListener {
Boolean OnDirectKeyEvent(UInt32 vkey, UInt8 scanCode, Boolean down);
}
}

View File

@@ -17,7 +17,7 @@ namespace winrt::TerminalApp::implementation
{
Controls::IconElement PaletteItem::ResolvedIcon()
{
const auto icon = IconPathConverter::IconWUX(Icon());
const auto icon = Microsoft::Terminal::UI::IconPathConverter::IconWUX(Icon());
icon.Width(16);
icon.Height(16);
return icon;

View File

@@ -19,7 +19,7 @@ using namespace winrt::Microsoft::Terminal::Settings::Model;
using namespace winrt::Microsoft::Terminal::Control;
using namespace winrt::Microsoft::Terminal::TerminalConnection;
using namespace winrt::TerminalApp;
using namespace winrt::TerminalApp::implementation;
using namespace TerminalApp;
static const int PaneBorderSize = 2;
static const int CombinedPaneBorderSize = 2 * PaneBorderSize;
@@ -124,7 +124,7 @@ void Pane::_removeControlEvents()
// terminal args.
// Return Value:
// - Arguments appropriate for a SplitPane or NewTab action
NewTerminalArgs Pane::GetTerminalArgsForPane(BuildStartupKind kind) const
NewTerminalArgs Pane::GetTerminalArgsForPane(const bool asContent) const
{
// Leaves are the only things that have controls
assert(_IsLeaf());
@@ -169,17 +169,12 @@ NewTerminalArgs Pane::GetTerminalArgsForPane(BuildStartupKind kind) const
// object. That would work for schemes set by the Terminal, but not ones set
// by VT, but that seems good enough.
switch (kind)
// Only fill in the ContentId if absolutely needed. If you fill in a number
// here (even 0), we'll serialize that number, AND treat that action as an
// "attach existing" rather than a "create"
if (asContent)
{
case BuildStartupKind::Content:
case BuildStartupKind::MovePane:
// Only fill in the ContentId if absolutely needed. If you fill in a number
// here (even 0), we'll serialize that number, AND treat that action as an
// "attach existing" rather than a "create"
args.ContentId(_control.ContentId());
break;
default:
break;
}
return args;
@@ -205,13 +200,16 @@ NewTerminalArgs Pane::GetTerminalArgsForPane(BuildStartupKind kind) const
// - The state from building the startup actions, includes a vector of commands,
// the original root pane, the id of the focused pane, and the number of panes
// created.
Pane::BuildStartupState Pane::BuildStartupActions(uint32_t currentId, uint32_t nextId, BuildStartupKind kind)
Pane::BuildStartupState Pane::BuildStartupActions(uint32_t currentId,
uint32_t nextId,
const bool asContent,
const bool asMovePane)
{
// Normally, if we're a leaf, return an empt set of actions, because the
// parent pane will build the SplitPane action for us. If we're building
// actions for a movePane action though, we'll still need to include
// ourselves.
if (kind != BuildStartupKind::MovePane && _IsLeaf())
if (!asMovePane && _IsLeaf())
{
if (_lastActive)
{
@@ -225,18 +223,18 @@ Pane::BuildStartupState Pane::BuildStartupActions(uint32_t currentId, uint32_t n
auto buildSplitPane = [&](auto newPane) {
ActionAndArgs actionAndArgs;
actionAndArgs.Action(ShortcutAction::SplitPane);
const auto terminalArgs{ newPane->GetTerminalArgsForPane(kind) };
const auto terminalArgs{ newPane->GetTerminalArgsForPane(asContent) };
// When creating a pane the split size is the size of the new pane
// and not position.
const auto splitDirection = _splitState == SplitState::Horizontal ? SplitDirection::Down : SplitDirection::Right;
const auto splitSize = (kind != BuildStartupKind::None && _IsLeaf() ? .5 : 1. - _desiredSplitPosition);
const auto splitSize = (asContent && _IsLeaf() ? .5 : 1. - _desiredSplitPosition);
SplitPaneArgs args{ SplitType::Manual, splitDirection, splitSize, terminalArgs };
actionAndArgs.Args(args);
return actionAndArgs;
};
if (kind != BuildStartupKind::None && _IsLeaf())
if (asContent && _IsLeaf())
{
return {
.args = { buildSplitPane(shared_from_this()) },
@@ -283,10 +281,10 @@ Pane::BuildStartupState Pane::BuildStartupActions(uint32_t currentId, uint32_t n
// We now need to execute the commands for each side of the tree
// We've done one split, so the first-most child will have currentId, and the
// one after it will be incremented.
auto firstState = _firstChild->BuildStartupActions(currentId, nextId + 1, kind);
auto firstState = _firstChild->BuildStartupActions(currentId, nextId + 1);
// the next id for the second branch depends on how many splits were in the
// first child.
auto secondState = _secondChild->BuildStartupActions(nextId, nextId + firstState.panesCreated + 1, kind);
auto secondState = _secondChild->BuildStartupActions(nextId, nextId + firstState.panesCreated + 1);
std::vector<ActionAndArgs> actions{};
actions.reserve(firstState.args.size() + secondState.args.size() + 3);

View File

@@ -31,7 +31,6 @@ namespace TerminalAppLocalTests
namespace winrt::TerminalApp::implementation
{
struct TerminalTab;
enum class BuildStartupKind;
}
enum class Borders : int
@@ -100,8 +99,8 @@ public:
std::optional<uint32_t> focusedPaneId;
uint32_t panesCreated;
};
BuildStartupState BuildStartupActions(uint32_t currentId, uint32_t nextId, winrt::TerminalApp::implementation::BuildStartupKind kind);
winrt::Microsoft::Terminal::Settings::Model::NewTerminalArgs GetTerminalArgsForPane(winrt::TerminalApp::implementation::BuildStartupKind kind) const;
BuildStartupState BuildStartupActions(uint32_t currentId, uint32_t nextId, const bool asContent = false, const bool asMovePane = false);
winrt::Microsoft::Terminal::Settings::Model::NewTerminalArgs GetTerminalArgsForPane(const bool asContent = false) const;
void UpdateSettings(const winrt::Microsoft::Terminal::Settings::Model::TerminalSettingsCreateResult& settings,
const winrt::Microsoft::Terminal::Settings::Model::Profile& profile);

View File

@@ -193,16 +193,16 @@
<value>Mehrere Bereiche</value>
</data>
<data name="TabCloseSubMenu" xml:space="preserve">
<value>Schließen</value>
<value>Schließen...</value>
</data>
<data name="TabCloseAfter" xml:space="preserve">
<value>Tabs nach rechts schließen</value>
<value>Registerkarten auf der rechten Seite schließen</value>
</data>
<data name="TabCloseOther" xml:space="preserve">
<value>Andere Registerkarten schließen</value>
</data>
<data name="TabClose" xml:space="preserve">
<value>Tab schließen</value>
<value>Registerkarte schließen</value>
</data>
<data name="PaneClose" xml:space="preserve">
<value>Bereich schließen</value>
@@ -211,16 +211,16 @@
<value>Registerkarte teilen</value>
</data>
<data name="SplitPaneText" xml:space="preserve">
<value>Bereich teilen</value>
<value>Geteilter Bereich</value>
</data>
<data name="SearchWebText" xml:space="preserve">
<value>Websuche</value>
</data>
<data name="TabColorChoose" xml:space="preserve">
<value>Registerkartenfarbe ändern</value>
<value>Farbe...</value>
</data>
<data name="TabColorCustomButton.Content" xml:space="preserve">
<value>Benutzerdefiniert</value>
<value>Benutzerdefiniert...</value>
</data>
<data name="TabColorClearButton.Content" xml:space="preserve">
<value>Zurücksetzen</value>
@@ -229,7 +229,7 @@
<value>Registerkarte umbenennen</value>
</data>
<data name="DuplicateTabText" xml:space="preserve">
<value>Registerkarte kopieren</value>
<value>Registerkarte duplizieren</value>
</data>
<data name="InvalidBackgroundImage" xml:space="preserve">
<value>Profil mit einem ungültigen "backgroundImage" gefunden. Dieses Profil hat standardmäßig kein Hintergrundbild. Stellen Sie sicher, dass beim Festlegen eines "backgroundImage" der Wert ein gültiger Dateipfad zu einem Bild ist.</value>
@@ -487,7 +487,7 @@
<comment>A hyperlink name for the Terminal's privacy policy</comment>
</data>
<data name="AboutDialog_ThirdPartyNoticesLink.Content" xml:space="preserve">
<value>Hinweise von Drittanbietern</value>
<value>Drittanbieter-Hinweise</value>
<comment>A hyperlink name for the Terminal's third-party notices</comment>
</data>
<data name="QuitDialog.CloseButtonText" xml:space="preserve">
@@ -761,7 +761,7 @@
<value>Suchen</value>
</data>
<data name="PlainText" xml:space="preserve">
<value>Unformatierter Text</value>
<value>Nur Text</value>
</data>
<data name="CloseOnExitInfoBar.Message" xml:space="preserve">
<value>Das Beendigungsverhalten kann in den erweiterten Profileinstellungen konfiguriert werden.</value>
@@ -837,7 +837,7 @@
<value>Diese Registerkarte schließen</value>
</data>
<data name="NewTabMenuFolderEmpty" xml:space="preserve">
<value>Leer</value>
<value>Leer...</value>
</data>
<data name="ClosePaneText" xml:space="preserve">
<value>Bereich schließen</value>

View File

@@ -194,43 +194,43 @@
<value>Multiple panes</value>
</data>
<data name="TabCloseSubMenu" xml:space="preserve">
<value>Close</value>
<value>Close...</value>
</data>
<data name="TabCloseAfter" xml:space="preserve">
<value>Close tabs to the right</value>
<value>Close Tabs to the Right</value>
</data>
<data name="TabCloseOther" xml:space="preserve">
<value>Close other tabs</value>
<value>Close Other Tabs</value>
</data>
<data name="TabClose" xml:space="preserve">
<value>Close tab</value>
<value>Close Tab</value>
</data>
<data name="PaneClose" xml:space="preserve">
<value>Close pane</value>
<value>Close Pane</value>
</data>
<data name="SplitTabText" xml:space="preserve">
<value>Split tab</value>
<value>Split Tab</value>
</data>
<data name="SplitPaneText" xml:space="preserve">
<value>Split pane</value>
<value>Split Pane</value>
</data>
<data name="SearchWebText" xml:space="preserve">
<value>Web search</value>
<value>Web Search</value>
</data>
<data name="TabColorChoose" xml:space="preserve">
<value>Change tab color</value>
<value>Color...</value>
</data>
<data name="TabColorCustomButton.Content" xml:space="preserve">
<value>Custom</value>
<value>Custom...</value>
</data>
<data name="TabColorClearButton.Content" xml:space="preserve">
<value>Reset</value>
</data>
<data name="RenameTabText" xml:space="preserve">
<value>Rename tab</value>
<value>Rename Tab</value>
</data>
<data name="DuplicateTabText" xml:space="preserve">
<value>Duplicate tab</value>
<value>Duplicate Tab</value>
</data>
<data name="InvalidBackgroundImage" xml:space="preserve">
<value>Found a profile with an invalid "backgroundImage". Defaulting that profile to have no background image. Make sure that when setting a "backgroundImage", the value is a valid file path to an image.</value>
@@ -462,7 +462,7 @@
<value>About</value>
</data>
<data name="AboutDialog.PrimaryButtonText" xml:space="preserve">
<value>Send feedback</value>
<value>Send Feedback</value>
</data>
<data name="AboutDialog.CloseButtonText" xml:space="preserve">
<value>OK</value>
@@ -472,11 +472,11 @@
<comment>This is the heading for a version number label</comment>
</data>
<data name="AboutDialog_GettingStartedLink.Content" xml:space="preserve">
<value>Getting started</value>
<value>Getting Started</value>
<comment>A hyperlink name for a guide on how to get started using Terminal</comment>
</data>
<data name="AboutDialog_SourceCodeLink.Content" xml:space="preserve">
<value>Source code</value>
<value>Source Code</value>
<comment>A hyperlink name for the Terminal's documentation</comment>
</data>
<data name="AboutDialog_DocumentationLink.Content" xml:space="preserve">
@@ -484,15 +484,15 @@
<comment>A hyperlink name for user documentation</comment>
</data>
<data name="AboutDialog_ReleaseNotesLink.Content" xml:space="preserve">
<value>Release notes</value>
<value>Release Notes</value>
<comment>A hyperlink name for the Terminal's release notes</comment>
</data>
<data name="AboutDialog_PrivacyPolicyLink.Content" xml:space="preserve">
<value>Privacy policy</value>
<value>Privacy Policy</value>
<comment>A hyperlink name for the Terminal's privacy policy</comment>
</data>
<data name="AboutDialog_ThirdPartyNoticesLink.Content" xml:space="preserve">
<value>Third-Party notices</value>
<value>Third-Party Notices</value>
<comment>A hyperlink name for the Terminal's third-party notices</comment>
</data>
<data name="QuitDialog.CloseButtonText" xml:space="preserve">
@@ -579,10 +579,10 @@
<value>Failed parsing command line:</value>
</data>
<data name="CommandPaletteControlName" xml:space="preserve">
<value>Command palette</value>
<value>Command Palette</value>
</data>
<data name="TabSwitcherControlName" xml:space="preserve">
<value>Tab switcher</value>
<value>Tab Switcher</value>
</data>
<data name="TabSwitcher_SearchBoxText" xml:space="preserve">
<value>Type a tab name...</value>
@@ -731,10 +731,10 @@
<value>Maximize</value>
</data>
<data name="WindowRestoreDownButtonToolTip" xml:space="preserve">
<value>Restore down</value>
<value>Restore Down</value>
</data>
<data name="CommandPaletteMenuItem" xml:space="preserve">
<value>Command palette</value>
<value>Command Palette</value>
</data>
<data name="NotificationIconFocusTerminal" xml:space="preserve">
<value>Focus Terminal</value>
@@ -754,7 +754,7 @@
<value>Split the window and start in given directory</value>
</data>
<data name="ExportTabText" xml:space="preserve">
<value>Export text</value>
<value>Export Text</value>
</data>
<data name="ExportFailure" xml:space="preserve">
<value>Failed to export terminal content</value>
@@ -766,16 +766,23 @@
<value>Find</value>
</data>
<data name="PlainText" xml:space="preserve">
<value>Plain text</value>
<value>Plain Text</value>
</data>
<data name="CloseOnExitInfoBar.Message" xml:space="preserve">
<value>Termination behavior can be configured in advanced profile settings.</value>
</data>
<data name="SetAsDefaultInfoBar.Message" xml:space="preserve">
<value>Windows Terminal can be set as the default terminal application in your settings.</value>
</data>
<data name="InfoBarDismissButton.Content" xml:space="preserve">
<value>Don't show again</value>
</data>
<data name="ElevationShield.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>This Terminal window is running as administrator</value>
<value>This Terminal window is running as Admin</value>
</data>
<data name="SetAsDefaultTip_OpenSettingsLink.Content" xml:space="preserve">
<value>Open Settings</value>
<comment>This is a call-to-action hyperlink; it will open the settings.</comment>
</data>
<data name="CommandPalette_MatchesAvailable" xml:space="preserve">
<value>Suggestions found: {0}</value>
@@ -835,10 +842,10 @@
<value>Close this tab</value>
</data>
<data name="NewTabMenuFolderEmpty" xml:space="preserve">
<value>Empty</value>
<value>Empty...</value>
</data>
<data name="ClosePaneText" xml:space="preserve">
<value>Close pane</value>
<value>Close Pane</value>
</data>
<data name="ClosePaneToolTip" xml:space="preserve">
<value>Close the active pane if multiple panes are present</value>
@@ -848,13 +855,13 @@
<comment>Text used to identify the reset button</comment>
</data>
<data name="MoveTabToNewWindowText" xml:space="preserve">
<value>Move tab to new window</value>
<value>Move Tab to New Window</value>
</data>
<data name="MoveTabToNewWindowToolTip" xml:space="preserve">
<value>Moves tab to a new window </value>
</data>
<data name="RunAsAdminFlyout.Text" xml:space="preserve">
<value>Run as administrator</value>
<value>Run as Administrator</value>
<comment>This text is displayed on context menu for profile entries in add new tab button.</comment>
</data>
<data name="TerminalPage_PaneMovedAnnouncement_ExistingTab" xml:space="preserve">
@@ -893,7 +900,7 @@
<value>If set, the command will be appended to the profile's default command instead of replacing it.</value>
</data>
<data name="RestartConnectionText" xml:space="preserve">
<value>Restart connection</value>
<value>Restart Connection</value>
</data>
<data name="RestartConnectionToolTip" xml:space="preserve">
<value>Restart the active pane connection</value>

View File

@@ -190,7 +190,7 @@
<value>Varios paneles</value>
</data>
<data name="TabCloseSubMenu" xml:space="preserve">
<value>Cerrar</value>
<value>Cerrar...</value>
</data>
<data name="TabCloseAfter" xml:space="preserve">
<value>Cerrar las pestañas de la derecha</value>
@@ -205,19 +205,19 @@
<value>Cerrar panel</value>
</data>
<data name="SplitTabText" xml:space="preserve">
<value>Dividir pestaña</value>
<value>Dividir tabla</value>
</data>
<data name="SplitPaneText" xml:space="preserve">
<value>Panel dividido</value>
</data>
<data name="SearchWebText" xml:space="preserve">
<value>Búsqueda en la web</value>
<value>Búsqueda en la Web</value>
</data>
<data name="TabColorChoose" xml:space="preserve">
<value>Cambiar color de pestaña</value>
<value>Color...</value>
</data>
<data name="TabColorCustomButton.Content" xml:space="preserve">
<value>Personalizar</value>
<value>Configuración personalizada...</value>
</data>
<data name="TabColorClearButton.Content" xml:space="preserve">
<value>Restablecer</value>
@@ -464,7 +464,7 @@
<comment>This is the heading for a version number label</comment>
</data>
<data name="AboutDialog_GettingStartedLink.Content" xml:space="preserve">
<value>Introducción</value>
<value>Tareas iniciales</value>
<comment>A hyperlink name for a guide on how to get started using Terminal</comment>
</data>
<data name="AboutDialog_SourceCodeLink.Content" xml:space="preserve">
@@ -480,7 +480,7 @@
<comment>A hyperlink name for the Terminal's release notes</comment>
</data>
<data name="AboutDialog_PrivacyPolicyLink.Content" xml:space="preserve">
<value>Política de privacidad</value>
<value>Directiva de privacidad</value>
<comment>A hyperlink name for the Terminal's privacy policy</comment>
</data>
<data name="AboutDialog_ThirdPartyNoticesLink.Content" xml:space="preserve">
@@ -723,7 +723,7 @@
<value>Maximizar</value>
</data>
<data name="WindowRestoreDownButtonToolTip" xml:space="preserve">
<value>Restaurar</value>
<value>Restaurar a tamaño normal</value>
</data>
<data name="CommandPaletteMenuItem" xml:space="preserve">
<value>Paleta de comandos</value>
@@ -834,7 +834,7 @@
<value>Cerrar esta pestaña</value>
</data>
<data name="NewTabMenuFolderEmpty" xml:space="preserve">
<value>Vacío</value>
<value>Vacío...</value>
</data>
<data name="ClosePaneText" xml:space="preserve">
<value>Cerrar panel</value>
@@ -847,7 +847,7 @@
<comment>Text used to identify the reset button</comment>
</data>
<data name="MoveTabToNewWindowText" xml:space="preserve">
<value>Mover pestaña a nueva ventana</value>
<value>Mover la Pestaña a una Nueva ventana</value>
</data>
<data name="MoveTabToNewWindowToolTip" xml:space="preserve">
<value>Mueve la pestaña a una nueva ventana </value>

View File

@@ -190,13 +190,13 @@
<value>Volets multiples</value>
</data>
<data name="TabCloseSubMenu" xml:space="preserve">
<value>Fermer</value>
<value>Fermez...</value>
</data>
<data name="TabCloseAfter" xml:space="preserve">
<value>Fermer les onglets à droite</value>
<value>Fermer les Onglets à Droite</value>
</data>
<data name="TabCloseOther" xml:space="preserve">
<value>Fermer les autres onglets</value>
<value>Fermez les Autres onglets</value>
</data>
<data name="TabClose" xml:space="preserve">
<value>Fermer longlet</value>
@@ -208,16 +208,16 @@
<value>Fractionner longlet</value>
</data>
<data name="SplitPaneText" xml:space="preserve">
<value>Fractionner le volet</value>
<value>Fractionner le volet...</value>
</data>
<data name="SearchWebText" xml:space="preserve">
<value>Recherche web</value>
</data>
<data name="TabColorChoose" xml:space="preserve">
<value>Modifier la couleur de longlet</value>
<value>Couleur...</value>
</data>
<data name="TabColorCustomButton.Content" xml:space="preserve">
<value>Personnalisé</value>
<value>Personnalisée...</value>
</data>
<data name="TabColorClearButton.Content" xml:space="preserve">
<value>Réinitialiser</value>
@@ -464,7 +464,7 @@
<comment>This is the heading for a version number label</comment>
</data>
<data name="AboutDialog_GettingStartedLink.Content" xml:space="preserve">
<value>Bien démarrer</value>
<value>Prise en main</value>
<comment>A hyperlink name for a guide on how to get started using Terminal</comment>
</data>
<data name="AboutDialog_SourceCodeLink.Content" xml:space="preserve">
@@ -480,11 +480,11 @@
<comment>A hyperlink name for the Terminal's release notes</comment>
</data>
<data name="AboutDialog_PrivacyPolicyLink.Content" xml:space="preserve">
<value>Charte de confidentialité</value>
<value>Politique de confidentialité</value>
<comment>A hyperlink name for the Terminal's privacy policy</comment>
</data>
<data name="AboutDialog_ThirdPartyNoticesLink.Content" xml:space="preserve">
<value>Mentions tierces</value>
<value>Avis de tiers</value>
<comment>A hyperlink name for the Terminal's third-party notices</comment>
</data>
<data name="QuitDialog.CloseButtonText" xml:space="preserve">
@@ -723,7 +723,7 @@
<value>Agrandir</value>
</data>
<data name="WindowRestoreDownButtonToolTip" xml:space="preserve">
<value>Restaurer</value>
<value>Niveau inférieur</value>
</data>
<data name="CommandPaletteMenuItem" xml:space="preserve">
<value>Palette de commandes</value>
@@ -770,7 +770,7 @@
<value>Ne plus afficher</value>
</data>
<data name="ElevationShield.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Cette fenêtre de terminal sexécute en tant quadministrateur</value>
<value>Cette fenêtre de terminal sexécute en tant quAdministrateur</value>
</data>
<data name="SetAsDefaultTip_OpenSettingsLink.Content" xml:space="preserve">
<value>Ouvrir les paramètres</value>
@@ -834,7 +834,7 @@
<value>Fermer cet onglet</value>
</data>
<data name="NewTabMenuFolderEmpty" xml:space="preserve">
<value>Vide</value>
<value>Vide...</value>
</data>
<data name="ClosePaneText" xml:space="preserve">
<value>Fermer le volet</value>
@@ -853,7 +853,7 @@
<value>Déplacer l'onglet vers une nouvelle fenêtre </value>
</data>
<data name="RunAsAdminFlyout.Text" xml:space="preserve">
<value>Exécuter en temps qu'administrateur (restreint)</value>
<value>Exécuter en tant qu'administrateur</value>
<comment>This text is displayed on context menu for profile entries in add new tab button.</comment>
</data>
<data name="TerminalPage_PaneMovedAnnouncement_ExistingTab" xml:space="preserve">

View File

@@ -190,7 +190,7 @@
<value>Più riquadri</value>
</data>
<data name="TabCloseSubMenu" xml:space="preserve">
<value>Chiudi</value>
<value>Chiudi...</value>
</data>
<data name="TabCloseAfter" xml:space="preserve">
<value>Chiudi schede a destra</value>
@@ -202,7 +202,7 @@
<value>Chiudi scheda</value>
</data>
<data name="PaneClose" xml:space="preserve">
<value>Chiudi il riquadro</value>
<value>Chiudi riquadro</value>
</data>
<data name="SplitTabText" xml:space="preserve">
<value>Dividi scheda</value>
@@ -214,10 +214,10 @@
<value>Ricerca nel Web</value>
</data>
<data name="TabColorChoose" xml:space="preserve">
<value>Cambia colore scheda</value>
<value>Colore...</value>
</data>
<data name="TabColorCustomButton.Content" xml:space="preserve">
<value>Personalizzato</value>
<value>Personalizzato...</value>
</data>
<data name="TabColorClearButton.Content" xml:space="preserve">
<value>Reimposta</value>
@@ -464,7 +464,7 @@
<comment>This is the heading for a version number label</comment>
</data>
<data name="AboutDialog_GettingStartedLink.Content" xml:space="preserve">
<value>Introduzione</value>
<value>Attività iniziali</value>
<comment>A hyperlink name for a guide on how to get started using Terminal</comment>
</data>
<data name="AboutDialog_SourceCodeLink.Content" xml:space="preserve">
@@ -484,7 +484,7 @@
<comment>A hyperlink name for the Terminal's privacy policy</comment>
</data>
<data name="AboutDialog_ThirdPartyNoticesLink.Content" xml:space="preserve">
<value>Comunicazioni di terze parti</value>
<value>Informative di terze parti</value>
<comment>A hyperlink name for the Terminal's third-party notices</comment>
</data>
<data name="QuitDialog.CloseButtonText" xml:space="preserve">
@@ -723,7 +723,7 @@
<value>Ingrandisci</value>
</data>
<data name="WindowRestoreDownButtonToolTip" xml:space="preserve">
<value>Ripristina in basso</value>
<value>Ripristina visualizzazione normale</value>
</data>
<data name="CommandPaletteMenuItem" xml:space="preserve">
<value>Riquadro comandi</value>
@@ -837,7 +837,7 @@
<value>Vuoto</value>
</data>
<data name="ClosePaneText" xml:space="preserve">
<value>Chiudi il riquadro</value>
<value>Chiudi riquadro</value>
</data>
<data name="ClosePaneToolTip" xml:space="preserve">
<value>Chiude il riquadro attivo se sono presenti più riquadri</value>

View File

@@ -191,7 +191,7 @@
<value>複数ウィンドウ</value>
</data>
<data name="TabCloseSubMenu" xml:space="preserve">
<value>閉じる</value>
<value>閉じる...</value>
</data>
<data name="TabCloseAfter" xml:space="preserve">
<value>タブを右側に閉じる</value>
@@ -206,28 +206,28 @@
<value>ウィンドウを閉じる</value>
</data>
<data name="SplitTabText" xml:space="preserve">
<value>[分割] タブ</value>
<value>分割タブ</value>
</data>
<data name="SplitPaneText" xml:space="preserve">
<value>ウィンドウを分割する</value>
<value>分割ウィンドウ</value>
</data>
<data name="SearchWebText" xml:space="preserve">
<value>Web 検索</value>
</data>
<data name="TabColorChoose" xml:space="preserve">
<value>タブの色の変更</value>
<value>色...</value>
</data>
<data name="TabColorCustomButton.Content" xml:space="preserve">
<value>カスタム</value>
<value>カスタム...</value>
</data>
<data name="TabColorClearButton.Content" xml:space="preserve">
<value>リセット</value>
</data>
<data name="RenameTabText" xml:space="preserve">
<value>[名前の変更] タブ</value>
<value>タブ名を変更</value>
</data>
<data name="DuplicateTabText" xml:space="preserve">
<value>タブ複製する</value>
<value>タブ複製</value>
</data>
<data name="InvalidBackgroundImage" xml:space="preserve">
<value>無効な "backgroundImage" を持つプロファイルが見つかりました。既定では、そのプロファイルに背景画像はありません。"backgroundImage" を設定するときに、値が画像への有効なファイル パスとなっていることをご確認ください。</value>
@@ -485,7 +485,7 @@
<comment>A hyperlink name for the Terminal's privacy policy</comment>
</data>
<data name="AboutDialog_ThirdPartyNoticesLink.Content" xml:space="preserve">
<value>サード パーティ通知</value>
<value>サードパーティに関する通知</value>
<comment>A hyperlink name for the Terminal's third-party notices</comment>
</data>
<data name="QuitDialog.CloseButtonText" xml:space="preserve">
@@ -724,7 +724,7 @@
<value>最大化</value>
</data>
<data name="WindowRestoreDownButtonToolTip" xml:space="preserve">
<value>元に戻す (縮小)</value>
<value>元に戻す</value>
</data>
<data name="CommandPaletteMenuItem" xml:space="preserve">
<value>コマンド パレット</value>
@@ -759,7 +759,7 @@
<value>検索する</value>
</data>
<data name="PlainText" xml:space="preserve">
<value>テキスト</value>
<value>プレーンテキスト</value>
</data>
<data name="CloseOnExitInfoBar.Message" xml:space="preserve">
<value>終了動作は、プロファイルの詳細設定で構成できます。</value>
@@ -835,7 +835,7 @@
<value>このタブを閉じます</value>
</data>
<data name="NewTabMenuFolderEmpty" xml:space="preserve">
<value>なし</value>
<value>空っぽ...</value>
</data>
<data name="ClosePaneText" xml:space="preserve">
<value>ウィンドウを閉じる</value>
@@ -854,7 +854,7 @@
<value>タブを新しいウィンドウに移動 </value>
</data>
<data name="RunAsAdminFlyout.Text" xml:space="preserve">
<value>管理者として実行</value>
<value>管理者として実行する</value>
<comment>This text is displayed on context menu for profile entries in add new tab button.</comment>
</data>
<data name="TerminalPage_PaneMovedAnnouncement_ExistingTab" xml:space="preserve">

View File

@@ -190,10 +190,10 @@
<value>여러 창</value>
</data>
<data name="TabCloseSubMenu" xml:space="preserve">
<value>닫기</value>
<value>닫기...</value>
</data>
<data name="TabCloseAfter" xml:space="preserve">
<value>오른쪽에 있는 탭 닫기</value>
<value>오른쪽으로 탭 닫기</value>
</data>
<data name="TabCloseOther" xml:space="preserve">
<value>다른 탭 닫기</value>
@@ -214,10 +214,10 @@
<value>웹 검색</value>
</data>
<data name="TabColorChoose" xml:space="preserve">
<value>탭 색 변경</value>
<value>색...</value>
</data>
<data name="TabColorCustomButton.Content" xml:space="preserve">
<value>사용자 정</value>
<value>사용자 정의...</value>
</data>
<data name="TabColorClearButton.Content" xml:space="preserve">
<value>다시 설정</value>
@@ -454,7 +454,7 @@
<value>정보</value>
</data>
<data name="AboutDialog.PrimaryButtonText" xml:space="preserve">
<value>의견 보내기</value>
<value>피드백 보내기</value>
</data>
<data name="AboutDialog.CloseButtonText" xml:space="preserve">
<value>확인</value>
@@ -468,7 +468,7 @@
<comment>A hyperlink name for a guide on how to get started using Terminal</comment>
</data>
<data name="AboutDialog_SourceCodeLink.Content" xml:space="preserve">
<value>원본 코드</value>
<value>소스 코드</value>
<comment>A hyperlink name for the Terminal's documentation</comment>
</data>
<data name="AboutDialog_DocumentationLink.Content" xml:space="preserve">
@@ -480,11 +480,11 @@
<comment>A hyperlink name for the Terminal's release notes</comment>
</data>
<data name="AboutDialog_PrivacyPolicyLink.Content" xml:space="preserve">
<value>개인정보 보호정책</value>
<value>개인정보 취급방침</value>
<comment>A hyperlink name for the Terminal's privacy policy</comment>
</data>
<data name="AboutDialog_ThirdPartyNoticesLink.Content" xml:space="preserve">
<value>타사 통지</value>
<value>타사 통지 사항</value>
<comment>A hyperlink name for the Terminal's third-party notices</comment>
</data>
<data name="QuitDialog.CloseButtonText" xml:space="preserve">
@@ -571,7 +571,7 @@
<value>명령줄 구문 분석 오류:</value>
</data>
<data name="CommandPaletteControlName" xml:space="preserve">
<value>명령 팔레트</value>
<value>명령 도구 모음</value>
</data>
<data name="TabSwitcherControlName" xml:space="preserve">
<value>탭 전환기</value>
@@ -723,10 +723,10 @@
<value>최대화</value>
</data>
<data name="WindowRestoreDownButtonToolTip" xml:space="preserve">
<value>이전 크기로 복원</value>
<value>아래로 복원</value>
</data>
<data name="CommandPaletteMenuItem" xml:space="preserve">
<value>명령 팔레트</value>
<value>명령 도구 모음</value>
</data>
<data name="NotificationIconFocusTerminal" xml:space="preserve">
<value>포커스 터미널</value>
@@ -834,7 +834,7 @@
<value>이 탭 닫기</value>
</data>
<data name="NewTabMenuFolderEmpty" xml:space="preserve">
<value>비어 있음</value>
<value>비어 있음...</value>
</data>
<data name="ClosePaneText" xml:space="preserve">
<value>창 닫기</value>
@@ -847,13 +847,13 @@
<comment>Text used to identify the reset button</comment>
</data>
<data name="MoveTabToNewWindowText" xml:space="preserve">
<value>탭을 새 창으로 이동</value>
<value>새 창으로 이동</value>
</data>
<data name="MoveTabToNewWindowToolTip" xml:space="preserve">
<value>탭을 새 창으로 이동 </value>
</data>
<data name="RunAsAdminFlyout.Text" xml:space="preserve">
<value>관리자 권한으로 실행</value>
<value>관리자로 실행</value>
<comment>This text is displayed on context menu for profile entries in add new tab button.</comment>
</data>
<data name="TerminalPage_PaneMovedAnnouncement_ExistingTab" xml:space="preserve">

View File

@@ -190,34 +190,34 @@
<value>Vários painéis</value>
</data>
<data name="TabCloseSubMenu" xml:space="preserve">
<value>Fechar</value>
<value>Fechar...</value>
</data>
<data name="TabCloseAfter" xml:space="preserve">
<value>Fechar guias à direita</value>
<value>Fechar Guias à Direita</value>
</data>
<data name="TabCloseOther" xml:space="preserve">
<value>Fechar outras guias</value>
<value>Fechar Outras Guias</value>
</data>
<data name="TabClose" xml:space="preserve">
<value>Fechar guia</value>
</data>
<data name="PaneClose" xml:space="preserve">
<value>Fechar o painel</value>
<value>Fechar Painel</value>
</data>
<data name="SplitTabText" xml:space="preserve">
<value>Guia Dividir</value>
<value>Dividir Guia</value>
</data>
<data name="SplitPaneText" xml:space="preserve">
<value>Dividir painel</value>
<value>Painel dividido</value>
</data>
<data name="SearchWebText" xml:space="preserve">
<value>Pesquisa na Web</value>
<value>Pesquisa na web</value>
</data>
<data name="TabColorChoose" xml:space="preserve">
<value>Alterar cor da guia</value>
<value>Cor...</value>
</data>
<data name="TabColorCustomButton.Content" xml:space="preserve">
<value>Personalizado</value>
<value>Personalizados...</value>
</data>
<data name="TabColorClearButton.Content" xml:space="preserve">
<value>Restaurar</value>
@@ -226,7 +226,7 @@
<value>Renomear guia</value>
</data>
<data name="DuplicateTabText" xml:space="preserve">
<value>Duplicar guia</value>
<value>Duplicar Guia</value>
</data>
<data name="InvalidBackgroundImage" xml:space="preserve">
<value>Foi encontrado um perfil com um "backgroundImage" inválido. O perfil deve ser o padrão para que não haja nenhuma imagem de tela de fundo. Certifique-se de que, ao definir um "backgroundImage", o valor é um caminho de arquivo válido para uma imagem.</value>
@@ -454,7 +454,7 @@
<value>Sobre</value>
</data>
<data name="AboutDialog.PrimaryButtonText" xml:space="preserve">
<value>Enviar comentários</value>
<value>Enviar Comentários</value>
</data>
<data name="AboutDialog.CloseButtonText" xml:space="preserve">
<value>OK</value>
@@ -464,7 +464,7 @@
<comment>This is the heading for a version number label</comment>
</data>
<data name="AboutDialog_GettingStartedLink.Content" xml:space="preserve">
<value>Introdução</value>
<value>Ponto de Partida</value>
<comment>A hyperlink name for a guide on how to get started using Terminal</comment>
</data>
<data name="AboutDialog_SourceCodeLink.Content" xml:space="preserve">
@@ -484,7 +484,7 @@
<comment>A hyperlink name for the Terminal's privacy policy</comment>
</data>
<data name="AboutDialog_ThirdPartyNoticesLink.Content" xml:space="preserve">
<value>Avisos de Terceiros</value>
<value>Avisos de terceiros</value>
<comment>A hyperlink name for the Terminal's third-party notices</comment>
</data>
<data name="QuitDialog.CloseButtonText" xml:space="preserve">
@@ -571,10 +571,10 @@
<value>Falha ao analisar a linha de comando:</value>
</data>
<data name="CommandPaletteControlName" xml:space="preserve">
<value>Paleta de comandos</value>
<value>Paleta de Comandos</value>
</data>
<data name="TabSwitcherControlName" xml:space="preserve">
<value>Alternador de guias</value>
<value>Seletor de guias</value>
</data>
<data name="TabSwitcher_SearchBoxText" xml:space="preserve">
<value>Digite o nome da guia...</value>
@@ -726,7 +726,7 @@
<value>Restaurar Tamanho Original</value>
</data>
<data name="CommandPaletteMenuItem" xml:space="preserve">
<value>Paleta de comandos</value>
<value>Paleta de Comandos</value>
</data>
<data name="NotificationIconFocusTerminal" xml:space="preserve">
<value>Terminal de foco</value>
@@ -746,7 +746,7 @@
<value>Dividir a janela e iniciar em determinado diretório</value>
</data>
<data name="ExportTabText" xml:space="preserve">
<value>Exportar texto</value>
<value>Exportar Texto</value>
</data>
<data name="ExportFailure" xml:space="preserve">
<value>Falha ao exportar o conteúdo do terminal</value>
@@ -758,7 +758,7 @@
<value>Localizar</value>
</data>
<data name="PlainText" xml:space="preserve">
<value>Texto sem formatação</value>
<value>Texto Simples</value>
</data>
<data name="CloseOnExitInfoBar.Message" xml:space="preserve">
<value>O comportamento de término pode ser configurado nas configurações avançadas do perfil.</value>
@@ -770,7 +770,7 @@
<value>Não mostra de novo</value>
</data>
<data name="ElevationShield.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Esta janela do Terminal está sendo executada como administrador</value>
<value>Esta janela do Terminal está funcionando como Administrador</value>
</data>
<data name="SetAsDefaultTip_OpenSettingsLink.Content" xml:space="preserve">
<value>Abrir Configurações</value>
@@ -834,10 +834,10 @@
<value>Fechar esta guia</value>
</data>
<data name="NewTabMenuFolderEmpty" xml:space="preserve">
<value>Vazio</value>
<value>Vazio...</value>
</data>
<data name="ClosePaneText" xml:space="preserve">
<value>Fechar o painel</value>
<value>Fechar Painel</value>
</data>
<data name="ClosePaneToolTip" xml:space="preserve">
<value>Feche o painel ativo se vários painéis estiverem presentes</value>
@@ -847,13 +847,13 @@
<comment>Text used to identify the reset button</comment>
</data>
<data name="MoveTabToNewWindowText" xml:space="preserve">
<value>Mover guia para nova janela</value>
<value>Mover Guia para Nova Janela</value>
</data>
<data name="MoveTabToNewWindowToolTip" xml:space="preserve">
<value>Move a guia para uma nova janela</value>
</data>
<data name="RunAsAdminFlyout.Text" xml:space="preserve">
<value>Executar como administrador</value>
<value>Executar como Administrador</value>
<comment>This text is displayed on context menu for profile entries in add new tab button.</comment>
</data>
<data name="TerminalPage_PaneMovedAnnouncement_ExistingTab" xml:space="preserve">
@@ -892,7 +892,7 @@
<value>Se definido, o comando será acrescentado ao comando padrão do perfil em vez de substituí-lo.</value>
</data>
<data name="RestartConnectionText" xml:space="preserve">
<value>Reiniciar conexão</value>
<value>Reiniciar Conexão</value>
</data>
<data name="RestartConnectionToolTip" xml:space="preserve">
<value>Reiniciar a conexão do painel ativo</value>

View File

@@ -194,43 +194,43 @@
<value>Μµľťιφļė ρаńêѕ !!! !</value>
</data>
<data name="TabCloseSubMenu" xml:space="preserve">
<value>Ćļôŝέ !</value>
<value>Çĺòšĕ... !!</value>
</data>
<data name="TabCloseAfter" xml:space="preserve">
<value>Ċĺοşέ ţаъş ťό ŧђé яΐğђт !!! !!! </value>
<value>€łǿѕē Ťäьş τб τнё Ѓΐĝђτ !!! !!! </value>
</data>
<data name="TabCloseOther" xml:space="preserve">
<value>Ćĺόѕ℮ őтђèř ŧâьś !!! !</value>
<value>Çľόśĕ Ωţђєŗ Ťǻьś !!! !</value>
</data>
<data name="TabClose" xml:space="preserve">
<value>Сĺôšę ťăв !!!</value>
<value>Ĉĺõŝĕ Τàъ !!!</value>
</data>
<data name="PaneClose" xml:space="preserve">
<value>Ćŀöśё ρаņé !!!</value>
<value>Ĉłŏşё Ρаπє !!!</value>
</data>
<data name="SplitTabText" xml:space="preserve">
<value>Šрľīτ τàв !!!</value>
<value>Šφļΐт Ťάь !!!</value>
</data>
<data name="SplitPaneText" xml:space="preserve">
<value>Šрŀіт φªňë !!!</value>
<value>Šφľίţ Ρªńе !!!</value>
</data>
<data name="SearchWebText" xml:space="preserve">
<value>Ẅёв şĕаŕčĥ !!!</value>
<value>Шеь Ѕ℮âґ¢ĥ !!!</value>
</data>
<data name="TabColorChoose" xml:space="preserve">
<value>Ċħāņğě τāв ςōĺöя !!! !</value>
<value>Çοℓõґ... !!</value>
</data>
<data name="TabColorCustomButton.Content" xml:space="preserve">
<value>Ċµѕťøм !</value>
<value>Çūŝŧσm... !!!</value>
</data>
<data name="TabColorClearButton.Content" xml:space="preserve">
<value>Ŕĕšęτ !</value>
</data>
<data name="RenameTabText" xml:space="preserve">
<value>Γεñамē ťãв !!!</value>
<value>Яěňämě Ťαв !!!</value>
</data>
<data name="DuplicateTabText" xml:space="preserve">
<value>Ďϋφľіčάтέ τàв !!! </value>
<value>Ðüрĺíсąтз Ťáь !!! </value>
</data>
<data name="InvalidBackgroundImage" xml:space="preserve">
<value>₣οüⁿδ ά ρѓőƒіĺз шιтћ аή îйνåℓīď "backgroundImage". Ðєƒâŭŀťïʼnģ ŧĥäτ рřŏƒīℓë τô ћãνё ñō ьàĉќġяοµπď îмǻġё. Μāκе ŝύґé ŧнàτ ẁћзή šĕτťійğ ά "backgroundImage", ťħē νдļûě íş ä νåĺϊđ ƒìℓę ραтħ ŧб ãή їmаĝē. !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !</value>
@@ -462,7 +462,7 @@
<value>Ąвοµτ !</value>
</data>
<data name="AboutDialog.PrimaryButtonText" xml:space="preserve">
<value>Ѕеηð ƒę℮đвäçк !!! </value>
<value>Ѕěиð ₣ëëðъаċќ !!! </value>
</data>
<data name="AboutDialog.CloseButtonText" xml:space="preserve">
<value>ǾЌ </value>
@@ -472,11 +472,11 @@
<comment>This is the heading for a version number label</comment>
</data>
<data name="AboutDialog_GettingStartedLink.Content" xml:space="preserve">
<value>Ġеťтΐñĝ ѕτдŗτęď !!! !</value>
<value>Ġєтťĩňģ Śŧåгτ℮ď !!! !</value>
<comment>A hyperlink name for a guide on how to get started using Terminal</comment>
</data>
<data name="AboutDialog_SourceCodeLink.Content" xml:space="preserve">
<value>Ѕοџŗсė ¢ŏđе !!!</value>
<value>Šőύѓċέ Čōðé !!!</value>
<comment>A hyperlink name for the Terminal's documentation</comment>
</data>
<data name="AboutDialog_DocumentationLink.Content" xml:space="preserve">
@@ -484,15 +484,15 @@
<comment>A hyperlink name for user documentation</comment>
</data>
<data name="AboutDialog_ReleaseNotesLink.Content" xml:space="preserve">
<value>Ŗеľ℮àşε πòτéš !!! </value>
<value>Ґзĺėàşě Ńотëѕ !!! </value>
<comment>A hyperlink name for the Terminal's release notes</comment>
</data>
<data name="AboutDialog_PrivacyPolicyLink.Content" xml:space="preserve">
<value>Ρґїνãсÿ ρöĺĩςỳ !!! !</value>
<value>Рřïνǻćý Рόľіςŷ !!! !</value>
<comment>A hyperlink name for the Terminal's privacy policy</comment>
</data>
<data name="AboutDialog_ThirdPartyNoticesLink.Content" xml:space="preserve">
<value>Ţћĩřð-Ρářŧγ ñοŧīĉęŝ !!! !!!</value>
<value>Ŧĥϊŗď-Рàŕтý Йŏţįсεś !!! !!!</value>
<comment>A hyperlink name for the Terminal's third-party notices</comment>
</data>
<data name="QuitDialog.CloseButtonText" xml:space="preserve">
@@ -579,10 +579,10 @@
<value>₣дїĺēď рåѓşĭⁿğ çõmмάñð ļîπ℮: !!! !!! !!</value>
</data>
<data name="CommandPaletteControlName" xml:space="preserve">
<value>Ćσmmăηδ ράŀĕтţ℮ !!! !</value>
<value>€őммάпď Рªļ℮ţţė !!! !</value>
</data>
<data name="TabSwitcherControlName" xml:space="preserve">
<value>Τăь ѕωîťςћêг !!! </value>
<value>Ťàь Śщíţςħєґ !!! </value>
</data>
<data name="TabSwitcher_SearchBoxText" xml:space="preserve">
<value>Τýрė à ţǻь иàмє... !!! !!</value>
@@ -731,10 +731,10 @@
<value>Μдхįmїżέ !!</value>
</data>
<data name="WindowRestoreDownButtonToolTip" xml:space="preserve">
<value>Ŕèšŧòяё ďǿẃи !!! </value>
<value>Ґęşŧóгè Đóшй !!! </value>
</data>
<data name="CommandPaletteMenuItem" xml:space="preserve">
<value>Ċòмmāńδ рªľėτťë !!! !</value>
<value>Ĉθммάⁿđ Ράłεтťè !!! !</value>
</data>
<data name="NotificationIconFocusTerminal" xml:space="preserve">
<value>₣осµѕ Ţèґmιйàł !!! !</value>
@@ -754,7 +754,7 @@
<value>Ѕрŀĭт τнє ẁìⁿδöщ άπď şţąѓт ĩⁿ ġĭνêŋ ďįгěçţбгŷ !!! !!! !!! !!! !</value>
</data>
<data name="ExportTabText" xml:space="preserve">
<value>Ė×φōŗŧ ţєхŧ !!!</value>
<value>Èхφóřŧ Τèжŧ !!!</value>
</data>
<data name="ExportFailure" xml:space="preserve">
<value>₣άιļěđ ŧо ěхрŏгť тēѓмïйäℓ ċбητėήт !!! !!! !!! </value>
@@ -766,7 +766,7 @@
<value>₣ìŋð !</value>
</data>
<data name="PlainText" xml:space="preserve">
<value>Ρĺáīň тěхт !!!</value>
<value>Ρłāîⁿ Ťĕם !!!</value>
</data>
<data name="CloseOnExitInfoBar.Message" xml:space="preserve">
<value>Ţėřmĩⁿäтîбň ьεђªνįог ĉαή ье ĉόπƒϊĝŭяэδ ΐп ǻđνǻήсєð φґσƒĭľе şέŧŧϊŋğѕ. !!! !!! !!! !!! !!! !!! !!</value>
@@ -778,7 +778,11 @@
<value>Đõŋ'ť šћσẁ àģаΐņ !!! !</value>
</data>
<data name="ElevationShield.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Ţђіś Тĕřмїηǻℓ шĩⁿðöŵ ïѕ ѓüñňĩñģ ãŝ áðmĭⁿîşŧŕãţθŕ !!! !!! !!! !!! !!</value>
<value>Ťħіš Ţзѓмϊηāℓ ẅìήδόŵ ĭѕ яџпņîйģ àŝ Āđмій !!! !!! !!! !!!</value>
</data>
<data name="SetAsDefaultTip_OpenSettingsLink.Content" xml:space="preserve">
<value>Ŏφėп Ѕėţŧΐņğş !!! </value>
<comment>This is a call-to-action hyperlink; it will open the settings.</comment>
</data>
<data name="CommandPalette_MatchesAvailable" xml:space="preserve">
<value>Śϋĝģėѕŧïöⁿś ƒоùлď: {0} !!! !!! </value>
@@ -838,10 +842,10 @@
<value>€ĺòŝэ τђíŝ ţåв !!! !</value>
</data>
<data name="NewTabMenuFolderEmpty" xml:space="preserve">
<value>Ёмφţγ !</value>
<value>Єmφтγ... !!</value>
</data>
<data name="ClosePaneText" xml:space="preserve">
<value>Ĉĺοŝе φаиę !!!</value>
<value>Çℓσş℮ Ράиε !!!</value>
</data>
<data name="ClosePaneToolTip" xml:space="preserve">
<value>Ĉĺοŝě ŧнέ άçŧινè φâηė īƒ mџľťĭрłέ рªņēŝ äя℮ ρŗеšěпť !!! !!! !!! !!! !!!</value>
@@ -851,13 +855,13 @@
<comment>Text used to identify the reset button</comment>
</data>
<data name="MoveTabToNewWindowText" xml:space="preserve">
<value>Мόνз ţǻь ŧö ʼn℮ω ώĭŋδōώ !!! !!! </value>
<value>Мōνє Тдь τő Ņėẅ Ẁîʼnďσщ !!! !!! </value>
</data>
<data name="MoveTabToNewWindowToolTip" xml:space="preserve">
<value>Мòνέš τдъ тσ ą ńэω ωìлðøẅ !!! !!! !</value>
</data>
<data name="RunAsAdminFlyout.Text" xml:space="preserve">
<value>Ŕμŋ ąś åďmįиíšťґąţőя !!! !!!</value>
<value>Ŕųň ăŝ Áďмîπĭšŧгăţόŗ !!! !!!</value>
<comment>This text is displayed on context menu for profile entries in add new tab button.</comment>
</data>
<data name="TerminalPage_PaneMovedAnnouncement_ExistingTab" xml:space="preserve">
@@ -896,9 +900,9 @@
<value>΃ śèţ, ţђέ ćòмmǻŋď шіŀľ ъэ дррэňδĕð тθ ťĥє φѓōƒíľэ'ś δéƒâūŀт ćомmāņď їиśťēāđ ŏƒ ѓēрłά¢íηĝ іт. !!! !!! !!! !!! !!! !!! !!! !!! !!! !</value>
</data>
<data name="RestartConnectionText" xml:space="preserve">
<value>Γēѕŧâяŧ ćǿńńēčťїöл !!! !!</value>
<value>Ŗεšτäřť Сòплέ¢тίøņ !!! !!</value>
</data>
<data name="RestartConnectionToolTip" xml:space="preserve">
<value>Ѓêşŧãřŧ тн℮ âçτìνе рàⁿê ćбñйєĉтĩόʼn !!! !!! !!! !</value>
</data>
</root>
</root>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -196,7 +196,7 @@
<value>Закрыть вкладки справа</value>
</data>
<data name="TabCloseOther" xml:space="preserve">
<value>Закрыть остальные вкладки</value>
<value>Закрыть другие вкладки</value>
</data>
<data name="TabClose" xml:space="preserve">
<value>Закрыть вкладку</value>
@@ -214,10 +214,10 @@
<value>Поиск в Интернете</value>
</data>
<data name="TabColorChoose" xml:space="preserve">
<value>Изменить цвет вкладки</value>
<value>Цвет...</value>
</data>
<data name="TabColorCustomButton.Content" xml:space="preserve">
<value>Настраиваемый</value>
<value>Настраиваемый...</value>
</data>
<data name="TabColorClearButton.Content" xml:space="preserve">
<value>Сбросить</value>
@@ -464,7 +464,7 @@
<comment>This is the heading for a version number label</comment>
</data>
<data name="AboutDialog_GettingStartedLink.Content" xml:space="preserve">
<value>Приступая к работе</value>
<value>Начало работы</value>
<comment>A hyperlink name for a guide on how to get started using Terminal</comment>
</data>
<data name="AboutDialog_SourceCodeLink.Content" xml:space="preserve">
@@ -484,7 +484,7 @@
<comment>A hyperlink name for the Terminal's privacy policy</comment>
</data>
<data name="AboutDialog_ThirdPartyNoticesLink.Content" xml:space="preserve">
<value>Уведомления третьих лиц</value>
<value>Уведомления сторонних производителей</value>
<comment>A hyperlink name for the Terminal's third-party notices</comment>
</data>
<data name="QuitDialog.CloseButtonText" xml:space="preserve">
@@ -723,7 +723,7 @@
<value>Развернуть</value>
</data>
<data name="WindowRestoreDownButtonToolTip" xml:space="preserve">
<value>Кнопка "Свернуть в окно"</value>
<value>Восстановить размер</value>
</data>
<data name="CommandPaletteMenuItem" xml:space="preserve">
<value>Палитра команд</value>
@@ -834,7 +834,7 @@
<value>Закрыть эту вкладку</value>
</data>
<data name="NewTabMenuFolderEmpty" xml:space="preserve">
<value>Очистить</value>
<value>Пусто...</value>
</data>
<data name="ClosePaneText" xml:space="preserve">
<value>Закрыть панель</value>

View File

@@ -190,7 +190,7 @@
<value>多个窗格</value>
</data>
<data name="TabCloseSubMenu" xml:space="preserve">
<value>关闭</value>
<value>关闭</value>
</data>
<data name="TabCloseAfter" xml:space="preserve">
<value>关闭右侧标签页</value>
@@ -211,13 +211,13 @@
<value>拆分窗格</value>
</data>
<data name="SearchWebText" xml:space="preserve">
<value>网络搜索</value>
<value>Web 搜索</value>
</data>
<data name="TabColorChoose" xml:space="preserve">
<value>更改选项卡颜色</value>
<value>颜色...</value>
</data>
<data name="TabColorCustomButton.Content" xml:space="preserve">
<value>自定义</value>
<value>自定义...</value>
</data>
<data name="TabColorClearButton.Content" xml:space="preserve">
<value>重置</value>
@@ -226,7 +226,7 @@
<value>重命名选项卡</value>
</data>
<data name="DuplicateTabText" xml:space="preserve">
<value>复制标签页</value>
<value>复制选项卡</value>
</data>
<data name="InvalidBackgroundImage" xml:space="preserve">
<value>找到一个具有无效 "backgroundImage" 的配置文件。将该配置文件设置为默认设置为不包含背景图像。请确保在设置 "backgroundImage" 时,该值是指向图像的有效文件路径。</value>
@@ -480,7 +480,7 @@
<comment>A hyperlink name for the Terminal's release notes</comment>
</data>
<data name="AboutDialog_PrivacyPolicyLink.Content" xml:space="preserve">
<value>隐私策</value>
<value>隐私策</value>
<comment>A hyperlink name for the Terminal's privacy policy</comment>
</data>
<data name="AboutDialog_ThirdPartyNoticesLink.Content" xml:space="preserve">
@@ -834,7 +834,7 @@
<value>关闭此选项卡</value>
</data>
<data name="NewTabMenuFolderEmpty" xml:space="preserve">
<value>空</value>
<value>空白...</value>
</data>
<data name="ClosePaneText" xml:space="preserve">
<value>关闭窗格</value>

View File

@@ -190,7 +190,7 @@
<value>多個窗格</value>
</data>
<data name="TabCloseSubMenu" xml:space="preserve">
<value>關閉</value>
<value>關閉...</value>
</data>
<data name="TabCloseAfter" xml:space="preserve">
<value>關閉右側的索引標籤</value>
@@ -205,19 +205,19 @@
<value>關閉窗格</value>
</data>
<data name="SplitTabText" xml:space="preserve">
<value>分割索引標籤</value>
<value>分割 Tab</value>
</data>
<data name="SplitPaneText" xml:space="preserve">
<value>分割窗格</value>
</data>
<data name="SearchWebText" xml:space="preserve">
<value>網頁搜尋</value>
<value>Web 搜尋</value>
</data>
<data name="TabColorChoose" xml:space="preserve">
<value>變更索引標籤色彩</value>
<value>色彩...</value>
</data>
<data name="TabColorCustomButton.Content" xml:space="preserve">
<value>自訂</value>
<value>自訂...</value>
</data>
<data name="TabColorClearButton.Content" xml:space="preserve">
<value>重設</value>
@@ -468,7 +468,7 @@
<comment>A hyperlink name for a guide on how to get started using Terminal</comment>
</data>
<data name="AboutDialog_SourceCodeLink.Content" xml:space="preserve">
<value>原始碼</value>
<value>原始程式碼</value>
<comment>A hyperlink name for the Terminal's documentation</comment>
</data>
<data name="AboutDialog_DocumentationLink.Content" xml:space="preserve">
@@ -480,11 +480,11 @@
<comment>A hyperlink name for the Terminal's release notes</comment>
</data>
<data name="AboutDialog_PrivacyPolicyLink.Content" xml:space="preserve">
<value>隱私權政策</value>
<value>隱私權原則</value>
<comment>A hyperlink name for the Terminal's privacy policy</comment>
</data>
<data name="AboutDialog_ThirdPartyNoticesLink.Content" xml:space="preserve">
<value>第三方注意事項</value>
<value>第三方聲明</value>
<comment>A hyperlink name for the Terminal's third-party notices</comment>
</data>
<data name="QuitDialog.CloseButtonText" xml:space="preserve">
@@ -834,7 +834,7 @@
<value>關閉此索引標籤</value>
</data>
<data name="NewTabMenuFolderEmpty" xml:space="preserve">
<value>空</value>
<value>空白...</value>
</data>
<data name="ClosePaneText" xml:space="preserve">
<value>關閉窗格</value>

View File

@@ -57,7 +57,7 @@ namespace winrt::TerminalApp::implementation
// re-evaluate including that arg in this action then.
// Return Value:
// - The list of actions.
std::vector<ActionAndArgs> SettingsTab::BuildStartupActions(BuildStartupKind) const
std::vector<ActionAndArgs> SettingsTab::BuildStartupActions(const bool /*asContent*/) const
{
ASSERT_UI_THREAD();
@@ -114,7 +114,7 @@ namespace winrt::TerminalApp::implementation
// The TabViewItem Icon needs MUX while the IconSourceElement in the CommandPalette needs WUX...
Icon(winrt::hstring{ glyph });
TabViewItem().IconSource(IconPathConverter::IconSourceMUX(glyph, false));
TabViewItem().IconSource(Microsoft::Terminal::UI::IconPathConverter::IconSourceMUX(glyph, false));
}
winrt::Windows::UI::Xaml::Media::Brush SettingsTab::_BackgroundBrush()

View File

@@ -30,7 +30,7 @@ namespace winrt::TerminalApp::implementation
void UpdateSettings(Microsoft::Terminal::Settings::Model::CascadiaSettings settings);
void Focus(winrt::Windows::UI::Xaml::FocusState focusState) override;
std::vector<Microsoft::Terminal::Settings::Model::ActionAndArgs> BuildStartupActions(BuildStartupKind kind) const override;
std::vector<Microsoft::Terminal::Settings::Model::ActionAndArgs> BuildStartupActions(const bool asContent = false) const override;
private:
winrt::Windows::UI::Xaml::ElementTheme _requestedTheme;

View File

@@ -2,7 +2,6 @@
// Licensed under the MIT license.
import "TabBase.idl";
import "IDirectKeyListener.idl";
import "HighlightedTextControl.idl";
import "FilteredCommand.idl";
@@ -21,7 +20,7 @@ namespace TerminalApp
BottomUp
};
[default_interface] runtimeclass SuggestionsControl : Windows.UI.Xaml.Controls.UserControl, Windows.UI.Xaml.Data.INotifyPropertyChanged, IDirectKeyListener
[default_interface] runtimeclass SuggestionsControl : Windows.UI.Xaml.Controls.UserControl, Windows.UI.Xaml.Data.INotifyPropertyChanged, Microsoft.Terminal.UI.IDirectKeyListener
{
SuggestionsControl();

View File

@@ -10,6 +10,7 @@
xmlns:local="using:TerminalApp"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:model="using:Microsoft.Terminal.Settings.Model"
xmlns:mtu="using:Microsoft.Terminal.UI"
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
AllowFocusOnInteraction="True"
AutomationProperties.Name="{x:Bind ControlName, Mode=OneWay}"
@@ -23,9 +24,6 @@
<UserControl.Resources>
<ResourceDictionary>
<local:EmptyStringVisibilityConverter x:Key="ParentCommandVisibilityConverter" />
<model:IconPathConverter x:Key="IconSourceConverter" />
<DataTemplate x:Key="ListItemTemplate"
x:DataType="local:FilteredCommand">
<ListViewItem Height="32"
@@ -161,7 +159,7 @@
<StackPanel Grid.Row="1"
Margin="8,0,8,8"
Orientation="Horizontal"
Visibility="{x:Bind ParentCommandName, Mode=OneWay, Converter={StaticResource ParentCommandVisibilityConverter}}">
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(ParentCommandName), Mode=OneWay}">
<Button x:Name="_parentCommandBackButton"
x:Uid="ParentCommandBackButton"

View File

@@ -12,14 +12,6 @@ namespace TerminalAppLocalTests
namespace winrt::TerminalApp::implementation
{
enum class BuildStartupKind
{
None,
Content,
MovePane,
Persist,
};
struct TabBase : TabBaseT<TabBase>
{
public:
@@ -30,7 +22,7 @@ namespace winrt::TerminalApp::implementation
void UpdateTabViewIndex(const uint32_t idx, const uint32_t numTabs);
void SetActionMap(const Microsoft::Terminal::Settings::Model::IActionMapView& actionMap);
virtual std::vector<Microsoft::Terminal::Settings::Model::ActionAndArgs> BuildStartupActions(BuildStartupKind kind) const = 0;
virtual std::vector<Microsoft::Terminal::Settings::Model::ActionAndArgs> BuildStartupActions(const bool asContent = false) const = 0;
virtual std::optional<winrt::Windows::UI::Color> GetTabColor();
void ThemeColor(const winrt::Microsoft::Terminal::Settings::Model::ThemeColor& focused,

View File

@@ -174,11 +174,12 @@ namespace winrt::TerminalApp::implementation
// Set this tab's icon to the icon from the user's profile
if (const auto profile{ newTabImpl->GetFocusedProfile() })
{
if (!profile.Icon().empty())
const auto& icon = profile.EvaluatedIcon();
if (!icon.empty())
{
const auto theme = _settings.GlobalSettings().CurrentTheme();
const auto iconStyle = (theme && theme.Tab()) ? theme.Tab().IconStyle() : IconStyle::Default;
newTabImpl->UpdateIcon(profile.Icon(), iconStyle);
newTabImpl->UpdateIcon(icon, iconStyle);
}
}
@@ -245,7 +246,7 @@ namespace winrt::TerminalApp::implementation
{
const auto theme = _settings.GlobalSettings().CurrentTheme();
const auto iconStyle = (theme && theme.Tab()) ? theme.Tab().IconStyle() : IconStyle::Default;
tab.UpdateIcon(profile.Icon(), iconStyle);
tab.UpdateIcon(profile.EvaluatedIcon(), iconStyle);
}
}
@@ -428,7 +429,7 @@ namespace winrt::TerminalApp::implementation
}
auto t = winrt::get_self<implementation::TabBase>(tab);
auto actions = t->BuildStartupActions(BuildStartupKind::None);
auto actions = t->BuildStartupActions();
_AddPreviouslyClosedPaneOrTab(std::move(actions));
_RemoveTab(tab);
@@ -485,7 +486,7 @@ namespace winrt::TerminalApp::implementation
// if the user manually closed all tabs.
// Do this only if we are the last window; the monarch will notice
// we are missing and remove us that way otherwise.
_CloseWindowRequestedHandlers(*this, nullptr);
_LastTabClosedHandlers(*this, winrt::make<LastTabClosedEventArgs>(!_maintainStateOnTabClose));
}
else if (focusedTabIndex.has_value() && focusedTabIndex.value() == gsl::narrow_cast<uint32_t>(tabIndex))
{
@@ -766,11 +767,11 @@ namespace winrt::TerminalApp::implementation
// This doesn't handle refocusing anything in particular, the
// result will be that the last pane created is focused. In the
// case of a single pane that is the desired behavior anyways.
auto state = pane->BuildStartupActions(0, 1, BuildStartupKind::None);
auto state = pane->BuildStartupActions(0, 1);
{
ActionAndArgs splitPaneAction{};
splitPaneAction.Action(ShortcutAction::SplitPane);
SplitPaneArgs splitPaneArgs{ SplitDirection::Automatic, state.firstPane->GetTerminalArgsForPane(BuildStartupKind::None) };
SplitPaneArgs splitPaneArgs{ SplitDirection::Automatic, state.firstPane->GetTerminalArgsForPane() };
splitPaneAction.Args(splitPaneArgs);
state.args.emplace(state.args.begin(), std::move(splitPaneAction));
@@ -1138,4 +1139,12 @@ namespace winrt::TerminalApp::implementation
{
return _tabs.Size() > 1;
}
void TerminalPage::_RemoveAllTabs()
{
// Since _RemoveTabs is asynchronous, create a snapshot of the tabs we want to remove
std::vector<winrt::TerminalApp::TabBase> tabsToRemove;
std::copy(begin(_tabs), end(_tabs), std::back_inserter(tabsToRemove));
_RemoveTabs(tabsToRemove);
}
}

View File

@@ -130,9 +130,6 @@
<DependentUpon>CommandPalette.xaml</DependentUpon>
</ClInclude>
<ClInclude Include="FilteredCommand.h" />
<ClInclude Include="EmptyStringVisibilityConverter.h">
<DependentUpon>EmptyStringVisibilityConverter.idl</DependentUpon>
</ClInclude>
<ClInclude Include="Pane.h" />
<ClInclude Include="ColorHelper.h" />
<ClInclude Include="pch.h" />
@@ -232,9 +229,6 @@
<DependentUpon>CommandPalette.xaml</DependentUpon>
</ClCompile>
<ClCompile Include="FilteredCommand.cpp" />
<ClCompile Include="EmptyStringVisibilityConverter.cpp">
<DependentUpon>EmptyStringVisibilityConverter.idl</DependentUpon>
</ClCompile>
<ClCompile Include="Pane.cpp" />
<ClCompile Include="Pane.LayoutSizeNode.cpp" />
<ClCompile Include="ColorHelper.cpp">
@@ -280,7 +274,6 @@
header in TerminalApp.vcxproj (as well as in this file) -->
<Midl Include="ActionPaletteItem.idl" />
<Midl Include="CommandLinePaletteItem.idl" />
<Midl Include="IDirectKeyListener.idl" />
<Midl Include="AboutDialog.idl">
<DependentUpon>AboutDialog.xaml</DependentUpon>
</Midl>
@@ -341,7 +334,6 @@
<SubType>Code</SubType>
</Midl>
<Midl Include="FilteredCommand.idl" />
<Midl Include="EmptyStringVisibilityConverter.idl" />
</ItemGroup>
<!-- ========================= Misc Files ======================== -->
<ItemGroup>
@@ -385,6 +377,9 @@
<Private>true</Private>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\UIHelpers\UIHelpers.vcxproj">
<Project>{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}</Project>
</ProjectReference>
</ItemGroup>
<PropertyGroup>
@@ -422,12 +417,7 @@
<Private>false</Private>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
</Reference>
<Reference Include="Microsoft.Terminal.Core">
<HintPath>$(OpenConsoleCommonOutDir)TerminalCore\Microsoft.Terminal.Core.winmd</HintPath>
<IsWinMDFile>true</IsWinMDFile>
<Private>false</Private>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
</Reference>
<!-- TODO VALIDATE DELETION -->
<Reference Include="$(WindowsSDK_MetadataPathVersioned)\Windows.UI.Xaml.Hosting.HostingContract\*\*.winmd">
<WinMDFile>true</WinMDFile>
<CopyLocal>false</CopyLocal>

View File

@@ -98,7 +98,6 @@
<Midl Include="ShortcutActionDispatch.idl">
<Filter>settings</Filter>
</Midl>
<Midl Include="IDirectKeyListener.idl" />
<Midl Include="SettingsTab.idl">
<Filter>tab</Filter>
</Midl>
@@ -116,7 +115,6 @@
</Midl>
<Midl Include="PaletteItemTemplateSelector.idl" />
<Midl Include="TabBase.idl" />
<Midl Include="EmptyStringVisibilityConverter.idl" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
@@ -187,4 +185,4 @@
<Filter>app</Filter>
</ApplicationDefinition>
</ItemGroup>
</Project>
</Project>

View File

@@ -5,6 +5,7 @@
#include "pch.h"
#include "TerminalPage.h"
#include "TerminalPage.g.cpp"
#include "LastTabClosedEventArgs.g.cpp"
#include "RenameWindowRequestedArgs.g.cpp"
#include "RequestMoveContentArgs.g.cpp"
#include "RequestReceiveContentArgs.g.cpp"
@@ -282,6 +283,8 @@ namespace winrt::TerminalApp::implementation
_defaultPointerCursor = CoreWindow::GetForCurrentThread().PointerCursor();
}
CATCH_LOG();
ShowSetAsDefaultInfoBar();
}
Windows::UI::Xaml::Automation::Peers::AutomationPeer TerminalPage::OnCreateAutomationPeer()
@@ -653,9 +656,9 @@ namespace winrt::TerminalApp::implementation
// GH#12267: Make sure that we don't instantly close ourselves when
// we're readying to accept a defterm connection. In that case, we don't
// have a tab yet, but will once we're initialized.
if (_tabs.Size() == 0 && !_shouldStartInboundListener && !_isEmbeddingInboundListener)
if (_tabs.Size() == 0 && !(_shouldStartInboundListener || _isEmbeddingInboundListener))
{
_CloseWindowRequestedHandlers(*this, nullptr);
_LastTabClosedHandlers(*this, winrt::make<LastTabClosedEventArgs>(false));
co_return;
}
else
@@ -1030,9 +1033,10 @@ namespace winrt::TerminalApp::implementation
// If there's an icon set for this profile, set it as the icon for
// this flyout item
if (!profile.Icon().empty())
const auto& iconPath = profile.EvaluatedIcon();
if (!iconPath.empty())
{
const auto icon = _CreateNewTabFlyoutIcon(profile.Icon());
const auto icon = _CreateNewTabFlyoutIcon(iconPath);
profileMenuItem.Icon(icon);
}
@@ -1097,7 +1101,7 @@ namespace winrt::TerminalApp::implementation
return nullptr;
}
auto icon = IconPathConverter::IconWUX(iconSource);
auto icon = UI::IconPathConverter::IconWUX(iconSource);
Automation::AutomationProperties::SetAccessibilityView(icon, Automation::Peers::AccessibilityView::Raw);
return icon;
@@ -1207,7 +1211,7 @@ namespace winrt::TerminalApp::implementation
TerminalConnection::ITerminalConnection connection{ nullptr };
auto connectionType = profile.ConnectionType();
winrt::guid sessionGuid{};
Windows::Foundation::Collections::ValueSet valueSet;
if (connectionType == TerminalConnection::AzureConnection::ConnectionType() &&
TerminalConnection::AzureConnection::IsAzureConnectionAvailable())
@@ -1223,23 +1227,16 @@ namespace winrt::TerminalApp::implementation
connection = TerminalConnection::ConptyConnection{};
}
auto valueSet = TerminalConnection::ConptyConnection::CreateSettings(azBridgePath.native(),
L".",
L"Azure",
false,
L"",
nullptr,
settings.InitialRows(),
settings.InitialCols(),
winrt::guid(),
profile.Guid());
if constexpr (Feature_VtPassthroughMode::IsEnabled())
{
valueSet.Insert(L"passthroughMode", Windows::Foundation::PropertyValue::CreateBoolean(settings.VtPassthrough()));
}
connection.Initialize(valueSet);
valueSet = TerminalConnection::ConptyConnection::CreateSettings(azBridgePath.native(),
L".",
L"Azure",
false,
L"",
nullptr,
settings.InitialRows(),
settings.InitialCols(),
winrt::guid(),
profile.Guid());
}
else
@@ -1264,38 +1261,38 @@ namespace winrt::TerminalApp::implementation
// process until later, on another thread, after we've already
// restored the CWD to its original value.
auto newWorkingDirectory{ _evaluatePathForCwd(settings.StartingDirectory()) };
auto conhostConn = TerminalConnection::ConptyConnection();
auto valueSet = TerminalConnection::ConptyConnection::CreateSettings(settings.Commandline(),
newWorkingDirectory,
settings.StartingTitle(),
settings.ReloadEnvironmentVariables(),
_WindowProperties.VirtualEnvVars(),
environment,
settings.InitialRows(),
settings.InitialCols(),
winrt::guid(),
profile.Guid());
valueSet.Insert(L"passthroughMode", Windows::Foundation::PropertyValue::CreateBoolean(settings.VtPassthrough()));
connection = TerminalConnection::ConptyConnection{};
valueSet = TerminalConnection::ConptyConnection::CreateSettings(settings.Commandline(),
newWorkingDirectory,
settings.StartingTitle(),
settings.ReloadEnvironmentVariables(),
_WindowProperties.VirtualEnvVars(),
environment,
settings.InitialRows(),
settings.InitialCols(),
winrt::guid(),
profile.Guid());
if (inheritCursor)
{
valueSet.Insert(L"inheritCursor", Windows::Foundation::PropertyValue::CreateBoolean(true));
}
conhostConn.Initialize(valueSet);
sessionGuid = conhostConn.Guid();
connection = conhostConn;
}
if constexpr (Feature_VtPassthroughMode::IsEnabled())
{
valueSet.Insert(L"passthroughMode", Windows::Foundation::PropertyValue::CreateBoolean(settings.VtPassthrough()));
}
connection.Initialize(valueSet);
TraceLoggingWrite(
g_hTerminalAppProvider,
"ConnectionCreated",
TraceLoggingDescription("Event emitted upon the creation of a connection"),
TraceLoggingGuid(connectionType, "ConnectionTypeGuid", "The type of the connection"),
TraceLoggingGuid(profile.Guid(), "ProfileGuid", "The profile's GUID"),
TraceLoggingGuid(sessionGuid, "SessionGuid", "The WT_SESSION's GUID"),
TraceLoggingGuid(connection.SessionId(), "SessionGuid", "The WT_SESSION's GUID"),
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
@@ -1899,11 +1896,19 @@ namespace winrt::TerminalApp::implementation
}
}
void TerminalPage::PersistState()
// Method Description:
// - Saves the window position and tab layout to the application state
// - This does not create the InitialPosition field, that needs to be
// added externally.
// Arguments:
// - <none>
// Return Value:
// - the window layout
WindowLayout TerminalPage::GetWindowLayout()
{
if (_startupState != StartupState::Initialized)
{
return;
return nullptr;
}
std::vector<ActionAndArgs> actions;
@@ -1911,7 +1916,7 @@ namespace winrt::TerminalApp::implementation
for (auto tab : _tabs)
{
auto t = winrt::get_self<implementation::TabBase>(tab);
auto tabActions = t->BuildStartupActions(BuildStartupKind::Persist);
auto tabActions = t->BuildStartupActions();
actions.insert(actions.end(), std::make_move_iterator(tabActions.begin()), std::make_move_iterator(tabActions.end()));
}
@@ -1938,7 +1943,7 @@ namespace winrt::TerminalApp::implementation
actions.emplace_back(std::move(action));
}
WindowLayout layout;
WindowLayout layout{};
layout.TabLayout(winrt::single_threaded_vector<ActionAndArgs>(std::move(actions)));
auto mode = LaunchMode::DefaultMode;
@@ -1955,15 +1960,20 @@ namespace winrt::TerminalApp::implementation
layout.InitialSize(windowSize);
ApplicationState::SharedInstance().AppendPersistedWindowLayout(layout);
return layout;
}
// Method Description:
// - Close the terminal app. If there is more
// than one tab opened, show a warning dialog.
fire_and_forget TerminalPage::CloseWindow()
// Arguments:
// - bypassDialog: if true a dialog won't be shown even if the user would
// normally get confirmation. This is used in the case where the user
// has already been prompted by the Quit action.
fire_and_forget TerminalPage::CloseWindow(bool bypassDialog)
{
if (_HasMultipleTabs() &&
if (!bypassDialog &&
_HasMultipleTabs() &&
_settings.GlobalSettings().ConfirmCloseAllTabs() &&
!_displayingCloseDialog)
{
@@ -1982,7 +1992,15 @@ namespace winrt::TerminalApp::implementation
}
}
_CloseWindowRequestedHandlers(*this, nullptr);
if (_settings.GlobalSettings().ShouldUsePersistedLayout())
{
// Don't delete the ApplicationState when all of the tabs are removed.
// If there is still a monarch living they will get the event that
// a window closed and trigger a new save without this window.
_maintainStateOnTabClose = true;
}
_RemoveAllTabs();
}
// Method Description:
@@ -2044,7 +2062,7 @@ namespace winrt::TerminalApp::implementation
{
if (const auto pane{ terminalTab->GetActivePane() })
{
auto startupActions = pane->BuildStartupActions(0, 1, BuildStartupKind::MovePane);
auto startupActions = pane->BuildStartupActions(0, 1, true, true);
_DetachPaneFromWindow(pane);
_MoveContent(std::move(startupActions.args), windowId, tabIdx);
focusedTab->DetachPane();
@@ -2186,7 +2204,7 @@ namespace winrt::TerminalApp::implementation
if (tab)
{
auto startupActions = tab->BuildStartupActions(BuildStartupKind::Content);
auto startupActions = tab->BuildStartupActions(true);
_DetachTabFromWindow(tab);
_MoveContent(std::move(startupActions), windowId, 0);
_RemoveTab(*tab);
@@ -3844,6 +3862,9 @@ namespace winrt::TerminalApp::implementation
// Request a summon of this window to the foreground
_SummonWindowRequestedHandlers(*this, nullptr);
const IInspectable unused{ nullptr };
_SetAsDefaultDismissHandler(unused, unused);
// TEMPORARY SOLUTION
// If the connection has requested for the window to be maximized,
// manually maximize it here. Ideally, we should be _initializing_
@@ -4025,6 +4046,35 @@ namespace winrt::TerminalApp::implementation
}
}
// Method Description:
// - Displays a info popup guiding the user into setting their default terminal.
void TerminalPage::ShowSetAsDefaultInfoBar() const
{
if (::winrt::Windows::UI::Xaml::Application::Current().try_as<::winrt::TerminalApp::App>() == nullptr)
{
// Just ignore this in the tests (where the Application::Current()
// is not a TerminalApp::App)
return;
}
if (!CascadiaSettings::IsDefaultTerminalAvailable() || _IsMessageDismissed(InfoBarMessage::SetAsDefault))
{
return;
}
// If the user has already configured any terminal for hand-off we
// shouldn't inform them again about the possibility to do so.
if (CascadiaSettings::IsDefaultTerminalSet())
{
_DismissMessage(InfoBarMessage::SetAsDefault);
return;
}
if (const auto infoBar = FindName(L"SetAsDefaultInfoBar").try_as<MUX::Controls::InfoBar>())
{
infoBar.IsOpen(true);
}
}
// Function Description:
// - Helper function to get the OS-localized name for the "Touch Keyboard
// and Handwriting Panel Service". If we can't open up the service for any
@@ -4486,6 +4536,40 @@ namespace winrt::TerminalApp::implementation
}
}
// Method Description:
// - Persists the user's choice not to show the information bar warning about "Windows Terminal can be set as your default terminal application"
// Then hides this information buffer.
// Arguments:
// - <none>
// Return Value:
// - <none>
void TerminalPage::_SetAsDefaultDismissHandler(const IInspectable& /*sender*/, const IInspectable& /*args*/)
{
_DismissMessage(InfoBarMessage::SetAsDefault);
if (const auto infoBar = FindName(L"SetAsDefaultInfoBar").try_as<MUX::Controls::InfoBar>())
{
infoBar.IsOpen(false);
}
TraceLoggingWrite(g_hTerminalAppProvider, "SetAsDefaultTipDismissed", TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
_FocusCurrentTab(true);
}
// Method Description:
// - Dismisses the Default Terminal tip and opens the settings.
void TerminalPage::_SetAsDefaultOpenSettingsHandler(const IInspectable& /*sender*/, const IInspectable& /*args*/)
{
if (const auto infoBar = FindName(L"SetAsDefaultInfoBar").try_as<MUX::Controls::InfoBar>())
{
infoBar.IsOpen(false);
}
TraceLoggingWrite(g_hTerminalAppProvider, "SetAsDefaultTipInteracted", TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
OpenSettingsUI();
}
// Method Description:
// - Checks whether information bar message was dismissed earlier (in the application state)
// Arguments:
@@ -4841,7 +4925,7 @@ namespace winrt::TerminalApp::implementation
if (!icon.empty())
{
auto iconElement = IconPathConverter::IconWUX(icon);
auto iconElement = UI::IconPathConverter::IconWUX(icon);
Automation::AutomationProperties::SetAccessibilityView(iconElement, Automation::Peers::AccessibilityView::Raw);
button.Icon(iconElement);
}
@@ -5113,7 +5197,7 @@ namespace winrt::TerminalApp::implementation
const uint32_t tabIndex,
std::optional<til::point> dragPoint)
{
auto startupActions = _stashed.draggedTab->BuildStartupActions(BuildStartupKind::Content);
auto startupActions = _stashed.draggedTab->BuildStartupActions(true);
_DetachTabFromWindow(_stashed.draggedTab);
_MoveContent(std::move(startupActions), windowId, tabIndex, dragPoint);

View File

@@ -7,6 +7,7 @@
#include "TerminalTab.h"
#include "AppKeyBindings.h"
#include "AppCommandlineArgs.h"
#include "LastTabClosedEventArgs.g.h"
#include "RenameWindowRequestedArgs.g.h"
#include "RequestMoveContentArgs.g.h"
#include "RequestReceiveContentArgs.g.h"
@@ -43,6 +44,15 @@ namespace winrt::TerminalApp::implementation
ScrollDown = 1
};
struct LastTabClosedEventArgs : LastTabClosedEventArgsT<LastTabClosedEventArgs>
{
WINRT_PROPERTY(bool, ClearPersistedState);
public:
LastTabClosedEventArgs(const bool& shouldClear) :
_ClearPersistedState{ shouldClear } {};
};
struct RenameWindowRequestedArgs : RenameWindowRequestedArgsT<RenameWindowRequestedArgs>
{
WINRT_PROPERTY(winrt::hstring, ProposedName);
@@ -95,6 +105,7 @@ namespace winrt::TerminalApp::implementation
bool ShouldImmediatelyHandoffToElevated(const Microsoft::Terminal::Settings::Model::CascadiaSettings& settings) const;
void HandoffToElevated(const Microsoft::Terminal::Settings::Model::CascadiaSettings& settings);
Microsoft::Terminal::Settings::Model::WindowLayout GetWindowLayout();
hstring Title();
@@ -110,8 +121,7 @@ namespace winrt::TerminalApp::implementation
SuggestionsControl LoadSuggestionsUI();
winrt::fire_and_forget RequestQuit();
winrt::fire_and_forget CloseWindow();
void PersistState();
winrt::fire_and_forget CloseWindow(bool bypassDialog);
void ToggleFocusMode();
void ToggleFullscreen();
@@ -135,6 +145,7 @@ namespace winrt::TerminalApp::implementation
winrt::TerminalApp::TaskbarState TaskbarState() const;
void ShowKeyboardServiceWarning() const;
void ShowSetAsDefaultInfoBar() const;
winrt::hstring KeyboardServiceDisabledText();
winrt::fire_and_forget IdentifyWindow();
@@ -165,7 +176,7 @@ namespace winrt::TerminalApp::implementation
// -------------------------------- WinRT Events ---------------------------------
TYPED_EVENT(TitleChanged, IInspectable, winrt::hstring);
TYPED_EVENT(CloseWindowRequested, IInspectable, IInspectable);
TYPED_EVENT(LastTabClosed, IInspectable, winrt::TerminalApp::LastTabClosedEventArgs);
TYPED_EVENT(SetTitleBarContent, IInspectable, winrt::Windows::UI::Xaml::UIElement);
TYPED_EVENT(FocusModeChanged, IInspectable, IInspectable);
TYPED_EVENT(FullscreenChanged, IInspectable, IInspectable);
@@ -222,6 +233,7 @@ namespace winrt::TerminalApp::implementation
std::optional<uint32_t> _loadFromPersistedLayoutIdx{};
bool _maintainStateOnTabClose{ false };
bool _rearranging{ false };
std::optional<int> _rearrangeFrom{};
std::optional<int> _rearrangeTo{};
@@ -338,6 +350,7 @@ namespace winrt::TerminalApp::implementation
void _DismissTabContextMenus();
void _FocusCurrentTab(const bool focusAlways);
bool _HasMultipleTabs() const;
void _RemoveAllTabs();
void _SelectNextTab(const bool bMoveRight, const Windows::Foundation::IReference<Microsoft::Terminal::Settings::Model::TabSwitcherMode>& customTabSwitcherMode);
bool _SelectTab(uint32_t tabIndex);
@@ -494,6 +507,8 @@ namespace winrt::TerminalApp::implementation
winrt::fire_and_forget _ConnectionStateChangedHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args) const;
void _CloseOnExitInfoDismissHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args) const;
void _KeyboardServiceWarningInfoDismissHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args) const;
void _SetAsDefaultDismissHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args);
void _SetAsDefaultOpenSettingsHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args);
static bool _IsMessageDismissed(const winrt::Microsoft::Terminal::Settings::Model::InfoBarMessage& message);
static void _DismissMessage(const winrt::Microsoft::Terminal::Settings::Model::InfoBarMessage& message);

View File

@@ -1,7 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import "TaskbarState.idl";
import "IDirectKeyListener.idl";
namespace TerminalApp
{
@@ -15,6 +14,11 @@ namespace TerminalApp
void Detach(Microsoft.Terminal.Control.TermControl control);
}
[default_interface] runtimeclass LastTabClosedEventArgs
{
Boolean ClearPersistedState { get; };
};
[default_interface] runtimeclass RenameWindowRequestedArgs
{
String ProposedName { get; };
@@ -52,7 +56,7 @@ namespace TerminalApp
Boolean IsQuakeWindow();
};
[default_interface] runtimeclass TerminalPage : Windows.UI.Xaml.Controls.Page, Windows.UI.Xaml.Data.INotifyPropertyChanged, IDirectKeyListener
[default_interface] runtimeclass TerminalPage : Windows.UI.Xaml.Controls.Page, Windows.UI.Xaml.Data.INotifyPropertyChanged, Microsoft.Terminal.UI.IDirectKeyListener
{
TerminalPage(WindowProperties properties, ContentManager manager);
@@ -82,7 +86,7 @@ namespace TerminalApp
void SendContentToOther(RequestReceiveContentArgs args);
event Windows.Foundation.TypedEventHandler<Object, String> TitleChanged;
event Windows.Foundation.TypedEventHandler<Object, Object> CloseWindowRequested;
event Windows.Foundation.TypedEventHandler<Object, LastTabClosedEventArgs> LastTabClosed;
event Windows.Foundation.TypedEventHandler<Object, Windows.UI.Xaml.UIElement> SetTitleBarContent;
event Windows.Foundation.TypedEventHandler<Object, Object> FocusModeChanged;
event Windows.Foundation.TypedEventHandler<Object, Object> FullscreenChanged;

View File

@@ -53,6 +53,21 @@
Click="_CloseOnExitInfoDismissHandler" />
</mux:InfoBar.ActionButton>
</mux:InfoBar>
<mux:InfoBar x:Name="SetAsDefaultInfoBar"
x:Uid="SetAsDefaultInfoBar"
x:Load="False"
CloseButtonClick="_SetAsDefaultDismissHandler"
CornerRadius="0"
IsClosable="True"
IsIconVisible="True"
IsOpen="False"
Severity="Informational">
<mux:InfoBar.ActionButton>
<HyperlinkButton x:Uid="SetAsDefaultTip_OpenSettingsLink"
Click="_SetAsDefaultOpenSettingsHandler" />
</mux:InfoBar.ActionButton>
</mux:InfoBar>
</StackPanel>
<Grid x:Name="TabContent"

View File

@@ -304,7 +304,7 @@ namespace winrt::TerminalApp::implementation
{
Icon(_lastIconPath);
bool isMonochrome = iconStyle == IconStyle::Monochrome;
TabViewItem().IconSource(IconPathConverter::IconSourceMUX(_lastIconPath, isMonochrome));
TabViewItem().IconSource(Microsoft::Terminal::UI::IconPathConverter::IconSourceMUX(_lastIconPath, isMonochrome));
}
}
@@ -327,7 +327,7 @@ namespace winrt::TerminalApp::implementation
else
{
Icon(_lastIconPath);
TabViewItem().IconSource(IconPathConverter::IconSourceMUX(_lastIconPath, _lastIconStyle == IconStyle::Monochrome));
TabViewItem().IconSource(Microsoft::Terminal::UI::IconPathConverter::IconSourceMUX(_lastIconPath, _lastIconStyle == IconStyle::Monochrome));
}
_iconHidden = hide;
}
@@ -427,18 +427,18 @@ namespace winrt::TerminalApp::implementation
// - <none>
// Return Value:
// - A vector of commands
std::vector<ActionAndArgs> TerminalTab::BuildStartupActions(BuildStartupKind kind) const
std::vector<ActionAndArgs> TerminalTab::BuildStartupActions(const bool asContent) const
{
ASSERT_UI_THREAD();
// Give initial ids (0 for the child created with this tab,
// 1 for the child after the first split.
auto state = _rootPane->BuildStartupActions(0, 1, kind);
auto state = _rootPane->BuildStartupActions(0, 1, asContent);
{
ActionAndArgs newTabAction{};
newTabAction.Action(ShortcutAction::NewTab);
NewTabArgs newTabArgs{ state.firstPane->GetTerminalArgsForPane(kind) };
NewTabArgs newTabArgs{ state.firstPane->GetTerminalArgsForPane(asContent) };
newTabAction.Args(newTabArgs);
state.args.emplace(state.args.begin(), std::move(newTabAction));
@@ -1321,7 +1321,7 @@ namespace winrt::TerminalApp::implementation
{
auto weakThis{ get_weak() };
// "Change tab color..."
// "Color..."
Controls::MenuFlyoutItem chooseColorMenuItem;
{
Controls::FontIcon colorPickSymbol;
@@ -1340,7 +1340,7 @@ namespace winrt::TerminalApp::implementation
Controls::MenuFlyoutItem renameTabMenuItem;
{
// "Rename tab"
// "Rename Tab"
Controls::FontIcon renameTabSymbol;
renameTabSymbol.FontFamily(Media::FontFamily{ L"Segoe Fluent Icons, Segoe MDL2 Assets" });
renameTabSymbol.Glyph(L"\xE8AC"); // Rename
@@ -1357,7 +1357,7 @@ namespace winrt::TerminalApp::implementation
Controls::MenuFlyoutItem duplicateTabMenuItem;
{
// "Duplicate tab"
// "Duplicate Tab"
Controls::FontIcon duplicateTabSymbol;
duplicateTabSymbol.FontFamily(Media::FontFamily{ L"Segoe Fluent Icons, Segoe MDL2 Assets" });
duplicateTabSymbol.Glyph(L"\xF5ED");
@@ -1374,7 +1374,7 @@ namespace winrt::TerminalApp::implementation
Controls::MenuFlyoutItem splitTabMenuItem;
{
// "Split tab"
// "Split Tab"
Controls::FontIcon splitTabSymbol;
splitTabSymbol.FontFamily(Media::FontFamily{ L"Segoe Fluent Icons, Segoe MDL2 Assets" });
splitTabSymbol.Glyph(L"\xF246"); // ViewDashboard
@@ -1391,7 +1391,7 @@ namespace winrt::TerminalApp::implementation
Controls::MenuFlyoutItem moveTabToNewWindowMenuItem;
{
// "Move tab to new window"
// "Move Tab to New Window"
Controls::FontIcon moveTabToNewWindowTabSymbol;
moveTabToNewWindowTabSymbol.FontFamily(Media::FontFamily{ L"Segoe Fluent Icons, Segoe MDL2 Assets" });
moveTabToNewWindowTabSymbol.Glyph(L"\xE8A7");
@@ -1408,7 +1408,7 @@ namespace winrt::TerminalApp::implementation
Controls::MenuFlyoutItem closePaneMenuItem = _closePaneMenuItem;
{
// "Close pane"
// "Close Pane"
closePaneMenuItem.Click({ get_weak(), &TerminalTab::_closePaneClicked });
closePaneMenuItem.Text(RS_(L"ClosePaneText"));
@@ -1420,7 +1420,7 @@ namespace winrt::TerminalApp::implementation
Controls::MenuFlyoutItem exportTabMenuItem;
{
// "Export tab"
// "Export Tab"
Controls::FontIcon exportTabSymbol;
exportTabSymbol.FontFamily(Media::FontFamily{ L"Segoe Fluent Icons, Segoe MDL2 Assets" });
exportTabSymbol.Glyph(L"\xE74E"); // Save
@@ -1454,7 +1454,7 @@ namespace winrt::TerminalApp::implementation
Controls::MenuFlyoutItem restartConnectionMenuItem = _restartConnectionMenuItem;
{
// "Restart connection"
// "Restart Connection"
Controls::FontIcon restartConnectionSymbol;
restartConnectionSymbol.FontFamily(Media::FontFamily{ L"Segoe Fluent Icons, Segoe MDL2 Assets" });
restartConnectionSymbol.Glyph(L"\xE72C");

View File

@@ -78,7 +78,7 @@ namespace winrt::TerminalApp::implementation
void EnterZoom();
void ExitZoom();
std::vector<Microsoft::Terminal::Settings::Model::ActionAndArgs> BuildStartupActions(BuildStartupKind kind) const override;
std::vector<Microsoft::Terminal::Settings::Model::ActionAndArgs> BuildStartupActions(const bool asContent = false) const override;
int GetLeafPaneCount() const noexcept;

View File

@@ -267,7 +267,7 @@ namespace winrt::TerminalApp::implementation
{
if (_root)
{
_root->PersistState();
_root->CloseWindow(true);
}
}
@@ -863,7 +863,7 @@ namespace winrt::TerminalApp::implementation
auto focusedObject{ Windows::UI::Xaml::Input::FocusManager::GetFocusedElement(xamlRoot) };
do
{
if (auto keyListener{ focusedObject.try_as<IDirectKeyListener>() })
if (auto keyListener{ focusedObject.try_as<UI::IDirectKeyListener>() })
{
if (keyListener.OnDirectKeyEvent(vkey, scanCode, down))
{
@@ -891,7 +891,7 @@ namespace winrt::TerminalApp::implementation
// don't want to go around the loop again.
if (!focusedObject)
{
if (auto keyListener{ _root.try_as<IDirectKeyListener>() })
if (auto keyListener{ _root.try_as<UI::IDirectKeyListener>() })
{
return keyListener.OnDirectKeyEvent(vkey, scanCode, down);
}
@@ -916,11 +916,32 @@ namespace winrt::TerminalApp::implementation
// - <none>
// Return Value:
// - <none>
void TerminalWindow::CloseWindow()
void TerminalWindow::CloseWindow(LaunchPosition pos, const bool isLastWindow)
{
if (_root)
{
_root->CloseWindow();
// If persisted layout is enabled and we are the last window closing
// we should save our state.
if (_settings.GlobalSettings().ShouldUsePersistedLayout() && isLastWindow)
{
if (const auto layout = _root->GetWindowLayout())
{
layout.InitialPosition(pos);
const auto state = ApplicationState::SharedInstance();
state.PersistedWindowLayouts(winrt::single_threaded_vector<WindowLayout>({ layout }));
}
}
_root->CloseWindow(false);
}
}
void TerminalWindow::ClearPersistedWindowState()
{
if (_settings.GlobalSettings().ShouldUsePersistedLayout())
{
auto state = ApplicationState::SharedInstance();
state.PersistedWindowLayouts(nullptr);
}
}
@@ -1113,6 +1134,19 @@ namespace winrt::TerminalApp::implementation
return winrt::to_hstring(_appArgs.GetExitMessage());
}
hstring TerminalWindow::GetWindowLayoutJson(LaunchPosition position)
{
if (_root != nullptr)
{
if (const auto layout = _root->GetWindowLayout())
{
layout.InitialPosition(position);
return WindowLayout::ToJson(layout);
}
}
return L"";
}
void TerminalWindow::SetPersistedLayoutIdx(const uint32_t idx)
{
_loadFromPersistedLayoutIdx = idx;

View File

@@ -95,6 +95,8 @@ namespace winrt::TerminalApp::implementation
bool AlwaysOnTop() const;
bool AutoHideWindow();
hstring GetWindowLayoutJson(Microsoft::Terminal::Settings::Model::LaunchPosition position);
void IdentifyWindow();
void RenameFailed();
@@ -102,6 +104,9 @@ namespace winrt::TerminalApp::implementation
winrt::Microsoft::Terminal::Settings::Model::WindowLayout LoadPersistedLayout();
void SetPersistedLayoutIdx(const uint32_t idx);
void SetNumberOfOpenWindows(const uint64_t num);
bool ShouldUsePersistedLayout() const;
void ClearPersistedWindowState();
void RequestExitFullscreen();
@@ -120,7 +125,7 @@ namespace winrt::TerminalApp::implementation
void TitlebarClicked();
bool OnDirectKeyEvent(const uint32_t vkey, const uint8_t scanCode, const bool down);
void CloseWindow();
void CloseWindow(Microsoft::Terminal::Settings::Model::LaunchPosition position, const bool isLastWindow);
void WindowVisibilityChanged(const bool showOrHide);
winrt::TerminalApp::TaskbarState TaskbarState();
@@ -210,7 +215,7 @@ namespace winrt::TerminalApp::implementation
FORWARDED_TYPED_EVENT(SetTitleBarContent, winrt::Windows::Foundation::IInspectable, winrt::Windows::UI::Xaml::UIElement, _root, SetTitleBarContent);
FORWARDED_TYPED_EVENT(TitleChanged, winrt::Windows::Foundation::IInspectable, winrt::hstring, _root, TitleChanged);
FORWARDED_TYPED_EVENT(CloseWindowRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, CloseWindowRequested);
FORWARDED_TYPED_EVENT(LastTabClosed, winrt::Windows::Foundation::IInspectable, winrt::TerminalApp::LastTabClosedEventArgs, _root, LastTabClosed);
FORWARDED_TYPED_EVENT(FocusModeChanged, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, FocusModeChanged);
FORWARDED_TYPED_EVENT(FullscreenChanged, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, FullscreenChanged);
FORWARDED_TYPED_EVENT(ChangeMaximizeRequested, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, ChangeMaximizeRequested);

View File

@@ -3,7 +3,6 @@
import "TerminalPage.idl";
import "ShortcutActionDispatch.idl";
import "IDirectKeyListener.idl";
namespace TerminalApp
{
@@ -40,7 +39,7 @@ namespace TerminalApp
// See IDialogPresenter and TerminalPage's DialogPresenter for more
// information.
[default_interface] runtimeclass TerminalWindow : IDirectKeyListener, IDialogPresenter, Windows.UI.Xaml.Data.INotifyPropertyChanged
[default_interface] runtimeclass TerminalWindow : Microsoft.Terminal.UI.IDirectKeyListener, IDialogPresenter, Windows.UI.Xaml.Data.INotifyPropertyChanged
{
TerminalWindow(SettingsLoadEventArgs result, ContentManager manager);
@@ -75,6 +74,7 @@ namespace TerminalApp
void IdentifyWindow();
void SetPersistedLayoutIdx(UInt32 idx);
void ClearPersistedWindowState();
void RenameFailed();
void RequestExitFullscreen();
@@ -89,7 +89,7 @@ namespace TerminalApp
Boolean GetInitialAlwaysOnTop();
Single CalcSnappedDimension(Boolean widthOrHeight, Single dimension);
void TitlebarClicked();
void CloseWindow();
void CloseWindow(Microsoft.Terminal.Settings.Model.LaunchPosition position, Boolean isLastWindow);
void WindowVisibilityChanged(Boolean showOrHide);
TaskbarState TaskbarState{ get; };
@@ -97,6 +97,8 @@ namespace TerminalApp
Windows.UI.Xaml.Media.Brush FrameBrush { get; };
void WindowActivated(Boolean activated);
String GetWindowLayoutJson(Microsoft.Terminal.Settings.Model.LaunchPosition position);
Boolean GetMinimizeToNotificationArea();
Boolean GetAlwaysShowNotificationIcon();
Boolean GetShowTitleInTitlebar();
@@ -116,7 +118,7 @@ namespace TerminalApp
event Windows.Foundation.TypedEventHandler<Object, Windows.UI.Xaml.UIElement> SetTitleBarContent;
event Windows.Foundation.TypedEventHandler<Object, String> TitleChanged;
event Windows.Foundation.TypedEventHandler<Object, Object> CloseWindowRequested;
event Windows.Foundation.TypedEventHandler<Object, LastTabClosedEventArgs> LastTabClosed;
event Windows.Foundation.TypedEventHandler<Object, Microsoft.Terminal.Settings.Model.Theme> RequestedThemeChanged;
event Windows.Foundation.TypedEventHandler<Object, Object> FocusModeChanged;
event Windows.Foundation.TypedEventHandler<Object, Object> FullscreenChanged;

View File

@@ -68,8 +68,15 @@
include Settings and Connection, since Control will include them for us) -->
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalConnection\TerminalConnection.vcxproj" />
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalControl\dll\TerminalControl.vcxproj" />
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\ITerminalCore\ITerminalCore.vcxproj">
<Private>false</Private>
<Project>{40503EDC-E3E4-46AB-BC26-D293B956CAE8}</Project>
</ProjectReference>
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalSettingsEditor\Microsoft.Terminal.Settings.Editor.vcxproj" />
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalSettingsModel\dll\Microsoft.Terminal.Settings.Model.vcxproj" />
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\UIHelpers\UIHelpers.vcxproj">
<Project>{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}</Project>
</ProjectReference>
<!-- Reference TerminalAppLib here, so we can use its TerminalApp.winmd as
our TerminalApp.winmd. This didn't work correctly in VS2017, you'd need to
manually reference the lib -->
@@ -80,18 +87,6 @@
</ItemGroup>
<ItemGroup>
<!-- Manually include the Terminal.Core winmd, so we know where those types
are defined. We don't want to include it as a project reference, because
that would make us link that lib into our own binary. -->
<Reference Include="Microsoft.Terminal.Core">
<HintPath>$(OpenConsoleCommonOutDir)TerminalCore\Microsoft.Terminal.Core.winmd</HintPath>
<IsWinMDFile>true</IsWinMDFile>
<Private>false</Private>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
</Reference>
</ItemGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(OpenConsoleDir)\dep\jsoncpp\json;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>

View File

@@ -60,6 +60,7 @@
#include <winrt/Microsoft.Terminal.TerminalConnection.h>
#include <winrt/Microsoft.Terminal.Settings.Editor.h>
#include <winrt/Microsoft.Terminal.Settings.Model.h>
#include <winrt/Microsoft.Terminal.UI.h>
#include <winrt/Windows.Services.Store.h>
#include <winrt/Windows.Storage.h>
#include <winrt/Windows.Storage.Provider.h>

View File

@@ -65,20 +65,18 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
return AzureConnectionType;
}
// This function exists because the clientID only gets added by the release pipelines
// and is not available on local builds, so we want to be able to make sure we don't
// try to make an Azure connection if its a local build
bool AzureConnection::IsAzureConnectionAvailable() noexcept
{
return (AzureClientID != L"0");
}
void AzureConnection::Initialize(const Windows::Foundation::Collections::ValueSet& settings)
{
if (settings)
{
_initialRows = gsl::narrow<til::CoordType>(winrt::unbox_value_or<uint32_t>(settings.TryLookup(L"initialRows").try_as<Windows::Foundation::IPropertyValue>(), _initialRows));
_initialCols = gsl::narrow<til::CoordType>(winrt::unbox_value_or<uint32_t>(settings.TryLookup(L"initialCols").try_as<Windows::Foundation::IPropertyValue>(), _initialCols));
_initialRows = unbox_prop_or<uint32_t>(settings, L"initialRows", _initialRows);
_initialCols = unbox_prop_or<uint32_t>(settings, L"initialCols", _initialCols);
_sessionId = unbox_prop_or<guid>(settings, L"sessionId", _sessionId);
}
if (_sessionId == guid{})
{
_sessionId = Utils::CreateGuid();
}
}

View File

@@ -8,15 +8,14 @@
#include <mutex>
#include <condition_variable>
#include "ConnectionStateHolder.h"
#include "BaseTerminalConnection.h"
#include "AzureClient.h"
namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
{
struct AzureConnection : AzureConnectionT<AzureConnection>, ConnectionStateHolder<AzureConnection>
struct AzureConnection : AzureConnectionT<AzureConnection>, BaseTerminalConnection<AzureConnection>
{
static winrt::guid ConnectionType() noexcept;
static bool IsAzureConnectionAvailable() noexcept;
AzureConnection() = default;
void Initialize(const Windows::Foundation::Collections::ValueSet& settings);

View File

@@ -1,14 +1,11 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import "ITerminalConnection.idl";
namespace Microsoft.Terminal.TerminalConnection
{
[default_interface] runtimeclass AzureConnection : ITerminalConnection
{
static Guid ConnectionType { get; };
static Boolean IsAzureConnectionAvailable();
AzureConnection();
};

View File

@@ -4,13 +4,28 @@
namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
{
template<typename T>
struct ConnectionStateHolder
struct BaseTerminalConnection
{
public:
ConnectionState State() const noexcept { return _connectionState; }
winrt::guid SessionId() const noexcept
{
return _sessionId;
}
ConnectionState State() const noexcept
{
return _connectionState;
}
TYPED_EVENT(StateChanged, ITerminalConnection, winrt::Windows::Foundation::IInspectable);
protected:
template<typename U>
U unbox_prop_or(const Windows::Foundation::Collections::ValueSet& blob, std::wstring_view key, U defaultValue)
{
return winrt::unbox_value_or<U>(blob.TryLookup(key).try_as<Windows::Foundation::IPropertyValue>(), defaultValue);
}
#pragma warning(push)
#pragma warning(disable : 26447) // Analyzer is still upset about noexcepts throwing even with function level try.
// Method Description:
@@ -86,6 +101,8 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
return _isStateOneOf(ConnectionState::Connected);
}
winrt::guid _sessionId{};
private:
std::atomic<ConnectionState> _connectionState{ ConnectionState::NotConnected };
mutable std::mutex _stateMutex;

View File

@@ -1,8 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import "ITerminalConnection.idl";
namespace Microsoft.Terminal.TerminalConnection
{
[default_interface] runtimeclass ConnectionInformation

View File

@@ -85,18 +85,12 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
auto environment = _initialEnv;
{
// Convert connection Guid to string and ignore the enclosing '{}'.
auto wsGuid{ Utils::GuidToString(_guid) };
wsGuid.pop_back();
const auto guidSubStr = std::wstring_view{ wsGuid }.substr(1);
// Ensure every connection has the unique identifier in the environment.
environment.as_map().insert_or_assign(L"WT_SESSION", guidSubStr.data());
// Convert connection Guid to string and ignore the enclosing '{}'.
environment.as_map().insert_or_assign(L"WT_SESSION", Utils::GuidToPlainString(_sessionId));
// The profile Guid does include the enclosing '{}'
const auto profileGuid{ Utils::GuidToString(_profileGuid) };
environment.as_map().insert_or_assign(L"WT_PROFILE_ID", profileGuid.data());
environment.as_map().insert_or_assign(L"WT_PROFILE_ID", Utils::GuidToString(_profileGuid));
// WSLENV is a colon-delimited list of environment variables (+flags) that should appear inside WSL
// https://devblogs.microsoft.com/commandline/share-environment-vars-between-wsl-and-windows/
@@ -104,7 +98,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
if (_environment)
{
// Order the environment variable names so that resolution order is consistent
std::set<std::wstring, til::wstring_case_insensitive_compare> keys{};
std::set<std::wstring, til::env_key_sorter> keys{};
for (const auto item : _environment)
{
keys.insert(item.Key().c_str());
@@ -171,7 +165,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
g_hTerminalConnectionProvider,
"ConPtyConnected",
TraceLoggingDescription("Event emitted when ConPTY connection is started"),
TraceLoggingGuid(_guid, "SessionGuid", "The WT_SESSION's GUID"),
TraceLoggingGuid(_sessionId, "SessionGuid", "The WT_SESSION's GUID"),
TraceLoggingWideString(_clientName.c_str(), "Client", "The attached client process"),
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
@@ -189,7 +183,6 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
TERMINAL_STARTUP_INFO startupInfo) :
_rows{ 25 },
_cols{ 80 },
_guid{ Utils::CreateGuid() },
_inPipe{ hIn },
_outPipe{ hOut }
{
@@ -249,12 +242,6 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
return vs;
}
template<typename T>
T unbox_prop_or(const Windows::Foundation::Collections::ValueSet& blob, std::wstring_view key, T defaultValue)
{
return winrt::unbox_value_or<T>(blob.TryLookup(key).try_as<Windows::Foundation::IPropertyValue>(), defaultValue);
}
void ConptyConnection::Initialize(const Windows::Foundation::Collections::ValueSet& settings)
{
if (settings)
@@ -268,7 +255,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
_startingTitle = unbox_prop_or<winrt::hstring>(settings, L"startingTitle", _startingTitle);
_rows = unbox_prop_or<uint32_t>(settings, L"initialRows", _rows);
_cols = unbox_prop_or<uint32_t>(settings, L"initialCols", _cols);
_guid = unbox_prop_or<winrt::guid>(settings, L"guid", _guid);
_sessionId = unbox_prop_or<winrt::guid>(settings, L"sessionId", _sessionId);
_environment = settings.TryLookup(L"environment").try_as<Windows::Foundation::Collections::ValueSet>();
if constexpr (Feature_VtPassthroughMode::IsEnabled())
{
@@ -299,17 +286,12 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
_initialEnv = til::env::from_current_environment();
}
}
if (_guid == guid{})
{
_guid = Utils::CreateGuid();
}
}
}
winrt::guid ConptyConnection::Guid() const noexcept
{
return _guid;
if (_sessionId == guid{})
{
_sessionId = Utils::CreateGuid();
}
}
winrt::hstring ConptyConnection::Commandline() const
@@ -382,7 +364,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
g_hTerminalConnectionProvider,
"ConPtyConnectedToDefterm",
TraceLoggingDescription("Event emitted when ConPTY connection is started, for a defterm session"),
TraceLoggingGuid(_guid, "SessionGuid", "The WT_SESSION's GUID"),
TraceLoggingGuid(_sessionId, "SessionGuid", "The WT_SESSION's GUID"),
TraceLoggingWideString(_clientName.c_str(), "Client", "The attached client process"),
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
@@ -686,7 +668,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
TraceLoggingWrite(g_hTerminalConnectionProvider,
"ReceivedFirstByte",
TraceLoggingDescription("An event emitted when the connection receives the first byte"),
TraceLoggingGuid(_guid, "SessionGuid", "The WT_SESSION's GUID"),
TraceLoggingGuid(_sessionId, "SessionGuid", "The WT_SESSION's GUID"),
TraceLoggingFloat64(delta.count(), "Duration"),
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance));

Some files were not shown because too many files have changed in this diff Show More