Compare commits

..

46 Commits

Author SHA1 Message Date
Dustin L. Howett
47da9a0502 Fix RequestLaunchPosition (e2a076c038) 2024-04-30 15:58:05 -05:00
James Holderness
12a5c95b98 Fix the DECTCEM reset position in the conpty stream (#17148)
## Summary of the Pull Request

When the conpty renderer determines that it needs to hide the cursor,
it does so by inserting a `DECTCEM` reset sequence at the start of the
output buffer, assuming that is the start of the frame. But when the
`_noFlushOnEnd` flag is set, you can have multiple frames pending in the
buffer, and the `DECTCEM` sequence will then end up in the wrong place.

This PR fixes the issue by saving the buffer size at the start of the
frame, and using that saved offset as the insert position for the
`DECTCEM` sequence.

## Validation Steps Performed

I have a game that was frequently affected by this issue (the cursor
would be visible when it was meant to be hidden). With this PR applied,
it now works perfectly.

## PR Checklist
- [x] Closes #15449

(cherry picked from commit ef318a1450)
Service-Card-Id: 92457090
Service-Version: 1.20
2024-04-30 14:26:41 -05:00
Mike Griese
fa7198de88 Fix repositioning with the cursor, again (#17141)
This shouldn't have ever worked...? This looks like it was a typo and
should have been `mark.end`.

Thanks @joadoumie for asking about the moving the cursor in the prompt,
that convo lead to me finding this.

(cherry picked from commit d14ff939dc)
Service-Card-Id: 92441646
Service-Version: 1.20
2024-04-30 14:26:39 -05:00
Dustin L. Howett
164df3c959 Revert "Properly fix ConPTY buffer corking (#16793)"
This reverts commit 275e8d115a.
2024-04-30 14:15:03 -05:00
Dustin L. Howett
743d5681cf Update Cascadia Code to 2404.23 (#17137)
This update adds support for:

- Unicode 16 Large Type Pieces (they are really cool, you *have* to see
them)
- Unicode 13 Sextants (U+1FB00 - U+1FB3B)
- Octants, sedecimants, eights, miscellanrous blocks, separated
quadrants and sextants, and diagonals
- Segmented digits (think LED numbers)
- Checkerboards

It also fixes the coordinate system used in all of the blocks,
half-blocks, quadrants and eights for consistency.

This update does **not** include the new "Nerd Fonts" variant of
Cascadia Code or Cascadia Mono.

With big thanks to @PhMajerus for contributing all of the new symbols
for legacy computing.

See microsoft/cascadia-code#723, microsoft/cascadia-code#708 and
microsoft/cascadia-code#727 for more details.

(cherry picked from commit 41bb28c46d)
Service-Card-Id: 92434845
Service-Version: 1.20
2024-04-26 11:33:08 -05:00
Mike Griese
464c0a3b3d Fix persisting the size of a focus mode window (#17068)
While I was fixing the initial position thing, I figured I'd fix this
too. We were mistakenly accounting for the size of the titlebar when we
should launch into focus mode (without one)

Closes #10730

(cherry picked from commit f36d589a8e)
Service-Card-Id: 92410732
Service-Version: 1.20
2024-04-26 11:33:06 -05:00
Dustin L. Howett
fb3147fd44 build: disable CheckCFlags for now, as it is blowing up the build (#17116)
OneBranch no likey. A test build is running now.

(cherry picked from commit 19f43f70bd)
Service-Card-Id: 92421264
Service-Version: 1.20
2024-04-26 11:33:04 -05:00
Dustin L. Howett
849766cda3 [REPLAY] Move to AzureFileCopy@6 for Managed Identity support (#17121)
This is required for us to move off Entra ID Application identity.

(cherry picked from commit 2e7c3fa313)

This was approved in #16957, so I will merge with one signoff.

(cherry picked from commit 3a63832c31)
Service-Card-Id: 92421061
Service-Version: 1.20
2024-04-26 11:33:03 -05:00
PankajBhojwani
7bb70b0330 Update Azure Cloud Shell API to the newer version (#17115)
Updates the `api-version` to `2023-02-01-preview` when requesting for
CloudShell settings and shell

## Validation Steps Performed
Can still use Azure Cloud Shell through Windows Terminal

(cherry picked from commit ce4e0df7b0)
Service-Card-Id: 92411552
Service-Version: 1.20
2024-04-26 11:33:01 -05:00
Leonard Hecker
f442109748 AtlasEngine: Fix custom shader time imprecision (#17104)
Since floats are imprecise we need to constrain the time value into a
range that can be accurately represented. Assuming a monitor refresh
rate of 1000 Hz, we can still easily represent 1000 seconds accurately
(roughly 16 minutes). So to solve this, we'll simply treat the shader
time modulo 1000s. This may lead to some unexpected jank every 16min
but it keeps any ongoing animation smooth otherwise.

(cherry picked from commit daffb2dbbf)
Service-Card-Id: 92409332
Service-Version: 1.20
2024-04-23 16:50:22 -05:00
Leonard Hecker
8c1316cf09 Fix TerminalPage not being released on window close (#17107)
Because this holds onto the root element, `TerminalPage` gets "leaked"
on Windows 10 when a window is closed until another is opened.

## Validation Steps Performed
* Set a breakpoint in `Renderer::~Renderer`
* Open and close a window
* Breakpoint used to not get hit and now it does 

(cherry picked from commit a590a1bff0)
Service-Card-Id: 92407667
Service-Version: 1.20
2024-04-23 16:49:58 -05:00
Mike Griese
e2a076c038 Also remember to persist window positions (#17066)
This got lost in #16598. `TerminalPage` needs to ask the window where
the it actually is, so it can persist it. More details in
https://github.com/microsoft/terminal/pull/16598#discussion_r1511519304

Closes #17010

(cherry picked from commit 643f7167a6)
Service-Card-Id: 92360686
Service-Version: 1.20
2024-04-23 16:49:57 -05:00
Leonard Hecker
ff99f4b7c4 [1.20] Backport session persistence improvements (#17049)
This contains all the changes of 5dda507, c4c5206, 9f08ee7, and
5f10159 (#16598 and all related PRs), but without the buffer restore
feature. The hope is that these changes fix some rarer issues
we've been hearing about, where persistence doesn't work correctly.

## Validation Steps Performed
This changeset was tested on Windows 11 with 2 windows and 4 tabs
where 1 tab had 2 mixed split panes. All windows and tabs got
restored properly. It didn't crash on Windows 10.
2024-04-23 16:47:14 -05:00
Dustin L. Howett
7637e89566 [1.20] Revert search result highlighting from stable (#17103)
This wasn't guarded under velocity, and some of the fixes are coming in
too hot to be serviced into 1.20.

Reverts PR #16227 and #16691
2024-04-23 12:00:23 -07:00
Leonard Hecker
8a6941c269 Replace WinRT clipboard API with Win32 for copying (#17006)
In the spirit of #15360 this implements the copy part.
The problem is that we have an issue accessing the clipboard while
other applications continue to work just fine. The major difference
between us and the others is that we use the WinRT clipboard APIs.
So, the idea is that we just use the Win32 APIs instead.

The feel-good side-effect is that this is (no joke) 200-1000x faster,
but I suspect no one will notice the -3ms difference down to <0.01ms.

The objective effect however is that it just works.

This may resolve #16982.

* Cycle through Text/HTML/RTF-only in the Interaction settings
* Paste the contents into Word each time
* Text is plain and HTML/RTF are colored 

(cherry picked from commit 5f3a857192)
Service-Card-Id: 92308708
Service-Version: 1.20
2024-04-22 17:27:52 -05:00
Leonard Hecker
c0b2f55b87 Add more TraceLogging to ApiDispatchers (#17085)
More TraceLogging = More better?
I made this change as I noticed that most calls are not being logged.
Even after this change some crucial information won't be logged
(for instance arrays of `INPUT_RECORD`), because I couldn't come up
with a clever way to do so, but I think this is better than nothing.

(cherry picked from commit f49cf44b79)
Service-Card-Id: 92374415
Service-Version: 1.20
2024-04-22 17:25:39 -05:00
Tushar Singh
248665b9bb Fix window style under minimized state (#17058)
Closes: #13961

This PR changes the window styling we use under the minimized state. We
now retain the active window styling so the content's height doesn't
change when switching between minimized and maximized states.

## Validation Steps Performed
- Open Terminal and go into Maximized mode.
- Click on the Minimize button.
- No `SizeChanged` event in `ControlCore`.
- Click on the WT icon in the taskbar to restore it.
- No `SizeChanged` event in `ControlCore`.

(cherry picked from commit 11c4aa459d)
Service-Card-Id: 92350319
Service-Version: 1.20
2024-04-22 17:25:32 -05:00
Mike Griese
b5b32dad19 Add a WT_SETTINGS_DIR env variable that portable profiles can use (#16949)
Basically, title.

It'd be a neat idea for portable installs of the Terminal to reference
files that are right there in the portable install.

This PR adds a `WT_SETTINGS_DIR` var to Terminal's own env block. This
allows us to resolve profiles relative to our own settings folder.

Closes #16295

(cherry picked from commit 36c81f24fb)
Service-Card-Id: 92352620
Service-Version: 1.20
2024-04-22 17:22:54 -05:00
Leonard Hecker
a2ab91f8a4 Make ploc translations predictable (#16924)
(cherry picked from commit 77d5e23ef2)
Service-Card-Id: 92350470
Service-Version: 1.20
2024-04-16 10:49:08 -05:00
Windows Console Service Bot
6e3fc69ae2 Localization Updates - main - associated with #16886 (#17035)
(cherry picked from commit f4d8a74082)
Service-Card-Id: 92350383
Service-Version: 1.20
2024-04-16 10:41:39 -05:00
Harsh Narayan Jha
485b4ab2ab Fix: UI style errors: Menu items capitalization and … (ellipses) mark misuse (#16886)
I changed the improper capitalization and misuse of ellipses mark (...)
in the context menu and various other places.

Fixes issues #16819 and #16846

## PR Checklist
- [ ] Closes #16846
- [x] Tests added/passed - NA
- [x] Documentation updated - NA
- If checked, please file a pull request on [our docs
repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
- [x] Schema updated (if necessary) - NA

(cherry picked from commit 8bd9578b3c)
Service-Card-Id: 92350387
Service-Version: 1.20
2024-04-16 10:36:49 -05:00
Windows Console Service Bot
5a4508a79c Localization Updates - main - 04/06/2024 03:04:16 (#17025)
(cherry picked from commit b90eb93d26)
Service-Card-Id: 92279783
Service-Version: 1.20
2024-04-16 10:32:44 -05:00
Dustin L. Howett
3cfd13d01d ci/rel: publish symbols using the internal symbol request API instead (#16991)
Work is ongoing to remove individually-authenticated service accounts
from some pipelines. This moves us closer to that goal.

Tested in Nightly 2403.28002.

(cherry picked from commit 2bcbe6b492)
Service-Card-Id: 92239368
Service-Version: 1.20
2024-04-16 10:32:44 -05:00
Leonard Hecker
275e8d115a Properly fix ConPTY buffer corking (#16793)
I've found that #16079 was never properly addressed (it still randomly
occurred after even after PR #16349), which later led to the issues
described in #16769 (nushell flickering due to too many flushes).

The crux of the fix is that this brings back the `_noFlushOnEnd` flag
that was removed in PR #15991. This is then combined with a change to
the cork API: An `uncork` on `VtEngine` now only flushes if `_Flush`
got called while it was corked in the first place.

`_noFlushOnEnd` prevents us from flushing in between two "unknown"
VT sequences (like soft fonts or FTCS) which prevents them from being
corrupted. The corking prevents the remaining cases of flushing too
often. Long-term, a proper fix would be to pass through VT unmodified.

Closes #16769

(cherry picked from commit 1ede023331)
Service-Card-Id: 91965217
Service-Version: 1.20
2024-04-16 10:32:44 -05:00
Dustin L. Howett
a50eba1cc9 Remove the "set default terminal" banner (#16873)
**Default Terminal**: Everyone who cares to know, knows. Everyone who
doesn't, has an annoying bar above all terminals

I had to introduce a workaround for the fact that unknown dismissed
message keys in `state.json` result in Terminal exploding on launch.
😁 That's tracked in #16874.

Closes #11930 (but not in the way you'd expect)

(cherry picked from commit febfbebf9b)
Service-Card-Id: 92139784
Service-Version: 1.20
2024-03-21 15:45:29 -05:00
Isaac Blanco
98f675ec11 Update CommandPalette.cpp to ignore _filterTextChanged on TabSwitchMode (#16858)
As mentioned in #11146, when the "Next/Prev" command is executed from
the command line with a string in the search bar, this is setting always
the first tab.

When using the command "Next/Previous Tab" from the command line, we are
creating another tab (as if we are using the keyboard shortcut), and
this triggers the `_filterTextChanged` that resets the index to the
first item in because the current mode that it has.

This could be cause because, It seems that it detects as if we are
deleting the entered letter or creating an empty string, causing the
execution of the mentioned method and resetting its index to 0.

To avoid this, we are making sure that when this action is triggerd and
we are in the `TabSwitchMode`, we should ignore the following execution
of the method.

## Validation Steps Performed
I tested out the following scenarios:
1. Performing the action with the keyboard shorcut
2. Perfoming the action with an empty string
3. Performing the action with a string in the search bar.

Also validated with the current tests.

Closes #11146

(cherry picked from commit 806d5e2d05)
Service-Card-Id: 92139800
Service-Version: 1.20
2024-03-21 15:45:27 -05:00
Dustin L. Howett
f5a6cf6bf9 build: roll back to a build container with the 14.38 compiler (#16907)
The 14.39 compiler seems pretty busted.

Refs #16794

(cherry picked from commit ff47e0c257)
Service-Card-Id: 92139755
Service-Version: 1.20
2024-03-20 15:58:38 -05:00
Leonard Hecker
6ac8bd9ee6 Fix a ReadConsoleOutputCharacter regression (#16898)
The `nLength` parameter of `ReadConsoleOutputCharacterW` indicates
the number of columns that should be read. For single-column (narrow)
surrogate pairs this previously clipped a trailing character of the
returned string. In the major Unicode support update in #13626
surrogate pairs truly got stored as atomic units for the first time.
This now meant that a 120 column read with such codepoints resulted
in 121 characters. Other parts of conhost still assume UCS2 however,
and so this results in the entire read failing.

This fixes the issue by turning surrogate pairs into U+FFFD
which makes it UCS2 compatible.

Closes #16892

* Write U+F15C0 and read it back with `ReadConsoleOutputCharacterW`
* Read succeeds with a single U+FFFD 

(cherry picked from commit 373faf00c9)
Service-Card-Id: 92121912
Service-Version: 1.20
2024-03-20 15:58:36 -05:00
Windows Console Service Bot
4ee7f395bb Localization Updates - main - 03/08/2024 20:28:42 (#16847)
(cherry picked from commit c238416ae1)
Service-Card-Id: 92019656
Service-Version: 1.20
2024-03-08 15:06:36 -06:00
Dustin L. Howett
db2e8d6f93 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.

(cherry picked from commit ab4b140aa4)
Service-Card-Id: 92019665
Service-Version: 1.20
2024-03-08 15:06:35 -06:00
James Holderness
4234fe48a1 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

(cherry picked from commit 563b7312b6)
Service-Card-Id: 92001662
Service-Version: 1.20
2024-03-08 15:06:33 -06:00
Leonard Hecker
c9e226e1c9 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.

(cherry picked from commit 043d5cd484)
Service-Card-Id: 91955569
Service-Version: 1.20
2024-02-29 16:35:52 -06:00
Leonard Hecker
4706697627 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: 91922826
Service-Version: 1.20
2024-02-26 11:51:31 -06:00
Dustin L. Howett
07c6168c9e build: add a tsa configuration for asyncSdl (#16728)
(cherry picked from commit e3ff44bb82)
Service-Card-Id: 91922823
Service-Version: 1.20
2024-02-26 11:51:29 -06:00
Dustin L. Howett
190c76afe0 build: switch to NuGetAuthenticate@1 (#16752)
It keeps warning us that v0 has been deprecated.

(cherry picked from commit 6b29ef51e3)
Service-Card-Id: 91903283
Service-Version: 1.20
2024-02-26 11:44:03 -06:00
Dustin Howett
774e74ae77 Merge remote-tracking branch 'origin/release-1.19' into release-1.20 2024-02-26 11:25:12 -06:00
Leonard Hecker
a2521cc3ef 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());
```

(cherry picked from commit d3ec47a7fc)
Service-Card-Id: 91885584
Service-Version: 1.20
2024-02-21 11:54:55 -06:00
Leonard Hecker
4c681449cd 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

(cherry picked from commit 5e9f223a6c)
Service-Card-Id: 91851715
Service-Version: 1.20
2024-02-21 11:53:42 -06:00
Dustin L. Howett
427135aeca 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: 91892152
Service-Version: 1.20
2024-02-21 11:53:41 -06:00
Sarim Khan
dcbc17bdbd 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.

(cherry picked from commit d3a18b9041)
Service-Card-Id: 91808635
Service-Version: 1.20
2024-02-21 11:46:26 -06:00
e82eric
b520c80067 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

(cherry picked from commit bef234081a)
Service-Card-Id: 91808626
Service-Version: 1.20
2024-02-21 11:46:25 -06:00
Mike Griese
f01fb266bd 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

(cherry picked from commit 71efdcb21b)
Service-Card-Id: 91781164
Service-Version: 1.20
2024-02-21 11:46:24 -06:00
James Holderness
f13ba96e98 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

(cherry picked from commit ec91be5995)
Service-Card-Id: 91738880
Service-Version: 1.20
2024-02-21 11:46:23 -06:00
Leonard Hecker
70ac08f264 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 

(cherry picked from commit ef96e225da)
Service-Card-Id: 91727726
Service-Version: 1.20
2024-02-21 11:46:22 -06:00
Leonard Hecker
29a46c36f6 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 

(cherry picked from commit c669afe2a0)
Service-Card-Id: 91719863
Service-Version: 1.20
2024-01-30 18:25:36 -06:00
Dustin L. Howett
d5a3499ed9 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.

(cherry picked from commit bcca7aac1b)
Service-Card-Id: 91719596
Service-Version: 1.20
2024-01-30 18:25:35 -06:00
444 changed files with 15690 additions and 15168 deletions

View File

@@ -18,8 +18,6 @@ consvc
copyable
Counterintuitively
CtrlDToClose
CVS
CUI
cybersecurity
dalet
Dcs
@@ -83,24 +81,19 @@ 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
@@ -121,7 +114,6 @@ toolset
truthiness
tshe
ubuntu
UEFI
uiatextrange
UIs
und

View File

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

View File

@@ -14,13 +14,13 @@ autoexec
backplating
bitmaps
BOMs
checkcflags
COMPUTERNAME
CPLs
cpptools
cppvsdbg
CPRs
cryptbase
cscript
DACL
DACLs
defaultlib
@@ -32,6 +32,7 @@ DWINRT
enablewttlogging
HOMESHARE
Intelli
issecret
IVisual
libucrt
libucrtd
@@ -46,7 +47,6 @@ MSAA
msixbundle
MSVC
MSVCP
mtu
muxc
netcore
Onefuzz
@@ -74,6 +74,7 @@ sid
Skype
SRW
sxs
symbolrequestprod
Sysinternals
sysnative
systemroot
@@ -90,12 +91,11 @@ Virtualization
visualstudio
vscode
VSTHRD
WINBASEAPI
winsdkver
wlk
wscript
wslpath
wtl
wtt
wttlog
Xamarin
xfgcheck

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -75,6 +75,7 @@ steps:
rm LocOutputMunged.tar
rm -r -fo LocOutput
& ./build/scripts/Copy-ContextMenuResourcesToCascadiaPackage.ps1
& ./build/scripts/Generate-PseudoLocalizations.ps1
displayName: Move Loc files to the right places
- pwsh: |-

View File

@@ -33,6 +33,8 @@ 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,3 +81,5 @@ extends:
terminalInternalPackageVersion: ${{ parameters.terminalInternalPackageVersion }}
publishSymbolsToPublic: ${{ parameters.publishSymbolsToPublic }}
publishVpackToWindows: ${{ parameters.publishVpackToWindows }}
symbolPublishingSubscription: $(SymbolPublishingServiceConnection)
symbolPublishingProject: $(SymbolPublishingProject)

View File

@@ -80,7 +80,7 @@ jobs:
Install-Module -Verbose -AllowClobber -Force Az.Accounts, Az.Storage, Az.Network, Az.Resources, Az.Compute
displayName: Install Azure Module Dependencies
- task: AzureFileCopy@5
- task: AzureFileCopy@6
displayName: Publish to Storage Account
inputs:
sourcePath: _out/*

View File

@@ -0,0 +1,117 @@
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,7 +56,6 @@ jobs:
- task: PowerShell@2
displayName: 'Run PGO Tests'
inputs:
pwsh: true
targetType: filePath
filePath: build\scripts\Run-Tests.ps1
arguments: >-

View File

@@ -44,7 +44,6 @@ 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)"
@@ -53,7 +52,6 @@ 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,6 +52,10 @@ parameters:
- name: publishVpackToWindows
type: boolean
default: false
- name: symbolPublishingSubscription
type: string
- name: symbolPublishingProject
type: string
- name: extraPublishJobs
type: object
@@ -78,6 +82,7 @@ extends:
cloudvault: # https://aka.ms/obpipelines/cloudvault
enabled: false
globalSdl: # https://aka.ms/obpipelines/sdl
enableCheckCFlags: false # CheckCFlags is broken and exploding our builds; to remove, :g/BAD-FLAGS/d
asyncSdl:
enabled: true
tsaOptionsFile: 'build/config/tsa.json'
@@ -103,6 +108,8 @@ extends:
parameters:
pool: { type: windows }
variables:
ob_sdl_checkcflags_enabled: false # BAD-FLAGS
ob_sdl_xfgcheck_enabled: false # BAD-FLAGS
ob_git_checkout: false # This job checks itself out
ob_git_skip_checkout_none: true
ob_outputDirectory: $(JobOutputDirectory)
@@ -137,6 +144,8 @@ extends:
parameters:
pool: { type: windows }
variables:
ob_sdl_checkcflags_enabled: false # BAD-FLAGS
ob_sdl_xfgcheck_enabled: false # BAD-FLAGS
ob_git_checkout: false # This job checks itself out
ob_git_skip_checkout_none: true
ob_outputDirectory: $(JobOutputDirectory)
@@ -168,6 +177,8 @@ extends:
parameters:
pool: { type: windows }
variables:
ob_sdl_checkcflags_enabled: false # BAD-FLAGS
ob_sdl_xfgcheck_enabled: false # BAD-FLAGS
ob_git_checkout: false # This job checks itself out
ob_git_skip_checkout_none: true
ob_outputDirectory: $(JobOutputDirectory)
@@ -219,6 +230,8 @@ extends:
parameters:
pool: { type: windows }
variables:
ob_sdl_checkcflags_enabled: false # BAD-FLAGS
ob_sdl_xfgcheck_enabled: false # BAD-FLAGS
ob_git_checkout: false # This job checks itself out
ob_git_skip_checkout_none: true
ob_outputDirectory: $(JobOutputDirectory)
@@ -234,6 +247,8 @@ extends:
parameters:
pool: { type: windows }
variables:
ob_sdl_checkcflags_enabled: false # BAD-FLAGS
ob_sdl_xfgcheck_enabled: false # BAD-FLAGS
ob_git_checkout: false # This job checks itself out
ob_git_skip_checkout_none: true
ob_outputDirectory: $(JobOutputDirectory)
@@ -248,13 +263,16 @@ extends:
displayName: Publish
dependsOn: [Build]
jobs:
- template: ./build/pipelines/templates-v2/job-publish-symbols.yml@self
- template: ./build/pipelines/templates-v2/job-publish-symbols-using-symbolrequestprod-api.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_sdl_checkcflags_enabled: false # BAD-FLAGS
ob_sdl_xfgcheck_enabled: false # BAD-FLAGS
ob_git_checkout: false # This job checks itself out
ob_git_skip_checkout_none: true
ob_outputDirectory: $(Build.ArtifactStagingDirectory)

View File

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

View File

@@ -1,49 +0,0 @@
<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,7 +30,6 @@
<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

@@ -0,0 +1,16 @@
Get-ChildItem -Recurse -Filter *.resw
| Where-Object { $_.Directory.Name.StartsWith("qps-ploc") }
| ForEach-Object {
$source = Join-Path $_.Directory "../en-US/$($_.Name)"
$target = $_
$ploc = ./tools/ConvertTo-PseudoLocalization.ps1 -Path $source
$writerSettings = [System.Xml.XmlWriterSettings]::new()
$writerSettings.NewLineChars = "`r`n"
$writerSettings.Indent = $true
$writer = [System.Xml.XmlWriter]::Create($target, $writerSettings)
$ploc.Save($writer)
$writer.Flush()
$writer.Close()
}

View File

@@ -16,48 +16,22 @@ Param(
# Find test DLLs based on the provided root, match pattern, and recursion
$testDlls = Get-ChildItem -Path $Root -Recurse -Filter $MatchPattern
$teArgs = @()
$args = @()
# Check if the LogPath parameter is provided and enable WTT logging
if ($LogPath) {
$teArgs += '/enablewttlogging'
$teArgs += '/appendwttlogging'
$teArgs += "/logFile:$LogPath"
$args += '/enablewttlogging'
$args += '/appendwttlogging'
$args += "/logFile:$LogPath"
Write-Host "WTT Logging Enabled"
}
$rootTe = "$Root\te.exe"
# Invoke the te.exe executable with arguments and test DLLs
& "$Root\te.exe" $args $testDlls.FullName $AdditionalTaefArguments
# 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
# Check the exit code of the te.exe process and exit accordingly
if ($LASTEXITCODE -ne 0) {
Exit $LASTEXITCODE
}
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>2024</XesBaseYearForStoreVersion>
<XesBaseYearForStoreVersion>2023</XesBaseYearForStoreVersion>
<VersionMajor>1</VersionMajor>
<VersionMinor>21</VersionMinor>
<VersionMinor>20</VersionMinor>
<VersionInfoProductName>Windows Terminal</VersionInfoProductName>
</PropertyGroup>
</Project>

View File

@@ -10,7 +10,6 @@
<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,6 +2791,11 @@
"description": "Use to set a path to a pixel shader to use with the Terminal. Overrides `experimental.retroTerminalEffect`. This is an experimental feature, and its continued existence is not guaranteed.",
"type": "string"
},
"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-002.png)
![figure 1](data-mockup.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,54 +36,38 @@ 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.
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
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
attempt to parse those entries into `ActionAndArgs` which we'll store in the
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.
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.
For a visual representation:
For a visual representation, let's assume the user has the following in their
`actions`:
![figure 2](data-mockup-actions-ids-keys-maps.png)
![figure 2](data-mockup-actions.png)
### Nested actions
We'll first parse the `actions` to generate the mapping of `id`->`Actions`:
We allow certain actions that take a form like this:
![figure 3](data-mockup-actions-and-ids.png)
```
{
// Select color scheme...
"name": { "key": "SetColorSchemeParentCommandName" },
"commands": [
{
"iterateOn": "schemes",
"name": "${scheme.name}",
"command": { "action": "setColorScheme", "colorScheme": "${scheme.name}" }
}
]
}
```
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`:
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.
![figure 4](data-mockup-actions-and-ids-and-keys.png)
### 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
@@ -103,9 +87,6 @@ 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.

Before

Width:  |  Height:  |  Size: 172 KiB

View File

@@ -1,396 +0,0 @@
---
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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -8,5 +8,5 @@ Please consult the [license](https://raw.githubusercontent.com/microsoft/cascadi
### Fonts Included
* Cascadia Code, Cascadia Mono (2111.01)
* from microsoft/cascadia-code@de36d62e777d34d3bed92a7e23988e5d61e0ba02
* Cascadia Code, Cascadia Mono (2404.23)
* from microsoft/cascadia-code@1034791e5fc6e060a448d2b29cd94a6c683edb36

View File

@@ -1,23 +0,0 @@
// 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

@@ -118,6 +118,6 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AppDescription" xml:space="preserve">
<value>А şςѓάţćћ ǻрр ƒθŗ χÂΜĿ Íŝĺąήðş ŧеšτş !!! !!! !!! !</value>
<value>Ά śςґàτсн ąρφ ƒоř ΧΆΜĻ Ìŝļàиđś τёşτś !!! !!! !!! !</value>
</data>
</root>

View File

@@ -118,6 +118,6 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AppDescription" xml:space="preserve">
<value>Ă šςґаτćĥ àρφ ƒǿя ЖΆΜĹ Іѕℓаñďş ťêšţŝ !!! !!! !!! !</value>
<value>Ά śςґàτсн ąρφ ƒоř ΧΆΜĻ Ìŝļàиđś τёşτś !!! !!! !!! !</value>
</data>
</root>

View File

@@ -118,6 +118,6 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AppDescription" xml:space="preserve">
<value>Ă śćяǻт¢н ãрρ ƒσг ХĂМĽ Īşłдήďѕ ťέśτş !!! !!! !!! !</value>
<value>Ά śςґàτсн ąρφ ƒоř ΧΆΜĻ Ìŝļàиđś τёşτś !!! !!! !!! !</value>
</data>
</root>

View File

@@ -31,12 +31,9 @@ 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

@@ -111,28 +111,6 @@ const til::point_span* Search::GetCurrent() const noexcept
return nullptr;
}
void Search::HighlightResults() const
{
std::vector<til::inclusive_rect> toSelect;
const auto& textBuffer = _renderData->GetTextBuffer();
for (const auto& r : _results)
{
const auto rbStart = textBuffer.BufferToScreenPosition(r.start);
const auto rbEnd = textBuffer.BufferToScreenPosition(r.end);
til::inclusive_rect re;
re.top = rbStart.y;
re.bottom = rbEnd.y;
re.left = rbStart.x;
re.right = rbEnd.x;
toSelect.emplace_back(re);
}
_renderData->SelectSearchRegions(std::move(toSelect));
}
// Routine Description:
// - Takes the found word and selects it in the screen buffer
@@ -149,7 +127,6 @@ bool Search::SelectCurrent() const
return true;
}
_renderData->ClearSelection();
return false;
}

View File

@@ -33,7 +33,6 @@ public:
void FindNext() noexcept;
const til::point_span* GetCurrent() const noexcept;
void HighlightResults() const;
bool SelectCurrent() const;
const std::vector<til::point_span>& Results() const noexcept;

View File

@@ -166,7 +166,7 @@
<comment>{Locked=qps-ploc,qps-ploca,qps-plocm}</comment>
</data>
<data name="AppDescription" xml:space="preserve">
<value>Τнĕ Ņëω Ẅίηđŏẃś Ťėŗmįйάĺ !!! !!! !</value>
<value>Τĥз Йéщ Ẃįńđôẃѕ Тéѓmĩиâļ !!! !!! !</value>
</data>
<data name="AppDescriptionDev" xml:space="preserve">
<value>The Windows Terminal, but Unofficial</value>
@@ -177,22 +177,22 @@
<comment>{Locked}</comment>
</data>
<data name="AppDescriptionPre" xml:space="preserve">
<value>Ŵíňďōẁŝ Тєřмīπǻļ ωїτĥ å ρѓēνіéŵ θƒ ũφсőмϊπġ ƒєąτΰґёѕ !!! !!! !!! !!! !!! </value>
<value>Щΐňδόŵѕ Ŧęřмĭʼnäℓ ẅîťħ à φřеνίëẃ θƒ џрсøмΐʼnğ ƒĕāŧųřэś !!! !!! !!! !!! !!! </value>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem_Dev" xml:space="preserve">
<value>Open in Terminal (&amp;Dev)</value>
<comment>{Locked} The dev build will never be seen in multiple languages</comment>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem_Canary" xml:space="preserve">
<value>Ŏрέи ìη Тèřmīŋªŀ (&amp;Cãńãґγ) !!! !!! !</value>
<value>Θρēņ ïη Ţéгmĭηäŀ (&amp;Çäņдѓγ) !!! !!! !</value>
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the Canary version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem_Preview" xml:space="preserve">
<value>Φφєň ΐñ Ŧéгмϊñаľ &amp;Pŕėνĭώ !!! !!! !</value>
<value>Όрèп ìņ Ţêŕmїʼnåļ &amp;Рѓзνι℮ω !!! !!! !</value>
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the Preview version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem" xml:space="preserve">
<value>Ωρєⁿ ïπ &amp;Těѓmĭñäĺ !!! !!</value>
<value>Óрêп ìл &amp;Ťěѓmιиåĺ !!! !!</value>
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the non-preview version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
</data>
</root>

View File

@@ -166,7 +166,7 @@
<comment>{Locked=qps-ploc,qps-ploca,qps-plocm}</comment>
</data>
<data name="AppDescription" xml:space="preserve">
<value>Ťĥё Ñēщ Шίⁿðоẅś Ťėгмîήāľ !!! !!! !</value>
<value>Τĥз Йéщ Ẃįńđôẃѕ Тéѓmĩиâļ !!! !!! !</value>
</data>
<data name="AppDescriptionDev" xml:space="preserve">
<value>The Windows Terminal, but Unofficial</value>
@@ -177,22 +177,22 @@
<comment>{Locked}</comment>
</data>
<data name="AppDescriptionPre" xml:space="preserve">
<value>Шίηđóŵš Ŧĕяmїйà ẁітħ ª φяęνîёщ όƒ ûφĉбмíήĝ ƒêåťµřεŝ !!! !!! !!! !!! !!! </value>
<value>Щΐňδόŵѕ Ŧęřмĭʼnäℓ ẅîťħ à φřеνίëẃ θƒ џрсøмΐʼnğ ƒĕāŧųřэś !!! !!! !!! !!! !!! </value>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem_Dev" xml:space="preserve">
<value>Open in Terminal (&amp;Dev)</value>
<comment>{Locked} The dev build will never be seen in multiple languages</comment>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem_Canary" xml:space="preserve">
<value>Óрëπ íи Ťēяmілǻŀ (&amp;Cäηàřÿ) !!! !!! !</value>
<value>Θρēņ ïη Ţéгmĭηäŀ (&amp;Çäņдѓγ) !!! !!! !</value>
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the Canary version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem_Preview" xml:space="preserve">
<value>Óрзń ΐή Ŧěґмιлāℓ &amp;Pѓéνīĕω !!! !!! !</value>
<value>Όрèп ìņ Ţêŕmїʼnåļ &amp;Рѓзνι℮ω !!! !!! !</value>
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the Preview version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem" xml:space="preserve">
<value>Ôрëη ïп &amp;Tēѓмϊŋãł !!! !!</value>
<value>Óрêп ìл &amp;Ťěѓmιиåĺ !!! !!</value>
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the non-preview version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
</data>
</root>

View File

@@ -166,7 +166,7 @@
<comment>{Locked=qps-ploc,qps-ploca,qps-plocm}</comment>
</data>
<data name="AppDescription" xml:space="preserve">
<value>Тĥё Ńēẁ Шіπđοωš Тěřмιňαŀ !!! !!! !</value>
<value>Τĥз Йéщ Ẃįńđôẃѕ Тéѓmĩиâļ !!! !!! !</value>
</data>
<data name="AppDescriptionDev" xml:space="preserve">
<value>The Windows Terminal, but Unofficial</value>
@@ -177,22 +177,22 @@
<comment>{Locked}</comment>
</data>
<data name="AppDescriptionPre" xml:space="preserve">
<value>Шίήďŏшś Ŧêямĩňāľ ŵíτн ă ρѓëνιêω øƒ ũρčŏмįηğ ƒєáţũŗêš !!! !!! !!! !!! !!! </value>
<value>Щΐňδόŵѕ Ŧęřмĭʼnäℓ ẅîťħ à φřеνίëẃ θƒ џрсøмΐʼnğ ƒĕāŧųřэś !!! !!! !!! !!! !!! </value>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem_Dev" xml:space="preserve">
<value>Open in Terminal (&amp;Dev)</value>
<comment>{Locked} The dev build will never be seen in multiple languages</comment>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem_Canary" xml:space="preserve">
<value>Фφěй ĩń Тêřmιπâł (&amp;Cãⁿǻřу) !!! !!! !</value>
<value>Θρēņ ïη Ţéгmĭηäŀ (&amp;Çäņдѓγ) !!! !!! !</value>
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the Canary version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem_Preview" xml:space="preserve">
<value>Óφ℮ʼn ΐŋ Τėřmīйäĺ &amp;Pяєνϊëẃ !!! !!! !</value>
<value>Όрèп ìņ Ţêŕmїʼnåļ &amp;Рѓзνι℮ω !!! !!! !</value>
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the Preview version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem" xml:space="preserve">
<value>Ορέл ϊŋ &amp;Téŕmįñā !!! !!</value>
<value>Óрêп ìл &amp;Ťěѓmιиåĺ !!! !!</value>
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the non-preview version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
</data>
</root>

View File

@@ -1,28 +0,0 @@
<?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,29 +0,0 @@
<?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

@@ -0,0 +1,404 @@
// 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

@@ -15,11 +15,24 @@ using namespace WEX::Logging;
using namespace WEX::TestExecution;
using namespace WEX::Common;
namespace SettingsModelUnitTests
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 CommandTests : public JsonTestClass
{
TEST_CLASS(CommandTests);
// 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(CommandTests)
TEST_CLASS_PROPERTY(L"RunAs", L"UAP")
TEST_CLASS_PROPERTY(L"UAP:AppXManifest", L"TestHostAppXManifest.xml")
END_TEST_CLASS()
TEST_METHOD(ManyCommandsSameAction);
TEST_METHOD(LayerCommand);

View File

@@ -19,11 +19,24 @@ using namespace winrt::Microsoft::Terminal::Settings::Model;
using namespace winrt::Microsoft::Terminal::Control;
using VirtualKeyModifiers = winrt::Windows::System::VirtualKeyModifiers;
namespace SettingsModelUnitTests
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 DeserializationTests : public JsonTestClass
{
TEST_CLASS(DeserializationTests);
// 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(DeserializationTests)
TEST_CLASS_PROPERTY(L"RunAs", L"UAP")
TEST_CLASS_PROPERTY(L"UAP:AppXManifest", L"TestHostAppXManifest.xml")
END_TEST_CLASS()
TEST_METHOD(ValidateProfilesExist);
TEST_METHOD(ValidateDefaultProfileExists);
@@ -61,13 +74,6 @@ namespace SettingsModelUnitTests
TEST_METHOD(TestInheritedCommand);
TEST_METHOD(LoadFragmentsWithMultipleUpdates);
TEST_METHOD(FragmentActionSimple);
TEST_METHOD(FragmentActionNoKeys);
TEST_METHOD(FragmentActionNested);
TEST_METHOD(FragmentActionNestedNoName);
TEST_METHOD(FragmentActionIterable);
TEST_METHOD(FragmentActionRoundtrip);
TEST_METHOD(MigrateReloadEnvVars);
private:
@@ -2017,189 +2023,6 @@ namespace SettingsModelUnitTests
VERIFY_ARE_EQUAL(L"NewName", loader.userSettings.profiles[0]->Name());
}
void DeserializationTests::FragmentActionSimple()
{
static constexpr std::wstring_view fragmentSource{ L"fragment" };
static constexpr std::string_view fragmentJson{ R"({
"actions": [
{
"command": { "action": "addMark" },
"name": "Test Action"
},
]
})" };
implementation::SettingsLoader loader{ std::string_view{}, DefaultJson };
loader.MergeInboxIntoUserSettings();
loader.MergeFragmentIntoUserSettings(winrt::hstring{ fragmentSource }, fragmentJson);
loader.FinalizeLayering();
const auto settings = winrt::make_self<implementation::CascadiaSettings>(std::move(loader));
const auto actionMap = winrt::get_self<implementation::ActionMap>(settings->GlobalSettings().ActionMap());
const auto actionsByName = actionMap->NameMap();
VERIFY_IS_NOT_NULL(actionsByName.TryLookup(L"Test Action"));
}
void DeserializationTests::FragmentActionNoKeys()
{
static constexpr std::wstring_view fragmentSource{ L"fragment" };
static constexpr std::string_view fragmentJson{ R"({
"actions": [
{
"command": { "action": "addMark" },
"keys": "ctrl+f",
"name": "Test Action"
},
]
})" };
implementation::SettingsLoader loader{ std::string_view{}, DefaultJson };
loader.MergeInboxIntoUserSettings();
loader.MergeFragmentIntoUserSettings(winrt::hstring{ fragmentSource }, fragmentJson);
loader.FinalizeLayering();
const auto settings = winrt::make_self<implementation::CascadiaSettings>(std::move(loader));
const auto actionMap = winrt::get_self<implementation::ActionMap>(settings->GlobalSettings().ActionMap());
const auto actionsByName = actionMap->NameMap();
VERIFY_IS_NOT_NULL(actionsByName.TryLookup(L"Test Action"));
VERIFY_IS_NULL(actionMap->GetActionByKeyChord({ VirtualKeyModifiers::Control, static_cast<int32_t>('F'), 0 }));
}
void DeserializationTests::FragmentActionNested()
{
static constexpr std::wstring_view fragmentSource{ L"fragment" };
static constexpr std::string_view fragmentJson{ R"({
"actions": [
{
"name": "nested command",
"commands": [
{
"name": "child1",
"command": { "action": "newTab", "commandline": "ssh me@first.com" }
},
{
"name": "child2",
"command": { "action": "newTab", "commandline": "ssh me@second.com" }
}
]
},
]
})" };
implementation::SettingsLoader loader{ std::string_view{}, DefaultJson };
loader.MergeInboxIntoUserSettings();
loader.MergeFragmentIntoUserSettings(winrt::hstring{ fragmentSource }, fragmentJson);
loader.FinalizeLayering();
const auto settings = winrt::make_self<implementation::CascadiaSettings>(std::move(loader));
const auto actionMap = winrt::get_self<implementation::ActionMap>(settings->GlobalSettings().ActionMap());
const auto actionsByName = actionMap->NameMap();
const auto& nested{ actionsByName.TryLookup(L"nested command") };
VERIFY_IS_NOT_NULL(nested);
VERIFY_IS_TRUE(nested.HasNestedCommands());
}
void DeserializationTests::FragmentActionNestedNoName()
{
// Basically the same as TestNestedCommandWithoutName
static constexpr std::wstring_view fragmentSource{ L"fragment" };
static constexpr std::string_view fragmentJson{ R"({
"actions": [
{
"commands": [
{
"name": "child1",
"command": { "action": "newTab", "commandline": "ssh me@first.com" }
},
{
"name": "child2",
"command": { "action": "newTab", "commandline": "ssh me@second.com" }
}
]
},
]
})" };
implementation::SettingsLoader loader{ std::string_view{}, DefaultJson };
loader.MergeInboxIntoUserSettings();
loader.MergeFragmentIntoUserSettings(winrt::hstring{ fragmentSource }, fragmentJson);
loader.FinalizeLayering();
const auto settings = winrt::make_self<implementation::CascadiaSettings>(std::move(loader));
VERIFY_ARE_EQUAL(0u, settings->Warnings().Size());
}
void DeserializationTests::FragmentActionIterable()
{
static constexpr std::wstring_view fragmentSource{ L"fragment" };
static constexpr std::string_view fragmentJson{ R"({
"actions": [
{
"name": "nested",
"commands": [
{
"iterateOn": "schemes",
"name": "${scheme.name}",
"command": { "action": "setColorScheme", "colorScheme": "${scheme.name}" }
}
]
},
]
})" };
implementation::SettingsLoader loader{ std::string_view{}, DefaultJson };
loader.MergeInboxIntoUserSettings();
loader.MergeFragmentIntoUserSettings(winrt::hstring{ fragmentSource }, fragmentJson);
loader.FinalizeLayering();
const auto settings = winrt::make_self<implementation::CascadiaSettings>(std::move(loader));
const auto actionMap = winrt::get_self<implementation::ActionMap>(settings->GlobalSettings().ActionMap());
const auto actionsByName = actionMap->NameMap();
const auto& nested{ actionsByName.TryLookup(L"nested") };
VERIFY_IS_NOT_NULL(nested);
VERIFY_IS_TRUE(nested.HasNestedCommands());
VERIFY_ARE_EQUAL(settings->GlobalSettings().ColorSchemes().Size(), nested.NestedCommands().Size());
}
void DeserializationTests::FragmentActionRoundtrip()
{
static constexpr std::wstring_view fragmentSource{ L"fragment" };
static constexpr std::string_view fragmentJson{ R"({
"actions": [
{
"command": { "action": "addMark" },
"name": "Test Action"
},
]
})" };
implementation::SettingsLoader loader{ std::string_view{}, DefaultJson };
loader.MergeInboxIntoUserSettings();
loader.MergeFragmentIntoUserSettings(winrt::hstring{ fragmentSource }, fragmentJson);
loader.FinalizeLayering();
const auto oldSettings = winrt::make_self<implementation::CascadiaSettings>(std::move(loader));
const auto actionMap = winrt::get_self<implementation::ActionMap>(oldSettings->GlobalSettings().ActionMap());
const auto actionsByName = actionMap->NameMap();
VERIFY_IS_NOT_NULL(actionsByName.TryLookup(L"Test Action"));
const auto oldResult{ oldSettings->ToJson() };
Log::Comment(L"Now, create a _new_ settings object from the re-serialization of the first");
implementation::SettingsLoader newLoader{ toString(oldResult), DefaultJson };
// NOTABLY! Don't load the fragment here.
newLoader.MergeInboxIntoUserSettings();
newLoader.FinalizeLayering();
const auto newSettings = winrt::make_self<implementation::CascadiaSettings>(std::move(newLoader));
const auto& newActionMap = winrt::get_self<implementation::ActionMap>(newSettings->GlobalSettings().ActionMap());
const auto newActionsByName = newActionMap->NameMap();
VERIFY_IS_NULL(newActionsByName.TryLookup(L"Test Action"));
}
void DeserializationTests::MigrateReloadEnvVars()
{
static constexpr std::string_view settings1Json{ R"(

View File

@@ -17,11 +17,24 @@ using namespace WEX::TestExecution;
using namespace WEX::Common;
using VirtualKeyModifiers = winrt::Windows::System::VirtualKeyModifiers;
namespace SettingsModelUnitTests
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 KeyBindingsTests : public JsonTestClass
{
TEST_CLASS(KeyBindingsTests);
// 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(KeyBindingsTests)
TEST_CLASS_PROPERTY(L"RunAs", L"UAP")
TEST_CLASS_PROPERTY(L"UAP:AppXManifest", L"TestHostAppXManifest.xml")
END_TEST_CLASS()
TEST_METHOD(KeyChords);
TEST_METHOD(ManyKeysSameAction);

View File

@@ -18,11 +18,24 @@ using namespace WEX::Logging;
using namespace WEX::TestExecution;
using namespace WEX::Common;
namespace SettingsModelUnitTests
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 NewTabMenuTests : public JsonTestClass
{
TEST_CLASS(NewTabMenuTests);
// 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(NewTabMenuTests)
TEST_CLASS_PROPERTY(L"RunAs", L"UAP")
TEST_CLASS_PROPERTY(L"UAP:AppXManifest", L"TestHostAppXManifest.xml")
END_TEST_CLASS()
TEST_METHOD(DefaultsToRemainingProfiles);
TEST_METHOD(ParseEmptyFolder);

View File

@@ -15,11 +15,24 @@ using namespace WEX::Logging;
using namespace WEX::TestExecution;
using namespace WEX::Common;
namespace SettingsModelUnitTests
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 ProfileTests : public JsonTestClass
{
TEST_CLASS(ProfileTests);
// 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(ProfileTests)
TEST_CLASS_PROPERTY(L"RunAs", L"UAP")
TEST_CLASS_PROPERTY(L"UAP:AppXManifest", L"TestHostAppXManifest.xml")
END_TEST_CLASS()
TEST_METHOD(ProfileGeneratesGuid);
TEST_METHOD(LayerProfileProperties);

View File

@@ -16,11 +16,24 @@ using namespace WEX::Common;
using namespace winrt::Microsoft::Terminal::Settings::Model;
using namespace winrt::Microsoft::Terminal::Control;
namespace SettingsModelUnitTests
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 SerializationTests : public JsonTestClass
{
TEST_CLASS(SerializationTests);
// 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(SerializationTests)
TEST_CLASS_PROPERTY(L"RunAs", L"UAP")
TEST_CLASS_PROPERTY(L"UAP:AppXManifest", L"TestHostAppXManifest.xml")
END_TEST_CLASS()
TEST_METHOD(GlobalSettings);
TEST_METHOD(Profile);
@@ -32,10 +45,6 @@ namespace SettingsModelUnitTests
TEST_METHOD(RoundtripReloadEnvVars);
TEST_METHOD(DontRoundtripNoReloadEnvVars);
TEST_METHOD(RoundtripUserModifiedColorSchemeCollision);
TEST_METHOD(RoundtripUserModifiedColorSchemeCollisionUnusedByProfiles);
TEST_METHOD(RoundtripUserDeletedColorSchemeCollision);
private:
// Method Description:
// - deserializes and reserializes a json string representing a settings object model of type T
@@ -59,19 +68,6 @@ namespace SettingsModelUnitTests
// written alphabetically.
VERIFY_ARE_EQUAL(toString(json), toString(result));
}
// Helper to remove the `$schema` property from a json object. We
// populate that based off the local path to the settings file. Of
// course, that's entirely unpredictable in tests. So cut it out before
// we do any sort of roundtrip testing.
static Json::Value removeSchema(Json::Value json)
{
if (json.isMember("$schema"))
{
json.removeMember("$schema");
}
return json;
}
};
void SerializationTests::GlobalSettings()
@@ -199,34 +195,9 @@ namespace SettingsModelUnitTests
"source": "local"
})" };
static constexpr std::string_view profileWithIcon{ R"(
{
"guid" : "{8b039d4d-77ca-5a83-88e1-dfc8e895a127}",
"name": "profileWithIcon",
"hidden": false,
"icon": "foo.png"
})" };
static constexpr std::string_view profileWithNullIcon{ R"(
{
"guid" : "{8b039d4d-77ca-5a83-88e1-dfc8e895a127}",
"name": "profileWithNullIcon",
"hidden": false,
"icon": null
})" };
static constexpr std::string_view profileWithNoIcon{ R"(
{
"guid" : "{8b039d4d-77ca-5a83-88e1-dfc8e895a127}",
"name": "profileWithNoIcon",
"hidden": false,
"icon": "none"
})" };
RoundtripTest<implementation::Profile>(profileString);
RoundtripTest<implementation::Profile>(smallProfileString);
RoundtripTest<implementation::Profile>(weirdProfileString);
RoundtripTest<implementation::Profile>(profileWithIcon);
RoundtripTest<implementation::Profile>(profileWithNullIcon);
RoundtripTest<implementation::Profile>(profileWithNoIcon);
}
void SerializationTests::ColorScheme()
@@ -291,6 +262,15 @@ namespace SettingsModelUnitTests
{ "command": { "action": "adjustFontSize", "delta": 1.0 }, "keys": "ctrl+c" },
{ "command": { "action": "adjustFontSize", "delta": 1.0 }, "keys": "ctrl+d" }
])" };
// GH#13323 - these can be fragile. In the past, the order these get
// re-serialized as has been not entirely stable. We don't really care
// about the order they get re-serialized in, but the tests aren't
// clever enough to compare the structure, only the literal string
// itself. Feel free to change as needed.
static constexpr std::string_view actionsString4B{ R"([
{ "command": { "action": "findMatch", "direction": "prev" }, "keys": "ctrl+shift+r" },
{ "command": { "action": "adjustFontSize", "delta": 1.0 }, "keys": "ctrl+d" }
])" };
// command with name and icon and multiple key chords
static constexpr std::string_view actionsString5{ R"([
@@ -404,6 +384,7 @@ namespace SettingsModelUnitTests
Log::Comment(L"complex commands with key chords");
RoundtripTest<implementation::ActionMap>(actionsString4A);
RoundtripTest<implementation::ActionMap>(actionsString4B);
Log::Comment(L"command with name and icon and multiple key chords");
RoundtripTest<implementation::ActionMap>(actionsString5);
@@ -502,8 +483,7 @@ namespace SettingsModelUnitTests
const auto settings{ winrt::make_self<implementation::CascadiaSettings>(settingsString) };
const auto result{ settings->ToJson() };
VERIFY_ARE_EQUAL(toString(removeSchema(VerifyParseSucceeded(settingsString))),
toString(removeSchema(result)));
VERIFY_ARE_EQUAL(toString(VerifyParseSucceeded(settingsString)), toString(result));
}
void SerializationTests::LegacyFontSettings()
@@ -646,306 +626,4 @@ namespace SettingsModelUnitTests
VERIFY_IS_FALSE(newSettings->ProfileDefaults().HasReloadEnvironmentVariables(),
L"Ensure that the new settings object didn't find a reloadEnvironmentVariables");
}
void SerializationTests::RoundtripUserModifiedColorSchemeCollision()
{
static constexpr std::string_view oldSettingsJson{ R"(
{
"defaultProfile": "{6239a42c-0000-49a3-80bd-e8fdd045185c}",
"profiles": [
{
"name": "profile0",
"guid": "{6239a42c-0000-49a3-80bd-e8fdd045185c}"
},
{
"name": "profile1",
"colorScheme": "Tango Dark",
"guid": "{d0a65a9d-8665-4128-97a4-a581aa747aa7}"
}
],
"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": "#000000",
"black": "#000000",
"blue": "#3465A4",
"brightBlack": "#555753",
"brightBlue": "#729FCF",
"brightCyan": "#34E2E2",
"brightGreen": "#8AE234",
"brightPurple": "#AD7FA8",
"brightRed": "#EF2929",
"brightWhite": "#EEEEEC",
"brightYellow": "#FCE94F",
"cursorColor": "#FFFFFF",
"cyan": "#06989A",
"foreground": "#D3D7CF",
"green": "#4E9A06",
"name": "Tango Dark",
"purple": "#75507B",
"red": "#CC0000",
"selectionBackground": "#FFFFFF",
"white": "#D3D7CF",
"yellow": "#C4A000"
},
]
})" };
// Key differences: one fewer color scheme (Tango Dark has been deleted) and defaults.colorScheme is set.
static constexpr std::string_view newSettingsJson{ R"-(
{
"defaultProfile": "{6239a42c-0000-49a3-80bd-e8fdd045185c}",
"profiles":
{
"defaults": {
"colorScheme": "Campbell (modified)"
},
"list":
[
{
"name": "profile0",
"guid": "{6239a42c-0000-49a3-80bd-e8fdd045185c}"
},
{
"name": "profile1",
"colorScheme": "Tango Dark",
"guid": "{d0a65a9d-8665-4128-97a4-a581aa747aa7}"
}
]
},
"actions": [ ],
"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"
}
]
})-" };
implementation::SettingsLoader oldLoader{ oldSettingsJson, DefaultJson };
oldLoader.MergeInboxIntoUserSettings();
oldLoader.FinalizeLayering();
VERIFY_IS_TRUE(oldLoader.FixupUserSettings(), L"Validate that this will indicate we need to write them back to disk");
const auto oldSettings = winrt::make_self<implementation::CascadiaSettings>(std::move(oldLoader));
const auto oldResult{ oldSettings->ToJson() };
implementation::SettingsLoader newLoader{ newSettingsJson, DefaultJson };
newLoader.MergeInboxIntoUserSettings();
newLoader.FinalizeLayering();
newLoader.FixupUserSettings();
const auto newSettings = winrt::make_self<implementation::CascadiaSettings>(std::move(newLoader));
const auto newResult{ newSettings->ToJson() };
VERIFY_ARE_EQUAL(toString(newResult), toString(oldResult));
}
void SerializationTests::RoundtripUserModifiedColorSchemeCollisionUnusedByProfiles()
{
static constexpr std::string_view oldSettingsJson{ R"(
{
"defaultProfile": "{6239a42c-0000-49a3-80bd-e8fdd045185c}",
"profiles": [
{
"name": "profile0",
"guid": "{6239a42c-0000-49a3-80bd-e8fdd045185c}"
}
],
"schemes": [
{
"background": "#111111",
"black": "#111111",
"blue": "#111111",
"brightBlack": "#111111",
"brightBlue": "#111111",
"brightCyan": "#111111",
"brightGreen": "#111111",
"brightPurple": "#111111",
"brightRed": "#111111",
"brightWhite": "#111111",
"brightYellow": "#111111",
"cursorColor": "#111111",
"cyan": "#111111",
"foreground": "#111111",
"green": "#111111",
"name": "Tango Dark",
"purple": "#111111",
"red": "#111111",
"selectionBackground": "#111111",
"white": "#111111",
"yellow": "#111111"
},
]
})" };
// Key differences: Tango Dark has been renamed; nothing else has changed
static constexpr std::string_view newSettingsJson{ R"-(
{
"defaultProfile": "{6239a42c-0000-49a3-80bd-e8fdd045185c}",
"profiles":
{
"list":
[
{
"name": "profile0",
"guid": "{6239a42c-0000-49a3-80bd-e8fdd045185c}"
}
]
},
"actions": [ ],
"schemes": [
{
"background": "#111111",
"black": "#111111",
"blue": "#111111",
"brightBlack": "#111111",
"brightBlue": "#111111",
"brightCyan": "#111111",
"brightGreen": "#111111",
"brightPurple": "#111111",
"brightRed": "#111111",
"brightWhite": "#111111",
"brightYellow": "#111111",
"cursorColor": "#111111",
"cyan": "#111111",
"foreground": "#111111",
"green": "#111111",
"name": "Tango Dark (modified)",
"purple": "#111111",
"red": "#111111",
"selectionBackground": "#111111",
"white": "#111111",
"yellow": "#111111"
},
]
})-" };
implementation::SettingsLoader oldLoader{ oldSettingsJson, DefaultJson };
oldLoader.MergeInboxIntoUserSettings();
oldLoader.FinalizeLayering();
VERIFY_IS_TRUE(oldLoader.FixupUserSettings(), L"Validate that this will indicate we need to write them back to disk");
const auto oldSettings = winrt::make_self<implementation::CascadiaSettings>(std::move(oldLoader));
const auto oldResult{ oldSettings->ToJson() };
implementation::SettingsLoader newLoader{ newSettingsJson, DefaultJson };
newLoader.MergeInboxIntoUserSettings();
newLoader.FinalizeLayering();
newLoader.FixupUserSettings();
const auto newSettings = winrt::make_self<implementation::CascadiaSettings>(std::move(newLoader));
const auto newResult{ newSettings->ToJson() };
VERIFY_ARE_EQUAL(toString(newResult), toString(oldResult));
}
void SerializationTests::RoundtripUserDeletedColorSchemeCollision()
{
static constexpr std::string_view oldSettingsJson{ R"(
{
"defaultProfile": "{6239a42c-0000-49a3-80bd-e8fdd045185c}",
"profiles": [
{
"name": "profile0",
"guid": "{6239a42c-0000-49a3-80bd-e8fdd045185c}"
}
],
"schemes": [
{
"name": "Tango Dark",
"foreground": "#D3D7CF",
"background": "#000000",
"cursorColor": "#FFFFFF",
"black": "#000000",
"red": "#CC0000",
"green": "#4E9A06",
"yellow": "#C4A000",
"blue": "#3465A4",
"purple": "#75507B",
"cyan": "#06989A",
"white": "#D3D7CF",
"brightBlack": "#555753",
"brightRed": "#EF2929",
"brightGreen": "#8AE234",
"brightYellow": "#FCE94F",
"brightBlue": "#729FCF",
"brightPurple": "#AD7FA8",
"brightCyan": "#34E2E2",
"brightWhite": "#EEEEEC"
}
]
})" };
// Key differences: Tango Dark has been deleted, as it was identical to the inbox one.
static constexpr std::string_view newSettingsJson{ R"-(
{
"defaultProfile": "{6239a42c-0000-49a3-80bd-e8fdd045185c}",
"profiles":
{
"list":
[
{
"name": "profile0",
"guid": "{6239a42c-0000-49a3-80bd-e8fdd045185c}"
}
]
},
"actions": [ ],
"schemes": [ ]
})-" };
implementation::SettingsLoader oldLoader{ oldSettingsJson, DefaultJson };
oldLoader.MergeInboxIntoUserSettings();
oldLoader.FinalizeLayering();
VERIFY_IS_TRUE(oldLoader.FixupUserSettings(), L"Validate that this will indicate we need to write them back to disk");
const auto oldSettings = winrt::make_self<implementation::CascadiaSettings>(std::move(oldLoader));
const auto oldResult{ oldSettings->ToJson() };
implementation::SettingsLoader newLoader{ newSettingsJson, DefaultJson };
newLoader.MergeInboxIntoUserSettings();
newLoader.FinalizeLayering();
newLoader.FixupUserSettings();
const auto newSettings = winrt::make_self<implementation::CascadiaSettings>(std::move(newLoader));
const auto newResult{ newSettings->ToJson() };
VERIFY_ARE_EQUAL(toString(newResult), toString(oldResult));
}
}

View File

@@ -14,9 +14,9 @@
<PropertyGroup>
<ProjectGuid>{CA5CAD1A-9B68-456A-B13E-C8218070DC42}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>SettingsModelUnitTests</RootNamespace>
<ProjectName>UnitTests_SettingsModel</ProjectName>
<TargetName>SettingsModel.Unit.Tests</TargetName>
<RootNamespace>SettingsModelLocalTests</RootNamespace>
<ProjectName>LocalTests_SettingsModel</ProjectName>
<TargetName>SettingsModel.LocalTests</TargetName>
<ConfigurationType>DynamicLibrary</ConfigurationType>
<OpenConsoleCppWinRTProject>true</OpenConsoleCppWinRTProject>
<!-- TerminalCppWinrt is not set intentionally -->
@@ -64,6 +64,7 @@
_ConsoleGenerateAdditionalWinmdManifests step won't gather the winmd's -->
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalControl\dll\TerminalControl.vcxproj" />
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalConnection\TerminalConnection.vcxproj" />
<ProjectReference Include="$(OpenConsoleDir)\src\cascadia\TerminalSettingsModel\dll\Microsoft.Terminal.Settings.Model.vcxproj" />
</ItemGroup>
<!-- ========================= Globals ======================== -->
@@ -97,16 +98,4 @@
<Import Project="$(OpenConsoleDir)src\common.build.post.props" />
<Import Project="$(OpenConsoleDir)src\common.build.tests.props" />
<Import Project="$(OpenConsoleDir)src\common.nugetversions.targets" />
<ItemGroup>
<ProjectPriFiles Include="$(TargetDir)\Microsoft.Terminal.Settings.Model.pri" />
<OutputPriFiles Include="$(TargetDir)\resources.pri" />
</ItemGroup>
<Target Name="AfterBuild" Inputs="@(ProjectPriFiles)" Outputs="@(OutputPriFiles)">
<Copy SourceFiles="@(ProjectPriFiles)"
DestinationFiles="@(OutputPriFiles)"
UseHardLinksIfPossible="true"
SkipUnchangedFiles="true" />
</Target>
</Project>

View File

@@ -16,11 +16,24 @@ using namespace WEX::Common;
using namespace winrt::Microsoft::Terminal::Settings::Model;
using namespace winrt::Microsoft::Terminal::Control;
namespace SettingsModelUnitTests
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 TerminalSettingsTests
{
TEST_CLASS(TerminalSettingsTests);
// 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(TerminalSettingsTests)
TEST_CLASS_PROPERTY(L"RunAs", L"UAP")
TEST_CLASS_PROPERTY(L"UAP:AppXManifest", L"TestHostAppXManifest.xml")
END_TEST_CLASS()
TEST_METHOD(TryCreateWinRTType);
TEST_METHOD(TestTerminalArgsForBinding);
@@ -140,7 +153,7 @@ namespace SettingsModelUnitTests
g.Data4[7]);
}
const auto tmpdir = std::filesystem::canonical(std::filesystem::temp_directory_path());
const auto tmpdir = std::filesystem::temp_directory_path();
const auto dir1 = tmpdir / guid;
const auto dir2 = tmpdir / (guid + L" two");
const auto file1 = dir1 / L"file 1.exe";
@@ -160,13 +173,13 @@ namespace SettingsModelUnitTests
{
const auto commandLine = file2.native() + LR"( -foo "bar1 bar2" -baz)"s;
const auto expected = file2.native() + L"\0-foo\0bar1 bar2\0-baz"s;
const auto actual = implementation::Profile::NormalizeCommandLine(commandLine.c_str());
const auto actual = implementation::CascadiaSettings::NormalizeCommandLine(commandLine.c_str());
VERIFY_ARE_EQUAL(expected, actual);
}
{
const auto commandLine = L"C:\\";
const auto expected = L"C:\\";
const auto actual = implementation::Profile::NormalizeCommandLine(commandLine);
const auto actual = implementation::CascadiaSettings::NormalizeCommandLine(commandLine);
VERIFY_ARE_EQUAL(expected, actual);
}
}

View File

@@ -17,11 +17,24 @@ using namespace WEX::Logging;
using namespace WEX::TestExecution;
using namespace WEX::Common;
namespace SettingsModelUnitTests
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 ThemeTests : public JsonTestClass
{
TEST_CLASS(ThemeTests);
// 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(ThemeTests)
TEST_CLASS_PROPERTY(L"RunAs", L"UAP")
TEST_CLASS_PROPERTY(L"UAP:AppXManifest", L"TestHostAppXManifest.xml")
END_TEST_CLASS()
TEST_METHOD(ParseSimpleTheme);
TEST_METHOD(ParseEmptyTheme);

View File

@@ -42,6 +42,7 @@ Author(s):
#include <winrt/Windows.system.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <Windows.Graphics.Imaging.Interop.h>
#include <winrt/windows.ui.core.h>
#include <winrt/Windows.ui.input.h>
#include <winrt/Windows.UI.ViewManagement.h>

View File

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

View File

@@ -133,6 +133,7 @@
<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

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

View File

@@ -1,31 +0,0 @@
/*++
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,12 +37,6 @@
<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">
@@ -78,12 +72,6 @@
<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,7 +6,6 @@
#include "Monarch.h"
#include "CommandlineArgs.h"
#include "FindTargetWindowArgs.h"
#include "QuitAllRequestedArgs.h"
#include "ProposeCommandlineResult.h"
#include "Monarch.g.cpp"
@@ -135,21 +134,13 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
// - <none> used
// Return Value:
// - <none>
winrt::fire_and_forget Monarch::_handleQuitAll(const winrt::Windows::Foundation::IInspectable& /*sender*/,
const winrt::Windows::Foundation::IInspectable& /*args*/)
void Monarch::_handleQuitAll(const winrt::Windows::Foundation::IInspectable& /*sender*/, const winrt::Windows::Foundation::IInspectable& /*args*/)
{
// 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())
if (_quitting.exchange(true, std::memory_order_relaxed))
{
co_await action;
return;
}
_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.
@@ -197,7 +188,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_acquire))
if (_quitting.load(std::memory_order_relaxed))
{
return;
}
@@ -1036,30 +1027,6 @@ 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,7 +96,6 @@ 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);
@@ -106,8 +105,6 @@ 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:
@@ -146,8 +143,8 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
void _renameRequested(const winrt::Windows::Foundation::IInspectable& sender,
const winrt::Microsoft::Terminal::Remoting::RenameRequestArgs& args);
winrt::fire_and_forget _handleQuitAll(const winrt::Windows::Foundation::IInspectable& sender,
const winrt::Windows::Foundation::IInspectable& args);
void _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,11 +46,6 @@ namespace Microsoft.Terminal.Remoting
Windows.Foundation.IReference<UInt64> WindowID;
}
[default_interface] runtimeclass QuitAllRequestedArgs {
QuitAllRequestedArgs();
Windows.Foundation.IAsyncAction BeforeQuitAllAction;
}
struct PeasantInfo
{
UInt64 Id;
@@ -72,7 +67,6 @@ 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);
@@ -82,7 +76,6 @@ 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,7 +5,6 @@
#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"
@@ -309,26 +308,6 @@ 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,7 +65,6 @@ 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);
@@ -82,7 +81,6 @@ 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,12 +32,6 @@ namespace Microsoft.Terminal.Remoting
Windows.Foundation.DateTime ActivatedTime { get; };
};
[default_interface] runtimeclass GetWindowLayoutArgs {
GetWindowLayoutArgs();
String WindowLayoutJson;
Windows.Foundation.IAsyncOperation<String> WindowLayoutJsonAsync;
}
enum MonitorBehavior
{
InPlace,
@@ -88,7 +82,6 @@ namespace Microsoft.Terminal.Remoting
void RequestHideNotificationIcon();
void RequestQuitAll();
void Quit();
String GetWindowLayout();
void AttachContentToWindow(AttachRequest request);
void SendContent(RequestReceiveContentArgs args);
@@ -102,7 +95,6 @@ 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

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

View File

@@ -1,29 +0,0 @@
/*++
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,8 +92,6 @@ 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 });
}
@@ -356,8 +354,6 @@ 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"),
@@ -412,18 +408,6 @@ 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();
@@ -434,19 +418,6 @@ 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,10 +38,8 @@ 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);
@@ -51,9 +49,6 @@ 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,12 +14,10 @@ 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();
@@ -33,8 +31,6 @@ 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

@@ -149,6 +149,11 @@ namespace winrt::TerminalApp::implementation
_languageProfileNotifier = winrt::make_self<LanguageProfileNotifier>([this]() {
_reloadSettings->Run();
});
// Do this here, rather than at the top of main. This will prevent us from
// including this variable in the vars we serialize in the
// Remoting::CommandlineArgs up in HandleCommandlineArgs.
_setupFolderPathEnvVar();
}
// Method Description:
@@ -697,22 +702,6 @@ 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;
@@ -720,4 +709,14 @@ namespace winrt::TerminalApp::implementation
return TerminalApp::ParseCommandlineResult{ winrt::to_hstring(_appArgs.GetExitMessage()), r };
}
// Function Description
// * Adds a `WT_SETTINGS_DIR` env var to our own environment block, that
// points at our settings directory. This allows portable installs to
// refer to files in the portable install using %WT_SETTINGS_DIR%
void AppLogic::_setupFolderPathEnvVar()
{
std::wstring path{ CascadiaSettings::SettingsPath() };
auto folderPath = path.substr(0, path.find_last_of(L"\\"));
SetEnvironmentVariableW(L"WT_SETTINGS_DIR", folderPath.c_str());
}
}

View File

@@ -53,9 +53,7 @@ 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;
@@ -112,6 +110,8 @@ namespace winrt::TerminalApp::implementation
void _RegisterSettingsChange();
fire_and_forget _DispatchReloadSettings();
void _setupFolderPathEnvVar();
#ifdef UNIT_TESTING
friend class TerminalAppLocalTests::CommandlineTest;
#endif

View File

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

View File

@@ -843,6 +843,16 @@ 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,12 +2,13 @@
// 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, Microsoft.Terminal.UI.IDirectKeyListener
[default_interface] runtimeclass CommandPalette : Windows.UI.Xaml.Controls.UserControl, Windows.UI.Xaml.Data.INotifyPropertyChanged, 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:mtu="using:Microsoft.Terminal.UI"
xmlns:model="using:Microsoft.Terminal.Settings.Model"
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
AllowFocusOnInteraction="True"
AutomationProperties.Name="{x:Bind ControlName, Mode=OneWay}"
@@ -23,6 +23,12 @@
<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"
@@ -56,7 +62,8 @@
<!--
The block for the key chord is only visible
when there's actual text set as the label.
when there's actual text set as the label. See
CommandKeyChordVisibilityConverter for details.
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,
@@ -70,7 +77,7 @@
AutomationProperties.AccessibilityView="Raw"
Background="{ThemeResource FlyoutPresenterBackground}"
Style="{ThemeResource KeyChordBorderStyle}"
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(Item.KeyChordText), Mode=OneWay}">
Visibility="{x:Bind Item.KeyChordText, Mode=OneWay, Converter={StaticResource CommandKeyChordVisibilityConverter}}">
<TextBlock AutomationProperties.AccessibilityView="Raw"
FontSize="12"
@@ -106,7 +113,8 @@
<!--
The block for the key chord is only visible
when there's actual text set as the label.
when there's actual text set as the label. See
CommandKeyChordVisibilityConverter for details.
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,
@@ -119,7 +127,7 @@
VerticalAlignment="Center"
AutomationProperties.AccessibilityView="Raw"
Style="{ThemeResource KeyChordBorderStyle}"
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(Item.KeyChordText), Mode=OneWay}">
Visibility="{x:Bind Item.KeyChordText, Mode=OneWay, Converter={StaticResource CommandKeyChordVisibilityConverter}}">
<TextBlock AutomationProperties.AccessibilityView="Raw"
FontSize="12"
@@ -339,12 +347,12 @@
VerticalAlignment="Center"
FontSize="14"
Text="{x:Bind PrefixCharacter, Mode=OneWay}"
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(PrefixCharacter), Mode=OneWay}" />
Visibility="{x:Bind PrefixCharacter, Mode=OneWay, Converter={StaticResource ParentCommandVisibilityConverter}}" />
<StackPanel Grid.Row="1"
Margin="8,0,8,8"
Orientation="Horizontal"
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(ParentCommandName), Mode=OneWay}">
Visibility="{x:Bind ParentCommandName, Mode=OneWay, Converter={StaticResource ParentCommandVisibilityConverter}}">
<Button x:Name="_parentCommandBackButton"
x:Uid="ParentCommandBackButton"
@@ -369,7 +377,7 @@
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Style="{ThemeResource ParsedCommandLineBorderStyle}"
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(ParsedCommandLineText), Mode=OneWay}">
Visibility="{x:Bind ParsedCommandLineText, Mode=OneWay, Converter={StaticResource ParsedCommandLineTextVisibilityConverter}}">
<ScrollViewer MaxHeight="200"
VerticalScrollBarVisibility="Auto">

View File

@@ -50,7 +50,6 @@ 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:
@@ -99,15 +98,6 @@ 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,8 +19,6 @@ 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

@@ -0,0 +1,38 @@
#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

@@ -0,0 +1,26 @@
#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

@@ -0,0 +1,19 @@
// 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

@@ -0,0 +1,14 @@
// 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

@@ -116,6 +116,9 @@ namespace winrt::TerminalApp::implementation
switch (visualState)
{
case WindowVisualState::WindowVisualStateIconified:
// Iconified (aka minimized) state should preserve the active window styling
break;
case WindowVisualState::WindowVisualStateMaximized:
VisualStateManager::GoToState(MaximizeButton(), L"WindowStateMaximized", false);
@@ -124,9 +127,7 @@ namespace winrt::TerminalApp::implementation
CloseButton().Height(maximizedHeight);
MaximizeToolTip().Text(RS_(L"WindowRestoreDownButtonToolTip"));
break;
case WindowVisualState::WindowVisualStateNormal:
case WindowVisualState::WindowVisualStateIconified:
default:
VisualStateManager::GoToState(MaximizeButton(), L"WindowStateNormal", false);

View File

@@ -17,7 +17,7 @@ namespace winrt::TerminalApp::implementation
{
Controls::IconElement PaletteItem::ResolvedIcon()
{
const auto icon = Microsoft::Terminal::UI::IconPathConverter::IconWUX(Icon());
const auto icon = 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 TerminalApp;
using namespace winrt::TerminalApp::implementation;
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(const bool asContent) const
NewTerminalArgs Pane::GetTerminalArgsForPane(BuildStartupKind kind) const
{
// Leaves are the only things that have controls
assert(_IsLeaf());
@@ -169,12 +169,17 @@ NewTerminalArgs Pane::GetTerminalArgsForPane(const bool asContent) const
// object. That would work for schemes set by the Terminal, but not ones set
// by VT, but that seems good enough.
// 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)
switch (kind)
{
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;
@@ -200,16 +205,13 @@ NewTerminalArgs Pane::GetTerminalArgsForPane(const bool asContent) 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,
const bool asContent,
const bool asMovePane)
Pane::BuildStartupState Pane::BuildStartupActions(uint32_t currentId, uint32_t nextId, BuildStartupKind kind)
{
// 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 (!asMovePane && _IsLeaf())
if (kind != BuildStartupKind::MovePane && _IsLeaf())
{
if (_lastActive)
{
@@ -223,18 +225,18 @@ Pane::BuildStartupState Pane::BuildStartupActions(uint32_t currentId,
auto buildSplitPane = [&](auto newPane) {
ActionAndArgs actionAndArgs;
actionAndArgs.Action(ShortcutAction::SplitPane);
const auto terminalArgs{ newPane->GetTerminalArgsForPane(asContent) };
const auto terminalArgs{ newPane->GetTerminalArgsForPane(kind) };
// 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 = (asContent && _IsLeaf() ? .5 : 1. - _desiredSplitPosition);
const auto splitSize = (kind != BuildStartupKind::None && _IsLeaf() ? .5 : 1. - _desiredSplitPosition);
SplitPaneArgs args{ SplitType::Manual, splitDirection, splitSize, terminalArgs };
actionAndArgs.Args(args);
return actionAndArgs;
};
if (asContent && _IsLeaf())
if (kind != BuildStartupKind::None && _IsLeaf())
{
return {
.args = { buildSplitPane(shared_from_this()) },
@@ -281,10 +283,10 @@ Pane::BuildStartupState Pane::BuildStartupActions(uint32_t currentId,
// 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);
auto firstState = _firstChild->BuildStartupActions(currentId, nextId + 1, kind);
// 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);
auto secondState = _secondChild->BuildStartupActions(nextId, nextId + firstState.panesCreated + 1, kind);
std::vector<ActionAndArgs> actions{};
actions.reserve(firstState.args.size() + secondState.args.size() + 3);

View File

@@ -31,6 +31,7 @@ namespace TerminalAppLocalTests
namespace winrt::TerminalApp::implementation
{
struct TerminalTab;
enum class BuildStartupKind;
}
enum class Borders : int
@@ -99,8 +100,8 @@ public:
std::optional<uint32_t> focusedPaneId;
uint32_t panesCreated;
};
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;
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;
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>Registerkarten auf der rechten Seite schließen</value>
<value>Tabs nach rechts schließen</value>
</data>
<data name="TabCloseOther" xml:space="preserve">
<value>Andere Registerkarten schließen</value>
</data>
<data name="TabClose" xml:space="preserve">
<value>Registerkarte schließen</value>
<value>Tab 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>Geteilter Bereich</value>
<value>Bereich teilen</value>
</data>
<data name="SearchWebText" xml:space="preserve">
<value>Websuche</value>
</data>
<data name="TabColorChoose" xml:space="preserve">
<value>Farbe...</value>
<value>Registerkartenfarbe ändern</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 duplizieren</value>
<value>Registerkarte kopieren</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>Drittanbieter-Hinweise</value>
<value>Hinweise von Drittanbietern</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>Nur Text</value>
<value>Unformatierter 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>Color...</value>
<value>Change tab 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,23 +766,16 @@
<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 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>
<value>This Terminal window is running as administrator</value>
</data>
<data name="CommandPalette_MatchesAvailable" xml:space="preserve">
<value>Suggestions found: {0}</value>
@@ -842,10 +835,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>
@@ -855,13 +848,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">
@@ -900,7 +893,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 tabla</value>
<value>Dividir pestaña</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>Color...</value>
<value>Cambiar color de pestaña</value>
</data>
<data name="TabColorCustomButton.Content" xml:space="preserve">
<value>Configuración personalizada...</value>
<value>Personalizar</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>Tareas iniciales</value>
<value>Introducción</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>Directiva de privacidad</value>
<value>Política 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 a tamaño normal</value>
<value>Restaurar</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 la Pestaña a una Nueva ventana</value>
<value>Mover pestaña a 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>Fermez...</value>
<value>Fermer</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>Fermez les Autres onglets</value>
<value>Fermer 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>Couleur...</value>
<value>Modifier la couleur de longlet</value>
</data>
<data name="TabColorCustomButton.Content" xml:space="preserve">
<value>Personnalisée...</value>
<value>Personnalisé</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>Prise en main</value>
<value>Bien démarrer</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>Politique de confidentialité</value>
<value>Charte de confidentialité</value>
<comment>A hyperlink name for the Terminal's privacy policy</comment>
</data>
<data name="AboutDialog_ThirdPartyNoticesLink.Content" xml:space="preserve">
<value>Avis de tiers</value>
<value>Mentions tierces</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>Niveau inférieur</value>
<value>Restaurer</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 tant qu'administrateur</value>
<value>Exécuter en temps qu'administrateur (restreint)</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 riquadro</value>
<value>Chiudi il 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>Colore...</value>
<value>Cambia colore scheda</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>Attività iniziali</value>
<value>Introduzione</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>Informative di terze parti</value>
<value>Comunicazioni 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 visualizzazione normale</value>
<value>Ripristina in basso</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 riquadro</value>
<value>Chiudi il 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 Painel</value>
<value>Fechar o painel</value>
</data>
<data name="SplitTabText" xml:space="preserve">
<value>Dividir Guia</value>
<value>Guia Dividir</value>
</data>
<data name="SplitPaneText" xml:space="preserve">
<value>Painel dividido</value>
<value>Dividir painel</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>Cor...</value>
<value>Alterar cor da guia</value>
</data>
<data name="TabColorCustomButton.Content" xml:space="preserve">
<value>Personalizados...</value>
<value>Personalizado</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>Ponto de Partida</value>
<value>Introdução</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>Seletor de guias</value>
<value>Alternador 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 Simples</value>
<value>Texto sem formatação</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á funcionando como Administrador</value>
<value>Esta janela do Terminal está sendo executada 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 Painel</value>
<value>Fechar o 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

@@ -166,7 +166,7 @@
<comment>{Locked=qps-ploc,qps-ploca,qps-plocm}</comment>
</data>
<data name="AppDescription" xml:space="preserve">
<value>Τнĕ Ņëω Ẅίηđŏẃś Ťėŗmįйάĺ !!! !!! !</value>
<value>Τĥз Йéщ Ẃįńđôẃѕ Тéѓmĩиâļ !!! !!! !</value>
</data>
<data name="AppDescriptionDev" xml:space="preserve">
<value>The Windows Terminal, but Unofficial</value>
@@ -177,22 +177,22 @@
<comment>{Locked}</comment>
</data>
<data name="AppDescriptionPre" xml:space="preserve">
<value>Ŵíňďōẁŝ Тєřмīπǻļ ωїτĥ å ρѓēνіéŵ θƒ ũφсőмϊπġ ƒєąτΰґёѕ !!! !!! !!! !!! !!! </value>
<value>Щΐňδόŵѕ Ŧęřмĭʼnäℓ ẅîťħ à φřеνίëẃ θƒ џрсøмΐʼnğ ƒĕāŧųřэś !!! !!! !!! !!! !!! </value>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem_Dev" xml:space="preserve">
<value>Open in Terminal (&amp;Dev)</value>
<comment>{Locked} The dev build will never be seen in multiple languages</comment>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem_Canary" xml:space="preserve">
<value>Ŏрέи ìη Тèřmīŋªŀ (&amp;Cãńãґγ) !!! !!! !</value>
<value>Θρēņ ïη Ţéгmĭηäŀ (&amp;Çäņдѓγ) !!! !!! !</value>
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the Canary version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem_Preview" xml:space="preserve">
<value>Φφєň ΐñ Ŧéгмϊñаľ &amp;Pŕėνĭώ !!! !!! !</value>
<value>Όрèп ìņ Ţêŕmїʼnåļ &amp;Рѓзνι℮ω !!! !!! !</value>
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the Preview version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem" xml:space="preserve">
<value>Ωρєⁿ ïπ &amp;Těѓmĭñäĺ !!! !!</value>
<value>Óрêп ìл &amp;Ťěѓmιиåĺ !!! !!</value>
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the non-preview version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
</data>
</root>

File diff suppressed because it is too large Load Diff

View File

@@ -166,7 +166,7 @@
<comment>{Locked=qps-ploc,qps-ploca,qps-plocm}</comment>
</data>
<data name="AppDescription" xml:space="preserve">
<value>Ťĥё Ñēщ Шίⁿðоẅś Ťėгмîήāľ !!! !!! !</value>
<value>Τĥз Йéщ Ẃįńđôẃѕ Тéѓmĩиâļ !!! !!! !</value>
</data>
<data name="AppDescriptionDev" xml:space="preserve">
<value>The Windows Terminal, but Unofficial</value>
@@ -177,22 +177,22 @@
<comment>{Locked}</comment>
</data>
<data name="AppDescriptionPre" xml:space="preserve">
<value>Шίηđóŵš Ŧĕяmїйà ẁітħ ª φяęνîёщ όƒ ûφĉбмíήĝ ƒêåťµřεŝ !!! !!! !!! !!! !!! </value>
<value>Щΐňδόŵѕ Ŧęřмĭʼnäℓ ẅîťħ à φřеνίëẃ θƒ џрсøмΐʼnğ ƒĕāŧųřэś !!! !!! !!! !!! !!! </value>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem_Dev" xml:space="preserve">
<value>Open in Terminal (&amp;Dev)</value>
<comment>{Locked} The dev build will never be seen in multiple languages</comment>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem_Canary" xml:space="preserve">
<value>Óрëπ íи Ťēяmілǻŀ (&amp;Cäηàřÿ) !!! !!! !</value>
<value>Θρēņ ïη Ţéгmĭηäŀ (&amp;Çäņдѓγ) !!! !!! !</value>
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the Canary version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem_Preview" xml:space="preserve">
<value>Óрзń ΐή Ŧěґмιлāℓ &amp;Pѓéνīĕω !!! !!! !</value>
<value>Όрèп ìņ Ţêŕmїʼnåļ &amp;Рѓзνι℮ω !!! !!! !</value>
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the Preview version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
</data>
<data name="ShellExtension_OpenInTerminalMenuItem" xml:space="preserve">
<value>Ôрëη ïп &amp;Tēѓмϊŋãł !!! !!</value>
<value>Óрêп ìл &amp;Ťěѓmιиåĺ !!! !!</value>
<comment>This is a menu item that will be displayed in the Windows File Explorer that launches the non-preview version of Windows Terminal. Please mark one of the characters to be an accelerator key.</comment>
</data>
</root>

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