Compare commits

...

80 Commits

Author SHA1 Message Date
Dustin L. Howett
d6a644a673 Migrate spelling-0.0.21 changes from main 2022-10-31 14:47:23 -05:00
Mike Griese
b4d06c0385 a breakthrough 2022-10-31 14:47:23 -05:00
Mike Griese
e1c6be1579 initial draft 2022-05-18 11:49:20 -05:00
James Holderness
e1086de512 Fix handling of cursor position reports in passthrough mode (#13109)
## Summary of the Pull Request

When the conpty passthrough mode is enabled, it often needs to send `DSR-CPR` queries (cursor position reports) to the client terminal to obtain the current cursor position. However, the code that originally handled the responses to these queries got broken by the refactoring of the `ConGetSet` API. This PR is an attempt to correct that regression.

## References

The conpty passthrough mode was introduced in PR #11264.
The refactoring that broke the cursor position handling was in PR #12703.

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

## Detailed Description of the Pull Request / Additional comments

Prior to the `ConGetSet` refactoring, the code that handled `DSR-CPR` responses (`InteractDispatch::MoveCursor`) would pass the cursor position to `ConGetSet::SetCursorPosition`, which in turn would forward it to the `SetConsoleCursorPositionImpl` API, and from there to the `VtIo` class.

After the refactor, all of those intermediate steps were removed - the cursor was simply updated directly in `InteractDispatch::MoveCursor`, and the `VtIo` call was moved from `SetConsoleCursorPositionImpl` to `InteractDispatch` (since that was the only place it was actually required).

However, when the conpty passthrough mode was introduced - which happened in parallel - it relied on the `SetConsoleCursorPositionImpl` API being called from `InteractDispatch` in order to handle its own `DSR-CPR` responses, and that's why things stopped working when the two PRs merged.

So what I've done now is made `InteractDispatch::MoveCursor` method call `SetConsoleCursorPositionImpl` again (although without the intermediate `ConGetSet` overhead), and moved the `VtIo::SetCursorPosition` call back into `SetConsoleCursorPositionImpl`.

This is not ideal, and there are still a bunch of problems with the `DSR-CPR` handling in passthrough mode, but it's at least as good as it was before.

## Validation Steps Performed

I've just manually tested various shells with passthrough mode enabled, and confirmed that they're working better now. There are still issues, but nothing that wasn't already a problem in the initial implementation, at least as far as I can tell.
2022-05-17 14:56:04 +00:00
Leonard Hecker
fa6b066747 AtlasEngine: Stop resizing buffers on scroll (#13100)
This regressed in ad2358d.
We're interested in the size of the viewport only, but it can shift up/down
during scrolling. In these situations we shouldn't resize our buffers of course.

## Validation Steps Performed
* Scroll
* Not setting `ApiInvalidations::Size` 
2022-05-17 00:07:48 +00:00
Carlos Zamora
b699f9275f Add experimental.useBackgroundImageForWindow to schema (#13114)
Adds the `experimental.useBackgroundImageForWindow` global setting introduced in #12893 to the schema.
2022-05-16 19:06:05 -05:00
Sergey Semushin
b851b0d3f4 Add find item to tab menu (#13055)
## Summary of the Pull Request

Add `Find` to tab context menu as describe in issue #5633.

## PR Checklist
* [x] Closes #5633
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA

## Detailed Description of the Pull Request / Additional comments

Just wanted to solve `Easy Starter` issue, so any corrections/suggestions welcome. There's a couple of points I'm not sure of
* Placement of item within menu, currently it's at the end before close tab block.
* Should it be named longer, something like `Find in Tab` of just `Find` is fine?
* The workaround for focus similar to tab rename is a bit annoying, especially because it required adding a method to `TermControl` but without it find window obviously opens without focus which is bad.

## Validation Steps Performed

Open menu, press menu item try to find things via opened find dialog.
2022-05-16 23:30:05 +00:00
Leonard Hecker
df627c26f1 Various improvements for til::hash/point/size/rect (#13093)
This commit includes various minor improvements to til::hash/point/size/rect
which accumulated while working on #4015.

* Allow xvalue containers and non-`size_t` indices in `til::at`.
* `til::as_unsigned` can be used to reinterpret a potentially signed integer
  as a unsigned one. This can potentially enable some optimizations as no sign
  extension is needed anymore. `til::hash` can make use of this to drop about
  20% of the hashing of signed integers <= 32 bit. On x86 this translates to
  a `mov` (virtually no latency) or no instructions at all, instead of
  requiring a `movsx` (some latency) for sign extension.
* `til::point` operators that prefer mutability.
  This is a opinionated change, but it follows the STL style beter and
  generates less assembly.
* Simpler `rect` scale_up/down and `size` divide_ceil.
  `scale_up` will not depend on the operator header anymore.
  `scale_down` / `divide_ceil` can be implemented without checked numerics,
  so I did. It also follows the related GdiEngine code better now, which
  makes me confident that we can replace GdiEngine's code with this.
* Removal of rect-size-shift operators.
  They were only used in DxEngine and confusing as they weren't commutative.
  Adding and then subtracting a size from a rect (and vice versa) didn't do
  what you'd intuitively think it'd do. The code was replaced with addition
  and clamps in DxEngine.
* Various unsafe `as_` casts for point/size/rect.
  This will aid the migration in #4015.

## Validation Steps Performed
* Vertical scrolling works in `DxEngine` 
2022-05-16 23:28:32 +00:00
Leonard Hecker
1db47ff8dc Simplify Utf16Parser (#13096)
This trivial commit simplifies `Utf16Parser::IsLeading/TrailingSurrogate`
methods, by replacing `<bitset>` with a simple, equivalent range check.
2022-05-16 22:18:13 +00:00
Leonard Hecker
003cbe7c29 Reduce integer type casts in VtEngine (#13097)
This commit is one of the more difficult rewrites that were necessary as part
of #4015, but still simple enough that it can be done as a separate commit.
The search for the `lastNonSpace` was replaced with a simpler
`std::string_view::find_last_not_of`.

## Validation Steps Performed
ConPTY appears to work 
2022-05-16 22:16:57 +00:00
Carlos Zamora
6ffc3dc7a8 Revert "Hide the window from DWM until we're finished with initialization (#12979)" (#13098)
This reverts commit 14098d71f2.

## Summary of the Pull Request
@zadjii-msft found that this is causing persisted windows on a secondary monitor to shrink a little each time. We're choosing to revert this commit until that gets resolved.

## References
#12979
2022-05-13 13:30:18 -05:00
Leonard Hecker
1cb58a6a02 Fix various unit/feature test bugs (#13092)
This commit fixes various bugs in our unit/feature test suite:
* 2 tests failed at 150% scale.
* The "null key" (@ on a US keyboard) isn't necessarily Shift+2.
  The proper way to get it is with `LOBYTE(VkKeyScanW(0))`
* `InputEngineTest::C0Test` never worked as it overwrote
  the loop variable, exiting the loop early
2022-05-13 18:29:01 +00:00
Leonard Hecker
0630b18eff Fix various issues with useBackgroundImageForWindow (#13090)
Fixes the following issues:
* `desktopWallpaper` not working
* switching tabs/panes causes the background to flicker
* settings preview having a transparent background

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

## Validation Steps Performed
Tested the 3 cases above. 
2022-05-12 22:49:13 +00:00
Carlos Zamora
17d1e2437c Fix the 'RunMakeKillTabs' PGO test (#13089)
## Summary of the Pull Request
For some reason, the PGO tests (specifically the `RunMakeKillTabs` test) started to fail after #12979 merged. After closer inspection, the test was actually improperly written. We should be using <kbd>ctrl+shift+t</kbd> to open new tabs, not <kbd>alt+shift+t</kbd>. Presumably, the <kbd>alt</kbd> was copied over from the previous test, because they look _very_ similar.

So I went ahead and fixed the test, and it now (1) tests what it's intended to test and (2) doesn't fail. Why did #12979 cause the tests to fail? idk, but it works now.

## References
#10071 - Introduce PGO Tests

## Validation Steps Performed
Ran PGO tests locally and confirmed that it works.
Ran PGO pipeline and confirmed that it works.
2022-05-12 20:38:26 +00:00
James Holderness
c2f830843a Restore virtual viewport position after resize with reflow (#13087)
When the buffer is resized with a reflow, we were previously calculating
the new virtual bottom based on the position of last non-space
character. If the viewport was largely blank when resized, this could
result in the new virtual bottom being higher than it should be.

This PR attempts to address that problem by restoring the virtual bottom
to a position that is the same distance from the cursor row as it was
prior to the resize.

This was a regression introduced in PR #12972.

We still take the last non-space row into account when determining the
virtual bottom, because if the content of the screen is forced to wrap,
the virtual bottom will need to be lower (relative to the cursor) than
it was before.

We also need to check that we don't overflow the bottom of the buffer,
which can occur when the viewport is at the bottom of the buffer, and
the cursor position is pushed down as a result of content wrapping above
it.

I've manually confirmed that this fixes the problem reported in issue
#13078, and I've also extended the existing `RefreshWithReflow` unit
test to cover that particular scenario.

Closes #13078
2022-05-12 20:26:35 +00:00
Ofer Zelig
1d3e1568a2 Fix some typos in mouseInput.cpp (#13085) 2022-05-12 20:20:06 +00:00
James Holderness
a69ce89712 Add support for the DECAC escape sequence (#13058)
The `DECAC` (Assign Colors) escape sequence controls which color table
entries are associated with the default foreground and background
colors. This is how you would change the default colors on the the
original DEC VT525 terminals.

But `DECAC` also allows you to assign the color table entries for the
"window frame", which in our case is mapped to the tab color (just the
background for now). So this now gives us a way to control the tab color
via an escape sequence as well.

DETAILS
-------

The way this works is there are now two new entries in the color table
for the frame colors, and two new aliases in the color alias table that
are mapped to those color table entries. As previously mentioned, only
the background is used for now.

By default, the colors are set to `INVALID_COLOR`, which indicates that
the system colors should be used. But if the user has set a `tabColor`
property in their profile, the frame background will be initialized with
that value instead.

And note that some of the existing color table entries are now
renumbered for compatibility with XTerm, which uses entries 256 to 260
for special colors which we don't yet support. Our default colors are
now at 261 and 262, the frame colors are 263 and 264, and the cursor
color is 265. 

So at runtime, you can change the tab color programmatically by setting
the color table entry at index 262 using `OSC 4` (assuming you need a
specific RGB value). Otherwise if you just want to set the tab color to
an existing color index, you can use `DECAC 2`.

You can even make the tab color automatically match background color by
mapping the frame background alias to the color table entry for the
default background, using `DECAC 2;261;262` (technically this is mapping
both the the foreground and background).

This PR doesn't include support for querying the color mapping with
`DECRQSS`, and doesn't support resetting the colors with `RIS`, but
hopefully those can be figured out in a future PR - there are some
complications that'll need to be resolved first.

## Validation Steps Performed

I've added a basic unit test that confirms the `DECAC` escape sequence
updates the color aliases in the render settings as expected. I've also
manually confirmed that the tab color in Windows Terminal is updated by
`DECAC 2`, and the default colors are updated in both conhost and WT
using `DECAC 1`.

Closes #6574
2022-05-12 20:18:40 +00:00
Carlos Zamora
9cb2bccd7f version: bump to 1.15 on main 2022-05-11 11:55:33 -07:00
Carlos Zamora
a657cb0192 [High Contrast] Fix red SUI background (#13083)
Fixes the SUI background being red in high contrast mode. The issue was
that `SolidBackgroundFillColorTertiary` purposefully has a bad High
Contrast color[^1].

The fix was to be explicit in the theme resources so that
`SolidBackgroundFillColorTertiary` is used in light and dark mode, but
the standard high contrast one is used in high contrast mode. Since the
page is the top-level XAML element in the Editor project, I had to
introduce this in the App.xaml resources so that the page can find the
theme resource.

Closes #13065 
Closes #13070

[^1]: 40df43a61c/dev/CommonStyles/Common_themeresources_any.xaml (L650-L651)
2022-05-11 18:31:50 +00:00
Carlos Zamora
d137d3fb5e Add 'selectAll' to schema (#13084)
Adds the `selectAll` action to the schema...because I forgot to do that in #13045.
2022-05-11 13:19:18 -05:00
Peretz Cohen
171524da77 Add BellSound to the schema (#13035)
Closes #12504
2022-05-10 12:36:00 -05:00
James Holderness
ec726e7ba7 Make sure the virtual viewport doesn't go negative (#13052)
## Summary of the Pull Request

When calculating the position of the virtual bottom after a resize with
reflow, it was possible for it to end up less than the height of the
viewport. This meant that the top of the virtual viewport would be
negative, which resulted in other operations failing further down the
line. This PR updates the virtual bottom calculation to fix that
scenario.

## References

This was probably a regression introduced in PR #12972.

## PR Checklist
* [x] Closes #13034
* [x] CLA signed.
* [x] Tests added/passed
* [ ] Documentation updated.
* [ ] Schema updated.
* [x] I've discussed this with core contributors already. Issue number where discussion took place: #13034

## Validation Steps Performed

I wasn't able to replicate the exact case described in issue #13034,
because I don't have Windows 11, so can't configure the default
terminal. However, I was able to reproduce a similar failure using a
`SetConsoleScreenBufferInfoEx` call, and I've confirmed that this PR
has fixed that.

I've also added another screen buffer test to make sure the
`ResizeWithReflow` method doesn't shrink the virtual bottom when
resizing at the top of the buffer.
2022-05-09 21:45:00 +00:00
Mike Griese
0d6c4df9fc Redraw all in conhost when changing the palette (#12659)
Does what it says on the tin. Not super complicated of a fix.

* [x] Fixes #399
* [x] I work here.
* [x] Tested manually (not sure there's a great test for this particular path)
![gh-399-fixed](https://user-images.githubusercontent.com/18356694/157707993-9d59fce6-ae3b-4a6e-8b83-3ec5f3d73c96.gif)
2022-05-09 10:58:57 +00:00
Dustin L. Howett
dad68edc03 Hide the VT Passthrough Mode switch from the Settings UI in Preview (#13051)
The setting will still be available, but be considered even more
"advanced" than the advanced section of the settings.
2022-05-06 17:51:54 -05:00
Mike Griese
14098d71f2 Hide the window from DWM until we're finished with initialization (#12979)
When we start up, our window is initially just a frame with a transparent content area. We're gonna do all this startup init on the UI thread, so the UI won't actually paint till it's all done. This results in a few frames where the frame is visible, before the page paints for the first time, before any tabs appears, etc. 

To mitigate this, we're gonna wait for the UI thread to finish everything it's gotta do for the initial init, and _then_ fire our Initialized event. By waiting for everything else to finish (`CoreDispatcherPriority::Low`), we let all the tabs and panes actually get created. In the window layer, we're gonna ~cloak~ just not show the window till this event is fired, so we don't actually see this frame until we're actually all ready to go. **This will result in the window seemingly not loading as fast**, but it will actually take exactly the same amount of time before it's usable. 

I also experimented with drawing a solid BG color before the initialization is finished. However, there are still a few frames after the frame is displayed before the XAML content first draws, so that didn't actually resolve any issues.

* [x] Closes #11561
* [x] Tested manually
* [x] I work here.
* [x] Accidentally also closes #9053. By switching the initial call from `ShowWindow(SW_SHOW)` to `ShowWindow(SW_SHOWDEFAULT)`, we actually obey the startup info now.
2022-05-06 20:08:39 +00:00
Carlos Zamora
60a4837548 Add ability to select all text in the buffer (#13045)
Adds the `selectAll` action which can be used to select all text in the buffer (regardless of whether a selection is present).

## References
#3663 - Mark Mode
#4993 - [Scenario] Keyboard selection

## PR Checklist
* [x] Closes #1469
* [x] Tests added/passed

## Detailed Description of the Pull Request / Additional comments
I've made it such that selecting the "entire buffer" really just selects up to the mutable viewport. This seems like a nice QOL improvement since there's generally nothing past that.

When the user selects all, the viewport does not move. This is consistent with CMD behavior and is intended to allow the user to not lose context when selecting everything.

A minor change had to be made to the DxRenderer because this uncovered an underflow issue. Basically, the selection rects were handed to the DxEngine relative to the viewport (which means that some had a negative y-value). At some point, those rects were stored into `size_t`s, resulting in an underflow issue. This caused the renderer to behave strangely when rendering the selection. Generally, these kinds of issues weren't really noticed because selection would always modify a portion of the viewport.

Funny enough, in a way, this satisfies the "mark mode" scenario because the user now has a way to initiate a selection using only the keyboard. Though this isn't ideal, just a fun thing to point out (that's why I'm not closing the mark mode issue).

## Validation Steps Performed
- Verified using DxEngine and AtlasEngine
- select all --> keyboard selection --> start moving the top-left endpoint (and scroll to there)
- select all --> do not scroll automatically
2022-05-06 20:06:49 +00:00
Mike Griese
d072314d83 Only add the ProfileVM.DeleteProfile handler once (#13044)
Turns out if you add that Delete handler there, then every time you navigate to the profile, we'll add another Delete handler to the list of handlers. That's bad - that'll cause us to try and delete the profile multiple times.

The repro I had before was 100%, now it's fixed.

* [x] Closes #13017
2022-05-06 19:55:59 +00:00
Chester Liu
0d17769b89 Use memcmp for TextAttribute & TextColor comparison (#10566)
`TextAttribute` and `TextColor` are commonly used structures in hot paths.
This commit replaces more complex comparisons where each field is compared
independently with a single call to `memcmp`. This compiles down to just
a few instructions. This reduces code and binary size and improves
performance for paths were `TextAttribute`s need to be compared.

## PR Checklist

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

## Validation Steps Performed

* termbench still works ✔️

Co-authored-by: Leonard Hecker <lhecker@microsoft.com>
2022-05-05 17:37:41 +00:00
Mike Griese
ce850cae18 Ignore newTab actions with a profile index greater than the number of profiles (#11621)
## Summary of the Pull Request

As discussed in team sync. Ignore `newTab` actions with a profile index greater than the number of profiles.

## PR Checklist
* [x] Closes #11114
* [x] I work here
* [ ] Tests added/passed
* [ ] Requires documentation to be updated - maybe
2022-05-05 15:23:13 +00:00
Mike Griese
cd86c0f671 Fix the TabTests, April 2022 edition (#12997)
In classic fashion, we never run the LocalTests locally before committing, so stuff breaks from time to time.

This time, the main trick was that the tests had a pretty hardcore dependency on the inner workings of `_PreviewActionHandler`, and when that changed, they broke.

Also, there was a weird crash I saw when I had the default terminal set to the Dev build version. That crash would let the test contents pass, but ultimately fail when TAEF tore down the conhost. Unsetting that fixed the crash 🤷 

Closes #12158
2022-05-05 13:42:34 +00:00
James Holderness
4b0ebbc087 Stop the viewport being moved when in the alt buffer (#13039)
## Summary of the Pull Request

When `TerminalDispatch` was merged with `AdaptDispatch` in PR #13024,
that broke the Terminal's `EraseAll` operation in the alt buffer. The
problem was that the `EraseAll` implementation makes a call to
`SetViewportPosition` which wasn't taking the alt buffer into account,
and thus modified the main viewport instead.

This PR corrects that mistake. If we're in the alt buffer, the
`SetViewportPosition` method now does nothing, since the alt buffer
viewport should always be at 0,0.

## References

This was a regression introduced in PR #13024.

## PR Checklist
* [x] Closes #13038
* [x] CLA signed.
* [ ] Tests added/passed
* [ ] Documentation updated.
* [ ] Schema updated.
* [x] I've discussed this with core contributors already. Issue number where discussion took place: #13038

## Validation Steps Performed

I've confirmed that the test case reported in issue #13038 is no longer
failing. I've also made sure the `ED 2` and `ED 3` sequences are still
working correctly in the main buffer.
2022-05-05 11:43:59 +00:00
Dustin L. Howett
9edf55de75 Switch WT and OpenConsole to the Segment Heap (#13033)
To quote an internal wiki:

> It generally provides improved footprint and performance over the
> existing default heap for native win32 applications.

It is apparently the default heap on ARM64, and for all UWPs.

This heap has different allocation and compaction characteristics.
I am not sure how it will impact terminal.
2022-05-04 21:52:38 +00:00
PankajBhojwani
71cbdc8a1f Add automation properties to expander-style settings (#13032)
## Summary of the Pull Request
Make sure we set `Name` and `FullDescription` on expander-style settings in the SUI

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

## Validation Steps Performed
Accessibility insights now shows the name/full description for the expander-style settings
2022-05-04 20:17:20 +00:00
James Holderness
f4e0d9f2bd Merge the TerminalDispatch and AdaptDispatch classes (#13024)
## Summary of the Pull Request

This PR replaces the `TerminalDispatch` class with the `AdaptDispatch` class from conhost, so we're no longer duplicating the VT functionality in two places. It also gives us a more complete VT implementation on the Terminal side, so it should work better in pass-through mode.

## References

This is essentially part two of PR #12703.

## PR Checklist
* [x] Closes #3849
* [x] CLA signed.
* [ ] Tests added/passed
* [ ] Documentation updated.
* [ ] Schema updated.
* [x] I've discussed this with core contributors already. Issue number where discussion took place: #12662

## Detailed Description of the Pull Request / Additional comments

The first thing was to give the `ConGetSet` interface a new name, since it's now no longer specific to conhost. I went with `ITerminalApi`, since that was the equivalent interface on the terminal side, and it still seemed like a generic enough name. I also changed the way the api is managed by the `AdaptDispatch` class, so it's now stored as a reference rather than a `unique_ptr`, which more closely matches the way the `TerminalDispatch` class worked.

I then had to make sure that `AdaptDispatch` actually included all of the functionality currently in `TerminalDispatch`. That meant copying across the code for bracketed paste mode, the copy to clipboard operation, and the various ConEmu OSC operations. This also required a few new methods to the `ConGetSet`/`ITerminalApi` interface, but for now these are just stubs in conhost.

Then there were a few thing in the api interface that needed cleaning up. The `ReparentWindow` method doesn't belong there, so I've moved that into `PtySignalInputThread` class. And the `WriteInput` method was too low-level for the Terminal requirements, so I've replaced that with a `ReturnResponse` method which takes a `wstring_view`.

It was then a matter of getting the `Terminal` class to implement all the methods in the new `ITerminalApi` interface that it didn't already have. This was mostly mapping to existing functionality, but there are still a number of methods that I've had to leave as stubs for now. However, what we have is still good enough that I could then nuke the `TerminalDispatch` class from the Terminal code and replace it with `AdaptDispatch`.

One oddity that came up in testing, though, was the `AdaptDispatch` implementation of `EraseAll` would push a blank line into the scrollback when called on an empty buffer, whereas the previous terminal implementation did not. That caused problems for the conpty connection, because one of the first things it does on startup is send an `ED 2` sequence. I've now updated the `AdaptDispatch` implementation to match the behavior of the terminal implementation in that regard.

Another problem was that the terminal implementation of the color table commands had special handling for the background color to notify the application window that it needed to repaint the background. I didn't want to have to push the color table operations through the `ITerminalApi` interface, so I've instead moved the handling of the background update into the renderer, initiated by a flag on the `TriggerRefreshAll` method.

## Validation Steps Performed

Surprisingly this PR didn't require a lot of changes to get the unit tests working again. There were just a few methods used from the original `ITerminalApi` that have now been removed, and which needed an equivalent replacement. Also the updated behavior of the `EraseAll` method in conhost resulted in a change to the expected cursor position in one of the screen buffer tests.

In terms of manual testing, I've tried out all the different shells in Windows Terminal to make sure there wasn't anything obviously wrong. And I've run a bunch of the tests from _vttest_ to try and get a wider coverage of the VT functionality, and confirmed everything still works at least as well as it used to. I've also run some of my own tests to verify the operations that had to be copied from `TerminalDispatch` to `AdaptDispatch`.
2022-05-04 11:14:51 +00:00
Leonard Hecker
eb5c26cc69 Add InteractivityOneCore/RendererWddmCon projects (#13007)
`InteractivityOneCore` and `RendererWddmCon` were the last two remaining
projects which are relevant for our internal console builds, but couldn't be
easily compiled publicly by users on GitHub. This commit adds all definitions
required to compile the two projects into dysfunctional libraries at least.
(Since the added definitions are deliberately incorrect.)

Additionally this commit fixes the AuditMode build for the two projects.

## Validation Steps Performed
The two new projects compile fine.
2022-05-04 00:49:43 +00:00
Mike Griese
223af3a54a Fix a crash when entering lots of text in the Japanese IME (#13031)
As noted in the issue. There's a case where backing up the `lineEnd` can result in the `lineEnd` pointing at exactly the `lineBegin`, which results in an empty view, which causes all sorts of pain later. 

Instead, just return early in this case.

* tested with an 80x24 conhost
* tested with an 79x24 conhost


I also tried making this a FAILFAST or a THROW_HR, but the failfast immediately died (of course it did), and the throw would result in a few frames where the composition was just... entirely not displayed? Probably not what we wanted.

* [x] Closes #12730
2022-05-03 18:08:04 +00:00
YanceyChiew
6e87e0bad0 Change TSFInputControl inputScope to AlphanumericHalfWidth (#13028)
Modified the scope of input control, it used to be `Text`, now it is
`AlphanumericHalfWidth`.  This input scope actually accepts any
characters, but English characters are preferred, and the soft keyboard
also displays English by default.

This should improve user friendliness for users using composition mode
input methods.

As a user who uses the composition mode input method, in applications
like windows terminal that should usually be input in English, it is
always required to manually switch to English mode by pressing Shift
before entering commands.

One keystroke is not a problem, but often for some reason there is no or
no successful switching, and additional more keystrokes are required to
clear the wrong input.

The input method that comes with windows will automatically switch to
English mode for a few programs such as conhost, but windows terminal is
not in this list.

This change should have no negative impact. Even if someone does tend to
use a shell oriented towards composition characters or non-alpha
letters, there should also were more users who in the same language are
more inclined to English characters shells, for example, cmd,
powershell, bash that comes with windows.

If there's any reason to have to keep the Text inputScope, maybe making
this setting customizable via `settings.json` would be a good idea, but
I don't see the need to do this, `AlphanumericHalfWidth` is perfect.

Closes #12731
2022-05-03 18:07:06 +00:00
Leonard Hecker
ad2358dc35 Fix resize crash in OpenConsole with AtlasEngine (#13015)
`_api.cellCount` caches the `TextBuffer` size in AtlasEngine.
Calculating it based on the `_api.sizeInPixel` is incorrect as the
`TextBuffer` size doesn't necessarily have to be the size of the window.
This can occur when the window is resized, as the main thread is receiving its
`WM_SIZE` message and resizing the `TextBuffer` concurrently with the render
thread performing a render pass and AtlasEngine checking the `GetClientRect`.

In order to inform `AtlasEngine` about the initial buffer size, `Renderer`
was modified to also invoke `UpdateViewport()` on the first render cycle.

The only other user of `UpdateViewport()` is `VtEngine` which used to call
`InvalidateAll()` in these situations. In order to prevent the `InvalidateAll()`
call, `VtEngine::UpdateViewport()` was modified to suppress this.

## Validation Steps Performed
* Resizing wide characters doesn't crash the terminal anymore 
* The additional call to `UpdateViewport()` doesn't break VtEngine 
2022-05-03 15:45:29 +00:00
YanceyChiew
c9468aa48a change 3 en-dash to hyphen in Microsoft.Terminal.Settings.ModelLib.vcxproj (#13026)
There are 3 en-dashes`(U+2013)` in the file when they should be hyphen `(U+002D)`.
This character causes the file to fail to compile in a non-utf8 encoding environment.

Just modified 3 characters to make it fall within the scope of ascii and keep it consistent with other files of the project.
2022-05-03 03:50:17 +00:00
James Holderness
e3f4ec88ec Prevent the virtual viewport bottom being updated incorrectly (#12972)
The "virtual bottom" marks the last line of the mutable viewport area,
which is the part of the buffer that VT sequences can write to. This
region should typically only move downwards as new lines are added to
the buffer, but there were a number of cases where it was incorrectly
being moved up, or moved down further than necessary. This PR attempts
to fix that.

There was an earlier, unsuccessful attempt to fix this in PR #9770 which
was later reverted (issue #9872 was the reason it had to be reverted).
PRs #2666, #2705, and #5317 were fixes for related virtual viewport
problems, some of which have either been extended or superseded by this
PR.

`SetConsoleCursorPositionImpl` is one of the cases that actually does
need to move the virtual viewport upwards sometimes, in particular when
the cmd shell resets the buffer with a `CLS` command. But when this
operation "snaps" the viewport to the location of the cursor, it needs
to use the virtual viewport as the frame of reference. This was
partially addressed by PR #2705, but that only applied in
terminal-scrolling mode, so I've now applied that fix regardless of the
mode.

`SetViewportOrigin` takes a flag which determines whether it will also
move the virtual bottom to match the visible viewport. In some case this
is appropriate (`SetConsoleCursorPositionImpl` being one example), but
in other cases (e.g. when panning the viewport downwards in the
`AdjustCursorPosition` function), it should only be allowed to move
downwards. We can't just not set the update flag in those cases, because
that also determines whether or not the viewport would be clamped, and
we don't want change that. So what I've done is limit
`SetViewportOrigin` to only move the virtual bottom downwards, and added
an explicit `UpdateBottom` call in those places that may also require
upward movement.

`ResizeWindow` in the `ConhostInternalGetSet` class has a similar
problem to `SetConsoleCursorPositionImpl`, in that it's updating the
viewport to account for the new size, but if that visible viewport is
scrolled back or forward, it would end up placing the virtual viewport
in the wrong place. So again the solution here was to use the virtual
viewport as the frame of reference for the position. However, if the
viewport is being shrunk, this can still result in the cursor falling
below the bottom, so we need an additional check to adjust for that.
This can't be applied in pty mode, though, because that would break the
conpty resizing operation.

`_InternalSetViewportSize` comes into play when resizing the window
manually, and again the viewport after the resize can end up truncating
the virtual bottom if not handled correctly. This was partially
addressed in the original code by clamping the new viewport above the
virtual bottom under certain conditions, and only in terminal scrolling
mode. I've replaced that with a new algorithm which links the virtual
bottom to the visible viewport bottom if the two intersect, but
otherwise leaves it unchanged. This applies regardless of the scrolling
mode.

`ResizeWithReflow` is another sizing operation that can affect the
virtual bottom. This occurs when a change of the window width requires
the buffer to be reflowed, and we need to reposition the viewport in the
newly generated buffer. Previously we were just setting the virtual
bottom to align with the new visible viewport, but that could easily
result in the buffer truncation if the visible viewport was scrolled
back at the time. We now set the virtual bottom to the last non-space
row, or the cursor row (whichever is larger). There'll be edge cases
where this is probably not ideal, but it should still work reasonably
well.

`MakeCursorVisible` was another case where the virtual bottom was being
updated (when requested with a flag) via a `SetViewportOrigin` call.
When I checked all the places it was used, though, none of them actually
required that behavior, and doing so could result in the virtual bottom
being incorrectly positioned, even after `SetViewportOrigin` was limited
to moving the virtual bottom downwards. So I've now made it so that
`MakeCursorVisible` never updates the virtual bottom.

`SelectAll` in the `Selection` class was a similar case. It was calling
`SetViewportOrigin` with the `updateBottom` flag set when that really
wasn't necessary and could result in the virtual bottom being
incorrectly set. I've changed the flag to false now.

## Validation Steps Performed

I've manually confirmed that the test cases in issue #9754 are working
now, except for the one involving margins, which is bigger problem with
`AdjustCursorPosition` which will need to be addressed separately.

I've also double checked the test cases from several other virtual
bottom issues (#1206, #1222, #5302, and #9872), and confirmed that
they're still working correctly with these changes.

And I've added a few screen buffer tests in which I've tried to cover as
many of the problematic code paths as possible.

Closes #9754
2022-05-02 22:19:31 +00:00
Ian O'Neill
96173b9210 Ensure tab close button color matches the text color (#13018)
## Summary of the Pull Request
Ensures the tab close button color matches the text color.

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

## Detailed Description of the Pull Request / Additional comments
Also re-ordered and aligned the properties cleared in the `_ClearTabBackgroundColor()` method to match `_ApplyTabColor()`.

## Validation Steps Performed
Manually tested
2022-05-02 20:05:35 +00:00
Dustin L. Howett
af943bdf94 Make package builds from main end with -experimental (#13003)
BRANCH / BRANDING | Release                    | Preview
------------------|----------------------------|----------------------------
release-*         | 1.12.20220427              | 1.13.20220427-preview
main              | 1.14.20220427-experimental | 1.14.20220427-experimental
all others        | 1.14.20220427-mybranch     | 1.14.20220427-mybranch
2022-04-29 15:59:48 -05:00
Mike Griese
79904361b3 Fix a crash when resizing conhost in Debug (#13001)
Don't clamp here, it's unnecessary. See notes in https://github.com/microsoft/terminal/issues/12917#issuecomment-1101423091

Closes #12917
2022-04-29 14:39:25 -05:00
dansmor7
a7d2885e4b Settings UI tweaks (#12973)
Some changes to the Settings UI:
* Removed borders, made Settings use a single background
* Updated color schemes buttons
* Created DeleteButtonStyle based on accent button - closes #10454

![image](https://user-images.githubusercontent.com/101892345/164984872-0fc75dc6-b4c0-4273-a2a6-b2b8a8d4d8ca.png)
2022-04-29 11:59:02 +00:00
dansmor7
b63102fb40 Command palette and search box visual tweaks (#12913)
Tweaked command palette and search box to better match the Windows 11 Fluent design:
* Now styled like a normal flyout, with acrylic, shadow and border
* TextBox now uses default style
* Tweaked button and key chord designs
* Adjusted spacing

Fixes #12968.

![searchlight](https://user-images.githubusercontent.com/101892345/163623805-3b860942-7e2e-401e-8739-3a966cf2b4a9.png)
![palettelight](https://user-images.githubusercontent.com/101892345/163623825-b1f187fa-557b-4921-86bc-4040ffd2952f.png)
![searchdark](https://user-images.githubusercontent.com/101892345/163623820-b3b7b138-d9af-4aae-a637-8e48717ddd2c.png)
![palettedark](https://user-images.githubusercontent.com/101892345/163623830-448354e6-6b37-4dbe-8cb4-e9275aa56322.png)
2022-04-29 11:58:22 +00:00
Mike Griese
bc73b9a35a Somehow CI missed this 2022-04-28 14:57:23 -05:00
Dustin L. Howett
9611433a98 Build a NuGet Package for ConPTY (#12980)
This pull request introduces a packaging phase that emits
Microsoft.Windows.Console.ConPTY, a nuget package that contains the
pseudoconsole API as well as the requisite copies of conhost.

* winconpty learned to load a version of OpenConsole.exe specific to the
  processor architecture on its hosting machine
* the package, as well as its contents, is signed properly and is nearly
  ready for distribution via nuget.org
* the API in conpty-static.h has been adjusted to expose
  CreatePseudoConsoleAsUser and stamp out the correct DLL import/export
  annotations.
* getting .NET to play right was somewhat challenging, but I tested this
  against .NET 6.0 and it seemed to work properly; it shipped conpty.dll
  in the right places, and it shipped OpenConsole.exe next to the
  published application.

In the future, we could provide an interop assembly for C# consumers;
that is, unfortunately, out of scope today.

Closes #3577
Closes #3568
Obsoletes #1130
2022-04-27 21:45:15 +00:00
Michael Niksa
6b936d9a74 Propagate show/hide window calls against the ConPTY pseudo window to the Terminal (#12515)
Propagate show/hide window calls against the ConPTY pseudo window to the Terminal

## PR Checklist
* [x] Closes #12570 
* [x] I work here
* [x] Manual Tests passed
* [x] Spec Link: →[Doc Link](https://github.com/microsoft/terminal/blob/dev/miniksa/msgs/doc/specs/%2312570%20-%20Show%20Hide%20operations%20on%20GetConsoleWindow%20via%20PTY.md)←

## Detailed Description of the Pull Request / Additional comments
- See the spec. It's pretty much everything I went through deciding on this.

## Validation Steps Performed
- [x] Manual validation against scratch application calling all of the `::ShowWindow` commands against the pseudo console "fake window" and observing the real terminal window state
2022-04-27 18:20:14 +00:00
Dustin L. Howett
d891e052f1 Exclude the NuGet prerelease suffix in branded release-* builds (#12984)
If we are building a branch called "release-*", we will also change the
NuGet suffix to "preview". If we don't do that, XES will set the suffix
to "release1" because it truncates the value after the first period. In
general, though, we want to disable the suffix entirely if we're Release
branded while on a release branch.

In effect:
BRANCH / BRANDING | Release                | Preview
------------------|------------------------|------------------------
release-*         | 1.12.20220427          | 1.13.20220427-preview
all others        | 1.14.20220427-mybranch | 1.14.20220427-mybranch
2022-04-27 12:03:07 -05:00
Nicolas Abram
d8379ff1d5 Add experimental setting to make bg images fit the whole tab (#12893)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
## Summary of the Pull Request
Fixes #6028
Setting is "experimental.useBackgroundImageForWindow"

<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> 
## References
https://github.com/microsoft/terminal/issues/6028
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [X] Closes #6028
* [X] CLA signed.
* [ ] Tests added/passed
* [ ] Documentation updated. I read CONTRIBUTING.md, but I'm not sure if a spec is needed for an experimental feature such as this one.
* [ ] Schema updated. I added a JSON key, not sure where I need to update it.
* [X] I've discussed this with core contributors already. Somewhat discussed in https://github.com/microsoft/terminal/issues/6028

<!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here
## Detailed Description of the Pull Request / Additional comments -->

<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Set ` "experimental.useBackgroundImageForWindow": true` and a bg image for one profile, then make splits and tabs and make sure the bg updates accordingly:
![xqMUWpo1JK](https://user-images.githubusercontent.com/24706838/162996037-ce2ec077-d0e8-43ab-ad5b-0e5c0354fc30.gif)
I also did the same with the setting off to make sure it still works correctly and didn't break. And I made sure opening the settings tab does not crash or show the bg image.
2022-04-27 16:57:01 +00:00
Leonard Hecker
57c3953aca Use type inference throughout the project (#12975)
#4015 requires sweeping changes in order to allow a migration of our buffer
coordinates from `int16_t` to `int32_t`. This commit reduces the size of
future commits by using type inference wherever possible, dropping the
need to manually adjust types throughout the project later.

As an added bonus this commit standardizes the alignment of cv qualifiers
to be always left of the type (e.g. `const T&` instead of `T const&`).

The migration to type inference with `auto` was mostly done
using JetBrains Resharper with some manual intervention and the
standardization of cv qualifier alignment using clang-format 14.

## References

This is preparation work for #4015.

## Validation Steps Performed
* Tests pass 
2022-04-25 15:40:47 +00:00
dansmor7
fa25dfbf7a Misc visual fixes (#12916)
Fixed various small issues:
* Made TabView bottom border span the entire window width
* Made ScrollBar inner thumb rounded again
* Made SplitButton look more like the new add tab button
* Adjusted rename box height (24px, like the official compact sizing height)
* Adjusted caption button colors to match Windows 11
* ColorPicker can now escape window bounds
* Tweaked ColorPicker buttons
2022-04-21 22:34:55 +00:00
Mike Griese
87f5034db1 Plumb Focus events through VT Input (#12900)
Further builds on #12799. #12799 assumes that the connection is prepared to receive FocusIn/FocusOut events as input. For ConPTY we can be relatively sure of that, but that's not _technically_ correct. In the hypothetical world where the connection is not a ConPTY connection, then the other side might not be expecting those sequences. 

This remedies the issue by
* ConPTY will always request focus event mode (from the terminal) when it starts up
* when a client tries to disable focus events in conpty, conpty is gonna note that internally, but never transmit that to the hosting terminal, to leave the terminal in focus event mode.
* `TerminalDispatch` and `ControlCore` are hooked up now to only send focus events when the Terminal is in focus event mode (which will be always for conpty)
* At this point, it was like, 4LOC in `terminalInput.cpp` to add support for focus events to conhost as well.

## checklist
* [x] closes #11682
  * This combined with #12515 will finally close out #2988 as well, but we can do that manually.
* [x] I work here
* [ ] There aren't tests for this. There probably should be.
2022-04-20 18:22:42 +00:00
Leonard Hecker
7af134cc7f Introduce VTInt to represent VT parameters (#12207)
This commit replaces our use of `size_t` to represent VT parameters with
`int32_t`. While unsigned integers have the inherent benefit of being less
ambiguous and enjoying two's complement, our buffer coordinates use signed
integers. Since a number of VT functions need to convert their parameters
to coordinates, this commit makes the conversion easier.
The benefit of this change becomes even more apparent if one considers
that a number of places performed unsafe conversions
of their size_t parameters to int or short already.

Files that had to be modified were converted to use til
wrappers instead of COORD or SMALL_RECT wherever possible.

## References

This commit contains about 20% of the work for #4015.

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

## Validation Steps Performed
I'm mostly relying on our unit tests here. Both OpenConsole and WT appear to work fine.
2022-04-20 11:21:41 +00:00
Mike Griese
0da5bd7726 Ensure a terminal requesting FG rights actually has them (#12899)
#### ⚠️ _Targets #12799_ ⚠️

This is an atomic bit of code that partners with #12799. It's separated as an individual PR to keep diffs more simple. 

This ensures that when a terminal tells ConPTY that it's focused, that ConPTY doesn't do the `ConsoleControl(CONSOLE_FOREGROUND` thing unless the terminal application is actually in the foreground. This prevents a trivial exploit whereby a `malicious.exe` could create a PTY, tell ConPTY it has focus (when it doesn't), then use this mechanism to launch an instance of itself into the foreground. 

When the terminal tells us it's in the foreground, we're gonna look at the owner of the ConPTY window handle. If that owner has focus, then cool, this is allowed. Otherwise, we won't grant them the FG right. For this to work, the terminal just have already called `ReparentPseudoConsole`.

* built on top of #12799 and #12526
* [x] Part of #2988
* [x] Tested manually.
2022-04-19 16:26:33 -05:00
Mike Griese
a496af3614 Allow windows created by console apps to appear above the Terminal (#12799)
## Window shenanigans, part the third:

Hooks the Terminal's focus state up to the underlying ConPTY. This is LOAD BEARING for allowing windows created by console applications to bring themselves to the foreground.

We're using the [FocusIn/FocusOut](https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-FocusIn_FocusOut) sequences to communicate to ConPTY when a control gains/loses focus. Theoretically, other terminals could do this as well.

## References

#11682 tracks _real_ support for this sequence in Console & conpty. When we do that, we should consider even if a client application disables this mode, the Terminal & conpty should always request this from the hosting terminal (and just ignore internally to ConPTY).

See also #12515, #12526, which are the other two parts of this effort. This was tested with all three merged together, and they worked beautifully for all our scenarios. They are kept separate for ease of review.

## PR Checklist
* [x] This is prototype 3 for #2988
* [x] I work here
* [ ] Tests added/passed
* [n/a] Requires documentation to be updated

## Detailed Description of the Pull Request / Additional comments

This allows windows spawned by console processes to bring themselves to the foreground _when the console is focused_. (Historically, this is also called in the WndProc, when focus changes).

Notably, before this, ConPTY was _never_ focused, so windows could never bring themselves to the foreground when run from a ConPTY console. We're not blanket granting the SetForeground right to all console apps when run in ConPTY. It's the responsibility of the hosting terminal emulator to always tell ConPTY when a particular instance is focused.

## Validation Steps Performed

(gif below)
2022-04-19 14:19:59 -05:00
John Melas
b7e4701bb9 Add some missing breaks to cases in IslandWindow (#12926)
Closes #12923
2022-04-18 17:44:50 -05:00
Dustin L. Howett
27b63ad02a git2git: remove some more things from the OS build (#12931)
This will result in the deletion of the following directories from the OS tree, under `onecore/windows/core/console/open`:

* doc/
* src/tools/MonarchPeasantPackage/
* src/api-ms-win-core-synch-l1-2-0/
* src/tools/ansi-color/
* src/tools/ColorTool/

We have gotten some PoliCheck flags on `doc/` (thanks to Niksa.md), but also the OS build just doesn't need these folders 😄
2022-04-18 19:35:58 +00:00
Leonard Hecker
0138a6f640 Fix profile commandlines being overwritten by profile.defaults (#12906)
#12149 introduced a bug where `ClearCommandline()` is called on any user
profile containing the non-canonical strings "cmd.exe" or "powershell.exe"
in the "commandline" field. If you happen to have set the "commandline"
field in your `profiles.defaults`, this will cause these user profiles
to adopt the base layer command-line instead of the defaults layer one.

This commit fixes the issue, by checking the command-line after the call
to `ClearCommandline()` and ensuring it's the expected string.

Additionally this moves the migration logic to `SettingsLoader` as this allows
us to write the fixed settings to disk, if any fixed had to be applied.

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

## Validation Steps Performed
* The modified unit test fails without these changes 
* The modified unit test succeeds with these changes 
* Setting `profiles.defaults.commandline` to "pwsh.exe" and setting
  my "...\\powershell.exe" profile to use just "powershell.exe" as
  the `commandline`, doesn't cause it to use "pwsh.exe" 
  The fixed settings are written to settings.json 
2022-04-18 19:15:21 +00:00
Mike Griese
f0d083118c Add support for rich code navigation in GitHub, redux (#12910)
This is exactly the same as #12855, save for one small difference:

```diff
diff --git a/build/pipelines/ci.yml b/build/pipelines/ci.yml
index e4e53e9b2..dc9040aeb 100644
--- a/build/pipelines/ci.yml
+++ b/build/pipelines/ci.yml
@@ -99,7 +99,6 @@ stages:
   - stage: CodeIndexer
     displayName: Github CodeNav Indexer
     dependsOn: [Build_x64]
-    condition: succeeded()
+    condition: and(succeeded(), not(eq(variables['Build.Reason'], 'PullRequest')))
     jobs:
       - template: ./templates/codenav-indexer.yml
-    condition: not(eq(variables['Build.Reason'], 'PullRequest'))

```

Because the first ones failed with an error about a duplicate condition
And that hosed the whole CI
2022-04-18 13:41:19 -05:00
Mike Griese
41ef5554f5 Don't reflow the alt buffer on resize (#12719)
VTE only rewraps the contents of the (normal screen + its scrollback
buffer) on a resize event. It doesn't rewrap the contents of the
alternate screen. The alternate screen is used by applications which
repaint it after a resize event. So, it doesn't really matter. However,
in that short time window, after resizing the terminal but before the
application catches up, this prevents vertical lines

It was really hard to get a gif of this where it happened and was small
enough to upload to GH, but there is one in #12719.

There's something in this branch that fixes a scrolling issue in the
parent PR. I'm partially filing this so I can look at the diffs here and
try and figure out what that is. I kinda want to just take all 3 alt
buffer PRs as a single atomic unit, but splitting them up made sense
from a review standpoint.

Closes #3493
2022-04-15 02:33:34 +00:00
Dustin L. Howett
30383ccc22 Revert "Add support for rich code navigation in GitHub (#12855)" (#12909)
This reverts commit 23ff07218e, as it broke CI.
2022-04-14 20:57:31 -05:00
Leonard Hecker
eeb8970c6c Another attempt at fixing nearby font loading (#12904)
The original research for a solution all the way back in #11032 contained an
unfortunate flaw. The nearby font loading code was written under the assumption
that Cascadia is missing in the system font collection, leading to our issues.
Adding nearby fonts last into the collection would thus ensure that we use
the system fonts whenever possible, but only have nearby fonts as a fallback.

This didn't work and we figured that we'd have to always prefer loading nearby
fonts over system fonts. #12554 tried to achieve this, but failed to change
the order in which the font set is built. In order to prefer nearby fonts
over system ones, we have to add the system font collection last.

## PR Checklist

* [x] Closes #11648
* [x] I work here
* [x] Tests added/passed
* [x] Embarrassment for my incompetence

## Validation Steps Performed

* Put Jetbrains Mono into the AppX directory of the Debug build
* Jetbrains Mono shows up in the font selector and is useable

Additionally a more complex mini-test was built:
Using FontForge I've cloned arial.ttf and removed all characters except for
the letter "0". Afterwards I've build a custom font collection the same way
we do it in Terminal, extracted a `FontFace` named "Arial" and called
`IDWriteFont::HasCharacter` for the letter "1".
Loading the system font collection first results in `TRUE` and loading it last
results in `FALSE` (since my custom arial.ttf doesn't have the letter "1").
This confirms that we need to load the system font collection last.
2022-04-14 22:05:33 +00:00
Mike Griese
23ff07218e Add support for rich code navigation in GitHub (#12855)
We discussed this with the GitHub folks. It's pretty cool.

(Rich code nav) brings editor-level navigation capabilities into
GitHub.com for C++ and C# repos

If you want to try it out, you can go to github.dev for this repo.

If you haven't used github.dev before there are two steps to get setup:

1. In the settings file you'll need to enable Rich Code Nav. If you just
   search for "rich", there'll be a checkbox to enable it.
2. Refresh the page and you should see a stacked papers icon in the task
   bar at the bottom. Click on that and select "Latest Index". Then one
   more refresh and you should be good to go with navigation in both C#
   and C++ files!
2022-04-14 15:46:34 -05:00
James Holderness
7f5caa1ba7 Further refactor and simplify the ConGetSet API (#12703)
This is an attempt to simplify the `ConGetSet` interface down to the
smallest set of methods necessary to support the `AdaptDispatch` class.
The idea is that it should then be easier to implement that interface in
Windows Terminal, so we can replace the `TerminalDispatch` class with
`AdaptDispatch`.

This is a continuation of the refactoring started in #12247, and a
significant step towards #3849.

## Detailed Description of the Pull Request / Additional comments

The general idea was to give the `AdaptDispatch` class direct access to
the high-level structures on which it needs to operate. Some of these
structures are now passed in when the class is constructed (the
`Renderer`, `RenderSettings`, and `TerminalInput`), and some are exposed
as new methods in `ConGetSet` (`GetStateMachine`, `GetTextBuffer`, and
`GetViewport`).

Many of the existing `ConhostInternalGetSet` methods could easily then
be reimplemented in `AdaptDispatch`, since they were often simply
forwarding to methods in one of the above structures. Some were a little
more complicated, though, and require further explanation.

* `GetConsoleScreenBufferInfoEx`: What we were typically using this for
  was to obtain the viewport, although what we really wanted was the
  virtual viewport, which is now accessible via the `GetViewport`
  method. This was also used to obtain the cursor position and buffer
  width, which we can now get via the `GetTextBuffer` method.

* `SetConsoleScreenBufferInfoEx`: This was only really used for the
  `AdaptDispatch::SetColumns` implementation (for `DECCOLM` mode), and
  that could be replaced with `ResizeWindow`. This is a slight change in
  behaviour (it sizes the window rather than the buffer), but neither is
  technically correct for `DECCOLM`, so I think it's good enough for
  now, and at least it's consistent with the other VT sizing operations.

* `SetCursorPosition`: This could mostly be replaced with direct
  manipulation of the `Cursor` object (accessible via the text buffer),
  although again this is a slight change in behavior. The original code
  would also have made a call to `ConsoleImeResizeCompStrView` (which I
  don't think is applicable to VT movement), and would potentially have
  moved the viewport (not essential for now, but could later be
  supported by `DECHCCM`). It also called `VtIo::SetCursorPosition` to
  handle cursor inheritance, but that should only apply to
  `InteractDispatch`, so I've moved that to the
  `InteractDispatch::MoveCursor` method.

* `ScrollRegion`: This has been replaced by two simple helper methods in
  `AdaptDispatch` which better meet the VT requirements -
  `_ScrollRectVertically` and `_ScrollRectHorizontally`. Unlike the
  original `ScrollRegion` implementation, these don't generate
  `EVENT_CONSOLE_UPDATE_SCROLL` events (see #12656 for more details).

* `FillRegion`: This has been replaced by the `_FillRect` helper method
  in `AdaptDispatch`. It differs from the original `FillRegion` in that
  it takes a rect rather than a start position and length, which gives
  us more flexibility for future operations.

* `ReverseLineFeed`: This has been replaced with a somewhat refactored
  reimplementation in `AdaptDispatch`, mostly using the
  `_ScrollRectVertically` helper described above.

* `EraseAll`: This was previously handled by
  `SCREEN_INFORMATION::VtEraseAll`, but has now been entirely
  reimplemented in the `AdaptDispatch::_EraseAll` method.

* `DeleteLines`/`InsertLines`/`_modifyLines`: These have been replaced
  by the `_InsertDeleteLineHelper` method in `AdaptDispatch`, which
  mostly relies on the `_ScrollRectVertically` helper described above.

Finally there were a few methods that weren't actually needed in the
`ConGetSet` interface:

* `MoveToBottom`: This was really just a hack to get the virtual
  viewport from `GetConsoleScreenBufferInfoEx`. We may still want
  something like in the future (e.g. to support `DECVCCM` or #8879), but
  I don't think it's essential for now.

* `SuppressResizeRepaint`: This was only needed in `InteractDispatch`
  and `PtySignalInputThread`, and they could easily access the `VtIo`
  object to implement it themselves.

* `ClearBuffer`: This was only used in `PtySignalInputThread`, and that
  could easily access the buffer directly via the global console
  information.

* `WriteControlInput`: This was only used in `InteractDispatch`, and
  that could easily be replaced with a direct call to
  `HandleGenericKeyEvent`.

As part of these changes, I've also refactored some of the existing
`AdaptDispatch` code:

* `_InsertDeleteHelper` (renamed `_InsertDeleteCharacterHelper`) is now
  just a straightforward call to the new `_ScrollRectHorizontally`
  helper.

* `EraseInDisplay` and `EraseInLine` have been implemented as a series
  of `_FillRect` calls, so `_EraseSingleLineHelper` is no longer
  required.

* `_EraseScrollback` is a essentially a special form of scrolling
  operation, which mostly depends on the `TextBuffer::ScrollRows`
  method, and with the filling now provided by the new `_FillRect`
  helper.

* There are quite a few operations now in `AdaptDispatch` that are
  affected by the scrolling margins, so I've pulled out the common
  margin setup into a new `_GetVerticalMargins` helper method. This also
  fixes some edge cases where margins could end up out of range.

## Validation Steps Performed
There were a number of unit tests that needed to be updated to work
around functions that have now been removed, but these substitutions
were fairly straightforward for the most part.

The adapter tests were a different story, though. In that case we were
explicitly testing how operations were passed through to the `ConGetSet`
interface, but with more than half those methods now gone, a significant
rewrite was required.

I've tried to retain the crux of the original tests, but we now have to
validate the state changes on the underlying data structures, where
before that state would have been tracked in the `TestGetSet` mock. And
in some cases we were testing what happened when a method failed, but
since that scenario is no longer possible, I've simply removed those
tests.

I've also tried to manually test all the affected operations to confirm
that they're still working as expected, both in vttest as well as my own
test scripts.

Closes #12662
2022-04-14 00:08:40 +00:00
Peretz Cohen
1b997559d3 Update README.md with prerequisite of Targeting Pack (#12896)
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes #12733
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
2022-04-13 17:05:13 +00:00
Mike Griese
9905192e1c Add support for alternate scroll mode in Terminal (#12569)
"Alternate scroll mode" is a neat little mode where the app wants mouse wheel events to come through as arrow keypresses instead, when in the alternate buffer. Now that we've got support for the alt buffer in the Terminal, we can support this as well.

* [x] Closes https://github.com/microsoft/terminal/issues/3321
* [x] I work here
* [ ] Tests would be nice

Tested manually with

```bash
printf "\e[?1007h" ; man ps
```
2022-04-12 23:00:46 +00:00
Mike Griese
26d67d9c0a Enable the Terminal to tell ConPTY who the owner is (#12526)
## Window shenanigans, part the first:

This PR enables terminals to tell ConPTY what the owning window for the
pseudo window should be. This allows thigs like MessageBoxes created by
console applications to work. It also enables console apps to use
`GetAncestor(GetConsoleWindow(), GA_ROOT)`  to get directly at the HWND
of the Terminal (but _don't please_).

This is tested with our internal partners and seems to work for their
scenario. 

See #2988, #12799, #12515, #12570.

## PR Checklist
This is 1/3 of #2988.
2022-04-12 17:44:01 -05:00
Mike Griese
13fb1f58d0 Enable using the alt buffer in the Terminal (#12561)
This PR allows the Terminal to actually use the alt buffer
appropriately. Currently, we just render the alt buffer state into the
main buffer and that is wild. It means things like `vim` will let the
user scroll up to see the previous history (which it shouldn't).

Very first thing this PR does: updates the
`{Trigger|Invalidate}Circling` methods to instead be
`{Trigger|Invalidate}Flush(bool circling)`. We need this so that when an
app requests the alt buffer in conpty, we can immediately flush the
frame before asking the Terminal side to switch to the other buffer. The
`Circling` methods was a great place to do this, but we don't actually
want to set the circled flag in VtRenderer when that happens just for a
flush. 

The Terminal's implementation is a little different than conhost's.
Conhost's implementation grew organically, so I had it straight up
create an entire new screen buffer for the alt buffer. The Terminal
doesn't need all that! All we need to do is have a separate `TextBuffer`
for the alt buffer contents. This makes other parts easier as well - we
don't really need to do anything with the `_mutableViewport` in the alt
buffer, because it's always in the same place. So, we can just leave it
alone and when we come back to the main buffer, there it is. Helper
methods have been updated to account for this. 

* [x] Closes #381
* [x] Closes #3492
* #3686, #3082, #3321, #3493 are all good follow-ups here.
2022-04-12 17:19:46 -05:00
Ítalo Masserano
7648411ade Create #4066 - Theme-controlled color scheme switch.md (#12613)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
## Summary of the Pull Request
Specs for feature request "Theme-controlled color scheme switch".

<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> 
## References
#4066
2022-04-12 11:02:05 +00:00
Mike Griese
b64fd774ce Remove default_interface from Monarch (#12856)
This is all of course, conjecture. This crash is totally wild and makes no sense at all. But, we're hoping that this fixes it. This should also make calls to the Monarch a little easier.

You may be asking yourself - why aren't I doing this for the Peasant too? Well, because the Peasant simply doesn't crash like the monarch does. I'm not gonna touch something that's not broken _during ask mode_.

References #12774. We can close the bug if it is verified fixed.
2022-04-08 14:06:40 -05:00
Leonard Hecker
10b9044120 Fix DBCS attribute corruption during reflow (#12853)
855e136 contains a regression which breaks buffer reflow if wide surrogate
characters are present. This happens because we made use of the
`TextBufferCellIterator` whose increment operator skips 2 cells for wide
characters. This created a "misalignment" in the reflow logic which was written
for cell-wise iteration. This commit fixes the issue, by reverting back to the
previous algorithm without iterators.

Closes #12837
Closes MSFT-38904421

## Validation Steps Performed
* Run ``pwsh -noprofile -command echo "`u{D83D}`u{DE43}"``
* Resizing conhost preserves all contents 
* Resizing Windows Terminal doesn't crash it 
* Added a test covering this issue 
2022-04-08 17:26:16 +00:00
Michael Grier
fe618fd2ae Fix retail build breaks with unreferenced locals (Closes #12769) (#12851)
Closes #12769
2022-04-07 17:41:32 +00:00
Mike Griese
866d22e3a1 Manually focus the scheme dropdown when deleting a scheme (#12841)
If we delete a scheme, and the next scheme we've loaded is an inbox one
that _can't_ be deleted, then we need to toss focus to something
sensible, rather than letting it fall out to the tab item.

When deleting a scheme and the next scheme _is_ deletable, this isn't an
issue, we'll already correctly focus the Delete button.

125e9c4790 focused the SelectionBackground
button, which is the _previous_ focusable control, rather than the
following one.

However, it seems even more useful for focus to ALWAYS land on the
scheme dropdown box. This forces Narrator to read the name of the newly
selected color scheme, which seemed more useful.

I'm waiting on feedback from a11y team to see if this solution is
acceptable.

* [x] Is for #11971
2022-04-07 00:15:49 +00:00
Dustin L. Howett
cdffc99f76 Upgrade WinUI2 to 2.7.1 (#12847)
This fixes a number of issues including a NavigationView crash.
2022-04-06 22:23:04 +00:00
Mike Griese
c4e5ebf238 Manually put our ContentDialogs in the tab content, rather than above (#12840)
After switching to ControlsV2, it seems that
delay-loading a dialog causes the ContentDialog to be assigned a
Height equal to it's content size. If we DON'T assign the
ContentDialog a Row, I believe it's assigned Row 0 by default. So,
when the dialog gets opened, the dialog seemingly causes a giant
hole to appear in the body of the app.

Assigning all the dialogs to Row 2 (where the rest of the content
is) makes the "hole" appear in the same space as the rest of the
TabContent, fixing the issue.

Note that the actual content in a content dialog gets parented to
the PopupRoot, so it actually always appeared in the correct place, it's
just this weird hole that appeared in Row 0.


* [x] Closes #12775
  * See also: 
    * #12202 was fixed by #12208
    * #12447 was fixed by #12517
* [x] Tested manually
* [x] Reverts #12625
* [x] Reverts #12517
2022-04-06 20:29:07 +00:00
Josh Soref
5dbdc6910a Spelling / Grammar (#12835)
Mostly this is dropping doubled words. There's one brand fix.

## Detailed Description of the Pull Request / Additional comments

I'm close to shipping an [upgrade to check-spelling](https://github.com/check-spelling/check-spelling/releases/tag/v0.0.20-alpha5), but in testing it against this repository, I see one behavior change that I'd like to resolve. So, while I try to figure out how, I figured I'd at least leave the fixes submitted.

(I have some ideas, as I've been slowly working towards a solution to this problem, but it isn't a simple one line change.)

## Validation Steps Performed

[Ran check-spelling v0.0.20-alpha5](https://github.com/check-spelling/terminal/actions/runs/2100515961) w/ a refresh of the configuration based on https://github.com/check-spelling/spell-check-this/tree/prerelease/.github/workflows/

(It identified one minor bug which is fixed in 0.0.20-alpha6 - unreleased.)
2022-04-06 20:16:20 +00:00
Mike Griese
475b38a905 Make sure we have a sensible HC color for the titlebar (#12839)
You'd think that if a key wasn't present in a ThemeDictionary, it'd fall back to the original value. You'd be wrong - if you provide a Light&dark version of a resource, but not the HighContrast version, the resource loader will fall back to the _Light_ value. Of course.

Before (left top), after (right bottom)
![image](https://user-images.githubusercontent.com/18356694/161997751-2ed8d053-488a-47fa-a289-8d7b465bd0b0.png)

Closes MSFT:38264744
2022-04-06 17:49:03 +00:00
Mike Griese
89bbbb8d6b Cache ProposeCommandlineResult locally (#12838)
This is like, 2-4% of our crashes. Impossible to say for sure, but this _looks_ like it's the root cause. This is just another one of our `HandleCommandlineArgs` buckets, hopefully the last.

* [x] Hopefully should close out MSFT:38542548
* [ ] No I didn't write tests, impossible to test
* [x] it builds
2022-04-06 15:42:51 +00:00
Mike Griese
9e03800438 Replace RadioButton expanders with ComboBoxes (#12833)
Replaces all the `RadioButton` expanders with `ComboBox`es, which can have the options inline, as opposed to in the expander content. For example, here's a single commit with the changes for a single one of these settings: 745c77d03e

### Checklist
* [x] Closes #12648
* [x] Actually closes #9566 as well (by just removing all radio buttons)
* [x] I work here
* [x] Tested manually
* [x] I'd love @carlos-zamora to have an a11y pass at this, just to see if it's egregious or not.

### Before, after:

![image](https://user-images.githubusercontent.com/18356694/161822068-939ff875-00ff-454a-8b58-cb843ba801f4.png)
2022-04-06 11:16:34 +00:00
641 changed files with 14596 additions and 12634 deletions

View File

@@ -11,7 +11,7 @@ AlignOperands: true
AlignTrailingComments: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Never
AllowShortFunctionsOnASingleLine: Inline
AllowShortFunctionsOnASingleLine: All
AllowShortCaseLabelsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: Never
#AllowShortLambdasOnASingleLine: Inline

15
.github/actions/spelling/README.md vendored Normal file
View File

@@ -0,0 +1,15 @@
# check-spelling/check-spelling configuration
File | Purpose | Format | Info
-|-|-|-
[allow/*.txt](allow/) | Add words to the dictionary | one word per line (only letters and `'`s allowed) | [allow](https://github.com/check-spelling/check-spelling/wiki/Configuration#allow)
[reject.txt](reject.txt) | Remove words from the dictionary (after allow) | grep pattern matching whole dictionary words | [reject](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-reject)
[excludes.txt](excludes.txt) | Files to ignore entirely | perl regular expression | [excludes](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-excludes)
[patterns/*.txt](patterns/) | Patterns to ignore from checked lines | perl regular expression (order matters, first match wins) | [patterns](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-patterns)
[candidate.patterns](candidate.patterns) | Patterns that might be worth adding to [patterns.txt](patterns.txt) | perl regular expression with optional comment block introductions (all matches will be suggested) | [candidates](https://github.com/check-spelling/check-spelling/wiki/Feature:-Suggest-patterns)
[line_forbidden.patterns](line_forbidden.patterns) | Patterns to flag in checked lines | perl regular expression (order matters, first match wins) | [patterns](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-patterns)
[expect/*.txt](expect.txt) | Expected words that aren't in the dictionary | one word per line (sorted, alphabetically) | [expect](https://github.com/check-spelling/check-spelling/wiki/Configuration#expect)
[advice.md](advice.md) | Supplement for GitHub comment when unrecognized words are found | GitHub Markdown | [advice](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-advice)
Note: you can replace any of these files with a directory by the same name (minus the suffix)
and then include multiple files inside that directory (with that suffix) to merge multiple files together.

View File

@@ -1,4 +1,4 @@
<!-- markdownlint-disable MD033 MD041 -->
<!-- See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-advice --> <!-- markdownlint-disable MD033 MD041 -->
<details>
<summary>
:pencil2: Contributor please read this
@@ -6,7 +6,7 @@
By default the command suggestion will generate a file named based on your commit. That's generally ok as long as you add the file to your commit. Someone can reorganize it later.
:warning: The command is written for posix shells. You can copy the contents of each `perl` command excluding the outer `'` marks and dropping any `'"`/`"'` quotation mark pairs into a file and then run `perl file.pl` from the root of the repository to run the code. Alternatively, you can manually insert the items...
:warning: The command is written for posix shells. If it doesn't work for you, you can manually _add_ (one word per line) / _remove_ items to `expect.txt` and the `excludes.txt` files.
If the listed items are:
@@ -20,31 +20,29 @@ See the `README.md` in each directory for more information.
:microscope: You can test your commits **without** *appending* to a PR by creating a new branch with that extra change and pushing it to your fork. The [check-spelling](https://github.com/marketplace/actions/check-spelling) action will run in response to your **push** -- it doesn't require an open pull request. By using such a branch, you can limit the number of typos your peers see you make. :wink:
<details><summary>:clamp: If you see a bunch of garbage</summary>
If it relates to a ...
<details><summary>well-formed pattern</summary>
<details><summary>If the flagged items are :exploding_head: false positives</summary>
See if there's a [pattern](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns) that would match it.
If items relate to a ...
* binary file (or some other file you wouldn't want to check at all).
If not, try writing one and adding it to a `patterns/{file}.txt`.
Please add a file path to the `excludes.txt` file matching the containing file.
Patterns are Perl 5 Regular Expressions - you can [test](
https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your lines.
Note that patterns can't match multiline strings.
</details>
<details><summary>binary-ish string</summary>
Please add a file path to the `excludes.txt` file instead of just accepting the garbage.
File paths are Perl 5 Regular Expressions - you can [test](
File paths are Perl 5 Regular Expressions - you can [test](
https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your files.
`^` refers to the file's path from the root of the repository, so `^README\.md$` would exclude [README.md](
`^` refers to the file's path from the root of the repository, so `^README\.md$` would exclude [README.md](
../tree/HEAD/README.md) (on whichever branch you're using).
</details>
* well-formed pattern.
If you can write a [pattern](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns) that would match it,
try adding it to the `patterns.txt` file.
Patterns are Perl 5 Regular Expressions - you can [test](
https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your lines.
Note that patterns can't match multiline strings.
</details>
</details>

View File

@@ -1,20 +1,21 @@
admins
apc
allcolors
Apc
bsd
apc
breadcrumb
breadcrumbs
bsd
calt
CMMI
ccmp
changelog
clickable
clig
CMMI
copyable
cybersecurity
dalet
dcs
Dcs
dcs
dialytika
dje
downside
@@ -26,36 +27,43 @@ EDDC
Enum'd
Fitt
formattings
FTCS
ftp
fvar
gantt
gcc
geeksforgeeks
ghe
github
gje
godbolt
hostname
hostnames
https
hyperlink
hyperlinking
hyperlinks
iconify
img
inlined
It'd
kje
libfuzzer
libuv
liga
lje
Llast
llvm
Lmid
locl
lol
lorem
Lorigin
maxed
minimalistic
mkmk
mnt
mru
noreply
nje
noreply
ogonek
@@ -76,13 +84,16 @@ runtimes
shcha
slnt
Sos
ssh
timeline
timelines
timestamped
TLDR
tokenizes
tonos
toolset
tshe
ubuntu
uiatextrange
UIs
und
@@ -91,6 +102,7 @@ versioned
vsdevcmd
We'd
wildcards
XBox
YBox
yeru
zhe
allcolors

View File

@@ -5,6 +5,7 @@ aclapi
alignas
alignof
APPLYTOSUBMENUS
appxrecipe
bitfield
bitfields
BUILDBRANCH
@@ -14,6 +15,7 @@ BYCOMMAND
BYPOSITION
charconv
CLASSNOTAVAILABLE
CLOSEAPP
cmdletbinding
COLORPROPERTY
colspan
@@ -28,9 +30,14 @@ dataobject
dcomp
DERR
dlldata
DNE
DONTADDTORECENT
DWMSBT
DWMWA
DWMWA
DWORDLONG
endfor
ENDSESSION
enumset
environstrings
EXPCMDFLAGS
@@ -70,6 +77,7 @@ IDirect
IExplorer
IFACEMETHOD
IFile
IGraphics
IInheritable
IMap
IMonarch
@@ -84,6 +92,7 @@ istream
IStringable
ITab
ITaskbar
itow
IUri
IVirtual
KEYSELECT
@@ -95,12 +104,15 @@ lround
Lsa
lsass
LSHIFT
LTGRAY
MAINWINDOW
memchr
memicmp
MENUCOMMAND
MENUDATA
MENUITEMINFOW
MENUINFO
MENUITEMINFOW
mmeapi
MOUSELEAVE
mov
mptt
@@ -136,14 +148,17 @@ OUTLINETEXTMETRICW
overridable
PACL
PAGESCROLL
PATINVERT
PEXPLICIT
PICKFOLDERS
pmr
ptstr
QUERYENDSESSION
rcx
REGCLS
RETURNCMD
rfind
ROOTOWNER
roundf
RSHIFT
SACL
@@ -153,6 +168,7 @@ serializer
SETVERSION
SHELLEXECUTEINFOW
shobjidl
SHOWHIDE
SHOWMINIMIZED
SHOWTIP
SINGLEUSE
@@ -173,6 +189,8 @@ Stubless
Subheader
Subpage
syscall
SYSTEMBACKDROP
TABROW
TASKBARCREATED
TBPF
THEMECHANGED
@@ -192,6 +210,8 @@ UOI
UPDATEINIFILE
userenv
USEROBJECTFLAGS
Viewbox
virtualalloc
wcsstr
wcstoui
winmain

View File

@@ -1,8 +1,10 @@
Anup
austdi
arkthur
Ballmer
bhoj
Bhojwani
Bluloco
carlos
dhowett
Diviness
@@ -22,6 +24,7 @@ Hernan
Howett
Illhardt
iquilezles
italo
jantari
jerrysh
Kaiyu
@@ -35,7 +38,9 @@ leonmsft
Lepilleur
lhecker
lukesampson
Macbook
Manandhar
masserano
mbadolato
Mehrain
menger
@@ -64,10 +69,13 @@ Rincewind
rprichard
Schoonover
shadertoy
Shomnipotence
simioni
Somuah
sonph
sonpham
stakx
talo
thereses
Walisch
WDX

View File

@@ -0,0 +1,523 @@
# marker to ignore all code on line
^.*/\* #no-spell-check-line \*/.*$
# marker for ignoring a comment to the end of the line
// #no-spell-check.*$
# patch hunk comments
^\@\@ -\d+(?:,\d+|) \+\d+(?:,\d+|) \@\@ .*
# git index header
index [0-9a-z]{7,40}\.\.[0-9a-z]{7,40}
# cid urls
(['"])cid:.*?\g{-1}
# data url in parens
\(data:[^)]*?(?:[A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,})[^)]*\)
# data url in quotes
([`'"])data:.*?(?:[A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,}).*\g{-1}
# data url
data:[-a-zA-Z=;:/0-9+]*,\S*
# mailto urls
mailto:[-a-zA-Z=;:/?%&0-9+@.]{3,}
# magnet urls
magnet:[?=:\w]+
# magnet urls
"magnet:[^"]+"
# obs:
"obs:[^"]*"
# The `\b` here means a break, it's the fancy way to handle urls, but it makes things harder to read
# In this examples content, I'm using a number of different ways to match things to show various approaches
# asciinema
\basciinema\.org/a/[0-9a-zA-Z]+
# apple
\bdeveloper\.apple\.com/[-\w?=/]+
# Apple music
\bembed\.music\.apple\.com/fr/playlist/usr-share/[-\w.]+
# appveyor api
\bci\.appveyor\.com/api/projects/status/[0-9a-z]+
# appveyor project
\bci\.appveyor\.com/project/(?:[^/\s"]*/){2}builds?/\d+/job/[0-9a-z]+
# Amazon
# Amazon
\bamazon\.com/[-\w]+/(?:dp/[0-9A-Z]+|)
# AWS S3
\b\w*\.s3[^.]*\.amazonaws\.com/[-\w/&#%_?:=]*
# AWS execute-api
\b[0-9a-z]{10}\.execute-api\.[-0-9a-z]+\.amazonaws\.com\b
# AWS ELB
\b\w+\.[-0-9a-z]+\.elb\.amazonaws\.com\b
# AWS SNS
\bsns\.[-0-9a-z]+.amazonaws\.com/[-\w/&#%_?:=]*
# AWS VPC
vpc-\w+
# While you could try to match `http://` and `https://` by using `s?` in `https?://`, sometimes there
# YouTube url
\b(?:(?:www\.|)youtube\.com|youtu.be)/(?:channel/|embed/|user/|playlist\?list=|watch\?v=|v/|)[-a-zA-Z0-9?&=_%]*
# YouTube music
\bmusic\.youtube\.com/youtubei/v1/browse(?:[?&]\w+=[-a-zA-Z0-9?&=_]*)
# YouTube tag
<\s*youtube\s+id=['"][-a-zA-Z0-9?_]*['"]
# YouTube image
\bimg\.youtube\.com/vi/[-a-zA-Z0-9?&=_]*
# Google Accounts
\baccounts.google.com/[-_/?=.:;+%&0-9a-zA-Z]*
# Google Analytics
\bgoogle-analytics\.com/collect.[-0-9a-zA-Z?%=&_.~]*
# Google APIs
\bgoogleapis\.(?:com|dev)/[a-z]+/(?:v\d+/|)[a-z]+/[-@:./?=\w+|&]+
# Google Storage
\b[-a-zA-Z0-9.]*\bstorage\d*\.googleapis\.com(?:/\S*|)
# Google Calendar
\bcalendar\.google\.com/calendar(?:/u/\d+|)/embed\?src=[@./?=\w&%]+
\w+\@group\.calendar\.google\.com\b
# Google DataStudio
\bdatastudio\.google\.com/(?:(?:c/|)u/\d+/|)(?:embed/|)(?:open|reporting|datasources|s)/[-0-9a-zA-Z]+(?:/page/[-0-9a-zA-Z]+|)
# The leading `/` here is as opposed to the `\b` above
# ... a short way to match `https://` or `http://` since most urls have one of those prefixes
# Google Docs
/docs\.google\.com/[a-z]+/(?:ccc\?key=\w+|(?:u/\d+|d/(?:e/|)[0-9a-zA-Z_-]+/)?(?:edit\?[-\w=#.]*|/\?[\w=&]*|))
# Google Drive
\bdrive\.google\.com/(?:file/d/|open)[-0-9a-zA-Z_?=]*
# Google Groups
\bgroups\.google\.com/(?:(?:forum/#!|d/)(?:msg|topics?|searchin)|a)/[^/\s"]+/[-a-zA-Z0-9$]+(?:/[-a-zA-Z0-9]+)*
# Google Maps
\bmaps\.google\.com/maps\?[\w&;=]*
# Google themes
themes\.googleusercontent\.com/static/fonts/[^/\s"]+/v\d+/[^.]+.
# Google CDN
\bclients2\.google(?:usercontent|)\.com[-0-9a-zA-Z/.]*
# Goo.gl
/goo\.gl/[a-zA-Z0-9]+
# Google Chrome Store
\bchrome\.google\.com/webstore/detail/[-\w]*(?:/\w*|)
# Google Books
\bgoogle\.(?:\w{2,4})/books(?:/\w+)*\?[-\w\d=&#.]*
# Google Fonts
\bfonts\.(?:googleapis|gstatic)\.com/[-/?=:;+&0-9a-zA-Z]*
# Google Forms
\bforms\.gle/\w+
# Google Scholar
\bscholar\.google\.com/citations\?user=[A-Za-z0-9_]+
# Google Colab Research Drive
\bcolab\.research\.google\.com/drive/[-0-9a-zA-Z_?=]*
# GitHub SHAs (api)
\bapi.github\.com/repos(?:/[^/\s"]+){3}/[0-9a-f]+\b
# GitHub SHAs (markdown)
(?:\[`?[0-9a-f]+`?\]\(https:/|)/(?:www\.|)github\.com(?:/[^/\s"]+){2,}(?:/[^/\s")]+)(?:[0-9a-f]+(?:[-0-9a-zA-Z/#.]*|)\b|)
# GitHub SHAs
\bgithub\.com(?:/[^/\s"]+){2}[@#][0-9a-f]+\b
# GitHub wiki
\bgithub\.com/(?:[^/]+/){2}wiki/(?:(?:[^/]+/|)_history|[^/]+(?:/_compare|)/[0-9a-f.]{40,})\b
# githubusercontent
/[-a-z0-9]+\.githubusercontent\.com/[-a-zA-Z0-9?&=_\/.]*
# githubassets
\bgithubassets.com/[0-9a-f]+(?:[-/\w.]+)
# gist github
\bgist\.github\.com/[^/\s"]+/[0-9a-f]+
# git.io
\bgit\.io/[0-9a-zA-Z]+
# GitHub JSON
"node_id": "[-a-zA-Z=;:/0-9+]*"
# Contributor
\[[^\]]+\]\(https://github\.com/[^/\s"]+\)
# GHSA
GHSA(?:-[0-9a-z]{4}){3}
# GitLab commit
\bgitlab\.[^/\s"]*/\S+/\S+/commit/[0-9a-f]{7,16}#[0-9a-f]{40}\b
# GitLab merge requests
\bgitlab\.[^/\s"]*/\S+/\S+/-/merge_requests/\d+/diffs#[0-9a-f]{40}\b
# GitLab uploads
\bgitlab\.[^/\s"]*/uploads/[-a-zA-Z=;:/0-9+]*
# GitLab commits
\bgitlab\.[^/\s"]*/(?:[^/\s"]+/){2}commits?/[0-9a-f]+\b
# binanace
accounts.binance.com/[a-z/]*oauth/authorize\?[-0-9a-zA-Z&%]*
# bitbucket diff
\bapi\.bitbucket\.org/\d+\.\d+/repositories/(?:[^/\s"]+/){2}diff(?:stat|)(?:/[^/\s"]+){2}:[0-9a-f]+
# bitbucket repositories commits
\bapi\.bitbucket\.org/\d+\.\d+/repositories/(?:[^/\s"]+/){2}commits?/[0-9a-f]+
# bitbucket commits
\bbitbucket\.org/(?:[^/\s"]+/){2}commits?/[0-9a-f]+
# bit.ly
\bbit\.ly/\w+
# bitrise
\bapp\.bitrise\.io/app/[0-9a-f]*/[\w.?=&]*
# bootstrapcdn.com
\bbootstrapcdn\.com/[-./\w]+
# cdn.cloudflare.com
\bcdnjs\.cloudflare\.com/[./\w]+
# circleci
\bcircleci\.com/gh(?:/[^/\s"]+){1,5}.[a-z]+\?[-0-9a-zA-Z=&]+
# gitter
\bgitter\.im(?:/[^/\s"]+){2}\?at=[0-9a-f]+
# gravatar
\bgravatar\.com/avatar/[0-9a-f]+
# ibm
[a-z.]*ibm\.com/[-_#=:%!?~.\\/\d\w]*
# imgur
\bimgur\.com/[^.]+
# Internet Archive
\barchive\.org/web/\d+/(?:[-\w.?,'/\\+&%$#_:]*)
# discord
/discord(?:app\.com|\.gg)/(?:invite/)?[a-zA-Z0-9]{7,}
# Disqus
\bdisqus\.com/[-\w/%.()!?&=_]*
# medium link
\blink\.medium\.com/[a-zA-Z0-9]+
# medium
\bmedium\.com/\@?[^/\s"]+/[-\w]+
# microsoft
\b(?:https?://|)(?:(?:download\.visualstudio|docs|msdn2?|research)\.microsoft|blogs\.msdn)\.com/[-_a-zA-Z0-9()=./%]*
# powerbi
\bapp\.powerbi\.com/reportEmbed/[^"' ]*
# vs devops
\bvisualstudio.com(?::443|)/[-\w/?=%&.]*
# microsoft store
\bmicrosoft\.com/store/apps/\w+
# mvnrepository.com
\bmvnrepository\.com/[-0-9a-z./]+
# now.sh
/[0-9a-z-.]+\.now\.sh\b
# oracle
\bdocs\.oracle\.com/[-0-9a-zA-Z./_?#&=]*
# chromatic.com
/\S+.chromatic.com\S*[")]
# codacy
\bapi\.codacy\.com/project/badge/Grade/[0-9a-f]+
# compai
\bcompai\.pub/v1/png/[0-9a-f]+
# mailgun api
\.api\.mailgun\.net/v3/domains/[0-9a-z]+\.mailgun.org/messages/[0-9a-zA-Z=@]*
# mailgun
\b[0-9a-z]+.mailgun.org
# /message-id/
/message-id/[-\w@./%]+
# Reddit
\breddit\.com/r/[/\w_]*
# requestb.in
\brequestb\.in/[0-9a-z]+
# sched
\b[a-z0-9]+\.sched\.com\b
# Slack url
slack://[a-zA-Z0-9?&=]+
# Slack
\bslack\.com/[-0-9a-zA-Z/_~?&=.]*
# Slack edge
\bslack-edge\.com/[-a-zA-Z0-9?&=%./]+
# Slack images
\bslack-imgs\.com/[-a-zA-Z0-9?&=%.]+
# shields.io
\bshields\.io/[-\w/%?=&.:+;,]*
# stackexchange -- https://stackexchange.com/feeds/sites
\b(?:askubuntu|serverfault|stack(?:exchange|overflow)|superuser).com/(?:questions/\w+/[-\w]+|a/)
# Sentry
[0-9a-f]{32}\@o\d+\.ingest\.sentry\.io\b
# Twitter markdown
\[\@[^[/\]:]*?\]\(https://twitter.com/[^/\s"')]*(?:/status/\d+(?:\?[-_0-9a-zA-Z&=]*|)|)\)
# Twitter hashtag
\btwitter\.com/hashtag/[\w?_=&]*
# Twitter status
\btwitter\.com/[^/\s"')]*(?:/status/\d+(?:\?[-_0-9a-zA-Z&=]*|)|)
# Twitter profile images
\btwimg\.com/profile_images/[_\w./]*
# Twitter media
\btwimg\.com/media/[-_\w./?=]*
# Twitter link shortened
\bt\.co/\w+
# facebook
\bfburl\.com/[0-9a-z_]+
# facebook CDN
\bfbcdn\.net/[\w/.,]*
# facebook watch
\bfb\.watch/[0-9A-Za-z]+
# dropbox
\bdropbox\.com/sh?/[^/\s"]+/[-0-9A-Za-z_.%?=&;]+
# ipfs protocol
ipfs://[0-9a-z]*
# ipfs url
/ipfs/[0-9a-z]*
# w3
\bw3\.org/[-0-9a-zA-Z/#.]+
# loom
\bloom\.com/embed/[0-9a-f]+
# regex101
\bregex101\.com/r/[^/\s"]+/\d+
# figma
\bfigma\.com/file(?:/[0-9a-zA-Z]+/)+
# freecodecamp.org
\bfreecodecamp\.org/[-\w/.]+
# image.tmdb.org
\bimage\.tmdb\.org/[/\w.]+
# mermaid
\bmermaid\.ink/img/[-\w]+|\bmermaid-js\.github\.io/mermaid-live-editor/#/edit/[-\w]+
# Wikipedia
\ben\.wikipedia\.org/wiki/[-\w%.#]+
# gitweb
[^"\s]+/gitweb/\S+;h=[0-9a-f]+
# HyperKitty lists
/archives/list/[^@/]+\@[^/\s"]*/message/[^/\s"]*/
# lists
/thread\.html/[^"\s]+
# list-management
\blist-manage\.com/subscribe(?:[?&](?:u|id)=[0-9a-f]+)+
# kubectl.kubernetes.io/last-applied-configuration
"kubectl.kubernetes.io/last-applied-configuration": ".*"
# pgp
\bgnupg\.net/pks/lookup[?&=0-9a-zA-Z]*
# Spotify
\bopen\.spotify\.com/embed/playlist/\w+
# Mastodon
\bmastodon\.[-a-z.]*/(?:media/|\@)[?&=0-9a-zA-Z_]*
# scastie
\bscastie\.scala-lang\.org/[^/]+/\w+
# images.unsplash.com
\bimages\.unsplash\.com/(?:(?:flagged|reserve)/|)[-\w./%?=%&.;]+
# pastebin
\bpastebin\.com/[\w/]+
# heroku
\b\w+\.heroku\.com/source/archive/\w+
# quip
\b\w+\.quip\.com/\w+(?:(?:#|/issues/)\w+)?
# badgen.net
\bbadgen\.net/badge/[^")\]'\s]+
# statuspage.io
\w+\.statuspage\.io\b
# media.giphy.com
\bmedia\.giphy\.com/media/[^/]+/[\w.?&=]+
# tinyurl
\btinyurl\.com/\w+
# getopts
\bgetopts\s+(?:"[^"]+"|'[^']+')
# ANSI color codes
(?:\\(?:u00|x)1b|\x1b)\[\d+(?:;\d+|)m
# URL escaped characters
\%[0-9A-F][A-F]
# IPv6
\b(?:[0-9a-fA-F]{0,4}:){3,7}[0-9a-fA-F]{0,4}\b
# c99 hex digits (not the full format, just one I've seen)
0x[0-9a-fA-F](?:\.[0-9a-fA-F]*|)[pP]
# Punycode
\bxn--[-0-9a-z]+
# sha
sha\d+:[0-9]*[a-f]{3,}[0-9a-f]*
# sha-... -- uses a fancy capture
(['"]|&quot;)[0-9a-f]{40,}\g{-1}
# hex runs
\b[0-9a-fA-F]{16,}\b
# hex in url queries
=[0-9a-fA-F]*?(?:[A-F]{3,}|[a-f]{3,})[0-9a-fA-F]*?&
# ssh
(?:ssh-\S+|-nistp256) [-a-zA-Z=;:/0-9+]{12,}
# PGP
\b(?:[0-9A-F]{4} ){9}[0-9A-F]{4}\b
# GPG keys
\b(?:[0-9A-F]{4} ){5}(?: [0-9A-F]{4}){5}\b
# Well known gpg keys
.well-known/openpgpkey/[\w./]+
# uuid:
\b[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}\b
# hex digits including css/html color classes:
(?:[\\0][xX]|\\u|[uU]\+|#x?|\%23)[0-9_a-fA-FgGrR]*?[a-fA-FgGrR]{2,}[0-9_a-fA-FgGrR]*(?:[uUlL]{0,3}|u\d+)\b
# integrity
integrity="sha\d+-[-a-zA-Z=;:/0-9+]{40,}"
# https://www.gnu.org/software/groff/manual/groff.html
# man troff content
\\f[BCIPR]
# '
\\\(aq
# .desktop mime types
^MimeTypes?=.*$
# .desktop localized entries
^[A-Z][a-z]+\[[a-z]+\]=.*$
# Localized .desktop content
Name\[[^\]]+\]=.*
# IServiceProvider
\bI(?=(?:[A-Z][a-z]{2,})+\b)
# crypt
"\$2[ayb]\$.{56}"
# scrypt / argon
\$(?:scrypt|argon\d+[di]*)\$\S+
# Input to GitHub JSON
content: "[-a-zA-Z=;:/0-9+]*="
# Python stringprefix / binaryprefix
# Note that there's a high false positive rate, remove the `?=` and search for the regex to see if the matches seem like reasonable strings
(?<!')\b(?:B|BR|Br|F|FR|Fr|R|RB|RF|Rb|Rf|U|UR|Ur|b|bR|br|f|fR|fr|r|rB|rF|rb|rf|u|uR|ur)'(?:[A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,})
# Regular expressions for (P|p)assword
\([A-Z]\|[a-z]\)[a-z]+
# JavaScript regular expressions
# javascript test regex
/.*/[gim]*\.test\(
# javascript match regex
\.match\(/[^/\s"]*/[gim]*\s*
# javascript match regex
\.match\(/\\[b].*?/[gim]*\s*\)(?:;|$)
# javascript regex
^\s*/\\[b].*/[gim]*\s*(?:\)(?:;|$)|,$)
# javascript replace regex
\.replace\(/[^/\s"]*/[gim]*\s*,
# Go regular expressions
regexp?\.MustCompile\(`[^`]*`\)
# sed regular expressions
sed 's/(?:[^/]*?[a-zA-Z]{3,}[^/]*?/){2}
# go install
go install(?:\s+[a-z]+\.[-@\w/.]+)+
# kubernetes pod status lists
# https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase
\w+(?:-\w+)+\s+\d+/\d+\s+(?:Running|Pending|Succeeded|Failed|Unknown)\s+
# kubectl - pods in CrashLoopBackOff
\w+-[0-9a-f]+-\w+\s+\d+/\d+\s+CrashLoopBackOff\s+
# kubernetes object suffix
-[0-9a-f]{10}-\w{5}\s
# posthog secrets
posthog\.init\((['"])phc_[^"',]+\g{-1},
# xcode
# xcodeproject scenes
(?:Controller|ID|id)="\w{3}-\w{2}-\w{3}"
# xcode api botches
customObjectInstantitationMethod
# font awesome classes
\.fa-[-a-z0-9]+
# Update Lorem based on your content (requires `ge` and `w` from https://github.com/jsoref/spelling; and `review` from https://github.com/check-spelling/check-spelling/wiki/Looking-for-items-locally )
# grep '^[^#].*lorem' .github/actions/spelling/patterns.txt|perl -pne 's/.*i..\?://;s/\).*//' |tr '|' "\n"|sort -f |xargs -n1 ge|perl -pne 's/^[^:]*://'|sort -u|w|sed -e 's/ .*//'|w|review -
# Warning, while `(?i)` is very neat and fancy, if you have some binary files that aren't proper unicode, you might run into:
## Operation "substitution (s///)" returns its argument for non-Unicode code point 0x1C19AE (the code point will vary).
## You could manually change `(?i)X...` to use `[Xx]...`
## or you could add the files to your `excludes` file (a version after 0.0.19 should identify the file path)
# Lorem
(?:\w|\s|[,.])*\b(?i)(?:amet|consectetur|cursus|dolor|eros|ipsum|lacus|libero|ligula|lorem|magna|neque|nulla|suscipit|tempus)\b(?:\w|\s|[,.])*
# Non-English
[a-zA-Z]*[ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź][a-zA-Z]{3}[a-zA-ZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź]*
# French
# This corpus only had capital letters, but you probably want lowercase ones as well.
\b[LN]'+[a-z]{2,}\b
# latex
\\(?:n(?:ew|ormal|osub)|r(?:enew)|t(?:able(?:of|)|he|itle))(?=[a-z]+)
# the negative lookahead here is to allow catching 'templatesz' as a misspelling
# but to otherwise recognize a Windows path with \templates\foo.template or similar:
\\(?:necessary|r(?:eport|esolve[dr]?|esult)|t(?:arget|emplates?))(?![a-z])
# ignore long runs of a single character:
\b([A-Za-z])\g{-1}{3,}\b
# Note that the next example is no longer necessary if you are using
# to match a string starting with a `#`, use a character-class:
[#]backwards
# version suffix <word>v#
(?:(?<=[A-Z]{2})V|(?<=[a-z]{2}|[A-Z]{2})v)\d+(?:\b|(?=[a-zA-Z_]))
# Compiler flags (Scala)
(?:^|[\t ,>"'`=(])-J-[DPWXY](?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,})
# Compiler flags
#(?:^|[\t ,"'`=(])-[DPWXYLlf](?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,})
# Compiler flags (linker)
,-B
# curl arguments
\b(?:\\n|)curl(?:\s+-[a-zA-Z]{1,2}\b)*(?:\s+-[a-zA-Z]{3,})(?:\s+-[a-zA-Z]+)*
# set arguments
\bset(?:\s+-[abefimouxE]{1,2})*\s+-[abefimouxE]{3,}(?:\s+-[abefimouxE]+)*
# tar arguments
\b(?:\\n|)g?tar(?:\.exe|)(?:(?:\s+--[-a-zA-Z]+|\s+-[a-zA-Z]+|\s[ABGJMOPRSUWZacdfh-pr-xz]+\b)(?:=[^ ]*|))+
# tput arguments -- https://man7.org/linux/man-pages/man5/terminfo.5.html -- technically they can be more than 5 chars long...
\btput\s+(?:(?:-[SV]|-T\s*\w+)\s+)*\w{3,5}\b
# macOS temp folders
/var/folders/\w\w/[+\w]+/(?:T|-Caches-)/

View File

@@ -1,28 +1,39 @@
# See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-excludes
(?:(?i)\.png$)
(?:^|/)(?i)COPYRIGHT
(?:^|/)(?i)LICEN[CS]E
(?:^|/)3rdparty/
(?:^|/)dirs$
(?:^|/)go\.mod$
(?:^|/)go\.sum$
(?:^|/)package-lock\.json$
(?:^|/)package(?:-lock|)\.json$
(?:^|/)sources(?:|\.dep)$
SUMS$
(?:^|/)vendor/
\.a$
\.ai$
\.avi$
\.bmp$
\.bz2$
\.cer$
\.class$
\.crl$
\.crt$
\.csr$
\.dll$
\.docx?$
\.drawio$
\.DS_Store$
\.eot$
\.eps$
\.exe$
\.gif$
\.gitattributes$
\.graffle$
\.gz$
\.icns$
\.ico$
\.jar$
\.jks$
\.jpeg$
\.jpg$
\.key$
@@ -30,28 +41,53 @@ SUMS$
\.lock$
\.map$
\.min\..
\.mod$
\.mp3$
\.mp4$
\.o$
\.ocf$
\.otf$
\.pbxproj$
\.pdf$
\.pem$
\.png$
\.psd$
\.pyc$
\.runsettings$
\.s$
\.sig$
\.so$
\.svg$
\.svgz$
\.svgz?$
\.tar$
\.tgz$
\.tiff?$
\.ttf$
\.vsdx$
\.wav$
\.webm$
\.webp$
\.woff
\.woff2?$
\.xcf$
\.xls
\.xlsx?$
\.xpm$
\.yml$
\.zip$
^\.github/actions/spelling/
^\.github/fabricbot.json$
^\.gitignore$
^\Q.git-blame-ignore-revs\E$
^\Q.github/workflows/spelling.yml\E$
^\Qdoc/reference/windows-terminal-logo.ans\E$
^\Qsamples/ConPTY/EchoCon/EchoCon/EchoCon.vcxproj.filters\E$
^\Qsrc/host/exe/Host.EXE.vcxproj.filters\E$
^\Qsrc/host/ft_host/chafa.txt\E$
^\Qsrc/tools/closetest/CloseTest.vcxproj.filters\E$
^\XamlStyler.json$
^build/config/
^consolegit2gitfilters\.json$
^dep/
^doc/reference/master-sequence-list.csv$
@@ -77,6 +113,5 @@ SUMS$
^src/tools/U8U16Test/(?:fr|ru|zh)\.txt$
^src/types/ut_types/UtilsTests.cpp$
^tools/ReleaseEngineering/ServicingPipeline.ps1$
^\.github/actions/spelling/
^\.gitignore$
^\XamlStyler.json$
ignore$
SUMS$

View File

@@ -5,26 +5,19 @@ AAAAAABBBBBBCCC
AAAAABBBBBBCCC
abcd
abcd
abcde
abcdef
ABCDEFG
ABCDEFGH
ABCDEFGHIJ
abcdefghijk
ABCDEFGHIJKLMNO
abcdefghijklmnop
ABCDEFGHIJKLMNOPQRST
abcdefghijklmnopqrstuvwxyz
ABCG
ABE
abf
BBBBB
BBBBBBBB
BBBBBBBBBBBBBBDDDD
BBBBBCCC
BBBBCCCCC
BBGGRR
CCE
EFG
EFGh
QQQQQQQQQQABCDEFGHIJ
@@ -33,7 +26,6 @@ QQQQQQQQQQABCDEFGHIJKLMNOPQRSTQQQQQQQQQQ
QQQQQQQQQQABCDEFGHIJPQRSTQQQQQQQQQQ
qrstuvwxyz
qwerty
QWERTYUIOP
qwertyuiopasdfg
YYYYYYYDDDDDDDDDDD
ZAAZZ

File diff suppressed because it is too large Load Diff

View File

@@ -1,29 +1,6 @@
http
www
easyrgb
php
ecma
rapidtables
WCAG
freedesktop
ycombinator
robertelder
kovidgoyal
leonerd
fixterms
winui
appshellintegration
mdtauk
cppreference
gfycat
Guake
azurewebsites
askubuntu
dostips
viewtopic
rosettacode
Rexx
tldp
HOWTO
uwspace
uwaterloo

View File

@@ -0,0 +1,62 @@
# reject `m_data` as there's a certain OS which has evil defines that break things if it's used elsewhere
# \bm_data\b
# If you have a framework that uses `it()` for testing and `fit()` for debugging a specific test,
# you might not want to check in code where you were debugging w/ `fit()`, in which case, you might want
# to use this:
#\bfit\(
# s.b. GitHub
\bGithub\b
# s.b. GitLab
\bGitlab\b
# s.b. JavaScript
\bJavascript\b
# s.b. Microsoft
\bMicroSoft\b
# s.b. another
\ban[- ]other\b
# s.b. greater than
\bgreater then\b
# s.b. into
#\sin to\s
# s.b. opt-in
\sopt in\s
# s.b. less than
\bless then\b
# s.b. otherwise
\bother[- ]wise\b
# s.b. nonexistent
\bnon existing\b
\b[Nn]o[nt][- ]existent\b
# s.b. preexisting
[Pp]re[- ]existing
# s.b. preempt
[Pp]re[- ]empt\b
# s.b. preemptively
[Pp]re[- ]emptively
# s.b. reentrancy
[Rr]e[- ]entrancy
# s.b. reentrant
[Rr]e[- ]entrant
# s.b. workaround(s)
#\bwork[- ]arounds?\b
# Reject duplicate words
\s([A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,})\s\g{-1}\s

View File

@@ -1,11 +1,6 @@
https://(?:(?:[-a-zA-Z0-9?&=]*\.|)microsoft\.com)/[-a-zA-Z0-9?&=_#\/.]*
https://aka\.ms/[-a-zA-Z0-9?&=\/_]*
https://www\.itscj\.ipsj\.or\.jp/iso-ir/[-0-9]+\.pdf
https://www\.vt100\.net/docs/[-a-zA-Z0-9#_\/.]*
https://www.w3.org/[-a-zA-Z0-9?&=\/_#]*
https://(?:(?:www\.|)youtube\.com|youtu.be)/[-a-zA-Z0-9?&=]*
https://(?:[a-z-]+\.|)github(?:usercontent|)\.com/[-a-zA-Z0-9?%&=_\/.+]*
https://www.xfree86.org/[-a-zA-Z0-9?&=\/_#]*
# See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns
https?://\S+
[Pp]ublicKeyToken="?[0-9a-fA-F]{16}"?
(?:[{"]|UniqueIdentifier>)[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}(?:[}"]|</UniqueIdentifier)
(?:0[Xx]|\\x|U\+|#)[a-f0-9A-FGgRr]{2,}[Uu]?[Ll]{0,2}\b
@@ -28,3 +23,74 @@ vcvars\w*
ROY\sG\.\sBIV
!(?:(?i)ESC)!\[
!(?:(?i)CSI)!(?:\d+(?:;\d+|)m|[ABCDF])
# Python stringprefix / binaryprefix
\b(?:B|BR|Br|F|FR|Fr|R|RB|RF|Rb|Rf|U|UR|Ur|b|bR|br|f|fR|fr|r|rB|rF|rb|rf|u|uR|ur)'
# Automatically suggested patterns
# hit-count: 3831 file-count: 582
# IServiceProvider
\bI(?=(?:[A-Z][a-z]{2,})+\b)
# hit-count: 71 file-count: 35
# Compiler flags
(?:^|[\t ,"'`=(])-[D](?=[A-Z]{2,}|[A-Z][a-z])
(?:^|[\t ,"'`=(])-[X](?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,})
# hit-count: 41 file-count: 28
# version suffix <word>v#
(?:(?<=[A-Z]{2})V|(?<=[a-z]{2}|[A-Z]{2})v)\d+(?:\b|(?=[a-zA-Z_]))
# hit-count: 20 file-count: 9
# hex runs
\b[0-9a-fA-F]{16,}\b
# hit-count: 10 file-count: 7
# uuid:
\b[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}\b
# hit-count: 4 file-count: 4
# mailto urls
mailto:[-a-zA-Z=;:/?%&0-9+@.]{3,}
# hit-count: 4 file-count: 1
# ANSI color codes
(?:\\(?:u00|x)1b|\x1b)\[\d+(?:;\d+|)m
# hit-count: 2 file-count: 1
# latex
\\(?:n(?:ew|ormal|osub)|r(?:enew)|t(?:able(?:of|)|he|itle))(?=[a-z]+)
# hit-count: 1 file-count: 1
# hex digits including css/html color classes:
(?:[\\0][xX]|\\u|[uU]\+|#x?|\%23)[0-9_a-fA-FgGrR]*?[a-fA-FgGrR]{2,}[0-9_a-fA-FgGrR]*(?:[uUlL]{0,3}|u\d+)\b
# hit-count: 1 file-count: 1
# Non-English
[a-zA-Z]*[ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź][a-zA-Z]{3}[a-zA-ZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź]*
# hit-count: 1 file-count: 1
# French
# This corpus only had capital letters, but you probably want lowercase ones as well.
\b[LN]'+[a-z]{2,}\b
# acceptable duplicates
# ls directory listings
[-bcdlpsw](?:[-r][-w][-sx]){3}\s+\d+\s+(\S+)\s+\g{-1}\s+\d+\s+
# C/idl types + English ...
\s(Guid|long|LONG|that) \g{-1}\s
# javadoc / .net
(?:[\\@](?:groupname|param)|(?:public|private)(?:\s+static|\s+readonly)*)\s+(\w+)\s+\g{-1}\s
# Commit message -- Signed-off-by and friends
^\s*(?:(?:Based-on-patch|Co-authored|Helped|Mentored|Reported|Reviewed|Signed-off)-by|Thanks-to): (?:[^<]*<[^>]*>|[^<]*)\s*$
# Autogenerated revert commit message
^This reverts commit [0-9a-f]{40}\.$
# vtmode
--vtmode\s+(\w+)\s+\g{-1}\s
# ignore long runs of a single character:
\b([A-Za-z])\g{-1}{3,}\b

View File

@@ -1,22 +1,12 @@
^attache$
^attacher$
^attachers$
^spae$
^spaebook$
^spaecraft$
^spaed$
^spaedom$
^spaeing$
^spaeings$
^spae-man$
^spaeman$
^spaer$
^Spaerobee$
^spaes$
^spaewife$
^spaewoman$
^spaework$
^spaewright$
^wether$
^wethers$
^wetherteg$
benefitting
occurences?
^dependan.*
^oer$
Sorce
^[Ss]pae.*
^untill$
^untilling$
^wether.*

View File

@@ -1,20 +1,134 @@
# spelling.yml is blocked per https://github.com/check-spelling/check-spelling/security/advisories/GHSA-g86g-chm8-7r2p
name: Spell checking
# Comment management is handled through a secondary job, for details see:
# https://github.com/check-spelling/check-spelling/wiki/Feature%3A-Restricted-Permissions
#
# `jobs.comment-push` runs when a push is made to a repository and the `jobs.spelling` job needs to make a comment
# (in odd cases, it might actually run just to collapse a commment, but that's fairly rare)
# it needs `contents: write` in order to add a comment.
#
# `jobs.comment-pr` runs when a pull_request is made to a repository and the `jobs.spelling` job needs to make a comment
# or collapse a comment (in the case where it had previously made a comment and now no longer needs to show a comment)
# it needs `pull-requests: write` in order to manipulate those comments.
# Updating pull request branches is managed via comment handling.
# For details, see: https://github.com/check-spelling/check-spelling/wiki/Feature:-Update-expect-list
#
# These elements work together to make it happen:
#
# `on.issue_comment`
# This event listens to comments by users asking to update the metadata.
#
# `jobs.update`
# This job runs in response to an issue_comment and will push a new commit
# to update the spelling metadata.
#
# `with.experimental_apply_changes_via_bot`
# Tells the action to support and generate messages that enable it
# to make a commit to update the spelling metadata.
#
# `with.ssh_key`
# In order to trigger workflows when the commit is made, you can provide a
# secret (typically, a write-enabled github deploy key).
#
# For background, see: https://github.com/check-spelling/check-spelling/wiki/Feature:-Update-with-deploy-key
on:
pull_request_target:
push:
branches:
- "**"
tags-ignore:
- "**"
pull_request_target:
branches:
- "**"
tags-ignore:
- "**"
types:
- 'opened'
- 'reopened'
- 'synchronize'
issue_comment:
types:
- 'created'
jobs:
spelling:
name: Spell checking
permissions:
contents: read
pull-requests: read
actions: read
outputs:
followup: ${{ steps.spelling.outputs.followup }}
runs-on: ubuntu-latest
if: "contains(github.event_name, 'pull_request') || github.event_name == 'push'"
concurrency:
group: spelling-${{ github.event.pull_request.number || github.ref }}
# note: If you use only_check_changed_files, you do not want cancel-in-progress
cancel-in-progress: true
steps:
- name: checkout-merge
if: "contains(github.event_name, 'pull_request')"
uses: actions/checkout@v2
- name: check-spelling
id: spelling
uses: check-spelling/check-spelling@v0.0.21
with:
ref: refs/pull/${{github.event.pull_request.number}}/merge
- name: checkout
if: "!contains(github.event_name, 'pull_request')"
uses: actions/checkout@v2
- uses: check-spelling/check-spelling@v0.0.19
suppress_push_for_open_pull_request: 1
checkout: true
check_file_names: 1
spell_check_this: check-spelling/spell-check-this@prerelease
post_comment: 0
use_magic_file: 1
extra_dictionary_limit: 10
extra_dictionaries:
cspell:software-terms/src/software-terms.txt
cspell:python/src/python/python-lib.txt
cspell:node/node.txt
cspell:cpp/src/stdlib-c.txt
cspell:cpp/src/stdlib-cpp.txt
cspell:fullstack/fullstack.txt
cspell:filetypes/filetypes.txt
cspell:html/html.txt
cspell:cpp/src/compiler-msvc.txt
cspell:python/src/common/extra.txt
cspell:powershell/powershell.txt
cspell:aws/aws.txt
cspell:cpp/src/lang-keywords.txt
cspell:npm/npm.txt
cspell:dotnet/dotnet.txt
cspell:python/src/python/python.txt
cspell:css/css.txt
cspell:cpp/src/stdlib-cmath.txt
check_extra_dictionaries: ''
comment-push:
name: Report (Push)
# If your workflow isn't running on push, you can remove this job
runs-on: ubuntu-latest
needs: spelling
permissions:
contents: write
if: (success() || failure()) && needs.spelling.outputs.followup && github.event_name == 'push'
steps:
- name: comment
uses: check-spelling/check-spelling@v0.0.21
with:
checkout: true
spell_check_this: check-spelling/spell-check-this@prerelease
task: ${{ needs.spelling.outputs.followup }}
comment-pr:
name: Report (PR)
# If you workflow isn't running on pull_request*, you can remove this job
runs-on: ubuntu-latest
needs: spelling
permissions:
pull-requests: write
if: (success() || failure()) && needs.spelling.outputs.followup && contains(github.event_name, 'pull_request')
steps:
- name: comment
uses: check-spelling/check-spelling@v0.0.21
with:
checkout: true
spell_check_this: check-spelling/spell-check-this@prerelease
task: ${{ needs.spelling.outputs.followup }}

View File

@@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29001.49
# Visual Studio Version 17
VisualStudioVersion = 17.2.32422.2
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Terminal", "Terminal", "{59840756-302F-44DF-AA47-441A9D673202}"
EndProject
@@ -406,6 +406,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Utils", "Utils", "{61901E80
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RendererAtlas", "src\renderer\atlas\atlas.vcxproj", "{8222900C-8B6C-452A-91AC-BE95DB04B95F}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "InteractivityOneCore", "src\interactivity\onecore\lib\onecore.LIB.vcxproj", "{06EC74CB-9A12-428C-B551-8537EC964726}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RendererWddmCon", "src\renderer\wddmcon\lib\wddmcon.vcxproj", "{75C6F576-18E9-4566-978A-F0A301CAC090}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
AuditMode|Any CPU = AuditMode|Any CPU
@@ -3375,6 +3379,76 @@ Global
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.Release|x64.Build.0 = Release|x64
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.Release|x86.ActiveCfg = Release|Win32
{8222900C-8B6C-452A-91AC-BE95DB04B95F}.Release|x86.Build.0 = Release|Win32
{06EC74CB-9A12-428C-B551-8537EC964726}.AuditMode|Any CPU.ActiveCfg = AuditMode|x64
{06EC74CB-9A12-428C-B551-8537EC964726}.AuditMode|ARM.ActiveCfg = AuditMode|x64
{06EC74CB-9A12-428C-B551-8537EC964726}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64
{06EC74CB-9A12-428C-B551-8537EC964726}.AuditMode|DotNet_x64Test.ActiveCfg = AuditMode|x64
{06EC74CB-9A12-428C-B551-8537EC964726}.AuditMode|DotNet_x86Test.ActiveCfg = AuditMode|x64
{06EC74CB-9A12-428C-B551-8537EC964726}.AuditMode|x64.ActiveCfg = AuditMode|x64
{06EC74CB-9A12-428C-B551-8537EC964726}.AuditMode|x64.Build.0 = AuditMode|x64
{06EC74CB-9A12-428C-B551-8537EC964726}.AuditMode|x86.ActiveCfg = AuditMode|Win32
{06EC74CB-9A12-428C-B551-8537EC964726}.Debug|Any CPU.ActiveCfg = Debug|x64
{06EC74CB-9A12-428C-B551-8537EC964726}.Debug|ARM.ActiveCfg = Debug|x64
{06EC74CB-9A12-428C-B551-8537EC964726}.Debug|ARM64.ActiveCfg = Debug|ARM64
{06EC74CB-9A12-428C-B551-8537EC964726}.Debug|ARM64.Build.0 = Debug|ARM64
{06EC74CB-9A12-428C-B551-8537EC964726}.Debug|DotNet_x64Test.ActiveCfg = Debug|x64
{06EC74CB-9A12-428C-B551-8537EC964726}.Debug|DotNet_x86Test.ActiveCfg = Debug|x64
{06EC74CB-9A12-428C-B551-8537EC964726}.Debug|x64.ActiveCfg = Debug|x64
{06EC74CB-9A12-428C-B551-8537EC964726}.Debug|x64.Build.0 = Debug|x64
{06EC74CB-9A12-428C-B551-8537EC964726}.Debug|x86.ActiveCfg = Debug|Win32
{06EC74CB-9A12-428C-B551-8537EC964726}.Debug|x86.Build.0 = Debug|Win32
{06EC74CB-9A12-428C-B551-8537EC964726}.Fuzzing|Any CPU.ActiveCfg = Fuzzing|x64
{06EC74CB-9A12-428C-B551-8537EC964726}.Fuzzing|ARM.ActiveCfg = Fuzzing|x64
{06EC74CB-9A12-428C-B551-8537EC964726}.Fuzzing|ARM64.ActiveCfg = Fuzzing|ARM64
{06EC74CB-9A12-428C-B551-8537EC964726}.Fuzzing|DotNet_x64Test.ActiveCfg = Fuzzing|x64
{06EC74CB-9A12-428C-B551-8537EC964726}.Fuzzing|DotNet_x86Test.ActiveCfg = Fuzzing|x64
{06EC74CB-9A12-428C-B551-8537EC964726}.Fuzzing|x64.ActiveCfg = Fuzzing|x64
{06EC74CB-9A12-428C-B551-8537EC964726}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32
{06EC74CB-9A12-428C-B551-8537EC964726}.Release|Any CPU.ActiveCfg = Release|x64
{06EC74CB-9A12-428C-B551-8537EC964726}.Release|ARM.ActiveCfg = Release|x64
{06EC74CB-9A12-428C-B551-8537EC964726}.Release|ARM64.ActiveCfg = Release|ARM64
{06EC74CB-9A12-428C-B551-8537EC964726}.Release|ARM64.Build.0 = Release|ARM64
{06EC74CB-9A12-428C-B551-8537EC964726}.Release|DotNet_x64Test.ActiveCfg = Release|x64
{06EC74CB-9A12-428C-B551-8537EC964726}.Release|DotNet_x86Test.ActiveCfg = Release|x64
{06EC74CB-9A12-428C-B551-8537EC964726}.Release|x64.ActiveCfg = Release|x64
{06EC74CB-9A12-428C-B551-8537EC964726}.Release|x64.Build.0 = Release|x64
{06EC74CB-9A12-428C-B551-8537EC964726}.Release|x86.ActiveCfg = Release|Win32
{06EC74CB-9A12-428C-B551-8537EC964726}.Release|x86.Build.0 = Release|Win32
{75C6F576-18E9-4566-978A-F0A301CAC090}.AuditMode|Any CPU.ActiveCfg = AuditMode|x64
{75C6F576-18E9-4566-978A-F0A301CAC090}.AuditMode|ARM.ActiveCfg = AuditMode|x64
{75C6F576-18E9-4566-978A-F0A301CAC090}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64
{75C6F576-18E9-4566-978A-F0A301CAC090}.AuditMode|DotNet_x64Test.ActiveCfg = AuditMode|x64
{75C6F576-18E9-4566-978A-F0A301CAC090}.AuditMode|DotNet_x86Test.ActiveCfg = AuditMode|x64
{75C6F576-18E9-4566-978A-F0A301CAC090}.AuditMode|x64.ActiveCfg = AuditMode|x64
{75C6F576-18E9-4566-978A-F0A301CAC090}.AuditMode|x86.ActiveCfg = AuditMode|Win32
{75C6F576-18E9-4566-978A-F0A301CAC090}.Debug|Any CPU.ActiveCfg = Debug|x64
{75C6F576-18E9-4566-978A-F0A301CAC090}.Debug|ARM.ActiveCfg = Debug|x64
{75C6F576-18E9-4566-978A-F0A301CAC090}.Debug|ARM64.ActiveCfg = Debug|ARM64
{75C6F576-18E9-4566-978A-F0A301CAC090}.Debug|ARM64.Build.0 = Debug|ARM64
{75C6F576-18E9-4566-978A-F0A301CAC090}.Debug|DotNet_x64Test.ActiveCfg = Debug|x64
{75C6F576-18E9-4566-978A-F0A301CAC090}.Debug|DotNet_x86Test.ActiveCfg = Debug|x64
{75C6F576-18E9-4566-978A-F0A301CAC090}.Debug|x64.ActiveCfg = Debug|x64
{75C6F576-18E9-4566-978A-F0A301CAC090}.Debug|x64.Build.0 = Debug|x64
{75C6F576-18E9-4566-978A-F0A301CAC090}.Debug|x86.ActiveCfg = Debug|Win32
{75C6F576-18E9-4566-978A-F0A301CAC090}.Debug|x86.Build.0 = Debug|Win32
{75C6F576-18E9-4566-978A-F0A301CAC090}.Fuzzing|Any CPU.ActiveCfg = Fuzzing|x64
{75C6F576-18E9-4566-978A-F0A301CAC090}.Fuzzing|ARM.ActiveCfg = Fuzzing|x64
{75C6F576-18E9-4566-978A-F0A301CAC090}.Fuzzing|ARM64.ActiveCfg = Fuzzing|ARM64
{75C6F576-18E9-4566-978A-F0A301CAC090}.Fuzzing|DotNet_x64Test.ActiveCfg = Fuzzing|x64
{75C6F576-18E9-4566-978A-F0A301CAC090}.Fuzzing|DotNet_x86Test.ActiveCfg = Fuzzing|x64
{75C6F576-18E9-4566-978A-F0A301CAC090}.Fuzzing|x64.ActiveCfg = Fuzzing|x64
{75C6F576-18E9-4566-978A-F0A301CAC090}.Fuzzing|x64.Build.0 = Fuzzing|x64
{75C6F576-18E9-4566-978A-F0A301CAC090}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32
{75C6F576-18E9-4566-978A-F0A301CAC090}.Release|Any CPU.ActiveCfg = Release|x64
{75C6F576-18E9-4566-978A-F0A301CAC090}.Release|ARM.ActiveCfg = Release|x64
{75C6F576-18E9-4566-978A-F0A301CAC090}.Release|ARM64.ActiveCfg = Release|ARM64
{75C6F576-18E9-4566-978A-F0A301CAC090}.Release|ARM64.Build.0 = Release|ARM64
{75C6F576-18E9-4566-978A-F0A301CAC090}.Release|DotNet_x64Test.ActiveCfg = Release|x64
{75C6F576-18E9-4566-978A-F0A301CAC090}.Release|DotNet_x86Test.ActiveCfg = Release|x64
{75C6F576-18E9-4566-978A-F0A301CAC090}.Release|x64.ActiveCfg = Release|x64
{75C6F576-18E9-4566-978A-F0A301CAC090}.Release|x64.Build.0 = Release|x64
{75C6F576-18E9-4566-978A-F0A301CAC090}.Release|x86.ActiveCfg = Release|Win32
{75C6F576-18E9-4566-978A-F0A301CAC090}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -3476,6 +3550,8 @@ Global
{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5} = {89CDCC5C-9F53-4054-97A4-639D99F169CD}
{61901E80-E97D-4D61-A9BB-E8F2FDA8B40C} = {59840756-302F-44DF-AA47-441A9D673202}
{8222900C-8B6C-452A-91AC-BE95DB04B95F} = {05500DEF-2294-41E3-AF9A-24E580B82836}
{06EC74CB-9A12-428C-B551-8537EC964726} = {E8F24881-5E37-4362-B191-A3BA0ED7F4EB}
{75C6F576-18E9-4566-978A-F0A301CAC090} = {05500DEF-2294-41E3-AF9A-24E580B82836}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3140B1B7-C8EE-43D1-A772-D82A7061A271}

View File

@@ -299,6 +299,7 @@ If you would like to ask a question that you feel doesn't warrant an issue
* Universal Windows Platform Development
* **The following Individual Components**
* C++ (v142) Universal Windows Platform Tools
* You must install the [.NET Framework Targeting Pack](https://docs.microsoft.com/dotnet/framework/install/guide-for-developers#to-install-the-net-framework-developer-pack-or-targeting-pack) to build test projects
## Building the Code

View File

@@ -0,0 +1,51 @@
{
"Version": "1.0.0",
"UseMinimatch": false,
"SignBatches": [
{
"MatchedPath": [
"conpty.dll",
"OpenConsole.exe"
],
"SigningInfo": {
"Operations": [
{
"KeyCode": "CP-230012",
"OperationSetCode": "SigntoolSign",
"Parameters": [
{
"parameterName": "OpusName",
"parameterValue": "Microsoft"
},
{
"parameterName": "OpusInfo",
"parameterValue": "http://www.microsoft.com"
},
{
"parameterName": "FileDigest",
"parameterValue": "/fd \"SHA256\""
},
{
"parameterName": "PageHash",
"parameterValue": "/NPH"
},
{
"parameterName": "TimeStamp",
"parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
}
],
"ToolName": "sign",
"ToolVersion": "1.0"
},
{
"KeyCode": "CP-230012",
"OperationSetCode": "SigntoolVerify",
"Parameters": [],
"ToolName": "sign",
"ToolVersion": "1.0"
}
]
}
}
]
}

View File

@@ -95,3 +95,10 @@ stages:
jobs:
- template: ./templates/check-formatting.yml
- stage: CodeIndexer
displayName: Github CodeNav Indexer
dependsOn: [Build_x64]
condition: and(succeeded(), not(eq(variables['Build.Reason'], 'PullRequest')))
jobs:
- template: ./templates/codenav-indexer.yml

View File

@@ -30,6 +30,10 @@ parameters:
displayName: "Build Windows Terminal VPack"
type: boolean
default: false
- name: buildConPTY
displayName: "Build ConPTY NuGet"
type: boolean
default: false
- name: buildWPF
displayName: "Build Terminal WPF Control"
type: boolean
@@ -60,6 +64,35 @@ parameters:
variables:
TerminalInternalPackageVersion: "0.0.7"
# If we are building a branch called "release-*", change the NuGet suffix
# to "preview". If we don't do that, XES will set the suffix to "release1"
# because it truncates the value after the first period.
# We also want to disable the suffix entirely if we're Release branded while
# on a release branch.
# main is special, however. XES ignores main. Since we never produce actual
# shipping builds from main, we want to force it to have a beta label as
# well.
#
# In effect:
# BRANCH / BRANDING | Release | Preview
# ------------------|----------------------------|-----------------------------
# release-* | 1.12.20220427 | 1.13.20220427-preview
# main | 1.14.20220427-experimental | 1.14.20220427-experimental
# all others | 1.14.20220427-mybranch | 1.14.20220427-mybranch
${{ if startsWith(variables['Build.SourceBranchName'], 'release-') }}:
${{ if eq(parameters.branding, 'Release') }}:
NoNuGetPackBetaVersion: true
${{ else }}:
NuGetPackBetaVersion: preview
${{ elseif eq(variables['Build.SourceBranchName'], 'main') }}:
NuGetPackBetaVersion: experimental
# The NuGet packages have to use *somebody's* DLLs. We used to force them to
# use the Win10 build outputs, but if there isn't a Win10 build we should use
# the Win11 one.
${{ if containsValue(parameters.buildWindowsVersions, 'Win10') }}:
TerminalBestVersionForNuGetPackages: Win10
${{ else }}:
TerminalBestVersionForNuGetPackages: Win11
name: $(BuildDefinitionName)_$(date:yyMM).$(date:dd)$(rev:rrr)
resources:
@@ -193,6 +226,15 @@ jobs:
msbuildArgs: /p:WindowsTerminalOfficialBuild=true /p:WindowsTerminalBranding=${{ parameters.branding }};PGOBuildMode=${{ parameters.pgoBuildMode }} /p:WindowsTerminalReleaseBuild=true /t:Terminal\wpf\PublicTerminalCore
platform: $(BuildPlatform)
configuration: $(BuildConfiguration)
- ${{ if eq(parameters.buildConPTY, true) }}:
- task: VSBuild@1
displayName: Build solution **\OpenConsole.sln for ConPTY
inputs:
solution: '**\OpenConsole.sln'
vsVersion: 16.0
msbuildArgs: /p:WindowsTerminalOfficialBuild=true /p:WindowsTerminalBranding=${{ parameters.branding }};PGOBuildMode=${{ parameters.pgoBuildMode }} /p:WindowsTerminalReleaseBuild=true /t:Conhost\Host_EXE;Conhost\winconpty_DLL
platform: $(BuildPlatform)
configuration: $(BuildConfiguration)
- task: PowerShell@2
displayName: Source Index PDBs
inputs:
@@ -237,6 +279,24 @@ jobs:
inputs:
PathtoPublish: $(Build.ArtifactStagingDirectory)/appx
ArtifactName: appx-$(BuildPlatform)-$(BuildConfiguration)-$(TerminalTargetWindowsVersion)
- ${{ if eq(parameters.buildConPTY, true) }}:
- task: CopyFiles@2
displayName: Copy ConPTY to Artifacts
inputs:
Contents: |-
$(Build.SourcesDirectory)/bin/**/conpty.dll
$(Build.SourcesDirectory)/bin/**/conpty.lib
$(Build.SourcesDirectory)/bin/**/conpty.pdb
$(Build.SourcesDirectory)/bin/**/OpenConsole.exe
$(Build.SourcesDirectory)/bin/**/OpenConsole.pdb
TargetFolder: $(Build.ArtifactStagingDirectory)/conpty
OverWrite: true
flattenFolders: true
- task: PublishBuildArtifacts@1
displayName: Publish Artifact (ConPTY)
inputs:
PathtoPublish: $(Build.ArtifactStagingDirectory)/conpty
ArtifactName: conpty-dll-$(BuildPlatform)-$(BuildConfiguration)-$(TerminalTargetWindowsVersion)
- ${{ if eq(parameters.buildWPF, true) }}:
- task: CopyFiles@2
displayName: Copy PublicTerminalCore.dll to Artifacts
@@ -343,6 +403,97 @@ jobs:
PathtoPublish: $(System.ArtifactsDirectory)
ArtifactName: appxbundle-signed-$(TerminalTargetWindowsVersion)
- ${{ if eq(parameters.buildConPTY, true) }}:
- job: PackageAndSignConPTY
strategy:
matrix:
${{ each config in parameters.buildConfigurations }}:
${{ config }}:
BuildConfiguration: ${{ config }}
displayName: Create NuGet Package (ConPTY)
dependsOn: Build
steps:
- checkout: self
clean: true
fetchDepth: 1
submodules: true
persistCredentials: True
- task: PkgESSetupBuild@12
displayName: Package ES - Setup Build
inputs:
disableOutputRedirect: true
- ${{ each platform in parameters.buildPlatforms }}:
- task: DownloadBuildArtifacts@0
displayName: Download ${{ platform }} ConPTY binaries
inputs:
artifactName: conpty-dll-${{ platform }}-$(BuildConfiguration)-$(TerminalBestVersionForNuGetPackages)
downloadPath: bin\${{ platform }}\$(BuildConfiguration)\
extractTars: false
- task: PowerShell@2
displayName: Move downloaded artifacts around
inputs:
targetType: inline
# Find all artifact files and move them up a directory. Ugh.
script: |-
Get-ChildItem bin -Recurse -Directory -Filter conpty-dll-* | % {
$_ | Get-ChildItem -Recurse -File | % {
Move-Item -Verbose $_.FullName $_.Directory.Parent.FullName
}
}
Move-Item bin\x86 bin\Win32
- task: EsrpCodeSigning@1
displayName: Submit ConPTY libraries and OpenConsole for code signing
inputs:
ConnectedServiceName: 9d6d2960-0793-4d59-943e-78dcb434840a
FolderPath: '$(Build.SourcesDirectory)/bin'
signType: batchSigning
batchSignPolicyFile: '$(Build.SourcesDirectory)\build\config\ESRPSigning_ConPTY.json'
- task: NuGetToolInstaller@1
displayName: Use NuGet 5.10.0
inputs:
versionSpec: 5.10.0
- task: NuGetCommand@2
displayName: NuGet pack
inputs:
command: pack
packagesToPack: $(Build.SourcesDirectory)\src\winconpty\package\winconpty.nuspec
packDestination: '$(Build.ArtifactStagingDirectory)/nupkg'
versioningScheme: byEnvVar
versionEnvVar: XES_PACKAGEVERSIONNUMBER
- task: EsrpCodeSigning@1
displayName: Submit *.nupkg to ESRP for code signing
inputs:
ConnectedServiceName: 9d6d2960-0793-4d59-943e-78dcb434840a
FolderPath: $(Build.ArtifactStagingDirectory)/nupkg
Pattern: '*.nupkg'
UseMinimatch: true
signConfigType: inlineSignParams
inlineOperation: >-
[
{
"KeyCode": "CP-401405",
"OperationCode": "NuGetSign",
"Parameters": {},
"ToolName": "sign",
"ToolVersion": "1.0"
},
{
"KeyCode": "CP-401405",
"OperationCode": "NuGetVerify",
"Parameters": {},
"ToolName": "sign",
"ToolVersion": "1.0"
}
]
- task: PublishBuildArtifacts@1
displayName: Publish Artifact (nupkg)
inputs:
PathtoPublish: $(Build.ArtifactStagingDirectory)\nupkg
ArtifactName: conpty-nupkg-$(BuildConfiguration)
- ${{ if eq(parameters.buildWPF, true) }}:
- job: PackageAndSignWPF
strategy:
@@ -366,7 +517,7 @@ jobs:
- task: DownloadBuildArtifacts@0
displayName: Download ${{ platform }} PublicTerminalCore
inputs:
artifactName: wpf-dll-${{ platform }}-$(BuildConfiguration)-Win10
artifactName: wpf-dll-${{ platform }}-$(BuildConfiguration)-$(TerminalBestVersionForNuGetPackages)
itemPattern: '**/*.dll'
downloadPath: bin\${{ platform }}\$(BuildConfiguration)\
extractTars: false

View File

@@ -11,6 +11,7 @@ jobs:
BuildConfiguration: ${{ parameters.configuration }}
BuildPlatform: ${{ parameters.platform }}
WindowsTerminalBranding: ${{ parameters.branding }}
EnableRichCodeNavigation: true
pool:
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
name: WinDevPoolOSS-L

View File

@@ -0,0 +1,22 @@
parameters:
artifactName: 'drop'
jobs:
- job: CodeNavIndexer
displayName: Run Github CodeNav Indexer
pool: { vmImage: windows-2019 }
steps:
- checkout: self
fetchDepth: 1
submodules: false
clean: true
- task: DownloadBuildArtifacts@0
inputs:
artifactName: ${{ parameters.artifactName }}
- task: RichCodeNavIndexer@0
inputs:
languages: 'cpp,csharp'
continueOnError: true

View File

@@ -18,14 +18,14 @@
This version should be tracked in all project packages.config files for projects that depend on Xaml.
-->
<TerminalMUXVersion>2.7.0-prerelease.210913003</TerminalMUXVersion>
<TerminalMUXVersion>2.7.2-prerelease.220406002</TerminalMUXVersion>
<!--
For the Windows 11-specific build, we're targeting the public version of Microsoft.UI.Xaml.
This version emits a package dependency instead of embedding the dependency in our own package.
This version should be tracked in build/packages.config.
-->
<TerminalMUXVersion Condition="'$(TerminalTargetWindowsVersion)'=='Win11'">2.7.0</TerminalMUXVersion>
<TerminalMUXVersion Condition="'$(TerminalTargetWindowsVersion)'=='Win11'">2.7.1</TerminalMUXVersion>
</PropertyGroup>
</Project>

View File

@@ -11,6 +11,7 @@
"/packages/",
"/ipch/",
"/dep/",
"/doc/",
"/.vs/",
"/build/",
"/src/cascadia/",
@@ -24,6 +25,10 @@
"/doc/cascadia/",
"/doc/user-docs/",
"/src/tools/MonarchPeasantSample/",
"/src/tools/MonarchPeasantPackage/",
"/src/api-ms-win-core-synch-l1-2-0/",
"/src/tools/ansi-color/",
"/src/tools/ColorTool/",
"/scratch/",
"Scratch.sln",
],

View File

@@ -17,7 +17,7 @@
<XesUseOneStoreVersioning>true</XesUseOneStoreVersioning>
<XesBaseYearForStoreVersion>2022</XesBaseYearForStoreVersion>
<VersionMajor>1</VersionMajor>
<VersionMinor>14</VersionMinor>
<VersionMinor>15</VersionMinor>
<VersionInfoProductName>Windows Terminal</VersionInfoProductName>
</PropertyGroup>
</Project>

76
dep/Console/ConIoSrv.h Normal file
View File

@@ -0,0 +1,76 @@
/*++
Copyright (c) Microsoft Corporation.
Licensed under the MIT license.
--*/
#pragma once
#include <ntlpcapi.h>
#define CIS_ALPC_PORT_NAME L""
#define CIS_EVENT_TYPE_INPUT (0)
#define CIS_EVENT_TYPE_FOCUS (1)
#define CIS_EVENT_TYPE_FOCUS_ACK (2)
#define CIS_MSG_TYPE_GETDISPLAYSIZE (3)
#define CIS_MSG_TYPE_GETFONTSIZE (4)
#define CIS_MSG_TYPE_SETCURSOR (5)
#define CIS_MSG_TYPE_UPDATEDISPLAY (6)
#define CIS_MSG_ATTR_FLAGS (0)
#define CIS_MSG_ATTR_BUFFER_SIZE (1024)
#define CIS_DISPLAY_MODE_NONE (0)
#define CIS_DISPLAY_MODE_BGFX (1)
#define CIS_DISPLAY_MODE_DIRECTX (2)
typedef struct {
PORT_MESSAGE AlpcHeader;
UCHAR Type;
union {
struct {
CD_IO_DISPLAY_SIZE DisplaySize;
NTSTATUS ReturnValue;
} GetDisplaySizeParams;
struct {
CD_IO_FONT_SIZE FontSize;
NTSTATUS ReturnValue;
} GetFontSizeParams;
struct {
CD_IO_CURSOR_INFORMATION CursorInformation;
NTSTATUS ReturnValue;
} SetCursorParams;
struct {
SHORT RowIndex;
NTSTATUS ReturnValue;
} UpdateDisplayParams;
struct {
USHORT DisplayMode;
} GetDisplayModeParams;
};
} CIS_MSG, *PCIS_MSG;
typedef struct {
UCHAR Type;
union {
struct {
INPUT_RECORD Record;
} InputEvent;
struct {
BOOLEAN IsActive;
} FocusEvent;
};
} CIS_EVENT, *PCIS_EVENT;

View File

@@ -158,8 +158,8 @@ typedef struct _CD_IO_DISPLAY_SIZE {
} CD_IO_DISPLAY_SIZE, *PCD_IO_DISPLAY_SIZE;
typedef struct _CD_IO_CHARACTER {
WCHAR Character;
USHORT Atribute;
WCHAR Character;
USHORT Attribute;
} CD_IO_CHARACTER, *PCD_IO_CHARACTER;
typedef struct _CD_IO_ROW_INFORMATION {
@@ -175,6 +175,11 @@ typedef struct _CD_IO_CURSOR_INFORMATION {
BOOLEAN IsVisible;
} CD_IO_CURSOR_INFORMATION, *PCD_IO_CURSOR_INFORMATION;
typedef struct _CD_IO_FONT_SIZE {
ULONG Width;
ULONG Height;
} CD_IO_FONT_SIZE, *PCD_IO_FONT_SIZE;
#define IOCTL_CONDRV_READ_IO \
CTL_CODE(FILE_DEVICE_CONSOLE, 1, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
@@ -213,3 +218,6 @@ typedef struct _CD_IO_CURSOR_INFORMATION {
#define IOCTL_CONDRV_LAUNCH_SERVER \
CTL_CODE(FILE_DEVICE_CONSOLE, 13, METHOD_NEITHER, FILE_ANY_ACCESS)
#define IOCTL_CONDRV_GET_FONT_SIZE \
CTL_CODE(FILE_DEVICE_CONSOLE, 14, METHOD_NEITHER, FILE_ANY_ACCESS)

24
dep/Console/csrmsg.h Normal file
View File

@@ -0,0 +1,24 @@
/*++
Copyright (c) Microsoft Corporation.
Licensed under the MIT license.
--*/
#pragma once
#include <ntcsrmsg.h>
typedef enum _USER_API_NUMBER {
UserpEndTask,
} USER_API_NUMBER, *PUSER_API_NUMBER;
typedef struct _ENDTASKMSG {
HANDLE ProcessId;
ULONG ConsoleEventCode;
ULONG ConsoleFlags;
} ENDTASKMSG, *PENDTASKMSG;
typedef struct _USER_API_MSG {
union {
ENDTASKMSG EndTask;
} u;
} USER_API_MSG, *PUSER_API_MSG;

15
dep/Console/ntcsrdll.h Normal file
View File

@@ -0,0 +1,15 @@
/*++
Copyright (c) Microsoft Corporation.
Licensed under the MIT license.
--*/
#pragma once
#include <ntcsrmsg.h>
NTSTATUS CsrClientCallServer(
PCSR_API_MSG m,
PCSR_CAPTURE_HEADER CaptureBuffer OPTIONAL,
ULONG ApiNumber,
ULONG ArgLength
);

16
dep/Console/ntcsrmsg.h Normal file
View File

@@ -0,0 +1,16 @@
/*++
Copyright (c) Microsoft Corporation.
Licensed under the MIT license.
--*/
#pragma once
#include <ntlpcapi.h>
typedef struct _CSR_CAPTURE_HEADER {
} CSR_CAPTURE_HEADER, *PCSR_CAPTURE_HEADER;
typedef struct _CSR_API_MSG {
} CSR_API_MSG, *PCSR_API_MSG;
#define CSR_MAKE_API_NUMBER(DllIndex, ApiIndex) 0

126
dep/Console/ntlpcapi.h Normal file
View File

@@ -0,0 +1,126 @@
/*++
Copyright (c) Microsoft Corporation.
Licensed under the MIT license.
--*/
#pragma once
#define OB_FILE_OBJECT_TYPE 1
typedef struct _PORT_MESSAGE {
union {
struct {
SHORT DataLength;
SHORT TotalLength;
} s1;
} u1;
union {
ULONG ZeroInit;
} u2;
union {
CLIENT_ID ClientId;
};
ULONG MessageId;
} PORT_MESSAGE, *PPORT_MESSAGE;
#define ALPC_MSGFLG_SYNC_REQUEST 0
#define ALPC_PORFLG_ACCEPT_DUP_HANDLES 1
#define ALPC_PORFLG_ACCEPT_INDIRECT_HANDLES 2
typedef struct _ALPC_DATA_VIEW_ATTR {
PVOID ViewBase;
SIZE_T ViewSize;
} ALPC_DATA_VIEW_ATTR, *PALPC_DATA_VIEW_ATTR;
typedef struct _ALPC_CONTEXT_ATTR {
} ALPC_CONTEXT_ATTR, *PALPC_CONTEXT_ATTR;
#define ALPC_INDIRECT_HANDLE_MAX 512
typedef struct _ALPC_HANDLE_ATTR {
union {
ULONG HandleCount;
};
} ALPC_HANDLE_ATTR, *PALPC_HANDLE_ATTR;
#define ALPC_FLG_MSG_DATAVIEW_ATTR 1
#define ALPC_FLG_MSG_HANDLE_ATTR 2
typedef struct _ALPC_MESSAGE_ATTRIBUTES {
} ALPC_MESSAGE_ATTRIBUTES, *PALPC_MESSAGE_ATTRIBUTES;
typedef struct _ALPC_PORT_ATTRIBUTES {
ULONG Flags;
SECURITY_QUALITY_OF_SERVICE SecurityQos;
SIZE_T MaxMessageLength;
SIZE_T MemoryBandwidth;
SIZE_T MaxPoolUsage;
SIZE_T MaxSectionSize;
SIZE_T MaxViewSize;
SIZE_T MaxTotalSectionSize;
ULONG DupObjectTypes;
#ifdef _WIN64
ULONG Reserved;
#endif
} ALPC_PORT_ATTRIBUTES, *PALPC_PORT_ATTRIBUTES;
typedef enum _ALPC_MESSAGE_INFORMATION_CLASS {
AlpcMessageHandleInformation
} ALPC_MESSAGE_INFORMATION_CLASS;
typedef struct _ALPC_MESSAGE_HANDLE_INFORMATION {
ULONG Index;
ULONG Handle;
} ALPC_MESSAGE_HANDLE_INFORMATION, *PALPC_MESSAGE_HANDLE_INFORMATION;
NTSTATUS AlpcInitializeMessageAttribute(
ULONG AttributeFlags,
PALPC_MESSAGE_ATTRIBUTES Buffer,
SIZE_T BufferSize,
PSIZE_T RequiredBufferSize
);
PVOID AlpcGetMessageAttribute(
PALPC_MESSAGE_ATTRIBUTES Buffer,
ULONG AttributeFlag
);
#define ALPC_GET_DATAVIEW_ATTRIBUTES(MsgAttr) \
((PALPC_DATA_VIEW_ATTR)AlpcGetMessageAttribute(MsgAttr, ALPC_FLG_MSG_DATAVIEW_ATTR))
#define ALPC_GET_HANDLE_ATTRIBUTES(MsgAttr) \
((PALPC_HANDLE_ATTR)AlpcGetMessageAttribute(MsgAttr, ALPC_FLG_MSG_HANDLE_ATTR))
NTSTATUS NtAlpcConnectPort(
PHANDLE PortHandle,
PUNICODE_STRING PortName,
POBJECT_ATTRIBUTES ObjectAttributes,
PALPC_PORT_ATTRIBUTES PortAttributes,
ULONG Flags,
PSID RequiredServerSid,
PPORT_MESSAGE ConnectionMessage,
PSIZE_T BufferLength,
PALPC_MESSAGE_ATTRIBUTES OutMessageAttributes,
PALPC_MESSAGE_ATTRIBUTES InMessageAttributes,
PLARGE_INTEGER Timeout
);
NTSTATUS NtAlpcSendWaitReceivePort(
HANDLE PortHandle,
ULONG Flags,
PPORT_MESSAGE SendMessage,
PALPC_MESSAGE_ATTRIBUTES SendMessageAttributes,
PPORT_MESSAGE ReceiveMessage,
PSIZE_T BufferLength,
PALPC_MESSAGE_ATTRIBUTES ReceiveMessageAttributes,
PLARGE_INTEGER Timeout
);
NTSTATUS NtAlpcQueryInformationMessage(
HANDLE PortHandle,
PPORT_MESSAGE PortMessage,
ALPC_MESSAGE_INFORMATION_CLASS MessageInformationClass,
PVOID MessageInformation,
ULONG Length,
PULONG ReturnLength
);

View File

@@ -10,7 +10,7 @@
<package id="Microsoft.VCRTForwarders.140" version="1.0.4" targetFramework="native" />
<package id="Microsoft.Internal.Windows.Terminal.ThemeHelpers" version="0.6.220404001" targetFramework="native" />
<package id="Microsoft.VisualStudio.Setup.Configuration.Native" version="2.3.2262" targetFramework="native" developmentDependency="true" />
<package id="Microsoft.UI.Xaml" version="2.7.0-prerelease.210913003" targetFramework="native" />
<package id="Microsoft.UI.Xaml" version="2.7.2-prerelease.220406002" targetFramework="native" />
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.220201.1" targetFramework="native" developmentDependency="true" />
<!-- Managed packages -->

View File

@@ -54,6 +54,24 @@
}
]
},
"BellSound": {
"default": "",
"description": "Sets the file location of the sound played when the application emits a BEL character. If the path is invalid no sound will be played. This property also accepts an array of sounds and the terminal will pick one at random.",
"oneOf": [
{
"type": [
"string",
"null"
]
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
},
"AppearanceConfig": {
"properties": {
"colorScheme": {
@@ -332,6 +350,7 @@
"tabSearch",
"toggleAlwaysOnTop",
"toggleFocusMode",
"selectAll",
"setFocusMode",
"toggleFullscreen",
"setFullScreen",
@@ -1689,6 +1708,11 @@
"description": "Force the terminal to use the legacy input encoding. Certain keys in some applications may stop working when enabling this setting.",
"type": "boolean"
},
"experimental.useBackgroundImageForWindow": {
"default": false,
"description": "When set to true, the background image for the currently focused profile is expanded to encompass the entire window, beneath other panes.",
"type": "boolean"
},
"initialCols": {
"default": 120,
"description": "The number of columns displayed in the window upon first load. If \"launchMode\" is set to \"maximized\" (or \"maximizedFocus\"), this property is ignored.",
@@ -2383,4 +2407,4 @@
]
}
]
}
}

View File

@@ -0,0 +1,370 @@
---
author: Michael Niksa @miniksa
created on: 2022-02-24
last updated: 2022-02-24
issue id: 12570
---
# Show Hide operations on GetConsoleWindow via PTY
## Abstract
To maintain compatibility with command-line tools, utilities, and tests that desire to
manipulate the final presentation window of their output through retrieving the raw
console window handle and performing `user32` operations against it like [ShowWindow](https://docs.microsoft.com//windows/win32/api/winuser/nf-winuser-showwindow),
we will create a compatibility layer that captures this intent and translates it into
the nearest equivalent in the cross-platform virtual terminal language and implement the
understanding of these sequences in our own Windows Terminal.
## Inspiration
When attempting to enable the Windows Terminal as the default terminal application on Windows
(to supersede the execution of command-line utilities inside the classic console host window),
we discovered that there were a bunch of automated tests, tools, and utilities that relied on
showing and hiding the console window using the `::GetConsoleWindow()` API in conjunction with
`::ShowWindow()`.
When we initially invented the ConPTY, we worked to ensure that we built to the common
denominator that would work cross-platform in all scenarios, avoiding situations that were
dependent on Windows-isms like `user32k` including the full knowledge of how windowing occurs
specific to the Windows platform.
We also understood that on Windows, the [**CreateProcess**](https://docs.microsoft.com/windows/win32/procthread/process-creation-flags) API provides ample flags specifically
for command-line applications to command the need for (or lack thereof) a window on startup
such as `CREATE_NEW_CONSOLE`, `CREATE_NO_WINDOW`, and `DETACHED_PROCESS`. The understanding
was that people who didn't need or want a window, or otherwise needed to manipulate the
console session, would use those flags on process creation to dictate the session. Additionally,
the `::CreateProcess` call will accept information in `STARTUPINFO` or `STARTUPINFOEX` that
can dictate the placement, size, and visibility of a window... including some fields specific
to console sessions. We had accepted those as ways applications would specify their intent.
Those assumptions have proven incorrect. Because it was too easy to just `::CreateProcess` in
the default manner and then get access to the session after-the-fact and manipulate it with
APIs like `::GetConsoleWindow()`, tooling and tests organically grew to make use of this process.
Instead of requesting up front that they didn't need a window or the overhead of a console session,
they would create one anyway by default and then manipulate it afterward to hide it, move it off-
screen, or otherwise push it around. Overall, this is terrible for their performance and overall
reliability because they've obscured their intent by not asking for it upfront and impacted their
performance by having the entire subsystem spin up interactive work when they intend to not use it.
But Windows is the place for compatibility, so we must react and compensate for the existing
non-ideal situation.
We will implement a mechanism to compensate for these that attempts to capture the intent of the
requests from the calling applications against the ConPTY and translates them into the "universal"
Virtual Terminal language to the best of its ability to make the same effects as prior to the
change to the new PTY + Terminal platform.
## Solution Design
Overall, there are three processes involved in this situation:
1. The client command-line application utility, tool, or test that will manipulate the window.
1. The console host (`conhost.exe` or `openconsole.exe`) operating in PTY mode.
1. The terminal (`windowsterminal.exe` when it's Windows Terminal, but could be a third party).
The following diagram shows the components and how they will interact.
```txt
┌─────────────────┐ ┌──────────────────┐ ┌──────────────────────┐
│ │ 1 │ │ │ │
│ Command-Line ├─────────────────► │ Console Host │ │ Windows Terminal │
│ Tool or │ │ as ConPTY │ │ Backend │
│ Utility │ 2 │ │ 6 │ │
│ │ ◄─────────────────┤ ├─────────────────► │ │
│ │ │ │ │ │
│ │ │ │ │ │
│ │ │ │ 9 │ │
│ │ │ │ ◄─────────────────┤ │
│ │ │ │ │ │
└─────┬───────────┘ └───────────┬──────┘ └─────────────────┬────┘
│ ▲ │ ▲ │
│ │ │ │ │
│ │ │10 │ │7
│3 5│ │ │8 │
│ │ ▼ │ ▼
│ ┌───┴────┐ ┌──┴────┬───────┬─────────────────────────┐
▼ │ Hidden │ │ │ │ v^x│
┌─────────────────┐ │ Fake │ ├───────┴───────┴─────────────────────────┤
│ │ 4 │ PTY │ │ │
│ ├──────────────────────► │ Window │ │ │
│ user32.dll │ └────────┘ │ Windows Terminal │
│ Window APIs │ │ Displayed Window │
│ │ │ │
│ │ │ │
└─────────────────┘ │ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└─────────────────────────────────────────┘
```
1. The command-line tool calls `::GetConsoleWindow()` on the PTY host
2. The PTY host returns the raw `HWND` to the *Hidden Fake PTY Window* in its control
3. The command-line tool calls `::ShowWindow()` on the `user32.dll` API surface to manipulate that window.
4. `user32.dll` sends a message to the window message queue on the *Fake PTY Window*
5. The PTY host retrieves the message from the queue and translates it to a virtual terminal message
6. The Windows Terminal connection layer receives the virtual terminal message and decodes it into a window operation.
7. The true displayed *Windows Terminal Window* is told to change its status to show or hide.
8. The changed Show/Hide status is returned to the back-end on completion.
9. The Windows Terminal connection layer returns that information to the PTY host so it can remain in-the-know.
10. The PTY updates its *Fake PTY Window* status to match the real one so it continues to receive appropriate messages from `user32`.
This can be conceptually understood in a few phases:
- The client application grabs a handle and attempts to send a command via a back-channel through user32.
- User32 decides what message to send based on the window state of the handle.
- The message is translated by the PTY and propagated to the true visible window.
- The visible window state is returned back to the hidden/fake window to remain in synchronization so the next call to user32 can make the correct decision.
The communication between the PTY and the hosting terminal application occurs with a virtual terminal sequence.
Fortunately, *xterm* had already invented and implemented one for this behavior called **XTWINOPS** which means
we should be able to utilize that one and not worry about inventing our own Microsoft-specific thing. This ensures
that there is some precedence for what we're doing, guarantees a major third party terminal can support the same
sequence, and induces a high probability of other terminals already using it given *xterm* is the defacto standard
for terminal emulation.
Information about **XTWINOPS** can be found at [Xterm control sequences](https://invisible-island.net/xterm/ctlseqs/ctlseqs.html). Search for *XTWINOPS*.
The sequence is **CSI** *Ps*; *Ps*; *Ps* **t**. It starts with the common "control sequence initiator" of `ESC [` (`0x1B 0x5B`).
Then between 1 and 3 numerical parameters are given, separated by semicolons (`0x3B`).
And finally, the sequence is terminated with `t` (`0x74`).
Specifically, the two parameter commands of `1` for *De-iconify window* and `2` for *Iconify window* appear relevant to our interests.
In `user32` parlance, "iconify" traditionally corresponds to minimize/restore state and is a good proxy for overall visibility of the window.
The theory then is to detect when the assorted calls to `::ShowWindow()` against the *Fake PTY Window* are asking for a command that
maps to either "iconify" or "deiconify" and translate them into the corresponding message over the VT channel to the attached terminal.
To detect this, we need to use some heuristics inside the [window procedure](https://docs.microsoft.com/windows/win32/winmsg/window-procedures) for the window owned by the PTY.
Unfortunately, calls to `::ShowWindow()` on research with the team that owns `user32` do not go straight into the window message queue. Instead, they're dispatched straight into `win32k` to be analyzed and then trigger an array of follow on window messages into the queue depending on the `HWND`'s current state. Most specifically, they vary based on the `WS_VISIBLE` state of the `HWND`. (See [Window Styles](https://docs.microsoft.com/windows/win32/winmsg/window-styles) for details on the `WS_VISIBLE` flag.)
I evaluated a handful of messages with the help of the IXP Essentials team to see which ones would telegraph the changes from `::ShowWindow()` into our window procedure:
- [WM_QUERYOPEN](https://docs.microsoft.com/windows/win32/winmsg/wm-queryopen) - This one allows us to accept/reject a minimize/restore call. Not really useful for finding out current state
- [WM_SYSCOMMAND](https://docs.microsoft.com/windows/win32/menurc/wm-syscommand) - This one is what is called when the minimize, maximize/restore, and exit buttons are called in the window toolbar. But apparently it is not generated for these requests coming from outside the window itself through the `user32` APIs.
- [WM_SHOWWINDOW](https://docs.microsoft.com/windows/win32/winmsg/wm-showwindow) - This one provides some insight in certain transitions, specifically around force hiding and showing. When the `lParam` is `0`, we're supposed to know that someone explicitly called `::ShowWindow()` to show or hide with the `wParam` being a `BOOL` where `TRUE` is "show" and `FALSE` is "hide". We can translate that into *de-iconify* and *iconify* respectively.
- [WM_WINDOWPOSCHANGING](https://docs.microsoft.com/windows/win32/winmsg/wm-windowposchanging) - This one I evaluated extensively as it looked to provide us insight into how the window was about to change before it did so and offered us the opportunity to veto some of those changes (for instance, if we wanted to remain invisible while propagating a "show" message). I'll detail more about this one in a sub-heading below.
- [WM_SIZE](https://docs.microsoft.com/windows/win32/winmsg/wm-size) - This one has a `wParam` that specifically sends `SIZE_MINIMIZED` (`1`) and `SIZE_RESTORED` (`0`) that should translate into *iconify* and *de-iconify respectively.
#### WM_WINDOWPOSCHANGING data
In investigating `WM_WINDOWPOSCHANGING`, I built a table of some of the states I observed while receiving messages from an external caller that was using `::ShowWindow()`:
|integer|constant|flags|Should Hide?|minimizing|maximizing|showing|hiding|activating|`0x8000`|`SWP_NOCOPYBITS`|`SWP_SHOWWINDOW`|`SWP_FRAMECHANGED`|`SWP_NOACTIVATE`|`SWP_NOZORDER`|`SWP_NOMOVE`|`SWP_NOSIZE`|
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|0|`SW_HIDE`|?|YES|?|?|?|?|?|?|?|?|?|?|?|?|?|
|1|`SW_NORMAL`|`0x43`|NO|F|F|T|F|T|||X||||X|X|
|2|`SW_SHOWMINIMIZED`|`0x8160`|YES|T|F|T|F|T|X|X|X|X|||||
|3|`SW_SHOWMAXIMIZED`|`0x8160`|NO|F|T|T|F|T|X|X|X|X|||||
|4|`SW_SHOWNOACTIVATE`|`0x8070`|NO|F|F|T|F|F|X||X|X|X||||
|5|`SW_SHOW`|`0x43`|NO|F|F|T|F|T|||X||||X|X|
|6|`SW_MINIMIZE`|`0x8170`|YES|T|F|T|F|F|X|X|X|X|X||||
|7|`SW_SHOWMINNOACTIVE`|`0x57`|YES|T|F|T|F|F|||X||X|X|X|X|
|8|`SW_SHOWNA`|`0x53`|NO|F|F|T|F|F|||X||X||X|X|
|9|`SW_RESTORE`|`0x8160`|NO|F|F|T|F|T|||X|X|||||
|10|`SW_SHOWDEFAULT`|`0x43`|NO|F|F|T|F|T|||X||||X|X|
|11|`SW_FORCEMINIMIZE`|?|YES|?|?|?|?|?|?|?|?|?|?|?|?|?|
The headings are as follows:
- integer - The value of the Show Window constant `SW_*` (see [ShowWindow](https://docs.microsoft.com/windows/win32/api/winuser/nf-winuser-showwindow))
- constant - The name of the Show Window constant
- flags - The `lParam` field is a pointer to a [**WINDOWPOS**](https://docs.microsoft.com/windows/win32/api/winuser/ns-winuser-windowpos) structure during this message. This the `UINT flags` field of that structure.
- Should Hide? - Whether or not I believe that the window should hide if this constant is seen. (Conversely, should show on the opposite.)
- minimizing - This is the `BOOL` response from a call to [**IsIconic()**](https://docs.microsoft.com/windows/win32/api/winuser/nf-winuser-isiconic) during this message.
- maximizing - This is the `BOOL` response from a call to [**IsZoomed()**](https://docs.microsoft.com/windows/win32/api/winuser/nf-winuser-iszoomed) during this message.
- showing - This is whether `SWP_SHOWWINDOW` is set on the `WINDOWPOS.flags` field during this message.
- hiding - This is whether `SWP_HIDEWINDOW` is set on the `WINDOWPOS.flags` field during this message.
- activating - This is the inverse of whether `SWP_NOACTIVATE` is set on the `WINDOWPOS.flags` field during this message.
- Remaining headings are `flags` values expanded to `X` is set and blank is unset. See [**SetWindowPos()**](https://docs.microsoft.com/windows/win32/api/winuser/nf-winuser-setwindowpos) for the definitions of all the flags.
From this data collection, I noticed a few things:
- The data in this table was unstable. The fields varied depending on the order in which I called the various constants against `ShowWindow()`. This is just one particular capture.
- Some of the states, I wouldn't see any message data at all (`SW_HIDE` and `SW_FORCEMINIMIZE`).
- There didn't seem to be a definitive way to use this data to reliably decide when to show or hide the window. I didn't have a reliable way of pulling this together with my *Should Hide?* column.
On further investigation, it became apparent that the values received were sometimes not coming through or varying because the `WS_VISIBLE` state of the `HWND` affected how `win32k` decided to dispatch messages and what values they contained. This is where I determined that steps #8-10 in the diagram above were going to be necessary: to report the state of the real window back to the *fake window* so it could report status to `user32` and `win32k` and receive state-appropriate messages.
For reporting back #8-10, I initially was going to use the `XTWINOPS` call with parameter `11`. The PTY could ask the attached terminal for its state and expect to hear back an answer of either `1` or `2` in the same format message depending on the state. However, on further consideration, I realized that the real window could change at a moments notice without prompting from the PTY, so I instead wrote the PTY to always listen for this and had the Windows Terminal send this back down unprompted.
#### Refined WM_SHOWWINDOW and WM_SIZE data
Upon setting up the synchronization for #8-10, I then tried again to build the table using just the two window messages that were giving me reliable data: `WM_SHOWWINDOW` and `WM_SIZE`:
|integer|constant|Should Hide?|`WM_SHOWWINDOW` OR `WM_SIZE` reported hide?|
|---|---|---|---|
|0|`SW_HIDE`|YES|YES|
|1|`SW_NORMAL`|NO|NO|
|2|`SW_SHOWMINIMIZED`|YES|YES|
|3|`SW_SHOWMAXIMIZED`|NO|NO|
|4|`SW_SHOWNOACTIVATE`|NO|NO|
|5|`SW_SHOW`|NO|NO|
|6|`SW_MINIMIZE`|YES|YES|
|7|`SW_SHOWMINNOACTIVE`|YES|YES|
|8|`SW_SHOWNA`|NO|NO|
|9|`SW_RESTORE`|NO|NO|
|10|`SW_SHOWDEFAULT`|NO|NO|
|11|`SW_FORCEMINIMIZE`|YES|YES|
Since this now matched up perfectly with what I was suspecting should happen *and* it was easier to implement than picking apart the `WM_WINDOWPOSCHANGING` message, it is what I believe the design should be.
Finally, with the *fake window* changing state to and from `WS_VISIBLE`... it was appearing on the screen and showing up in the taskbar and alt-tab. To resolve this, I utilized [**DWMWA_CLOAK**](https://docs.microsoft.com//windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute) which makes the window completely invisible even when in a normally `WS_VISIBLE` state. I then added the [**WS_EX_TOOLWINDOW**](https://docs.microsoft.com/windows/win32/winmsg/extended-window-styles) extended window style to hide it from alt-tab and taskbar.
With this setup, the PTY now has a completely invisible window with a synchronized `WS_VISIBLE` state with the real terminal window, a bidirectional signal channel to adjust the state between the terminal and PTY, and the ability to catch `user32` calls being made against the *fake window* that the PTY stands up for the client command-line application.
## UI/UX Design
The visible change in behavior is that a call to `::ShowWindow()` against the `::GetConsoleWindow()`
handle that is returned by the ConPTY will be propagated to the attached Terminal. As such, a
user will see the entire window be shown or hidden if one of the underlying attached
command-line applications requests a show or hide.
At the initial moment, the fact that the Terminal contains tabbed and/or paned sessions and
therefore multiple command-line clients on "different sessions" are attached to the same window
is partially ignored. If one attached client calls "show", the entire window will be shown with
all tabs. If another calls "hide", the entire window will be hidden including the other tab
that just requested a show. In the opposite direction, when the window is shown, all attached
PTYs for all tabs/panes will be alerted that they're now shown at once.
## Capabilities
### Accessibility
Users of assistive devices will have the same experience that they did with the legacy Windows
Console after this change. If a command-line application decides to show or hide the window
through the API without their consent, they will receive notification of the showing/hiding
window through our UIA framework.
Prior to this change, the window would have always remained visible and there would be no
action.
Overall, the experience will be consistent between what is happening on-screen and what is
presented through the UIA framework to assistive tools.
For third party terminals, it will be up to them to decide what their reaction and experience is.
### Security
We will maintain the security and integrity of the Terminal application chosen for presentation
by not revealing its true window handle information to the client process through the existing
`::GetConsoleWindow()` API. Through our design for default terminal applications, the final
presentation terminal could be Windows Terminal or it could be any third-party terminal that
meets the same specifications for communication. Giving raw access to its `HWND` to a client
application could disrupt its security.
By maintaining a level of separation with this feature by generating a "fake window" in the
ConPTY layer and only forwarding events, the attached terminal (whether ours or a 3rd party)
maintains the final level of control on whether or not it processes the message. This is
improved security over the legacy console host where the tool had full backdoor style access
to all `user32` based window APIs.
### Reliability
This test doesn't improve overall reliability in the system because utilities that are relying
on the behavior that this compatibility shim will restore are already introducing additional
layers of complexity and additional processes into their operation than were strictly necessary
simply by not stating their desires upfront at creation time.
In some capacity, you could argue it increases reliability of the existing tests that were
using this complex behavior in that they didn't work before and they will work now, but
the entire process is fragile. We're just restoring the fragile process instead of having
it not work at all.
### Compatibility
This change restores compatibility with existing applications that were relying on the behavior
we had excluded from our initial designs.
### Performance, Power, and Efficiency
The performance of tooling that is leveraging this process to create a console and then hide
or manipulate the session after the fact will be significantly worse when we enable the
default Windows Terminal than it was with the old Windows Console. This is because the
Terminal is significantly heavier weight (with its modern technologies like WinUI) and
will take more time to start and more committed memory. Additionally, more processes
will be in use because there will be the `conhost.exe` doing the ConPTY translation
and then the `windowsterminal.exe` doing the presentation.
However, this particular feature doesn't do anything to make that better or worse.
The appropriate solution for any tooling, test, or scenario that has a need for
performance and efficiency is to use the flags to `::CreateProcess` in the first place
to specify that they did not need a console window session at all, or to direct its
placement and visibility as a part of the creation call. We are working with
Microsoft's test automation tooling (TAEF) as well as the Windows performance
fundamentals (FUN) team to ensure that the test automation supports creating sessions
without a console window and that our internal performance test suite uses those
specifications on creation so we have accurate performance testing of the operating
system.
## Potential Issues
### Multiple clients sharing the same window host
With the initial design, multiple clients sharing the same window host will effectively
share the window state. Two different tabs or panes with two different client applications
could fight over the show/hide state of the window. In the initial revision, this is
ignored because this feature is being driven by a narrow failure scenario in the test gates.
In the reported scenario, a singular application is default-launched into a singular tab
in a terminal window and then the application expects to be able to hide it after the creation.
In the future, we may have to implement a conflict resolution or a graphical variance to
compensate for multiple tabs.
### Other verbs against the console window handle
This scenario initially focuses on just the `::ShowWindow()` call against the window handle
from `::GetConsoleWindow()`. Other functions from `user32` against the `HWND` will not
necessarily be captured and forwarded to the attached terminal application. And even more
specifically, we're focusing only on the Show and Hide state. Other state modifications that
are subtle related to z-ordering, activation, maximizing, snapping, and so on are not considered.
## Future considerations
### Multiple clients
If the multiple clients problem becomes more widespread, we may need to change the graphical
behavior of the Windows Terminal window to only hide certain tabs or panes when a command
comes in instead of hiding the entire window (unless of course there is only one tab/pane).
We may also need to adjust that once consensus is reached among tabs/panes that it can then
and only then propagate up to the entire window.
We will decide on this after we receive feedback that it is a necessary scenario. Otherwise,
we will hold for now.
### Other verbs
If it turns out that we discover tests/scenarios that need maximizing, activation, or other
properties of the `::ShowWindow()` call to be propagated to maintain compatibility, we will
be able to carry those through on the same channel and command. Most of them have an existing
equivalent in `XTWINOPS`. Those that do not, we would want to probably avoid as they will not
be implemented in any other terminal. We would extend the protocol as an absolute last resort
and only after receiving feedback from the greater worldwide terminal community.
### Z-ordering
The channel we're establishing here to communicate information about the window and its
placement may be useful for the z-ordering issues we have in #2988. In those scenarios,
a console client application is attempting to launch and position a window on top of the
terminal, wherever it is. Further synchronizing the state of the new fake-window in the
ConPTY with the real window on the terminal side may enable those tools to function as
they expect.
This is another circumstance we didn't expect: having command-line applications create windows
with a need for complex layout and ordering. These sorts of behaviors cannot be translated
to a universal language and will not be available off the singular machine, so encouraged
alternative methods like command-line based UI. However, for single-box scenarios, this
behavior is engrained in some Windows tooling due to its ease of use.
## Resources
- [Default Terminal spec](https://github.com/microsoft/terminal/pull/7414)
- [Z-ordering issue](https://github.com/microsoft/terminal/issues/2988)
- See all the embedded links in this document to Windows API resources

View File

@@ -60,7 +60,7 @@ Users will be able to add a new setting to their font objects (added in [#10433]
There is one point to note here about clashing. For example, if a user has the old "weight" setting defined _as well as_ a "wght" axis defined, we will only use the "wght" axis value. We prioritize that value for a few reasons:
1. It is the more recent addition to our settings model. Thus, it is likely that a user that has defined both values probably just forgot to remove the old value.
2. It is the more precise value, it is a specific float value whereas the the old "weight" setting is an enum (that eventually gets mapped to a float value).
2. It is the more precise value, it is a specific float value whereas the old "weight" setting is an enum (that eventually gets mapped to a float value).
## Capabilities

View File

@@ -0,0 +1,79 @@
---
author: Ítalo Masserano arkthur/italo.masserano@gmail.com
created on: 2022-03-02
last updated: 2022-03-02
issue id: 4066
---
# Theme-controlled color scheme switch
## Abstract
The idea is for Windows Terminal to change automatically its color schemes according to what theme is selected, including the case where `system` theme is selected.
## Inspiration
I work remotely as a developer, so I have to spend a lot of hours in front of my PC screen. In my setup, right behind my desk I have a window, which is the only source of natural sunlight in my room.
Normally I like dark modes in all the programs and apps I use, but when there's too much sunlight, it becomes annoying, and sometimes even painful, to work in dark mode. So, I have all the programs and apps I use (at least, those that can) set to switch their color themes to what the system has.
The company I work for sent me a Macbook Pro, and my personal phone is an Android, both with automatic dark mode at sunset and light mode at sunrise, and in those devices it's been working relatively well. In Windows, as it is known, there's no such feature, so I manually change between dark and light mode when it's needed, and most of the programs and apps I use go along with this change. Windows Terminal, is not one of them.
The theme changes just as expected, but in an app like this, this change only affects the top of the window, leaving almost all of the screen at the mercy of what the color scheme is, and it doesn't depend on the theme, which defeats any attempt to make a good use of the `system` theme feature.
## Solution Design
Could be implemented in the form of:
```json
"colorScheme": {
"light": "BlulocoLight",
"dark": "BlulocoDark"
}
```
or:
```json
"colorSchemeLight": "BlulocoLight",
"colorSchemeDark": "BlulocoDark"
```
## UI/UX Design
In a first version it could look like the terminal in Visual Studio Code, and an improvement could be to have light mode specific color schemes, just like those already present in Windows terminal. A good idea could be to get an inspiration in Dark++ and Light++ VSCode color themes.
A user could benefit from a more healthy light level contrast between the screen their looking at and the environment they are, reducing the risk of headache or developing/intensifying eye problems, and any other related eye conditions. Plus, it adds to a more consistent experience between different programs and apps, and the system itself.
## Capabilities
### Accessibility
This feature improves accessibility more than any other capability, because the key is to be able to read and see anything better when the environment, both the external to the device, and the device's system itself, is in a certain mode (dark/light).
### Security
The proposed solution is based in the current way one sets Windows Terminal settings, so it isn't expected to add any security issues.
### Reliability
Adding this feature would make Windows Terminal more reliable when it's expected that it changes it's visual theme/color scheme along with the whole system.
### Compatibility
The solution is not expected to break anything.
### Performance, Power, and Efficiency
It might increase the energy spent in the cases where people who were used to use the terminal in regular dark color schemes start using more light color schemes, but that is the case for any other program that shows lighter colors and I don't think the increment would be as high as to be even considered a downside.
## Potential Issues
Some users might not like the change in color schemes or be too used to the terminal being dark, but this may be avoided making the current schemes a default and adding this solution as an alternative setting.
## Future considerations
This solution might bring more attention to the color schemes setting, even more when considering light mode specific color schemes
## Resources
Inspired by what's been said in the issue comments. Credits to them.

View File

@@ -75,7 +75,7 @@ Some things we considered during this investigation:
- We could theoretically build an RPC tunnel between content and window
processes, and use the RPC connection to marshal the content process to the
elevated window. However, then _we_ would need to be responsible for
securing access the the RPC endpoint, and we feel even less confident doing
securing access the RPC endpoint, and we feel even less confident doing
that.
- Attempts were also made to use a window-broker-content architecture, with
the broker process having a static CLSID in the registry, and having the
@@ -456,7 +456,7 @@ accessible.
Unfortunately, these issues are OS bugs that are largely out of our own control.
We will continue to apply pressure to the centennial app team internally as we
encounter these issues. They are are team best equipped to resolve these issues.
encounter these issues. They are the team best equipped to resolve these issues.
### Default Terminal & auto-elevation

View File

@@ -317,7 +317,7 @@ Some things we considered during this investigation:
- We could theoretically build an RPC tunnel between content and window
processes, and use the RPC connection to marshal the content process to the
elevated window. However, then _we_ would need to be responsible for
securing access the the RPC endpoint, and we feel even less confident doing
securing access the RPC endpoint, and we feel even less confident doing
that.
- Attempts were also made to use a window-broker-content architecture, with
the broker process having a static CLSID in the registry, and having the

View File

@@ -35,7 +35,7 @@ through commandline arguments.
## User Stories
Lets consider some different ways that a user or developer might want want to
Lets consider some different ways that a user or developer might want to
use commandline arguments, to help guide the design.
1. A user wants to open the Windows Terminal with their default profile.

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

View File

@@ -0,0 +1,274 @@
---
author: Mike Griese @zadjii-msft
created on: 2022-05-18
last updated: 2022-10-28
issue id: n/a
---
# Markdown Notebooks in the Terminal
## Abstract
Notebooks have risen to popularity in recent years as a way of combining both
code and documentation in a single experience. They enable users to seamlessly
write code, and execute it to see the output, write documentation on the code,
and share that with others. However, there's not really anything like notebooks
for generic commandline experiences.
There are, however, markdown files. Markdown has become a bit of a lingua franca
of the developer experience. It's used prominently on GitHub - the "homepage" of
any repo on GitHub is now typically a markdown file. This file will have all
sorts of documentation, and notably these READMEs are often filled with commands
that one can execute for this project. Downloading, installing its dependencies,
building and running the project, etc, all commands that are already listed
todcay in READMEs across the world.
It would be a major convenience for users to be able to just load a pre-rendered
markdown file directly into their terminal windows. These files already include
marked blocks of code which identify sets of commands for the command line. It
should be as simple as clicking a button to run these commands in the Terminal,
or even to run a whole file worth of commands automatically.
## Background
### Inspiration
[Jupyter notebooks] ([a Jupyter example]) served as the primary inspiration for
this feature. Another shoutout to [this comment on HackerNews], which inspired a
lot of brainstorming on this topic over the last year since it was posted.
Many initial brainstorms were focused on more notebook-like features in the
Terminal. For example, finding ways to create individual terminal blocks inline
with commands, where each input command and its output would be separated from
one another, possibly separated by some sort of text/rich markup. This seemed to
precipitate the need for a new file syntax to be authored, where we could save
commands as they were run. The Terminal would then open this new file type as a
set of terminal blocks each pre-populated with these saved commands. Hoever,
this came with the drawback that projects which would like to leverage this
feature would have to author entirely new files, in a new syntax, just to make
use of this functionality. It seemed as though it was a niche enough UX that it
would be unlikely to broadly catch on.
The real inspiration here was that there's already a file type with broad
adoption that's already filled with commands like this. Markdown files. Take a
look at something like [building.md](../../../building.md). That file _already_
has a long set of commands for building the Terminal, running tests, deploying,
and various other helper scripts. Being able to immediately leverage this
existing ecosystem would undobtably lead to quicker adoption.
### User Stories
* **A**: The user can perform some commandline action (like `wt open
README.md`), which opens a new pane in the Terminal, with the markdown file
rendered into that pane.
* **B**: Markdown panes have buttons next to code blocks that allow the text of
that block to be sent directly to the adjacent terminal as input.
* **C**: The user can press different buttons to run some subset of all the
commands in the file
- **C.1**: Run all the commands in this file
- **C.2**: Run all the commands from (the currently selected block) to the end
of the file
- **C.1**: Run all the commands from (the currently selected block) to the
next header. (e.g., run all the commands in this section of the doc.)
* **D**: The user can edit the contents of the markdown file directly in the
Terminal.
* **E**: The Terminal could be configured to automatically open a markdown file
when `cd`ing to a directory
* **F**: The command for opening a markdown file also supports opening files
from the web (e.g. directly from GitHub)
* **G**: Code blocks in the markdown file are automatically assigned
autoincrementing IDs. The user can perform an action (via keybinding, command
palette, whatever) to execute a command block from the file, based on it's
assigned ID.
* **H**: ...
## Solution Design
The Terminal will allow for non-terminal content in a pane. This is something
that's been prototyped before, just needs a stronger justification for
finishing.
We'll leverage the Terminal's existing `sendInput` command to handle a lot of
this. That can be used to send keystrokes to the Terminal. Figuring out which
pane to send the `sendInput` command to might be a bit tricky. We'll need to
figure out what an action like that does when the active pane is not a terminal
pane.
Below are two different structures that could be used for imlpementing notebooks
in the Terminal. These are **Side-by-side** notebooks, and **Inline** notebooks.
Side-by-side notebooks consist of two panes - a standard terminal control in
one, and rendered markdown in the other. Inline notebooks are more like
traditional notebooks, with the terminal output rendered as a block within the
rendered markdown content.
### Side-by-side notebooks
Opening Markdown side-by-side with the Terminal output is certainly a little
different than the way a notebook traditionally works. Notebooks typically have
the code in a block, with output inline, below the block. Blocks could also just
be dedicated to text, for documentation mixed between the code. The feature
proposed here is different from that, for sure. For this proposal, the Terminal
still exists side-by-side from the source markdown. Running commands from the
markdown text would then send the command as a string of input to the connected
terminal. This approach was elected over attempting to create artificial
boundaries between different blocks.
Oftentimes, the command line is a very stateful experience. Set some environment
variables, run some script, use the errorlevel from the previous command, etc.
Running each block in wholly separate console instances would likely not be
useful.
Additionally, finding the separation between command line input and its output,
and the separation between individual commands is not an entirely trivial
process. Should we try to separate out the command input line into one buffer,
then the output into another buffer sounds great on paper. Consider, however,
something like `cmd.exe`, which does not provide any sort of distinction between
its input line and its output. Or `python.exe`, as an interactive REPL, which
certainly doesn't tell the terminal the difference. How would we be able to
detect something like a multi-line command at the REPL?
By keeing the command blocks out-of-band from the terminal output, we keep the
familiar terminal experience. It acts just as you'd expect, with no additional
configuration on the user's side. The commands are something that are already
written down, just waiting for the user to run them. They could even be sent to
something that isn't necessarily a shell - like pasting a bit of configuration
into a text editor like `vim` or `emacs`. The commands in the markdown side are
just strings of text to send to the terminal side - nothing more.
### Inline notebooks
Is there a way to have a more traditional notebook experience, where the
terminal output is rendered as blocks within the markdown itself? I believe
there is, by making agressive use of the FTCS mark VT sequences. These are
sequences that enable identifying the parts of the buffer as a prompt, the
commandline, or the output. We can use these to pull out individual rows of the
buffer, and display them as miniature terminal controls within the notebook.
This involves a single terminal insance backing the entire notebook. When the
user runs a code block in the notebook, we'll `sendInput` the text to the
backing terminal the same as before. We'll then use the `FTCS_COMMAND_EXECUTED`
sequence to know where the actual start of the output of the command is. We'll
gather all output from that moment on, and tee that to a separate "front"
control, which we use as the display for the output of the command. We'll render
that "front" control inline with the rest of the markdown content, immediately
below the code block for that command.
## UI/UX Design
### Side-by-side
![A rough mockup of what this feature might look like](./mockup-000.png)
### Inline
![](./inline-blocks-000.png)
## Tenents
<table>
<tr><td><strong>Accessibility</strong></td><td>
[comment]: # How will the proposed change impact accessibility for users of screen readers, assistive input devices, etc.
</td></tr>
<tr><td><strong>Security</strong></td><td>
[comment]: # How will the proposed change impact security?
Opening a file like this will _never_ auto-run commands. Commands must always be
intentionally interacted with, to provide a positive confirmation from the user
"yes, I intended to run `curl some.website.com/foo.txt`".
</td></tr>
<tr><td><strong>Reliability</strong></td><td>
[comment]: # Will the proposed change improve reliability? If not, why make the change?
</td></tr>
<tr><td><strong>Compatibility</strong></td><td>
[comment]: # Will the proposed change break existing code/behaviors? If so, how, and is the breaking change "worth it"?
It's critically important that nothing about this feature be necessarily Windows
Terminal-dependent. These features shouldn't be powered by some new undocumented
escape sequence that only we support. They should NOT be powered by new Windows
APIs, especially not any extensions to the Console API. There's no reason other
terminals couldn't also implement similar functionality.
</td></tr>
<tr><td><strong>Performance, Power, and Efficiency</strong></td><td>
[comment]: # Will the proposed change break existing code/behaviors? If so, how, and is the breaking change "worth it"?
</td></tr>
</table>
## Potential Issues
For rendering markdown, we'll either need:
* A way to display a WebView in a WinUI2 XAML Island
- This is something that's on the backlog currently for MUX 2.x. Theoretically
not too hard to add an `IInitializeWithWindow` to `WebView2` which should
enable XAML Islands, but needs more research.
* To migrate to WinUI 3
- In WinUI 3 I believe we should be able to get WebViews for free.
- We might still be a XAML Island in WinUI 3, which may complicate that.
* A C++ based method of rendering Markdown to UWP XAML
- There's a Windows Community Toolkit control for rendering to XAML currently,
but that is backed by C#, so we can't use that.
We'll also need the markdown rendering to be extensible, so that we can insert
"play" buttons alongside the blocks.
## Future considerations
### Tighter GitHub integration
GitHub already has the helpful "Open In GitHub" button for opening a repo in the
GitHub desktop client, or in Visual Studio.
![GitHub's "Clone, open or download" flyout](GitHub-open-with.png)
It'd be cool if there was a similar button for opening it up in the Terminal. It
could open the README immediately as a new tab, and then provide some sort of
InfoBar with a button that would allow the user to immediately clone the repo to
some location on their PC. This would likely need a protocol handler installed
by the Terminal to help connect the browser to the Terminal.
### Collapsible Blocks
One of the key features of notebooks is the ability to easily collapse regions
of the notebook. With the command output being out of band from the input of the
command, not as independent blocks, this becomes a bit trickier. To try and
reproduce a similar ability to collapse regions of the buffer, we'll look to
[Marks] in the terminal as a potential solution. The FinalTerm sequences allow a
client to mark up the region of the buffer that's the prompt, the command line,
and the output. Using those marks would provide an easy heuristic to allow users
to collapse the output of commands. These sequences however do require manual
configuration by the user, and are not expected to be able to work in all
environments (and shells). While powerful, because of this limitation, we didn't
want to architect the entire experience around something that wouldn't always
work.
## Resources
[comment]: # Be sure to add links to references, resources, footnotes, etc.
### Footnotes
<a name="footnote-1"><a>[1]:
[Jupyter notebooks]: https://jupyter.org/
[a Jupyter example]: https://jupyter.org/try-jupyter/retro/notebooks/?path=notebooks/Intro.ipynb
[this comment on HackerNews]: https://news.ycombinator.com/item?id=26617656
[Marks]: https://github.com/microsoft/terminal/issues/11000

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 868 KiB

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\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.UI.Xaml.2.7.1\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.7.1\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\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.UI.Xaml.2.7.1\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.7.1\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\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.UI.Xaml.2.7.1\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.7.1\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\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.UI.Xaml.2.7.1\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.7.1\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\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.UI.Xaml.2.7.1\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.7.1\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\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.UI.Xaml.2.7.1\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.7.1\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" targetFramework="native" />
<package id="Microsoft.UI.Xaml" version="2.7.1" 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\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.UI.Xaml.2.7.1\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.7.1\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\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.UI.Xaml.2.7.1\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.UI.Xaml.2.7.1\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" targetFramework="native" />
<package id="Microsoft.UI.Xaml" version="2.7.1" targetFramework="native" />
<package id="Microsoft.VCRTForwarders.140" version="1.0.4" targetFramework="native" />
</packages>

View File

@@ -95,7 +95,7 @@ void ATTR_ROW::ReplaceAttrs(const TextAttribute& toBeReplacedAttr, const TextAtt
// Routine Description:
// - Takes an attribute, and merges it into this row from beginIndex (inclusive) to endIndex (exclusive).
// - For example, if the current row was was [{4, BLUE}], the merge arguments were
// - For example, if the current row was [{4, BLUE}], the merge arguments were
// { beginIndex = 1, endIndex = 3, newAttr = RED }, then the row would modified to be
// [{ 1, BLUE}, {2, RED}, {1, BLUE}].
// Arguments:

View File

@@ -95,7 +95,7 @@ typename CharRow::const_iterator CharRow::cend() const noexcept
// - The calculated left boundary of the internal string.
size_t CharRow::MeasureLeft() const noexcept
{
const_iterator it = _data.cbegin();
auto it = _data.cbegin();
while (it != _data.cend() && it->IsSpace())
{
++it;
@@ -111,7 +111,7 @@ size_t CharRow::MeasureLeft() const noexcept
// - The calculated right boundary of the internal string.
size_t CharRow::MeasureRight() const
{
const_reverse_iterator it = _data.crbegin();
auto it = _data.crbegin();
while (it != _data.crend() && it->IsSpace())
{
++it;
@@ -132,7 +132,7 @@ void CharRow::ClearCell(const size_t column)
// - True if there is valid text in this row. False otherwise.
bool CharRow::ContainsText() const noexcept
{
for (const value_type& cell : _data)
for (const auto& cell : _data)
{
if (!cell.IsSpace())
{

View File

@@ -110,7 +110,7 @@ CharRowCellReference::const_iterator CharRowCellReference::end() const
bool operator==(const CharRowCellReference& ref, const std::vector<wchar_t>& glyph)
{
const DbcsAttribute& dbcsAttr = ref._cellData().DbcsAttr();
const auto& dbcsAttr = ref._cellData().DbcsAttr();
if (glyph.size() == 1 && dbcsAttr.IsGlyphStored())
{
return false;

View File

@@ -24,7 +24,7 @@ enum class LineRendition
constexpr SMALL_RECT ScreenToBufferLine(const SMALL_RECT& line, const LineRendition lineRendition)
{
// Use shift right to quickly divide the Left and Right by 2 for double width lines.
const auto scale = lineRendition == LineRendition::SingleWidth ? 0 : 1;
const SHORT scale = lineRendition == LineRendition::SingleWidth ? 0 : 1;
return { line.Left >> scale, line.Top, line.Right >> scale, line.Bottom };
}

View File

@@ -97,14 +97,14 @@ OutputCellIterator::OutputCellIterator(const std::wstring_view utf16Text) :
// Arguments:
// - utf16Text - UTF-16 text range
// - attribute - Color to apply over the entire range
OutputCellIterator::OutputCellIterator(const std::wstring_view utf16Text, const TextAttribute attribute) :
OutputCellIterator::OutputCellIterator(const std::wstring_view utf16Text, const TextAttribute& attribute, const size_t fillLimit) :
_mode(Mode::Loose),
_currentView(s_GenerateView(utf16Text, attribute)),
_run(utf16Text),
_attr(attribute),
_distance(0),
_pos(0),
_fillLimit(0)
_fillLimit(fillLimit)
{
}
@@ -302,7 +302,7 @@ OutputCellIterator& OutputCellIterator::operator++()
// - Reference to self after advancement.
OutputCellIterator OutputCellIterator::operator++(int)
{
auto temp(*this);
auto temp = *this;
operator++();
return temp;
}
@@ -478,7 +478,7 @@ OutputCellView OutputCellIterator::s_GenerateView(const wchar_t& wch, const Text
// - Object representing the view into this cell
OutputCellView OutputCellIterator::s_GenerateViewLegacyAttr(const WORD& legacyAttr) noexcept
{
WORD cleanAttr = legacyAttr;
auto cleanAttr = legacyAttr;
WI_ClearAllFlags(cleanAttr, COMMON_LVB_SBCSDBCS); // don't use legacy lead/trailing byte flags for colors
const TextAttribute attr(cleanAttr);

View File

@@ -38,7 +38,7 @@ public:
OutputCellIterator(const wchar_t& wch, const TextAttribute& attr, const size_t fillLimit = 0) noexcept;
OutputCellIterator(const CHAR_INFO& charInfo, const size_t fillLimit = 0) noexcept;
OutputCellIterator(const std::wstring_view utf16Text);
OutputCellIterator(const std::wstring_view utf16Text, const TextAttribute attribute);
OutputCellIterator(const std::wstring_view utf16Text, const TextAttribute& attribute, const size_t fillLimit = 0);
OutputCellIterator(const gsl::span<const WORD> legacyAttributes) noexcept;
OutputCellIterator(const gsl::span<const CHAR_INFO> charInfos) noexcept;
OutputCellIterator(const gsl::span<const OutputCell> cells);

View File

@@ -113,8 +113,8 @@ OutputCellIterator ROW::WriteCells(OutputCellIterator it, const size_t index, co
auto currentColor = it->TextAttr();
uint16_t colorUses = 0;
uint16_t colorStarts = gsl::narrow_cast<uint16_t>(index);
uint16_t currentIndex = colorStarts;
auto colorStarts = gsl::narrow_cast<uint16_t>(index);
auto currentIndex = colorStarts;
while (it && currentIndex <= finalColumnInRow)
{
@@ -141,7 +141,7 @@ OutputCellIterator ROW::WriteCells(OutputCellIterator it, const size_t index, co
// Fill the text if the behavior isn't set to saying there's only a color stored in this iterator.
if (it->TextAttrBehavior() != TextAttributeBehavior::StoredOnly)
{
const bool fillingLastColumn = currentIndex == finalColumnInRow;
const auto fillingLastColumn = currentIndex == finalColumnInRow;
// TODO: MSFT: 19452170 - We need to ensure when writing any trailing byte that the one to the left
// is a matching leading byte. Likewise, if we're writing a leading byte, we need to make sure we still have space in this loop

View File

@@ -11,6 +11,8 @@ static_assert(sizeof(TextAttribute) == 14);
static_assert(alignof(TextAttribute) == 2);
// Ensure that we can memcpy() and memmove() the struct for performance.
static_assert(std::is_trivially_copyable_v<TextAttribute>);
// Assert that the use of memcmp() for comparisons is safe.
static_assert(std::has_unique_object_representations_v<TextAttribute>);
namespace
{
@@ -112,10 +114,10 @@ TextAttribute TextAttribute::StripErroneousVT16VersionsOfLegacyDefaults(const Te
// - a WORD with legacy-style attributes for this textattribute.
WORD TextAttribute::GetLegacyAttributes() const noexcept
{
const BYTE fgIndex = _foreground.GetLegacyIndex(s_legacyDefaultForeground);
const BYTE bgIndex = _background.GetLegacyIndex(s_legacyDefaultBackground);
const auto fgIndex = _foreground.GetLegacyIndex(s_legacyDefaultForeground);
const auto bgIndex = _background.GetLegacyIndex(s_legacyDefaultBackground);
const WORD metaAttrs = _wAttrLegacy & META_ATTRS;
const bool brighten = IsIntense() && _foreground.CanBeBrightened();
const auto brighten = IsIntense() && _foreground.CanBeBrightened();
return fgIndex | (bgIndex << 4) | metaAttrs | (brighten ? FOREGROUND_INTENSITY : 0);
}

View File

@@ -76,12 +76,15 @@ public:
void Invert() noexcept;
friend constexpr bool operator==(const TextAttribute& a, const TextAttribute& b) noexcept;
friend constexpr bool operator!=(const TextAttribute& a, const TextAttribute& b) noexcept;
friend constexpr bool operator==(const TextAttribute& attr, const WORD& legacyAttr) noexcept;
friend constexpr bool operator!=(const TextAttribute& attr, const WORD& legacyAttr) noexcept;
friend constexpr bool operator==(const WORD& legacyAttr, const TextAttribute& attr) noexcept;
friend constexpr bool operator!=(const WORD& legacyAttr, const TextAttribute& attr) noexcept;
inline bool operator==(const TextAttribute& other) const noexcept
{
return memcmp(this, &other, sizeof(TextAttribute)) == 0;
}
inline bool operator!=(const TextAttribute& other) const noexcept
{
return memcmp(this, &other, sizeof(TextAttribute)) != 0;
}
bool IsLegacy() const noexcept;
bool IsIntense() const noexcept;
@@ -167,7 +170,7 @@ private:
uint16_t _hyperlinkId; // sizeof: 2, alignof: 2
TextColor _foreground; // sizeof: 4, alignof: 1
TextColor _background; // sizeof: 4, alignof: 1
ExtendedAttributes _extendedAttrs; // sizeof: 1, alignof: 1
ExtendedAttributes _extendedAttrs; // sizeof: 2, alignof: 2
#ifdef UNIT_TESTING
friend class TextBufferTests;
@@ -184,20 +187,6 @@ enum class TextAttributeBehavior
StoredOnly, // only use the contained text attribute and skip the insertion of anything else
};
constexpr bool operator==(const TextAttribute& a, const TextAttribute& b) noexcept
{
return a._wAttrLegacy == b._wAttrLegacy &&
a._foreground == b._foreground &&
a._background == b._background &&
a._extendedAttrs == b._extendedAttrs &&
a._hyperlinkId == b._hyperlinkId;
}
constexpr bool operator!=(const TextAttribute& a, const TextAttribute& b) noexcept
{
return !(a == b);
}
#ifdef UNIT_TESTING
#define LOG_ATTR(attr) (Log::Comment(NoThrowString().Format( \

View File

@@ -54,6 +54,8 @@ constexpr std::array<BYTE, 256> Index256ToIndex16 = {
// We should only need 4B for TextColor. Any more than that is just waste.
static_assert(sizeof(TextColor) == 4);
// Assert that the use of memcmp() for comparisons is safe.
static_assert(std::has_unique_object_representations_v<TextColor>);
bool TextColor::CanBeBrightened() const noexcept
{
@@ -111,6 +113,8 @@ void TextColor::SetIndex(const BYTE index, const bool isIndex256) noexcept
{
_meta = isIndex256 ? ColorType::IsIndex256 : ColorType::IsIndex16;
_index = index;
_green = 0;
_blue = 0;
}
// Method Description:
@@ -123,6 +127,9 @@ void TextColor::SetIndex(const BYTE index, const bool isIndex256) noexcept
void TextColor::SetDefault() noexcept
{
_meta = ColorType::IsDefault;
_red = 0;
_green = 0;
_blue = 0;
}
// Method Description:

View File

@@ -49,6 +49,8 @@ enum class ColorAlias : size_t
{
DefaultForeground,
DefaultBackground,
FrameForeground,
FrameBackground,
ENUM_COUNT // must be the last element in the enum class
};
@@ -72,10 +74,13 @@ public:
static constexpr BYTE BRIGHT_CYAN = 14;
static constexpr BYTE BRIGHT_WHITE = 15;
static constexpr size_t DEFAULT_FOREGROUND = 256;
static constexpr size_t DEFAULT_BACKGROUND = 257;
static constexpr size_t CURSOR_COLOR = 258;
static constexpr size_t TABLE_SIZE = 259;
// Entries 256 to 260 are reserved for XTerm compatibility.
static constexpr size_t DEFAULT_FOREGROUND = 261;
static constexpr size_t DEFAULT_BACKGROUND = 262;
static constexpr size_t FRAME_FOREGROUND = 263;
static constexpr size_t FRAME_BACKGROUND = 264;
static constexpr size_t CURSOR_COLOR = 265;
static constexpr size_t TABLE_SIZE = 266;
constexpr TextColor() noexcept :
_meta{ ColorType::IsDefault },
@@ -101,8 +106,15 @@ public:
{
}
friend constexpr bool operator==(const TextColor& a, const TextColor& b) noexcept;
friend constexpr bool operator!=(const TextColor& a, const TextColor& b) noexcept;
bool operator==(const TextColor& other) const noexcept
{
return memcmp(this, &other, sizeof(TextColor)) == 0;
}
bool operator!=(const TextColor& other) const noexcept
{
return memcmp(this, &other, sizeof(TextColor)) != 0;
}
bool CanBeBrightened() const noexcept;
bool IsLegacy() const noexcept;
@@ -151,19 +163,6 @@ private:
#endif
};
bool constexpr operator==(const TextColor& a, const TextColor& b) noexcept
{
return a._meta == b._meta &&
a._red == b._red &&
a._green == b._green &&
a._blue == b._blue;
}
bool constexpr operator!=(const TextColor& a, const TextColor& b) noexcept
{
return !(a == b);
}
#ifdef UNIT_TESTING
namespace WEX

View File

@@ -140,10 +140,10 @@ std::pair<COORD, COORD> Search::GetFoundLocation() const noexcept
// - direction - The intended direction of the search
// Return Value:
// - Coordinate to start the search from.
COORD Search::s_GetInitialAnchor(IUiaData& uiaData, const Direction direction)
COORD Search::s_GetInitialAnchor(const IUiaData& uiaData, const Direction direction)
{
const auto& textBuffer = uiaData.GetTextBuffer();
const COORD textBufferEndPosition = uiaData.GetTextBufferEndPosition();
const auto textBufferEndPosition = uiaData.GetTextBufferEndPosition();
if (uiaData.IsSelectionActive())
{
// Convert the screen position of the selection anchor into an equivalent
@@ -192,7 +192,7 @@ bool Search::_FindNeedleInHaystackAt(const COORD pos, COORD& start, COORD& end)
start = { 0 };
end = { 0 };
COORD bufferPos = pos;
auto bufferPos = pos;
for (const auto& needleCell : _needle)
{
@@ -307,7 +307,7 @@ void Search::_UpdateNextPosition()
// We put the next position to:
// Forward: (0, 0)
// Backward: the position of the end of the text buffer
const COORD bufferEndPosition = _uiaData.GetTextBufferEndPosition();
const auto bufferEndPosition = _uiaData.GetTextBufferEndPosition();
if (_coordNext.Y > bufferEndPosition.Y ||
(_coordNext.Y == bufferEndPosition.Y && _coordNext.X > bufferEndPosition.X))

View File

@@ -66,7 +66,7 @@ private:
void _IncrementCoord(COORD& coord) const noexcept;
void _DecrementCoord(COORD& coord) const noexcept;
static COORD s_GetInitialAnchor(Microsoft::Console::Types::IUiaData& uiaData, const Direction dir);
static COORD s_GetInitialAnchor(const Microsoft::Console::Types::IUiaData& uiaData, const Direction dir);
static std::vector<std::vector<wchar_t>> s_CreateNeedleFromString(const std::wstring& wstr);

View File

@@ -91,7 +91,7 @@ const ROW& TextBuffer::GetRowByOffset(const size_t index) const
const size_t totalRows = TotalRowCount();
// Rows are stored circularly, so the index you ask for is offset by the start position and mod the total of rows.
const size_t offsetIndex = (_firstRow + index) % totalRows;
const auto offsetIndex = (_firstRow + index) % totalRows;
return _storage.at(offsetIndex);
}
@@ -107,7 +107,7 @@ ROW& TextBuffer::GetRowByOffset(const size_t index)
const size_t totalRows = TotalRowCount();
// Rows are stored circularly, so the index you ask for is offset by the start position and mod the total of rows.
const size_t offsetIndex = (_firstRow + index) % totalRows;
const auto offsetIndex = (_firstRow + index) % totalRows;
return _storage.at(offsetIndex);
}
@@ -201,8 +201,8 @@ TextBufferCellIterator TextBuffer::GetCellDataAt(const COORD at, const Viewport
bool TextBuffer::_AssertValidDoubleByteSequence(const DbcsAttribute dbcsAttribute)
{
// To figure out if the sequence is valid, we have to look at the character that comes before the current one
const COORD coordPrevPosition = _GetPreviousFromCursor();
ROW& prevRow = GetRowByOffset(coordPrevPosition.Y);
const auto coordPrevPosition = _GetPreviousFromCursor();
auto& prevRow = GetRowByOffset(coordPrevPosition.Y);
DbcsAttribute prevDbcsAttr;
try
{
@@ -214,8 +214,8 @@ bool TextBuffer::_AssertValidDoubleByteSequence(const DbcsAttribute dbcsAttribut
return false;
}
bool fValidSequence = true; // Valid until proven otherwise
bool fCorrectableByErase = false; // Can't be corrected until proven otherwise
auto fValidSequence = true; // Valid until proven otherwise
auto fCorrectableByErase = false; // Can't be corrected until proven otherwise
// Here's the matrix of valid items:
// N = None (single byte)
@@ -290,7 +290,7 @@ bool TextBuffer::_PrepareForDoubleByteSequence(const DbcsAttribute dbcsAttribute
// older versions of conhost simply let pass by unflinching.
LOG_HR_IF(E_NOT_VALID_STATE, !(_AssertValidDoubleByteSequence(dbcsAttribute))); // Shouldn't be uncorrectable sequences unless something is very wrong.
bool fSuccess = true;
auto fSuccess = true;
// Now compensate if we don't have enough space for the upcoming double byte sequence
// We only need to compensate for leading bytes
if (dbcsAttribute.IsLeading())
@@ -385,12 +385,12 @@ OutputCellIterator TextBuffer::WriteLine(const OutputCellIterator givenIt,
}
// Get the row and write the cells
ROW& row = GetRowByOffset(target.Y);
auto& row = GetRowByOffset(target.Y);
const auto newIt = row.WriteCells(givenIt, target.X, wrap, limitRight);
// Take the cell distance written and notify that it needs to be repainted.
const auto written = newIt.GetCellDistance(givenIt);
const Viewport paint = Viewport::FromDimensions(target, { gsl::narrow<SHORT>(written), 1 });
const auto paint = Viewport::FromDimensions(target, { gsl::narrow<SHORT>(written), 1 });
TriggerRedraw(paint);
return newIt;
@@ -410,19 +410,19 @@ bool TextBuffer::InsertCharacter(const std::wstring_view chars,
const TextAttribute attr)
{
// Ensure consistent buffer state for double byte characters based on the character type we're about to insert
bool fSuccess = _PrepareForDoubleByteSequence(dbcsAttribute);
auto fSuccess = _PrepareForDoubleByteSequence(dbcsAttribute);
if (fSuccess)
{
// Get the current cursor position
short const iRow = GetCursor().GetPosition().Y; // row stored as logical position, not array position
short const iCol = GetCursor().GetPosition().X; // column logical and array positions are equal.
const auto iRow = GetCursor().GetPosition().Y; // row stored as logical position, not array position
const auto iCol = GetCursor().GetPosition().X; // column logical and array positions are equal.
// Get the row associated with the given logical position
ROW& Row = GetRowByOffset(iRow);
auto& Row = GetRowByOffset(iRow);
// Store character and double byte data
CharRow& charRow = Row.GetCharRow();
auto& charRow = Row.GetCharRow();
try
{
@@ -506,7 +506,7 @@ bool TextBuffer::IncrementCursor()
// Move the cursor one position to the right
GetCursor().IncrementXPosition(1);
bool fSuccess = true;
auto fSuccess = true;
// If we've passed the final valid column...
if (GetCursor().GetPosition().X > iFinalColumnIndex)
{
@@ -527,8 +527,8 @@ bool TextBuffer::IncrementCursor()
// - true if we successfully moved the cursor.
bool TextBuffer::NewlineCursor()
{
bool fSuccess = false;
short const iFinalRowIndex = GetSize().BottomInclusive();
auto fSuccess = false;
const auto iFinalRowIndex = GetSize().BottomInclusive();
// Reset the cursor position to 0 and move down one line
GetCursor().SetXPosition(0);
@@ -562,7 +562,7 @@ bool TextBuffer::IncrementCircularBuffer(const bool inVtMode)
// to the logical position 0 in the window (cursor coordinates and all other coordinates).
if (_isActiveBuffer)
{
_renderer.TriggerCircling();
_renderer.TriggerFlush(true);
}
// Prune hyperlinks to delete obsolete references
@@ -576,7 +576,7 @@ bool TextBuffer::IncrementCircularBuffer(const bool inVtMode)
// the current background color, but with no meta attributes set.
fillAttributes.SetStandardErase();
}
const bool fSuccess = _storage.at(_firstRow).Reset(fillAttributes);
const auto fSuccess = _storage.at(_firstRow).Reset(fillAttributes);
if (fSuccess)
{
// Now proceed to increment.
@@ -618,7 +618,7 @@ COORD TextBuffer::GetLastNonSpaceCharacter(std::optional<const Microsoft::Consol
// If the X coordinate turns out to be -1, the row was empty, we need to search backwards for the real end of text.
const auto viewportTop = viewport.Top();
bool fDoBackUp = (coordEndOfText.X < 0 && coordEndOfText.Y > viewportTop); // this row is empty, and we're not at the top
auto fDoBackUp = (coordEndOfText.X < 0 && coordEndOfText.Y > viewportTop); // this row is empty, and we're not at the top
while (fDoBackUp)
{
coordEndOfText.Y--;
@@ -645,7 +645,7 @@ COORD TextBuffer::GetLastNonSpaceCharacter(std::optional<const Microsoft::Consol
// - NOTE: Will return 0,0 if already in the top left corner
COORD TextBuffer::_GetPreviousFromCursor() const
{
COORD coordPosition = GetCursor().GetPosition();
auto coordPosition = GetCursor().GetPosition();
// If we're not at the left edge, simply move the cursor to the left by one
if (coordPosition.X > 0)
@@ -826,7 +826,7 @@ void TextBuffer::SetCurrentLineRendition(const LineRendition lineRendition)
auto fillAttrs = GetCurrentAttributes();
fillAttrs.SetStandardErase();
const size_t fillOffset = GetLineWidth(rowIndex);
const size_t fillLength = GetSize().Width() - fillOffset;
const auto fillLength = GetSize().Width() - fillOffset;
const auto fillData = OutputCellIterator{ fillChar, fillAttrs, fillLength };
row.WriteCells(fillData, fillOffset, false);
// We also need to make sure the cursor is clamped within the new width.
@@ -917,7 +917,7 @@ void TextBuffer::Reset()
const SHORT TopRowIndex = (GetFirstRowIndex() + TopRow) % currentSize.Y;
// rotate rows until the top row is at index 0
for (int i = 0; i < TopRowIndex; i++)
for (auto i = 0; i < TopRowIndex; i++)
{
_storage.emplace_back(std::move(_storage.front()));
_storage.erase(_storage.begin());
@@ -1081,7 +1081,7 @@ ROW& TextBuffer::_GetFirstRow()
// - will throw exception if called with the first row of the text buffer
ROW& TextBuffer::_GetPrevRowNoWrap(const ROW& Row)
{
int prevRowIndex = Row.GetId() - 1;
auto prevRowIndex = Row.GetId() - 1;
if (prevRowIndex < 0)
{
prevRowIndex = TotalRowCount() - 1;
@@ -1167,9 +1167,9 @@ const COORD TextBuffer::GetWordStart(const COORD target, const std::wstring_view
// - The COORD for the first character on the current/previous READABLE "word" (inclusive)
const COORD TextBuffer::_GetWordStartForAccessibility(const COORD target, const std::wstring_view wordDelimiters) const
{
COORD result = target;
auto result = target;
const auto bufferSize = GetSize();
bool stayAtOrigin = false;
auto stayAtOrigin = false;
// ignore left boundary. Continue until readable text found
while (_GetDelimiterClassAt(result, wordDelimiters) != DelimiterClass::RegularChar)
@@ -1212,7 +1212,7 @@ const COORD TextBuffer::_GetWordStartForAccessibility(const COORD target, const
// - The COORD for the first character on the current word or delimiter run (stopped by the left margin)
const COORD TextBuffer::_GetWordStartForSelection(const COORD target, const std::wstring_view wordDelimiters) const
{
COORD result = target;
auto result = target;
const auto bufferSize = GetSize();
const auto initialDelimiter = _GetDelimiterClassAt(result, wordDelimiters);
@@ -1284,7 +1284,7 @@ const COORD TextBuffer::GetWordEnd(const COORD target, const std::wstring_view w
const COORD TextBuffer::_GetWordEndForAccessibility(const COORD target, const std::wstring_view wordDelimiters, const COORD limit) const
{
const auto bufferSize{ GetSize() };
COORD result{ target };
auto result{ target };
if (bufferSize.CompareInBounds(target, limit, true) >= 0)
{
@@ -1341,7 +1341,7 @@ const COORD TextBuffer::_GetWordEndForSelection(const COORD target, const std::w
return target;
}
COORD result = target;
auto result = target;
const auto initialDelimiter = _GetDelimiterClassAt(result, wordDelimiters);
// expand right until we hit the right boundary or a different delimiter class
@@ -1465,7 +1465,7 @@ bool TextBuffer::MoveToPreviousWord(COORD& pos, std::wstring_view wordDelimiters
// - pos - The COORD for the first cell of the current glyph (inclusive)
const til::point TextBuffer::GetGlyphStart(const til::point pos, std::optional<til::point> limitOptional) const
{
COORD resultPos = pos.to_win32_coord();
auto resultPos = pos.to_win32_coord();
const auto bufferSize = GetSize();
const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
@@ -1493,7 +1493,7 @@ const til::point TextBuffer::GetGlyphStart(const til::point pos, std::optional<t
// - pos - The COORD for the last cell of the current glyph (exclusive)
const til::point TextBuffer::GetGlyphEnd(const til::point pos, bool accessibilityMode, std::optional<til::point> limitOptional) const
{
COORD resultPos = pos.to_win32_coord();
auto resultPos = pos.to_win32_coord();
const auto bufferSize = GetSize();
const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
@@ -1569,7 +1569,7 @@ bool TextBuffer::MoveToNextGlyph(til::point& pos, bool allowExclusiveEnd, std::o
// - pos - The COORD for the first cell of the previous glyph (inclusive)
bool TextBuffer::MoveToPreviousGlyph(til::point& pos, std::optional<til::point> limitOptional) const
{
COORD resultPos = pos.to_win32_coord();
auto resultPos = pos.to_win32_coord();
const auto bufferSize = GetSize();
const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
@@ -1582,7 +1582,7 @@ bool TextBuffer::MoveToPreviousGlyph(til::point& pos, std::optional<til::point>
}
// try to move. If we can't, we're done.
const bool success = bufferSize.DecrementInBounds(resultPos, true);
const auto success = bufferSize.DecrementInBounds(resultPos, true);
if (resultPos != bufferSize.EndExclusive() && GetCellDataAt(resultPos)->DbcsAttr().IsLeading())
{
bufferSize.DecrementInBounds(resultPos, true);
@@ -1713,10 +1713,10 @@ const TextBuffer::TextAndColor TextBuffer::GetText(const bool includeCRLF,
const bool formatWrappedRows) const
{
TextAndColor data;
const bool copyTextColor = GetAttributeColors != nullptr;
const auto copyTextColor = GetAttributeColors != nullptr;
// preallocate our vectors to reduce reallocs
size_t const rows = selectionRects.size();
const auto rows = selectionRects.size();
data.text.reserve(rows);
if (copyTextColor)
{
@@ -1729,7 +1729,7 @@ const TextBuffer::TextAndColor TextBuffer::GetText(const bool includeCRLF,
{
const UINT iRow = selectionRects.at(i).Top;
const Viewport highlight = Viewport::FromInclusive(selectionRects.at(i));
const auto highlight = Viewport::FromInclusive(selectionRects.at(i));
// retrieve the data from the screen buffer
auto it = GetCellDataAt(highlight.Origin(), highlight);
@@ -1774,7 +1774,7 @@ const TextBuffer::TextAndColor TextBuffer::GetText(const bool includeCRLF,
}
// We apply formatting to rows if the row was NOT wrapped or formatting of wrapped rows is allowed
const bool shouldFormatRow = formatWrappedRows || !GetRowByOffset(iRow).WasWrapForced();
const auto shouldFormatRow = formatWrappedRows || !GetRowByOffset(iRow).WasWrapForced();
if (trimTrailingWhitespace)
{
@@ -1806,7 +1806,7 @@ const TextBuffer::TextAndColor TextBuffer::GetText(const bool includeCRLF,
if (copyTextColor)
{
// can't see CR/LF so just use black FG & BK
COLORREF const Blackness = RGB(0x00, 0x00, 0x00);
const auto Blackness = RGB(0x00, 0x00, 0x00);
selectionFgAttr.push_back(Blackness);
selectionFgAttr.push_back(Blackness);
selectionBkAttr.push_back(Blackness);
@@ -1883,7 +1883,7 @@ std::string TextBuffer::GenHTML(const TextAndColor& rows,
}
// copy text and info color from buffer
bool hasWrittenAnyText = false;
auto hasWrittenAnyText = false;
std::optional<COLORREF> fgColor = std::nullopt;
std::optional<COLORREF> bkColor = std::nullopt;
for (size_t row = 0; row < rows.text.size(); row++)
@@ -1931,7 +1931,7 @@ std::string TextBuffer::GenHTML(const TextAndColor& rows,
break;
}
bool colorChanged = false;
auto colorChanged = false;
if (!fgColor.has_value() || rows.FgAttr.at(row).at(col) != fgColor.value())
{
fgColor = rows.FgAttr.at(row).at(col);
@@ -1990,10 +1990,10 @@ std::string TextBuffer::GenHTML(const TextAndColor& rows,
constexpr size_t ClipboardHeaderSize = 157;
// these values are byte offsets from start of clipboard
const size_t htmlStartPos = ClipboardHeaderSize;
const size_t htmlEndPos = ClipboardHeaderSize + gsl::narrow<size_t>(htmlBuilder.tellp());
const size_t fragStartPos = ClipboardHeaderSize + gsl::narrow<size_t>(htmlHeader.length());
const size_t fragEndPos = htmlEndPos - HtmlFooter.length();
const auto htmlStartPos = ClipboardHeaderSize;
const auto htmlEndPos = ClipboardHeaderSize + gsl::narrow<size_t>(htmlBuilder.tellp());
const auto fragStartPos = ClipboardHeaderSize + gsl::narrow<size_t>(htmlHeader.length());
const auto fragEndPos = htmlEndPos - HtmlFooter.length();
// header required by HTML 0.9 format
std::ostringstream clipHeaderBuilder;
@@ -2050,7 +2050,7 @@ std::string TextBuffer::GenRTF(const TextAndColor& rows, const int fontHeightPoi
// keys are colors represented by COLORREF
// values are indices of the corresponding colors in the color table
std::unordered_map<COLORREF, int> colorMap;
int nextColorIndex = 1; // leave 0 for the default color and start from 1.
auto nextColorIndex = 1; // leave 0 for the default color and start from 1.
// RTF color table
std::ostringstream colorTableBuilder;
@@ -2103,7 +2103,7 @@ std::string TextBuffer::GenRTF(const TextAndColor& rows, const int fontHeightPoi
break;
}
bool colorChanged = false;
auto colorChanged = false;
if (!fgColor.has_value() || rows.FgAttr.at(row).at(col) != fgColor.value())
{
fgColor = rows.FgAttr.at(row).at(col);
@@ -2120,7 +2120,7 @@ std::string TextBuffer::GenRTF(const TextAndColor& rows, const int fontHeightPoi
{
writeAccumulatedChars(false);
int bkColorIndex = 0;
auto bkColorIndex = 0;
if (colorMap.find(bkColor.value()) != colorMap.end())
{
// color already exists in the map, just retrieve the index
@@ -2137,7 +2137,7 @@ std::string TextBuffer::GenRTF(const TextAndColor& rows, const int fontHeightPoi
bkColorIndex = nextColorIndex++;
}
int fgColorIndex = 0;
auto fgColorIndex = 0;
if (colorMap.find(fgColor.value()) != colorMap.end())
{
// color already exists in the map, just retrieve the index
@@ -2234,31 +2234,31 @@ HRESULT TextBuffer::Reflow(TextBuffer& oldBuffer,
const std::optional<Viewport> lastCharacterViewport,
std::optional<std::reference_wrapper<PositionInformation>> positionInfo)
{
const Cursor& oldCursor = oldBuffer.GetCursor();
Cursor& newCursor = newBuffer.GetCursor();
const auto& oldCursor = oldBuffer.GetCursor();
auto& newCursor = newBuffer.GetCursor();
// We need to save the old cursor position so that we can
// place the new cursor back on the equivalent character in
// the new buffer.
const COORD cOldCursorPos = oldCursor.GetPosition();
const COORD cOldLastChar = oldBuffer.GetLastNonSpaceCharacter(lastCharacterViewport);
const auto cOldCursorPos = oldCursor.GetPosition();
const auto cOldLastChar = oldBuffer.GetLastNonSpaceCharacter(lastCharacterViewport);
const short cOldRowsTotal = cOldLastChar.Y + 1;
COORD cNewCursorPos = { 0 };
bool fFoundCursorPos = false;
bool foundOldMutable = false;
bool foundOldVisible = false;
HRESULT hr = S_OK;
auto fFoundCursorPos = false;
auto foundOldMutable = false;
auto foundOldVisible = false;
auto hr = S_OK;
// Loop through all the rows of the old buffer and reprint them into the new buffer
short iOldRow = 0;
for (; iOldRow < cOldRowsTotal; iOldRow++)
{
// Fetch the row and its "right" which is the last printable character.
const ROW& row = oldBuffer.GetRowByOffset(iOldRow);
const short cOldColsTotal = oldBuffer.GetLineWidth(iOldRow);
const CharRow& charRow = row.GetCharRow();
short iRight = gsl::narrow_cast<short>(charRow.MeasureRight());
const auto& row = oldBuffer.GetRowByOffset(iOldRow);
const auto cOldColsTotal = oldBuffer.GetLineWidth(iOldRow);
const auto& charRow = row.GetCharRow();
auto iRight = gsl::narrow_cast<short>(charRow.MeasureRight());
// If we're starting a new row, try and preserve the line rendition
// from the row in the original buffer.
@@ -2297,8 +2297,6 @@ HRESULT TextBuffer::Reflow(TextBuffer& oldBuffer,
// the "right" boundary, which is one past the final valid
// character)
short iOldCol = 0;
auto chars{ row.GetCharRow().cbegin() };
auto attrs{ row.GetAttrRow().begin() };
const auto copyRight = iRight;
for (; iOldCol < copyRight; iOldCol++)
{
@@ -2311,9 +2309,9 @@ HRESULT TextBuffer::Reflow(TextBuffer& oldBuffer,
try
{
// TODO: MSFT: 19446208 - this should just use an iterator and the inserter...
const auto glyph = chars->Char();
const auto dbcsAttr = chars->DbcsAttr();
const auto textAttr = *attrs;
const auto glyph = row.GetCharRow().GlyphAt(iOldCol);
const auto dbcsAttr = row.GetCharRow().DbcsAttrAt(iOldCol);
const auto textAttr = row.GetAttrRow().GetAttrByColumn(iOldCol);
if (!newBuffer.InsertCharacter(glyph, dbcsAttr, textAttr))
{
@@ -2322,9 +2320,6 @@ HRESULT TextBuffer::Reflow(TextBuffer& oldBuffer,
}
}
CATCH_RETURN();
++chars;
++attrs;
}
// GH#32: Copy the attributes from the rest of the row into this new buffer.
@@ -2353,23 +2348,20 @@ HRESULT TextBuffer::Reflow(TextBuffer& oldBuffer,
const auto newWidth = newBuffer.GetLineWidth(newRowY);
// Stop when we get to the end of the buffer width, or the new position
// for inserting an attr would be past the right of the new buffer.
for (short copyAttrCol = iOldCol;
for (auto copyAttrCol = iOldCol;
copyAttrCol < cOldColsTotal && newAttrColumn < newWidth;
copyAttrCol++)
copyAttrCol++, newAttrColumn++)
{
try
{
// TODO: MSFT: 19446208 - this should just use an iterator and the inserter...
const auto textAttr = *attrs;
const auto textAttr = row.GetAttrRow().GetAttrByColumn(copyAttrCol);
if (!newRow.GetAttrRow().SetAttrToEnd(newAttrColumn, textAttr))
{
break;
}
}
CATCH_LOG(); // Not worth dying over.
++newAttrColumn;
++attrs;
}
// If we found the old row that the caller was interested in, set the
@@ -2444,7 +2436,7 @@ HRESULT TextBuffer::Reflow(TextBuffer& oldBuffer,
// |aaaaaaaaaaaaaaaaaaa| no wrap at the end (preserved hard newline)
// | |
// ^ and the cursor is now here.
const COORD coordNewCursor = newCursor.GetPosition();
const auto coordNewCursor = newCursor.GetPosition();
if (coordNewCursor.X == 0 && coordNewCursor.Y > 0)
{
if (newBuffer.GetRowByOffset(gsl::narrow_cast<size_t>(coordNewCursor.Y) - 1).WasWrapForced())
@@ -2468,7 +2460,7 @@ HRESULT TextBuffer::Reflow(TextBuffer& oldBuffer,
iOldRow < oldHeight && newRowY < newHeight;
iOldRow++)
{
const ROW& row = oldBuffer.GetRowByOffset(iOldRow);
const auto& row = oldBuffer.GetRowByOffset(iOldRow);
// Optimization: Since all these rows are below the last printable char,
// we can reasonably assume that they are filled with just spaces.
@@ -2502,9 +2494,9 @@ HRESULT TextBuffer::Reflow(TextBuffer& oldBuffer,
// Advance the cursor to the same offset as before
// get the number of newlines and spaces between the old end of text and the old cursor,
// then advance that many newlines and chars
int iNewlines = cOldCursorPos.Y - cOldLastChar.Y;
const int iIncrements = cOldCursorPos.X - cOldLastChar.X;
const COORD cNewLastChar = newBuffer.GetLastNonSpaceCharacter();
auto iNewlines = cOldCursorPos.Y - cOldLastChar.Y;
const auto iIncrements = cOldCursorPos.X - cOldLastChar.X;
const auto cNewLastChar = newBuffer.GetLastNonSpaceCharacter();
// If the last row of the new buffer wrapped, there's going to be one less newline needed,
// because the cursor is already on the next line
@@ -2522,7 +2514,7 @@ HRESULT TextBuffer::Reflow(TextBuffer& oldBuffer,
}
}
for (int r = 0; r < iNewlines; r++)
for (auto r = 0; r < iNewlines; r++)
{
if (!newBuffer.NewlineCursor())
{
@@ -2532,7 +2524,7 @@ HRESULT TextBuffer::Reflow(TextBuffer& oldBuffer,
}
if (SUCCEEDED(hr))
{
for (int c = 0; c < iIncrements - 1; c++)
for (auto c = 0; c < iIncrements - 1; c++)
{
if (!newBuffer.IncrementCursor())
{
@@ -2547,7 +2539,7 @@ HRESULT TextBuffer::Reflow(TextBuffer& oldBuffer,
if (SUCCEEDED(hr))
{
// Save old cursor size before we delete it
ULONG const ulSize = oldCursor.GetSize();
const auto ulSize = oldCursor.GetSize();
// Set size back to real size as it will be taking over the rendering duties.
newCursor.SetSize(ulSize);
@@ -2734,14 +2726,14 @@ PointTree TextBuffer::GetPatterns(const size_t firstRow, const size_t lastRow) c
// match and the previous match, so we use the size of the prefix
// along with the size of the match to determine the locations
size_t prefixSize = 0;
for (const std::vector<wchar_t> parsedGlyph : Utf16Parser::Parse(i->prefix().str()))
for (const auto parsedGlyph : Utf16Parser::Parse(i->prefix().str()))
{
const std::wstring_view glyph{ parsedGlyph.data(), parsedGlyph.size() };
prefixSize += IsGlyphFullWidth(glyph) ? 2 : 1;
}
const auto start = lenUpToThis + prefixSize;
size_t matchSize = 0;
for (const std::vector<wchar_t> parsedGlyph : Utf16Parser::Parse(i->str()))
for (const auto parsedGlyph : Utf16Parser::Parse(i->str()))
{
const std::wstring_view glyph{ parsedGlyph.data(), parsedGlyph.size() };
matchSize += IsGlyphFullWidth(glyph) ? 2 : 1;

View File

@@ -96,7 +96,7 @@ TextBufferCellIterator& TextBufferCellIterator::operator+=(const ptrdiff_t& move
{
// Note that this method is called intensively when the terminal is under heavy load.
// We need to aggressively optimize it, comparing to the -= operator.
ptrdiff_t move = movement;
auto move = movement;
if (move < 0)
{
// Early branching to leave the rare case to -= operator.
@@ -165,7 +165,7 @@ TextBufferCellIterator& TextBufferCellIterator::operator+=(const ptrdiff_t& move
_attrIter += diff;
_view.UpdateTextAttribute(*_attrIter);
const CharRow& charRow = _pRow->GetCharRow();
const auto& charRow = _pRow->GetCharRow();
_view.UpdateText(charRow.GlyphAt(newX));
_view.UpdateDbcsAttribute(charRow.DbcsAttrAt(newX));
_pos.X = newX;
@@ -191,7 +191,7 @@ TextBufferCellIterator& TextBufferCellIterator::operator+=(const ptrdiff_t& move
// - Reference to self after movement.
TextBufferCellIterator& TextBufferCellIterator::operator-=(const ptrdiff_t& movement)
{
ptrdiff_t move = movement;
auto move = movement;
if (move < 0)
{
return (*this) += (-move);
@@ -233,7 +233,7 @@ TextBufferCellIterator& TextBufferCellIterator::operator--()
// - Value with previous position prior to movement.
TextBufferCellIterator TextBufferCellIterator::operator++(int)
{
auto temp(*this);
auto temp = *this;
operator++();
return temp;
}
@@ -244,7 +244,7 @@ TextBufferCellIterator TextBufferCellIterator::operator++(int)
// - Value with previous position prior to movement.
TextBufferCellIterator TextBufferCellIterator::operator--(int)
{
auto temp(*this);
auto temp = *this;
operator--();
return temp;
}
@@ -257,7 +257,7 @@ TextBufferCellIterator TextBufferCellIterator::operator--(int)
// - Value with previous position prior to movement.
TextBufferCellIterator TextBufferCellIterator::operator+(const ptrdiff_t& movement)
{
auto temp(*this);
auto temp = *this;
temp += movement;
return temp;
}
@@ -270,7 +270,7 @@ TextBufferCellIterator TextBufferCellIterator::operator+(const ptrdiff_t& moveme
// - Value with previous position prior to movement.
TextBufferCellIterator TextBufferCellIterator::operator-(const ptrdiff_t& movement)
{
auto temp(*this);
auto temp = *this;
temp -= movement;
return temp;
}

View File

@@ -45,7 +45,7 @@ void TextAttributeTests::TestRoundtripLegacy()
WORD expectedLegacy = FOREGROUND_BLUE | BACKGROUND_RED;
WORD bgOnly = expectedLegacy & BG_ATTRS;
WORD bgShifted = bgOnly >> 4;
BYTE bgByte = (BYTE)(bgShifted);
auto bgByte = (BYTE)(bgShifted);
VERIFY_ARE_EQUAL(FOREGROUND_RED, bgByte);
@@ -65,9 +65,9 @@ void TextAttributeTests::TestRoundtripMetaBits()
COMMON_LVB_UNDERSCORE
};
for (int i = 0; i < ARRAYSIZE(metaFlags); ++i)
for (auto i = 0; i < ARRAYSIZE(metaFlags); ++i)
{
WORD flag = metaFlags[i];
auto flag = metaFlags[i];
WORD expectedLegacy = FOREGROUND_BLUE | BACKGROUND_RED | flag;
WORD metaOnly = expectedLegacy & META_ATTRS;
VERIFY_ARE_EQUAL(flag, metaOnly);
@@ -114,9 +114,9 @@ void TextAttributeTests::TestRoundtripExhaustive()
void TextAttributeTests::TestTextAttributeColorGetters()
{
const auto& colorTable = _renderSettings.GetColorTable();
const COLORREF red = RGB(255, 0, 0);
const COLORREF faintRed = RGB(127, 0, 0);
const COLORREF green = RGB(0, 255, 0);
const auto red = RGB(255, 0, 0);
const auto faintRed = RGB(127, 0, 0);
const auto green = RGB(0, 255, 0);
TextAttribute attr(red, green);
// verify that calculated foreground/background are the same as the direct
@@ -178,8 +178,8 @@ void TextAttributeTests::TestTextAttributeColorGetters()
void TextAttributeTests::TestReverseDefaultColors()
{
const auto& colorTable = _renderSettings.GetColorTable();
const COLORREF red = RGB(255, 0, 0);
const COLORREF green = RGB(0, 255, 0);
const auto red = RGB(255, 0, 0);
const auto green = RGB(0, 255, 0);
TextAttribute attr{};
// verify that calculated foreground/background are the same as the direct
@@ -260,9 +260,9 @@ void TextAttributeTests::TestRoundtripDefaultColors()
void TextAttributeTests::TestIntenseAsBright()
{
const auto& colorTable = _renderSettings.GetColorTable();
const COLORREF darkBlack = til::at(colorTable, 0);
const COLORREF brightBlack = til::at(colorTable, 8);
const COLORREF darkGreen = til::at(colorTable, 2);
const auto darkBlack = til::at(colorTable, 0);
const auto brightBlack = til::at(colorTable, 8);
const auto darkGreen = til::at(colorTable, 2);
TextAttribute attr{};

View File

@@ -118,7 +118,7 @@ void TextColorTests::TestBrightIndexColor()
void TextColorTests::TestRgbColor()
{
COLORREF myColor = RGB(7, 8, 9);
auto myColor = RGB(7, 8, 9);
TextColor rgbColor(myColor);
VERIFY_IS_FALSE(rgbColor.IsDefault());
@@ -140,7 +140,7 @@ void TextColorTests::TestRgbColor()
void TextColorTests::TestChangeColor()
{
COLORREF myColor = RGB(7, 8, 9);
auto myColor = RGB(7, 8, 9);
TextColor rgbColor(myColor);
VERIFY_IS_FALSE(rgbColor.IsDefault());

View File

@@ -28,7 +28,7 @@ class UnicodeStorageTests
// verify it was stored
auto findIt = storage._map.find(coord);
VERIFY_ARE_NOT_EQUAL(findIt, storage._map.end());
const std::vector<wchar_t>& newMoonGlyph = findIt->second;
const auto& newMoonGlyph = findIt->second;
VERIFY_ARE_EQUAL(newMoonGlyph.size(), newMoon.size());
for (size_t i = 0; i < newMoon.size(); ++i)
{
@@ -41,7 +41,7 @@ class UnicodeStorageTests
// verify the glyph was overwritten
findIt = storage._map.find(coord);
VERIFY_ARE_NOT_EQUAL(findIt, storage._map.end());
const std::vector<wchar_t>& fullMoonGlyph = findIt->second;
const auto& fullMoonGlyph = findIt->second;
VERIFY_ARE_EQUAL(fullMoonGlyph.size(), fullMoon.size());
for (size_t i = 0; i < fullMoon.size(); ++i)
{

View File

@@ -90,7 +90,7 @@ namespace SettingsModelLocalTests
}
Log::Comment(L"Roundtrip Test for Color Scheme");
Json::Value outJson{ scheme->ToJson() };
auto outJson{ scheme->ToJson() };
VERIFY_ARE_EQUAL(schemeObject, outJson);
}

View File

@@ -58,7 +58,7 @@ namespace SettingsModelLocalTests
const auto commands1Json = VerifyParseSucceeded(commands1String);
const auto commands2Json = VerifyParseSucceeded(commands2String);
IMap<winrt::hstring, Command> commands = winrt::single_threaded_map<winrt::hstring, Command>();
auto commands = winrt::single_threaded_map<winrt::hstring, Command>();
VERIFY_ARE_EQUAL(0u, commands.Size());
{
auto warnings = implementation::Command::LayerJson(commands, commands0Json);
@@ -92,7 +92,7 @@ namespace SettingsModelLocalTests
const auto commands2Json = VerifyParseSucceeded(commands2String);
const auto commands3Json = VerifyParseSucceeded(commands3String);
IMap<winrt::hstring, Command> commands = winrt::single_threaded_map<winrt::hstring, Command>();
auto commands = winrt::single_threaded_map<winrt::hstring, Command>();
VERIFY_ARE_EQUAL(0u, commands.Size());
{
auto warnings = implementation::Command::LayerJson(commands, commands0Json);
@@ -154,7 +154,7 @@ namespace SettingsModelLocalTests
const auto commands0Json = VerifyParseSucceeded(commands0String);
IMap<winrt::hstring, Command> commands = winrt::single_threaded_map<winrt::hstring, Command>();
auto commands = winrt::single_threaded_map<winrt::hstring, Command>();
VERIFY_ARE_EQUAL(0u, commands.Size());
auto warnings = implementation::Command::LayerJson(commands, commands0Json);
VERIFY_ARE_EQUAL(0u, warnings.size());
@@ -272,7 +272,7 @@ namespace SettingsModelLocalTests
const auto commands0Json = VerifyParseSucceeded(commands0String);
IMap<winrt::hstring, Command> commands = winrt::single_threaded_map<winrt::hstring, Command>();
auto commands = winrt::single_threaded_map<winrt::hstring, Command>();
VERIFY_ARE_EQUAL(0u, commands.Size());
auto warnings = implementation::Command::LayerJson(commands, commands0Json);
VERIFY_ARE_EQUAL(3u, warnings.size());
@@ -298,7 +298,7 @@ namespace SettingsModelLocalTests
const std::string commands0String{ R"([ { "name": { "key": "DuplicateTabCommandKey"}, "command": "copy" } ])" };
const auto commands0Json = VerifyParseSucceeded(commands0String);
IMap<winrt::hstring, Command> commands = winrt::single_threaded_map<winrt::hstring, Command>();
auto commands = winrt::single_threaded_map<winrt::hstring, Command>();
VERIFY_ARE_EQUAL(0u, commands.Size());
{
auto warnings = implementation::Command::LayerJson(commands, commands0Json);
@@ -340,7 +340,7 @@ namespace SettingsModelLocalTests
const auto commands0Json = VerifyParseSucceeded(commands0String);
IMap<winrt::hstring, Command> commands = winrt::single_threaded_map<winrt::hstring, Command>();
auto commands = winrt::single_threaded_map<winrt::hstring, Command>();
VERIFY_ARE_EQUAL(0u, commands.Size());
auto warnings = implementation::Command::LayerJson(commands, commands0Json);
VERIFY_ARE_EQUAL(0u, warnings.size());
@@ -410,7 +410,7 @@ namespace SettingsModelLocalTests
const auto commands0Json = VerifyParseSucceeded(commands0String);
IMap<winrt::hstring, Command> commands = winrt::single_threaded_map<winrt::hstring, Command>();
auto commands = winrt::single_threaded_map<winrt::hstring, Command>();
VERIFY_ARE_EQUAL(0u, commands.Size());
auto warnings = implementation::Command::LayerJson(commands, commands0Json);
VERIFY_ARE_EQUAL(0u, warnings.size());
@@ -473,7 +473,7 @@ namespace SettingsModelLocalTests
const auto commands0Json = VerifyParseSucceeded(commands0String);
IMap<winrt::hstring, Command> commands = winrt::single_threaded_map<winrt::hstring, Command>();
auto commands = winrt::single_threaded_map<winrt::hstring, Command>();
VERIFY_ARE_EQUAL(0u, commands.Size());
auto warnings = implementation::Command::LayerJson(commands, commands0Json);
VERIFY_ARE_EQUAL(0u, warnings.size());

View File

@@ -159,7 +159,7 @@ namespace SettingsModelLocalTests
}
{
// Case 2: Bad settings
bool caughtExpectedException = false;
auto caughtExpectedException = false;
try
{
auto settings = winrt::make_self<implementation::CascadiaSettings>(settingsWithoutProfiles);
@@ -173,7 +173,7 @@ namespace SettingsModelLocalTests
}
{
// Case 3: Bad settings
bool caughtExpectedException = false;
auto caughtExpectedException = false;
try
{
auto settings = winrt::make_self<implementation::CascadiaSettings>(settingsWithEmptyProfiles);
@@ -886,7 +886,7 @@ namespace SettingsModelLocalTests
const winrt::guid guid1{ Utils::GuidFromString(L"{6239a42c-6666-49a3-80bd-e8fdd045185c}") };
const winrt::guid guid2{ Utils::GuidFromString(L"{2C4DE342-38B7-51CF-B940-2309A097F518}") };
const winrt::guid fakeGuid{ Utils::GuidFromString(L"{FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF}") };
const winrt::guid autogeneratedGuid{ implementation::Profile::_GenerateGuidForProfile(name3, L"") };
const auto autogeneratedGuid{ implementation::Profile::_GenerateGuidForProfile(name3, L"") };
const auto settings = createSettings(settings0String);

View File

@@ -24,7 +24,7 @@ public:
Json::Value root;
std::string errs;
const bool parseResult = reader->parse(content.data(), content.data() + content.size(), &root, &errs);
const auto parseResult = reader->parse(content.data(), content.data() + content.size(), &root, &errs);
VERIFY_IS_TRUE(parseResult, winrt::to_hstring(errs).c_str());
return root;
};

View File

@@ -40,7 +40,6 @@ namespace SettingsModelLocalTests
TEST_METHOD(LayerProfilesOnArray);
TEST_METHOD(DuplicateProfileTest);
TEST_METHOD(TestGenGuidsForProfiles);
TEST_METHOD(TestCorrectOldDefaultShellPaths);
};
@@ -367,31 +366,43 @@ namespace SettingsModelLocalTests
]
})" };
static constexpr std::string_view userProfiles{ R"({
"profiles": [
"profiles": {
"defaults":
{
"name" : "powershell 1",
"commandline": "powershell.exe",
"guid" : "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}"
"commandline": "pwsh.exe"
},
{
"name" : "powershell 2",
"commandline": "powershell.exe",
"guid" : "{61c54bbd-0000-5271-96e7-009a87ff44bf}"
},
{
"name" : "cmd 1",
"commandline": "cmd.exe",
"guid" : "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}"
},
{
"name" : "cmd 2",
"commandline": "cmd.exe",
"guid" : "{0caa0dad-0000-5f56-a8ff-afceeeaa6101}"
}
]
"list":
[
{
"name" : "powershell 1",
"commandline": "powershell.exe",
"guid" : "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}"
},
{
"name" : "powershell 2",
"commandline": "powershell.exe",
"guid" : "{61c54bbd-0000-5271-96e7-009a87ff44bf}"
},
{
"name" : "cmd 1",
"commandline": "cmd.exe",
"guid" : "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}"
},
{
"name" : "cmd 2",
"commandline": "cmd.exe",
"guid" : "{0caa0dad-0000-5f56-a8ff-afceeeaa6101}"
}
]
}
})" };
const auto settings = winrt::make_self<implementation::CascadiaSettings>(userProfiles, inboxProfiles);
implementation::SettingsLoader loader{ userProfiles, inboxProfiles };
loader.MergeInboxIntoUserSettings();
loader.FinalizeLayering();
loader.FixupUserSettings();
const auto settings = winrt::make_self<implementation::CascadiaSettings>(std::move(loader));
const auto allProfiles = settings->AllProfiles();
VERIFY_ARE_EQUAL(4u, allProfiles.Size());
VERIFY_ARE_EQUAL(L"powershell 1", allProfiles.GetAt(0).Name());

View File

@@ -82,9 +82,9 @@ namespace SettingsModelLocalTests
expectedArgv.reserve(expectedArgc * 65);
input.reserve(expectedArgc * 67);
for (int i = 0; i < expectedArgc; ++i)
for (auto i = 0; i < expectedArgc; ++i)
{
const bool useQuotes = static_cast<bool>(rng(2));
const auto useQuotes = static_cast<bool>(rng(2));
// 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');

View File

@@ -199,7 +199,7 @@ namespace TerminalAppLocalTests
VERIFY_SUCCEEDED(TestData::TryGetValue(L"testPass", testPass), L"Get a commandline to test");
AppCommandlineArgs appArgs{};
std::vector<const wchar_t*>& rawCommands{ commandsToTest.at(testPass) };
auto& rawCommands{ commandsToTest.at(testPass) };
_logCommandline(rawCommands);
auto commandlines = AppCommandlineArgs::BuildCommands(rawCommands);
@@ -232,7 +232,7 @@ namespace TerminalAppLocalTests
VERIFY_SUCCEEDED(TestData::TryGetValue(L"testPass", testPass), L"Get a commandline to test");
AppCommandlineArgs appArgs{};
std::vector<const wchar_t*>& rawCommands{ commandsToTest.at(testPass) };
auto& rawCommands{ commandsToTest.at(testPass) };
_logCommandline(rawCommands);
auto commandlines = AppCommandlineArgs::BuildCommands(rawCommands);
@@ -266,7 +266,7 @@ namespace TerminalAppLocalTests
VERIFY_SUCCEEDED(TestData::TryGetValue(L"testPass", testPass), L"Get a commandline to test");
AppCommandlineArgs appArgs{};
std::vector<const wchar_t*>& rawCommands{ commandsToTest.at(testPass) };
auto& rawCommands{ commandsToTest.at(testPass) };
_logCommandline(rawCommands);
auto commandlines = AppCommandlineArgs::BuildCommands(rawCommands);
@@ -439,7 +439,7 @@ namespace TerminalAppLocalTests
END_TEST_METHOD_PROPERTIES()
INIT_TEST_PROPERTY(bool, useShortForm, L"If true, use `nt` instead of `new-tab`");
const wchar_t* subcommand = useShortForm ? L"nt" : L"new-tab";
auto subcommand = useShortForm ? L"nt" : L"new-tab";
{
AppCommandlineArgs appArgs{};
@@ -697,7 +697,7 @@ namespace TerminalAppLocalTests
END_TEST_METHOD_PROPERTIES()
INIT_TEST_PROPERTY(bool, useShortForm, L"If true, use `sp` instead of `split-pane`");
const wchar_t* subcommand = useShortForm ? L"sp" : L"split-pane";
auto subcommand = useShortForm ? L"sp" : L"split-pane";
{
AppCommandlineArgs appArgs{};
@@ -880,8 +880,8 @@ namespace TerminalAppLocalTests
INIT_TEST_PROPERTY(bool, useShortFormNewTab, L"If true, use `nt` instead of `new-tab`");
INIT_TEST_PROPERTY(bool, useShortFormSplitPane, L"If true, use `sp` instead of `split-pane`");
const wchar_t* ntSubcommand = useShortFormNewTab ? L"nt" : L"new-tab";
const wchar_t* spSubcommand = useShortFormSplitPane ? L"sp" : L"split-pane";
auto ntSubcommand = useShortFormNewTab ? L"nt" : L"new-tab";
auto spSubcommand = useShortFormSplitPane ? L"sp" : L"split-pane";
AppCommandlineArgs appArgs{};
std::vector<const wchar_t*> rawCommands{ L"wt.exe", ntSubcommand, L";", spSubcommand };
@@ -1009,7 +1009,7 @@ namespace TerminalAppLocalTests
END_TEST_METHOD_PROPERTIES()
INIT_TEST_PROPERTY(bool, useShortForm, L"If true, use `ft` instead of `focus-tab`");
const wchar_t* subcommand = useShortForm ? L"ft" : L"focus-tab";
auto subcommand = useShortForm ? L"ft" : L"focus-tab";
{
AppCommandlineArgs appArgs{};
@@ -1101,7 +1101,7 @@ namespace TerminalAppLocalTests
END_TEST_METHOD_PROPERTIES()
INIT_TEST_PROPERTY(bool, useShortForm, L"If true, use `mf` instead of `move-focus`");
const wchar_t* subcommand = useShortForm ? L"mf" : L"move-focus";
auto subcommand = useShortForm ? L"mf" : L"move-focus";
{
AppCommandlineArgs appArgs{};
@@ -1214,7 +1214,7 @@ namespace TerminalAppLocalTests
void CommandlineTest::ParseSwapPaneArgs()
{
const wchar_t* subcommand = L"swap-pane";
auto subcommand = L"swap-pane";
{
AppCommandlineArgs appArgs{};
@@ -1332,7 +1332,7 @@ namespace TerminalAppLocalTests
END_TEST_METHOD_PROPERTIES()
INIT_TEST_PROPERTY(bool, useShortForm, L"If true, use `fp` instead of `focus-pane`");
const wchar_t* subcommand = useShortForm ? L"fp" : L"focus-pane";
auto subcommand = useShortForm ? L"fp" : L"focus-pane";
{
AppCommandlineArgs appArgs{};
@@ -1765,7 +1765,7 @@ namespace TerminalAppLocalTests
END_TEST_METHOD_PROPERTIES()
INIT_TEST_PROPERTY(bool, useShortForm, L"If true, use `sp` instead of `split-pane`");
const wchar_t* subcommand = useShortForm ? L"sp" : L"split-pane";
auto subcommand = useShortForm ? L"sp" : L"split-pane";
{
AppCommandlineArgs appArgs{};

View File

@@ -81,7 +81,7 @@ HRESULT RunOnUIThread(const TFunction& function)
return HRESULT_FROM_WIN32(::GetLastError());
}
HRESULT invokeResult = E_FAIL;
auto invokeResult = E_FAIL;
auto asyncAction = d.RunAsync(winrt::Windows::UI::Core::CoreDispatcherPriority::Normal,
[&invokeResult, &function]() {
@@ -94,7 +94,7 @@ HRESULT RunOnUIThread(const TFunction& function)
});
// Wait for the callback to complete
HRESULT hr = completedEvent.Wait();
auto hr = completedEvent.Wait();
if (FAILED(hr))
{
return hr;

View File

@@ -681,6 +681,10 @@ namespace TerminalAppLocalTests
void TabTests::TryZoomPane()
{
BEGIN_TEST_METHOD_PROPERTIES()
TEST_METHOD_PROPERTY(L"IsolationLevel", L"Method")
END_TEST_METHOD_PROPERTIES()
auto page = _commonSetup();
Log::Comment(L"Create a second pane");
@@ -1052,7 +1056,7 @@ namespace TerminalAppLocalTests
VERIFY_ARE_EQUAL(4u, page->_tabs.Size());
TestOnUIThread([&page]() {
uint32_t focusedIndex = page->_GetFocusedTabIndex().value_or(-1);
auto focusedIndex = page->_GetFocusedTabIndex().value_or(-1);
VERIFY_ARE_EQUAL(3u, focusedIndex, L"Verify the fourth tab is the focused one");
});
@@ -1062,7 +1066,7 @@ namespace TerminalAppLocalTests
});
TestOnUIThread([&page]() {
uint32_t focusedIndex = page->_GetFocusedTabIndex().value_or(-1);
auto focusedIndex = page->_GetFocusedTabIndex().value_or(-1);
VERIFY_ARE_EQUAL(1u, focusedIndex, L"Verify the second tab is the focused one");
});
@@ -1088,7 +1092,7 @@ namespace TerminalAppLocalTests
});
TestOnUIThread([&page]() {
uint32_t focusedIndex = page->_GetFocusedTabIndex().value_or(-1);
auto focusedIndex = page->_GetFocusedTabIndex().value_or(-1);
VERIFY_ARE_EQUAL(3u, focusedIndex, L"Verify the fourth tab is the focused one");
});
@@ -1109,7 +1113,7 @@ namespace TerminalAppLocalTests
});
TestOnUIThread([&page]() {
uint32_t focusedIndex = page->_GetFocusedTabIndex().value_or(-1);
auto focusedIndex = page->_GetFocusedTabIndex().value_or(-1);
VERIFY_ARE_EQUAL(1u, focusedIndex, L"Verify the second tab is the focused one");
});
@@ -1121,7 +1125,7 @@ namespace TerminalAppLocalTests
page->_SelectNextTab(true, nullptr);
});
TestOnUIThread([&page]() {
uint32_t focusedIndex = page->_GetFocusedTabIndex().value_or(-1);
auto focusedIndex = page->_GetFocusedTabIndex().value_or(-1);
VERIFY_ARE_EQUAL(2u, focusedIndex, L"Verify the third tab is the focused one");
});
@@ -1133,7 +1137,7 @@ namespace TerminalAppLocalTests
page->_SelectNextTab(true, nullptr);
});
TestOnUIThread([&page]() {
uint32_t focusedIndex = page->_GetFocusedTabIndex().value_or(-1);
auto focusedIndex = page->_GetFocusedTabIndex().value_or(-1);
VERIFY_ARE_EQUAL(3u, focusedIndex, L"Verify the fourth tab is the focused one");
});
}
@@ -1244,7 +1248,7 @@ namespace TerminalAppLocalTests
page->WindowName(args.ProposedName());
});
bool windowNameChanged = false;
auto windowNameChanged = false;
page->PropertyChanged([&page, &windowNameChanged](auto&&, const winrt::WUX::Data::PropertyChangedEventArgs& args) mutable {
if (args.PropertyName() == L"WindowNameForDisplay")
{
@@ -1274,7 +1278,7 @@ namespace TerminalAppLocalTests
page->RenameFailed();
});
bool windowNameChanged = false;
auto windowNameChanged = false;
page->PropertyChanged([&page, &windowNameChanged](auto&&, const winrt::WUX::Data::PropertyChangedEventArgs& args) mutable {
if (args.PropertyName() == L"WindowNameForDisplay")
@@ -1312,7 +1316,8 @@ namespace TerminalAppLocalTests
TestOnUIThread([&page]() {
Log::Comment(L"Emulate previewing the SetColorScheme action");
SetColorSchemeArgs args{ L"Vintage" };
page->_PreviewColorScheme(args);
ActionAndArgs actionAndArgs{ ShortcutAction::SetColorScheme, args };
page->_PreviewAction(actionAndArgs);
});
TestOnUIThread([&page]() {
@@ -1379,7 +1384,8 @@ namespace TerminalAppLocalTests
TestOnUIThread([&page]() {
Log::Comment(L"Emulate previewing the SetColorScheme action");
SetColorSchemeArgs args{ L"Vintage" };
page->_PreviewColorScheme(args);
ActionAndArgs actionAndArgs{ ShortcutAction::SetColorScheme, args };
page->_PreviewAction(actionAndArgs);
});
TestOnUIThread([&page]() {

View File

@@ -38,7 +38,7 @@ static bool _IsGlyphWideForceNarrowFallback(const std::wstring_view /* glyph */)
static bool _EnsureStaticInitialization()
{
// use C++11 magic statics to make sure we only do this once.
static bool initialized = []() {
static auto initialized = []() {
// *** THIS IS A SINGLETON ***
SetGlyphWidthFallback(_IsGlyphWideForceNarrowFallback);
@@ -55,7 +55,7 @@ LRESULT CALLBACK HwndTerminal::HwndTerminalWndProc(
try
{
#pragma warning(suppress : 26490) // Win32 APIs can only store void*, have to use reinterpret_cast
HwndTerminal* terminal = reinterpret_cast<HwndTerminal*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
auto terminal = reinterpret_cast<HwndTerminal*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
if (terminal)
{
@@ -178,7 +178,7 @@ HwndTerminal::HwndTerminal(HWND parentHwnd) :
{
_EnsureStaticInitialization();
HINSTANCE hInstance = wil::GetModuleInstanceHandle();
auto hInstance = wil::GetModuleInstanceHandle();
if (RegisterTermClass(hInstance))
{
@@ -214,7 +214,9 @@ HRESULT HwndTerminal::Initialize()
_terminal = std::make_unique<::Microsoft::Terminal::Core::Terminal>();
auto renderThread = std::make_unique<::Microsoft::Console::Render::RenderThread>();
auto* const localPointerToThread = renderThread.get();
const auto& renderSettings = _terminal->GetRenderSettings();
auto& renderSettings = _terminal->GetRenderSettings();
renderSettings.SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, RGB(12, 12, 12));
renderSettings.SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, RGB(204, 204, 204));
_renderer = std::make_unique<::Microsoft::Console::Render::Renderer>(renderSettings, _terminal.get(), nullptr, 0, std::move(renderThread));
RETURN_HR_IF_NULL(E_POINTER, localPointerToThread);
RETURN_IF_FAILED(localPointerToThread->Initialize(_renderer.get()));
@@ -237,11 +239,7 @@ HRESULT HwndTerminal::Initialize()
_renderEngine = std::move(dxEngine);
_terminal->SetBackgroundCallback([](auto) {});
_terminal->Create(COORD{ 80, 25 }, 1000, *_renderer);
_terminal->SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, RGB(12, 12, 12));
_terminal->SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, RGB(204, 204, 204));
_terminal->SetWriteInputCallback([=](std::wstring_view input) noexcept { _WriteTextToConnection(input); });
localPointerToThread->EnablePainting();
@@ -536,7 +534,7 @@ try
};
auto lock = _terminal->LockForWriting();
const bool altPressed = GetKeyState(VK_MENU) < 0;
const auto altPressed = GetKeyState(VK_MENU) < 0;
const til::size fontSize{ this->_actualFont.GetSize() };
this->_terminal->SetBlockSelection(altPressed);
@@ -626,7 +624,7 @@ void _stdcall TerminalClearSelection(void* terminal)
bool _stdcall TerminalIsSelectionActive(void* terminal)
{
const auto publicTerminal = static_cast<const HwndTerminal*>(terminal);
const bool selectionActive = publicTerminal->_terminal->IsSelectionActive();
const auto selectionActive = publicTerminal->_terminal->IsSelectionActive();
return selectionActive;
}
@@ -684,7 +682,7 @@ static ControlKeyStates getControlKeyState() noexcept
bool HwndTerminal::_CanSendVTMouseInput() const noexcept
{
// Only allow the transit of mouse events if shift isn't pressed.
const bool shiftPressed = GetKeyState(VK_SHIFT) < 0;
const auto shiftPressed = GetKeyState(VK_SHIFT) < 0;
return !shiftPressed && _focused && _terminal->IsTrackingMouseInput();
}
@@ -703,7 +701,7 @@ try
wheelDelta = HIWORD(wParam);
// If it's a *WHEEL event, it's in screen coordinates, not window (?!)
POINT coordsToTransform = cursorPosition.to_win32_point();
auto coordsToTransform = cursorPosition.to_win32_point();
ScreenToClient(_hwnd.get(), &coordsToTransform);
cursorPosition = til::point{ coordsToTransform };
}
@@ -788,15 +786,17 @@ void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR font
{
auto lock = publicTerminal->_terminal->LockForWriting();
publicTerminal->_terminal->SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, theme.DefaultForeground);
publicTerminal->_terminal->SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, theme.DefaultBackground);
auto& renderSettings = publicTerminal->_terminal->GetRenderSettings();
renderSettings.SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, theme.DefaultForeground);
renderSettings.SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, theme.DefaultBackground);
publicTerminal->_renderEngine->SetSelectionBackground(theme.DefaultSelectionBackground, theme.SelectionBackgroundAlpha);
// Set the font colors
for (size_t tableIndex = 0; tableIndex < 16; tableIndex++)
{
// It's using gsl::at to check the index is in bounds, but the analyzer still calls this array-to-pointer-decay
[[gsl::suppress(bounds .3)]] publicTerminal->_terminal->SetColorTableEntry(tableIndex, gsl::at(theme.ColorTable, tableIndex));
[[gsl::suppress(bounds .3)]] renderSettings.SetColorTableEntry(tableIndex, gsl::at(theme.ColorTable, tableIndex));
}
}
@@ -849,7 +849,7 @@ void __stdcall TerminalKillFocus(void* terminal)
// Arguments:
// - rows - Rows of text data to copy
// - fAlsoCopyFormatting - true if the color and formatting should also be copied, false otherwise
HRESULT HwndTerminal::_CopyTextToSystemClipboard(const TextBuffer::TextAndColor& rows, bool const fAlsoCopyFormatting)
HRESULT HwndTerminal::_CopyTextToSystemClipboard(const TextBuffer::TextAndColor& rows, const bool fAlsoCopyFormatting)
try
{
std::wstring finalString;
@@ -861,17 +861,17 @@ try
}
// allocate the final clipboard data
const size_t cchNeeded = finalString.size() + 1;
const size_t cbNeeded = sizeof(wchar_t) * cchNeeded;
const auto cchNeeded = finalString.size() + 1;
const auto cbNeeded = sizeof(wchar_t) * cchNeeded;
wil::unique_hglobal globalHandle(GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, cbNeeded));
RETURN_LAST_ERROR_IF_NULL(globalHandle.get());
PWSTR pwszClipboard = static_cast<PWSTR>(GlobalLock(globalHandle.get()));
auto pwszClipboard = static_cast<PWSTR>(GlobalLock(globalHandle.get()));
RETURN_LAST_ERROR_IF_NULL(pwszClipboard);
// The pattern gets a bit strange here because there's no good wil built-in for global lock of this type.
// Try to copy then immediately unlock. Don't throw until after (so the hglobal won't be freed until we unlock).
const HRESULT hr = StringCchCopyW(pwszClipboard, cchNeeded, finalString.data());
const auto hr = StringCchCopyW(pwszClipboard, cchNeeded, finalString.data());
GlobalUnlock(globalHandle.get());
RETURN_IF_FAILED(hr);
@@ -889,13 +889,13 @@ try
if (fAlsoCopyFormatting)
{
const auto& fontData = _actualFont;
int const iFontHeightPoints = fontData.GetUnscaledSize().Y; // this renderer uses points already
const COLORREF bgColor = _terminal->GetAttributeColors({}).second;
const int iFontHeightPoints = fontData.GetUnscaledSize().Y; // this renderer uses points already
const auto bgColor = _terminal->GetAttributeColors({}).second;
std::string HTMLToPlaceOnClip = TextBuffer::GenHTML(rows, iFontHeightPoints, fontData.GetFaceName(), bgColor);
auto HTMLToPlaceOnClip = TextBuffer::GenHTML(rows, iFontHeightPoints, fontData.GetFaceName(), bgColor);
_CopyToSystemClipboard(HTMLToPlaceOnClip, L"HTML Format");
std::string RTFToPlaceOnClip = TextBuffer::GenRTF(rows, iFontHeightPoints, fontData.GetFaceName(), bgColor);
auto RTFToPlaceOnClip = TextBuffer::GenRTF(rows, iFontHeightPoints, fontData.GetFaceName(), bgColor);
_CopyToSystemClipboard(RTFToPlaceOnClip, L"Rich Text Format");
}
}
@@ -916,22 +916,22 @@ CATCH_RETURN()
// - lpszFormat - the name of the format
HRESULT HwndTerminal::_CopyToSystemClipboard(std::string stringToCopy, LPCWSTR lpszFormat)
{
const size_t cbData = stringToCopy.size() + 1; // +1 for '\0'
const auto cbData = stringToCopy.size() + 1; // +1 for '\0'
if (cbData)
{
wil::unique_hglobal globalHandleData(GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, cbData));
RETURN_LAST_ERROR_IF_NULL(globalHandleData.get());
PSTR pszClipboardHTML = static_cast<PSTR>(GlobalLock(globalHandleData.get()));
auto pszClipboardHTML = static_cast<PSTR>(GlobalLock(globalHandleData.get()));
RETURN_LAST_ERROR_IF_NULL(pszClipboardHTML);
// The pattern gets a bit strange here because there's no good wil built-in for global lock of this type.
// Try to copy then immediately unlock. Don't throw until after (so the hglobal won't be freed until we unlock).
const HRESULT hr2 = StringCchCopyA(pszClipboardHTML, cbData, stringToCopy.data());
const auto hr2 = StringCchCopyA(pszClipboardHTML, cbData, stringToCopy.data());
GlobalUnlock(globalHandleData.get());
RETURN_IF_FAILED(hr2);
UINT const CF_FORMAT = RegisterClipboardFormatW(lpszFormat);
const auto CF_FORMAT = RegisterClipboardFormatW(lpszFormat);
RETURN_LAST_ERROR_IF(0 == CF_FORMAT);
RETURN_LAST_ERROR_IF_NULL(SetClipboardData(CF_FORMAT, globalHandleData.get()));
@@ -953,14 +953,14 @@ void HwndTerminal::_PasteTextFromClipboard() noexcept
return;
}
HANDLE ClipboardDataHandle = GetClipboardData(CF_UNICODETEXT);
auto ClipboardDataHandle = GetClipboardData(CF_UNICODETEXT);
if (ClipboardDataHandle == nullptr)
{
CloseClipboard();
return;
}
PCWCH pwstr = static_cast<PCWCH>(GlobalLock(ClipboardDataHandle));
auto pwstr = static_cast<PCWCH>(GlobalLock(ClipboardDataHandle));
_StringPaste(pwstr);

View File

@@ -109,7 +109,7 @@ private:
void _UpdateFont(int newDpi);
void _WriteTextToConnection(const std::wstring_view text) noexcept;
HRESULT _CopyTextToSystemClipboard(const TextBuffer::TextAndColor& rows, bool const fAlsoCopyFormatting);
HRESULT _CopyTextToSystemClipboard(const TextBuffer::TextAndColor& rows, const bool fAlsoCopyFormatting);
HRESULT _CopyToSystemClipboard(std::string stringToCopy, LPCWSTR lpszFormat);
void _PasteTextFromClipboard() noexcept;
void _StringPaste(const wchar_t* const pData) noexcept;

View File

@@ -13,7 +13,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
// It must be defined after CommandlineArgs.g.cpp, otherwise the compiler
// will give you just the most impossible template errors to try and
// decipher.
void CommandlineArgs::Commandline(winrt::array_view<const winrt::hstring> const& value)
void CommandlineArgs::Commandline(const winrt::array_view<const winrt::hstring>& value)
{
_args = { value.begin(), value.end() };
}

View File

@@ -22,7 +22,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
winrt::hstring CurrentDirectory() { return _cwd; };
void Commandline(winrt::array_view<const winrt::hstring> const& value);
void Commandline(const winrt::array_view<const winrt::hstring>& value);
winrt::com_array<winrt::hstring> Commandline();
private:

View File

@@ -821,7 +821,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
void Monarch::_renameRequested(const winrt::Windows::Foundation::IInspectable& /*sender*/,
const winrt::Microsoft::Terminal::Remoting::RenameRequestArgs& args)
{
bool successfullyRenamed = false;
auto successfullyRenamed = false;
try
{
@@ -972,7 +972,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
bool Monarch::DoesQuakeWindowExist()
{
bool result = false;
auto result = false;
const auto func = [&](const auto& /*id*/, const auto& p) {
if (p.WindowName() == QuakeWindowName)
{

View File

@@ -68,7 +68,7 @@ namespace Microsoft.Terminal.Remoting
event Windows.Foundation.TypedEventHandler<Object, QuitAllRequestedArgs> QuitAllRequested;
};
[default_interface] runtimeclass Monarch : IMonarch
runtimeclass Monarch : [default] IMonarch
{
Monarch();
};

View File

@@ -86,7 +86,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
// activated.
_lastActivatedArgs = args;
bool successfullyNotified = false;
auto successfullyNotified = false;
// Raise our WindowActivated event, to let the monarch know we've been
// activated.
try
@@ -172,7 +172,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
// - <none>
void Peasant::RequestIdentifyWindows()
{
bool successfullyNotified = false;
auto successfullyNotified = false;
try
{
@@ -197,7 +197,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
void Peasant::RequestRename(const winrt::Microsoft::Terminal::Remoting::RenameRequestArgs& args)
{
bool successfullyNotified = false;
auto successfullyNotified = false;
const auto oldName{ _WindowName };
try
{

View File

@@ -25,6 +25,11 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
struct ProposeCommandlineResult : public ProposeCommandlineResultT<ProposeCommandlineResult>
{
public:
ProposeCommandlineResult(const Remoting::ProposeCommandlineResult& other) :
_Id{ other.Id() },
_WindowName{ other.WindowName() },
_ShouldCreateWindow{ other.ShouldCreateWindow() } {};
WINRT_PROPERTY(Windows::Foundation::IReference<uint64_t>, Id);
WINRT_PROPERTY(winrt::hstring, WindowName);
WINRT_PROPERTY(bool, ShouldCreateWindow, true);

View File

@@ -6,7 +6,11 @@ Class Name:
- SummonWindowBehavior.h
Abstract:
- TODO!
- This is a helper class for encapsulating all the information about how a
window should be summoned. Includes info like if we should switch desktops or
monitors, if we should dropdown (and how fast), and if we should toggle to
hidden if we're already visible. Used by the Monarch to tell a Peasant how it
should behave.
--*/

View File

@@ -7,6 +7,7 @@
#include "CommandlineArgs.h"
#include "../inc/WindowingBehavior.h"
#include "FindTargetWindowArgs.h"
#include "ProposeCommandlineResult.h"
#include "WindowManager.g.cpp"
#include "../../types/inc/utils.hpp"
@@ -25,7 +26,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
// Register with COM as a server for the Monarch class
_registerAsMonarch();
// Instantiate an instance of the Monarch. This may or may not be in-proc!
bool foundMonarch = false;
auto foundMonarch = false;
while (!foundMonarch)
{
try
@@ -82,8 +83,8 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
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);
static constexpr auto RPC_SERVER_UNAVAILABLE_HR = HRESULT_FROM_WIN32(RPC_S_SERVER_UNAVAILABLE);
static constexpr auto 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:
@@ -100,13 +101,21 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
// starting a defterm, and when that BP gets hit, kill the original
// monarch, and see what happens here.
bool proposedCommandline = false;
auto proposedCommandline = false;
Remoting::ProposeCommandlineResult result{ nullptr };
while (!proposedCommandline)
{
try
{
result = _monarch.ProposeCommandline(args);
// MSFT:38542548 _We believe_ that this is the source of the
// crash here. After we get the result, stash it's values into a
// local copy, so that we can check them later. If the Monarch
// dies between now and the inspection of
// `result.ShouldCreateWindow` below, we don't want to explode
// (since _proposeToMonarch is not try/caught).
auto outOfProcResult = _monarch.ProposeCommandline(args);
result = winrt::make<implementation::ProposeCommandlineResult>(outOfProcResult);
proposedCommandline = true;
}
catch (const winrt::hresult_error& e)
@@ -332,8 +341,8 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
//
// * If we're running unpackaged: the .winmd must be a sibling of the .exe
// * If we're running packaged: the .winmd must be in the package root
_monarch = create_instance<Remoting::Monarch>(Monarch_clsid,
CLSCTX_LOCAL_SERVER);
_monarch = create_instance<Remoting::IMonarch>(Monarch_clsid,
CLSCTX_LOCAL_SERVER);
}
// NOTE: This can throw! Callers include:
@@ -541,7 +550,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
waits[1] = _monarchWaitInterrupt.get();
const auto peasantID = _peasant.GetID(); // safe: _peasant is in-proc.
bool exitThreadRequested = false;
auto exitThreadRequested = false;
while (!exitThreadRequested)
{
// At any point in all this, the current monarch might die. If it
@@ -643,7 +652,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
TraceLoggingUInt64(peasantID, "peasantID", "Our peasant ID"),
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE),
TraceLoggingKeyword(TIL_KEYWORD_TRACE));
bool foundNewMonarch = false;
auto foundNewMonarch = false;
while (!foundNewMonarch)
{
try

View File

@@ -64,7 +64,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
bool _shouldCreateWindow{ false };
bool _isKing{ false };
DWORD _registrationHostClass{ 0 };
winrt::Microsoft::Terminal::Remoting::Monarch _monarch{ nullptr };
winrt::Microsoft::Terminal::Remoting::IMonarch _monarch{ nullptr };
winrt::Microsoft::Terminal::Remoting::Peasant _peasant{ nullptr };
wil::unique_event _monarchWaitInterrupt;

View File

@@ -18,7 +18,7 @@ using namespace winrt::Microsoft::Terminal::Settings::Model;
namespace winrt::TerminalApp::implementation
{
ActionPaletteItem::ActionPaletteItem(Microsoft::Terminal::Settings::Model::Command const& command) :
ActionPaletteItem::ActionPaletteItem(const Microsoft::Terminal::Settings::Model::Command& command) :
_Command(command)
{
Name(command.Name());

View File

@@ -11,7 +11,7 @@ namespace winrt::TerminalApp::implementation
struct ActionPaletteItem : ActionPaletteItemT<ActionPaletteItem, PaletteItem>
{
ActionPaletteItem() = default;
ActionPaletteItem(Microsoft::Terminal::Settings::Model::Command const& command);
ActionPaletteItem(const Microsoft::Terminal::Settings::Model::Command& command);
WINRT_PROPERTY(Microsoft::Terminal::Settings::Model::Command, Command, nullptr);

View File

@@ -35,18 +35,18 @@ namespace winrt::TerminalApp::implementation
// Method Description:
// - Stop previewing the currently previewed action. We can use this to
// clean up any state from that action's preview.
// - We use _lastPreviewedCommand to determine what type of action to clean up.
// - We use _lastPreviewedAction to determine what type of action to clean up.
// Arguments:
// - <none>
// Return Value:
// - <none>
void TerminalPage::_EndPreview()
{
if (_lastPreviewedCommand == nullptr || _lastPreviewedCommand.ActionAndArgs() == nullptr)
if (_lastPreviewedAction == nullptr)
{
return;
}
switch (_lastPreviewedCommand.ActionAndArgs().Action())
switch (_lastPreviewedAction.Action())
{
case ShortcutAction::SetColorScheme:
case ShortcutAction::AdjustOpacity:
@@ -55,7 +55,7 @@ namespace winrt::TerminalApp::implementation
break;
}
}
_lastPreviewedCommand = nullptr;
_lastPreviewedAction = nullptr;
}
// Method Description:
@@ -140,6 +140,29 @@ namespace winrt::TerminalApp::implementation
});
}
void TerminalPage::_PreviewAction(const Settings::Model::ActionAndArgs& args)
{
switch (args.Action())
{
case ShortcutAction::SetColorScheme:
_PreviewColorScheme(args.Args().try_as<SetColorSchemeArgs>());
break;
case ShortcutAction::AdjustOpacity:
_PreviewAdjustOpacity(args.Args().try_as<AdjustOpacityArgs>());
break;
}
// GH#9818 Other ideas for actions that could be preview-able:
// * Set Font size
// * Set acrylic true/false/opacity?
// * SetPixelShaderPath?
// * SetWindowTheme (light/dark/system/<some theme from #3327>)?
// Stash this action, so we know what to do when we're done
// previewing.
_lastPreviewedAction = args;
}
// Method Description:
// - Handler for the CommandPalette::PreviewAction event. The Command
// Palette will raise this even when an action is selected, but _not_
@@ -164,29 +187,7 @@ namespace winrt::TerminalApp::implementation
}
else
{
switch (args.ActionAndArgs().Action())
{
case ShortcutAction::SetColorScheme:
{
_PreviewColorScheme(args.ActionAndArgs().Args().try_as<SetColorSchemeArgs>());
break;
}
case ShortcutAction::AdjustOpacity:
{
_PreviewAdjustOpacity(args.ActionAndArgs().Args().try_as<AdjustOpacityArgs>());
break;
}
}
// GH#9818 Other ideas for actions that could be preview-able:
// * Set Font size
// * Set acrylic true/false/opacity?
// * SetPixelShaderPath?
// * SetWindowTheme (light/dark/system/<some theme from #3327>)?
// Stash this action, so we know what to do when we're done
// previewing.
_lastPreviewedCommand = args;
_PreviewAction(args.ActionAndArgs());
}
}
}

View File

@@ -7,12 +7,12 @@ namespace winrt::TerminalApp::implementation
{
using IXamlType = ::winrt::Windows::UI::Xaml::Markup::IXamlType;
IXamlType GetXamlType(::winrt::Windows::UI::Xaml::Interop::TypeName const& type)
IXamlType GetXamlType(const ::winrt::Windows::UI::Xaml::Interop::TypeName& type)
{
return _appProvider.GetXamlType(type);
}
IXamlType GetXamlType(::winrt::hstring const& fullName)
IXamlType GetXamlType(const ::winrt::hstring& fullName)
{
return _appProvider.GetXamlType(fullName);
}

View File

@@ -44,7 +44,7 @@ namespace winrt::TerminalApp::implementation
/// will be used such as when the application is launched to open a specific file.
/// </summary>
/// <param name="e">Details about the launch request and process.</param>
void App::OnLaunched(LaunchActivatedEventArgs const& /*e*/)
void App::OnLaunched(const LaunchActivatedEventArgs& /*e*/)
{
// if this is a UWP... it means its our problem to hook up the content to the window here.
if (_isUwp)

View File

@@ -12,7 +12,7 @@ namespace winrt::TerminalApp::implementation
{
public:
App();
void OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs const&);
void OnLaunched(const Windows::ApplicationModel::Activation::LaunchActivatedEventArgs&);
TerminalApp::AppLogic Logic();

View File

@@ -46,10 +46,87 @@
Color="{ThemeResource SystemErrorTextColor}" />
<!-- Suppress top padding -->
<Thickness x:Key="TabViewHeaderPadding">9,0,8,0</Thickness>
<Thickness x:Key="TabViewHeaderPadding">9,0,5,0</Thickness>
<!-- Remove when implementing WinUI 2.6 -->
<Thickness x:Key="FlyoutContentPadding">12</Thickness>
<!-- Shadow that can be used by any control. -->
<ThemeShadow x:Name="SharedShadow" />
<!-- Colored button which changes on hover/press -->
<Style x:Key="ColorButtonStyle"
TargetType="Button">
<Setter Property="BackgroundSizing" Value="OuterBorderEdge" />
<Setter Property="BorderBrush" Value="{ThemeResource ButtonBorderBrush}" />
<Setter Property="BorderThickness" Value="{ThemeResource ButtonBorderThemeThickness}" />
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
<Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}" />
<Setter Property="FocusVisualMargin" Value="-3" />
<Setter Property="Width" Value="32" />
<Setter Property="Height" Value="32" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Border x:Name="ColorButtonBackground"
Background="{TemplateBinding Background}"
BackgroundSizing="{TemplateBinding BackgroundSizing}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}" />
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ColorButtonBackground"
Storyboard.TargetProperty="Opacity">
<DiscreteObjectKeyFrame KeyTime="0"
Value="0.9" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ColorButtonBackground"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{ThemeResource ButtonBorderBrushPointerOver}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ColorButtonBackground"
Storyboard.TargetProperty="Opacity">
<DiscreteObjectKeyFrame KeyTime="0"
Value="0.8" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ColorButtonBackground"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{ThemeResource ButtonBorderBrushPressed}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ColorButtonBackground"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{ThemeResource ButtonBackgroundDisabled}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ColorButtonBackground"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{ThemeResource ButtonBorderBrushDisabled}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Dark">
@@ -77,6 +154,8 @@
<StaticResource x:Key="UnfocusedBorderBrush"
ResourceKey="ApplicationPageBackgroundThemeBrush" />
<StaticResource x:Key="SettingsPageBackground"
ResourceKey="SolidBackgroundFillColorTertiary" />
</ResourceDictionary>
@@ -91,6 +170,29 @@
<StaticResource x:Key="UnfocusedBorderBrush"
ResourceKey="ApplicationPageBackgroundThemeBrush" />
<StaticResource x:Key="SettingsPageBackground"
ResourceKey="SolidBackgroundFillColorTertiary" />
</ResourceDictionary>
<ResourceDictionary x:Key="HighContrast">
<!-- Define resources for HighContrast mode here -->
<!--
MSFT:38264744
You'd think that if a key wasn't present in a ThemeDictionary,
it'd fall back to the original value. You'd be wrong - if you
provide a Light&dark version of a resource, but not the
HighContrast version, the resource loader will fall back to the
Light value.
SystemColorButtonFaceColorBrush is the default background color for WinUI's TabViewBackground under high contrast mode.
-->
<StaticResource x:Key="TabViewBackground"
ResourceKey="SystemColorButtonFaceColorBrush" />
<StaticResource x:Key="SettingsPageBackground"
ResourceKey="SystemColorWindowColorBrush" />
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>

View File

@@ -189,6 +189,18 @@ namespace winrt::TerminalApp::implementation
}
else if (const auto& realArgs = args.ActionArgs().try_as<SplitPaneArgs>())
{
if (const auto& newTerminalArgs{ realArgs.TerminalArgs() })
{
if (const auto index = realArgs.TerminalArgs().ProfileIndex())
{
if (gsl::narrow<uint32_t>(index.Value()) >= _settings.ActiveProfiles().Size())
{
args.Handled(false);
return;
}
}
}
_SplitPane(realArgs.SplitDirection(),
// This is safe, we're already filtering so the value is (0, 1)
::base::saturated_cast<float>(realArgs.SplitSize()),
@@ -305,6 +317,18 @@ namespace winrt::TerminalApp::implementation
}
else if (const auto& realArgs = args.ActionArgs().try_as<NewTabArgs>())
{
if (const auto& newTerminalArgs{ realArgs.TerminalArgs() })
{
if (const auto index = newTerminalArgs.ProfileIndex())
{
if (gsl::narrow<uint32_t>(index.Value()) >= _settings.ActiveProfiles().Size())
{
args.Handled(false);
return;
}
}
}
LOG_IF_FAILED(_OpenNewTab(realArgs.TerminalArgs()));
args.Handled(true);
}
@@ -837,7 +861,7 @@ namespace winrt::TerminalApp::implementation
if (WindowRenamer() == nullptr)
{
// We need to use FindName to lazy-load this object
if (MUX::Controls::TeachingTip tip{ FindName(L"WindowRenamer").try_as<MUX::Controls::TeachingTip>() })
if (auto tip{ FindName(L"WindowRenamer").try_as<MUX::Controls::TeachingTip>() })
{
tip.Closed({ get_weak(), &TerminalPage::_FocusActiveControl });
}
@@ -1009,4 +1033,14 @@ namespace winrt::TerminalApp::implementation
}
}
}
void TerminalPage::_HandleSelectAll(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
if (const auto& control{ _GetActiveControl() })
{
control.SelectAll();
args.Handled(true);
}
}
}

View File

@@ -30,7 +30,7 @@ AppCommandlineArgs::AppCommandlineArgs()
// - nonzero return values are defined in CLI::ExitCodes
int AppCommandlineArgs::ParseCommand(const Commandline& command)
{
const int argc = static_cast<int>(command.Argc());
const auto argc = static_cast<int>(command.Argc());
// Stash a pointer to the current Commandline instance we're parsing.
// When we're trying to parse the commandline for a new-tab/split-pane
@@ -809,7 +809,7 @@ void AppCommandlineArgs::_addCommandsForArg(std::vector<Commandline>& commands,
else
{
// Harder case: There was a match.
const bool matchedFirstChar = match.position(0) == 0;
const auto matchedFirstChar = match.position(0) == 0;
// If the match was at the beginning of the string, then the
// next arg should be "", since there was no content before the
// delimiter. Otherwise, add one, since the regex will include
@@ -1013,7 +1013,7 @@ int AppCommandlineArgs::ParseArgs(const winrt::Microsoft::Terminal::Settings::Mo
// Convert the commandline into an array of args with
// CommandLineToArgvW, similar to how the app typically does when
// called from the commandline.
int argc = 0;
auto argc = 0;
wil::unique_any<LPWSTR*, decltype(&::LocalFree), ::LocalFree> argv{ CommandLineToArgvW(args.Commandline().c_str(), &argc) };
if (argv)
{

View File

@@ -18,8 +18,8 @@ namespace winrt::TerminalApp::implementation
{
AppKeyBindings() = default;
bool TryKeyChord(winrt::Microsoft::Terminal::Control::KeyChord const& kc);
bool IsKeyChordExplicitlyUnbound(winrt::Microsoft::Terminal::Control::KeyChord const& kc);
bool TryKeyChord(const winrt::Microsoft::Terminal::Control::KeyChord& kc);
bool IsKeyChordExplicitlyUnbound(const winrt::Microsoft::Terminal::Control::KeyChord& kc);
void SetDispatch(const winrt::TerminalApp::ShortcutActionDispatch& dispatch);
void SetActionMap(const Microsoft::Terminal::Settings::Model::IActionMapView& actionMap);

View File

@@ -122,10 +122,10 @@ static Documents::Run _BuildErrorRun(const winrt::hstring& text, const ResourceD
textRun.Text(text);
// Color the text red (light theme) or yellow (dark theme) based on the system theme
winrt::IInspectable key = winrt::box_value(L"ErrorTextBrush");
auto key = winrt::box_value(L"ErrorTextBrush");
if (resources.HasKey(key))
{
winrt::IInspectable g = resources.Lookup(key);
auto g = resources.Lookup(key);
auto brush = g.try_as<winrt::Windows::UI::Xaml::Media::Brush>();
textRun.Foreground(brush);
}
@@ -348,11 +348,7 @@ 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.
@@ -400,14 +396,6 @@ 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
@@ -613,7 +601,7 @@ namespace winrt::TerminalApp::implementation
winrt::Windows::Foundation::Size proposedSize{};
const float scale = static_cast<float>(dpi) / static_cast<float>(USER_DEFAULT_SCREEN_DPI);
const auto scale = static_cast<float>(dpi) / static_cast<float>(USER_DEFAULT_SCREEN_DPI);
if (const auto layout = _root->LoadPersistedLayout(_settings))
{
if (layout.InitialSize())
@@ -793,7 +781,7 @@ namespace winrt::TerminalApp::implementation
// - S_OK if we successfully parsed the settings, otherwise an appropriate HRESULT.
[[nodiscard]] HRESULT AppLogic::_TryLoadSettings() noexcept
{
HRESULT hr = E_FAIL;
auto hr = E_FAIL;
try
{
@@ -1135,6 +1123,22 @@ namespace winrt::TerminalApp::implementation
}
}
// Method Description:
// - Used to tell the PTY connection that the window visibility has changed.
// The underlying PTY might need to expose window visibility status to the
// client application for the `::GetConsoleWindow()` API.
// Arguments:
// - showOrHide - True is show; false is hide.
// Return Value:
// - <none>
void AppLogic::WindowVisibilityChanged(const bool showOrHide)
{
if (_root)
{
_root->WindowVisibilityChanged(showOrHide);
}
}
// Method Description:
// - Implements the F7 handler (per GH#638)
// - Implements the Alt handler (per GH#6421)
@@ -1366,7 +1370,7 @@ namespace winrt::TerminalApp::implementation
// now.
if (parsedTarget.empty())
{
int32_t windowId = WindowingBehaviorUseNew;
auto windowId = WindowingBehaviorUseNew;
switch (windowingBehavior)
{
case WindowingMode::UseNew:
@@ -1387,7 +1391,7 @@ namespace winrt::TerminalApp::implementation
// window's ID:
try
{
int32_t windowId = ::base::saturated_cast<int32_t>(std::stoi(parsedTarget));
auto windowId = ::base::saturated_cast<int32_t>(std::stoi(parsedTarget));
// If the user provides _any_ negative number, then treat it as
// -1, for "use a new window".

View File

@@ -114,6 +114,7 @@ namespace winrt::TerminalApp::implementation
bool OnDirectKeyEvent(const uint32_t vkey, const uint8_t scanCode, const bool down);
void CloseWindow(Microsoft::Terminal::Settings::Model::LaunchPosition position);
void WindowVisibilityChanged(const bool showOrHide);
winrt::TerminalApp::TaskbarState TaskbarState();
@@ -122,7 +123,6 @@ 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();
@@ -208,6 +208,7 @@ namespace winrt::TerminalApp::implementation
FORWARDED_TYPED_EVENT(CloseRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, CloseRequested);
FORWARDED_TYPED_EVENT(OpenSystemMenu, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, OpenSystemMenu);
FORWARDED_TYPED_EVENT(QuitRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, QuitRequested);
FORWARDED_TYPED_EVENT(ShowWindowChanged, Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Control::ShowWindowArgs, _root, ShowWindowChanged);
#ifdef UNIT_TESTING
friend class TerminalAppLocalTests::CommandlineTest;

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