Compare commits

...

54 Commits

Author SHA1 Message Date
Dustin L. Howett
ccffc18ccb Fix the appxbundle version to be the appx version (#12691)
The store did not like when I uploaded two Windows Terminal packages
built on the same date, because the appxbundle version defaulted to
YYYY.MMDD.something.

There was a risk that using *this* version number will fail because it is
thousands of numbers less than "2022". We'll have to see if the store
rolls it out properly. I cannot find any documentation on how the store
rolls out *bundle* versions (it is very aware of .appx versions...).

A local test with 1.14.72x (Preview) published via the store seems to
have worked.

(cherry picked from commit a5194b0c44)
2022-03-14 13:53:44 -05:00
Leonard Hecker
5d4797ff77 Fix "Element not found" error during settings loading (#12687)
This commit fixes a stray exception during settings loading,
caused by a failure to obtain the app's extension catalog.

## PR Checklist
* [x] Closes #12305
* [x] I work here
* [x] Tests added/passed

## Validation Steps Performed
I'm unable to replicate the issue. 
However an error log was provided in #12305 with which
the function causing the exception could be determined.

(cherry picked from commit 9c6ec75082)
2022-03-14 12:07:39 -05:00
Carlos Zamora
4c81dd4df5 Use UIA notifications for text output (#12358)
## Summary of the Pull Request
This change makes Windows Terminal raise a `RaiseNotificationEvent()` ([docs](https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.automation.peers.automationpeer.raisenotificationevent?view=winrt-22000)) for new text output to the buffer.

This is intended to help Narrator identify what new output appears and reduce the workload of diffing the buffer when a `TextChanged` event occurs.

## Detailed Description of the Pull Request / Additional comments
The flow of the event occurs as follows:
- `Terminal::_WriteBuffer()`
   - New text is output to the text buffer. Notify the renderer that we have new text (and what that text is).
- `Renderer::TriggerNewTextNotification()`
   - Cycle through all the rendering engines and tell them to notify handle the new text output.
   - None of the rendering engines _except_ `UiaEngine` has it implemented, so really we're just notifying UIA.
- `UiaEngine::NotifyNewText()`
   - Concatenate any new output into a string.
   - When we're done painting, tell the notification system to actually notify of new events occurring and clear any stored output text. That way, we're ready for the next renderer frame.
- `InteractivityAutomationPeer::NotifyNewOutput()` --> `TermControlAutomationPeer::NotifyNewOutput`
   - NOTE: these are split because of the in-proc and out-of-proc separation of the buffer.
   - Actually `RaiseNotificationEvent()` for the new text output.

Additionally, we had to handle the "local echo" problem: when a key is pressed, the character is said twice (once for the keyboard event, and again for the character being written to the buffer). To accomplish this, we did the following:
- `TermControl`:
   - here, we already handle keyboard events, so I added a line saying "if we have an automation peer attached, record the keyboard event in the automation peer".
- `TermControlAutomationPeer`:
   - just before the notification is dispatched, check if the string of recent keyboard events match the beginning of the string of new output. If that's the case, we can assume that the common prefix was the "local echo".

This is a fairly naive heuristic, but it's been working.

Closes the following ADO bugs:
- https://dev.azure.com/microsoft/OS/_workitems/edit/36506838
- (Probably) https://dev.azure.com/microsoft/OS/_workitems/edit/38011453

## Test cases
- [x] Base case: "echo hello"
- [x] Partial line change
- [x] Scrolling (should be unaffected)
- [x] Large output
- [x] "local echo": keyboard events read input character twice

(cherry picked from commit f9be1720bd)
2022-03-11 17:59:21 -06:00
Mike Griese
2dd9f098bd When we delete a profile, focus the delete button automatically (#12558)
This sure is bodgy, but it makes sense. Right now, when we delete a profile, we load in a totally new content for the new profile's settings. That one resets the scroll view and the focus, and now the "delete" button is obviously not focused.

Instead, this PR will manually re-focus the delete button of a profile page when the page is navigated to _because we deleted another profile_.

* [x] This will take care of #11971

(cherry picked from commit 7fdcd6f5b3)
Signed-off-by: Dustin Howett <duhowett@microsoft.com>
2022-03-11 17:45:22 -06:00
Leonard Hecker
fda81886aa Fix overflow in Viewport::FromDimensions (#12669)
This removes one source of potential integer overflows from the Viewport class.
Other parts were left untouched, as this entire class of overflow issues gets
 fixed all at once, as soon as we replace COORD with til::coord (etc.).

## PR Checklist
* [x] Closes #5271
* [x] I work here
* [x] Tests added/passed

## Validation Steps Performed
* Call `ScrollConsoleScreenBufferW` with out of bounds coordinates
* Doesn't crash 

(cherry picked from commit a4a6dfcc8d)
Signed-off-by: Dustin Howett <duhowett@microsoft.com>
2022-03-11 17:45:21 -06:00
Mike Griese
7d8db27482 Fix a pair of crashes, likely related to defterm (#12666)
This fixes a pair of inbox bugs, hopefully.

* MSFT:35731327
  * There's a small window where a peasant is being created when a monarch is exiting. When that happens, the new peasant will try to tell itself (the new monarch) when the peasant was last activated, but because the window hasn't actually finished instantiating, the peasant doesn't yet have a LastActivatedArgs to tell the monarch about.
* MSFT:32518679 (ARM version) / MSFT:32279047 (AMD64 version)
  * This one's tricky. Not totally sure this is the fix, bug assuming my hypothesis is correct, this should fix it. Regardless, this does fix a bug that was in the code.
  * If the king dies right as another window is starting, right while the new window is starting to ProposeCommandline to the monarch, the monarch could die. If it does, the new window just explodes too. Not what you want.

Vaguely tested the second bug manually, by setting breakpoints in the monarch, starting a defterm, then exiting the monarch while the handoff was in process. That now creates a new window, so that's at least something. `RemotingTests::TestProposeCommandlineWithDeadMonarch` was the closest I could get to testing that.

The first bug only got an eye check. Not sure how to repro, but I figured yeet and hopefully we get it.

* [x] Closes #12624

(cherry picked from commit f507d9f491)
2022-03-11 13:54:05 -06:00
Leonard Hecker
d8622b941e AtlasEngine: Fix ConstBuffer invalidation for background color changes (#12667)
The `bg != _r.backgroundColor` invalidation check wasn't symmetric with
us setting `_r.backgroundColor` to `bg | _api.backgroundOpaqueMixin`.
Due to this, when the `backgroundOpaqueMixin` changed,
we didn't always update the const buffer appropriately.

## PR Checklist
* [x] Closes #11773
* [x] I work here
* [x] Tests added/passed

## Validation Steps Performed
* Enable window transparency (`backgroundOpaqueMixin == 0x00000000`)
* Maximize window (ensure we have gutters in the first place)
* Disable window transparency (`backgroundOpaqueMixin == 0xff000000`)
* Gutters are filled 

(cherry picked from commit f17c2babd4)
2022-03-11 13:54:03 -06:00
Dustin L. Howett
7a0712d719 Revert "Make sure Terminal Stable shows up default on 22544+" (#12664)
This reverts commit 457738e388.

(cherry picked from commit 814386f2c3)
2022-03-10 17:31:57 -06:00
Mike Griese
8f7769468e Fix showing a dialog multiple times (#12625)
After the dialog is displayed, always clear it out. If we don't, we won't be able to display another!

* regressed in #12517.
* [x] Fixes #12622.

(cherry picked from commit 2e78ebfdc7)
2022-03-10 16:52:10 -06:00
Leonard Hecker
e321956f9f Fix Windows 10 support for nearby font loading (#12554)
By replacing `IDWriteFontSetBuilder2::AddFontFile` with
`IDWriteFactory5::CreateFontFileReference` and
`IDWriteFontSetBuilder1::AddFontFile` we add nearby
font loading support for Windows 10, build 15021.

This commit also fixes font fallback for AtlasEngine,
which was crashing during testing.

Finally it fixes a bug in DxEngine, where we only created a "nearby" font
collection if we couldn't find the font in the system collection. This doesn't
fix the bug, if the font is locked or broken in the system collection.

This is related to #11648.

## PR Checklist
* [x] Closes #12420
* [x] I work here
* [x] Tests added/passed

## Validation Steps Performed
* Build a Debug version of Windows Terminal
* Put Jetbrains Mono into the writeable AppX directory
* Jetbrains Mono is present in the settings UI 
* DxEngine works with Jetbrains Mono 
* AtlasEngine works with Jetbrains Mono 

(cherry picked from commit f84ccad42d)
2022-03-10 16:52:09 -06:00
Leonard Hecker
8dfe520427 Fix activation context generation for conhost (#12653)
This regressed in 2b202ce6, which removed `ACTCTX_FLAG_RESOURCE_NAME_VALID`
during `CreateActCtxW` under the assumption that an executable only has
one manifest. conhost has two however and we need to pick the correct one.

On OpenConsole this causes the expected `ERROR_SXS_PROCESS_DEFAULT_ALREADY_SET`.

Closes MSFT:38355907

(cherry picked from commit c820af46b7)
2022-03-10 16:52:08 -06:00
Mike Griese
1388b5933a Update the tab colors some more (#12635)
Again, to reflect continuing discussion with the WinUI team. A doc may have been misread - these are the colors they're proposing, which are generally a lot better.

See also: #12400, #12356, #12398

![image](https://user-images.githubusercontent.com/18356694/157041174-c0eb2140-3b49-4494-8746-b3a12f396fe6.png)

(cherry picked from commit aaa3ee77db)
2022-03-10 16:52:07 -06:00
Mike Griese
5a5c17dedb Make the Scrollbar 16dips again (#12608)
BODGY: Controlsv2 changed the size of the scrollbars from 16dips to
12dips. This is harder for folks to hit with the mouse, and isn't
consistent with the rest of the scrollbars on the platform (as much
as they can be).

To work around this, we have to entirely copy the template for the
ScrollBar into our XAML file. We're then also re-defining
ScrollBarSize here to 16, so that the new template will pick up on
the new value.

This is kinda a pain, and we have to be careful to be sure to ingest
an updated version of the template any time we update MUX. The
latest Controlsv2 version of the template can be found at:
https://github.com/microsoft/microsoft-ui-xaml/blob/main/dev/CommonStyles/ScrollBar_themeresources.xaml#L218

We're also planning on making this adjustable in the future
(GH#9218), where we might need this anyways.

##### after, before:
![image](https://user-images.githubusercontent.com/18356694/156254464-1a9080f6-51ce-4619-b002-2a3c607cdf5f.png)

##### after overlayed on top of before
![image](https://user-images.githubusercontent.com/18356694/156254546-fccc3cee-12a3-4e1a-8fd7-7470f1ec93ad.png)

##### comparison
![image](https://user-images.githubusercontent.com/18356694/156257934-ec4ac840-c8ca-4fca-a848-08a32b1c55c3.png)

* reported originally in #12395
* upstream: https://github.com/microsoft/microsoft-ui-xaml/issues/6684
* closes an element of #12400

(cherry picked from commit da2cf8c3f6)
2022-03-10 16:52:05 -06:00
Carlos Zamora
763f9b07c0 Stop making settings.json backups (#12652)
## Summary of the Pull Request
This makes it so that the settings.json backups are no longer created when the user saves their settings via the Settings UI.

Closes #11703

(cherry picked from commit 91f5648b5e)
2022-03-10 16:52:04 -06:00
Leonard Hecker
cdd0376951 Replace Summon with Show/Hide for improved i18n (#12603)
"Summon" was translated as a synonym for "citation" in Spanish instead
of treating it as a RPG-related word. "Show/Hide" will hopefully
allow an improved automatic translation in the future.

Closes #10691

(cherry picked from commit f217f6dc33)
2022-03-10 16:52:03 -06:00
Michael Niksa
a15044c83d Fix release YML paths for VPACK for Win10/11 split (#12621)
(cherry picked from commit f4066cd0b0)
2022-03-10 16:52:02 -06:00
Ian O'Neill
2308a22af9 Fix RTF generation for Unicode characters (#12586)
## Summary of the Pull Request
Fixes RTF generation for text with Unicode characters.

## PR Checklist
* [x] Closes #12379
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [x] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx

## Validation Steps Performed
Added some unit tests.

Ran the following in PowerShell and copied the emitted text into WordPad.
```pwsh
echo "This is some Ascii \ {}`nLow code units: á é í ó ú `u{2b81} `u{2b82}`nHigh code units: `u{a7b5} `u{a7b7}`nSurrogates: `u{1f366} `u{1f47e} `u{1f440}"
```

(cherry picked from commit 00113e3e48)
2022-03-10 16:52:01 -06:00
Leonard Hecker
9e960ceef4 Fix fail-fast due to unlocked FreeProcessData call (#12599)
2b202ce6 introduced a bug, where FreeProcessData was called without the console
lock being held. The previous code can be found in 40e3dea, on line 441-454.

## PR Checklist
* [x] Closes MSFT:21372705
* [x] I work here
* [x] Tests added/passed

## Validation Steps Performed
None, as this fix is purely theoretic, but it matches the stack trace
and 40e3dea clearly wasn't correctly ported to strict C++ either.

(cherry picked from commit 79a08ecd18)
2022-03-10 16:52:00 -06:00
Mike Griese
3914779f85 Fix a crash setting the hotkey during teardown (#12580)
From MSFT:36797001. Okay so this is only .22% of our crashes, but every little bit helps, right?

Turns out this is also hitting in:
* MSFT:35726322
* MSFT:34662459

and together they're a fairly hot bug.

There's a large class of bugs where we might get a callback to one of our event handlers when we call `app.Close()` in the `AppHost` dtor. This PR adds manual revokers to these events, and makes sure to revoke them BEFORE nulling out the `_window`. That will prevent callbacks during the rest of the dtor, when the `_window` is null.

(cherry picked from commit 8962c75c61)
2022-03-10 16:51:58 -06:00
Mike Griese
4f2bce18a0 Update light theme tab background for greater contrast. (#12529)
Changes the tab view BG to `#e8e8e8`, as discussed in mail thread.

Closes #12398

(cherry picked from commit c62705ea9f)
2022-03-10 16:51:57 -06:00
Leonard Hecker
bc166b874f AtlasEngine: Fix inverted cursor alpha (#12548)
The previous implementation only inverted the RGB values of the cell,
but failed to account for situations where the `color` is transparent,
which is the case when `backgroundOpaqueMixin` is 0 (for instance if
acrylic backgrounds are enabled). In these situations the alpha
component remained 0 which caused the cursor to be invisible.

For some inexplicable reason this issue is only visible on a HDR display,
even though it should also effect regular ones. God knows why.

With this commit the cursor texture is treated as a mask that inverts the color.
We use branching here, because I couldn't come up with a more clever solution.

## PR Checklist
* [x] Closes #12507
* [x] I work here
* [x] Tests added/passed

## Validation Steps Performed
* Cursor is visible on a HDR display with acrylic background 
* TBD performance benchmark for `[branch]` 

(cherry picked from commit 9ab4abfb54)
2022-03-10 16:51:56 -06:00
Dustin L. Howett
3631720b55 Protect the command palette against being paged with no items (#12528)
Fixes two crashes amounting to 14% of our crash burden in Simulated
Selfhost. I can't reproduce this organically, but I was able to do so by
forcing the command palette to be empty.

(cherry picked from commit 30aa514276)
2022-03-10 16:51:55 -06:00
Ian O'Neill
0a8cb7d7c1 Don't crash trying to parse a command line that's a directory (#12538)
## Summary of the Pull Request
Prevents a crash that could occur when invoking `wt C:\`

## PR Checklist
* [x] Closes #12535
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [x] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx

## Detailed Description of the Pull Request / Additional comments
Updates `CascadiaSettings::NormalizeCommandLine()` to check that there are a suitable number of command line arguments to be concatenated together, to prevent accessing an array index in `argv` that doesn't exist.

Also prevents a test flake that could occur in `TerminalSettingsTests::CommandLineToArgvW()`, due to generating an empty command line argument.

## Validation Steps Performed
Added a test, and checked that invoking each of the command lines below behaved as expected:
```
wtd C:\ # Window pops up with [error 2147942405 (0x80070005) when launching `C:\']
wtd C:\Program Files # Window pops up with [error 2147942402 (0x80070002) when launching `C:\Program Files']
wtd cmd # cmd profile pops up
wtd C:\Program Files\Powershell\7\pwsh -WorkingDirectory C:\ # PowerShell profile pops up in C:\
wtd "C:\Program Files\Powershell\7\pwsh" -WorkingDirectory C:\ # PowerShell profile pops up in C:\
wtd . # Window pops up with [error 2147942405 (0x80070005) when launching `.']
```

(cherry picked from commit 722aafadeb)
2022-03-10 16:51:54 -06:00
PankajBhojwani
c4266ccd95 No longer load content dialogs when there is already one being shown (#12517)
## Summary of the Pull Request
Somehow, the controls v2 update caused an issue where if you as much as _load_ a content dialog when there's already one open, we get holes in the terminal window (#12447)

This commit introduces logic to `TerminalPage` to check whether there is a content dialog open before we try to load another one.

## PR Checklist
* [x] Closes #12447
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [x] I work here

## Validation Steps Performed
Can no longer repro #12447

(cherry picked from commit 788d33ce94)
2022-03-10 16:51:53 -06:00
Carlos Zamora
3a42dc2065 Remove "Window Persistence" feature flag (#12499)
Removes the `Feature_PersistedWindowLayout` feature flag so that it's always enabled.

Closes #12422

(cherry picked from commit d36cb754db)
2022-03-10 16:51:52 -06:00
Dustin L. Howett
e6a1947918 build: ship a Win11 build of Terminal that's <=half the size (#12560)
Four (4) squashed changes, with messages preserved.

Right now, symbol publication happens every time we produce a final
bundle. In the future, we may be producing multiple bundles from the
same pipeline run, and we need to make sure we only do *one* symbol
publication to MSDL.

When we do that, it will be advantageous for us to have just one phase
that source-indexes and publishes all of the symbols.

This removes the trick we pulled in #5661 and saves us ~550kb per arch.

Some of our dependencies still depend on the "app" versions of the
runtime libraries, so we are going to continue shipping the forwarders
in our package. Build rules have been updated to remove the non-Desktop
VCLibs dependency to slim down our package graph.

This is not a problem on Windows 11 -- it looks like it's shipped inbox.

**BREAKING CHANGE**: When launched unpackaged, Terminal now requires the
vcruntime redist to be installed.

common.openconsole.props is a pretty good place to stash the XAML
version since it is included in every project (including the WAP
project (unlike the C++ build props!)).

I've gone ahead and added a "double dependency" on multiple XAML
versions. We'll toggle them with a build flag.

This required some changes in how we download artifacts to make sure
that we could control which version of Windows we were processing in any
individual step.

We're also going to patch the package manifest on the Windows 11 version
so the store targets it more specifically.

On top of the prior three steps, this lets us ship a Windows 11
package that costs only ~15MB on disk. The Windows 10 version, for
comparison, is about 40.

(cherry picked from commit 53a454fbd3)
Signed-off-by: Dustin Howett <duhowett@microsoft.com>
2022-02-24 18:15:34 -06:00
PankajBhojwani
b8398d865b Fix font axes/features not working on DPI change (#12492)
When the dpi is changed, call `updateFont()` instead of `TriggerFontChange`, this
means that we continue to use the existing font features/axes

Closes #11287

(cherry picked from commit 3b4679431d)
2022-02-16 11:57:52 -06:00
Dustin L. Howett
e6010b8a49 Copy localized strings from ContextMenu into the resource root (#12491)
We chose to use the "ContextMenu" resource compartment when we
changed the package name to Terminal in #12264 because it was more
broadly localized than the rest of the application.

It appears as though some platform features have trouble with the
"more qualified" resource paths that #12264 required.

To fix this, we will:

1. Copy all of the ContextMenu localizations into CascadiaPackage's
   resource root
2. Switch all manifest resource paths to use resources from the package
   root.

Regressed in #12264
Closes #12384
Closes #12406 (tracked in microsoft/powertoys#16118)

(cherry picked from commit 9501b23ad1)
2022-02-16 11:57:52 -06:00
Mike Griese
ed2de8fa2e DON'T default-construct the MediaPlayer (#12463)
I believe this fixes #12383, but I can't seem to find a way to set up a N SKU VM to confirm this.

* [ ] TODO: wait till the morning to finish copying the N vhd I found off the build shares, to confirm this doesn't crash on launch.

(cherry picked from commit 2cf46d41cc)
2022-02-16 11:57:51 -06:00
Mike Griese
9f3e459e97 Manually set the colors of the TabViewBackground (#12460)
This has been a saga.

Basically, any resources in `App.xaml` aren't going to be able to reference other theme-aware resources. We can't change the theme of the app at runtime, only elements within the app. So we can't use `ApplicationPageBackgroundThemeBrush` in app.xaml, because it will ALWAYS be evaluated as the OS theme version of that brush.

* regressed in #12326
* See also #10864
* #3917 CANNOT be fixed in the same way. We're lucky here that the TabView uses a `{ThemeResource TabViewBackground}` in markup to set the bg. We're not similarly lucky with the Pane one.
* [x] closes #12356
* [x] Tested manually. You can confirm, my eyes are bleeding from the OS-wide light mode

(cherry picked from commit 5ba0d618f5)
2022-02-16 11:57:51 -06:00
Leonard Hecker
ea69e10ad4 Fix off-by-one bug in NormalizeCommandLine (#12484)
#12348 introduced an off-by-one bug. While the `NormalizeCommandLine` loop
should exit early when there aren't at least _two_ arguments to be joined,
the final argument-append needs to happen even if just _one_ argument exists.

This commit fixes the issue and introduces changes to additionally monitor
the early loop exit, as well as the call to `ExpandEnvironmentStringsW`.

## PR Checklist
* [x] Closes #12461
* [x] I work here
* [x] Tests added/passed

## Validation Steps Performed
* All `TerminalSettingsTests` tests pass 

(cherry picked from commit e06e1314a8)
2022-02-16 11:57:51 -06:00
Mike Griese
6413d242c2 Enable Segoe Variable (#12462)
By adding another entry to our `maxversiontested`s.

Screenshots in https://github.com/microsoft/terminal/issues/12452#issuecomment-1035356054

* [x] Closes #12452
* [x] I work here
* [x] Docs are fine
* [x] Tests are fine

(cherry picked from commit 09e9915672)
2022-02-16 11:57:51 -06:00
Mike Griese
f646a28408 Updates all our icons to use Segoe Fluent (#12469)
* use `FontFamily="{ThemeResource SymbolThemeFontFamily}"` where possible, in XAML
* use `FontFamily{ L"Segoe Fluent Icons, Segoe MDL2 Assets" }` in codebehind

Basically just a simple string replace.

* [x] This was a bullet point in #11353
* [x] Confirmed manually on my win10 PC
* see also #12438

Actually, this is the last bullet in #11353, so I'm gonna say closes #11353.

Screenshots below.

(cherry picked from commit 0a15643c9c)
2022-02-16 11:57:50 -06:00
Michael Niksa
99eee04914 Source index the public symbols too (#12450)
Now that we've figured out how to publish the public symbols to the official Microsoft download server... we may as well embed the source code linking information inside of them given that it's right here on GitHub. This attempts to run our existing source linking scripts against the public copy of the symbols.

## PR Checklist
* [x] Closes #12443
* [x] I work here
* [x] Tested manually

## Validation Steps Performed
* [x] Build with it: https://dev.azure.com/microsoft/Dart/_build/results?buildId=44930661&view=logs&j=8f802011-b567-5b81-5fa6-bce316c020ce
* [x] Point the debugger at them and see if it can find the sources
* [x] Maybe also look at them in a hex editor or whatnot and validate I can see the source paths pointing at GitHub

(cherry picked from commit 8b9066962d)
2022-02-16 11:57:50 -06:00
Mike Griese
cd2830c946 Update the cmdpal narrator message to include the number of results. (#12429)
Updates this narrator announcement message to include the number of results it found. There are two versions:
* one for a singular result
* one for multiple results.

which should help with loc.

We're trying to get this in with the loc hotfix, so 👀 please

* [x] will take care of the last bit of #7907

verified with narrator locally.

(cherry picked from commit 9ea0c93435)
2022-02-16 11:57:50 -06:00
Michael Niksa
f30d6a859d Automate packaged submission into Windows (#12449)
We're now building a fully provenance, compliance, and security
validated package (vpack) through our Release pipeline. This attaches
the last phase which automates the submission into the Windows product.
It will also automatically trace back the source, commit SHA, and build
to the submission here from the Windows side.

* [x] Automates a manual activity I performed a few times recently
* [x] I work here
* [x] Ran a test of it against `release-1.12` and it worked

(cherry picked from commit 10c963a7db)
2022-02-16 11:57:50 -06:00
Mike Griese
076ca02a12 Don't ever allow ~ as a startingDirectory (#12437)
Basically, some WSL distros ship fragments that replace the `commandline` with the executable for their distro (`ubuntu.exe`, etc.). We didn't expect that when we changed the `startingDirectory` for them all to `~`.

Unfortunately, `~` is really never a valid path for a process on windows, so those distros would now fail with

```
[error 2147942667 (0x8007010b) when launching `ubuntu1804.exe']
Could not access starting directory "~"
```

If we find that we were unable to mangle `~` into the user's WSL `commandline`, then we will re-evaluate that `startingDirectory` as `%USERPROFILE%`, which is at least something sensible, if albeit not what they wanted.

* regressed in #12315
* [x] Closes #12353
* [x] Tested with a (`ubuntu1804.exe`, `~`) profile - launched successfully, where 1.13 in market fails.
* [x] added tests

(cherry picked from commit 1870feeca3)
2022-02-08 18:52:50 -06:00
Mike Griese
37b59c180c Fix defterm + elevate by default (#12442)
We absolutely cannot allow a defterm connection to
auto-elevate. Defterm doesn't work for elevated senarios in the
first place. If we try accepting the connection, the spawning an
elevated version of the Terminal with that profile... that's a
recipe for disaster. We won't ever open up a tab in this window.

* [x] Closes #12370
* [x] Tested manually, since there's not a great way to add defterm tests

(cherry picked from commit 303f9d7cbd)
2022-02-08 18:52:50 -06:00
James Holderness
f740cf09b6 Allow exceptions from ITerminalApi and TerminalDispatch (#12432)
This PR updates the `ITerminalApi` and `TerminalDispatch` classes to
allow exceptions to be thrown in case of errors instead of using boolean
return values.

## References

This brings the Terminal code into alignment with the `AdaptDispatch`
and `ConGetSet` changes made in PR #12247.

And while this isn't exactly a fix for #12378, it does at least stop the
app from crashing now.

## Detailed Description of the Pull Request / Additional comments

All the `TerminalDispatch` methods have had their `noexcept` specifiers
dropped, and any `try`/`catch` wrapping removed, so exceptions will now
fall through to the `StateMachine` class where they should be safely
caught and logged.

The same goes for the `ITerminalApi` interface and its implementation in
the `Terminal` class. And many of the methods in this interface have
also had their `bool` return values changed to `void`, since there is
usually not a need for error return values now.

## Validation Steps Performed

I've manually tested the `OSC 9;9` sequence described in #12378 and
confirmed that it no longer crashes.

(cherry picked from commit 9c11e025bb)
2022-02-08 18:52:49 -06:00
Carlos Zamora
7f660c2786 Validate cursor position in UIA UTR ctor (#12436)
This adds some validation in the `UiaTextRange` ctor for the cursor position.

#8730 was caused by creating a `UiaTextRange` at the cursor position when it was in a delayed state (meaning it's purposefully hanging off of the right edge of the buffer). Normally, `Cursor` maintains a flag to keep track of when that occurs, but Windows Terminal isn't maintaining that properly in `Terminal::WriteBuffer`.

The _correct_ approach would be to fix `WriteBuffer` then leverage that flag for validation in `UiaTextRange`. However, messing with `WriteBuffer` is a little too risky for our comfort right now. So we'll do the second half of that by checking if the cursor position is valid. Since the cursor is really only expected to be out of bounds when it's in that delayed state, we get the same result (just maybe a tad slower than simply checking a flag).

Closes #8730

Filed #12440 to track changes in `Terminal::_WriteBuffer` for delayed EOL wrap.

## Validation Steps Performed
While using magnifier, input/delete wrapped text in input buffer.

(cherry picked from commit 5dcf5262b4)
2022-02-08 18:52:49 -06:00
Dustin L. Howett
287030377f Publish the symbols from our MSIX bundle to the public server (#12441)
Closes #12203

(cherry picked from commit 59ef21a124)
2022-02-08 18:52:49 -06:00
Mike Griese
a94989c89d Properly fall back to Segoe MDL2 for our icons on Win10 (#12438)
Segoe Fluent isn't available on Windows 10, and doesn't stealthily ship with WinUI. So if we manually set the font family to `"Segoe Fluent Icons"`, then that will just display boxes in Win10.

This instead uses the resource `"{ThemeResource SymbolThemeFontFamily}"` which will gracefully fall back on Win10.

See:
* https://github.com/microsoft/microsoft-ui-xaml/issues/3745, which inspired this solution.

Guess what! The backgound image icons were also manually specifying this font, so they had to get updated too. I couldn't find any other `Segoe Fluent` references in the code.

* [x] Closes #12350
* [x] Checked Windows 11 locally
* [x] Checked Win10 (screenshots incoming from other machine)

(cherry picked from commit 27a1b9de13)
2022-02-08 18:52:49 -06:00
Leonard Hecker
4c62adf17b XtermEngine: Explicitly emit cursor state on the first frame (#12434)
This commit fixes an issue, where we failed to emit a DECTCEM sequence to hide
the cursor if it was hidden before XtermEngine's first frame was finalized.
Even in such cases we need to emit a DECTCEM sequence
in order to ensure we're in a consistent state.

## Validation Steps Performed
* Added test
* Run #12401's repro steps around 30 times

Closes #12401

(cherry picked from commit dbb70778d4)
2022-02-08 18:52:49 -06:00
PankajBhojwani
8243087dcc Fix focus box around color schemes combo box (#12439)
The focus box around the color schemes combo box was getting cut off, this change adds a small margin to the stackpanel to allow space for the focus box

## PR Checklist
* [x] Closes #12328

(cherry picked from commit f5f0712ae3)
2022-02-08 18:52:48 -06:00
Mike Griese
25d4e72d77 Fix a potential crash when setting up the jumplist (#12430)
I have no idea how this is even possible to hit. If this is able to be null, then we failed to load the settings in such a catastrophic way that nothing should work. However, OP's Terminal seemed to have already loaded the settings. By all accounts, doesn't make sense.

Regardless, the code here would crash if this ever is null, so we may as well catch it.

* [x] Closes #12360
* [ ] No way to verify this since it isn't even reproable on OPs machine, but it does have a lot of hits for that failure bucket (!!!)

(cherry picked from commit d0daab6252)
2022-02-08 18:52:48 -06:00
Leonard Hecker
4cc8481fc7 Fix profile matching for paths containing unquoted whitespace (#12348)
The previous code had two bugs for:
* paths with more than 1 whitespace
  The code joins the argv array by replacing null-word terminators with
  whitespace. Unfortunately it always referred to the separator between
  `argv[0]` and `argv[1]` for this instead of continuing to join
  those between 1 and 2, etc.
* paths sharing a common prefix with another directory
  `SearchPathW` returns paths that aren't necessarily paths to files.
  A call to `GetFileAttributesW` was added, ensuring we only resolve file paths.

## PR Checklist
* [x] Closes #12345
* [x] I work here
* [ ] Tests added/passed

## Validation Steps Performed
* Paths with more than 1 whitespace resolve correctly 
* Paths with neighboring directories sharing a common prefix resolve correctly 
* Tests added 

(cherry picked from commit 3171a8957b)
2022-02-08 18:52:48 -06:00
PankajBhojwani
4d058c638a Fix invoking the rightmost breadcrumb bringing you back to Profiles_Base (#12376)
## Summary of the Pull Request
We no longer do anything when the rightmost breadcrumb is invoked

## PR Checklist
* [x] Closes #12325
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [x] I work here

## Validation Steps Performed
Tested manually, cannot repro #12325 anymore

(cherry picked from commit 527b9cdf78)
2022-02-08 18:52:48 -06:00
PankajBhojwani
34aa297be2 Fix disclaimer text not centralizing when maximized (#12374)
## Summary of the Pull Request
Fix the disclaimer text boxes in `Rendering` and `Defaults`not centralizing along with the expanders when the window is maximized

## PR Checklist
* [ ] Closes #xxx
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [x] I work here

## Validation Steps Performed
<img width="1128" alt="defaults" src="https://user-images.githubusercontent.com/26824113/152584084-a999cb29-73bc-4970-889a-f95ea64c1b4c.png">
<img width="1128" alt="rendering" src="https://user-images.githubusercontent.com/26824113/152584099-a54519da-7bca-4ebe-b487-b68ac5cf1a37.png">

(cherry picked from commit 260435860e)
2022-02-08 18:52:48 -06:00
Michael Niksa
db25a217ac Hardcode the language list for the package manifest and settings dropdown (#12375)
The `x-generate` statement seems to have fallen apart somewhere and is no longer generating the valid list of languages for display. This hardcodes the list into the manifest to restore it, which is a valid option per the documentation.

We also hardcode the limited subset of languages into the Settings application because the main application supports fewer languages than we have been translated into for the shell extensions for Windows Explorer and Start Menu integration.

## PR Checklist
* [x] Closes #12351
* [x] I work here.
* [x] Manual tests below

## Validation Steps Performed
- [x] Clean built locally with `msbuild.exe openconsole.sln /p:Configuration=Release /p:Platform=x64 /p:WindowsTerminalBranding=Release /t:Terminal\CascadiaPackage /m /bl:log4.binlog` and checked that the `appxmanifest.xml` that popped out the other side contained the same languages that it used to contain.
- [x] Built in the release pipeline
- [x] Installed release and preview branded packages. Changed my machine language to Polish (pl-PL) which is not one of the fully localized languages, but is one of the limited ones. Checked the start menu and right-click menus and saw Polish text for Terminal and Terminal Preview. Checked the Settings page in our app and saw only the limited 14 language list for the application itself.

(cherry picked from commit 7734cd7d80)
2022-02-08 18:52:47 -06:00
PankajBhojwani
3adf80d919 Fix toggle switches needing a negative margin (#12381)
## Summary of the Pull Request
Reducing the `MinWidth` of a toggle switch means it no longer needs a negative margin to align it correctly

## PR Checklist
* [ ] Closes #xxx
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [x] I work here

## Validation Steps Performed
Setting a different language no longer causes the toggle switch to fall out of the expander

(cherry picked from commit 64efa6745d)
2022-02-08 18:52:47 -06:00
Dustin L. Howett
93b5c3843e appx: Use a different resource for the Properties DisplayName (#12337)
We have to do this so that the store sees us as one thing ("Windows
Terminal") and the Start menu sees us as another ("Terminal").

The store will reject our package if the value we use for "DisplayName"
here doesn't match the store's "reserved names".

This value is *not used* by the start menu.

(cherry picked from commit e064c15675)
2022-02-02 21:00:06 -06:00
PankajBhojwani
1aab365ee1 Fix more SUI and Rejuvenated UI issues (#12326)
- The add new profile page now uses a dropdown rather than radio buttons
- Subheaders, breadcrumb bar, buttons etc are now all centralized when the window is maximized (so they all align with the expanders now)
- We no longer override the titlebar colors and instead use the xaml defaults (these still aren't great but at least we will get the fix automatically when it happens upstream)
- Breadcrumb bar no longer has a negative margin, so there's no weird overlap that happens when the window becomes small
- The number boxes for launch size and font size now use the `Inline` placement mode rather than compact, allowing modification to the number with fewer clicks
- Textboxes now have a greater max width so they can occupy more space in the expander if needed

(cherry picked from commit 0a545b7b94)
2022-02-02 15:44:44 -06:00
Carlos Zamora
8557748a06 Update accessible names for 'add profile' page buttons (#12324)
## Summary of the Pull Request
When using a screen reader, the buttons on the "add a new profile" page were being read weirdly:
- "New empty profile" button read as "create new button button"
- "duplicate" button read as "duplicate button button"

It's generally standard to read out the text inside the button, so I did just that by reusing the existing localized resources. This also removes the redundant "button" that is said by the screen reader.

I also removed the unused `AutomationId` and unnecessary `Button.Content` tags.

#11156 can be closed upon validation by the accessibility team.

## Validation Steps Performed
 navigate to both buttons using Narrator; make sure it sounds right

(cherry picked from commit 24c5f7bba4)
2022-02-02 15:00:33 -06:00
Dustin Howett
6ccbd62f04 PGO: train 1.13 separately
(cherry picked from commit 989a9303c39d924653472b3e4ee640411e969455)
2022-02-02 13:03:41 -06:00
150 changed files with 3724 additions and 1491 deletions

View File

@@ -21,6 +21,8 @@ downside
downsides
dze
dzhe
EDDB
EDDC
Enum'd
Fitt
formattings
@@ -74,6 +76,8 @@ runtimes
shcha
slnt
Sos
timeline
timelines
timestamped
TLDR
tokenizes

View File

@@ -10,16 +10,16 @@ bitfields
BUILDBRANCH
BUILDMSG
BUILDNUMBER
BYPOSITION
BYCOMMAND
BYPOSITION
charconv
CLASSNOTAVAILABLE
cmdletbinding
COLORPROPERTY
colspan
COMDLG
comparand
commandlinetoargv
comparand
cstdint
CXICON
CYICON
@@ -52,8 +52,8 @@ hotkeys
href
hrgn
HTCLOSE
HWINSTA
hwinsta
HWINSTA
IActivation
IApp
IAppearance
@@ -72,12 +72,13 @@ IFACEMETHOD
IFile
IInheritable
IMap
IMonarch
IObject
iosfwd
IPackage
IPeasant
isspace
ISetup
isspace
IStorage
istream
IStringable
@@ -94,14 +95,14 @@ lround
Lsa
lsass
LSHIFT
memicmp
MENUCOMMAND
MENUDATA
MENUINFO
MENUITEMINFOW
memicmp
mptt
MOUSELEAVE
mov
mptt
msappx
MULTIPLEUSE
NCHITTEST
@@ -125,6 +126,7 @@ oaidl
ocidl
ODR
offsetof
ofstream
onefuzz
osver
OSVERSIONINFOEXW
@@ -176,6 +178,7 @@ THEMECHANGED
tlg
TME
tmp
tmpdir
tolower
toupper
TRACKMOUSEEVENT
@@ -188,7 +191,6 @@ UOI
UPDATEINIFILE
userenv
USEROBJECTFLAGS
WSF
wcsstr
wcstoui
winmain
@@ -196,6 +198,7 @@ winsta
winstamin
wmemcmp
wpc
WSF
wsregex
wwinmain
xchg

View File

@@ -19,6 +19,7 @@ CPRs
cryptbase
DACL
DACLs
defaultlib
diffs
disposables
dotnetfeed
@@ -27,6 +28,8 @@ DWINRT
enablewttlogging
Intelli
IVisual
libucrt
libucrtd
LKG
LOCKFILE
Lxss
@@ -36,10 +39,11 @@ microsoftonline
MSAA
msixbundle
MSVC
MSVCP
muxc
netcore
osgvsowi
Onefuzz
osgvsowi
PFILETIME
pgc
pgo
@@ -63,6 +67,8 @@ systemroot
taskkill
tasklist
tdbuildteamid
ucrt
ucrtd
unvirtualized
VCRT
vcruntime

View File

@@ -237,6 +237,7 @@ charlespetzold
charset
CHARSETINFO
chcp
Checkin
checkbox
checkboxes
chh
@@ -318,6 +319,7 @@ concat
concfg
conclnt
conddkrefs
condev
condrv
conechokey
conemu
@@ -471,6 +473,7 @@ cygwin
CYHSCROLL
CYMIN
CYPADDEDBORDER
CYRL
CYSIZE
CYSIZEFRAME
CYSMICON
@@ -671,6 +674,7 @@ dwriteglyphrundescriptionclustermap
dxgi
dxgidwm
dxinterop
dxp
dxsm
dxttbmp
Dyreen
@@ -1151,6 +1155,7 @@ ioctl
iomanip
iostream
iot
ipa
ipch
ipconfig
IPersist
@@ -1238,12 +1243,14 @@ KLF
KLMNO
KLMNOPQRST
KLMNOPQRSTQQQQQ
KOK
KPRIORITY
KVM
langid
LANGUAGELIST
lasterror
lastexitcode
LATN
LAYOUTRTL
LBN
LBound
@@ -1460,6 +1467,7 @@ msctls
msdata
msdn
msft
MSDL
MSGCMDLINEF
MSGF
MSGFILTER
@@ -1471,6 +1479,7 @@ MSGSELECTMODE
msiexec
MSIL
msix
mspartners
msrc
msvcrt
MSVCRTD
@@ -1792,6 +1801,9 @@ placeholders
platforming
playsound
plist
PLOC
PLOCA
PLOCM
PLOGICAL
plugin
PMv
@@ -1925,6 +1937,7 @@ qsort
queryable
QUESTIONMARK
quickedit
QUZ
QWER
qzmp
RAII
@@ -2075,6 +2088,7 @@ rxvt
safearray
SAFECAST
safemath
sapi
sba
SBCS
SBCSDBCS
@@ -2437,6 +2451,7 @@ TREX
triaged
triaging
TRIANGLESTRIP
Tribool
TRIMZEROHEADINGS
truetype
trx
@@ -2564,6 +2579,7 @@ uuidv
UVWX
UVWXY
UWA
UWAs
uwp
uxtheme
vals
@@ -2659,6 +2675,7 @@ wddmcon
wddmconrenderer
WDDMCONSOLECONTEXT
wdm
wdx
webclient
webpage
website
@@ -2693,6 +2710,7 @@ wincontypes
WINCORE
windbg
WINDEF
windev
WINDIR
windll
WINDOWALPHA

View File

@@ -0,0 +1,24 @@
{
"Branch": [
{
"collection": "microsoft",
"project": "OS",
"repo": "os.2020",
"name": "official/rs_wdx_dxp_windev",
"workitem": "38106206",
"CheckinFiles": [
{
"source": "WindowsTerminal.app.man",
"path": "/redist/mspartners/ipa/WindowsTerminal",
"type": "File"
}
]
}
],
"Email": [
{
"sendTo": "condev",
"sendOnErrorOnly": "False"
}
]
}

View File

@@ -9,7 +9,7 @@
<PropertyGroup>
<!-- Optional, defaults to main. Name of the branch which will be used for calculating branch point. -->
<PGOBranch>main</PGOBranch>
<PGOBranch>release-1.13</PGOBranch>
<!-- Mandatory. Name of the NuGet package which will contain PGO databases for consumption by build system. -->
<PGOPackageName>Microsoft.Internal.Windows.Terminal.PGODatabase</PGOPackageName>

View File

@@ -22,6 +22,10 @@ parameters:
displayName: "Run Compliance and Security Build"
type: boolean
default: true
- name: publishSymbolsToPublic
displayName: "Publish Symbols to MSDL"
type: boolean
default: true
- name: buildTerminalVPack
displayName: "Build Windows Terminal VPack"
type: boolean
@@ -48,6 +52,11 @@ parameters:
- x64
- x86
- arm64
- name: buildWindowsVersions
type: object
default:
- Win10
- Win11
variables:
TerminalInternalPackageVersion: "0.0.7"
@@ -64,9 +73,11 @@ jobs:
matrix:
${{ each config in parameters.buildConfigurations }}:
${{ each platform in parameters.buildPlatforms }}:
${{ config }}_${{ platform }}:
BuildConfiguration: ${{ config }}
BuildPlatform: ${{ platform }}
${{ each windowsVersion in parameters.buildWindowsVersions }}:
${{ config }}_${{ platform }}_${{ windowsVersion }}:
BuildConfiguration: ${{ config }}
BuildPlatform: ${{ platform }}
TerminalTargetWindowsVersion: ${{ windowsVersion }}
displayName: Build
timeoutInMinutes: 240
cancelTimeoutInMinutes: 1
@@ -151,6 +162,11 @@ jobs:
$Files | % { Move-Item -Verbose $_.Directory $_.Directory.Parent.Parent -EA:Ignore }
pwsh: true
- task: PowerShell@2
displayName: Copy the Context Menu Loc Resources to CascadiaPackage
inputs:
filePath: ./build/scripts/Copy-ContextMenuResourcesToCascadiaPackage.ps1
pwsh: true
- task: PowerShell@2
displayName: Generate NOTICE.html from NOTICE.md
inputs:
@@ -158,6 +174,10 @@ jobs:
arguments: -MarkdownNoticePath .\NOTICE.md -OutputPath .\src\cascadia\CascadiaPackage\NOTICE.html
pwsh: true
- ${{ if eq(parameters.buildTerminal, true) }}:
- pwsh: |-
./build/scripts/Patch-ManifestsToWindowsVersion.ps1 -NewWindowsVersion "10.0.22000.0"
displayName: Update manifest target version to Win11 (if necessary)
condition: and(succeeded(), eq(variables['TerminalTargetWindowsVersion'], 'Win11'))
- task: VSBuild@1
displayName: Build solution **\OpenConsole.sln
condition: true
@@ -175,7 +195,7 @@ jobs:
continueOnError: True
inputs:
PathtoPublish: $(Build.SourcesDirectory)\msbuild.binlog
ArtifactName: binlog-$(BuildPlatform)
ArtifactName: binlog-$(BuildPlatform)-$(TerminalTargetWindowsVersion)
- task: PowerShell@2
displayName: Check MSIX for common regressions
inputs:
@@ -238,7 +258,7 @@ jobs:
displayName: Publish Artifact (appx)
inputs:
PathtoPublish: $(Build.ArtifactStagingDirectory)/appx
ArtifactName: appx-$(BuildPlatform)-$(BuildConfiguration)
ArtifactName: appx-$(BuildPlatform)-$(BuildConfiguration)-$(TerminalTargetWindowsVersion)
- ${{ if eq(parameters.buildWPF, true) }}:
- task: CopyFiles@2
displayName: Copy PublicTerminalCore.dll to Artifacts
@@ -256,7 +276,7 @@ jobs:
condition: and(succeeded(), ne(variables['BuildPlatform'], 'arm64'))
inputs:
PathtoPublish: $(Build.ArtifactStagingDirectory)/wpf
ArtifactName: wpf-dll-$(BuildPlatform)-$(BuildConfiguration)
ArtifactName: wpf-dll-$(BuildPlatform)-$(BuildConfiguration)-$(TerminalTargetWindowsVersion)
- task: PublishSymbols@2
displayName: Publish symbols path
@@ -274,6 +294,11 @@ jobs:
- ${{ if eq(parameters.buildTerminal, true) }}:
- job: BundleAndSign
strategy:
matrix:
${{ each windowsVersion in parameters.buildWindowsVersions }}:
${{ windowsVersion }}:
TerminalTargetWindowsVersion: ${{ windowsVersion }}
displayName: Create and sign AppX/MSIX bundles
dependsOn: Build
steps:
@@ -286,20 +311,16 @@ jobs:
displayName: Package ES - Setup Build
inputs:
disableOutputRedirect: true
- task: DownloadBuildArtifacts@0
displayName: Download Artifacts (*.appx, *.msix)
inputs:
downloadType: specific
itemPattern: >-
**/*.msix
**/*.appx
extractTars: false
- ${{ each platform in parameters.buildPlatforms }}:
- task: DownloadBuildArtifacts@0
displayName: Download Artifacts ${{ platform }} $(TerminalTargetWindowsVersion)
inputs:
artifactName: appx-${{ platform }}-Release-$(TerminalTargetWindowsVersion)
- task: PowerShell@2
displayName: Create WindowsTerminal*.msixbundle
inputs:
filePath: build\scripts\Create-AppxBundle.ps1
arguments: -InputPath "$(System.ArtifactsDirectory)" -ProjectName CascadiaPackage -BundleVersion 0.0.0.0 -OutputPath "$(System.ArtifactsDirectory)\Microsoft.WindowsTerminal_$(XES_APPXMANIFESTVERSION)_8wekyb3d8bbwe.msixbundle"
arguments: -InputPath "$(System.ArtifactsDirectory)" -ProjectName CascadiaPackage -BundleVersion $(XES_APPXMANIFESTVERSION) -OutputPath "$(System.ArtifactsDirectory)\Microsoft.WindowsTerminal_$(TerminalTargetWindowsVersion)_$(XES_APPXMANIFESTVERSION)_8wekyb3d8bbwe.msixbundle"
- task: EsrpCodeSigning@1
displayName: Submit *.msixbundle to ESRP for code signing
inputs:
@@ -334,11 +355,12 @@ jobs:
"ToolVersion": "1.0"
}
]
- task: PublishBuildArtifacts@1
displayName: 'Publish Artifact: appxbundle-signed'
inputs:
PathtoPublish: $(System.ArtifactsDirectory)
ArtifactName: appxbundle-signed
ArtifactName: appxbundle-signed-$(TerminalTargetWindowsVersion)
- ${{ if eq(parameters.buildWPF, true) }}:
- job: PackageAndSignWPF
@@ -362,14 +384,14 @@ jobs:
- task: DownloadBuildArtifacts@0
displayName: Download x86 PublicTerminalCore
inputs:
artifactName: wpf-dll-x86-$(BuildConfiguration)
artifactName: wpf-dll-x86-$(BuildConfiguration)-Win10
itemPattern: '**/*.dll'
downloadPath: bin\Win32\$(BuildConfiguration)\
extractTars: false
- task: DownloadBuildArtifacts@0
displayName: Download x64 PublicTerminalCore
inputs:
artifactName: wpf-dll-x64-$(BuildConfiguration)
artifactName: wpf-dll-x64-$(BuildConfiguration)-Win10
itemPattern: '**/*.dll'
downloadPath: bin\x64\$(BuildConfiguration)\
extractTars: false
@@ -451,6 +473,71 @@ jobs:
PathtoPublish: $(Build.ArtifactStagingDirectory)\nupkg
ArtifactName: wpf-nupkg-$(BuildConfiguration)
- ${{ if eq(parameters.publishSymbolsToPublic, true) }}:
- job: PublishSymbols
displayName: Publish Symbols
dependsOn: BundleAndSign
steps:
- checkout: self
clean: true
fetchDepth: 1
submodules: true
- task: PkgESSetupBuild@12
displayName: Package ES - Setup Build
# Download the appx-PLATFORM-CONFIG-VERSION artifact for every platform/version combo
- ${{ each platform in parameters.buildPlatforms }}:
- ${{ each windowsVersion in parameters.buildWindowsVersions }}:
- task: DownloadBuildArtifacts@0
displayName: Download Symbols ${{ platform }} ${{ windowsVersion }}
inputs:
artifactName: appx-${{ platform }}-Release-${{ windowsVersion }}
# It seems easier to do this -- download every appxsym -- then enumerate all the PDBs in the build directory for the
# public symbol push. Otherwise, we would have to list all of the PDB files one by one.
- pwsh: |-
mkdir $(Build.SourcesDirectory)/appxsym-temp
Get-ChildItem "$(System.ArtifactsDirectory)" -Filter *.appxsym -Recurse | % {
$src = $_.FullName
$dest = Join-Path "$(Build.SourcesDirectory)/appxsym-temp/" $_.Name
mkdir $dest
Write-Host "Extracting $src to $dest..."
tar -x -v -f $src -C $dest
}
displayName: Extract symbols for public consumption
# Pull the Windows SDK for the developer tools like the debuggers so we can index sources later
- template: .\templates\install-winsdk-steps.yml
- task: PowerShell@2
displayName: Source Index PDBs (the public ones)
inputs:
filePath: build\scripts\Index-Pdbs.ps1
arguments: -SearchDir '$(Build.SourcesDirectory)/appxsym-temp' -SourceRoot '$(Build.SourcesDirectory)' -recursive -Verbose -CommitId $(Build.SourceVersion)
# Publish the app symbols to the public MSDL symbol server
# accessible via https://msdl.microsoft.com/download/symbols
- task: PublishSymbols@2
displayName: 'Publish app symbols to MSDL'
inputs:
symbolsFolder: '$(Build.SourcesDirectory)/appxsym-temp'
searchPattern: '**/*.pdb'
SymbolsMaximumWaitTime: 30
SymbolServerType: 'TeamServices'
SymbolsProduct: 'Windows Terminal Application Binaries'
SymbolsVersion: '$(XES_APPXMANIFESTVERSION)'
# The ADO task does not support indexing of GitHub sources.
indexSources: false
detailedLog: true
# There is a bug which causes this task to fail if LIB includes an inaccessible path (even though it does not depend on it).
# To work around this issue, we just force LIB to be any dir that we know exists.
# Copied from https://github.com/microsoft/icu/blob/f869c214adc87415dfe751d81f42f1bca55dcf5f/build/azure-nuget.yml#L564-L583
env:
LIB: $(Build.SourcesDirectory)
ArtifactServices_Symbol_AccountName: microsoftpublicsymbols
ArtifactServices_Symbol_PAT: $(ADO_microsoftpublicsymbols_PAT)
- ${{ if eq(parameters.buildTerminalVPack, true) }}:
- job: VPack
displayName: Create Windows vPack
@@ -465,7 +552,7 @@ jobs:
- task: DownloadBuildArtifacts@0
displayName: Download Build Artifacts
inputs:
artifactName: appxbundle-signed
artifactName: appxbundle-signed-Win11
extractTars: false
- task: PowerShell@2
displayName: Rename and stage packages for vpack
@@ -474,7 +561,7 @@ jobs:
script: >-
# Rename to known/fixed name for Windows build system
Get-ChildItem Microsoft.WindowsTerminal_*.msixbundle | Rename-Item -NewName { 'Microsoft.WindowsTerminal_8wekyb3d8bbwe.msixbundle' }
Get-ChildItem Microsoft.WindowsTerminal_Win11_*.msixbundle | Rename-Item -NewName { 'Microsoft.WindowsTerminal_8wekyb3d8bbwe.msixbundle' }
# Create vpack directory and place item inside
@@ -482,14 +569,25 @@ jobs:
mkdir WindowsTerminal.app
mv Microsoft.WindowsTerminal_8wekyb3d8bbwe.msixbundle .\WindowsTerminal.app\
workingDirectory: $(System.ArtifactsDirectory)\appxbundle-signed
workingDirectory: $(System.ArtifactsDirectory)\appxbundle-signed-Win11
- task: PkgESVPack@12
displayName: 'Package ES - VPack'
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
inputs:
sourceDirectory: $(System.ArtifactsDirectory)\appxbundle-signed\WindowsTerminal.app
description: Windows Terminal pre-install application
sourceDirectory: $(System.ArtifactsDirectory)\appxbundle-signed-Win11\WindowsTerminal.app
description: VPack for the Windows Terminal Application
pushPkgName: WindowsTerminal.app
owner: condev
owner: conhost
- task: PublishPipelineArtifact@1
displayName: 'Copy VPack Manifest to Drop'
inputs:
targetPath: $(XES_VPACKMANIFESTDIRECTORY)
artifactName: VPackManifest
- task: PkgESFCIBGit@12
displayName: 'Submit VPack Manifest to Windows'
inputs:
configPath: '$(Build.SourcesDirectory)\build\config\GitCheckin.json'
artifactsDirectory: $(XES_VPACKMANIFESTDIRECTORY)
prTimeOut: 5
...

View File

@@ -0,0 +1,34 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
$LocalizationsFromContextMenu = Get-ChildItem ./src/cascadia/TerminalApp/Resources -Recurse -Filter ContextMenu.resw
$Languages = [System.Collections.HashTable]::New()
$LocalizationsFromContextMenu | ForEach-Object {
$Languages[$_.Directory.Name] = $_
}
ForEach ($pair in $Languages.GetEnumerator()) {
$LanguageDir = "./src/cascadia/CascadiaPackage/Resources/$($pair.Key)"
$ResPath = "$LanguageDir/Resources.resw"
$PreexistingResw = Get-Item $ResPath -EA:Ignore
If ($null -eq $PreexistingResw) {
Write-Host "Copying $($pair.Value.FullName) to $ResPath"
New-Item -type Directory $LanguageDir -EA:Ignore
Copy-Item $pair.Value.FullName $ResPath
} Else {
# Merge Them!
Write-Host "Merging $($pair.Value.FullName) into $ResPath"
$existingXml = [xml](Get-Content $PreexistingResw.FullName)
$newXml = [xml](Get-Content $pair.Value.FullName)
$newDataKeys = $newXml.root.data.name
$existingXml.root.data | % {
If ($_.name -in $newDataKeys) {
$null = $existingXml.root.RemoveChild($_)
}
}
$newXml.root.data | % {
$null = $existingXml.root.AppendChild($existingXml.ImportNode($_, $true))
}
$existingXml.Save($PreexistingResw.FullName)
}
}

View File

@@ -0,0 +1,14 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
Param(
[string]$NewWindowsVersion = "10.0.22000.0"
)
Get-ChildItem src/cascadia/CascadiaPackage -Recurse -Filter *.appxmanifest | ForEach-Object {
$xml = [xml](Get-Content $_.FullName)
$xml.Package.Dependencies.TargetDeviceFamily | Where-Object Name -Like "Windows*" | ForEach-Object {
$_.MinVersion = $NewWindowsVersion
}
$xml.Save($_.FullName)
}

View File

@@ -10,4 +10,18 @@
<OpenConsoleDir>$(MSBuildThisFileDirectory)</OpenConsoleDir>
</PropertyGroup>
<PropertyGroup>
<!--
For the Windows 10 build, we're targeting the prerelease version of Microsoft.UI.Xaml.
This version emits every XAML DLL directly into our package.
This is a workaround for us not having deliverable MSFT-21242953 on this version of Windows.
-->
<TerminalMUXVersion>2.7.0-prerelease.210913003</TerminalMUXVersion>
<!--
For the Windows 11-specific build, we're targeting the public version of Microsoft.UI.Xaml.
This version emits a package dependency instead of embedding the dependency in our own package.
-->
<TerminalMUXVersion Condition="'$(TerminalTargetWindowsVersion)'=='Win11'">2.7.0</TerminalMUXVersion>
</PropertyGroup>
</Project>

View File

@@ -2,6 +2,18 @@
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- This file is read by XES, which we use in our Release builds. -->
<PropertyGroup Label="Version">
<!--
The Windows 11 build is going to have the same package name, so it *must* have a different version.
The easiest way for us to do this is to add 1 to the revision field.
In short, for a given Terminal build 1.11, we will emit two different versions (assume this is build
4 on day 23 of the year):
- 1.11.234.0 for Windows 10
- 1.11.235.0 for Windows 11
This presents a potential for conflicts if we want to ship two builds produced back to back on the
same day... which is terribly unlikely.
-->
<VersionBuildRevision Condition="'$(TerminalTargetWindowsVersion)'=='Win11' and '$(VersionBuildRevision)'!=''">$([MSBuild]::Add($(VersionBuildRevision), 1))</VersionBuildRevision>
<XesUseOneStoreVersioning>true</XesUseOneStoreVersioning>
<XesBaseYearForStoreVersion>2021</XesBaseYearForStoreVersion>
<VersionMajor>1</VersionMajor>

View File

@@ -140,12 +140,12 @@
<!-- **END VC LIBS HACK** -->
<!-- This is required to get the package dependency in the AppXManifest. -->
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets')" />
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.7.0\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.7.0\build\native\Microsoft.UI.Xaml.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\..\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.UI.Xaml.2.7.0\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.7.0\build\native\Microsoft.UI.Xaml.targets'))" />
</Target>

View File

@@ -147,13 +147,13 @@
<!-- ========================= Globals ======================== -->
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets')" />
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.7.0\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.7.0\build\native\Microsoft.UI.Xaml.targets')" />
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets'))" />
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.7.0\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.7.0\build\native\Microsoft.UI.Xaml.targets'))" />
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
</Target>

View File

@@ -80,13 +80,13 @@
</ItemGroup>
<Import Project="$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets')" />
<Import Project="$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.7.0\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.7.0\build\native\Microsoft.UI.Xaml.targets')" />
<Import Project="$(OpenConsoleDir)packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('$(OpenConsoleDir)packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets'))" />
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.7.0\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.7.0\build\native\Microsoft.UI.Xaml.targets'))" />
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
</Target>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Toolkit.Win32.UI.XamlApplication" version="6.1.3" targetFramework="native" />
<package id="Microsoft.UI.Xaml" version="2.7.0-prerelease.210913003" targetFramework="native" />
<package id="Microsoft.UI.Xaml" version="2.7.0" targetFramework="native" />
<package id="Microsoft.Windows.CppWinRT" version="2.0.210825.3" targetFramework="native" />
</packages>

View File

@@ -137,14 +137,14 @@
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets')" />
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.7.0\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.7.0\build\native\Microsoft.UI.Xaml.targets')" />
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
<Import Project="..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.4\build\native\Microsoft.VCRTForwarders.140.targets" Condition="Exists('..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.4\build\native\Microsoft.VCRTForwarders.140.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\..\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.UI.Xaml.2.7.0\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.7.0\build\native\Microsoft.UI.Xaml.targets'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.props'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.4\build\native\Microsoft.VCRTForwarders.140.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.VCRTForwarders.140.1.0.4\build\native\Microsoft.VCRTForwarders.140.targets'))" />

View File

@@ -2,6 +2,6 @@
<packages>
<package id="Microsoft.Windows.CppWinRT" version="2.0.210825.3" targetFramework="native" />
<package id="Microsoft.Toolkit.Win32.UI.XamlApplication" version="6.1.3" targetFramework="native" />
<package id="Microsoft.UI.Xaml" version="2.7.0-prerelease.210913003" targetFramework="native" />
<package id="Microsoft.UI.Xaml" version="2.7.0" targetFramework="native" />
<package id="Microsoft.VCRTForwarders.140" version="1.0.4" targetFramework="native" />
</packages>

View File

@@ -2034,20 +2034,8 @@ std::string TextBuffer::GenRTF(const TextAndColor& rows, const int fontHeightPoi
const auto writeAccumulatedChars = [&](bool includeCurrent) {
if (col >= startOffset)
{
const auto unescapedText = ConvertToA(CP_UTF8, std::wstring_view(rows.text.at(row)).substr(startOffset, col - startOffset + includeCurrent));
for (const auto c : unescapedText)
{
switch (c)
{
case '\\':
case '{':
case '}':
contentBuilder << "\\" << c;
break;
default:
contentBuilder << c;
}
}
const auto text = std::wstring_view{ rows.text.at(row) }.substr(startOffset, col - startOffset + includeCurrent);
_AppendRTFText(contentBuilder, text);
startOffset = col;
}
@@ -2146,6 +2134,31 @@ std::string TextBuffer::GenRTF(const TextAndColor& rows, const int fontHeightPoi
}
}
void TextBuffer::_AppendRTFText(std::ostringstream& contentBuilder, const std::wstring_view& text)
{
for (const auto codeUnit : text)
{
if (codeUnit <= 127)
{
switch (codeUnit)
{
case L'\\':
case L'{':
case L'}':
contentBuilder << "\\" << gsl::narrow<char>(codeUnit);
break;
default:
contentBuilder << gsl::narrow<char>(codeUnit);
}
}
else
{
// Windows uses unsigned wchar_t - RTF uses signed ones.
contentBuilder << "\\u" << std::to_string(til::bit_cast<int16_t>(codeUnit)) << "?";
}
}
}
// Function Description:
// - Reflow the contents from the old buffer into the new buffer. The new buffer
// can have different dimensions than the old buffer. If it does, then this

View File

@@ -247,6 +247,8 @@ private:
void _PruneHyperlinks();
static void _AppendRTFText(std::ostringstream& contentBuilder, const std::wstring_view& text);
std::unordered_map<size_t, std::wstring> _idsAndPatterns;
size_t _currentPatternId;

View File

@@ -138,36 +138,34 @@
</ItemGroup>
</Target>
<!-- **BEGIN VC LIBS HACK** -->
<!--
For our release builds, we're just going to integrate the UWPDesktop CRT into our package and delete the package dependencies.
It's very difficult for users who do not have access to the store to get our dependency packages, and we want to be robust
and deployable everywhere. Since these libraries can be redistributed, it's easiest if we simply redistribute them.
See also the "VC LIBS HACK" section in WindowsTerminal.vcxproj.
Some of our dependencies still require a CRT, so we're going to ship the forwarders in our package and
depend on the desktop CRT. This lets us unify the Windows 10 and Windows 11 builds around a common CRT.
-->
<!-- This target removes the FrameworkSdkReferences from before the AppX package targets manifest generation happens.
This is part of the generic machinery that applies to every AppX. -->
<Target Name="_OpenConsoleStripAllDependenciesFromPackageFirstManifest" BeforeTargets="_GenerateCurrentProjectAppxManifest">
<ItemGroup Condition="'$(WindowsTerminalOfficialBuild)'=='true'">
<FrameworkSdkReference Remove="@(FrameworkSdkReference)" />
<ItemGroup>
<FrameworkSdkReference Remove="@(FrameworkSdkReference)" Condition="'%(FrameworkSdkReference.SimpleName)'=='Microsoft.VCLibs'" />
<FrameworkSdkPackage Remove="@(FrameworkSdkPackage)" Condition="'%(FrameworkSdkPackage.Name)'=='Microsoft.VCLibs.140.00' or '%(FrameworkSdkPackage.Name)'=='Microsoft.VCLibs.140.00.Debug'" />
</ItemGroup>
</Target>
<!-- This target removes the FrameworkSdkPackages from before the *desktop bridge* manifest generation happens. -->
<Target Name="_OpenConsoleStripAllDependenciesFromPackageSecondManifest" BeforeTargets="_GenerateDesktopBridgeAppxManifest" DependsOnTargets="_ResolveVCLibDependencies">
<ItemGroup Condition="'$(WindowsTerminalOfficialBuild)'=='true'">
<FrameworkSdkPackage Remove="@(FrameworkSdkPackage)" />
<ItemGroup>
<FrameworkSdkReference Remove="@(FrameworkSdkReference)" Condition="'%(FrameworkSdkReference.SimpleName)'=='Microsoft.VCLibs'" />
<FrameworkSdkPackage Remove="@(FrameworkSdkPackage)" Condition="'%(FrameworkSdkPackage.Name)'=='Microsoft.VCLibs.140.00' or '%(FrameworkSdkPackage.Name)'=='Microsoft.VCLibs.140.00.Debug'" />
</ItemGroup>
</Target>
<!-- **END VC LIBS HACK** -->
<!-- This is required to get the package dependency in the AppXManifest. -->
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets')" />
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\..\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets'))" />
</Target>
<Import Project="$(SolutionDir)build\rules\CollectWildcardResources.targets" />

View File

@@ -20,7 +20,7 @@
Version="0.0.1.0" />
<Properties>
<DisplayName>ms-resource:TerminalApp/ContextMenu/AppNameDev</DisplayName>
<DisplayName>ms-resource:AppStoreNameDev</DisplayName>
<PublisherDisplayName>A Lone Developer</PublisherDisplayName>
<Logo>Images\StoreLogo.png</Logo>
</Properties>
@@ -30,7 +30,7 @@
</Dependencies>
<Resources>
<Resource Language="x-generate"/>
<Resource Language="EN-US" />
</Resources>
<Applications>
@@ -38,8 +38,8 @@
Executable="$targetnametoken$.exe"
EntryPoint="$targetentrypoint$">
<uap:VisualElements
DisplayName="ms-resource:TerminalApp/ContextMenu/AppNameDev"
Description="ms-resource:TerminalApp/ContextMenu/AppDescriptionDev"
DisplayName="ms-resource:AppNameDev"
Description="ms-resource:AppDescriptionDev"
BackgroundColor="transparent"
Square150x150Logo="Images\Square150x150Logo.png"
Square44x44Logo="Images\Square44x44Logo.png">
@@ -47,7 +47,7 @@
Wide310x150Logo="Images\Wide310x150Logo.png"
Square71x71Logo="Images\SmallTile.png"
Square310x310Logo="Images\LargeTile.png"
ShortName="ms-resource:TerminalApp/ContextMenu/AppShortNameDev">
ShortName="ms-resource:AppShortNameDev">
<uap:ShowNameOnTiles>
<uap:ShowOn Tile="square150x150Logo"/>
<uap:ShowOn Tile="wide310x150Logo"/>
@@ -66,7 +66,7 @@
<uap5:StartupTask
TaskId="StartTerminalOnLoginTask"
Enabled="false"
DisplayName="ms-resource:TerminalApp/ContextMenu/AppNameDev" />
DisplayName="ms-resource:AppNameDev" />
</uap5:Extension>
<uap3:Extension Category="windows.appExtensionHost">
<uap3:AppExtensionHost>

View File

@@ -21,7 +21,7 @@
Version="0.5.0.0" />
<Properties>
<DisplayName>ms-resource:TerminalApp/ContextMenu/AppNamePre</DisplayName>
<DisplayName>ms-resource:AppStoreNamePre</DisplayName>
<PublisherDisplayName>Microsoft Corporation</PublisherDisplayName>
<Logo>Images\StoreLogo.png</Logo>
</Properties>
@@ -31,7 +31,95 @@
</Dependencies>
<Resources>
<Resource Language="x-generate"/>
<Resource Language="EN-US" />
<Resource Language="EN-GB" />
<Resource Language="AF-ZA" />
<Resource Language="AM-ET" />
<Resource Language="AR-SA" />
<Resource Language="AS-IN" />
<Resource Language="AZ-LATN-AZ" />
<Resource Language="BG-BG" />
<Resource Language="BN-IN" />
<Resource Language="BS-LATN-BA" />
<Resource Language="CA-ES" />
<Resource Language="CA-ES-VALENCIA" />
<Resource Language="CS-CZ" />
<Resource Language="CY-GB" />
<Resource Language="DA-DK" />
<Resource Language="DE-DE" />
<Resource Language="EL-GR" />
<Resource Language="ES-ES" />
<Resource Language="ES-MX" />
<Resource Language="ET-EE" />
<Resource Language="EU-ES" />
<Resource Language="FA-IR" />
<Resource Language="FI-FI" />
<Resource Language="FIL-PH" />
<Resource Language="FR-CA" />
<Resource Language="FR-FR" />
<Resource Language="GA-IE" />
<Resource Language="GD-GB" />
<Resource Language="GL-ES" />
<Resource Language="GU-IN" />
<Resource Language="HE-IL" />
<Resource Language="HI-IN" />
<Resource Language="HR-HR" />
<Resource Language="HU-HU" />
<Resource Language="HY-AM" />
<Resource Language="ID-ID" />
<Resource Language="IS-IS" />
<Resource Language="IT-IT" />
<Resource Language="JA-JP" />
<Resource Language="KA-GE" />
<Resource Language="KK-KZ" />
<Resource Language="KM-KH" />
<Resource Language="KN-IN" />
<Resource Language="KO-KR" />
<Resource Language="KOK-IN" />
<Resource Language="LB-LU" />
<Resource Language="LO-LA" />
<Resource Language="LT-LT" />
<Resource Language="LV-LV" />
<Resource Language="MI-NZ" />
<Resource Language="MK-MK" />
<Resource Language="ML-IN" />
<Resource Language="MR-IN" />
<Resource Language="MS-MY" />
<Resource Language="MT-MT" />
<Resource Language="NB-NO" />
<Resource Language="NE-NP" />
<Resource Language="NL-NL" />
<Resource Language="NN-NO" />
<Resource Language="OR-IN" />
<Resource Language="PA-IN" />
<Resource Language="PL-PL" />
<Resource Language="PT-BR" />
<Resource Language="PT-PT" />
<Resource Language="QPS-PLOC" />
<Resource Language="QPS-PLOCA" />
<Resource Language="QPS-PLOCM" />
<Resource Language="QUZ-PE" />
<Resource Language="RO-RO" />
<Resource Language="RU-RU" />
<Resource Language="SK-SK" />
<Resource Language="SL-SI" />
<Resource Language="SQ-AL" />
<Resource Language="SR-CYRL-BA" />
<Resource Language="SR-CYRL-RS" />
<Resource Language="SR-LATN-RS" />
<Resource Language="SV-SE" />
<Resource Language="TA-IN" />
<Resource Language="TE-IN" />
<Resource Language="TH-TH" />
<Resource Language="TR-TR" />
<Resource Language="TT-RU" />
<Resource Language="UG-CN" />
<Resource Language="UK-UA" />
<Resource Language="UR-PK" />
<Resource Language="UZ-LATN-UZ" />
<Resource Language="VI-VN" />
<Resource Language="ZH-CN" />
<Resource Language="ZH-TW" />
</Resources>
<Applications>
@@ -39,8 +127,8 @@
Executable="$targetnametoken$.exe"
EntryPoint="$targetentrypoint$">
<uap:VisualElements
DisplayName="ms-resource:TerminalApp/ContextMenu/AppNamePre"
Description="ms-resource:TerminalApp/ContextMenu/AppDescriptionPre"
DisplayName="ms-resource:AppNamePre"
Description="ms-resource:AppDescriptionPre"
BackgroundColor="transparent"
Square150x150Logo="Images\Square150x150Logo.png"
Square44x44Logo="Images\Square44x44Logo.png">
@@ -48,7 +136,7 @@
Wide310x150Logo="Images\Wide310x150Logo.png"
Square71x71Logo="Images\SmallTile.png"
Square310x310Logo="Images\LargeTile.png"
ShortName="ms-resource:TerminalApp/ContextMenu/AppShortNamePre">
ShortName="ms-resource:AppShortNamePre">
<uap:ShowNameOnTiles>
<uap:ShowOn Tile="square150x150Logo"/>
<uap:ShowOn Tile="wide310x150Logo"/>
@@ -72,7 +160,7 @@
<uap5:StartupTask
TaskId="StartTerminalOnLoginTask"
Enabled="false"
DisplayName="ms-resource:TerminalApp/ContextMenu/AppNamePre" />
DisplayName="ms-resource:AppNamePre" />
</uap5:Extension>
<uap3:Extension Category="windows.appExtension">
<uap3:AppExtension Name="com.microsoft.windows.console.host"

View File

@@ -21,7 +21,7 @@
Version="1.0.0.0" />
<Properties>
<DisplayName>ms-resource:TerminalApp/ContextMenu/AppName</DisplayName>
<DisplayName>ms-resource:AppStoreName</DisplayName>
<PublisherDisplayName>Microsoft Corporation</PublisherDisplayName>
<Logo>Images\StoreLogo.png</Logo>
</Properties>
@@ -31,7 +31,95 @@
</Dependencies>
<Resources>
<Resource Language="x-generate"/>
<Resource Language="EN-US" />
<Resource Language="EN-GB" />
<Resource Language="AF-ZA" />
<Resource Language="AM-ET" />
<Resource Language="AR-SA" />
<Resource Language="AS-IN" />
<Resource Language="AZ-LATN-AZ" />
<Resource Language="BG-BG" />
<Resource Language="BN-IN" />
<Resource Language="BS-LATN-BA" />
<Resource Language="CA-ES" />
<Resource Language="CA-ES-VALENCIA" />
<Resource Language="CS-CZ" />
<Resource Language="CY-GB" />
<Resource Language="DA-DK" />
<Resource Language="DE-DE" />
<Resource Language="EL-GR" />
<Resource Language="ES-ES" />
<Resource Language="ES-MX" />
<Resource Language="ET-EE" />
<Resource Language="EU-ES" />
<Resource Language="FA-IR" />
<Resource Language="FI-FI" />
<Resource Language="FIL-PH" />
<Resource Language="FR-CA" />
<Resource Language="FR-FR" />
<Resource Language="GA-IE" />
<Resource Language="GD-GB" />
<Resource Language="GL-ES" />
<Resource Language="GU-IN" />
<Resource Language="HE-IL" />
<Resource Language="HI-IN" />
<Resource Language="HR-HR" />
<Resource Language="HU-HU" />
<Resource Language="HY-AM" />
<Resource Language="ID-ID" />
<Resource Language="IS-IS" />
<Resource Language="IT-IT" />
<Resource Language="JA-JP" />
<Resource Language="KA-GE" />
<Resource Language="KK-KZ" />
<Resource Language="KM-KH" />
<Resource Language="KN-IN" />
<Resource Language="KO-KR" />
<Resource Language="KOK-IN" />
<Resource Language="LB-LU" />
<Resource Language="LO-LA" />
<Resource Language="LT-LT" />
<Resource Language="LV-LV" />
<Resource Language="MI-NZ" />
<Resource Language="MK-MK" />
<Resource Language="ML-IN" />
<Resource Language="MR-IN" />
<Resource Language="MS-MY" />
<Resource Language="MT-MT" />
<Resource Language="NB-NO" />
<Resource Language="NE-NP" />
<Resource Language="NL-NL" />
<Resource Language="NN-NO" />
<Resource Language="OR-IN" />
<Resource Language="PA-IN" />
<Resource Language="PL-PL" />
<Resource Language="PT-BR" />
<Resource Language="PT-PT" />
<Resource Language="QPS-PLOC" />
<Resource Language="QPS-PLOCA" />
<Resource Language="QPS-PLOCM" />
<Resource Language="QUZ-PE" />
<Resource Language="RO-RO" />
<Resource Language="RU-RU" />
<Resource Language="SK-SK" />
<Resource Language="SL-SI" />
<Resource Language="SQ-AL" />
<Resource Language="SR-CYRL-BA" />
<Resource Language="SR-CYRL-RS" />
<Resource Language="SR-LATN-RS" />
<Resource Language="SV-SE" />
<Resource Language="TA-IN" />
<Resource Language="TE-IN" />
<Resource Language="TH-TH" />
<Resource Language="TR-TR" />
<Resource Language="TT-RU" />
<Resource Language="UG-CN" />
<Resource Language="UK-UA" />
<Resource Language="UR-PK" />
<Resource Language="UZ-LATN-UZ" />
<Resource Language="VI-VN" />
<Resource Language="ZH-CN" />
<Resource Language="ZH-TW" />
</Resources>
<Applications>
@@ -39,8 +127,8 @@
Executable="$targetnametoken$.exe"
EntryPoint="$targetentrypoint$">
<uap:VisualElements
DisplayName="ms-resource:TerminalApp/ContextMenu/AppName"
Description="ms-resource:TerminalApp/ContextMenu/AppDescription"
DisplayName="ms-resource:AppName"
Description="ms-resource:AppDescription"
BackgroundColor="transparent"
Square150x150Logo="Images\Square150x150Logo.png"
Square44x44Logo="Images\Square44x44Logo.png">
@@ -48,7 +136,7 @@
Wide310x150Logo="Images\Wide310x150Logo.png"
Square71x71Logo="Images\SmallTile.png"
Square310x310Logo="Images\LargeTile.png"
ShortName="ms-resource:TerminalApp/ContextMenu/AppShortName">
ShortName="ms-resource:AppShortName">
<uap:ShowNameOnTiles>
<uap:ShowOn Tile="square150x150Logo"/>
<uap:ShowOn Tile="wide310x150Logo"/>
@@ -72,7 +160,7 @@
<uap5:StartupTask
TaskId="StartTerminalOnLoginTask"
Enabled="false"
DisplayName="ms-resource:TerminalApp/ContextMenu/AppName" />
DisplayName="ms-resource:AppName" />
</uap5:Extension>
<uap3:Extension Category="windows.appExtension">
<uap3:AppExtension Name="com.microsoft.windows.console.host"

View File

@@ -117,4 +117,52 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AppName" xml:space="preserve">
<value>Terminal</value>
<comment>{Locked}</comment>
</data>
<data name="AppNameDev" xml:space="preserve">
<value>Terminal Dev</value>
<comment>{Locked}</comment>
</data>
<data name="AppNamePre" xml:space="preserve">
<value>Terminal Preview</value>
<comment>{Locked}</comment>
</data>
<data name="AppStoreName" xml:space="preserve">
<value>Windows Terminal</value>
<comment>{Locked}</comment>
</data>
<data name="AppStoreNameDev" xml:space="preserve">
<value>Windows Terminal Dev</value>
<comment>{Locked}</comment>
</data>
<data name="AppStoreNamePre" xml:space="preserve">
<value>Windows Terminal Preview</value>
<comment>{Locked}</comment>
</data>
<data name="AppShortName" xml:space="preserve">
<value>Terminal</value>
<comment>{Locked}</comment>
</data>
<data name="AppShortNameDev" xml:space="preserve">
<value>Terminal Dev</value>
<comment>{Locked}</comment>
</data>
<data name="AppShortNamePre" xml:space="preserve">
<value>Terminal Preview</value>
<comment>{Locked}</comment>
</data>
<data name="AppDescription" xml:space="preserve">
<value>The New Windows Terminal</value>
<comment>{Locked}</comment>
</data>
<data name="AppDescriptionDev" xml:space="preserve">
<value>The Windows Terminal, but Unofficial</value>
<comment>{Locked}</comment>
</data>
<data name="AppDescriptionPre" xml:space="preserve">
<value>Windows Terminal with a preview of upcoming features</value>
<comment>{Locked}</comment>
</data>
</root>

View File

@@ -81,8 +81,8 @@
If you don't have this, then you'll see an error like
"(init.obj) : error LNK2005: DllMain already defined in MSVCRTD.lib(dll_dllmain_stub.obj)"
-->
<AdditionalOptions Condition="'$(Platform)'=='Win32'">/INCLUDE:_DllMain@12</AdditionalOptions>
<AdditionalOptions Condition="'$(Platform)'!='Win32'">/INCLUDE:DllMain</AdditionalOptions>
<AdditionalOptions Condition="'$(Platform)'=='Win32'">%(AdditionalOptions) /INCLUDE:_DllMain@12</AdditionalOptions>
<AdditionalOptions Condition="'$(Platform)'!='Win32'">%(AdditionalOptions) /INCLUDE:DllMain</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
@@ -99,10 +99,10 @@
<!-- From Microsoft.UI.Xaml.targets -->
<Native-Platform Condition="'$(Platform)' == 'Win32'">x86</Native-Platform>
<Native-Platform Condition="'$(Platform)' != 'Win32'">$(Platform)</Native-Platform>
<_MUXBinRoot>&quot;$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\runtimes\win10-$(Native-Platform)\native\&quot;</_MUXBinRoot>
<_MUXBinRoot>&quot;$(OpenConsoleDir)packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\runtimes\win10-$(Native-Platform)\native\&quot;</_MUXBinRoot>
</PropertyGroup>
<!-- We actually can just straight up reference MUX here, it's fine -->
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets')" />
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets')" />
</Project>

View File

@@ -38,6 +38,7 @@ namespace SettingsModelLocalTests
TEST_METHOD(TryCreateWinRTType);
TEST_METHOD(TestTerminalArgsForBinding);
TEST_METHOD(CommandLineToArgvW);
TEST_METHOD(NormalizeCommandLine);
TEST_METHOD(GetProfileForArgsWithCommandline);
TEST_METHOD(MakeSettingsForProfile);
TEST_METHOD(MakeSettingsForDefaultProfileThatDoesntExist);
@@ -84,7 +85,8 @@ namespace SettingsModelLocalTests
for (int i = 0; i < expectedArgc; ++i)
{
const bool useQuotes = static_cast<bool>(rng(2));
const auto count = static_cast<size_t>(rng(64));
// We need to ensure there is at least one character
const auto count = static_cast<size_t>(rng(64) + 1);
const auto ch = static_cast<wchar_t>(rng('z' - 'a' + 1) + 'a');
if (i != 0)
@@ -106,6 +108,7 @@ namespace SettingsModelLocalTests
input.push_back(L'"');
}
}
Log::Comment(NoThrowString().Format(input.c_str()));
int argc;
wil::unique_hlocal_ptr<PWSTR[]> argv{ ::CommandLineToArgvW(input.c_str(), &argc) };
@@ -120,6 +123,67 @@ namespace SettingsModelLocalTests
VERIFY_ARE_EQUAL(0, memcmp(beg, expectedArgv.data(), expectedArgv.size()));
}
// This unit test covers GH#12345.
// * paths with more than 1 whitespace
// * paths sharing a common prefix with another directory
void TerminalSettingsTests::NormalizeCommandLine()
{
using namespace std::string_literals;
static constexpr auto touch = [](const auto& path) {
std::ofstream file{ path };
};
std::wstring guid;
{
GUID g{};
THROW_IF_FAILED(CoCreateGuid(&g));
guid = fmt::format(
L"{:08x}-{:04x}-{:04x}-{:02x}{:02x}-{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}",
g.Data1,
g.Data2,
g.Data3,
g.Data4[0],
g.Data4[1],
g.Data4[2],
g.Data4[3],
g.Data4[4],
g.Data4[5],
g.Data4[6],
g.Data4[7]);
}
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";
const auto file2 = dir2 / L"file 2.exe";
const auto cleanup = wil::scope_exit([&]() {
std::error_code ec;
remove_all(dir1, ec);
remove_all(dir2, ec);
});
create_directory(dir1);
create_directory(dir2);
touch(file1);
touch(file2);
{
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::CascadiaSettings::NormalizeCommandLine(commandLine.c_str());
VERIFY_ARE_EQUAL(expected, actual);
}
{
const auto commandLine = L"C:\\";
const auto expected = L"C:\\";
const auto actual = implementation::CascadiaSettings::NormalizeCommandLine(commandLine);
VERIFY_ARE_EQUAL(expected, actual);
}
}
void TerminalSettingsTests::GetProfileForArgsWithCommandline()
{
// I'm exclusively using cmd.exe as I know exactly where it resides at.
@@ -145,6 +209,10 @@ namespace SettingsModelLocalTests
"guid": "{6239a42c-3333-49a3-80bd-e8fdd045185c}",
"commandline": "cmd.exe /A /C",
"connectionType": "{9a9977a7-1fe0-49c0-b6c0-13a0cd1c98a1}"
},
{
"guid": "{6239a42c-4444-49a3-80bd-e8fdd045185c}",
"commandline": "C:\\invalid.exe",
}
]
}
@@ -163,7 +231,7 @@ namespace SettingsModelLocalTests
TestCase{ L"cmd.exe", 0 },
// SearchPathW() normalization + case insensitive matching.
TestCase{ L"cmd.exe /a", 1 },
TestCase{ L"C:\\Windows\\System32\\cmd.exe /A", 1 },
TestCase{ L"%SystemRoot%\\System32\\cmd.exe /A", 1 },
// Test that we don't pick the equally long but different "/A /B" variant.
TestCase{ L"C:\\Windows\\System32\\cmd.exe /A /C", 1 },
// Test that we don't pick the shorter "/A" variant,
@@ -173,6 +241,9 @@ namespace SettingsModelLocalTests
// Ignore profiles with a connection type, like the Azure cloud shell.
// Instead it should pick any other prefix.
TestCase{ L"C:\\Windows\\System32\\cmd.exe /A /C", 1 },
// Failure to normalize a path (e.g. because the path doesn't exist)
// should yield the unmodified input string (see NormalizeCommandLine).
TestCase{ L"C:\\invalid.exe /A /B", 4 },
// Return base layer profile for missing profiles.
TestCase{ L"C:\\Windows\\regedit.exe", -1 },
};

View File

@@ -92,11 +92,11 @@
<!-- From Microsoft.UI.Xaml.targets -->
<Native-Platform Condition="'$(Platform)' == 'Win32'">x86</Native-Platform>
<Native-Platform Condition="'$(Platform)' != 'Win32'">$(Platform)</Native-Platform>
<_MUXBinRoot>&quot;$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\runtimes\win10-$(Native-Platform)\native\&quot;</_MUXBinRoot>
<_MUXBinRoot>&quot;$(OpenConsoleDir)packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\runtimes\win10-$(Native-Platform)\native\&quot;</_MUXBinRoot>
</PropertyGroup>
<!-- We actually can just straight up reference MUX here, it's fine -->
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets')" />
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets')" />
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
</Project>

View File

@@ -123,7 +123,7 @@
</Reference>
</ItemGroup>
<Import Project="$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets')" />
<Import Project="$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets')" />
<Import Project="$(OpenConsoleDir)\src\common.build.post.props" />

View File

@@ -353,6 +353,14 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
// - <none>
void Monarch::HandleActivatePeasant(const Remoting::WindowActivatedArgs& args)
{
if (args == nullptr)
{
// MSFT:35731327, GH #12624. There's a chance that the way the
// window gets set up for defterm, the ActivatedArgs haven't been
// created for this window yet. Check here and just ignore them if
// they're null. They'll come back with real args soon
return;
}
// Start by making a local copy of these args. It's easier for us if our
// tracking of these args is all in-proc. That way, the only thing that
// could fail due to the peasant dying is _this first copy_.
@@ -418,6 +426,9 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
// - <none>
void Monarch::_doHandleActivatePeasant(const winrt::com_ptr<implementation::WindowActivatedArgs>& localArgs)
{
// We're sure that localArgs isn't null here, we checked before in our
// one caller (in Monarch::HandleActivatePeasant)
const auto newLastActiveTime = localArgs->ActivatedTime().time_since_epoch().count();
// * Check all the current lists to look for this peasant.

View File

@@ -44,8 +44,8 @@ namespace Microsoft.Terminal.Remoting
String TabTitle;
};
[default_interface] runtimeclass Monarch {
Monarch();
interface IMonarch
{
UInt64 GetPID();
UInt64 AddPeasant(IPeasant peasant);
@@ -67,4 +67,9 @@ namespace Microsoft.Terminal.Remoting
event Windows.Foundation.TypedEventHandler<Object, Object> WindowClosed;
event Windows.Foundation.TypedEventHandler<Object, QuitAllRequestedArgs> QuitAllRequested;
};
[default_interface] runtimeclass Monarch : IMonarch
{
Monarch();
};
}

View File

@@ -77,6 +77,145 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
}
}
void WindowManager::_proposeToMonarch(const Remoting::CommandlineArgs& args,
std::optional<uint64_t>& givenID,
winrt::hstring& givenName)
{
// these two errors are Win32 errors, convert them to HRESULTS so we can actually compare below.
static constexpr HRESULT RPC_SERVER_UNAVAILABLE_HR = HRESULT_FROM_WIN32(RPC_S_SERVER_UNAVAILABLE);
static constexpr HRESULT RPC_CALL_FAILED_HR = HRESULT_FROM_WIN32(RPC_S_CALL_FAILED);
// The monarch may respond back "you should be a new
// window, with ID,name of (id, name)". Really the responses are:
// * You should not create a new window
// * Create a new window (but without a given ID or name). The
// Monarch will assign your ID/name later
// * Create a new window, and you'll have this ID or name
// - This is the case where the user provides `wt -w 1`, and
// there's no existing window 1
// You can emulate the monarch dying by: starting a terminal, sticking a
// breakpoint in
// TerminalApp!winrt::TerminalApp::implementation::AppLogic::_doFindTargetWindow,
// starting a defterm, and when that BP gets hit, kill the original
// monarch, and see what happens here.
bool proposedCommandline = false;
Remoting::ProposeCommandlineResult result{ nullptr };
while (!proposedCommandline)
{
try
{
result = _monarch.ProposeCommandline(args);
proposedCommandline = true;
}
catch (const winrt::hresult_error& e)
{
// We did not successfully ask the king what to do. They
// hopefully just died here. That's okay, let's just go ask the
// next in the line of succession. At the very worst, we'll find
// _us_, (likely last in the line).
//
// If the king returned some _other_ error here, than lets
// bubble that up because that's a real issue.
//
// I'm checking both these here. I had previously got a
// RPC_S_CALL_FAILED about here once.
if (e.code() == RPC_SERVER_UNAVAILABLE_HR || e.code() == RPC_CALL_FAILED_HR)
{
TraceLoggingWrite(g_hRemotingProvider,
"WindowManager_proposeToMonarch_kingDied",
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE),
TraceLoggingKeyword(TIL_KEYWORD_TRACE));
// We failed to ask the monarch. It must have died. Try and
// find the real monarch. Don't perform an election, that
// assumes we have a peasant, which we don't yet.
_createMonarchAndCallbacks();
// _createMonarchAndCallbacks will initialize _isKing
if (_isKing)
{
// We became the king. We don't need to ProposeCommandline to ourself, we're just
// going to do it.
//
// Return early, because there's nothing else for us to do here.
TraceLoggingWrite(g_hRemotingProvider,
"WindowManager_proposeToMonarch_becameKing",
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE),
TraceLoggingKeyword(TIL_KEYWORD_TRACE));
// In WindowManager::ProposeCommandline, had we been the
// king originally, we would have started by setting
// this to true. We became the monarch here, so set it
// here as well.
_shouldCreateWindow = true;
return;
}
// Here, we created the new monarch, it wasn't us, so we're
// gonna go through the while loop again and ask the new
// king.
TraceLoggingWrite(g_hRemotingProvider,
"WindowManager_proposeToMonarch_tryAgain",
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE),
TraceLoggingKeyword(TIL_KEYWORD_TRACE));
}
else
{
TraceLoggingWrite(g_hRemotingProvider,
"WindowManager_proposeToMonarch_unexpectedResultFromKing",
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE),
TraceLoggingKeyword(TIL_KEYWORD_TRACE));
LOG_CAUGHT_EXCEPTION();
throw;
}
}
catch (...)
{
// If the monarch (maybe us) failed for _any other reason_ than
// them dying. This IS quite unexpected. Let this bubble out.
TraceLoggingWrite(g_hRemotingProvider,
"WindowManager_proposeToMonarch_unexpectedExceptionFromKing",
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE),
TraceLoggingKeyword(TIL_KEYWORD_TRACE));
LOG_CAUGHT_EXCEPTION();
throw;
}
}
// Here, the monarch (not us) has replied to the message. Get the
// valuables out of the response:
_shouldCreateWindow = result.ShouldCreateWindow();
if (result.Id())
{
givenID = result.Id().Value();
}
givenName = result.WindowName();
// TraceLogging doesn't have a good solution for logging an
// optional. So we have to repeat the calls here:
if (givenID)
{
TraceLoggingWrite(g_hRemotingProvider,
"WindowManager_ProposeCommandline",
TraceLoggingBoolean(_shouldCreateWindow, "CreateWindow", "true iff we should create a new window"),
TraceLoggingUInt64(givenID.value(), "Id", "The ID we should assign our peasant"),
TraceLoggingWideString(givenName.c_str(), "Name", "The name we should assign this window"),
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE),
TraceLoggingKeyword(TIL_KEYWORD_TRACE));
}
else
{
TraceLoggingWrite(g_hRemotingProvider,
"WindowManager_ProposeCommandline",
TraceLoggingBoolean(_shouldCreateWindow, "CreateWindow", "true iff we should create a new window"),
TraceLoggingPointer(nullptr, "Id", "No ID provided"),
TraceLoggingWideString(givenName.c_str(), "Name", "The name we should assign this window"),
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE),
TraceLoggingKeyword(TIL_KEYWORD_TRACE));
}
}
void WindowManager::ProposeCommandline(const Remoting::CommandlineArgs& args)
{
// If we're the king, we _definitely_ want to process the arguments, we were
@@ -88,46 +227,11 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
winrt::hstring givenName{};
if (!_isKing)
{
// The monarch may respond back "you should be a new
// window, with ID,name of (id, name)". Really the responses are:
// * You should not create a new window
// * Create a new window (but without a given ID or name). The
// Monarch will assign your ID/name later
// * Create a new window, and you'll have this ID or name
// - This is the case where the user provides `wt -w 1`, and
// there's no existing window 1
const auto result = _monarch.ProposeCommandline(args);
_shouldCreateWindow = result.ShouldCreateWindow();
if (result.Id())
{
givenID = result.Id().Value();
}
givenName = result.WindowName();
// TraceLogging doesn't have a good solution for logging an
// optional. So we have to repeat the calls here:
if (givenID)
{
TraceLoggingWrite(g_hRemotingProvider,
"WindowManager_ProposeCommandline",
TraceLoggingBoolean(_shouldCreateWindow, "CreateWindow", "true iff we should create a new window"),
TraceLoggingUInt64(givenID.value(), "Id", "The ID we should assign our peasant"),
TraceLoggingWideString(givenName.c_str(), "Name", "The name we should assign this window"),
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE),
TraceLoggingKeyword(TIL_KEYWORD_TRACE));
}
else
{
TraceLoggingWrite(g_hRemotingProvider,
"WindowManager_ProposeCommandline",
TraceLoggingBoolean(_shouldCreateWindow, "CreateWindow", "true iff we should create a new window"),
TraceLoggingPointer(nullptr, "Id", "No ID provided"),
TraceLoggingWideString(givenName.c_str(), "Name", "The name we should assign this window"),
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE),
TraceLoggingKeyword(TIL_KEYWORD_TRACE));
}
_proposeToMonarch(args, givenID, givenName);
}
else
// During _proposeToMonarch, it's possible that we found that the king was dead, and we're the new king. Cool! Do this now.
if (_isKing)
{
// We're the monarch, we don't need to propose anything. We're just
// going to do it.
@@ -195,6 +299,10 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
_createPeasantThread();
}
// This right here will just tell us to stash the args away for the
// future. The AppHost hasnt yet set up the callbacks, and the rest
// of the app hasn't started at all. We'll note them and come back
// later.
_peasant.ExecuteCommandline(args);
}
// Otherwise, we'll do _nothing_.

View File

@@ -82,6 +82,10 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
void _waitOnMonarchThread();
void _raiseFindTargetWindowRequested(const winrt::Windows::Foundation::IInspectable& sender,
const winrt::Microsoft::Terminal::Remoting::FindTargetWindowArgs& args);
void _proposeToMonarch(const Remoting::CommandlineArgs& args,
std::optional<uint64_t>& givenID,
winrt::hstring& givenName);
};
}

View File

@@ -54,20 +54,43 @@
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Dark">
<!-- Define resources for Dark mode here -->
<SolidColorBrush x:Key="TabViewBackground"
Color="#FF333333" />
<SolidColorBrush x:Key="UnfocusedBorderBrush"
Color="#FF333333" />
<!--
Originally, we were using the raw value of
ApplicationPageBackgroundThemeBrush here, which is
evaluated as SolidBackgroundFillColorBase. If we try
to use those resources directly though, we don't get
the properly themed versions. Presumably because the
App itself can't have it's RequestedTheme changed at
runtime.
However, after more discussion with the WinUI
team, we determined that those colors don't
provide enough contrast. The color here (and in
light mode) were chosen for greater contrast.
See GH #12356 for more history on the subject.
-->
<SolidColorBrush x:Key="TabViewBackground"
Color="#0a0a0a" />
<StaticResource x:Key="UnfocusedBorderBrush"
ResourceKey="ApplicationPageBackgroundThemeBrush" />
</ResourceDictionary>
<ResourceDictionary x:Key="Light">
<!-- Define resources for Light mode here -->
<SolidColorBrush x:Key="TabViewBackground"
Color="#FFCCCCCC" />
<SolidColorBrush x:Key="UnfocusedBorderBrush"
Color="#FFCCCCCC" />
<!--
GH #12398 has more history on this value, as well as GH #12400
-->
<SolidColorBrush x:Key="TabViewBackground"
Color="#dadada" />
<StaticResource x:Key="UnfocusedBorderBrush"
ResourceKey="ApplicationPageBackgroundThemeBrush" />
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>

View File

@@ -348,7 +348,11 @@ namespace winrt::TerminalApp::implementation
}
_dialog = dialog;
// GH#12622: After the dialog is displayed, always clear it out. If we
// don't, we won't be able to display another!
const auto cleanup = wil::scope_exit([this]() {
_dialog = nullptr;
});
// IMPORTANT: This is necessary as documented in the ContentDialog MSDN docs.
// Since we're hosting the dialog in a Xaml island, we need to connect it to the
// xaml tree somehow.
@@ -396,6 +400,14 @@ namespace winrt::TerminalApp::implementation
}
}
// Method Description:
// - Returns true if there is no dialog currently being shown (meaning that we can show a dialog)
// - Returns false if there is a dialog currently being shown (meaning that we cannot show another dialog)
bool AppLogic::CanShowDialog()
{
return (_dialog == nullptr);
}
// Method Description:
// - Displays a dialog for errors found while loading or validating the
// settings. Uses the resources under the provided title and content keys

View File

@@ -122,6 +122,7 @@ namespace winrt::TerminalApp::implementation
bool GetShowTitleInTitlebar();
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> ShowDialog(winrt::Windows::UI::Xaml::Controls::ContentDialog dialog);
bool CanShowDialog();
void DismissDialog();
Windows::Foundation::Collections::IMapView<Microsoft::Terminal::Control::KeyChord, Microsoft::Terminal::Settings::Model::Command> GlobalHotkeys();

View File

@@ -33,6 +33,8 @@ namespace TerminalApp
SystemMenuItemHandler Handler { get; };
};
// See IDialogPresenter and TerminalPage's DialogPresenter for more
// information.
[default_interface] runtimeclass AppLogic : IDirectKeyListener, IDialogPresenter
{
AppLogic();
@@ -106,11 +108,6 @@ namespace TerminalApp
Windows.Foundation.Collections.IMapView<Microsoft.Terminal.Control.KeyChord, Microsoft.Terminal.Settings.Model.Command> GlobalHotkeys();
// See IDialogPresenter and TerminalPage's DialogPresenter for more
// information.
Windows.Foundation.IAsyncOperation<Windows.UI.Xaml.Controls.ContentDialogResult> ShowDialog(Windows.UI.Xaml.Controls.ContentDialog dialog);
void DismissDialog();
event Windows.Foundation.TypedEventHandler<Object, Windows.UI.Xaml.UIElement> SetTitleBarContent;
event Windows.Foundation.TypedEventHandler<Object, String> TitleChanged;
event Windows.Foundation.TypedEventHandler<Object, LastTabClosedEventArgs> LastTabClosed;

View File

@@ -164,11 +164,16 @@ namespace winrt::TerminalApp::implementation
// - the approximate number of items visible in the list (in other words the size of the page)
uint32_t CommandPalette::_getNumVisibleItems()
{
const auto container = _filteredActionsView().ContainerFromIndex(0);
const auto item = container.try_as<winrt::Windows::UI::Xaml::Controls::ListViewItem>();
const auto itemHeight = ::base::saturated_cast<int>(item.ActualHeight());
const auto listHeight = ::base::saturated_cast<int>(_filteredActionsView().ActualHeight());
return listHeight / itemHeight;
if (const auto container = _filteredActionsView().ContainerFromIndex(0))
{
if (const auto item = container.try_as<winrt::Windows::UI::Xaml::Controls::ListViewItem>())
{
const auto itemHeight = ::base::saturated_cast<int>(item.ActualHeight());
const auto listHeight = ::base::saturated_cast<int>(_filteredActionsView().ActualHeight());
return listHeight / itemHeight;
}
}
return 0;
}
// Method Description:
@@ -827,7 +832,9 @@ namespace winrt::TerminalApp::implementation
automationPeer.RaiseNotificationEvent(
Automation::Peers::AutomationNotificationKind::ActionCompleted,
Automation::Peers::AutomationNotificationProcessing::ImportantMostRecent,
currentNeedleHasResults ? RS_(L"CommandPalette_MatchesAvailable") : NoMatchesText(), // what to announce if results were found
currentNeedleHasResults ?
winrt::hstring{ fmt::format(std::wstring_view{ RS_(L"CommandPalette_MatchesAvailable") }, _filteredActions.Size()) } :
NoMatchesText(), // what to announce if results were found
L"CommandPaletteResultAnnouncement" /* unique name for this group of notifications */);
}
}

View File

@@ -145,7 +145,7 @@
<!-- xE70E is ChevronUp. Rotated 90 degrees, it's _ChevronRight_ -->
<FontIcon Grid.Column="2"
HorizontalAlignment="Right"
FontFamily="Segoe MDL2 Assets"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
Glyph="&#xE70E;">
<FontIcon.RenderTransform>
@@ -199,20 +199,20 @@
Orientation="Horizontal">
<FontIcon Margin="0,0,8,0"
FontFamily="Segoe MDL2 Assets"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="12"
Glyph="&#xEA8F;"
Visibility="{x:Bind Item.(local:TabPaletteItem.TabStatus).BellIndicator, Mode=OneWay}" />
<FontIcon Margin="0,0,8,0"
FontFamily="Segoe MDL2 Assets"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="12"
Glyph="&#xE8A3;"
Visibility="{x:Bind Item.(local:TabPaletteItem.TabStatus).IsPaneZoomed, Mode=OneWay}" />
<FontIcon x:Name="HeaderLockIcon"
Margin="0,0,8,0"
FontFamily="Segoe MDL2 Assets"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="12"
Glyph="&#xE72E;"
Visibility="{x:Bind Item.(local:TabPaletteItem.TabStatus).IsReadOnlyActive, Mode=OneWay}" />
@@ -445,7 +445,7 @@
Background="Transparent"
Click="_moveBackButtonClicked"
ClickMode="Press">
<FontIcon FontFamily="Segoe MDL2 Assets"
<FontIcon FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="12"
Glyph="&#xE76b;" />
</Button>

View File

@@ -62,6 +62,19 @@ static std::wstring _normalizeIconPath(std::wstring_view path)
// - <none>
winrt::fire_and_forget Jumplist::UpdateJumplist(const CascadiaSettings& settings) noexcept
{
if (!settings)
{
// By all accounts, this shouldn't be null. Seemingly however (GH
// #12360), it sometimes is. So just check this case here and log a
// message.
TraceLoggingWrite(g_hTerminalAppProvider,
"Jumplist_UpdateJumplist_NullSettings",
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE),
TraceLoggingKeyword(TIL_KEYWORD_TRACE));
co_return;
}
// make sure to capture the settings _before_ the co_await
const auto strongSettings = settings;

View File

@@ -1044,7 +1044,12 @@ winrt::fire_and_forget Pane::_playBellSound(winrt::Windows::Foundation::Uri uri)
if (!_bellPlayer)
{
_bellPlayer = winrt::Windows::Media::Playback::MediaPlayer();
// The MediaPlayer might not exist on Windows N SKU.
try
{
_bellPlayer = winrt::Windows::Media::Playback::MediaPlayer();
}
CATCH_LOG();
}
if (_bellPlayer)
{

View File

@@ -241,7 +241,7 @@ private:
bool _zoomed{ false };
winrt::Windows::Media::Playback::MediaPlayer _bellPlayer;
winrt::Windows::Media::Playback::MediaPlayer _bellPlayer{ nullptr };
winrt::Windows::Media::Playback::MediaPlayer::MediaEnded_revoker _mediaEndedRevoker;
bool _IsLeaf() const noexcept;

View File

@@ -127,6 +127,16 @@
<data name="AppNamePre" xml:space="preserve">
<value>Terminal Preview</value>
</data>
<data name="AppStoreName" xml:space="preserve">
<value>Windows Terminal</value>
</data>
<data name="AppStoreNameDev" xml:space="preserve">
<value>Windows Terminal Dev</value>
<comment>{Locked} The dev build will never be seen in multiple languages</comment>
</data>
<data name="AppStoreNamePre" xml:space="preserve">
<value>Windows Terminal Preview</value>
</data>
<data name="AppShortName" xml:space="preserve">
<value>Terminal</value>
</data>

View File

@@ -729,6 +729,7 @@
<comment>This is a call-to-action hyperlink; it will open the settings.</comment>
</data>
<data name="CommandPalette_MatchesAvailable" xml:space="preserve">
<value>Suggestions available</value>
<value>Suggestions found: {0}</value>
<comment>{0} will be replaced with a number.</comment>
</data>
</root>
</root>

View File

@@ -98,7 +98,6 @@ namespace winrt::TerminalApp::implementation
if (auto tab{ weakThis.get() })
{
auto fontFamily = winrt::WUX::Media::FontFamily(L"Segoe MDL2 Assets");
auto glyph = L"\xE713"; // This is the Setting icon (looks like a gear)
// The TabViewItem Icon needs MUX while the IconSourceElement in the CommandPalette needs WUX...

View File

@@ -90,7 +90,7 @@ namespace winrt::TerminalApp::implementation
// Close
Controls::MenuFlyoutItem closeTabMenuItem;
Controls::FontIcon closeSymbol;
closeSymbol.FontFamily(Media::FontFamily{ L"Segoe MDL2 Assets" });
closeSymbol.FontFamily(Media::FontFamily{ L"Segoe Fluent Icons, Segoe MDL2 Assets" });
closeSymbol.Glyph(L"\xE711");
closeTabMenuItem.Click([weakThis](auto&&, auto&&) {

View File

@@ -48,19 +48,19 @@
-->
<FontIcon x:Name="HeaderBellIndicator"
Margin="0,0,8,0"
FontFamily="Segoe MDL2 Assets"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="12"
Glyph="&#xEA8F;"
Visibility="{x:Bind TabStatus.BellIndicator, Mode=OneWay}" />
<FontIcon x:Name="HeaderZoomIcon"
Margin="0,0,8,0"
FontFamily="Segoe MDL2 Assets"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="12"
Glyph="&#xE8A3;"
Visibility="{x:Bind TabStatus.IsPaneZoomed, Mode=OneWay}" />
<FontIcon x:Name="HeaderLockIcon"
Margin="0,0,8,0"
FontFamily="Segoe MDL2 Assets"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="12"
Glyph="&#xE72E;"
Visibility="{x:Bind TabStatus.IsReadOnlyActive, Mode=OneWay}" />

View File

@@ -24,7 +24,7 @@
<!-- EA18 is the "Shield" glyph -->
<FontIcon x:Uid="ElevationShield"
Margin="9,4,0,4"
FontFamily="Segoe MDL2 Assets"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="16"
Foreground="{ThemeResource SystemControlForegroundBaseMediumBrush}"
Glyph="&#xEA18;"
@@ -44,7 +44,7 @@
CornerRadius="{Binding Source={ThemeResource OverlayCornerRadius}, Converter={StaticResource TopCornerRadiusFilterConverter}}"
DragOver="OnNewTabButtonDragOver"
Drop="OnNewTabButtonDrop"
FontFamily="Segoe MDL2 Assets"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="12"
FontWeight="SemiLight"
UseLayoutRounding="true">

View File

@@ -400,13 +400,13 @@
<!-- ========================= Globals ======================== -->
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets')" />
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets')" />
<Import Project="..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('..\..\..\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets'))" />
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets'))" />
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.VisualStudio.Setup.Configuration.Native.2.3.2262\build\native\Microsoft.VisualStudio.Setup.Configuration.Native.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.VisualStudio.Setup.Configuration.Native.2.3.2262\build\native\Microsoft.VisualStudio.Setup.Configuration.Native.targets'))" />
</Target>

View File

@@ -156,7 +156,6 @@ namespace winrt::TerminalApp::implementation
if (_settings.GlobalSettings().UseAcrylicInTabRow())
{
const auto res = Application::Current().Resources();
const auto lightKey = winrt::box_value(L"Light");
const auto darkKey = winrt::box_value(L"Dark");
const auto tabViewBackgroundKey = winrt::box_value(L"TabViewBackground");
@@ -298,8 +297,7 @@ namespace winrt::TerminalApp::implementation
// - true if the ApplicationState should be used.
bool TerminalPage::ShouldUsePersistedLayout(CascadiaSettings& settings) const
{
return Feature_PersistedWindowLayout::IsEnabled() &&
settings.GlobalSettings().FirstWindowPreference() == FirstWindowPreference::PersistedWindowLayout;
return settings.GlobalSettings().FirstWindowPreference() == FirstWindowPreference::PersistedWindowLayout;
}
// Method Description:
@@ -687,10 +685,7 @@ namespace winrt::TerminalApp::implementation
// Notes link, and privacy policy link.
void TerminalPage::_ShowAboutDialog()
{
if (auto presenter{ _dialogPresenter.get() })
{
presenter.ShowDialog(FindName(L"AboutDialog").try_as<WUX::Controls::ContentDialog>());
}
_ShowDialogHelper(L"AboutDialog");
}
winrt::hstring TerminalPage::ApplicationDisplayName()
@@ -710,6 +705,33 @@ namespace winrt::TerminalApp::implementation
ShellExecute(nullptr, nullptr, currentPath.c_str(), nullptr, nullptr, SW_SHOW);
}
// Method description:
// - Called when the user closes a content dialog
// - Tells the presenter to update its knowledge of whether there is a content dialog open
void TerminalPage::_DialogCloseClick(const IInspectable&,
const ContentDialogButtonClickEventArgs&)
{
if (auto presenter{ _dialogPresenter.get() })
{
presenter.DismissDialog();
}
}
// Method Description:
// - Helper to show a content dialog
// - We only open a content dialog if there isn't one open already
winrt::Windows::Foundation::IAsyncOperation<ContentDialogResult> TerminalPage::_ShowDialogHelper(const std::wstring_view& name)
{
if (auto presenter{ _dialogPresenter.get() })
{
if (presenter.CanShowDialog())
{
co_return co_await presenter.ShowDialog(FindName(name).try_as<WUX::Controls::ContentDialog>());
}
}
co_return ContentDialogResult::None;
}
// Method Description:
// - Displays a dialog to warn the user that they are about to close all open windows.
// Once the user clicks the OK button, shut down the application.
@@ -718,11 +740,7 @@ namespace winrt::TerminalApp::implementation
// when this is called, nothing happens. See _ShowDialog for details
winrt::Windows::Foundation::IAsyncOperation<ContentDialogResult> TerminalPage::_ShowQuitDialog()
{
if (auto presenter{ _dialogPresenter.get() })
{
co_return co_await presenter.ShowDialog(FindName(L"QuitDialog").try_as<WUX::Controls::ContentDialog>());
}
co_return ContentDialogResult::None;
return _ShowDialogHelper(L"QuitDialog");
}
// Method Description:
@@ -734,22 +752,14 @@ namespace winrt::TerminalApp::implementation
// when this is called, nothing happens. See _ShowDialog for details
winrt::Windows::Foundation::IAsyncOperation<ContentDialogResult> TerminalPage::_ShowCloseWarningDialog()
{
if (auto presenter{ _dialogPresenter.get() })
{
co_return co_await presenter.ShowDialog(FindName(L"CloseAllDialog").try_as<WUX::Controls::ContentDialog>());
}
co_return ContentDialogResult::None;
return _ShowDialogHelper(L"CloseAllDialog");
}
// Method Description:
// - Displays a dialog for warnings found while closing the terminal tab marked as read-only
winrt::Windows::Foundation::IAsyncOperation<ContentDialogResult> TerminalPage::_ShowCloseReadOnlyDialog()
{
if (auto presenter{ _dialogPresenter.get() })
{
co_return co_await presenter.ShowDialog(FindName(L"CloseReadOnlyDialog").try_as<WUX::Controls::ContentDialog>());
}
co_return ContentDialogResult::None;
return _ShowDialogHelper(L"CloseReadOnlyDialog");
}
// Method Description:
@@ -762,11 +772,7 @@ namespace winrt::TerminalApp::implementation
// when this is called, nothing happens. See _ShowDialog for details
winrt::Windows::Foundation::IAsyncOperation<ContentDialogResult> TerminalPage::_ShowMultiLinePasteWarningDialog()
{
if (auto presenter{ _dialogPresenter.get() })
{
co_return co_await presenter.ShowDialog(FindName(L"MultiLinePasteDialog").try_as<WUX::Controls::ContentDialog>());
}
co_return ContentDialogResult::None;
return _ShowDialogHelper(L"MultiLinePasteDialog");
}
// Method Description:
@@ -777,11 +783,7 @@ namespace winrt::TerminalApp::implementation
// when this is called, nothing happens. See _ShowDialog for details
winrt::Windows::Foundation::IAsyncOperation<ContentDialogResult> TerminalPage::_ShowLargePasteWarningDialog()
{
if (auto presenter{ _dialogPresenter.get() })
{
co_return co_await presenter.ShowDialog(FindName(L"LargePasteDialog").try_as<WUX::Controls::ContentDialog>());
}
co_return ContentDialogResult::None;
return _ShowDialogHelper(L"LargePasteDialog");
}
// Method Description:
@@ -914,7 +916,7 @@ namespace winrt::TerminalApp::implementation
WUX::Controls::FontIcon commandPaletteIcon{};
commandPaletteIcon.Glyph(L"\xE945");
commandPaletteIcon.FontFamily(Media::FontFamily{ L"Segoe MDL2 Assets" });
commandPaletteIcon.FontFamily(Media::FontFamily{ L"Segoe Fluent Icons, Segoe MDL2 Assets" });
commandPaletteFlyout.Icon(commandPaletteIcon);
commandPaletteFlyout.Click({ this, &TerminalPage::_CommandPaletteButtonOnClick });
@@ -3095,9 +3097,12 @@ namespace winrt::TerminalApp::implementation
{
NewTerminalArgs newTerminalArgs;
newTerminalArgs.Commandline(connection.Commandline());
const auto profile{ _settings.GetProfileForArgs(newTerminalArgs) };
const auto settings{ TerminalSettings::CreateWithProfile(_settings, profile, *_bindings) };
// GH #12370: We absolutely cannot allow a defterm connection to
// auto-elevate. Defterm doesn't work for elevated scenarios in the
// first place. If we try accepting the connection, the spawning an
// elevated version of the Terminal with that profile... that's a
// recipe for disaster. We won't ever open up a tab in this window.
newTerminalArgs.Elevate(false);
_CreateNewTabFromPane(_MakePane(newTerminalArgs, false, connection));
// Request a summon of this window to the foreground

View File

@@ -215,12 +215,15 @@ namespace winrt::TerminalApp::implementation
std::shared_ptr<Toast> _windowIdToast{ nullptr };
std::shared_ptr<Toast> _windowRenameFailedToast{ nullptr };
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> _ShowDialogHelper(const std::wstring_view& name);
void _ShowAboutDialog();
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> _ShowQuitDialog();
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> _ShowCloseWarningDialog();
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> _ShowCloseReadOnlyDialog();
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> _ShowMultiLinePasteWarningDialog();
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> _ShowLargePasteWarningDialog();
void _DialogCloseClick(const IInspectable& sender, const Windows::UI::Xaml::Controls::ContentDialogButtonClickEventArgs& eventArgs);
void _CreateNewTabFlyout();
void _OpenNewTabDropdown();

View File

@@ -14,6 +14,8 @@ namespace TerminalApp
interface IDialogPresenter
{
Windows.Foundation.IAsyncOperation<Windows.UI.Xaml.Controls.ContentDialogResult> ShowDialog(Windows.UI.Xaml.Controls.ContentDialog dialog);
Boolean CanShowDialog();
void DismissDialog();
};
[default_interface] runtimeclass TerminalPage : Windows.UI.Xaml.Controls.Page, Windows.UI.Xaml.Data.INotifyPropertyChanged

View File

@@ -75,6 +75,7 @@
<ContentDialog x:Name="AboutDialog"
x:Uid="AboutDialog"
x:Load="False"
CloseButtonClick="_DialogCloseClick"
DefaultButton="Close">
<StackPanel Orientation="Vertical">
<TextBlock IsTextSelectionEnabled="True">
@@ -96,21 +97,25 @@
<ContentDialog x:Name="QuitDialog"
x:Uid="QuitDialog"
x:Load="False"
CloseButtonClick="_DialogCloseClick"
DefaultButton="Primary" />
<ContentDialog x:Name="CloseAllDialog"
x:Uid="CloseAllDialog"
x:Load="False"
CloseButtonClick="_DialogCloseClick"
DefaultButton="Primary" />
<ContentDialog x:Name="CloseReadOnlyDialog"
x:Uid="CloseReadOnlyDialog"
x:Load="False"
CloseButtonClick="_DialogCloseClick"
DefaultButton="Close" />
<ContentDialog x:Name="MultiLinePasteDialog"
x:Uid="MultiLinePasteDialog"
x:Load="False"
CloseButtonClick="_DialogCloseClick"
DefaultButton="Primary">
<StackPanel>
<TextBlock x:Uid="MultiLineWarningText"
@@ -130,11 +135,13 @@
<ContentDialog x:Name="LargePasteDialog"
x:Uid="LargePasteDialog"
x:Load="False"
CloseButtonClick="_DialogCloseClick"
DefaultButton="Primary" />
<ContentDialog x:Name="ControlNoticeDialog"
x:Uid="ControlNoticeDialog"
x:Load="False"
CloseButtonClick="_DialogCloseClick"
DefaultButton="Primary">
<TextBlock IsTextSelectionEnabled="True"
TextWrapping="WrapWholeWords">
@@ -145,6 +152,7 @@
<ContentDialog x:Name="CouldNotOpenUriDialog"
x:Uid="CouldNotOpenUriDialog"
x:Load="False"
CloseButtonClick="_DialogCloseClick"
DefaultButton="Primary">
<TextBlock IsTextSelectionEnabled="True"
TextWrapping="WrapWholeWords">

View File

@@ -1178,7 +1178,7 @@ namespace winrt::TerminalApp::implementation
// "Color..."
Controls::MenuFlyoutItem chooseColorMenuItem;
Controls::FontIcon colorPickSymbol;
colorPickSymbol.FontFamily(Media::FontFamily{ L"Segoe MDL2 Assets" });
colorPickSymbol.FontFamily(Media::FontFamily{ L"Segoe Fluent Icons, Segoe MDL2 Assets" });
colorPickSymbol.Glyph(L"\xE790");
chooseColorMenuItem.Click([weakThis](auto&&, auto&&) {
@@ -1209,7 +1209,7 @@ namespace winrt::TerminalApp::implementation
{
// "Rename Tab"
Controls::FontIcon renameTabSymbol;
renameTabSymbol.FontFamily(Media::FontFamily{ L"Segoe MDL2 Assets" });
renameTabSymbol.FontFamily(Media::FontFamily{ L"Segoe Fluent Icons, Segoe MDL2 Assets" });
renameTabSymbol.Glyph(L"\xE8AC"); // Rename
renameTabMenuItem.Click([weakThis](auto&&, auto&&) {
@@ -1226,7 +1226,7 @@ namespace winrt::TerminalApp::implementation
{
// "Duplicate Tab"
Controls::FontIcon duplicateTabSymbol;
duplicateTabSymbol.FontFamily(Media::FontFamily{ L"Segoe MDL2 Assets" });
duplicateTabSymbol.FontFamily(Media::FontFamily{ L"Segoe Fluent Icons, Segoe MDL2 Assets" });
duplicateTabSymbol.Glyph(L"\xF5ED");
duplicateTabMenuItem.Click([weakThis](auto&&, auto&&) {
@@ -1243,7 +1243,7 @@ namespace winrt::TerminalApp::implementation
{
// "Split Tab"
Controls::FontIcon splitTabSymbol;
splitTabSymbol.FontFamily(Media::FontFamily{ L"Segoe MDL2 Assets" });
splitTabSymbol.FontFamily(Media::FontFamily{ L"Segoe Fluent Icons, Segoe MDL2 Assets" });
splitTabSymbol.Glyph(L"\xF246"); // ViewDashboard
splitTabMenuItem.Click([weakThis](auto&&, auto&&) {
@@ -1260,7 +1260,7 @@ namespace winrt::TerminalApp::implementation
{
// "Split Tab"
Controls::FontIcon exportTabSymbol;
exportTabSymbol.FontFamily(Media::FontFamily{ L"Segoe MDL2 Assets" });
exportTabSymbol.FontFamily(Media::FontFamily{ L"Segoe Fluent Icons, Segoe MDL2 Assets" });
exportTabSymbol.Glyph(L"\xE74E"); // Save
exportTabMenuItem.Click([weakThis](auto&&, auto&&) {

View File

@@ -89,13 +89,13 @@
</ItemGroup>
<Import Project="$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets')" />
<Import Project="$(OpenConsoleDir)packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('$(OpenConsoleDir)packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets')" />
<Import Project="$(OpenConsoleDir)packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets" Condition="Exists('$(OpenConsoleDir)packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets'))" />
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets'))" />
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.Toolkit.Win32.UI.XamlApplication.6.1.3\build\native\Microsoft.Toolkit.Win32.UI.XamlApplication.targets'))" />
</Target>

View File

@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Toolkit.Win32.UI.XamlApplication" version="6.1.3" targetFramework="native" />
<package id="Microsoft.UI.Xaml" version="2.7.0" targetFramework="native" />
<package id="Microsoft.UI.Xaml" version="2.7.0-prerelease.210913003" targetFramework="native" />
<package id="Microsoft.Windows.CppWinRT" version="2.0.210825.3" targetFramework="native" />
<package id="Microsoft.Internal.PGO-Helpers.Cpp" version="0.2.34" targetFramework="native" />

View File

@@ -917,16 +917,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation
return;
}
const auto dpi = (float)(scale * USER_DEFAULT_SCREEN_DPI);
const auto actualFontOldSize = _actualFont.GetSize();
auto lock = _terminal->LockForWriting();
_compositionScale = scale;
_renderer->TriggerFontChange(::base::saturated_cast<int>(dpi),
_desiredFont,
_actualFont);
// _updateFont relies on the new _compositionScale set above
_updateFont();
const auto actualFontNewSize = _actualFont.GetSize();
if (actualFontNewSize != actualFontOldSize)

View File

@@ -93,6 +93,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_CursorChangedHandlers(*this, nullptr);
}
void InteractivityAutomationPeer::NotifyNewOutput(std::wstring_view newOutput)
{
_NewOutputHandlers(*this, hstring{ newOutput });
}
#pragma region ITextProvider
com_array<XamlAutomation::ITextRangeProvider> InteractivityAutomationPeer::GetSelection()
{

View File

@@ -49,6 +49,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void SignalSelectionChanged() override;
void SignalTextChanged() override;
void SignalCursorChanged() override;
void NotifyNewOutput(std::wstring_view newOutput) override;
#pragma endregion
#pragma region ITextProvider Pattern
@@ -73,6 +74,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
TYPED_EVENT(SelectionChanged, IInspectable, IInspectable);
TYPED_EVENT(TextChanged, IInspectable, IInspectable);
TYPED_EVENT(CursorChanged, IInspectable, IInspectable);
TYPED_EVENT(NewOutput, IInspectable, hstring);
private:
Windows::UI::Xaml::Automation::Provider::ITextRangeProvider _CreateXamlUiaTextRange(::ITextRangeProvider* returnVal) const;

View File

@@ -14,5 +14,6 @@ namespace Microsoft.Terminal.Control
event Windows.Foundation.TypedEventHandler<Object, Object> SelectionChanged;
event Windows.Foundation.TypedEventHandler<Object, Object> TextChanged;
event Windows.Foundation.TypedEventHandler<Object, Object> CursorChanged;
event Windows.Foundation.TypedEventHandler<Object, String> NewOutput;
}
}

View File

@@ -255,7 +255,7 @@
Click="GoBackwardClicked"
IsChecked="True"
Style="{StaticResource ToggleButtonStyle}">
<FontIcon FontFamily="Segoe MDL2 Assets"
<FontIcon FontFamily="{ThemeResource SymbolThemeFontFamily}"
Glyph="&#xE74A;"
Style="{ThemeResource FontIconStyle}" />
</ToggleButton>
@@ -263,7 +263,7 @@
x:Uid="SearchBox_SearchForwards"
Click="GoForwardClicked"
Style="{StaticResource ToggleButtonStyle}">
<FontIcon FontFamily="Segoe MDL2 Assets"
<FontIcon FontFamily="{ThemeResource SymbolThemeFontFamily}"
Glyph="&#xE74B;"
Style="{ThemeResource FontIconStyle}" />
</ToggleButton>
@@ -278,7 +278,7 @@
x:Uid="SearchBox_Close"
Click="CloseClick"
Style="{ThemeResource ButtonStyle}">
<FontIcon FontFamily="Segoe MDL2 Assets"
<FontIcon FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="12"
Glyph="&#xE711;" />
</Button>

View File

@@ -1097,6 +1097,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
keyDown) :
true;
if (vkey && keyDown && _automationPeer)
{
get_self<TermControlAutomationPeer>(_automationPeer)->RecordKeyEvent(vkey);
}
if (_cursorTimer)
{
// Manually show the cursor when a key is pressed. Restarting

File diff suppressed because it is too large Load Diff

View File

@@ -28,6 +28,43 @@ namespace XamlAutomation
using winrt::Windows::UI::Xaml::Automation::Provider::ITextRangeProvider;
}
static constexpr wchar_t UNICODE_NEWLINE{ L'\n' };
// Method Description:
// - creates a copy of the provided text with all of the control characters removed
// Arguments:
// - text: the string we're sanitizing
// Return Value:
// - a copy of "sanitized" with all of the control characters removed
static std::wstring Sanitize(std::wstring_view text)
{
std::wstring sanitized{ text };
sanitized.erase(std::remove_if(sanitized.begin(), sanitized.end(), [](wchar_t c) {
return (c < UNICODE_SPACE && c != UNICODE_NEWLINE) || c == 0x7F /*DEL*/;
}),
sanitized.end());
return sanitized;
}
// Method Description:
// - verifies if a given string has text that would be read by a screen reader.
// - a string of control characters, for example, would not be read.
// Arguments:
// - text: the string we're validating
// Return Value:
// - true, if the text is readable. false, otherwise.
static constexpr bool IsReadable(std::wstring_view text)
{
for (const auto c : text)
{
if (c > UNICODE_SPACE)
{
return true;
}
}
return false;
}
namespace winrt::Microsoft::Terminal::Control::implementation
{
TermControlAutomationPeer::TermControlAutomationPeer(TermControl* owner,
@@ -45,6 +82,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_contentAutomationPeer.SelectionChanged([this](auto&&, auto&&) { SignalSelectionChanged(); });
_contentAutomationPeer.TextChanged([this](auto&&, auto&&) { SignalTextChanged(); });
_contentAutomationPeer.CursorChanged([this](auto&&, auto&&) { SignalCursorChanged(); });
_contentAutomationPeer.NewOutput([this](auto&&, hstring newOutput) { NotifyNewOutput(newOutput); });
_contentAutomationPeer.ParentProvider(*this);
};
@@ -68,6 +106,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_contentAutomationPeer.SetControlPadding(padding);
}
void TermControlAutomationPeer::RecordKeyEvent(const WORD vkey)
{
if (const auto charCode{ MapVirtualKey(vkey, MAPVK_VK_TO_CHAR) })
{
if (const auto keyEventChar{ gsl::narrow_cast<wchar_t>(charCode) }; IsReadable({ &keyEventChar, 1 }))
{
_keyEvents.emplace_back(keyEventChar);
}
}
}
// Method Description:
// - Signals the ui automation client that the terminal's selection has changed and should be updated
// Arguments:
@@ -142,8 +191,66 @@ namespace winrt::Microsoft::Terminal::Control::implementation
});
}
void TermControlAutomationPeer::NotifyNewOutput(std::wstring_view newOutput)
{
// Try to suppress any events (or event data)
// that is just the keypress the user made
auto sanitized{ Sanitize(newOutput) };
while (!_keyEvents.empty() && IsReadable(sanitized))
{
if (til::toupper_ascii(sanitized.front()) == _keyEvents.front())
{
// the key event's character (i.e. the "A" key) matches
// the output character (i.e. "a" or "A" text).
// We can assume that the output character resulted from
// the pressed key, so we can ignore it.
sanitized = sanitized.substr(1);
_keyEvents.pop_front();
}
else
{
// The output doesn't match,
// so clear the input stack and
// move on to fire the event.
_keyEvents.clear();
break;
}
}
// Suppress event if the remaining text is not readable
if (!IsReadable(sanitized))
{
return;
}
auto dispatcher{ Dispatcher() };
if (!dispatcher)
{
return;
}
// IMPORTANT:
// [1] make sure the scope returns a copy of "sanitized" so that it isn't accidentally deleted
// [2] AutomationNotificationProcessing::All --> ensures it can be interrupted by keyboard events
// [3] Do not "RunAsync(...).get()". For whatever reason, this causes NVDA to just not receive "SignalTextChanged()"'s events.
dispatcher.RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, [weakThis{ get_weak() }, sanitizedCopy{ hstring{ sanitized } }]() {
if (auto strongThis{ weakThis.get() })
{
try
{
strongThis->RaiseNotificationEvent(AutomationNotificationKind::ActionCompleted,
AutomationNotificationProcessing::All,
sanitizedCopy,
L"TerminalTextOutput");
}
CATCH_LOG();
}
});
}
hstring TermControlAutomationPeer::GetClassNameCore() const
{
// IMPORTANT: Do NOT change the name. Screen readers like JAWS may be dependent on this being "TermControl".
return L"TermControl";
}

View File

@@ -48,6 +48,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void UpdateControlBounds();
void SetControlPadding(const Core::Padding padding);
void RecordKeyEvent(const WORD vkey);
#pragma region FrameworkElementAutomationPeer
hstring GetClassNameCore() const;
@@ -64,6 +65,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void SignalSelectionChanged() override;
void SignalTextChanged() override;
void SignalCursorChanged() override;
void NotifyNewOutput(std::wstring_view newOutput) override;
#pragma endregion
#pragma region ITextProvider Pattern
@@ -78,5 +80,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
private:
winrt::Microsoft::Terminal::Control::implementation::TermControl* _termControl;
Control::InteractivityAutomationPeer _contentAutomationPeer;
std::deque<wchar_t> _keyEvents;
};
}

View File

@@ -19,54 +19,54 @@ namespace Microsoft::Terminal::Core
ITerminalApi& operator=(const ITerminalApi&) = default;
ITerminalApi& operator=(ITerminalApi&&) = default;
virtual bool PrintString(std::wstring_view string) noexcept = 0;
virtual bool ExecuteChar(wchar_t wch) noexcept = 0;
virtual void PrintString(std::wstring_view string) = 0;
virtual void ExecuteChar(wchar_t wch) = 0;
virtual TextAttribute GetTextAttributes() const noexcept = 0;
virtual void SetTextAttributes(const TextAttribute& attrs) noexcept = 0;
virtual TextAttribute GetTextAttributes() const = 0;
virtual void SetTextAttributes(const TextAttribute& attrs) = 0;
virtual Microsoft::Console::Types::Viewport GetBufferSize() noexcept = 0;
virtual bool SetCursorPosition(short x, short y) noexcept = 0;
virtual COORD GetCursorPosition() noexcept = 0;
virtual bool SetCursorVisibility(const bool visible) noexcept = 0;
virtual bool CursorLineFeed(const bool withReturn) noexcept = 0;
virtual bool EnableCursorBlinking(const bool enable) noexcept = 0;
virtual Microsoft::Console::Types::Viewport GetBufferSize() = 0;
virtual void SetCursorPosition(short x, short y) = 0;
virtual COORD GetCursorPosition() = 0;
virtual void SetCursorVisibility(const bool visible) = 0;
virtual void CursorLineFeed(const bool withReturn) = 0;
virtual void EnableCursorBlinking(const bool enable) = 0;
virtual bool DeleteCharacter(const size_t count) noexcept = 0;
virtual bool InsertCharacter(const size_t count) noexcept = 0;
virtual bool EraseCharacters(const size_t numChars) noexcept = 0;
virtual bool EraseInLine(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) noexcept = 0;
virtual bool EraseInDisplay(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) noexcept = 0;
virtual void DeleteCharacter(const size_t count) = 0;
virtual void InsertCharacter(const size_t count) = 0;
virtual void EraseCharacters(const size_t numChars) = 0;
virtual bool EraseInLine(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) = 0;
virtual bool EraseInDisplay(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) = 0;
virtual bool WarningBell() noexcept = 0;
virtual bool SetWindowTitle(std::wstring_view title) noexcept = 0;
virtual void WarningBell() = 0;
virtual void SetWindowTitle(std::wstring_view title) = 0;
virtual COLORREF GetColorTableEntry(const size_t tableIndex) const noexcept = 0;
virtual bool SetColorTableEntry(const size_t tableIndex, const COLORREF color) noexcept = 0;
virtual void SetColorAliasIndex(const ColorAlias alias, const size_t tableIndex) noexcept = 0;
virtual COLORREF GetColorTableEntry(const size_t tableIndex) const = 0;
virtual void SetColorTableEntry(const size_t tableIndex, const COLORREF color) = 0;
virtual void SetColorAliasIndex(const ColorAlias alias, const size_t tableIndex) = 0;
virtual bool SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle) noexcept = 0;
virtual void SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle) = 0;
virtual bool SetInputMode(const ::Microsoft::Console::VirtualTerminal::TerminalInput::Mode mode, const bool enabled) noexcept = 0;
virtual bool SetRenderMode(const ::Microsoft::Console::Render::RenderSettings::Mode mode, const bool enabled) noexcept = 0;
virtual void SetInputMode(const ::Microsoft::Console::VirtualTerminal::TerminalInput::Mode mode, const bool enabled) = 0;
virtual void SetRenderMode(const ::Microsoft::Console::Render::RenderSettings::Mode mode, const bool enabled) = 0;
virtual bool EnableXtermBracketedPasteMode(const bool enabled) noexcept = 0;
virtual void EnableXtermBracketedPasteMode(const bool enabled) = 0;
virtual bool IsXtermBracketedPasteModeEnabled() const = 0;
virtual bool IsVtInputEnabled() const = 0;
virtual bool CopyToClipboard(std::wstring_view content) noexcept = 0;
virtual void CopyToClipboard(std::wstring_view content) = 0;
virtual bool AddHyperlink(std::wstring_view uri, std::wstring_view params) noexcept = 0;
virtual bool EndHyperlink() noexcept = 0;
virtual void AddHyperlink(std::wstring_view uri, std::wstring_view params) = 0;
virtual void EndHyperlink() = 0;
virtual bool SetTaskbarProgress(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::TaskbarState state, const size_t progress) noexcept = 0;
virtual void SetTaskbarProgress(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::TaskbarState state, const size_t progress) = 0;
virtual bool SetWorkingDirectory(std::wstring_view uri) noexcept = 0;
virtual std::wstring_view GetWorkingDirectory() noexcept = 0;
virtual void SetWorkingDirectory(std::wstring_view uri) = 0;
virtual std::wstring_view GetWorkingDirectory() = 0;
virtual bool PushGraphicsRendition(const ::Microsoft::Console::VirtualTerminal::VTParameters options) noexcept = 0;
virtual bool PopGraphicsRendition() noexcept = 0;
virtual void PushGraphicsRendition(const ::Microsoft::Console::VirtualTerminal::VTParameters options) = 0;
virtual void PopGraphicsRendition() = 0;
protected:
ITerminalApi() = default;

View File

@@ -1002,6 +1002,11 @@ void Terminal::_WriteBuffer(const std::wstring_view& stringView)
_AdjustCursorPosition(proposedCursorPosition);
}
// Notify UIA of new text.
// It's important to do this here instead of in TextBuffer, because here you have access to the entire line of text,
// whereas TextBuffer writes it one character at a time via the OutputCellIterator.
_buffer->GetRenderTarget().TriggerNewTextNotification(stringView);
cursor.EndDeferDrawing();
}

View File

@@ -95,47 +95,47 @@ public:
#pragma region ITerminalApi
// These methods are defined in TerminalApi.cpp
bool PrintString(std::wstring_view stringView) noexcept override;
bool ExecuteChar(wchar_t wch) noexcept override;
TextAttribute GetTextAttributes() const noexcept override;
void SetTextAttributes(const TextAttribute& attrs) noexcept override;
Microsoft::Console::Types::Viewport GetBufferSize() noexcept override;
bool SetCursorPosition(short x, short y) noexcept override;
COORD GetCursorPosition() noexcept override;
bool SetCursorVisibility(const bool visible) noexcept override;
bool EnableCursorBlinking(const bool enable) noexcept override;
bool CursorLineFeed(const bool withReturn) noexcept override;
bool DeleteCharacter(const size_t count) noexcept override;
bool InsertCharacter(const size_t count) noexcept override;
bool EraseCharacters(const size_t numChars) noexcept override;
bool EraseInLine(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) noexcept override;
bool EraseInDisplay(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) noexcept override;
bool WarningBell() noexcept override;
bool SetWindowTitle(std::wstring_view title) noexcept override;
COLORREF GetColorTableEntry(const size_t tableIndex) const noexcept override;
bool SetColorTableEntry(const size_t tableIndex, const COLORREF color) noexcept override;
void SetColorAliasIndex(const ColorAlias alias, const size_t tableIndex) noexcept override;
bool SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle) noexcept override;
void PrintString(std::wstring_view stringView) override;
void ExecuteChar(wchar_t wch) override;
TextAttribute GetTextAttributes() const override;
void SetTextAttributes(const TextAttribute& attrs) override;
Microsoft::Console::Types::Viewport GetBufferSize() override;
void SetCursorPosition(short x, short y) override;
COORD GetCursorPosition() override;
void SetCursorVisibility(const bool visible) override;
void EnableCursorBlinking(const bool enable) override;
void CursorLineFeed(const bool withReturn) override;
void DeleteCharacter(const size_t count) override;
void InsertCharacter(const size_t count) override;
void EraseCharacters(const size_t numChars) override;
bool EraseInLine(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) override;
bool EraseInDisplay(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) override;
void WarningBell() override;
void SetWindowTitle(std::wstring_view title) override;
COLORREF GetColorTableEntry(const size_t tableIndex) const override;
void SetColorTableEntry(const size_t tableIndex, const COLORREF color) override;
void SetColorAliasIndex(const ColorAlias alias, const size_t tableIndex) override;
void SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle) override;
bool SetInputMode(const ::Microsoft::Console::VirtualTerminal::TerminalInput::Mode mode, const bool enabled) noexcept override;
bool SetRenderMode(const ::Microsoft::Console::Render::RenderSettings::Mode mode, const bool enabled) noexcept override;
void SetInputMode(const ::Microsoft::Console::VirtualTerminal::TerminalInput::Mode mode, const bool enabled) override;
void SetRenderMode(const ::Microsoft::Console::Render::RenderSettings::Mode mode, const bool enabled) override;
bool EnableXtermBracketedPasteMode(const bool enabled) noexcept override;
bool IsXtermBracketedPasteModeEnabled() const noexcept override;
void EnableXtermBracketedPasteMode(const bool enabled) override;
bool IsXtermBracketedPasteModeEnabled() const override;
bool IsVtInputEnabled() const noexcept override;
bool IsVtInputEnabled() const override;
bool CopyToClipboard(std::wstring_view content) noexcept override;
void CopyToClipboard(std::wstring_view content) override;
bool AddHyperlink(std::wstring_view uri, std::wstring_view params) noexcept override;
bool EndHyperlink() noexcept override;
void AddHyperlink(std::wstring_view uri, std::wstring_view params) override;
void EndHyperlink() override;
bool SetTaskbarProgress(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::TaskbarState state, const size_t progress) noexcept override;
bool SetWorkingDirectory(std::wstring_view uri) noexcept override;
std::wstring_view GetWorkingDirectory() noexcept override;
void SetTaskbarProgress(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::TaskbarState state, const size_t progress) override;
void SetWorkingDirectory(std::wstring_view uri) override;
std::wstring_view GetWorkingDirectory() override;
bool PushGraphicsRendition(const ::Microsoft::Console::VirtualTerminal::VTParameters options) noexcept override;
bool PopGraphicsRendition() noexcept override;
void PushGraphicsRendition(const ::Microsoft::Console::VirtualTerminal::VTParameters options) override;
void PopGraphicsRendition() override;
#pragma endregion

View File

@@ -11,39 +11,32 @@ using namespace Microsoft::Console::Types;
using namespace Microsoft::Console::VirtualTerminal;
// Print puts the text in the buffer and moves the cursor
bool Terminal::PrintString(std::wstring_view stringView) noexcept
try
void Terminal::PrintString(std::wstring_view stringView)
{
_WriteBuffer(stringView);
return true;
}
CATCH_RETURN_FALSE()
bool Terminal::ExecuteChar(wchar_t wch) noexcept
try
void Terminal::ExecuteChar(wchar_t wch)
{
_WriteBuffer({ &wch, 1 });
return true;
}
CATCH_RETURN_FALSE()
TextAttribute Terminal::GetTextAttributes() const noexcept
TextAttribute Terminal::GetTextAttributes() const
{
return _buffer->GetCurrentAttributes();
}
void Terminal::SetTextAttributes(const TextAttribute& attrs) noexcept
void Terminal::SetTextAttributes(const TextAttribute& attrs)
{
_buffer->SetCurrentAttributes(attrs);
}
Viewport Terminal::GetBufferSize() noexcept
Viewport Terminal::GetBufferSize()
{
return _buffer->GetSize();
}
bool Terminal::SetCursorPosition(short x, short y) noexcept
try
void Terminal::SetCursorPosition(short x, short y)
{
const auto viewport = _GetMutableViewport();
const auto viewOrigin = viewport.Origin();
@@ -52,12 +45,9 @@ try
COORD newPos{ absoluteX, absoluteY };
viewport.Clamp(newPos);
_buffer->GetCursor().SetPosition(newPos);
return true;
}
CATCH_RETURN_FALSE()
COORD Terminal::GetCursorPosition() noexcept
COORD Terminal::GetCursorPosition()
{
const auto absoluteCursorPos = _buffer->GetCursor().GetPosition();
const auto viewport = _GetMutableViewport();
@@ -75,9 +65,8 @@ COORD Terminal::GetCursorPosition() noexcept
// Arguments:
// - withReturn, set to true if a carriage return should be performed as well.
// Return value:
// - true if succeeded, false otherwise
bool Terminal::CursorLineFeed(const bool withReturn) noexcept
try
// - <none>
void Terminal::CursorLineFeed(const bool withReturn)
{
auto cursorPos = _buffer->GetCursor().GetPosition();
@@ -91,10 +80,7 @@ try
cursorPos.X = 0;
}
_AdjustCursorPosition(cursorPos);
return true;
}
CATCH_RETURN_FALSE()
// Method Description:
// - deletes count characters starting from the cursor's current position
@@ -105,24 +91,17 @@ CATCH_RETURN_FALSE()
// Arguments:
// - count, the number of characters to delete
// Return value:
// - true if succeeded, false otherwise
bool Terminal::DeleteCharacter(const size_t count) noexcept
try
// - <none>
void Terminal::DeleteCharacter(const size_t count)
{
SHORT dist;
if (!SUCCEEDED(SizeTToShort(count, &dist)))
{
return false;
}
THROW_IF_FAILED(SizeTToShort(count, &dist));
const auto cursorPos = _buffer->GetCursor().GetPosition();
const auto copyToPos = cursorPos;
const COORD copyFromPos{ cursorPos.X + dist, cursorPos.Y };
const auto sourceWidth = _mutableViewport.RightExclusive() - copyFromPos.X;
SHORT width;
if (!SUCCEEDED(UIntToShort(sourceWidth, &width)))
{
return false;
}
THROW_IF_FAILED(UIntToShort(sourceWidth, &width));
// Get a rectangle of the source
auto source = Viewport::FromDimensions(copyFromPos, width, 1);
@@ -140,10 +119,7 @@ try
const auto data = OutputCell(*(_buffer->GetCellDataAt(sourcePos)));
_buffer->Write(OutputCellIterator({ &data, 1 }), targetPos);
} while (source.WalkInBounds(sourcePos, walkDirection) && target.WalkInBounds(targetPos, walkDirection));
return true;
}
CATCH_RETURN_FALSE()
// Method Description:
// - Inserts count spaces starting from the cursor's current position, moving over the existing text
@@ -153,28 +129,21 @@ CATCH_RETURN_FALSE()
// Arguments:
// - count, the number of spaces to insert
// Return value:
// - true if succeeded, false otherwise
bool Terminal::InsertCharacter(const size_t count) noexcept
try
// - <none>
void Terminal::InsertCharacter(const size_t count)
{
// NOTE: the code below is _extremely_ similar to DeleteCharacter
// We will want to use this same logic and implement a helper function instead
// that does the 'move a region from here to there' operation
// TODO: Github issue #2163
SHORT dist;
if (!SUCCEEDED(SizeTToShort(count, &dist)))
{
return false;
}
THROW_IF_FAILED(SizeTToShort(count, &dist));
const auto cursorPos = _buffer->GetCursor().GetPosition();
const auto copyFromPos = cursorPos;
const COORD copyToPos{ cursorPos.X + dist, cursorPos.Y };
const auto sourceWidth = _mutableViewport.RightExclusive() - copyFromPos.X;
SHORT width;
if (!SUCCEEDED(UIntToShort(sourceWidth, &width)))
{
return false;
}
THROW_IF_FAILED(UIntToShort(sourceWidth, &width));
// Get a rectangle of the source
auto source = Viewport::FromDimensions(copyFromPos, width, 1);
@@ -195,13 +164,9 @@ try
} while (source.WalkInBounds(sourcePos, walkDirection) && target.WalkInBounds(targetPos, walkDirection));
const auto eraseIter = OutputCellIterator(UNICODE_SPACE, _buffer->GetCurrentAttributes(), dist);
_buffer->Write(eraseIter, cursorPos);
return true;
}
CATCH_RETURN_FALSE()
bool Terminal::EraseCharacters(const size_t numChars) noexcept
try
void Terminal::EraseCharacters(const size_t numChars)
{
const auto absoluteCursorPos = _buffer->GetCursor().GetPosition();
const auto viewport = _GetMutableViewport();
@@ -209,9 +174,7 @@ try
const short fillLimit = std::min(static_cast<short>(numChars), distanceToRight);
const auto eraseIter = OutputCellIterator(UNICODE_SPACE, _buffer->GetCurrentAttributes(), fillLimit);
_buffer->Write(eraseIter, absoluteCursorPos);
return true;
}
CATCH_RETURN_FALSE()
// Method description:
// - erases a line of text, either from
@@ -223,8 +186,7 @@ CATCH_RETURN_FALSE()
// - the erase type
// Return value:
// - true if succeeded, false otherwise
bool Terminal::EraseInLine(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) noexcept
try
bool Terminal::EraseInLine(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType)
{
const auto cursorPos = _buffer->GetCursor().GetPosition();
const auto viewport = _GetMutableViewport();
@@ -257,7 +219,6 @@ try
_buffer->Write(eraseIter, startPos, false);
return true;
}
CATCH_RETURN_FALSE()
// Method description:
// - erases text in the buffer in two ways depending on erase type
@@ -267,8 +228,7 @@ CATCH_RETURN_FALSE()
// - the erase type
// Return Value:
// - true if succeeded, false otherwise
bool Terminal::EraseInDisplay(const DispatchTypes::EraseType eraseType) noexcept
try
bool Terminal::EraseInDisplay(const DispatchTypes::EraseType eraseType)
{
// Store the relative cursor position so we can restore it later after we move the viewport
const auto cursorPos = _buffer->GetCursor().GetPosition();
@@ -341,27 +301,20 @@ try
return true;
}
CATCH_RETURN_FALSE()
bool Terminal::WarningBell() noexcept
try
void Terminal::WarningBell()
{
_pfnWarningBell();
return true;
}
CATCH_RETURN_FALSE()
bool Terminal::SetWindowTitle(std::wstring_view title) noexcept
try
void Terminal::SetWindowTitle(std::wstring_view title)
{
if (!_suppressApplicationTitle)
{
_title.emplace(title);
_pfnTitleChanged(_title.value());
}
return true;
}
CATCH_RETURN_FALSE()
// Method Description:
// - Retrieves the value in the colortable at the specified index.
@@ -369,15 +322,10 @@ CATCH_RETURN_FALSE()
// - tableIndex: the index of the color table to retrieve.
// Return Value:
// - the COLORREF value for the color at that index in the table.
COLORREF Terminal::GetColorTableEntry(const size_t tableIndex) const noexcept
try
COLORREF Terminal::GetColorTableEntry(const size_t tableIndex) const
{
return _renderSettings.GetColorTableEntry(tableIndex);
}
catch (...)
{
return INVALID_COLOR;
}
// Method Description:
// - Updates the value in the colortable at index tableIndex to the new color
@@ -386,9 +334,8 @@ catch (...)
// - tableIndex: the index of the color table to update.
// - color: the new COLORREF to use as that color table value.
// Return Value:
// - true iff we successfully updated the color table entry.
bool Terminal::SetColorTableEntry(const size_t tableIndex, const COLORREF color) noexcept
try
// - <none>
void Terminal::SetColorTableEntry(const size_t tableIndex, const COLORREF color)
{
_renderSettings.SetColorTableEntry(tableIndex, color);
@@ -399,9 +346,7 @@ try
// Repaint everything - the colors might have changed
_buffer->GetRenderTarget().TriggerRedrawAll();
return true;
}
CATCH_RETURN_FALSE()
// Method Description:
// - Sets the position in the color table for the given color alias.
@@ -410,7 +355,7 @@ CATCH_RETURN_FALSE()
// - tableIndex: the new position of the alias in the color table.
// Return Value:
// - <none>
void Terminal::SetColorAliasIndex(const ColorAlias alias, const size_t tableIndex) noexcept
void Terminal::SetColorAliasIndex(const ColorAlias alias, const size_t tableIndex)
{
_renderSettings.SetColorAliasIndex(alias, tableIndex);
}
@@ -420,8 +365,8 @@ void Terminal::SetColorAliasIndex(const ColorAlias alias, const size_t tableInde
// Arguments:
// - cursorStyle: the style to be set for the cursor
// Return Value:
// - true iff we successfully set the cursor style
bool Terminal::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) noexcept
// - <none>
void Terminal::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle)
{
CursorType finalCursorType = CursorType::Legacy;
bool shouldBlink = false;
@@ -459,58 +404,48 @@ bool Terminal::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) noex
default:
// Invalid argument should be ignored.
return true;
return;
}
_buffer->GetCursor().SetType(finalCursorType);
_buffer->GetCursor().SetBlinkingAllowed(shouldBlink);
return true;
}
bool Terminal::SetInputMode(const TerminalInput::Mode mode, const bool enabled) noexcept
try
void Terminal::SetInputMode(const TerminalInput::Mode mode, const bool enabled)
{
_terminalInput->SetInputMode(mode, enabled);
return true;
}
CATCH_RETURN_FALSE()
bool Terminal::SetRenderMode(const RenderSettings::Mode mode, const bool enabled) noexcept
try
void Terminal::SetRenderMode(const RenderSettings::Mode mode, const bool enabled)
{
_renderSettings.SetRenderMode(mode, enabled);
// Repaint everything - the colors will have changed
_buffer->GetRenderTarget().TriggerRedrawAll();
return true;
}
CATCH_RETURN_FALSE()
bool Terminal::EnableXtermBracketedPasteMode(const bool enabled) noexcept
void Terminal::EnableXtermBracketedPasteMode(const bool enabled)
{
_bracketedPasteMode = enabled;
return true;
}
bool Terminal::IsXtermBracketedPasteModeEnabled() const noexcept
bool Terminal::IsXtermBracketedPasteModeEnabled() const
{
return _bracketedPasteMode;
}
bool Terminal::IsVtInputEnabled() const noexcept
bool Terminal::IsVtInputEnabled() const
{
// We should never be getting this call in Terminal.
FAIL_FAST();
}
bool Terminal::SetCursorVisibility(const bool visible) noexcept
void Terminal::SetCursorVisibility(const bool visible)
{
_buffer->GetCursor().SetIsVisible(visible);
return true;
}
bool Terminal::EnableCursorBlinking(const bool enable) noexcept
void Terminal::EnableCursorBlinking(const bool enable)
{
_buffer->GetCursor().SetBlinkingAllowed(enable);
@@ -521,17 +456,12 @@ bool Terminal::EnableCursorBlinking(const bool enable) noexcept
// cursor visibility property controls whether the user can see it or not.
// (Yes, the cursor can be On and NOT Visible)
_buffer->GetCursor().SetIsOn(true);
return true;
}
bool Terminal::CopyToClipboard(std::wstring_view content) noexcept
try
void Terminal::CopyToClipboard(std::wstring_view content)
{
_pfnCopyToClipboard(content);
return true;
}
CATCH_RETURN_FALSE()
// Method Description:
// - Updates the buffer's current text attributes to start a hyperlink
@@ -539,27 +469,25 @@ CATCH_RETURN_FALSE()
// - The hyperlink URI
// - The customID provided (if there was one)
// Return Value:
// - true
bool Terminal::AddHyperlink(std::wstring_view uri, std::wstring_view params) noexcept
// - <none>
void Terminal::AddHyperlink(std::wstring_view uri, std::wstring_view params)
{
auto attr = _buffer->GetCurrentAttributes();
const auto id = _buffer->GetHyperlinkId(uri, params);
attr.SetHyperlinkId(id);
_buffer->SetCurrentAttributes(attr);
_buffer->AddHyperlinkToMap(uri, id);
return true;
}
// Method Description:
// - Updates the buffer's current text attributes to end a hyperlink
// Return Value:
// - true
bool Terminal::EndHyperlink() noexcept
// - <none>
void Terminal::EndHyperlink()
{
auto attr = _buffer->GetCurrentAttributes();
attr.SetHyperlinkId(0);
_buffer->SetCurrentAttributes(attr);
return true;
}
// Method Description:
@@ -568,8 +496,8 @@ bool Terminal::EndHyperlink() noexcept
// - state: indicates the progress state
// - progress: indicates the progress value
// Return Value:
// - true
bool Terminal::SetTaskbarProgress(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::TaskbarState state, const size_t progress) noexcept
// - <none>
void Terminal::SetTaskbarProgress(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::TaskbarState state, const size_t progress)
{
_taskbarState = static_cast<size_t>(state);
@@ -610,16 +538,14 @@ bool Terminal::SetTaskbarProgress(const ::Microsoft::Console::VirtualTerminal::D
{
_pfnTaskbarProgressChanged();
}
return true;
}
bool Terminal::SetWorkingDirectory(std::wstring_view uri) noexcept
void Terminal::SetWorkingDirectory(std::wstring_view uri)
{
_workingDirectory = uri;
return true;
}
std::wstring_view Terminal::GetWorkingDirectory() noexcept
std::wstring_view Terminal::GetWorkingDirectory()
{
return _workingDirectory;
}
@@ -631,11 +557,10 @@ std::wstring_view Terminal::GetWorkingDirectory() noexcept
// should be saved. Only a small subset of GraphicsOptions are actually supported;
// others are ignored. If no options are specified, all attributes are stored.
// Return Value:
// - true
bool Terminal::PushGraphicsRendition(const VTParameters options) noexcept
// - <none>
void Terminal::PushGraphicsRendition(const VTParameters options)
{
_sgrStack.Push(_buffer->GetCurrentAttributes(), options);
return true;
}
// Method Description:
@@ -644,10 +569,9 @@ bool Terminal::PushGraphicsRendition(const VTParameters options) noexcept
// Arguments:
// - <none>
// Return Value:
// - true
bool Terminal::PopGraphicsRendition() noexcept
// - <none>
void Terminal::PopGraphicsRendition()
{
const TextAttribute current = _buffer->GetCurrentAttributes();
_buffer->SetCurrentAttributes(_sgrStack.Pop(current));
return true;
}

View File

@@ -19,77 +19,74 @@ TerminalDispatch::TerminalDispatch(ITerminalApi& terminalApi) noexcept :
{
}
void TerminalDispatch::Execute(const wchar_t wchControl) noexcept
void TerminalDispatch::Execute(const wchar_t wchControl)
{
_terminalApi.ExecuteChar(wchControl);
}
void TerminalDispatch::Print(const wchar_t wchPrintable) noexcept
void TerminalDispatch::Print(const wchar_t wchPrintable)
{
_terminalApi.PrintString({ &wchPrintable, 1 });
}
void TerminalDispatch::PrintString(const std::wstring_view string) noexcept
void TerminalDispatch::PrintString(const std::wstring_view string)
{
_terminalApi.PrintString(string);
}
bool TerminalDispatch::CursorPosition(const size_t line,
const size_t column) noexcept
try
const size_t column)
{
SHORT x{ 0 };
SHORT y{ 0 };
RETURN_BOOL_IF_FALSE(SUCCEEDED(SizeTToShort(column, &x)) &&
SUCCEEDED(SizeTToShort(line, &y)));
THROW_IF_FAILED(SizeTToShort(column, &x));
THROW_IF_FAILED(SizeTToShort(line, &y));
RETURN_BOOL_IF_FALSE(SUCCEEDED(ShortSub(x, 1, &x)) &&
SUCCEEDED(ShortSub(y, 1, &y)));
THROW_IF_FAILED(ShortSub(x, 1, &x));
THROW_IF_FAILED(ShortSub(y, 1, &y));
return _terminalApi.SetCursorPosition(x, y);
_terminalApi.SetCursorPosition(x, y);
return true;
}
CATCH_LOG_RETURN_FALSE()
bool TerminalDispatch::CursorVisibility(const bool isVisible) noexcept
bool TerminalDispatch::CursorVisibility(const bool isVisible)
{
return _terminalApi.SetCursorVisibility(isVisible);
_terminalApi.SetCursorVisibility(isVisible);
return true;
}
bool TerminalDispatch::EnableCursorBlinking(const bool enable) noexcept
bool TerminalDispatch::EnableCursorBlinking(const bool enable)
{
return _terminalApi.EnableCursorBlinking(enable);
_terminalApi.EnableCursorBlinking(enable);
return true;
}
bool TerminalDispatch::CursorForward(const size_t distance) noexcept
try
bool TerminalDispatch::CursorForward(const size_t distance)
{
const auto cursorPos = _terminalApi.GetCursorPosition();
const COORD newCursorPos{ cursorPos.X + gsl::narrow<short>(distance), cursorPos.Y };
return _terminalApi.SetCursorPosition(newCursorPos.X, newCursorPos.Y);
_terminalApi.SetCursorPosition(newCursorPos.X, newCursorPos.Y);
return true;
}
CATCH_LOG_RETURN_FALSE()
bool TerminalDispatch::CursorBackward(const size_t distance) noexcept
try
bool TerminalDispatch::CursorBackward(const size_t distance)
{
const auto cursorPos = _terminalApi.GetCursorPosition();
const COORD newCursorPos{ cursorPos.X - gsl::narrow<short>(distance), cursorPos.Y };
return _terminalApi.SetCursorPosition(newCursorPos.X, newCursorPos.Y);
_terminalApi.SetCursorPosition(newCursorPos.X, newCursorPos.Y);
return true;
}
CATCH_LOG_RETURN_FALSE()
bool TerminalDispatch::CursorUp(const size_t distance) noexcept
try
bool TerminalDispatch::CursorUp(const size_t distance)
{
const auto cursorPos = _terminalApi.GetCursorPosition();
const COORD newCursorPos{ cursorPos.X, cursorPos.Y + gsl::narrow<short>(distance) };
return _terminalApi.SetCursorPosition(newCursorPos.X, newCursorPos.Y);
_terminalApi.SetCursorPosition(newCursorPos.X, newCursorPos.Y);
return true;
}
CATCH_LOG_RETURN_FALSE()
bool TerminalDispatch::LineFeed(const DispatchTypes::LineFeedType lineFeedType) noexcept
try
bool TerminalDispatch::LineFeed(const DispatchTypes::LineFeedType lineFeedType)
{
switch (lineFeedType)
{
@@ -97,45 +94,42 @@ try
// There is currently no need for mode-specific line feeds in the Terminal,
// so for now we just treat them as a line feed without carriage return.
case DispatchTypes::LineFeedType::WithoutReturn:
return _terminalApi.CursorLineFeed(false);
_terminalApi.CursorLineFeed(false);
return true;
case DispatchTypes::LineFeedType::WithReturn:
return _terminalApi.CursorLineFeed(true);
_terminalApi.CursorLineFeed(true);
return true;
default:
return false;
}
}
CATCH_LOG_RETURN_FALSE()
bool TerminalDispatch::EraseCharacters(const size_t numChars) noexcept
try
bool TerminalDispatch::EraseCharacters(const size_t numChars)
{
return _terminalApi.EraseCharacters(numChars);
_terminalApi.EraseCharacters(numChars);
return true;
}
CATCH_LOG_RETURN_FALSE()
bool TerminalDispatch::WarningBell() noexcept
try
bool TerminalDispatch::WarningBell()
{
return _terminalApi.WarningBell();
_terminalApi.WarningBell();
return true;
}
CATCH_LOG_RETURN_FALSE()
bool TerminalDispatch::CarriageReturn() noexcept
try
bool TerminalDispatch::CarriageReturn()
{
const auto cursorPos = _terminalApi.GetCursorPosition();
return _terminalApi.SetCursorPosition(0, cursorPos.Y);
_terminalApi.SetCursorPosition(0, cursorPos.Y);
return true;
}
CATCH_LOG_RETURN_FALSE()
bool TerminalDispatch::SetWindowTitle(std::wstring_view title) noexcept
try
bool TerminalDispatch::SetWindowTitle(std::wstring_view title)
{
return _terminalApi.SetWindowTitle(title);
_terminalApi.SetWindowTitle(title);
return true;
}
CATCH_LOG_RETURN_FALSE()
bool TerminalDispatch::HorizontalTabSet() noexcept
bool TerminalDispatch::HorizontalTabSet()
{
const auto width = _terminalApi.GetBufferSize().Dimensions().X;
const auto column = _terminalApi.GetCursorPosition().X;
@@ -145,7 +139,7 @@ bool TerminalDispatch::HorizontalTabSet() noexcept
return true;
}
bool TerminalDispatch::ForwardTab(const size_t numTabs) noexcept
bool TerminalDispatch::ForwardTab(const size_t numTabs)
{
const auto width = _terminalApi.GetBufferSize().Dimensions().X;
const auto cursorPosition = _terminalApi.GetCursorPosition();
@@ -162,10 +156,11 @@ bool TerminalDispatch::ForwardTab(const size_t numTabs) noexcept
}
}
return _terminalApi.SetCursorPosition(column, row);
_terminalApi.SetCursorPosition(column, row);
return true;
}
bool TerminalDispatch::BackwardsTab(const size_t numTabs) noexcept
bool TerminalDispatch::BackwardsTab(const size_t numTabs)
{
const auto width = _terminalApi.GetBufferSize().Dimensions().X;
const auto cursorPosition = _terminalApi.GetCursorPosition();
@@ -182,25 +177,23 @@ bool TerminalDispatch::BackwardsTab(const size_t numTabs) noexcept
}
}
return _terminalApi.SetCursorPosition(column, row);
_terminalApi.SetCursorPosition(column, row);
return true;
}
bool TerminalDispatch::TabClear(const DispatchTypes::TabClearType clearType) noexcept
bool TerminalDispatch::TabClear(const DispatchTypes::TabClearType clearType)
{
bool success = false;
switch (clearType)
{
case DispatchTypes::TabClearType::ClearCurrentColumn:
success = _ClearSingleTabStop();
break;
_ClearSingleTabStop();
return true;
case DispatchTypes::TabClearType::ClearAllColumns:
success = _ClearAllTabStops();
break;
_ClearAllTabStops();
return true;
default:
success = false;
break;
return false;
}
return success;
}
// Method Description:
@@ -209,63 +202,57 @@ bool TerminalDispatch::TabClear(const DispatchTypes::TabClearType clearType) noe
// - tableIndex: The VT color table index
// - color: The new RGB color value to use.
// Return Value:
// True if handled successfully. False otherwise.
// - True.
bool TerminalDispatch::SetColorTableEntry(const size_t tableIndex,
const DWORD color) noexcept
try
const DWORD color)
{
return _terminalApi.SetColorTableEntry(tableIndex, color);
_terminalApi.SetColorTableEntry(tableIndex, color);
return true;
}
CATCH_LOG_RETURN_FALSE()
bool TerminalDispatch::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) noexcept
try
bool TerminalDispatch::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle)
{
return _terminalApi.SetCursorStyle(cursorStyle);
_terminalApi.SetCursorStyle(cursorStyle);
return true;
}
CATCH_LOG_RETURN_FALSE()
bool TerminalDispatch::SetCursorColor(const DWORD color) noexcept
try
bool TerminalDispatch::SetCursorColor(const DWORD color)
{
return _terminalApi.SetColorTableEntry(TextColor::CURSOR_COLOR, color);
_terminalApi.SetColorTableEntry(TextColor::CURSOR_COLOR, color);
return true;
}
CATCH_LOG_RETURN_FALSE()
bool TerminalDispatch::SetClipboard(std::wstring_view content) noexcept
try
bool TerminalDispatch::SetClipboard(std::wstring_view content)
{
return _terminalApi.CopyToClipboard(content);
_terminalApi.CopyToClipboard(content);
return true;
}
CATCH_LOG_RETURN_FALSE()
// Method Description:
// - Sets the default foreground color to a new value
// Arguments:
// - color: The new RGB color value to use, in 0x00BBGGRR form
// Return Value:
// True if handled successfully. False otherwise.
bool TerminalDispatch::SetDefaultForeground(const DWORD color) noexcept
try
// - True.
bool TerminalDispatch::SetDefaultForeground(const DWORD color)
{
_terminalApi.SetColorAliasIndex(ColorAlias::DefaultForeground, TextColor::DEFAULT_FOREGROUND);
return _terminalApi.SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, color);
_terminalApi.SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, color);
return true;
}
CATCH_LOG_RETURN_FALSE()
// Method Description:
// - Sets the default background color to a new value
// Arguments:
// - color: The new RGB color value to use, in 0x00BBGGRR form
// Return Value:
// True if handled successfully. False otherwise.
bool TerminalDispatch::SetDefaultBackground(const DWORD color) noexcept
try
// - True.
bool TerminalDispatch::SetDefaultBackground(const DWORD color)
{
_terminalApi.SetColorAliasIndex(ColorAlias::DefaultBackground, TextColor::DEFAULT_BACKGROUND);
return _terminalApi.SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, color);
_terminalApi.SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, color);
return true;
}
CATCH_LOG_RETURN_FALSE()
// Method Description:
// - Erases characters in the buffer depending on the erase type
@@ -273,38 +260,34 @@ CATCH_LOG_RETURN_FALSE()
// - eraseType: the erase type (from beginning, to end, or all)
// Return Value:
// True if handled successfully. False otherwise.
bool TerminalDispatch::EraseInLine(const DispatchTypes::EraseType eraseType) noexcept
try
bool TerminalDispatch::EraseInLine(const DispatchTypes::EraseType eraseType)
{
return _terminalApi.EraseInLine(eraseType);
}
CATCH_LOG_RETURN_FALSE()
// Method Description:
// - Deletes count number of characters starting from where the cursor is currently
// Arguments:
// - count, the number of characters to delete
// Return Value:
// True if handled successfully. False otherwise.
bool TerminalDispatch::DeleteCharacter(const size_t count) noexcept
try
// - True.
bool TerminalDispatch::DeleteCharacter(const size_t count)
{
return _terminalApi.DeleteCharacter(count);
_terminalApi.DeleteCharacter(count);
return true;
}
CATCH_LOG_RETURN_FALSE()
// Method Description:
// - Adds count number of spaces starting from where the cursor is currently
// Arguments:
// - count, the number of spaces to add
// Return Value:
// True if handled successfully, false otherwise
bool TerminalDispatch::InsertCharacter(const size_t count) noexcept
try
// - True.
bool TerminalDispatch::InsertCharacter(const size_t count)
{
return _terminalApi.InsertCharacter(count);
_terminalApi.InsertCharacter(count);
return true;
}
CATCH_LOG_RETURN_FALSE()
// Method Description:
// - Moves the viewport and erases text from the buffer depending on the eraseType
@@ -312,19 +295,17 @@ CATCH_LOG_RETURN_FALSE()
// - eraseType: the desired erase type
// Return Value:
// True if handled successfully. False otherwise
bool TerminalDispatch::EraseInDisplay(const DispatchTypes::EraseType eraseType) noexcept
try
bool TerminalDispatch::EraseInDisplay(const DispatchTypes::EraseType eraseType)
{
return _terminalApi.EraseInDisplay(eraseType);
}
CATCH_LOG_RETURN_FALSE()
// - DECKPAM, DECKPNM - Sets the keypad input mode to either Application mode or Numeric mode (true, false respectively)
// Arguments:
// - applicationMode - set to true to enable Application Mode Input, false for Numeric Mode Input.
// Return Value:
// - True if handled successfully. False otherwise.
bool TerminalDispatch::SetKeypadMode(const bool applicationMode) noexcept
// - True.
bool TerminalDispatch::SetKeypadMode(const bool applicationMode)
{
_terminalApi.SetInputMode(TerminalInput::Mode::Keypad, applicationMode);
return true;
@@ -334,8 +315,8 @@ bool TerminalDispatch::SetKeypadMode(const bool applicationMode) noexcept
// Arguments:
// - applicationMode - set to true to enable Application Mode Input, false for Normal Mode Input.
// Return Value:
// - True if handled successfully. False otherwise.
bool TerminalDispatch::SetCursorKeysMode(const bool applicationMode) noexcept
// - True.
bool TerminalDispatch::SetCursorKeysMode(const bool applicationMode)
{
_terminalApi.SetInputMode(TerminalInput::Mode::CursorKey, applicationMode);
return true;
@@ -347,10 +328,11 @@ bool TerminalDispatch::SetCursorKeysMode(const bool applicationMode) noexcept
// Arguments:
// - reverseMode - set to true to enable reverse screen mode, false for normal mode.
// Return Value:
// - True if handled successfully. False otherwise.
bool TerminalDispatch::SetScreenMode(const bool reverseMode) noexcept
// - True.
bool TerminalDispatch::SetScreenMode(const bool reverseMode)
{
return _terminalApi.SetRenderMode(RenderSettings::Mode::ScreenReversed, reverseMode);
_terminalApi.SetRenderMode(RenderSettings::Mode::ScreenReversed, reverseMode);
return true;
}
// Method Description:
@@ -359,8 +341,8 @@ bool TerminalDispatch::SetScreenMode(const bool reverseMode) noexcept
// Arguments:
// - win32InputMode - set to true to enable win32-input-mode, false to disable.
// Return Value:
// - True if handled successfully. False otherwise.
bool TerminalDispatch::EnableWin32InputMode(const bool win32Mode) noexcept
// - True.
bool TerminalDispatch::EnableWin32InputMode(const bool win32Mode)
{
_terminalApi.SetInputMode(TerminalInput::Mode::Win32, win32Mode);
return true;
@@ -371,8 +353,8 @@ bool TerminalDispatch::EnableWin32InputMode(const bool win32Mode) noexcept
//Arguments:
// - enabled - true to enable, false to disable.
// Return value:
// True if handled successfully. False otherwise.
bool TerminalDispatch::EnableVT200MouseMode(const bool enabled) noexcept
// - True.
bool TerminalDispatch::EnableVT200MouseMode(const bool enabled)
{
_terminalApi.SetInputMode(TerminalInput::Mode::DefaultMouseTracking, enabled);
return true;
@@ -384,8 +366,8 @@ bool TerminalDispatch::EnableVT200MouseMode(const bool enabled) noexcept
//Arguments:
// - enabled - true to enable, false to disable.
// Return value:
// True if handled successfully. False otherwise.
bool TerminalDispatch::EnableUTF8ExtendedMouseMode(const bool enabled) noexcept
// - True.
bool TerminalDispatch::EnableUTF8ExtendedMouseMode(const bool enabled)
{
_terminalApi.SetInputMode(TerminalInput::Mode::Utf8MouseEncoding, enabled);
return true;
@@ -397,8 +379,8 @@ bool TerminalDispatch::EnableUTF8ExtendedMouseMode(const bool enabled) noexcept
//Arguments:
// - enabled - true to enable, false to disable.
// Return value:
// True if handled successfully. False otherwise.
bool TerminalDispatch::EnableSGRExtendedMouseMode(const bool enabled) noexcept
// - True.
bool TerminalDispatch::EnableSGRExtendedMouseMode(const bool enabled)
{
_terminalApi.SetInputMode(TerminalInput::Mode::SgrMouseEncoding, enabled);
return true;
@@ -409,8 +391,8 @@ bool TerminalDispatch::EnableSGRExtendedMouseMode(const bool enabled) noexcept
//Arguments:
// - enabled - true to enable, false to disable.
// Return value:
// True if handled successfully. False otherwise.
bool TerminalDispatch::EnableButtonEventMouseMode(const bool enabled) noexcept
// - True.
bool TerminalDispatch::EnableButtonEventMouseMode(const bool enabled)
{
_terminalApi.SetInputMode(TerminalInput::Mode::ButtonEventMouseTracking, enabled);
return true;
@@ -422,8 +404,8 @@ bool TerminalDispatch::EnableButtonEventMouseMode(const bool enabled) noexcept
//Arguments:
// - enabled - true to enable, false to disable.
// Return value:
// True if handled successfully. False otherwise.
bool TerminalDispatch::EnableAnyEventMouseMode(const bool enabled) noexcept
// - True.
bool TerminalDispatch::EnableAnyEventMouseMode(const bool enabled)
{
_terminalApi.SetInputMode(TerminalInput::Mode::AnyEventMouseTracking, enabled);
return true;
@@ -435,8 +417,8 @@ bool TerminalDispatch::EnableAnyEventMouseMode(const bool enabled) noexcept
//Arguments:
// - enabled - true to enable, false to disable.
// Return value:
// True if handled successfully. False otherwise.
bool TerminalDispatch::EnableAlternateScroll(const bool enabled) noexcept
// - True.
bool TerminalDispatch::EnableAlternateScroll(const bool enabled)
{
_terminalApi.SetInputMode(TerminalInput::Mode::AlternateScroll, enabled);
return true;
@@ -448,19 +430,19 @@ bool TerminalDispatch::EnableAlternateScroll(const bool enabled) noexcept
//Arguments:
// - enabled - true to enable, false to disable.
// Return value:
// True if handled successfully. False otherwise.
bool TerminalDispatch::EnableXtermBracketedPasteMode(const bool enabled) noexcept
// - True.
bool TerminalDispatch::EnableXtermBracketedPasteMode(const bool enabled)
{
_terminalApi.EnableXtermBracketedPasteMode(enabled);
return true;
}
bool TerminalDispatch::SetMode(const DispatchTypes::ModeParams param) noexcept
bool TerminalDispatch::SetMode(const DispatchTypes::ModeParams param)
{
return _ModeParamsHelper(param, true);
}
bool TerminalDispatch::ResetMode(const DispatchTypes::ModeParams param) noexcept
bool TerminalDispatch::ResetMode(const DispatchTypes::ModeParams param)
{
return _ModeParamsHelper(param, false);
}
@@ -472,18 +454,20 @@ bool TerminalDispatch::ResetMode(const DispatchTypes::ModeParams param) noexcept
// - params - the optional custom ID
// Return Value:
// - true
bool TerminalDispatch::AddHyperlink(const std::wstring_view uri, const std::wstring_view params) noexcept
bool TerminalDispatch::AddHyperlink(const std::wstring_view uri, const std::wstring_view params)
{
return _terminalApi.AddHyperlink(uri, params);
_terminalApi.AddHyperlink(uri, params);
return true;
}
// Method Description:
// - End a hyperlink
// Return Value:
// - true
bool TerminalDispatch::EndHyperlink() noexcept
bool TerminalDispatch::EndHyperlink()
{
return _terminalApi.EndHyperlink();
_terminalApi.EndHyperlink();
return true;
}
// Method Description:
@@ -493,7 +477,7 @@ bool TerminalDispatch::EndHyperlink() noexcept
// - string: contains the parameters that define which action we do
// Return Value:
// - true
bool TerminalDispatch::DoConEmuAction(const std::wstring_view string) noexcept
bool TerminalDispatch::DoConEmuAction(const std::wstring_view string)
{
unsigned int state = 0;
unsigned int progress = 0;
@@ -538,7 +522,8 @@ bool TerminalDispatch::DoConEmuAction(const std::wstring_view string) noexcept
// progress is greater than the maximum allowed value, clamp it to the max
progress = TaskbarMaxProgress;
}
return _terminalApi.SetTaskbarProgress(static_cast<DispatchTypes::TaskbarState>(state), progress);
_terminalApi.SetTaskbarProgress(static_cast<DispatchTypes::TaskbarState>(state), progress);
return true;
}
// 9 is SetWorkingDirectory, which informs the terminal about the current working directory.
else if (subParam == 9)
@@ -550,14 +535,15 @@ bool TerminalDispatch::DoConEmuAction(const std::wstring_view string) noexcept
// An example: 9;"D:/"
if (path.at(0) == L'"' && path.at(path.size() - 1) == L'"' && path.size() >= 3)
{
return _terminalApi.SetWorkingDirectory(path.substr(1, path.size() - 2));
_terminalApi.SetWorkingDirectory(path.substr(1, path.size() - 2));
}
else
{
// If we fail to find the surrounding quotation marks, we'll give the path a try anyway.
// ConEmu also does this.
return _terminalApi.SetWorkingDirectory(path);
_terminalApi.SetWorkingDirectory(path);
}
return true;
}
}
@@ -571,7 +557,7 @@ bool TerminalDispatch::DoConEmuAction(const std::wstring_view string) noexcept
// - enable - True for set, false for unset.
// Return Value:
// - True if handled successfully. False otherwise.
bool TerminalDispatch::_ModeParamsHelper(const DispatchTypes::ModeParams param, const bool enable) noexcept
bool TerminalDispatch::_ModeParamsHelper(const DispatchTypes::ModeParams param, const bool enable)
{
bool success = false;
switch (param)
@@ -621,24 +607,22 @@ bool TerminalDispatch::_ModeParamsHelper(const DispatchTypes::ModeParams param,
return success;
}
bool TerminalDispatch::_ClearSingleTabStop() noexcept
void TerminalDispatch::_ClearSingleTabStop()
{
const auto width = _terminalApi.GetBufferSize().Dimensions().X;
const auto column = _terminalApi.GetCursorPosition().X;
_InitTabStopsForWidth(width);
_tabStopColumns.at(column) = false;
return true;
}
bool TerminalDispatch::_ClearAllTabStops() noexcept
void TerminalDispatch::_ClearAllTabStops()
{
_tabStopColumns.clear();
_initDefaultTabStops = false;
return true;
}
void TerminalDispatch::_ResetTabStops() noexcept
void TerminalDispatch::_ResetTabStops()
{
_tabStopColumns.clear();
_initDefaultTabStops = true;
@@ -663,7 +647,7 @@ void TerminalDispatch::_InitTabStopsForWidth(const size_t width)
}
}
bool TerminalDispatch::SoftReset() noexcept
bool TerminalDispatch::SoftReset()
{
// TODO:GH#1883 much of this method is not yet implemented in the Terminal,
// because the Terminal _doesn't need to_ yet. The terminal is only ever
@@ -675,23 +659,23 @@ bool TerminalDispatch::SoftReset() noexcept
// This code is left here (from its original form in conhost) as a reminder
// of what needs to be done.
bool success = CursorVisibility(true); // Cursor enabled.
// success = SetOriginMode(false) && success; // Absolute cursor addressing.
// success = SetAutoWrapMode(true) && success; // Wrap at end of line.
success = SetCursorKeysMode(false) && success; // Normal characters.
success = SetKeypadMode(false) && success; // Numeric characters.
CursorVisibility(true); // Cursor enabled.
// SetOriginMode(false); // Absolute cursor addressing.
// SetAutoWrapMode(true); // Wrap at end of line.
SetCursorKeysMode(false); // Normal characters.
SetKeypadMode(false); // Numeric characters.
// // Top margin = 1; bottom margin = page length.
// success = _DoSetTopBottomScrollingMargins(0, 0) && success;
// _DoSetTopBottomScrollingMargins(0, 0);
// _termOutput = {}; // Reset all character set designations.
// if (_initialCodePage.has_value())
// {
// // Restore initial code page if previously changed by a DOCS sequence.
// success = _pConApi->SetConsoleOutputCP(_initialCodePage.value()) && success;
// _pConApi->SetConsoleOutputCP(_initialCodePage.value());
// }
success = SetGraphicsRendition({}) && success; // Normal rendition.
SetGraphicsRendition({}); // Normal rendition.
// // Reset the saved cursor state.
// // Note that XTerm only resets the main buffer state, but that
@@ -699,10 +683,10 @@ bool TerminalDispatch::SoftReset() noexcept
// _savedCursorState.at(0) = {}; // Main buffer
// _savedCursorState.at(1) = {}; // Alt buffer
return success;
return true;
}
bool TerminalDispatch::HardReset() noexcept
bool TerminalDispatch::HardReset()
{
// TODO:GH#1883 much of this method is not yet implemented in the Terminal,
// because the Terminal _doesn't need to_ yet. The terminal is only ever
@@ -713,35 +697,33 @@ bool TerminalDispatch::HardReset() noexcept
// This code is left here (from its original form in conhost) as a reminder
// of what needs to be done.
bool success = true;
// // If in the alt buffer, switch back to main before doing anything else.
// if (_usingAltBuffer)
// {
// success = _pConApi->PrivateUseMainScreenBuffer();
// _usingAltBuffer = !success;
// _pConApi->PrivateUseMainScreenBuffer();
// _usingAltBuffer = false;
// }
// Sets the SGR state to normal - this must be done before EraseInDisplay
// to ensure that it clears with the default background color.
success = SoftReset() && success;
SoftReset();
// Clears the screen - Needs to be done in two operations.
success = EraseInDisplay(DispatchTypes::EraseType::All) && success;
success = EraseInDisplay(DispatchTypes::EraseType::Scrollback) && success;
EraseInDisplay(DispatchTypes::EraseType::All);
EraseInDisplay(DispatchTypes::EraseType::Scrollback);
// Set the DECSCNM screen mode back to normal.
success = SetScreenMode(false) && success;
SetScreenMode(false);
// Cursor to 1,1 - the Soft Reset guarantees this is absolute
success = CursorPosition(1, 1) && success;
CursorPosition(1, 1);
// Reset the mouse mode
success = EnableSGRExtendedMouseMode(false) && success;
success = EnableAnyEventMouseMode(false) && success;
EnableSGRExtendedMouseMode(false);
EnableAnyEventMouseMode(false);
// Delete all current tab stops and reapply
_ResetTabStops();
return success;
return true;
}

View File

@@ -12,74 +12,74 @@ class TerminalDispatch : public Microsoft::Console::VirtualTerminal::TermDispatc
public:
TerminalDispatch(::Microsoft::Terminal::Core::ITerminalApi& terminalApi) noexcept;
void Execute(const wchar_t wchControl) noexcept override;
void Print(const wchar_t wchPrintable) noexcept override;
void PrintString(const std::wstring_view string) noexcept override;
void Execute(const wchar_t wchControl) override;
void Print(const wchar_t wchPrintable) override;
void PrintString(const std::wstring_view string) override;
bool SetGraphicsRendition(const ::Microsoft::Console::VirtualTerminal::VTParameters options) noexcept override;
bool SetGraphicsRendition(const ::Microsoft::Console::VirtualTerminal::VTParameters options) override;
bool PushGraphicsRendition(const ::Microsoft::Console::VirtualTerminal::VTParameters options) noexcept override;
bool PopGraphicsRendition() noexcept override;
bool PushGraphicsRendition(const ::Microsoft::Console::VirtualTerminal::VTParameters options) override;
bool PopGraphicsRendition() override;
bool CursorPosition(const size_t line,
const size_t column) noexcept override; // CUP
const size_t column) override; // CUP
bool EnableWin32InputMode(const bool win32InputMode) noexcept override; // win32-input-mode
bool EnableWin32InputMode(const bool win32InputMode) override; // win32-input-mode
bool CursorVisibility(const bool isVisible) noexcept override; // DECTCEM
bool EnableCursorBlinking(const bool enable) noexcept override; // ATT610
bool CursorVisibility(const bool isVisible) override; // DECTCEM
bool EnableCursorBlinking(const bool enable) override; // ATT610
bool CursorForward(const size_t distance) noexcept override;
bool CursorBackward(const size_t distance) noexcept override;
bool CursorUp(const size_t distance) noexcept override;
bool CursorForward(const size_t distance) override;
bool CursorBackward(const size_t distance) override;
bool CursorUp(const size_t distance) override;
bool LineFeed(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::LineFeedType lineFeedType) noexcept override;
bool LineFeed(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::LineFeedType lineFeedType) override;
bool EraseCharacters(const size_t numChars) noexcept override;
bool WarningBell() noexcept override;
bool CarriageReturn() noexcept override;
bool SetWindowTitle(std::wstring_view title) noexcept override;
bool EraseCharacters(const size_t numChars) override;
bool WarningBell() override;
bool CarriageReturn() override;
bool SetWindowTitle(std::wstring_view title) override;
bool HorizontalTabSet() noexcept override; // HTS
bool ForwardTab(const size_t numTabs) noexcept override; // CHT, HT
bool BackwardsTab(const size_t numTabs) noexcept override; // CBT
bool TabClear(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::TabClearType clearType) noexcept override; // TBC
bool HorizontalTabSet() override; // HTS
bool ForwardTab(const size_t numTabs) override; // CHT, HT
bool BackwardsTab(const size_t numTabs) override; // CBT
bool TabClear(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::TabClearType clearType) override; // TBC
bool SetColorTableEntry(const size_t tableIndex, const DWORD color) noexcept override;
bool SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle) noexcept override;
bool SetCursorColor(const DWORD color) noexcept override;
bool SetColorTableEntry(const size_t tableIndex, const DWORD color) override;
bool SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle) override;
bool SetCursorColor(const DWORD color) override;
bool SetClipboard(std::wstring_view content) noexcept override;
bool SetClipboard(std::wstring_view content) override;
bool SetDefaultForeground(const DWORD color) noexcept override;
bool SetDefaultBackground(const DWORD color) noexcept override;
bool EraseInLine(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) noexcept override; // ED
bool DeleteCharacter(const size_t count) noexcept override;
bool InsertCharacter(const size_t count) noexcept override;
bool EraseInDisplay(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) noexcept override;
bool SetDefaultForeground(const DWORD color) override;
bool SetDefaultBackground(const DWORD color) override;
bool EraseInLine(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) override; // ED
bool DeleteCharacter(const size_t count) override;
bool InsertCharacter(const size_t count) override;
bool EraseInDisplay(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) override;
bool SetCursorKeysMode(const bool applicationMode) noexcept override; // DECCKM
bool SetKeypadMode(const bool applicationMode) noexcept override; // DECKPAM, DECKPNM
bool SetScreenMode(const bool reverseMode) noexcept override; // DECSCNM
bool SetCursorKeysMode(const bool applicationMode) override; // DECCKM
bool SetKeypadMode(const bool applicationMode) override; // DECKPAM, DECKPNM
bool SetScreenMode(const bool reverseMode) override; // DECSCNM
bool SoftReset() noexcept override; // DECSTR
bool HardReset() noexcept override; // RIS
bool SoftReset() override; // DECSTR
bool HardReset() override; // RIS
bool EnableVT200MouseMode(const bool enabled) noexcept override; // ?1000
bool EnableUTF8ExtendedMouseMode(const bool enabled) noexcept override; // ?1005
bool EnableSGRExtendedMouseMode(const bool enabled) noexcept override; // ?1006
bool EnableButtonEventMouseMode(const bool enabled) noexcept override; // ?1002
bool EnableAnyEventMouseMode(const bool enabled) noexcept override; // ?1003
bool EnableAlternateScroll(const bool enabled) noexcept override; // ?1007
bool EnableXtermBracketedPasteMode(const bool enabled) noexcept override; // ?2004
bool EnableVT200MouseMode(const bool enabled) override; // ?1000
bool EnableUTF8ExtendedMouseMode(const bool enabled) override; // ?1005
bool EnableSGRExtendedMouseMode(const bool enabled) override; // ?1006
bool EnableButtonEventMouseMode(const bool enabled) override; // ?1002
bool EnableAnyEventMouseMode(const bool enabled) override; // ?1003
bool EnableAlternateScroll(const bool enabled) override; // ?1007
bool EnableXtermBracketedPasteMode(const bool enabled) override; // ?2004
bool SetMode(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::ModeParams /*param*/) noexcept override; // DECSET
bool ResetMode(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::ModeParams /*param*/) noexcept override; // DECRST
bool SetMode(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::ModeParams /*param*/) override; // DECSET
bool ResetMode(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::ModeParams /*param*/) override; // DECRST
bool AddHyperlink(const std::wstring_view uri, const std::wstring_view params) noexcept override;
bool EndHyperlink() noexcept override;
bool AddHyperlink(const std::wstring_view uri, const std::wstring_view params) override;
bool EndHyperlink() override;
bool DoConEmuAction(const std::wstring_view string) noexcept override;
bool DoConEmuAction(const std::wstring_view string) override;
private:
::Microsoft::Terminal::Core::ITerminalApi& _terminalApi;
@@ -89,12 +89,12 @@ private:
size_t _SetRgbColorsHelper(const ::Microsoft::Console::VirtualTerminal::VTParameters options,
TextAttribute& attr,
const bool isForeground) noexcept;
const bool isForeground);
bool _ModeParamsHelper(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::ModeParams param, const bool enable) noexcept;
bool _ModeParamsHelper(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::ModeParams param, const bool enable);
bool _ClearSingleTabStop() noexcept;
bool _ClearAllTabStops() noexcept;
void _ResetTabStops() noexcept;
void _ClearSingleTabStop();
void _ClearAllTabStops();
void _ResetTabStops();
void _InitTabStopsForWidth(const size_t width);
};

View File

@@ -20,7 +20,7 @@ using namespace Microsoft::Console::VirtualTerminal::DispatchTypes;
// - The number of options consumed, not including the initial 38/48.
size_t TerminalDispatch::_SetRgbColorsHelper(const VTParameters options,
TextAttribute& attr,
const bool isForeground) noexcept
const bool isForeground)
{
size_t optionsConsumed = 1;
const DispatchTypes::GraphicsOptions typeOpt = options.at(0);
@@ -67,7 +67,7 @@ size_t TerminalDispatch::_SetRgbColorsHelper(const VTParameters options,
// one at a time by setting or removing flags in the font style properties.
// Return Value:
// - True if handled successfully. False otherwise.
bool TerminalDispatch::SetGraphicsRendition(const VTParameters options) noexcept
bool TerminalDispatch::SetGraphicsRendition(const VTParameters options)
{
TextAttribute attr = _terminalApi.GetTextAttributes();
@@ -254,12 +254,14 @@ bool TerminalDispatch::SetGraphicsRendition(const VTParameters options) noexcept
return true;
}
bool TerminalDispatch::PushGraphicsRendition(const VTParameters options) noexcept
bool TerminalDispatch::PushGraphicsRendition(const VTParameters options)
{
return _terminalApi.PushGraphicsRendition(options);
_terminalApi.PushGraphicsRendition(options);
return true;
}
bool TerminalDispatch::PopGraphicsRendition() noexcept
bool TerminalDispatch::PopGraphicsRendition()
{
return _terminalApi.PopGraphicsRendition();
_terminalApi.PopGraphicsRendition();
return true;
}

View File

@@ -375,29 +375,30 @@
</Page.Resources>
<ScrollViewer ViewChanging="ViewChanging">
<StackPanel MaxWidth="600"
HorizontalAlignment="Left"
Spacing="8"
Style="{StaticResource SettingsStackStyle}">
<!-- Add New Button -->
<Button x:Name="AddNewButton"
Click="AddNew_Click">
<Button.Content>
<StackPanel Orientation="Horizontal">
<FontIcon FontSize="{StaticResource StandardIconSize}"
Glyph="&#xE710;" />
<TextBlock x:Uid="Actions_AddNewTextBlock"
Style="{StaticResource IconButtonTextBlockStyle}" />
</StackPanel>
</Button.Content>
</Button>
<!-- Keybindings -->
<ListView x:Name="KeyBindingsListView"
ItemTemplate="{StaticResource KeyBindingTemplate}"
ItemsSource="{x:Bind KeyBindingList, Mode=OneWay}"
SelectionMode="None" />
</StackPanel>
<Border MaxWidth="{StaticResource StandardControlMaxWidth}">
<StackPanel MaxWidth="600"
HorizontalAlignment="Left"
Spacing="8"
Style="{StaticResource SettingsStackStyle}">
<!-- Add New Button -->
<Button x:Name="AddNewButton"
Click="AddNew_Click">
<Button.Content>
<StackPanel Orientation="Horizontal">
<FontIcon FontSize="{StaticResource StandardIconSize}"
Glyph="&#xE710;" />
<TextBlock x:Uid="Actions_AddNewTextBlock"
Style="{StaticResource IconButtonTextBlockStyle}" />
</StackPanel>
</Button.Content>
</Button>
<!-- Keybindings -->
<ListView x:Name="KeyBindingsListView"
ItemTemplate="{StaticResource KeyBindingTemplate}"
ItemsSource="{x:Bind KeyBindingList, Mode=OneWay}"
SelectionMode="None" />
</StackPanel>
</Border>
</ScrollViewer>
</Page>

View File

@@ -7,9 +7,12 @@
#include "AddProfilePageNavigationState.g.cpp"
#include "EnumEntry.h"
#include <LibraryResources.h>
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::System;
using namespace winrt::Windows::UI::Core;
using namespace winrt::Windows::UI::Xaml;
using namespace winrt::Windows::UI::Xaml::Navigation;
using namespace winrt::Microsoft::Terminal::Settings::Model;
@@ -18,6 +21,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
AddProfile::AddProfile()
{
InitializeComponent();
Automation::AutomationProperties::SetName(AddNewButton(), RS_(L"AddProfile_AddNewTextBlock/Text"));
Automation::AutomationProperties::SetName(DuplicateButton(), RS_(L"AddProfile_DuplicateTextBlock/Text"));
}
void AddProfile::OnNavigatedTo(const NavigationEventArgs& e)

View File

@@ -23,27 +23,29 @@
<ScrollViewer ViewChanging="ViewChanging">
<StackPanel Style="{StaticResource SettingsStackStyle}">
<Button x:Uid="AddProfile_AddNewButton"
AutomationProperties.AutomationId="AddProfile_AddNewButton"
AutomationProperties.Name="{Binding Tag, RelativeSource={RelativeSource Self}}"
Click="AddNewClick"
Style="{StaticResource AccentButtonStyle}">
<Button.Content>
<StackPanel Orientation="Horizontal">
<FontIcon FontSize="{StaticResource StandardIconSize}"
Glyph="&#xE710;" />
<TextBlock x:Uid="AddProfile_AddNewTextBlock"
Style="{StaticResource IconButtonTextBlockStyle}" />
</StackPanel>
</Button.Content>
</Button>
<Border MaxWidth="{StaticResource StandardControlMaxWidth}">
<Button x:Name="AddNewButton"
Click="AddNewClick"
Style="{StaticResource AccentButtonStyle}">
<Button.Content>
<StackPanel Orientation="Horizontal">
<FontIcon FontSize="{StaticResource StandardIconSize}"
Glyph="&#xE710;" />
<TextBlock x:Uid="AddProfile_AddNewTextBlock"
Style="{StaticResource IconButtonTextBlockStyle}" />
</StackPanel>
</Button.Content>
</Button>
</Border>
<StackPanel Margin="{StaticResource StandardControlMargin}">
<local:SettingContainer x:Uid="AddProfile_Duplicate">
<muxc:RadioButtons x:Name="Profiles"
AutomationProperties.AccessibilityView="Content"
ItemsSource="{x:Bind State.Settings.AllProfiles, Mode=OneWay}"
SelectionChanged="ProfilesSelectionChanged">
<muxc:RadioButtons.ItemTemplate>
<ComboBox x:Name="Profiles"
AutomationProperties.AccessibilityView="Content"
ItemsSource="{x:Bind State.Settings.AllProfiles, Mode=OneWay}"
SelectedIndex="0"
SelectionChanged="ProfilesSelectionChanged"
Style="{StaticResource ComboBoxSettingStyle}">
<ComboBox.ItemTemplate>
<DataTemplate x:DataType="model:Profile">
<Grid HorizontalAlignment="Stretch"
ColumnSpacing="8">
@@ -65,25 +67,25 @@
</Grid>
</DataTemplate>
</muxc:RadioButtons.ItemTemplate>
</muxc:RadioButtons>
</ComboBox.ItemTemplate>
</ComboBox>
</local:SettingContainer>
<Button x:Uid="AddProfile_DuplicateButton"
Margin="{StaticResource StandardControlMargin}"
AutomationProperties.AutomationId="AddProfile_DuplicateButton"
AutomationProperties.Name="{Binding Tag, RelativeSource={RelativeSource Self}}"
Click="DuplicateClick"
IsEnabled="{x:Bind IsProfileSelected, Mode=OneWay}"
Style="{StaticResource AccentButtonStyle}">
<Button.Content>
<StackPanel Orientation="Horizontal">
<FontIcon FontSize="{StaticResource StandardIconSize}"
Glyph="&#xE8C8;" />
<TextBlock x:Uid="AddProfile_DuplicateTextBlock"
Style="{StaticResource IconButtonTextBlockStyle}" />
</StackPanel>
</Button.Content>
</Button>
<Border MaxWidth="{StaticResource StandardControlMaxWidth}">
<Button x:Name="DuplicateButton"
Margin="{StaticResource StandardControlMargin}"
Click="DuplicateClick"
IsEnabled="{x:Bind IsProfileSelected, Mode=OneWay}"
Style="{StaticResource AccentButtonStyle}">
<Button.Content>
<StackPanel Orientation="Horizontal">
<FontIcon FontSize="{StaticResource StandardIconSize}"
Glyph="&#xE8C8;" />
<TextBlock x:Uid="AddProfile_DuplicateTextBlock"
Style="{StaticResource IconButtonTextBlockStyle}" />
</StackPanel>
</Button.Content>
</Button>
</Border>
</StackPanel>
</StackPanel>
</ScrollViewer>

View File

@@ -41,7 +41,7 @@
<StackPanel Style="{StaticResource PivotStackStyle}">
<!-- Grouping: Text -->
<TextBlock x:Uid="Profile_TextHeader"
Style="{StaticResource SubtitleTextBlockStyle}" />
Style="{StaticResource TextBlockSubHeaderStyle}" />
<!-- Color Scheme -->
<local:SettingContainer x:Uid="Profile_ColorScheme"
@@ -170,7 +170,7 @@
<!-- Grouping: Cursor -->
<StackPanel Style="{StaticResource PivotStackStyle}">
<TextBlock x:Uid="Profile_CursorHeader"
Style="{StaticResource SubtitleTextBlockStyle}" />
Style="{StaticResource TextBlockSubHeaderStyle}" />
<!-- Cursor Shape -->
<local:SettingContainer x:Uid="Profile_CursorShape"
@@ -210,7 +210,7 @@
<!-- Grouping: Background -->
<StackPanel Style="{StaticResource PivotStackStyle}">
<TextBlock x:Uid="Profile_BackgroundHeader"
Style="{StaticResource SubtitleTextBlockStyle}" />
Style="{StaticResource TextBlockSubHeaderStyle}" />
<!-- Background Image -->
<local:SettingContainer x:Name="BackgroundImageContainer"
@@ -292,7 +292,7 @@
<x:Int32>17</x:Int32>
</ToggleButton.Tag>
<ToggleButton.Content>
<FontIcon FontFamily="Segoe Fluent Icons"
<FontIcon FontFamily="{ThemeResource SymbolThemeFontFamily}"
Glyph="&#xE744;"
RenderTransformOrigin="0.5,0.5">
<FontIcon.RenderTransform>
@@ -312,7 +312,7 @@
<x:Int32>16</x:Int32>
</ToggleButton.Tag>
<ToggleButton.Content>
<FontIcon FontFamily="Segoe Fluent Icons"
<FontIcon FontFamily="{ThemeResource SymbolThemeFontFamily}"
Glyph="&#xE745;"
RenderTransformOrigin="0.5,0.5">
<FontIcon.RenderTransform>
@@ -332,7 +332,7 @@
<x:Int32>18</x:Int32>
</ToggleButton.Tag>
<ToggleButton.Content>
<FontIcon FontFamily="Segoe Fluent Icons"
<FontIcon FontFamily="{ThemeResource SymbolThemeFontFamily}"
Glyph="&#xEA5F;"
RenderTransformOrigin="0.5,0.5">
<FontIcon.RenderTransform>
@@ -354,7 +354,7 @@
<x:Int32>1</x:Int32>
</ToggleButton.Tag>
<ToggleButton.Content>
<FontIcon FontFamily="Segoe Fluent Icons"
<FontIcon FontFamily="{ThemeResource SymbolThemeFontFamily}"
Glyph="&#xE746;" />
</ToggleButton.Content>
</ToggleButton>
@@ -369,7 +369,7 @@
<x:Int32>0</x:Int32>
</ToggleButton.Tag>
<ToggleButton.Content>
<FontIcon FontFamily="Segoe Fluent Icons"
<FontIcon FontFamily="{ThemeResource SymbolThemeFontFamily}"
Glyph="&#xF16E;" />
</ToggleButton.Content>
</ToggleButton>
@@ -384,7 +384,7 @@
<x:Int32>2</x:Int32>
</ToggleButton.Tag>
<ToggleButton.Content>
<FontIcon FontFamily="Segoe Fluent Icons"
<FontIcon FontFamily="{ThemeResource SymbolThemeFontFamily}"
Glyph="&#xEA61;" />
</ToggleButton.Content>
</ToggleButton>
@@ -401,7 +401,7 @@
<x:Int32>33</x:Int32>
</ToggleButton.Tag>
<ToggleButton.Content>
<FontIcon FontFamily="Segoe Fluent Icons"
<FontIcon FontFamily="{ThemeResource SymbolThemeFontFamily}"
Glyph="&#xE744;" />
</ToggleButton.Content>
</ToggleButton>
@@ -416,7 +416,7 @@
<x:Int32>32</x:Int32>
</ToggleButton.Tag>
<ToggleButton.Content>
<FontIcon FontFamily="Segoe Fluent Icons"
<FontIcon FontFamily="{ThemeResource SymbolThemeFontFamily}"
Glyph="&#xE745;" />
</ToggleButton.Content>
</ToggleButton>
@@ -431,7 +431,7 @@
<x:Int32>34</x:Int32>
</ToggleButton.Tag>
<ToggleButton.Content>
<FontIcon FontFamily="Segoe Fluent Icons"
<FontIcon FontFamily="{ThemeResource SymbolThemeFontFamily}"
Glyph="&#xEA5F;" />
</ToggleButton.Content>
</ToggleButton>
@@ -464,7 +464,7 @@
<!-- Grouping: Text Formatting -->
<StackPanel Style="{StaticResource PivotStackStyle}">
<TextBlock x:Uid="Appearance_TextFormattingHeader"
Style="{StaticResource SubtitleTextBlockStyle}" />
Style="{StaticResource TextBlockSubHeaderStyle}" />
<!-- Intense is bold, bright -->
<local:SettingContainer x:Uid="Appearance_IntenseTextStyle"

View File

@@ -94,11 +94,13 @@
</Page.Resources>
<ScrollViewer ViewChanging="ViewChanging">
<StackPanel Margin="{StaticResource StandardIndentMargin}"
<StackPanel MaxWidth="{StaticResource StandardControlMaxWidth}"
Margin="{StaticResource StandardIndentMargin}"
Spacing="24">
<!-- Select Color and Add New Button -->
<StackPanel Orientation="Horizontal">
<StackPanel Margin="0,5,0,0"
Orientation="Horizontal">
<StackPanel Orientation="Horizontal"
Visibility="{x:Bind local:Converters.InvertedBooleanToVisibility(IsRenaming), Mode=OneWay}">

View File

@@ -15,6 +15,7 @@
<Thickness x:Key="StandardIndentMargin">13,0,0,0</Thickness>
<Thickness x:Key="StandardControlMargin">0,24,0,0</Thickness>
<x:Double x:Key="StandardBoxMinWidth">250</x:Double>
<x:Double x:Key="StandardControlMaxWidth">1000</x:Double>
<!--
This is for styling the entire items control used on the
@@ -48,16 +49,24 @@
<Style x:Key="TextBoxSettingStyle"
BasedOn="{StaticResource DefaultTextBoxStyle}"
TargetType="TextBox">
<Setter Property="Width" Value="{StaticResource StandardBoxMinWidth}" />
<Setter Property="MinWidth" Value="{StaticResource StandardBoxMinWidth}" />
<Setter Property="MaxWidth" Value="500" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="TextWrapping" Value="Wrap" />
</Style>
<Style x:Key="TextBlockSubHeaderStyle"
BasedOn="{StaticResource SubtitleTextBlockStyle}"
TargetType="TextBlock">
<Setter Property="MaxWidth" Value="{StaticResource StandardControlMaxWidth}" />
</Style>
<!-- Used for disclaimers -->
<Style x:Key="DisclaimerStyle"
TargetType="TextBlock">
<Setter Property="FontStyle" Value="Italic" />
<Setter Property="TextWrapping" Value="WrapWholeWords" />
<Setter Property="MaxWidth" Value="1000" />
</Style>
<!-- Used for flyout messages -->
@@ -71,7 +80,7 @@
<!-- Number Box -->
<Style x:Key="NumberBoxSettingStyle"
TargetType="muxc:NumberBox">
<Setter Property="SpinButtonPlacementMode" Value="Compact" />
<Setter Property="SpinButtonPlacementMode" Value="Inline" />
<Setter Property="HorizontalAlignment" Value="Left" />
</Style>
@@ -159,7 +168,8 @@
<Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}" />
<Setter Property="MinWidth" Value="{StaticResource ToggleSwitchThemeMinWidth}" />
<Setter Property="FocusVisualMargin" Value="-7,-3,-7,-3" />
<Setter Property="Margin" Value="0,0,-80,0" />
<Setter Property="Margin" Value="0,0,10,0" />
<Setter Property="MinWidth" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleSwitch">

View File

@@ -24,6 +24,23 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
// --> "und" is synonymous for "Use system language".
constexpr std::wstring_view systemLanguageTag{ L"und" };
static constexpr std::array appLanguageTags{
L"en-US",
L"de-DE",
L"es-ES",
L"fr-FR",
L"it-IT",
L"ja",
L"ko",
L"pt-BR",
L"qps-PLOC",
L"qps-PLOCA",
L"qps-PLOCM",
L"ru",
L"zh-Hans-CN",
L"zh-Hant-TW",
};
GlobalAppearance::GlobalAppearance()
{
InitializeComponent();
@@ -88,43 +105,22 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
// [1]:
{
// ManifestLanguages contains languages the app ships with.
//
// Languages is a computed list that merges the ManifestLanguages with the
// user's ranked list of preferred languages taken from the system settings.
// As is tradition the API documentation is incomplete though, as it can also
// contain regional language variants. If our app supports en-US, but the user
// has en-GB or en-DE in their system's preferred language list, Languages will
// contain those as well, as they're variants from a supported language. We should
// allow a user to select those, as regional formattings can vary significantly.
const std::array tagSources{
winrt::Windows::Globalization::ApplicationLanguages::ManifestLanguages(),
winrt::Windows::Globalization::ApplicationLanguages::Languages()
};
// tags will hold all the flattened results from tagSources.
// We resize() the vector to the proper size in order to efficiently GetMany() all items.
tags.resize(std::accumulate(
tagSources.begin(),
tagSources.end(),
// tags[0] will be "und" - the "Use system language" item
// tags[1..n] will contain tags from tagSources.
// --> totalTags is offset by 1
1,
[](uint32_t sum, const auto& v) -> uint32_t {
return sum + v.Size();
}));
// Unfortunately, we cannot use this source. Our manifest must contain the
// ~100 languages that are localized for the shell extension and start menu
// presentation so we align with Windows display languages for those surfaces.
// However, the actual content of our application is limited to a much smaller
// subset of approximately 14 languages. As such, we will code the limited
// subset of languages that we support for selection within the Settings
// dropdown to steer users towards the ones that we can display in the app.
// As per the function definition, the first item
// is always "Use system language" ("und").
auto data = tags.data();
*data++ = systemLanguageTag;
tags.emplace_back(systemLanguageTag);
// Finally GetMany() all the tags from tagSources.
for (const auto& v : tagSources)
// Add our hardcoded languages after the system definition.
for (const auto& v : appLanguageTags)
{
const auto size = v.Size();
v.GetMany(0, winrt::array_view(data, size));
data += size;
tags.push_back(v);
}
}

View File

@@ -73,9 +73,4 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
return winrt::single_threaded_observable_vector(std::move(profiles));
}
bool Launch::ShowFirstWindowPreference() const noexcept
{
return Feature_PersistedWindowLayout::IsEnabled();
}
}

View File

@@ -29,8 +29,6 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
void CurrentDefaultProfile(const IInspectable& value);
winrt::Windows::Foundation::Collections::IObservableVector<IInspectable> DefaultProfiles() const;
bool ShowFirstWindowPreference() const noexcept;
WINRT_PROPERTY(Editor::LaunchPageNavigationState, State, nullptr);
GETSET_BINDABLE_ENUM_SETTING(FirstWindowPreference, Model::FirstWindowPreference, State().Settings().GlobalSettings().FirstWindowPreference);

View File

@@ -20,9 +20,6 @@ namespace Microsoft.Terminal.Settings.Editor
// https://github.com/microsoft/microsoft-ui-xaml/issues/5395
IObservableVector<IInspectable> DefaultProfiles { get; };
Boolean ShowFirstWindowPreference { get; };
IInspectable CurrentFirstWindowPreference;
IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> FirstWindowPreferenceList { get; };

View File

@@ -138,8 +138,7 @@
<!-- First Window Behavior -->
<local:SettingContainer x:Uid="Globals_FirstWindowPreference"
Style="{StaticResource ExpanderSettingContainerStyle}"
Visibility="{x:Bind ShowFirstWindowPreference}">
Style="{StaticResource ExpanderSettingContainerStyle}">
<muxc:RadioButtons AutomationProperties.AccessibilityView="Content"
ItemTemplate="{StaticResource EnumRadioButtonTemplate}"
ItemsSource="{x:Bind FirstWindowPreferenceList}"

View File

@@ -410,11 +410,12 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
// - NOTE: this does not update the selected item.
// Arguments:
// - profile - the profile object we are getting a view of
void MainPage::_Navigate(const Editor::ProfileViewModel& profile, BreadcrumbSubPage subPage)
void MainPage::_Navigate(const Editor::ProfileViewModel& profile, BreadcrumbSubPage subPage, const bool focusDeleteButton)
{
auto state{ winrt::make<ProfilePageNavigationState>(profile,
_settingsClone.GlobalSettings().ColorSchemes(),
*this) };
state.FocusDeleteButton(focusDeleteButton);
_PreNavigateHelper();
@@ -476,15 +477,18 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
void MainPage::BreadcrumbBar_ItemClicked(Microsoft::UI::Xaml::Controls::BreadcrumbBar const& /*sender*/, Microsoft::UI::Xaml::Controls::BreadcrumbBarItemClickedEventArgs const& args)
{
const auto tag = args.Item().as<Breadcrumb>()->Tag();
const auto subPage = args.Item().as<Breadcrumb>()->SubPage();
if (const auto profileViewModel = tag.try_as<ProfileViewModel>())
if (gsl::narrow_cast<uint32_t>(args.Index()) < (_breadcrumbs.Size() - 1))
{
_Navigate(*profileViewModel, subPage);
}
else
{
_Navigate(tag.as<hstring>(), subPage);
const auto tag = args.Item().as<Breadcrumb>()->Tag();
const auto subPage = args.Item().as<Breadcrumb>()->SubPage();
if (const auto profileViewModel = tag.try_as<ProfileViewModel>())
{
_Navigate(*profileViewModel, subPage);
}
else
{
_Navigate(tag.as<hstring>(), subPage);
}
}
}
@@ -587,7 +591,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
// navigate to the profile next to this one
const auto newSelectedItem{ menuItems.GetAt(index < menuItems.Size() - 1 ? index : index - 1) };
SettingsNav().SelectedItem(newSelectedItem);
_Navigate(newSelectedItem.try_as<MUX::Controls::NavigationViewItem>().Tag().try_as<Editor::ProfileViewModel>(), BreadcrumbSubPage::None);
_Navigate(newSelectedItem.try_as<MUX::Controls::NavigationViewItem>().Tag().try_as<Editor::ProfileViewModel>(), BreadcrumbSubPage::None, true);
}
IObservableVector<IInspectable> MainPage::Breadcrumbs() noexcept

View File

@@ -61,7 +61,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
void _PreNavigateHelper();
void _Navigate(hstring clickedItemTag, BreadcrumbSubPage subPage);
void _Navigate(const Editor::ProfileViewModel& profile, BreadcrumbSubPage subPage);
void _Navigate(const Editor::ProfileViewModel& profile, BreadcrumbSubPage subPage, const bool focusDeleteButton = false);
winrt::Microsoft::Terminal::Settings::Editor::ColorSchemesPageNavigationState _colorSchemesNavState{ nullptr };

View File

@@ -42,9 +42,14 @@
ItemInvoked="SettingsNav_ItemInvoked"
Loaded="SettingsNav_Loaded"
TabFocusNavigation="Cycle">
<muxc:NavigationView.Resources>
<ResourceDictionary>
<Thickness x:Key="NavigationViewHeaderMargin">15,0,0,0</Thickness>
</ResourceDictionary>
</muxc:NavigationView.Resources>
<muxc:NavigationView.Header>
<muxc:BreadcrumbBar x:Name="NavigationBreadcrumbBar"
Margin="-40,-40,0,16"
MaxWidth="{StaticResource StandardControlMaxWidth}"
ItemClicked="BreadcrumbBar_ItemClicked"
ItemsSource="{x:Bind Breadcrumbs}">
<muxc:BreadcrumbBar.ItemTemplate>
@@ -131,7 +136,7 @@
</muxc:NavigationViewItem>
</muxc:NavigationView.FooterMenuItems>
<Grid Margin="0,-30,0,0">
<Grid Margin="0,0,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />

View File

@@ -345,12 +345,12 @@
</ItemDefinitionGroup>
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets')" />
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.7.0-prerelease.210913003\build\native\Microsoft.UI.Xaml.targets'))" />
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.$(TerminalMUXVersion)\build\native\Microsoft.UI.Xaml.targets'))" />
</Target>
<Import Project="$(SolutionDir)build\rules\CollectWildcardResources.targets" />
</Project>

View File

@@ -7,55 +7,8 @@
#include "EnumEntry.h"
#include <LibraryResources.h>
#include "..\WinRTUtils\inc\Utils.h"
// This function is a copy of DxFontInfo::_NearbyCollection() with
// * the call to DxFontInfo::s_GetNearbyFonts() inlined
// * checkForUpdates for GetSystemFontCollection() set to true
static wil::com_ptr<IDWriteFontCollection1> NearbyCollection(IDWriteFactory* dwriteFactory)
{
// The convenience interfaces for loading fonts from files
// are only available on Windows 10+.
wil::com_ptr<IDWriteFactory6> factory6;
// wil's query() facilities don't work inside WinRT land at the moment.
// They produce a compilation error due to IUnknown and winrt::Windows::Foundation::IUnknown being ambiguous.
if (!SUCCEEDED(dwriteFactory->QueryInterface(__uuidof(IDWriteFactory6), factory6.put_void())))
{
return nullptr;
}
wil::com_ptr<IDWriteFontCollection1> systemFontCollection;
THROW_IF_FAILED(factory6->GetSystemFontCollection(false, systemFontCollection.addressof(), true));
wil::com_ptr<IDWriteFontSet> systemFontSet;
THROW_IF_FAILED(systemFontCollection->GetFontSet(systemFontSet.addressof()));
wil::com_ptr<IDWriteFontSetBuilder2> fontSetBuilder2;
THROW_IF_FAILED(factory6->CreateFontSetBuilder(fontSetBuilder2.addressof()));
THROW_IF_FAILED(fontSetBuilder2->AddFontSet(systemFontSet.get()));
{
const std::filesystem::path module{ wil::GetModuleFileNameW<std::wstring>(nullptr) };
const auto folder{ module.parent_path() };
for (const auto& p : std::filesystem::directory_iterator(folder))
{
if (til::ends_with(p.path().native(), L".ttf"))
{
fontSetBuilder2->AddFontFile(p.path().c_str());
}
}
}
wil::com_ptr<IDWriteFontSet> fontSet;
THROW_IF_FAILED(fontSetBuilder2->CreateFontSet(fontSet.addressof()));
wil::com_ptr<IDWriteFontCollection1> fontCollection;
THROW_IF_FAILED(factory6->CreateFontCollectionFromFontSet(fontSet.get(), &fontCollection));
return fontCollection;
}
#include "../WinRTUtils/inc/Utils.h"
#include "../../renderer/base/FontCache.h"
using namespace winrt::Windows::UI::Text;
using namespace winrt::Windows::UI::Xaml;
@@ -166,15 +119,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
std::vector<Editor::Font> fontList;
std::vector<Editor::Font> monospaceFontList;
// get a DWriteFactory
com_ptr<IDWriteFactory> factory;
THROW_IF_FAILED(DWriteCreateFactory(
DWRITE_FACTORY_TYPE_SHARED,
__uuidof(IDWriteFactory),
reinterpret_cast<::IUnknown**>(factory.put())));
// get the font collection; subscribe to updates
const auto fontCollection = NearbyCollection(factory.get());
const auto fontCollection = ::Microsoft::Console::Render::FontCache::GetFresh();
for (UINT32 i = 0; i < fontCollection->GetFontFamilyCount(); ++i)
{

View File

@@ -33,5 +33,6 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
}
}
WINRT_PROPERTY(Editor::ProfileViewModel, Profile, nullptr);
WINRT_PROPERTY(bool, FocusDeleteButton, false);
};
};

View File

@@ -9,5 +9,6 @@ namespace Microsoft.Terminal.Settings.Editor
runtimeclass ProfilePageNavigationState
{
ProfileViewModel Profile { get; };
Boolean FocusDeleteButton;
};
}

View File

@@ -45,13 +45,15 @@
ViewChanging="ViewChanging">
<StackPanel Style="{StaticResource SettingsStackStyle}">
<!-- Control Preview -->
<Border x:Name="ControlPreview"
Width="350"
Height="160"
Margin="0,0,0,12"
HorizontalAlignment="Left"
BorderBrush="{ThemeResource SystemControlForegroundBaseMediumLowBrush}"
BorderThickness="1" />
<Border MaxWidth="{StaticResource StandardControlMaxWidth}">
<Border x:Name="ControlPreview"
Width="350"
Height="160"
Margin="0,0,0,12"
HorizontalAlignment="Left"
BorderBrush="{ThemeResource SystemControlForegroundBaseMediumLowBrush}"
BorderThickness="1" />
</Border>
<local:Appearances Appearance="{x:Bind Profile.DefaultAppearance, Mode=OneWay}"
SourceProfile="{x:Bind Profile, Mode=OneWay}" />
@@ -59,7 +61,7 @@
<!-- Grouping: Transparency -->
<StackPanel Style="{StaticResource PivotStackStyle}">
<TextBlock x:Uid="Profile_TransparencyHeader"
Style="{StaticResource SubtitleTextBlockStyle}" />
Style="{StaticResource TextBlockSubHeaderStyle}" />
<!-- Opacity -->
<local:SettingContainer x:Name="OpacityContainer"
@@ -99,7 +101,7 @@
<!-- Grouping: Window -->
<StackPanel Style="{StaticResource PivotStackStyle}">
<TextBlock x:Uid="Profile_WindowHeader"
Style="{StaticResource SubtitleTextBlockStyle}" />
Style="{StaticResource TextBlockSubHeaderStyle}" />
<!-- Padding -->
<local:SettingContainer x:Uid="Profile_Padding"
@@ -133,7 +135,7 @@
SelectedItem="{x:Bind Profile.CurrentScrollState, Mode=TwoWay}" />
</local:SettingContainer>
</StackPanel>
<StackPanel>
<StackPanel MaxWidth="{StaticResource StandardControlMaxWidth}">
<StackPanel Orientation="Horizontal"
Visibility="{x:Bind Profile.EditableUnfocusedAppearance, Mode=OneWay}">
<TextBlock x:Uid="Profile_UnfocusedAppearanceTextBlock"

View File

@@ -37,6 +37,23 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
StartingDirectoryUseParentCheckbox().IsChecked(true);
}
_layoutUpdatedRevoker = LayoutUpdated(winrt::auto_revoke, [state, this](auto /*s*/, auto /*e*/) {
// This event fires every time the layout changes, but it is always the last one to fire
// in any layout change chain. That gives us great flexibility in finding the right point
// at which to initialize our renderer (and our terminal).
// Any earlier than the last layout update and we may not know the terminal's starting size.
// Only let this succeed once.
_layoutUpdatedRevoker.revoke();
if (state.FocusDeleteButton())
{
DeleteButton().Focus(FocusState::Programmatic);
state.FocusDeleteButton(false);
ProfilesBase_ScrollView().ChangeView(nullptr, ProfilesBase_ScrollView().ScrollableHeight(), nullptr);
}
});
}
void Profiles_Base::OnNavigatedFrom(const NavigationEventArgs& /*e*/)

View File

@@ -29,6 +29,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
private:
Windows::UI::Xaml::Data::INotifyPropertyChanged::PropertyChanged_revoker _ViewModelChangedRevoker;
winrt::Windows::UI::Xaml::Controls::SwapChainPanel::LayoutUpdated_revoker _layoutUpdatedRevoker;
};
};

View File

@@ -31,7 +31,8 @@
Margin="{StaticResource StandardIndentMargin}"
Style="{StaticResource DisclaimerStyle}"
Visibility="{x:Bind Profile.IsBaseLayer}" />
<ScrollViewer Grid.Row="1"
<ScrollViewer Name="ProfilesBase_ScrollView"
Grid.Row="1"
ViewChanging="ViewChanging">
<StackPanel Style="{StaticResource SettingsStackStyle}">
@@ -105,7 +106,7 @@
Style="{StaticResource ExpanderSettingContainerStyle}">
<StackPanel Orientation="Horizontal">
<TextBox x:Uid="Profile_IconBox"
FontFamily="Segoe UI, Segoe MDL2 Assets"
FontFamily="Segoe UI, Segoe Fluent Icons, Segoe MDL2 Assets"
IsSpellCheckEnabled="False"
Style="{StaticResource TextBoxSettingStyle}"
Text="{x:Bind Profile.Icon, Mode=TwoWay}" />
@@ -144,7 +145,7 @@
<TextBlock x:Uid="Profile_AdditionalSettingsHeader"
Margin="0,48,0,0"
Style="{StaticResource SubtitleTextBlockStyle}" />
Style="{StaticResource TextBlockSubHeaderStyle}" />
<Button x:Name="AppearanceNavigator"
Click="Appearance_Click"
@@ -159,77 +160,79 @@
Text="Advanced" />
</Button>
<!-- Delete Button -->
<Button x:Name="DeleteButton"
Margin="{StaticResource StandardControlMargin}"
Style="{StaticResource DeleteButtonStyle}"
Visibility="{x:Bind Profile.CanDeleteProfile}">
<Button.Resources>
<ResourceDictionary>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Light">
<SolidColorBrush x:Key="ButtonBackground"
Color="Firebrick" />
<SolidColorBrush x:Key="ButtonBackgroundPointerOver"
Color="#C23232" />
<SolidColorBrush x:Key="ButtonBackgroundPressed"
Color="#A21212" />
<SolidColorBrush x:Key="ButtonForeground"
Color="White" />
<SolidColorBrush x:Key="ButtonForegroundPointerOver"
Color="White" />
<SolidColorBrush x:Key="ButtonForegroundPressed"
Color="White" />
</ResourceDictionary>
<ResourceDictionary x:Key="Dark">
<SolidColorBrush x:Key="ButtonBackground"
Color="Firebrick" />
<SolidColorBrush x:Key="ButtonBackgroundPointerOver"
Color="#C23232" />
<SolidColorBrush x:Key="ButtonBackgroundPressed"
Color="#A21212" />
<SolidColorBrush x:Key="ButtonForeground"
Color="White" />
<SolidColorBrush x:Key="ButtonForegroundPointerOver"
Color="White" />
<SolidColorBrush x:Key="ButtonForegroundPressed"
Color="White" />
</ResourceDictionary>
<ResourceDictionary x:Key="HighContrast">
<SolidColorBrush x:Key="ButtonBackground"
Color="{ThemeResource SystemColorButtonFaceColor}" />
<SolidColorBrush x:Key="ButtonBackgroundPointerOver"
Color="{ThemeResource SystemColorHighlightColor}" />
<SolidColorBrush x:Key="ButtonBackgroundPressed"
Color="{ThemeResource SystemColorHighlightColor}" />
<SolidColorBrush x:Key="ButtonForeground"
Color="{ThemeResource SystemColorButtonTextColor}" />
<SolidColorBrush x:Key="ButtonForegroundPointerOver"
Color="{ThemeResource SystemColorHighlightTextColor}" />
<SolidColorBrush x:Key="ButtonForegroundPressed"
Color="{ThemeResource SystemColorHighlightTextColor}" />
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
</Button.Resources>
<Button.Content>
<StackPanel Orientation="Horizontal">
<FontIcon FontSize="{StaticResource StandardIconSize}"
Glyph="&#xE74D;" />
<TextBlock x:Uid="Profile_DeleteButton"
Margin="10,0,0,0" />
</StackPanel>
</Button.Content>
<Button.Flyout>
<Flyout>
<StackPanel>
<TextBlock x:Uid="Profile_DeleteConfirmationMessage"
Style="{StaticResource CustomFlyoutTextStyle}" />
<Button x:Uid="Profile_DeleteConfirmationButton"
Click="DeleteConfirmation_Click" />
<Border MaxWidth="{StaticResource StandardControlMaxWidth}">
<Button x:Name="DeleteButton"
Margin="{StaticResource StandardControlMargin}"
Style="{StaticResource DeleteButtonStyle}"
Visibility="{x:Bind Profile.CanDeleteProfile}">
<Button.Resources>
<ResourceDictionary>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Light">
<SolidColorBrush x:Key="ButtonBackground"
Color="Firebrick" />
<SolidColorBrush x:Key="ButtonBackgroundPointerOver"
Color="#C23232" />
<SolidColorBrush x:Key="ButtonBackgroundPressed"
Color="#A21212" />
<SolidColorBrush x:Key="ButtonForeground"
Color="White" />
<SolidColorBrush x:Key="ButtonForegroundPointerOver"
Color="White" />
<SolidColorBrush x:Key="ButtonForegroundPressed"
Color="White" />
</ResourceDictionary>
<ResourceDictionary x:Key="Dark">
<SolidColorBrush x:Key="ButtonBackground"
Color="Firebrick" />
<SolidColorBrush x:Key="ButtonBackgroundPointerOver"
Color="#C23232" />
<SolidColorBrush x:Key="ButtonBackgroundPressed"
Color="#A21212" />
<SolidColorBrush x:Key="ButtonForeground"
Color="White" />
<SolidColorBrush x:Key="ButtonForegroundPointerOver"
Color="White" />
<SolidColorBrush x:Key="ButtonForegroundPressed"
Color="White" />
</ResourceDictionary>
<ResourceDictionary x:Key="HighContrast">
<SolidColorBrush x:Key="ButtonBackground"
Color="{ThemeResource SystemColorButtonFaceColor}" />
<SolidColorBrush x:Key="ButtonBackgroundPointerOver"
Color="{ThemeResource SystemColorHighlightColor}" />
<SolidColorBrush x:Key="ButtonBackgroundPressed"
Color="{ThemeResource SystemColorHighlightColor}" />
<SolidColorBrush x:Key="ButtonForeground"
Color="{ThemeResource SystemColorButtonTextColor}" />
<SolidColorBrush x:Key="ButtonForegroundPointerOver"
Color="{ThemeResource SystemColorHighlightTextColor}" />
<SolidColorBrush x:Key="ButtonForegroundPressed"
Color="{ThemeResource SystemColorHighlightTextColor}" />
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
</Button.Resources>
<Button.Content>
<StackPanel Orientation="Horizontal">
<FontIcon FontSize="{StaticResource StandardIconSize}"
Glyph="&#xE74D;" />
<TextBlock x:Uid="Profile_DeleteButton"
Margin="10,0,0,0" />
</StackPanel>
</Flyout>
</Button.Flyout>
</Button>
</Button.Content>
<Button.Flyout>
<Flyout>
<StackPanel>
<TextBlock x:Uid="Profile_DeleteConfirmationMessage"
Style="{StaticResource CustomFlyoutTextStyle}" />
<Button x:Uid="Profile_DeleteConfirmationButton"
Click="DeleteConfirmation_Click" />
</StackPanel>
</Flyout>
</Button.Flyout>
</Button>
</Border>
</StackPanel>
</ScrollViewer>
</Grid>

View File

@@ -68,7 +68,7 @@
TargetType="FontIcon">
<Setter Property="Foreground" Value="{StaticResource SystemAccentColor}" />
<Setter Property="FontSize" Value="11" />
<Setter Property="FontFamily" Value="Segoe Fluent Icons" />
<Setter Property="FontFamily" Value="{ThemeResource SymbolThemeFontFamily}" />
</Style>
<Style x:Key="NonExpanderGrid"
@@ -171,7 +171,7 @@
Margin="0,0,-16,0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
FontFamily="Segoe UI, Segoe MDL2 Assets"
FontFamily="Segoe UI, Segoe Fluent Icons, Segoe MDL2 Assets"
Style="{StaticResource SettingsPageItemDescriptionStyle}"
Text="{TemplateBinding CurrentValue}" />
</Grid>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.UI.Xaml" version="2.7.0-prerelease.210913003" targetFramework="native" />
<package id="Microsoft.UI.Xaml" version="2.7.0" targetFramework="native" />
<package id="Microsoft.Windows.CppWinRT" version="2.0.210825.3" targetFramework="native" />
<package id="Microsoft.Internal.PGO-Helpers.Cpp" version="0.2.34" targetFramework="native" />
</packages>

View File

@@ -130,7 +130,7 @@ namespace Microsoft.Terminal.Settings.Model
String ColorScheme;
// This needs to be an optional so that the default value (null) does
// not modify whatever the profile's value is (either true or false)
Windows.Foundation.IReference<Boolean> Elevate { get; };
Windows.Foundation.IReference<Boolean> Elevate;
Boolean Equals(NewTerminalArgs other);
String GenerateName();

View File

@@ -593,7 +593,7 @@ Model::Profile CascadiaSettings::GetProfileForArgs(const Model::NewTerminalArgs&
Model::Profile CascadiaSettings::_getProfileForCommandLine(const winrt::hstring& commandLine) const
{
// We're going to cache all the command lines we got, as
// _normalizeCommandLine is a relatively heavy operation.
// NormalizeCommandLine is a relatively heavy operation.
std::call_once(_commandLinesCacheOnce, [this]() {
_commandLinesCache.reserve(_allProfiles.Size());
@@ -612,7 +612,7 @@ Model::Profile CascadiaSettings::_getProfileForCommandLine(const winrt::hstring&
try
{
_commandLinesCache.emplace_back(_normalizeCommandLine(cmd.c_str()), profile);
_commandLinesCache.emplace_back(NormalizeCommandLine(cmd.c_str()), profile);
}
CATCH_LOG()
}
@@ -631,7 +631,7 @@ Model::Profile CascadiaSettings::_getProfileForCommandLine(const winrt::hstring&
try
{
const auto needle = _normalizeCommandLine(commandLine.c_str());
const auto needle = NormalizeCommandLine(commandLine.c_str());
// til::starts_with(string, prefix) will always return false if prefix.size() > string.size().
// --> Using binary search we can safely skip all items in _commandLinesCache where .first.size() > needle.size().
@@ -678,7 +678,7 @@ Model::Profile CascadiaSettings::_getProfileForCommandLine(const winrt::hstring&
// is considered a compatible profile with
// "C:\Program Files\PowerShell\7\pwsh.exe -WorkingDirectory ~"
// as it shares the same (normalized) prefix.
std::wstring CascadiaSettings::_normalizeCommandLine(LPCWSTR commandLine)
std::wstring CascadiaSettings::NormalizeCommandLine(LPCWSTR commandLine)
{
// Turn "%SystemRoot%\System32\cmd.exe" into "C:\WINDOWS\System32\cmd.exe".
// We do this early, as environment variables might occur anywhere in the commandLine.
@@ -692,6 +692,10 @@ std::wstring CascadiaSettings::_normalizeCommandLine(LPCWSTR commandLine)
wil::unique_hlocal_ptr<PWSTR[]> argv{ CommandLineToArgvW(normalized.c_str(), &argc) };
THROW_LAST_ERROR_IF(!argc);
// The index of the first argument in argv for our executable in argv[0].
// Given {"C:\Program Files\PowerShell\7\pwsh.exe", "-WorkingDirectory", "~"} this will be 1.
int startOfArguments = 1;
// The given commandLine should start with an executable name or path.
// For instance given the following argv arrays:
// * {"C:\WINDOWS\System32\cmd.exe"}
@@ -713,39 +717,44 @@ std::wstring CascadiaSettings::_normalizeCommandLine(LPCWSTR commandLine)
// CreateProcessW uses RtlGetExePath to get the lpPath for SearchPathW.
// The difference between the behavior of SearchPathW if lpPath is nullptr and what RtlGetExePath returns
// seems to be mostly whether SafeProcessSearchMode is respected and the support for relative paths.
// Windows Terminal makes the use relative paths rather impractical which is why we simply dropped the call to RtlGetExePath.
// Windows Terminal makes the use of relative paths rather impractical which is why we simply dropped the call to RtlGetExePath.
const auto status = wil::SearchPathW(nullptr, argv[0], L".exe", normalized);
if (status == S_OK)
{
std::filesystem::path path{ std::move(normalized) };
const auto attributes = GetFileAttributesW(normalized.c_str());
// ExpandEnvironmentStringsW() might have returned a string that's not in the canonical capitalization.
// For instance %SystemRoot% is set to C:\WINDOWS on my system (ugh), even though the path is actually C:\Windows.
// We need to fix this as case-sensitive path comparisons will fail otherwise (Windows supports case-sensitive file systems).
// If we fail to resolve the path for whatever reason (pretty unlikely given that SearchPathW found it)
// we fall back to leaving the path as is. Better than throwing a random exception and making this unusable.
if (attributes != INVALID_FILE_ATTRIBUTES && WI_IsFlagClear(attributes, FILE_ATTRIBUTE_DIRECTORY))
{
std::error_code ec;
auto canonicalPath = std::filesystem::canonical(path, ec);
if (!ec)
{
path = std::move(canonicalPath);
}
}
std::filesystem::path path{ std::move(normalized) };
// std::filesystem::path has no way to extract the internal path.
// So about that.... I own you, computer. Give me that path.
normalized = std::move(const_cast<std::wstring&>(path.native()));
// canonical() will resolve symlinks, etc. for us.
{
std::error_code ec;
auto canonicalPath = std::filesystem::canonical(path, ec);
if (!ec)
{
path = std::move(canonicalPath);
}
}
// std::filesystem::path has no way to extract the internal path.
// So about that.... I own you, computer. Give me that path.
normalized = std::move(const_cast<std::wstring&>(path.native()));
break;
}
}
// All other error types aren't handled at the moment.
else if (status != HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
{
break;
}
// If the file path couldn't be found by SearchPathW this could be the result of us being given a commandLine
// like "C:\foo bar\baz.exe -arg" which is resolved to the argv array {"C:\foo", "bar\baz.exe", "-arg"}.
// like "C:\foo bar\baz.exe -arg" which is resolved to the argv array {"C:\foo", "bar\baz.exe", "-arg"},
// or we were erroneously given a directory to execute (e.g. someone ran `wt .`).
// Just like CreateProcessW() we thus try to concatenate arguments until we successfully resolve a valid path.
// Of course we can only do that if we have at least 2 remaining arguments in argv.
// All other error types aren't handled at the moment.
if (argc < 2 || status != HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
if ((argc - startOfArguments) < 2)
{
break;
}
@@ -753,19 +762,19 @@ std::wstring CascadiaSettings::_normalizeCommandLine(LPCWSTR commandLine)
// As described in the comment right above, we concatenate arguments in an attempt to resolve a valid path.
// The code below turns argv from {"C:\foo", "bar\baz.exe", "-arg"} into {"C:\foo bar\baz.exe", "-arg"}.
// The code abuses the fact that CommandLineToArgvW allocates all arguments back-to-back on the heap separated by '\0'.
argv[1][-1] = L' ';
--argc;
argv[startOfArguments][-1] = L' ';
++startOfArguments;
}
// We've (hopefully) finished resolving the path to the executable.
// We're now going to append all remaining arguments to the resulting string.
// If argv is {"C:\Program Files\PowerShell\7\pwsh.exe", "-WorkingDirectory", "~"},
// then we'll get "C:\Program Files\PowerShell\7\pwsh.exe\0-WorkingDirectory\0~"
if (argc > 1)
if (startOfArguments < argc)
{
// normalized contains a canonical form of argv[0] at this point.
// -1 allows us to include the \0 between argv[0] and argv[1] in the call to append().
const auto beg = argv[1] - 1;
const auto beg = argv[startOfArguments] - 1;
const auto lastArg = argv[argc - 1];
const auto end = lastArg + wcslen(lastArg);
normalized.append(beg, end);

View File

@@ -134,6 +134,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
winrt::hstring GetSerializationErrorMessage() const;
// defterm
static std::wstring NormalizeCommandLine(LPCWSTR commandLine);
static bool IsDefaultTerminalAvailable() noexcept;
static bool IsDefaultTerminalSet() noexcept;
winrt::Windows::Foundation::Collections::IObservableVector<Model::DefaultTerminal> DefaultTerminals() noexcept;
@@ -142,7 +143,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
private:
static const std::filesystem::path& _settingsPath();
static std::wstring _normalizeCommandLine(LPCWSTR commandLine);
winrt::com_ptr<implementation::Profile> _createNewProfile(const std::wstring_view& name) const;
Model::Profile _getProfileForCommandLine(const winrt::hstring& commandLine) const;

View File

@@ -27,6 +27,8 @@
#include "DefaultTerminal.h"
#include "FileUtils.h"
using namespace winrt::Windows::Foundation::Collections;
using namespace winrt::Windows::ApplicationModel::AppExtensions;
using namespace winrt::Microsoft::Terminal::Settings;
using namespace winrt::Microsoft::Terminal::Settings::Model::implementation;
@@ -235,10 +237,29 @@ void SettingsLoader::FindFragmentsAndMergeIntoUserSettings()
}
}
// Search through app extensions
// Gets the catalog of extensions with the name "com.microsoft.windows.terminal.settings"
const auto catalog = winrt::Windows::ApplicationModel::AppExtensions::AppExtensionCatalog::Open(AppExtensionHostName);
const auto extensions = extractValueFromTaskWithoutMainThreadAwait(catalog.FindAllAsync());
// Search through app extensions.
// Gets the catalog of extensions with the name "com.microsoft.windows.terminal.settings".
//
// GH#12305: Open() can throw an 0x80070490 "Element not found.".
// It's unclear to me under which circumstances this happens as no one on the team
// was able to reproduce the user's issue, even if the application was run unpackaged.
// The error originates from `CallerIdentity::GetCallingProcessAppId` which returns E_NOT_SET.
// A comment can be found, reading:
// > Gets the "strong" AppId from the process token. This works for UWAs and Centennial apps,
// > strongly named processes where the AppId is stored securely in the process token. [...]
// > E_NOT_SET is returned for processes without strong AppIds.
IVectorView<AppExtension> extensions;
try
{
const auto catalog = AppExtensionCatalog::Open(AppExtensionHostName);
extensions = extractValueFromTaskWithoutMainThreadAwait(catalog.FindAllAsync());
}
CATCH_LOG();
if (!extensions)
{
return;
}
for (const auto& ext : extensions)
{
@@ -894,12 +915,6 @@ void CascadiaSettings::WriteSettingsToDisk() const
{
const auto settingsPath = _settingsPath();
{
// create a timestamped backup file
const auto backupSettingsPath = fmt::format(L"{}.{:%Y-%m-%dT%H-%M-%S}.backup", settingsPath.native(), fmt::localtime(std::time(nullptr)));
LOG_IF_WIN32_BOOL_FALSE(CopyFileW(settingsPath.c_str(), backupSettingsPath.c_str(), TRUE));
}
// write current settings to current settings file
Json::StreamWriterBuilder wbuilder;
wbuilder.settings_["indentation"] = " ";

View File

@@ -124,7 +124,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
const bool isMDL2Icon = ch >= L'\uE700' && ch <= L'\uF8FF';
if (isMDL2Icon)
{
icon.FontFamily(winrt::Windows::UI::Xaml::Media::FontFamily{ L"Segoe MDL2 Assets" });
icon.FontFamily(winrt::Windows::UI::Xaml::Media::FontFamily{ L"Segoe Fluent Icons, Segoe MDL2 Assets" });
}
else
{

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